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_cant_delete_subgraph( self, ug ): (edges, moreEdges) = ug assume( len( edges ) < 6 ) assume( len( moreEdges ) < 4 ) # OK, build the graph and label the edges so the deletion can only happen # in one way (which is disallowed) l = self.undirectedGraphFromEdgeList( edges ) for (s,t) in edges: l.nodes[s]['tag'] = 'kill' l.nodes[t]['tag'] = 'kill' r = nx.Graph() self._buildRename( r ) g_orig = self.undirectedGraphFromEdgeList( edges + moreEdges ) for (s,t) in edges: g_orig.nodes[s]['tag'] = 'kill' g_orig.nodes[t]['tag'] = 'kill' g = sg.graphIdentifiersToNumbers( g_orig ) finder = sg.MatchFinder( g, verbose=False ) finder.maxMatches = 2 finder.maxMatchTime = 0.2 finder.leftSide( l ) finder.rightSide( r ) m = finder.matches() self.assertEqual( len( m ), 0 )
def test_impossible_match_none(self): g = self.twoEdgesX() lhs2 = nx.Graph() lhs2.add_edge( 'X', 'Y' ) finder2 = sg.MatchFinder( g, verbose=testVerbose ) finder2.leftSide( lhs2 ) #self.assertTrue( finder2.impossible ) m = finder2.matches() self.assertEqual( len( m ), 0 )
def test_impossible_match_edge(self): g = self.twoEdgesX() lhs = nx.Graph() lhs.add_edge( 'X', 'Y', tag='z') finder = sg.MatchFinder( g, verbose=testVerbose ) finder.leftSide( lhs ) #self.assertTrue( finder.impossible ) m = finder.matches() self.assertEqual( len( m ), 0 )
def test_directed_vs_undirected_error( self ): g = nx.Graph() g.add_edge( 'A', 'B' ) lhs = nx.DiGraph() lhs.add_edge( 'X', 'Y' ) finder = sg.MatchFinder( g, verbose=testVerbose ) with self.assertRaises( sg.MatchError ) as me: finder.leftSide( lhs ) if testVerbose: print( me.exception )
def test_multiple_paths_fail( self ): srcs = [ "S1", "S2", "S3" ] inter = [ "A", "B" ] g = self.multiPath( srcs, inter ) lhs2 = nx.Graph() lhs2.add_node( "X", tag="src" ) lhs2.add_node( "Z", tag="dst" ) lhs2.add_edge( "X", "Z" ) finder = sg.MatchFinder( g, verbose=testVerbose ) finder.leftSide( lhs2 ) mList = finder.matches() self.assertEqual( len( mList ), 0 )
def test_match_self( self, edges ): # FIXME: empty graphs do cause problems, they should be fixed # or else error out more explicitly. assume( len( edges ) > 0 ) assume( len( edges ) < 6 ) l = self.undirectedGraphFromEdgeList( edges ) g = sg.graphIdentifiersToNumbers( l ) finder = sg.MatchFinder( g ) finder.maxMatches = 2 finder.maxMatchTime = 0.2 finder.leftSide( l ) m = finder.matches() self.assertGreaterEqual( len( m ), 1 )
def test_match_subgraph( self, edges, moreEdges ): assume( len( edges ) > 0 ) assume( len( moreEdges ) > 0 ) # FIXME: temporarily reduced maximum number of edges. assume( len( edges ) < 6 ) assume( len( moreEdges ) < 4 ) l = self.undirectedGraphFromEdgeList( edges ) g = self.undirectedGraphFromEdgeList( edges + moreEdges ) g = sg.graphIdentifiersToNumbers( g ) finder = sg.MatchFinder( g ) finder.maxMatches = 2 finder.maxMatchTime = 0.2 finder.leftSide( l ) m = finder.matches() self.assertGreaterEqual( len( m ), 1 )
def test_lhs_match_directededge( self ): g = nx.DiGraph() g.add_edge( 'A', 'B', tag='x' ) g.add_edge( 'B', 'C', tag='x' ) lhs = nx.DiGraph() lhs.add_edge( 'X', 'Y', tag='x' ) finder = sg.MatchFinder( g, verbose=testVerbose ) finder.leftSide( lhs ) self.assertFalse( finder.impossible ) mList = finder.matches() if testVerbose: print( mList ) self.assertEqual( len( mList ), 2 ) edges = set( [ ('A', 'B'), ('B', 'C' ) ] ) foundEdges = set( m.edge( ( 'X', 'Y' ) ) for m in mList ) self.assertEqual( edges, foundEdges )
def test_lhs_match_singlenode( self ): g = nx.Graph() g.add_node( 'A', tag='x' ) g.add_node( 'B', tag='x' ) lhs = nx.Graph() lhs.add_node( 'X', tag='x' ) finder = sg.MatchFinder( g, verbose=testVerbose ) finder.leftSide( lhs ) self.assertFalse( finder.impossible ) m = finder.matches() if testVerbose: print( m ) self.assertEqual( len( m ), 2 ) if m[0].node( 'X' ) == 'A': self.assertEqual( m[1].node('X'), 'B' ) else: self.assertEqual( m[1].node('X'), 'A' )
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_multiple_paths( self ): srcs = [ "S1", "S2", "S3" ] inter = [ "A", "B" ] g = self.multiPath( srcs, inter ) lhs = nx.Graph() lhs.add_node( "X", tag="src" ) lhs.add_node( "Y" ) lhs.add_node( "Z", tag="dst" ) lhs.add_edge( "X", "Y" ) finder = sg.MatchFinder( g, verbose=testVerbose ) finder.leftSide( lhs ) mList = finder.matches() self.assertEqual( len( mList ), len( srcs ) * len( inter ) ) for m in mList: if testVerbose: print( m ) self.assertIn( m.node( "X" ), srcs ) self.assertIn( m.node( "Y"), inter ) self.assertEqual( m.node( "Z" ), "DST" )
def test_complicated_directed_single_path( self ): g = nx.DiGraph() g.add_edge( 'A', 'B', tag='1' ) g.add_edge( 'A', 'C', tag='2' ) g.add_edge( 'A', 'D', tag='3' ) g.add_edge( 'B', 'E', tag='4' ) g.add_edge( 'C', 'E', tag='5' ) g.add_edge( 'D', 'E', tag='6' ) g.add_edge( 'E', 'A', tag='x' ) lhs = nx.DiGraph() lhs.add_edge( 'X1', 'X2', tag='1' ) lhs.add_edge( 'X2', 'X3', tag='4' ) lhs.add_edge( 'X3', 'X1', tag='x' ) finder = sg.MatchFinder( g, verbose=testVerbose ) finder.leftSide( lhs ) self.assertFalse( finder.impossible ) mList = finder.matches() self.assertEqual( len( mList ), 1 )
def test_cant_delete_directed_subgraph( self, dg ): (edges, moreEdges) = dg l = self.directedGraphFromEdgeList( edges ) for (s,t) in edges: l.nodes[s]['tag'] = 'kill' l.nodes[t]['tag'] = 'kill' r = nx.DiGraph() self._buildRename( r ) g_orig = self.directedGraphFromEdgeList( edges + moreEdges ) for (s,t) in edges: g_orig.nodes[s]['tag'] = 'kill' g_orig.nodes[t]['tag'] = 'kill' g = sg.graphIdentifiersToNumbers( g_orig ) finder = sg.MatchFinder( g, verbose=False ) finder.maxMatches = 2 finder.maxMatchTime = 0.2 finder.leftSide( l ) finder.rightSide( r ) m = finder.matches() self.assertEqual( len( m ), 0 )
def test_delete_directed_subgraph( self, sgs ): (edges, moreEdges ) = sgs nodesG = set( [ s for (s,t) in moreEdges ] + [ t for (s,t) in moreEdges ] ) l = self.directedGraphFromEdgeList( edges ) r = nx.DiGraph() self._buildRename( r ) g_orig = self.directedGraphFromEdgeList( edges + moreEdges ) g = sg.graphIdentifiersToNumbers( g_orig ) finder = sg.MatchFinder( g, verbose=False ) finder.maxMatches = 2 finder.maxMatchTime = 0.2 finder.leftSide( l ) finder.rightSide( r ) m = finder.matches() self.assertGreater( len( m ), 0 ) app = sg.RuleApplication( finder, m[0] ) g2 = app.result() self.assertEqual( len( g2.nodes ), len( nodesG ) )