I’m trying to understand why the Prolog implementations do not behave according to the execution model in textbooks - for example, in Sterling and Shapiro's book “The Art of Prolog” (chapter 6, “Clean Prolog”, section 6.1, “Prolog Execution Model”).
The performance model to which I belong is (p. 93 Stirling and Shapiro):
Entrance: Goal G and Program P
Conclusion: An instance of G, which is a logical consequence of P, or else
Algorithm:
Initialize resolvent to the goal G while resolvent not empty: choose goal A from resolvent choose renamed clause A' <- B_1, ..., B_n from P such that A, A' unify with mgu θ (if no such goal and clause exist, exit the "while" loop) replace A by B_1, ..., B_n in resolvent apply θ to resolvent and to G If resolvent empty, then output G, else output NO
Additionally (page 120 of the same book), Prolog selects goals ( choose goal A
) in the order from left to right and searches for offers ( choose renamed clause ...
) in the order in which they are displayed in the program.
The program below has the definition of not
(called n
in the program) and one fact.
n(X) :- X, !, fail. n(X). f(a).
If I try to prove n(n(f(X)))
, it will succeed (according to two tutorials, as well as SWI Prolog, GNU Prolog and Yap). But isn't that weird? According to this execution model, which several books put up, this is what I would expect (skipping the renaming of variables so that everything is simple, since there will be no conflict anyway):
RESOLVENT: n(n(f(Z)))
Unionmatches X
in the first sentence with n(f(Z))
and replaces the target with the tail of that sentence.
RESOLVENT: n(f(Z)), !, fail
.
the union again combines X
in the first section with f(Z)
and replaces the first target in the resolution with the tail of the sentence
RESOLVENT: f(Z), !, fail, !, fail
.
the union corresponds to f(Z)
→ success! Now this is excluded from the resolvent.
RESOLVENT: !, fail, !, fail
.
And " !, fail, !, fail
" should not succeed! After the cut, a failure occurs. The end of the story. (And indeed, input !,fail,!,fail
, because the request will fail on all Prolog systems to which I have access).
So, can I assume that the execution model in textbooks is not what Prolog uses?
edit : changing the first sentence to n(X) :- call(X), !, fail
does not make any difference in all the prologs I tried.