2017-02-03 12 views
0

Мне нужно сделать предикат reverseeven(List, Reversed), который изменит список ТОЛЬКО, если список имеет четное число элементов и вернет пустой список, если это не так. У меня есть функция, которая определяет, есть ли список четное число элементов и обратную функцию:Сочетание предикатов в Prolog

evenlength([_,_]). 
evenlength([_,_|X]):- 
    evenlength(X). 

reverse([_,_],R). 
reverse([H|T], R):- 
    reverse(T,ReverseT), append(ReverseT, [H], R). 

Но я не уверен в том, как объединить два.

ответ

0

Вы не можете «комбинировать» предикаты, но вы можете иметь логический союз между двумя (или более) предикатами, которые преуспеют только, если оба они успешно:

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]]). 
+0

к сожалению, этот код дает два решения 'reverseEven ([а, Ь], R)'. Один правильный ('R = [b, a]'), а другой неверный, 'R = []'. – lurker

+0

@ lurker Вы правы, спасибо. Обновит ответ, хотя на самом деле это не вопрос. –

+0

Я согласен, что это не фокус, но при предоставлении решения это хорошо для правильного решения или явно указывает на то, что оно неправильное или полное, и оставляйте его как упражнение для OP, чтобы найти полное решение. :) – lurker