首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽视目标排序?

忽视目标排序?
EN

Stack Overflow用户
提问于 2017-10-26 01:53:48
回答 1查看 207关注 0票数 1

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

代码语言:javascript
复制
?- rotate(1,[4,1,2,3],[1,2,3,4]). 

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

代码语言:javascript
复制
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将忽略下面的谓词

代码语言:javascript
复制
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

从另一个谓词(直接在下面)进行回溯。

代码语言:javascript
复制
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。

我也对更好的方法持开放态度,因为这是期中考试的练习。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-26 04:39:50

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

当一个谓词有N个替代项时,您可以在测试后立即对第一个N1子句进行裁剪,然后(最终)在最后一个子句中避免测试。

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

我还建议避免“早期优化”您的作业:当逻辑正确时,程序应该独立工作,而S大于列表长度。相反,也许你应该考虑一下,如果给出一个负S作为论证,会发生什么。

如果您以“声明式”调试,则您的谓词似乎无法工作:

代码语言:javascript
复制
?- rotate(2,[4,1,2,3],R). 
R = [2, 3, 1, 4] ;
false

相反,我希望[2, 3, 4, 1],也就是这个简单定义的结果

代码语言:javascript
复制
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).

旋转/2使用方便的追加/2助手,以“发送回”头部。我相信你不会有问题用附件/3或你自己的定义.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46944639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档