2014-01-21 58 views
5

这个问题是指材料在本书的第3章:序言,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([],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) 

我的问题是:

  1. 的是这两种表示方法(使用 - 而不是使用它)之间的差异

  2. 在哪些情况下最好是用他们每个人的?

感谢

+0

谢谢大家的宝贵意见。 – user17302

回答

6

务必:不要使用(-)/2(\)/2或任何其他运营商来表示“差异列表”。原因是你经常会有一个谓词带有一个列表参数和一个使用差异列表的内部谓词。由于两者具有相同的名称,并且可能同名,所以事情会变得混乱。更糟糕的是,它可能适用于“某些情况”。此外,该操作员会产生一些成本,您可以通过两个单独的参数避免这些成本。

尝试坚持一个干净的命名约定。那就是S0,S1 ... S。以这种方式,表示差异列表的参数将很容易看到。为了更好地强调这些参数属于一起,有些人在分隔逗号之后不使用空格,而是将其用于其他参数。因此:

p(L+R, S0,S) :- 
    p(L, S0,S1), 
    p(R, S1,S). 

另外,(-)/2在Prolog中有另一个含义。它用于表示一对Key-Value,如在keysort/2中。

任何Prolog书籍我都知道为差异列表建议运算符来自20世纪80年代。

+0

@ will:现在有[真实答案](https://www.quora.com/profile/Alan-Kay-11)! – false

+0

有意思,谢谢。 –

6

我在序言的经验是有限的,但似乎旧的教科书,多倾向于请使用-或其他字符(例如\)来表示列表和它的尾巴。较新的Prolog代码始终使用两个参数(如第一个示例中所示)。例如,SWI-Prolog中的所有内置和库谓词始终使用两个单独的参数。

从理论上讲,你更喜欢哪种风格。我想在你自己的代码中保持一致并没有什么坏处。

实际上,不同之处在于,在一个参数中不是一个复合项,而是两个参数,这应该是一个更有效的表示。

编辑

确保还@false阅读答案。

6

我同意鲍里斯对不同陈述的看法(+1)。此外,这在我看来很清楚,你应该使用DCG而不是明确地编码列表差异。例如,考虑代码以下版本:

parts(X) --> { basicpart(X) }, [X]. 
parts(X) --> { assembly(X, Parts) }, assembly_(Parts). 

assembly_([])  --> []. 
assembly_([X|Xs]) --> parts(X), assembly_(Xs). 

使用,定义assembly/2basicpart/1完全按照你的例子后:

?- phrase(parts(X), Ls).

的DCG有一个明确的声明,易于阅读的解释并且需要更少的参数。