def generate_random_moore_machine(num_states, input_alphabet, output_alphabet, compute_prefixes=False) -> MooreMachine: """ Generates a random Moore machine. Args: num_states: number of states input_alphabet: input alphabet output_alphabet: output alphabet compute_prefixes: if true, shortest path to reach each state will be computed (Default value = False) Returns: Moore machine with num_states states """ states = list() for i in range(num_states): states.append(MooreState(i, random.choice(output_alphabet))) for state in states: for a in input_alphabet: state.transitions[a] = random.choice(states) mm = MooreMachine(states[0], states) if compute_prefixes: for state in states: state.prefix = mm.get_shortest_path(mm.initial_state, state) return mm
def moore_from_state_setup(state_setup) -> MooreMachine: """ First state in the state setup is the initial state. Example state setup: state_setup = { "a": ("a", {"x": "b1", "y": "a"}), "b1": ("b", {"x": "b2", "y": "a"}), "b2": ("b", {"x": "b3", "y": "a"}), "b3": ("b", {"x": "b4", "y": "a"}), "b4": ("b", {"x": "c", "y": "a"}), "c": ("c", {"x": "a", "y": "a"}), } Args: state_setup: map from state_id to tuple(output and transitions_dict) Returns: Moore machine """ # build states with state_id and output states = {key: MooreState(key, val[0]) for key, val in state_setup.items()} # add transitions to states for state_id, state in states.items(): for _input, target_state_id in state_setup[state_id][1].items(): state.transitions[_input] = states[target_state_id] # states to list states = [state for state in states.values()] # build moore machine with first state as starting state mm = MooreMachine(states[0], states) for state in states: state.prefix = mm.get_shortest_path(mm.initial_state, state) return mm
def gen_moore_from_state_setup(state_setup) -> MooreMachine: # state_setup shoud map from state_id to tuple(output and transitions_dict) # build states with state_id and output states = { key: MooreState(key, val[0]) for key, val in state_setup.items() } # add transitions to states for state_id, state in states.items(): for _input, target_state_id in state_setup[state_id][1].items(): state.transitions[_input] = states[target_state_id] # states to list states = [state for state in states.values()] # build moore machine with first state as starting state mm = MooreMachine(states[0], states) for state in states: state.prefix = mm.get_shortest_path(mm.initial_state, state) return mm
def gen_hypothesis(self, check_for_duplicate_rows=False) -> Automaton: """ Generate automaton based on the values found in the observation table. :return: Args: check_for_duplicate_rows: (Default value = False) Returns: Automaton of type `automaton_type` """ state_distinguish = dict() states_dict = dict() initial_state = None automaton_class = { 'dfa': Dfa, 'mealy': MealyMachine, 'moore': MooreMachine } # delete duplicate rows, only possible if no counterexample processing is present # counterexample processing removes the need for consistency check, as it ensures # that no two rows in the S set are the same if check_for_duplicate_rows: rows_to_delete = set() for i, s1 in enumerate(self.S): for s2 in self.S[i + 1:]: if self.T[s1] == self.T[s2]: rows_to_delete.add(s2) for row in rows_to_delete: self.S.remove(row) # create states based on S set stateCounter = 0 for prefix in self.S: state_id = f's{stateCounter}' if self.automaton_type == 'dfa': states_dict[prefix] = DfaState(state_id) states_dict[prefix].is_accepting = self.T[prefix][0] elif self.automaton_type == 'moore': states_dict[prefix] = MooreState(state_id, output=self.T[prefix][0]) else: states_dict[prefix] = MealyState(state_id) states_dict[prefix].prefix = prefix state_distinguish[tuple(self.T[prefix])] = states_dict[prefix] if not prefix: initial_state = states_dict[prefix] stateCounter += 1 # add transitions based on extended S set for prefix in self.S: for a in self.A: state_in_S = state_distinguish[self.T[prefix + a]] states_dict[prefix].transitions[a[0]] = state_in_S if self.automaton_type == 'mealy': states_dict[prefix].output_fun[a[0]] = self.T[prefix][ self.E.index(a)] automaton = automaton_class[self.automaton_type]( initial_state, list(states_dict.values())) automaton.characterization_set = self.E return automaton