2013-11-25 77 views
3

我正在處理序言,處理序言中的列表。基本思想是,給定一個列表,prolog應該能夠確定一個值是否重複,重複一次,或只重複兩次,等等。我認爲最簡單的解決方案是計算一個值出現的次數然後使用該計數來確定它重複的次數。學習序言,一些列表函數

list_count([],X,0). 
list_count([X|T],X,Y) :- list_count(T,X,Z), Y is 1 + Z. 
list_count([X1|T],X,Z) :- X1 \= X, list_count(T,X,Z). 

repeated_in(+E,+List) :- list_count(List,E,Num), Num >= 2. 

無論我做什麼,雖然我的第一個謂詞總是失敗。幫幫我?

回答

3

list_count/3確實有效。我認爲,唯一的問題是前綴「+」使用不當:儘量

% repeated_in(+E,+List) 
repeated_in(E,List):- list_count(List,E,Num), Num >= 2. 

注:前綴參數用於文檔目的,作爲一個回顧一下關於模式使用

+0

我下面給定的原型repeated_in。你能解釋爲什麼'+'前綴不正確嗎? – theiwarlock

+1

它給你的謂詞一個意想不到的「形狀」輸入參數。也就是說,你應該把它稱爲'repeated_in(+ a,+ [a,a])'來讓它工作,並將參數傳遞給list_count。這在語法上不是不正確的,但肯定會引起誤解。 – CapelliC

2

這裏一個邏輯純實施,基於 if_/3(=)/3 by @false。

atLeastOnceMember_of(E,[X|Xs]) :- 
    if_(E = X, true, atLeastOnceMember_of(E,Xs)). 

atLeastTwiceMember_of(E,[X|Xs]) :- 
    if_(E = X, atLeastOnceMember_of(E,Xs), atLeastTwiceMember_of(E,Xs)). 

首先,讓我們來看看你在你的問題提出了疑問:

​​

的代碼是單調,所以我們得到更普遍的應用邏輯的聲音回答呢!

 
?- atLeastTwiceMember_of(X,[a,b,a,b,a,c]). 
X = a ; 
X = b ; 
false. 

最後,讓我們考慮上述查詢的概括

?- atLeastTwiceMember_of(X,[A,B,C,D,E,F]). 
X = A, A = B           ; 
X = A, A = C, dif(C,B)        ; 
X = A, A = D, dif(D,C), dif(D,B)      ; 
X = A, A = E, dif(E,D), dif(E,C), dif(E,B)   ; 
X = A, A = F, dif(F,E), dif(F,D), dif(F,C), dif(F,B) ; 
X = B, B = C, dif(C,A)        ; 
X = B, B = D, dif(D,C), dif(D,A)      ; 
X = B, B = E, dif(E,D), dif(E,C), dif(E,A)   ; 
X = B, B = F, dif(F,E), dif(F,D), dif(F,C), dif(F,A) ; 
X = C, C = D, dif(D,B), dif(D,A)      ; 
X = C, C = E, dif(E,D), dif(E,B), dif(E,A)   ; 
X = C, C = F, dif(F,E), dif(F,D), dif(F,B), dif(F,A) ; 
X = D, D = E, dif(E,C), dif(E,B), dif(E,A)   ; 
X = D, D = F, dif(F,E), dif(F,C), dif(F,B), dif(F,A) ; 
X = E, E = F, dif(F,D), dif(F,C), dif(F,B), dif(F,A) ; 
false.