* Implementation of relations between expressions */
/*
- * GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2020 Johannes Gutenberg University Mainz, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <iostream>
-#include <stdexcept>
-
#include "relational.h"
#include "operators.h"
#include "numeric.h"
#include "archive.h"
#include "utils.h"
+#include "hash_seed.h"
+
+#include <iostream>
+#include <stdexcept>
namespace GiNaC {
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(relational, basic,
print_func<print_context>(&relational::do_print).
- print_func<print_tree>(&basic::do_print_tree).
+ print_func<print_tree>(&relational::do_print_tree).
print_func<print_python_repr>(&relational::do_print_python_repr))
//////////
// default constructor
//////////
-relational::relational() : basic(TINFO_relational) {}
+relational::relational() { }
//////////
// other constructors
// public
-relational::relational(const ex & lhs, const ex & rhs, operators oper) : basic(TINFO_relational), lh(lhs), rh(rhs), o(oper) {}
+relational::relational(const ex & lhs, const ex & rhs, operators oper) :
+ lh(lhs), rh(rhs), o(oper) { }
//////////
// archiving
//////////
-relational::relational(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void relational::read_archive(const archive_node& n, lst& sym_lst)
{
+ inherited::read_archive(n, sym_lst);
unsigned int opi;
if (!(n.find_unsigned("op", opi)))
throw (std::runtime_error("unknown relational operator in archive"));
n.find_ex("lh", lh, sym_lst);
n.find_ex("rh", rh, sym_lst);
}
+GINAC_BIND_UNARCHIVER(relational);
void relational::archive(archive_node &n) const
{
n.add_unsigned("op", o);
}
-DEFAULT_UNARCHIVE(relational)
-
//////////
// functions overriding virtual functions from base classes
//////////
ex relational::map(map_function & f) const
{
- return (new relational(f(lh), f(rh), o))->setflag(status_flags::dynallocated);
-}
+ const ex &mapped_lh = f(lh);
+ const ex &mapped_rh = f(rh);
-ex relational::eval(int level) const
-{
- if (level==1)
- return this->hold();
-
- if (level == -max_recursion_level)
- throw(std::runtime_error("max recursion level reached"));
-
- return (new relational(lh.eval(level-1),rh.eval(level-1),o))->setflag(status_flags::dynallocated | status_flags::evaluated);
+ if (!are_ex_trivially_equal(lh, mapped_lh)
+ || !are_ex_trivially_equal(rh, mapped_rh))
+ return dynallocate<relational>(mapped_lh, mapped_rh, o);
+ else
+ return *this;
}
ex relational::subs(const exmap & m, unsigned options) const
GINAC_ASSERT(lh.return_type()==rh.return_type());
return lh.return_type();
}
-
-unsigned relational::return_type_tinfo() const
+
+return_type_t relational::return_type_tinfo() const
{
GINAC_ASSERT(lh.return_type_tinfo()==rh.return_type_tinfo());
return lh.return_type_tinfo();
unsigned relational::calchash() const
{
- unsigned v = golden_ratio_hash(tinfo());
+ unsigned v = make_hash_seed(typeid(*this));
unsigned lhash = lh.gethash();
unsigned rhash = rh.gethash();
break;
case greater:
case greater_or_equal:
- v ^= lhash;
+ v ^= lhash;
lhash = rhash;
break;
}
// new virtual functions which can be overridden by derived classes
//////////
-/** Left hand side of relational. */
-ex relational::lhs() const
-{
- return lh;
-}
-
-/** Right hand side of relational. */
-ex relational::rhs() const
-{
- return rh;
-}
+// none
//////////
// non-virtual functions in this class
relational::safe_bool relational::make_safe_bool(bool cond) const
{
- return cond? &safe_bool_helper::nonnull : 0;
+ return cond? &safe_bool_helper::nonnull : nullptr;
}
-/** Cast the relational into a boolean, mainly for evaluation within an
+/** Cast the relational into a Boolean, mainly for evaluation within an
* if-statement. Note that (a<b) == false does not imply (a>=b) == true in
* the general symbolic case. A false result means the comparison is either
* false or undecidable (except of course for !=, where true means either
case not_equal:
return make_safe_bool(!ex_to<numeric>(df).is_zero());
case less:
- return make_safe_bool(ex_to<numeric>(df)<_num0);
+ return make_safe_bool(ex_to<numeric>(df)<(*_num0_p));
case less_or_equal:
- return make_safe_bool(ex_to<numeric>(df)<=_num0);
+ return make_safe_bool(ex_to<numeric>(df)<=(*_num0_p));
case greater:
- return make_safe_bool(ex_to<numeric>(df)>_num0);
+ return make_safe_bool(ex_to<numeric>(df)>(*_num0_p));
case greater_or_equal:
- return make_safe_bool(ex_to<numeric>(df)>=_num0);
+ return make_safe_bool(ex_to<numeric>(df)>=(*_num0_p));
default:
throw(std::logic_error("invalid relational operator"));
}