Loki
Loki

Reputation: 87

Recursion in prolog using append

I'm new in Prolog and I have some problem understanding how the recursion works.

The think I want to do is to create a list of numbers (to later draw a graphic).

So I have this code :

nbClassTest(0, _). 

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

But it keeps giving me 'false' as an answer and I don't understand why it doesn't fill the list. It should end if X reaches 0 right?

The numberTestClass(A,X), gives me a number (in the variable A) for some X as if it was a function.

Upvotes: 2

Views: 4726

Answers (3)

CapelliC
CapelliC

Reputation: 60014

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

Upvotes: 2

thanos
thanos

Reputation: 5858

the problem is that you use the same variable for the old and the new list. right now your first to append/3 creates a list of infinite length consisting of elements equal to the value of 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].

then, if the next A is not the same with the previous A it will fail.

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

there is still on more issue with the code; your base case has an non-instantiated variable. you might want that but i believe that you actually want an empty list:

nbClassTest(0, []). 

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

last, append/3 is kinda inefficient so you might want to avoid it and build the list the other way around (or use difference lists)

Upvotes: 2

whd
whd

Reputation: 1861

It fails because you use append in wrong way try

nbClassTest(0, _). 

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

append concatenate 2 lists so there is no such list which after adding to it element still will be same list.

Upvotes: 1

Related Questions