Si vous voulez le rendre facile, trier, inverse, prendre la tête:
mymax(List, Max) :-
sort(List, Sorted),
reverse(Sorted, [Max|_]).
Sinon, prenez le premier élément et définissez-le pour être le plus grand (jusqu'à présent). Ensuite, regardez dans le reste de la liste et si vous trouvez un élément plus grand que le plus grand courant, remplacez votre max actuel par celui-ci. C'est ce que fait @CapelliC (en quelque sorte), en utilisant un prédicat de contrôle if-then-else.
Une façon de le faire sans à l'aide d'un if-then prédicat, en utilisant des clauses sous-jacentes à la place, et en profitant du prédicat ISO compare
:
mymax([First|Rest], Max) :-
mymax_1(Rest, First, Max).
mymax_1([], Max, Max).
mymax_1([This|Rest], Current, Max) :-
compare(Cmp, This, Current),
mymax_2(Cmp, Rest, This, Current, Max).
mymax_2(>, Rest, This, _, Max) :-
mymax_1(Rest, This, Max).
mymax_2(=, Rest, _, Current, Max) :-
mymax_1(Rest, Current, Max).
mymax_2(<, Rest, _, Current, Max) :-
mymax_1(Rest, Current, Max).
Mais ce style de prédicats d'écriture n'est pas très populaire , probablement parce que c'est trop explicite et implique trop de taper. D'un autre côté, il est récursif et déterministe. Il ne se casse pas aussi lorsque vous passez une variable comme premier argument:
?- mymax(L, 13).
Vous pouvez également consulter la mise en œuvre de max_list/2
et max_member/2
de la bibliothèque standard de toute implémentation Prolog open-source (SWI-Prolog par exemple) pour une approche plus pragmatique (mais en utilisant toujours if-then-else).
Vous devriez probablement indiquer explicitement que ce prédicat cherche le numéro le plus grand dans une liste. –