[CP-SAT] more work on python layer

This commit is contained in:
Laurent Perron
2024-12-29 22:49:05 +01:00
parent 39248b01c2
commit 2b223565f4
3 changed files with 320 additions and 216 deletions

View File

@@ -189,8 +189,8 @@ LinearExpr* LinearExpr::Constant(int64_t value) {
return new IntConstant(value);
}
LinearExpr* LinearExpr::Add(LinearExpr* other) {
return new BinaryAdd(this, other);
LinearExpr* LinearExpr::Add(LinearExpr* expr) {
return new BinaryAdd(this, expr);
}
LinearExpr* LinearExpr::AddInt(int64_t cst) {
@@ -203,40 +203,40 @@ LinearExpr* LinearExpr::AddDouble(double cst) {
return new FloatAffine(this, 1.0, cst);
}
LinearExpr* LinearExpr::Sub(ExprOrValue other) {
if (other.expr != nullptr) {
return new IntWeightedSum({this, other.expr}, {1, -1}, 0);
} else if (other.double_value != 0.0) {
return new FloatAffine(this, 1.0, -other.double_value);
} else if (other.int_value != 0) {
return new IntAffine(this, 1, -other.int_value);
} else {
return this;
}
LinearExpr* LinearExpr::Sub(LinearExpr* expr) {
return new IntWeightedSum({this, expr}, {1, -1}, 0);
}
LinearExpr* LinearExpr::RSub(ExprOrValue other) {
if (other.expr != nullptr) {
return new IntWeightedSum({this, other.expr}, {-1, 1}, 0);
} else if (other.double_value != 0.0) {
return new FloatAffine(this, -1.0, other.double_value);
} else {
return new IntAffine(this, -1, other.int_value);
}
LinearExpr* LinearExpr::SubInt(int64_t cst) {
if (cst == 0) return this;
return new IntAffine(this, 1, -cst);
}
LinearExpr* LinearExpr::Mul(double cst) {
if (cst == 0.0) return new IntConstant(0);
if (cst == 1.0) return this;
return new FloatAffine(this, cst, 0.0);
LinearExpr* LinearExpr::SubDouble(double cst) {
if (cst == 0.0) return this;
return new FloatAffine(this, 1.0, -cst);
}
LinearExpr* LinearExpr::Mul(int64_t cst) {
LinearExpr* LinearExpr::RSubInt(int64_t cst) {
return new IntAffine(this, -1, cst);
}
LinearExpr* LinearExpr::RSubDouble(double cst) {
return new FloatAffine(this, -1.0, cst);
}
LinearExpr* LinearExpr::MulInt(int64_t cst) {
if (cst == 0) return new IntConstant(0);
if (cst == 1) return this;
return new IntAffine(this, cst, 0);
}
LinearExpr* LinearExpr::MulDouble(double cst) {
if (cst == 0.0) return new IntConstant(0);
if (cst == 1.0) return this;
return new FloatAffine(this, cst, 0.0);
}
LinearExpr* LinearExpr::Neg() { return new IntAffine(this, -1, 0); }
void FloatExprVisitor::AddToProcess(LinearExpr* expr, double coeff) {
@@ -449,152 +449,142 @@ std::string FloatAffine::DebugString() const {
return absl::StrCat("FloatAffine(expr=", expr_->DebugString(),
", coeff=", coeff_, ", offset=", offset_, ")");
}
BoundedLinearExpression* LinearExpr::Eq(ExprOrValue other) {
if (other.double_value != 0.0) return nullptr;
if (other.expr != nullptr) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(other.expr, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset, Domain(0));
} else {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset,
Domain(other.int_value));
}
BoundedLinearExpression* LinearExpr::Eq(LinearExpr* rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(rhs, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset, Domain(0));
}
BoundedLinearExpression* LinearExpr::Ne(ExprOrValue other) {
if (other.double_value != 0.0) return nullptr;
if (other.expr != nullptr) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(other.expr, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset,
Domain(0).Complement());
} else {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset,
Domain(other.int_value).Complement());
}
BoundedLinearExpression* LinearExpr::EqCst(int64_t rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset, Domain(rhs));
}
BoundedLinearExpression* LinearExpr::Le(ExprOrValue other) {
if (other.double_value != 0.0) return nullptr;
if (other.expr != nullptr) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(other.expr, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(std::numeric_limits<int64_t>::min(), 0));
} else {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset,
Domain(std::numeric_limits<int64_t>::min(), other.int_value));
}
BoundedLinearExpression* LinearExpr::Ne(LinearExpr* rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(rhs, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset,
Domain(0).Complement());
}
BoundedLinearExpression* LinearExpr::Lt(ExprOrValue other) {
if (other.double_value != 0.0) return nullptr;
if (other.expr != nullptr) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(other.expr, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(std::numeric_limits<int64_t>::min(), -1));
} else {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset,
Domain(std::numeric_limits<int64_t>::min(), other.int_value - 1));
}
BoundedLinearExpression* LinearExpr::NeCst(int64_t rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(vars, coeffs, offset,
Domain(rhs).Complement());
}
BoundedLinearExpression* LinearExpr::Ge(ExprOrValue other) {
if (other.double_value != 0.0) return nullptr;
if (other.expr != nullptr) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(other.expr, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(0, std::numeric_limits<int64_t>::max()));
} else {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset,
Domain(other.int_value, std::numeric_limits<int64_t>::max()));
}
BoundedLinearExpression* LinearExpr::Le(LinearExpr* rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(rhs, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(std::numeric_limits<int64_t>::min(), 0));
}
BoundedLinearExpression* LinearExpr::Gt(ExprOrValue other) {
if (other.double_value != 0.0) return nullptr;
if (other.expr != nullptr) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(other.expr, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(1, std::numeric_limits<int64_t>::max()));
} else {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset,
Domain(other.int_value + 1, std::numeric_limits<int64_t>::max()));
}
BoundedLinearExpression* LinearExpr::LeCst(int64_t rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(std::numeric_limits<int64_t>::min(), rhs));
}
BoundedLinearExpression* LinearExpr::Lt(LinearExpr* rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(rhs, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(std::numeric_limits<int64_t>::min(), -1));
}
BoundedLinearExpression* LinearExpr::LtCst(int64_t rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset,
Domain(std::numeric_limits<int64_t>::min(), rhs - 1));
}
BoundedLinearExpression* LinearExpr::Ge(LinearExpr* rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(rhs, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(0, std::numeric_limits<int64_t>::max()));
}
BoundedLinearExpression* LinearExpr::GeCst(int64_t rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(rhs, std::numeric_limits<int64_t>::max()));
}
BoundedLinearExpression* LinearExpr::Gt(LinearExpr* rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
lin.AddToProcess(rhs, -1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset, Domain(1, std::numeric_limits<int64_t>::max()));
}
BoundedLinearExpression* LinearExpr::GtCst(int64_t rhs) {
IntExprVisitor lin;
lin.AddToProcess(this, 1);
std::vector<BaseIntVar*> vars;
std::vector<int64_t> coeffs;
int64_t offset;
if (!lin.Process(&vars, &coeffs, &offset)) return nullptr;
return new BoundedLinearExpression(
vars, coeffs, offset,
Domain(rhs + 1, std::numeric_limits<int64_t>::max()));
}
void IntExprVisitor::AddToProcess(LinearExpr* expr, int64_t coeff) {

View File

@@ -78,21 +78,30 @@ class LinearExpr {
static LinearExpr* Constant(int64_t value);
static LinearExpr* Constant(double value);
LinearExpr* Add(LinearExpr* other);
LinearExpr* Add(LinearExpr* expr);
LinearExpr* AddInt(int64_t cst);
LinearExpr* AddDouble(double cst);
LinearExpr* Sub(ExprOrValue other);
LinearExpr* RSub(ExprOrValue other);
LinearExpr* Mul(double cst);
LinearExpr* Mul(int64_t cst);
LinearExpr* Sub(LinearExpr* expr);
LinearExpr* SubInt(int64_t cst);
LinearExpr* SubDouble(double cst);
LinearExpr* RSubInt(int64_t cst);
LinearExpr* RSubDouble(double cst);
LinearExpr* MulInt(int64_t cst);
LinearExpr* MulDouble(double cst);
LinearExpr* Neg();
BoundedLinearExpression* Eq(ExprOrValue other);
BoundedLinearExpression* Ne(ExprOrValue other);
BoundedLinearExpression* Ge(ExprOrValue other);
BoundedLinearExpression* Le(ExprOrValue other);
BoundedLinearExpression* Lt(ExprOrValue other);
BoundedLinearExpression* Gt(ExprOrValue other);
BoundedLinearExpression* Eq(LinearExpr* rhs);
BoundedLinearExpression* EqCst(int64_t rhs);
BoundedLinearExpression* Ne(LinearExpr* rhs);
BoundedLinearExpression* NeCst(int64_t rhs);
BoundedLinearExpression* Ge(LinearExpr* rhs);
BoundedLinearExpression* GeCst(int64_t rhs);
BoundedLinearExpression* Le(LinearExpr* rhs);
BoundedLinearExpression* LeCst(int64_t rhs);
BoundedLinearExpression* Lt(LinearExpr* rhs);
BoundedLinearExpression* LtCst(int64_t rhs);
BoundedLinearExpression* Gt(LinearExpr* rhs);
BoundedLinearExpression* GtCst(int64_t rhs);
};
// Compare the indices of variables.

View File

@@ -394,18 +394,18 @@ PYBIND11_MODULE(swig_helper, m) {
const std::vector<double>&>(
&LinearExpr::WeightedSum),
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def_static("Term",
py::overload_cast<LinearExpr*, int64_t>(&LinearExpr::Term),
arg("expr"), arg("coeff"), "Returns expr * coeff.",
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def_static("Term",
py::overload_cast<LinearExpr*, double>(&LinearExpr::Term),
arg("expr"), arg("coeff"), "Returns expr * coeff.",
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def_static(
"Term", py::overload_cast<LinearExpr*, int64_t>(&LinearExpr::Term),
arg("expr").none(false), arg("coeff"), "Returns expr * coeff.",
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def_static(
"Term", py::overload_cast<LinearExpr*, double>(&LinearExpr::Term),
arg("expr").none(false), arg("coeff"), "Returns expr * coeff.",
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__str__", &LinearExpr::ToString)
.def("__repr__", &LinearExpr::DebugString)
.def("is_integer", &LinearExpr::IsInteger)
.def("__add__", &LinearExpr::Add, arg("other"),
.def("__add__", &LinearExpr::Add, arg("other").none(false),
py::return_value_policy::automatic, py::keep_alive<0, 1>(),
py::keep_alive<0, 2>())
.def("__add__", &LinearExpr::AddInt, arg("cst"),
@@ -416,34 +416,76 @@ PYBIND11_MODULE(swig_helper, m) {
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__radd__", &LinearExpr::AddDouble, arg("cst"),
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__sub__", &LinearExpr::Sub, arg("other"),
.def("__sub__", &LinearExpr::Sub, arg("other").none(false),
py::return_value_policy::automatic, py::keep_alive<0, 1>(),
py::keep_alive<0, 2>())
.def("__rsub__", &LinearExpr::RSub, arg("other"),
py::return_value_policy::automatic, py::keep_alive<0, 1>(),
py::keep_alive<0, 2>())
.def("__mul__", py::overload_cast<double>(&LinearExpr::Mul), arg("cst"),
.def("__sub__", &LinearExpr::SubInt, arg("cst"),
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__mul__", py::overload_cast<int64_t>(&LinearExpr::Mul), arg("cst"),
.def("__sub__", &LinearExpr::SubDouble, arg("cst"),
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__rmul__", py::overload_cast<double>(&LinearExpr::Mul), arg("cst"),
.def("__rsub__", &LinearExpr::RSubInt, arg("cst"),
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__rmul__", py::overload_cast<int64_t>(&LinearExpr::Mul), arg("cst"),
.def("__rsub__", &LinearExpr::RSubDouble, arg("cst"),
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__mul__", py::overload_cast<int64_t>(&LinearExpr::MulInt),
arg("cst"), py::return_value_policy::automatic,
py::keep_alive<0, 1>())
.def("__mul__", py::overload_cast<double>(&LinearExpr::MulDouble),
arg("cst"), py::return_value_policy::automatic,
py::keep_alive<0, 1>())
.def("__rmul__", py::overload_cast<int64_t>(&LinearExpr::MulInt),
arg("cst"), py::return_value_policy::automatic,
py::keep_alive<0, 1>())
.def("__rmul__", py::overload_cast<double>(&LinearExpr::MulDouble),
arg("cst"), py::return_value_policy::automatic,
py::keep_alive<0, 1>())
.def("__neg__", &LinearExpr::Neg, py::return_value_policy::automatic,
py::keep_alive<0, 1>())
.def(
"__eq__",
[](LinearExpr* expr, ExprOrValue rhs) {
if (rhs.int_value == std::numeric_limits<int64_t>::max() ||
rhs.int_value == std::numeric_limits<int64_t>::min()) {
throw_error(PyExc_ValueError,
"== INT_MIN or INT_MAX is not supported");
[](LinearExpr* expr, LinearExpr* rhs) {
if (rhs == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints do not accept None as argument.");
}
BoundedLinearExpression* result = expr->Eq(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraint only accepts integer values "
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
},
py::return_value_policy::automatic, py::keep_alive<0, 1>(),
py::keep_alive<0, 2>())
.def(
"__eq__",
[](LinearExpr* expr, int64_t rhs) {
if (rhs == std::numeric_limits<int64_t>::max() ||
rhs == std::numeric_limits<int64_t>::min()) {
throw_error(PyExc_ValueError,
"== INT_MIN or INT_MAX is not supported");
}
BoundedLinearExpression* result = expr->EqCst(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
},
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def(
"__ne__",
[](LinearExpr* expr, LinearExpr* rhs) {
if (rhs == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints do not accept None as argument.");
}
BoundedLinearExpression* result = expr->Ne(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
@@ -452,11 +494,27 @@ PYBIND11_MODULE(swig_helper, m) {
py::keep_alive<0, 2>())
.def(
"__ne__",
[](LinearExpr* expr, ExprOrValue rhs) {
BoundedLinearExpression* result = expr->Ne(rhs);
[](LinearExpr* expr, int64_t rhs) {
BoundedLinearExpression* result = expr->NeCst(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraint only accepts integer values "
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
},
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def(
"__le__",
[](LinearExpr* expr, LinearExpr* rhs) {
if (rhs == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints do not accept None as argument.");
}
BoundedLinearExpression* result = expr->Le(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
@@ -465,14 +523,30 @@ PYBIND11_MODULE(swig_helper, m) {
py::keep_alive<0, 2>())
.def(
"__le__",
[](LinearExpr* expr, ExprOrValue rhs) {
if (rhs.int_value == std::numeric_limits<int64_t>::min()) {
[](LinearExpr* expr, int64_t rhs) {
if (rhs == std::numeric_limits<int64_t>::min()) {
throw_error(PyExc_ArithmeticError, "<= INT_MIN is not supported");
}
BoundedLinearExpression* result = expr->Le(rhs);
BoundedLinearExpression* result = expr->LeCst(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraint only accepts integer values "
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
},
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def(
"__lt__",
[](LinearExpr* expr, LinearExpr* rhs) {
if (rhs == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints do not accept None as argument.");
}
BoundedLinearExpression* result = expr->Lt(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
@@ -481,14 +555,30 @@ PYBIND11_MODULE(swig_helper, m) {
py::keep_alive<0, 2>())
.def(
"__lt__",
[](LinearExpr* expr, ExprOrValue rhs) {
if (rhs.int_value == std::numeric_limits<int64_t>::min()) {
[](LinearExpr* expr, int64_t rhs) {
if (rhs == std::numeric_limits<int64_t>::min()) {
throw_error(PyExc_ArithmeticError, "< INT_MIN is not supported");
}
BoundedLinearExpression* result = expr->Lt(rhs);
BoundedLinearExpression* result = expr->LtCst(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraint only accepts integer values "
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
},
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def(
"__ge__",
[](LinearExpr* expr, LinearExpr* rhs) {
if (rhs == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints do not accept None as argument.");
}
BoundedLinearExpression* result = expr->Ge(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
@@ -497,14 +587,30 @@ PYBIND11_MODULE(swig_helper, m) {
py::keep_alive<0, 2>())
.def(
"__ge__",
[](LinearExpr* expr, ExprOrValue rhs) {
if (rhs.int_value == std::numeric_limits<int64_t>::max()) {
[](LinearExpr* expr, int64_t rhs) {
if (rhs == std::numeric_limits<int64_t>::max()) {
throw_error(PyExc_ArithmeticError, ">= INT_MAX is not supported");
}
BoundedLinearExpression* result = expr->Ge(rhs);
BoundedLinearExpression* result = expr->GeCst(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraint only accepts integer values "
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
},
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def(
"__gt__",
[](LinearExpr* expr, LinearExpr* rhs) {
if (rhs == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints do not accept None as argument.");
}
BoundedLinearExpression* result = expr->Gt(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
@@ -513,20 +619,19 @@ PYBIND11_MODULE(swig_helper, m) {
py::keep_alive<0, 2>())
.def(
"__gt__",
[](LinearExpr* expr, ExprOrValue rhs) {
if (rhs.int_value == std::numeric_limits<int64_t>::max()) {
[](LinearExpr* expr, int64_t rhs) {
if (rhs == std::numeric_limits<int64_t>::max()) {
throw_error(PyExc_ArithmeticError, "> INT_MAX is not supported");
}
BoundedLinearExpression* result = expr->Gt(rhs);
BoundedLinearExpression* result = expr->GtCst(rhs);
if (result == nullptr) {
throw_error(PyExc_TypeError,
"Linear constraint only accepts integer values "
"Linear constraints only accept integer values "
"and coefficients.");
}
return result;
},
py::return_value_policy::automatic, py::keep_alive<0, 1>(),
py::keep_alive<0, 2>())
py::return_value_policy::automatic, py::keep_alive<0, 1>())
.def("__div__",
[](LinearExpr* /*self*/, LinearExpr* /*other*/) {
throw_error(PyExc_NotImplementedError,