def showMatches(l, r, g, outputFile): try: l = parseGraphString(l) r = parseGraphString(r, joinAllowed=True) g = graphIdentifiersToNumbers(parseGraphString(g)) except ParseError as pe: pe.prettyPrint() exit(1) finder = MatchFinder(g) finder.leftSide(l) finder.rightSide(r) allMatches = finder.matches() if len(allMatches) == 0: h = parseGraphString("") drawMatch(l, r, g, h, m, outputFile) for (i, m) in enumerate(allMatches[:20]): if len(allMatches) > 0: fn = outputFile.split(".") myFile = ".".join(fn[0:-1] + [str(i)] + fn[-1:]) print(myFile, m) else: myFile = outputFile h = RuleApplication(finder, m).result() drawMatch(l, r, g, h, m, myFile)
def rightConditionTest( self, matchLen, l, r, g ): l = parseGraphString( l ) r = parseGraphString( r, joinAllowed=True ) g = parseGraphString( g ) if nx.is_directed( l ) or nx.is_directed( r ) or nx.is_directed( g ): if not nx.is_directed( l ): l = l.to_directed() if not nx.is_directed( r ): r = r.to_directed() if not nx.is_directed( g ): g = g.to_directed() finder = sg.MatchFinder( g, verbose=testVerbose ) finder.leftSide( l ) finder.rightSide( r ) mList = finder.matches() if testVerbose: for m in mList: print( m ) self.assertEqual( len( mList ), matchLen ) return mList
def test_redefine_tag(self): with self.assertRaises(ParseError): parseGraphString("P[x]; Q[y]; P[z]") g = parseGraphString("P[x]; Q[y]; P") self.assertEqual(len(g.nodes), 2) g = parseGraphString("P[x]; Q[y]; P [x]") self.assertEqual(len(g.nodes), 2) self.assertEqual(g.nodes['P']['tag'], 'x')
def test_empty_graph(self): g = parseGraphString("") self.assertIsNotNone(g) self.assertEqual(len(g.nodes), 0) self.assertEqual(len(g.edges), 0) g2 = parseGraphString(";") self.assertIsNotNone(g2) self.assertEqual(len(g2.nodes), 0) self.assertEqual(len(g2.edges), 0)
def test_semicolon_optional(self): g1 = parseGraphString("X; Y; Z") g2 = parseGraphString("X; Y; Z;") self.assertIsNotNone(g1) self.assertIsNotNone(g2) self.assertTrue(nx.is_isomorphic(g1, g2)) g3 = parseGraphString("X") g4 = parseGraphString("X;") self.assertIsNotNone(g3) self.assertIsNotNone(g4) self.assertTrue(nx.is_isomorphic(g3, g4))
def test_edge_whitespace(self): g1 = parseGraphString("X--Z") self.assertIsNotNone(g1) g2 = parseGraphString("X-- Z") self.assertIsNotNone(g2) self.assertTrue(nx.is_isomorphic(g1, g2)) g3 = parseGraphString("X -- Z") self.assertIsNotNone(g3) self.assertTrue(nx.is_isomorphic(g1, g3)) g4 = parseGraphString(" X-- Z") self.assertIsNotNone(g4) self.assertTrue(nx.is_isomorphic(g1, g4)) g5 = parseGraphString("X-- Z ") self.assertIsNotNone(g5) self.assertTrue(nx.is_isomorphic(g1, g5))
def test_tag_merged_node(self): g = parseGraphString("A[x]; A^C--B^D; D[y]", joinAllowed=True) self.assertEqual(len(g.nodes), 2) # FIXME: fragile? self.assertIn('A', g.nodes) self.assertIn('B', g.nodes) self.assertEqual(g.nodes['A']['tag'], 'x') self.assertEqual(g.nodes['B']['tag'], 'y')
def test_multi_node(self): g = parseGraphString("X; Y; Z") self.assertIsNotNone(g) self.assertEqual(len(g.nodes), 3) self.assertTrue(g.has_node("X")) self.assertTrue(g.has_node("Y")) self.assertTrue(g.has_node("Z")) self.assertFalse(g.has_node(";"))
def test_single_edge(self): g = parseGraphString("X -- A") self.assertIsNotNone(g) self.assertEqual(len(g.nodes), 2) self.assertEqual(len(g.edges), 1) self.assertTrue(g.has_node("X")) self.assertTrue(g.has_node("A")) self.assertTrue(g.has_edge("X", "A"))
def showGraph(graphString, outputFile): try: g = parseGraphString(graphString, joinAllowed=True) except ParseError as pe: pe.prettyPrint() exit(1) drawSvg(g, outputFile)
def test_directed_square(self): g = parseGraphString("A->B->D; A->C->D; A[src]; D[dst]; A->D [new]", joinAllowed=True) self.assertEqual(len(g.nodes), 4) self.assertEqual(len(g.edges), 5) self.assertEqual(g.graph['rename']['A'], 'A') self.assertEqual(g.graph['rename']['B'], 'B') self.assertEqual(g.graph['rename']['C'], 'C') self.assertEqual(g.graph['rename']['D'], 'D')
def test_christmas_tree(self): g = parseGraphString("P[x]; Q[y]; P -- Q^R[z]; P--Z99[x\[\]]", joinAllowed=True) self.assertEqual(len(g.nodes), 3) self.assertEqual(len(g.edges), 2) self.assertEqual(g.nodes['P']['tag'], 'x') self.assertEqual(g.nodes['Q']['tag'], 'y') self.assertEqual(g['P']['Q']['tag'], 'z') self.assertEqual(g['P']['Z99']['tag'], 'x[]') self.assertEqual(g.graph['join'], {'R': 'Q'})
def test_tagged_nodes(self): g = parseGraphString("P [x]; Q[2] ; R; Z [a\[b\]=c d=e]") self.assertEqual(len(g.nodes), 4) self.assertIn('tag', g.nodes['P']) self.assertIn('tag', g.nodes['Q']) self.assertNotIn('tag', g.nodes['R']) self.assertIn('tag', g.nodes['Z']) self.assertEqual(g.nodes['P']['tag'], "x") self.assertEqual(g.nodes['Q']['tag'], "2") self.assertEqual(g.nodes['Z']['tag'], "a[b]=c d=e")
def test_unicode_chars(self): n1 = "😖" n2 = "꼭지점" n3 = "顶角" g = parseGraphString("--".join([n1, n2, n3])) self.assertIsNotNone(g) self.assertTrue(g.has_node(n1)) self.assertTrue(g.has_node(n2)) self.assertTrue(g.has_node(n3)) self.assertEqual(len(g.nodes), 3)
def test_long_node_names(self): n1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxzy" n2 = "node2431412xyz" n3 = "エンタープライズフラッシュストレージ&ソフトウェア" g = parseGraphString("--".join([n1, n2, n3])) self.assertIsNotNone(g) self.assertTrue(g.has_node(n1)) self.assertTrue(g.has_node(n2)) self.assertTrue(g.has_node(n3)) self.assertEqual(len(g.nodes), 3)
def test_untagged_undirected(self, edges): g = self.undirectedGraphFromEdgeList(edges) t = self.textForUndirectedGraph(g) h = sp.parseGraphString(t) gV = set(g.nodes) hV = set(h.nodes) self.assertEqual(gV, hV) gE = set((min(s, t), max(s, t)) for (s, t) in g.edges) hE = set((min(s, t), max(s, t)) for (s, t) in h.edges) self.assertEqual(gE, hE)
def test_cycle(self): g = parseGraphString("X -- A -- B -- X") self.assertIsNotNone(g) self.assertEqual(len(g.nodes), 3) self.assertEqual(len(g.edges), 3) self.assertTrue(g.has_node("X")) self.assertTrue(g.has_node("A")) self.assertTrue(g.has_node("B")) self.assertTrue(g.has_edge("X", "A")) self.assertTrue(g.has_edge("A", "B")) self.assertTrue(g.has_edge("X", "B"))
def setup_rewrite( self, l, r, g, realMatches = True ): l = parseGraphString( l ) r = parseGraphString( r, joinAllowed=True ) g = sg.graphIdentifiersToNumbers( parseGraphString( g ) ) (l, r, g) = self.make_all_directed( l, r, g ) self.before = g if verbose: print() print( "*** BEFORE ***" ) self.dump_text( g ) finder = sg.MatchFinder( g, verbose=False) #finder = sg.MatchFinder( g, verbose=True) finder.leftSide( l ) finder.rightSide( r ) self.finder = finder if realMatches: return finder.matches()
def test_bidrectional_edges(self): g = parseGraphString("A<-CENTER->B") self.assertIsNotNone(g) self.assertEqual(len(g.nodes), 3) self.assertEqual(len(g.edges), 2) self.assertTrue(g.has_node("CENTER")) self.assertTrue(g.has_node("A")) self.assertTrue(g.has_node("B")) self.assertTrue(g.has_edge("CENTER", "A")) self.assertTrue(g.has_edge("CENTER", "B")) self.assertFalse(g.has_edge("B", "CENTER")) self.assertFalse(g.has_edge("A", "CENTER"))
def test_tag_many_merged_nodes(self): g = parseGraphString("A^B; B^C; C^D[y]; E^F; F^C; G^B; G[y]", joinAllowed=True) self.assertEqual(len(g.nodes), 1) n0 = list(g.nodes)[0] self.assertEqual(g.nodes[n0]['tag'], 'y') self.assertEqual(g.graph['rename']['A'], n0) self.assertEqual(g.graph['rename']['B'], n0) self.assertEqual(g.graph['rename']['C'], n0) self.assertEqual(g.graph['rename']['D'], n0) self.assertEqual(g.graph['rename']['E'], n0) self.assertEqual(g.graph['rename']['F'], n0) self.assertEqual(g.graph['rename']['G'], n0)
def test_merge_unequal_tgs(self): with self.assertRaises(ParseError): parseGraphString("A[x]; B[y]; B^A -- C") with self.assertRaises(ParseError): parseGraphString("A[x]; B^A; B[y];") with self.assertRaises(ParseError): parseGraphString("A[x]; A^C; B^C[y]")
def test_tag_errors(self): with self.assertRaises(ParseError): parseGraphString("X[3]--Y") with self.assertRaises(ParseError): parseGraphString("X--Y[4][5];") with self.assertRaises(ParseError): parseGraphString("[6]X;")
def test_tagged_edges(self): g = parseGraphString("P -- Q [2]; A--B--C[!] ;") self.assertEqual(len(g.nodes), 5) self.assertEqual(len(g.edges), 3) self.assertNotIn('tag', g.nodes['P']) self.assertNotIn('tag', g.nodes['Q']) self.assertNotIn('tag', g.nodes['A']) self.assertNotIn('tag', g.nodes['B']) self.assertNotIn('tag', g.nodes['C']) self.assertIn('tag', g.edges['P', 'Q']) self.assertIn('tag', g.edges['Q', 'P']) self.assertIn('tag', g.edges['A', 'B']) self.assertIn('tag', g.edges['B', 'C']) self.assertEqual(g.edges['P', 'Q']['tag'], '2') self.assertEqual(g.edges['Q', 'P']['tag'], '2') self.assertEqual(g.edges['A', 'B']['tag'], '!') self.assertEqual(g.edges['C', 'B']['tag'], '!')
def test_invalid_node_names(self): with self.assertRaises(ParseError): self.assertIsNone(parseGraphString("123")) with self.assertRaises(ParseError): self.assertIsNone(parseGraphString("\n--X")) with self.assertRaises(ParseError): self.assertIsNone(parseGraphString("«")) with self.assertRaises(ParseError): self.assertIsNone(parseGraphString("+")) with self.assertRaises(ParseError): self.assertIsNone(parseGraphString("-")) with self.assertRaises(ParseError): self.assertIsNone(parseGraphString("Y.Z"))
def test_multiple_elements(self): g = parseGraphString("Q; X--Y--Z--X; Y--A; S; Y--B; B--C") self.assertIsNotNone(g) self.assertEqual(len(g.nodes), 8) self.assertEqual(len(g.edges), 6) self.assertTrue(g.has_node("A")) self.assertTrue(g.has_node("B")) self.assertTrue(g.has_node("C")) self.assertTrue(g.has_node("Q")) self.assertTrue(g.has_node("S")) self.assertTrue(g.has_node("X")) self.assertTrue(g.has_node("Y")) self.assertTrue(g.has_node("Z")) self.assertTrue(g.has_edge("Y", "A")) self.assertTrue(g.has_edge("Y", "B")) self.assertTrue(g.has_edge("Y", "Z")) self.assertTrue(g.has_edge("Y", "X")) self.assertTrue(g.has_edge("X", "Z")) self.assertTrue(g.has_edge("B", "C"))
def test_merged_graphs_cyclic(self): g2 = parseGraphString("P^Q; Q^R; R^S; S^P", joinAllowed=True) self.assertIsNotNone(g2) self.assertIn("join", g2.graph) join = g2.graph['join'] # The "root" object is not included in the dictionary self.assertEqual(len(join), 3) self.assertEqual(len(g2.nodes), 1) self.assertEqual(self.follow(join, "P"), self.follow(join, "Q")) self.assertEqual(self.follow(join, "P"), self.follow(join, "R")) self.assertEqual(self.follow(join, "P"), self.follow(join, "S")) rename = g2.graph['rename'] n0 = list(g2.nodes)[0] self.assertEqual(rename['P'], n0) self.assertEqual(rename['Q'], n0) self.assertEqual(rename['R'], n0) self.assertEqual(rename['S'], n0)
def test_tag_node_after_first_use(self): g = parseGraphString("P -- Q [x]; P[1]; Q[2]") self.assertEqual(g.nodes['P']['tag'], '1') self.assertEqual(g.nodes['Q']['tag'], '2') self.assertEqual(g['P']['Q']['tag'], 'x')
def test_implicit_name(self): g = parseGraphString("A--D; B--C", joinAllowed=True) self.assertEqual(g.graph['rename']['A'], 'A') self.assertEqual(g.graph['rename']['B'], 'B') self.assertEqual(g.graph['rename']['C'], 'C') self.assertEqual(g.graph['rename']['D'], 'D')
def test_directed_unequal_tags(self): g = parseGraphString("A->B [left]; A<-B [right]") self.assertEqual(len(g.nodes), 2) self.assertEqual(len(g.edges), 2) self.assertEqual(g.edges['A', 'B']['tag'], 'left') self.assertEqual(g.edges['B', 'A']['tag'], 'right')
def test_merge_same_node(self): g = parseGraphString("A -- B [x]; A^B", joinAllowed=True) self.assertEqual(len(g.nodes), 1) n0 = list(g.nodes)[0] self.assertIn((n0, n0), g.edges) self.assertEqual(g[n0][n0]['tag'], 'x')