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