Prolog忽略目标排序?

Prolog忽略目标排序?,prolog,Prolog,我似乎不能完全理解prolog(gprolog)的一些行为。作为一些背景,rotate应该比较两个列表,看看它们是否已被移动(如下所示) 应该返回true。然而,当提出上述问题时,prolog似乎并不尊重规则顺序 rotate(0,[],[],[]). %base case rotate(0,[],[H|T1],[H|T2]):- rotate(0,[],T1,T2). %recurse over the remainder list (the first list

我似乎不能完全理解prolog(gprolog)的一些行为。作为一些背景,rotate应该比较两个列表,看看它们是否已被移动(如下所示)

应该返回true。然而,当提出上述问题时,prolog似乎并不尊重规则顺序

rotate(0,[],[],[]).     
%base case

rotate(0,[],[H|T1],[H|T2]):- rotate(0,[],T1,T2).        
%recurse over the remainder list (the first list from S to the end)

rotate(S,[H|T1],[H|T2],L):-S=:=0,rotate(0,T1,T2,L).         
%recurse over the elements from S to the end of list1
从另一个谓词回溯(直接在下面)

我通过跟踪发现了这种行为,坦率地说,我很困惑为什么它不会回溯并命中下一个谓词,而是失败并返回false


我也愿意用更好的方法来做这件事,因为这是期中考试。

对不起,我没有回答你的主要问题。跟踪执行以确定回溯行为是调试Prolog时的一种“最后机会”,您最好信任引擎-还因为调试器有时会出现错误:)

当一个谓词有N个可选项时,可以在测试前N-1个子句后立即放置cut,然后(最终)可以避免最后一个子句中的测试

目的很明确:将执行提交到成功路径。相反,您做了相反的操作,将剪切放在最后一个rotate/4子句中,在那里它是无用的。所以,这不应该是罪魁祸首,只是一个细微差别,表明您还没有掌握Prolog编程模型

我还建议避免“提前优化”你的作业:当逻辑正确时,程序应该独立于大于列表长度的S工作。相反,也许你应该想想,如果一个否定的S作为参数,会发生什么

如果“声明式”调试,则谓词似乎不起作用:

?- rotate(2,[4,1,2,3],R). 
R = [2, 3, 1, 4] ;
false
相反,我期望的是
[2,3,4,1]
,即这个更简单定义的结果

rotate(N, L, R) :- N > 0, N1 is N-1, rotate(L, T), rotate(N1, T, R).
rotate(0, L, L).

rotate([X|Xs],R) :- append([Xs,[X]],R).

rotate/2使用handy/2辅助工具“发送到后面”头部。我相信用append/3或您自己的定义替换它不会有问题…

对不起,我没有您的主要问题的答案。跟踪执行以确定回溯行为是调试Prolog时的一种“最后机会”,您最好信任引擎-还因为调试器有时会出现错误:)

当一个谓词有N个可选项时,可以在测试前N-1个子句后立即放置cut,然后(最终)可以避免最后一个子句中的测试

目的很明确:将执行提交到成功路径。相反,您做了相反的操作,将剪切放在最后一个rotate/4子句中,在那里它是无用的。所以,这不应该是罪魁祸首,只是一个细微差别,表明您还没有掌握Prolog编程模型

我还建议避免“提前优化”你的作业:当逻辑正确时,程序应该独立于大于列表长度的S工作。相反,也许你应该想想,如果一个否定的S作为参数,会发生什么

如果“声明式”调试,则谓词似乎不起作用:

?- rotate(2,[4,1,2,3],R). 
R = [2, 3, 1, 4] ;
false
相反,我期望的是
[2,3,4,1]
,即这个更简单定义的结果

rotate(N, L, R) :- N > 0, N1 is N-1, rotate(L, T), rotate(N1, T, R).
rotate(0, L, L).

rotate([X|Xs],R) :- append([Xs,[X]],R).

rotate/2使用handy/2辅助工具“发送到后面”头部。我相信用append/3或您自己的定义替换它是没有问题的…

可能对您来说很有趣。谓词描述任意旋转,是一个真实的关系(在所有方向上都有效)。可能对您来说很有趣。谓词描述任意旋转,是一个真实的关系(在所有方向上都有效)。我想我明白了你的意思(在所有情况下),我认为如下:-切割是无用的,因为它实际上不阻止回溯(hur dur,我应该已经看到了)-->我的代码中prolog中的算法是无用的(即mod),逻辑应该能够使用prolog回溯来找到解决方案。我认为主要的想法是,我必须去解决这个问题(按照我想要完成的步骤思考),而不是去看我可以利用的事实,以便让prolog找到解决方案。我的“感觉”:计数和回溯朝着相反的“方向”。在通过撤消/重做枚举时不容易计数。。。我们通常谈论向前和向后计算,我想我明白你的意思(在所有方面),我认为如下:-切割是无用的,因为它实际上不会阻止回溯(hur dur,我应该看到)-->我的代码中prolog中的算术没有用(即mod),逻辑应该能够使用prolog回溯来找到解决方案。我认为主要的想法是,我必须去解决这个问题(按照我想要完成的步骤思考),而不是去看我可以利用的事实,以便让prolog找到解决方案。我的“感觉”:计数和回溯朝着相反的“方向”。在通过撤消/重做枚举时不容易计数。。。我们通常谈论向前和向后的计算