Search code examples
prologclpfd

Generate lists of all lengths between limits


I'm trying to generate a list of random length using the lists and clpfd libraries. I've tried the following:

?- use_module(library(clpfd)).
?- use_module(library(lists)).

gen_mem_burst(X) :-
    Len in 1..2,
    length(X, Len).

I see that Prolog first finds a solution with only one list element, then a solution with two elements, just as I expected. Afterwards it issues an 'out of global stack' message. I traced it and I noticed that it keeps trying to set Len to 3, 4, 5, ... and so on. How can I get it to stop?

I'm a Prolog newbie and I'm not even sure if this is a valid use model. In other constraint based languages I've used (e.g. SystemVerilog), this is easily possible.


Solution

  • At least with SWI-Prolog, length/2 does not work exactly as expected when constrained variables are involved: I was stuck on the exact same problem. There are several good answers that may give you pointers.

    Anyway, answering the title of your question: generating a list of random length:

    ?- set_random(seed(1)), /* if you want to seed */
       Len is random(9),
       length(L, Len).
    Len = 2,
    L = [_G2748, _G2751].
    

    If you just need to generate lists of all lengths between two limits,

    ?- between(1, 3, Len), length(L, Len).
    

    is probably the easiest way to go.