Вопрос:
Мне нужно найти максимальное число в списке. Например
goal: maxEVEN([4,10,-2,-1,23],M). M=10.
Я написал следующий код:
maxeven([],M). maxeven([X|R],M):- Rest is X mod 2, isRest(Rest, X, M, R). isRest(0,X,M,[List]):- X > M, maxeven(List,X). isRest(0,X,M,[List]):- X < M, maxeven(List,M). isRest(Rest,X,M,[List]):- maxeven(List,M).
Он будет бросать каждый член цикла и проверять, является ли он четным, если он проверяет, является ли это создателем, чем уже присвоенное значение M. проблема заключается в том, что для первого вызова isRest предикат значение M пусто, поэтому он всегда возвращает false. Я не знаю, какое значение я могу присвоить этой переменной в первый раз, когда этот алгоритм будет работать со всеми числами.
Лучший ответ:
есть несколько простых способов: либо сначала искать первый четный, инициализировать M, либо начать с M unbound и проверить статус с помощью var/1.
Но я думаю, что у вашего кода есть другие проблемы. Это необычный синтаксис:
isRest(0,X,M,[List]):-..
[List] это список одного элемента, поэтому я не вижу, как он соответствует вашему алгоритму. Возможно, проблема возникает из-за того, что ваш код является более сложным, чем необходимо. Если предположить, что maxeven/2 может терпеть неудачу, когда нет четных чисел, может быть просто, как
maxeven([X|Xs], M) :- 0 is X mod 2, % fail if not even ( maxeven(Xs, T), T > X, !, M = T ; M = X). maxeven([_|Xs], M) :- maxeven(Xs, M).
Как это работает: когда X четный, попробуйте увидеть, если какая-либо другая четность находится в Xs, и сравните, но если нет другого даже (например, когда X является последним), храните X. В противном случае, когда X не является четным, искать хвост Xs…
Посмотрите, можете ли понять, почему требуется разрез, и играть, перемещая его в другое место, чтобы лучше понять поток контроля Prolog… Это не очень интуитивно понятно…
Если вас интересует Prolog, не забудьте изучить его библиотеку: maxeven/2 может быть таким же простым, как
maxeven(Xs, M) :- setof(X, (member(X, Xs), 0 is X mod 2), Evens), last(Evens, M). Ответ №1
Вот хвостовая рекурсивная версия:
maxeven([X|T], MaxEven) :- 0 is X mod 2, !, maxeven(T, X, MaxEven). maxeven([_|T], MaxEven) :- maxeven(T, MaxEven). maxeven([X|T], LastMax, MaxEven) :- 0 is X mod 2, !, M is max(X, LastMax), maxeven(T, M, MaxEven). maxeven([_|T], LastMax, MaxEven) :- maxeven(T, LastMax, MaxEven). maxeven([], LastMax, LastMax).