B
    [ฏ  ใ               @   s๊   d Z ddlmZmZ ddlmZ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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 ้    )ฺprint_functionฺdivision)ฺBasicฺAddฺMulฺPow)ฺMatAddฺMatMulฺ
MatrixExpr)ฺUnionฺIntersectionฺ	FiniteSet)ฺAssocOpฺ	LatticeOp)ฺ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ฉ ๚1lib/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   Z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   5   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>Z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    7   s    
r    c             C   s   t t| S )zY Rebuild a SymPy expression

    This removes harm caused by Expr-Rules interactions
    )r    r(   )r,   r   r   r   ฺrebuildD   s    r3   Nc             +   s|   fdd |pi }t  fdd| ก D }tj |  ||fttd|}x$|D ]}t dd | ก D V  qXW dS )a^   Structural unification of two expressions/patterns

    Examples
    ========

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

    >>> next(unify(Basic(1, 2), Basic(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>u   s    zunify.<locals>.<lambda>c             3   s"   | ]\}} | |fV  qd S )Nr   )r   ฺkฺv)ฺdeconsr   r   r   w   s    zunify.<locals>.<genexpr>)r   r!   c             s   s"   | ]\}}t |t |fV  qd S )N)r    )r   r5   r6   r   r   r   r   ~   s    N)ฺdictฺitemsr   ฺunifyr   r!   )r   ฺyr,   r)   ฺkwargsZdsฺdr   )r7   r)   r   r:   K   s    *
r:   )r   )Nr   )&ฺ__doc__Z
__future__r   r   Z
sympy.corer   r   r   r   Zsympy.matricesr   r	   r
   Zsympy.sets.setsr   r   r   Zsympy.core.operationsr   r   Zsympy.unify.corer   r   r   Zsympy.unifyr   r1   r/   Zillegalr   r   r   r!   r'   r(   r    r3   r:   r   r   r   r   ฺ<module>   s&   

