我尝试在 Prolog 中编写一个程序来解决众所周知的 Wolf Goat Cabbage 谜题。假设一个农民想带着他的狼、山羊和卷心菜过河。船只能同时容纳两个,他不能让狼和山羊或山羊和白菜一起离开。
我知道 Stackoverflow 上有针对此问题的有效解决方案。但我想在我的代码中找到错误以用于学习目的。这是我的代码。它导致所谓的本地堆栈溢出,我猜逻辑中存在错误。由于我对每个块都进行了评论,因此应该很容易理解。
% Helper function to check if first list
% is fully contained in second one.
subset([], []).
subset([E|Tail], [E|NTail]):-
subset(Tail, NTail).
subset([_|Tail], NTail):-
subset(Tail, NTail).
% There is space for two objects on the
% boat, but one of them must be the farmer.
crew(farmer).
crew(farmer, wolf).
crew(farmer, goat).
crew(farmer, cabbage).
% The riverside is safe if either the
% farmer is there, or not both wolf and
% goat or both goat and cabbage are there.
safe(Side) :-
member(farmer, Side).
safe(Side) :-
not(member(wolf, Side)),
not(member(goat, Side)).
safe(Side) :-
not(member(goat, Side)),
not(member(cabbage, Side)).
% To embark, objects from one riverside,
% the crew must be valid an the riverside
% must stay safe. Disembarking is easy.
embark(Crew, Side, New) :-
subset(Crew, Side),
crew(Crew),
safe(Side),
delete(Side, Crew, New).
disembark(Crew, Side, New) :-
append(Side, Crew, New).
% Crossing the river from one or the other side.
cross(Left, Right, Nextleft, Nextright) :-
embark(Left, Crew, L),
disembark(Right, Crew, R),
cross(L, R, Nextleft, Nextright).
cross(Left, Right, Nextleft, Nextright) :-
embark(Right, Crew, R),
disembark(Left, Crew, L),
cross(L, R, Nextleft, Nextright).
% Find solution to bring all objects from left
% riverside to right. Run this after consulting
% the file.
% cross([farmer, wolf, goat, cabbage], [], [], [farmer, wolf, goat, cabbage]).
这段代码有什么问题?我只是尝试更深入地了解 Prolog。