I think the problem is that solve() is designed as an interactive function. If you are sitting down in an interactive session and using solve(), then its output makes sense. It has different return types, but that's fine if you are just passing it something and looking directly at the solution. It sometimes gives partial results, but this is also fine in this setting because you can iterate. In these situations, solve() is actually kind of OK, because it just tries to do something helpful, although it's still not great, because with solve(), it can be hard to know how to tell it to do exactly what you do want.
But this whole idea falls apart once you want to work programmatically, because it's harder to programmatically react to different return types or different kinds of solution output, especially if you don't even know what the possible options are that you might get. This is sort of similar to simplify() vs. targetted simplification functions. If you use simplify(), you could get really anything. It's SymPy's prerogative to do whatever it wants. This is fine if you are working interactively because you can check yourself whether you like what it is doing. But in situations where you aren't manually eyeballing the result of every function call, it's a bad idea, and you're better off trying to think about what the exact simplifications you need are, and calling the appropriate functions for those. This disconnect exists in a lot of places in SymPy. We might try to document it better to make it clearer to users what the best practices are for interactive use vs. the best practices for programmatic/library use. So I'm starting to wonder if the real fix here isn't so much to "fix solve" (although solve() should definitely be improved and cleaned up), but rather to treat solve() as the "interactive only" function for equation solving, just as simplify() is the "interactive only" function for simplification. Users who know what they want should be encouraged to call more targeted solution routines, which only work on a specific type of equation, but also always give a fixed known output type with certain guarantees. solve() itself should be no more than a wrapper on top of these with some heuristics to guess what you want, just as simplify() just calls other simplification functions. Aaron Meurer On Wed, Mar 9, 2022 at 3:40 PM Oscar Benjamin <[email protected]> wrote: > > On Wed, 9 Mar 2022 at 19:29, Chris Smith <[email protected]> wrote: > > > > For the case of `eqs = [x+y+a, x+y+1]` you get the solution for `a = 1` if > > you give it the freedom to tell you that: `solve(eqs) -> {a: 1, x: -y - > > 1}`. This gives you the conditions for a solution: a value for `a` and a > > relationship between `x` and `y`. > > In very simple cases that approach might seem to work but it's not > hard to show when it doesn't if you go beyond trivial examples: > > In [22]: a, b, c, d, e, f, x, y = symbols('a:f, x, y') > > In [23]: eqs = [a*x + b*y + c, a*x + b*y + d] > > In [24]: solve(eqs, [x, y]) > Out[24]: [] > > In [26]: print(solve(eqs)) > [{a: -(b*y + d)/x, c: d}] > > Clearly I didn't want to solve for a and c here: that's why solve has > an argument to say what the unknowns are. > > -- > Oscar > > -- > 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 [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sympy/CAHVvXxRqw_1da01a%2BUvkeGkF5xA3ge%3DRuPYWv5UZDE-ez_reyg%40mail.gmail.com. -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAKgW%3D6K7jfrzj-%2BTLAYco5Wpem1hb4XDJpeyqH4hcT9K%3Di0w%3DQ%40mail.gmail.com.
