U
    ZÊ¹j3  ã                   @   sl   d Z ddlmZ ddlmZ efdd„Zdd„ Zefd	d
„Zdd„ Zdd„ Z	dd„ Z
efdd„Zdd„ ZdS )zP Generic Rules for SymPy

This file assumes knowledge of Basic and little else.
é    )Úsifté   )Únewc                    s   ‡ ‡fdd„}|S )aÃ   Create a rule to remove identities.

    isid - fn :: x -> Bool  --- whether or not this element is an identity.

    Examples
    ========

    >>> from sympy.strategies import rm_id
    >>> from sympy import Basic, S
    >>> remove_zeros = rm_id(lambda x: x==0)
    >>> remove_zeros(Basic(S(1), S(0), S(2)))
    Basic(1, 2)
    >>> remove_zeros(Basic(S(0), S(0))) # If only identites then we keep one
    Basic(0)

    See Also:
        unpack
    c                    sh   t tˆ | jƒƒ}t|ƒdkr | S t|ƒt|ƒkrRˆ| jfdd„ t| j|ƒD ƒžŽ S ˆ| j| jd ƒS dS )z Remove identities r   c                 S   s   g | ]\}}|s|‘qS © r   )Ú.0ÚargÚxr   r   úR/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/strategies/rl.pyÚ
<listcomp>$   s      z/rm_id.<locals>.ident_remove.<locals>.<listcomp>N)ÚlistÚmapÚargsÚsumÚlenÚ	__class__Úzip)ÚexprZids©Úisidr   r   r	   Úident_remove   s    ÿzrm_id.<locals>.ident_remover   )r   r   r   r   r   r	   Úrm_id
   s    r   c                    s   ‡ ‡‡fdd„}|S )a6   Create a rule to conglomerate identical args.

    Examples
    ========

    >>> from sympy.strategies import glom
    >>> from sympy import Add
    >>> from sympy.abc import x

    >>> key     = lambda x: x.as_coeff_Mul()[1]
    >>> count   = lambda x: x.as_coeff_Mul()[0]
    >>> combine = lambda cnt, arg: cnt * arg
    >>> rl = glom(key, count, combine)

    >>> rl(Add(x, -x, 3*x, 2, 3, evaluate=False))
    3*x + 5

    Wait, how are key, count and combine supposed to work?

    >>> key(2*x)
    x
    >>> count(2*x)
    2
    >>> combine(2, x)
    2*x
    c                    sd   t | jˆƒ}‡fdd„| ¡ D ƒ}‡ fdd„| ¡ D ƒ}t|ƒt| jƒkr\tt| ƒf|žŽ S | S dS )z2 Conglomerate together identical args x + x -> 2x c                    s    i | ]\}}|t tˆ |ƒƒ“qS r   )r   r   )r   Úkr   )Úcountr   r	   Ú
<dictcomp>I   s      z.glom.<locals>.conglomerate.<locals>.<dictcomp>c                    s   g | ]\}}ˆ ||ƒ‘qS r   r   )r   ZmatZcnt)Úcombiner   r	   r
   J   s     z.glom.<locals>.conglomerate.<locals>.<listcomp>N)r   r   ÚitemsÚsetr   Útype)r   ÚgroupsÚcountsZnewargs©r   r   Úkeyr   r	   ÚconglomerateF   s    zglom.<locals>.conglomerater   )r!   r   r   r"   r   r    r	   Úglom+   s    
r#   c                    s   ‡ ‡fdd„}|S )zï Create a rule to sort by a key function.

    Examples
    ========

    >>> from sympy.strategies import sort
    >>> from sympy import Basic, S
    >>> sort_rl = sort(str)
    >>> sort_rl(Basic(S(3), S(1), S(2)))
    Basic(1, 2, 3)
    c                    s   ˆ| j ft| jˆ d�žŽ S )N)r!   )r   Úsortedr   ©r   ©r!   r   r   r	   Úsort_rl`   s    zsort.<locals>.sort_rlr   )r!   r   r'   r   r&   r	   ÚsortS   s    r(   c                    s   ‡ ‡fdd„}|S )aW   Turns an A containing Bs into a B of As

    where A, B are container types

    >>> from sympy.strategies import distribute
    >>> from sympy import Add, Mul, symbols
    >>> x, y = symbols('x,y')
    >>> dist = distribute(Mul, Add)
    >>> expr = Mul(2, x+y, evaluate=False)
    >>> expr
    2*(x + y)
    >>> dist(expr)
    2*x + 2*y
    c                    sp   t | jƒD ]`\}}t|ˆƒr
| jd |… | j| | j|d d …   ‰ }‰ˆ‡‡ ‡fdd„|jD ƒŽ   S q
| S )Nr   c                    s   g | ]}ˆ ˆ|f ˆ Ž ‘qS r   r   )r   r   )ÚAÚfirstÚtailr   r	   r
   y   s     z5distribute.<locals>.distribute_rl.<locals>.<listcomp>)Ú	enumerater   Ú
isinstance)r   Úir   Úb©r)   ÚB)r*   r+   r	   Údistribute_rlu   s
    
."z!distribute.<locals>.distribute_rlr   )r)   r1   r2   r   r0   r	   Ú
distributee   s    r3   c                    s   ‡ ‡fdd„}|S )z Replace expressions exactly c                    s   | ˆ krˆS | S d S )Nr   r%   ©Úar/   r   r	   Úsubs_rl€   s    zsubs.<locals>.subs_rlr   )r5   r/   r6   r   r4   r	   Úsubs~   s    r7   c                 C   s    t | jƒdkr| jd S | S dS )z• Rule to unpack singleton args

    >>> from sympy.strategies import unpack
    >>> from sympy import Basic, S
    >>> unpack(Basic(S(2)))
    2
    r   r   N)r   r   r%   r   r   r	   Úunpack‰   s    
r8   c                 C   sH   | j }g }| jD ]&}|j |kr,| |j¡ q| |¡ q|| j f|žŽ S )z9 Flatten T(a, b, T(c, d), T2(e)) to T(a, b, c, d, T2(e)) )r   r   ÚextendÚappend)r   r   Úclsr   r   r   r   r	   Úflatten—   s    

r<   c                 C   s$   | j r
| S | jttt| jƒƒŽ S dS )zç Rebuild a SymPy tree.

    Explanation
    ===========

    This function recursively calls constructors in the expression tree.
    This forces canonicalization and removes ugliness introduced by the use of
    Basic.__new__
    N)Zis_AtomÚfuncr   r   Úrebuildr   r%   r   r   r	   r>   £   s    
r>   N)Ú__doc__Zsympy.utilities.iterablesr   Úutilr   r   r#   r(   r3   r7   r8   r<   r>   r   r   r   r	   Ú<module>   s   !(