1 :- multifile generate/2.
2 :- multifile shrink/3.
3
4 :- use_module(library(random),[random/3,random_member/2]).
5
6 % Options:
7 % not-well-defined
8 % preds(List) - a predefined list of predicates to randomly choose from
9 % all options of any type are accepted and will be applied when valid
10
11 generate_from_predlist(PredList, Options, Value) :-
12 (member(noQuantifier,Options)
13 -> Predicates = PredList
14 ; append(PredList,[exists,forall],Predicates)) ,
15 random_member(Pred,Predicates) ,
16 generate(prob_ast_pred(Pred,Options),Value).
17
18 generate(prob_ast_pred,Value) :-
19 generate(prob_ast_pred([]),Value).
20
21 % Pred :: boolean
22 generate(prob_ast_pred(Options),Value) :-
23 member(preds(PredList), Options),
24 PredList \== [],
25 !,
26 generate_from_predlist(PredList, Options, Value).
27 generate(prob_ast_pred(Options),Value) :-
28 PredList = [conjunct,disjunct,implication,equivalence,negation,finite,
29 equal,not_equal,less_equal,less,greater_equal,greater,member,
30 not_member,subset,not_subset,subset_strict,not_subset_strict] , %truth,falsity
31 generate_from_predlist(PredList, Options, Value).
32
33 % specific predicate
34 generate(prob_ast_pred(truth,_),b(truth,pred,[])).
35 generate(prob_ast_pred(falsity,_),b(falsity,pred,[])).
36
37 generate(prob_ast_pred(finite,Options),b(finite(Set),pred,[])) :-
38 generate(prob_ast_set(_,[any|Options]),Set).
39
40 generate(prob_ast_pred(negation,Options),b(negation(Value),pred,[])) :-
41 generate(prob_ast_pred(Options),Value).
42
43 generate(prob_ast_pred(Pred,Options),b(NewPred,pred,[])) :-
44 member(Pred,[conjunct,disjunct,implication,equivalence]) ,
45 generate(prob_ast_pred(Options),Value1) ,
46 generate(prob_ast_pred(Options),Value2) ,
47 NewPred =.. [Pred,Value1,Value2].
48
49 generate(prob_ast_pred(Pred,Options),b(NewPred,pred,[])) :-
50 member(Pred,[member,not_member]) ,
51 generate(ground_type,Temp) ,
52 Temp =.. [TypeNoOpt|_] ,
53 Type =.. [TypeNoOpt,Options] ,
54 gen_type(Type,ast,NType) ,
55 generate(NType,Value) ,
56 generate(prob_ast_set(Type,Options),Set) ,
57 NewPred =.. [Pred,Value,Set].
58
59 generate(prob_ast_pred(Pred,Options),b(NewPred,pred,[])) :-
60 member(Pred,[subset,not_subset,subset_strict,not_subset_strict]) ,
61 generate(prob_ast_set_expr(Options),Value1) ,
62 Value1 = b(_,set(Type),_) ,
63 (Type = empty
64 -> generate(ground_type,NType)
65 ; inner_type(Type,Inner,Outter) ,
66 Temp =.. [Inner,[]] , % no options
67 surround_type(Temp,Outter,NType)) ,
68 generate(prob_ast_set(NType,Options),Value2) ,
69 NewPred =.. [Pred,Value1,Value2].
70
71 % generate two records of the same type using the same field names with random values
72 generate(prob_ast_pred(Pred,Options),b(NewPred,pred,[])) :-
73 member(Pred,[equal,not_equal]) ,
74 member(record,Options) , ! ,
75 generate(ground_type,RecordType) ,
76 generate(prob_ast_record(RecordType,[list:2]),[Value1,Value2]) ,
77 NewPred =.. [equal,Value1,Value2].
78
79 generate(prob_ast_pred(Pred,Options),b(NewPred,pred,[])) :-
80 member(Pred,[equal,not_equal]) ,
81 % generate any value for equal, not_equal
82 % make sure both values are of the same type
83 generate(prob_ast_expr(Options),Value1) ,
84 Value1 = b(_,Type,_) ,
85 inner_type(Type,Inner,Outter) ,
86 % if empty structure then just use an integer
87 (Inner = empty -> NInner = integer ; NInner = Inner) ,
88 Temp =.. [NInner,Options] ,
89 surround_type(Temp,Outter,TempType) ,
90 gen_type(TempType,ast,NType) ,
91 generate(NType,Value2) ,
92 NewPred =.. [Pred,Value1,Value2].
93
94 generate(prob_ast_pred(Pred,Options),b(NewPred,pred,[])) :-
95 member(Pred,[greater,greater_equal,less,less_equal]) ,
96 generate(prob_ast_int_expr([small|Options]),Value1) ,
97 generate(prob_ast_int_expr([small|Options]),Value2) ,
98 NewPred =.. [Pred,Value1,Value2].
99
100 % quantifier
101 /*generate(prob_ast_pred(exists,Options),b(exists(ListOfIDNodes,NewPredicate),pred,[used_ids(UsedIDs)])) :-
102 (member(id,Options)
103 -> generate(prob_ast_pred(Options),Predicate)
104 ; generate(prob_ast_pred([id|Options]),Predicate)) ,
105 % get a list of all used identifier nodes
106 % TO DO: find identifier uses in TempListOfIDNodes
107 set_wd_option(Options, WD),
108 % if there are no identifier just insert one instead of backtracking
109 (TempListOfIDNodes = []
110 -> insert_identifier_to_ast(WD,Predicate,2,NewPredicate) ,
111 % TO DO: find identifier uses in ListOfIDNodes
112 ; TempListOfIDNodes = ListOfIDNodes ,
113 NewPredicate = Predicate) ,
114 b_ast_cleanup:find_identifier_uses(NewPredicate,[],UsedIDs).
115
116 generate(prob_ast_pred(forall,Options),b(forall(ListOfIDNodes,IDConstraints,NewPredicate),pred,[used_ids(UsedIDs)])) :-
117 (member(id,Options)
118 -> generate(prob_ast_pred(Options),Predicate)
119 ; generate(prob_ast_pred([id|Options]),Predicate)) ,
120 % get a list of all used identifier nodes
121 % TO DO: find identifier uses in TempListOfIDNodes
122 set_wd_option(Options, WD),
123 (TempListOfIDNodes = []
124 -> insert_identifier_to_ast(WD,Predicate,2,NewPredicate) ,
125 % TO DO: find identifier uses in ListOfIDNodes
126 ; TempListOfIDNodes = ListOfIDNodes ,
127 NewPredicate = Predicate) ,
128 b_ast_cleanup:find_identifier_uses(NewPredicate,[],UsedIDs) ,
129 % set constraints for every identifier (except of boolean, string)
130 % defined in prob_ast_identifier.pl
131 generate(prob_ast_id_constraints(ListOfIDNodes),IDConstraints).*/
132
133 shrink(Type,Value,Shrunken) :-
134 Type =.. [prob_ast_pred|_] ,
135 minimize_pred(Value,Shrunken).
136
137 shrink(Type,Value,Shrunken) :-
138 Type =.. [prob_ast_pred|_] ,
139 get_inner_pred(Value,Shrunken).