
    wg                         d Z ddlmZ g dZd Z G d dej                        Z G d dej                        Z G d	 d
e      Z G d de      Z	y)a  
Module to simplify the specification of user-defined equality functions for
node and edge attributes during isomorphism checks.

During the construction of an isomorphism, the algorithm considers two
candidate nodes n1 in G1 and n2 in G2.  The graphs G1 and G2 are then
compared with respect to properties involving n1 and n2, and if the outcome
is good, then the candidate nodes are considered isomorphic. NetworkX
provides a simple mechanism for users to extend the comparisons to include
node and edge attributes.

Node attributes are handled by the node_match keyword. When considering
n1 and n2, the algorithm passes their node attribute dictionaries to
node_match, and if it returns False, then n1 and n2 cannot be
considered to be isomorphic.

Edge attributes are handled by the edge_match keyword. When considering
n1 and n2, the algorithm must verify that outgoing edges from n1 are
commensurate with the outgoing edges for n2. If the graph is directed,
then a similar check is also performed for incoming edges.

Focusing only on outgoing edges, we consider pairs of nodes (n1, v1) from
G1 and (n2, v2) from G2. For graphs and digraphs, there is only one edge
between (n1, v1) and only one edge between (n2, v2). Those edge attribute
dictionaries are passed to edge_match, and if it returns False, then
n1 and n2 cannot be considered isomorphic. For multigraphs and
multidigraphs, there can be multiple edges between (n1, v1) and also
multiple edges between (n2, v2).  Now, there must exist an isomorphism
from "all the edges between (n1, v1)" to "all the edges between (n2, v2)".
So, all of the edge attribute dictionaries are passed to edge_match, and
it must determine if there is an isomorphism between the two sets of edges.
   )isomorphvf2)GraphMatcherDiGraphMatcherMultiGraphMatcherMultiDiGraphMatcherc                    | j                   C| j                  | j                  j                  |   | j                  j                  |         }|sy| j                  y| j
                  |   }| j                  |   }| j                  }| j                  }|D ]>  }||k(  r||v s |||   ||         r y||v s$||   }	|	|v s. |||   ||	         r> y y)DReturns True if mapping G1_node to G2_node is semantically feasible.FT)
node_matchG1nodesG2
edge_matchG1_adjG2_adjcore_1)
selfG1_nodeG2_nodenmG1nbrsG2nbrsr   r   neighborG2_nbrs
             p/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/algorithms/isomorphism/vf2userfunc.py_semantic_feasibilityr   '   s     "__TWW]]73TWW]]75KL "W%W%__
 	!H7"f$Z7OVG_. !V#)V#J8$fVn- !	!     c                       e Zd ZdZddZeZy)r   z.VF2 isomorphism checker for undirected graphs.Nc                     t         j                  j                  | ||       || _        || _        | j
                  j                  | _        | j                  j                  | _	        y)a  Initialize graph matcher.

        Parameters
        ----------
        G1, G2: graph
            The graphs to be tested.

        node_match: callable
            A function that returns True iff node n1 in G1 and n2 in G2
            should be considered equal during the isomorphism test. The
            function will be called like::

               node_match(G1.nodes[n1], G2.nodes[n2])

            That is, the function will receive the node attribute dictionaries
            of the nodes under consideration. If None, then no attributes are
            considered when testing for an isomorphism.

        edge_match: callable
            A function that returns True iff the edge attribute dictionary for
            the pair of nodes (u1, v1) in G1 and (u2, v2) in G2 should be
            considered equal during the isomorphism test. The function will be
            called like::

               edge_match(G1[u1][v1], G2[u2][v2])

            That is, the function will receive the edge attribute dictionaries
            of the edges under consideration. If None, then no attributes are
            considered when testing for an isomorphism.

        N)
vf2r   __init__r
   r   r   adjr   r   r   r   r   r   r
   r   s        r   r    zGraphMatcher.__init__L   sK    @ 	!!$B/$$ ggkkggkkr   NN)__name__
__module____qualname____doc__r    r   semantic_feasibility r   r   r   r   I   s    8'"R 1r   r   c                       e Zd ZdZddZd Zy)r   z,VF2 isomorphism checker for directed graphs.Nc                     t         j                  j                  | ||       || _        || _        | j
                  j                  | _        | j                  j                  | _	        y)a  Initialize graph matcher.

        Parameters
        ----------
        G1, G2 : graph
            The graphs to be tested.

        node_match : callable
            A function that returns True iff node n1 in G1 and n2 in G2
            should be considered equal during the isomorphism test. The
            function will be called like::

               node_match(G1.nodes[n1], G2.nodes[n2])

            That is, the function will receive the node attribute dictionaries
            of the nodes under consideration. If None, then no attributes are
            considered when testing for an isomorphism.

        edge_match : callable
            A function that returns True iff the edge attribute dictionary for
            the pair of nodes (u1, v1) in G1 and (u2, v2) in G2 should be
            considered equal during the isomorphism test. The function will be
            called like::

               edge_match(G1[u1][v1], G2[u2][v2])

            That is, the function will receive the edge attribute dictionaries
            of the edges under consideration. If None, then no attributes are
            considered when testing for an isomorphism.

        N)
r   r   r    r
   r   r   r!   r   r   r   r"   s        r   r    zDiGraphMatcher.__init__{   sK    @ 	##D"b1$$ ggkkggkkr   c                    t        | ||      }|sy| j                  j                  | _        | j                  j                  | _        t        | ||      }| j                  j                  | _        | j                  j                  | _        |S )r	   F)r   r   predr   r   r   r!   )r   r   r   feasibles       r   r(   z#DiGraphMatcher.semantic_feasibility   si     )w@ ggllggll(w@ggkkggkkr   r#   )r$   r%   r&   r'   r    r(   r)   r   r   r   r   x   s    6'"Rr   r   c                       e Zd ZdZy)r   z3VF2 isomorphism checker for undirected multigraphs.Nr$   r%   r&   r'   r)   r   r   r   r      s    =r   r   c                       e Zd ZdZy)r   z1VF2 isomorphism checker for directed multigraphs.Nr0   r)   r   r   r   r      s    ;r   r   N)
r'    r   r   __all__r   r   r   r   r   r)   r   r   <module>r4      sY   B !
XD,13## ,1^;S'' ;F> ><. <r   