我想用 Prolog 作为练习来解决“狐狸、鹅和豆袋难题”。
所以我写了
p(left).
p(right).
valid((Man, Goose, Fox, Beans)) :- p(Man),p(Goose),p(Fox),p(Beans), Man == Goose.
valid((Man, Goose, Fox, Beans)) :- p(Man),p(Goose),p(Fox),p(Beans), Man == Beans, Goose \= Fox.
valid((Man, Goose, Fox, Beans)) :- p(Man),p(Goose),p(Fox),p(Beans), Man == Fox, Goose \= Beans.
step((Man1, Goose, Fox, Beans), "Man", (Man2, Goose, Fox, Beans)) :-
valid((Man1, Goose, Fox, Beans)), valid((Man2, Goose, Fox, Beans)),
Man1 \= Man2.
step((Man1, Goose1, Fox, Beans), "Goose", (Man2, Goose2, Fox, Beans)) :-
valid((Man1, Goose1, Fox, Beans)), valid((Man2, Goose2, Fox, Beans)),
Man1 \= Man2, Goose1 \= Goose2.
step((Man1, Goose, Fox1, Beans), "Fox", (Man2, Goose, Fox2, Beans)) :-
valid((Man1, Goose, Fox1, Beans)), valid((Man2, Goose, Fox2, Beans)),
Man1 \= Man2, Fox1 \= Fox2.
step((Man1, Goose, Fox, Beans1), "Beans", (Man2, Goose, Fox, Beans1)) :-
valid((Man1, Goose, Fox, Beans1)), valid((Man2, Goose, Fox, Beans2)),
Man1 \= Man2, Beans1 \= Beans2.
reachable(S, _,[], S).
reachable(S, Visited, [Step|Steps], Z) :-
step(S,Step,Tmp),valid(Tmp), not(member(Tmp,Visited)),
reachable(Tmp, [Tmp|Visited], Steps, Z).
start((left,left,left,left)).
goal((right,right,right,right)).
solve(Steps) :- start(S), goal(Z), reachable(S, [], Steps, Z).
问题
我想solve(X).
我会得到一系列有效的步骤。但相反,我得到
?- solve(X).
false.
为什么我没有得到从开始到目标的步骤列表?
代码解释
valid
检查一个 4 元组,其中第一个元素是“Man”的位置,第二个是“Goose”的位置,第三个是“Beans”的位置,如果没有人被吃掉。
step(Situation1, Description, Situation2)
从一个有效的情境迈向另一个有效的情境。
reachable(Start, SituationList, Steps, Goal)
检查是否Goal
可以从情境中到达情境Goal
,而每个情境SituationList
都只被访问一次,并且Steps
描述了按顺序采取了哪些步骤。