o
    8VaG                     @   s   d Z ddlmZmZmZ ddl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mZmZ ddlmZ ddlmZ dd	lmZ G d
d dZe Zdd ZdefddZdd Zdd Zdd Z ddl!m"Z"m#Z# dS )z4Module for querying SymPy objects about assumptions.    )global_assumptions	PredicateAppliedPredicate)CNF
EncodedCNFLiteral)sympify)BooleanKind)EqNeGtLtGeLe)satisfiable)memoize_property)SymPyDeprecationWarningc                   @   s  e Zd ZdZedd Zedd Zedd Zedd	 Zed
d Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zed d! Zed"d# Zed$d% Zed&d' Zed(d) Zed*d+ Zed,d- Zed.d/ Zed0d1 Zed2d3 Zed4d5 Zed6d7 Zed8d9 Z ed:d; Z!ed<d= Z"ed>d? Z#ed@dA Z$edBdC Z%edDdE Z&edFdG Z'edHdI Z(edJdK Z)edLdM Z*edNdO Z+edPdQ Z,edRdS Z-edTdU Z.edVdW Z/edXdY Z0edZd[ Z1ed\d] Z2ed^d_ Z3ed`da Z4edbdc Z5eddde Z6edfdg Z7edhdi Z8edjdk Z9edldm Z:edndo Z;dpS )qAssumptionKeyszy
    This class contains all the supported keys by ``ask``.
    It should be accessed via the instance ``sympy.Q``.

    c                 C      ddl m} | S )N   )HermitianPredicate)handlers.setsr   )selfr    r   7/usr/lib/python3/dist-packages/sympy/assumptions/ask.py	hermitian      zAssumptionKeys.hermitianc                 C   r   )Nr   )AntihermitianPredicate)r   r   )r   r   r   r   r   antihermitian#   r   zAssumptionKeys.antihermitianc                 C   r   )Nr   )RealPredicate)r   r   )r   r   r   r   r   real(   r   zAssumptionKeys.realc                 C   r   )Nr   )ExtendedRealPredicate)r   r!   )r   r!   r   r   r   extended_real-   r   zAssumptionKeys.extended_realc                 C   r   )Nr   )ImaginaryPredicate)r   r#   )r   r#   r   r   r   	imaginary2   r   zAssumptionKeys.imaginaryc                 C   r   )Nr   )ComplexPredicate)r   r%   )r   r%   r   r   r   complex7   r   zAssumptionKeys.complexc                 C   r   )Nr   )AlgebraicPredicate)r   r'   )r   r'   r   r   r   	algebraic<   r   zAssumptionKeys.algebraicc                 C   r   )Nr   )TranscendentalPredicate)Zpredicates.setsr)   )r   r)   r   r   r   transcendentalA   r   zAssumptionKeys.transcendentalc                 C   r   )Nr   )IntegerPredicate)r   r+   )r   r+   r   r   r   integerF   r   zAssumptionKeys.integerc                 C   r   )Nr   )RationalPredicate)r   r-   )r   r-   r   r   r   rationalK   r   zAssumptionKeys.rationalc                 C   r   )Nr   )IrrationalPredicate)r   r/   )r   r/   r   r   r   
irrationalP   r   zAssumptionKeys.irrationalc                 C   r   )Nr   )FinitePredicate)handlers.calculusr1   )r   r1   r   r   r   finiteU   r   zAssumptionKeys.finitec                 C   r   )Nr   )InfinitePredicate)r2   r4   )r   r4   r   r   r   infiniteZ   r   zAssumptionKeys.infinitec                 C   r   )Nr   )PositiveInfinitePredicate)r2   r6   )r   r6   r   r   r   positive_infinite_   r   z AssumptionKeys.positive_infinitec                 C   r   )Nr   )NegativeInfinitePredicate)r2   r8   )r   r8   r   r   r   negative_infinited   r   z AssumptionKeys.negative_infinitec                 C   r   )Nr   )PositivePredicate)handlers.orderr:   )r   r:   r   r   r   positivei   r   zAssumptionKeys.positivec                 C   r   )Nr   )NegativePredicate)r;   r=   )r   r=   r   r   r   negativen   r   zAssumptionKeys.negativec                 C   r   )Nr   )ZeroPredicate)r;   r?   )r   r?   r   r   r   zeros   r   zAssumptionKeys.zeroc                 C   r   )Nr   )ExtendedPositivePredicate)r;   rA   )r   rA   r   r   r   extended_positivex   r   z AssumptionKeys.extended_positivec                 C   r   )Nr   )ExtendedNegativePredicate)r;   rC   )r   rC   r   r   r   extended_negative}   r   z AssumptionKeys.extended_negativec                 C   r   )Nr   )NonZeroPredicate)r;   rE   )r   rE   r   r   r   nonzero   r   zAssumptionKeys.nonzeroc                 C   r   )Nr   )NonPositivePredicate)r;   rG   )r   rG   r   r   r   nonpositive   r   zAssumptionKeys.nonpositivec                 C   r   )Nr   )NonNegativePredicate)r;   rI   )r   rI   r   r   r   nonnegative   r   zAssumptionKeys.nonnegativec                 C   r   )Nr   )ExtendedNonZeroPredicate)r;   rK   )r   rK   r   r   r   extended_nonzero   r   zAssumptionKeys.extended_nonzeroc                 C   r   )Nr   )ExtendedNonPositivePredicate)r;   rM   )r   rM   r   r   r   extended_nonpositive   r   z#AssumptionKeys.extended_nonpositivec                 C   r   )Nr   )ExtendedNonNegativePredicate)r;   rO   )r   rO   r   r   r   extended_nonnegative   r   z#AssumptionKeys.extended_nonnegativec                 C   r   )Nr   )EvenPredicate)handlers.ntheoryrQ   )r   rQ   r   r   r   even   r   zAssumptionKeys.evenc                 C   r   )Nr   )OddPredicate)rR   rT   )r   rT   r   r   r   odd   r   zAssumptionKeys.oddc                 C   r   )Nr   )PrimePredicate)rR   rV   )r   rV   r   r   r   prime   r   zAssumptionKeys.primec                 C   r   )Nr   )CompositePredicate)rR   rX   )r   rX   r   r   r   	composite   r   zAssumptionKeys.compositec                 C   r   )Nr   )CommutativePredicate)handlers.commonrZ   )r   rZ   r   r   r   commutative   r   zAssumptionKeys.commutativec                 C   r   )Nr   )IsTruePredicate)r[   r]   )r   r]   r   r   r   is_true   r   zAssumptionKeys.is_truec                 C   r   )Nr   )SymmetricPredicate)handlers.matricesr_   )r   r_   r   r   r   	symmetric   r   zAssumptionKeys.symmetricc                 C   r   )Nr   )InvertiblePredicate)r`   rb   )r   rb   r   r   r   
invertible   r   zAssumptionKeys.invertiblec                 C   r   )Nr   )OrthogonalPredicate)r`   rd   )r   rd   r   r   r   
orthogonal   r   zAssumptionKeys.orthogonalc                 C   r   )Nr   )UnitaryPredicate)r`   rf   )r   rf   r   r   r   unitary   r   zAssumptionKeys.unitaryc                 C   r   )Nr   )PositiveDefinitePredicate)r`   rh   )r   rh   r   r   r   positive_definite   r   z AssumptionKeys.positive_definitec                 C   r   )Nr   )UpperTriangularPredicate)r`   rj   )r   rj   r   r   r   upper_triangular   r   zAssumptionKeys.upper_triangularc                 C   r   )Nr   )LowerTriangularPredicate)r`   rl   )r   rl   r   r   r   lower_triangular   r   zAssumptionKeys.lower_triangularc                 C   r   )Nr   )DiagonalPredicate)r`   rn   )r   rn   r   r   r   diagonal   r   zAssumptionKeys.diagonalc                 C   r   )Nr   )FullRankPredicate)r`   rp   )r   rp   r   r   r   fullrank   r   zAssumptionKeys.fullrankc                 C   r   )Nr   )SquarePredicate)r`   rr   )r   rr   r   r   r   square   r   zAssumptionKeys.squarec                 C   r   )Nr   )IntegerElementsPredicate)r`   rt   )r   rt   r   r   r   integer_elements   r   zAssumptionKeys.integer_elementsc                 C   r   )Nr   )RealElementsPredicate)r`   rv   )r   rv   r   r   r   real_elements   r   zAssumptionKeys.real_elementsc                 C   r   )Nr   )ComplexElementsPredicate)r`   rx   )r   rx   r   r   r   complex_elements   r   zAssumptionKeys.complex_elementsc                 C   r   )Nr   )SingularPredicate)predicates.matricesrz   )r   rz   r   r   r   singular   r   zAssumptionKeys.singularc                 C   r   )Nr   )NormalPredicate)r{   r}   )r   r}   r   r   r   normal  r   zAssumptionKeys.normalc                 C   r   )Nr   )TriangularPredicate)r{   r   )r   r   r   r   r   
triangular	  r   zAssumptionKeys.triangularc                 C   r   )Nr   )UnitTriangularPredicate)r{   r   )r   r   r   r   r   unit_triangular  r   zAssumptionKeys.unit_triangularc                 C   r   )Nr   )EqualityPredicate)relation.equalityr   )r   r   r   r   r   eq  r   zAssumptionKeys.eqc                 C   r   )Nr   )UnequalityPredicate)r   r   )r   r   r   r   r   ne  r   zAssumptionKeys.nec                 C   r   )Nr   )StrictGreaterThanPredicate)r   r   )r   r   r   r   r   gt  r   zAssumptionKeys.gtc                 C   r   )Nr   )GreaterThanPredicate)r   r   )r   r   r   r   r   ge"  r   zAssumptionKeys.gec                 C   r   )Nr   )StrictLessThanPredicate)r   r   )r   r   r   r   r   lt'  r   zAssumptionKeys.ltc                 C   r   )Nr   )LessThanPredicate)r   r   )r   r   r   r   r   le,  r   zAssumptionKeys.leN)<__name__
__module____qualname____doc__r   r   r   r    r"   r$   r&   r(   r*   r,   r.   r0   r3   r5   r7   r9   r<   r>   r@   rB   rD   rF   rH   rJ   rL   rN   rP   rS   rU   rW   rY   r\   r^   ra   rc   re   rg   ri   rk   rm   ro   rq   rs   ru   rw   ry   r|   r~   r   r   r   r   r   r   r   r   r   r   r   r   r      s    






















































r   c                 C   s~   t  }| jD ]4}g }|D ]$}t|jtr0t|jjdkr0|jj|v r.|t	|jj
|j q n
q|r:|t| qt|S )a  
    Extract all relevant assumptions from *assump* with respect to given *exprs*.

    Parameters
    ==========

    assump : sympy.assumptions.cnf.CNF

    exprs : tuple of expressions

    Returns
    =======

    sympy.assumptions.cnf.CNF

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.cnf import CNF
    >>> from sympy.assumptions.ask import _extract_all_facts
    >>> from sympy.abc import x, y
    >>> assump = CNF.from_prop(Q.positive(x) & Q.integer(y))
    >>> exprs = (x,)
    >>> cnf = _extract_all_facts(assump, exprs)
    >>> cnf.clauses
    {frozenset({Literal(Q.positive, False)})}

    r   )setclauses
isinstanceZlitr   len	argumentsargappendr   functionis_Notadd	frozensetr   )ZassumpZexprsZfactsclauseargsliteralr   r   r   _extract_all_facts4  s   
r   Tc                 C   sh  ddl m} t| } t|}t| ts| jturtdt|ts&|jtur*tdtt	j
tt	jtt	jtt	jtt	jtt	ji}t| trK| j| j}}n| j|v rZ|| j | j}}nt	j| f}}t|}|| t||}t }	t  }
|
!t|	 |
"| |j#rt$|
du rt%d| t&||}|dur|S || '|}|durt(|S || ||d}|S )	a	  
    Function to evaluate the proposition with assumptions.

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

    This function evaluates the proposition to ``True`` or ``False`` if
    the truth value can be determined. If not, it returns ``None``.

    It should be discerned from :func:`~.refine()` which, when applied to a
    proposition, simplifies the argument to symbolic ``Boolean`` instead of
    Python built-in ``True``, ``False`` or ``None``.

    **Syntax**

        * ask(proposition)
            Evaluate the *proposition* in global assumption context.

        * ask(proposition, assumptions)
            Evaluate the *proposition* with respect to *assumptions* in
            global assumption context.

    Parameters
    ==========

    proposition : Any boolean expression.
        Proposition which will be evaluated to boolean value. If this is
        not ``AppliedPredicate``, it will be wrapped by ``Q.is_true``.

    assumptions : Any boolean expression, optional.
        Local assumptions to evaluate the *proposition*.

    context : AssumptionsContext, optional.
        Default assumptions to evaluate the *proposition*. By default,
        this is ``sympy.assumptions.global_assumptions`` variable.

    Returns
    =======

    ``True``, ``False``, or ``None``

    Raises
    ======

    TypeError : *proposition* or *assumptions* is not valid logical expression.

    ValueError : assumptions are inconsistent.

    Examples
    ========

    >>> from sympy import ask, Q, pi
    >>> from sympy.abc import x, y
    >>> ask(Q.rational(pi))
    False
    >>> ask(Q.even(x*y), Q.even(x) & Q.integer(y))
    True
    >>> ask(Q.prime(4*x), Q.integer(x))
    False

    If the truth value cannot be determined, ``None`` will be returned.

    >>> print(ask(Q.odd(3*x))) # cannot determine unless we know x
    None

    ``ValueError`` is raised if assumptions are inconsistent.

    >>> ask(Q.integer(x), Q.even(x) & Q.odd(x))
    Traceback (most recent call last):
      ...
    ValueError: inconsistent assumptions Q.even(x) & Q.odd(x)

    Notes
    =====

    Relations in assumptions are not implemented (yet), so the following
    will not give a meaningful result.

    >>> ask(Q.positive(x), x > 0)

    It is however a work in progress.

    See Also
    ========

    sympy.assumptions.refine.refine : Simplification using assumptions.
        Proposition is not reduced to ``None`` if the truth value cannot
        be determined.
    r   )sataskz.proposition must be a valid logical expressionz.assumptions must be a valid logical expressionFzinconsistent assumptions %sN)assumptionscontext))Zsympy.assumptions.sataskr   r   r   r   kindr	   	TypeErrorr
   Qr   r   r   r   r   r   r   r   r   r   r   r   r   r   funcr   r^   r   Z	from_propextendr   get_all_known_factsr   Zfrom_cnfZadd_from_cnfr   r   
ValueError_ask_single_factZ	_eval_askbool)Zpropositionr   r   r   Zbinrelpredskeyr   Z
assump_cnflocal_factsZknown_facts_cnfZenc_cnfresr   r   r   askd  s<   Z(






r   c           	      C   s   |j rgt }t|j dkr5|j \}t|dkr5|\}|| d}|dur(|d nt }|jr5|j|v r5dS |j D ].}t|dkrf|\}|jsM||jdnd}|du rTq8|\}}| |v r_ dS | |v rf dS q8dS )a  
    Compute the truth value of single predicate using assumptions.

    Parameters
    ==========

    key : sympy.assumptions.assume.Predicate
        Proposition predicate.

    local_facts : sympy.assumptions.cnf.CNF
        Local assumption in CNF form.

    Returns
    =======

    ``True``, ``False`` or ``None``

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.cnf import CNF
    >>> from sympy.assumptions.ask import _ask_single_fact

    If prerequisite of proposition is rejected by the assumption,
    return ``False``.

    >>> key, assump = Q.zero, ~Q.zero
    >>> local_facts = CNF.from_prop(assump)
    >>> _ask_single_fact(key, local_facts)
    False
    >>> key, assump = Q.zero, ~Q.even
    >>> local_facts = CNF.from_prop(assump)
    >>> _ask_single_fact(key, local_facts)
    False

    If assumption implies the proposition, return ``True``.

    >>> key, assump = Q.even, Q.zero
    >>> local_facts = CNF.from_prop(assump)
    >>> _ask_single_fact(key, local_facts)
    True

    If proposition rejects the assumption, return ``False``.

    >>> key, assump = Q.even, Q.odd
    >>> local_facts = CNF.from_prop(assump)
    >>> _ask_single_fact(key, local_facts)
    False
    r   Nr   FT)r   get_known_facts_dictr   getr   r   r   )	r   r   Zknown_facts_dictZclfZ
prop_factsZprop_reqr   Zprop_rejr   r   r   r     s.   3
r   c                 C   sb   t ddddd  t| tr| jj} tt| d}|dur$|| dS tt| t| |gd dS )z
    Register a handler in the ask system. key must be a string and handler a
    class inheriting from AskHandler.

    .. deprecated:: 1.8.
        Use multipledispatch handler instead. See :obj:`~.Predicate`.

    zregister_handler() function%multipledispatch handler of PredicateQ  1.8ZfeatureZ
useinsteadZissueZdeprecated_since_versionN)handlers)	r   warnr   r   namegetattrr   Zadd_handlersetattr)r   handlerZQkeyr   r   r   register_handlerD  s   	
r   c                 C   s:   t ddddd  t| tr| jj} tt| | dS )z
    Removes a handler from the ask system. Same syntax as register_handler

    .. deprecated:: 1.8.
        Use multipledispatch handler instead. See :obj:`~.Predicate`.

    zremove_handler() functionr   r   r   r   N)r   r   r   r   r   r   r   remove_handler)r   r   r   r   r   r   \  s   
r   )r   r   N)$r   Zsympy.assumptions.assumer   r   r   Zsympy.assumptions.cnfr   r   r   Z
sympy.corer   Zsympy.core.kindr	   Zsympy.core.relationalr
   r   r   r   r   r   Zsympy.logic.inferencer   Zsympy.utilities.decoratorr   Zsympy.utilities.exceptionsr   r   r   r   r   r   r   r   Zsympy.assumptions.ask_generatedr   r   r   r   r   r   <module>   s(       !0 S