<s> import sys <EOL> if sys . version_info [ : <NUM_LIT:2> ] > ( <NUM_LIT:2> , <NUM_LIT:4> ) : <EOL> __doc__ = """<STR_LIT>""" <EOL> else : <EOL> __doc__ = "<STR_LIT>" <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> from rdflib . graph import Graph , ConjunctiveGraph , ReadOnlyGraphAggregate <EOL> from rdflib . term import BNode <EOL> try : <EOL> import hashlib <EOL> md = hashlib . md5 ( ) <EOL> except ImportError : <EOL> import md5 <EOL> md = md5 . new ( ) <EOL> class IsomorphicGraph ( ConjunctiveGraph ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , ** kwargs ) : <EOL> super ( IsomorphicGraph , self ) . __init__ ( ** kwargs ) <EOL> def __eq__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( other , IsomorphicGraph ) : <EOL> return False <EOL> elif len ( self ) != len ( other ) : <EOL> return False <EOL> elif list ( self ) == list ( other ) : <EOL> return True <EOL> return self . internal_hash ( ) == other . internal_hash ( ) <EOL> def __ne__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> return not self . __eq__ ( other ) <EOL> def internal_hash ( self ) : <EOL> """<STR_LIT>""" <EOL> return _TripleCanonicalizer ( self ) . to_hash ( ) <EOL> class _TripleCanonicalizer ( object ) : <EOL> def __init__ ( self , graph , hashfunc = hash ) : <EOL> self . graph = graph <EOL> self . hashfunc = hashfunc <EOL> def to_hash ( self ) : <EOL> return self . hashfunc ( tuple ( sorted ( <EOL> map ( self . hashfunc , self . canonical_triples ( ) ) ) ) ) <EOL> def canonical_triples ( self ) : <EOL> for triple in self . graph : <EOL> yield tuple ( self . _canonicalize_bnodes ( triple ) ) <EOL> def _canonicalize_bnodes ( self , triple ) : <EOL> for term in triple : <EOL> if isinstance ( term , BNode ) : <EOL> yield BNode ( value = "<STR_LIT>" % self . _canonicalize ( term ) ) <EOL> else : <EOL> yield term <EOL> def _canonicalize ( self , term , done = False ) : <EOL> return self . hashfunc ( tuple ( sorted ( self . _vhashtriples ( term , done ) , <EOL> key = _hetero_tuple_key ) ) ) <EOL> def _vhashtriples ( self , term , done ) : <EOL> for triple in self . graph : <EOL> if term in triple : <EOL> yield tuple ( self . _vhashtriple ( triple , term , done ) ) <EOL> def _vhashtriple ( self , triple , target_term , done ) : <EOL> for i , term in enumerate ( triple ) : <EOL> if not isinstance ( term , BNode ) : <EOL> yield term <EOL> elif done or ( term == target_term ) : <EOL> yield i <EOL> else : <EOL> yield self . _canonicalize ( term , done = True ) <EOL> def _hetero_tuple_key ( x ) : <EOL> "<STR_LIT>" <EOL> return tuple ( ( type ( a ) . __name__ , a ) for a in x ) <EOL> def to_isomorphic ( graph ) : <EOL> if isinstance ( graph , IsomorphicGraph ) : <EOL> return graph <EOL> return IsomorphicGraph ( store = graph . store ) <EOL> def isomorphic ( graph1 , graph2 ) : <EOL> """<STR_LIT>""" <EOL> return _TripleCanonicalizer ( graph1 ) . to_hash ( ) == _TripleCanonicalizer ( graph2 ) . to_hash ( ) <EOL> def to_canonical_graph ( g1 ) : <EOL> """<STR_LIT>""" <EOL> graph = Graph ( ) <EOL> graph += _TripleCanonicalizer ( g1 , _md5_hash ) . canonical_triples ( ) <EOL> return ReadOnlyGraphAggregate ( [ graph ] ) <EOL> def graph_diff ( g1 , g2 ) : <EOL> """<STR_LIT>""" <EOL> cg1 = to_canonical_graph ( g1 ) <EOL> cg2 = to_canonical_graph ( g2 ) <EOL> in_both = cg1 * cg2 <EOL> in_first = cg1 - cg2 <EOL> in_second = cg2 - cg1 <EOL> return ( in_both , in_first , in_second ) <EOL> def _md5_hash ( t ) : <EOL> h = md <EOL> for i in t : <EOL> if isinstance ( i , tuple ) : <EOL> h . update ( _md5_hash ( i ) . encode ( '<STR_LIT:ascii>' ) ) <EOL> else : <EOL> h . update ( unicode ( i ) . encode ( "<STR_LIT:utf8>" ) ) <EOL> return h . hexdigest ( ) <EOL> _MOCK_BNODE = BNode ( ) <EOL> def similar ( g1 , g2 ) : <EOL> """<STR_LIT>""" <EOL> return all ( t1 == t2 for ( t1 , t2 ) in _squashed_graphs_triples ( g1 , g2 ) ) <EOL> def _squashed_graphs_triples ( g1 , g2 ) : <EOL> for ( t1 , t2 ) in zip ( sorted ( _squash_graph ( g1 ) ) , sorted ( _squash_graph ( g2 ) ) ) : <EOL> yield t1 , t2 <EOL> def _squash_graph ( graph ) : <EOL> return ( _squash_bnodes ( triple ) for triple in graph ) <EOL> def _squash_bnodes ( triple ) : <EOL> return tuple ( ( isinstance ( t , BNode ) and _MOCK_BNODE ) or t for t in triple ) </s>
