2014-01-30 47 views
1

我是Prolog的新手。我想實現一個函數來計算列表的大小。例如,我有[[1,2,3],[a,b,c],[12,ab]],返回的值應該是8。所以我有這樣的代碼:如何傳遞參數

size([], _). 
    size([_|T], X):- X1 is X + 1, size(T, X1). 

    total_size([], X):- write('size = '), write(X). 
    total_size([H|T], X):- size(H, X), total_size(T, X). 

但我的函數返回0所有的時間。我的計劃是將X傳遞給size函數,並在每次撥打size時遞增X的值。查詢是:

?- total_size([[1,2,3],[a,b,c],[12,ab]], 0).

我在做什麼錯?

謝謝你在前進,

科爾內留

PS:我知道我不應該用「功能」附近的「序言」的任何地方。

+1

是的。它們是表達邏輯「關係」的「謂詞」。它們不是「返回」值的「功能」。這不僅僅是一個命名法。 :) – lurker

+0

你也可以這樣做:'total_size(L,X): - flatten(L,LF),length(LF,X).' – lurker

+0

@mbratch:非常感謝。您的解決方案運作良好你想寫一個答案,並獲得獎勵?如果你這樣做,我會將其標記爲解決方案。如果不是,那麼我會回答我自己的問題。 PS:我不關心合法性(謂詞,關係,功能)。那些發明了prolog的人顯然是一羣受虐狂的虐待主義者或虐待狂的受虐狂者,無論你喜歡什麼。 – corneliu

回答

0

想想size/2能夠「返回」一個值。一個值只能被「返回」綁定一個參數(我們稱之爲參數)。然後第一步應該是糾正第一個條款(我們稱之爲'代碼')。

size([], 0). 

這是一個關係,他說,一個空的列表中有大小爲0

現在遞歸步驟也可以糾正的:它會使用遞歸調用的值,然後

編輯糾正我的錯誤

size([_|T], X):- size(T, X1), X is X1 + 1. 

可以看到,值「FLO從計算的步驟返回。

total_size/2它是不同的,因爲計算值必須顯示在遞歸結束時(實際上,這些都是循環)。計算值「降低」呼叫。只是,你忘了添加size/2返回的值。

total_size([], X):- write('size = '), write(X). 
total_size([H|T], SoFar):- size(H, X), Sum is SoFar + X, total_size(T, Sum). 
+0

謝謝你的回答,但我認爲你的代碼存在錯誤。如果我嘗試運行它,swipl會拋出一個錯誤:'參數沒有充分實例化我猜是因爲X1沒有在第2行中實例化,而X也沒有在第4行中實例化。我不知道你使用哪個編譯器。我必須使用swipl。 – corneliu

+0

赦免,我會殺死bug ... – CapelliC

+0

謝謝。你的解決方案現在工作正常 – corneliu