diff --git a/include/mp/flat/constr_2_expr.h b/include/mp/flat/constr_2_expr.h index 8a534f6d9..3955afd76 100644 --- a/include/mp/flat/constr_2_expr.h +++ b/include/mp/flat/constr_2_expr.h @@ -89,14 +89,14 @@ class Constraints2Expr { bool ConvertWithExpressions( const AlgebraicConstraint& con, int i, - ConstraintAcceptanceLevel cal) { + ConstraintAcceptanceLevel cal, ExpressionAcceptanceLevel ) { assert(stage_cvt2expr_>0); /// Replace \a con by a NLConstraint, /// if either the ModelAPI does not accept it, /// or the linear/quadratic terms have expressions /// (and then they are non-flat.) if (1==stage_cvt2expr_ - && (ConstraintAcceptanceLevel::Recommended != cal + && (ConstraintAcceptanceLevel::Recommended != cal || HasExpressionArgs(con.GetBody()))) { ConvertToNLCon(con, i); return true; // to remove the original \a con @@ -112,16 +112,18 @@ class Constraints2Expr { bool ConvertWithExpressions( const ConditionalConstraint< AlgebraicConstraint >& con, int i, - ConstraintAcceptanceLevel ) { + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel eal) { assert(stage_cvt2expr_>0 && stage_cvt2expr_<=2); - if (1==stage_cvt2expr_) { - if (!con.GetConstraint().GetBody().is_variable()) { // already a variable - ConvertConditionalConLHS(con, i); - return true; + if (ExpressionAcceptanceLevel::NotAccepted != eal) { // going into an expr + if (1==stage_cvt2expr_) { + if (!con.GetConstraint().GetBody().is_variable()) { // already a variable + ConvertConditionalConLHS(con, i); + return true; + } } + else // if (2==stage_cvt2expr_) + ConsiderExplicifyingExpression(con, i); // this is a func con too } - else // if (2==stage_cvt2expr_) - ConsiderExplicifyingExpression(con, i); // this is a func con too return false; } @@ -132,9 +134,12 @@ class Constraints2Expr { std::enable_if_t< std::is_base_of_v, bool > = true > bool ConvertWithExpressions( - const FuncCon& con, int i, ConstraintAcceptanceLevel ) { - if (2==stage_cvt2expr_) - ConsiderExplicifyingExpression(con, i); + const FuncCon& con, int i, + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel eal) { + if (ExpressionAcceptanceLevel::NotAccepted != eal) { // going into an expr + if (2==stage_cvt2expr_) + ConsiderExplicifyingExpression(con, i); + } return false; // leave it active } @@ -145,7 +150,7 @@ class Constraints2Expr { bool ConvertWithExpressions( const ComplementarityConstraint& con, int i, - ConstraintAcceptanceLevel ) { + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { // TODO check acc for NLCompl if (1==stage_cvt2expr_ && !con.GetExpression().is_variable()) { // already a variable ConvertComplementarityExpr(con, i); @@ -158,14 +163,16 @@ class Constraints2Expr { /// But check that they are flat? template bool ConvertWithExpressions( - const IndicatorConstraint& , int , ConstraintAcceptanceLevel ) { + const IndicatorConstraint& , int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { return false; } /// SOS1: do nothing. /// But check that they are flat? bool ConvertWithExpressions( - const SOS1Constraint& con, int , ConstraintAcceptanceLevel ) { + const SOS1Constraint& con, int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { if (2==stage_cvt2expr_) for (int v: con.GetArguments()) { assert(MPCD( IsProperVar(v) )); @@ -176,7 +183,8 @@ class Constraints2Expr { /// SOS1: do nothing. /// But check that they are flat? bool ConvertWithExpressions( - const SOS2Constraint& con, int , ConstraintAcceptanceLevel ) { + const SOS2Constraint& con, int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { if (2==stage_cvt2expr_) for (int v: con.GetArguments()) { assert(MPCD( IsProperVar(v) )); @@ -186,27 +194,32 @@ class Constraints2Expr { /// NLConstraint: just produced. bool ConvertWithExpressions( - const NLConstraint& , int , ConstraintAcceptanceLevel ) { + const NLConstraint& , int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { return false; } /// NLLogical: just produced. bool ConvertWithExpressions( - const NLLogical& , int , ConstraintAcceptanceLevel ) { + const NLLogical& , int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { return false; } /// NLEquivalence: just produced. bool ConvertWithExpressions( - const NLEquivalence& , int , ConstraintAcceptanceLevel ) { + const NLEquivalence& , int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { return false; } /// NLImpl: just produced. bool ConvertWithExpressions( - const NLImpl& , int , ConstraintAcceptanceLevel ) { + const NLImpl& , int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { return false; } /// NLRimpl: just produced. bool ConvertWithExpressions( - const NLRimpl& , int , ConstraintAcceptanceLevel ) { + const NLRimpl& , int , + ConstraintAcceptanceLevel , ExpressionAcceptanceLevel ) { return false; } diff --git a/include/mp/flat/constr_keeper.h b/include/mp/flat/constr_keeper.h index f4e2329ca..4db7e9503 100644 --- a/include/mp/flat/constr_keeper.h +++ b/include/mp/flat/constr_keeper.h @@ -380,9 +380,10 @@ class ConstraintKeeper final void DoCvtWithExprs() { auto cal = GetChosenAcceptanceLevel(); + auto eal = GetChosenAcceptanceLevelEXPR(); ForEachActive( - [this, cal](const auto& con, int i) { - return this->GetConverter().ConvertWithExpressions(con, i, cal); + [this, cal, eal](const auto& con, int i) { + return this->GetConverter().ConvertWithExpressions(con, i, cal, eal); }); }