你不能「結合」謂詞,但你可以有兩個(或更多)謂語之間的邏輯結合,將只許成功,如果他們都成功:
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]]).
不幸的是,此代碼產生兩個解決方案,以'reverseEven([A,b],R)'。一個是正確的('R = [b,a]'),另一個是不正確的,'R = []'。 – lurker
@ lurker你是對的,謝謝。將更新答案,但這不是問題的重點。 –
我同意這不是重點,但是當提供解決方案時,解決方案是正確的,或明確聲明它不正確或完整,並將其留作OP的練習以找到完整的解決方案。 :) – lurker