这是我第一次使用Prolog进行编程,我在掌握如何正确使用该语言方面遇到了一些麻烦。我正在构建一个分析谜题的程序,并返回解决谜题的动作(路径)列表。这是一个非常简化的版本:
puzzle(Size,start(StartX,StartY),goal(GoalX,GoalY),Clues,Path) :-
solve(Size,StartX,StartY,XX,YY,Turns,Clues,GoalX,GoalY,[field(StartX,StartY)],Path).
solve(Size,X,Y,XX,YY,Turns,Clues,GoalX,GoalY,Visited,Path) :-
X=GoalX, Y=GoalY,!;
Turns == 0, neighbor(X,Y,XX,YY), append(link(X,Y,XX,YY),Path,Newpath), solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,Newpath);
Turns > 1, turn(X,Y,XX,YY), append(link(X,Y,XX,YY), Path, Newpath), solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,Newpath).
我通过递归调用solve函数创建路径,并在每次新调用时以递增方式将某个操作附加到路径,直到达到目标。现在我的问题是最后一个递归调用有我正在寻找的路径,但是如果我问
?- puzzle(3, start(1,1), goal(3,3), [clue(2,1,2),clue(2,2,2)],Path)
它不会返回该路径。举例说明:
Exit: (13) solve(3, 3, 2, 0, 1, _G1027, _G1028, 1, 0, 1, [clue(2, 2, 2)], 3, 3, [feld(3, 2), feld(3, 1), feld(2, 1), feld(1, 1)], [link(3, 1, 3, 2), link(2, 1, 3, 1), link(1, 1, 2, 1), _G1012]) ? creep
[link(3,1,3,2),link(2,1,3,1),link(1,1,2,1),_ G1012]是我需要的路径。
Exit: (12) move2(3, 3, 1, 1, 0, _G1027, _G1028, 1, 0, 2, [clue(2, 2, 2)], 3, 3, [feld(3, 1), feld(2, 1), feld(1, 1)], [link(2, 1, 3, 1), link(1, 1, 2, 1), _G1012]) ? creep
Exit: (11) solve(3, 3, 1, 1, 0, _G1027, _G1028, _G1029, _G1030, 2, [clue(2, 2, 2)], 3, 3, [feld(3, 1), feld(2, 1), feld(1, 1)], [link(2, 1, 3, 1), link(1, 1, 2, 1), _G1012]) ? creep
Exit: (10) stepfromclue(3, 2, 1, 1, 0, 2, [clue(2, 2, 2)], 3, 3, [feld(2, 1), feld(1, 1)], [link(1, 1, 2, 1), _G1012]) ? creep
Exit: (9) checkclue(3, 2, 1, 1, 0, [clue(2, 1, 2), clue(2, 2, 2)], 3, 3, [feld(2, 1), feld(1, 1)], [link(1, 1, 2, 1), _G1012]) ? creep
Exit: (8) solve(3, 1, 1, 1, 0, 2, 1, _G1029, _G1030, 0, [clue(2, 1, 2), clue(2, 2, 2)], 3, 3, [feld(1, 1)], [_G1012]) ? creep
Exit: (7) puzzle(3, start(1, 1), goal(3, 3), [clue(2, 1, 2), clue(2, 2, 2)], [_G1012]) ? creep
Exit: (6) puzzle(1, [_G1012]) ? creep
路径= [_G1012]是我得到的路径。我真的无法理解如何在不完全重写程序的情况下“询问”我需要的路径。
答案 0 :(得分:0)
没有看到完整的代码(包括link/4
事实),这有点难以猜测,因为我无法自己跟踪程序。但我认为问题如下:
您尝试做的是通过在路径中附加链接来迭代地构建路径,在变量NewPath
中创建新路径:
append(link(X,Y,XX,YY),Path,Newpath),
这里有两个问题。首先,link(X,Y,XX,YY)
不是列表,因此append/3
将失败。第二个更重要的是,Path
是输入变量,NewPath
是输出,但是您只将NewPath
传递给solve/11
的下一个调用,但不是。这样,完整路径永远不会传递回调用者。因此,回到puzzle/5
调用的级别,Path
变量保持未实例化。
solve
的代码应该看起来更像这样:
solve(_,X,Y,_,_,_,_,GoalX,GoalY,_,Path,Path) :-
X=GoalX, Y=GoalY,!.
solve(Size,X,Y,XX,YY,Turns,Clues,GoalX,GoalY,Visited,PathIn,Path) :-
Turns == 0,
neighbor(X,Y,XX,YY),
append(PathIn,[link(X,Y,XX,YY)],PathOut),
solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,PathOut,Path).
solve(Size,X,Y,XX,YY,Turns,Clues,GoalX,GoalY,Visited,PathIn,Path) :-
turn(X,Y,XX,YY),
append(PathIn,[link(X,Y,XX,YY)],PathOut),
solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,PathOut,Path).
但可以进一步简化。