Skip to content

Commit

Permalink
'acc:...' options, -c with expressions #237
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Apr 26, 2024
1 parent 74c394f commit 0ea0b8f
Show file tree
Hide file tree
Showing 8 changed files with 383 additions and 299 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,11 @@ set(MP_SOURCES )
add_prefix(MP_SOURCES src/
expr.cc expr-writer.h nl-reader.cc option.cc os.cc
problem.cc rstparser.cc sol.cc solver.cc solver-c.h sp.h sp.cc
std_constr.cc
utils_file.cc utils_string.cc utils_clock.cc)

set(MP_FLAT_SOURCES )
add_prefix(MP_FLAT_SOURCES src/mp/flat/
std_constr.cc
encodings.cpp piecewise_linear.cpp)


Expand Down
1 change: 1 addition & 0 deletions include/mp/flat/constr_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ inline void WriteJSON(JW jw,
struct Name ## Id { \
static constexpr const char* description() { return Descr; } \
static constexpr const char* GetTypeName() { return #Name; } \
static constexpr const char* GetExprTypeName() { return #Name "Expression"; } \
}; \
using Name ## Constraint = CustomFunctionalConstraint<Args, Params, NumLogic, Name ## Id>; \
using Name ## Expression = ExprWrapper< Name ## Constraint >
Expand Down
150 changes: 54 additions & 96 deletions include/mp/flat/constr_keeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,11 @@

namespace mp {


/// Converters handling custom constraints should derive from
class BasicFlatConverter;


static const mp::OptionValueInfo values_item_acceptance[] = {
{ "0", "Not accepted natively, automatic redefinition will be attempted", 0},
{ "1", "Accepted but automatic redefinition will be used where possible", 1},
{ "2", "Accepted natively and preferred", 2}
};


/// Violation summary for a class of vars/cons/objs
struct ViolSummary {
/// Check if this violation should be counted.
Expand Down Expand Up @@ -392,10 +386,13 @@ class BasicConstraintKeeper {
/// Convert to use expressions
virtual void ConvertWithExpressions(BasicFlatConverter& cvt) = 0;

/// Query (user-chosen, if sensible) constraint acceptance level
virtual ConstraintAcceptanceLevel GetChosenAcceptanceLevel()
const {
assert(0<=acceptance_level_); // has been initialized
/// Query (user-chosen, if sensible) constraint acceptance level.
/// This is "combined" for constraint or expression
virtual ConstraintAcceptanceLevel GetChosenAcceptanceLevel() const {
if (acceptance_level_<0) { // not initialized
std::array<int, 5> alv = {0, 1, 2, 1, 2};
acceptance_level_ = alv.at(acc_level_item_);
}
return ConstraintAcceptanceLevel(acceptance_level_);
}

Expand All @@ -409,6 +406,16 @@ class BasicConstraintKeeper {
virtual ConstraintAcceptanceLevel GetModelAPIAcceptance(
const BasicFlatModelAPI& ) const = 0;

/// ModelAPI's acceptance level for the expression type.
/// This should not be used directly, instead:
/// GetChosenAcceptanceLevelEXPR()
virtual ExpressionAcceptanceLevel GetModelAPIAcceptanceEXPR(
const BasicFlatModelAPI& ) const = 0;

/// Acceptance level of the overall expression interface in the ModelAPI
virtual ExpressionAcceptanceLevel GetModelAPIAcceptance_EXPR_INTF(
const BasicFlatModelAPI& ba) const = 0;

/// Constraint type_info
virtual const std::type_info& GetTypeInfo() const =0;

Expand Down Expand Up @@ -456,73 +463,16 @@ class BasicConstraintKeeper {
virtual const char* GetShortTypeName() const;

/// See what options are available for this constraint:
/// whether it is accepted natively by ModelAPI and/or can be
/// converted by the Converter.
/// whether it is accepted natively by ModelAPI,
/// as flat constraint or expression.
/// If both, add constraint acceptance option.
/// @note This should be called before using the class.
virtual void ConsiderAcceptanceOptions(
void ConsiderAcceptanceOptions(
BasicFlatConverter& cvt,
const BasicFlatModelAPI& ma,
Env& env) {
auto cancvt = IfConverterConverts(cvt);
SetChosenAcceptanceLevel( GetModelAPIAcceptance(ma) );
bool optadded = true;
if (true || cancvt) { // Changing to show all native cons
if (ConstraintAcceptanceLevel::Recommended ==
GetChosenAcceptanceLevel()) {
env.AddStoredOption(GetAcceptanceOptionNames(),
fmt::format(
"Solver acceptance level for '{}', "
"default 2:\n\n.. value-table::",
GetConstraintName()).c_str(),
GetAccLevRef(), values_item_acceptance);
} else
if (ConstraintAcceptanceLevel::AcceptedButNotRecommended ==
GetChosenAcceptanceLevel()) {
env.AddStoredOption(GetAcceptanceOptionNames(),
fmt::format(
"Solver acceptance level for '{}', "
"default 1:\n\n.. value-table::",
GetConstraintName()).c_str(),
GetAccLevRef(), values_item_acceptance);
} else
optadded = false;
} else
optadded = false;
if (!optadded) // Still add as hidden option
env.AddStoredOption(GetAcceptanceOptionNames(),
"HIDDEN",
GetAccLevRef(), 0, 2);
// Description table
env.SetConstraintListHeader(
"List of flat constraints.\n"
"For each constraint the following are given:\n"
"\n"
" - name,\n"
" - convertibility into simpler forms,\n"
" - solver acceptance natively,\n"
" - driver option(s) to modify acceptance\n"
" (enabled if both convertible and accepted).");
std::string con_descr = (cancvt) ? "Convertible" : "NonConvertible";
con_descr += "; ";
if (ConstraintAcceptanceLevel::Recommended ==
GetChosenAcceptanceLevel())
con_descr += "NativeRecommended";
else if (ConstraintAcceptanceLevel::AcceptedButNotRecommended ==
GetChosenAcceptanceLevel())
con_descr += "NativeAcceptedButNotRecommended";
else
con_descr += "NotAccepted";
con_descr += "; ";
con_descr += GetAcceptanceOptionNames();
env.AddConstraintDescr(GetConstraintName(), con_descr);
}

/// Set user preferred acceptance level
virtual void SetChosenAcceptanceLevel(
ConstraintAcceptanceLevel acc) {
acceptance_level_ = static_cast<
std::underlying_type_t<ConstraintAcceptanceLevel> >(acc);
DoAddAcceptanceOptions(cvt, ma, env);
DoPopulateConstraintList(cvt, ma, env);
}

/// Mark as bridged. Use index only.
Expand Down Expand Up @@ -553,38 +503,27 @@ class BasicConstraintKeeper {
}

protected:
int& GetAccLevRef() { return acceptance_level_; }
void DoAddAcceptanceOptions(
BasicFlatConverter& cvt,
const BasicFlatModelAPI& ma,
Env& env);
void DoPopulateConstraintList(
BasicFlatConverter& cvt,
const BasicFlatModelAPI& ma,
Env& env);


private:
pre::ValueNode value_node_;
const char* const constr_name_;
const char* const solver_opt_nm_;
mutable std::string type_name_short_;
int acceptance_level_ {-1};
mutable int acceptance_level_ {-1}; // combined, for either con or expr
int acc_level_item_ {0}; // item, corresp. to the solver option 0..4
mutable int acc_level_expr_ {-1}; // expression only
BasicLogger* exporter_{};
};

const char*
BasicConstraintKeeper::GetShortTypeName() const {
if (type_name_short_.empty()) {
std::string acc_opt = GetAcceptanceOptionNames();
assert(acc_opt.size());
auto word_end = std::min(acc_opt.find(' '),
acc_opt.size());
auto colon_pos = acc_opt.find(':');
if (colon_pos>word_end)
colon_pos = 0;
type_name_short_ = acc_opt.substr(
colon_pos, word_end-colon_pos);
for (auto& c: type_name_short_)
if (':'==c)
c = '_'; // Markdown
assert(type_name_short_.size());
}
return type_name_short_.c_str();
}


/// Full id of a constraint: CK + index
/// This helper class is parameterized by the Keeper
Expand Down Expand Up @@ -699,6 +638,9 @@ class ConstraintKeeper final
/// Constraint type
using ConstraintType = Constraint;

/// The corresponding flat expression type
using FlatExprType = ExprWrapper<Constraint>;

/// Expression type, or, if appropriate, constraint type name,
/// e.g., 'Abs'
const char* GetExprOrConstraintName() const override
Expand Down Expand Up @@ -804,6 +746,22 @@ class ConstraintKeeper final
AcceptanceLevel((Constraint*)nullptr);
}

/// Acceptance level of the corresponding expression type in the ModelAPI
ExpressionAcceptanceLevel GetModelAPIAcceptanceEXPR(
const BasicFlatModelAPI& ba) const override {
return
static_cast<const Backend&>( ba ).
AcceptanceLevel((FlatExprType*)nullptr);
}

/// Acceptance level of the overall expression interface in the ModelAPI
ExpressionAcceptanceLevel GetModelAPIAcceptance_EXPR_INTF(
const BasicFlatModelAPI& ba) const override {
return
static_cast<const Backend&>( ba ).
ExpressionInterfaceAcceptanceLevel();
}

/// Constraint type_info
const std::type_info& GetTypeInfo() const override
{ return typeid(ConstraintType); }
Expand Down Expand Up @@ -893,7 +851,7 @@ class ConstraintKeeper final
private:
// Storing in the ExprWrapper,
// so we can send (wrapper &) to ModelAPI::AddExpression().
ExprWrapper<Constraint> con_;
FlatExprType con_;
int depth_ = 0;
bool is_bridged_ = false;
bool is_unused_ = false;
Expand Down
1 change: 0 additions & 1 deletion include/mp/flat/model_api_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ static mp::ConstraintAcceptanceLevel \
#define ACCEPT_EXPRESSION(FlatExprType, level) \
static mp::ExpressionAcceptanceLevel \
AcceptanceLevel(const FlatExprType*) { \
typename FlatExprType::FlatConType* pc{}; \
static_assert( std::is_same_v<FlatExprType, \
ExprWrapper<typename FlatExprType::FlatConType> >, \
#FlatExprType \
Expand Down
6 changes: 0 additions & 6 deletions include/mp/flat/model_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,6 @@ class FlatModelInfoImpl : public FlatModelInfo {
int nUnfxIntVars_ = 0;
};


/// FlatModelInfo factory
std::unique_ptr<FlatModelInfo> CreateFlatModelInfo() {
return std::unique_ptr<FlatModelInfo>{new FlatModelInfoImpl()};
}

} // namespace mp

#endif // MODEL_INFO_HPP
20 changes: 10 additions & 10 deletions include/mp/valcvt-node.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class ValueNode {

/// Retrieve T, dummy version
template <class T>
const T& GetVal(size_t ) const { return {}; }
const T& GetVal(size_t ) const { assert(false); return {}; }

/// Set T, dummy version
template <class T>
Expand Down Expand Up @@ -337,32 +337,32 @@ class ValueNode {


template <>
std::vector<double>& ValueNode::GetValVec<double>() { return vd_; }
inline std::vector<double>& ValueNode::GetValVec<double>() { return vd_; }

template <>
std::vector<int>& ValueNode::GetValVec<int>() { return vi_; }
inline std::vector<int>& ValueNode::GetValVec<int>() { return vi_; }

template <>
std::vector<VCString>& ValueNode::GetValVec<VCString>() { return vStr_; }
inline std::vector<VCString>& ValueNode::GetValVec<VCString>() { return vStr_; }

template <>
const double& ValueNode::GetVal<double>(size_t i) const { return GetDblRef(i); }
inline const double& ValueNode::GetVal<double>(size_t i) const { return GetDblRef(i); }

template <>
const int& ValueNode::GetVal<int>(size_t i) const { return GetIntRef(i); }
inline const int& ValueNode::GetVal<int>(size_t i) const { return GetIntRef(i); }

template <>
const VCString& ValueNode::GetVal<VCString>(size_t i) const
inline const VCString& ValueNode::GetVal<VCString>(size_t i) const
{ return GetStr(i); }

template <>
void ValueNode::SetVal<double>(size_t i, double v) { SetDbl(i, v); }
inline void ValueNode::SetVal<double>(size_t i, double v) { SetDbl(i, v); }

template <>
void ValueNode::SetVal<int>(size_t i, int v) { SetInt(i, v); }
inline void ValueNode::SetVal<int>(size_t i, int v) { SetInt(i, v); }

template <>
void ValueNode::SetVal<VCString>(size_t i, VCString v)
inline void ValueNode::SetVal<VCString>(size_t i, VCString v)
{ SetStr(i, std::move(v)); }


Expand Down
Loading

0 comments on commit 0ea0b8f

Please sign in to comment.