Prolog false is returned instead of a number
I am trying to write a predicate that returns the minimum and maximum between two numbers. The predicates min
and max
work fine, however, when I try to use a function min_max
for example min_max(2,5,X,Y)
, I get false. Can anyone please help?
min(X,Y,X) :- X=<Y.
min(X,Y,Y) :- Y<X.
max(X,Y,Y) :- X=<Y.
max(X,Y,X) :- Y<X.
min_max(X,Y,MIN,MAX) :-
min(X,Y,MIN),
max(X,Y,MAX).
source to share
Yours min/2
and max/2
are vague, so there are alternatives to search. When do you rate
min_max(2,5,X,Y).
You see
X = 2,
Y = 5
and it pauses, waiting for input from you. If you then click .
, it will be successful. If, however, you click ;
, it looks for alternatives and finds nothing.
You need to change your min/2
and max/2
to define something like this:
min(X,Y,Z) :- ( X < Y -> Z = X ; Z = Y ) .
max(X,Y,Z) :- ( X > Y -> Z = X ; Z = Y ) .
[The operator ->
(implication) effectively acts as a "soft cut", eliminating alternatives.]
Once you do that, it works as you would expect, without pause for input (since you eliminated the selection points):
13 ?- min_max(2,5,X,Y). X = 2, Y = 5. 14 ?-
This can help if you think of your prolog program as a tree with selection points as branches (and decisions as leaf nodes). The prologue walks through this tree trying to find solutions.
In your original program, yours min_max/4
has 4 possible solutions (2 for min/2
and 2 for max/2
), although there is only one "functional" solution. When tracking back, the prologue engine tries to find alternative solutions and finds nothing.
By rewriting min/2
and max/2
to eliminate selection points, we effectively prune the tree as we descend, leaving us one solution.
source to share
How about combining min/3
and max/3
multiple ways? Consider this definition:
min_max(X,Y,X,Y) :- X =< Y.
min_max(X,Y,Y,X) :- Y < X.
Examples of requests:
?- min_max(2,5,Min,Max). Min = 2, Max = 5 ; false. ?- min_max(20,5,Min,Max). Min = 5, Max = 20. ?- min_max(10,10,Min,Max). Min = 10, Max = 10 ; false.
source to share