Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Логическое прогаммирование. Курс лекций. М. 200...doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
610.82 Кб
Скачать

Этот вызов приводит к бесконечному циклу

?- pred3(lis,jim)

==> бесконечный цикл

Вариант 4

pred4(X,Z):-

pred4(X,Y),

parent(Y,Z).

pred4(X,Z):-

parent(Y,Z).

?- pred4(tom,pat).

==> бесконечный цикл

Данный пример показывает, как пролог-система может пытаться решить задачу таким способом, при котором решение никогда не будет достигнуто, хотя оно существует. Такая ситуация не является редкостью при программировании на Прологе (как и на других языках).

Рекомендации:

1) в первую очередь применяйте самое простое правило;

2) избегайте левой рекурсии.

3.2. Декларативная и процедурная семантики

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

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

Декларативная семантика программы на “чистом” Прологе не зависит от порядка предложений и от порядка целей в предложениях.

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

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

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

Определение – это попытка окружить пустыню стеной из слов.

Сэмюэль Батлер 1835-1902

4. Структуры данных

4.1. Арифметика в Прологе

Арифметические выражения

Простейшие операнды в арифметических выражениях:

  • переменные,

  • числа,

  • вызовы арифметических функций,

  • атомы.

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

Знаки операций:

унарные + , -

+ , - , * , /

// - целочисленное деление

mod - остаток от деления

^ - возведение в степень

Арифметические функции:

abs(X)

max(X,Y)

min(X,Y)

random(N) => 0 i  N (N,i - целые)

integer(X) - округление X до ближайшего целого

floor(R) => N (N R<N+1, пол - наибольшее целое  R)

ceil(R) => N (N-1 < R  N, потолок - наименьшее целое  R)

sqrt(X)

sin(X) - углы в радианах

cos(X)

tan(X)

asin(X)

acos(X)

atan(X)

log(X)  ln X

log10 (X)

exp(X)  e^X

pi =3.14159265358

e = 2.718281828459045

Описание предикатов. Используются следующие соглашения при описании предикатов в дальнейшем тексте (то же самое действует в help'е).

predicate(+A,-A,?A).

+ - входной аргумент

- - выходной аргумент

? - входной или выходной

Шаблон указывает возможные способы вызова предиката. Арность предиката указывается следующим образом:

predicate/3 - предикат с местностью (арностью) 3

Встроенные арифметические предикаты

Арифметические выражения вычисляются только тогда, когда они служат аргументами одного из встроенных арифметических предикатов.

=(?A,?B) , ?A = ? B - унификация термов A и B

?- X=3.

X = 3

Yes

?- X= 3+5.

X = 3 + 5

Yes

?- 3 = 1+2.

No

?- X = a+b.

X = a + b

Yes

is(-Number, +Expr) , -Number is +Expr

- детерминированный предикат (дает один ответ)

?- 5 is 2+(8 // 2).

No

?- 5 is (2+8) // 2.

Yes

?- X is 2*3,Y is 2^X.

X = 6

Y = 64

Yes

?- A is a+b. => ошибка

Предикаты сравнения чисел

+Expr1 > +Expr2 или >(+Expr1,+Expr2)

+Expr1 < +Expr2

+Expr1 =< +Expr2

+Expr1 >= +Expr2

+Expr1 =:= +Expr2 (равно)

+Expr1 =\= +Expr2 (не равно)

Программирование числовых функций

Предикат f(+N,?R) истинен тогда и только тогда, когда R равно факториалу натурального числа N, т.е. N! = R (= 12…N).

f(0,1).

f(X,Y):-

X > 0,

X1 is X -1,

f(X1,Y1),

Y is X*Y1.

Программирование с накапливающим параметром позволяет писать эффективные рекурсивные программы.

f1(N,N,R,R).

f1(N,X,Y,R):-

X =\= N,

X1 is X+1,

Y1 is Y*X1,

f1(N,X1,Y1,R).

f(N,R):-

f1(N,0,1,R).

Здесь второй параметр накапливает значение аргумента, третий – текущее значение факториала.

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