I can’t seem to wrap my head around this. Consider the following dummy predicate:
foo(X, a) :- X < 10.
foo(X, b) :- X > 20.
When consulting:
?- foo(1, a).
true;
false.
I am not sure I completely understand how the choice point is created anyway (Perhaps because the two possible foo
predicates are in a kind of or relationship and Prolog just tries to unify with both? Based on this line in the trace: Redo: (24) test:foo(8, a)
and the subsequent fail, I suppose this is the case), but what really confuses me is why it works when the argument order is changed:
foo(a, X) :- X < 10.
foo(b, X) :- X > 20.
?- foo(a, 1).
true.
No choice point. What am I missing here?
TL;DR: read the documentation of the Prolog you are using. Pay attention to "clause indexing" or something of the kind.
You are missing that whichever Prolog implementation you are using is just clever enough to do indexing on the first argument in your second example. So when you pose the query ?- foo(a, Something).
it never considers the other clause.
But this is really a matter of Prolog implementation, and not a matter of Prolog as a language. Maybe there are Prologs that can also avoid the choice point in the first example. Or maybe it provides a different mechanism to achieve the same. For example SWI-Prolog (among other Prologs) has something called "tabling". With it, you can do it like this:
:- table foo/2.
foo(X, a) :- X < 10.
foo(X, b) :- X > 20.
bar(a, X) :- X < 10.
bar(b, X) :- X > 20.
Now neither foo/2
nor bar/2
has the unexpected choice point:
?- foo(1, a).
true.
?- bar(a, 1).
true.