Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" This module contains the machinery handling assumptions.
All symbolic objects have assumption attributes that can be accessed via .is_<assumption name> attribute.
Assumptions determine certain properties of symbolic objects and can have 3 possible values: True, False, None. True is returned if the object has the property and False is returned if it doesn't or can't (i.e. doesn't make sense):
>>> from sympy import I >>> I.is_algebraic True >>> I.is_real False >>> I.is_prime False
When the property cannot be determined (or when a method is not implemented) None will be returned, e.g. a generic symbol, x, may or may not be positive so a value of None is returned for x.is_positive.
By default, all symbolic values are in the largest set in the given context without specifying the property. For example, a symbol that has a property being integer, is also real, complex, etc.
Here follows a list of possible assumption names:
.. glossary::
commutative object commutes with any other object with respect to multiplication operation.
complex object can have only values from the set of complex numbers.
imaginary object value is a number that can be written as a real number multiplied by the imaginary unit ``I``. See [3]_. Please note, that ``0`` is not considered to be an imaginary number, see `issue #7649 <https://github.com/sympy/sympy/issues/7649>`_.
real object can have only values from the set of real numbers.
integer object can have only values from the set of integers.
odd even object can have only values from the set of odd (even) integers [2]_.
prime object is a natural number greater than ``1`` that has no positive divisors other than ``1`` and itself. See [6]_.
composite object is a positive integer that has at least one positive divisor other than ``1`` or the number itself. See [4]_.
zero object has the value of ``0``.
nonzero object is a real number that is not zero.
rational object can have only values from the set of rationals.
algebraic object can have only values from the set of algebraic numbers [11]_.
transcendental object can have only values from the set of transcendental numbers [10]_.
irrational object value cannot be represented exactly by Rational, see [5]_.
finite infinite object absolute value is bounded (arbitrarily large). See [7]_, [8]_, [9]_.
negative nonnegative object can have only negative (nonnegative) values [1]_.
positive nonpositive object can have only positive (only nonpositive) values.
hermitian antihermitian object belongs to the field of hermitian (antihermitian) operators.
Examples ========
>>> from sympy import Symbol >>> x = Symbol('x', real=True); x x >>> x.is_real True >>> x.is_complex True
See Also ========
.. seealso::
:py:class:`sympy.core.numbers.ImaginaryUnit` :py:class:`sympy.core.numbers.Zero` :py:class:`sympy.core.numbers.One`
Notes =====
Assumption values are stored in obj._assumptions dictionary or are returned by getter methods (with property decorators) or are attributes of objects/classes.
References ==========
.. [1] http://en.wikipedia.org/wiki/Negative_number .. [2] http://en.wikipedia.org/wiki/Parity_%28mathematics%29 .. [3] http://en.wikipedia.org/wiki/Imaginary_number .. [4] http://en.wikipedia.org/wiki/Composite_number .. [5] http://en.wikipedia.org/wiki/Irrational_number .. [6] http://en.wikipedia.org/wiki/Prime_number .. [7] http://en.wikipedia.org/wiki/Finite .. [8] https://docs.python.org/3/library/math.html#math.isfinite .. [9] http://docs.scipy.org/doc/numpy/reference/generated/numpy.isfinite.html .. [10] http://en.wikipedia.org/wiki/Transcendental_number .. [11] http://en.wikipedia.org/wiki/Algebraic_number
""" from __future__ import print_function, division
from sympy.core.facts import FactRules, FactKB from sympy.core.core import BasicMeta from sympy.core.compatibility import integer_types
from random import shuffle
_assume_rules = FactRules([
'integer -> rational', 'rational -> real', 'rational -> algebraic', 'algebraic -> complex', 'real -> complex', 'real -> hermitian', 'imaginary -> complex', 'imaginary -> antihermitian', 'complex -> commutative',
'odd == integer & !even', 'even == integer & !odd',
'real == negative | zero | positive', 'transcendental == complex & !algebraic',
'negative == nonpositive & nonzero', 'positive == nonnegative & nonzero', 'zero == nonnegative & nonpositive',
'nonpositive == real & !positive', 'nonnegative == real & !negative',
'zero -> even & finite',
'prime -> integer & positive', 'composite -> integer & positive & !prime',
'irrational == real & !rational',
'imaginary -> !real',
'infinite -> !finite', 'noninteger == real & !integer', 'nonzero == real & !zero', ])
_assume_defined = _assume_rules.defined_facts.copy() _assume_defined.add('polar') _assume_defined = frozenset(_assume_defined)
class StdFactKB(FactKB): """A FactKB specialised for the built-in rules
This is the only kind of FactKB that Basic objects should use. """ rules = _assume_rules
def __init__(self, facts=None): # save a copy of the facts dict else:
def copy(self):
@property def generator(self):
def as_property(fact): """Convert a fact name to the name of the corresponding property"""
def make_property(fact): """Create the automagic property corresponding to a fact."""
def getit(self):
getit.func_name = as_property(fact) return property(getit)
def _ask(fact, obj): """ Find the truth value for a property of an object.
This function is called when a request is made to see what a fact value is.
For this we use several techniques:
First, the fact-evaluation function is tried, if it exists (for example _eval_is_integer). Then we try related facts. For example
rational --> integer
another example is joined rule:
integer & !odd --> even
so in the latter case if we are looking at what 'even' value is, 'integer' and 'odd' facts will be asked.
In all cases, when we settle on some fact value, its implications are deduced, and the result is cached in ._assumptions. """
# Store None into the assumptions so that recursive attempts at # evaluating the same fact don't trigger infinite recursion.
# First try the assumption evaluation function if it exists else:
# Try assumption's prerequisites
# we might have found the value of fact
# Note: the result has already been cached
class ManagedProperties(BasicMeta): """Metaclass for classes with old-style assumptions""" def __init__(cls, *args, **kws):
except AttributeError: pass
# Put definite results directly into the class dict, for speed
# protection e.g. for Integer.is_even=F <- (Rational.is_integer=F) except AttributeError: continue # not an assumption-aware class pname = as_property(fact) if pname not in cls.__dict__: setattr(cls, pname, make_property(fact))
# Finally, add any missing automagic property (e.g. for Basic) setattr(cls, pname, make_property(fact)) |