关于Prolog语法

关于Prolog语法,prolog,iso-prolog,Prolog,Iso Prolog,有时我会看到这样的术语: X=a:b 或 X=a-b 我可以这样做 X=Y:Z 正如预期的那样,编译器将Y与a、Z与b统一起来 现在我的回答是: 允许我使用哪些字符(或字符序列)组合两个Prolog原子 也许你可以给我一些关于这个问题的更多信息的链接 感谢您的帮助和来自德国的亲切问候让我们看看里面有什么X=Y:Z ?- display( X = Y:Z ). =(_G3,:(_G1,_G2)) true. 然后我们有一个嵌套结构,其中函子是运算符 运算符是一个原子,原子语法的规则说我们需要考虑

有时我会看到这样的术语: X=a:b 或 X=a-b

我可以这样做 X=Y:Z 正如预期的那样,编译器将Y与a、Z与b统一起来

现在我的回答是: 允许我使用哪些字符(或字符序列)组合两个Prolog原子

也许你可以给我一些关于这个问题的更多信息的链接


感谢您的帮助和来自德国的亲切问候

让我们看看里面有什么
X=Y:Z

?- display( X = Y:Z ).
=(_G3,:(_G1,_G2))
true.
然后我们有一个嵌套结构,其中函子是运算符

运算符是一个原子,原子语法的规则说我们需要考虑三种类型:

  • 包含在单引号中的任何可打印字符的序列
  • 仅一个特殊字符序列,其中一个特殊字符是O.p.“..=:-+*/>中的一个,表示(我引用):

    有时我会看到这样的术语:
    X=a:b
    X=a-b

    我可以执行像
    X=Y:Z
    这样的请求,编译器会像预期的那样将Y与a和Z与b统一起来

    现在我的答案是:我可以使用哪些字符(或字符序列) 用来组合两个Prolog原子

    简单的答案几乎是你想要的任何东西(只要它是一个原子)

    较长的答案是:

    我们看到的是中缀(
    x infix_op b
    )、前缀(
    pfx_op b
    )和后缀(
    b sfx_op
    )运算符。算术数为2的任何结构都可以是中缀运算符。arity为1的任何结构都可以是前缀或后缀运算符。因此,任何原子都可以是算符

    Prolog是通过一个优先驱动的递归下降解析器(自然是用Prolog编写的)来解析的。在
    运算符/3
    谓词中定义并枚举运算符及其优先级和关联性。关联性与解析树的构造方式有关。像
    a-b-c
    这样的表达式可以解析为
    (a-(b-c))
    (右关联)或
    ((a-b)-c)
    (左关联)

    优先级与运算符绑定的紧密程度有关。像
    a+b*c
    这样的表达式绑定为
    (a+(b*c)
    不是因为结合性,而是因为“*”/2(乘法)的优先级高于“+”/2(加法)

    你可以添加、删除和更改操作符,但这并不是说这会给你很大的空间,让你打破prolog的语法

    但是,应注意,任何运算符表达式也可以通过普通符号书写:

    a + b * c
    
    与完全相同

    '+'( a , '*'(b,c) )
    
    允许我使用哪些字符(或字符序列)组合两个Prolog原子

    您在这里要求的是Prolog的整个运算符语法定义。要获得此问题的完整答案,请参阅以获取如何获得Prolog标准ISO/IEC 13211-1的完整信息

    但作为一个简短的回答,首先:

    Prolog语法包括

  • 函数表示法,如
    +(a,b)
    ,以及

  • 可动态重新定义的运算符语法,以及

  • 一些额外的

  • 您似乎想知道哪些“字符”可以用作运算符

    简短的回答是,您可以使用所有成功的原子
    Op
    ,用于
    current\u Op(Pri,Fix,Op)
    。因此,您可以动态询问存在哪些运算符:

    ?- current_op(Pri, Fix, Op). Pri = 1, Fix = fx, Op = ($) ; Pri = 1150, Fix = fx, Op = (module_transparent) ; Pri = 700, Fix = xfx, Op = (=@=) ; Pri = 700, Fix = xfx, Op = (@>=) ; Pri = 700, Fix = xfx, Op = (>=) ... ?当前操作(Pri、Fix、op)。 Pri=1, Fix=fx, Op=($); Pri=1150, Fix=fx, Op=(模块_透明); Pri=700, Fix=xfx, Op=(=@=); Pri=700, Fix=xfx, Op=(@>=); Pri=700, Fix=xfx, Op=(>=) ... 所有这些运算符都可以以指定的方式使用,如具有指定优先级的前缀、in或后缀。其中一些运算符特定于SWI,一些运算符由标准定义。如上所述,只有
    @>=
    =
    是标准运算符

    大多数运算符仅由图形字符
    #$&*+-./:?^
    组成,或由字母、数字和下划线组成,以小写字母开头。有两个单独的字符
    ,还有更为特殊的
    ,|
    。与上述不同的运算符名称需要引用-您很少会使用反对他们

    要查看操作符如何嵌套,请使用
    write\u canonical(Term)

    答案很长是您也可以自己定义此类运算符。但是,请注意,更改运算符语法通常会产生许多难以理解的影响。更重要的是,由于许多系统在一些很少使用的配置中存在差异。例如,您提到的系统SWI


    我建议在您对Prolog语言有了更多了解之前,不要定义新的运算符。

    要想获得一个更可移植的解决方案来研究术语的结构而不使用运算符语法,您可以使用ISO Prolog标准
    write\u canonical/1
    谓词。谢谢Paulo,您是对的。我熟悉write\u canonical/1,就在今天早上(或昨天?)我注意到Jan使用了display/1,我不知道。它比写_canonical要容易记住得多……首先,感谢你非常有用的评论!他们帮了我很多忙!如果我理解正确,上面例子中的“:”-字符是函子?!而在这个例子中,函子(确切地说是什么函子?!)是运算符,还是?现在还有一个问题:除了“:”之外,我还可以使用其他哪些字符。
    在您编写时不是一个“特殊”字符。它是一个图形字符,如
    $&*+-./:?@^
    有很多“特殊”字符运算符的字符在
    +(a,*(b,c))
    中没有理由引用
    +
    *
    ,引用原子不会造成伤害,而且可以提高理解力。functor/arity是表示谓词或结构名称和arity的正常方式,如“foo/2”。 ?- current_op(Pri, Fix, Op). Pri = 1, Fix = fx, Op = ($) ; Pri = 1150, Fix = fx, Op = (module_transparent) ; Pri = 700, Fix = xfx, Op = (=@=) ; Pri = 700, Fix = xfx, Op = (@>=) ; Pri = 700, Fix = xfx, Op = (>=) ...