Пролог - привязка операторов - PullRequest
0 голосов
/ 10 января 2019

Я делаю упражнение из «Программирования пролога для искусственного интеллекта» Ивана Братко. Упражнение говорит:

Определите операторы 'if', 'then', 'else' и ': =', чтобы следующее становится юридическим термином:

если X> Y, то Z: = X, иначе Z: = Y

Выберите приоритеты, чтобы «если» было основным функтором.

У меня возникают проблемы с определением из операторов then и else того, какой из них должен иметь более низкий приоритет (и связываться сильнее). Мой ответ на этот вопрос был:

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

(В книге также указано, что оператор '>' имеет приоритет 700).

Я думал, что «тогда» будет связываться сильнее, чем «иначе», однако ответ на это упражнение гласит иначе:

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

Я не уверен в обосновании того, что «иное» имеет более низкий приоритет, чем «тогда». Любые идеи приветствуются.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

/ * Когда я работаю над созданием конструкций, требующих операторов, мне нравится начинать с установка всех приоритетов оператора на 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
    */
0 голосов
/ 10 января 2019

Рассмотрим, например, с вашим определением:

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

и с определением из книги:

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

и далее, с вашим определением:

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

и с определением из книги:

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

Обратите внимание, в частности, что с вашим определением if ... then ... else иногда анализируется как if(else(..., а иногда как if(then(...!

...