
Задача 6
Напишите предикат p(+N, -L) - истинный тогда и только тогда, когда список L содержит все последовательности (списки) из N нулей, единиц и двоек, в которых никакая цифра не повторяется два раза подряд (нет куска вида XX).
Решение
p(1,[[0],[1],[2]]).
p(N,R):- N>1,
N1 is N-1,
p(N1,R1),
t(R1,R).
t([],[]).
t([X|T],Z):-
t(T,R1),
s(X,R),
append(R,R1,Z).
s([0|T],[[1,0|T],[2,0|T]]).
s([1|T],[[0,1|T],[2,1|T]]).
s([2|T],[[0,2|T],[1,2|T]]).
Задача 7 Сортирока Хоара
Предикат быстрая_сортировка/2 выдает список с отсортированными элементами – числами.
быстрая_сортировка(L,S):-
append(L1,[X,Y|T],L),
X>Y,
аppend(L1,[Y,X|T],R),
быстрая_сортировка(R,S).
быстрая_сортировка(L,L).
Помощь в SWI-Prolog’е
После инсталляции интерпретатора SWI-Prolog есть возможность обратиться к помощи через ярлык «manual.html». Кроме того, документация для пользователя находится в файле manual.pdf (читается с помощью программы Adobe Acrobat).
Кроме того, SWI-Prolog имеет помощь online. Вызов «?- help(<имя предиката>).» выдает на экран информацию об этом предикате. Вызов «?- help.» выдает информацию о том, как пользоваться этой помощью.
Трассировка выполнения программы
Предикат trace позволяет пользователю отслеживать состояние интерпретатора Пролога.
trace/0
Стартует трассировщик. В процессе мониторинга в выходной файл выводятся все целевые утверждения, обрабатываемые интерпретатором языка. Зачастую этой информации для пользователя слишком много.
trace(+Pred)
Эквивалентно вызову trace(+Pred, +all).
trace(+Pred, + Ports)
Устанавливаются точки трассировки на всех предикатах, удовлетворяющих спецификации Pred. Ports есть список портов (call, redo, exit, fail). Атом all ссылается на все порты. Если перед именем порта стоит символ «–», то данный порт не трассируется. Знак «+» говорит о том, что установлена трассировка данного порта.
При трассировке предиката получаем следующую информацию:
уровень глубины рекурсивных вызовов;
когда предпринимается первая попытка обработки целевого утверждения (порт call);
когда цель успешно достигнута (порт exit);
возможность других соответствий целевому утверждению (порт redo);
невозможность достижения цели, поскольку все попытки завершились неудачно (порт fail).
Примеры:
?- trace(hello). % трассировка всех портов предиката hello с любой арность
?- trace(foo/2, +fail). % трассировка foo/2
?- trace(bar/1, -all). % прекращение трассировки bar/1.
Проведем трассировку для программы:
родитель( пэм, боб).
родитель( том, боб).
родитель( том, лиз).
родитель( боб, энн).
родитель( боб, пэт).
родитель( пэт, джим).
предок(X,Y):-
родитель(X,Y).
предок(X,Y):-
родитель(X,Z),
предок(Z,Y).
?- trace(родитель).
% родитель/2: [call, redo, exit, fail]
Yes
[debug] ?- trace(предок).
% предок/2: [call, redo, exit, fail]
Yes
[debug] ?- предок(том,пэт).
T Call: (6) предок(том, пэт)
T Call: (7) родитель(том, пэт)
T Fail: (7) родитель(том, пэт)
T Redo: (6) предок(том, пэт)
T Call: (7) родитель(том, _G414)
T Exit: (7) родитель(том, боб)
T Call: (7) предок(боб, пэт)
T Call: (8) родитель(боб, пэт)
T Exit: (8) родитель(боб, пэт)
T Exit: (7) предок(боб, пэт)
T Exit: (6) предок(том, пэт)
Yes