So a few things to respond to... Tom: >Can you describe what went wrong with these branches? In particular, >why can the following naive strategy not work: > >1. Make the new system at least as good as the old one. That is >whenever I can write foo.is_bar I can write ask(foo, Q.bar) and I will >get at least as good an answer. In particular Symbol('x', >positive=True) should register automatically in the global assumptions >that x > 0 (if I understand correctly how the new system works...). >2. Replace all queries foo.is_bar by ask(foo, Q.bar). >3. Remove all implementations of the is_bar properties. >4. Remove all remaining remnants of the old system.
This is what was largely tried with a branch last summer: - https://github.com/haz/sympy/tree/disconnect-assumptions-2 <https://github.com/haz/sympy/tree/disconnect-assumptions-2> There was push-back from the community since removing the Symbol('x', positive=True) syntax was largely frowned upon. Vinzent: >I think the only problem could be that ask() is much slower for >trivial queries, needs to be verified. This should be not too hard to >fix though. I don't think this is the case. Trivial queries (those that already have obvious implications) are compiled into quick reference dictionaries. In particular: - https://github.com/sympy/sympy/blob/master/sympy/assumptions/ask.py#L114 ----- In the end, everything in the new assumption system is done with a particular assumption context -- design decisions must be made on which context is used in the ambiguous cases. There is also an issue (feature request) that makes things more natural that will be worked on after the assumptions shift has taken place -- things like the following would be possible: with <some assumptions on variables>: <do stuff> This gives the assumptions an explicit local scope. The branch from last summer was mostly filled with fixing test cases so they used the new assumption system (with the global assumptions), and then cleaned up after themselves. It should also be emphasized that it isn't just a simple notion of cleaning up assumptions after yourself -- the cache interacts in quite an intertwined way. Under the right assumptions, expressions will be simplified, and variables will be assigned certain values. If that's stored in the cache, changing any related assumption will invalidate the result. For this reason, I had to manually clear the cache on a regular basis. I think that the cache is only really needed for lengthy solve algorithms (so you don't recompute an expression over and over), in which case we can probably wipe it after any sympy command is invoked (i.e., only use the cache while sympy is computing things, and then flush it just before returning the result). However, the branches from last summer never made it this far. I think a few things are generally universally accepted (correct me if I'm wrong though): 1. sympy/core/assumptions.py should be removed, and everything patched up to use sympy/assumptions/* 2. sympy/core/logic.py should be removed and replaced with sympy/logic/* 3. Assumptions should probably have the right references to be properly deleted from a context when their symbol is deleted -- this goes for any AssumptionContext (not just the global one) Open questions that need to be hashed out: 4. Do we remove the Symbol('x', positive=True) syntax? 5. If not, where does the assumption that x is positive get placed? (locally / globally) 6. How do we reconcile the issues with the cache remembering computations under certain assumptions? (flush after sympy computations / flush after an assumption changes / etc) Am I missing anything? Ronan: Can you elaborate on this? (my memory is failing me at the moment) > * Remove the cumbersome and confusing Assume() syntax Cheers On Sat, Apr 30, 2011 at 1:07 PM, Ronan Lamy <ronan.l...@gmail.com> wrote: > Le samedi 30 avril 2011 à 08:59 -0700, Tom Bachmann a écrit : > > This is roughly what I had in mind: > > [Everything is fake here, to only thing that is supposed to be > > illustrated is how assumptions get cleared up when their objects > > vanish.] > > > > import weakref > > > > class Assumption(object): > > pass > > > > class AssumePositive(Assumption): > > > > def __init__(self, x): > > self.var = weakref.ref(x, self.cb) > > > > def cb(self, var): > > if self.callback: > > self.callback(self) > > > > def __str__(self): > > return str(self.var) + ' > 0' > > > > class Symbol(object): > > def __init__(self, name): > > self.name = name > > > > def __str__(self): > > return str(self.name) > > > > assumptions = {} > > > > def remove_assumption(wr): > > print 'removing assumption', assumptions[wr] > > del assumptions[wr] > > > > N = 0 > > def assume(a): > > global N > > print 'adding assumption', a, 'as', N > > assumptions[a] = N > > a.callback = remove_assumption > > N += 1 > > > > def test2(): > > x = Symbol('y') > > assume(AssumePositive(x)) > > print assumptions > > print 'leaving test2' > > > > def test(): > > x = Symbol('x') > > assume(AssumePositive(x)) > > print assumptions > > print 'entering test2' > > test2() > > print assumptions > > print 'leaving test' > > > > test() > > > I don't see how this is in any way better than storing the assumptions > on the object. For instance, assume(AssumePositive(x + y)) won't work > properly. And it's not clear how assumptions can be retrieved. > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To post to this group, send email to sympy@googlegroups.com. > To unsubscribe from this group, send email to > sympy+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/sympy?hl=en. > > -- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to sympy@googlegroups.com. To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.