Эквивалентность оператора дизъюнкции и определение с несколькими правилами - PullRequest
0 голосов
/ 14 февраля 2019

Я только что наткнулся на определение ;/2 в Руководстве по прологу SWI , в котором говорится:

The `or' predicate is defined as:

Goal1 ; _Goal2 :- Goal1.
_Goal1 ; Goal2 :- Goal2.

Не означает ли это, что ;/2 ведет себя точно так же, как если бы мынаписал наш собственный предикат помощника, состоящий из двух правил?Я запомнил, что ;/2 была нечистой конструкцией (но возможно, я смешиваю это с if-then-else), но это определение чисто (хотя и мета-логическое).

Семантика ;/2 определены в стандарте ISO в пункте 7.8.6, но это делается с точки зрения манипулирования текущим состоянием, точками выбора и т. Д.

Соответствует ли определение в руководстве по SWI определению ISO?Если нет, знаете ли вы пример, где они отличаются?

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Не означает ли это, что / 2 ведет себя точно так же, как если бы мы написали наш собственный предикат помощника, состоящий из двух правил?

Нет.Преобразование термин в тело имеет значение.

Но сначала его (;)/2, который определен в и 7.8.6 (дизъюнкция) и 7.8.8 (if-then-else)) - как предлагает самое первое предложение в 7.8.6.Круглые скобки вокруг ; см. В примечании 7.1.6.6.

Итак, первый вопрос - как можно решить, какой подпункт применяется, если вы видите ( G_0 ; H_0 ) в своей программе.Это не зависит от экземпляра, присутствующего при вызове (;)/2, а скорее зависит от экземпляра во время преобразования термина в тело (7.6.2).

?- G_0 = ( true -> X = si ), ( G_0 ; X = nisi ).
   G_0 =  (true->si=si),
   X = si
;  G_0 =  (true->nisi=si),
   X = nisi.

?- G_0 = ( true -> X = si ), call( ( G_0 ; X = nisi ) ).
   G_0 =  (true->si=si),
   X = si.

В первом запросе термин-в-телопреобразование тела заменяется в дизъюнкции G_0 на call(G_0), и, таким образом,

( call( ( true -> X = si ) ) ; X = nisi ) )

будет выполнено.

Во втором запросе два преобразования члена в тело один раз длявесь запрос и один раз для явного call/1, но оба оставляют все как есть, и, таким образом,

call( ( true -> X = si ; X = nisi ) )

будет выполнено, а остальное пропущено.

Дальнейшие различия из-запреобразование терминов в тело для порезов и ошибок из-за уродливых тел.

0 голосов
/ 14 февраля 2019

Насколько я знаю, определение

p(X) :- G1 ; G2 .

- это то же самое, что определение

p(X) :- G1 .
p(X) :- G2 .

И да, вы смешиваете это ; с чем-то связанным, но полностьюразные _ -> _ ; _.

...