Skip to content

Commit

Permalink
Export constraints #232
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Mar 1, 2024
1 parent 191728c commit e72f0c0
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 61 deletions.
30 changes: 30 additions & 0 deletions include/mp/flat/constr_algebraic.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,18 @@ template <int kind_>
class AlgConRhs {
static constexpr const char* kind_str_[] =
{ "LT", "LE", "EQ", "GE", "GT" };
static constexpr const char* kind_cmp_[] =
{ "<", "<=", "==", ">=", ">" };
public:
/// name
static std::string GetTypeName()
{ return std::string("Rhs") + kind_str_[kind_+2]; }
/// Comparison name as string
static const char* GetCmpName()
{ return kind_str_[kind_+2]; }
/// Comparison operator as string
static const char* GetCmpStr()
{ return kind_cmp_[kind_+2]; }
/// Constructor
AlgConRhs(double r) : rhs_(r) { }
/// Kind
Expand Down Expand Up @@ -227,6 +235,28 @@ using QuadConGE = QuadConRhs< 1>;
/// Quadratic constraint c'x+x`Qx > d
using QuadConGT = QuadConRhs< 2>;


/// Write an algebraic constraint
template <class Body, class RhsOrRange>
inline void WriteJSON(JSONW jw,
const AlgebraicConstraint<Body, RhsOrRange>& algc) {
WriteJSON(jw["body"], algc.GetBody());
WriteJSON(jw["rhs_or_range"], algc.GetRhsOrRange());
}

/// Write alg con range
inline void WriteJSON(JSONW jw,
const AlgConRange& acr) {
jw << acr.lb() << acr.ub();
}

/// Write alg con rhs
template <int kind>
inline void WriteJSON(JSONW jw,
const AlgConRhs<kind>& acrhs) {
jw << acrhs.GetCmpName() << acrhs.rhs();
}

} // namespace mp

#endif // CONSTRAINTS_ALGEBRAIC_H
19 changes: 19 additions & 0 deletions include/mp/flat/constr_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ class CustomFunctionalConstraint :
};


/// Write a CustomFunctionalConstraint<>
template <class JW, class A, class P, class N, class I>
inline void WriteJSON(JW jw,
const CustomFunctionalConstraint<A,P,N,I>& cfc) {
jw["res_var"] = cfc.GetResultVar();
WriteJSON(jw["args"], cfc.GetArguments());
WriteJSON(jw["params"], cfc.GetParameters());
}


/// 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 Expand Up @@ -336,6 +346,15 @@ class ConditionalConstraint :
}
};

/// Write a CondCon
template <class JW, class Con>
inline void WriteJSON(JW jw,
const ConditionalConstraint<Con>& condc) {
jw["res_var"] = condc.GetResultVar();
WriteJSON(jw["con"], condc.GetConstraint());
}


////////////////////////////////////////////////////////////////////////
/// Args is the argument type, e.g., array of variables, or an expression
/// Params is the parameter type, e.g., array of numbers. Can be empty
Expand Down
27 changes: 27 additions & 0 deletions include/mp/flat/constr_functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,15 @@ class LinearFunctionalConstraint :
}
};


/// Write a LinFuncCon
inline void WriteJSON(JSONW jw,
const LinearFunctionalConstraint& lfc) {
jw["res_var"] = lfc.GetResultVar();
WriteJSON(jw["expr"], lfc.GetAffineExpr());
}


////////////////////////////////////////////////////////////////////////
/// Quadratic Functional Constraint: r = quad_expr
class QuadraticFunctionalConstraint :
Expand Down Expand Up @@ -267,6 +276,14 @@ class QuadraticFunctionalConstraint :
};


/// Write a QuadrFuncCon
inline void WriteJSON(JSONW jw,
const QuadraticFunctionalConstraint& qfc) {
jw["res_var"] = qfc.GetResultVar();
WriteJSON(jw["expr"], qfc.GetQuadExpr());
}


////////////////////////////////////////////////////////////////////////
/// AMPL represents PWL by a list of slopes
/// and breakpoints between them, assuming (X0,Y0) is on the line
Expand Down Expand Up @@ -375,6 +392,16 @@ class PLConParams {
DEF_NUMERIC_FUNC_CONSTR_WITH_PRM( PLConstraint,
VarArray1, PLConParams, "r = piecewise_linear(x)");


/// Write PLConParams
inline void WriteJSON(JSONW jw,
const PLConParams& plp) {
const auto& p = plp.GetPLPoints();
jw["pl_x"] = p.x_;
jw["pl_y"] = p.y_;
}


} // namespace mp

#endif // CONSTRAINTS_FUNCTIONAL_H
37 changes: 26 additions & 11 deletions include/mp/flat/constr_general.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ using IndicatorConstraintQuadEQ = IndicatorConstraint<QuadConEQ>;
using IndicatorConstraintQuadGE = IndicatorConstraint<QuadConGE>;


/// Write an indicator constraint
template <class Con>
inline void WriteJSON(JSONW jw,
const IndicatorConstraint<Con>& ic) {
jw["bin_var"] = ic.get_binary_var();
jw["bin_val"] = ic.get_binary_value();
WriteJSON(jw["con"], ic.get_constraint());
}


/// Unary encoding.
/// Currently a dummy constraint just to build
/// the reformulation graph.
Expand Down Expand Up @@ -222,18 +232,13 @@ using SOS2Constraint = SOS_1or2_Constraint<2>;


/// Write a SOS1, SOS2 constraint
template <class Writer, int type>
inline void WriteJSON(Writer& wrt, const SOS_1or2_Constraint<type>& sos) {
wrt.write("{} ", '{');
wrt.write("\"sos_type\": {}, ", sos.get_sos_type());
wrt.write("\"vars\": ");
WriteJSONVec(wrt, sos.get_vars());
wrt.write(", \"weights\": ");
WriteJSONVec(wrt, sos.get_weights());
template <int type>
inline void WriteJSON(JSONW jw, const SOS_1or2_Constraint<type>& sos) {
jw["SOS_type"] = sos.get_sos_type();
jw["vars"] = sos.get_vars();
jw["weights"] = sos.get_weights();
auto bnds = sos.get_sum_of_vars_range();
wrt.write(", \"sum_of_vars_range\": [{}, {}]",
bnds.lb_, bnds.ub_);
wrt.write(" {}", '}');
jw["sum_of_vars_range"] << bnds.lb_ << bnds.ub_;
}

////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -291,6 +296,16 @@ using ComplementarityLinear = ComplementarityConstraint<AffineExpr>;
/// Typedef ComplementarityQuadRange
using ComplementarityQuadratic = ComplementarityConstraint<QuadraticExpr>;


/// Write a ComplementarityCon
template <class Expr>
inline void WriteJSON(JSONW jw,
const ComplementarityConstraint<Expr>& cc) {
WriteJSON(jw["expr"], cc.GetExpression());
jw["compl_var"] = cc.GetVariable();
}


/// Quadratic cone
DEF_STATIC_CONSTR_WITH_PRM( QuadraticConeConstraint, VarArray, DblParamArray,
"Quadratic cone p1*x1 >= sqrt((p2*x2)^2 + ...)),"
Expand Down
3 changes: 1 addition & 2 deletions include/mp/flat/constr_keeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -884,8 +884,7 @@ class ConstraintKeeper final
jw["CON_TYPE"] = GetShortTypeName();
jw["index"] = i_con;
jw["depth"] = cnt.GetDepth();
// wrt.write("\"data\": ");
// WriteJSON(wrt, cnt.con_);
WriteJSON(jw["data"], cnt.con_);
}
wrt.write("\n"); // EOL
GetLogger()->Append(wrt);
Expand Down
11 changes: 4 additions & 7 deletions include/mp/flat/converter_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class FlatModel
fmt::MemoryWriter wrt;
{
MiniJSONWriter jw(wrt);
jw["VAR_INDEX"] = i+i_start;
jw["VAR_index"] = i+i_start;
jw["bounds"] << lbs[i] << ubs[i];
jw["type"] = (int)types[i];
jw["is_from_nl"] = (int)is_var_original(i);
Expand Down Expand Up @@ -238,13 +238,10 @@ class FlatModel
fmt::MemoryWriter wrt;
{
MiniJSONWriter jw(wrt);
jw["OBJ_INDEX"] = i_obj;
jw["OBJECTIVE_index"] = i_obj;
jw["sense"] = (int)obj.obj_sense();
wrt.write("\"qp_terms\": ");
WriteJSON(wrt, obj.GetQPTerms());
wrt.write("\"lin_terms\": ");
WriteJSON(wrt, obj.GetLinTerms());
wrt.write(" {}\n", '}'); // with EOL
WriteJSON(jw["qp_terms"], obj.GetQPTerms());
WriteJSON(jw["lin_terms"], obj.GetLinTerms());
}
wrt.write("\n"); // EOL
GetFileAppender().Append(wrt);
Expand Down
4 changes: 4 additions & 0 deletions include/mp/flat/expr_affine.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ class LinTerms {
std::vector<int> vars_;
};

/// Specialize
template <>
void WriteJSON(JSONW jw, const LinTerms& qt);


/// Typedef AffineExpr
using AffineExpr = AlgebraicExpression<LinTerms>;
Expand Down
21 changes: 16 additions & 5 deletions include/mp/flat/expr_algebraic.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string>
#include <cmath>

#include "mp/util-json-write.hpp"
#include "mp/arrayref.h"

namespace mp {
Expand Down Expand Up @@ -112,13 +113,23 @@ class AlgebraicExpression : public Body {
};

/// Very general template to write
/// a JSON representation of anything
/// a JSON-like representation of anything
template <class Writer, class Obj>
void WriteJSON(Writer& , const Obj& );
void WriteJSON(Writer w, const Obj& o) {
w = o; // default: assume assignable
} // unless WriteJSON is specialized for Obj

/// Specialize our JSON writer
using JSONW = MiniJSONWriter<fmt::MemoryWriter>;

/// Write an AlgebraicExpression
template <class Terms>
inline void WriteJSON(JSONW jw,
const AlgebraicExpression<Terms>& ale) {
WriteJSON(jw["body"], ale.GetBody());
jw["const_term"] = ale.constant_term();
}

/// Write JSON string of a vector
template <class Writer, class Vec>
void WriteJSONVec(Writer& wrt, const Vec& vec);

} // namespace mp

Expand Down
7 changes: 7 additions & 0 deletions include/mp/flat/expr_quadratic.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ class QuadTerms {
std::vector<int> vars2_;
};

/// Specialize
template <>
void WriteJSON(JSONW jw, const QuadTerms& qt);

////////////////////////////////////////////////////////////////////////
/// Quadratic and linear terms.
Expand Down Expand Up @@ -229,6 +232,10 @@ class QuadAndLinTerms :
bool operator==(const QuadAndLinTerms& qlc) const { return equals(qlc); }
};

/// Specialize
template <>
void WriteJSON(JSONW jw, const QuadAndLinTerms& qt);


/// Typedef QuadraticExpr
using QuadraticExpr = AlgebraicExpression<QuadAndLinTerms>;
Expand Down
31 changes: 21 additions & 10 deletions include/mp/util-json-write.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,24 +65,34 @@ class MiniJSONWriter {
/// operator<<: make/ensure *this an array
/// and write \a val a new element.
///
/// Equivalent: `++(*this) = val; return *this;`
///
/// @param val: scalar, tuple or container.
/// For non-supported types, define global method
/// Serialize(MiniJSONWriter& , const YourType& ).
/// For non-supported types,
/// write elements manually into
/// `auto jw_child = ++jw;`,
/// or define, e.g.,
/// `Serialize(MiniJSONWriter , const YourType& )`,
/// to be used as follows:
/// `Serialize(++jw, obj[5]);`
/// (instead of `jw << obj[5]`.)
///
/// @return *this.
template <class Value>
Node& operator<<(const Value& val) {
EnsureArray();
InsertElementSeparator();
Write(val);
return *this;
}
Node& operator<<(const Value& val)
{ ++(*this) = val; return *this; }

/// operator=: write \a val as a whole.
///
/// @param val: scalar, tuple or container.
/// For non-supported types, define global method
/// Serialize(MiniJSONWriter& , const YourType& ).
/// For non-supported types,
/// write elements manually into
/// `auto jw_child = jw["data"];`,
/// or define, e.g.,
/// `Serialize(MiniJSONWriter , const YourType& )`,
/// to be used as follows:
/// `Serialize(jw["data"], obj_data);`
/// (instead of `jw["data"] = obj_data`.)
///
/// @note Can be called only once on a single node.
template <class Value>
Expand Down Expand Up @@ -155,6 +165,7 @@ class MiniJSONWriter {
int> = 0> // C++17
void DoWrite(Arithmetic v) { DoWriteScalar(v); }

/// Write a container
template <typename C,
typename T = std::decay_t<
decltype(*begin(std::declval<C>()))> >
Expand Down
2 changes: 1 addition & 1 deletion include/mp/valcvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ class ValuePresolverImpl : public BasicValuePresolver {
void WriteNodes(JSON jw, const std::vector<NodeRange>& nodes) {
for (size_t i=0; i<nodes.size(); ++i) {
const auto& nd = nodes[i];
auto jelement = ++jw; // We write an array
auto jelement = ++jw; // jw is an array of dict's
if (nd.IsSingleIndex())
jelement[nd.GetValueNode()->GetName()] = (int)nd;
else
Expand Down
Loading

0 comments on commit e72f0c0

Please sign in to comment.