Smarter relational to Boolean conversion.
authorVladimir V. Kisil <V.Kisilv@leeds.ac.uk>
Sun, 6 Jun 2021 12:00:50 +0000 (14:00 +0200)
committerRichard Kreckel <kreckel@ginac.de>
Sun, 6 Jun 2021 12:00:50 +0000 (14:00 +0200)
If a relational contains symbolic entries we look to ex::info
to decide whether it can be converted to true value.

ginac/relational.cpp

index 1b7e07fd1b016f0f9d4cbd67622c7208cfe232b4..892d2e911e123afe0b6832f7b8a3edc213b718cf 100644 (file)
@@ -309,25 +309,42 @@ relational::safe_bool relational::make_safe_bool(bool cond) const
 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"));
+       // 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"));
+               }
        }
 }