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