skip to Main Content

I am doing an exercise from ‘Prolog Programming for Artificial Intelligence’ by Ivan Bratko. The exercise says:

Define the operators ‘if’, ‘then’, ‘else’ and ‘:=’, so that the
following becomes a legal term:

if X > Y then Z := X else Z := Y

Choose the precedences so that ‘if’ will be the principal functor.

I am having trouble determining out of the operators ‘then’ and ‘else’, which one should have the lower precedence (and bind stronger). My answer to this question was:

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

(It is also stated in the book that the ‘>’ operator has a precedence of 700).

I thought that ‘then’ would bind stronger than ‘else’, however the answer for this exercise states otherwise:

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

I am not sure of the rationale behind making ‘else’ have a lower precedence than ‘then’. Any insights are greatly appreciated.

2

Answers


  1. Consider for example, with your definition:

    ?- write_canonical(if a then b else c).
    if(else(then(a,b),c))
    true.
    

    and with the definition from the book:

    ?- write_canonical(if a then b else c).
    if(then(a,else(b,c)))
    true.
    

    and further, with your definition:

    ?- write_canonical(if a then (if b then c) else d).
    if(else(then(a,if(then(b,c))),d))
    true.
    

    and with the definition from the book:

    ?- write_canonical(if a then (if b then c) else d).
    if(then(a,else(if(then(b,c)),d)))
    true.
    

    Note in particular that with your definition, if ... then ... else, is sometimes parsed as if(else(..., and sometimes as if(then(...!

    Login or Signup to reply.
  2. /*
    When working on the creation of constructs requiring operators I like to start with
    setting all of the operator priority’s to 10’1 .

    If the construct can be made to work with all of the operators at priority at 10’1 that is ideal .
    Once that is established then the priority can be changed to accomodate further requirements .

    For example the further requirements of if _if_ then _then_ else _else_
    are considerations of what should be containable in the _if_ and the _then_ and the _else_ parts .

    For example if that is desirable for ; such as if foo ; bar then baz ; qux
    then the priority will have to be greater than 10'1100 .

    For example if that is desirable for , such as if foo , bar then baz , qux
    then the priority will have to be greater than 10'1000 .

    For example if that is desirable for + such as if + foo then + bar
    then the priority will have to be greater than 10'950 .

    For example if that is desirable for = such as if _foo_ = bar then _baz_ = qux
    then the priority will have to be greater than 10'700 .
    Those 4 operators are the most important considerations .
    */

    :- 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
        */
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search