o
    ˷eE                     @   sB   d Z ddlmZ ddlZddlmZmZ dgZeddd Z	dS )u  
Algorithm for testing d-separation in DAGs.

*d-separation* is a test for conditional independence in probability
distributions that can be factorized using DAGs.  It is a purely
graphical test that uses the underlying graph and makes no reference
to the actual distribution parameters.  See [1]_ for a formal
definition.

The implementation is based on the conceptually simple linear time
algorithm presented in [2]_.  Refer to [3]_, [4]_ for a couple of
alternative algorithms.


Examples
--------

>>>
>>> # HMM graph with five states and observation nodes
... g = nx.DiGraph()
>>> g.add_edges_from(
...     [
...         ("S1", "S2"),
...         ("S2", "S3"),
...         ("S3", "S4"),
...         ("S4", "S5"),
...         ("S1", "O1"),
...         ("S2", "O2"),
...         ("S3", "O3"),
...         ("S4", "O4"),
...         ("S5", "O5"),
...     ]
... )
>>>
>>> # states/obs before 'S3' are d-separated from states/obs after 'S3'
... nx.d_separated(g, {"S1", "S2", "O1", "O2"}, {"S4", "S5", "O4", "O5"}, {"S3"})
True


References
----------

.. [1] Pearl, J.  (2009).  Causality.  Cambridge: Cambridge University Press.

.. [2] Darwiche, A.  (2009).  Modeling and reasoning with Bayesian networks. 
   Cambridge: Cambridge University Press.

.. [3] Shachter, R.  D.  (1998).
   Bayes-ball: rational pastime (for determining irrelevance and requisite
   information in belief networks and influence diagrams).
   In , Proceedings of the Fourteenth Conference on Uncertainty in Artificial
   Intelligence (pp.  480–487).
   San Francisco, CA, USA: Morgan Kaufmann Publishers Inc.

.. [4] Koller, D., & Friedman, N. (2009).
   Probabilistic graphical models: principles and techniques. The MIT Press.

    )dequeN)	UnionFindnot_implemented_ford_separated
undirectedc                    s@  t  s
t d|||}t fdd|D r"t d  tfddjD }t	|dkr_|
 }||vrY|D ]}j| dkrS|| qE| t	|dks8t|}| t }	t D ]}
|	j|
  qv|	j|  |	j|  |r|r|	tt| |	tt| krd	S d
S )a:  
    Return whether node sets ``x`` and ``y`` are d-separated by ``z``.

    Parameters
    ----------
    G : graph
        A NetworkX DAG.

    x : set
        First set of nodes in ``G``.

    y : set
        Second set of nodes in ``G``.

    z : set
        Set of conditioning nodes in ``G``. Can be empty set.

    Returns
    -------
    b : bool
        A boolean that is true if ``x`` is d-separated from ``y`` given ``z`` in ``G``.

    Raises
    ------
    NetworkXError
        The *d-separation* test is commonly used with directed
        graphical models which are acyclic.  Accordingly, the algorithm
        raises a :exc:`NetworkXError` if the input graph is not a DAG.

    NodeNotFound
        If any of the input nodes are not found in the graph,
        a :exc:`NodeNotFound` exception is raised.

    z graph should be directed acyclicc                 3   s    | ]}| j vV  qd S )N)nodes.0n)G W/var/www/ideatree/venv/lib/python3.10/site-packages/networkx/algorithms/d_separation.py	<genexpr>n   s    zd_separated.<locals>.<genexpr>z2one or more specified nodes not found in the graphc                    s   g | ]} j | d kr|qS )r   )
out_degreer   )G_copyr   r   
<listcomp>u   s    zd_separated.<locals>.<listcomp>r      FT)nxis_directed_acyclic_graphNetworkXErrorunionanyNodeNotFoundcopyr   r   lenpopleftpredecessorsr   appendremove_nodelist	out_edgesremove_edges_fromr   weakly_connected_componentsnextiter)r   xyz	union_xyzleavesleafpedges_to_removedisjoint_set	componentr   )r   r   r   r   D   s4   
%







()
__doc__collectionsr   networkxr   networkx.utilsr   r   __all__r   r   r   r   r   <module>   s    ;