2012-05-22 43 views
2

我是Prolog中的新手,我對理解遞歸如何工作有些問題。在prolog中使用append遞歸

我想要做的是創建一個數字列表(以便以後繪製圖形)。

所以我有這樣的代碼:

nbClassTest(0, _). 

nbClassTest(X, L) :- 
    numberTestClass(A,X), 
    append([A], L, L), 
    X is X - 1, 
    nbClassTest(X, L). 

但它一直給我「假」作爲答案,我不明白爲什麼它不填充列表。它應該結束,如果X達到0的權利?

numberTestClass(A,X)給了我一個數字(在變量A中)一些X,就像它是一個函數一樣。

+0

使用'trace.'逐步執行代碼的嘗試。 ('notrace'關閉) – keyser

+0

以下是找到問題的一般方法:首先設置'set_prolog_flag(occurrence_check,error)'。然後運行您的查詢。它會產生一個錯誤,因爲目標爲'append/3',如其他答案所示 – false

回答

2

你應該建立沒有附加的列表,因爲它效率很低。 這段代碼可以做:

nbClassTest(0, []). 
nbClassTest(X, [A|R]) :- 
    numberTestClass(A, X), 
    X is X - 1, 
    nbClassTest(X, R). 

,或者,如果你的系統有/ 3之間,你可以使用「所有解決方案」的成語:

nbClassTest(X, L) :- 
    findall(A, (between(1, X, N), numberTestClass(A, X)), R), 
    reverse(R, L). 
+1

之間的作品太棒了!非常感謝,它似乎是一種「翻譯」迭代循環的簡單方法:-) – Loki

+0

我無法獲得第一個解決方案,但是在工作之間。 – David

1

它失敗,因爲您使用錯誤的方法追加 嘗試

nbClassTest(0, _). 

nbClassTest(X, L) :- 
    numberTestClass(A,X), 
    append([A], L, Nl), 
    X is X - 1, 
    nbClassTest(X, Nl). 

追加連擊2所列出所以不存在這樣的列表,它向它添加元素後,仍然會相同的列表。

+1

由於明確說明,但仍然有錯誤結果 – Loki

+0

您不需要追加/ 3來追加帶有單個元素的列表到另一個列表中......您可以簡單地用[A | L]替換N1。此外,/ 2將始終返回錯誤。試試X是X1 - 1. –

2

問題是你使用舊的和新的列表相同的變量。現在你的第一個追加/ 3創造無限長的由等於A的價值元素的

?-append([42],L,L). 
L = [42|L]. 

?- append([42],L,L), [A,B,C,D|E]=L. 
L = [42|L], 
A = B, B = C, C = D, D = 42, 
E = [42|L]. 

然後列表,如果下一個是不是與前一個會失敗一樣。

?- append([42],L,L), append([41],L,L). 
false. 

還有更多關於代碼的問題;你的基本情況有一個非實例化的變量。你可能想這一點,但我相信,你需要的是一個空列表:

nbClassTest(0, []). 

nbClassTest(X, L) :- 
    numberTestClass(A,X), 
    append([A], L, NL), 
    X is X - 1, 
    nbClassTest(X, NL). 

最後,追加/ 3是有點低效率的,所以你可能要避免它,並生成列表的其他方式(或使用差異表)

+0

感謝您的回答,並且在我對whd說過的時候表達清楚。 在我的基本情況下,我不想要一個空列表,因爲我填充了列表,所以它不會是空的,但它將具有未知數量的組件。 – Loki

+0

我無法獲得此代碼的工作。它返回「false」並且沒有結果。 – David