K iKdZddlmZmZmZddlmZmZmZddl m Z ddl m Z ddl mZmZmZmZmZmZddlmZddlmZdd lmZmZmZGd d ZeZd Zd efdZdZ dZ!dZ"ddl#m$Z$m%Z%y)z4Module for querying SymPy objects about assumptions.)global_assumptions PredicateAppliedPredicate)CNF EncodedCNFLiteral)sympify) BooleanKind)EqNeGtLtGeLe) satisfiable)memoize_property)sympy_deprecation_warningSymPyDeprecationWarningignore_warningsceZdZdZedZedZedZedZedZ edZ edZ ed Z ed Z ed Zed Zed ZedZedZedZedZedZedZedZedZedZedZedZedZedZedZedZedZ edZ!edZ"ed Z#ed!Z$ed"Z%ed#Z&ed$Z'ed%Z(ed&Z)ed'Z*ed(Z+ed)Z,ed*Z-ed+Z.ed,Z/ed-Z0ed.Z1ed/Z2ed0Z3ed1Z4ed2Z5ed3Z6ed4Z7ed5Z8ed6Z9ed7Z:ed8Z;ed9Zrr cddlm}|S)Nr)TranscendentalPredicate)predicates.setsr5)rr5s rtranscendentalzAssumptionKeys.transcendentalCs<&((r cddlm}|S)Nr)IntegerPredicate)rr9)rr9s rintegerzAssumptionKeys.integerHr0r cddlm}|S)Nr)NonIntegerPredicate)r6r<)rr<s r nonintegerzAssumptionKeys.nonintegerMs8"$$r cddlm}|S)Nr)RationalPredicate)rr?)rr?s rrationalzAssumptionKeys.rationalRs4 ""r cddlm}|S)Nr)IrrationalPredicate)rrB)rrBs r irrationalzAssumptionKeys.irrationalWs6"$$r cddlm}|S)Nr)FinitePredicate)handlers.calculusrE)rrEs rfinitezAssumptionKeys.finite\6  r cddlm}|S)Nr)InfinitePredicate)rFrJ)rrJs rinfinitezAssumptionKeys.infinitea8 ""r cddlm}|S)Nr)PositiveInfinitePredicate)rFrN)rrNs rpositive_infinitez AssumptionKeys.positive_infinitef@(**r cddlm}|S)Nr)NegativeInfinitePredicate)rFrR)rrRs rnegative_infinitez AssumptionKeys.negative_infinitekrPr cddlm}|S)Nr)PositivePredicate)handlers.orderrU)rrUs rpositivezAssumptionKeys.positivep5 ""r cddlm}|S)Nr)NegativePredicate)rVrZ)rrZs rnegativezAssumptionKeys.negativeurXr cddlm}|S)Nr) ZeroPredicate)rVr])rr]s rzerozAssumptionKeys.zerozs 1r cddlm}|S)Nr)ExtendedPositivePredicate)rVr`)rr`s rextended_positivez AssumptionKeys.extended_positive=(**r cddlm}|S)Nr)ExtendedNegativePredicate)rVrd)rrds rextended_negativez AssumptionKeys.extended_negativerbr cddlm}|S)Nr)NonZeroPredicate)rVrg)rrgs rnonzerozAssumptionKeys.nonzeros4!!r cddlm}|S)Nr)NonPositivePredicate)rVrj)rrjs r nonpositivezAssumptionKeys.nonpositive8#%%r cddlm}|S)Nr)NonNegativePredicate)rVrn)rrns r nonnegativezAssumptionKeys.nonnegativerlr cddlm}|S)Nr)ExtendedNonZeroPredicate)rVrq)rrqs rextended_nonzerozAssumptionKeys.extended_nonzeros<'))r cddlm}|S)Nr)ExtendedNonPositivePredicate)rVrt)rrts rextended_nonpositivez#AssumptionKeys.extended_nonpositive@+--r cddlm}|S)Nr)ExtendedNonNegativePredicate)rVrx)rrxs rextended_nonnegativez#AssumptionKeys.extended_nonnegativervr cddlm}|S)Nr) EvenPredicate)handlers.ntheoryr{)rr{s revenzAssumptionKeys.evens 3r cddlm}|S)Nr) OddPredicate)r|r)rrs roddzAssumptionKeys.odds 2~r cddlm}|S)Nr)PrimePredicate)r|r)rrs rprimezAssumptionKeys.primes4r cddlm}|S)Nr)CompositePredicate)r|r)rrs r compositezAssumptionKeys.composites8!##r cddlm}|S)Nr)CommutativePredicate)handlers.commonr)rrs r commutativezAssumptionKeys.commutatives9#%%r cddlm}|S)Nr)IsTruePredicate)rr)rrs ris_truezAssumptionKeys.is_trues4  r cddlm}|S)Nr)SymmetricPredicate)handlers.matricesr)rrs r symmetriczAssumptionKeys.symmetrics9!##r cddlm}|S)Nr)InvertiblePredicate)rr)rrs r invertiblezAssumptionKeys.invertible:"$$r cddlm}|S)Nr)OrthogonalPredicate)rr)rrs r orthogonalzAssumptionKeys.orthogonalrr cddlm}|S)Nr)UnitaryPredicate)rr)rrs runitaryzAssumptionKeys.unitarys7!!r cddlm}|S)Nr)PositiveDefinitePredicate)rr)rrs rpositive_definitez AssumptionKeys.positive_definiterPr cddlm}|S)Nr)UpperTriangularPredicate)rr)rrs rupper_triangularzAssumptionKeys.upper_triangular?'))r cddlm}|S)Nr)LowerTriangularPredicate)rr)rrs rlower_triangularzAssumptionKeys.lower_triangularrr cddlm}|S)Nr)DiagonalPredicate)rr)rrs rdiagonalzAssumptionKeys.diagonalrLr cddlm}|S)Nr)FullRankPredicate)rr)rrs rfullrankzAssumptionKeys.fullrankrLr cddlm}|S)Nr)SquarePredicate)rr)rrs rsquarezAssumptionKeys.squarerHr cddlm}|S)Nr)IntegerElementsPredicate)rr)rrs rinteger_elementszAssumptionKeys.integer_elementsrr cddlm}|S)Nr)RealElementsPredicate)rr)rrs r real_elementszAssumptionKeys.real_elementss<$&&r cddlm}|S)Nr)ComplexElementsPredicate)rr)rrs rcomplex_elementszAssumptionKeys.complex_elementsrr cddlm}|S)Nr)SingularPredicate)predicates.matricesr)rrs rsingularzAssumptionKeys.singulars: ""r cddlm}|S)Nr)NormalPredicate)rr)rrs rnormalzAssumptionKeys.normal s8  r cddlm}|S)Nr)TriangularPredicate)rr)rrs r triangularzAssumptionKeys.triangulars<"$$r cddlm}|S)Nr)UnitTriangularPredicate)rr)rrs runit_triangularzAssumptionKeys.unit_triangulars@&((r cddlm}|S)Nr)EqualityPredicate)relation.equalityr)rrs reqzAssumptionKeys.eqrLr cddlm}|S)Nr)UnequalityPredicate)rr)rrs rnezAssumptionKeys.nerr cddlm}|S)Nr)StrictGreaterThanPredicate)rr)rrs rgtzAssumptionKeys.gt$sA)++r cddlm}|S)Nr)GreaterThanPredicate)rr)rrs rgezAssumptionKeys.ge)s;#%%r cddlm}|S)Nr)StrictLessThanPredicate)rr)rrs rltzAssumptionKeys.lt.s>&((r cddlm}|S)Nr)LessThanPredicate)rr)rrs rlezAssumptionKeys.le3rLr N)=__name__ __module__ __qualname____doc__rrr#r&r)r,r/r3r7r:r=r@rCrGrKrOrSrWr[r^rarerhrkrorrruryr}rrrrrrrrrrrrrrrrrrrrrrrrrrrrr rrrsg$$((''$$""$$))""%%##%%!!##++++####++++""&&&&**....  $$&&!!$$%%%%""++****####!!**''**##!!%%))##%%,,&&))##r rct}|jD]}g}|D]}t|jtrvt |jj dk(rT|jj|vr:|jt|jj|j|s|jt|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)setclauses isinstancelitrlen argumentsargappendrfunctionis_Notadd frozensetr)assumpexprsfactsclauseargsliterals r_extract_all_factsr;s< EE..+ +G'++'78SAVAV=W[\=\;;??e+KK (<(|f}}tAjB|} | jE|tG| |} tI} tK} | jMtA| | jO| | jPrtS| durtUd|ztW|| } | | S||jY|} | t[| S|||| } | | S |||| } | S#|$rYy wxYw) ay 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 : Boolean Proposition which will be evaluated to boolean value. If this is not ``AppliedPredicate``, it will be wrapped by ``Q.is_true``. assumptions : Boolean, 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)satask) lra_satask)UnhandledInputz.proposition must be a valid logical expressionz.assumptions must be a valid logical expressionFzinconsistent assumptions %sN) assumptionscontext).sympy.assumptions.sataskrsympy.assumptions.lra_sataskr!sympy.logic.algorithms.lra_theoryrr rrkindr TypeErrorr Qrr rr rrrrrrrrrrfunctyperrr from_propextendrget_all_known_factsrfrom_cnf add_from_cnfrr ValueError_ask_single_fact _eval_askbool) propositionrrrrr binrelpredskeyr assump_cnf local_factsknown_facts_cnfenc_cnfress raskrost07@+&K+&K+y)[-=-=[-PHII+y)[-=-=[-PHIIqttRr144QTT2qttRNK+/0((+*?*?T   [ ([ 12K4D4DTII ~T{+Jg%Z6K*+OlG S)* %{73u<6DEE 3 ,C   t*  { +C Cy +w GC  +wO J s; IIIc|jrt}t|jdk(r^|j\}t|dk(rB|\}|j|d}||dn t }|j r|j |vry|jD]S}t|dk(s|\}|j s|j|j dnd}|C|\}}||vry||vsSyy)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 rNrFT)rget_known_facts_dictrgetrrr) r r known_facts_dictclf prop_factsprop_reqrprop_rejs rrrsf/1 {"" #q (%%CB2w!|-11#t< ,6,B:a=88 1 !)) !F6{aFGhh-11!%%>TX %%/"((?H_  ! r ctdddt|tr|jj}t t |d}||j |ytt |t||gy)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 The AskHandler system is deprecated. The register_handler() function should be replaced with the multipledispatch handler of Predicate. 1.8deprecated-askhandlerdeprecated_since_versionactive_deprecations_targetN)handlers)rrrnamegetattrr add_handlersetattr)r handlerQkeys rregister_handlerr'Ysi "'#: #y!hhmm 1c4 D  !3 # :;r ctdddt|tr|jj}t t 5t t|j|dddy#1swYyxYw)z Removes a handler from the ask system. .. deprecated:: 1.8. Use multipledispatch handler instead. See :obj:`~.Predicate`. z The AskHandler system is deprecated. The remove_handler() function should be replaced with the multipledispatch handler of Predicate. rrrN) rrrr!rrr"rremove_handler)r r%s rr)r)ssd "'#: #y!hhmm 0 103&&w/000s  A--A6)rrN)&rsympy.assumptions.assumerrrsympy.assumptions.cnfrrr sympy.corer sympy.core.kindr sympy.core.relationalr r r rrrsympy.logic.inferencersympy.utilities.decoratorrsympy.utilities.exceptionsrrrrrrrrr'r)sympy.assumptions.ask_generatedrrrr rr3s{:::'88-699a#a#H 1h"&/ATnPf<40.r