2017-02-03 160 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 

以上還不是最高效的實現(例如,在檢查均勻長度後,您可以使用剪切的!運算符)。但它顯示了這個想法。

更新 順便說一句,你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]]). 
+0

不幸的是,此代碼產生兩個解決方案,以'reverseEven([A,b],R)'。一個是正​​確的('R = [b,a]'),另一個是不正確的,'R = []'。 – lurker

+0

@ lurker你是對的,謝謝。將更新答案,但這不是問題的重點。 –

+0

我同意這不是重點,但是當提供解決方案時,解決方案是正確的,或明確聲明它不正確或完整,並將其留作OP的練習以找到完整的解決方案。 :) – lurker