【问题标题】:Prolog Ignoring Goal Ordering?Prolog忽略目标排序?
【发布时间】:2017-10-26 01:53:48
【问题描述】:

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

?- rotate(1,[4,1,2,3],[1,2,3,4]). 

应该返回真。但是,当提出上述问题时,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)

Prolog 会忽略下面的谓词 when

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

从这个其他谓词回溯(直接在下面)。

rotate(S,[H|T1],L,T2):-S > 0,S1 is S - 1,rotate(S1,T1,L,[H|T2]).        
%add elements 1 to S into the remainder list

rotate(S,L1,L2):-len(L1,Len),S1 is S mod Len,!,rotate(S1,L1,L2,[]). 
%ensure the shift is not out of bounds, call rotate/4

%utility function because couldn't use length
len([],Ret,Ret).
len([_|T],Len,Ret):-Len1 is Len+1,len(T,Len1,Ret).
len(L,Len):-len(L,0,Len).

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

我也愿意接受更好的方法来做到这一点,因为这是期中练习。

【问题讨论】:

  • 也许this answer 对你来说很有趣。谓词描述任意旋转并且是真实的关系(适用于所有方向)。

标签: prolog


【解决方案1】:

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

当您有 N 个谓词备选方案时,您可以在前 N-1 个子句的每个子句的测试之后立即进行切割,然后您可以(最终)避免在最后一个子句中进行测试。

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

我还建议避免“早期优化”您的分配:当逻辑正确时,程序应该独立于 S 大于列表长度。相反,也许您应该考虑如果将 negative 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 使用方便的 append/2 助手,将头部“发送回”。我相信你用 append/3 或你自己的定义替换它是没有问题的......

【讨论】:

  • 我想我明白你的意思(在所有方面),我认为如下: - 剪切是无用的,因为它实际上并不能防止回溯(hur-dur 我应该已经看到了) -
  • ->我的代码中prolog中的算术没有用(即mod),逻辑应该能够使用prolog回溯来找到解决方案。我认为主要的想法是我迫切地解决问题(考虑我想要完成的步骤),而不是查看我能够让 prolog 找到解决方案的事实。
  • 我的“感觉”:计数和回溯的“方向”是相反的。 while 通过 undo/redo 枚举不容易计数...我们通常说 forwardbackward 计算
猜你喜欢
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 2012-01-23
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多