Reputation: 65
I am trying to generate a list with random values between 1 and 10, but when I run the code, I'm receiving "false"...
geraL(0,_).
geraL(C,Y):-
C is C-1,
random(1,10,U),
Y = [U|Y],
geraL(C,Y).
?-geraL(13,X).
Upvotes: 1
Views: 6802
Reputation: 18726
No need to write recursive code!
Simply use random/3
, length/2
, and maplist/2
like so:
?- length(Zs, 13), maplist(random(0,10), Zs). Zs = [8, 9, 3, 5, 0, 7, 6, 7, 9, 9, 2, 4, 7]. ?- length(Zs, 13), maplist(random(0,10), Zs). Zs = [1, 7, 7, 6, 2, 5, 2, 9, 9, 2, 0, 7, 1]. ?- length(Zs, 13), maplist(random(0,10), Zs). Zs = [4, 6, 7, 0, 1, 3, 4, 9, 0, 8, 3, 8, 5]. ?- length(Zs, 13), maplist(random(0,10), Zs). Zs = [3, 1, 2, 1, 5, 3, 9, 8, 3, 7, 8, 1, 7].
Note the impurity! We get different answers—at least, most of the time...
For reproducible results, write down the actual prng method and its initial state, random-seed.
Upvotes: 4
Reputation: 4078
There is a built-in predicate findnsols/4
which finds at most N solutions.
This predicate can be used for the equivalent of a loop. Since random/3
is deterministic, we need to add repeat/0
to the goal to make it repeat.
geraL(C, Y) :- findnsols(C, U, (repeat, random(1, 10, U)), Y).
Also, please note that random/3
has been deprecated in SWI Prolog; it is advised to use random/1
or random_between/3
instead.
Most notably, random/3
excludes the upper bound, so random(1, 10, U)
will never yield U = 10
.
Upvotes: 1
Reputation: 58304
We'll cover each issue individually:
geraL(0, _)
says that if you want zero random numbers, anything could be the result. I'm sure that's not what you mean. What should the result be if the number of elements is 0?
You should have a constraint that says C > 0
in your general case to avoid executing this rule when it's not desired
C is C - 1
will always fail because for any value of C
, C
and C-1
can never be the same value. You cannot reinstantiate a variable once it has a value within a predicate clause, except through backtracking.
Although Y = [U|Y]
is allowed, it's a cyclical list definition (a list defined in terms of itself with an additional head element), and I'm sure that's not what you want, either.
If you fix these items, your program will work. The first two are fixed by using an auxiliary (different) variable. The last one is defining the base case correctly to associate the empty list with 0, not an anonymous variable.
geraL(0, []). % Fix for item 1: zero values should be an empty list
geraL(C, Y):-
C > 0, % Fix for item 2
C1 is C-1, % Fix for item 3: use C1 for the new value
random(1, 10, U),
Y = [U|T], % Fix for item 4: use T for the new value (tail)
geraL(C1, T).
Upvotes: 2