def get_benchmark_ONFSM(): """ Returns ONFSM presented in 'Learning Finite State Models of Observable Nondeterministic Systems in a Testing Context'. """ from aalpy.automata import Onfsm, OnfsmState a = OnfsmState('q0') b = OnfsmState('q1') c = OnfsmState('g2') d = OnfsmState('q3') a.transitions['a'].append((0, b)) a.transitions['b'].append((2, a)) a.transitions['b'].append((0, c)) b.transitions['a'].append((2, a)) b.transitions['b'].append((3, b)) c.transitions['a'].append((2, d)) c.transitions['b'].append((0, c)) c.transitions['b'].append((3, c)) d.transitions['a'].append((2, b)) d.transitions['b'].append((3, d)) return Onfsm(a, [a, b, c, d])
def get_benchmark_ONFSM(): """ Returns ONFSM presented in 'Learning Finite State Models of Observable Nondeterministic Systems in a Testing Context'. """ a = OnfsmState('a') b = OnfsmState('b') c = OnfsmState('c') d = OnfsmState('d') a.transitions['a'].append((0, b)) a.transitions['b'].append((2, a)) a.transitions['b'].append((0, c)) b.transitions['a'].append((2, a)) b.transitions['b'].append((3, b)) c.transitions['a'].append((2, d)) c.transitions['b'].append((0, c)) c.transitions['b'].append((3, c)) d.transitions['a'].append((2, b)) d.transitions['b'].append((3, d)) return Onfsm(a, [a, b, c, d])
def gen_hypothesis(self) -> Onfsm: """ Generate automaton based on the values found in the abstracted observation table. Returns: Current abstracted hypothesis """ state_distinguish = dict() states_dict = dict() initial = None unified_S = self.S + self.S_dot_A stateCounter = 0 for prefix in self.S: state_id = f's{stateCounter}' states_dict[prefix] = OnfsmState(state_id) states_dict[prefix].prefix = prefix state_distinguish[self.row_to_hashable( prefix)] = states_dict[prefix] if prefix == self.S[0]: initial = states_dict[prefix] stateCounter += 1 for prefix in self.S: similar_rows = [] for row in unified_S: if self.row_to_hashable(row) == self.row_to_hashable(prefix): similar_rows.append(row) for row in similar_rows: for a in self.A: for t in self.observation_table.T[row][a]: if (row[0] + a, row[1] + tuple([t])) in unified_S: state_in_S = state_distinguish[ self.row_to_hashable( (row[0] + a, row[1] + tuple([t])))] if (t, state_in_S ) not in states_dict[prefix].transitions[a[0]]: states_dict[prefix].transitions[a[0]].append( (t, state_in_S)) assert initial automaton = Onfsm(initial, [s for s in states_dict.values()]) automaton.characterization_set = self.E return automaton
def gen_hypothesis(self) -> Automaton: """ Generate automaton based on the values found in the observation table. Returns: Current hypothesis """ state_distinguish = dict() states_dict = dict() initial = None stateCounter = 0 for prefix in self.S: state_id = f's{stateCounter}' states_dict[prefix] = OnfsmState(state_id) states_dict[prefix].prefix = prefix state_distinguish[self.row_to_hashable( prefix)] = states_dict[prefix] if prefix == self.S[0]: initial = states_dict[prefix] stateCounter += 1 for prefix in self.S: curr_node = self.sul.pta.get_to_node(prefix[0], prefix[1]) for a in self.A: trace = self.sul.pta.get_all_traces(curr_node, a) for t in trace: reached_row = (prefix[0] + a, prefix[1] + (t[-1], )) if self.row_to_hashable( reached_row) not in state_distinguish.keys(): print('reeee') state_in_S = state_distinguish[self.row_to_hashable( reached_row)] assert state_in_S # shouldn't be necessary because of the if condition states_dict[prefix].transitions[a[0]].append( (t[-1], state_in_S)) assert initial automaton = Onfsm(initial, [s for s in states_dict.values()]) automaton.characterization_set = self.E return automaton
def gen_hypothesis(self) -> Automaton: """ Generate automaton based on the values found in the observation table. Returns: Current hypothesis """ state_distinguish = dict() states_dict = dict() initial = None stateCounter = 0 for prefix in self.S: state_id = f's{stateCounter}' states_dict[prefix] = OnfsmState(state_id) states_dict[prefix].prefix = prefix state_distinguish[self.row_to_hashable( prefix)] = states_dict[prefix] if prefix == self.S[0]: initial = states_dict[prefix] stateCounter += 1 for prefix in self.S: for a in self.A: for t in self.T[prefix][a]: state_in_S = state_distinguish[self.row_to_hashable( (prefix[0] + a, prefix[1] + tuple([t])))] assert state_in_S states_dict[prefix].transitions[a[0]].append( (t, state_in_S)) assert initial automaton = Onfsm(initial, [s for s in states_dict.values()]) automaton.characterization_set = self.E return automaton
def get_ONFSM(): """ Returns example of an ONFSM. """ from aalpy.automata import Onfsm, OnfsmState q0 = OnfsmState('q0') q1 = OnfsmState('q1') q2 = OnfsmState('q2') q3 = OnfsmState('q3') q4 = OnfsmState('q4') q5 = OnfsmState('q5') q6 = OnfsmState('q6') q7 = OnfsmState('q7') q8 = OnfsmState('q8') q0.transitions['a'].append((2, q1)) q0.transitions['b'].append((0, q0)) q1.transitions['a'].append((2, q0)) q1.transitions['b'].append((0, q2)) q2.transitions['a'].append((1, q2)) q2.transitions['b'].append((0, q3)) q3.transitions['a'].append((2, q8)) q3.transitions['b'].append((0, q4)) q4.transitions['a'].append((1, q4)) q4.transitions['b'].append((0, q5)) q5.transitions['a'].append((2, q6)) q5.transitions['b'].append((0, q7)) q6.transitions['a'].append((2, q5)) q6.transitions['b'].append((0, q6)) q7.transitions['a'].append((1, q7)) q7.transitions['b'].append(('O', q0)) q8.transitions['a'].append((2, q3)) q8.transitions['b'].append((0, q8)) return Onfsm(q0, [q0, q1, q2, q3, q4, q5, q6, q7, q8])
def generate_random_ONFSM(num_states, num_inputs, num_outputs, multiple_out_prob=0.1): """ Randomly generate an observable non-deterministic finite-state machine. Args: num_states: number of states num_inputs: number of inputs num_outputs: number of outputs multiple_out_prob: probability that state will have multiple outputs (Default value = 0.1) Returns: randomly generated ONFSM """ inputs = [ random_string_generator(random.randint(1, 3)) for _ in range(num_inputs) ] outputs = [ random_string_generator(random.randint(3, 7)) for _ in range(num_outputs) ] states = [] for i in range(num_states): state = OnfsmState(f's{i}') states.append(state) for state in states: for i in inputs: state_outputs = 1 if random.random() <= multiple_out_prob and num_outputs > 1: state_outputs = random.randint(2, num_outputs) random_out = random.sample(outputs, state_outputs) for index in range(state_outputs): state.transitions[i].append( (random_out[index], random.choice(states))) return Onfsm(states[0], states)
def generate_random_ONFSM(num_states, num_inputs, num_outputs, multiple_out_prob=0.1): """ Randomly generate an observable non-deterministic finite-state machine. Args: num_states: number of states num_inputs: number of inputs num_outputs: number of outputs multiple_out_prob: probability that state will have multiple outputs (Default value = 0.5) Returns: randomly generated ONFSM """ inputs = [f'i{i+1}' for i in range(num_inputs)] outputs = [f'o{i+1}' for i in range(num_outputs)] states = [] for i in range(num_states): state = OnfsmState(f's{i}') states.append(state) state_buffer = states.copy() for state in states: for i in inputs: state_outputs = 1 if random.random() <= multiple_out_prob and num_outputs >= 2: state_outputs = random.randint(2, num_outputs) random_out = random.sample(outputs, state_outputs) for index in range(state_outputs): if state_buffer: new_state = random.choice(state_buffer) state_buffer.remove(new_state) else: new_state = random.choice(states) state.transitions[i].append((random_out[index], new_state)) return Onfsm(states[0], states)