From 7e268ccc7dc68f4e1ca3452f95951b9e8a76f03e Mon Sep 17 00:00:00 2001 From: "Vladimir V. Kisil" Date: Sun, 6 Jun 2021 14:00:50 +0200 Subject: [PATCH] Smarter relational to Boolean conversion. If a relational contains symbolic entries we look to ex::info to decide whether it can be converted to true value. --- ginac/relational.cpp | 55 +++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/ginac/relational.cpp b/ginac/relational.cpp index 1b7e07fd..892d2e91 100644 --- a/ginac/relational.cpp +++ b/ginac/relational.cpp @@ -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(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(df).is_zero()); - case not_equal: - return make_safe_bool(!ex_to(df).is_zero()); - case less: - return make_safe_bool(ex_to(df)<(*_num0_p)); - case less_or_equal: - return make_safe_bool(ex_to(df)<=(*_num0_p)); - case greater: - return make_safe_bool(ex_to(df)>(*_num0_p)); - case greater_or_equal: - return make_safe_bool(ex_to(df)>=(*_num0_p)); - default: - throw(std::logic_error("invalid relational operator")); + // We treat numeric and symbolic expression differently + if (is_exactly_a(df)) { + switch (o) { + case equal: + return make_safe_bool(ex_to(df).is_zero()); + case not_equal: + return make_safe_bool(!ex_to(df).is_zero()); + case less: + return make_safe_bool(ex_to(df)<(*_num0_p)); + case less_or_equal: + return make_safe_bool(ex_to(df)<=(*_num0_p)); + case greater: + return make_safe_bool(ex_to(df)>(*_num0_p)); + case greater_or_equal: + return make_safe_bool(ex_to(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")); + } } } -- 2.44.0