Syntax PROLOG中的垂直斜杠函数到底是什么?是接线员吗?

Syntax PROLOG中的垂直斜杠函数到底是什么?是接线员吗?,syntax,prolog,operators,semantics,Syntax,Prolog,Operators,Semantics,我在学习PROLOG编程语言,测试一些示例并阅读文档。然后我开始在PROLOG中对列表进行大量研究。想法是:头和尾。然后我了解到列表可以用PROLOG表示如下: [Head | Tail] 语法非常简单,方括号中有一个头和一个尾,用垂直斜杠隔开。然后我问自己PROLOG中垂直斜杠的意思(语义)是什么。正如我所说的,我也做过关于列表和垂直斜线的研究,但我没能找到一些有用的东西。 这就是为什么我有点困惑的原因。我想它确实是一个特殊的字符,但为什么它必须是一个垂直斜杠呢?是接线员吗?它是用于系统

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

  • [Head | Tail]
语法非常简单,方括号中有一个头和一个尾,用垂直斜杠隔开。然后我问自己PROLOG中垂直斜杠的意思(语义)是什么。正如我所说的,我也做过关于列表和垂直斜线的研究,但我没能找到一些有用的东西。


这就是为什么我有点困惑的原因。我想它确实是一个特殊的字符,但为什么它必须是一个垂直斜杠呢?是接线员吗?它是用于系统还是语言(元)应用程序?它在语言中的具体功能是什么?

是的,
|
是一个优先级为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术语之上的语法糖。序言列表如下所示:

  • 空列表由atom
    []
    表示。为什么?因为这看起来像是空列表的数学符号。他们本可以使用类似于
    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