As a Prolog newbie, I try to define a predicate filter_min/2
which takes two lists to determine if the second list is the same as the first, but with all occurrences of the minimum number removed.
Sample queries with expected results:
?- filter_min([3,2,7,8], N).
N = [3,7,8].
?- filter_min([3,2,7,8], [3,7,8]).
true.
I tried but I always get the same result: false
. I don't know what the problem is. I need help!
Here is my code:
filter_min(X,Y) :-
X == [],
write("ERROR: List parameter is empty!"),
!;
min_list(X,Z),
filter(X,Y,Z).
filter([],[],0).
filter([H1|T1],[H2|T2],Z) :-
\+ number(H1),
write("ERROR: List parameter contains a non-number element"),
!;
H1 \= Z -> H2 is H1, filter(T1,T2,Z);
filter(T1,T2,Z).
There are a couple of problems with your code:
filter([],[],0).
will not unify when working with any list that does not have 0 as its minimum value, which is not what you want. You want it to unify regardless of the minimum value to end your recursion.filter([H1|T1],[H2|T2],Z)
and its body will make it so that the two lists always have the same number of elements, when in fact the second one should have at least one less.A correct implementation of
filter/3
would be the following:A bounty was offered...
Here's a candidate implementation handling integer values, built on clpfd:
Some sample queries:
Now, some queries terminate even though both list lengths are unknown:
Note that the implementation doesn't always finitely fail (terminate) in cases that are logically false:
First, we can get the minimum number using the predicate
list_minnum/2
:We can define
list_minnum/2
like this:For the sake of completeness, here's the super-similar
list_maxnum/2
:Next, we use meta-predicate
tfilter/3
in tandem withdif/3
to exclude all occurrences ofM
:Put the two steps together and define
min_excluded/2
:Let's run some queries!
For a Prolog newbie, better start with the basics. The following works when first argument is fully instantiated, and the second is an uninstantiated variable, computing the result in one pass over the input list.