B
    ˜‘[Ì  ã               @   s¦   d dl mZmZ d dlZd dlmZ d dlmZ d dl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edd„ ƒZdS )é    )Úprint_functionÚdivisionN)Úcacheit)ÚS)Ú_sympify)ÚBoolean)Ú	get_class)Úcontextmanagerc                   s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )ÚAssumptionsContextaÕ  Set representing assumptions.

    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
    ========

    >>> from sympy import AppliedPredicate, Q
    >>> from sympy.assumptions.assume import global_assumptions
    >>> global_assumptions
    AssumptionsContext()
    >>> from sympy.abc import x
    >>> global_assumptions.add(Q.real(x))
    >>> global_assumptions
    AssumptionsContext({Q.real(x)})
    >>> global_assumptions.remove(Q.real(x))
    >>> global_assumptions
    AssumptionsContext()
    >>> global_assumptions.clear()

    c                s"   x|D ]}t t| ƒ |¡ qW dS )zAdd an assumption.N)Úsuperr
   Úadd)ÚselfÚassumptionsÚa)Ú	__class__© ú7lib/python3.7/site-packages/sympy/assumptions/assume.pyr   $   s    
zAssumptionsContext.addc             C   s&   | sd| j j S d| j j| | ¡f S )Nz%s()z%s(%s))r   Ú__name__Z
_print_set)r   Zprinterr   r   r   Ú	_sympystr)   s    zAssumptionsContext._sympystr)r   Ú
__module__Ú__qualname__Ú__doc__r   r   Ú__classcell__r   r   )r   r   r
      s   r
   c                   s~   e Zd ZdZg Zdd„ ZdZedd„ ƒZedd„ ƒZ	ed	d
„ ƒZ
eddd„ƒZdd„ Z‡ fdd„Zdd„ Zedd„ ƒZ‡  ZS )ÚAppliedPredicatea  The class of expressions resulting from applying a Predicate.

    Examples
    ========

    >>> from sympy import Q, Symbol
    >>> x = Symbol('x')
    >>> Q.integer(x)
    Q.integer(x)
    >>> type(Q.integer(x))
    <class 'sympy.assumptions.assume.AppliedPredicate'>

    c             C   s   t |ƒ}t | ||¡S )N)r   r   Ú__new__)ÚclsZ	predicateÚargr   r   r   r   A   s    zAppliedPredicate.__new__Tc             C   s
   | j d S )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

        é   )Ú_args)r   r   r   r   r   G   s    zAppliedPredicate.argc             C   s   | j dd … S )Nr   )r   )r   r   r   r   ÚargsX   s    zAppliedPredicate.argsc             C   s
   | j d S )Nr   )r   )r   r   r   r   Úfunc\   s    zAppliedPredicate.funcNc             C   s*   |   ¡ d| jj| j ¡ fftj ¡ tjfS )Né   )Ú	class_keyr    Únamer   Úsort_keyr   ÚOne)r   Úorderr   r   r   r$   `   s    zAppliedPredicate.sort_keyc             C   s   t |ƒtkr| j|jkS dS )NF)Útyper   r   )r   Úotherr   r   r   Ú__eq__e   s    zAppliedPredicate.__eq__c                s   t t| ƒ ¡ S )N)r   r   Ú__hash__)r   )r   r   r   r*   j   s    zAppliedPredicate.__hash__c             C   s   | j  | j|¡S )N)r    Úevalr   )r   r   r   r   r   Ú	_eval_askm   s    zAppliedPredicate._eval_askc             C   sH   ddl m}m} | jjdkrB| j}|js<|js<t|||fƒrB|j	S t
ƒ S )Nr   )ÚEqÚNe)Zis_trueZis_false)Zsympy.core.relationalr-   r.   r    r#   r   Z
is_BooleanZ	is_SymbolÚ
isinstanceÚbinary_symbolsÚset)r   r-   r.   Úir   r   r   r0   p   s    zAppliedPredicate.binary_symbols)N)r   r   r   r   Ú	__slots__r   Úis_AtomÚpropertyr   r   r    r   r$   r)   r*   r,   r0   r   r   r   )r   r   r   1   s   r   c               @   s^   e Zd ZdZdZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
eddd„ƒZddd„ZdS )Ú	Predicatea«  A predicate is a function that returns a boolean value.

    Predicates merely wrap their argument and remain unevaluated:

        >>> from sympy import Q, ask
        >>> type(Q.prime)
        <class 'sympy.assumptions.assume.Predicate'>
        >>> Q.prime.name
        'prime'
        >>> Q.prime(7)
        Q.prime(7)
        >>> _.func.name
        'prime'

    To obtain the truth value of an expression containing predicates, use
    the function ``ask``:

        >>> ask(Q.prime(7))
        True

    The tautological predicate ``Q.is_true`` can be used to wrap other objects:

        >>> from sympy.abc import x
        >>> Q.is_true(x > 1)
        Q.is_true(x > 1)

    TNc             C   s   t  | ¡}||_|pg |_|S )N)r   r   r#   Úhandlers)r   r#   r7   Úobjr   r   r   r   ™   s    

zPredicate.__new__c             C   s   | j fS )N)r#   )r   r   r   r   Ú_hashable_contentŸ   s    zPredicate._hashable_contentc             C   s   | j fS )N)r#   )r   r   r   r   Ú__getnewargs__¢   s    zPredicate.__getnewargs__c             C   s
   t | |ƒS )N)r   )r   Úexprr   r   r   Ú__call__¥   s    zPredicate.__call__c             C   s   | j  |¡ d S )N)r7   Úappend)r   Úhandlerr   r   r   Úadd_handler¨   s    zPredicate.add_handlerc             C   s   | j  |¡ d S )N)r7   Úremove)r   r>   r   r   r   Úremove_handler«   s    zPredicate.remove_handlerc             C   s    |   ¡ d| jfftj ¡ tjfS )Nr   )r"   r#   r   r%   r$   )r   r&   r   r   r   r$   ®   s    zPredicate.sort_keyc       
   
   C   sª   d\}}t  t|ƒ¡}xŽ| jD ]„}t|ƒ}xv|D ]n}yt||jƒ}	W n tk
rZ   w0Y nX |	||ƒ}|dkrpq0|dkr~|}n|dkrŒ|}n||krœtdƒ‚P q0W qW |S )zŒ
        Evaluate self(expr) under the given assumptions.

        This uses only direct resolution methods, not logical inference.
        )NNNzincompatible resolutors)	ÚinspectZgetmror'   r7   r   Úgetattrr   ÚAttributeErrorÚ
ValueError)
r   r;   r   ZresZ_resÚmror>   r   Úsubclassr+   r   r   r   r+   ²   s(    


zPredicate.eval)N)N)T)r   r   r   r   r4   r   r9   r:   r<   r?   rA   r   r$   r+   r   r   r   r   r6   z   s   
r6   c           	   g   s6   t  ¡ }t  | ¡ z
dV  W dt  ¡  t  |¡ X dS )a0   Context manager for assumptions

    Examples
    ========

    >>> from sympy.assumptions 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   Zold_global_assumptionsr   r   r   ÚassumingÓ   s    

rL   )Z
__future__r   r   rB   Zsympy.core.cacher   Zsympy.core.singletonr   Zsympy.core.sympifyr   Zsympy.logic.boolalgr   Zsympy.utilities.sourcer   Ú
contextlibr	   r1   r
   rH   r   r6   rL   r   r   r   r   Ú<module>   s   #IY