def __init__(self, fsm: MealyMachine): self.fsm = fsm self.A = fsm.get_alphabet() self.states = self.fsm.get_states() self.root = PartitionNode(self.states, self.A, self) self.nodes = [self.root] self.wanted = set([state.name for state in fsm.get_states()]) self.closed = set() self.solution = set()
class LearnSimpleMealy(unittest.TestCase): def setUp(self): s1 = MealyState('1') s2 = MealyState('2') s3 = MealyState('3') s1.add_edge('a', 'nice', s2) s1.add_edge('b', 'B', s1) s2.add_edge('a', 'nice', s3) s2.add_edge('b', 'back', s1) s3.add_edge('a', 'A', s3) s3.add_edge('b', 'back', s1) self.mm = MealyMachine(s1) def test_lstar_wmethod(self): eqc = WmethodEquivalenceChecker(self.mm, m=len(self.mm.get_states())) teacher = Teacher(self.mm, eqc) learner = LStarMealyLearner(teacher) hyp = learner.run() equivalent, _ = eqc.test_equivalence(hyp) self.assertTrue(equivalent) self.assertEqual( len(self.mm.get_states()), len(hyp.get_states()), ) def test_lstar_bruteforce(self): eqc = BFEquivalenceChecker(self.mm, max_depth=len(self.mm.get_states())) teacher = Teacher(self.mm, eqc) learner = LStarMealyLearner(teacher) hyp = learner.run() equivalent, _ = WmethodEquivalenceChecker( self.mm, m=len(self.mm.get_states())).test_equivalence(hyp) self.assertTrue(equivalent) self.assertEqual( len(self.mm.get_states()), len(hyp.get_states()), )
def _render(fsm: MealyMachine, filename): states = sorted(fsm.get_states(), key=lambda x: int(x.name.strip('s'))) alphabet = sorted(fsm.get_alphabet()) g = Digraph('G', filename=filename) g.attr(rankdir='LR') # Add states for state in states: g.node(state.name) # Add transitions: for state in states: for action, (other_state, output) in sorted(state.edges.items(), key=lambda x: x[0]): g.edge(state.name, other_state.name, label=f'{action}/{output}') g.save()
def _minimize(mm: MealyMachine): dset = get_distinguishing_set(mm) dset_outputs = get_dset_outputs(mm, dset) # Find non-unique states: state_map = {} for state, outputs in dset_outputs.items(): if outputs not in state_map: state_map[outputs] = [state] else: state_map[outputs].append(state) for outputs, states in state_map.items(): if len(states) > 1: og_state = states[0] rest_states = states[1:] states = mm.get_states() for state in states: for action, (other_state, output) in state.edges.items(): if other_state in rest_states: state.edges[action] = og_state, output return mm
from stmlearn.equivalencecheckers import WmethodEquivalenceChecker from stmlearn.learners import TTTMealyLearner from stmlearn.suls import MealyState, MealyMachine from stmlearn.teachers import Teacher # Set up an example mealy machine s1 = MealyState('1') s2 = MealyState('2') s3 = MealyState('3') s1.add_edge('a', 'nice', s2) s1.add_edge('b', 'B', s1) s2.add_edge('a', 'nice', s3) s2.add_edge('b', 'back', s1) s3.add_edge('a', 'A', s3) s3.add_edge('b', 'back', s1) mm = MealyMachine(s1) # Use the W method equivalence checker eqc = WmethodEquivalenceChecker(mm, m=len(mm.get_states())) teacher = Teacher(mm, eqc) # We are learning a mealy machine learner = TTTMealyLearner(teacher) hyp = learner.run() hyp.render_graph(tempfile.mktemp('.gv')) learner.DTree.render_graph(tempfile.mktemp('.gv'))