def __init__(self, PWState, TheAnalyzer): self.uniform_door_id = UniformObject() self.uniform_terminal_door_id = UniformObject() self.door_id_sequence_list = [] for step_list in PWState.path_list: # Meaningful paths consist of more than one state and a terminal. assert len(step_list) > 2 door_id_sequence = self.__determine_door_id_sequence(step_list, TheAnalyzer, PWState) self.door_id_sequence_list.append(door_id_sequence) return
def _interfere_acceptance(cls, snapshot_set_db, EntryRecipeDb, StateIndex): """If the acceptance scheme differs for only two recipes, then the acceptance must be determined upon entry and stored in the LastAcceptance register. RETURN: [0] Accumulated 'accepter' """ # Interference requires determined entry recipes. assert none_is_None(EntryRecipeDb.itervalues()) # Irrelevant E_R.AcceptanceRegister? Impossible! Acceptance is relevant # for all states! '.accepter is None' is not treated. accepter = UniformObject.from_iterable( recipe.accepter for recipe in EntryRecipeDb.itervalues()).plain_content() if accepter != E_Values.VOID: # Homogeneity pass else: # Inhomogeneity accepter = [ cls.RestoreAcceptance ] snapshot_set_db[E_R.AcceptanceRegister] = set([StateIndex]) assert accepter and accepter[-1].pre_context_id() == E_PreContextIDs.NONE return accepter
def _interfere_acceptance(cls, snapshot_set_db, EntryRecipeDb, StateIndex): """If the acceptance scheme differs for only two recipes, then the acceptance must be determined upon entry and stored in the LastAcceptance register. RETURN: [0] Accumulated 'accepter' """ # Interference requires determined entry recipes. assert none_is_None(EntryRecipeDb.itervalues()) # Irrelevant E_R.AcceptanceRegister? Impossible! Acceptance is relevant # for all states! '.accepter is None' is not treated. accepter = UniformObject.from_iterable( recipe.accepter for recipe in EntryRecipeDb.itervalues()).plain_content() if accepter != E_Values.VOID: # Homogeneity pass else: # Inhomogeneity accepter = [ cls.RestoreAcceptance ] snapshot_set_db[E_R.AcceptanceRegister] = set([StateIndex]) assert accepter and accepter[-1].pre_context_id() == E_PreContextIDs.NONE return accepter
def __init__(self, StartState, TheTransitionMap, TransitionCharacter): if StartState is None: return # Only for Clone assert isinstance(StartState, FSM_State) assert isinstance(TransitionCharacter, (int, long)), "Found '%s'" % TransitionCharacter assert isinstance(TheTransitionMap, TransitionMap) # uniform_entry_OpList: # The entry into the StartState happens from outside. # => A 'state_key' is assigned (the path_iterator) # and it is not part of the iteration loop. # => The StartState's entry IS NOT subject to uniformity considerations. self.uniform_entry_OpList = UniformObject() self.__step_list = [ CharacterPathStep(StartState.index, TransitionCharacter) ] self.transition_map_data = TransitionMapData(TheTransitionMap, TransitionCharacter)
def from_scheme(SchemeAsList): result = TargetByStateKey() result.__scheme = tuple(SchemeAsList) result.__scheme_id = None result.__uniform_door_id = UniformObject.from_iterable(SchemeAsList).content assert isinstance(result.__uniform_door_id, (types.NoneType, DoorID)) return result
def from_scheme(SchemeAsList): result = TargetByStateKey() result.__scheme = tuple(SchemeAsList) result.__scheme_id = None result.__uniform_door_id = UniformObject.from_iterable( SchemeAsList).content assert isinstance(result.__uniform_door_id, (types.NoneType, DoorID)) return result
def __init__(self, Represented_AnalyzerState, DropOutCatcher): assert not isinstance(Represented_AnalyzerState, MegaState) state_index = Represented_AnalyzerState.index transition_map = Represented_AnalyzerState.transition_map adapted_transition_map = transition_map.relate_to_TargetByStateKeys( state_index, DropOutCatcher) ski_db = StateKeyIndexDB([state_index]) MegaState.__init__(self, state_index, adapted_transition_map, ski_db) # Uniform Entry: In contrast to path compression, here we consider # all entries into the MegaState. self.uniform_entry_OpList = UniformObject() for action in Represented_AnalyzerState.entry.itervalues(): self.uniform_entry_OpList <<= action.command_list if self.uniform_entry_OpList.is_uniform() == False: break # No more need to investigate self.entry.absorb(Represented_AnalyzerState.entry)
class PseudoTemplateState(MegaState): """________________________________________________________________________ Represents an FSM_State in a way to that it acts homogeneously with other MegaState-s. That is, the transition_map is adapted so that it maps from a character interval to a TargetByStateKey. transition_map: interval --> TargetByStateKey instead of mapping to a target state index. ___________________________________________________________________________ """ @typed(DropOutCatcher=Processor) def __init__(self, Represented_AnalyzerState, DropOutCatcher): assert not isinstance(Represented_AnalyzerState, MegaState) state_index = Represented_AnalyzerState.index transition_map = Represented_AnalyzerState.transition_map adapted_transition_map = transition_map.relate_to_TargetByStateKeys(state_index, DropOutCatcher) ski_db = StateKeyIndexDB([state_index]) MegaState.__init__(self, state_index, adapted_transition_map, ski_db, dial_db=Represented_AnalyzerState.entry.dial_db) # Uniform Entry: In contrast to path compression, here we consider # all entries into the MegaState. self.uniform_entry_OpList = UniformObject() for action in Represented_AnalyzerState.entry.itervalues(): self.uniform_entry_OpList <<= action.command_list if self.uniform_entry_OpList.is_uniform() == False: break # No more need to investigate self.entry.absorb(Represented_AnalyzerState.entry) @property def target_scheme_n(self): return 0 def _finalize_transition_map(self, TheAnalyzer): pass # Nothing to be done def _finalize_entry_OpLists(self): pass def _finalize_content(self): pass
def __init__(self, StartState, TheTransitionMap, TransitionCharacter): if StartState is None: return # Only for Clone assert isinstance(StartState, AnalyzerState) assert isinstance(TransitionCharacter, (int, long)), "Found '%s'" % TransitionCharacter assert isinstance(TheTransitionMap, TransitionMap) # uniform_entry_OpList: # The entry into the StartState happens from outside. # => A 'state_key' is assigned (the path_iterator) # and it is not part of the iteration loop. # => The StartState's entry IS NOT subject to uniformity considerations. self.uniform_entry_OpList = UniformObject() self.__step_list = [ CharacterPathStep(StartState.index, TransitionCharacter) ] self.transition_map_data = TransitionMapData(TheTransitionMap, TransitionCharacter)
class PseudoTemplateState(MegaState): """________________________________________________________________________ Represents an AnalyzerState in a way to that it acts homogeneously with other MegaState-s. That is, the transition_map is adapted so that it maps from a character interval to a TargetByStateKey. transition_map: interval --> TargetByStateKey instead of mapping to a target state index. ___________________________________________________________________________ """ @typed(DropOutCatcher=Processor) def __init__(self, Represented_AnalyzerState, DropOutCatcher): assert not isinstance(Represented_AnalyzerState, MegaState) state_index = Represented_AnalyzerState.index transition_map = Represented_AnalyzerState.transition_map adapted_transition_map = transition_map.relate_to_TargetByStateKeys(state_index, DropOutCatcher) ski_db = StateKeyIndexDB([state_index]) MegaState.__init__(self, state_index, adapted_transition_map, ski_db) # Uniform Entry: In contrast to path compression, here we consider # all entries into the MegaState. self.uniform_entry_OpList = UniformObject() for action in Represented_AnalyzerState.entry.itervalues(): self.uniform_entry_OpList <<= action.command_list if self.uniform_entry_OpList.is_uniform() == False: break # No more need to investigate self.entry.absorb(Represented_AnalyzerState.entry) @property def target_scheme_n(self): return 0 def _finalize_transition_map(self, TheAnalyzer): pass # Nothing to be done def _finalize_entry_OpLists(self): pass def _finalize_content(self): pass
def __init__(self, Candidate): StateA = Candidate.state_a StateB = Candidate.state_b # Combined DropOut and Entry schemes are generated by the same function transition_map, target_scheme_n = combine_maps(StateA.transition_map, StateB.transition_map) ski_db = StateKeyIndexDB(StateA.state_index_sequence() + StateB.state_index_sequence()) MegaState.__init__(self, index.get(), transition_map, ski_db) self.uniform_entry_OpList = UniformObject.from_iterable(( StateA.uniform_entry_OpList, StateB.uniform_entry_OpList)) self.__target_scheme_n = target_scheme_n self.__engine_type = None # StateA.engine_type MegaState.bad_company_set(self, StateA.bad_company().union(StateB.bad_company()))
def __init__(self, Candidate): StateA = Candidate.state_a StateB = Candidate.state_b # Combined DropOut and Entry schemes are generated by the same function transition_map, target_scheme_n = combine_maps(StateA.transition_map, StateB.transition_map) ski_db = StateKeyIndexDB(StateA.state_index_sequence() + StateB.state_index_sequence()) MegaState.__init__(self, index.get(), transition_map, ski_db, dial_db=StateA.entry.dial_db) self.uniform_entry_OpList = UniformObject.from_iterable(( StateA.uniform_entry_OpList, StateB.uniform_entry_OpList)) self.__target_scheme_n = target_scheme_n self.__engine_type = None # StateA.engine_type MegaState.bad_company_set(self, StateA.bad_company().union(StateB.bad_company()))
def __init__(self, Represented_AnalyzerState, DropOutCatcher): assert not isinstance(Represented_AnalyzerState, MegaState) state_index = Represented_AnalyzerState.index transition_map = Represented_AnalyzerState.transition_map adapted_transition_map = transition_map.relate_to_TargetByStateKeys(state_index, DropOutCatcher) ski_db = StateKeyIndexDB([state_index]) MegaState.__init__(self, state_index, adapted_transition_map, ski_db) # Uniform Entry: In contrast to path compression, here we consider # all entries into the MegaState. self.uniform_entry_OpList = UniformObject() for action in Represented_AnalyzerState.entry.itervalues(): self.uniform_entry_OpList <<= action.command_list if self.uniform_entry_OpList.is_uniform() == False: break # No more need to investigate self.entry.absorb(Represented_AnalyzerState.entry)
def _interfere_input_position_storage(cls, snapshot_set_db, EntryRecipeDb, RequiredVariableSet, StateIndex): """Each position register is considered separately. If for one register the offset differs, then it can only be determined from storing it in this mouth state and restoring it later. """ assert none_is_None( flatten_it_list_of_lists(recipe.ip_offset_db.itervalues() for recipe in EntryRecipeDb.itervalues())) ip_offset_db = {} for variable_id in RequiredVariableSet: if type(variable_id) != tuple: continue register_id = variable_id[1] # Irrelevant position register? Possible! A recipe that considers # a position register irrelevant is 'equal' to any other. Thus, it # can be filtered out. Irrelevant position register is not mentioned # in 'ip_offset_db' => 'offset = None'. offset_list = [ recipe.ip_offset_db.get(register_id) for recipe in EntryRecipeDb.itervalues() ] offset = UniformObject.from_iterable( x for x in offset_list if x is not None).plain_content() if offset != E_Values.VOID: # Homogeneity pass else: # Inhomogeneity offset = E_Values.RESTORE snapshot_set_db[variable_id] = set([StateIndex]) ip_offset_db[register_id] = offset assert none_is_None(ip_offset_db.itervalues()) return ip_offset_db
def _interfere_read_position_storage(cls, snapshot_set_db, EntryRecipeDb, RequiredVariableSet, StateIndex): """Each position register is considered separately. If for one register the offset differs, then it can only be determined from storing it in this mouth state and restoring it later. """ assert none_is_None( flatten_it_list_of_lists(recipe.ip_offset_db.itervalues() for recipe in EntryRecipeDb.itervalues())) ip_offset_db = {} for variable_id in RequiredVariableSet: if type(variable_id) != tuple: continue register_id = variable_id[1] # Irrelevant position register? Possible! A recipe that considers # a position register irrelevant is 'equal' to any other. Thus, it # can be filtered out. Irrelevant position register is not mentioned # in 'ip_offset_db' => 'offset = None'. offset_list = [ recipe.ip_offset_db.get(register_id) for recipe in EntryRecipeDb.itervalues() ] offset = UniformObject.from_iterable( x for x in offset_list if x is not None).plain_content() if offset != E_Values.VOID: # Homogeneity pass else: # Inhomogeneity offset = E_Values.RESTORE snapshot_set_db[variable_id] = set([StateIndex]) ip_offset_db[register_id] = offset assert none_is_None(ip_offset_db.itervalues()) return ip_offset_db
def from_2_TargetByStateKeys(A, B, scheme_pair_db): """Generates a TargetByStateKey as a combination of two TargetByStateKey-s 'A' and 'B'. The generation may rely on a 'scheme_pair_db' which: (1) Helps to avoid double generation of TargetByStateKey-s for the same combination. (2) Lets determine the number of different schemes in the transition map, later. """ result = TargetByStateKey() if scheme_pair_db is not None: key = (A.__scheme, B.__scheme) scheme = scheme_pair_db.get(key) if scheme is None: scheme = A.__scheme + B.__scheme scheme_pair_db[key] = scheme else: scheme = A.__scheme + B.__scheme result.__scheme = scheme result.__scheme_id = None # This is done later result.__uniform_door_id = UniformObject.from_2( A.__uniform_door_id, B.__uniform_door_id).content assert isinstance(result.__uniform_door_id, (types.NoneType, DoorID)) return result
def from_2_TargetByStateKeys(A, B, scheme_pair_db): """Generates a TargetByStateKey as a combination of two TargetByStateKey-s 'A' and 'B'. The generation may rely on a 'scheme_pair_db' which: (1) Helps to avoid double generation of TargetByStateKey-s for the same combination. (2) Lets determine the number of different schemes in the transition map, later. """ result = TargetByStateKey() if scheme_pair_db is not None: key = (A.__scheme, B.__scheme) scheme = scheme_pair_db.get(key) if scheme is None: scheme = A.__scheme + B.__scheme scheme_pair_db[key] = scheme else: scheme = A.__scheme + B.__scheme result.__scheme = scheme result.__scheme_id = None # This is done later result.__uniform_door_id = UniformObject.from_2(A.__uniform_door_id, B.__uniform_door_id).content assert isinstance(result.__uniform_door_id, (types.NoneType, DoorID)) return result
class CharacterPath(object): """________________________________________________________________________ Represents identified path in the state machine such as: ( 1 )--- 'a' -->( 2 )--- 'b' -->( 3 )--- 'c' -->( 4 )--- 'd' -->( 5 ) where the remaining transitions in each state match (except for the last). During analysis, the CharacterPath acts as a container which also stores information about the transition_map. The TransitionMapData object maintains information about possible transition_map matches with other states. ___________________________________________________________________________ MEMBERS: .step_list: (list of CharacterPathStep-s) .------------------. .------------------. .--------------------. |.state_index = 1 | |.state_index = 2 | |.state_index = 4711 | |.trigger = 'a'| |.trigger = 'b'| . . . |.trigger = None | '------------------' '------------------' '--------------------' The last element of the '__step_list' contains the terminal. The terminal state is not implemented by the path walker. It is the first state entered after the path walker has finished. Its role is further indicated by a trigger of 'None'. .uniform_entry_OpList: This object keeps track about the actions to be executed upon entry into a state on the path and upon drop-out of a state on on the path. If any of them is the same for all paths on the state it contains an object which is not 'None'. In case it is not uniform 'None' is contained. .transition_map_data maintains data about the common transition map of all states. ___________________________________________________________________________ """ __slots__ = ("__step_list", "transition_map_data", "uniform_entry_OpList") def __init__(self, StartState, TheTransitionMap, TransitionCharacter): if StartState is None: return # Only for Clone assert isinstance(StartState, AnalyzerState) assert isinstance(TransitionCharacter, (int, long)), "Found '%s'" % TransitionCharacter assert isinstance(TheTransitionMap, TransitionMap) # uniform_entry_OpList: # The entry into the StartState happens from outside. # => A 'state_key' is assigned (the path_iterator) # and it is not part of the iteration loop. # => The StartState's entry IS NOT subject to uniformity considerations. self.uniform_entry_OpList = UniformObject() self.__step_list = [ CharacterPathStep(StartState.index, TransitionCharacter) ] self.transition_map_data = TransitionMapData(TheTransitionMap, TransitionCharacter) def clone(self): result = CharacterPath(None, None, None) result.uniform_entry_OpList = self.uniform_entry_OpList.clone() result.__step_list = [ x for x in self.__step_list ] # CharacterPathStep are immutable result.transition_map_data = self.transition_map_data.clone() return result def extended_clone(self, PreviousTerminal, TransitionCharacter, TransitionMapWildCardPlug): """Append 'State' to path: -- add 'State' to the sequence of states on the path. -- absorb the 'State's' drop-out and entry actions into the path's drop-out and entry actions. If 'TransitionCharacter' is None, then the state is considered a terminal state. Terminal states are not themselves implemented inside a PathWalkerState. Thus, their entry and drop out information does not have to be absorbed. """ assert TransitionCharacter is not None assert isinstance(TransitionMapWildCardPlug, DoorID) \ or TransitionMapWildCardPlug == -1 result = self.clone() # OpList upon Entry to State # (TriggerIndex == 0, because there can only be one transition from # one state to the next on the path). prev_step = self.__step_list[-1] entry_OpList = PreviousTerminal.entry.get_command_list(PreviousTerminal.index, prev_step.state_index, TriggerId=0) assert entry_OpList is not None result.uniform_entry_OpList <<= entry_OpList result.__step_list.append(CharacterPathStep(PreviousTerminal.index, TransitionCharacter)) result.transition_map_data.plug_this(TransitionMapWildCardPlug) return result def uniformity_with_predecessor(self, State): """Check whether the entry of the last state on the path executes the same OpList as the entry to 'State'. """ # This function is supposed to be called only when uniformity is required. # If so, then the path must be in a uniform state at any time. assert self.uniform_entry_OpList.is_uniform() # Check on 'Entry' for what is done along the path. # # OpList upon Entry to State # (TriggerIndex == 0, because there can only be one transition from # one state to the next on the path). prev_step = self.__step_list[-1] command_list = State.entry.get_command_list(State.index, prev_step.state_index, TriggerId=0) assert command_list is not None if not self.uniform_entry_OpList.fit(command_list): return False return True def has_wildcard(self): return self.transition_map_data.wildcard_char is not None @property def step_list(self): return self.__step_list @property def transition_map(self): return self.transition_map_data.transition_map def finalize(self, TerminalStateIndex): self.__step_list.append(CharacterPathStep(TerminalStateIndex, None)) self.transition_map_data.finalize() def contains_state(self, StateIndex): """Is 'StateIndex' on the path(?). This includes the terminal.""" for dummy in (x for x in self.__step_list if x.state_index == StateIndex): return True return False def implemented_state_index_set(self): return set(x.state_index for x in self.__step_list[:-1]) def state_index_set_size(self): return len(self.__step_list) - 1 def state_index_set(self): assert len(self.__step_list) > 1 return set(x.state_index for x in self.__step_list[:-1]) def __repr__(self): return self.get_string() def get_string(self, NormalizeDB=None): # assert NormalizeDB is None, "Sorry, I guessed that this was no longer used." def norm(X): assert isinstance(X, (int, long)) or X is None return X if NormalizeDB is None else NormalizeDB[X] skeleton_txt = self.transition_map_data.get_string() sequence_txt = "" for x in self.__step_list[:-1]: sequence_txt += "(%i)--'%s'-->" % (x.state_index, chr(x.trigger)) sequence_txt += "[%i]" % norm(self.__step_list[-1].state_index) return "".join(["start = %i;\n" % norm(self.__step_list[0].state_index), "path = %s;\n" % sequence_txt, "skeleton = {\n%s}\n" % skeleton_txt, "wildcard = %s;\n" % repr(self.transition_map_data.wildcard_char is not None)]) def assert_consistency(self, TheAnalyzer, CompressionType): assert len(self.__step_list) >= 2 # If uniformity was required, it must have been maintained. if CompressionType == E_Compression.PATH_UNIFORM: assert self.uniform_entry_OpList.is_uniform() # If entry command list is claimed to be uniform # => then all states in path must have this particular drop-out (except for the first). if self.uniform_entry_OpList.is_uniform(): prev_state_index = self.__step_list[0].state_index for state in (TheAnalyzer.state_db[s.state_index] for s in self.__step_list[1:-1]): command_list = state.entry.get_command_list(state.index, prev_state_index, TriggerId=0) assert command_list == self.uniform_entry_OpList.content prev_state_index = state.index return
class CharacterPath(object): """________________________________________________________________________ Represents identified path in the state machine such as: ( 1 )--- 'a' -->( 2 )--- 'b' -->( 3 )--- 'c' -->( 4 )--- 'd' -->( 5 ) where the remaining transitions in each state match (except for the last). During analysis, the CharacterPath acts as a container which also stores information about the transition_map. The TransitionMapData object maintains information about possible transition_map matches with other states. ___________________________________________________________________________ MEMBERS: .step_list: (list of CharacterPathStep-s) .------------------. .------------------. .--------------------. |.state_index = 1 | |.state_index = 2 | |.state_index = 4711 | |.trigger = 'a'| |.trigger = 'b'| . . . |.trigger = None | '------------------' '------------------' '--------------------' The last element of the '__step_list' contains the terminal. The terminal state is not implemented by the path walker. It is the first state entered after the path walker has finished. Its role is further indicated by a trigger of 'None'. .uniform_entry_OpList: This object keeps track about the actions to be executed upon entry into a state on the path and upon drop-out of a state on on the path. If any of them is the same for all paths on the state it contains an object which is not 'None'. In case it is not uniform 'None' is contained. .transition_map_data maintains data about the common transition map of all states. ___________________________________________________________________________ """ __slots__ = ("__step_list", "transition_map_data", "uniform_entry_OpList") def __init__(self, StartState, TheTransitionMap, TransitionCharacter): if StartState is None: return # Only for Clone assert isinstance(StartState, FSM_State) assert isinstance(TransitionCharacter, (int, long)), "Found '%s'" % TransitionCharacter assert isinstance(TheTransitionMap, TransitionMap) # uniform_entry_OpList: # The entry into the StartState happens from outside. # => A 'state_key' is assigned (the path_iterator) # and it is not part of the iteration loop. # => The StartState's entry IS NOT subject to uniformity considerations. self.uniform_entry_OpList = UniformObject() self.__step_list = [ CharacterPathStep(StartState.index, TransitionCharacter) ] self.transition_map_data = TransitionMapData(TheTransitionMap, TransitionCharacter) def clone(self): result = CharacterPath(None, None, None) result.uniform_entry_OpList = self.uniform_entry_OpList.clone() result.__step_list = [ x for x in self.__step_list ] # CharacterPathStep are immutable result.transition_map_data = self.transition_map_data.clone() return result def extended_clone(self, PreviousTerminal, TransitionCharacter, TransitionMapWildCardPlug): """Append 'State' to path: -- add 'State' to the sequence of states on the path. -- absorb the 'State's' drop-out and entry actions into the path's drop-out and entry actions. If 'TransitionCharacter' is None, then the state is considered a terminal state. Terminal states are not themselves implemented inside a PathWalkerState. Thus, their entry and drop out information does not have to be absorbed. """ assert TransitionCharacter is not None assert isinstance(TransitionMapWildCardPlug, DoorID) \ or TransitionMapWildCardPlug == -1 result = self.clone() # OpList upon Entry to State # (TriggerIndex == 0, because there can only be one transition from # one state to the next on the path). prev_step = self.__step_list[-1] entry_OpList = PreviousTerminal.entry.get_command_list(PreviousTerminal.index, prev_step.state_index, TriggerId=0) assert entry_OpList is not None result.uniform_entry_OpList <<= entry_OpList result.__step_list.append(CharacterPathStep(PreviousTerminal.index, TransitionCharacter)) result.transition_map_data.plug_this(TransitionMapWildCardPlug) return result def uniformity_with_predecessor(self, State): """Check whether the entry of the last state on the path executes the same OpList as the entry to 'State'. """ # This function is supposed to be called only when uniformity is required. # If so, then the path must be in a uniform state at any time. assert self.uniform_entry_OpList.is_uniform() # Check on 'Entry' for what is done along the path. # # OpList upon Entry to State # (TriggerIndex == 0, because there can only be one transition from # one state to the next on the path). prev_step = self.__step_list[-1] command_list = State.entry.get_command_list(State.index, prev_step.state_index, TriggerId=0) assert command_list is not None if not self.uniform_entry_OpList.fit(command_list): return False return True def has_wildcard(self): return self.transition_map_data.wildcard_char is not None @property def step_list(self): return self.__step_list @property def transition_map(self): return self.transition_map_data.transition_map def finalize(self, TerminalStateIndex): self.__step_list.append(CharacterPathStep(TerminalStateIndex, None)) self.transition_map_data.finalize() def contains_state(self, StateIndex): """Is 'StateIndex' on the path(?). This includes the terminal.""" for dummy in (x for x in self.__step_list if x.state_index == StateIndex): return True return False def implemented_state_index_set(self): return set(x.state_index for x in self.__step_list[:-1]) def state_index_set_size(self): return len(self.__step_list) - 1 def state_index_set(self): assert len(self.__step_list) > 1 return set(x.state_index for x in self.__step_list[:-1]) def __repr__(self): return self.get_string() def get_string(self, NormalizeDB=None): # assert NormalizeDB is None, "Sorry, I guessed that this was no longer used." def norm(X): assert isinstance(X, (int, long)) or X is None return X if NormalizeDB is None else NormalizeDB[X] skeleton_txt = self.transition_map_data.get_string() sequence_txt = "" for x in self.__step_list[:-1]: sequence_txt += "(%i)--'%s'-->" % (x.state_index, chr(x.trigger)) sequence_txt += "[%i]" % norm(self.__step_list[-1].state_index) return "".join(["start = %i;\n" % norm(self.__step_list[0].state_index), "path = %s;\n" % sequence_txt, "skeleton = {\n%s}\n" % skeleton_txt, "wildcard = %s;\n" % repr(self.transition_map_data.wildcard_char is not None)]) def assert_consistency(self, TheAnalyzer, CompressionType): assert len(self.__step_list) >= 2 # If uniformity was required, it must have been maintained. if CompressionType == E_Compression.PATH_UNIFORM: assert self.uniform_entry_OpList.is_uniform() # If entry command list is claimed to be uniform # => then all states in path must have this particular drop-out (except for the first). if self.uniform_entry_OpList.is_uniform(): prev_state_index = self.__step_list[0].state_index for state in (TheAnalyzer.state_db[s.state_index] for s in self.__step_list[1:-1]): command_list = state.entry.get_command_list(state.index, prev_state_index, TriggerId=0) assert command_list == self.uniform_entry_OpList.content prev_state_index = state.index return