domains
list=integer*
predicates
member(integer,list)
clauses
(1) member(Head,[Head|_]).
( 2)member(Head,[_|Tail]):-
member(Head,Tail).
Алгоритм: (декларативная точка зрения)
Элемент принадлежит списку, если
(1) первый элемент списка и есть искомый элемент
(2) искомый элемент входит в состав хвоста списка
С процедурной точки зрения предложения программы 1 и 2 можно трактовать так: чтобы найти принадлежность элемента списку, надо проверить, не совпадает ли элемент с головой списка и если нет, то попытаться найти этот элемент в хвосте списка.
Цели
? member(3,[5,6,3,8,9]) –просим Пролог выяснить верно ли это утверждение.
(ответ: Yes или No в зависимости от того, входит или нет элемент с состав списка)
? member(X,[6,8,9])- вывод всего списка
И процедурная и декларативная точки зрения соотносятся с целями 1 и 2.
(ответ:
X=6
X=8
X=9
)
Модифицируем первое предложение member(Head,[Head|__]):-!.
Как изменится ответ, если поставим цель ?member(X,[6,8,9])
(ответ: X=6- только одно решение) Отсечение не позволит нам получить оставшиеся элементы списка, следовательно, это можно использовать только для получения одного конкретного значения –первого элемента списка.
|
|
Проверим, имеет ли значение порядок написания двух предложений для предиката member()? Поменяем местами эти предложения. Поставим цель member(X,[6,8,9]).Ответ будет напечатан в обратном порядке:
(ответ:
X=9
X=8
X=6
)
Убедились, что с процедурной точки зрения порядок предложений в программе важен. Изменение порядка правил в процедуре приведет к перестановке ветвей в дереве поиска цели, использующей данную процедуру. Само дерево поиска не изменится, но обход деревабудет производиться в ином порядке, а значит и процесс унификации пойдет иначе.
Замечание: Порядок целей более существенен, чем порядок предложений. Порядок целей имеет решающее значение при определении последовательности действий в программе. Изменение порядка целей приведет к изменению дерева поиска.