Сначала давайте обратимся к исходному предикату: форматирование предполагает вложенный 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
интерпретирует ;
как дизъюнкцию, потому что самый внешний функтор левой части - это конъюнкция ,
. Prolog сообщает о подстановке ответов для каждой ветви.
(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
для ползучести, но я не понимал, что мне нужно ввести ;
, когда фактический ответ был сообщен.
person
lambda.xy.x
schedule
06.06.2019
?- (true -> X=a); X=b.
я получаюX = a.
Вместо этого:trace, (true -> X=a); X=b.
я получаюX = a ; X = b
. Я в сети SWISH. - person damianodamiano   schedule 07.06.2019p1 -> p2
эквивалентомp1, !, p2
. Однако(true, !, X=a), true); X = b
дает только одно решениеX=a
, тогда как((true -> X=a), true); X=b.
дает два. Я действительно удивлен, что это дает два. - person lurker   schedule 07.06.2019trace, (true -> X=a); X=b.
дает два решения, ноtrace, (true, !, X=a) ; X=b
дает только одно (X=a
), чего я ожидал и от->
. - person lurker   schedule 07.06.2019;
и if-then-else-> ;
. - person lambda.xy.x   schedule 07.06.2019I wanted other people to earn the points and add my solution in the end.
Я тоже так думаю. Нет ничего плохого в том, чтобы опубликовать такой вопрос, который должен быть известен и который нелегко найти, а затем быстро опубликовать ответ. Проблема возникает, когда вы отправляете ответ и быстро принимаете свой ответ. Отправив ответ сразу, другие увидят ответ, а затем извлекут из него уроки, в основном это новички в этой теме, и, не принимая ваш ответ, вы следуете обычной практике в SO. :) - person Guy Coder   schedule 07.06.2019