Equivalence of disjunction operator and definition with several rules

让人想犯罪 __ 提交于 2019-12-10 13:39:45

问题


I just stumbled over the definition of ;/2 in the SWI Prolog Manual which states:

The `or' predicate is defined as:

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

Wouldn't that mean that ;/2 behaves exactly as if we wrote our own helper predicate consisting of two rules? I had memorized that ;/2 was an impure construct (but it's possible I'm mixing this up with if-then-else) but this definition is pure (although meta-logical).

The semantics of ;/2 are defined in the ISO standard in paragraph 7.8.6 but this is done in terms of manipulation of the current state, choice points etc.

Is the definition in the SWI manual equivalent to the ISO definition? If no, do you know an example where they differ?


回答1:


Wouldn't that mean that ;/2 behaves exactly as if we wrote our own helper predicate consisting of two rules?

No. Term-to-body conversion makes the difference.

But first, its (;)/2 which is defined in both 7.8.6 (disjunction) and 7.8.8 (if-then-else) — as the very first sentence in 7.8.6 suggests. For the round brackets around ; see the note in 7.1.6.6.

So the first question is how it is possible to decide which subclause applies in case you see ( G_0 ; H_0 ) in your program. This does not depend on the instantiation present when calling (;)/2 but rather it depends on the instantiation during term-to-body conversion (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.

In the first query term-to-body conversion replaces within the disjunction G_0 by call(G_0) and thus

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

will be executed.

In the second query there are two term-to-body conversions once for the entire query and once for the explicit call/1, but both leave everything as is, and thus

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

will be executed and the else case is left out.

Further differences due to term-to-body conversion are for cuts and errors due to malformed bodies.




回答2:


As far as I know, defining

p(X) :- G1 ; G2 .

is the same as defining

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

And yes, you're mixing this ; with the somewhat related but completely different _ -> _ ; _.



来源:https://stackoverflow.com/questions/54691932/equivalence-of-disjunction-operator-and-definition-with-several-rules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!