Reputation: 33
i'm writing a function that returns true if E is the second largest element from the list, especially trying to use the library https://www.swi-prolog.org/pldoc/man?section=lists
like this:
secLarg([], E).
secLarg([_], E).
secLarg([T], E) :- L is max_member(T, E), delete(T, L), max_member(E, L).
so using some sort of composition of library functions max_member and delete, however this solution is not working, as max_member appears to return only true/false, not what the specific largest element is. do you have any idea about how could I find if E is the second largest element by any way using these functions?
Upvotes: 1
Views: 283
Reputation: 476614
The problem is that L is max_member(T, E)
does not make much sense. A predicate does not return a value: it either succeeds or fails. It uses unification to unify a variable with the result.
If you use [T]
to unify with, you will only unify with lists with exactly one element. Whereas you probably want to unify with lists with an arbitrary number of elements.
delete/3
also does not alter the list, it produces a new list where it removed the largest member:
secLarg(Xs, E) :-
max_member(Lg, Xs),
delete(Xs, Lg, Xs1),
max_member(E, Xs1).
It also does not make much sense to write secLarg([], E)
and secLarg([_], E)
, since for such lists, there is no second largest:
% secLarg([], E).
% secLarg([_], E).
secLarg(Xs, E) :-
max_member(Lg, Xs),
delete(Xs, Lg, Xs1),
max_member(E, Xs1).
Beware that delete/3
will delete all elements with the given value. Indeed:
?- delete([1,4,2,5,4], 4, R).
R = [1, 2, 5].
So if there is a list where the largest value occurs multiple times, it will not select the largest value (which is also the second largest one).
Upvotes: 2