【问题标题】:Prolog - binding of operatorsProlog - 运算符的绑定
【发布时间】:2019-01-10 10:28:22
【问题描述】:

我正在做 Ivan Bratko 的“人工智能 Prolog 编程”的练习。练习说:

定义运算符“if”、“then”、“else”和“:=”,这样 以下成为法律术语:

如果 X > Y 那么 Z := X 否则 Z := Y

选择优先级,使 'if' 成为主要函子。

我无法从运算符“then”和“else”中确定哪一个应该具有较低的优先级(并且绑定更强)。我对这个问题的回答是:

:- op(900, fx, if).
:- op(800, xfx, else).
:- op(700, xfx, then).
:- op(600, xfx, :=).

(书中也有说明'>'运算符的优先级为700)。

我认为 'then' 的结合力比 'else' 强,但本练习的答案却相反:

:- op(900, fx, if).
:- op(800, xfx, then).   
:- op(700, xfx, else).  
:- op(600, xfx, :=).

我不确定让“else”的优先级低于“then”的原因。非常感谢任何见解。

【问题讨论】:

    标签: prolog artificial-intelligence


    【解决方案1】:

    以您的定义为例:

    ?- write_canonical(如果 a 则 b 否则 c)。 如果(否则(则(a,b),c)) 真的。

    以及书中的定义:

    ?- write_canonical(如果 a 则 b 否则 c)。 如果(那么(a,else(b,c))) 真的。

    还有你的定义:

    ?- write_canonical(如果 a 则(如果 b 则 c)否则 d)。 if(else(then(a,if(then(b,c))),d)) 真的。

    以及书中的定义:

    ?- write_canonical(如果 a 则(如果 b 则 c)否则 d)。 if(那么(a,else(if(then(b,c)),d))) 真的。

    请特别注意,在您的定义中,if ... then ... else 有时会被解析为 if(else(...,有时会被解析为 if(then(...

    【讨论】:

    • 所以我只是想澄清一下,这个问题没有明确的正确答案,因为答案会根据定义的解析方式而有所不同?
    • 在我看来,这个问题不合适,因为要正确解析“if...then...else...”,您需要定义 ternary运算符,在 Prolog 中不可用。因此,使用中缀和前缀运算符,您最多只能得到一些特别的近似值,这通常会导致某些情况错误或令人惊讶。
    【解决方案2】:

    /* 在创建需要运算符的构造时,我喜欢从 将所有操作员优先级设置为 10'1 。

    如果可以使构造与优先级为 10'1 的所有运算符一起使用,那是理想的。 一旦确定了优先级,就可以更改优先级以适应进一步的要求。

    例如if _if_ then _then_ else _else_的进一步要求 是对 _if__then__else_ 部分中应该包含的内容的考虑。

    例如,如果 ; 需要这样,例如 if foo ; bar then baz ; qux 那么优先级必须大于10'1100

    例如,如果 , 需要这样,例如 if foo , bar then baz , qux 那么优先级必须大于10'1000

    例如,如果 \+ 需要这样,例如 if \+ foo then \+ bar 那么优先级必须大于10'950

    例如,如果 = 需要这样,例如 if _foo_ = bar then _baz_ = qux 那么优先级必须大于 10'700 。 这 4 个运营商是最重要的考虑因素。 */

    :- op(10'1,'fx','if') .
    :- op(10'1,'yfx','then') .
    :- op(10'1,'yfx','else') .
    
    if _if_ then _then_ else _else_
    :-
    _if_ -> _then_ ; _else_
    .
    
    if _if_ then _then_
    :-
    if _if_ then _then_ else false
    .
    
    /* -- testing -- */
    
    :- op(10'1,'fy','consider') .
    :- op(10'1,'xfy','perform') .
    :- op(10'1,'xfy','form') .
    :- op(10'1,'xfy','expect') .
    :- op(10'1,'xfy','actual') .
    :- op(10'1,'xfy','success') .
    :- op(10'1,'xfy','fail') .
    
    consider _consider_ perform _perform_ form _form_ expect _expect_
    :-
    findall(_form_,(_consider_,_perform_),_actual_) ,
    (
        _actual_ = _expect_ ->
        writeq((success perform _perform_)) , nl ;
        writeq((failure perform _perform_ expect _expect_ actual _actual_)) , nl
    )
    .
    
    test
    :-
    consider
    (
        (_a_ = true) ; 
        (_a_ = false)
    )
    perform
    (
        if _a_ then (_z_ = b) else (_z_ = c)
    )
    form
    (
        _z_
    )
    expect
    [
        b ,
        c
    ]
    .
    
    test
    :-
    consider
    (
        (_a_ = true) ; 
        (_a_ = false)
    )
    perform
    (
        if _a_ then (_z_ = b)
    )
    form
    (
        _z_
    )
    expect
    [
        b
    ]
    .
    
    test
    :-
    consider
    (
        (_a_ = true , _b_ = true) ;
        (_a_ = true , _b_ = false) ; 
        (_a_ = false , _b_ = true) ; 
        (_a_ = false , _b_ = false)
    )
    perform
    (
        if _a_ then (if _b_ then (_z_ = c) else (_z_ = d)) else (_z_ = e)
    )
    form
    (
        _z_
    )
    expect
    [
        c ,
        d ,
        e ,
        e
    ]
    .
    
    
        /*
        YAP 6.2.2 (x86_64-linux): Sat Sep 17 13:59:03 UTC 2016
    I   ?-  \+ (test , \+ true) .
        (success)perform if _131254 then(_131271=b)else(_131271=c)
        (success)perform if _131254 then(_131268=b)
        (success)perform if _131257 then(if _131260 then(_131315=c)else(_131315=d))else(_131315=e)
        yes
        */
    

    【讨论】:

      猜你喜欢
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      • 2018-03-08
      • 1970-01-01
      相关资源
      最近更新 更多