2012-05-22 40 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