I am trying to find max,mid and min number from 3 given number. The code is:
t_max(X,Y,Z):-
A is max(max(X,Y),max(Y,Z)),
C is min(min(X,Y),min(Y,Z)),
(X>=A,X=<C)->B is X;
(Y>=A,Y=<C)->B is Y;
(Z>=A,Z=<C)->B is Z;
format('~w ~w ~w',[A,B,C]).
When i try to run the method with any three numbers, I get this error
ERROR: >=/2: Arguments are not sufficiently instantiated
Why I'm getting this error?
The problem is that the ;
binds with lower priority than the ,
so what you have written is equivalent to:
t_max(X, Y, Z) :-
( A is max(max(X, Y), max(Y, Z)),
C is min(min(X, Y), min(Y, Z)),
X>=A,
X=<C
-> B is X
; Y>=A,
Y=<C
-> B is Y
; Z>=A,
Z=<C
-> B is Z
; format('~w ~w ~w', [A, B, C])
).
What does this mean: Prolog evaluates:
A is max(max(X,Y),max(Y,Z)),
C is min(min(X,Y),min(Y,Z)),
first and then checks the condition:
X>=A,X=<C
if that fails however, the program backtracks entirely to the beginning of the clause. So now A
and C
are again uninstantiated and Prolog performs a new attempt by checking:
Y>=A,Y=<C
but now A
and C
are not grounded.
You can resolve the problem by adding brackets:
t_max(X,Y,Z):-
A is max(max(X,Y),max(Y,Z)),
C is min(min(X,Y),min(Y,Z)),
((X>=C,X=<A)
-> B is X
; ((Y>=C,Y=<A)
->B is Y
; ((Z>=C,Z=<A)
-> B is Z;
true
)
)
),
format('~w ~w ~w',[A,B,C]).
If I understand your problem correctly. If you however want to sort them from large to small, a compact way to do this for three numbers is:
t_max(X,Y,Z) :-
Max is max(X,max(Y,Z)),
Min is min(X,min(Y,Z)),
Mid is X+Y+Z-Max-Min,
format('~w ~w ~w',[Max,Mid,Min]).