Skip to content

Commit ee42ef4

Browse files
author
Edi Muskardin
committed
- account for an empty sequance in execute_sequence for DFAs and Moore machines
- make bisimilar return tuple
1 parent ea16830 commit ee42ef4

File tree

4 files changed

+11
-13
lines changed

4 files changed

+11
-13
lines changed

aalpy/automata/Dfa.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def compute_output_seq(self, state, sequence):
5353

5454
def execute_sequence(self, origin_state, seq):
5555
if not seq:
56-
return self.current_state.output
56+
return origin_state.output
5757
return super(Dfa, self).execute_sequence(origin_state, seq)
5858

5959

aalpy/automata/MooreMachine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def compute_output_seq(self, state, sequence):
5050

5151
def execute_sequence(self, origin_state, seq):
5252
if not seq:
53-
return self.current_state.output
53+
return origin_state.output
5454
return super(MooreMachine, self).execute_sequence(origin_state, seq)
5555

5656
def to_state_setup(self):

aalpy/base/Automaton.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ def make_input_complete(self, missing_transition_go_to='self_loop'):
143143
make_input_complete(self, missing_transition_go_to)
144144

145145
def execute_sequence(self, origin_state, seq):
146-
# to account epsilon in DFAs, Moore, MDPs machines
147-
# if not seq:
148-
# return origin_state.output
146+
"""
147+
Note that execute sequance changes the state!
148+
"""
149149
self.current_state = origin_state
150150
return [self.step(s) for s in seq]
151151

aalpy/utils/ModelChecking.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,13 @@ def stop_based_on_confidence(hypothesis, property_based_stopping, print_level=2)
235235
return True
236236

237237

238-
def bisimilar(a1: DeterministicAutomaton, a2: DeterministicAutomaton, return_cex=False) -> Union[bool, None, list]:
238+
def bisimilar(a1: DeterministicAutomaton, a2: DeterministicAutomaton, return_cex=False) -> Union[bool, None, tuple]:
239239
"""
240240
Checks whether the provided automata are bisimilar.
241241
If return_cex the function returns a counter example or None, otherwise a Boolean is returned.
242242
243243
Returns:
244-
object:
244+
object: true or false if return_cex is set to False, otherwise None (no counterexample) or a counterexample
245245
"""
246246

247247
# TODO allow states as inputs instead of automata
@@ -259,28 +259,26 @@ def bisimilar(a1: DeterministicAutomaton, a2: DeterministicAutomaton, return_cex
259259
to_check: Queue[Tuple[AutomatonState, AutomatonState]] = Queue()
260260
to_check.put((a1.initial_state, a2.initial_state))
261261
requirements = dict()
262-
requirements[(a1.initial_state, a2.initial_state)] = []
262+
requirements[(a1.initial_state, a2.initial_state)] = ()
263263

264264
while not to_check.empty():
265265
s1, s2 = to_check.get()
266266

267267
# check output equivalence for Dfa / Moore
268-
if (isinstance(s1, DfaState)) and s1.is_accepting != s2.is_accepting:
269-
return requirements[(s1, s2)] if return_cex else False
270-
if (isinstance(s1, MooreState) and s1.output != s2.output):
268+
if isinstance(s1, (DfaState, MooreState)) and s1.output != s2.output:
271269
return requirements[(s1, s2)] if return_cex else False
272270

273271
# check whether the same inputs are enabled + output equivalence for Mealy
274272
t1, t2 = s1.transitions, s2.transitions
275273
for t in it.chain(t1.keys(), filter(lambda x : x not in t1.keys(), t2.keys())):
276274
common = t in t1.keys() and t in t2.keys()
277275
if (not common) or (isinstance(s1, MealyState) and s1.output_fun[t] != s2.output_fun[t]) :
278-
return requirements[(s1, s2)] + [t] if return_cex else False
276+
return requirements[(s1, s2)] + (t,) if return_cex else False
279277

280278
for t in t1.keys():
281279
c1, c2 = t1[t], t2[t]
282280
if (c1, c2) not in requirements:
283-
requirements[(c1, c2)] = requirements[(s1, s2)] + [t]
281+
requirements[(c1, c2)] = requirements[(s1, s2)] + (t,)
284282
to_check.put((c1, c2))
285283

286284
return None if return_cex else True

0 commit comments

Comments
 (0)