Сначала давайте обратимся к исходному предикату: форматирование предполагает вложенный if-then-else, но круглые скобки вокруг второй группы тел первой true
в ветвь else:
?- listing(p).
p(A, B) :-
( cond1(A, B)
-> q(A)
; true,
( cond2(A, B)
-> q(B)
)
; true
).
Вот какмы заканчиваем запросами, начинающимися с true, ...
.Вторая проблема здесь заключается в том, что использование ;
перегружено: термин формы G1; G2
интерпретируется как дизъюнкция, только если G1
не имеет формы (Cond -> Goal)
.В противном случае это интерпретируется как если-то-еще.Давайте рассмотрим различные случаи:
(true, true -> X=a); X=b
интерпретирует ;
как дизъюнкцию, потому что самый внешний функтор с левой стороны является соединением ,
.Пролог сообщает о замене ответа для каждой ветви. (true -> X=a, true); X=b
: это дизъюнкция по той же причине (true -> X=a); X=b
: это if-then-else, потому что самый внешний функтор слевасо стороны - оператор if-then ->
.Пролог сообщает только о замене ответа для ветви true
.
Интересно, что когда мы помещаем условие в переменную, это больше не работает (на SWI 8):
?- G1 = (true -> (X = a)), (G1 ; X=b).
G1 = (true->a=a),
X = a ;
G1 = (true->b=a),
X = b.
То же самое происходит, когда я заключаю G1
в call/1
:
?- G1 = (true -> (X = a)), (call(G1) ; X=b).
G1 = (true->a=a),
X = a ;
G1 = (true->b=a),
X = b.
Если я правильно прочитал ответ на предыдущий вопрос, первый долженбыть другим.
Я бы предположил, что различное поведение трассировки заключается в том, что точки останова мешают обнаружению if-then-else. Моя ошибка во время трассировки состояла в том, что вы нажали enter
, чтобы подкрастьсяно не понял, что мне нужно было ввести ;
, когда был получен фактический ответ.