]> www.ginac.de Git - ginac.git/blobdiff - ginac/add.cpp
- minor fix in error log.
[ginac.git] / ginac / add.cpp
index c4e53360b1ed665dd9f7047bc7c63ba178697f1b..4cb118251b4b2e17cb2a71888ad718896b2c22bf 100644 (file)
@@ -107,7 +107,7 @@ add::add(epvector * vp, const ex & oc)
 DEFAULT_ARCHIVING(add)
 
 //////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
 //////////
 
 // public
@@ -131,27 +131,27 @@ void add::print(const print_context & c, unsigned level) const
                
                        // If the coefficient is -1, it is replaced by a single minus sign
                        if (it->coeff.compare(_num1()) == 0) {
-                               it->rest.bp->print(c, precedence());
+                               it->rest.print(c, precedence());
                        } else if (it->coeff.compare(_num_1()) == 0) {
                                c.s << "-";
-                               it->rest.bp->print(c, precedence());
+                               it->rest.print(c, precedence());
                        } else if (ex_to<numeric>(it->coeff).numer().compare(_num1()) == 0) {
-                               it->rest.bp->print(c, precedence());
+                               it->rest.print(c, precedence());
                                c.s << "/";
                                ex_to<numeric>(it->coeff).denom().print(c, precedence());
                        } else if (ex_to<numeric>(it->coeff).numer().compare(_num_1()) == 0) {
                                c.s << "-";
-                               it->rest.bp->print(c, precedence());
+                               it->rest.print(c, precedence());
                                c.s << "/";
                                ex_to<numeric>(it->coeff).denom().print(c, precedence());
                        } else {
-                               it->coeff.bp->print(c, precedence());
+                               it->coeff.print(c, precedence());
                                c.s << "*";
-                               it->rest.bp->print(c, precedence());
+                               it->rest.print(c, precedence());
                        }
                
                        // Separator is "+", except if the following expression would have a leading minus sign
-                       it++;
+                       ++it;
                        if (it != itend && !(it->coeff.compare(_num0()) < 0 || (it->coeff.compare(_num1()) == 0 && is_exactly_a<numeric>(it->rest) && it->rest.compare(_num0()) < 0)))
                                c.s << "+";
                }
@@ -159,7 +159,7 @@ void add::print(const print_context & c, unsigned level) const
                if (!overall_coeff.is_zero()) {
                        if (overall_coeff.info(info_flags::positive))
                                c.s << '+';
-                       overall_coeff.bp->print(c, precedence());
+                       overall_coeff.print(c, precedence());
                }
        
                if (precedence() <= level)
@@ -215,7 +215,7 @@ void add::print(const print_context & c, unsigned level) const
                                        c.s << '*';
                        }
                        it->rest.print(c, precedence());
-                       it++;
+                       ++it;
                }
 
                if (precedence() <= level) {
@@ -307,11 +307,15 @@ ex add::coeff(const ex & s, int n) const
        return (new add(coeffseq, n==0 ? overall_coeff : _ex0()))->setflag(status_flags::dynallocated);
 }
 
+/** Perform automatic term rewriting rules in this class.  In the following
+ *  x stands for a symbolic variables of type ex and c stands for such
+ *  an expression that contain a plain number.
+ *  - +(;c) -> c
+ *  - +(x;1) -> x
+ *
+ *  @param level cut-off in recursive evaluation */
 ex add::eval(int level) const
 {
-       // simplifications: +(;c) -> c
-       //                  +(x;1) -> x
-       
        debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION);
        
        epvector *evaled_seqp = evalchildren(level);
@@ -324,10 +328,10 @@ ex add::eval(int level) const
 #ifdef DO_GINAC_ASSERT
        epvector::const_iterator i = seq.begin(), end = seq.end();
        while (i != end) {
-               GINAC_ASSERT(!is_ex_exactly_of_type(i->rest,add));
+               GINAC_ASSERT(!is_exactly_a<add>(i->rest));
                if (is_ex_exactly_of_type(i->rest,numeric))
                        dbgprint();
-               GINAC_ASSERT(!is_ex_exactly_of_type(i->rest,numeric));
+               GINAC_ASSERT(!is_exactly_a<numeric>(i->rest));
                ++i;
        }
 #endif // def DO_GINAC_ASSERT
@@ -339,12 +343,14 @@ ex add::eval(int level) const
        }
        
        int seq_size = seq.size();
-       if (seq_size==0) {
+       if (seq_size == 0) {
                // +(;c) -> c
                return overall_coeff;
-       } else if ((seq_size==1) && overall_coeff.is_zero()) {
+       } else if (seq_size == 1 && overall_coeff.is_zero()) {
                // +(x;0) -> x
                return recombine_pair_to_ex(*(seq.begin()));
+       } else if (!overall_coeff.is_zero() && seq[0].rest.return_type() != return_types::commutative) {
+               throw (std::logic_error("add::eval(): sum of non-commutative objects has non-zero numeric term"));
        }
        return this->hold();
 }
@@ -464,7 +470,7 @@ expair add::split_ex_to_pair(const ex & e) const
 expair add::combine_ex_with_coeff_to_pair(const ex & e,
                                                                                  const ex & c) const
 {
-       GINAC_ASSERT(is_ex_exactly_of_type(c, numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(c));
        if (is_ex_exactly_of_type(e, mul)) {
                const mul &mulref(ex_to<mul>(e));
                ex numfactor = mulref.overall_coeff;
@@ -490,8 +496,8 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e,
 expair add::combine_pair_with_coeff_to_pair(const expair & p,
                                                                                        const ex & c) const
 {
-       GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
-       GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(p.coeff));
+       GINAC_ASSERT(is_exactly_a<numeric>(c));
 
        if (is_ex_exactly_of_type(p.rest,numeric)) {
                GINAC_ASSERT(ex_to<numeric>(p.coeff).is_equal(_num1())); // should be normalized
@@ -511,9 +517,6 @@ ex add::recombine_pair_to_ex(const expair & p) const
 
 ex add::expand(unsigned options) const
 {
-       if (options == 0 && (flags & status_flags::expanded))
-               return *this;
-       
        epvector *vp = expandchildren(options);
        if (vp == NULL) {
                // the terms have not changed, so it is safe to declare this expanded