
    PiV                    F   d Z ddlmZ g dZddlmZ ddlmZ ddlmZ ddl	m
Z
mZmZmZmZmZmZmZmZ ddlmZmZmZmZ dd	lmZmZmZmZ e
rdd
lmZ d Z G d d          Z  G d d          Z! G d de          Z"ee#ge$f         Z%eee$e#f         eee$e#f         f         Z&ee&df         Z'eee'e#f                  Z(ee#ee$e#f         f         Z) G d d          Z*eg df         Z+ G d d          Z,d-dZ-d.dZ.	 d/d0d%Z/d1d(Z0 e            Z1d2d)Z2d2d*Z3d3d+Z4d, Z5d S )4a  
A collection of utilities for canonicalizing and inspecting graphs.

Among other things, they solve of the problem of deterministic bnode
comparisons.

Warning: the time to canonicalize bnodes may increase exponentially on
degenerate larger graphs. Use with care!

Example of comparing two graphs:

```python
>>> g1 = Graph().parse(format='n3', data='''
...     @prefix : <http://example.org/ns#> .
...     <http://example.org> :rel
...         <http://example.org/same>,
...         [ :label "Same" ],
...         <http://example.org/a>,
...         [ :label "A" ] .
... ''')
>>> g2 = Graph().parse(format='n3', data='''
...     @prefix : <http://example.org/ns#> .
...     <http://example.org> :rel
...         <http://example.org/same>,
...         [ :label "Same" ],
...         <http://example.org/b>,
...         [ :label "B" ] .
... ''')
>>>
>>> iso1 = to_isomorphic(g1)
>>> iso2 = to_isomorphic(g2)

```

These are not isomorphic

```python
>>> iso1 == iso2
False

```

Diff the two graphs:

```python
>>> in_both, in_first, in_second = graph_diff(iso1, iso2)

```

Present in both:

```python
>>> def dump_nt_sorted(g):
...     for l in sorted(g.serialize(format='nt').splitlines()):
...         if l: print(l.decode('ascii'))
>>> dump_nt_sorted(in_both) #doctest: +SKIP
<http://example.org>
    <http://example.org/ns#rel> <http://example.org/same> .
<http://example.org>
    <http://example.org/ns#rel> _:cbcaabaaba17fecbc304a64f8edee4335e .
_:cbcaabaaba17fecbc304a64f8edee4335e
    <http://example.org/ns#label> "Same" .
```

Only in first:

```python
>>> dump_nt_sorted(in_first) #doctest: +SKIP
<http://example.org>
    <http://example.org/ns#rel> <http://example.org/a> .
<http://example.org>
    <http://example.org/ns#rel> _:cb124e4c6da0579f810c0ffe4eff485bd9 .
_:cb124e4c6da0579f810c0ffe4eff485bd9
    <http://example.org/ns#label> "A" .
```

Only in second:

```python
>>> dump_nt_sorted(in_second) #doctest: +SKIP
<http://example.org>
    <http://example.org/ns#rel> <http://example.org/b> .
<http://example.org>
    <http://example.org/ns#rel> _:cb558f30e21ddfc05ca53108348338ade8 .
_:cb558f30e21ddfc05ca53108348338ade8
    <http://example.org/ns#label> "B" .
```
    )annotations)IsomorphicGraphto_isomorphic
isomorphicto_canonical_graph
graph_diffsimilar)defaultdict)datetime)sha256)	TYPE_CHECKINGCallableDictIteratorListOptionalSetTupleUnion)ConjunctiveGraphGraphReadOnlyGraphAggregate_TripleType)BNodeIdentifiedNodeNodeURIRef)HASHc                T    | j         dz  dz  dz  }|| j        z  }|| j        dz  z  }|S )N   <   g    .A)dayssecondsmicroseconds)tdresults     b/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/rdflib/compare.py_total_secondsr(      s9    Wr\B#F
bjF
bo	))FM    c                      e Zd Zd Zd ZdS )_runtimec                    || _         d S Nlabelselfr/   s     r'   __init__z_runtime.__init__       


r)   c                B      j         j        dz    _          fd}|S )Nr+   c                     t          j                    } | i |}d|v r;|d         3|d         }t          t          j                    |z
            |j        <   |S )Nstats)r   nowr(   r/   )argskwargsstartr&   r6   fr1   s        r'   	wrapped_fz$_runtime.__call__.<locals>.wrapped_f   sc    LNNEQ'''F&  VG_%@w$28<>>E3I$J$Jdj!Mr)   r/   __name__r1   r;   r<   s   `` r'   __call__z_runtime.__call__   s@    :j0DJ	 	 	 	 	 	 r)   Nr>   
__module____qualname__r2   r@    r)   r'   r+   r+      2              r)   r+   c                      e Zd Zd Zd ZdS )_call_countc                    || _         d S r-   r.   r0   s     r'   r2   z_call_count.__init__   r3   r)   c                B      j         j        dz    _          fd}|S )Nr+   c                     d|v r8|d         0|d         }j         |vr
d|j         <   |j         xx         dz  cc<    | i |S )Nr6   r      r.   )r8   r9   r6   r;   r1   s      r'   r<   z'_call_count.__call__.<locals>.wrapped_f   sl    &  VG_%@w:U**()E$*%dj!!!Q&!!!1d%f%%%r)   r=   r?   s   `` r'   r@   z_call_count.__call__   s@    :j0DJ	& 	& 	& 	& 	& 	& r)   NrA   rD   r)   r'   rG   rG      rE   r)   rG   c                  H     e Zd ZdZ fdZd Zd Z fdZd	dZd	dZ	 xZ
S )
r   a%  An implementation of the RGDA1 graph digest algorithm.

    An implementation of RGDA1 (publication below),
    a combination of Sayers & Karp's graph digest algorithm using
    sum and SHA-256 <http://www.hpl.hp.com/techreports/2003/HPL-2003-235R1.pdf>
    and traces <http://pallini.di.uniroma1.it>, an average case
    polynomial time algorithm for graph canonicalization.

    McCusker, J. P. (2015). WebSig: A Digital Signature Framework for the Web.
    Rensselaer Polytechnic Institute, Troy, NY.
    http://gradworks.umi.com/3727015.pdf
    c                H     t          t          |           j        di | d S )NrD   )superr   r2   )r1   r9   	__class__s     r'   r2   zIsomorphicGraph.__init__   s,    -ot$$-7777777r)   c                    t          |t                    sdS t          |           t          |          k    rdS |                                 |                                k    S )zGraph isomorphism testing.F)
isinstancer   leninternal_hashr1   others     r'   __eq__zIsomorphicGraph.__eq__   sX    %11 	5YY#e**$$5!!##u':':'<'<<<r)   c                .    |                      |           S )z#Negative graph isomorphism testing.)rV   rT   s     r'   __ne__zIsomorphicGraph.__ne__   s    ;;u%%%%r)   c                R    t          t          |                                           S r-   )rN   r   __hash__)r1   rO   s    r'   rZ   zIsomorphicGraph.__hash__   s    _d++44666r)   Nc                .    |                      |          S )z*Synonym for IsomorphicGraph.internal_hash.r6   )rS   r1   r6   s     r'   graph_digestzIsomorphicGraph.graph_digest   s    !!!...r)   c                H    t          |                               |          S )z
        This is defined instead of `__hash__` to avoid a circular recursion
        scenario with the Memory store for rdflib which requires a hash lookup
        in order to return a generator of triples.
        r\   _TripleCanonicalizerto_hashr]   s     r'   rS   zIsomorphicGraph.internal_hash   s#     $D))111>>>r)   r-   )r>   rB   rC   __doc__r2   rV   rX   rZ   r^   rS   __classcell__)rO   s   @r'   r   r      s         8 8 8 8 8= = =& & &7 7 7 7 7/ / / /? ? ? ? ? ? ? ?r)   r   .c                  F    e Zd Z	 	 dddZd Zd ZdddZddZd Zd Z	dS )ColorrD   NnodesList[IdentifiedNode]hashfuncHashFunccolorColorItemTuple
hash_cache	HashCachec                T    |i }|| _         || _        || _        || _        d | _        d S r-   )_hash_cacherk   rg   ri   _hash_color)r1   rg   ri   rk   rm   s        r'   r2   zColor.__init__   s:     J%

 r)   c                B    |                                  \  }}d|d|dS )NzColor z (z nodes)key)r1   rg   rk   s      r'   __str__zColor.__str__   s(    xxzzuu(-uuu55r)   c                R    t          | j                  |                                 fS r-   )rR   rg   
hash_colorr1   s    r'   rt   z	Color.key   s    DJ!2!233r)   Optional[Tuple[ColorItem, ...]]returnstrc                &   || j         }|| j        v r| j        |         S d t          |t                    r |          S d}|D ]9}||                     d                    fd|D                                 z  }:d|z  }|| j        |<   |S )Nc                r    t          | t                    r|                                 S t          |           S r-   )rQ   r   n3r{   xs    r'   	stringifyz#Color.hash_color.<locals>.stringify   s,    !T"" ttvv1vvr)   r    c                &    g | ]} |          S rD   rD   ).0r   r   s     r'   
<listcomp>z$Color.hash_color.<locals>.<listcomp>  s!    ,J,J,JaYYq\\,J,J,Jr)   %x)rk   rp   rQ   r   ri   join)r1   rk   valuetriplevalr   s        @r'   rw   zColor.hash_color   s    =JED$$$#E**	 	 	 eT"" 	$9U### 	M 	MFT]]388,J,J,J,J6,J,J,J#K#KLLLEE%<"%
r)   Wgraphr   c           	        i }| j         D ]}t          | j                  }j         D ]P}|fd|                    |d |f          D             z  }|fd|                    |d |f          D             z  }Qt	          |          }|                     |          }||vr"t          g | j        || j                  }|||<   ||         j         	                    |           |
                                S )Nc                F    g | ]\  }}}d |                                 fS )rK   rw   r   spor   s       r'   r   z%Color.distinguish.<locals>.<listcomp>  s;       /6q!QQ1<<>>*  r)   c                F    g | ]\  }}}                                 |d fS )   r   r   s       r'   r   z%Color.distinguish.<locals>.<listcomp>  s;       /6q!QQ\\^^Q*  r)   rm   )rg   listrk   triplestuplerw   rf   ri   rp   appendvalues)	r1   r   r   colorsn	new_colornodenew_hash_colorcs	    `       r'   distinguishzColor.distinguish  s@   #% 	3 	3A/3DJ/?/?I      :?--DRV:X:X   	     :?--tUV:X:X   		 i((I!__Y77NV++"dmY4CSTTT)*~&>"(//2222}}r)   c                2    t          | j                  dk    S )NrK   )rR   rg   rx   s    r'   discretezColor.discrete!  s    4:!##r)   c                `    t          | j        d d          | j        | j        | j                  S Nr   )rf   rg   ri   rk   rp   rx   s    r'   copyz
Color.copy$  s3    JqqqM4=$*AQ
 
 
 	
r)   )rD   N)rg   rh   ri   rj   rk   rl   rm   rn   r-   )rk   ry   rz   r{   )r   rf   r   r   )
r>   rB   rC   r2   ru   rt   rw   r   r   r   rD   r)   r'   rf   rf      s        
 !# $         6 6 64 4 4    *   ($ $ $
 
 
 
 
r)   rf   r   c                      e Zd Zefd(dZd)d
Zd*dZd Zd+dZd,dZ	 e
d          d-d.d            Zd/dZ	 d-d0dZ ed          ddgfd1d!            Zd-d.d"Zd2d'ZdS )3ra   r   r   ri   _HashTc                >    || _         dfd}i | _        || _        d S )Nr   r{   c                                 }|                     t          |                               d                     t          |                                d          S )Nutf8   )updater{   encodeint	hexdigest)r   hri   s     r'   	_hashfuncz0_TripleCanonicalizer.__init__.<locals>._hashfunc1  sJ    

AHHSVV]]6**+++q{{}}b)))r)   )r   r{   )r   rp   ri   )r1   r   ri   r   s     ` r'   r2   z_TripleCanonicalizer.__init__.  s=    
	* 	* 	* 	* 	* 	*
 ')!r)   coloringList[Color]rz   boolc                <    t          d |D                       dk    S )Nc                :    g | ]}|                                 |S rD   r   r   r   s     r'   r   z2_TripleCanonicalizer._discrete.<locals>.<listcomp>:  s%    <<<!qzz||<A<<<r)   r   )rR   )r1   r   s     r'   	_discretez_TripleCanonicalizer._discrete9  s$    <<x<<<==BBr)   c                >    t                      }t                      }t          t                      _         j        D ]\  }}}t          |||g          }t          d |D                       }t	          |          dk    r|||z
  z  }||z  }t          |t                    r  j        |                             |           t          |t                    r  j        |                             |           t          |t                    r@ j        |                             |            j        |                             |           t	          |          dk    r9t          t          |           j
         j                  g fd|D             z   S g S )a\  Finds an initial color for the graph.

        Finds an initial color of the graph by finding all blank nodes and
        non-blank nodes that are adjacent. Nodes that are not adjacent to blank
        nodes are not included, as they are a) already colored (by URI or literal)
        and b) do not factor into the color of any blank node.
        c                <    g | ]}t          |t                    |S rD   rQ   r   r   r   s     r'   r   z7_TripleCanonicalizer._initial_color.<locals>.<listcomp>I  s'    >>>1Au)=)=>Q>>>r)   r   r   c                L    g | ] }t          |gj        |j                   !S )r   )rf   ri   rp   r   r   r1   s     r'   r   z7_TripleCanonicalizer._initial_color.<locals>.<listcomp>U  sI     X X X  qc4=!8HIIIX X Xr)   )setr
   
_neighborsr   rR   rQ   r   addrf   r   ri   rp   )r1   bnodesothersr   r   r   rg   bs   `       r'   _initial_colorz#_TripleCanonicalizer._initial_color<  s    !UU%c**z 	. 	.GAq!Aq	NNE>>>>>??A1vvzz%!)#!a'' .OA&**1---a'' .OA&**1---a'' .OA&**1---OA&**1---v;;??$v,,$BRSSST X X X X  	X X X   Ir)   c                   t          |j                  }|                    t          |j                  f           |j                            |           t          |g| j        t          |          | j	                  }|S r   )
r   rk   r   rR   rg   removerf   ri   r   rp   )r1   rk   
individualr   r   s        r'   _individuatez!_TripleCanonicalizer._individuate^  s{    %%	#ek**,---:&&&L$-y)9)9dFV
 
 
 r)   Iterator[Tuple[Node, Color]]c              #  H   K   d |D             D ]}|j         D ]}||fV  	d S )Nc                :    g | ]}|                                 |S rD   r   r   s     r'   r   z8_TripleCanonicalizer._get_candidates.<locals>.<listcomp>i  s%    :::QZZ\\:!:::r)   rg   )r1   r   r   r   s       r'   _get_candidatesz$_TripleCanonicalizer._get_candidatesh  sR      ::X::: 	 	A  Ag	 	r)   sequencec                   t          |d d          }|d d          }t          |          dk    r=|                     |          s'|                                }|d d          D ]}t          |j                  dk    s t          |j        d         t                    rt          |                    || j                  d d          }|	                    |           |
                    |           	 |                    |          }|d |         |z   ||dz   d          z   }# t          $ r |dd          |z   }Y w xY wt          |          dk    r|                     |          'g }t                      }|D ]Z}	|	                                }
|
|v r&||
         j        
                    |	j                   @|                    |	           |	||
<   [|S )Nc                *    |                                  S r-   rs   r   s    r'   <lambda>z._TripleCanonicalizer._refine.<locals>.<lambda>n  s    !%%'' r)   T)rt   reverser   rK   c                *    |                                  S r-   rs   r   s    r'   r   z._TripleCanonicalizer._refine.<locals>.<lambda>v  s    aeegg r)   )sortedrR   r   poprg   rQ   r   r   r   r   extendindex
ValueErrordictrw   r   )r1   r   r   r   r   r   sicombined_colorscombined_color_maprk   
color_hashs              r'   _refinez_TripleCanonicalizer._refinem  s   ((9(94HHHAAA;(mmax(@(@Aaaa[ 9 9qw<<!##z!'!*e'D'D##a44-- $  F
 OOA&&&OOF+++9%^^A..#+CRC=6#9HR!VXX<N#N% 9 9 9#)!"":#89 $ (mmax(@(@  (*/3vv 	7 	7E))++J///":.4;;EKHHHH&&u---16":..s   70D((EEto_hash_runtimeNr6   Optional[Stats]c                    d}|                      |          D ]7}||                     d                    d |D                                 z  }8|d|z  |d<   |S )Nr   r\   r   c                6    g | ]}|                                 S rD   )r~   r   s     r'   r   z0_TripleCanonicalizer.to_hash.<locals>.<listcomp>  s     -E-E-Eaddff-E-E-Er)   r   r^   )canonical_triplesri   r   )r1   r6   r&   r   s       r'   rb   z_TripleCanonicalizer.to_hash  su    ,,5,99 	H 	HFdmmCHH-E-Ef-E-E-E$F$FGGGFF$(6ME.!r)   c                4   d |D             }|                      |          svd |D             d         }|j        d         }|                     ||          }|                    |           |                     ||g          }|                      |          v|S )Nc                6    g | ]}|                                 S rD   )r   r   s     r'   r   z;_TripleCanonicalizer._experimental_path.<locals>.<listcomp>  s     ///AFFHH///r)   c                :    g | ]}|                                 |S rD   r   r   s     r'   r   z;_TripleCanonicalizer._experimental_path.<locals>.<listcomp>  s%    ===1

=Q===r)   r   )r   rg   r   r   r   )r1   r   rk   r   r   s        r'   _experimental_pathz'_TripleCanonicalizer._experimental_path  s    //h///..** 	;=====a@E;q>D))%66IOOI&&&||Hyk::H ..** 	; r)   	coloringsList[List[Color]]	groupingsOptional[Dict[Node, Set[Node]]]Dict[Node, Set[Node]]c                    |st          t                    }t          | D ]5}t          d |D                       }|D ]}|||         z  }|D ]}|||<   6|S )Nc                (    g | ]}|j         d          S r   r   r   s     r'   r   z:_TripleCanonicalizer._create_generator.<locals>.<listcomp>  s    ///AQWQZ///r)   )r
   r   zip)r1   r   r   groupgr   s         r'   _create_generatorz&_TripleCanonicalizer._create_generator  s    
  	)#C((I)_ 	! 	!E/////00A " "Yq\! ! ! 	!!r)   individuationsr   depth	List[int]c                P    |	d|vrd|d<   |dxx         dz  cc<                         |          }g }d }d }d }t          t                    }	t                      }
|D ]\  }}||	v r4|	|         |
z  }t          |          dk    r|
                    |           >|
                    |           g }d }|D ]3}|                                }|                    |           ||k    r|}4                     ||          }|                    |                                ||g          }t          d |D                       } 
                    |          }t          d |D                       }|r                     ||g|	          }	|}|||k     r	|g}|}|}C||k    r/|+t          |d         t                    r|dxx         dz  cc<   x||k    r|                    |           |+t          |d         t                    r|dxx         dz  cc<   Ĉ fd|D             }t          |          dk    r]d }d }|D ]Q}|d         g}                     |||          }t          d |D                       }|||k    r|g}|}|d         }R||d<   |d         S )	Npruningsr   rK   c                6    g | ]}|                                 S rD   rs   r   s     r'   r   z0_TripleCanonicalizer._traces.<locals>.<listcomp>  s      C C CQ C C Cr)   c                6    g | ]}|                                 S rD   rs   r   s     r'   r   z0_TripleCanonicalizer._traces.<locals>.<listcomp>  s     %D%D%D!aeegg%D%D%Dr)   c                >    g | ]}                     |          |S rD   )r   r   s     r'   r   z0_TripleCanonicalizer._traces.<locals>.<listcomp>  s*    &L&L&LQ$..:K:K&Lq&L&L&Lr)   r6   r   c                6    g | ]}|                                 S rD   rs   r   s     r'   r   z0_TripleCanonicalizer._traces.<locals>.<listcomp>  s     $G$G$GQUUWW$G$G$Gr)   )r   r
   r   rR   r   r   r   r   r   r   r   r   rQ   r   _traces)r1   r   r6   r   
candidatesbest
best_scorebest_experimental_scorelast_coloring	generatorvisited	candidaterk   vcoloring_copy
color_copyr   c_copyr   refined_coloringcolor_scoreexperimentalexperimental_scorer   
best_depthds   `                         r'   r  z_TripleCanonicalizer._traces  sW    5!8!8 !E*aA))(33
"$
"&+6s+;+;	 UU * '	+ '	+IuI%%i(72q66A::KK	***KK	""")+MJ ( ($$V,,,::!'J))*i@@I  +++#||MI;GG C C2B C C CDDK22=AAL!$%D%D|%D%D%D!E!E  22"L19 	 )M!Z+%=%=()(
*<''k))$E*4Es)K)K$*%%%*%%%#'>>>,---- $E*4Es)K)K$*%%%*%%%&L&L&L&L$&L&L&Lx==AJJ  & &1XJ LLaLHH	#$G$G6F$G$G$GHH%z)A)A ){H!,J!"1J!E!H{r)   c              #  $  K   |t          j                    }|                                 }|:t          | j                  |d<   t          dt          |          dz
            |d<   |                     ||d d                    }|8t          t          j                    |z
            |d<   t          |          |d<   |                     |          s)dg}| 	                    |||          }||d         |d<   n|
d|d	<   d|d<   |t          |          |d
<   t          d |D                       }|&t          t          j                    |z
            |d<   | j        D ])}t          |                     ||                    }|V  *d S )Ntriple_countr   rK   adjacent_nodesinitial_coloring_runtimeinitial_color_countr   
tree_depthr   color_countc                P    g | ]#}|j         d          |                                f$S r   )rg   rw   r   s     r'   r   z:_TripleCanonicalizer.canonical_triples.<locals>.<listcomp>  s+    <<<aagaj!,,..)<<<r)   canonicalize_triples_runtime)r   r7   r   rR   r   maxr   r(   r   r  r   r   _canonicalize_bnodes)r1   r6   start_coloringr   r   bnode_labelsr   r&   s           r'   r   z&_TripleCanonicalizer.canonical_triples  s     %\^^N&&(($'
OOE.!&)!S]]Q->&?&?E"#<<(111+660>/1 1E,- ,/x==E'(~~h'' 	$CE||HE|GGH &+Ahl#&'E"#"#E,#&x==E- (,<<8<<<)
 )
 4B/5 5E01 j 	 	F444V\JJKKFLLLL	 	r)   r   r   labelsDict[Node, str]c              #  ~   K   |D ]7}t          |t                    rt          d||         z            V  3|V  8d S )Nzcb%s)r   r   )r1   r   r"  terms       r'   r  z)_TripleCanonicalizer._canonicalize_bnodes  sa      
  	 	D$&& &6$<"78888888



		 	r)   )r   r   ri   r   )r   r   rz   r   )rz   r   )r   r   rz   r   )r   r   r   r   rz   r   r-   )r6   r   )r   r   rz   r   )r   r   r   r   rz   r   )r   r   r6   r   r   r   rz   r   )r   r   r"  r#  )r>   rB   rC   r   r2   r   r   r   r   r   r+   rb   r   r   rG   r  r   r  rD   r)   r'   ra   ra   -  sf       8> 	" 	" 	" 	" 	"C C C C       D     
   > X      !     6:     [!"" "&3	E E E E #"EN" " " " "H	 	 	 	 	 	r)   ra   r   r   rz   c                    t          | t                    r| S t                      }t          | d          rt          | j                  }|| z  }|S )N
identifier)r'  )rQ   r   hasattrr'  )r   r&   s     r'   r   r   &  sW    %)) Ful## > E,<===
eOFMr)   graph1graph2r   c                    t          |                                           }t          |                                          }||k    S )a  Compare graph for equality.

    Uses an algorithm to compute unique hashes which takes bnodes into account.

    Example:
        ```python
        >>> g1 = Graph().parse(format='n3', data='''
        ...     @prefix : <http://example.org/ns#> .
        ...     <http://example.org> :rel <http://example.org/a> .
        ...     <http://example.org> :rel <http://example.org/b> .
        ...     <http://example.org> :rel [ :label "A bnode." ] .
        ... ''')
        >>> g2 = Graph().parse(format='n3', data='''
        ...     @prefix ns: <http://example.org/ns#> .
        ...     <http://example.org> ns:rel [ ns:label "A bnode." ] .
        ...     <http://example.org> ns:rel <http://example.org/b>,
        ...             <http://example.org/a> .
        ... ''')
        >>> isomorphic(g1, g2)
        True
        >>> g3 = Graph().parse(format='n3', data='''
        ...     @prefix : <http://example.org/ns#> .
        ...     <http://example.org> :rel <http://example.org/a> .
        ...     <http://example.org> :rel <http://example.org/b> .
        ...     <http://example.org> :rel <http://example.org/c> .
        ... ''')
        >>> isomorphic(g1, g3)
        False

        ```
    r`   )r)  r*  gd1gd2s       r'   r   r   0  sA    @ v
&
&
.
.
0
0C
v
&
&
.
.
0
0C#:r)   Ng1r6   r   r   c                    t                      }|t          |                               |          z  }t          |g          S )zCreates a canonical, read-only graph.

    Creates a canonical, read-only graph where all bnode id:s are based on
    deterministical SHA-256 checksums, correlated with the graph contents.
    r\   )r   ra   r   r   )r.  r6   r   s      r'   r   r   U  sA     GGE	!"%%77e7DDDE!5'***r)   g2Tuple[Graph, Graph, Graph]c                f    t          |           }t          |          }||z  }||z
  }||z
  }|||fS )zEReturns three sets of triples: "in both", "in first" and "in second".)r   )r.  r0  cg1cg2in_bothin_first	in_seconds          r'   r   r   b  sF     R
 
 C
R
 
 CCiGSyHc	IXy))r)   c                P    t          d t          | |          D                       S )a<  Checks if the two graphs are "similar".

    Checks if the two graphs are "similar", by comparing sorted triples where
    all bnodes have been replaced by a singular mock bnode (the
    `_MOCK_BNODE`).

    This is a much cheaper, but less reliable, alternative to the comparison
    algorithm in `isomorphic`.
    c              3  (   K   | ]\  }}||k    V  d S r-   rD   )r   t1t2s      r'   	<genexpr>zsimilar.<locals>.<genexpr>z  s*      IIHRrRxIIIIIIr)   )all_squashed_graphs_triples)r.  r0  s     r'   r	   r	   p  s,     II(@R(H(HIIIIIIr)   c              #     K   t          t          t          |                     t          t          |                              D ]\  }}||fV  d S r-   )r   r   _squash_graph)r.  r0  r:  r;  s       r'   r>  r>  }  s\      f]2..//b8I8I1J1JKK  B"f r)   c                    d | D             S )Nc              3  4   K   | ]}t          |          V  d S r-   )_squash_bnodes)r   r   s     r'   r<  z _squash_graph.<locals>.<genexpr>  s*      77vN6""777777r)   rD   )r   s    r'   r@  r@    s    777777r)   c                4    t          d | D                       S )Nc              3  R   K   | ]"}t          |t                    rt          p|V  #d S r-   )rQ   r   _MOCK_BNODE)r   ts     r'   r<  z!_squash_bnodes.<locals>.<genexpr>  s6      MM*Q&&6;<1MMMMMMr)   )r   )r   s    r'   rC  rC    s    MMfMMMMMMr)   )r   r   rz   r   )r)  r   r*  r   rz   r   r-   )r.  r   r6   r   rz   r   )r.  r   r0  r   rz   r1  )r.  r   r0  r   )r   r   )6rc   
__future__r   __all__collectionsr
   r   hashlibr   typingr   r   r   r   r   r   r   r   r   rdflib.graphr   r   r   r   rdflib.termr   r   r   r   _hashlibr   r(   r+   rG   r   r{   r   rj   	ColorItemrl   rn   Statsrf   r   ra   r   r   r   r   rF  r	   r>  r@  rC  rD   r)   r'   <module>rR     sq  W Wr # " " " " "   $ # # # # #            
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 V U U U U U U U U U U U ; ; ; ; ; ; ; ; ; ; ; ;          &       &*? *? *? *? *?& *? *? *?Z SE3J%S/65c?:;	y#~&T.#-./	S%S/!"F
 F
 F
 F
 F
 F
 F
 F
R 
"f*	v v v v v v v vr   " " " "L )-
+ 
+ 
+ 
+ 
+* * * * egg
J 
J 
J 
J   
8 8 8 8N N N N Nr)   