Использование «или» в Прологе - PullRequest
0 голосов
/ 10 января 2019

По какой-то причине эти два фрагмента кода не эквивалентны, причем первый дает очень странные (и неверные результаты).

-- Method 1
highestElement1([],A,A).
highestElement1([H|T],A,Max) :-
                    H > A,
                    highestElement1(T,H,Max);
                    highestElement1(T,A,Max).

-- Method 2
highestElement2([],A,A).
highestElement2([H|T],A,Max) :-
                    H > A,
                    highestElement2(T,H,Max).

highestElement2([H|T],A,Max) :-
                    H =< A,
                    highestElement2(T,A,Max).

Насколько я понимаю, они должны быть идентичными, так как я считаю, (d) что сопоставление с образцом и 'или' в основном являются синтетическим сахаром для друг друга. Разве это не так?

1 Ответ

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

Method1 фактически эквивалентен:

highestElement2([],A,A).

highestElement2([H|T],A,Max) :-
    H > A,
    highestElement2(T,H,Max).

highestElement2([H|T],A,Max) :-
    highestElement2(T,A,Max).

Это связано с относительными приоритетами операторов (,)/2 и (;)/2:

| ?- current_op(Priority, Type, ',').

Priority = 1000
Type = xfy

yes
| ?- current_op(Priority, Type, ';').

Priority = 1100
Type = xfy

yes

т.е. второй пункт highestElement1 анализируется как:

highestElement1([H|T],A,Max) :-
    (H > A, highestElement1(T,H,Max))
    ;
    highestElement1(T,A,Max).

Один способ визуализировать, как анализируется термин, если мы не уверены в нотации оператора, - это использовать стандартный write_canonical/1 встроенный предикат:

| ?- write_canonical((a :- b,c; d)).
:-(a,;(','(b,c),d))

(1 ms) yes

Вывод говорит нам, что у нас есть составной термин с именем :- и двумя аргументами, a и ;(','(b,c),d). Второй аргумент также является составным термином с именем ; и двумя аргументами ','(b,c) и d.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...