Fixed a bug in is_polynomial() that caused expressions like
authorJens Vollinga <jensv@nikhef.nl>
Fri, 20 May 2011 11:55:35 +0000 (13:55 +0200)
committerJens Vollinga <jensv@nikhef.nl>
Fri, 20 May 2011 11:55:35 +0000 (13:55 +0200)
sqrt(x*x+1)*sqrt(x+1) to be wrongly identified as polynomials in x.
Thanks to Florent Hivert for reporting.

check/exam_paranoia.cpp
ginac/expairseq.cpp

index 5fdfb35..972270f 100644 (file)
@@ -494,6 +494,18 @@ static unsigned exam_paranoia19()
        return 0;
 }
 
+// Bug in expairseq::is_polynomial (fixed 2011-05-20).
+static unsigned exam_paranoia20()
+{
+       symbol x("x");
+       ex e = sqrt(x*x+1)*sqrt(x+1);
+       if (e.is_polynomial(x)) {
+               clog << "sqrt(x*x+1)*sqrt(x+1) is wrongly reported to be a polynomial in x\n";
+               return 1;
+       }
+       return 0;
+}
+
 unsigned exam_paranoia()
 {
        unsigned result = 0;
@@ -519,6 +531,7 @@ unsigned exam_paranoia()
        result += exam_paranoia17();  cout << '.' << flush;
        result += exam_paranoia18();  cout << '.' << flush;
        result += exam_paranoia19();  cout << '.' << flush;
+       result += exam_paranoia20();  cout << '.' << flush;
        
        return result;
 }
index 90ec763..88d986e 100644 (file)
@@ -377,11 +377,22 @@ ex expairseq::conjugate() const
 
 bool expairseq::is_polynomial(const ex & var) const
 {
-       if (!is_exactly_a<add>(*this) && !is_exactly_a<mul>(*this))
+       if (is_exactly_a<add>(*this)) {
+               for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+                       if (!(i->rest).is_polynomial(var)) {
+                               return false;
+                       }
+               }
+       }
+       else if (is_exactly_a<mul>(*this)) {
+               for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+                       if (!(i->rest).is_polynomial(var) || !(i->coeff.info(info_flags::integer))) {
+                               return false;
+                       }
+               }
+       }
+       else {
                return basic::is_polynomial(var);
-       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
-               if (!(i->rest).is_polynomial(var))
-                       return false;
        }
        return true;
 }