Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Шумихин / Шумихин / Шумихин - лекция 5

.txt
Скачиваний:
7
Добавлен:
20.05.2015
Размер:
6.86 Кб
Скачать
ЛЕКЦИЯ 5
5.10.12

Первая программа на Прологе *_*

domains
product, sum = integer
predicates
add(sum, sum, sum)
mult(product, product, product)
clauses
add(X, Y, Z) :- Z = X + Y.
mult(X, Y, Z) :- Z - X * Y.
goal
add(1, 2, X)

X=3

Если цель является внешней, Пролог на найденном решении не остановится и попытается найти альтернативные.
X=3
1 решение

= -- не оператор присваивания, а встроенный предикат, проверяет на равенство.

!!! Поэкспериментировать с вышеизложенной программой и такой целью:
add(1, X, 3)
Это обратная задача. Здесь всё зависит от того, как организована работа встроенного предиката "=", как описана задача. Так что обязательно просят поэкспериментировать.
И с этим тоже:
add(X, Y, 3)
add(X, 1, Y)


goal
add(1,2,X), mult(X,5,Z)
ошибка! ошибкаааа!!! домены не совпадают. x - sum, z - product. так-то.

Вероятно, после описания цели нужна точка.

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

Есть возможность задавать директивы компилятору.

Информация от предиката к предикату передаётся только через связывание переменных. Другого механизма в Прологе нет. Так же происходит извлечение информации из правил.
В тот момент, когда Пролог доходит до точки, все связанные переменные исчезают.
add(X, Y, Z) :- Z = X + Y.
mult(X, Y, Z) :- Z - X * Y.
В данных строках X, Y, Z -- разные переменные, на данный момент никак друг с другом не связанные.

№2
domains
name = symbol
group = integer
predicates
player(name, group)
clauses
player(иван, 1).
player(пётр, 2).
player(татьяна, 1).
...

goal
player(P1,_), player(P2,_), P1<>P2
все играют со всеми по 2 раза

player(P1,X), player(P2,X), P1<>P2
играют только с членами своей группы по 2 раза

goal
player(P,N), 1=2.
выдаст список всех участников группы

Во все версиси пролога встроен предикат fail, который всегда имеет значение "ложь". Этот предикат предназначен для поиска с возвратом.

goal
player(P,N), fail.

Предикат fail -- всегда последний предикат в проекте, ибо всё, что написано после него, никогда не будет достигнуто Прологом.

Как избавиться от "решений нет" в конце вывода результирующего списка?
Модифицируем программу (добавим предикат start):

domains
name = symbol
group = integer
predicates
player(name, group)
start
clauses
player(иван, 1).
player(пётр, 2).
player(татьяна, 1).
...
start :- player(P,N), write(P,N), fail.
start.

goal
start

"start." значит, что значение start -- истина.
Пролог переберёт все возможные пары P и N по первому правилу, каждый раз распечатает пару, каждый раз натолкнётся на fail, перейдёт к следующему клаузу (факту) "start.", получит истину, завершит работу программы без вывода странных с точки зрения заказчика комментариев вроде "решений нет".

SWI выводит первое решение и ждёт: введёте ли вы точку (всё) или точку с запятой (или). Если ввести точку с запятой, получим следующее решение. И т.д.

Предикат, который удаляют точку возврата, -- cut. Альтернативный вариант: ! (восклицательный знак).
Как только пролог встречает слово cut, все точки возврата отсекаются. Это обозначает, что движения по альтернативным путям уже не будет.
Необходимость в отсечении возникает:
1. мы знаем, что при движении по альтернативным путям решений не будет, нет смысла заставлять пролог туда идти, -- зелёные отсечения;
2. в силу алгоритма двигаться в каком-то направлении нельзя -- красные отсечения.

Зелёные отсечения -- это отсечения, которые не влияют на результат.
Красные отсечения -- это те отсечения, которые влияют на результат.

С точки зрения синтаксиса те отсечения и другие -- суть одно и то же.

Как работают отсечения?
z :- a,b,!,c.
Пролог находит первое решение для a, первое решение для b, и т.д., найдёт первое решение, удовлетворяющее и a, и b. Предположим, есть ещё решения. Попадаем на !, получаем отсечение. Если у c есть несколько решений, которые удовлетворяют и a, и b, пролог найдёт их все, т.к. точка возврата была поставлена позже точки отсечения.
Итак, это правило выдаст _первое_ решение для a и b и _все_ решения для c.
___________________________________________________________________________