On Fri, 2009-07-24 at 21:10 +0200, Vinzent Steinberg wrote: > 2009/7/21 Fabian Pedregosa <fab...@fseoane.net>: > > > > This is now independent from objects and out of the core. Assume is > > the basic object is this new model, and it is only a container > > (all logic is done by sympy.logic and sympy.queries). > > --- > > sympy/__init__.py | 2 +- > > sympy/assumptions/__init__.py | 2 + > > sympy/assumptions/assume.py | 97 > > +++++++++++++++++++++++++ > > sympy/assumptions/tests/test_assumptions_2.py | 58 +++++++++++++++ > > sympy/printing/pretty/pretty.py | 3 + > > 5 files changed, 161 insertions(+), 1 deletions(-) > > create mode 100644 sympy/assumptions/__init__.py > > create mode 100644 sympy/assumptions/assume.py > > create mode 100644 sympy/assumptions/tests/test_assumptions_2.py > > > > diff --git a/sympy/__init__.py b/sympy/__init__.py > > index 3be16a4..c813490 100644 > > --- a/sympy/__init__.py > > +++ b/sympy/__init__.py > > @@ -21,7 +21,7 @@ def __sympy_debug(): > > > > import symbol as stdlib_symbol > > from sympy.core import * > > - > > +from assumptions import * > > from polys import * > > from series import * > > from functions import * > > diff --git a/sympy/assumptions/__init__.py b/sympy/assumptions/__init__.py > > new file mode 100644 > > index 0000000..bdd47c2 > > --- /dev/null > > +++ b/sympy/assumptions/__init__.py > > @@ -0,0 +1,2 @@ > > +from assume import Assume, register_global_assumptions, > > list_global_assumptions, \ > > + remove_global_assumptions, clean_global_assumptions > > diff --git a/sympy/assumptions/assume.py b/sympy/assumptions/assume.py > > new file mode 100644 > > index 0000000..4069ee9 > > --- /dev/null > > +++ b/sympy/assumptions/assume.py > > @@ -0,0 +1,97 @@ > > +# doctests are disabled because of issue #1521 > > +from sympy.core import Basic, Symbol > > +from sympy.core.relational import Relational > > + > > +__global_assumptions = [] > > + > > +def register_global_assumptions(*assump): > > + """Register an assumption as global > > + > > + Examples: > > +# >>> from sympy import * > > +# >>> list_global() > > +# [] > > +# >>> x = Symbol('x') > > +# >>> register_global(Assume(x, real=True)) > > +# True > > +# >>> list_global() > > +# [Assume(x, real=True)] > > + > > + You can undo this calling remove_global > > + """ > > + __global_assumptions.extend(assump) > > + > > +def list_global_assumptions(): > > + """List all global assumptions""" > > + return __global_assumptions[:] # make a copy > > + > > +def remove_global_assumptions(*assump): > > + """Remove a global assumption. If argument is not > > + a global assumption, it will raise ValueError > > + """ > > + for assumption in assump: > > + __global_assumptions.remove(assumption) > > + > > +def clean_global_assumptions(): > > + """Remove all global assumptions""" > > + global __global_assumptions > > + __global_assumptions = [] > > What about a global_assumptions object with methods? I would prefer > this over this functional approach
Yes, I also considered this approach, but for that I would need an object GlobalAssumptions with methods .Add(), .Remove(), .Clean(). Plus, this object should be a singleton of provide some way of preserving data. I just felt that it was too complicated, while current approach is much simpler (but I am willing to change it if there is a good reason to do so). > > > +class Assume(Basic): > > + """New-style assumptions > > + > > +# >>> from sympy import Symbol, Assume > > +# >>> x = Symbol('x') > > +# >>> Assume(x, integer=True) > > +# Assume( x, integer = True ) > > +# >>> Assume(x, integer=False) > > +# Assume( x, integer = False ) > > +# >>> Assume( x > 1 ) > > +# Assume( x > 1, relational = True) > > Why the additional spaces? ('( ', ' = ') > That's a bug, I'll correct it. > > + """hat > > + > > + def __init__(self, expr, *args, **kwargs): > > + if isinstance(expr, Symbol): > > + key, value = kwargs.popitem() > > + elif isinstance(expr, Relational): > > + key, value = 'relational', True > > + if kwargs: > > + raise ValueError('Wrong set of arguments') > > + self._args = (expr, key, value) > > + > > + is_Atom = True # do not attempt to decompose this > > + > > + @property > > + def expr(self): > > + return self._args[0] > > + > > + @property > > + def key(self): > > + return self._args[1] > > + > > + @property > > + def value(self): > > + return self._args[2] > > + > > + def __eq__(self, other): > > + if type(other) == Assume: > > + return self._args == other._args > > + return False > > + > > +def eliminate_assume(expr, symbol=None): > > + """ > > + Will convert an expression with assumptions to an equivalent with all > > assumptions > > + replaced by symbols > > + Assume(x, integer=True) --> integer > > + Assume(x, integer=False) --> ~integer > > + """ > > A doctest would be helpful, even if disabled. > indeed > > + if type(expr) == Assume: > > + if symbol is not None: > > + if not expr.expr.has(symbol): return > > + if expr.value: return Symbol(expr.key) > > + return ~Symbol(expr.key) > > + args = [] > > + for a in expr.args: > > + args.append(eliminate_assume(a)) > > + return type(expr)(*args) > > + > > diff --git a/sympy/assumptions/tests/test_assumptions_2.py > > b/sympy/assumptions/tests/test_assumptions_2.py > > new file mode 100644 > > index 0000000..d95162f > > --- /dev/null > > +++ b/sympy/assumptions/tests/test_assumptions_2.py > > @@ -0,0 +1,58 @@ > > +"""rename this to test_assumptions.py when the old assumptions system is > > deleted""" > > +from sympy.core import symbols > > +from sympy.assumptions import Assume, register_global_assumptions, \ > > + list_global_assumptions, remove_global_assumptions, > > clean_global_assumptions > > +from sympy.assumptions.assume import eliminate_assume > > +from sympy.printing import pretty > > + > > +def test_assume(): > > + x = symbols('x') > > + assump = Assume(x, integer=True) > > + assert assump.expr == x > > + assert assump.key == 'integer' > > + assert assump.value == True > > + > > +def test_False(): > > + """Test Assume object with False keys""" > > + x = symbols('x') > > + assump = Assume(x, integer=False) > > + assert assump.expr == x > > + assert assump.key == 'integer' > > + assert assump.value == False > > + > > +def test_equal(): > > + """Test for equality""" > > + x = symbols('x') > > + assert Assume(x, positive=True) == Assume(x, positive=True) > > + assert Assume(x, positive=True) != Assume(x, positive=False) > > + assert Assume(x, positive=False) == Assume(x, positive=False) > > + > > +def test_pretty(): > > + x = symbols('x') > > + assert pretty(Assume(x, positive=True)) == 'Assume(x, positive=True)' > > + > > +def test_eliminate_assumptions(): > > + a, b, x, y = symbols('abxy') > > + assert eliminate_assume(Assume(x, a=True)) == a > > + assert eliminate_assume(Assume(x, a=True), symbol=x) == a > > + assert eliminate_assume(Assume(x, a=True), symbol=y) == None > > + assert eliminate_assume(Assume(x, a=False)) == ~a > > + assert eliminate_assume(Assume(x, a=False), symbol=y) == None > > + assert eliminate_assume(Assume(x, a=True) | Assume(x, b=True)) == a | b > > + assert eliminate_assume(Assume(x, a=True) | Assume(x, b=False)) == a | > > ~b > > + > > +def test_global(): > > + """Test for global assumptions""" > > + x, y = symbols('x y') > > + register_global_assumptions(Assume(x>0)) > > + assert Assume(x>0) in list_global_assumptions() > > + remove_global_assumptions(Assume(x>0)) > > + assert (Assume(x>0) in list_global_assumptions()) == False > > + > > + # same with multiple of assumptions > > + register_global_assumptions(Assume(x>0), Assume(y>0)) > > + assert Assume(x>0) in list_global_assumptions() > > + assert Assume(y>0) in list_global_assumptions() > > + clean_global_assumptions() > > + assert (Assume(x>0) in list_global_assumptions()) == False > > + assert (Assume(y>0) in list_global_assumptions()) == False > > diff --git a/sympy/printing/pretty/pretty.py > > b/sympy/printing/pretty/pretty.py > > index 19ffff2..6d7f4da 100644 > > --- a/sympy/printing/pretty/pretty.py > > +++ b/sympy/printing/pretty/pretty.py > > @@ -56,6 +56,9 @@ def _print_Atom(self, e): > > except KeyError: > > return self.emptyPrinter(e) > > > > + def _print_Assume(self, e): > > + return prettyForm("Assume(%s, %s=%s)" % (e.expr, e.key, e.value)) > > + > > # Infinity inherits from Rational, so we have to override _print_XXX > > order > > _print_Infinity = _print_Atom > > _print_NegativeInfinity = _print_Atom > > -- > > 1.6.2.2 > > > > > > > > > > > Your work on assumptions is really shaping nicely! > Thanks!. > Vinzent > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy-patches" group. To post to this group, send email to sympy-patches@googlegroups.com To unsubscribe from this group, send email to sympy-patches+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sympy-patches?hl=en -~----------~----~----~----~------~----~------~--~---