Finally figured this all out (at least for everything I've tried it works). 
Option #3 described above was almost correct. Instead of setting the 
`_assumptions` attributes equal between the alias and the expression 
though, the `_assumptions` attribute should be cleared for the alias. If it 
has anything in it, the `prop_handler` won't be used, and it will just 
invoke the methods of the alias instead. Which is not what I want. Further, 
there was some funny behavior with using `lambda` functions to do the 
aliasing. It may be (probably was) coder error, but works now using full 
methods instead. That's what I get for trying to do things the easy way :/

Anyway, problem is *tentatively* solved. Still need to do the same for 
`MatrixExpr` types, this only works for `Expr`. Can't imagine it will be 
that different though.

- Jim


On Thursday, September 25, 2014 12:07:51 PM UTC-5, James Crist wrote:
>
> So I've spent some time trying to get this to work, and am still 
> struggling. Here's what I've tried:
>
> 1.) Subclass from `Expr`. Define `__getattr__`, and alias calls over to 
> the base expr. Unfortunately, `__getattr__` is only called for attributes 
> that are missing, and since all the `is_*` attributes already exist, this 
> doesn't actually work.
>
> 2.) Subclass from `Symbol`, and store the corresponding routine not in 
> `args`. When creating the symbol, pass in the underlying expr.assumptions0 
> as assumptions. This is wrong on so many levels. Things that aren't known 
> absolutely beforehand will be completely ignored. Also, while the `routine` 
> itself shouldn't be messed with by things like subs, the calling args 
> should be. So having the `RoutineCallResult` type as an atom isn't correct. 
> It should be closer to a function.
>
> 3.) Subclass from `Expr`. After creation, assign the _assumptions dict of 
> the underlying expr to RoutineCallResult._assumptions. Define methods in 
> RoutineCallResult._prop_handler for everything in 
> sympy.core.assumptions._assume_defined that reference the appropriate 
> `is_*` method in the underlying expression. This resulted in really weird 
> things happening when querying assumptions that weren't *known*. All sorts 
> of wrong responses for queries on both the underlying expression and the 
> RoutineCallResult object. Basically broke sympy.
>
> 4.) Subclass from `Expr`. Define explicit methods in the RoutineCallResult 
> class for every `is_*` attribute, that call self.expr.is_* and return the 
> result. This *worked*, but is super hackish, and I'd hope there'd be a 
> better way. That's like 30+ methods that I had to manually add, and if 
> SymPy adds more, then I'd have to do the same. There's probably a magic way 
> to go about this, but I'd still prefer something else if possible.
>
> Anyone have any thoughts? This is just for scalar return objects, those 
> that are Matrices will have another type that handles the same issue for 
> them.
>
> -Jim
>
> On Friday, September 19, 2014 1:54:04 PM UTC-5, Aaron Meurer wrote:
>>
>> On Fri, Sep 19, 2014 at 1:52 PM, Aaron Meurer <asme...@gmail.com> wrote: 
>> > On Fri, Sep 19, 2014 at 9:20 AM, James Crist <cris...@umn.edu> wrote: 
>> >>> it looks like in the first example that the expression is returned 
>> >>> directly while in the second case it is not(?) 
>> >> 
>> >> 
>> >> Ideally, for routines with one expr, `routine` and `routine[0]` will 
>> be 
>> >> identical. Not sure if this is possible, and I may decide that's too 
>> much 
>> >> magic. The main purpose behind all this is to make a more composable 
>> way of 
>> >> combining underlying compiled code. 
>> > 
>> > I don't think that's a good idea. To me, Routine((a, b, c), expr) and 
>> > Routine((a, b, c), (expr,)) should be different. 
>> > 
>> >> 
>> >> After playing around for a bit, it looks like this is going to be 
>> >> complicated. Even combinatorial operations (add, mul, etc...) call 
>> methods 
>> >> that refer to the underlying expression being computed. I'm not sure 
>> of the 
>> >> best way to do it, but right now I'm thinking I'll make a list of 
>> operations 
>> >> I want to be aliased to the underlying expression. Then I'll redefine 
>> >> `__getattribute__`, and redirect requests to the expression if they're 
>> in 
>> >> that list. That still may end up being too complicated, and I may have 
>> to 
>> >> rethink my approach. 
>> > 
>> > __getattr__, not __getattribute__. Don't override __getattribute__ 
>> > unless you really know what you are doing. 
>> > 
>> > Something like 
>> > 
>> > def __getattr__(self, attr): 
>> >     if attr.startswith('_eval_is_'): 
>> >         return getattr(self.expr, attr) 
>>
>> Oops, there should be a raise AttributeError here. Otherwise all other 
>> attributes will give None. 
>>
>> Aaron Meurer 
>>
>> > 
>> > For an applied routine, you probably want to substitute the values in 
>> > first as that can affect the assumptions. 
>> > 
>> > Aaron Meurer 
>> > 
>> >> 
>> >> On Fri, Sep 19, 2014 at 9:00 AM, Chris Smith <smi...@gmail.com> 
>> wrote: 
>> >>> 
>> >>> The assumptions system will try to call `_eval_is_foo` if it exists 
>> for 
>> >>> the object. So if you add definitions for ``_eval_is_integer` to your 
>> >>> Routine object you can return the value of `is_integer` for the 
>> return 
>> >>> value. I suspect there will be issues with how you define Routine, 
>> however, 
>> >>> since it looks like in the first example that the expression is 
>> returned 
>> >>> directly while in the second case it is not(?). 
>> >>> 
>> >>> 
>> >>> On Thursday, September 18, 2014 10:32:01 PM UTC-5, James Crist wrote: 
>> >>>> 
>> >>>> I have a new SymPy type that serves to represent a unit of 
>> computation 
>> >>>> (contains an expression/expressions that is/are being computed). I'd 
>> like to 
>> >>>> be able to alias queries on the assumptions of the element to 
>> assumptions of 
>> >>>> the underlying expression it represents. Example: 
>> >>>> 
>> >>>> >>> a, b, c = symbols('a, b, c', integer=True) 
>> >>>> >>> expr = a + b + c 
>> >>>> 
>> >>>> # Create the tree element 
>> >>>> >>> r = Routine((a, b, c), (expr)) 
>> >>>> 
>> >>>> # r now represents a computational routine. 
>> >>>> # We can use this as a function in other expressions. 
>> >>>> >>> new_expr = 1 + 2 + r(a, b, c) 
>> >>>> >>> new_expr 
>> >>>> 1 + 2 + r(a, b, c) 
>> >>>> 
>> >>>> # The following should work 
>> >>>> >>> new_expr.is_integer 
>> >>>> True 
>> >>>> >>> r(1, 2, 3).is_integer 
>> >>>> True 
>> >>>> 
>> >>>> For `Routine` objects with multiple returns, the results are indexed 
>> to 
>> >>>> select the output element: 
>> >>>> 
>> >>>> >>> exprs = (a + b + c, a*b*c + 4.1) 
>> >>>> >>> r = Routine((a, b, c), exprs) 
>> >>>> 
>> >>>> # Use it in a new expression 
>> >>>> >>> (1 + r(1, 2, 3)[0]).is_integer 
>> >>>> True 
>> >>>> >>> (1 + r(1, 2, 3)[1]).is_integer 
>> >>>> False 
>> >>>> 
>> >>>> Any idea how to go about doing this? I have little to no 
>> understanding of 
>> >>>> the assumption system, so before I start digging through the code I 
>> thought 
>> >>>> I'd ask if anyone had thoughts on how to tackle this. The `Routine` 
>> type, 
>> >>>> the `AppliedRoutine` type, and the results/arguments are all done. I 
>> just 
>> >>>> need to figure out (if possible) how I can make this play well with 
>> the 
>> >>>> assumption system. 
>> >>>> 
>> >>>> -Jim 
>> >>> 
>> >>> -- 
>> >>> You received this message because you are subscribed to a topic in 
>> the 
>> >>> Google Groups "sympy" group. 
>> >>> To unsubscribe from this topic, visit 
>> >>> https://groups.google.com/d/topic/sympy/XX4K-OhvqTU/unsubscribe. 
>> >>> To unsubscribe from this group and all its topics, send an email to 
>> >>> sympy+un...@googlegroups.com. 
>> >>> To post to this group, send email to sy...@googlegroups.com. 
>> >>> Visit this group at http://groups.google.com/group/sympy. 
>> >>> To view this discussion on the web visit 
>> >>> 
>> https://groups.google.com/d/msgid/sympy/7c9a540b-7661-40ab-8f99-39ddeef19f9c%40googlegroups.com.
>>  
>>
>> >>> 
>> >>> For more options, visit https://groups.google.com/d/optout. 
>> >> 
>> >> 
>> >> -- 
>> >> You received this message because you are subscribed to the Google 
>> Groups 
>> >> "sympy" group. 
>> >> To unsubscribe from this group and stop receiving emails from it, send 
>> an 
>> >> email to sympy+un...@googlegroups.com. 
>> >> To post to this group, send email to sy...@googlegroups.com. 
>> >> Visit this group at http://groups.google.com/group/sympy. 
>> >> To view this discussion on the web visit 
>> >> 
>> https://groups.google.com/d/msgid/sympy/CAJ2L7mdh7ObsxOv_rmiH8NaF%3Di6kNnoX5jq2f2XLBYs6uzaDQQ%40mail.gmail.com.
>>  
>>
>> >> 
>> >> For more options, visit https://groups.google.com/d/optout. 
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sympy+unsubscr...@googlegroups.com.
To post to this group, send email to sympy@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/9d3a52a2-b53c-4c32-a0e1-0f1a2c94f146%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to