From f408b8901cf6bd2e6b28423efe6853559cb46774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vio=20Lisb=C3=B4a?= Date: Mon, 11 Sep 2017 02:26:09 -0300 Subject: [PATCH] Finished implementing dense_dbm, major refactorings and revampings - (I'm all over the place here, sorry.) - (At least I implemented more unit tests!) --- CMakeLists.txt | 2 +- include/adl/crtp.hpp | 5 +- include/adl/oct/cons/basic_oct_cons.hpp | 26 +- .../oct/cons/basic_octdiff_conjunction.hpp | 8 +- include/adl/oct/cons/basic_octdiff_cons.hpp | 33 ++- include/adl/oct/cons/cons_base_.hpp | 29 ++- include/adl/oct/cpu/dense_dbm.hpp | 2 +- include/adl/oct/dbm.hpp | 2 +- include/adl/oct/dbm/dbm_base_.hpp | 9 +- .../{dense_dbm.hpp => dense_dbm_base_.hpp} | 245 ++++-------------- include/adl/oct/system/oct_system_.hpp | 197 +++++++++----- include/adl/oct/system/octdiff_system_.hpp | 158 +++++++---- include/adl/oct/system/system_base_.hpp | 3 +- include/adl/oct/system/var_set_.hpp | 4 +- include/adl/oct/traits.hpp | 1 + include/adl/oct/var/var_base_.hpp | 32 +-- include/adl/oct/vexpr/basic_oct_vexpr.hpp | 39 ++- include/adl/oct/vexpr/basic_octdiff_vexpr.hpp | 21 +- include/adl/oct/vexpr/vexpr_base_.hpp | 5 - test/include/adl_catch/macros.hpp | 20 ++ test/unit/adl/oct/cons.unit.cpp | 92 ++++++- test/unit/adl/oct/cpu/dense_dbm.unit.cpp | 189 +++++++++++--- test/unit/adl/oct/dbm/dense_dbm.unit.cpp | 2 +- test/unit/adl/oct/system.unit.cpp | 88 +++++-- 24 files changed, 740 insertions(+), 472 deletions(-) rename include/adl/oct/dbm/{dense_dbm.hpp => dense_dbm_base_.hpp} (53%) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa8a666..72b1c25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,7 +114,7 @@ target_sources(${api} INTERFACE "${api_dir_root}/adl/oct/dbm.hpp" "${api_dir_root}/adl/oct/dbm/traits.hpp" "${api_dir_root}/adl/oct/dbm/dbm_base_.hpp" - "${api_dir_root}/adl/oct/dbm/dense_dbm.hpp" + "${api_dir_root}/adl/oct/dbm/dense_dbm_base_.hpp" #adl/oct/cpu "${api_dir_root}/adl/oct/cpu.hpp" diff --git a/include/adl/crtp.hpp b/include/adl/crtp.hpp index f4519e3..bf43068 100644 --- a/include/adl/crtp.hpp +++ b/include/adl/crtp.hpp @@ -14,6 +14,9 @@ adl_BEGIN_ROOT_MODULE template class crtp_base { +public: + friend SubClass; + protected: using subclass_ = SubClass; @@ -50,7 +53,7 @@ constexpr typename crtp_base::subclass_& crtp_base::as_const template constexpr typename crtp_base::subclass_ const& crtp_base::as_const_() noexcept { - return const_cast(*this); + return const_cast(*this); } template diff --git a/include/adl/oct/cons/basic_oct_cons.hpp b/include/adl/oct/cons/basic_oct_cons.hpp index 525f64d..6b4d290 100644 --- a/include/adl/oct/cons/basic_oct_cons.hpp +++ b/include/adl/oct/cons/basic_oct_cons.hpp @@ -62,9 +62,16 @@ class basic_oct_cons : public cons_base_ { typename VarType_, typename = std::enable_if_t< common_var::is_oct_space - && !std::is_same::value + && (!std::is_same::value || !std::is_same::value) && std::is_convertible::value>> - constexpr basic_oct_cons(basic_oct_cons cons); + constexpr basic_oct_cons(basic_oct_cons const& cons); + + template < + typename VarType_, + typename = std::enable_if_t< + common_var::is_oct_space + && !std::is_same::value>> + explicit constexpr basic_oct_cons(basic_oct_vexpr vexpr); constexpr basic_oct_cons(var_type xi, value_type c); constexpr static basic_oct_cons make_upper_limit(var_type xi, value_type c) noexcept; // xi <= c @@ -96,6 +103,9 @@ class basic_oct_cons : public cons_base_ { constexpr octdiff_conjunction_type split() const noexcept; }; +template constexpr oct_cons to_identity(oct_cons cons) { return cons; } +template constexpr oct_cons to_identity(oct_lcons cons) { return cons.to_identity(); } + template < typename ValueType, typename VarType, @@ -290,6 +300,7 @@ std::basic_ostream& operator<<( // [[ TEMPLATE IMPLEMENTATION ]] // #include "adl/oct/cons/basic_octdiff_cons.hpp" +#include "adl/oct/cons/basic_octdiff_conjunction.hpp" adl_BEGIN_ROOT_MODULE namespace oct { @@ -300,9 +311,14 @@ namespace oct { template template -constexpr basic_oct_cons::basic_oct_cons(basic_oct_cons cons) +constexpr basic_oct_cons::basic_oct_cons(basic_oct_cons const& cons) : basic_oct_cons(vexpr_type(var_type(cons.xi()), var_type(cons.xj())), value_type(cons.c())) {}; +template +template +constexpr basic_oct_cons::basic_oct_cons(basic_oct_vexpr vexpr) + : basic_oct_cons(basic_oct_vexpr(vexpr.xi(), vexpr.xj()), value_type()) {}; + template constexpr basic_oct_cons::basic_oct_cons(var_type xi, value_type c) : superclass_(vexpr_type::make_unit(xi), c) {} @@ -398,8 +414,8 @@ basic_oct_cons::split() const noexcept { ); } return octdiff_conjunction_type::from_cons( - octdiff_conjunction_cons_type(octdiff_conjunction_vexpr_type(vexpr.xi(), vexpr.xj()), c_), - octdiff_conjunction_cons_type(octdiff_conjunction_vexpr_type(vexpr.xJ(), vexpr.xI()), constant) + octdiff_conjunction_cons_type(octdiff_conjunction_vexpr_type(vexpr.xi(), vexpr.xJ()), constant), + octdiff_conjunction_cons_type(octdiff_conjunction_vexpr_type(vexpr.xj(), vexpr.xI()), constant) ); } diff --git a/include/adl/oct/cons/basic_octdiff_conjunction.hpp b/include/adl/oct/cons/basic_octdiff_conjunction.hpp index 2a9bfe9..bc7909e 100644 --- a/include/adl/oct/cons/basic_octdiff_conjunction.hpp +++ b/include/adl/oct/cons/basic_octdiff_conjunction.hpp @@ -21,6 +21,7 @@ #include "adl/oct/var.hpp" #include "adl/oct/vexpr.hpp" + // // [[ API ]] // @@ -49,10 +50,9 @@ class basic_octdiff_conjunction { using identity_vexpr_type = typename var_traits::identity_vexpr_type; // Cons types - typedef typename var_traits::template cons_type cons_type; - typedef typename var_traits::template counterpart_cons_type counterpart_cons_type; // always basic_oct_cons - typedef typename var_traits::template identity_cons_type identity_cons_type; - typedef typename var_traits::template octdiff_conjunction_type octdiff_conjunction_type; + using cons_type = basic_octdiff_cons; + using counterpart_cons_type = basic_oct_cons; + using identity_cons_type = basic_oct_cons; struct less { constexpr bool operator()(basic_octdiff_conjunction const& lhs, basic_octdiff_conjunction const& rhs) const noexcept; diff --git a/include/adl/oct/cons/basic_octdiff_cons.hpp b/include/adl/oct/cons/basic_octdiff_cons.hpp index b8f3ba9..8e2441d 100644 --- a/include/adl/oct/cons/basic_octdiff_cons.hpp +++ b/include/adl/oct/cons/basic_octdiff_cons.hpp @@ -52,7 +52,6 @@ class basic_octdiff_cons : public cons_base_ { constexpr basic_octdiff_cons& operator=(basic_octdiff_cons &&) noexcept = default; constexpr basic_octdiff_cons(vexpr_type vexpr, value_type c); - constexpr static basic_octdiff_cons make_upper_limit(var_type xi, value_type c) noexcept; // xi <= c constexpr static basic_octdiff_cons make_upper_limit(vexpr_type vexpr, value_type c) noexcept; // +-xi [+- xj] <= c template < @@ -60,9 +59,16 @@ class basic_octdiff_cons : public cons_base_ { typename VarType_, typename = std::enable_if_t< common_var::is_octdiff_space - && !std::is_same::value + && (!std::is_same::value || !std::is_same::value) && std::is_convertible::value>> - constexpr basic_octdiff_cons(basic_octdiff_cons cons); + constexpr basic_octdiff_cons(basic_octdiff_cons cons) noexcept; + + template < + typename VarType_, + typename = std::enable_if_t< + common_var::is_octdiff_space + && !std::is_same::value>> + explicit constexpr basic_octdiff_cons(basic_octdiff_vexpr vexpr) noexcept; template < typename VarType_ = var_type, @@ -80,6 +86,9 @@ class basic_octdiff_cons : public cons_base_ { constexpr basic_octdiff_cons to_commuted() const noexcept; }; +template constexpr octdiff_cons to_identity(octdiff_cons cons) { return cons; } +template constexpr octdiff_cons to_identity(octdiff_lcons cons) { return cons.to_identity(); } + template < typename ValueType, typename VarType, @@ -169,6 +178,7 @@ std::basic_ostream& operator<<( // [[ TEMPLATE IMPLEMENTATION ]] // #include "adl/oct/cons/basic_oct_cons.hpp" +#include "adl/oct/cons/basic_octdiff_conjunction.hpp" adl_BEGIN_ROOT_MODULE namespace oct { @@ -180,10 +190,23 @@ namespace oct { template constexpr basic_octdiff_cons::basic_octdiff_cons(vexpr_type vexpr, value_type c) : superclass_(vexpr, c) {}; +template +constexpr basic_octdiff_cons +basic_octdiff_cons::make_upper_limit(vexpr_type vexpr, value_type c) noexcept { + return basic_octdiff_cons(vexpr, c); +}; + template template -constexpr basic_octdiff_cons::basic_octdiff_cons(basic_octdiff_cons cons) - : basic_octdiff_cons(vexpr_type(cons.xi(), cons.xj()), cons.c()) {}; +constexpr basic_octdiff_cons::basic_octdiff_cons( + basic_octdiff_cons cons +) noexcept : basic_octdiff_cons(vexpr_type(cons.xi(), cons.xj()), cons.c()) {}; + +template +template +constexpr basic_octdiff_cons::basic_octdiff_cons( + basic_octdiff_vexpr vexpr +) noexcept : basic_octdiff_cons(vexpr, value_type()) {}; template template diff --git a/include/adl/oct/cons/cons_base_.hpp b/include/adl/oct/cons/cons_base_.hpp index e501514..ef4117c 100644 --- a/include/adl/oct/cons/cons_base_.hpp +++ b/include/adl/oct/cons/cons_base_.hpp @@ -46,13 +46,22 @@ class cons_base_ { using counterpart_vexpr_type = typename var_traits::counterpart_vexpr_type; using identity_vexpr_type = typename var_traits::identity_vexpr_type; + // + // Const-static Variable definitions + // + + constexpr static const domain_space space = var_type::space; + constexpr static const domain_space counterpart_space = var_type::counterpart_space; + constexpr static const bool has_unit_cons = vexpr_type::has_unit_vexpr; + constexpr static const bool has_add_cons = vexpr_type::has_add_vexpr; + // Cons types - typedef typename var_traits::template cons_type cons_type; - typedef typename var_traits::template counterpart_cons_type counterpart_cons_type; - typedef typename var_traits::template identity_cons_type identity_cons_type; - typedef typename var_traits::template octdiff_conjunction_type octdiff_conjunction_type; - using octdiff_conjunction_cons_type = typename octdiff_conjunction_type::cons_type; - using octdiff_conjunction_vexpr_type = typename octdiff_conjunction_type::vexpr_type; + using cons_type = typename var_traits::template cons_type; + using counterpart_cons_type = typename var_traits::template counterpart_cons_type; + using identity_cons_type = typename var_traits::template identity_cons_type; + using octdiff_conjunction_type = std::conditional_t, basic_octdiff_conjunction>; + using octdiff_conjunction_vexpr_type = std::conditional_t; + using octdiff_conjunction_cons_type = std::conditional_t; struct less { constexpr bool operator()(cons_type const& lhs, cons_type const& rhs) const noexcept; @@ -62,14 +71,6 @@ class cons_base_ { constexpr std::size_t operator()(cons_type const& lhs) const noexcept; }; - // - // Const-static Variable definitions - // - - constexpr static const domain_space space = var_type::space; - constexpr static const domain_space counterpart_space = var_type::counterpart_space; - constexpr static const bool has_unit_cons = vexpr_type::has_unit_vexpr; - constexpr static const bool has_add_cons = vexpr_type::has_add_vexpr; private: using subclass_ = cons_type; diff --git a/include/adl/oct/cpu/dense_dbm.hpp b/include/adl/oct/cpu/dense_dbm.hpp index a70f757..322c2ab 100644 --- a/include/adl/oct/cpu/dense_dbm.hpp +++ b/include/adl/oct/cpu/dense_dbm.hpp @@ -10,7 +10,7 @@ #include "adl.cfg.hpp" #include "adl/oct/dbm/traits.hpp" -#include "adl/oct/dbm/dense_dbm.hpp" +#include "adl/oct/dbm/dense_dbm_base_.hpp" adl_BEGIN_ROOT_MODULE namespace oct { diff --git a/include/adl/oct/dbm.hpp b/include/adl/oct/dbm.hpp index 512ac2e..749dca7 100644 --- a/include/adl/oct/dbm.hpp +++ b/include/adl/oct/dbm.hpp @@ -7,6 +7,6 @@ #include "adl/oct/dbm/traits.hpp" #include "adl/oct/dbm/dbm_base_.hpp" -#include "adl/oct/dbm/dense_dbm.hpp" +#include "adl/oct/dbm/dense_dbm_base_.hpp" #endif //adl__oct__dbm__hpp__ diff --git a/include/adl/oct/dbm/dbm_base_.hpp b/include/adl/oct/dbm/dbm_base_.hpp index c49be2e..ebb4aad 100644 --- a/include/adl/oct/dbm/dbm_base_.hpp +++ b/include/adl/oct/dbm/dbm_base_.hpp @@ -23,7 +23,7 @@ class dbm_base_ : public dbm_types_, public crtp_base> - constexpr static std::size_t to_end_index_(VarType_ var) noexcept; + constexpr static std::size_t to_end_index_(VarType_ last_var) noexcept; public: using typename superclass_::identity_var_type; @@ -52,11 +52,8 @@ namespace oct { template template -constexpr std::size_t dbm_base_::to_end_index_(VarType_ var) noexcept { - auto diff_var = to_octdiff(var); - return diff_var.positive() // Goes to the next positive (that is the end variable if negative-coerced var is the last) - ? diff_var.to_incremented(2).to_index() // Var is positive, needs 2 increments in octdiff space instead of one - : diff_var.to_incremented().to_index(); +constexpr std::size_t dbm_base_::to_end_index_(VarType_ last_var) noexcept { + return to_octdiff(last_var).normalize().increment(2).to_index(); }; template diff --git a/include/adl/oct/dbm/dense_dbm.hpp b/include/adl/oct/dbm/dense_dbm_base_.hpp similarity index 53% rename from include/adl/oct/dbm/dense_dbm.hpp rename to include/adl/oct/dbm/dense_dbm_base_.hpp index a736915..f0efd3d 100644 --- a/include/adl/oct/dbm/dense_dbm.hpp +++ b/include/adl/oct/dbm/dense_dbm_base_.hpp @@ -2,8 +2,8 @@ /** * @file dense_dbm.hpp.hpp */ -#ifndef adl__oct__dbm__dense_dbm__hpp__ -#define adl__oct__dbm__dense_dbm__hpp__ +#ifndef adl__oct__dbm__dense_dbm_base___hpp__ +#define adl__oct__dbm__dense_dbm_base___hpp__ #include #include @@ -53,6 +53,7 @@ class dense_dbm_base_ : public dbm_base_ { public: bool dense() const noexcept; bool autocoherent() const noexcept; + dbm_major major() const noexcept; octdiff_cons get(oct_var xi) const; octdiff_cons get(octdiff_var xi, octdiff_var xj) const; @@ -72,72 +73,17 @@ class dense_dbm_base_ : public dbm_base_ { constant_type const& operator[](octdiff_vexpr vexpr) const; constant_type const& operator[](oct_vexpr vexpr) const; constant_type const& operator[](oct_var var) const; + constant_type const& operator[](std::size_t index) const; constant_type& operator[](octdiff_vexpr vexpr); constant_type& operator[](oct_vexpr vexpr); constant_type& operator[](oct_var var); + constant_type& operator[](std::size_t index); protected: dbm_major const major_; }; -template -class dense_dbm : public dense_dbm_base_, ValueType, ValueLimits> { -private: - using superclass_ = dense_dbm_base_; - using container_type_ = std::vector; - -public: - using typename superclass_::superclass_; - using typename superclass_::subclass_; - using typename superclass_::traits_; - using typename superclass_::identity_var_type; - using typename superclass_::constant_type; - using typename superclass_::value_limits; - - using allocator_type = Allocator; - - dense_dbm(); - dense_dbm(dense_dbm const&) = default; - dense_dbm(dense_dbm &&) noexcept = default; - dense_dbm& operator=(dense_dbm const&) = default; - dense_dbm& operator=(dense_dbm &&) noexcept = default; - - template ::value> > - dense_dbm(octdiff_system const& rhs, dbm_major major = traits_::default_major); - explicit dense_dbm(std::size_t max_vars, dbm_major major = traits_::default_major); - template > - explicit dense_dbm(VarType_ last_var, dbm_major major = traits_::default_major); - - explicit dense_dbm(std::size_t max_vars, constant_type value, dbm_major major = traits_::default_major); - template > - explicit dense_dbm(VarType_ last_var, constant_type value, dbm_major major = traits_::default_major); - - static dense_dbm const null(); - static dense_dbm top(std::size_t max_vars, dbm_major major = traits_::default_major); - template > - static dense_dbm top(VarType_ last_var, dbm_major major = traits_::default_major); - static dense_dbm bottom(std::size_t max_vars, dbm_major major = traits_::default_major); - template > - static dense_dbm bottom(VarType_ last_var, dbm_major major = traits_::default_major); - - std::size_t size() const noexcept; - allocator_type get_allocator() const; - - void initialize(constant_type value); - template > - void resize(VarType_ new_last_var, constant_type value = value_limits::top()); - -private: - constant_type& constant_(std::size_t index); - constant_type const& constant_(std::size_t index) const; - -public: - container_type_ data_; -}; - } // namespace oct adl_END_ROOT_MODULE @@ -174,6 +120,11 @@ bool dense_dbm_base_::autocoherent() const noe return false; }; +template +dbm_major dense_dbm_base_::major() const noexcept { + return major_; +}; + template inline octdiff_cons::constant_type> dense_dbm_base_::get(oct_var xi) const { @@ -209,80 +160,86 @@ dense_dbm_base_::get(octdiff_vexpr vexpr) cons template inline typename dense_dbm_base_::constant_type& dense_dbm_base_::at(oct_var xi) { - using cons_type_ = oct_cons; - using vexpr_type_ = typename cons_type_::vexpr_type; - auto cons = cons_type_::make_lower_limit(vexpr_type_::make_unit(xi), constant_type()); - auto diff_cons = cons.split().di().to_vexpr(); - return at(diff_cons); + return const_cast(const_cast(*this).at(xi)); }; template inline typename dense_dbm_base_::constant_type& dense_dbm_base_::at(octdiff_var xi, octdiff_var xj) { - if (xi.invalid() || xj.invalid()) throw std::logic_error("Invalid variables passed as indexes to DBM."); - auto real_xi = major_ == dbm_major::row ? xi : xj; - auto real_xj = major_ == dbm_major::row ? xj : xi; - std::size_t var_size = this->as_subclass_().size(); - std::size_t index = real_xi.to_index() * var_size + real_xj.to_index(); - return this->as_subclass_().constant_(index); + return const_cast(const_cast(*this).at(xi, xj)); }; template inline typename dense_dbm_base_::constant_type& dense_dbm_base_::at(oct_vexpr vexpr) { - using cons_type_ = oct_cons; - using vexpr_type_ = typename cons_type_::vexpr_type; - auto cons = cons_type_::make_lower_limit(vexpr, constant_type()); - auto diff_cons = cons.split().di().to_vexpr(); - return at(vexpr); + return const_cast(const_cast(*this).at(vexpr)); }; template inline typename dense_dbm_base_::constant_type& dense_dbm_base_::at(octdiff_vexpr vexpr) { - return at(vexpr.xi(), vexpr.xj()); + return const_cast(const_cast(*this).at(vexpr)); }; template inline typename dense_dbm_base_::constant_type const& dense_dbm_base_::at(oct_var xi) const { - return this->as_const_().at(xi); + using cons_type_ = oct_cons; + using vexpr_type_ = typename cons_type_::vexpr_type; + auto cons = cons_type_::make_upper_limit(vexpr_type_::make_unit(xi), constant_type()); + auto diff_vexpr = cons.split().di().to_vexpr(); + return at(diff_vexpr); }; template inline typename dense_dbm_base_::constant_type const& dense_dbm_base_::at(octdiff_var xi, octdiff_var xj) const { - return this->as_const_().at(xi, xj); + if (!xi.valid() || !xj.valid()) throw std::logic_error("Invalid variables passed as indexes to DBM."); + auto real_xi = major_ == dbm_major::row ? xi : xj; + auto real_xj = major_ == dbm_major::row ? xj : xi; + std::size_t var_size = this->as_subclass_().size(); + std::size_t index = real_xi.to_index() * var_size + real_xj.to_index(); + return this->as_subclass_().constant_(index); }; template inline typename dense_dbm_base_::constant_type const& dense_dbm_base_::at(oct_vexpr vexpr) const { - return this->as_const_().at(vexpr); + using cons_type_ = oct_cons; + using vexpr_type_ = typename cons_type_::vexpr_type; + auto cons = cons_type_::make_upper_limit(vexpr, constant_type()); + auto diff_vexpr = cons.split().di().to_vexpr(); + return at(diff_vexpr); }; template inline typename dense_dbm_base_::constant_type const& dense_dbm_base_::at(octdiff_vexpr vexpr) const { - return this->as_const_().at(vexpr); + return at(vexpr.xi(), vexpr.xj()); }; template inline typename dense_dbm_base_::constant_type const& dense_dbm_base_::operator[](octdiff_vexpr vexpr) const { - return this->as_const_().operator[](vexpr); + return const_cast(*this).operator[](vexpr); }; template inline typename dense_dbm_base_::constant_type const& dense_dbm_base_::operator[](oct_vexpr vexpr) const { - return this->as_const_().operator[](vexpr); + return const_cast(*this).operator[](vexpr); }; template typename dense_dbm_base_::constant_type const& dense_dbm_base_::operator[](oct_var var) const { - return this->as_const_().operator[](var); + return const_cast(*this).operator[](var); +}; + +template +typename dense_dbm_base_::constant_type const& +dense_dbm_base_::operator[](std::size_t index) const { + return this->as_subclass_().constant_(index); }; template @@ -303,126 +260,14 @@ dense_dbm_base_::operator[](oct_var var) { return at(var); }; - -// -// dense_dbm -// -template -inline dense_dbm::dense_dbm() - : superclass_(traits_::default_major) {}; - -template -template -inline dense_dbm::dense_dbm( - octdiff_system const& rhs, - dbm_major major) - : superclass_(major) -{ - resize(rhs.vars().last_var()); - for (auto cons : rhs) superclass_::at(cons) = cons.c(); -}; - -template -inline dense_dbm::dense_dbm( - std::size_t max_vars, - dbm_major major) - : superclass_(major) -{ - resize(max_vars); -}; - -template -template -inline dense_dbm::dense_dbm(VarType_ last_var, dbm_major major) - : dense_dbm(to_end_index_(last_var), major) {}; - -template -inline dense_dbm::dense_dbm(std::size_t max_vars, constant_type value, dbm_major major) - : superclass_(major) -{ - resize(max_vars, value); -}; - -template -template -inline dense_dbm::dense_dbm(VarType_ last_var, constant_type value, dbm_major major) - : dense_dbm(to_end_index_(last_var), value, major) {}; - -template -inline dense_dbm const dense_dbm::null() { - return dense_dbm(); -}; - -template -inline dense_dbm dense_dbm::top( - std::size_t max_vars, - dbm_major major -) { - return dense_dbm(max_vars, value_limits::top(), major); -}; - -template -template -inline dense_dbm dense_dbm::top( - VarType_ last_var, - dbm_major major -) { - return top(to_end_index_(last_var), major); -}; - -template -inline dense_dbm dense_dbm::bottom( - std::size_t max_vars, - dbm_major major -) { - return dense_dbm(max_vars, value_limits::bottom(), major); -}; - -template -template -inline dense_dbm dense_dbm::bottom( - VarType_ last_var, - dbm_major major -) { - return bottom(to_end_index_(last_var), major); -}; - -template -inline std::size_t dense_dbm::size() const noexcept { - return data_.size() >> 1; -}; - -template -typename dense_dbm::allocator_type -inline dense_dbm::get_allocator() const { - return data_.get_allocator(); -}; - -template -inline void dense_dbm::initialize(constant_type value) { - data_.assign(data_.size(), value); -}; - -template -template -inline void dense_dbm::resize(VarType_ new_last_var, constant_type value) { - data_.resize(to_end_index_(new_last_var), value); -}; - -template -inline typename dense_dbm::constant_type& -dense_dbm::constant_(std::size_t index) { - return data_.at(index); -}; - -template -inline typename dense_dbm::constant_type const& -dense_dbm::constant_(std::size_t index) const { - return data_.at(index); +template +typename dense_dbm_base_::constant_type& +dense_dbm_base_::operator[](std::size_t index) { + return this->as_subclass_().constant_(index); }; } // namespace oct adl_END_ROOT_MODULE -#endif //adl__oct__dbm__dense_dbm__hpp__ +#endif //adl__oct__dbm__dense_dbm_base___hpp__ diff --git a/include/adl/oct/system/oct_system_.hpp b/include/adl/oct/system/oct_system_.hpp index 7f250fd..f6789fb 100644 --- a/include/adl/oct/system/oct_system_.hpp +++ b/include/adl/oct/system/oct_system_.hpp @@ -32,12 +32,14 @@ class oct_system : public system_base_::value - && common_var::is_oct_space>> - oct_system(std::initializer_list> const& list); - - template ::value - && common_var::is_oct_space>> - oct_system(std::initializer_list> && list); - - template ::is_oct_space> > - std::size_t count(basic_oct_vexpr vexpr) const; - template ::is_oct_space> > - const_iterator find(basic_oct_vexpr vexpr) const; - template ::is_oct_space> > - value_type const& get(basic_oct_vexpr vexpr) const; - template ::is_oct_space> > - constant_type const& operator[](basic_oct_vexpr vexpr) const; + oct_system& operator=(oct_system &&) noexcept = default; + + oct_system(std::initializer_list> list); + oct_system(std::initializer_list> list); oct_system& clear(); oct_system& reset(); + + std::size_t count(oct_var var) const; + std::size_t count(oct_vexpr vexpr) const; + + const_iterator find(oct_var var) const; + const_iterator find(oct_vexpr vexpr) const; + + value_type get(oct_var var) const; + value_type get(oct_vexpr vexpr) const; + + value_type const& at(oct_var var) const; + value_type const& at(oct_vexpr vexpr) const; + + constant_type const& operator[](oct_var var) const; + constant_type const& operator[](oct_vexpr vexpr) const; + template > void setup_var(VarType_ var); // Can only be done if the variable hasn't been configured before template > + value_type to_value_(VarType_ var) const; template > value_type to_value_(basic_oct_vexpr vexpr) const; template > @@ -118,69 +118,118 @@ namespace oct { // // oct_system // +//template +//template +//inline oct_system::oct_system( +// std::initializer_list> list +//) { +// for (auto cons : list) { +// constant_type value = cons.constant(); +// insert(literal_cons_type(cons.to_vexpr(), value)); +// } +//}; + template -template -inline oct_system::oct_system( - std::initializer_list> const& list -) { +inline oct_system::oct_system(std::initializer_list> list) { for (auto cons : list) { - value_type value = cons.constant(); - insert(literal_cons_type(cons.to_vexpr(), value)); + constant_type value = cons.constant(); + insert(cons); } }; template -template -inline oct_system::oct_system( - std::initializer_list> && list -) : oct_system(list) {}; +inline oct_system::oct_system(std::initializer_list> list) { + for (auto cons : list) { + constant_type value = cons.constant(); + insert(cons); + } +}; template -template -inline std::size_t oct_system::count(basic_oct_vexpr vexpr) const { - auto idx = to_value_(vexpr); - return constraints_.count(idx); +inline oct_system& +oct_system::clear() { + constraints_.clear(); + variables_.clear(); + return *this; } template -template +inline oct_system& +oct_system::reset() { + constraints_.clear(); + variables_.reset(); + return *this; +} + +template +inline std::size_t oct_system::count(oct_var var) const { + auto key = to_value_(var); + return constraints_.count(key); +}; + +template +inline std::size_t oct_system::count(oct_vexpr vexpr) const { + auto key = to_value_(vexpr); + return constraints_.count(key); +}; + +template inline typename oct_system::const_iterator -oct_system::find(basic_oct_vexpr vexpr) const { +oct_system::find(oct_var var) const { + auto idx = to_value_(var); + return constraints_.find(idx); +}; + +template +inline typename oct_system::const_iterator +oct_system::find(oct_vexpr vexpr) const { auto idx = to_value_(vexpr); return constraints_.find(idx); -} +}; template -template -inline typename oct_system::value_type const& -oct_system::get(basic_oct_vexpr vexpr) const { +inline typename oct_system::value_type +oct_system::get(oct_var var) const { + auto iter = find(var); + if (iter != this->end()) return *iter; + return value_type::invalid(); +}; + +template +inline typename oct_system::value_type +oct_system::get(oct_vexpr vexpr) const { auto iter = find(vexpr); + if (iter != this->end()) return *iter; + return value_type::invalid(); +}; + +template +inline typename oct_system::value_type const& +oct_system::at(oct_var var) const { + auto iter = find(var); if (iter == this->end()) throw std::logic_error("Constraint not found."); return *iter; -} +}; template -template -inline typename oct_system::constant_type const& -oct_system::operator[](basic_oct_vexpr vexpr) const { - return get(vexpr).c(); -} +inline typename oct_system::value_type const& +oct_system::at(oct_vexpr vexpr) const { + auto iter = find(vexpr); + if (iter == this->end()) throw std::logic_error("Constraint not found."); + return *iter; +}; template -inline oct_system& -oct_system::clear() { - constraints_.clear(); - variables_.clear(); - return *this; -} +inline typename oct_system::constant_type const& +oct_system::operator[](oct_var var) const { + return at(var).c(); +}; template -inline oct_system& -oct_system::reset() { - constraints_.clear(); - variables_.reset(); - return *this; -} +inline typename oct_system::constant_type const& +oct_system::operator[](oct_vexpr vexpr) const { + return at(vexpr).c(); +}; template template @@ -210,6 +259,14 @@ oct_system::to_counterpart() const { return counterpart_system_type(*this); } +template +template +inline typename oct_system::value_type +oct_system::to_value_(VarType_ var) const { + auto vexpr = literal_vexpr_type::make_unit(var); + return to_value_(vexpr); +}; + template template inline typename oct_system::value_type @@ -218,18 +275,14 @@ oct_system::to_value_(basic_oct_vexpr vexpr) c auto real_xi = to_var_(vexpr.xi()); auto real_xj = (vexpr.xj().valid()) ? to_var_(vexpr.xj()) : literal_var_type::invalid(); typename value_type::vexpr_type real_vexpr(real_xi, real_xj); - return value_type(real_vexpr, ValueType()); + return value_type(real_vexpr, constant_type()); } template template inline typename oct_system::value_type oct_system::to_value_(basic_oct_vexpr vexpr) { - if (!vexpr.valid()) throw std::logic_error("Invalid variable expression."); - auto real_xi = to_var_(vexpr.xi()); - auto real_xj = (vexpr.xj().valid()) ? to_var_(vexpr.xj()) : literal_var_type::invalid(); - typename value_type::vexpr_type real_vexpr(real_xi, real_xj); - return value_type(real_vexpr, ValueType()); + return to_value_(basic_oct_cons::make_upper_limit(vexpr, constant_type())); } template @@ -238,7 +291,7 @@ inline typename oct_system::value_type oct_system::to_value_(basic_oct_cons cons) { if (!cons.valid()) throw std::logic_error("Invalid constraint."); auto real_xi = to_var_(cons.xi()); - auto real_xj = (cons.xj().valid()) ? to_var_(cons.xj()) : literal_var_type::invalid();; + auto real_xj = (cons.xj().valid()) ? to_var_(cons.xj()) : literal_var_type::invalid(); typename value_type::vexpr_type real_vexpr(real_xi, real_xj); return value_type(real_vexpr, cons.c()); } @@ -247,7 +300,8 @@ template template inline typename oct_system::literal_var_type oct_system::to_var_(VarType_ var) const { - literal_var_type real_var = variables_.get(var).normalized_var(); + literal_var_type real_var = variables_.at(var).normalized_var(); + if (var.negative()) real_var.negate(); return real_var; } @@ -258,6 +312,7 @@ oct_system::to_var_(VarType_ var) { auto iter = variables_.insert(var); auto& var_data = *iter.first; literal_var_type real_var = var_data.normalized_var(); + if (var.negative()) real_var.negate(); return real_var; } diff --git a/include/adl/oct/system/octdiff_system_.hpp b/include/adl/oct/system/octdiff_system_.hpp index 0bb38ce..f60397f 100644 --- a/include/adl/oct/system/octdiff_system_.hpp +++ b/include/adl/oct/system/octdiff_system_.hpp @@ -36,6 +36,7 @@ class octdiff_system : public system_base_::is_octdiff_space>> - std::size_t count(basic_octdiff_vexpr vexpr) const; - template ::is_oct_space>> - std::size_t count(basic_oct_vexpr vexpr) const; + std::size_t count(oct_var var) const; + std::size_t count(octdiff_vexpr vexpr) const; + std::size_t count(oct_vexpr vexpr) const; - template ::is_octdiff_space>> - const_iterator find(basic_octdiff_vexpr vexpr) const; - template ::is_oct_space>> - const_iterator find(basic_oct_vexpr vexpr) const; + const_iterator find(oct_var var) const; + const_iterator find(octdiff_vexpr vexpr) const; + const_iterator find(oct_vexpr vexpr) const; - template ::is_octdiff_space>> - value_type const& get(basic_octdiff_vexpr vexpr) const; - template ::is_oct_space>> - value_type const& get(basic_oct_vexpr vexpr) const; + value_type get(oct_var var) const; + value_type get(octdiff_vexpr vexpr) const; + value_type get(oct_vexpr vexpr) const; - template ::is_octdiff_space>> - constant_type const& operator[](basic_octdiff_vexpr vexpr) const; - template ::is_oct_space>> - constant_type const& operator[](basic_oct_vexpr vexpr) const; + value_type const& at(oct_var var) const; + value_type const& at(octdiff_vexpr vexpr) const; + value_type const& at(oct_vexpr vexpr) const; + + constant_type const& operator[](oct_var var) const; + constant_type const& operator[](octdiff_vexpr vexpr) const; + constant_type const& operator[](oct_vexpr vexpr) const; private: template ::value && common_var::is_octdiff_space>> std::pair insert_(basic_octdiff_cons cons); + key_type to_key_(oct_var var) const; template ::is_octdiff_space>> - value_type to_value_(basic_octdiff_vexpr vexpr) const; + key_type to_key_(basic_octdiff_vexpr vexpr) const; template ::is_oct_space>> literal_octdiff_conjunction_type split_(basic_oct_vexpr vexpr) const; }; @@ -108,37 +110,43 @@ octdiff_system::octdiff_system(counterpart_system_type c } template -template -inline std::size_t -octdiff_system::count(basic_octdiff_vexpr vexpr) const { - auto value = to_value_(vexpr); - return constraints_.count(value); -} +inline std::size_t octdiff_system::count(oct_var var) const { + const auto key = to_key_(var); + return key.valid() ? constraints_.count(key) : 0; +}; template -template -inline std::size_t -octdiff_system::count(basic_oct_vexpr vexpr) const { - std::size_t c = 0; - auto split = split_(vexpr); - if (split.di().valid()) c += count(split.di()); - if (split.dj().valid()) c += count(split.dj()); - return c; -} +inline std::size_t octdiff_system::count(octdiff_vexpr vexpr) const { + const auto key = to_key_(vexpr); + return key.valid() ? constraints_.count(key) : 0; +}; + +template +inline std::size_t octdiff_system::count(oct_vexpr vexpr) const { + const auto conj = split_(vexpr); + const auto key_di = key_type(conj.di()); + const auto key_dj = key_type(conj.dj()); + return (key_di.valid() ? constraints_.count(key_di) : 0) + (key_dj.valid() ? constraints_.count(key_dj) : 0); +}; template -template inline typename octdiff_system::const_iterator -octdiff_system::find(basic_octdiff_vexpr vexpr) const { - auto value = to_value_(vexpr); - return constraints_.find(value); -} +octdiff_system::find(oct_var var) const { + const auto key = to_key_(var); + return key.valid() ? constraints_.find(key) : constraints_.end(); +}; template -template inline typename octdiff_system::const_iterator -octdiff_system::find(basic_oct_vexpr vexpr) const { - auto split = split_(vexpr); +octdiff_system::find(octdiff_vexpr vexpr) const { + const auto key = to_key_(vexpr); + return key.valid() ? constraints_.find(key) : constraints_.end(); +}; + +template +inline typename octdiff_system::const_iterator +octdiff_system::find(oct_vexpr vexpr) const { + const auto split = split_(vexpr); if (split.di().valid()) { auto iter = constraints_.find(split.di()); if (iter != constraints_.end()) return iter; @@ -148,39 +156,73 @@ octdiff_system::find(basic_oct_vexpr vexpr) co if (iter != constraints_.end()) return iter; } return constraints_.end(); +}; + +template +inline typename octdiff_system::value_type +octdiff_system::get(oct_var var) const { + auto iter = find(var); + if (iter != this->end()) return *iter; + return value_type::invalid(); +}; + +template +inline typename octdiff_system::value_type +octdiff_system::get(octdiff_vexpr vexpr) const { + auto iter = find(vexpr); + if (iter != this->end()) return *iter; + return value_type::invalid(); +}; + +template +inline typename octdiff_system::value_type +octdiff_system::get(oct_vexpr vexpr) const { + auto iter = find(vexpr); + if (iter != this->end()) return *iter; + return value_type::invalid(); +}; + +template +inline typename octdiff_system::value_type const& +octdiff_system::at(oct_var var) const { + auto iter = find(var); + if (iter == this->end()) throw std::logic_error("Constraint not found."); + return *iter; } template -template inline typename octdiff_system::value_type const& -octdiff_system::get(basic_octdiff_vexpr vexpr) const { +octdiff_system::at(octdiff_vexpr vexpr) const { auto iter = find(vexpr); if (iter == this->end()) throw std::logic_error("Constraint not found."); return *iter; } template -template inline typename octdiff_system::value_type const& -octdiff_system::get(basic_oct_vexpr vexpr) const { +octdiff_system::at(oct_vexpr vexpr) const { auto iter = find(vexpr); if (iter == this->end()) throw std::logic_error("Constraint not found."); return *iter; }; template -template inline typename octdiff_system::constant_type const& -octdiff_system::operator[](basic_octdiff_vexpr vexpr) const { - return get(vexpr).c(); -} +octdiff_system::operator[](oct_var var) const { + return at(var).c(); +}; template -template inline typename octdiff_system::constant_type const& -octdiff_system::operator[](basic_oct_vexpr vexpr) const { - return get(vexpr).c(); -} +octdiff_system::operator[](octdiff_vexpr vexpr) const { + return at(vexpr).c(); +}; + +template +inline typename octdiff_system::constant_type const& +octdiff_system::operator[](oct_vexpr vexpr) const { + return at(vexpr).c(); +}; template template @@ -195,11 +237,17 @@ octdiff_system::insert_(basic_octdiff_cons +inline typename octdiff_system::key_type +octdiff_system::to_key_(oct_var var) const { + return to_key_(split_(oct_vexpr::make_unit(var)).di()); +}; + template template -inline typename octdiff_system::value_type -octdiff_system::to_value_(basic_octdiff_vexpr vexpr) const { - return value_type(vexpr, value_type()); +inline typename octdiff_system::key_type +octdiff_system::to_key_(basic_octdiff_vexpr vexpr) const { + return value_type(vexpr); } template diff --git a/include/adl/oct/system/system_base_.hpp b/include/adl/oct/system/system_base_.hpp index 054ae43..76e2120 100644 --- a/include/adl/oct/system/system_base_.hpp +++ b/include/adl/oct/system/system_base_.hpp @@ -75,12 +75,13 @@ class system_base_ { public: using var_set_type = var_set; using value_type = container_value_type_; + using key_type = value_type; using const_iterator = container_const_iterator_; using iterator = container_iterator_; using reverse_iterator = container_reverse_iterator_; using const_reverse_iterator = container_const_reverse_iterator_; - system_base_() noexcept = default; + system_base_() = default; system_base_(system_base_ const&) = default; system_base_(system_base_ &&) noexcept = default; system_base_& operator=(system_base_ const&) = default; diff --git a/include/adl/oct/system/var_set_.hpp b/include/adl/oct/system/var_set_.hpp index 2c0dd61..f94763c 100644 --- a/include/adl/oct/system/var_set_.hpp +++ b/include/adl/oct/system/var_set_.hpp @@ -109,7 +109,7 @@ class var_set { std::size_t count(var_type var) const; // unnormalized occurences std::size_t count_all(var_type var) const; // considers all occurrences, positive + negative const_iterator find(var_type var) const; - value_type const& get(var_type var) const; + value_type const& at(var_type var) const; value_type const& operator[](var_type var) const; // returns invalid if the var is not included private: @@ -391,7 +391,7 @@ adl_IMPL std::pair::iterator, bool> var_set::fi } template -adl_IMPL typename var_set::value_type const& var_set::get(var_type var) const { +adl_IMPL typename var_set::value_type const& var_set::at(var_type var) const { auto iter = find(var); if (iter != end()) return *iter; return dummy_data_; diff --git a/include/adl/oct/traits.hpp b/include/adl/oct/traits.hpp index 3b1c620..5812175 100644 --- a/include/adl/oct/traits.hpp +++ b/include/adl/oct/traits.hpp @@ -83,6 +83,7 @@ struct var_id_traits { template struct var_traits { constexpr static const bool valid = false; + constexpr static domain_space space = domain_space::oct; #if 0 // Types using var_id_traits = oct::var_id_traits; diff --git a/include/adl/oct/var/var_base_.hpp b/include/adl/oct/var/var_base_.hpp index 639fb41..2f84138 100644 --- a/include/adl/oct/var/var_base_.hpp +++ b/include/adl/oct/var/var_base_.hpp @@ -152,7 +152,8 @@ class var_base_ : public crtp_base { template ::valid - && var_traits::valid> + && var_traits::valid + && var_traits::space == var_traits::space> struct common_var_ { constexpr static const bool valid = specialized; constexpr static const bool is_oct_space = false; @@ -228,29 +229,29 @@ namespace operators { constexpr VarType& operator-=(VarType& var, std::size_t off) noexcept { return var.decrement(off); }; } inline namespace comparison { - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr bool operator==(VarTypeA const& var, VarTypeB var2) noexcept { return var.equals(var2); }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr bool operator==(VarTypeA && var, VarTypeB var2) noexcept { return var.equals(var2); }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr bool operator!=(VarTypeA const& var, VarTypeB var2) noexcept { return !var.equals(var2); }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr bool operator!=(VarTypeA && var, VarTypeB var2) noexcept { return !var.equals(var2); }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator<(VarTypeA const& var, VarTypeB var2) noexcept { return var.compare(var2) < 0; }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator<(VarTypeA && var, VarTypeB var2) noexcept { return var.compare(var2) < 0; }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator<=(VarTypeA const& var, VarTypeB var2) noexcept { return var.compare(var2) <= 0; }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator<=(VarTypeA && var, VarTypeB var2) noexcept { return var.compare(var2) <= 0; }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator>(VarTypeA const& var, VarTypeB var2) noexcept { return var.compare(var2) > 0; }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator>(VarTypeA && var, VarTypeB var2) noexcept { return var.compare(var2) > 0; }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator>=(VarTypeA const& var, VarTypeB var2) noexcept { return var.compare(var2) >= 0; }; - template > + template ::valid && ::adl::oct::common_var::valid>> constexpr int operator>=(VarTypeA && var, VarTypeB var2) noexcept { return var.compare(var2) >= 0; }; } } @@ -449,7 +450,8 @@ var_base_::ensure_valid() const { template constexpr typename var_base_::var_type& var_base_::as_valid() noexcept { - return (id_ = valid() ? id_ : var_id_limits::invalid_var_id, this->as_subclass_()); + id_ = valid() ? id_ : var_id_limits::invalid_var_id; + return this->as_subclass_(); } template @@ -502,7 +504,7 @@ var_base_::from_range(N id) noexcept { template constexpr typename var_base_::var_type var_base_::from_index(std::size_t id) noexcept { - return var_type(var_id_traits::arithmetic_to_valid(id)); + return var_type(var_id_traits::index_to_id(id)); }; template diff --git a/include/adl/oct/vexpr/basic_oct_vexpr.hpp b/include/adl/oct/vexpr/basic_oct_vexpr.hpp index 5b93fd3..410731b 100644 --- a/include/adl/oct/vexpr/basic_oct_vexpr.hpp +++ b/include/adl/oct/vexpr/basic_oct_vexpr.hpp @@ -33,6 +33,7 @@ class basic_oct_vexpr : public vexpr_base_ { public: using typename superclass_::var_type; + using typename superclass_::counterpart_var_type; using superclass_::vexpr_base_; using superclass_::operator=; @@ -55,20 +56,30 @@ class basic_oct_vexpr : public vexpr_base_ { && std::is_convertible::value>> constexpr basic_oct_vexpr(basic_oct_vexpr const& vexpr) noexcept : basic_oct_vexpr(vexpr.xi(), vexpr.xj()) {}; - constexpr basic_oct_vexpr(var_type xi) noexcept; + explicit constexpr basic_oct_vexpr(var_type xi) noexcept; constexpr basic_oct_vexpr(var_type xi, var_type xj) noexcept; constexpr static basic_oct_vexpr make_unit(var_type xi) noexcept; constexpr static basic_oct_vexpr make_add(var_type xi, var_type xj) noexcept; + + constexpr basic_octdiff_vexpr to_counterpart_() const noexcept; }; +constexpr oct_vexpr to_identity(oct_vexpr vexpr) { return vexpr; } +constexpr oct_vexpr to_identity(oct_lvexpr vexpr) { return vexpr.to_identity(); } + template ::is_oct_space>> constexpr basic_oct_vexpr make_unit_vexpr(VarType xi) noexcept { - return basic_oct_vexpr<>::make_unit(xi); + return basic_oct_vexpr::make_unit(xi); +}; + +template ::is_oct_space && ::adl::oct::common_var::valid>> +constexpr basic_oct_vexpr make_add_vexpr(VarTypeA xi, VarTypeB xj) noexcept { + return basic_oct_vexpr::make_add(xi, xj); }; -template ::is_oct_space>> -constexpr basic_oct_vexpr> make_add_vexpr(VarTypeA xi, VarTypeB xj) noexcept { - return common_vexpr_t::make_add(xi, xj); +template ::is_oct_space && ::adl::oct::common_var::valid>> +constexpr basic_oct_vexpr make_sub_vexpr(VarTypeA xi, VarTypeB xj) noexcept { + return basic_oct_vexpr::make_sub(xi, xj); }; } // namespace oct @@ -76,14 +87,14 @@ constexpr basic_oct_vexpr> make_add_vexpr(VarTy namespace dsl { inline namespace oct { inline namespace vexpr { - template ::is_oct_space>> - constexpr ::adl::oct::basic_oct_vexpr<::adl::oct::common_var_t> operator+(VarTypeA lhs, VarTypeB rhs) { - return ::adl::oct::basic_oct_vexpr<::adl::oct::common_var_t>::make_add(lhs, rhs); + template ::is_oct_space && ::adl::oct::common_var::valid>> + constexpr ::adl::oct::basic_oct_vexpr operator+(VarTypeA lhs, VarTypeB rhs) { + return ::adl::oct::basic_oct_vexpr::make_add(lhs, rhs); }; - template ::is_oct_space>> - constexpr ::adl::oct::basic_oct_vexpr<::adl::oct::common_var_t> operator-(VarTypeA lhs, VarTypeB rhs) { - return ::adl::oct::basic_oct_vexpr<::adl::oct::common_var_t>::make_sub(lhs, rhs); + template ::is_oct_space && ::adl::oct::common_var::valid>> + constexpr ::adl::oct::basic_oct_vexpr operator-(VarTypeA lhs, VarTypeB rhs) { + return ::adl::oct::basic_oct_vexpr::make_sub(lhs, rhs); }; } } @@ -172,6 +183,12 @@ basic_oct_vexpr::make_unit(var_type xi) noexcept { return basic_oct_vexpr(xi); } +template +constexpr basic_octdiff_vexpr::counterpart_var_type> +basic_oct_vexpr::to_counterpart_() const noexcept { + return basic_octdiff_vexpr(xi_.to_counterpart(), xj_.to_negated().to_counterpart()); +} + } // namespace oct adl_END_ROOT_MODULE diff --git a/include/adl/oct/vexpr/basic_octdiff_vexpr.hpp b/include/adl/oct/vexpr/basic_octdiff_vexpr.hpp index 88238df..acbf10f 100644 --- a/include/adl/oct/vexpr/basic_octdiff_vexpr.hpp +++ b/include/adl/oct/vexpr/basic_octdiff_vexpr.hpp @@ -51,25 +51,22 @@ class basic_octdiff_vexpr : public vexpr_base_ { !std::is_same::value && common_var::is_octdiff_space && std::is_convertible::value>> - constexpr basic_octdiff_vexpr(basic_octdiff_vexpr const& vexpr) noexcept + constexpr basic_octdiff_vexpr(basic_octdiff_vexpr const& vexpr) noexcept : basic_octdiff_vexpr(vexpr.xi(), vexpr.xj()) {}; constexpr basic_octdiff_vexpr& commute() noexcept; constexpr basic_octdiff_vexpr to_commuted() const noexcept; }; -} // namespace oct +constexpr octdiff_vexpr to_identity(octdiff_vexpr vexpr) { return vexpr; } +constexpr octdiff_vexpr to_identity(octdiff_lvexpr vexpr) { return vexpr.to_identity(); } -namespace dsl { - inline namespace oct { - inline namespace vexpr { - template ::is_octdiff_space>> - constexpr ::adl::oct::basic_octdiff_vexpr<::adl::oct::common_var_t> operator-(VarTypeA lhs, VarTypeB rhs) { - return ::adl::oct::basic_octdiff_vexpr<::adl::oct::common_var_t>::make_sub(lhs, rhs); - }; - } - } -} +template ::is_octdiff_space && ::adl::oct::common_var::valid>> +constexpr basic_octdiff_vexpr make_sub_vexpr(VarTypeA xi, VarTypeB xj) noexcept { + return basic_octdiff_vexpr::make_sub(xi, xj); +}; + +} // namespace oct namespace operators { inline namespace oct { diff --git a/include/adl/oct/vexpr/vexpr_base_.hpp b/include/adl/oct/vexpr/vexpr_base_.hpp index 947e2d9..641f4e5 100644 --- a/include/adl/oct/vexpr/vexpr_base_.hpp +++ b/include/adl/oct/vexpr/vexpr_base_.hpp @@ -169,11 +169,6 @@ struct common_vexpr_ { template struct common_vexpr : public common_vexpr_ {}; -template ::is_oct_space>> -constexpr common_vexpr_t make_sub_vexpr(VarTypeA xi, VarTypeB xj) noexcept { - return common_vexpr_t::make_sub(xi, xj); -}; - } // namespace oct adl_END_ROOT_MODULE diff --git a/test/include/adl_catch/macros.hpp b/test/include/adl_catch/macros.hpp index a1be1bd..ee77bc6 100644 --- a/test/include/adl_catch/macros.hpp +++ b/test/include/adl_catch/macros.hpp @@ -18,4 +18,24 @@ #define REQUIRE_SECTION_NOTHROW(test__, name__) SECTION( (name__) ) { REQUIRE_TRUE_NOTHROW(test__); } #define REQUIRE_SECTION_THROWS_AS(test__, exception__, name__) SECTION( (name__) ) { REQUIRE_THROWS_AS( REQUIRE( (test__) ), exception__ ); } +#define INFO_REQUIRE_MAXSIZE__ 8 +#define INFO_REQUIRE_SIZE_N__(x,x8,x7,x6,x5,x4,x3,x2,x1,xn,...) xn +#define INFO_REQUIRE_SIZE__(...) INFO_REQUIRE_SIZE_N__(0,__VA_ARGS__,8,7,6,5,4,3,2,1,0) +#define INFO_REQUIRE_BASE_NAME__ scopedMessage +#define INFO_REQUIRE_UNIQUE_NAME_LINE2( name, line, argn ) name##line##_##argn +#define INFO_REQUIRE_UNIQUE_NAME_LINE( name, line, argn ) INFO_REQUIRE_UNIQUE_NAME_LINE2( name, line, argn ) +#define INFO_REQUIRE_CATCH_INFO__( argn, log ) Catch::ScopedMessage INFO_REQUIRE_UNIQUE_NAME_LINE( INFO_REQUIRE_BASE_NAME__, __LINE__, argn ) = Catch::MessageBuilder( "INFO", CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; +#define INFO_REQUIRE_INFO__(argn__, obj__) INFO_REQUIRE_CATCH_INFO__(argn__, #obj__ << " = " << (obj__)) +#define INFO_REQUIRE_INFO__1(obj__) INFO_REQUIRE_INFO__(1, obj__) +#define INFO_REQUIRE_INFO__2(obj__, ...) INFO_REQUIRE_INFO__(2, obj__); INFO_REQUIRE_INFO__1(__VA_ARGS__) +#define INFO_REQUIRE_INFO__3(obj__, ...) INFO_REQUIRE_INFO__(3, obj__); INFO_REQUIRE_INFO__2(__VA_ARGS__) +#define INFO_REQUIRE_INFO__4(obj__, ...) INFO_REQUIRE_INFO__(4, obj__); INFO_REQUIRE_INFO__3(__VA_ARGS__) +#define INFO_REQUIRE_INFO__5(obj__, ...) INFO_REQUIRE_INFO__(5, obj__); INFO_REQUIRE_INFO__4(__VA_ARGS__) +#define INFO_REQUIRE_INFO__6(obj__, ...) INFO_REQUIRE_INFO__(6, obj__); INFO_REQUIRE_INFO__5(__VA_ARGS__) +#define INFO_REQUIRE_INFO__7(obj__, ...) INFO_REQUIRE_INFO__(7, obj__); INFO_REQUIRE_INFO__6(__VA_ARGS__) +#define INFO_REQUIRE_INFO__8(obj__, ...) INFO_REQUIRE_INFO__(8, obj__); INFO_REQUIRE_INFO__7(__VA_ARGS__) +#define INFO_REQUIRE_INFO__N(n__, ...) INFO_REQUIRE_INFO__ ## n__ (__VA_ARGS__) +#define INFO_REQUIRE_INFO_N__(n__, ...) INFO_REQUIRE_INFO__N(n__, __VA_ARGS__) +#define INFO_REQUIRE(test__, ...) INFO_REQUIRE_INFO_N__(INFO_REQUIRE_SIZE__(__VA_ARGS__), __VA_ARGS__); REQUIRE(test__) + #endif //adl_catch__macros__hpp__ diff --git a/test/unit/adl/oct/cons.unit.cpp b/test/unit/adl/oct/cons.unit.cpp index 27a976f..1a17186 100644 --- a/test/unit/adl/oct/cons.unit.cpp +++ b/test/unit/adl/oct/cons.unit.cpp @@ -6,20 +6,94 @@ #include "adl/oct/cons.hpp" +#define SHOW_CONS_INFO_(cons) INFO( #cons \ + << " valid: " << cons.valid() \ + << ", xi: " << cons.xi().to_string() \ + << ", xj: " << cons.xj().to_string() \ + << ", c: " << cons.c() ) + TEST_CASE("unit:adl/oct/cons") { using namespace adl::literals; // For "x1"_ol using namespace adl::operators; // For common operators (not part of a DSL, e.g. x1 <= x2) using namespace adl::dsl; // for x1 - x2 using namespace adl::oct; // For type definitions - auto x1 = 1_ov; - auto x2 = "x2"_ov; - auto x3 = octdiff_var(3); - auto vexpr2 = make_sub_vexpr(x3, x2); - auto comp = x1 == x2; - auto vexpr = x3 + x1; - auto cons = make_cons(vexpr, 10.0); - //std::cout << x3 << " (oct: " << ((oct_var) x3) << ")" << std::endl << vexpr << std::endl << cons << std::endl << cons.split() << std::endl; + auto xi = "x1"_ov; + auto xj = "x2"_ov; + auto dxi = xi.to_counterpart(); + auto dxj = xj.to_counterpart(); + auto c = 10.1; + auto c2 = c * 2; + + SECTION("Correctness of variable conversion") { + REQUIRE( ( xi.id() == 1 && (-xi).id() == -1) ); + REQUIRE( ( xj.id() == 2 && (-xj).id() == -2) ); + REQUIRE( (dxi.id() == 1 && (-dxi).id() == 2) ); + REQUIRE( (dxj.id() == 3 && (-dxj).id() == 4) ); + } + + SECTION("Binary constraints: xi + xj") { + auto cons = xi + xj <= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == ( dxi) && di.xj() == (-dxj) && di.c() == c) ); + SHOW_CONS_INFO_(dj); REQUIRE( (dj.valid() && dj.xi() == ( dxj) && dj.xj() == (-dxi) && dj.c() == c) ); + } + + SECTION("Binary constraints: xi - xj") { + auto cons = xi - xj <= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == ( dxi) && di.xj() == ( dxj) && di.c() == c) ); + SHOW_CONS_INFO_(dj); REQUIRE( (dj.valid() && dj.xi() == (-dxj) && dj.xj() == (-dxi) && dj.c() == c) ); + } + + SECTION("Binary constraints: -xi - xj") { + auto cons = -xi - xj <= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == (-dxi) && di.xj() == ( dxj) && di.c() == c) ); + SHOW_CONS_INFO_(dj); REQUIRE( (dj.valid() && dj.xi() == (-dxj) && dj.xj() == ( dxi) && dj.c() == c) ); + } + + SECTION("Binary constraints: -xi + xj = xj - xi") { + auto cons = -xi + xj <= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == (-dxi) && di.xj() == (-dxj) && di.c() == c) ); + SHOW_CONS_INFO_(dj); REQUIRE( (dj.valid() && dj.xi() == ( dxj) && dj.xj() == ( dxi) && dj.c() == c) ); + } + + SECTION("Binary constraints: xi <= c") { + auto cons = xi <= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == ( dxi) && di.xj() == (-dxi) && di.c() == c2) ); + SHOW_CONS_INFO_(dj); REQUIRE( (!dj.valid()) ); + } + + SECTION("Binary constraints: -xi <= c") { + auto cons = -xi <= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == (-dxi) && di.xj() == ( dxi) && di.c() == c2) ); + SHOW_CONS_INFO_(dj); REQUIRE( (!dj.valid()) ); + } + + SECTION("Binary constraints: -xi >= c -> xi <= -c") { + auto cons = -xi >= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == ( dxi) && di.xj() == (-dxi) && di.c() == -c2) ); + SHOW_CONS_INFO_(dj); REQUIRE( (!dj.valid()) ); + } + + SECTION("Binary constraints: xi >= c -> -xi <= -c") { + auto cons = xi >= c; + auto split = cons.split(); + auto di = split.di(), dj = split.dj(); + SHOW_CONS_INFO_(di); REQUIRE( (di.valid() && di.xi() == (-dxi) && di.xj() == ( dxi) && di.c() == -c2) ); + SHOW_CONS_INFO_(dj); REQUIRE( (!dj.valid()) ); + } - // TODO Tests (remember to remove all the commented ios stuff) } diff --git a/test/unit/adl/oct/cpu/dense_dbm.unit.cpp b/test/unit/adl/oct/cpu/dense_dbm.unit.cpp index 09c7296..687091b 100644 --- a/test/unit/adl/oct/cpu/dense_dbm.unit.cpp +++ b/test/unit/adl/oct/cpu/dense_dbm.unit.cpp @@ -1,6 +1,6 @@ // $flisboac 2017-08-28 #include "adl_catch.hpp" -#include +#include #include "adl/oct/var.hpp" #include "adl/oct/vexpr.hpp" #include "adl/oct/cons.hpp" @@ -16,45 +16,162 @@ using namespace adl::literals; using namespace adl::operators; using namespace adl::dsl; - template -static void test_dbm(T dbm) { - INFO(dbm.size()); - REQUIRE( (dbm.size() == 200) ); - INFO(dbm.last_var().to_string()); - REQUIRE( ( dbm.last_var() == "x100"_ov ) ); -} - -static void test_with_fixed_size(cpu::seq_context & seq_ctx) { - test_dbm(seq_ctx.make_dbm(100_ov)); - auto dbm = seq_ctx.make_dbm(100_ov, 10); - test_dbm(dbm); - //REQUIRE( (dbm[1_ov] == 10) ); -} - -static void test_with_octdiff_system(cpu::seq_context & seq_ctx) { - oct_system system; - constexpr auto cons = 1_ov - 2_ov <= 10.2f; - constexpr auto split = cons.split(); - system.insert(cons); - auto diff_system = system.to_counterpart(); - //test_dbm(seq_ctx.make_dbm(diff_system)); - auto dbm = seq_ctx.make_dbm(diff_system, 10); - //test_dbm(dbm); - WARN(cons.to_vexpr().to_string() << ", " << split.to_string()); - WARN(dbm.at(cons.xi(), cons.xj())); - WARN(dbm.at(split.di().to_identity_vexpr())); - WARN(dbm.at(split.dj().to_identity_vexpr())); - for (int i = 0; i < dbm.size() * dbm.size(); ++i) { - if (i > 0 && i % dbm.size() == 0) std::cout << std::endl; - std::cout << *(&dbm.constant_(0) + i) << " "; +static std::string dbm_to_string_(T const& dbm) { + char const* sep = "\t"; + std::stringstream ss; + ss << std::endl; + for (auto i = dbm.first_var(); i < dbm.end_var(); ++i) { + for (auto j = dbm.first_var(); j < dbm.end_var(); ++j) { + ss << sep << "[" << i.to_index() << "," << j.to_index() << "=" << dbm.at(i, j) << "]"; + sep = " "; + } + sep = "\t"; + ss << std::endl; } - REQUIRE( (dbm.at(cons.xi(), cons.xj()) == 10.2f) ); - REQUIRE( (dbm[1_ov] == 10) ); + return ss.str(); +} + +template < + template class DbmClass, + typename ContextType, + typename ValueType, + typename ValueLimits> +static void require_dbm_size_( + DbmClass const& dbm, + octdiff_var last_var +) { + const auto end_var = last_var + 1; + const auto var_size = end_var.to_index(); + INFO_REQUIRE( (dbm.size() == var_size), dbm.size(), var_size ); + INFO_REQUIRE( (dbm.last_var() == last_var), dbm.last_var().to_string(), last_var.to_string() ); + INFO_REQUIRE( (dbm.end_var() == end_var), dbm.end_var().to_string(), end_var.to_string() ); +} + +template < + template class DbmClass, + typename ContextType, + typename ValueType, + typename ValueLimits, + typename CheckFunction, + typename = std::enable_if_t::value>> +static void require_dbm_values_( + DbmClass const& dbm, + CheckFunction check +) { + for (auto i = dbm.first_var(); i < dbm.end_var(); ++i) { + for (auto j = dbm.first_var(); j < dbm.end_var(); ++j) { + octdiff_vexpr vexpr(i, j); + auto value_at = dbm.at(i, j); + auto value_oper = dbm[vexpr]; + INFO_REQUIRE(( value_at == value_oper ), value_at, value_oper, i.to_string(), j.to_string(), vexpr.to_string()); + INFO_REQUIRE(( check(value_at, i, j) ), value_at, i.to_string(), j.to_string()); + } + } +} + +template < + template class DbmClass, + typename ContextType, + typename ValueType, + typename ValueLimits, + typename = std::enable_if_t::value>> +static void require_dbm_values_( + DbmClass const& dbm, + ValueType value = DbmClass::default_constant() +) { + require_dbm_values_(dbm, [value](ValueType v, octdiff_var, octdiff_var) -> bool { return value == v; }); +} + +template +static octdiff_system make_diff_system_(basic_oct_cons cons) { + oct_system system = { cons }; + return system.to_counterpart(); +}; + +static void test_dbm_creation_by_size_(cpu::seq_context & seq_ctx) { + constexpr auto size_var = 100_ov; + constexpr auto last_var = -size_var; + constexpr auto initial_value = 1.11; + + using constant_type_ = std::remove_const::type; + + SECTION("Making DBM with fixed size and NO initial value") { + auto dbm = seq_ctx.make_dbm(size_var); + require_dbm_size_(dbm, last_var); + require_dbm_values_(dbm, dbm.default_constant()); + } + + SECTION("Making DBM with fixed size and initial value") { + // last_var here to showcase the fact that the DBM can be created with a negative variable. The last_var will + // be the next normalized variable (that is, `to_octdiff(var).normalize().increment(2)`) + auto dbm = seq_ctx.make_dbm(last_var, initial_value); + require_dbm_size_(dbm, last_var); + require_dbm_values_(dbm, initial_value); + } +} + +template +static void do_test_dbm_by_cons_(cpu::seq_context & seq_ctx, oct_cons cons) { + const auto xi = cons.xi(); + const auto xj = cons.xj(); + const auto c = cons.c(); + const auto c2 = c * 2; + const auto split = cons.split(); + const auto di = split.di(), dj = split.dj(); + const auto last_var = -to_octdiff(xi.compare(xj) >= 0 ? xi : xj).normalize(); + const auto initial_value = c2 + 13; + const auto diff_system = make_diff_system_(cons); + const auto dbm = seq_ctx.make_dbm(diff_system, initial_value); + const std::size_t index_di = di.xi().to_index() * dbm.size() + di.xj().to_index(); + const std::size_t index_dj = dj.valid() ? dj.xi().to_index() * dbm.size() + dj.xj().to_index() : 0; + + auto test_dbm_value = [&](ValueType value, octdiff_var xi_, octdiff_var xj_) { + octdiff_vexpr vexpr_(xi_, xj_); + bool valid_index = (vexpr_ == to_identity(split.di()).to_vexpr() || vexpr_ == to_identity(split.dj()).to_vexpr()); + INFO("cons = " << cons.to_string()); // Not working, why? + return valid_index + ? (cons.unit() ? value == c2 : value == c) + : value == initial_value; + }; + + auto test_diff_cons = [&](octdiff_cons cons_) { + const std::size_t index = (dbm.major() == dbm_major::row) + ? cons_.xi().to_index() * dbm.size() + cons_.xj().to_index() + : cons_.xj().to_index() * dbm.size() + cons_.xi().to_index(); + INFO_REQUIRE(( dbm.at(cons_) == dbm.at(cons_.xi(), cons_.xj()) ), + dbm.at(cons_), dbm.at(cons_.xi(), cons_.xj()), cons_.to_string(), cons_.xi().to_string(), cons_.xj().to_string()); + INFO_REQUIRE(( dbm.at(cons_) == dbm[cons_] ), + dbm.at(cons_) , dbm[cons_], cons_.to_string()); + INFO_REQUIRE(( dbm.at(cons_) == dbm[index] ), + dbm.at(cons_) , dbm[index], cons_.to_string(), index); + INFO_REQUIRE(( dbm[cons_] == cons_.c() ), + dbm[cons_], cons_.c(), cons_.to_string()); + }; + + require_dbm_size_(dbm, last_var); + require_dbm_values_(dbm, test_dbm_value); + test_diff_cons(di); + if (dj.valid()) { + test_diff_cons(dj); + INFO_REQUIRE(( dbm[di] == dbm[dj] ), dbm[di], dbm[dj], di.to_string(), dj.to_string()); + } +} + +static void test_dbm_creation_by_conversion_(cpu::seq_context & seq_ctx) { + constexpr auto xi = 1_ov; + constexpr auto xj = 2_ov; + constexpr auto c = 10.4; + + SECTION("Making system from constraint: xi - xj <= c") { do_test_dbm_by_cons_(seq_ctx, xi - xj <= c); } + SECTION("Making system from constraint: xi + xj <= c") { do_test_dbm_by_cons_(seq_ctx, xi + xj <= c); } + SECTION("Making system from constraint: -xi - xj <= c") { do_test_dbm_by_cons_(seq_ctx, -xi - xj <= c); } + SECTION("Making system from constraint: xi <= c") { do_test_dbm_by_cons_(seq_ctx, xi <= c); } + SECTION("Making system from constraint: -xi <= c") { do_test_dbm_by_cons_(seq_ctx, -xi <= c); } } TEST_CASE("unit:adl/oct/cpu/dense_dbm.hpp", "[unit][adl][adl/oct][adl/oct/cpu]") { auto seq_ctx = cpu::seq_context::make(); - //test_with_fixed_size(seq_ctx); - test_with_octdiff_system(seq_ctx); + test_dbm_creation_by_size_(seq_ctx); + test_dbm_creation_by_conversion_(seq_ctx); } diff --git a/test/unit/adl/oct/dbm/dense_dbm.unit.cpp b/test/unit/adl/oct/dbm/dense_dbm.unit.cpp index 79f1c73..77c6abc 100644 --- a/test/unit/adl/oct/dbm/dense_dbm.unit.cpp +++ b/test/unit/adl/oct/dbm/dense_dbm.unit.cpp @@ -1,3 +1,3 @@ // $flisboac 2017-08-21 #include "adl_catch.hpp" -#include "adl/oct/dbm/dense_dbm.hpp" +#include "adl/oct/dbm/dense_dbm_base_.hpp" diff --git a/test/unit/adl/oct/system.unit.cpp b/test/unit/adl/oct/system.unit.cpp index 5a2686c..410a2f3 100644 --- a/test/unit/adl/oct/system.unit.cpp +++ b/test/unit/adl/oct/system.unit.cpp @@ -9,9 +9,6 @@ #include "adl/oct/system.hpp" - - - adl::oct::oct_system make_system() { using namespace adl::oct; using namespace adl::literals; @@ -20,20 +17,79 @@ adl::oct::oct_system make_system() { auto xi = "x1"_ov; auto xj = "x2"_ov; - auto cons = -xi - xj <= 10.1; - basic_oct_vexpr vexpr = cons; - auto split = cons.split(); - auto converted_cons = split.to_oct(); - INFO(split.to_string() << " -> {" << cons.to_string() << "} == {" << converted_cons.to_string() << "}"); - oct_system system; + auto xk = "x3000"_ov; + auto dxi = xi.to_counterpart(); + auto dxj = xj.to_counterpart(); + auto dxk = xk.to_counterpart(); + + oct_system system = { + xi + xj <= 5.3, // xi+ - xj- <= 5.3 && xj+ - xi- <= 5.3 + xi - xj <= 10.2, // xi+ - xj+ <= 10.2 && xj- - xi- <= 10.2 + -xi - xj <= 10.4, // xi- - xj+ <= 10.4 && xj- - xi+ <= 10.4 + xi <= 20.2, // xi+ - xi- <= 40.4 + xi >= 10.1, // xi- - xi+ <= 20.2 + xj >= 30.0, // xj- - xj+ <= -60.0 + -xk <= 200.0 // xk- - xk+ <= 400.0 + }; + + INFO( "system = " << system.to_string() ); + // CLion doesn't like SFINAE - system.insert(xi - xj <= 10.2); - system.insert(xi <= 20.2); - if (xi <= xj) { - system.insert(xj >= 30); - } - INFO("count(xj) = " << system.vars().get(xj).count()); - INFO("x1 - x2 <= " << system[vexpr]); + REQUIRE( (system.vars().count_all(xi) == 5) ); + REQUIRE( (system.vars().count(-xi) == 2) ); + REQUIRE( (system.vars().count(xi) == 3) ); + + REQUIRE( (system.vars().at(-xj).count() == 4) ); + REQUIRE( (system.vars().at(xj).negative_count() == 3) ); + REQUIRE( (system.vars().at(-xj).positive_count() == 1) ); + + REQUIRE( (system.vars().at(xk).count() == 1) ); + REQUIRE( (system.vars().at(-xk).negative_count() == 1) ); + REQUIRE( (system.vars().at(xk).positive_count() == 0) ); + + REQUIRE( (system[xi + xj] == 5.3) ); + REQUIRE( (system[xi - xj] == 10.2) ); + REQUIRE( (system[-xi - xj] == 10.4) ); + REQUIRE( (system[xi] == 20.2) ); + REQUIRE( (system[-xi] == -10.1) ); + REQUIRE_THROWS ( (system[xj]) ); + REQUIRE( (system[-xj] == -30.0) ); + REQUIRE_THROWS ( (system[xk]) ); + REQUIRE( (system[-xk] == 200.0) ); + + auto diff_system = system.to_counterpart(); + INFO( "diff_system = " << diff_system.to_string() ); + + REQUIRE( (diff_system.vars().count_all(xi) == 10) ); + REQUIRE( (diff_system.vars().count(-xi) == 5) ); + REQUIRE( (diff_system.vars().count(xi) == 5) ); + + REQUIRE( (diff_system.vars().at(-xj).count() == 8) ); + REQUIRE( (diff_system.vars().at(xj).negative_count() == 4) ); + REQUIRE( (diff_system.vars().at(-xj).positive_count() == 4) ); + + REQUIRE( (diff_system.vars().at(xk).count() == 2) ); + REQUIRE( (diff_system.vars().at(-xk).negative_count() == 1) ); + REQUIRE( (diff_system.vars().at(xk).positive_count() == 1) ); + + // xi + xj <= 5.3 -> xi+ - xj- <= 5.3 && xj+ - xi- <= 5.3 + auto split_c1 = (xi + xj <= 5.3).split(); + REQUIRE( (diff_system[split_c1.di()] == split_c1.di().c()) ); + REQUIRE( (diff_system[split_c1.dj()] == split_c1.dj().c()) ); + + // xi - xj <= 10.2 -> xi+ - xj+ <= 10.2 && xj- - xi- <= 10.2 + REQUIRE( (diff_system[octdiff_vexpr( dxi, dxj)] == 10.2) ); + REQUIRE( (diff_system[octdiff_vexpr(-dxj, -dxi)] == 10.2) ); + + // -xi - xj <= 10.4 -> xi- - xj+ <= 10.4 && xj- - xi+ <= 10.4 + //REQUIRE( (diff_system[-dxi - dxj] == 10.2) ); + //REQUIRE( (diff_system[-dxj - dxi] == 10.2) ); + + // xi <= 20.2, -> xi+ - xi- <= 40.4 + // xi >= 10.1, -> xi- - xi+ <= 20.2 + // xj >= 30.0, -> xj- - xj+ <= -60.0 + // -xk <= 200.0 -> xk- - xk+ <= 400.0 + return system; }