2014-11-13 21 views
1

我試圖找到列表L X的出現的次數爲例如: -X的出現在列表L在序言數

occurrences(a, [b, a, b, c, a, d, a], N). 
N =3 

我的代碼無法正常工作。這裏是我的代碼。

occ(K,L,N) :- N1=0, occ1(K,L,N1,N). 

occ1(K,[],N1,N) :- N=N1. 
occ1(K,L,N1,N) :- 
    L=[X|L1], 
    (K=X -> N1 is N1+1, occ1(K,L1,N1,N) ; occ1(K,L1,N1,N)). 

有人可以告訴我什麼是錯的代碼。

回答

1

問題是

N1 is N1+1 

變量不能在序言 「覆蓋」。您只需要一個新變量,例如

N2 is N1+1, occ1(K,L1,N2,N) 

你的問題「我們可以更換特定列表元素,如果是,什麼是語法?」:

只能建立一個新的列表:

replace(_, _, [], []). 
replace(Old, New, [H0|T0], [H1|T1]) :- 
    (H0 = Old -> H1 = New; H1 = H0), 
    replace(Old, New, T0, T1). 
+0

我們可以替換一個特定的列表元素嗎?如果是,什麼是syntex。謝謝 – Squirtle

2

雖然@Kay給出的答案就固定錯誤而言是專注的,但它完全避開了一個更大的問題:occ1/4的代碼是邏輯上不純

這可能不是現在, 顯得你很重要,但使用不純的代碼中有幾個不良後果:

  1. 不純的代碼不能被讀出聲明,只是在程序上。
  2. 調試不純代碼通常是單調乏味且痛苦的。
  3. 不純的謂詞比純粹的對應關係更少「關係」。
  4. 邏輯雜質妨礙代碼重用。
  5. 由於它是非單調的,不純代碼很容易導致邏輯上不合理的答案,特別是在使用非基礎條件時。

爲了表明這些問題在被修復後仍然存在於您的代碼中,請按照建議的@Kay進行「修復」,讓我們考慮「更正後的」代碼和一些查詢。首先,這裏的更正後的代碼:

occ(K,L,N) :- N1=0, occ1(K,L,N1,N). 

occ1(_,[],N1,N) :- N=N1. 
occ1(K,L,N1,N) :- 
    L=[X|L1], 
    (K=X -> N2 is N1+1, occ1(K,L1,N2,N) ; occ1(K,L1,N1,N)). 

這裏是你在你的問題給出了查詢:

?- occ(a,[b,a,b,c,a,d,a],N). 
N = 3 ; 
false. 

好吧!如果我們以不同的方式編寫查詢呢?

?- A=a,B=b,C=c,D=d, occ(a,[B,A,B,C,A,D,A],N). 
A = a, B = b, C = c, D = d, N = 3 ; 
false. 

好吧!如果我們重新排列目標呢?邏輯與應該是可交換...

?- occ(a,[B,A,B,C,A,D,A],N), A=a,B=b,C=c,D=d. 
false. 

失敗!似乎occ1/4是好的,但現在我們得到一個邏輯上不合理的答案。 看純淨單調代碼我給在my answer到相關的問題「Prolog - count repititions in list (sic)」:

這可以通過使用邏輯純代碼來避免。