]> www.ginac.de Git - ginac.git/blobdiff - ginac/relational.cpp
Fix relational::compare_same_type.
[ginac.git] / ginac / relational.cpp
index 1b7e07fd1b016f0f9d4cbd67622c7208cfe232b4..dbc541a31c88e3377ff253161bcfdbd1effa9b05 100644 (file)
@@ -223,8 +223,8 @@ int relational::compare_same_type(const basic & other) const
                                return (o < oth.o) ? -1 : 1;
                        break;
        }
-       const int lcmpval = lh.compare(oth.rh);
-       return (lcmpval!=0) ? lcmpval : rh.compare(oth.lh);
+       const int lcmpval = lh.compare(oth.lh);
+       return (lcmpval!=0) ? lcmpval : rh.compare(oth.rh);
 }
 
 bool relational::match_same_type(const basic & other) const
@@ -308,27 +308,51 @@ relational::safe_bool relational::make_safe_bool(bool cond) const
  *  unequal or undecidable). */
 relational::operator relational::safe_bool() const
 {
-       const ex df = lh-rh;
-       if (!is_exactly_a<numeric>(df))
-               // cannot decide on non-numerical results
-               return o==not_equal ? make_safe_bool(true) : make_safe_bool(false);
-
-       switch (o) {
-               case equal:
-                       return make_safe_bool(ex_to<numeric>(df).is_zero());
-               case not_equal:
-                       return make_safe_bool(!ex_to<numeric>(df).is_zero());
-               case less:
-                       return make_safe_bool(ex_to<numeric>(df)<(*_num0_p));
-               case less_or_equal:
-                       return make_safe_bool(ex_to<numeric>(df)<=(*_num0_p));
-               case greater:
-                       return make_safe_bool(ex_to<numeric>(df)>(*_num0_p));
-               case greater_or_equal:
-                       return make_safe_bool(ex_to<numeric>(df)>=(*_num0_p));
-               default:
-                       throw(std::logic_error("invalid relational operator"));
+       const ex df = lh-rh;  // like ::canonical() method
+       // We treat numeric and symbolic expression differently
+       if (is_exactly_a<numeric>(df)) {
+               switch (o) {
+                       case equal:
+                               return make_safe_bool(ex_to<numeric>(df).is_zero());
+                       case not_equal:
+                               return make_safe_bool(!ex_to<numeric>(df).is_zero());
+                       case less:
+                               return make_safe_bool(ex_to<numeric>(df)<(*_num0_p));
+                       case less_or_equal:
+                               return make_safe_bool(ex_to<numeric>(df)<=(*_num0_p));
+                       case greater:
+                               return make_safe_bool(ex_to<numeric>(df)>(*_num0_p));
+                       case greater_or_equal:
+                               return make_safe_bool(ex_to<numeric>(df)>=(*_num0_p));
+                       default:
+                               throw(std::logic_error("invalid relational operator"));
+               }
+       } else {
+               // The conversion for symbolic expressions is based on the info flags
+               switch (o) {
+                       case equal:
+                               return make_safe_bool(df.is_zero());
+                       case not_equal:
+                               return make_safe_bool(! df.is_zero());
+                       case less:
+                               return make_safe_bool(df.info(info_flags::negative));
+                       case less_or_equal:
+                               return make_safe_bool((-df).info(info_flags::nonnegative));
+                       case greater:
+                               return make_safe_bool(df.info(info_flags::positive));
+                       case greater_or_equal:
+                               return make_safe_bool(df.info(info_flags::nonnegative));
+                       default:
+                               throw(std::logic_error("invalid relational operator"));
+               }
        }
 }
 
+/** Returns an equivalent relational with zero right-hand side.
+ */
+ex relational::canonical() const
+{
+       return relational(lh-rh, _ex0, o);
+}
+
 } // namespace GiNaC