def _transition_cost_combined(StateA, StateB): """Computes the storage consumption of a transition map. """ involved_state_n = len(StateA.implemented_state_index_list()) + len(StateB.implemented_state_index_list()) TM_A = StateA.transition_map TM_B = StateB.transition_map # Count the number of unique schemes and the total interval number interval_n = 0 scheme_set = set() for begin, end, a_target, b_target in transition_map_tools.zipped_iterable(TM_A, TM_B): interval_n += 1 TargetFactory.update_scheme_set(a_target, b_target, scheme_set) scheme_n = len(scheme_set) return __transition_cost(involved_state_n, interval_n, scheme_n)
def _transition_cost_combined(StateA, StateB): """Computes the storage consumption of a transition map. """ involved_state_n = len(StateA.implemented_state_index_list()) + len( StateB.implemented_state_index_list()) TM_A = StateA.transition_map TM_B = StateB.transition_map # Count the number of unique schemes and the total interval number interval_n = 0 scheme_set = set() for begin, end, a_target, b_target in transition_map_tools.zipped_iterable( TM_A, TM_B): interval_n += 1 TargetFactory.update_scheme_set(a_target, b_target, scheme_set) scheme_n = len(scheme_set) return __transition_cost(involved_state_n, interval_n, scheme_n)
def match(self, TransitionMap, TargetDoorID, TriggerCharToTarget): """A single character transition TriggerCharToTarget --> DoorID has been detected. The question is, if the remaining transitions of the state match the skeleton of the current path. There might be a wild card, that is the character that is overlapped by the first single character transition. As long as a transition map differs only by this single character, the wild card is plugged into the position. RETURNS: int > 0, the character that the wild card shall take so that the skeleton matches the TransitionMap. - 1, if skeleton and TransitionMap match anyway and no wild card plug is necessary. None, if there is no way that the skeleton and the TransitionMap could match. """ wildcard_target = -1 for begin, end, a_target, b_target in transition_map_tools.zipped_iterable(self.__transition_map, TransitionMap): if a_target == b_target: continue # There is no problem at all size = end - begin assert size > 0 if size == 1: if b_target == TargetDoorID: continue elif a_target == E_StateIndices.VOID: wildcard_target = b_target; continue else: return None else: return None # Here: The transition maps match, but possibly require the use of a wildcard. return wildcard_target
def match(self, TransitionMap, TargetDoorID, TriggerCharToTarget): """A single character transition TriggerCharToTarget --> DoorID has been detected. The question is, if the remaining transitions of the state match the transition map of the current path. There might be a wild card, that is the character that is overlapped by the first single character transition. As long as a transition map differs only by this single character, the wild card is plugged into the position. RETURNS: int > 0, the character that the wild card shall take so that the path's transition map matches the TransitionMap. - 1, if path's transition map and TransitionMap match anyway and no wild card plug is necessary. None, if there is no way that the path's transition map and the TransitionMap could match. """ wildcard_target = -1 for begin, end, a_target, b_target in transition_map_tools.zipped_iterable(self.__transition_map, TransitionMap): if a_target == b_target: continue # There is no problem at all size = end - begin assert size > 0 if size == 1: if b_target == TargetDoorID: continue elif a_target == E_StateIndices.VOID: wildcard_target = b_target; continue else: return None else: return None # Here: The transition maps match, but possibly require the use of a wildcard. return wildcard_target
def combine_maps(StateA, StateB): """RETURNS: -- Transition map = combined transition map of StateA and StateB. -- List of target schemes that have been identified. NOTE: If the entries of both states are uniform, then a transition to itself of both states can be implemented as a recursion of the template state without knowing the particular states. EXPLANATION: This function combines two transition maps. A transition map is a list of tuples: [ ... (interval, target) ... ] Each tuple tells about a character range [interval.begin, interval.end) where the state triggers to the given target. In a normal AnalyzerState the target is the index of the target state. In a TemplateState, though, multiple states are combined. A TemplateState operates on behalf of a state which is identified by its 'state_key'. If two states (even TemplateStates) are combined the trigger maps are observed, e.g. Trigger Map A Trigger Map B [ [ ([0, 10), DropOut) ([0, 10), State_4) ([10, 15), State_0) ([10, 15), State_1) ([15, 20), DropOut) ([15, 20), State_0) ([20, 21), State_1) ([20, 21), DropOut) ([21, 255), DropOut) ([21, 255), State_0) ] ] For some intervals, the target is the same. But for some it is different. In a TemplateState, the intervals are associated with MegaState_Target objects. A MegaState_Target object tells the target state dependent on the 'state_key'. The above example may result in a transition map as below: Trigger Map A [ # intervals: target schemes: ( [0, 10), { A: DropOut, B: State_4, }, ( [10, 15), { A: State_0, B: State_1, }, ( [15, 20), { A: DropOut, B: State_0, }, ( [20, 21), { A: State_1, B: DropOut, }, ( [21, 255), { A: DropOut, B: State_0, }, ] Note, that the 'scheme' for interval [12, 20) and [21, 255) are identical. We try to profit from it by storing only it only once. A template scheme is associated with an 'index' for reference. TemplateStates may be combined with AnalyzerStates and other TemplateStates. Thus, MegaState_Targets must be combined with trigger targets and other MegaState_Targets. NOTE: The resulting target map results from the combination of both transition maps, which may introduce new borders, e.g. |----------------| (where A triggers to X) |---------------| (where B triggers to Y) becomes |----|-----------|---| 1 2 3 where: Domain: A triggers to: B triggers to: 1 X Nothing 2 X Y 3 Nothing Y ----------------------------------------------------------------------------- Transition maps of TemplateState-s function based on 'state_keys'. Those state keys are used as indices into TemplateMegaState_Targets. The 'state_key' of a given state relates to the 'state_index' by (1) self.state_index_sequence[state_key] == state_index where 'state_index' is the number by which the state is identified inside its state machine. Correspondingly, for a given TemplateMegaState_Target T (2) T[state_key] gives the target of the template if it operates for 'state_index' determined from 'state_key' by relation (1). The state index list approach facilitates the computation of target schemes. For this reason no dictionary {state_index->target} is used. """ transition_map_tools.assert_adjacency(StateA.transition_map, TotalRangeF=True) transition_map_tools.assert_adjacency(StateB.transition_map, TotalRangeF=True) MegaState_Target.init( ) # Initialize the tracking of generated MegaState_Target-s factory = TargetFactory(StateA, StateB) result = [] for begin, end, a_target, b_target in transition_map_tools.zipped_iterable( StateA.transition_map, StateB.transition_map): target = factory.get(a_target, b_target) result.append((Interval(begin, end), target)) # Return the database of generated MegaState_Target objects mega_state_target_db = MegaState_Target.disconnect_object_db() # Number of different target schemes: scheme_n = 0 for x in (key for key in mega_state_target_db.iterkeys() if isinstance(key, tuple)): scheme_n += 1 return result, scheme_n
def combine_maps(StateA, StateB): """RETURNS: -- Transition map = combined transition map of StateA and StateB. -- List of target schemes that have been identified. NOTE: If the entries of both states are uniform, then a transition to itself of both states can be implemented as a recursion of the template state without knowing the particular states. EXPLANATION: This function combines two transition maps. A transition map is a list of tuples: [ ... (interval, target) ... ] Each tuple tells about a character range [interval.begin, interval.end) where the state triggers to the given target. In a normal AnalyzerState the target is the index of the target state. In a TemplateState, though, multiple states are combined. A TemplateState operates on behalf of a state which is identified by its 'state_key'. If two states (even TemplateStates) are combined the trigger maps are observed, e.g. Trigger Map A Trigger Map B [ [ ([0, 10), DropOut) ([0, 10), State_4) ([10, 15), State_0) ([10, 15), State_1) ([15, 20), DropOut) ([15, 20), State_0) ([20, 21), State_1) ([20, 21), DropOut) ([21, 255), DropOut) ([21, 255), State_0) ] ] For some intervals, the target is the same. But for some it is different. In a TemplateState, the intervals are associated with MegaState_Target objects. A MegaState_Target object tells the target state dependent on the 'state_key'. The above example may result in a transition map as below: Trigger Map A [ # intervals: target schemes: ( [0, 10), { A: DropOut, B: State_4, }, ( [10, 15), { A: State_0, B: State_1, }, ( [15, 20), { A: DropOut, B: State_0, }, ( [20, 21), { A: State_1, B: DropOut, }, ( [21, 255), { A: DropOut, B: State_0, }, ] Note, that the 'scheme' for interval [12, 20) and [21, 255) are identical. We try to profit from it by storing only it only once. A template scheme is associated with an 'index' for reference. TemplateStates may be combined with AnalyzerStates and other TemplateStates. Thus, MegaState_Targets must be combined with trigger targets and other MegaState_Targets. NOTE: The resulting target map results from the combination of both transition maps, which may introduce new borders, e.g. |----------------| (where A triggers to X) |---------------| (where B triggers to Y) becomes |----|-----------|---| 1 2 3 where: Domain: A triggers to: B triggers to: 1 X Nothing 2 X Y 3 Nothing Y ----------------------------------------------------------------------------- Transition maps of TemplateState-s function based on 'state_keys'. Those state keys are used as indices into TemplateMegaState_Targets. The 'state_key' of a given state relates to the 'state_index' by (1) self.state_index_sequence[state_key] == state_index where 'state_index' is the number by which the state is identified inside its state machine. Correspondingly, for a given TemplateMegaState_Target T (2) T[state_key] gives the target of the template if it operates for 'state_index' determined from 'state_key' by relation (1). The state index list approach facilitates the computation of target schemes. For this reason no dictionary {state_index->target} is used. """ transition_map_tools.assert_adjacency(StateA.transition_map, TotalRangeF=True) transition_map_tools.assert_adjacency(StateB.transition_map, TotalRangeF=True) MegaState_Target.init() # Initialize the tracking of generated MegaState_Target-s factory = TargetFactory(StateA, StateB) result = [] for begin, end, a_target, b_target in transition_map_tools.zipped_iterable(StateA.transition_map, StateB.transition_map): target = factory.get(a_target, b_target) result.append((Interval(begin, end), target)) # Return the database of generated MegaState_Target objects mega_state_target_db = MegaState_Target.disconnect_object_db() # Number of different target schemes: scheme_n = 0 for x in (key for key in mega_state_target_db.iterkeys() if isinstance(key, tuple)): scheme_n += 1 return result, scheme_n