结构(差异列表)Prolog
此问题涉及本书第3章中的材料: Prolog、Clocksin和Mellish编程,第5版 在本书第72页中,显示了使用差异列表的程序:结构(差异列表)Prolog,prolog,dcg,difference-lists,Prolog,Dcg,Difference Lists,此问题涉及本书第3章中的材料: Prolog、Clocksin和Mellish编程,第5版 在本书第72页中,显示了使用差异列表的程序: partsOf(X,P):- partsacc(X,P,Hole) , Hole=[]. partsacc(X,[X|Hole],Hole):-basicpart(X). partsacc(X,P,Hole):- assembly(X,Subparts), partsacclist(Subparts, P, Hole). partsacclist([],H
partsOf(X,P):- partsacc(X,P,Hole) , Hole=[].
partsacc(X,[X|Hole],Hole):-basicpart(X).
partsacc(X,P,Hole):- assembly(X,Subparts), partsacclist(Subparts, P, Hole).
partsacclist([],Hole,Hole).
partsacclist([P|T], Total, Hole):- partsacc(P,Total,Hole1), partsacclist(T,Hole1,Hole).
在许多在线教程中,使用了以下格式的“-”,例如:
append([ A , B , C | R1 ] – R1 , [ D , E | R2 ] – R2 , R3)
我的问题是:
谢谢我在Prolog中的经验是有限的,但是旧的文本似乎倾向于使用
-
或另一个字符(例如\
)来表示列表及其尾部。较新的Prolog代码始终使用两个参数(如第一个示例中所示)。例如,SWI Prolog中的所有内置谓词和库谓词始终使用两个独立的参数
理论上,你喜欢哪种风格没有区别。我想在你自己的代码中保持一致不会有什么坏处
在实践中,不同之处在于,不是一个复合术语在一个参数中包含两个列表,而是有两个参数,这应该是一种更有效的表示方式
编辑
请务必阅读@false的答案。我同意Boris关于不同表述所说的(+1)。此外,在我看来,这显然是一个应该使用DCG而不是显式编码列表差异的情况。例如,考虑下面的代码版本:
parts(X) --> { basicpart(X) }, [X].
parts(X) --> { assembly(X, Parts) }, assembly_(Parts).
assembly_([]) --> [].
assembly_([X|Xs]) --> parts(X), assembly_(Xs).
用法,在定义assembly/2
和basicpart/1
之后,与您的示例完全相同:
?-短语(第(X)部分,Ls)。
DCG具有清晰的声明性和易于阅读的解释,并且需要更少的参数 无论如何:不要使用
(-)/2
或(\)/2
或任何其他运算符来表示“差异列表”。原因是您经常会有一个带有一个列表参数的谓词和一个使用差异列表的内部谓词。由于两者具有相同的算术数,而且可能也具有相同的名称,事情会变得混乱。更糟糕的是,它可能适用于“某些情况”。此外,该运算符将产生一些成本,您可以使用两个单独的参数来避免
尽量遵守干净的命名约定。即S0
,S1
<代码>S。通过这种方式,表示差异列表的参数将很容易看到。为了更好地强调这些参数属于同一个参数,有些人不在分隔逗号后使用空格,而将其用于其他参数。因此:
p(L+R, S0,S) :-
p(L, S0,S1),
p(R, S1,S).
此外,(-)/2
在Prolog中还有另一种含义。它用于表示一对键值
,如中所示
我所知道的任何一本为差异列表建议运算符的序言书都是20世纪80年代出版的。谢谢大家的宝贵意见。@威尔:现在有了!