Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Prolog > Фермер, волк, козел, капуста


Автор: Ak47black 17.10.2010, 13:16
Здравствуйте.
Есть полностью рабочий код, но чувствую что не до конца его понимаю
Код

move(state(X,X,G,C),state(Y,Y,G,C)):-opposite(X,Y). /* FARMER + WOLF */
move(state(X,W,X,C),state(Y,W,Y,C)):-opposite(X,Y). /* FARMER + GOAT */
move(state(X,W,G,X),state(Y,W,G,Y)):-opposite(X,Y). /*FARMER + CABBIDGE*/
move(state(X,W,G,C),state(Y,W,G,C)):-opposite(X,Y). /* ONLY FARMER */

opposite(east,west).
opposite(west,east).

unsafe( state(F,X,X,_) ):- opposite(F,X). 
unsafe( state(F,_,X,X) ):- opposite(F,X).

path(S,G,L,L1):-
       move(S,S1),
       not( unsafe(S1) ),
       not( member(S1,L) ),
       path( S1,G,[S1|L],L1),!.
path(G,G,T,T):-!.   /* The final state is reached  */

go:-  go(state(east,east,east,east),state(west,west,west,west)).
 
go(S,G):-
      path(S,G,[S],L),
      nl,write('A solution is:'),nl,
      write_path(L),
      fail.
go(_,_).
   
member(X,[X|_]).
member(X,[_|L]):-member(X,L).

write_move( state(X,W,G,C), state(Y,W,G,C) ) :-!,
        write('The farmer crosses the river from '),
        write(X),
        write(' to '),
        write(Y),nl. 
write_move( state(X,X,G,C), state(Y,Y,G,C) ) :-!,
        write('The farmer takes the Wolf from '),
        write(X),
        write(' of the river to '),
        write(Y),nl.
write_move( state(X,W,X,C), state(Y,W,Y,C) ) :-!,
        write('The farmer takes the Goat from' ),
        write(X),
        write(' of the river to '),
        write(Y),nl.
write_move( state(X,W,G,X), state(Y,W,G,Y) ) :-!,
        write('The farmer takes the cabbage from '),
        write(X),
        write(' of the river to '),
        write(Y),nl.
               
write_path( [H1,H2|T] ) :- !,
        write_move(H1,H2),write_path([H2|T]).
write_path( _ ).

Трудно выразить что именно мне непонятно поэтому, попробую описать ход своей мысли
Цитата

Нахождение решения начинается с ввода команды go.
После этого начинается проверка истинности предиката go.
go(_,_). - означает что он всегда будет истинным (зачем это нужно точно незнаю) 
go(S,G) - берёт в качестве своих аргументов state(east,east,east,east),state(west,west,west,west) и является истинным в случае истинности предикатов 
      path(S,G,[S],L),
      nl,write('A solution is:'),nl,
      write_path(L),
      fail.
Зачем тут нужен fail - тоже дял меня не ясно. (можен он связан с go(_,_). ?)

Проверяется истинность предиката path(S,G,[S],L), где L - это путь получаемый при выполнении проверки данного предиката?

Дальше проверяется на истинность предикат 
path(S,G,L,L1):-
       move(S,S1),
       not( unsafe(S1) ),
       not( member(S1,L) ),
       path( S1,G,[S1|L],L1),!.
path(G,G,T,T):-!.

Но я что-то тут совсем запутался.

Может как-то кто-то может подсказать, вывести меня на истинное понимание этого примера?

Добавлено @ 13:18
Пример я сам взял http://www.mari.ru/mmlab/home/prolog/LECTION6/index.html если что.

Автор: Nevidimko 17.10.2010, 22:30
go(_,_). - для того чтобы выйти из отката fail во втором правиле. Без него ты увидишь No, и правило будет считаться невыполненным
В path мне тоже кажется что L - путь.
В path берется один вариант пути, проверяются условия и есть он подходит то дальнейший поиск решений не происходит, результат красиво выводится на экран (nl,write('A solution is:'),nl,write_path(L)). Вот тут в правиле path предикат fail отправляется искать следующее истинное решение...

Автор: Ak47black 18.10.2010, 10:54
А как выполняется move(S,S1) (13 строка) ?
Я вот смотрю сейчас в данный момент, пытаюсь понять. Но что-то никак немогу представить выполнение.

Автор: Фантом 18.10.2010, 12:55
Цитата(Ak47black @  18.10.2010,  10:54 Найти цитируемый пост)
А как выполняется move(S,S1) (13 строка) ?
Я вот смотрю сейчас в данный момент, пытаюсь понять. Но что-то никак немогу представить выполнение.


move не "выполняется".  smile Это все-таки Пролог, а не императивный язык, и move в данном случае - нечто вроде булевой функции, проверяющей возможность выполнения той или иной перевозки. Конструкция с fail в предикате go заставляет цель path все время передоказываться, при этом пролог-машина перебирает различные варианты перемещений, а move отбирает из них допустимые.

Автор: Ak47black 18.10.2010, 14:08
А S1 откуда там берёться?  smile 

Автор: Фантом 18.10.2010, 17:40
Цитата(Ak47black @  18.10.2010,  14:08 Найти цитируемый пост)
А S1 откуда там берёться? 

Так именно она и меняется при передоказывании, система просто подставляет в нее все возможные варианты по очереди.

Автор: Ak47black 18.10.2010, 19:12
А, понятно......
Вообщем я вроде-бы теперь понимаю что к чему
Фантом, Спасибо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)