Если ваша система Prolog имеет передний цепной блок, вы также можете решить
проблема, моделируя ее с помощью правил прямой цепочки. Вот
пример того, как решить проблему кувшина с водой в Jekejeke Minlog.
Состояние представлено предикатом состояния / 2.
Сначала вы даете правило, которое фильтрует дубликаты, следующим образом.
правило говорит, что факт входящего состояния / 2 должен быть удален,
если он уже находится в магазине форвардов:
% avoid duplicate state
unit &:- &- state(X,Y) && state(X,Y), !.
Затем вы даете правила, которые утверждают, что поиск не нужно продолжать
когда конечное состояние достигнуто. В настоящем примере мы проверяем
что в одном из сосудов содержится 1 литр воды:
% halt for final states
unit &:- state(_,1), !.
unit &:- state(1,_), !.
В качестве следующего шага моделируются переходы состояний как прямая цепочка
правила. Это прямо вперед. Мы моделируем опорожнение, наполнение и розлив
судов:
% emptying a vessel
state(0,X) &:- state(_,X).
state(X,0) &:- state(X,_).
% filling a vessel
state(5,X) &:- state(_,X).
state(X,7) &:- state(X,_).
% pouring water from one vessel to the other vessel
state(Z,T) &:- state(X,Y), Z is min(5,X+Y), T is max(0,X+Y-5).
state(T,Z) &:- state(X,Y), Z is min(7,X+Y), T is max(0,X+Y-7).
Теперь мы можем использовать механизм прямой цепочки, чтобы выполнить эту работу за нас. Это
не будет делать итеративное углубление, и он также не будет делать ширину в первую очередь.
Он просто сделает разрешение блока по стратегии, которая жадна для
данный факт и процесс только завершается, так как пространство состояний
конечно. Вот результат:
?- post(state(0,0)), posted.
state(0, 0).
state(5, 0).
state(5, 7).
state(0, 7).
Etc..
Подход покажет вам, есть ли решение, но не объяснит
решение. Один из способов сделать это объяснимым заключается в использовании факта
состояние / 4 вместо факта состояние / 2. Последние два аргумента используются для
список действий и для длины списка.
Правило, которое избегает дубликатов, затем изменяется на правило, которое выбирает
самое маленькое решение. Оно гласит:
% choose shorter path
unit &:- &- state(X,Y,_,N) && state(X,Y,_,M), M<N, !.
unit &:- state(X,Y,_,N) && &- state(X,Y,_,M), N<M.
Затем получаем:
?- post(state(0,0,[],0)), posted.
state(0, 0, [], 0).
state(5, 0, [fl], 1).
state(5, 7, [fr,fl], 2).
state(0, 5, [plr,fl], 2).
Etc..
С помощью небольшого предиката-помощника мы можем вызвать объяснение
действия, которые ведут к пути:
?- post(state(0,0,[],0)), state(1,7,L,_), explain(L).
0-0
fill left vessel
5-0
pour left vessel into right vessel
0-5
fill left vessel
5-5
pour left vessel into right vessel
3-7
empty right vessel
3-0
pour left vessel into right vessel
0-3
fill left vessel
5-3
pour left vessel into right vessel
1-7
Bye
Исходный код: Water Jug State
http://www.xlog.ch/jekejeke/forward/jugs3.p
Исходный код: состояние и путь кувшина с водой
http://www.xlog.ch/jekejeke/forward/jugs3path.p