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).

      

+3


source to share


2 answers


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.

+1


source


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.

      

+1


source







All Articles