ó
    …~iI�  ã                   ón  • S r SSKrSSKr/ SQr\R
                  " S/ SQ5      r\R
                  " S/ SQ5      r\R                  " SSS	.S
S0S9SS j5       r	\R                  " SSS	.S
S0S9SS j5       r
\R                  " SSS	.S
S0S9SS j5       rS rSS jrS rS rS rS rS rS rS rS rS rg)uu  
***************
VF2++ Algorithm
***************

An implementation of the VF2++ algorithm [1]_ for Graph Isomorphism testing.

The simplest interface to use this module is to call:

`vf2pp_is_isomorphic`: to check whether two graphs are isomorphic.
`vf2pp_isomorphism`: to obtain the node mapping between two graphs,
in case they are isomorphic.
`vf2pp_all_isomorphisms`: to generate all possible mappings between two graphs,
if isomorphic.

Introduction
------------
The VF2++ algorithm, follows a similar logic to that of VF2, while also
introducing new easy-to-check cutting rules and determining the optimal access
order of nodes. It is also implemented in a non-recursive manner, which saves
both time and space, when compared to its previous counterpart.

The optimal node ordering is obtained after taking into consideration both the
degree but also the label rarity of each node.
This way we place the nodes that are more likely to match, first in the order,
thus examining the most promising branches in the beginning.
The rules also consider node labels, making it easier to prune unfruitful
branches early in the process.

Examples
--------

Suppose G1 and G2 are Isomorphic Graphs. Verification is as follows:

Without node labels:

>>> import networkx as nx
>>> G1 = nx.path_graph(4)
>>> G2 = nx.path_graph(4)
>>> nx.vf2pp_is_isomorphic(G1, G2, node_label=None)
True
>>> nx.vf2pp_isomorphism(G1, G2, node_label=None)
{1: 1, 2: 2, 0: 0, 3: 3}

With node labels:

>>> G1 = nx.path_graph(4)
>>> G2 = nx.path_graph(4)
>>> mapped = {1: 1, 2: 2, 3: 3, 0: 0}
>>> nx.set_node_attributes(
...     G1, dict(zip(G1, ["blue", "red", "green", "yellow"])), "label"
... )
>>> nx.set_node_attributes(
...     G2,
...     dict(zip([mapped[u] for u in G1], ["blue", "red", "green", "yellow"])),
...     "label",
... )
>>> nx.vf2pp_is_isomorphic(G1, G2, node_label="label")
True
>>> nx.vf2pp_isomorphism(G1, G2, node_label="label")
{1: 1, 2: 2, 0: 0, 3: 3}

References
----------
.. [1] JÃ¼ttner, AlpÃ¡r & Madarasi, PÃ©ter. (2018). "VF2++â€”An improved subgraph
   isomorphism algorithm". Discrete Applied Mathematics. 242.
   https://doi.org/10.1016/j.dam.2018.02.018

é    N)Úvf2pp_isomorphismÚvf2pp_is_isomorphicÚvf2pp_all_isomorphismsÚ_GraphParameters)ÚG1ÚG2Ú	G1_labelsÚ	G2_labelsÚnodes_of_G1LabelsÚnodes_of_G2LabelsÚG2_nodes_of_degreeÚ_StateParameters)
ÚmappingÚreverse_mappingÚT1ÚT1_inÚT1_tildeÚT1_tilde_inÚT2ÚT2_inÚT2_tildeÚT2_tilde_iné   )r   r   Ú
node_labelÚdefault_label)ÚgraphsÚ
node_attrsc                 óR   •  [        [        XX#5      5      nU$ ! [         a     gf = f)a®  Return an isomorphic mapping between `G1` and `G2` if it exists.

Parameters
----------
G1, G2 : NetworkX Graph or MultiGraph instances.
    The two graphs to check for isomorphism.

node_label : str, optional
    The name of the node attribute to be used when comparing nodes.
    The default is `None`, meaning node attributes are not considered
    in the comparison. Any node that doesn't have the `node_label`
    attribute uses `default_label` instead.

default_label : scalar
    Default value to use when a node doesn't have an attribute
    named `node_label`. Default is `None`.

Returns
-------
dict or None
    Node mapping if the two graphs are isomorphic. None otherwise.
N)Únextr   ÚStopIteration)r   r   r   r   r   s        Úb/home/mande/repo/quber/.venv/lib/python3.13/site-packages/networkx/algorithms/isomorphism/vf2pp.pyr   r   k   s0   € ð0ÜÔ-¨b°jÓPÓQˆØˆøÜó Ùðús   ‚ ™
&¥&c                 ó    • [        XX#5      b  gg)a‰  Examines whether G1 and G2 are isomorphic.

Parameters
----------
G1, G2 : NetworkX Graph or MultiGraph instances.
    The two graphs to check for isomorphism.

node_label : str, optional
    The name of the node attribute to be used when comparing nodes.
    The default is `None`, meaning node attributes are not considered
    in the comparison. Any node that doesn't have the `node_label`
    attribute uses `default_label` instead.

default_label : scalar
    Default value to use when a node doesn't have an attribute
    named `node_label`. Default is `None`.

Returns
-------
bool
    True if the two graphs are isomorphic, False otherwise.
TF)r   )r   r   r   r   s       r!   r   r   Š   s   € ô0 ˜ Ó;ÑGØØó    c           	   #   ó.  #   • U R                  5       S:X  d  UR                  5       S:X  a  gU R                  5       (       a  [        U R                  U R                  5       VVVVs0 s H  u  u  pEu  pgXEU4_M     nnnnn[        UR                  UR                  5       VVVVs0 s H  u  u  pEu  pgXEU4_M     n	nnnnO*[        U R                  5      n[        UR                  5      n	U R                  5       (       d  [        n
[        nO[        n
[        nU R                  5       UR                  5       :w  a  g[        UR                  5       5      [        U	R                  5       5      :w  a  g[        XX’U5      u  pÍ[        U5      (       d  g[!        U5      n/ n[#        U
" US   XÍU5      5      nUR%                  US   U45        UR&                  nUR(                  nSnU(       a³  US   u  nn [+        U5      n[1        UUXÍ5      (       aƒ  [3        U5      UR                  5       S-
  :X  a  UR5                  5       nUUU'   Uv •  Mh  UUU'   UUU'   [7        UUXÍ5        [#        U
" UU   XÍU5      5      nUR%                  UU   U45        US-  nU(       a  M²  ggs  snnnnf s  snnnnf ! [,         aZ    UR/                  5         US-  nU(       a9  US   u  nnUU   nUR/                  U5        UR/                  U5        U" UUXÍ5         GM.  f = f7f)a�  Yields all the possible mappings between G1 and G2.

Parameters
----------
G1, G2 : NetworkX Graph or MultiGraph instances.
    The two graphs to check for isomorphism.

node_label : str, optional
    The name of the node attribute to be used when comparing nodes.
    The default is `None`, meaning node attributes are not considered
    in the comparison. Any node that doesn't have the `node_label`
    attribute uses `default_label` instead.

default_label : scalar
    Default value to use when a node doesn't have an attribute
    named `node_label`. Default is `None`.

Yields
------
dict
    Isomorphic mapping between the nodes in `G1` and `G2`.
r   Fr   éÿÿÿÿN)Únumber_of_nodesÚis_directedÚzipÚ	in_degreeÚ
out_degreeÚdictÚdegreeÚ_find_candidatesÚ_restore_TinoutÚ_find_candidates_DiÚ_restore_Tinout_DiÚorderÚsortedÚvaluesÚ_initialize_parametersÚ_precheck_label_propertiesÚ_matching_orderÚiterÚappendr   r   r   r    ÚpopÚ_feasibilityÚlenÚcopyÚ_update_Tinout)r   r   r   r   Únr)   Ú_r*   Ú	G1_degreeÚ	G2_degreeÚfind_candidatesÚrestore_TinoutÚgraph_paramsÚstate_paramsÚ
node_orderÚstackÚ
candidatesr   r   Úmatching_nodeÚcurrent_nodeÚcandidate_nodesÚ	candidateÚpopped_node1Úpopped_node2Ú
cp_mappings                             r!   r   r   §   s	  é € ð0 
×ÑÓ˜qÓ  B×$6Ñ$6Ó$8¸AÓ$=Øð 
‡~�~×Ñô 47°r·|±|ÀRÇ]Á]Ô3Sö
â3SÑ/‘�¡ ð ˜:Ð&Ò&Ù3Sð 	ó 
ô 47°r·|±|ÀRÇ]Á]Ô3Sö
â3SÑ/‘�¡ ð ˜:Ð&Ò&Ù3Sð 	ó 
ˆ	ô
 ˜Ÿ™“Oˆ	Ü˜Ÿ™“Oˆ	à�>‰>×ÑÜ*ˆÜ(‰ä-ˆÜ+ˆð 
‡x�xƒz�R—X‘X“ZÓØÜˆi×ÑÓ Ó!¤V¨I×,<Ñ,<Ó,>Ó%?Ó?Øô "8Ø
�	 }ó"Ñ€Lô & l×3Ñ3Øô ! Ó.€Jð €EÜÙ˜
 1™ |À9ÓMó€Jð 
‡L�L�*˜Q‘- Ð,Ô-à×"Ñ"€GØ"×2Ñ2€Oð €Mæ
Ø(-¨b©	Ñ%ˆ�oð	Ü˜_Ó-ˆIô ˜ i°×LÑLä�7‹|˜r×1Ñ1Ó3°aÑ7Ó7Ø$Ÿ\™\›^�
Ø+4�
˜<Ñ(Ø Ò Ùð %.ˆG�LÑ!Ø)5ˆO˜IÑ&Ü˜<¨°LÔOäÙØ˜}Ñ-¨|È9óóˆJð
 �L‰L˜* ]Ñ3°ZÐ@ÔAØ˜QÑˆM÷K Š%ùõg
ùõ
øôh ó 	à�I‰IŒKØ˜QÑˆMÞà"'¨¡)‘�˜aØ& |Ñ4�Ø—‘˜LÔ)Ø×#Ñ# LÔ1Ù˜|¨\¸<ÔVÛð	üsK   ‚A$LÁ&J
Á;*LÂ%J&
Â:D8LÇ3J. Ç>BLÊLÊ.ALÌLÌLÌLc                 óf   ^• U u  pp4mpV[        U4S jUR                  5        5       5      (       a  gg)Nc              3   ót   >#   • U  H-  u  pUT;  =(       d    [        TU   5      [        U5      :g  v •  M/     g 7f©N)r;   )Ú.0ÚlabelÚnodesr   s      €r!   Ú	<genexpr>Ú-_precheck_label_properties.<locals>.<genexpr>!  s<   øé € ð â5‰LˆEð 	Ð&Ñ&×U¬#Ð.?ÀÑ.FÓ*GÌ3ÈuË:Ñ*UÔUÚ5ùs   ƒ58FT)ÚanyÚitems)rD   r   r   r	   r
   r   r?   r   s          @r!   r5   r5     s>   ø€ ØLXÑI€BˆIÐ"3Ð5FÜ
ô à-×3Ñ3Ô5ó÷ ñ ð Ør#   c                 óê  • [        U R                  X4S95      n[        UR                  X4S95      n[        U UUU[        R                  R                  U5      [        R                  R                  U5      [        R                  R                  U5      5      n[        5       [        5       p˜[        5       [        5       pºU R                  5       (       aE  [        U R                  5       5      [        5       pÜ[        UR                  5       5      [        5       pþOD[        U R                  5       5      [        5       pÜ[        UR                  5       5      [        5       pþ[        0 0 UU	UUU
UUU5
      nUU4$ )aæ  Initializes all the necessary parameters for VF2++

Parameters
----------
G1,G2: NetworkX Graph or MultiGraph instances.
    The two graphs to check for isomorphism or monomorphism

G1_labels,G2_labels: dict
    The label of every node in G1 and G2 respectively

Returns
-------
graph_params: namedtuple
    Contains all the Graph-related parameters:

    G1,G2
    G1_labels,G2_labels: dict

state_params: namedtuple
    Contains all the State-related parameters:

    mapping: dict
        The mapping as extended so far. Maps nodes of G1 to nodes of G2

    reverse_mapping: dict
        The reverse mapping as extended so far. Maps nodes from G2 to nodes of G1.
        It's basically "mapping" reversed

    T1, T2: set
        Ti contains uncovered neighbors of covered nodes from Gi, i.e. nodes
        that are not in the mapping, but are neighbors of nodes that are.

    T1_out, T2_out: set
        Ti_out contains all the nodes from Gi, that are neither in the mapping
        nor in Ti
)ÚdataÚdefault)	r+   rU   r   ÚnxÚutilsÚgroupsÚsetr'   r   )r   r   rA   r   r   r	   r
   rD   r   r   r   r   r   r   r   r   rE   s                    r!   r4   r4   )  s!  € ôJ �R—X‘X :�XÐEÓF€IÜ�R—X‘X :�XÐEÓF€Iä#Ø
Ø
ØØÜ
�‰�‰˜	Ó"Ü
�‰�‰˜	Ó"Ü
�‰�‰˜	Ó"ó€Lô “”s“uˆÜ“”s“uˆØ	‡~�~×Ñä�—‘“
‹OÜ‹Eð ô !$ B§H¡H£J£´³‘+ä # B§H¡H£J£´³�+Ü # B§H¡H£J£´³�+ä#Ø
Ø
Ø
ØØØØ
ØØØó€Lð ˜Ð%Ð%r#   c                 ó|  ^^^^• U u  mnm  p#nT(       d	  U(       d  0 $ TR                  5       (       a  TR                  SS9m[        TR                  5       5      nUR	                  5        VVs0 s H  u  pVU[        U5      _M     snnmT Vs0 s H  owS_M     snm/ nU(       Ga{  [        UU4S jU 5       5      n	U V
s/ s H  n
TTU
      U	:X  d  M  U
PM     nn
[        UTR                  S9n[        R                  " TU5       GH  nUR                  5       nU(       d  M  [        U4S jU 5       5      nU V
s/ s H  n
TU
   U:X  d  M  U
PM     nn
[        U4S jU 5       5      nU V
s/ s H  n
TR                  U
   U:X  d  M  U
PM     nn
[        UUU4S jS9nUR                  U5        TR                  U5       H  nTU==   S	-  ss'   M     UR                  U5        TTU   ==   S	-  ss'   UR                  U5        U(       a  Mî  GM     U(       a  GM{  U$ s  snnf s  snf s  sn
f s  sn
f s  sn
f )
a/  The node ordering as introduced in VF2++.

Notes
-----
Taking into account the structure of the Graph and the node labeling, the
nodes are placed in an order such that, most of the unfruitful/infeasible
branches of the search space can be pruned on high levels, significantly
decreasing the number of visited states. The premise is that, the algorithm
will be able to recognize inconsistencies early, proceeding to go deep into
the search tree only if it's needed.

Parameters
----------
graph_params: namedtuple
    Contains:

        G1,G2: NetworkX Graph or MultiGraph instances.
            The two graphs to check for isomorphism or monomorphism.

        G1_labels,G2_labels: dict
            The label of every node in G1 and G2 respectively.

Returns
-------
node_order: list
    The ordering of the nodes.
T)Úas_viewr   c              3   ó4   >#   • U  H  nTTU      v •  M     g 7frR   © )rS   Úxr	   Úlabel_raritys     €€r!   rV   Ú"_matching_order.<locals>.<genexpr>   s   øé € ÐJº\¸˜ i°¡lÖ3º\ùs   ƒ)Úkeyc              3   ó.   >#   • U  H
  nTU   v •  M     g 7frR   rd   )rS   r>   Úused_degreess     €r!   rV   rg   ©  s   øé € Ð%Lº|¸! l°1¦oº|ùs   ƒc              3   óB   >#   • U  H  nTR                   U   v •  M     g 7frR   )r,   )rS   r>   r   s     €r!   rV   rg   ­  s   øé € Ð MÒ7L°! §¡¨1¦Ò7Lùs   ƒc                 ó   >• TTU       $ rR   rd   )re   r	   rf   s    €€r!   Ú<lambda>Ú!_matching_order.<locals>.<lambda>²  s   ø€ °LÀÈ1ÁÒ4Nr#   r   )r'   Úto_undirectedr`   rU   rY   r;   ÚminÚmaxr,   r]   Ú
bfs_layersr<   r8   Ú	neighborsÚremoveÚdiscard)rD   r   r?   r   ÚV1_unorderedrT   rU   ÚnoderF   Ú
max_rarityr>   Úrarest_nodesÚmax_nodeÚdlevel_nodesÚnodes_to_addÚmax_used_degreeÚmax_used_degree_nodesÚ
max_degreeÚmax_degree_nodesÚ	next_noder   r	   rf   rj   s                       @@@@r!   r6   r6   w  s,  û€ ð8 5AÑ1€BˆˆI�q˜!°Þ–bØˆ	à	‡~�~×ÑØ×Ñ dÐÐ+ˆä�r—x‘x“z“?€LØ:K×:QÑ:QÔ:SÔTÒ:S©,¨%�Eœ3˜u›:Ò%Ñ:SÒT€LÙ(*Ó+ª ˜!’G©Ñ+€LØ€Jç
ÜÕJ¹\ÓJÓJˆ
á#ó
Ú#�! |°I¸a±LÑ'AÀZÑ'O�A‘|ð 	ð 
ô �|¨¯©Ñ3ˆäŸMšM¨"¨h×7ˆLØ'×,Ñ,Ó.ˆLß�,Ü"%Ô%L¹|Ó%LÓ"L�á+ó)Ú+˜!¨|¸A©À/Ñ/Q—A™|ð &ð )ô !Ô MÑ7LÓ MÓM�
á4ó$Ú4˜!¸¿	¹	À!¹È
Ñ8R—AÑ4ð !ð $ô  Ø$Õ*Nñ�	ð ×!Ñ! )Ô,ØŸL™L¨Ö3�DØ  Ó&¨!Ñ+Õ&ñ 4ð ×#Ñ# IÔ.Ø˜Y yÑ1Ó2°aÑ7Ó2Ø×$Ñ$ YÔ/÷' “,ñ 8÷ ‰,ð< ÐùóE UùÚ+ùò

ùò)ùò$s0   Á.H$ÂH*ÃH/ÃH/Ä>H4ÅH4Å0H9ÆH9c           
      ó‚  • Uu  pEn  pxn	Uu
  p«          p|nX@    Vs/ s H  oÝU
;   d  M
  UPM     nnU(       d¨  [        X†U       5      nUR                  X“U       5        UR                  U5        UR                  U5        UR                  5       (       aI  UR                  U Vs1 s H,  nUR	                  X 5      UR	                  UU5      :w  d  M*  UiM.     sn5        U$ US   n[        XZU      5      nUSS  H  nUR                  XZU      5        M     UR                  U5        UR                  X“U       5        UR                  X†U       5        UR                  5       (       aI  UR                  U Vs1 s H,  nUR	                  X 5      UR	                  UU5      :w  d  M*  UiM.     sn5        U$ s  snf s  snf s  snf )ah  Given node u of G1, finds the candidates of u from G2.

Parameters
----------
u: Graph node
    The node from G1 for which to find the candidates from G2.

graph_params: namedtuple
    Contains all the Graph-related parameters:

    G1,G2: NetworkX Graph or MultiGraph instances.
        The two graphs to check for isomorphism or monomorphism

    G1_labels,G2_labels: dict
        The label of every node in G1 and G2 respectively

state_params: namedtuple
    Contains all the State-related parameters:

    mapping: dict
        The mapping as extended so far. Maps nodes of G1 to nodes of G2

    reverse_mapping: dict
        The reverse mapping as extended so far. Maps nodes from G2 to nodes
        of G1. It's basically "mapping" reversed

    T1, T2: set
        Ti contains uncovered neighbors of covered nodes from Gi, i.e. nodes
        that are not in the mapping, but are neighbors of nodes that are.

    T1_tilde, T2_tilde: set
        Ti_tilde contains all the nodes from Gi, that are neither in the
        mapping nor in Ti

Returns
-------
candidates: set
    The nodes from G2 which are candidates for u.
r   r   N)r`   Úintersection_updateÚdifference_updateÚis_multigraphÚnumber_of_edges)ÚurD   rE   r@   r   r   r	   r?   r   r   r   r   r   ÚnbrÚcovered_nbrsrH   rw   Únbr1Úcommon_nodess                      r!   r-   r-   À  sß  € ðT FRÑB€BˆI�q˜!Ð0BØ>JÑ;€G˜a  A q¨!¨Q¸!à#%¢5Ó;¢5˜C°7©N—C¡5€LÐ;ÞÜÐ*°Q©<Ñ8Ó9ˆ
Ø×&Ñ&Ð'9ÀA¹,Ñ'GÔHØ×&Ñ& xÔ0Ø×$Ñ$ _Ô5Ø×Ñ×ÑØ×(Ñ(ñ !+óâ *˜Ø×)Ñ)¨!Ó/°2×3EÑ3EÀdÈDÓ3QÑQ÷ Ù *ñôð Ðà˜‰?€DÜ�r $™-Ñ(Ó)€Là˜Q˜RÓ ˆØ×(Ñ(¨°D©MÑ):Ö;ñ !ð ×"Ñ" ?Ô3Ø×$Ñ$Ð%7À!¹Ñ%EÔFØ×$Ñ$Ð%6À±|Ñ%DÔEØ	×Ñ×ÑØ×&Ñ&ñ )óâ(�DØ×%Ñ% aÓ+¨r×/AÑ/AÀ$ÈÓ/MÑM÷ Ù(ñô	
ð ÐùòC <ùòùò&s"   š	F2§F2Â")F7ÃF7Å6)F<Æ#F<c           
      ó   • Uu  pEn  pxn	Uu
  p«          p|nX@    Vs/ s H  oÝU
;   d  M
  UPM     nnUR                   U     Vs/ s H  oÿU
;   d  M
  UPM     nnU(       d¯  U(       d¨  [        X†U       5      nUR                  X“U       5        UR                  U5        UR                  U5        UR	                  5       (       aI  UR                  U Vs1 s H,  nUR                  X 5      UR                  UU5      :w  d  M*  UiM.     sn5        U$ U(       aN  US   n[        UR                   U
U      5      nUSS   H$  nUR                  UR                   U
U      5        M&     O UR                  5       n[        XZU      5      nU H  nUR                  XZU      5        M     UR                  U5        UR                  X“U       5        UR                  X†U       5        UR	                  5       (       aI  UR                  U Vs1 s H,  nUR                  X 5      UR                  UU5      :w  d  M*  UiM.     sn5        U$ s  snf s  snf s  snf s  snf )Nr   r   )Úpredr`   rƒ   r„   r…   r†   r9   )r‡   rD   rE   r@   r   r   r	   r?   r   r   r   r   r   ÚsuccÚcovered_successorsr�   Úcovered_predecessorsrH   rw   Úsucc1r‹   Úpred1s                         r!   r/   r/     sS  € ØEQÑB€BˆI�q˜!Ð0BØ>JÑ;€G˜a  A q¨!¨Q¸!à+-ª5ÓDª5 4¸G±OŸ$©5ÐÐDØ-/¯W©W°QªZÓKªZ TÀ7¹?ŸD©ZÐÐKæÖ"6ÜÐ*°Q©<Ñ8Ó9ˆ
Ø×&Ñ&Ð'9ÀA¹,Ñ'GÔHØ×&Ñ& xÔ0Ø×$Ñ$ _Ô5Ø×Ñ×ÑØ×(Ñ(ñ !+óâ *˜Ø×)Ñ)¨!Ó/°2×3EÑ3EÀdÈDÓ3QÑQ÷ Ù *ñôð ÐæØ" 1Ñ%ˆÜ˜2Ÿ7™7 7¨5¡>Ñ2Ó3ˆà'¨¨Ó+ˆEØ×,Ñ,¨R¯W©W°W¸U±^Ñ-DÖEò ,ð %×(Ñ(Ó*ˆÜ˜2 e™nÑ-Ó.ˆã%ˆØ×(Ñ(¨°E©NÑ);Ö<ñ &ð ×"Ñ" ?Ô3Ø×$Ñ$Ð%7À!¹Ñ%EÔFØ×$Ñ$Ð%6À±|Ñ%DÔEØ	×Ñ×ÑØ×&Ñ&ñ )óâ(�DØ×%Ñ% aÓ+¨r×/AÑ/AÀ$ÈÓ/MÑM÷ Ù(ñô	
ð ÐùòU EùÚKùòùò4s.   š	H<§H<Á 	IÁIÃ)IÃ<IÈ )IÈ-Ic                 óŽ   • UR                   n[        XX#5      (       a  gUR                  5       (       a  [        XX#5      (       d  gg)a'  Given a candidate pair of nodes u and v from G1 and G2 respectively,
checks if it's feasible to extend the mapping, i.e. if u and v can be matched.

Notes
-----
This function performs all the necessary checking by applying both consistency
and cutting rules.

Parameters
----------
node1, node2: Graph node
    The candidate pair of nodes being checked for matching

graph_params: namedtuple
    Contains all the Graph-related parameters:

    G1,G2: NetworkX Graph or MultiGraph instances.
        The two graphs to check for isomorphism or monomorphism

    G1_labels,G2_labels: dict
        The label of every node in G1 and G2 respectively

state_params: namedtuple
    Contains all the State-related parameters:

    mapping: dict
        The mapping as extended so far. Maps nodes of G1 to nodes of G2

    reverse_mapping: dict
        The reverse mapping as extended so far. Maps nodes from G2 to nodes
        of G1. It's basically "mapping" reversed

    T1, T2: set
        Ti contains uncovered neighbors of covered nodes from Gi, i.e. nodes
        that are not in the mapping, but are neighbors of nodes that are.

    T1_out, T2_out: set
        Ti_out contains all the nodes from Gi, that are neither in the mapping
        nor in Ti

Returns
-------
True if all checks are successful, False otherwise.
FT)r   Ú_cut_PTr…   Ú_consistent_PT)Únode1Únode2rD   rE   r   s        r!   r:   r:   B  s@   € ðZ 
�‰€Bäˆu˜\×8Ñ8Øà	×Ñ×ÑÜ˜e¨L×GÑGØàr#   c           
      óJ  ^ ^^^• Uu  mmpE    nUu
  nnnnn	nn
nnn0 0 píTR                  5       (       aµ  [        R                  R                  TR                  T     Vs0 s H  oÿXO   _M	     sn5      n[        R                  R                  TR                  T    Vs0 s H	  nUUU   _M     sn5      n[        UR                  5       5      [        UR                  5       5      :w  a  g[        R                  R                  TT     Vs0 s H  oÿXO   _M	     sn5      n[        R                  R                  TT    Vs0 s H	  nUUU   _M     sn5      n[        UR                  5       5      [        UR                  5       5      :w  a  gUR                  5        GH/  u  nnUU   nTR                  5       (       aO  [        UU 4S jU 5       5      n[        UU4S jU 5       5      n[        S [        UU5       5       5      (       a    g[        UR                  U5      5      [        U
R                  U5      5      :w  a    g[        U	R                  U5      5      [        UR                  U5      5      :w  a    gTR                  5       (       d  M÷  [        UR                  U5      5      [        UR                  U5      5      :w  d  GM0    g   TR                  5       (       d  gUR                  5        GH  u  nnUU   nTR                  5       (       aO  [        UU 4S jU 5       5      n[        UU4S jU 5       5      n[        S [        UU5       5       5      (       a    g[        UR                  U5      5      [        U
R                  U5      5      :w  a    g[        U	R                  U5      5      [        UR                  U5      5      :w  a    g[        UR                  U5      5      [        UR                  U5      5      :w  d  GM    g   gs  snf s  snf s  snf s  snf )	as  Implements the cutting rules for the ISO problem.

Parameters
----------
u, v: Graph node
    The two candidate nodes being examined.

graph_params: namedtuple
    Contains all the Graph-related parameters:

    G1,G2: NetworkX Graph or MultiGraph instances.
        The two graphs to check for isomorphism or monomorphism

    G1_labels,G2_labels: dict
        The label of every node in G1 and G2 respectively

state_params: namedtuple
    Contains all the State-related parameters:

    mapping: dict
        The mapping as extended so far. Maps nodes of G1 to nodes of G2

    reverse_mapping: dict
        The reverse mapping as extended so far. Maps nodes from G2 to nodes
        of G1. It's basically "mapping" reversed

    T1, T2: set
        Ti contains uncovered neighbors of covered nodes from Gi, i.e. nodes
        that are not in the mapping, but are neighbors of nodes that are.

    T1_tilde, T2_tilde: set
        Ti_out contains all the nodes from Gi, that are neither in the
        mapping nor in Ti

Returns
-------
True if we should prune this branch, i.e. the node pair failed the cutting checks. False otherwise.
Tc              3   óH   >#   • U  H  nTR                  TU5      v •  M     g 7frR   ©r†   ©rS   re   r   r‡   s     €€r!   rV   Ú_cut_PT.<locals>.<genexpr>È  ó!   øé € Ð!KÂF¸q "×"4Ñ"4°Q¸×":Ð":ÂFùó   ƒ"c              3   óH   >#   • U  H  nTR                  TU5      v •  M     g 7frR   rš   ©rS   re   r   Úvs     €€r!   rV   rœ   É  r�   rž   c              3   ó.   #   • U  H  u  pX:g  v •  M     g 7frR   rd   ©rS   Úu_nbr_edgesÚv_nbr_edgess      r!   rV   rœ   Ê  ó   é € ð â0OÑ,�Kð Ö*Ú0Oùó   ‚Fc              3   óH   >#   • U  H  nTR                  TU5      v •  M     g 7frR   rš   r›   s     €€r!   rV   rœ   á  ó!   øé € Ð!LÂG¸q "×"4Ñ"4°Q¸×":Ð":ÂGùrž   c              3   óH   >#   • U  H  nTR                  TU5      v •  M     g 7frR   rš   r    s     €€r!   rV   rœ   â  r©   rž   c              3   ó.   #   • U  H  u  pX:g  v •  M     g 7frR   rd   r£   s      r!   rV   rœ   ã  r¦   r§   )r'   r]   r^   r_   r�   r`   ÚkeysrY   r…   r2   rX   r(   r;   Úintersection)r‡   r¡   rD   rE   r	   r
   r?   r   r   r   r   r   r   Úu_labels_predecessorsÚv_labels_predecessorsÚn1Ún2Úu_labels_successorsÚv_labels_successorsrT   ÚG1_nbhÚG2_nbhÚu_nbrs_edgesÚv_nbrs_edgesÚG1_predÚG2_predÚu_pred_edgesÚv_pred_edgesr   r   s   ``                          @@r!   r”   r”   {  s–  û€ ðN -9Ñ)€BˆˆI ! Q¨ð 	ñØ	Ø	Ø
ØØØ	Ø
ØØØ	ð 46°rÐ0Ø	‡~�~×ÑÜ "§¡§¡Ø)+¯©°ªÓ4ª 2�‘Ò©Ñ4ó!
Ðô !#§¡§¡Ø)+¯©°ªÓ4ª 2ˆR�˜2‘Ò©Ñ4ó!
Ðô Ð$×)Ñ)Ó+Ó,´Ð4I×4NÑ4NÓ4PÓ0QÓQØäŸ(™(Ÿ/™/ÀrÈ!ÂuÓ*MÂuÀ¨y©}Ò+<ÁuÑ*MÓNÐÜŸ(™(Ÿ/™/ÀrÈ!ÂuÓ*MÂuÀ¨2¨y¸©}Ò+<ÁuÑ*MÓNÐô Ð×#Ñ#Ó%Ó&¬#Ð.A×.FÑ.FÓ.HÓ*IÓIØà,×2Ñ2×4‰ˆˆvØ$ UÑ+ˆà×Ñ×Ñä!Õ!KÁFÓ!KÓKˆLÜ!Õ!KÁFÓ!KÓKˆLÜñ ä03°LÀ,Ô0Oó÷ ñ ñ äˆr�‰˜vÓ&Ó'¬3¨r¯©¸vÓ/FÓ+GÓGÙÜˆx×$Ñ$ VÓ,Ó-´°X×5JÑ5JÈ6Ó5RÓ1SÓSÙØ�>‰>×Ó¤ E×$6Ñ$6°vÓ$>Ó ?Ä3Ø×Ñ˜vÓ&óD
ö !
ñ ñ) 5ð, �>‰>×ÑØà/×5Ñ5×7‰ˆˆwØ'¨Ñ.ˆà×Ñ×Ñä!Õ!LÁGÓ!LÓLˆLÜ!Õ!LÁGÓ!LÓLˆLÜñ ä03°LÀ,Ô0Oó÷ ñ ñ äˆr�‰˜wÓ'Ó(¬C°·±ÀÓ0HÓ,IÓIÙÜˆx×$Ñ$ WÓ-Ó.´#°h×6KÑ6KÈGÓ6TÓ2UÓUÙÜˆu×!Ñ! 'Ó*Ó+¬s°5×3EÑ3EÀgÓ3NÓ/OÖOÙñ% 8ð( ùò{ 5ùò 5ùò +NùÚ*Ms   ÁPÂPÄPÄ=P c                 ó�  • UR                   UR                  pTUR                  UR                  pvX@    H3  nX†;   d  M
  UR	                  X5      UR	                  XU   5      :w  d  M3    g   XQ    H3  nX‡;   d  M
  UR	                  XU   5      UR	                  X5      :w  d  M3    g   UR                  5       (       d  gUR                  U     H3  n	X–;   d  M
  UR	                  X�5      UR	                  Xi   U5      :w  d  M3    g   UR                  U    H3  n	X—;   d  M
  UR	                  Xy   U 5      UR	                  X‘5      :w  d  M3    g   g)ax  Checks the consistency of extending the mapping using the current node pair.

Parameters
----------
u, v: Graph node
    The two candidate nodes being examined.

graph_params: namedtuple
    Contains all the Graph-related parameters:

    G1,G2: NetworkX Graph or MultiGraph instances.
        The two graphs to check for isomorphism or monomorphism

    G1_labels,G2_labels: dict
        The label of every node in G1 and G2 respectively

state_params: namedtuple
    Contains all the State-related parameters:

    mapping: dict
        The mapping as extended so far. Maps nodes of G1 to nodes of G2

    reverse_mapping: dict
        The reverse mapping as extended so far. Maps nodes from G2 to nodes of G1.
        It's basically "mapping" reversed

    T1, T2: set
        Ti contains uncovered neighbors of covered nodes from Gi, i.e. nodes
        that are not in the mapping, but are neighbors of nodes that are.

    T1_out, T2_out: set
        Ti_out contains all the nodes from Gi, that are neither in the mapping
        nor in Ti

Returns
-------
True if the pair passes all the consistency checks successfully. False otherwise.
FT)r   r   r   r   r†   r'   r�   )
r‡   r¡   rD   rE   r   r   r   r   ÚneighborÚpredecessors
             r!   r•   r•   ó  sL  € ðN �_‰_˜lŸo™oˆØ+×3Ñ3°\×5QÑ5Qˆ_à”EˆØÕØ×!Ñ! !Ó.°"×2DÑ2DØ˜8Ñ$ó3õ ñ ñ ð ”EˆØÕ&Ø×!Ñ! !°XÑ%>Ó?À2×CUÑCUØóDõ ñ ñ ð �>‰>×ÑØà—w‘w˜q”zˆØÕ!Ø×!Ñ! +Ó1°R×5GÑ5GØÑ$ aó6õ ñ ñ "ð —w‘w˜q”zˆØÕ)Ø×!Ñ!ØÑ,¨aóà×#Ñ# KÓ3õ4ñ ñ "ð r#   c           
      ó°  • Uu  pE        nUu
  nnn	n
nnnnnnX@    Vs1 s H  nUU;  d  M  UiM     nnXQ    Vs1 s H  nUU;  d  M  UiM     nnU	R                  U5        UR                  U5        U	R                  U 5        UR                  U5        UR                  U5        UR                  U5        UR                  U 5        UR                  U5        UR                  5       (       d  gUR                  U     Vs1 s H  nUU;  d  M  UiM     nnUR                  U    Vs1 s H  nUU;  d  M  UiM     nnU
R                  U5        UR                  U5        U
R                  U 5        UR                  U5        UR                  U5        UR                  U5        UR                  U 5        UR                  U5        gs  snf s  snf s  snf s  snf )aã  Updates the Ti/Ti_out (i=1,2) when a new node pair u-v is added to the mapping.

Notes
-----
This function should be called right after the feasibility checks are passed,
and node1 is mapped to node2. The purpose of this function is to avoid brute
force computing of Ti/Ti_out by iterating over all nodes of the graph and
checking which nodes satisfy the necessary conditions. Instead, in every step
of the algorithm we focus exclusively on the two nodes that are being added
to the mapping, incrementally updating Ti/Ti_out.

Parameters
----------
new_node1, new_node2: Graph node
    The two new nodes, added to the mapping.

graph_params: namedtuple
    Contains all the Graph-related parameters:

    G1,G2: NetworkX Graph or MultiGraph instances.
        The two graphs to check for isomorphism or monomorphism

    G1_labels,G2_labels: dict
        The label of every node in G1 and G2 respectively

state_params: namedtuple
    Contains all the State-related parameters:

    mapping: dict
        The mapping as extended so far. Maps nodes of G1 to nodes of G2

    reverse_mapping: dict
        The reverse mapping as extended so far. Maps nodes from G2 to nodes of G1.
        It's basically "mapping" reversed

    T1, T2: set
        Ti contains uncovered neighbors of covered nodes from Gi, i.e. nodes
        that are not in the mapping, but are neighbors of nodes that are.

    T1_tilde, T2_tilde: set
        Ti_out contains all the nodes from Gi, that are neither in the mapping nor in Ti
N)Úupdateru   r„   r'   r�   )Ú	new_node1Ú	new_node2rD   rE   r   r   r?   r   r   r   r   r   r   r   r   r   r   rŽ   Úuncovered_successors_G1Úuncovered_successors_G2r�   Úuncovered_predecessors_G1Úuncovered_predecessors_G2s                          r!   r=   r=   ?  sä  € ðV )Ñ€BˆAˆq�!�Q˜ð 	ñØØØ
ØØØØ
ØØØð 13²ÓU²¨ÀÈWÑATŸt±ÐÐUàšóÚ&�¨$°oÑ*E�™ð ð ð
 ‡I�IÐ%Ô&Ø‡I�IÐ%Ô&Ø‡J�JˆyÔØ‡J�JˆyÔà×ÑÐ6Ô7Ø×ÑÐ6Ô7Ø×Ñ�YÔØ×Ñ�YÔà�>‰>×ÑØð Ÿ™ Ò+ó!Ú+�¨t¸7Ñ/B�Ñ+ð ð !ð Ÿ™ Ò+ó!Ú+�¨t¸?Ñ/J�Ñ+ð ð !ð 
‡L�LÐ*Ô+Ø	‡L�LÐ*Ô+Ø	‡M�M�)ÔØ	‡M�M�)Ôà×ÑÐ8Ô9Ø×ÑÐ8Ô9Ø×Ñ�YÔØ×Ñ�YÕùòE Vùòùò$!ùò!s-   �
G«G¹
G	ÁG	Ã>
GÄGÄ%
GÄ3Gc           
      ó:  ^^• Uu  pE        nUu
  mmnnn	n
nnnnSnX@    H_  nUT;   a  SnUR                  U 5        M  [        U4S jUU    5       5      (       a  M=  UR                  U5        U	R                  U5        Ma     U(       d  U	R                  U 5        SnXQ    H_  nUT;   a  SnUR                  U5        M  [        U4S jUU    5       5      (       a  M=  UR                  U5        UR                  U5        Ma     U(       d  UR                  U5        gg)a;  Restores the previous version of Ti/Ti_out when a node pair is deleted
from the mapping.

Parameters
----------
popped_node1, popped_node2: Graph node
    The two nodes deleted from the mapping.

graph_params: namedtuple
    Contains all the Graph-related parameters:

    G1,G2: NetworkX Graph or MultiGraph instances.
        The two graphs to check for isomorphism or monomorphism

    G1_labels,G2_labels: dict
        The label of every node in G1 and G2 respectively

state_params: namedtuple
    Contains all the State-related parameters:

    mapping: dict
        The mapping as extended so far. Maps nodes of G1 to nodes of G2

    reverse_mapping: dict
        The reverse mapping as extended so far. Maps nodes from G2 to nodes of G1.
        It's basically "mapping" reversed

    T1, T2: set
        Ti contains uncovered neighbors of covered nodes from Gi, i.e. nodes
        that are not in the mapping, but are neighbors of nodes that are.

    T1_tilde, T2_tilde: set
        Ti_out contains all the nodes from Gi, that are neither in the mapping
        nor in Ti
FTc              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   )rS   rˆ   r   s     €r!   rV   Ú"_restore_Tinout.<locals>.<genexpr>Ú  s   øé € Ð:ª\ c˜'–>ª\ùó   ƒc              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   )rS   rˆ   r   s     €r!   rV   rÉ   ê  s   øé € ÐB²\¨c˜/Ö)²\ùrÊ   N)ÚaddrX   ru   )rM   rN   rD   rE   r   r   r?   r   r   r   r   r   r   r   r   Úis_addedr½   r   r   s                    @@r!   r.   r.   �  s!  ù€ ðL )Ñ€BˆAˆq�!�Q˜ð 	ñØØØ
ØØØØ
ØØØð €HØÔ$ˆØ�wÓàˆHØ�F‰F�<Ö ô Ô:¨R°ª\Ó:×:Ñ:ÙØ�J‰J�xÔ Ø�L‰L˜Ö"ñ %ö Ø�‰�\Ô"à€HØÔ$ˆØ�Ó&ØˆHØ�F‰F�<Ö äÔB°R¸²\ÓB×BÑBÙØ�J‰J�xÔ Ø�L‰L˜Ö"ñ %ö Ø�‰�\Õ"ð r#   c           
      ó2  ^^• Uu  pE        nUu
  mmnnn	n
nnnnSnX@    H¥  nUT;   a  SnUR                  U 5        M  [        U4S jUR                  U    5       5      (       d  UR                  U5        [        U4S jUU    5       5      (       d  UR                  U5        UU;  d  MŒ  UU;  d  M”  U	R                  U5        M§     UR                  U     H¥  nUT;   a  SnUR                  U 5        M  [        U4S jUR                  U    5       5      (       d  UR                  U5        [        U4S jUU    5       5      (       d  UR                  U5        UU;   a  MŒ  UU;   a  M”  U	R                  U5        M§     U(       d  U	R                  U 5        SnXQ    H¥  nUT;   a  SnUR                  U5        M  [        U4S jUR                  U    5       5      (       d  UR                  U5        [        U4S jUU    5       5      (       d  UR                  U5        UU;  d  MŒ  UU;  d  M”  UR                  U5        M§     UR                  U    H¥  nUT;   a  SnUR                  U5        M  [        U4S	 jUR                  U    5       5      (       d  UR                  U5        [        U4S
 jUU    5       5      (       d  UR                  U5        UU;   a  MŒ  UU;   a  M”  UR                  U5        M§     U(       d  UR                  U5        g g )NFTc              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   ©rS   r�   r   s     €r!   rV   Ú%_restore_Tinout_Di.<locals>.<genexpr>  s   øé € ÐFÒ3E¨4˜w–Ò3EùrÊ   c              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   ©rS   rŽ   r   s     €r!   rV   rÑ     s   øé € ÐA²=¨4˜w–²=ùrÊ   c              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   rÐ   s     €r!   rV   rÑ     s   øé € ÐHÒ3G¨4˜w–Ò3GùrÊ   c              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   rÓ   s     €r!   rV   rÑ   !  s   øé € ÐC²?¨4˜w–²?ùrÊ   c              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   ©rS   r�   r   s     €r!   rV   rÑ   2  s   øé € ÐNÒ;M°4˜Ö.Ò;MùrÊ   c              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   ©rS   rŽ   r   s     €r!   rV   rÑ   5  s   øé € ÐIº=°4˜Ö.º=ùrÊ   c              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   r×   s     €r!   rV   rÑ   D  s   øé € ÐPÒ;O°4˜Ö.Ò;OùrÊ   c              3   ó,   >#   • U  H	  oT;   v •  M     g 7frR   rd   rÙ   s     €r!   rV   rÑ   G  s   øé € ÐKº?°4˜Ö.º?ùrÊ   )rÌ   rX   r�   ru   )rM   rN   rD   rE   r   r   r?   r   r   r   r   r   r   r   r   rÍ   Ú	successorr¾   r   r   s                     @@r!   r0   r0   ó  s¨  ù€ à(Ñ€BˆAˆq�!�Q˜ð 	ñØØØ
ØØØØ
ØØØð €HØÔ%ˆ	Ø˜ÓàˆHØ�I‰I�lÖ#ô ÔF°2·7±7¸9Ò3EÓF×FÑFØ—
‘
˜9Ô%äÔA°2°i²=ÓA×AÑAØ—‘˜iÔ(à Õ"Ø EÕ)Ø—L‘L Ö+ñ! &ð$ —w‘w˜|Ô,ˆØ˜'Ó!àˆHØ�F‰F�<Ö ô ÔH°2·7±7¸;Ò3GÓH×HÑHØ—
‘
˜;Ô'äÔC°2°k²?ÓC×CÑCØ—‘˜kÔ*à 2Õ%¨¸Õ)=Ø—‘˜[Ö)ñ -ö& Ø�‰�\Ô"à€HØÔ%ˆ	Ø˜Ó'ØˆHØ�I‰I�lÖ#äÔN¸2¿7¹7À9Ò;MÓN×NÑNØ—
‘
˜9Ô%äÔI¸2¸iº=ÓI×IÑIØ—‘˜iÔ(à Õ"Ø EÕ)Ø—L‘L Ö+ñ &ð —w‘w˜|Ô,ˆØ˜/Ó)àˆHØ�F‰F�<Ö ô ÔP¸2¿7¹7À;Ò;OÓP×PÑPØ—
‘
˜;Ô'äÔK¸2¸kº?ÓK×KÑKØ—‘˜kÔ*à 2Õ%¨¸Õ)=Ø—‘˜[Ö)ñ -ö" Ø�‰�\Õ"ð r#   )NN)Nr%   )Ú__doc__ÚcollectionsÚnetworkxr]   Ú__all__Ú
namedtupler   r   Ú_dispatchabler   r   r   r5   r4   r6   r-   r/   r:   r”   r•   r=   r.   r0   rd   r#   r!   Ú<module>rã      s  ðñDóL ã â
P€à×)Ò)ØòóÐ ð ×)Ò)ØòóÐ ð" ×Ò ¨Ñ+¸ÀÐ8WÑXóó Yðð< ×Ò ¨Ñ+¸ÀÐ8WÑXóó Yðð8 ×Ò ¨Ñ+¸ÀÐ8WÑXótó YðtònôK&ò\FòRNòb.òb6òruòpIòX[ ò|S#ól[#r#   