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 
> <javascript:>> wrote: 
> > On Fri, Sep 19, 2014 at 9:20 AM, James Crist <cris...@umn.edu 
> <javascript:>> 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 
> <javascript:>> 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 <javascript:>. 
> >>> To post to this group, send email to sy...@googlegroups.com 
> <javascript:>. 
> >>> 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 <javascript:>. 
> >> To post to this group, send email to sy...@googlegroups.com 
> <javascript:>. 
> >> 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/c53a49ab-5503-4f61-9d03-3c0a9f3a4f33%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to