我試圖在Prolog中編寫程序來解決衆所周知的狼山羊白菜拼圖。鑑於一個想用狼,山羊和捲心菜過河的農民。船隻同時舉行兩次,他不能與山羊或山羊一起離開狼。狼山羊白菜拼圖解算器中的堆棧溢出
我知道這裏有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。
一個肯定的錯誤就是你稱之爲船員(船員)的方式,或者更確切地說你如何定義船員。我想你想製作一份名單:「船員([農夫,狼])'。 –
在運行之前,請使用'trace。',這將允許您逐步執行並查看它開始在循環中運行的點 - 這是非常有用的學習工具。 – magus
@Amicable好吧,我不知道代碼評論中沒有工作代碼是關於主題的。 – danijar