PROLOG 中的垂直斜线函数到底是啥?是运营商吗?

Posted

技术标签:

【中文标题】PROLOG 中的垂直斜线函数到底是啥?是运营商吗?【英文标题】:What exactly is the vertical slash function in PROLOG? Is it an operator?PROLOG 中的垂直斜线函数到底是什么?是运营商吗? 【发布时间】:2021-08-02 09:58:58 【问题描述】:

我正在学习 PROLOG 编程语言,测试一些示例并阅读文档。然后我开始对 PROLOG 中的列表进行大量研究。这个想法是:头和尾。然后我了解到列表可以像这样在 PROLOG 中表示:

[Head | Tail]

语法非常简单,方括号带有头尾,由垂直斜线|分隔。然后我问自己PROLOG中垂直斜线|的含义(语义)是什么。正如我所说,我也对列表和垂直斜线进行了研究,但我找不到有用的东西。

所以这就是我有点困惑的原因。我想它确实是一个特殊字符,但为什么它必须是一个垂直斜线?是运营商吗?它用于系统或语言(元)应用程序吗?它在语言中的具体作用是什么?

【问题讨论】:

| 本身不是运算符,[|] 是。如果您熟悉任何 lisps,则相当于 cons。 en.wikipedia.org/wiki/Cons 是的,| 是一个操作员。在这里查看:swi-prolog.org/pldoc/doc_for?object=op/3. Au contraire,@rajashekar:| 只是一个运算符。试试`current_op(Precedence, Type, '|')。你没有必须将它用于列表(但如果你这样做了,你可能会混淆其他人在看你的代码。) | 是一个(垂直)条形。它用作头尾分离器和运算符。 嗯,所以 | 也是一个已弃用的 ;/2 swi-prolog.org/pldoc/doc_for?object=%27|%27/2 。 【参考方案1】:

是的,| 是优先级为 1105 的右结合中缀运算符,右结合表示像这样的表达式

 a|b|c|d

绑定为

'|'( a , '|'( b , '|'( c , d ) ) )

而不是左关联绑定

'|'( '|'( '|'( a , b ) , c ) , d ) 

它是 Prolog 的列表符号语法糖的一部分。在 Prolog 中,任何非空列表都有一个项目,表示为它的 head,而列表的其余部分本身就是另一个列表(可能为空) ,表示为 tail。 (一个相当不错的递归定义,嗯?)

因此,使用| 可以轻松地将列表划分为headtail。所以

[Head|Tail] = [a,b,c,d]

结果

Head = a
Tail = [b,c,d]

根据我的回答here,

Prolog 的列表表示法是句法糖 在非常简单的 prolog 术语之上。 Prolog 列表表示如下:

    空列表由原子[] 表示。为什么?因为这看起来像一个空列表的数学符号。他们本可以使用像 nil 这样的原子来表示空列表,但他们没有。

    非空列表由术语.\2 表示,其中第一个(最左边)参数是列表的head,第二个(最右边)参数是tail 列表,递归地,它本身就是一个列表。

一些例子:

一个空列表:[] 表示为原子:

  []

一个元素的列表,[a] 在内部存储为

  .(a,[])

两个元素的列表[a,b]在内部存储为

  .(a,.(b,[]))

三个元素的列表,[a,b,c] 内部存储为

  .(a,.(b,.(c,[])))

对列表头部的检查同样是相同./2符号的语法糖:

[X|Xs] 等同于.(X,Xs)

[A,B|Xs] 等同于.(A,.(B,Xs))

[A,B].(A,.(B,[])) 相同(见上文)

【讨论】:

而是s/'|' d/d/ Right-associative 操作符绑定到右边,所以a|b|c|d 被解析为a|(b|(c|d))left-associative 运算符绑定到左边,所以a|b|c|d 被解析为((a|b)|c)|d 但它只是一个运算符:它实际上并没有任何事情,除了在列表符号的上下文中。除了创建条款。在列表符号之外,像 a|b 这样的表达式只会创建术语 '|'(a,b) 哦,现在我明白了。非常感谢你澄清它!现在完全有道理了,谢谢@NicholasCarey 感谢您的回答和贡献,阅读您分享的信息让我对事情有了更深的理解。【参考方案2】:

列表模式匹配中通常使用的竖线||/2 运算符的使用似乎有点混乱。

我不熟悉其他序言,所以这可能是特定于 swi-prolog 的。 '|' 的帮助说明 following:

help('|').
:Goal1 | :Goal2
    Equivalent to ;/2. Retained for compatibility only. New code should use ;/2.

所以,列表符号中使用的| 不是这个运算符。

?- X = '[|]'(1, []).
X = [1].

?- X = '|'(1, []).
X =  (1| []).

?- [1] = '|'(1, []).
false.

?- [1] = '[|]'(1, []).
true.

如上所示,仅使用 | 只会创建复合词,而不是列表。

以下使用 Univ =.. 并使其更加清晰。

?- X = '[|]'(a, '[|]'(b, [])).
X = [a, b].

?- [a, b, c] =.. X.
X = ['[|]', a, [b, c]].

?- deep_univ([a, b, c, d], X).
X = ['[|]', a, ['[|]', b, ['[|]', c, ['[|]', d, []]]]].

我使用了here中的deep_univ/2

【讨论】:

以上是关于PROLOG 中的垂直斜线函数到底是啥?是运营商吗?的主要内容,如果未能解决你的问题,请参考以下文章

Prolog中的“逻辑纯度”是啥意思?

JQUERY中的scrollTop 和scrollleft到底是啥意思

Prolog 中的返回值

help() 输出中的斜线是啥意思?

Rails 3.0 中的 Arel 到底是啥?

Matlab eig 函数中的 nobalance 选项到底是啥?