Reputation: 1459
Hello I want to generate a list as following. Given a list like [x,y] I want to generate a list that is x,x,...,x : y times eg [2,3]=[2,2,2]
but I cannot figure out how.
This is my implementation so far:
generate([T,1],[T]).
generate([X,S],[X|T]):-S1 is S-1,generate([X,S1],[T]).
but for some reason it fails. Can you help me?
Upvotes: 2
Views: 690
Reputation: 10102
generate([E,R], Es) :-
length(Es, R),
maplist(=(E), Es).
You said that your version fails. But in fact it does not:
?- generate([a,0], Xs).
false.
?- generate([a,1], Xs).
Xs = [a]
; false.
?- generate([a,2], Xs).
Xs = [a|a]
; false.
?- generate([a,3], Xs).
false.
It doesn't work for 0, seems to work for length 1, then, produces an incorrect solution Xs = [a|a]
for length 2, and finally fails from length 3 on. [a|a]
is a good hint that at someplace in your definition, lists and their elements are confused. To better distinguish them, use a variable in plural for a list, like Es
which is the plural of E
.
Upvotes: 2
Reputation: 2477
The problem is in your second clause. When you have [X|T]
, it means that T is a list. In the body you write generate([X,S1],[T])
: by writing [T]
you're now saying the second argument to generate is a list of which the only element is this list T. What you want to say is that it is simply this list T:
generate([T,1], [T]).
generate([X,S], [X|T]) :- S1 is S-1, generate([X,S1], T).
Upvotes: 0