This code used to cause an infinite loop that eventually killed Axiom.
The bug exists in the intef.spad, in ElementaryIntegration (INTEF),
in the routines lfextendedint and lflimitedint.

The input

  integrate((z^a+1)^b,z)

triggers the bug because of line 2 of each function.
Line 2 of these functions used to read:

      symbolIfCan(k := kmax(l := union(l, varselect(kernels g, x))))


The loop occurs when the call to union causes 

                     a log(z)
                   %e        

to get added to the list every time. This gives the argument to kmax 

                 a log(z)
      arg1= [z,%e        ]

and the result being

        a log(z)
      %e

We keep coming back to process this term, which ends up 
putting the same term back on the list and we loop.
Waldek's solution is to remove the union call. 

If we look at the original problem we see:
integrate((z^a+1)^b,z)

           z
         ++     a     b
   (1)   |   (%I  + 1) d%I
        ++
                                          Type: Union(Expression Integer,...)

and if we replace %I by z we get the original expression

           z
         ++    a     b
         |   (z  + 1) dz
        ++


=========================================================================
diff --git a/changelog b/changelog
index d6c0bdd..9baab4b 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,7 @@
+20070915 tpd merge bug100 branch
+20070915 tpd src/input/Makefile add bug100.input regression test
+20070915 tpd src/input/bug100.input test integrate((z^a+1)^b,z) infinite loop
+20070915 wxh src/algebra/intef.spad fix integrate((z^a+1)^b,z) infinite loop
 20070915 tpd src/algebra/carten minor edit for regression cleanup
 20070914 wxh src/hyper/hyper fix bad bracing of )hd change
 20070914 tpd src/algebra/fraction.spad remove double )spool command
diff --git a/src/algebra/intef.spad.pamphlet b/src/algebra/intef.spad.pamphlet
index 4dbbc26..955d284 100644
--- a/src/algebra/intef.spad.pamphlet
+++ b/src/algebra/intef.spad.pamphlet
@@ -227,9 +227,41 @@ ElementaryIntegration(R, F): Exports == Implementation 
where
         algint(f, t, y, differentiate(#1, differentiate(#1, x),
                                             differentiate(t::F, x)::UP))
 
+@
+Bug \#100 is an infinite loop that eventually kills Axiom 
+from the input
+\begin{verbatim}
+  integrate((z^a+1)^b,z)
+\end{verbatim}
+
+Line 2 of this function used to read:
+\begin{verbatim}
+      symbolIfCan(k := kmax(l := union(l, varselect(kernels g, x))))
+\end{verbatim}
+
+The loop occurs when the call to union causes 
+\begin{verbatim}
+                     a log(z)
+                   %e        
+\end{verbatim}
+to get added to the list every time. This gives the argument to kmax 
+\begin{verbatim}
+                 a log(z)
+      arg1= [z,%e        ]
+\end{verbatim}
+and the result being
+\begin{verbatim}
+        a log(z)
+      %e
+\end{verbatim}
+We keep coming back to process this term, which ends up 
+putting the same term back on the list and we loop.
+Waldek's solution is to remove the union call. 
+
+<<package INTEF ElementaryIntegration>>=
     lfextendedint(f, x, g) ==
       empty?(l := varselect(kernels f, x)) => [x::F * f, 0]
-      symbolIfCan(k := kmax(l := union(l, varselect(kernels g, x))))
+      symbolIfCan(k := kmax(l))
         case SE =>
           map(multivariate(#1, k), extendedint(univariate(f, k),
                                                univariate(g, k)))
@@ -238,9 +270,16 @@ ElementaryIntegration(R, F): Exports == Implementation 
where
       has?(operator k, ALGOP) => alglfextint(f, k, l, x, g)
       unkextint(f, x, g)
 
+@
+This is part of the fix for bug 100. Line 2 of this function used to read:
+\begin{verbatim}
+      symbolIfCan(k := kmax(l := union(l, vark(lu, x)))) case SE =>
+\end{verbatim}
+See the above discussion for why this causes an infinite loop.
+<<package INTEF ElementaryIntegration>>=
     lflimitedint(f, x, lu) ==
       empty?(l := varselect(kernels f, x)) => [x::F * f, empty()]
-      symbolIfCan(k := kmax(l := union(l, vark(lu, x)))) case SE =>
+      symbolIfCan(k := kmax(l)) case SE =>
        map(multivariate(#1, k), limitedint(univariate(f, k),
                                         [univariate(u, k) for u in lu]))
       is?(k, "exp"::SE) => explimint(f, x, k, lu)
diff --git a/src/input/Makefile.pamphlet b/src/input/Makefile.pamphlet
index 16a3b98..92c1dc5 100644
--- a/src/input/Makefile.pamphlet
+++ b/src/input/Makefile.pamphlet
@@ -287,7 +287,7 @@ REGRES= algaggr.regress algbrbf.regress  algfacob.regress 
alist.regress  \
     arrows.regress    assign.regress   atansqrt.regress \
     asec.regress      bags.regress      bbtree.regress \
     binary.regress    bop.regress      bstree.regress   bouquet.regress \
-    bug10069.regress \
+    bug100.regress    bug10069.regress \
     bugs.regress      bug10312.regress bug6357.regress  bug9057.regress \
     calcprob.regress  \
     calculus2.regress calculus.regress cardinal.regress card.regress \
@@ -502,7 +502,8 @@ FILES= ${OUT}/algaggr.input  ${OUT}/algbrbf.input    
${OUT}/algfacob.input \
        ${OUT}/bags.input     ${OUT}/bbtree.input     ${OUT}/bern.input \
        ${OUT}/bernpoly.input ${OUT}/binary.input     ${OUT}/bop.input \
        ${OUT}/bouquet.input  ${OUT}/bstree.input     ${OUT}/bug6357.input \
-       ${OUT}/bug9057.input  ${OUT}/bug10069.input   ${OUT}/bug10312.input \
+       ${OUT}/bug9057.input  ${OUT}/bug100.input \
+       ${OUT}/bug10069.input ${OUT}/bug10312.input \
        ${OUT}/calcprob.input ${OUT}/calculus.input \
        ${OUT}/cardinal.input ${OUT}/card.input       ${OUT}/carten.input \
        ${OUT}/cclass.input   ${OUT}/cdraw.input      ${OUT}/char.input \
@@ -677,6 +678,7 @@ DOCFILES= \
   ${DOC}/bernpoly.input.dvi    ${DOC}/binary.input.dvi     \
   ${DOC}/bop.input.dvi         ${DOC}/bouquet.input.dvi    \
   ${DOC}/bstree.input.dvi      ${DOC}/bug10069.input.dvi   \
+  ${DOC}/bug100.input.dvi \
   ${DOC}/bug10312.input.dvi    ${DOC}/bug6357.input.dvi    \
   ${DOC}/bug9057.input.dvi     ${DOC}/bugs.input.dvi       \
   ${DOC}/c02aff.input.dvi      ${DOC}/c02agf.input.dvi     \
diff --git a/src/input/bug100.input.pamphlet b/src/input/bug100.input.pamphlet
new file mode 100644
index 0000000..799d339
--- /dev/null
+++ b/src/input/bug100.input.pamphlet
@@ -0,0 +1,80 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/input bug100.input}
+\author{Timothy Daly}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+@
+This code used to cause an infinite loop that eventually killed Axiom.
+The bug exists in the {\tt intef.spad}, in ElementaryIntegration (INTEF),
+in the routines {\tt lfextendedint} and {\tt lflimitedint}.
+
+The input
+\begin{verbatim}
+  integrate((z^a+1)^b,z)
+\end{verbatim}
+triggers the bug because of line 2 of each function.
+Line 2 of these functions used to read:
+\begin{verbatim}
+      symbolIfCan(k := kmax(l := union(l, varselect(kernels g, x))))
+\end{verbatim}
+
+The loop occurs when the call to union causes 
+\begin{verbatim}
+                     a log(z)
+                   %e        
+\end{verbatim}
+to get added to the list every time. This gives the argument to kmax 
+\begin{verbatim}
+                 a log(z)
+      arg1= [z,%e        ]
+\end{verbatim}
+and the result being
+\begin{verbatim}
+        a log(z)
+      %e
+\end{verbatim}
+We keep coming back to process this term, which ends up 
+putting the same term back on the list and we loop.
+Waldek's solution is to remove the union call. 
+
+<<*>>=
+)spool bug100.output
+)set message test on
+)set message auto off
+)clear all
+ 
+--S 1 of 1
+integrate((z^a+1)^b,z)
+--R
+--R           z
+--R         ++     a     b
+--R   (1)   |   (%I  + 1) d%I
+--R        ++
+--R                                          Type: Union(Expression 
Integer,...)
+--E 1
+@
+If we substitute z for %I we get:
+\begin{verbatim}
+           z
+         ++    a     b
+         |   (z  + 1) dz
+        ++
+
+\end{verbatim}
+which is the original input integral.
+<<*>>=
+)spool 
+)lisp (bye)
+ 
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}


_______________________________________________
Axiom-developer mailing list
Axiom-developer@nongnu.org
http://lists.nongnu.org/mailman/listinfo/axiom-developer

Reply via email to