我阅读了立即学习Prolog网站,并尝试进行以下练习:
6.5编写一个谓词swapfl(List1,List2),该谓词检查List1是否与List2相同,只是交换了第一个和最后一个元素。在这里,append / 3可能会再次有用,但是也可以编写递归定义而无需使用append / 3(或任何其他)谓词。
我已经编写了它,并且可以正常工作,但是它试图找到不止一种解决方案。
swapfl([HL1|TL1],[HL2|TL2]):-
swpfl(TL1,TL2,HL2,HL1).
swpfl([HL1|TL1],[HL2|TL2],AccEL1,AccEL2):-
swpfl(TL1,TL2,AccEL1,AccEL2),
HL1=HL2.
swpfl([H1],[H2],H1,H2).
我看一下代码和跟踪
[trace] [5] ?- swapfl([1,2,3],[3,2,1]).
Call: (51) swapfl([1, 2, 3], [3, 2, 1]) ? creep
Call: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
Call: (53) swpfl([3], [1], 3, 1) ? creep
Exit: (53) swpfl([3], [1], 3, 1) ? creep
Call: (53) 2=2 ? creep
Exit: (53) 2=2 ? creep
Exit: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
Exit: (51) swapfl([1, 2, 3], [3, 2, 1]) ? creep
true ;
Redo: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
Fail: (52) swpfl([2, 3], [2, 1], 3, 1) ? creep
Fail: (51) swapfl([1, 2, 3], [3, 2, 1]) ? creep
false.
我不明白为什么Prolog认为值得重做Redo。
有人可以解释为什么解决方案树中存在未搜索的分支吗?
答案 0 :(得分:1)
在做出最终决定之前,Prolog始终会探索所有选项。
尝试查看以下堆栈溢出问题: Prolog: stop condition?
错误的响应可能与开始的Prolog程序员不一致,并且像错误或警告一样“感觉”,但这实际上是完全正常的Prolog响应。 Prolog尝试查找解决方案的行为非常一致,并且当不存在更多选择时,将返回false。如果Prolog在找到最终解决方案之前已经用尽了所有其他选择,则它将显示解决方案,并且不会返回false。