B
    ed|  ใ               @   sฺ   d Z ddlmZmZmZmZ ddlmZmZ ddl	m
Z
mZmZ ddlmZmZmZ ddlmZmZmZ ddlmZ egZeeegZegZdd	 Zd
d Zdd Zdd Zdd ZdddZdd Z dd Z!dddZ"dS )z SymPy interface to Unification engine

See sympy.unify for module level docstring
See sympy.unify.core for algorithmic docstring ้    )ฺBasicฺAddฺMulฺPow)ฺAssocOpฺ	LatticeOp)ฺMatAddฺMatMulฺ
MatrixExpr)ฺUnionฺIntersectionฺ	FiniteSet)ฺCompoundฺVariableฺCondVariable)ฺcorec                s&   t tttttf}t fdd|D S )Nc             3   s   | ]}t  |V  qd S )N)ฺ
issubclass)ฺ.0Zaop)ฺopฉ ๚_/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/sympy/unify/usympy.py๚	<genexpr>   s    z$sympy_associative.<locals>.<genexpr>)r   r   r	   r   r   r   ฺany)r   Z	assoc_opsr   )r   r   ฺsympy_associative   s    r   c                s$   t ttttf}t fdd|D S )Nc             3   s   | ]}t  |V  qd S )N)r   )r   ฺcop)r   r   r   r      s    z$sympy_commutative.<locals>.<genexpr>)r   r   r   r   r   r   )r   Zcomm_opsr   )r   r   ฺsympy_commutative   s    r   c             C   s   t | tot| jS )N)ฺ
isinstancer   r   r   )ฺxr   r   r   ฺis_associative   s    r   c             C   s@   t | tsdS t| jrdS t| jtr<tdd | jD S d S )NFTc             s   s   | ]}t |jV  qd S )N)ฺ	constructฺis_commutative)r   ฺargr   r   r   r   "   s    z!is_commutative.<locals>.<genexpr>)r   r   r   r   r   r   ฺallฺargs)r   r   r   r   r       s    

r    c                s    fdd}|S )Nc                s    t |  pt | tot| j S )N)r   r   r   r   )r   )ฺtypr   r   ฺ	matchtype%   s    
zmk_matchtype.<locals>.matchtyper   )r$   r%   r   )r$   r   ฺmk_matchtype$   s    r&   r   c                sV   |  krt | S t| t tfr"| S t| tr2| jr6| S t| jt fdd| jD S )z% Turn a SymPy object into a Compound c             3   s   | ]}t | V  qd S )N)ฺdeconstruct)r   r!   )ฺ	variablesr   r   r   3   s    zdeconstruct.<locals>.<genexpr>)	r   r   r   r   Zis_Atomr   ฺ	__class__ฺtupler#   )ฺsr(   r   )r(   r   r'   *   s    r'   c                s   t  ttfr jS t  ts" S t fddtD rP jtt	 j
ddiS t fddtD rtj jftt	 j
 S  jtt	 j
 S dS )z% Turn a Compound into a SymPy object c             3   s   | ]}t  j|V  qd S )N)r   r   )r   ฺcls)ฺtr   r   r   ;   s    zconstruct.<locals>.<genexpr>ฺevaluateFc             3   s   | ]}t  j|V  qd S )N)r   r   )r   r,   )r-   r   r   r   =   s    N)r   r   r   r!   r   r   ฺeval_false_legalr   ฺmapr   r#   ฺbasic_new_legalr   ฺ__new__)r-   r   )r-   r   r   5   s    
r   c             C   s   t t| S )z[ Rebuild a SymPy expression.

    This removes harm caused by Expr-Rules interactions.
    )r   r'   )r+   r   r   r   ฺrebuildB   s    r3   Nc             +   st   fdd |pi } fdd|  ก D }tj |  ||fttd|}x |D ]}dd |  ก D V  qTW dS )af   Structural unification of two expressions/patterns.

    Examples
    ========

    >>> from sympy.unify.usympy import unify
    >>> from sympy import Basic, S
    >>> from sympy.abc import x, y, z, p, q

    >>> next(unify(Basic(S(1), S(2)), Basic(S(1), x), variables=[x]))
    {x: 2}

    >>> expr = 2*x + y + z
    >>> pattern = 2*p + q
    >>> next(unify(expr, pattern, {}, variables=(p, q)))
    {p: x, q: y + z}

    Unification supports commutative and associative matching

    >>> expr = x + y + z
    >>> pattern = p + q
    >>> len(list(unify(expr, pattern, {}, variables=(p, q))))
    12

    Symbols not indicated to be variables are treated as literal,
    else they are wild-like and match anything in a sub-expression.

    >>> expr = x*y*z + 3
    >>> pattern = x*y + 3
    >>> next(unify(expr, pattern, {}, variables=[x, y]))
    {x: y, y: x*z}

    The x and y of the pattern above were in a Mul and matched factors
    in the Mul of expr. Here, a single symbol matches an entire term:

    >>> expr = x*y + 3
    >>> pattern = p + 3
    >>> next(unify(expr, pattern, {}, variables=[p]))
    {p: x*y}

    c                s
   t |  S )N)r'   )r   )r(   r   r   ฺ<lambda>s   ๓    zunify.<locals>.<lambda>c                s   i | ]\}} | |qS r   r   )r   ฺkฺv)ฺdeconsr   r   ๚
<dictcomp>u   s    zunify.<locals>.<dictcomp>)r   r    c             S   s   i | ]\}}t |t |qS r   )r   )r   r6   r7   r   r   r   r9   |   s    N)ฺitemsr   ฺunifyr   r    )r   ฺyr+   r(   ฺkwargsZdsฺdr   )r8   r(   r   r;   I   s    *
r;   )r   )Nr   )#ฺ__doc__Z
sympy.corer   r   r   r   Zsympy.core.operationsr   r   Zsympy.matricesr   r	   r
   Zsympy.sets.setsr   r   r   Zsympy.unify.corer   r   r   Zsympy.unifyr   r1   r/   ฺillegalr   r   r   r    r&   r'   r   r3   r;   r   r   r   r   ฺ<module>   s$   

