Чтение онлайн

ЖАНРЫ

Программирование на языке Пролог для искусственного интеллекта

Братко Иван

Шрифт:

нод( X , Y, Д)

Тогда наши три правила можно выразить тремя предложениями так:

нод( X, X, X).

нод( X, Y, Д) :-

 X < Y,

 Y1 is Y - X,

 нод( X, Y1, Д).

нод( X, Y, Д) :-

 Y < X,

 нод( Y, X, Д).

Разумеется, с таким же успехом можно последнюю цель в третьем предложении заменить

двумя:

X1 is X - Y,

нод( X1, Y, Д)

В нашем следующем примере требуется произвести некоторый подсчет, для чего, как правило, необходимы арифметические действия. Примером такой задачи может служить вычисление длины какого-либо списка; иначе говоря, подсчет числа его элементов. Определим процедуру

длина( Список, N)

которая будет подсчитывать элементы списка

Список
и конкретизировать
N
полученным числом. Как и раньше, когда речь шла о списках, полезно рассмотреть два случая:

(1) Если список пуст, то его длина равна 0.

(2) Если он не пуст, то

Список = [Голова1 | Хвост]
и его длина равна 1 плюс длина хвоста
Хвост
.

Эти два случая соответствуют следующей программе:

длина( [], 0).

длина( [ _ | Хвост], N) :-

 длина( Хвост, N1),

 N is 1 + N1.

Применить процедуру

длина
можно так:

?- длина( [a, b, [c, d], e], N).

N = 4

Заметим, что во втором предложении этой процедуры две цели его тела нельзя поменять местами. Причина этого состоит в том, что переменная N1 должна быть конкретизирована до того, как начнет вычисляться цель

N is 1 + N1

Таким образом мы видим, что введение встроенной процедуры

is
привело нас к примеру отношения, чувствительного к порядку обработки предложений и целей. Очевидно, что процедурные соображения для подобных отношений играют жизненно важную роль.

Интересно посмотреть, что произойдет, если мы попытаемся запрограммировать отношение

длина
без использования
is
. Попытка может быть такой:

длина1( [ ], 0).

длина1( [ _ | Хвост], N) :-

 длина1( Хвост, N1),

 N = 1 + N1.

Теперь уже цель

?- длина1( [a, b, [c, d], e], N).

породит ответ:

N = 1+(1+(1+(1+0)))

Сложение ни разу в действительности не запускалось и поэтому ни разу не было выполнено. Но в процедуре

длина1
, в отличие от процедуры
длина
, мы можем поменять местами цели во втором предложении:

длина1( _ | Хвост], N) :-

 N = 1 + N1,

 длина1( Хвост, N1).

Такая версия

длина1
будет давать те же результаты, что и исходная. Ее можно записать короче:

длина1( [ _ | Хвост], 1 + N) :-

 длина1( Хвост, N).

и

она и в этом случае будет давать те же результаты. С помощью
длина1
, впрочем, тоже можно вычислять количество элементов списка:

?- длина( [а, b, с], N), Длина is N.

N = 1+(1+(l+0))

Длина = 3

Итак:

• Для выполнения арифметических действий используются встроенные процедуры.

• Арифметические операции необходимо явно запускать при помощи встроенной процедуры

is
. Встроенные процедуры связаны также с предопределенными операторами 
+
*
/
div
и 
mod
.

• К моменту выполнения операций все их аргументы должны быть конкретизированы числами.

• Значения арифметических выражений можно сравнивать с помощью таких операторов, как 

<
=<
 и т.д. Эти операторы вычисляют значения своих аргументов.

Упражнения

3.16. Определите отношение

mах( X, Y, Мах)

так, чтобы

Мах
равнялось наибольшому из двух чисел X и Y.

3.17. Определите предикат

максспис( Список, Мах)

так, чтобы

Мах
равнялось наибольшему из чисел, входящих в
Список
.

3.18. Определите предикат

сумспис( Список, Сумма)

так, чтобы

Сумма
равнялось сумме чисел, входящих в
Список
.

3.19. Определите предикат

упорядоченный( Список)

который принимает значение истина, если

Список
представляет собой упорядоченный список чисел. Например:
упорядоченный [1, 5, 6, 6, 9, 12] )
.

3.20. Определите предикат

подсумма( Множ, Сумма, ПодМнож)

где

Множ
это список чисел,
Подмнож
подмножество этих чисел, а сумма чисел из
ПодМнож
равна
Сумма
. Например:

?- подсумма( [1, 2, 5, 3, 2], 5, ПМ).

ПМ = [1, 2, 2];

ПМ = [2, 3];

ПМ = [5];

...

3.21. Определите процедуру

между( N1, N2, X)

которая, с помощью перебора, порождает все целые числа X, отвечающие условию N1≤X≤N2.

3.22. Определите операторы 'если', 'то', 'иначе' и ':=" таким образом, чтобы следующее выражение стало правильным термом:

если X > Y то Z := X иначе Z := Y

Выберите приоритеты так, чтобы 'если' стал главным функтором. Затем определите отношение 'если' так, чтобы оно стало как бы маленьким интерпретатором выражений типа 'если-то-иначе'. Например, такого

если Вел1 > Вел2 то Перем := Вел3

иначе Перем := Вел4

Поделиться с друзьями: