Программирование на языке Пролог для искусственного интеллекта | страница 60
>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
.
• К моменту выполнения операций все их аргументы должны быть конкретизированы числами.