This succeeds because Prolog uses negation as finite failure.
If we evaluate the Prolog predicate, we see that:
[trace] ?- two(X, Y).
Call: (8) two(_660, _662) ? creep
Call: (9) one(_660) ? creep
Exit: (9) one(s) ? creep
Call: (9) one(_662) ? creep
Exit: (9) one(s) ? creep
Call: (9) three(s) ? creep
Exit: (9) three(s) ? creep
Call: (9) three(s) ? creep
Exit: (9) three(s) ? creep
Redo: (9) one(_662) ? creep
Exit: (9) one(t) ? creep
Call: (9) three(s) ? creep
Exit: (9) three(s) ? creep
Call: (9) three(t) ? creep
Fail: (9) three(t) ? creep
Redo: (8) two(s, t) ? creep
Call: (9) two(t, s) ? creep
Call: (10) one(t) ? creep
Exit: (10) one(t) ? creep
Call: (10) one(s) ? creep
Exit: (10) one(s) ? creep
Call: (10) three(t) ? creep
Fail: (10) three(t) ? creep
Fail: (9) two(t, s) ? creep
Redo: (8) two(s, t) ? creep
Exit: (8) two(s, t) ? creep
X = s,
Y = t .
So in a first "path" that fails X and Y are both set to s:
two(X,Y) :-
one(X), %% X = s
one(Y), %% Y = s
three(X), %% X = s
\+three(Y), %% Y = s, fail
\+two(Y,X).
But then we backtrack over the one(Y) call, and we obtain:
two(X,Y) :-
one(X), %% X = s
one(Y), %% Y = t
three(X), %% X = s
\+three(Y), %% Y = t
\+two(Y,X) %% call two(t, s).
Now \+ p(X, Y) is considered true, given p(X, Y) can not be satisfied, and gets stuck in an infinite loop. We thus call two(t, s), and this fails, since:
two(t,s) :-
one(t), %% succeeds
one(s), %% succeeds
three(t), %% fails
\+three(s), %%
\+two(s,t) %%
So three(t) fails, and since there are no backtracking opportunities here, two(t, s) thus ends. So that means that two(t, s) has finite failure, hence \+ two(t, s) succeeds, and thus two(X, Y) succeeds with X = s, Y = t.
one(X), one(Y), three(X)to succeed, which isX = sandY = t. Then\+ three(Y)succeeds sincethree(t)fails, and\+ two(Y,X)succeeds becausetwo(t,s)fails. In short,two(Y,X)has only one solution, which is the one your query shows. Prolog doesn't call\+ two(Y,X)infinitely many times because there aren't infinitely many choices for a possible solution. - lurkertwo(X, Y) :- \+ two(Y, X), ...would produce an infinite loop. But because you have constrained whatXandYcan be prior to the recursion, it won’t. - Daniel Lyonstrace.to see how Prolog obtains a certain result. - Willem Van Onsem