所以我被分配了一个任务来尝试在 Prolog 中解决这个问题,尽管老师只介绍了基础知识,这基本上是 Prolog 中唯一的项目。我觉得我想多了,而且他对第一次 Prolog 程序的期望太高了。
下面列出了问题,我应该如何解决这个问题?
编写一个 Prolog 程序来解决下面的单词问题。作为解决方案的一部分,它应该打印所有的交叉点,首先列出桨手。
汤姆、杰克、比尔和吉姆不得不使用只能容纳两个人的独木舟过河。
在河的左岸到右岸的三个渡口中,独木舟都有两个人,从右到左岸的两个渡口中,独木舟的每个人都有一个人。当其他人在独木舟中时,汤姆无法划桨。
当除比尔以外的其他人在独木舟中时,杰克无法划桨。每个人至少划过一个路口。
这是我到目前为止所拥有的,虽然它“有效”,但它并不能确保每个人都至少划一次。
state(tom(Side),jim(Side),jack(Side),bill(Side),c(Side)).
initial(state(tom(l),jim(l),jack(l),bill(l),c(l))).
final(state(tom(r),jim(r),jack(r),bill(r),c(r))).
canoe(P):-P=p.
canoe(P,C):-P=p,C=c.
bad(state(tom(W),jim(X),jack(Y),bill(Z),c(C))):-
C=l,(W=c;X=c;Y=c;Z=c).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W1),jim(X),jack(Y),bill(Z),c(C1))):-
((canoe(W1),W=r,W=C,C1=m);(canoe(W),W1=l,W1=C1)).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W),jim(X1),jack(Y),bill(Z),c(C1))):-
((canoe(X1),X=r,X=C,C1=m);(canoe(X),X1=l,X1=C1)).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W),jim(X),jack(Y1),bill(Z),c(C1))):-
((canoe(Y1),Y=r,Y=C,C1=m);(canoe(Y),Y1=l,Y1=C1)).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W),jim(X),jack(Y),bill(Z1),c(C1))):-
((canoe(Z1),Z=r,Z=C,C1=m);(canoe(Z),Z1=l,Z1=C1)).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W1),jim(X1),jack(Y),bill(Z),c(C1))):-
((canoe(X1,W1),W=l,W=X,W=C,C1=m);
(canoe(X,W),W1=r,W1=X1,W1=C1)).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W1),jim(X),jack(Y),bill(Z1),c(C1))):-
((canoe(Z1,W1),W=l,W=Z,W=C,C1=m);
(canoe(Z,W),W1=r,W1=Z1,W1=C1)).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W),jim(X1),jack(Y1),bill(Z),c(C1))):-
((canoe(X1,Y1),Y=l,Y=X,Y=C,C1=m);
(canoe(X,Y),Y1=r,Y1=X1,Y1=C1)).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W),jim(X1),jack(Y),bill(Z1),c(C1))):-
((canoe(Z1,X1);canoe(X1,Z1)),
Z=l,Z=X,Z=C,C1=m);
((canoe(Z,X);canoe(X,Z)),Z1=r,Z1=X1,Z1=C1).
move(state(tom(W),jim(X),jack(Y),bill(Z),c(C)),
state(tom(W),jim(X),jack(Y1),bill(Z1),c(C1))):-
((canoe(Y1,Z1);canoe(Z1,Y1)),
Y=l,Y=Z,Y=C,C1=m);
((canoe(Y,Z);canoe(Z,Y)),Y1=r,Y1=Z1,Y1=C1).
find(Path):-initial(S),rez(S,Path).
bkt(State,Path,[Path|State]):-final(State).
bkt(State,Path,Sol):-move(State,Next),not(bad(Next)),
not(member(Next,Path)),bkt(Next,[Path|Next],Sol).
rez(State,Sol):-bkt(State,[State],Sol).
start:-find(D),writef('%w\n',D).