1 :- multifile generate/2.
2 :- multifile shrink/3.
3
4 :- use_module(library(random),[random/3]).
5 :- use_module(library(avl),[list_to_avl/2, avl_to_list/2]).
6 :- use_module(library(lists)).
7
8 % Options:
9 % not-well-defined-values, size:S, list, avl or none for random value sequence
10
11 % any type
12 generate(prob_value_seq(Options),Value) :-
13 is_list(Options) ,
14 generate(ground_type,Type) ,
15 generate(prob_value_seq(Type,Options),Value).
16 % no options
17 generate(prob_value_seq(Type),Value) :-
18 generate(prob_value_seq(Type,[]),Value).
19
20 generate(prob_value_seq(Type,Options),Value) :-
21 (member(not-well-defined,Options)
22 -> delete(Options,not-well-defined,T) ,
23 TOptions = [not-well-defined-values|T]
24 ; TOptions = Options) ,
25 (member(size:Size,TOptions)
26 -> true
27 ; random(1,20,Size)) ,
28 gen_type(Type,value,NType) ,
29 length(List,Size) ,
30 maplist(generate(NType),List) ,
31 (member(not-well-defined-values,TOptions)
32 -> maplist(gen_random_indexed_couple,List,CoupleList)
33 ; remove_dups(List,NList) ,
34 gen_indexed_couple_list(1,NList,CoupleList)) ,
35 % random choice of list set or avl set if no option is given
36 random(0,2,R) ,
37 ( \+member(list,TOptions) , (member(avl,TOptions) ; R = 0)
38 -> % add key to every element to use list_to_avl
39 findall(Key-true,member(Key,CoupleList),Pairs) ,
40 list_to_avl(Pairs,AVL) ,
41 Value = avl_set(AVL)
42 ; % else list sequence
43 Value = CoupleList).
44
45 % replace each list element with an indexed couple, starting at 1
46 gen_indexed_couple_list(_,[],[]).
47 gen_indexed_couple_list(C,[Elm|T],[(int(C),Elm)|NT]) :-
48 C1 is C + 1 ,
49 gen_indexed_couple_list(C1,T,NT).
50
51 % use for no well-definedness
52 gen_random_indexed_couple(Value,(Index,Value)) :-
53 generate(prob_value_integer([small]),Index).
54
55 shrink(Type,avl_set(Value),avl_set(Shrunken)) :-
56 Type =..[prob_value_seq|_] ,
57 avl_to_list(Value,AVLList) ,
58 findall(Key,member(Key-_,AVLList),SeqList) ,
59 shrink(prob_value_seq,SeqList,NewSeqList) ,
60 findall(Key-true,member(Key,NewSeqList),NewAVL) ,
61 list_to_avl(NewAVL,Shrunken).
62
63 shrink(Type,Value,Shrunken) :-
64 Type =..[prob_value_seq|_] ,
65 findall(Val,member((_,Val),Value),ValueList) ,
66 shrink(list,ValueList,ShrunkenList) ,
67 gen_indexed_couple_list(1,ShrunkenList,Shrunken).