Re: [sage-devel] weirdness in simplifying a symbolic expression

40 views
Skip to first unread message
Message has been deleted

Nick Alexander

unread,
Jan 14, 2010, 11:14:23 PM1/14/10
to sage-...@googlegroups.com
> sage: y = expand(K.det()); y
> a*d*e*h - a*d*f*g - b*c*e*h + b*c*f*g
> sage: simplify(y)
> -a*d*f*g + a*d*h*e + b*c*f*g - b*c*h*e

To me, these look like the same expressions, just one has variables
sorted differently (h < e?) and different term orders. What is the
issue?

Nick

Jason Bandlow

unread,
Jan 14, 2010, 11:22:37 PM1/14/10
to sage-...@googlegroups.com

I think this is OK and shows how this sequence of commands is "supposed
to work". The calculation above it uses the same commands with
different variable names, and gets much stranger results.

-Jason

Message has been deleted

Craig Citro

unread,
Jan 15, 2010, 12:14:29 AM1/15/10
to sage-...@googlegroups.com
Yeah, this is wacky. I can tell you why it's happening, though someone
who's ever used Maxima before should really think about the right fix.
Here's the issue: in sage.calculus.calculus, there's an instance of
Maxima that gets created and passed the argument 'load(simplify_sum)'.
This causes the expression 'd2' to get simplified to
(3*n+k-1)!/(6*n+2*k)!. Here's a sample session illustrating the issue:

sage: maxima("d2")
d2
sage: sage.calculus.calculus.maxima("d2")
(3*n+k-1)!/(6*n+2*k)!
sage: Maxima(init_code=['load(simplify_sum)', 'display2d:false'])("d2")
(3*n+k-1)!/(6*n+2*k)!

Maybe someone who knows Maxima better could point us in the right direction?

As far as a workaround, in sage.symbolic.expression, the
Expression._maxima_ method imports maxima from sage.calculus.calculus
(which is initialized with the simplify_sum option). We could switch
that to the maxima session in sage.interfaces.maxima, but this is just
skirting the issue -- someone probably put simplify_sum there for a
reason, and I'd like to know what it is before changing it. Or, for
that matter, why do we have multiple maxima sessions running around?

-cc

kcrisman

unread,
Jan 15, 2010, 12:56:00 AM1/15/10
to sage-devel

There aren't multiple Maxima sessions in general. But if you needed
one you could get it. symbolic_sum is in there so that (surprise)
symbolic sums work. sorry for the brief reply, hopefully more time
later.

- kcrisman

rjf

unread,
Jan 15, 2010, 12:57:05 AM1/15/10
to sage-devel
It seems clear that in Maxima, something you directly or indirectly
loaded, set those names to values.
Maybe because d1, d2, ...., were used for the labels automatically
generated for display lines.

You can find all such values by maxima("values").

RJF

andrejv

unread,
Jan 15, 2010, 1:43:29 AM1/15/10
to sage-devel

On Jan 15, 6:14 am, Craig Citro <craigci...@gmail.com> wrote:
> Yeah, this is wacky. I can tell you why it's happening, though someone
> who's ever used Maxima before should really think about the right fix.
> Here's the issue: in sage.calculus.calculus, there's an instance of
> Maxima that gets created and passed the argument 'load(simplify_sum)'.
> This causes the expression 'd2' to get simplified to
> (3*n+k-1)!/(6*n+2*k)!. Here's a sample session illustrating the issue:
>
> sage: maxima("d2")
> d2
> sage: sage.calculus.calculus.maxima("d2")
> (3*n+k-1)!/(6*n+2*k)!
> sage: Maxima(init_code=['load(simplify_sum)', 'display2d:false'])("d2")
> (3*n+k-1)!/(6*n+2*k)!
>
> Maybe someone who knows Maxima better could point us in the right direction?

d2 is defined in the testsuite for the Zeilberger algorithm. It is not
necessary to load the tests, in share/contrib/Zeilberger/
zeilberger.mac remove the last line which loads them.

Andrej

Craig Citro

unread,
Jan 15, 2010, 1:48:55 AM1/15/10
to sage-...@googlegroups.com

Actually, I think it is, even though I agree it shouldn't be. For example:

[boxen ~] $ sage
----------------------------------------------------------------------
| Sage Version 4.3, Release Date: 2009-12-24                         |
| Type notebook() for the GUI, and license() for information.        |
----------------------------------------------------------------------
sage: maxima(5)
5
sage: exit
Exiting SAGE (CPU time 0m0.07s, Wall time 0m16.09s).
Exiting spawned Maxima process.
[boxen ~] $ sage
----------------------------------------------------------------------
| Sage Version 4.3, Release Date: 2009-12-24                         |
| Type notebook() for the GUI, and license() for information.        |
----------------------------------------------------------------------
sage: maxima(5)
5
sage: sage.calculus.calculus.maxima(5)
5
sage: exit
Exiting SAGE (CPU time 0m0.08s, Wall time 1m5.56s).
Exiting spawned Maxima process.
Exiting spawned Maxima process.
[boxen ~] $

Notice the two spawned Maxima processes in the second one ...

-cc

On Jan 14, 2010 9:56 PM, "kcrisman" <kcri...@gmail.com> wrote:

On Jan 15, 12:14 am, Craig Citro <craigci...@gmail.com> wrote: > Yeah, this is wacky. I can tell y...

There aren't multiple Maxima sessions in general.  But if you needed
one you could get it.  symbolic_sum is in there so that (surprise)
symbolic sums work.  sorry for the brief reply, hopefully more time
later.

- kcrisman

--
To post to this group, send an email to sage-...@googlegroups.com
To unsubscribe from this group, send an email to sage-devel+...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org

William Stein

unread,
Jan 15, 2010, 3:37:42 AM1/15/10
to sage-...@googlegroups.com

Wow, that's pretty annoying. So we have:

sage: d2 = var('d2')
sage: d2.simplify()
factorial(k + 3*n - 1)/factorial(2*k + 6*n)

and even worse things like:

sage: factorial = var('factorial')
sage: factorial^3 + factorial/7 - 1
factorial^3 + 1/7*factorial - 1
sage: (factorial^3 + factorial/7 - 1).simplify()
BOOM!

--

This could all be avoided if before changing a variable to maxima we
prepended it with _sage_var_ (say), and stripped those off when moving
from maxima back to Sage. This is worth considering...

Basically, right now, any time that one makes a symbolic variables
that just *happens* to be the same as the name of a function defined
in maxima's large global namespace, any symbolic calls to maxima
involving that variable break. One could imagine e.g., writing code
that works and uses an innocent sounding variable like x2 (say),
upgrading maxima in a few months, and finding that the code suddenly
doesn't work in arbitrarily confusing ways (since x2 could be defined
in Maxima to be something entirely weird/crazy like "factorial(k + 3*n
- 1)/factorial(2*k + 6*n)").

Thoughts?

Message has been deleted

andrejv

unread,
Jan 15, 2010, 6:13:34 AM1/15/10
to sage-devel
On Jan 15, 9:37 am, William Stein <wst...@gmail.com> wrote:

I think this is because factorial is a function in Sage. There is no
problem for ratsimp:

sage: ratsimp=var('ratsimp')
sage: (ratsimp^4+ratsimp^2+ratsimp+1).simplify()
ratsimp^4 + ratsimp^2 + ratsimp + 1

Prepending something to variable names probably does not fix the
problem for factorial.

Andrej

kcrisman

unread,
Jan 15, 2010, 10:00:09 AM1/15/10
to sage-devel
> >> Maybe someone who knows Maxima better could point us in the right direction?
>
> > d2 is defined in the testsuite for the Zeilberger algorithm. It is not
> > necessary to load the tests, in share/contrib/Zeilberger/
> > zeilberger.mac remove the last line which loads them.
>
> > Andrej
>
> Wow, that's pretty annoying.  So we have:
>
> sage: d2 = var('d2')
> sage: d2.simplify()
> factorial(k + 3*n - 1)/factorial(2*k + 6*n)
>
> and even worse things like:
>
> sage: factorial = var('factorial')
> sage: factorial^3 + factorial/7 - 1
> factorial^3 + 1/7*factorial - 1
> sage: (factorial^3 + factorial/7 - 1).simplify()
> BOOM!
>
> --
>
> This could all be avoided if before changing a variable to maxima we
> prepended it with _sage_var_ (say), and stripped those off when moving
> from maxima back to Sage.  This is worth considering...

Yeah, we might have to. See the following:

----------------------------------------------------------------------
| Sage Version 4.3.1.alpha2, Release Date: 2010-01-13 |


| Type notebook() for the GUI, and license() for information. |
----------------------------------------------------------------------

**********************************************************************
* *
* Warning: this is a prerelease version, and it may be unstable. *
* *
**********************************************************************
sage: from sage.calculus.calculus import maxima
sage: maxima.eval('values')
'[messlrats2,fullratsubstflag,dir,nonverbose,summary,very_verbose,extra,NO_HYP,HYP,PROOF_SILENT,PROOF_LOW,PROOF_MEDIUM,PROOF_HIGH,big_primes,max_ord,simplified_output,linear_solver,mod_test,modular_linear_solver,ev_point,mod_big_prime,mod_threshold,warnings,Gosper_in_Zeilberger,trivial_solutions,gs_prove_detail,zb_prove_detail,g1,g2,g3,g4,g5,g6,g7,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,h1,h2,h3,h4,h5,h6,h6b,h7,h8,h9,h10,h11,h12,h13,d1,d2,GOSPER_TEST,EASY_TEST,HARD_TEST,EXTREME_TEST,FULL_TEST,solve_rec_warn,simplify_products,normalize_products,distribute_products,simplify_products_deg,product_use_gamma,use_hyper,use_ratsol,hyper_factor_solve,hyper_all_solutions,hyper_to_product,solve_rec_method,shift_op,
%n,%f,%m,%l,%j,%k,%x,%u,
%z,zeilberger_check,sum_min,use_simpsum,use_harmonic,use_integral,use_gosper,use_ratfun,use_zeilberger,use_hgfred,simplify_sum_depth,simplify_sum_max_depth,verbose_level,harmonic_number_expand,sum_by_integral_transforms,sage0]'


Yikes - so g1-7, f1-10, h1-13, and d1, d2 are all pre-defined, not to
mention several other % guys.

These are the most likely candidates, so if Minh's fix gets rid of all
of them, that would be ideal and we might not have to do this.
Although 'extra' and 'big_primes' also seems like variables one might
actually use.

As to Craig's point, yes you can make another Maxima session, but in
general all internal Maxima use either uses _maxima_(), which calls
the "calculus" copy, or directly uses the "calculus" copy of Maxima.
For instance for assumptions we really want to only be using one
Maxima session.

Maybe Nils has a comment on whether library use of Maxima would make
it easier to work around this problem? I know he's hoping to do
something with this at the Bug Days.

- kcrisman

Craig Citro

unread,
Jan 15, 2010, 12:47:51 PM1/15/10
to sage-...@googlegroups.com
> This could all be avoided if before changing a variable to maxima we
> prepended it with _sage_var_ (say), and stripped those off when moving
> from maxima back to Sage.  This is worth considering...
>

I think we'll have to do something along these lines.

> Basically, right now, any time that one makes a symbolic variables
> that just *happens* to be the same as the name of a function defined
> in maxima's large global namespace, any symbolic calls to maxima
> involving that variable break.   One could imagine e.g., writing code
> that works and uses an innocent sounding variable like x2 (say),
> upgrading maxima in a few months, and finding that the code suddenly
> doesn't work in arbitrarily confusing ways (since x2 could be defined
> in Maxima to be something entirely weird/crazy like "factorial(k + 3*n
> - 1)/factorial(2*k + 6*n)").
>

Yep, this is definitely worrisome. Actually, thanks to the command
that RJF mentioned, it would be easy enough to check for collisions
when creating a variable -- however, this still doesn't solve the
issue that what variables are legal may change from one version of
maxima to another. (Heck, they could happen to pick _sage_var_x as a
variable in their namespace at some point ...)

Interestingly, though, this isn't what's happening in the example
below -- there's a second thing we have to worry about:

> sage: factorial = var('factorial')
> sage: factorial^3 + factorial/7 - 1
> factorial^3 + 1/7*factorial - 1
> sage: (factorial^3 + factorial/7 - 1).simplify()
> BOOM!
>

Here, the issue isn't that we're hitting the "factorial" in the maxima
namespace. It's that we're hitting factorial when we try to recreate a
sage symbolic expression from it. e.simplify() just does
SR(e._maxima_()), so let's do it in steps:

sage: factorial = var("factorial")

sage: e = factorial^3 + factorial/7 - 1
sage: e._maxima_()
factorial^3+factorial/7-1
sage: SR(e._maxima_())
BOOM!

> Thoughts?
>

I think we should rename variables when we move them over to maxima,
as you mentioned above, but also do a check when we first start a
maxima session to make sure that no entries that start with whatever
our prefix is pop up in their namespace. I think this will solve both
of the obvious issues -- but I'm sure there are more I'm not thinking
of. :)

-cc

Craig Citro

unread,
Jan 15, 2010, 12:58:20 PM1/15/10
to sage-...@googlegroups.com
> As to Craig's point, yes you can make another Maxima session, but in
> general all internal Maxima use either uses _maxima_(), which calls
> the "calculus" copy, or directly uses the "calculus" copy of Maxima.
> For instance for assumptions we really want to only be using one
> Maxima session.
>

Actually, that's not what I was saying. The point that I was making
(too briefly, apparently -- I was typing on my Droid :) ) is that we
already have two default sessions of maxima floating around: one in
sage.interfaces.maxima, which is what a call to maxima() from the
command line uses, and sage.calculus.calculus.maxima, which is what
gets used by the symbolics behind the scenes. So I have two questions:

1) Do we have two maxima sessions floating around on purpose? That is,
do we *want* the session we use for symbolic simplification to be a
different session than the one the user has access to from the command
line? (I could see an argument for doing this, but I'm not clear as to
whether it was on purpose or by accident.)

2) We start them with different options, which is why maxima("d2")
just returns d2, but sage.calculus.calculus.maxima("d2") returns the
factorial business that started this thread. Do we want to have some
of the options used to start sage.calculus.calculus.maxima also used
in sage.interfaces.maxima?

I also want to point out something that other people may have
realized, but has confused me before: if you're trying to do a
symbolic simplification, and maxima asks you a question, if you do
maxima("assume(x>0)") and try again, it will fail -- because it's
getting sent to the wrong maxima session:

sage: sqrt(x^2)
sqrt(x^2)
sage: sqrt(x^2).simplify()
sqrt(x^2)
sage: maxima.assume("x>0")
[x>0]
sage: sqrt(x^2).simplify()
sqrt(x^2)
sage: sage.calculus.calculus.maxima.assume("x>0")
[x>0]
sage: sqrt(x^2).simplify()
x

Do other people find this confusing?

-cc

Robert Bradshaw

unread,
Jan 15, 2010, 1:16:21 PM1/15/10
to sage-...@googlegroups.com
On Jan 15, 2010, at 9:58 AM, Craig Citro wrote:

>> As to Craig's point, yes you can make another Maxima session, but in
>> general all internal Maxima use either uses _maxima_(), which calls
>> the "calculus" copy, or directly uses the "calculus" copy of Maxima.
>> For instance for assumptions we really want to only be using one
>> Maxima session.
>>
>
> Actually, that's not what I was saying. The point that I was making
> (too briefly, apparently -- I was typing on my Droid :) ) is that we
> already have two default sessions of maxima floating around: one in
> sage.interfaces.maxima, which is what a call to maxima() from the
> command line uses, and sage.calculus.calculus.maxima, which is what
> gets used by the symbolics behind the scenes. So I have two questions:
>
> 1) Do we have two maxima sessions floating around on purpose? That is,
> do we *want* the session we use for symbolic simplification to be a
> different session than the one the user has access to from the command
> line? (I could see an argument for doing this, but I'm not clear as to
> whether it was on purpose or by accident.)

I think we do. Maxima sessions can have so much state that it's nice
to keep them separate to ensure consistency of the calculus modules.
Also, that means you won't be accidently clobbering your calculus
variables, functions, etc.

> 2) We start them with different options, which is why maxima("d2")
> just returns d2, but sage.calculus.calculus.maxima("d2") returns the
> factorial business that started this thread. Do we want to have some
> of the options used to start sage.calculus.calculus.maxima also used
> in sage.interfaces.maxima?
>
> I also want to point out something that other people may have
> realized, but has confused me before: if you're trying to do a
> symbolic simplification, and maxima asks you a question, if you do
> maxima("assume(x>0)") and try again, it will fail -- because it's
> getting sent to the wrong maxima session:
>
> sage: sqrt(x^2)
> sqrt(x^2)
> sage: sqrt(x^2).simplify()
> sqrt(x^2)
> sage: maxima.assume("x>0")
> [x>0]
> sage: sqrt(x^2).simplify()
> sqrt(x^2)
> sage: sage.calculus.calculus.maxima.assume("x>0")
> [x>0]
> sage: sqrt(x^2).simplify()
> x
>
> Do other people find this confusing?

Eventually (if not already) assumptions and the like will need to be
recorded and used at a higher level than the maxima interpreter
process, so I don't think we could always count on the above working.

- Robert


Craig Citro

unread,
Jan 15, 2010, 2:07:07 PM1/15/10
to sage-...@googlegroups.com
> I think we do. Maxima sessions can have so much state that it's nice to keep
> them separate to ensure consistency of the calculus modules. Also, that
> means you won't be accidently clobbering your calculus variables, functions,
> etc.
>

I think I agree in principle, but maybe not in practice. For the user
who knows nothing about Maxima, they're definitely not going to try to
do anything via maxima("...") themselves, so I think it doesn't matter
for them. On the other hand, our use of Maxima clearly isn't perfect
-- if someone knows enough about Maxima to be able to fix the problem
they're having on the Maxima side, it would be nice if that were a
little easier. Since integrate() and friends often comes back with an
error message talking about what we need to tell Maxima first, it'd be
nice if it were easier to do that. I guess I'm saying that I think the
benefits outweigh the dangers -- someone making calls via
maxima("...") probably realizes the prospect of clobbering variables,
unless maybe they were just copy-pasting someone else's code that does
it.

> Eventually (if not already) assumptions and the like will need to be
> recorded and used at a higher level than the maxima interpreter process, so
> I don't think we could always count on the above working.
>

I agree -- ultimately the user should never need to know that we're
using Maxima, and in theory we could one day be using some completely
different backend for integrals. But right now, lots of integrals end
in tracebacks like this:

TypeError: Computation failed since Maxima requested additional
constraints (try the command 'assume(sin(x+%pi/3)>0)' before integral
or limit evaluation, for example):
Is sin(x+%pi/3) positive, negative, or zero?

Using assume or maxima.assume doesn't help, but using
sage.calculus.calculus.maxima.assume *does* fix it. I just tested, and
the first three problems on sage-support about maxima and assume I
looked at were all fixed by using sage.calculus.calculus.maxima.assume
instead. I agree that it's not the solution we want in the long term,
but either (1) unifying the two maxima sessions or (2) making the
assume() command available at top-level point to
sage.calculus.calculus.maxima.assume *would* make it so that the user
could easily compute the integral that's frustrating them. (I know
that the one time I've run into this, I tried an integral, got a
traceback about assume, tried maxima("assume(...)"), which didn't fix
it -- so I gave up and just did the integral by hand.)

-cc

William Stein

unread,
Jan 15, 2010, 2:14:32 PM1/15/10
to sage-devel
On Fri, Jan 15, 2010 at 10:16 AM, Robert Bradshaw
<robe...@math.washington.edu> wrote:
> On Jan 15, 2010, at 9:58 AM, Craig Citro wrote:
>
>>> As to Craig's point, yes you can make another Maxima session, but in
>>> general all internal Maxima use either uses _maxima_(), which calls
>>> the "calculus" copy, or directly uses the "calculus" copy of Maxima.
>>> For instance for assumptions we really want to only be using one
>>> Maxima session.
>>>
>>
>> Actually, that's not what I was saying. The point that I was making
>> (too briefly, apparently -- I was typing on my Droid :) ) is that we
>> already have two default sessions of maxima floating around: one in
>> sage.interfaces.maxima, which is what a call to maxima() from the
>> command line uses, and sage.calculus.calculus.maxima, which is what
>> gets used by the symbolics behind the scenes. So I have two questions:
>>
>> 1) Do we have two maxima sessions floating around on purpose? That is,
>> do we *want* the session we use for symbolic simplification to be a
>> different session than the one the user has access to from the command
>> line? (I could see an argument for doing this, but I'm not clear as to
>> whether it was on purpose or by accident.)
>
> I think we do. Maxima sessions can have so much state that it's nice to keep
> them separate to ensure consistency of the calculus modules. Also, that
> means you won't be accidently clobbering your calculus variables, functions,
> etc.

This is definitely on purpose. I made this design decision long ago.
It's for the reason Robert mentions.

They are already recorded at a higher level -- this has been the case
since 2007.

sage: sqrt(x^2)
sqrt(x^2)
sage: assume(x>0)
sage: sqrt(x^2)
sqrt(x^2)

Hey wait, WTF?! This is really bad. I don't know what went wrong.
Evidently there is a new bug.

Anyway, regarding the above, Maxima should *never* need to be
explicitly invoked or mentioned for using Sage symbolics. Doing so is
very bad, since it would make is so symbolic user code depends
explicitly on Maxima. That's not good, since someday Sage's symbolics
likely won't use Maxima for any symbolic functionality.

-- William

William Stein

unread,
Jan 15, 2010, 2:18:29 PM1/15/10
to sage-devel
On Fri, Jan 15, 2010 at 11:07 AM, Craig Citro <craig...@gmail.com> wrote:
>> I think we do. Maxima sessions can have so much state that it's nice to keep
>> them separate to ensure consistency of the calculus modules. Also, that
>> means you won't be accidently clobbering your calculus variables, functions,
>> etc.
>>
>
> I think I agree in principle, but maybe not in practice. For the user
> who knows nothing about Maxima, they're definitely not going to try to
> do anything via maxima("...") themselves, so I think it doesn't matter
> for them. On the other hand, our use of Maxima clearly isn't perfect
> -- if someone knows enough about Maxima to be able to fix the problem
> they're having on the Maxima side, it would be nice if that were a
> little easier. Since integrate() and friends often comes back with an
> error message talking about what we need to tell Maxima first, it'd be
> nice if it were easier to do that. I guess I'm saying that I think the
> benefits outweigh the dangers -- someone making calls via
> maxima("...") probably realizes the prospect of clobbering variables,
> unless maybe they were just copy-pasting someone else's code that does
> it.

I disagree. This would lead to people writing code that will just
break later as Sage symbolic stop depending on Maxima (this dependence
is a temporary thing, IMHO).

>
>> Eventually (if not already) assumptions and the like will need to be
>> recorded and used at a higher level than the maxima interpreter process, so
>> I don't think we could always count on the above working.
>>
>
> I agree -- ultimately the user should never need to know that we're
> using Maxima, and in theory we could one day be using some completely
> different backend for integrals. But right now, lots of integrals end
> in tracebacks like this:
>
> TypeError: Computation failed since Maxima requested additional
> constraints (try the command 'assume(sin(x+%pi/3)>0)' before integral
> or limit evaluation, for example):
> Is  sin(x+%pi/3)  positive, negative, or zero?
>
> Using assume or maxima.assume doesn't help, but using

If that is true (is it?), that's just a big bug. It did help until
very recently.

> sage.calculus.calculus.maxima.assume *does* fix it. I just tested, and
> the first three problems on sage-support about maxima and assume I
> looked at were all fixed by using sage.calculus.calculus.maxima.assume
> instead. I agree that it's not the solution we want in the long term,
> but either (1) unifying the two maxima sessions or

No.

> (2) making the
> assume() command available at top-level point to
> sage.calculus.calculus.maxima.assume *would* make it so that the user
> could easily compute the integral that's frustrating them.

Again, (2) *was* the case since the beginning, and if it isn't now, it
is because somebody screwed stuff up and introduced a *huge* bug into
Sage recently.

> (I know
> that the one time I've run into this, I tried an integral, got a
> traceback about assume, tried maxima("assume(...)"), which didn't fix
> it -- so I gave up and just did the integral by hand.)
>
> -cc
>

> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to sage-devel+...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org
>
>

--
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

Robert Dodier

unread,
Jan 15, 2010, 2:35:00 PM1/15/10
to sage-devel
On Jan 14, 11:43 pm, andrejv <andrej.vodopi...@gmail.com> wrote:

> d2 is defined in the testsuite for the Zeilberger algorithm. It is not
> necessary to load the tests, in share/contrib/Zeilberger/
> zeilberger.mac remove the last line which loads them.

As a superficial correction, I threw a bit of code into
testZeilberger.mac to kill off the variables d1, d2, f1, f2, f3 ....
after they are used. Diff below.

best

Robert Dodier

PS.
--- share/contrib/Zeilberger/testZeilberger.mac 9 Feb 2007 22:32:34
-0000 1.4
+++ share/contrib/Zeilberger/testZeilberger.mac 15 Jan 2010 19:10:53
-0000
@@ -110,3 +110,8 @@

FULL_TEST : append(GOSPER_TEST,EASY_TEST,
HARD_TEST,EXTREME_TEST);
+
+kill (g1, g2, g3, g4, g5, g6, g7,
+ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10,
+ h1, h2, h3, h4, h5, h6, h6b, h7, h8, h9, h10, h11, h12, h13,
+ d1, d2);

Craig Citro

unread,
Jan 15, 2010, 2:37:47 PM1/15/10
to sage-...@googlegroups.com
>>  (2) making the
>> assume() command available at top-level point to
>> sage.calculus.calculus.maxima.assume *would* make it so that the user
>> could easily compute the integral that's frustrating them.
>
> Again, (2) *was* the case since the beginning, and if it isn't now, it
> is because somebody screwed stuff up and introduced a *huge* bug into
> Sage recently.
>

So if things were designed to work this way, then I'm definitely
strongly in favor of just finding this bug and fixing it. The user
that wants to fiddle with the Maxima session that's doing the calculus
can do it the same way I did, if they really need to ...

Now, back to the original issue we were talking about in this thread.
:) I'm still in favor of William's idea of prefixing variables, and
doing a check to make sure they're unbound. Is there a simpler/better
way to do it, though?

-cc

Nils Bruin

unread,
Jan 15, 2010, 2:43:23 PM1/15/10
to sage-devel
On Jan 15, 7:00 am, kcrisman <kcris...@gmail.com> wrote:

> Maybe Nils has a comment on whether library use of Maxima would make
> it easier to work around this problem?  I know he's hoping to do
> something with this at the Bug Days.

If we use maxima via a library interface and communicate exclusively
via strings, then the problem is exactly the same. However, if we move
to translating expression trees directly (which becomes a possibility
with the library interface) it is much easier to let new sage
variables correspond to a "(GENSYM)" [a guaranteed unique symbol] in
LISP and Maxima. The prototype on

http://trac.sagemath.org/sage_trac/ticket/7377

already does this. There is no problem working with a var('sin") in
that code.

It has the slight problem that any question or error from maxima has
very low probability of actually referring to any identifiers you can
make sense of. You'll have to look up in a dictionary what they
correspond to on the sage side.

kcrisman

unread,
Jan 15, 2010, 2:45:37 PM1/15/10
to sage-devel

No, this is (somewhere) documented behavior - we don't use the
assumption unless we use Maxima, which is via simplify()

sage: sqrt(x^2)
sqrt(x^2)
sage: assume(x>0)
sage: sqrt(x^2)
sqrt(x^2)

sage: _.simplify()
x

At any rate, that is what assumptions currently do. But it's not a
new bug, at any rate, as far as I know.

- kcrisman

Robert Bradshaw

unread,
Jan 15, 2010, 2:40:08 PM1/15/10
to sage-...@googlegroups.com

Yep, I remember working on that during the symbolics switch over. I
don't think we use it much yet though (though there's been a lot of
talk about doing so for the result of the solve command).

> sage: sqrt(x^2)
> sqrt(x^2)
> sage: assume(x>0)
> sage: sqrt(x^2)
> sqrt(x^2)
>
> Hey wait, WTF?! This is really bad. I don't know what went wrong.
> Evidently there is a new bug.

This is because assumptions don't get used until we simplify (or
otherwise make the round-trip to maxima).

sage: sqrt(x^2).simplify()
sqrt(x^2)
sage: assume(x>0)
sage: sqrt(x^2).simplify()
x

Perhaps Pynac could be informed of assumptions as well.

> Anyway, regarding the above, Maxima should *never* need to be
> explicitly invoked or mentioned for using Sage symbolics. Doing so is
> very bad, since it would make is so symbolic user code depends
> explicitly on Maxima. That's not good, since someday Sage's symbolics
> likely won't use Maxima for any symbolic functionality.

+1

Even if we use Maxima for some stuff for a long time to come (which I
think is the case), it hurts our flexibility to require the end user
to interact with it directly.

- Robert

kcrisman

unread,
Jan 15, 2010, 2:48:25 PM1/15/10
to sage-devel

> Again, (2) *was* the case since the beginning, and if it isn't now, it
> is because somebody screwed stuff up and introduced a *huge* bug into
> Sage recently.

We have done a few things in assumptions in the last few months, so
that is possible. However, in this case none of the doctests caught
it? And we do have some doctests which do those kinds of integrals...
don't we?

- kcrisman

Robert Dodier

unread,
Jan 15, 2010, 2:55:28 PM1/15/10
to sage-devel
On Jan 15, 1:37 am, William Stein <wst...@gmail.com> wrote:

> This could all be avoided if before changing a variable to maxima we
> prepended it with _sage_var_ (say), and stripped those off when moving
> from maxima back to Sage. This is worth considering...

Well, I think there is a neater way to go about it, which is
to exploit the Lisp package (i.e. namespace) machinery.
In summary, one can define groups of symbols at run time.
(A symbol package is a dynamic, not lexical, construct.)
So the general strategy would be to create a Sage namespace
and work within that, so that Sage symbols could be
distinguished from similarly-named ones in the Maxima namespace.

Some time ago I created a Maxima add-on named namespaces
to expose the Lisp package stuff. It more or less works as
intended but there are probably surprising effects related to
some Maxima symbol being visible or invisible. Also if you're
accustomed to lexical namespaces (as in Java and, for the
most part, Python) then dynamic namespaces might be
surprising.

A bare outline of the use of this namespace package:

load (foo);
load (bar);
/* ... and any other Maxima add-ons ... */
load (namespaces);
/* At this point any existing Maxima symbols are
* visible in new packages. Any new symbols e.g. blurf
* are visible only if qualified.
*/
blurf : 1234;
in_namespace (sage);
blurf : 5678;
blurf;
=> 1234
maxima|blurf;
=> 5678
in_namespace (maxima);
blurf;
=> 1234
sage|blurf;
=> 5678

I've probably promoted this idea before, and I'll probably
do so again; sorry for the repetition. As ever I wouldn't
mind having some help to finish it, if only some complaints
"well, it would be more useful if it would do Y instead of X ...".

FWIW

Robert Dodier

Craig Citro

unread,
Jan 15, 2010, 3:01:25 PM1/15/10
to sage-...@googlegroups.com
> Well, I think there is a neater way to go about it, which is
> to exploit the Lisp package (i.e. namespace) machinery.
> In summary, one can define groups of symbols at run time.

To quote the Zen of Python:

Namespaces are one honking great idea -- let's do more of those!

-cc

rjf

unread,
Jan 16, 2010, 1:36:12 PM1/16/10
to sage-devel
To some extent, these problems might go away if people used
nolabels:true in the files that they wrote to define their packages.
Then the the names that they leave around might be more likely to
be the names that they deliberately left around, and not the auto-
generated
names like C1, D1, %i1, %o2, ... used for labels.

Yes, a more elaborate solution involving name spaces
would allow programmer A to leave around names that programmer
B could use or not, but would not be likely to interfere by accident.

I think the common lisp standard for name spaces leaves a lot
to be desired, and there are elaborations of it (e.g. hierarchical)
that would be better.

Reply all
Reply to author
Forward
0 new messages