> On Tue, Jan 31, 2012 at 4:38 PM, Nathan Rice
> <nathan.alexander.r...@gmail.com> wrote:
>> I am the author of elementwise (http://packages.python.org/
>> elementwise/) and constraints (http://packages.python.org/
>> constraintslib/).  These tools are similar to SymPy in their use of
>> symbolic proxy objects to represent values that may be provided later
>> (and to some degree in their target audience).
>
> This is cool.  Where can I get the code for these projects? I didn't
> see any download links (I know I can pip install, but I want to play
> with the code too).

My bad:

https://github.com/nathan-rice/Constraints
https://github.com/nathan-rice/Elementwise

>>
>> I'm getting in touch because:
>>
>> 1.) I'd like to get people on board with the idea of a standard symbol
>> proxy.  The general case is basically doing anything with a symbol
>> returns another symbol representing the resulting expression.  While
>> you do this to some degree now, the way in which you've gone about it
>> only allows you to use functions that return a wrapper object (Add,
>> Pow, etc).  Anyone that wants to interact SymPy has to take and return
>> these objects.  A much better scenario is to have and symbolic
>> expressions that can be realized down to normal python code (and which
>> can be generated in a general manner from ASTs).    This gives you
>> full interoperability with regular Python code.
>
> So I'm trying to understand exactly what you are suggesting here?  You
> want to do the sort of thing that SymPy does where you can build up
> expression symbolically, but abstract out the mathematical properties?
>  For example, x + x would not necessarily auto-reduce to 2*x (because
> "x" could be anything that supports __add__, like str).  We have an
> idea to make it easier to produce unevaluated expressions that I think
> is similar to what you are suggesting (see
> http://code.google.com/p/sympy/issues/detail?id=2738).

Basically, instead of having the specialized properties at the proxy
level, just use the proxy to build something resembling a generic AST.
 If done properly, it should be a fairly trivial matter to convert a
"true" python AST into a symbolic expression AST.  That lets you do
fun things with normal python functions :)  Granted, to really do fun
stuff, you will need to provide some annotations for any python
functions you want to use (it is possible to infer these automatically
in a great many cases but I don't think it is time to go down that
rabbit hole yet).

Also, building a generic AST means if you want to implement some
calculus down the line where distributivity or commutativity hold in
very different circumstances, you touch a lot less code.

>>
>> 2.) I noticed that a type system was on your roadmap.  Given a
>> solution can be achieved for #1, I feel this has broad applicability
>> to the community.  This also ties into your assumption architecture,
>> which I understand you are currently overhauling.  Ideally, your types
>> and assumptions should pretty much be one and the same.
>
> Definitely.  We are still in the process of removing the old system,
> and to some degree, evolving the new one.
>
> By the way, here's an example of the sort of thing to think about.
> Right now, our relationals (a < b, a <= b, etc.) work like this.  Expr
> < Expr creates Lt(Expr, Expr) (Expr is the base class of SymPy
> mathematical objects).  If the relational can be evaluated to True or
> False, that is returned. Otherwise, it is done mathematically.  For
> example:
>
> In [55]: S(1) < S(2)
> Out[55]: True
>
> In [56]: x < x
> Out[56]: False
>
> In [57]: x < y
> Out[57]: x < y
>
> (S() is a shortcut to sympify(), which converts the arguments into
> SymPy objects: in this case, Integer objects).
>
> The problem with this is in the auto-evaluation.  The relationals are
> serving a double purpose. On the one hand, they represent boolean
> objects (i.e., x < y means asking if x is less than y).  On the other
> hand, they represent symbolic (mathematical) objects.  (x < y as a
> mathematical statement).
>
> The difference may seem subtle, but the point is that the former
> should try to evaluate to boolean types, and the latter should not.
> We have an open issue to split the two
> (http://code.google.com/p/sympy/issues/detail?id=1887).
>
> The sort of thing I'd like to discuss is how to combine the two.  My
> idea is to make __lt__ default to the symbolic type.  But any call to
> bool() would coerce it to the boolean type.  This would also happen
> automatically if they are used in the assumptions system (like ask(x <
> y)).  On the other hand, even if x = Symbol('x', positive=True) (or
> assume(Q.positive(x)) or whatever the system looks like), you would
> want x**2 > 0 to remain unevaluated, so you can pass it to solve
> (solve(x**2 > 0), which would give something like x > 0).
>
> What is the best way to make the object unevaluated by default, but to
> evaluate intelligently in the right contexts, so that the user rarely
> has to think about such things.  The same question could apply to any
> kind of symbolic object.

My simple rule has been anything done with a symbol returns a symbol.
I think that works well for the general symbol proxy case.

I think in the more specific case, it depends on the context.  If you
know that a particular expression exists in the context of some
specific calculus, and under the accepted axioms you can make a
simplification that will __always__ be valid, you should go ahead and
make it.  You can fix the calculus based on what functions are used on
the expression, and any symbols would ideally have constraints, so
that requirement seems reasonable to me.  To reference your ask
example, if you assume that calling ask imposes an elementary algebra
context, that would give you a green light to reduce and transform,
without introducing inconsistencies in the behavior of the symbol
proxy itself.

So, to answer the question, I would build a general expression that is
"as written", then transform it as needed once the specific context
can be clearly identified.


I will go ahead and try to generalize the proxy base I have now to
support multiple variables and generate a full AST.  Once I've got
that I'll create a SymPy-experimental fork and start nibbling around
the edges of a rather large refactor as time permits :)


Nathan

-- 
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.

Reply via email to