From b282c18cdb50de436728cc6ce16dca04ad33a9f1 Mon Sep 17 00:00:00 2001 From: Gleb Belov Date: Mon, 28 Aug 2023 13:14:13 +1000 Subject: [PATCH] Don't check unused constraints #200 Currently 'unused' can be, e.g., abs(x) replaced by norm in a conic constraint --- include/mp/flat/constr_keeper.h | 82 ++++++++++++++++++++++----------- include/mp/flat/converter.h | 16 +++++-- 2 files changed, 65 insertions(+), 33 deletions(-) diff --git a/include/mp/flat/constr_keeper.h b/include/mp/flat/constr_keeper.h index 66a9b6015..cf685389c 100644 --- a/include/mp/flat/constr_keeper.h +++ b/include/mp/flat/constr_keeper.h @@ -273,8 +273,11 @@ class BasicConstraintKeeper { virtual void SetChosenAcceptanceLevel( ConstraintAcceptanceLevel acc) { acceptance_level_ = acc;} - /// Mark as deleted, use index only - virtual void MarkAsDeleted(int i) = 0; + /// Mark as bridged. Use index only. + virtual void MarkAsBridged(int i) = 0; + + /// Mark as unused. Use index only. + virtual void MarkAsUnused(int i) = 0; /// Copy names from ValueNodes virtual void CopyNamesFromValueNodes() = 0; @@ -491,7 +494,7 @@ class ConstraintKeeper : public BasicConstraintKeeper { /// Report how many will be added to Backend int GetNumberOfAddable() const override { - return (int)cons_.size()-n_bridged_; + return (int)cons_.size()-n_bridged_or_unused_; } /// Group number of this constraint type in the Backend. @@ -527,16 +530,24 @@ class ConstraintKeeper : public BasicConstraintKeeper { struct Container { Container(Constraint&& c) noexcept : con_(std::move(c)) { } - bool IsDeleted() const { return IsBridged(); } + /// Bridged (reformulated or just unused.) + /// If only reformulated, can still be checked + /// for solution correctness. bool IsBridged() const { return is_bridged_; } + /// Mark as bridged void MarkAsBridged() { is_bridged_=true; } - /// Depth in the redef tree - int GetDepth() const { return depth_; } + /// Unused (should not be checked) + bool IsUnused() const { return is_unused_; } + /// Mark as unused + void MarkAsUnused() { + MarkAsBridged(); + is_unused_=true; + } Constraint con_; bool is_bridged_ = false; - int depth_ {0}; + bool is_unused_ = false; }; /// Convert all new constraints of this type @@ -580,22 +591,35 @@ class ConstraintKeeper : public BasicConstraintKeeper { void ConvertConstraint(Container& cnt, int i) { assert(!cnt.IsBridged()); GetConverter().RunConversion(cnt.con_, i); - MarkAsDeleted(cnt, i); + MarkAsBridged(cnt, i); } - /// Mark item as deleted - void MarkAsDeleted(Container& cnt, int ) { + /// Mark item as reformulated + void MarkAsBridged(Container& cnt, int ) { cnt.MarkAsBridged(); - ++n_bridged_; + ++n_bridged_or_unused_; } + /// Mark item as unused + void MarkAsUnused(Container& cnt, int ) { + cnt.MarkAsUnused(); + ++n_bridged_or_unused_; + } + public: - /// Mark as deleted, use index only - void MarkAsDeleted(int i) override { - MarkAsDeleted(cons_.at(i), i); + /// Mark cons[\a i] as reformulated. + /// Use index only. + void MarkAsBridged(int i) override { + MarkAsBridged(cons_.at(i), i); } + /// Mark cons[\a i] as unused. + /// Use index only. + void MarkAsUnused(int i) override { + MarkAsUnused(cons_.at(i), i); + } + /// Copy names from ValueNodes void CopyNamesFromValueNodes() override { const auto& vn = GetValueNode().GetStrVec(); @@ -611,12 +635,12 @@ class ConstraintKeeper : public BasicConstraintKeeper { for (int i=0; i<(int)cons_.size(); ++i) if (!cons_[i].IsBridged()) if (fn(cons_[i].con_, i)) - MarkAsDeleted(cons_[i], i); + MarkAsBridged(cons_[i], i); } /// Compute violations for this constraint type. /// We do it for redefined (intermediate) ones too. - void ComputeViolations(SolCheck& chk) { + void ComputeViolations(SolCheck& chk) override { if (cons_.size()) { auto& conviolmap = cons_.front().con_.IsLogical() ? @@ -625,17 +649,19 @@ class ConstraintKeeper : public BasicConstraintKeeper { const auto& x = chk.x(); ViolSummArray<3>* conviolarray {nullptr}; for (int i=(int)cons_.size(); i--; ) { - auto viol = cons_[i].con_.ComputeViolation(x); - if (viol > chk.GetFeasTol()) { - if (!conviolarray) - conviolarray = - &conviolmap[cons_.front().con_.GetTypeName()]; - /// Solver-side? - /// TODO also original NL constraints (index 0) - int index = cons_[i].IsDeleted() ? 1 : 2; - assert(index < (int)conviolarray->size()); - (*conviolarray)[index].CountViol( - viol, cons_[i].con_.name()); + if (!cons_[i].IsUnused()) { + auto viol = cons_[i].con_.ComputeViolation(x); + if (viol > chk.GetFeasTol()) { + if (!conviolarray) + conviolarray = + &conviolmap[cons_.front().con_.GetTypeName()]; + /// index==2 <==> solver-side constraint. + /// TODO also original NL constraints (index 0) + int index = cons_[i].IsBridged() ? 1 : 2; + assert(index < (int)conviolarray->size()); + (*conviolarray)[index].CountViol( + viol, cons_[i].con_.name()); + } } } } @@ -666,7 +692,7 @@ class ConstraintKeeper : public BasicConstraintKeeper { Converter& cvt_; std::deque cons_; int i_cvt_last_ = -1; // Last converted constraint. - int n_bridged_ = 0; // Number of converted items, + int n_bridged_or_unused_ = 0; // Number of converted items, // they won't go to Backend const std::string desc_ { std::string("ConstraintKeeper< ") + diff --git a/include/mp/flat/converter.h b/include/mp/flat/converter.h index 793bfa238..c68393e97 100644 --- a/include/mp/flat/converter.h +++ b/include/mp/flat/converter.h @@ -169,7 +169,7 @@ class FlatConverter : auto& ck = GET_CONSTRAINT_KEEPER( FuncConstraint ); ConInfo ci{&ck, i}; ReplaceInitExpression(res_var, ci); - MarkAsDeleted(ci_old); + MarkAsBridged(ci_old); } @@ -189,7 +189,7 @@ class FlatConverter : assert(VarUsageRef(v)>0); if (! (--VarUsageRef(v))) { if (HasInitExpression(v)) - MarkAsDeleted(GetInitExpression(v)); + MarkAsUnused(GetInitExpression(v)); } } @@ -443,11 +443,17 @@ class FlatConverter : return GET_CONST_CONSTRAINT_KEEPER(Constraint).GetConstraint(i); } - /// Delete constraint - void MarkAsDeleted(const ConInfo& ci) { - ci.GetCK()->MarkAsDeleted(ci.GetIndex()); + /// Mark constraint as reformulated + void MarkAsBridged(const ConInfo& ci) { + ci.GetCK()->MarkAsBridged(ci.GetIndex()); } + /// Mark constraint as unused + void MarkAsUnused(const ConInfo& ci) { + ci.GetCK()->MarkAsUnused(ci.GetIndex()); + } + + protected: USE_BASE_MAP_FINDERS( BaseConverter )