What you're really asking is how to create a choice point. You get a solution whenever you have a successful unification. That's what happens in @seanmcl's first predicate:
bet(N, M, K) :- N =< M, K = N.
To get a choice point, you need to have alternatives. There are only two ways to get an alternative in Prolog: with an explicit "or": ;
, or by supplying another rule. @seanmcl's code gives another rule, which is idiomatic for this situation.
To give another example, member/2
generates a solution for every item in the list, but there's no magic C function needed, just two rules:
member(X, [X|_]).
member(X, [_|Xs]) :- member(X, Xs).
Let's look at what happens here with member(X, [1,2])
. First, the first rule is used and [X|_]
is unified with [1,2]
, producing X=1
, _=[2]
. This is a successful unification, so a solution is generated. If this fails (such as by you pressing ;
at the console), backtracking is initiated. The next choice point is between the two rules, so the next rule is entered. [_|Xs]
unifies with [1,2], producing the binding Xs=[2]
and then member(X, [2])
is called. Upon re-entry, the same decisions are available to be made again, so the first rule member(X, [X|_])
is applied and the X=2
binding is produced. This is a solution. If you backtrack again, you'll get a harmless failure because neither of the rules unify with []
.
I hope this helps make sense of the situation a little bit.