Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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