Вы не можете «комбинировать» предикаты, но вы можете иметь логический союз между двумя (или более) предикатами, которые преуспеют только, если оба они успешно:
reverseEven(List, Reversed) :-
evenlength(List), % This must succeed
reverse(List, Reversed). % and this one in order this case to succeed
reverseEven(_, []). % this will succeed otherwise
выше, не самый (вы можете использовать оператор cut !
после проверки на четную длину, например). Но это показывает идею.
Update Кстати, ваш reverse
предикат должен выглядеть следующим образом:
reverse([],[]). % Empty list is a reverse of empty list
reverse([H|T], R):-
reverse(T,ReverseT), append(ReverseT, [H], R).
Update 2 Благодаря @Lurker. Вышеприведенный код даст два ответа. Первый будет правильным. Если мы попросим Prolog продолжить поиск, он найдет другой ответ, пустой список, так как второе предложение всегда верно. Чтобы решить эту проблему, мы можем явно проверить, что длина списка даже не используется с помощью оператора отрицания, или то, что я нахожу более элегантным, - это просто добавить другое предложение для пустого списка, а для нечеткой проверки просто используйте существующий evenlength
со списком с дополнительным элементом:
reverseEven([], []).
reverseEven(List, Reversed) :-
evenlength(List), % This must succeed
reverse(List, Reversed). % and this one in order this case to succeed
reverseEven([H|T], []) :-
evenlength([H|[H|T]]).
к сожалению, этот код дает два решения 'reverseEven ([а, Ь], R)'. Один правильный ('R = [b, a]'), а другой неверный, 'R = []'. – lurker
@ lurker Вы правы, спасибо. Обновит ответ, хотя на самом деле это не вопрос. –
Я согласен, что это не фокус, но при предоставлении решения это хорошо для правильного решения или явно указывает на то, что оно неправильное или полное, и оставляйте его как упражнение для OP, чтобы найти полное решение. :) – lurker