| 1 | :- multifile generate/2. | |
| 2 | :- multifile shrink/3. | |
| 3 | ||
| 4 | :- use_module(library(random),[random/3,random_member/2]). | |
| 5 | ||
| 6 | generate(prob_ast_int_expr,Value) :- | |
| 7 | generate(prob_ast_int_expr([]),Value). | |
| 8 | ||
| 9 | % Options: | |
| 10 | % not-well-defined | |
| 11 | % id to enable random generation of identifier | |
| 12 | % all options of any type are accepted and will be applied when valid | |
| 13 | ||
| 14 | % Expr :: integer | |
| 15 | generate(prob_ast_int_expr(Options),Value) :- | |
| 16 | % double the chance of generating recursive expression | |
| 17 | % (i.e. add,minus,multiplication,div,unary_minus) to increase depth, | |
| 18 | % because modulo and power_of also just generate ground integer nodes for well-definedness | |
| 19 | random_member(Expr,[add,minus,multiplication,div,unary_minus, | |
| 20 | modulo,power_of,max,min,max_int,min_int, | |
| 21 | add,minus,multiplication,div,unary_minus]) , | |
| 22 | generate(prob_ast_int_expr(Expr,Options),Value). | |
| 23 | ||
| 24 | generate(prob_ast_int_expr(card,Options),b(card(Set),integer,[])) :- | |
| 25 | random_member(Type,[integer([]),string([]),boolean([])]) , | |
| 26 | (member(id,Options) | |
| 27 | -> generate(id_or_ast(set(Type)),Set) | |
| 28 | ; generate(prob_ast_set(Type,Options),Set)). | |
| 29 | ||
| 30 | % also generate empty list for no well-definedness | |
| 31 | generate(prob_ast_int_expr(Expr,Options),b(NewPred,integer,[])) :- | |
| 32 | memberchk(not-well-defined,Options) , | |
| 33 | !, | |
| 34 | member(Expr,[max,min]) , | |
| 35 | random(0,9,R) , | |
| 36 | (R > 3 | |
| 37 | -> generate(prob_ast_set(integer([small]),[extension|Options]),Set) | |
| 38 | ; generate(prob_ast_set(empty([]),Options),Set)) , | |
| 39 | NewPred =.. [Expr,Set]. | |
| 40 | generate(prob_ast_int_expr(Expr,Options),b(NewPred,integer,[])) :- | |
| 41 | member(Expr,[max,min]) , | |
| 42 | generate(prob_ast_set(integer([small]),[extension|Options]),Set) , % no expression | |
| 43 | NewPred =.. [Expr,Set]. | |
| 44 | ||
| 45 | generate(prob_ast_int_expr(Expr,_),b(Expr,integer,[])) :- | |
| 46 | member(Expr,[max_int,min_int]). | |
| 47 | ||
| 48 | generate(prob_ast_int_expr(Expr,Options),b(NewPred,integer,[])) :- | |
| 49 | member(Expr,[add,minus,multiplication]) , | |
| 50 | Type = integer([small,random|Options]) , | |
| 51 | generate_aux(Options,Type,Type,A,B) , | |
| 52 | NewPred =.. [Expr,A,B]. | |
| 53 | ||
| 54 | generate(prob_ast_int_expr(Expr,Options),b(NewPred,integer,[])) :- | |
| 55 | memberchk(not-well-defined,Options) , | |
| 56 | !, | |
| 57 | memberchk(Expr,[modulo,power_of,div]) , | |
| 58 | % generate expressions (not well defined for zero, negative values or float) | |
| 59 | TypeA = integer([small,random,not-well-defined|Options]) , | |
| 60 | TypeB = integer([small,not-well-defined|Options]) , | |
| 61 | generate_aux(Options,TypeA,TypeB,A,B) , | |
| 62 | NewPred =.. [Expr,A,B]. | |
| 63 | % use really small numbers to receive well-definedness for | |
| 64 | % integer expressions in predicates | |
| 65 | generate(prob_ast_int_expr(power_of,Options),b(NewPred,integer,[])) :- | |
| 66 | Type = integer([between(0,7)|Options]) , | |
| 67 | % disabled generation of identifier | |
| 68 | /*(member(id,Options) -> | |
| 69 | generate(id_or_ast(Type),A) , | |
| 70 | generate(id_or_ast(Type),B) | |
| 71 | ;*/ gen_type(Type,ast,NType) , | |
| 72 | generate(NType,A) , | |
| 73 | generate(NType,B), | |
| 74 | NewPred =.. [power_of,A,B]. | |
| 75 | generate(prob_ast_int_expr(modulo,Options),b(NewPred,integer,[])) :- | |
| 76 | TypeA = integer([small,positive|Options]) , | |
| 77 | TypeB = integer([small,positive,nozero|Options]) , | |
| 78 | generate_aux(Options,TypeA,TypeB,A,B) , | |
| 79 | NewPred =.. [modulo,A,B]. | |
| 80 | generate(prob_ast_int_expr(div,Options),b(div(A,B),integer,[])) :- | |
| 81 | TypeA = integer([small,random|Options]) , | |
| 82 | TypeB = integer([small,positive,nozero|Options]) , | |
| 83 | generate_aux(Options,TypeA,TypeB,A,B). | |
| 84 | ||
| 85 | generate(prob_ast_int_expr(unary_minus,Options),b(unary_minus(Expr),integer,[])) :- | |
| 86 | Type = integer([small,random|Options]) , | |
| 87 | (member(id,Options) | |
| 88 | -> generate(id_or_ast(Type),Expr) | |
| 89 | ; gen_type(Type,ast,NType) , | |
| 90 | generate(NType,Expr)). | |
| 91 | ||
| 92 | generate(prob_ast_int_expr(size),b(size(Seq),integer,[])) :- | |
| 93 | generate(ground_type,Type) , | |
| 94 | generate(prob_ast_seq(Type),Seq). | |
| 95 | ||
| 96 | % generate two nodes for given types and options | |
| 97 | generate_aux(Options,TypeA,TypeB,NodeA,NodeB) :- | |
| 98 | member(id,Options) , ! , | |
| 99 | generate(id_or_ast(TypeA),NodeA) , | |
| 100 | generate(id_or_ast(TypeB),NodeB). | |
| 101 | generate_aux(_,TypeA,TypeB,NodeA,NodeB) :- | |
| 102 | gen_type(TypeA,ast,NTypeA) , generate(NTypeA,NodeA) , | |
| 103 | gen_type(TypeB,ast,NTypeB) , generate(NTypeB,NodeB). | |
| 104 | ||
| 105 | shrink(Type,Expression,Shrunken) :- | |
| 106 | Type =.. [prob_ast_int_expr|_] , | |
| 107 | minimize_int_expr(Expression,Shrunken). | |
| 108 | shrink(Type,Expression,Shrunken) :- | |
| 109 | Type =.. [prob_ast_int_expr|_] , | |
| 110 | get_inner_expr(Expression,Shrunken). |