Skip to content

Commit a752949

Browse files
committed
significant scaling of Wp Oracle
1 parent 87d62a2 commit a752949

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

aalpy/oracles/WpMethodEqOracle.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def i_star(alphabet, max_seq_len):
3333
return chain(*(product_with_possible_empty_iterable(alphabet, repeat=i) for i in range(max_seq_len)))
3434

3535

36-
def second_phase_it(hyp, alphabet, difference, middle):
36+
def second_phase_test_case_generator(hyp, alphabet, difference, middle):
3737
"""
3838
Return an iterator that generates all possible sequences for the second phase of the Wp-method.
3939
Args:
@@ -50,7 +50,7 @@ def second_phase_it(hyp, alphabet, difference, middle):
5050
state_mapping[state] = state_characterization_set(hyp, alphabet, state)
5151

5252
for sm in state_mapping[state]:
53-
yield (t,) + (mid,) + (sm,)
53+
yield t + mid + sm
5454

5555

5656
class WpMethodEqOracle(Oracle):
@@ -63,6 +63,21 @@ def __init__(self, alphabet: list, sul: SUL, max_number_of_states=4):
6363
self.m = max_number_of_states
6464
self.cache = set()
6565

66+
def test_sequance(self, hypothesis, seq_under_test):
67+
self.reset_hyp_and_sul(hypothesis)
68+
69+
for ind, letter in enumerate(seq_under_test):
70+
out_hyp = hypothesis.step(letter)
71+
out_sul = self.sul.step(letter)
72+
self.num_steps += 1
73+
74+
if out_hyp != out_sul:
75+
self.sul.post()
76+
return seq_under_test[: ind + 1]
77+
self.cache.add(seq_under_test)
78+
79+
return None
80+
6681
def find_cex(self, hypothesis):
6782
if not hypothesis.characterization_set:
6883
hypothesis.characterization_set = hypothesis.compute_characterization_set()
@@ -80,27 +95,26 @@ def find_cex(self, hypothesis):
8095
middle_1, middle_2 = tee(i_star(self.alphabet, self.m - hypothesis.size + 1), 2)
8196

8297
# first phase State Cover * Middle * Characterization Set
83-
first_phase = product_with_possible_empty_iterable(state_cover, middle_1, hypothesis.characterization_set)
98+
state_cover = state_cover or [()]
99+
char_set = hypothesis.characterization_set or [()]
100+
101+
for sc in state_cover:
102+
for m in middle_1:
103+
for cs in char_set:
104+
test_seq = sc + m + cs
105+
if test_seq not in self.cache:
106+
counterexample = self.test_sequance(hypothesis, test_seq)
107+
if counterexample:
108+
return counterexample
84109

85110
# second phase (Transition Cover - State Cover) * Middle * Characterization Set
86111
# of the state that the prefix leads to
87-
second_phase = second_phase_it(hypothesis, self.alphabet, difference, middle_2)
88-
test_suite = chain(first_phase, second_phase)
89-
90-
for seq in test_suite:
91-
seq = tuple([i for sub in seq for i in sub])
92-
93-
if seq not in self.cache:
94-
self.reset_hyp_and_sul(hypothesis)
95-
96-
for ind, letter in enumerate(seq):
97-
out_hyp = hypothesis.step(letter)
98-
out_sul = self.sul.step(letter)
99-
self.num_steps += 1
112+
second_phase = second_phase_test_case_generator(hypothesis, self.alphabet, difference, middle_2)
100113

101-
if out_hyp != out_sul:
102-
self.sul.post()
103-
return seq[: ind + 1]
104-
self.cache.add(seq)
114+
for test_seq in second_phase:
115+
if test_seq not in self.cache:
116+
counterexample = self.test_sequance(hypothesis, test_seq)
117+
if counterexample:
118+
return counterexample
105119

106120
return None

0 commit comments

Comments
 (0)