1 :- multifile generate/2.
2
3 % shrinking of all mutations defined in mutation.pl
4
5 :- use_module(library(lists),[is_list/1]).
6 :- use_module(library(random),[random_permutation/2,random_member/2,random/3]).
7
8 % mutation of ProB ast set expressions
9 generate(mutation(Expression:prob_ast_set_expr),NewExpression) :-
10 \+is_list(Expression) ,
11 random_set_expr_mutation(Expression,NewExpression).
12 % list of set expressions, random concatenation of expression then
13 % mutation of consisting set expressions
14 generate(mutation(Expressions:prob_ast_set_expr),NewExpression) :-
15 maplist(random_set_expr_mutation,Expressions,Mutated) ,
16 concatenate_ast(Mutated,[union,intersection],NewExpression).
17
18 % mutation of ProB value list sets
19 generate(mutation(L:prob_value_set),Value) :-
20 generate(mutation(L:list),Value).
21
22 % mutation of ProB value avl sets
23 generate(mutation(avl_set(Set):prob_value_set),avl_set(Value)) :-
24 avl_to_list(Set,AvlList) ,
25 random_permutation(AvlList,Permutation) ,
26 % don't sort values during creation of avl
27 ord_list_to_avl(Permutation,Value).
28 % mutate several avl sets and return a single one
29 generate(mutation(L:prob_value_set),avl_set(Value)) :-
30 maplist(avl_to_list,L,ListOfLists) ,
31 flatten(ListOfLists,List) ,
32 random_permutation(List,Permutation) ,
33 ord_list_to_avl(Permutation,Value).
34
35 % union, intersection, set_subtraction
36 random_set_expr_mutation(b(Expression,set(SetType),Info),b(NewExpression,set(SetType),Info)) :-
37 Expression =.. [Type,Expr1,Expr2] ,
38 member(Type,[union,intersection,set_subtraction]) ,
39 random(0,3,R) ,
40 random_set_expr_mutation_aux(R,Expr1,Expr2,NewExpr1,NewExpr2) ,
41 NewExpression =.. [Type,NewExpr1,NewExpr2].
42
43 % general_union, general_intersection
44 random_set_expr_mutation(b(Expression,set(SetType),Info),b(NewExpression,set(SetType),Info)) :-
45 Expression =.. [Type,Expr] ,
46 member(Type,[general_union,general_intersection]) ,
47 Expr = b(set_extension([Set]),set(set(SetType)),ArgInfo) ,
48 % just permutation
49 permutate_set(Set,NewSet) ,
50 NewExpr = b(set_extension([NewSet]),set(set(SetType)),ArgInfo) ,
51 NewExpression =.. [Type,NewExpr].
52
53 % if set_extension or value set is given
54 random_set_expr_mutation(Expression,NewExpression) :-
55 mutate_set(Expression,NewExpression).
56
57 % don't mutate empty set or interval
58 random_set_expr_mutation(Expression,Expression).
59
60 random_set_expr_mutation_aux(0,Expr1,Expr2,NewExpr1,Expr2) :-
61 random_set_expr_mutation(Expr1,NewExpr1).
62 random_set_expr_mutation_aux(1,Expr1,Expr2,Expr1,NewExpr2) :-
63 random_set_expr_mutation(Expr2,NewExpr2).
64 random_set_expr_mutation_aux(2,Expr1,Expr2,NewExpr1,NewExpr2) :-
65 random_set_expr_mutation(Expr1,NewExpr1) ,
66 random_set_expr_mutation(Expr2,NewExpr2).
67
68 % mutate set_extension nodes by replacing with matching set expressions like union or set_subtraction
69 mutate_set(b(set_extension(Set),SetType,Info),Mutation) :-
70 (random(0,2,0)
71 -> random_union(Set,SubSetA,SubSetB) ,
72 Temp = b(union(b(set_extension(SubSetA),SetType,Info),b(set_extension(SubSetB),SetType,Info)),SetType,[])
73 ; random_subtraction(Set,SetA,SetB) ,
74 Temp = b(set_subtraction(b(set_extension(SetA),SetType,Info),b(set_extension(SetB),SetType,Info)),SetType,[])) ,
75 % random choice of further mutation
76 random(0,10,R) ,
77 (R < 7
78 -> Mutation = Temp
79 ; random_set_expr_mutation(Temp,Mutation)).
80 mutate_set(b(value(Set),SetType,Info),b(value(NewSet),SetType,Info)) :-
81 generate(mutation(Set:prob_value_set),NewSet).
82
83 % just permutate given data, no generation
84 permutate_set(b(set_extension(Set),SetType,Info),b(set_extension(NewSet),SetType,Info)) :-
85 generate(mutation(Set:list),NewSet).
86 permutate_set(b(value(Set),SetType,Info),b(value(NewSet),SetType,Info)) :-
87 generate(mutation(Set:prob_value_set),NewSet).
88
89 % split a list in two sublists randomly
90 random_union([],[],[]).
91 random_union(List,A,B) :-
92 length(List,Length) ,
93 generate(integer([between(1,Length)]),LengthA) ,
94 LengthB is Length - LengthA ,
95 LengthA >= 0 , LengthB >= 0 ,
96 % set length of both sublists
97 length(A,LengthA) ,
98 length(B,LengthB) ,
99 % use append to find solutions
100 append(A,B,List).
101 random_union(_,[],[]).
102
103 % add random list B to first argument so that A - B = List
104 % like replace [1,2] with [1,2,3] - [3]
105 random_subtraction(List,A,B) :-
106 List = [b(_,Type,_)|_] ,
107 NType =.. [Type,[]] ,
108 generate(prob_ast_set(NType,[extension]),b(set_extension(B),_,_)) ,
109 append(List,B,A).