def __init__(self): # values will point to values of _*_label_def below self.state_vars = dict() self.inputs = dict() self.outputs = dict() # self.set_actions = {} # state labeling self._state_label_def = dict() self._state_dot_label_format = {'type?label': ':', 'separator': r'\\n'} # edge labeling self._transition_label_def = dict() self._transition_dot_label_format = { 'type?label': ':', 'separator': r'\\n' } self._transition_dot_mask = dict() self._state_dot_mask = dict() self.default_export_fname = 'fsm' LabeledDiGraph.__init__(self) self.dot_node_shape = {'normal': 'ellipse'} self.default_export_fname = 'fsm'
def __init__(self): # values will point to values of _*_label_def below self.state_vars = dict() self.inputs = dict() self.outputs = dict() # self.set_actions = {} # state labeling self._state_label_def = dict() self._state_dot_label_format = {'type?label': ':', 'separator': '\n'} # edge labeling self._transition_label_def = dict() self._transition_dot_label_format = {'type?label': ':', 'separator': '\n'} self._transition_dot_mask = dict() self._state_dot_mask = dict() self.default_export_fname = 'fsm' LabeledDiGraph.__init__(self) self.dot_node_shape = {'normal': 'ellipse'} self.default_export_fname = 'fsm'
def tensor_product(self, other, prod_sys=None): """Return strong product with given graph. Reference ========= http://en.wikipedia.org/wiki/Strong_product_of_graphs nx.algorithms.operators.product.strong_product """ prod_graph = nx.product.tensor_product(self, other) # not populating ? if prod_sys is None: if self.states.mutants or other.states.mutants: mutable = True else: mutable = False prod_sys = LabeledDiGraph(mutable=mutable) prod_sys = self._multiply_mutable_states(other, prod_graph, prod_sys) return prod_sys
def cartesian_product(self, other, prod_sys=None): """Return Cartesian product with given graph. If u,v are nodes in C{self} and z,w nodes in C{other}, then ((u,v), (z,w) ) is an edge in the Cartesian product of self with other if and only if: - (u == v) and (z,w) is an edge of C{other} OR - (u,v) is an edge in C{self} and (z == w) In system-theoretic terms, the Cartesian product is the interleaving where at each step, only one system/process/player makes a move/executes. So it is a type of parallel system. This is an important distinction with the C{strong_product}, because that includes "diagonal" transitions, i.e., two processes executing truly concurrently. Note that a Cartesian interleaving is different from a strong interleaving, because the latter can skip states and transition directly along the diagonal. For a model of computation, strong interleaving would accurately model the existence of multiple cores, not just multiple processes executing on a single core. References ========== - U{http://en.wikipedia.org/wiki/Cartesian_product_of_graphs} - networkx.algorithms.operators.product.cartesian_product """ prod_graph = nx.product.cartesian_product(self, other) # not populating ? if prod_sys is None: if self.states.mutants or other.states.mutants: mutable = True else: mutable = False prod_sys = LabeledDiGraph(mutable=mutable) prod_sys = self._multiply_mutable_states( other, prod_graph, prod_sys) return prod_sys