1

我最近在 Mercury 中遇到了这个代码示例:

append(X,Y,Z) :-
  X == [],
  Z := Y.
append(X,Y,Z) :-
  X => [H | T],
  append(T,Y,NT),
  Z <= [H | NT].

= 作为一名 Prolog 程序员,我想知道:正常的统一和这里使用的:=or有什么区别?=>

Mercury 参考文献中,这些运算符获得不同的优先级,但它们没有解释差异。

4

3 回答 3

4

首先让我们使用缩进重写代码:

append(X, Y, Z) :-
    X == [],
    Z := Y.
append(X, Y, Z) :-
    X => [H | T],
    append(T, Y, NT),
    Z <= [H | NT].

您似乎必须将所有代码缩进四个空格,这在评论中似乎不起作用,我上面的评论应该被忽略(我无法删除它们)。

上面的代码不是真正的 Mercury 代码,而是伪代码。它作为真正的 Mercury 代码没有意义,因为<=and=>运算符用于类型类 (IIRC),而不是统一。另外,我以前没有见过:=操作员,我不确定它是做什么的。

在这种伪代码风格(我相信)中,作者试图证明这:=是一种统一的赋值类型,其中X赋值为Y. 类似地=>显示的解构和显示X构造。还显示了和空列表之间的相等性测试。所有这些操作都是统一的类型。编译器知道谓词的每种模式应该使用哪种类型的统一。对于此代码,有意义的模式是<=Z==Xappend(in, in, out)

Mercury 在这方面与 Prolog 不同,它知道要使用哪种类型的统一,因此可以生成更高效的代码并确保程序是模式正确的

还有一件事,这个伪代码的真正Mercury 代码是:

:- pred append(list(T)::in, list(T)::in, list(T)::out) is det.

append(X, Y, Z) :-
    X = [],
    Z = Y.
append(X, Y, Z) :-
    X = [H | T],
    append(T, Y, NT),
    Z = [H | NT].

请注意,每个统一都是 a=并且已添加谓词和模式声明。

于 2011-08-04T03:05:58.043 回答
3

在具体的 Mercury 语法中,运算符:=用于字段更新。

于 2011-08-13T07:13:09.720 回答
1

也许我们在最近的 Mercury 版本中无法使用像 ':=' '<=' '=>' '==' 这样的运算符,但根据 Nancy Mazur 论文中的描述,这些运算符实际上是专门统一的。'=>' 代表解构,例如 X => f(Y1, Y2, ..., Yn) 其中 X 是输入,所有 Yn 都是输出。是半分。'<=' 恰恰相反,是 det。'==' 用在两边都磨的情况下,是semidet。':=' 就像任何其他语言中的常规分配运算符一样,它是 det。在旧论文中,我什至看到他们使用 '==' 而不是 '=>' 来执行解构。(我觉得我的英语很糟糕= x =)

于 2018-05-19T16:16:41.313 回答