U
    L?h$                     @   s  d dl mZ d dlmZ d dlmZmZmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZmZmZmZ d dlmZ dd	 Zd
d Zdd ZG dd dZe Ze
dZeedd Zeedd Zeedd Zeedd Zeedd Zeedd Zeedd Zeedd Zeedd Zeedd Zejdd ej dd ej!dd ej"d d ej#d!d ej$d"d ej%d#d ej&d$d ej'd%d ej(d&d i
Z)eee	ed'd Zd(S ))    )defaultdict)Q)AddMulPowNumberNumberSymbolSymbol)ImaginaryUnit)Abs)
EquivalentAndOrImplies)MatMulc                    s   t  fdd|jD  S )a  
    Apply all arguments of the expression to the fact structure.

    Parameters
    ==========

    symbol : Symbol
        A placeholder symbol.

    fact : Boolean
        Resulting ``Boolean`` expression.

    expr : Expr

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.sathandlers import allargs
    >>> from sympy.abc import x, y
    >>> allargs(x, Q.negative(x) | Q.positive(x), x*y)
    (Q.negative(x) | Q.positive(x)) & (Q.negative(y) | Q.positive(y))

    c                    s   g | ]}  |qS  subs.0argfactsymbolr   O/var/www/html/venv/lib/python3.8/site-packages/sympy/assumptions/sathandlers.py
<listcomp>(   s     zallargs.<locals>.<listcomp>)r   argsr   r   exprr   r   r   allargs   s    r   c                    s   t  fdd|jD  S )a  
    Apply any argument of the expression to the fact structure.

    Parameters
    ==========

    symbol : Symbol
        A placeholder symbol.

    fact : Boolean
        Resulting ``Boolean`` expression.

    expr : Expr

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.sathandlers import anyarg
    >>> from sympy.abc import x, y
    >>> anyarg(x, Q.negative(x) & Q.positive(x), x*y)
    (Q.negative(x) & Q.positive(x)) | (Q.negative(y) & Q.positive(y))

    c                    s   g | ]}  |qS r   r   r   r   r   r   r   D   s     zanyarg.<locals>.<listcomp>)r   r   r   r   r   r   anyarg+   s    r    c                    s8    fdd|j D tfddttD  }|S )a  
    Apply exactly one argument of the expression to the fact structure.

    Parameters
    ==========

    symbol : Symbol
        A placeholder symbol.

    fact : Boolean
        Resulting ``Boolean`` expression.

    expr : Expr

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.sathandlers import exactlyonearg
    >>> from sympy.abc import x, y
    >>> exactlyonearg(x, Q.positive(x), x*y)
    (Q.positive(x) & ~Q.positive(y)) | (Q.positive(y) & ~Q.positive(x))

    c                    s   g | ]}  |qS r   r   r   r   r   r   r   `   s     z!exactlyonearg.<locals>.<listcomp>c              	      s@   g | ]8}t  | fd d  d|  |d d  D  qS )c                 S   s   g | ]
}| qS r   r   )r   Zlitr   r   r   r   a   s     z,exactlyonearg.<locals>.<listcomp>.<listcomp>N   )r   )r   i)	pred_argsr   r   r   a   s   )r   r   rangelen)r   r   r   resr   )r   r#   r   r   exactlyoneargG   s
    
r'   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )ClassFactRegistrya  
    Register handlers against classes.

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

    ``register`` method registers the handler function for a class. Here,
    handler function should return a single fact. ``multiregister`` method
    registers the handler function for multiple classes. Here, handler function
    should return a container of multiple facts.

    ``registry(expr)`` returns a set of facts for *expr*.

    Examples
    ========

    Here, we register the facts for ``Abs``.

    >>> from sympy import Abs, Equivalent, Q
    >>> from sympy.assumptions.sathandlers import ClassFactRegistry
    >>> reg = ClassFactRegistry()
    >>> @reg.register(Abs)
    ... def f1(expr):
    ...     return Q.nonnegative(expr)
    >>> @reg.register(Abs)
    ... def f2(expr):
    ...     arg = expr.args[0]
    ...     return Equivalent(~Q.zero(arg), ~Q.zero(expr))

    Calling the registry with expression returns the defined facts for the
    expression.

    >>> from sympy.abc import x
    >>> reg(Abs(x))
    {Q.nonnegative(Abs(x)), Equivalent(~Q.zero(x), ~Q.zero(Abs(x)))}

    Multiple facts can be registered at once by ``multiregister`` method.

    >>> reg2 = ClassFactRegistry()
    >>> @reg2.multiregister(Abs)
    ... def _(expr):
    ...     arg = expr.args[0]
    ...     return [Q.even(arg) >> Q.even(expr), Q.odd(arg) >> Q.odd(expr)]
    >>> reg2(Abs(x))
    {Implies(Q.even(x), Q.even(Abs(x))), Implies(Q.odd(x), Q.odd(Abs(x)))}

    c                 C   s   t t| _t t| _d S N)r   	frozensetsinglefacts
multifacts)selfr   r   r   __init__   s    
zClassFactRegistry.__init__c                    s    fdd}|S )Nc                    s   j    | hO  < | S r)   )r+   )funcclsr-   r   r   _   s    z%ClassFactRegistry.register.<locals>._r   )r-   r1   r2   r   r0   r   register   s    zClassFactRegistry.registerc                    s    fdd}|S )Nc                    s"    D ]}j |  | hO  < q| S r)   )r,   )r/   r1   classesr-   r   r   r2      s    z*ClassFactRegistry.multiregister.<locals>._r   )r-   r5   r2   r   r4   r   multiregister   s    zClassFactRegistry.multiregisterc                 C   sd   | j | }| j D ]}t||r|| j | O }q| j| }| jD ]}t||r>|| j| O }q>||fS r)   )r+   
issubclassr,   )r-   keyZret1kZret2r   r   r   __getitem__   s    





zClassFactRegistry.__getitem__c                    sJ   t  }| t  \}}| fdd|D  |D ]}||  q2|S )Nc                 3   s   | ]}| V  qd S r)   r   )r   hr   r   r   	<genexpr>   s     z-ClassFactRegistry.__call__.<locals>.<genexpr>)settypeupdate)r-   r   retZ	handlers1Z	handlers2r;   r   r<   r   __call__   s    zClassFactRegistry.__call__N)	__name__
__module____qualname____doc__r.   r3   r6   r:   rB   r   r   r   r   r(   h   s   /r(   xc                 C   sd   | j d }t| tt| t|  t|t| ? t|t| ? t|t| ? gS )Nr   )r   r   nonnegativer   zeroevenoddinteger)r   r   r   r   r   r2      s    
r2   c              
   C   s   t ttt| t| ? t ttt| t| ? t ttt| t| ? t ttt| t| ? t ttt| t| ? tttt | t|  ? gS r)   )	r   rG   r   positivenegativerealrationalrL   r'   r<   r   r   r   r2      s    c                 C   s:   t ttt| }tttt| }t|t|t| S r)   r   rG   r   rO   r'   
irrationalr   r   Zallargs_realZonearg_irrationalr   r   r   r2      s    c                 C   s   t t| tttt| tttt| t| ? tttt| t| ? tttt| t| ? ttt	t| t	| ? t
ttt | t	|  ? tttt| t| ? gS r)   )r   r   rI   r    rG   r   rM   rO   rP   rL   r'   Zcommutativer<   r   r   r   r2      s    c                 C   s$   t ttt| }t|t|  S r)   )r   rG   r   primer   )r   Zallargs_primer   r   r   r2      s    c                 C   sD   t tttttB | }tttt| }t|t|t| S r)   )r   rG   r   	imaginaryrO   r'   r   )r   Zallargs_imag_or_realZonearg_imaginaryr   r   r   r2      s    c                 C   s:   t ttt| }tttt| }t|t|t| S r)   rQ   rS   r   r   r   r2     s    c                 C   s:   t ttt| }tttt| }t|t|t| S r)   )r   rG   r   rL   r    rJ   r   r   )r   Zallargs_integerZanyarg_evenr   r   r   r2     s    c                 C   s:   t ttt| }t ttt| }t|tt| |S r)   )r   rG   r   ZsquareZ
invertibler   r   )r   Zallargs_squareZallargs_invertibler   r   r   r2     s    c              	   C   s   | j | j }}t|t|@ t|@ t| ? t|t|@ t|@ t| ? t|t|@ t|@ t| ? tt	| t	|t
|@ gS r)   )baseexpr   rO   rJ   rH   rK   nonpositiver   rI   rM   )r   rV   rW   r   r   r   r2      s    &&&c                 C   s   | j S r)   )Zis_positiveor   r   r   <lambda>.      r[   c                 C   s   | j S r)   )is_zerorY   r   r   r   r[   /  r\   c                 C   s   | j S r)   )Zis_negativerY   r   r   r   r[   0  r\   c                 C   s   | j S r)   )Zis_rationalrY   r   r   r   r[   1  r\   c                 C   s   | j S r)   )Zis_irrationalrY   r   r   r   r[   2  r\   c                 C   s   | j S r)   )Zis_evenrY   r   r   r   r[   3  r\   c                 C   s   | j S r)   )Zis_oddrY   r   r   r   r[   4  r\   c                 C   s   | j S r)   )Zis_imaginaryrY   r   r   r   r[   5  r\   c                 C   s   | j S r)   )Zis_primerY   r   r   r   r[   6  r\   c                 C   s   | j S r)   )Zis_compositerY   r   r   r   r[   7  r\   c                 C   sB   g }t  D ]0\}}|| }|| }|d k	r|t|| q|S r)   )_old_assump_gettersitemsappendr   )r   rA   pgetterpredpropr   r   r   r2   :  s    N)*collectionsr   Zsympy.assumptions.askr   Z
sympy.corer   r   r   r   r   r	   Zsympy.core.numbersr
   Z$sympy.functions.elementary.complexesr   Zsympy.logic.boolalgr   r   r   r   Zsympy.matrices.expressionsr   r   r    r'   r(   Zclass_fact_registryrG   r6   r2   r3   rM   rI   rN   rP   rR   rJ   rK   rU   rT   Z	compositer^   r   r   r   r   <module>   sn    !X

	








          