结合Prolog中的谓词

时间:2017-02-03 21:59:48

标签: list recursion prolog reverse

我必须创建一个谓词reverseeven(List, Reversed),如果列表中包含偶数个元素,它将反转列表,如果没有则返回空列表。 我有一个函数来确定列表是否具有偶数个元素和反向函数:

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

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

但我不确定如何将两者结合起来。

1 个答案:

答案 0 :(得分: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

以上不是最有效的实现(例如,在检查偶数长度后,您可以使用剪切!运算符)。但它显示了这个想法。

<强>更新 顺便说一句,您的reverse谓词应如下所示:

reverse([],[]).    % Empty list is a reverse of empty list
reverse([H|T], R):-
    reverse(T,ReverseT), append(ReverseT, [H], R).    

更新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]]).