def handleNormalState(self, node: ET.Element) -> None: self.states.append(node.attrib['id']) for each in node: if each.tag == 'transition': # case: regular state transition if 'target' in each.attrib: ed: Edge = Edge() ed.start = node.attrib['id'] ed.target = each.attrib['target'] if 'event' in each.attrib: ed.add_event(reduTransEvnt(each.attrib['event']), '') ed.color = self.detEdgeColor(each.attrib['event']) else: print('Warning: State ' + node.attrib['id'] + ' lacks a event in a transition. Sad.') if 'cond' in each.attrib: ed.events[-1] = ed.events[-1][0], each.attrib['cond'] self.internalEdges.append(ed) # case: send event transition else: for every in each: if every.tag == 'send': ed: Edge = Edge() ed.start = node.attrib['id'] ed.add_event(every.attrib['event'], '') if 'cond' in each.attrib: ed.events[-1] = ed.events[-1][0], each.attrib[ 'cond'] self.outGoingEdges.append(ed) elif each.tag == 'send': # dead code? ed: Edge = Edge() ed.start = node.attrib['id'] ed.add_event(each.attrib['event'], '') self.outGoingEdges.append(ed)
def handleSource(self, node : ET.Element) -> None: path : str = node.attrib['src'] sourcedTree : ET.Element = readGraph(path) events : list(str) = getSendEvents(sourcedTree) eventsCatched : list(str)= [] self.graph.node(node.attrib['id'], style='filled', shape='doublecircle') for propTrans in node: if propTrans.tag == 'transition': if 'target' in propTrans.attrib: ed = Edge() ed.start = node.attrib['id'] ed.target = propTrans.attrib['target'] ed.label = reduTransEvnt(propTrans.attrib['event']) eventsCatched.append(ed.label) ed.color = 'blue' self.internalEdges.append(ed) else: for send_evnt in propTrans: ed = Edge() ed.start = node.attrib['id'] ed.label = send_evnt.attrib['event'] eventsCatched.append(ed.label) self.outGoingEdges.append(ed) if not set(events) == set(eventsCatched): print('Warning: Events catched and events thrown of sourced statemachine in state ' + node.attrib['id'] + ' do not match!')
def handleParallel(self, node : ET.Element) -> None: parallelmaschine : Statemachine = Statemachine(node, 'cluster_' + node.attrib['id']) parallelmaschine.graph.body.append('style=""') parallelmaschine.graph.body.append('color="black"') parallelmaschine.graph.body.append('label="' + node.attrib['id'] + '"') self.parallelStates.append(parallelmaschine) parallelmaschine.graph.node(node.attrib['id'], shape='triangle') parallelmaschine.iterateThroughNodes() for state in parallelmaschine.states: triangleEdge : Edge = Edge(start=node.attrib['id'], target=state) parallelmaschine.internalEdges.append(triangleEdge) for potential_transition in node: if potential_transition.tag.endswith('transition'): starting_node : str = '' for state in parallelmaschine.states: if state.endswith(potential_transition.attrib['event'].split('.')[0]): starting_node = state outgoing_edge : Edge = Edge(start=starting_node) # Find way to reconstruct state name if 'target' in potential_transition.attrib: outgoing_edge.target = potential_transition.attribs['target'] self.internalEdges.append(outgoing_edge) else: for potential_send in potential_transition: if potential_send.tag == 'send': outgoing_edge.cond = reduTransEvnt(potential_transition.attrib['event']) self.outGoingEdges.append(outgoing_edge) break
def handleParallel(self, node: ET.Element) -> None: parallelmaschine: Statemachine = Statemachine( node, 'cluster_' + node.attrib['id']) parallelmaschine.graph.body.append('style=""') parallelmaschine.graph.body.append('color="black"') parallelmaschine.graph.body.append('label="' + node.attrib['id'] + '"') self.parallelStates.append(parallelmaschine) parallelmaschine.graph.node(node.attrib['id'], shape='triangle') parallelmaschine.iterateThroughNodes() for state in parallelmaschine.states: triangleEdge: Edge = Edge(start=node.attrib['id'], target=state) parallelmaschine.internalEdges.append(triangleEdge) for machine in parallelmaschine.parallelStates: triangleEdge: Edge = Edge(start=node.attrib['id'], target=machine.graphname.replace( 'cluster_', '')) parallelmaschine.internalEdges.append(triangleEdge) for machine in parallelmaschine.compoundStates: triangleEdge: Edge = Edge(start=node.attrib['id'], target=resolve_initial(machine)) parallelmaschine.internalEdges.append(triangleEdge) for potential_transition in node: if potential_transition.tag.endswith('transition'): event_full: str = potential_transition.attrib['event'] statename: str = event_full.split('.')[0] event_less: str = event_full.split('.')[1:] outgoing_edge: Edge = Edge( ) # Find way to reconstruct state name for state in parallelmaschine.states: if state.endswith(statename): outgoing_edge.start = state outgoing_edge.add_event('.'.join(event_less), '') for machine in parallelmaschine.parallelStates: if machine.graphname.endswith(statename): outgoing_edge.start = machine.graphname.replace( 'cluster_', '') outgoing_edge.add_event('.'.join(event_less), '') for machine in parallelmaschine.compoundStates: for encapsulated_state in get_all_states(machine): if encapsulated_state.endswith(statename): outgoing_edge.start = encapsulated_state outgoing_edge.add_event('.'.join(event_less), '') if 'target' in potential_transition.attrib: outgoing_edge.target = potential_transition.attrib[ 'target'] self.internalEdges.append(outgoing_edge) else: for potential_send in potential_transition: if potential_send.tag == 'send': outgoing_edge.add_event( reduTransEvnt( potential_transition.attrib['event']), '') self.outGoingEdges.append(outgoing_edge) break if 'cond' in potential_transition.attrib: outgoing_edge.events[-1] = outgoing_edge.events[-1][ 0], potential_transition.attrib['cond'] parallelmaschine.redirectNonInternalEdges() self.internalEdges.extend(parallelmaschine.outGoingEdges)
def test_between_graphs_edges(): b0 = Wire("b0") b1 = Wire("b1") b2 = Wire("b2") b3 = Wire("b3") v0 = Node("v0", 0.0, "X", 3) v1 = Node("v1", 0.0, "X", 3) v2 = Node("v2", 0.0, arity=3) v3 = Node("v3", 0.0, arity=3) e0 = Edge("e0", v0, v3) e1 = Edge("e1", v1, v2) e2 = Edge("e2", v2, v0) e3 = Edge("e3", v1, v3) e4 = Edge("e4", v0, b1) e5 = Edge("e5", v2, b0) e7 = Edge("e7", v1, b2) e8 = Edge("e8", v3, b3) inputs = [b1, b2] outputs = [b0, b3] nodes = [v3, v1, v0, v2] edges = [e3, e5, e0, e4, e2, e8, e1, e7] graph = Graph(nodes, edges, inputs, outputs) g1 = Graph([v0], [e4], [b1]) g2 = Graph([v3, v1, v2], [e2, e0, e1, e3, e7, e8, e5], [b2], [b0, b3]) result = qf.between_graphs_edges(g1, g2, graph) expected_result = [e2, e0] assert set(result) - set(expected_result) == set()
def test_split_and_reunite(): b0 = Wire("b0") b1 = Wire("b1") b2 = Wire("b2") b3 = Wire("b3") v0 = Node("v0", 0.0, "X", 3) v1 = Node("v1", 0.0, "X", 3) v2 = Node("v2", 0.0, arity=3) v3 = Node("v3", 0.0, arity=3) e0 = Edge("e0", v0, v3) e1 = Edge("e1", v1, v2) e2 = Edge("e2", v2, v0) e3 = Edge("e3", v1, v3) e4 = Edge("e4", v0, b1) e5 = Edge("e5", v2, b0) e7 = Edge("e7", v1, b2) e8 = Edge("e8", v3, b3) inputs = [b1, b2] outputs = [b0, b3] nodes = [v3, v1, v0, v2] edges = [e3, e5, e0, e4, e2, e8, e1, e7] graph = Graph(nodes, edges, inputs, outputs) m1 = [[32, 0, 0, 0], [0, 0, 0, 32], [0, 0, 0, 32], [32, 0, 0, 0]] m2 = np.zeros((4, 4)) m3 = np.zeros((4, 4)) m4 = np.zeros((4, 4)) expected_result = Pi4Matrix(m1, m2, m3, m4, 6) assert not (qf.split_and_reunite(graph) - expected_result).any()
def test_wires_to_connection_point_edge_sorted(): b0 = Wire("b0") b1 = Wire("b1") b2 = Wire("b2") b3 = Wire("b3") e2 = Edge("e2", b3, b1) e1 = Edge("e1", b0, b2) wires = [b0, b1] edges1 = [e2] edges2 = [e1] result = qf.wires_to_connection_point_edge_sorted(wires, edges1, edges2, False) c0 = ConnectionPoint(is_matrix_2=True, is_out=False) c1 = ConnectionPoint(index=1, is_matrix_2=False, is_out=False) expected_result = [c0, c1] assert result == expected_result
def test_matrix_linker(): v0 = Node("v0", arity=2, node_type="hadamard") v3 = Node("v3", arity=2, node_type="hadamard") v5 = Node("v5", angle=1.0, arity=3, node_type="X") we5 = Wire("e5") we6 = Wire("e6") e5 = Edge("e5", v5, v0) e6 = Edge("e6", v0, v3) graph1 = Graph([v0], [e5, e6], [we5], [we6]) we8 = Wire("e8") v8 = Node("v8", 0.5, arity=4) e8 = Edge("e8", v8, v3) graph2 = Graph([v3], [e8, e6], [we8, we6], []) result = qf.matrix_linker(graph1, graph2) p1 = ConnectionPoint(False, True) p2 = ConnectionPoint(True, False, 1) expected_result = [InterMatrixLink(p1, p2)] assert result == expected_result
def dictionary_to_data(wire_vertices_dictionary: dict, node_vertices_dictionary: dict, undir_edges_dictionary: dict) -> (List[Wire], List[Node], List[Edge]): """dictionary_to_data(wire_vertices_dictionary: dict, node_vertices_dictionary: dict, undir_edges_dictionary: dict) -> List[Wire], List[Node], List[Edge] Converts the three dictionaries (wires, nodes and edges) to lists of classes defined in :ref:`data` Args: wire_vertices_dictionary (dict): dictionary containing the data about the wires node_vertices_dictionary (dict): dictionary containing the data about the nodes undir_edges_dictionary (dict): dictionary containing the data about the edges Returns: List[Wire], List[Node], List[Edge]: lists of wires, nodes and edges """ wires = [] # type: List[Wire] for wire_name in wire_vertices_dictionary: wires.append(Wire(wire_name)) nodes = [] # type: List[Node] for node_name in node_vertices_dictionary: angle = 0. node_type = 'Z' if 'data' in node_vertices_dictionary[node_name]: node_type = node_vertices_dictionary[node_name]['data']['type'] angle = node_vertices_dictionary[node_name]['data']['value'] if angle == '': angle = 0. else: angle = angle.replace('\\pi', '1') angle = angle.replace('pi', '1') angle = angle.replace('Pi', '1') angle = float(eval(angle)) nodes.append(Node(node_name, angle, node_type)) edges = [] # type: List[Edge] for edge_name in undir_edges_dictionary: label = "" if 'data' in undir_edges_dictionary[edge_name]: label = undir_edges_dictionary[edge_name]['data']['label'] n1 = None n2 = None for node in nodes: if node.name == undir_edges_dictionary[edge_name]['src']: node.arity += 1 n1 = node if node.name == undir_edges_dictionary[edge_name]['tgt']: node.arity += 1 n2 = node for wire in wires: if wire.name == undir_edges_dictionary[edge_name]['src']: n1 = wire if wire.name == undir_edges_dictionary[edge_name]['tgt']: n2 = wire edges.append(Edge(edge_name, n1, n2, label)) return wires, nodes, edges
def createEdge(self, start_node: Node, end_node: Node): index = len(self.edges_matrix[start_node.id][end_node.id]) edge = Edge(id=composite_id(start_node.id, end_node.id, index), start_node=start_node, end_node=end_node, length=self.edgePrompt.length, speed=self.edgePrompt.speed) self.edgePrompt = None self.addEdge(edge)
def deserialize_edge(self, edge: dict) -> Edge: id_ = self._get_or_raise(edge, 'Edge', 'id') start_node_id = self._get_or_raise(edge, 'Edge', 'start_node') end_node_id = self._get_or_raise(edge, 'Edge', 'end_node') length = self._get_or_raise(edge, 'Edge', 'length') speed = self._get_or_raise(edge, 'Edge', 'speed') start_node = self.data.nodes[start_node_id] end_node = self.data.nodes[end_node_id] offset = edge.get('offset') return Edge(id_, start_node, end_node, length, speed, offset=offset)
def test_wires_to_connection_point_node_sorted(): we5 = Wire("e5") we8 = Wire("e8") v5 = Node("v5") v8 = Node("v8") v0 = Node("v0", node_type='hadamard', arity=2) v3 = Node("v3", node_type='hadamard', arity=2) e5 = Edge("e5", v5, v0) e6 = Edge("e6", v0, v3) e8 = Edge("e8", v8, v3) wires = [we5, we8] edges = [e8, e6, e5] nodes1 = [v0] nodes2 = [v3] result = qf.wires_to_connection_point_node_sorted(wires, edges, nodes1, nodes2, False) c0 = ConnectionPoint(is_matrix_2=False, is_out=False) c1 = ConnectionPoint(is_matrix_2=True, is_out=False) expected_result = [c0, c1] assert result == expected_result
def test_no_node_matrix(): # # b4 b0 b5 # \ | / # --|- # | # b2 # b0 = Wire("b0") b2 = Wire("b2") b4 = Wire("b4") b5 = Wire("b5") e0 = Edge("e0", b4, b5) e1 = Edge("e1", b0, b2) edges = [e0, e1] inputs = [b4, b0, b5] outputs = [b2] result = qf.no_node_matrix(edges, inputs, outputs) expected_result = Pi4Matrix([[1, 0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1]]) assert not (result - expected_result).any()
def test_filter_inputs_outputs_by_edges(): b0 = Wire("b0") b1 = Wire("b1") b2 = Wire("b2") b3 = Wire("b3") b4 = Wire("b4") b5 = Wire("b5") e1 = Edge("e1", b0, b2) edges = [e1] inputs = [b4, b0, b5, b1] outputs = [b3, b2] result = qf.filter_inputs_outputs_by_edges(edges, inputs, outputs) expected_result = [b0], [b2] assert result == expected_result
def handleSource(self, node: ET.Element) -> None: path: str = node.attrib['src'] sourcedTree: ET.Element = readGraph(path) events: list(str) = getSendEvents(sourcedTree) eventsCatched: list(str) = [] self.graph.node(node.attrib['id'], style='filled', shape='doubleoctagon') self.states.append(node.attrib['id']) for propTrans in node: if propTrans.tag == 'transition': ed: Edge = Edge() ed.start = node.attrib['id'] cond = '' if 'cond' in propTrans.attrib: cond = propTrans.attrib['cond'] if 'target' in propTrans.attrib: ed.target = propTrans.attrib['target'] event: str = reduTransEvnt(propTrans.attrib['event']) ed.add_event(event, cond) eventsCatched.append(event) ed.color = 'blue' self.internalEdges.append(ed) else: for send_evnt in propTrans: if not send_evnt.tag == 'send': continue event: str = send_evnt.attrib['event'] ed.add_event(event, cond) eventsCatched.append(event) self.outGoingEdges.append(ed) break debug_print('attribs for source transitions (' + node.attrib['id'] + '): ' + str(propTrans.attrib)) eventsNotInCatchedEvents: List[str] = [ event for event in events if event not in eventsCatched and '*' not in eventsCatched ] if len(eventsNotInCatchedEvents) > 0: print( 'Warning: Events catched and events thrown of sourced statemachine in state ' + node.attrib['id'] + ' do not match!\n' + str(set(eventsNotInCatchedEvents)) + ' (not in catched events)\n' + str(set(events)) + ' (send events) VS \n' + str(set(eventsCatched)) + ' (catched events)')
def addEdge(self, edge: Edge): """Will add an Edge to this Graph. Args: edge: The Edge which will be added. Returns: Nothing. But will modify the graph of this statemachine. """ labelevent: str = edge.get_label() self.graph.edge(edge.start, edge.target, color=edge.color, label=labelevent, fontcolor=edge.fontcolor)
def test_no_node_edges_detection_true(): assert qf.no_node_edges_detection([Edge("e0", Wire("b0"), Wire("b1"))])
'N87': Node(350, 400), 'N88': Node(400, 400), 'N89': Node(450, 400), 'N91': Node(50, 450), 'N92': Node(100, 450), 'N93': Node(150, 450), 'N94': Node(200, 450), 'N95': Node(250, 450), 'N96': Node(300, 450), 'N97': Node(350, 450), 'N98': Node(400, 450), 'N99': Node(450, 450), } EDGES: List[Edge] = [ Edge(NODES['N11'], NODES['N12']), Edge(NODES['N12'], NODES['N13']), Edge(NODES['N13'], NODES['N14']), Edge(NODES['N14'], NODES['N15']), Edge(NODES['N15'], NODES['N16']), Edge(NODES['N16'], NODES['N17']), Edge(NODES['N17'], NODES['N18']), Edge(NODES['N18'], NODES['N19']), Edge(NODES['N21'], NODES['N22']), Edge(NODES['N22'], NODES['N23']), Edge(NODES['N23'], NODES['N24']), Edge(NODES['N24'], NODES['N25']), Edge(NODES['N27'], NODES['N28']), Edge(NODES['N28'], NODES['N29']), Edge(NODES['N31'], NODES['N32']), Edge(NODES['N32'], NODES['N33']),
if __name__ == '__main__': file : str = sys.argv[1] node = readGraph(file) statemachine = Statemachine(node, file) try: statemachine.iterateThroughNodes() except Exception as e: print('Got an error iterating through the nodes: ' + str(e)) print('Exact Exception: ' + str(traceback.format_exc())) sys.exit(0) # Stuff for top level statemachine.graph.body.append('fontsize=20') statemachine.graph.node('Start', shape='Mdiamond') statemachine.graph.node('Finish', shape='Msquare') startingEdge : Edge = Edge(start='Start') initial : str = statemachine.rootnode.attrib['initial'] currentStatemachine : Statemachine = statemachine while initial in [x.rootnode.attrib['id'] for x in currentStatemachine.compoundStates]: for x in currentStatemachine.compoundStates: if x.rootnode.attrib['id'] == initial: initial = x.rootnode.attrib['initial'] currentStatemachine = x startingEdge.target = currentStatemachine.rootnode.attrib['initial'] statemachine.addEdge(startingEdge) trailingEdge : Edge = Edge(target='Finish') for node in statemachine.rootnode: if 'final' in node.attrib: trailingEdge.start = node.attrib['id'] if trailingEdge.start:
def test_graph_subtraction(): # a b c # | | | # n0 n1 n2 # |\/|\/| # |/\|/\| # n3 n4 n5 # | | | # d e f a, b, c, d, e, f = Wire('a'), Wire('b'), Wire('c'), Wire('d'), Wire( 'e'), Wire('f') n0, n1, n2, n3, n4, n5 = Node('0'), Node('1'), Node('2'), Node('3'), Node( '4'), Node('5') e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 = \ Edge('0', a, n0), Edge('1', b, n1), Edge('2', c, n2), \ Edge('3', n0, n3), Edge('4', n0, n4), \ Edge('5', n1, n3), Edge('6', n1, n4), Edge('7', n1, n5), \ Edge('8', n2, n4), Edge('9', n2, n5), \ Edge('10', d, n3), Edge('11', e, n4), Edge('12', f, n5) inputs = [a, b, c] outputs = [d, e, f] nodes = [n0, n1, n2, n3, n4, n5] edges = [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12] graph = Graph(nodes, edges, inputs, outputs) inputs_graph = Graph(inputs=inputs) assert graph - inputs_graph == Graph(nodes, edges, [], outputs)
def test_graph_augmentation(): # a b c # | | | # n0 n1 n2 # |\/|\/| # |/\|/\| # n3 n4 n5 # | | | # d e f a, b, c, d, e, f = Wire('a'), Wire('b'), Wire('c'), Wire('d'), Wire( 'e'), Wire('f') n0, n1, n2, n3, n4, n5 = Node('0'), Node('1'), Node('2'), Node('3'), Node( '4'), Node('5') e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13 = \ Edge('0', a, n0), Edge('1', b, n1), Edge('2', c, n2), \ Edge('3', n0, n3), Edge('4', n0, n4), \ Edge('5', n1, n3), Edge('6', n1, n4), Edge('7', n1, n5), \ Edge('8', n2, n4), Edge('9', n2, n5), \ Edge('10', d, n3), Edge('11', e, n4), Edge('12', f, n5), \ Edge('13', n0, n0) inputs = [a, b, c] outputs = [d, e, f] nodes = [n0, n1, n2, n3, n4, n5] edges = [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13] graph = Graph(nodes, edges, inputs, outputs) inputs_graph = Graph(inputs=inputs, nodes=[n0], edges=[e0, e13]) inputs_graph.augment(graph) expected_result = Graph([n0, n1, n2, n3, n4], [e0, e1, e2, e3, e4, e5, e6, e8, e13], inputs, []) assert inputs_graph == expected_result
def test_connected_graphs_split(): # a b c # | | | # n0 n1 n2 g # |\/|\/| | # |/\|/\| h # n3 n4 n5 # | | | # d e f # # problem if an edge has the same name as a node a, b, c, d, e, f = Wire('a'), Wire('b'), Wire('c'), Wire('d'), Wire( 'e'), Wire('f') g, h = Wire('g'), Wire('h') n0, n1, n2, n3, n4, n5 = Node('n0'), Node('n1'), Node('n2'), Node( 'n3'), Node('n4'), Node('n5') e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13 = \ Edge('e0', a, n0), Edge('e1', b, n1), Edge('e2', c, n2), \ Edge('e3', n0, n3), Edge('e4', n0, n4), \ Edge('e5', n1, n3), Edge('e6', n1, n4), Edge('e7', n1, n5), \ Edge('e8', n2, n4), Edge('e9', n2, n5), \ Edge('e10', d, n3), Edge('e11', e, n4), Edge('e12', f, n5), \ Edge('e13', n0, n0) e14 = Edge('e14', g, h) inputs = [a, b, c, g] outputs = [d, e, f, h] nodes = [n0, n1, n2, n3, n4, n5] edges = [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14] graph = Graph(nodes, edges, inputs, outputs) small_graph = Graph(inputs=[g], outputs=[h], edges=[e14]) g1, g2 = qf.connected_graphs_split(graph) assert g1 == small_graph or g2 == small_graph
def test_no_node_edges_detection_false(): assert not qf.no_node_edges_detection([Edge("e0", Node("n0"), Wire("b1"))])