def __find(analyzer, StateIndex, CompressionType, AvailableStateIndexSet): """Searches for the BEGINNING of a path, i.e. a single character transition to a subsequent state. If such a transition is found, a search for a path is initiated (call to '__find_continuation(..)'). This function itself it not recursive. """ result_list = [] State = analyzer.state_db[StateIndex] target_map = State.map_target_index_to_character_set transition_map = transition_map_tools.relate_to_door_ids( State.transition_map, analyzer, State.index) for target_idx, trigger_set in target_map.iteritems(): if target_idx not in AvailableStateIndexSet: continue # State is not an option. elif target_idx == StateIndex: continue # Recursion! Do not go further! # Only single character transitions can be element of a path. transition_char = trigger_set.get_the_only_element() if transition_char is None: continue # Not a single char transition. result = __find_continuation(analyzer, CompressionType, AvailableStateIndexSet, State, transition_map, transition_char, target_idx) result_list.extend(result) return result_list
def __find(analyzer, StateIndex, CompressionType, AvailableStateIndexSet): """Searches for the BEGINNING of a path, i.e. a single character transition to a subsequent state. If such a transition is found, a 'skeleton' transition map is computed. A 'skeleton' is a transition map which contains 'wildcards' for the characters which constitute the path's transition. For a subsequent state to be part of the path, its transition map must match that skeleton. This function is not recursive. It simply iterates over all states in the state machine. For each state, in isolation, it checks wether it might be the beginning of a path. """ result_list = [] State = analyzer.state_db[StateIndex] target_map = State.map_target_index_to_character_set transition_map = transition_map_tools.relate_to_door_ids(State.transition_map, analyzer, State.index) for target_idx, trigger_set in target_map.iteritems(): if target_idx not in AvailableStateIndexSet: continue # State is not an option. elif target_idx == StateIndex: continue # Recursion! Do not go further! # Only single character transitions can be element of a path. transition_char = trigger_set.get_the_only_element() if transition_char is None: continue result = __find_continuation(analyzer, CompressionType, AvailableStateIndexSet, State, transition_map, transition_char, target_idx) result_list.extend(result) return result_list
def __find(analyzer, StateIndex, CompressionType, AvailableStateIndexSet): """Searches for the BEGINNING of a path, i.e. a single character transition to a subsequent state. If such a transition is found, a search for a path is initiated (call to '__find_continuation(..)'). This function itself it not recursive. """ result_list = [] State = analyzer.state_db[StateIndex] target_map = State.map_target_index_to_character_set transition_map = transition_map_tools.relate_to_door_ids(State.transition_map, analyzer, State.index) for target_idx, trigger_set in target_map.iteritems(): if target_idx not in AvailableStateIndexSet: continue # State is not an option. elif target_idx == StateIndex: continue # Recursion! Do not go further! # Only single character transitions can be element of a path. transition_char = trigger_set.get_the_only_element() if transition_char is None: continue # Not a single char transition. result = __find_continuation(analyzer, CompressionType, AvailableStateIndexSet, State, transition_map, transition_char, target_idx) result_list.extend(result) return result_list
def on_enter(self, Args): path = Args[0] State = Args[1] # list: (interval, target) --> (interval, door_id) transition_map = transition_map_tools.relate_to_door_ids(State.transition_map, self.analyzer, State.index) # BRANCH __________________________________________________________ sub_list = [] for target_index, trigger_set in State.map_target_index_to_character_set.iteritems(): if target_index not in self.available_set: return # Only single character transitions can be element of a path. transition_char = trigger_set.get_the_only_element() if transition_char is None: continue # A PathWalkerState cannot implement a loop. if path.contains_state(target_index): continue # Loop--don't go! target_state = self.analyzer.state_db[target_index] # Do the transitions fit the path's transition map? target_door_id = target_state.entry.get_door_id(target_index, State.index) plug = path.match(transition_map, target_door_id, transition_char) if plug is None: continue # No match possible # If required, can uniformity be maintained? uniform_drop_out_expected_f = False if self.uniform_f: if not PathFinder.check_uniformity(path, target_state): continue uniform_drop_out_expected_f = True # RECURSION STEP ______________________________________________ # May be, we do not have to clone the transition map if plug == -1 new_path = path.clone() # Find a continuation of the path new_path.append_state(State, transition_char) if uniform_drop_out_expected_f: assert len(new_path.drop_out) == 1 if plug != -1: new_path.plug_wildcard(plug) sub_list.append((new_path, target_state)) # TERMINATION _____________________________________________________ if len(sub_list) == 0: if len(path) > 1: path.append_state(State, None) # trans. char = None => do not consider entry_db path.finalize() self.add_result(path) return return sub_list
def on_enter(self, Args): path = Args[0] State = Args[1] # list: (interval, target) --> (interval, door_id) transition_map = transition_map_tools.relate_to_door_ids( State.transition_map, self.analyzer, State.index) # BRANCH __________________________________________________________ sub_list = [] for target_index, trigger_set in State.map_target_index_to_character_set.iteritems( ): if target_index not in self.available_set: return # Only single character transitions can be element of a path. transition_char = trigger_set.get_the_only_element() if transition_char is None: continue # A PathWalkerState cannot implement a loop. if path.contains_state(target_index): continue # Loop--don't go! target_state = self.analyzer.state_db[target_index] # Do the transitions fit the path's transition map? target_door_id = target_state.entry.get_door_id( target_index, State.index) plug = path.match(transition_map, target_door_id, transition_char) if plug is None: continue # No match possible # If required, can uniformity be maintained? uniform_drop_out_expected_f = False if self.uniform_f: if not PathFinder.check_uniformity(path, target_state): continue uniform_drop_out_expected_f = True # RECURSION STEP ______________________________________________ # May be, we do not have to clone the transition map if plug == -1 new_path = path.clone() # Find a continuation of the path new_path.append_state(State, transition_char) if uniform_drop_out_expected_f: assert len(new_path.drop_out) == 1 if plug != -1: new_path.plug_wildcard(plug) sub_list.append((new_path, target_state)) # TERMINATION _____________________________________________________ if len(sub_list) == 0: if len(path) > 1: path.append_state( State, None) # trans. char = None => do not consider entry_db path.finalize() self.add_result(path) return return sub_list