Syntax PROLOG中的垂直斜杠函数到底是什么?是接线员吗?
我在学习PROLOG编程语言,测试一些示例并阅读文档。然后我开始在PROLOG中对列表进行大量研究。想法是:头和尾。然后我了解到列表可以用PROLOG表示如下:Syntax PROLOG中的垂直斜杠函数到底是什么?是接线员吗?,syntax,prolog,operators,semantics,Syntax,Prolog,Operators,Semantics,我在学习PROLOG编程语言,测试一些示例并阅读文档。然后我开始在PROLOG中对列表进行大量研究。想法是:头和尾。然后我了解到列表可以用PROLOG表示如下: [Head | Tail] 语法非常简单,方括号中有一个头和一个尾,用垂直斜杠隔开。然后我问自己PROLOG中垂直斜杠的意思(语义)是什么。正如我所说的,我也做过关于列表和垂直斜线的研究,但我没能找到一些有用的东西。 这就是为什么我有点困惑的原因。我想它确实是一个特殊的字符,但为什么它必须是一个垂直斜杠呢?是接线员吗?它是用于系统
[Head | Tail]
这就是为什么我有点困惑的原因。我想它确实是一个特殊的字符,但为什么它必须是一个垂直斜杠呢?是接线员吗?它是用于系统还是语言(元)应用程序?它在语言中的具体功能是什么?是的,
|
是一个优先级为1105的右联想中缀运算符,右联想意味着表达式
a|b|c|d
绑定为
'|'( a , '|'( b , '|'( c , d ) ) )
而不是左关联绑定
'|'( '|'( '|'( a , b ) , c ) , d )
它是Prolog的列表表示法语法糖的一部分。在Prolog中,任何非空列表都有一个单独的项,表示为它的头,而列表的其余部分本身就是另一个列表(可能是空的),表示为尾。(一个相当不错的递归定义,嗯?)
因此,可以使用|
轻松地将列表划分为头尾两部分。所以
[Head|Tail] = [a,b,c,d]
导致
Head = a
Tail = [b,c,d]
从我的回答来看
Prolog的列表表示法是在非常简单的Prolog术语之上的语法糖。序言列表如下所示:
[]
表示。为什么?因为这看起来像是空列表的数学符号。他们本可以使用类似于nil
的原子来表示空列表,但他们没有这样做
\2
表示,其中第一个(最左端)参数是列表的头部,第二个(最右端)参数是列表的尾部,它本身就是一个递归列表
- 空列表:
表示为原子:[]
[]
- 一个元素的列表,
在内部存储为[A]
.(a,[])
.(a,.(b,[]))
.(a,.(b,.(c,[])))
- 两个元素的列表
在内部存储为[A,b]
.(a,[])
.(a,.(b,[]))
.(a,.(b,.(c,[])))
- 三个元素的列表,
在内部存储为[A,b,c]
.(a,[])
.(a,.(b,[]))
.(a,.(b,.(c,[])))
与[X | Xs]
(X,Xs)
与[A,B | Xs]
(A,B,Xs))
与[A,B]
(A,.(B,[])
对于列表模式匹配中常用的竖条
和/2
操作符的使用,似乎有点混淆
?- X = '[|]'(1, []).
X = [1].
?- X = '|'(1, []).
X = (1| []).
?- [1] = '|'(1, []).
false.
?- [1] = '[|]'(1, []).
true.
我不熟悉其他序言,因此这可能是特定于swi序言的。“|”的帮助说明:
因此,列表表示法中使用的|
不是此运算符
?- X = '[|]'(1, []).
X = [1].
?- X = '|'(1, []).
X = (1| []).
?- [1] = '|'(1, []).
false.
?- [1] = '[|]'(1, []).
true.
如上所示,使用just|
只创建一个复合术语,而不是列表
下面使用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, []]]]].
我使用了来自
的deep|univ/2
本身不是操作员,[|]
是。如果您熟悉任何LISP,它相当于cons
。是,|
是一个运算符。在这里查看:@rajashekar:
只是一个操作员。请尝试“当前”操作(优先级,键入“|”)。你不必在列表中使用它(但是如果你这样做了,你可能会把其他人看你的代码弄糊涂了。)
是一个(垂直)条。它用作头尾分隔符和操作符。嗯,所以|
也是一个不推荐使用的/2
。更确切地说,s/'|'d/d/
对不起,我不知道什么是“右关联”和“左关联”绑定。我知道关联是一种可以用于逻辑命题的属性。是这样吗?这是一个优先顺序吗?它在实践中发生了什么变化?右关联运算符绑定到右侧,因此a | b | c | d
被解析为好像它是a |(b |(c | d))
;左关联运算符绑定到左,因此a | b | c | d
被解析为((a | b | c)| d
),但它只是一个运算符:除了在列表表示法的上下文中,它实际上什么都不做。除了创建术语。在列表表示法之外,像a | b
这样的表达式只是创建了术语“|”(a,b)
。哦,现在我明白了。非常感谢您的澄清!现在完全有道理了,谢谢你@NicholasCarey