1:- discontiguous random_element/2.    2:- discontiguous random_element/4.    3
    4type(int).
    5type(float).
    6generator(int).
    7generator(pos_int).
    8generator(pos_int_no_zero).
    9generator(neg_int).
   10generator(neg_int_no_zero).
   11generator(float).
   12generator(pos_float).
   13generator(neg_float).
   14generator(number).
   15generator(list).
   16generator(nonempty_list). % TODO?
   17generator(any).
   18generator(var). % variable
   19
   20% valid_generator(Generator): check whether Generator is a valid generator
   21valid_generator(Generator):-
   22    generator(Generator), !.
   23valid_generator(int(L,U)):-
   24    maplist(integer,[L,U]),
   25    U > L, !.
   26valid_generator(float(L,U)):-
   27    maplist(float,[L,U]),
   28    U > L, !.
   29valid_generator(number(L,U)):-
   30    maplist(number,[L,U]),
   31    U > L, !.
   32valid_generator(list(A)):-
   33    integer(A), !.
   34valid_generator(list(L)):- 
   35    is_list(L),
   36    maplist(valid_generator,L), !.
   37valid_generator(list(N,L)):-
   38    (integer(N) ; N = any),
   39    maplist(valid_generator,L), !.
   40
   41% variable
   42random_element(var,_).
   43
   44% any element: number or list
   45random_element(any,V):-
   46    random_member(T,[number,list]),
   47    random_element(T,V).
   48
   49% for integers
   50% random_element(int,V): V is a random integer between -2**31 and 2**31 
   51% random_element(pos_int,V): V is a random integer between 0 and 2**31 
   52% random_element(neg_int,V): V is a random integer between -2**31 and 0 
   53% random_element(int,L,U,V): V is a random integer between L and U 
   54random_element(int,V):-
   55    setting(minVal,MinV),
   56    setting(maxVal,MaxV),
   57    random_element(int,MinV,MaxV,V).
   58random_element(pos_int,V):-
   59    setting(maxVal,MaxV),
   60    random_element(int,0,MaxV,V).
   61random_element(pos_int_no_zero,V):-
   62    setting(maxVal,MaxV),
   63    random_element(int,1,MaxV,V).
   64random_element(neg_int,V):-
   65    setting(minVal,MinV),
   66    random_element(int,MinV,0,V).
   67random_element(neg_int_no_zero,V):-
   68    setting(minVal,MinV),
   69    random_element(int,MinV,-1,V).
   70random_element(int,Lower,Upper,V):-
   71    random_between(Lower, Upper, V).
   72
   73% for floats
   74% random_element(float,V): V is a random float between -2**31 and 2**31 
   75% random_element(pos_float,V): V is a random float between 0 and 2**31 
   76% random_element(neg_float,V): V is a random float between -2**31 and 0 
   77% random_element(float,L,U,V): V is a random float between L and U 
   78random_element(float,V):-
   79    setting(minVal,MinV),
   80    setting(maxVal,MaxV),
   81    random_element(float,MinV,MaxV,V).
   82random_element(pos_float,V):-
   83    setting(maxVal,MaxV),
   84    random_element(float,0,MaxV,V).
   85random_element(neg_float,V):-
   86    setting(minVal,MinV),
   87    random_element(float,MinV,0,V).
   88random_element(float,Lower,Upper,V):-
   89    random(R),
   90    V is R*(Upper - Lower) + Lower.
   91
   92% for number (int or float)
   93random_element(number,V):-
   94    random_member(T,[int,float]),
   95    random_element(T,V).
   96random_element(number,L,U,V):-
   97    random_member(T,[int,float]),
   98    random_element(T,L,U,V).
   99
  100% pick_random_type(V): V is a random type among all possible types
  101% pick_random_type(Allowed,V): V is a random type among the allowed
  102pick_random_type(V):-
  103    findall(T,type(T),LT),
  104    random_member(Type,LT),
  105    random_element(Type,V).
  106pick_random_type(Allowed,V):-
  107    random_member(Type,Allowed),
  108    random_element(Type,V).
  109
  110% for lists
  111% random_element(list,L): L is a list of random length of any type
  112% random_element(list(N), L): L is a list of fixed length N of random types
  113% random_element(list(N,LT),L): L is a list of length N (possibly random, *) of types LT
  114% random_element(list(LT),L): L is a list of the same length of LT where each element of LT
  115%   denotes a type in that specific position
  116random_element(list,L):-
  117    setting(maxLenList, MaxLen),
  118    random_between(0, MaxLen, Len), % ok empty list
  119    length(L, Len),
  120    maplist(pick_random_type,L).
  121% list of fixed length of random types
  122random_element(list(N), L):-
  123    integer(N), !,
  124    length(L, N),
  125    maplist(pick_random_type, L).
  126% list of fixed types LT of length N
  127random_element(list(N,LT),L):-
  128    ( N = any -> % any length
  129        setting(maxLenList, MaxLen),
  130        random_between(0, MaxLen, Len) ;
  131        Len = N
  132    ),
  133    length(L, Len),
  134    maplist(pick_random_type(LT), L).
  135% list of the same length of LT where each element of LT
  136% denotes a type
  137random_element(list(LT),L):-
  138    length(LT,N), !,
  139    length(L,N),
  140    maplist(random_element, LT, L)