Reputation: 1
Here is my code to make a countdown procedure which when I type in countdown(5,L).
should return
L = [5,4,3,2,1]
and countdown(5,[5,4,3,2,1])
should return true
.
The input countdown(5,L).
returns
ERROR: is/2: Type error:
[]' expected, found
[5,4]' ("x" must hold one character)
which shows me my program is beginning to create the list.
%countdown
countdown(1,[1]).
countdown(A,L) :-
concat([],[A],Z),
makeList(Z,A,List),
L is List.
makeList(X,Y,List) :-
N1 is Y-1,
N1 > 0,
concat(X,[N1],Z),
List is Z,
makeList(Z,N1,List).
concat([],Y,Y).
concat([H|X],Y,[H|Z]):-
concat(X,Y,Z).
Upvotes: 0
Views: 299
Reputation: 74197
Some comments on your code:
countdown/2
, clause 2, line 1:
concat([],[A],Z)
is completely unnecessary.
At the end of this exercise, Z
is unified with [A]
.
countdown/2
, clause 2, line 3:**
As was pointed out, is/2
evaluates the right hand term as an
arithmetic expression and unifies the result with the left-hand side.
This should be L = List
.
Even better, just change the line above from makeList(Z,A,List)
to makeList(Z,A,L)
.
But this is overly complicated. If one was to take your general approach, you could do it thusly:
count_down(N,L) :- % To count down to 1 from N,
integer(N) , % N must first be integral
N > 0 , % and positive
range(N,1,L). % Then you just need to generate the desired range.
range/3
could be implemented simply as this:
range( X , Y , [X] ) :- X = Y .
range( X , Y , [X|Xs] ) :- X > Y , X1 is X-1 , range(X1,Y,Xs) .
range( X , Y , [X|Xs] ) :- X < Y , X1 is X+1 , range(X1,Y,Xs) .
Upvotes: 0
Reputation: 18299
Why so difficult?
countdown(1, [1]).
countdown(N, [N|T]) :-
N1 is N-1,
countdown(N1, T).
Upvotes: 1