-
Notifications
You must be signed in to change notification settings - Fork 1
/
mutate_automata.py
114 lines (91 loc) · 3.81 KB
/
mutate_automata.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import random
import math
def mutate_automata(file_path, template_name, amount_of_parameters_to_change=1, rate_of_changes=0.2):
r_file = open(file_path, 'r')
w_file = open(file_path[0:-4] + '_mutated.xml', 'w')
template = []
reading_template = 0
for line in r_file:
if reading_template:
template.append(line)
if '</template>' in line:
write_template(template, w_file, template_name,
amount_of_parameters_to_change, rate_of_changes)
template = []
reading_template = 0
else:
if '<template>' in line:
template.append(line)
reading_template = 1
else:
w_file.write(line)
def write_template(template, w_file, target_template_name, amount_of_parameters_to_change, rate_of_changes):
template_name_line = template[1]
template_name_start = template_name_line.find('>') + 1
template_name_end = template_name_line.find('<', template_name_start)
template_name = template_name_line[template_name_start: template_name_end].strip(
)
if target_template_name != template_name:
for line in template:
w_file.write(line)
return
c_count = 0
for line in template:
c_count += line.count('>')
c_count += line.count('<')
if amount_of_parameters_to_change >= c_count:
change_choice = [1] * c_count
else:
change_choice = [1] * amount_of_parameters_to_change + \
[0] * (c_count - amount_of_parameters_to_change)
random.shuffle(change_choice)
for line in template:
if "label kind=\"invariant\"" in line or "label kind=\"guard\"" in line:
constraints_start = line.find('>') + 1
constraints_end = line.find('<', constraints_start)
constraints = line[constraints_start: constraints_end]
constraints = constraints.split('&&')
w_file.write(line[:constraints_start])
result = []
for c in constraints:
if '>' in c:
if change_choice[0] == 0:
change_choice = change_choice[1:]
result.append(c)
continue
t_start = c.find('>')
if c[t_start+4] == '=':
t_start = t_start + 5
else:
t_start = t_start + 4
threshold = c[t_start:].strip()
c = c[:t_start]
c += ' ' + \
str(int(threshold) +
int(math.ceil(rate_of_changes * int(threshold)))) + ' '
result.append(c)
change_choice = change_choice[1:]
elif '<' in c:
if change_choice[0] == 0:
change_choice = change_choice[1:]
result.append(c)
continue
t_start = c.find('<')
if c[t_start+4] == '=':
t_start = t_start + 5
else:
t_start = t_start + 4
threshold = c[t_start:].strip()
c = c[:t_start]
threshold = int(
math.ceil((1-rate_of_changes) * int(threshold)))
threshold *= (threshold > 0)
c += ' ' + str(threshold) + ' '
result.append(c)
change_choice = change_choice[1:]
else:
result.append(c)
w_file.write('&&'.join(result))
w_file.write(line[constraints_end:])
else:
w_file.write(line)