I am trying to find the minimum value of a list (as a learning experience, so without min
).
My approach is the following:
minimo([X], X).
minimo([X,Y|Tail], N):-
(X > Y, minimo([Y,Tail], Y));
(X <= Y, minimo([X,Tail], X)).
This gives me the following error:
Syntax error: Operator expected
So my questions are:
- What is causing the syntax error?
- I will try it myself once that is fixed if it actually gives the correct value back, but would this actually be a correct approach?
Thanks in advance.
There are several bugs in your program:
as pointed out by Joe Lehmann, there is no
'<='/2
. It must be'=<'/2
.when you call
minimo/2
recursively, you construct the lists wrong. Instead of[Y,Tail]
use[Y|Tail]
. Otherwise, you get a list with a list as second element.you bind the second argument of the recursive call of
minimo/2
toY
orX
. Instead it must be bound toN
. Otherwise, yourN
will never be instantiated.You can improve your program further by adding cuts or using if-then-else (
'->'
+;
):In addition to the other versions posted already, consider also a version without if-then-else, and using a more descriptive name for the relation (which relates a list to its minimum):
Such a pattern is called a fold (from the left), and we can write it equivalently using `foldl/4:
Example query:
Note though that this is not a true relation and cannot be used in all directions due to the use of low-level arithmetic. For example, if we try to use it in the other direction, we get:
To make it a true solution, use constraints like clpfd and clpq. For example, for a solution over integers:
This works in all directions:
The syntax error is, because less or equal in Prolog is =<, not <=.
I think the approach will work, but you really should avoid ; in a clause. Just split it up into two clauses.
Also I think that you want to do something like [X|Tail] in the recursion rather than [X,Tail]