Skip to content

Commit

Permalink
Mark result and arg variables #237
Browse files Browse the repository at this point in the history
Mark as proper variables when expression not accepted and for non-algebraic static constraints
  • Loading branch information
glebbelov committed Apr 30, 2024
1 parent ddf78d8 commit e20edc5
Show file tree
Hide file tree
Showing 20 changed files with 213 additions and 25 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ endfunction ()
add_mp_library(format OBJECT
include/mp/format.h include/mp/posix.h src/format.cc src/posix.cc)


# gen-expr-info
set(MP_EXPR_INFO_FILE ${MP_SOURCE_DIR}/src/expr-info.cc)
set(MP_NL_OPCODES_FILE
Expand Down Expand Up @@ -356,10 +357,11 @@ add_prefix(MP_HEADERS include/mp/
utils-clock.h utils-file.h
util-json-write.h util-json-write.hpp
utils-hash.h utils-hash-stream.h
utils-string.h utils-math.h)
utils-string.h utils-math.h utils-vec.h)

add_prefix(MP_FLAT_HEADERS include/mp/flat/
backend_flat.h
constr_2_expr.h
constr_base.h constr_eval.h constr_keeper.h constr_hash.h
constr_std.h constr_static.h constr_functional.h
constr_algebraic.h constr_general.h
Expand Down
68 changes: 68 additions & 0 deletions include/mp/flat/constr_2_expr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#ifndef CONSTR_2_EXPR_H
#define CONSTR_2_EXPR_H

#include <functional>

#include "mp/flat/constr_keeper.h"

namespace mp {

/// A mix-in base class
/// facilitating "inlining" of some functional constraints
/// into expression trees.
template <class Impl>
class Constraints2Expr {
public:

/// Consider marking the result and argument variables as
/// "explicit variables" (not expressions)
template <class Con>
void ConsiderMarkingResultAndArgVars(
const Con& con, int i, ExpressionAcceptanceLevel eal) {
if (con.HasResultVar()) { // A functional constraint
if (ExpressionAcceptanceLevel::NotAccepted==eal) {
MPD( MarkAsResultVar(con.GetResultVar()) );
}
} // Any constraint
MPD( ConsiderMarkingArgumentsAsVars(con, i, eal) );
}

/// Generic request to consider marking arguments
template <class Con>
void ConsiderMarkingArgumentsAsVars(
const Con& con, int i, ExpressionAcceptanceLevel eal) {
bool fMarkArgs = false;
if (con.HasResultVar()) // func cons: non-accepted ones by default
fMarkArgs = (ExpressionAcceptanceLevel::NotAccepted==eal);
else
fMarkArgs = true; // static cons: all non-algebraic by default
if (fMarkArgs)
MPD( DoMarkArgsAsVars(con, i) );
}


protected:
/// Algebraic cons: no marking (when NLConstraint accepted?)
template <class Body, class RhsOrRange>
void DoMarkArgsAsVars( // needs to appear before the most generic template
const AlgebraicConstraint<Body, RhsOrRange>& , int ) { }

/// @todo not mark Complementarity (NL accepts expressions)

/// Generic arguments marking call
template <class Con>
void DoMarkArgsAsVars(const Con& con, int ) {
VisitArguments(con, MarkVar_);
}


private:
/// (Argument) variable visitor
std::function<void( int )> MarkVar_ = [this](int v){
MPD( MarkAsResultVar(v) ); // no recursion
};
};

} // namespace mp

#endif // CONSTR_2_EXPR_H
2 changes: 1 addition & 1 deletion include/mp/flat/constr_algebraic.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CONSTRAINTS_ALGEBRAIC_H
#define CONSTRAINTS_ALGEBRAIC_H

/**
/*
* Static algebraic constraints
*/

Expand Down
22 changes: 22 additions & 0 deletions include/mp/flat/constr_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vector>
#include <string>
#include <cmath>
#include <functional>
#include <utility>
#include <typeinfo>

Expand Down Expand Up @@ -277,6 +278,27 @@ inline void WriteJSON(JW jw,
}


/// Argument container visitor: VarArrayN
template <size_t N> // Needs to appear before the generic template version, CLang 15
inline void VisitArguments(const std::array<int, N>& cnt, std::function<void (int)> argv) {
for (auto v: cnt)
argv(v);
}

/// Generic constraint/objective argument visitor
template <class Item>
inline void VisitArguments(const Item& item, std::function<void (int)> argv) {
VisitArguments(item.GetArguments(), argv); // redirect to the arguments' visitor
}

/// Argument container visitor: VarArray
template <>
inline void VisitArguments(const std::vector<int>& cnt, std::function<void (int)> argv) {
for (auto v: cnt)
argv(v);
}


/// Dummy template: compute result of functional constraint.
/// Should be implemented for proper functional specializations,
/// but has no sense for conic constraints, for example.
Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_eval.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CONSTR_EVAL_H
#define CONSTR_EVAL_H

/**
/*
* Evaluations and violations
* of (mainly functional) constraints.
*
Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_functional.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CONSTRAINTS_FUNCTIONAL_H
#define CONSTRAINTS_FUNCTIONAL_H

/**
/*
* Functional flat constraints
*/

Expand Down
22 changes: 21 additions & 1 deletion include/mp/flat/constr_general.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CONSTRAINTS_GENERAL_H
#define CONSTRAINTS_GENERAL_H

/**
/*
* Static general constraints
*/

Expand Down Expand Up @@ -99,6 +99,15 @@ inline void WriteJSON(JSONW jw,
}


/// Specialize
template <class Con>
inline void VisitArguments(const IndicatorConstraint<Con>& ic,
std::function<void (int) > argv) {
argv(ic.get_binary_var());
VisitArguments(ic.get_constraint(), argv);
}


/// Unary encoding.
/// Currently a dummy constraint just to build
/// the reformulation graph.
Expand Down Expand Up @@ -147,6 +156,8 @@ class SOS_1or2_Constraint: public BasicConstraint {
int size() const { return (int)v_.size(); }
/// Returns vector of variables, sorted by weights
const std::vector<int>& get_vars() const { return v_; }
/// vars via GetArguments()
const std::vector<int>& GetArguments() const { return get_vars(); }
/// Returns weights, sorted
const std::vector<double>& get_weights() const { return w_; }
/// SOS2 extra info
Expand Down Expand Up @@ -340,6 +351,15 @@ inline void WriteJSON(JSONW jw,
}


/// Specialize
template <class Expr>
inline void VisitArguments(const ComplementarityConstraint<Expr>& cc,
std::function<void (int) > argv) {
argv(cc.GetVariable());
VisitArguments(cc.GetExpression(), argv);
}


/// Quadratic cone
DEF_STATIC_CONSTR_WITH_PRM( QuadraticCone, VarArray, DblParamArray,
"Quadratic cone p1*x1 >= sqrt((p2*x2)^2 + ...)),"
Expand Down
2 changes: 0 additions & 2 deletions include/mp/flat/constr_hash.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#ifndef CONSTRAINT_HASH_H
#define CONSTRAINT_HASH_H

/// Specialize std::hash<> for some standard constraints

#include <functional>
#include <array>
#include <vector>
Expand Down
31 changes: 24 additions & 7 deletions include/mp/flat/constr_keeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,16 +386,25 @@ class BasicConstraintKeeper {
/// Convert to use expressions
virtual void ConvertWithExpressions(BasicFlatConverter& cvt) = 0;

/// Query (user-chosen, if sensible) constraint acceptance level.
/// Query (user-chosen) acceptance level.
/// This is "combined" for constraint or expression
virtual ConstraintAcceptanceLevel GetChosenAcceptanceLevel() const {
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_);
}

/// Query (user-chosen) expression acceptance level.
ExpressionAcceptanceLevel GetChosenAcceptanceLevelEXPR() const {
if (acc_level_expr_<0) { // not initialized
std::array<int, 5> alv = {0, 0, 0, 1, 2};
acc_level_expr_ = alv.at(acc_level_item_);
}
return ExpressionAcceptanceLevel(acc_level_expr_);
}

/// Converter's ability to convert the constraint type
virtual bool IfConverterConverts(
BasicFlatConverter& cvt ) const = 0;
Expand Down Expand Up @@ -465,14 +474,15 @@ class BasicConstraintKeeper {
/// See what options are available for this constraint:
/// whether it is accepted natively by ModelAPI,
/// as flat constraint or expression.
/// If both, add constraint acceptance option.
/// Add acceptance option(s) "acc:...".
/// Populate constraint list for -c output.
/// @note This should be called before using the class.
void ConsiderAcceptanceOptions(
BasicFlatConverter& cvt,
const BasicFlatModelAPI& ma,
Env& env) {
DoAddAcceptanceOptions(cvt, ma, env);
DoPopulateConstraintList(cvt, ma, env);
DoPopulateConstraintList(cvt, ma, env); // for -c option
}

/// Mark as bridged. Use index only.
Expand Down Expand Up @@ -507,6 +517,7 @@ class BasicConstraintKeeper {
BasicFlatConverter& cvt,
const BasicFlatModelAPI& ma,
Env& env);
/// For -c
void DoPopulateConstraintList(
BasicFlatConverter& cvt,
const BasicFlatModelAPI& ma,
Expand Down Expand Up @@ -891,9 +902,15 @@ class ConstraintKeeper final
}

void DoMarkForResultVars() {
const auto acceptanceLevel =
GetChosenAcceptanceLevel();

const auto eal // expr only
= GetChosenAcceptanceLevelEXPR();
for (int i=0; i< (int)cons_.size(); ++i) {
const auto& cnt = cons_[i];
if (!cnt.IsBridged()) { // Delegate actual logic to Converter
const auto& con = cnt.GetCon();
GetConverter().ConsiderMarkingResultAndArgVars(con, i, eal);
}
}
}

void DoCvtWithExprs() { }
Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_prepro.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CONSTR_PREPRO_H
#define CONSTR_PREPRO_H

/**
/*
* Preprocess flat constraints before adding.
*
* Possible tasks:
Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_prop_down.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CONSTR_PROP_DOWN_H
#define CONSTR_PROP_DOWN_H

/**
/*
* Propagate flat constraints from result (result bounds & context)
* "down", i.e., to the arguments
*/
Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_static.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CONSTRAINTS_STATIC_H
#define CONSTRAINTS_STATIC_H

/**
/*
* Static (non-functional) flat constraints
*/

Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_std.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef STD_CONSTR_H
#define STD_CONSTR_H

/**
/*
* Convenience header to include all standard
* flat constraints
*/
Expand Down
17 changes: 10 additions & 7 deletions include/mp/flat/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "mp/flat/expr_bounds.h"
#include "mp/flat/constr_prepro.h"
#include "mp/flat/constr_prop_down.h"
#include "mp/flat/constr_2_expr.h"
#include "mp/flat/sol_check.h"
#include "mp/valcvt.h"
#include "mp/flat/redef/std/range_con.h"
Expand All @@ -35,13 +36,14 @@ namespace mp {
template <class Impl, class ModelAPI,
class FlatModel = FlatModel< > >
class FlatConverter :
public BasicFlatConverter,
public FlatModel,
public BoundComputations<Impl>,
public ConstraintPreprocessors<Impl>,
public ConstraintPropagatorsDown<Impl>,
public SolutionChecker<Impl>,
public EnvKeeper
public BasicFlatConverter,
public FlatModel,
public BoundComputations<Impl>,
public ConstraintPreprocessors<Impl>,
public ConstraintPropagatorsDown<Impl>,
public Constraints2Expr<Impl>,
public SolutionChecker<Impl>,
public EnvKeeper
{
public:
/// Class name
Expand Down Expand Up @@ -854,6 +856,7 @@ class FlatConverter :
== ci.GetCK();
}


/////////////////////// AUTO LINKING ////////////////////////////

/// Auto link node range \a nr.
Expand Down
18 changes: 18 additions & 0 deletions include/mp/flat/converter_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,20 @@ class FlatModel
var_ub_[v] = u;
}

/// Mark as an explicit result variable
void MarkAsResultVar(int v) {
if (var_result_.size()<=v)
var_result_.resize(num_vars());
var_result_[v] = true;
}

/// Is the variable an explicit result var?
bool IsResultVar(int v) const {
if (var_result_.size()<=v)
var_result_.resize(num_vars());
return var_result_[v];
}

///////////////////////////// OBJECTIVES ////////////////////////////
public:
/// List of objectives
Expand Down Expand Up @@ -379,6 +393,10 @@ class FlatModel
VarBndVec var_lb_, var_ub_;
/// Variables' types
VarTypeVec var_type_;
/// Whether the variable, being the result variable of a functional constraint,
/// needs to stay a variable (vs being eliminated because the constraint
/// is becoming an expression)
std::vector<bool> var_result_;
/// Variables' names
mutable VarNameVec var_names_;
std::vector<std::string> var_names_storage_;
Expand Down
Loading

0 comments on commit e20edc5

Please sign in to comment.