2

我是 Prolog 的新手,在理解递归的工作原理时遇到了一些问题。

我想做的是创建一个数字列表(稍后绘制图形)。

所以我有这个代码:

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,就好像它是一个函数一样。

4

3 回答 3

2

You should build the list without appending, because it's rather inefficient. This code could do:

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

or, if your system has between/3, you can use an 'all solutions' idiom:

nbClassTest(X, L) :-
    findall(A, (between(1, X, N), numberTestClass(A, X)), R),
    reverse(R, L).
于 2012-05-22T18:55:03.937 回答
2

问题是您对旧列表和新列表使用相同的变量。现在你第一个 append/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].

那么,如果下一个 A 与前一个 A 不同,它将失败。

?- 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).

最后, append/3 有点低效,所以你可能想避免它并以另一种方式构建列表(或使用差异列表)

于 2012-05-22T18:42:54.600 回答
1

它失败了,因为您以错误的方式使用附加尝试

nbClassTest(0, _). 

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

追加连接 2 个列表,因此没有这样的列表在添加到它之后仍然是相同的列表。

于 2012-05-22T18:36:25.790 回答