在 Prolog 中组合谓词
Combining predicates in Prolog
我必须做一个谓词 reverseeven(List, Reversed)
,只有当列表的元素个数为偶数时,它才会反转列表,如果不是,则 return 为空列表。
我有一个判断列表是否有偶数个元素的函数和一个反向函数:
evenlength([_,_]).
evenlength([_,_|X]):-
evenlength(X).
reverse([_,_],R).
reverse([H|T], R):-
reverse(T,ReverseT), append(ReverseT, [H], R).
但我不确定如何将两者结合起来。
你不能 "combine" 谓词,但你可以在两个(或更多)谓词之间进行逻辑连接,只有当它们都成功时才会成功:
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 !
运算符)。但它显示了这个想法。
更新
顺便说一下,您的 reverse
谓词应该如下所示:
reverse([],[]). % Empty list is a reverse of empty list
reverse([H|T], R):-
reverse(T,ReverseT), append(ReverseT, [H], R).
更新 2 谢谢@Lurker。上面的代码将产生两个答案。第一个将是正确的。如果我们要求 Prolog 进一步搜索,它将找到另一个空列表的答案,因为第二个子句始终为真。为了解决这个问题,我们可以明确地检查列表的长度是否甚至没有使用否定运算符,或者我觉得更优雅的是只是为空列表添加另一个子句,以及 non-even 检查只需将现有的 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(List, Reversed)
,只有当列表的元素个数为偶数时,它才会反转列表,如果不是,则 return 为空列表。
我有一个判断列表是否有偶数个元素的函数和一个反向函数:
evenlength([_,_]).
evenlength([_,_|X]):-
evenlength(X).
reverse([_,_],R).
reverse([H|T], R):-
reverse(T,ReverseT), append(ReverseT, [H], R).
但我不确定如何将两者结合起来。
你不能 "combine" 谓词,但你可以在两个(或更多)谓词之间进行逻辑连接,只有当它们都成功时才会成功:
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 !
运算符)。但它显示了这个想法。
更新
顺便说一下,您的 reverse
谓词应该如下所示:
reverse([],[]). % Empty list is a reverse of empty list
reverse([H|T], R):-
reverse(T,ReverseT), append(ReverseT, [H], R).
更新 2 谢谢@Lurker。上面的代码将产生两个答案。第一个将是正确的。如果我们要求 Prolog 进一步搜索,它将找到另一个空列表的答案,因为第二个子句始终为真。为了解决这个问题,我们可以明确地检查列表的长度是否甚至没有使用否定运算符,或者我觉得更优雅的是只是为空列表添加另一个子句,以及 non-even 检查只需将现有的 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]]).