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。 (一个相当不错的递归定义,嗯?)
因此,使用|
可以轻松地将列表划分为head 和tail。所以
[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 中的垂直斜线函数到底是啥?是运营商吗?的主要内容,如果未能解决你的问题,请参考以下文章