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). |