在处理列表时,Prolog中的“ - ”符号是什么意思?

时间:2013-03-16 23:38:57

标签: prolog dcg prolog-cut difference-lists

我正在阅读this问题的答案,

p(X) :- read(A), q(A,X-[]).

q(end,X-X) :- !.    
q(A,[A|X]-Y) :- read(B), q(B,X-Y).

上面的代码使用语法 List-List 。我有点理解发生了什么,但我想知道“ - ”符号/谓词到底是做什么的。 此外,这个SWI是否具体?

2 个答案:

答案 0 :(得分:6)

代表差异列表的(-)/2是一种相当罕见的惯例。在旧书中,也使用了另一个运算符(\)/2

许多人更喜欢使用两个单独的参数。与使用运算符相比,有几个优点:

  1. 谓词不能意外地与参数的未实例化变量一起使用。考虑调用q(A, X)代替q(A, X-[])

  2. 使用两个参数时,执行效率更高一些。许多系统(如SWI)必须动态创建每个(-)/2结构。

  3. 尽管如此,还有另一种方法可以使用差异列表,这通常不易出错:您可以使用来实现此目的。

    实际上,程序中有两个错误,其中一个错误是由差异列表的处理方式引起的。另一个错误是程序不处理文件结束。最好使用end_of_file代替end。但这是一个你迟早会发现自己的肤浅的东西。

    另一个更微妙的错误是由于差异列表和剪切之间的相互作用。我不是削减的忠实粉丝,但让我们看看这条规则。在左侧的所有东西都被执行后切割。

    q(end_of_file,X-X) :- !.
    

    第一个参数是原子end_of_file。由于我们仅使用q/2作为第一个参数的read/1结果,因此这只能是一个比较。所以我们在文件(或流)的末尾。然而,还有其他事情必须坚持下去。只有那些成功的人才会被执行:第二个参数必须是(-)/2(好的,在所有地方都有一个减号)。然后:(-)/2的两个参数必须相同(必须统一)。为什么?我们在文件的末尾,但如果这些参数没有统一,那么将尝试另一个规则。

    这是什么时候发生的?这是一个令人讨厌的案例:

    p([X,Y,Z]).
    

    只需输入一个常量,例如my_constant.,然后按 Cntrl-d Cntrl + z p/1在这种情况下该做什么?理想情况下,完成输入后会失败。但是,它会等待进一步的输入。

    原因是切割位置不合适。我们说p/1不是坚定。这是Prolog程序中的常见错误。我只能建议减少削减的使用和DCG的采用。使用DCG,这不可能发生:

    p2(X) :- read(A), phrase(q2(A),X).
    
    q2(end_of_file) --> !.
    q2(A) --> [A], {read(B)}, q2(B).
    

    使用DCG,无论p/1的参数如何,都会执行剪切。

答案 1 :(得分:2)

我以为你的意思是: - 。

这是一个差异列表。

http://en.wikibooks.org/wiki/Prolog/Difference_Lists