Subject: asksign, clearsign, and meval* causes problems
From: Dieter Kaiser
Date: Sun, 01 Nov 2009 17:34:29 +0100
I had again a look at the bug report ID: 626607 "Defint doesn't clean up
asksign db" and I think I have found the underlying problem. It is the
mechanism of asksign itself and meval*, which causes the problem.
First, we confirm the bug in a fresh Maxima session. After we have done
the integration Maxima still knows that n is positive, if we ask with
asksign(n):
(%i2) integrate(x^n,x,1,inf);
Is n positive, negative, or zero?
p;
defint: integral is divergent.
-- an error. To debug this try: debugmode(true);
(%i3) asksign(n);
(%o3) pos
Second, we look at the sign of n with the function sign and not asksign.
Maxima does not know the sign. The fact is not present in the database:
(%i2) integrate(x^n,x,1,inf);
Is n positive, negative, or zero?
p;
defint: integral is divergent.
-- an error. To debug this try: debugmode(true);
(%i3) sign(n);
(%o3) pnz
(%i4) asksign(n);
Is n positive, negative, or zero?
p;
(%o4) pos
Last, we do first an evaluation after the integration. It does not
matter, what we exactly do, but the information about the sign of n is
lost after every next evaluation:
(%i2) integrate(x^n,x,1,inf);
Is n positive, negative, or zero?
p;
defint: integral is divergent.
-- an error. To debug this try: debugmode(true);
(%i3) 2+2;
(%o3) 4
(%i4) asksign(n);
Is n positive, negative, or zero?
p;
(%o4) pos
That is what happens:
1.
ASKSIGN puts its facts in a global variable LOCALES. ASKSIGN uses its
own syntax to store the facts.
2.
The facts in the global variable LOCALES are cleared with the function
CLEARSIGN, which is called from MEVAL* after evaluating an expression.
Therefore, the facts of ASKSIGN are only present during the current
evaluation of an expression.
3.
If the evaluation of an expression does not end normally, e.g. we get a
Maxima error, the facts in LOCALES are not cleared and are still present
in the following evaluation. That is the observation in the reported
bug.
This is what we can do to improve the function meval*:
(defun meval* (test)
;; Make sure that clearsign is called.
(unwind-protect
(let (refchkl baktrcl checkfactors)
(if $ratvarswitch (setq varlist (cdr $ratvars)))
(meval test))
(clearsign)))
With this code, CLEARSIGN is executed after an Maxima error too. The
reported bug is no longer present:
(%i4) integrate(x^n,x,1,inf);
Is n positive, negative, or zero?
p;
defint: integral is divergent.
-- an error. To debug this try: debugmode(true);
1. Trace: (CLEARSIGN)
1. Trace: CLEARSIGN ==> NIL
(%i5) asksign(n);
Is n positive, negative, or zero?
Remark:
meval* is called 68 times in Maxima core and share code. I am in doubt,
that all of this calls are appropriate. meval* should be called only at
the top level evaluation. Because every call of meval* clears the facts
from asksign, we might have some more bugs (See e.g. problems with
redundant questions form asksign).
I have tested the change of meval* and have got no problems with the
test_suite and share_testsuite.
Dieter Kaiser