o
    jg9                     @   s   d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	m
Z
mZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ G dd deZe ZG dd de	ZG dd deZG dd de	edZG dd deZedd ZdS )z<A module which implements predicates and assumption context.    )contextmanagerN)Str)_sympify)Booleanfalsetrue)
Dispatcherstr_signature)sympy_deprecation_warning)is_sequence)	get_classc                       s(   e Zd ZdZ fddZdd Z  ZS )AssumptionsContexta  
    Set containing default assumptions which are applied to the ``ask()``
    function.

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

    This is used to represent global assumptions, but you can also use this
    class to create your own local assumptions contexts. It is basically a thin
    wrapper to Python's set, so see its documentation for advanced usage.

    Examples
    ========

    The default assumption context is ``global_assumptions``, which is initially empty:

    >>> from sympy import ask, Q
    >>> from sympy.assumptions import global_assumptions
    >>> global_assumptions
    AssumptionsContext()

    You can add default assumptions:

    >>> from sympy.abc import x
    >>> global_assumptions.add(Q.real(x))
    >>> global_assumptions
    AssumptionsContext({Q.real(x)})
    >>> ask(Q.real(x))
    True

    And remove them:

    >>> global_assumptions.remove(Q.real(x))
    >>> print(ask(Q.real(x)))
    None

    The ``clear()`` method removes every assumption:

    >>> global_assumptions.add(Q.positive(x))
    >>> global_assumptions
    AssumptionsContext({Q.positive(x)})
    >>> global_assumptions.clear()
    >>> global_assumptions
    AssumptionsContext()

    See Also
    ========

    assuming

    c                    s   |D ]}t  | qdS )zAdd assumptions.N)superadd)selfassumptionsa	__class__ P/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/assumptions/assume.pyr   C   s   zAssumptionsContext.addc                 C   s&   | sd| j j S d| j j|| S )Nz%s()z{}({}))r   __name__format
_print_set)r   printerr   r   r   	_sympystrH   s   zAssumptionsContext._sympystr)r   
__module____qualname____doc__r   r   __classcell__r   r   r   r   r      s    4r   c                       s\   e Zd ZdZdZ fddZedd Zedd Zed	d
 Z	dd Z
edd Z  ZS )AppliedPredicatea  
    The class of expressions resulting from applying ``Predicate`` to
    the arguments. ``AppliedPredicate`` merely wraps its argument and
    remain unevaluated. To evaluate it, use the ``ask()`` function.

    Examples
    ========

    >>> from sympy import Q, ask
    >>> Q.integer(1)
    Q.integer(1)

    The ``function`` attribute returns the predicate, and the ``arguments``
    attribute returns the tuple of arguments.

    >>> type(Q.integer(1))
    <class 'sympy.assumptions.assume.AppliedPredicate'>
    >>> Q.integer(1).function
    Q.integer
    >>> Q.integer(1).arguments
    (1,)

    Applied predicates can be evaluated to a boolean value with ``ask``:

    >>> ask(Q.integer(1))
    True

    r   c                    s6   t |tstd| tt|}t j| |g|R  S )Nz%s is not a Predicate.)
isinstance	Predicate	TypeErrormapr   r   __new__)cls	predicateargsr   r   r   r%   o   s   

zAppliedPredicate.__new__c                 C   s"   | j }t|dkr|d S td)z
        Return the expression used by this assumption.

        Examples
        ========

        >>> from sympy import Q, Symbol
        >>> x = Symbol('x')
        >>> a = Q.integer(x + 1)
        >>> a.arg
        x + 1

              z4'arg' property is allowed only for unary predicates.)_argslenr#   r   r(   r   r   r   argu   s   zAppliedPredicate.argc                 C   
   | j d S )z'
        Return the predicate.
        r   r+   r   r   r   r   function   s   
zAppliedPredicate.functionc                 C   s   | j dd S )zJ
        Return the arguments which are applied to the predicate.
        r*   Nr0   r1   r   r   r   	arguments   s   zAppliedPredicate.argumentsc                 C   s   | j | j|S N)r2   evalr3   r   r   r   r   r   	_eval_ask      zAppliedPredicate._eval_askc                 C   s   ddl m} | j|jkr| jd }|js|jr|jS | j|j|j	fv rEt
| jv s-t| jv rE| jd jr9| jd hS | jd jrE| jd hS t S )Nr*   )Qr   )askr9   r2   is_truer3   
is_Boolean	is_Symbolbinary_symbolseqner   r   set)r   r9   ir   r   r   r>      s   
zAppliedPredicate.binary_symbols)r   r   r   r   	__slots__r%   propertyr.   r2   r3   r7   r>   r   r   r   r   r   r    P   s    


r    c                       s(   e Zd Z fddZedd Z  ZS )PredicateMetac                    sR   d|vrd|   d}t|d| d}||d< |dd|d< t | |||S )	NhandlerAskHandlerzHandler for key %s)docr    	_orig_doc)
capitalizer   getr   r%   )r&   clsnamebasesdctnamerF   r   r   r   r%      s   zPredicateMeta.__new__c                 C   s  | j }| j}| tur|d ur|d7 }|d7 }d|j g}|jr1|j D ]}|s)q$|d|  q$g }|jd d d D ]5}|j| }|j	ridt
| }g }	|j	 D ]	}|	d|  qR|d|	7 }|| q;|t
| q;|rd}
|D ]}|
d	| 7 }
qw||
 |d
|7 }|S )NzHandler
z    =======

z"    Multiply dispatched method: %sz    %sz    Inputs: <%s>
z    Other signatures:z
        * %sz

)rF   rK   r"   rQ   rI   
splitlinesappendorderingfuncsr   r	   join)r&   rF   rI   docslineothersigfuncslinesothersigr   r   r   r      s:   

zPredicateMeta.__doc__)r   r   r   r%   rD   r   r   r   r   r   r   rE      s    rE   c                       sb   e Zd ZdZdZ fddZedd Zedd Z	ed	d
 Z
dd ZdddZdd Z  ZS )r"   aJ
  
    Base class for mathematical predicates. It also serves as a
    constructor for undefined predicate objects.

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

    Predicate is a function that returns a boolean value [1].

    Predicate function is object, and it is instance of predicate class.
    When a predicate is applied to arguments, ``AppliedPredicate``
    instance is returned. This merely wraps the argument and remain
    unevaluated. To obtain the truth value of applied predicate, use the
    function ``ask``.

    Evaluation of predicate is done by multiple dispatching. You can
    register new handler to the predicate to support new types.

    Every predicate in SymPy can be accessed via the property of ``Q``.
    For example, ``Q.even`` returns the predicate which checks if the
    argument is even number.

    To define a predicate which can be evaluated, you must subclass this
    class, make an instance of it, and register it to ``Q``. After then,
    dispatch the handler by argument types.

    If you directly construct predicate using this class, you will get
    ``UndefinedPredicate`` which cannot be dispatched. This is useful
    when you are building boolean expressions which do not need to be
    evaluated.

    Examples
    ========

    Applying and evaluating to boolean value:

    >>> from sympy import Q, ask
    >>> ask(Q.prime(7))
    True

    You can define a new predicate by subclassing and dispatching. Here,
    we define a predicate for sexy primes [2] as an example.

    >>> from sympy import Predicate, Integer
    >>> class SexyPrimePredicate(Predicate):
    ...     name = "sexyprime"
    >>> Q.sexyprime = SexyPrimePredicate()
    >>> @Q.sexyprime.register(Integer, Integer)
    ... def _(int1, int2, assumptions):
    ...     args = sorted([int1, int2])
    ...     if not all(ask(Q.prime(a), assumptions) for a in args):
    ...         return False
    ...     return args[1] - args[0] == 6
    >>> ask(Q.sexyprime(5, 11))
    True

    Direct constructing returns ``UndefinedPredicate``, which can be
    applied but cannot be dispatched.

    >>> from sympy import Predicate, Integer
    >>> Q.P = Predicate("P")
    >>> type(Q.P)
    <class 'sympy.assumptions.assume.UndefinedPredicate'>
    >>> Q.P(1)
    Q.P(1)
    >>> Q.P.register(Integer)(lambda expr, assump: True)
    Traceback (most recent call last):
      ...
    TypeError: <class 'sympy.assumptions.assume.UndefinedPredicate'> cannot be dispatched.

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Predicate_%28mathematical_logic%29
    .. [2] https://en.wikipedia.org/wiki/Sexy_prime

    Tc                    s.   | t u rt|i |S t j| g|R  }|S r4   )r"   UndefinedPredicater   r%   )r&   r(   kwargsobjr   r   r   r%   1  s   zPredicate.__new__c                 C   s
   t | jS r4   )typer   r1   r   r   r   rQ   7  s   
zPredicate.namec                 O   s,   | j du rtdt|  | j j|i |S )z8
        Register the signature to the handler.
        Nz%s cannot be dispatched.)rF   r#   rd   register)r&   typesrb   r   r   r   re   <  s   
zPredicate.registerc                    s    fdd}|S )z?
        Register multiple signatures to same handler.
        c                    s0   D ]}t |s|f} j|i |  qd S r4   )r   re   )r]   tr&   rb   rf   r   r   _J  s
   z"Predicate.register_many.<locals>._r   )r&   rf   rb   ri   r   rh   r   register_manyE  s   zPredicate.register_manyc                 G   s   t | g|R  S r4   r    r-   r   r   r   __call__Q  r8   zPredicate.__call__c                 C   s0   d}z| j |d|i}W |S  ty   Y |S w )z
        Evaluate ``self(*args)`` under the given assumptions.

        This uses only direct resolution methods, not logical inference.
        Nr   )rF   NotImplementedError)r   r(   r   resultr   r   r   r5   T  s   zPredicate.evalc                 C   s   | S r4   r   r6   r   r   r   _eval_refinea  s   zPredicate._eval_refineT)r   r   r   r   is_Atomr%   rD   rQ   classmethodre   rj   rl   r5   ro   r   r   r   r   r   r"      s    N



r"   )	metaclassc                       sd   e Zd ZdZdZd fdd	Zedd Zdd Zd	d
 Z	dd Z
dd Zdd ZdddZ  ZS )ra   a  
    Predicate without handler.

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

    This predicate is generated by using ``Predicate`` directly for
    construction. It does not have a handler, and evaluating this with
    arguments is done by SAT solver.

    Examples
    ========

    >>> from sympy import Predicate, Q
    >>> Q.P = Predicate('P')
    >>> Q.P.func
    <class 'sympy.assumptions.assume.UndefinedPredicate'>
    >>> Q.P.name
    Str('P')

    Nc                    s2   t |ts	t|}tt| | |}|pg |_|S r4   )r!   r   r   r   r%   handlers)r&   rQ   rt   rc   r   r   r   r%     s
   

zUndefinedPredicate.__new__c                 C   r/   )Nr   )r(   r1   r   r   r   rQ     s   
zUndefinedPredicate.namec                 C      | j fS r4   rQ   r1   r   r   r   _hashable_content     z$UndefinedPredicate._hashable_contentc                 C   ru   r4   rv   r1   r   r   r   __getnewargs__  rx   z!UndefinedPredicate.__getnewargs__c                 C   s
   t | |S r4   rk   )r   exprr   r   r   rl     s   
zUndefinedPredicate.__call__c                 C      t dddd | j| d S )Nz
            The AskHandler system is deprecated. Predicate.add_handler()
            should be replaced with the multipledispatch handler of Predicate.
            1.8deprecated-askhandlerdeprecated_since_versionactive_deprecations_target)r
   rt   rU   r   rF   r   r   r   add_handler     zUndefinedPredicate.add_handlerc                 C   r{   )Nz
            The AskHandler system is deprecated. Predicate.remove_handler()
            should be replaced with the multipledispatch handler of Predicate.
            r|   r}   r~   )r
   rt   remover   r   r   r   remove_handler  r   z!UndefinedPredicate.remove_handlerTc                 C   s   t ddddd |\}d\}}tt|}| jD ]0}t|}|D ]'}	t||	jd }
|
d u r/q!|
||}|d u r9q!|d u r@|}n||krHtd q|S )Nz
            The AskHandler system is deprecated. Evaluating UndefinedPredicate
            objects should be replaced with the multipledispatch handler of
            Predicate.
            r|   r}      )r   r   
stacklevel)NNzincompatible resolutors)	r
   inspectgetmrord   rt   r   getattrr   
ValueError)r   r(   r   rz   res_resmrorF   r&   subclasseval_r   r   r   r5     s2   


zUndefinedPredicate.evalr4   rp   )r   r   r   r   rF   r%   rD   rQ   rw   ry   rl   r   r   r5   r   r   r   r   r   ra   f  s    
ra   c               	   g   sH    t  }t |  zdV  W t   t | dS t   t | w )a'  
    Context manager for assumptions.

    Examples
    ========

    >>> from sympy import assuming, Q, ask
    >>> from sympy.abc import x, y
    >>> print(ask(Q.integer(x + y)))
    None
    >>> with assuming(Q.integer(x), Q.integer(y)):
    ...     print(ask(Q.integer(x + y)))
    True
    N)global_assumptionscopyupdateclear)r   old_global_assumptionsr   r   r   assuming  s   
r   )r   
contextlibr   r   sympy.core.symbolr   sympy.core.sympifyr   sympy.logic.boolalgr   r   r   !sympy.multipledispatch.dispatcherr   r	   sympy.utilities.exceptionsr
   sympy.utilities.iterablesr   sympy.utilities.sourcer   rA   r   r   r    rd   rE   r"   ra   r   r   r   r   r   <module>   s&    ?^2 i