o
    oh3                     @   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                        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                    sf   t t | j}t|dkr| S t|t|kr*| jgdd t| j|D R  S | j| jd S )z Remove identities r   c                 S   s   g | ]\}}|s|qS  r   ).0argxr   r   g/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/strategies/rl.py
<listcomp>$   s    z/rm_id.<locals>.ident_remove.<locals>.<listcomp>)listmapargssumlen	__class__zip)expr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                    sb   t | j}fdd| D } fdd| D }t|t| jkr/tt| g|R  S | 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   matcnt)combiner   r
   r   J   s    z.glom.<locals>.conglomerate.<locals>.<listcomp>)r   r   itemssetr   type)r   groupscountsnewargsr   r   keyr   r
   conglomerateF   s   zglom.<locals>.conglomerater   )r&   r   r   r'   r   r%   r
   glom+   s   
r(   c                    r   )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 gt| j dR  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                    r   )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 ]0\}}t|r5| 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/   r0   r
   distribute_rlu   s   
. z!distribute.<locals>.distribute_rlr   )r.   r6   r7   r   r5   r
   
distributee   s   r8   c                    r   )z Replace expressions exactly c                    s   |  krS | S )Nr   r*   ar4   r   r
   subs_rl   s   zsubs.<locals>.subs_rlr   )r:   r4   r;   r   r9   r
   subs~   s   r<   c                 C   s   t | jdkr| jd S | S )z Rule to unpack singleton args

    >>> from sympy.strategies import unpack
    >>> from sympy import Basic, S
    >>> unpack(Basic(S(2)))
    2
    r   r   )r   r   r*   r   r   r
   unpack   s   
r=   c                 C   sJ   | j }g }| jD ]}|j |kr||j q|| q|| j g|R  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   

rA   c                 C   s    | j r| S | jttt| j 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__
    )is_Atomfuncr   r   rebuildr   r*   r   r   r
   rD      s   
rD   N)__doc__sympy.utilities.iterablesr   utilr   r   r(   r-   r8   r<   r=   rA   rD   r   r   r   r
   <module>   s    !(