Files

807 lines
26 KiB
C++
Raw Permalink Normal View History

2025-01-10 11:35:44 +01:00
// Copyright 2010-2025 Google LLC
2010-09-15 12:42:33 +00:00
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2010-09-15 12:42:33 +00:00
// Range constraints
2011-09-21 15:16:48 +00:00
#include <stddef.h>
2011-09-21 15:16:48 +00:00
#include <string>
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
#include "absl/strings/str_format.h"
#include "ortools/base/logging.h"
#include "ortools/constraint_solver/constraint_solver.h"
#include "ortools/constraint_solver/constraint_solveri.h"
2010-09-15 12:42:33 +00:00
namespace operations_research {
//-----------------------------------------------------------------------------
// RangeEquality
namespace {
2010-09-15 12:42:33 +00:00
class RangeEquality : public Constraint {
2020-10-22 23:36:58 +02:00
public:
2020-10-29 14:25:39 +01:00
RangeEquality(Solver* const s, IntExpr* const l, IntExpr* const r)
: Constraint(s), left_(l), right_(r) {}
~RangeEquality() override {}
void Post() override {
2020-10-29 14:25:39 +01:00
Demon* const d = solver()->MakeConstraintInitialPropagateCallback(this);
left_->WhenRange(d);
right_->WhenRange(d);
}
void InitialPropagate() override {
left_->SetRange(right_->Min(), right_->Max());
right_->SetRange(left_->Min(), left_->Max());
}
std::string DebugString() const override {
return left_->DebugString() + " == " + right_->DebugString();
}
2020-10-29 14:25:39 +01:00
IntVar* Var() override { return solver()->MakeIsEqualVar(left_, right_); }
2020-10-29 14:25:39 +01:00
void Accept(ModelVisitor* const visitor) const override {
visitor->BeginVisitConstraint(ModelVisitor::kEquality, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
right_);
visitor->EndVisitConstraint(ModelVisitor::kEquality, this);
2011-07-11 20:13:14 +00:00
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntExpr* const left_;
IntExpr* const right_;
2010-09-15 12:42:33 +00:00
};
//-----------------------------------------------------------------------------
// RangeLessOrEqual
class RangeLessOrEqual : public Constraint {
2020-10-22 23:36:58 +02:00
public:
2023-05-31 14:27:08 +02:00
RangeLessOrEqual(Solver* s, IntExpr* l, IntExpr* r);
~RangeLessOrEqual() override {}
void Post() override;
void InitialPropagate() override;
std::string DebugString() const override;
2020-10-29 14:25:39 +01:00
IntVar* Var() override {
return solver()->MakeIsLessOrEqualVar(left_, right_);
}
2020-10-29 14:25:39 +01:00
void Accept(ModelVisitor* const visitor) const override {
2011-07-11 20:13:14 +00:00
visitor->BeginVisitConstraint(ModelVisitor::kLessOrEqual, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
2011-07-11 20:13:14 +00:00
right_);
visitor->EndVisitConstraint(ModelVisitor::kLessOrEqual, this);
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntExpr* const left_;
IntExpr* const right_;
Demon* demon_;
2010-09-15 12:42:33 +00:00
};
2020-10-29 14:25:39 +01:00
RangeLessOrEqual::RangeLessOrEqual(Solver* const s, IntExpr* const l,
IntExpr* const r)
: Constraint(s), left_(l), right_(r), demon_(nullptr) {}
2010-09-15 12:42:33 +00:00
void RangeLessOrEqual::Post() {
2012-07-06 13:47:48 +00:00
demon_ = solver()->MakeConstraintInitialPropagateCallback(this);
left_->WhenRange(demon_);
right_->WhenRange(demon_);
2010-09-15 12:42:33 +00:00
}
void RangeLessOrEqual::InitialPropagate() {
left_->SetMax(right_->Max());
right_->SetMin(left_->Min());
2012-07-06 13:47:48 +00:00
if (left_->Max() <= right_->Min()) {
demon_->inhibit(solver());
}
2010-09-15 12:42:33 +00:00
}
std::string RangeLessOrEqual::DebugString() const {
2010-09-15 12:42:33 +00:00
return left_->DebugString() + " <= " + right_->DebugString();
}
//-----------------------------------------------------------------------------
// RangeLess
class RangeLess : public Constraint {
2020-10-22 23:36:58 +02:00
public:
2023-05-31 14:27:08 +02:00
RangeLess(Solver* s, IntExpr* l, IntExpr* r);
~RangeLess() override {}
void Post() override;
void InitialPropagate() override;
std::string DebugString() const override;
2020-10-29 14:25:39 +01:00
IntVar* Var() override { return solver()->MakeIsLessVar(left_, right_); }
void Accept(ModelVisitor* const visitor) const override {
2011-07-11 20:13:14 +00:00
visitor->BeginVisitConstraint(ModelVisitor::kLess, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
2011-07-11 20:13:14 +00:00
right_);
visitor->EndVisitConstraint(ModelVisitor::kLess, this);
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntExpr* const left_;
IntExpr* const right_;
Demon* demon_;
2010-09-15 12:42:33 +00:00
};
2020-10-29 14:25:39 +01:00
RangeLess::RangeLess(Solver* const s, IntExpr* const l, IntExpr* const r)
: Constraint(s), left_(l), right_(r), demon_(nullptr) {}
2010-09-15 12:42:33 +00:00
void RangeLess::Post() {
2012-07-06 13:49:59 +00:00
demon_ = solver()->MakeConstraintInitialPropagateCallback(this);
left_->WhenRange(demon_);
right_->WhenRange(demon_);
2010-09-15 12:42:33 +00:00
}
void RangeLess::InitialPropagate() {
2022-12-07 17:37:45 +01:00
if (right_->Max() == kint64min) solver()->Fail();
2010-09-15 12:42:33 +00:00
left_->SetMax(right_->Max() - 1);
2022-12-07 17:37:45 +01:00
if (left_->Min() == kint64max) solver()->Fail();
2010-09-15 12:42:33 +00:00
right_->SetMin(left_->Min() + 1);
2012-07-06 13:49:59 +00:00
if (left_->Max() < right_->Min()) {
demon_->inhibit(solver());
}
2010-09-15 12:42:33 +00:00
}
std::string RangeLess::DebugString() const {
2010-09-15 12:42:33 +00:00
return left_->DebugString() + " < " + right_->DebugString();
}
//-----------------------------------------------------------------------------
// DiffVar
class DiffVar : public Constraint {
2020-10-22 23:36:58 +02:00
public:
2023-05-31 14:27:08 +02:00
DiffVar(Solver* s, IntVar* l, IntVar* r);
~DiffVar() override {}
void Post() override;
void InitialPropagate() override;
std::string DebugString() const override;
2020-10-29 14:25:39 +01:00
IntVar* Var() override { return solver()->MakeIsDifferentVar(left_, right_); }
void LeftBound();
void RightBound();
2020-10-29 14:25:39 +01:00
void Accept(ModelVisitor* const visitor) const override {
2011-07-11 20:13:14 +00:00
visitor->BeginVisitConstraint(ModelVisitor::kNonEqual, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
2011-07-11 20:13:14 +00:00
right_);
visitor->EndVisitConstraint(ModelVisitor::kNonEqual, this);
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntVar* const left_;
IntVar* const right_;
2010-09-15 12:42:33 +00:00
};
2020-10-29 14:25:39 +01:00
DiffVar::DiffVar(Solver* const s, IntVar* const l, IntVar* const r)
: Constraint(s), left_(l), right_(r) {}
2010-09-15 12:42:33 +00:00
void DiffVar::Post() {
2020-10-29 14:25:39 +01:00
Demon* const left_demon =
MakeConstraintDemon0(solver(), this, &DiffVar::LeftBound, "LeftBound");
2020-10-29 14:25:39 +01:00
Demon* const right_demon =
MakeConstraintDemon0(solver(), this, &DiffVar::RightBound, "RightBound");
left_->WhenBound(left_demon);
right_->WhenBound(right_demon);
2010-09-15 12:42:33 +00:00
// TODO(user) : improve me, separated demons, actually to test
}
void DiffVar::LeftBound() {
if (right_->Size() < 0xFFFFFF) {
2020-10-22 23:36:58 +02:00
right_->RemoveValue(left_->Min()); // we use min instead of value
} else {
solver()->AddConstraint(solver()->MakeNonEquality(right_, left_->Min()));
}
}
void DiffVar::RightBound() {
if (left_->Size() < 0xFFFFFF) {
2020-10-22 23:36:58 +02:00
left_->RemoveValue(right_->Min()); // see above
} else {
solver()->AddConstraint(solver()->MakeNonEquality(left_, right_->Min()));
}
}
2010-09-15 12:42:33 +00:00
void DiffVar::InitialPropagate() {
if (left_->Bound()) {
LeftBound();
2010-09-15 12:42:33 +00:00
}
if (right_->Bound()) {
RightBound();
2010-09-15 12:42:33 +00:00
}
}
std::string DiffVar::DebugString() const {
2010-09-15 12:42:33 +00:00
return left_->DebugString() + " != " + right_->DebugString();
}
2012-07-04 22:05:58 +00:00
// --------------------- Reified API -------------------
2023-05-31 14:27:08 +02:00
// A reified API transforms a constraint into a status variables.
// For example x == y is transformed into IsEqual(x, y, b) where
// b is a boolean variable which is true if and only if x is equal to b.
2012-07-04 22:05:58 +00:00
// IsEqualCt
class IsEqualCt : public CastConstraint {
2020-10-22 23:36:58 +02:00
public:
2020-10-29 14:25:39 +01:00
IsEqualCt(Solver* const s, IntExpr* const l, IntExpr* const r,
IntVar* const b)
: CastConstraint(s, b), left_(l), right_(r), range_demon_(nullptr) {}
2012-07-04 22:05:58 +00:00
~IsEqualCt() override {}
2012-07-04 22:05:58 +00:00
void Post() override {
2013-07-14 04:22:33 +00:00
range_demon_ = solver()->MakeConstraintInitialPropagateCallback(this);
2012-07-04 22:05:58 +00:00
left_->WhenRange(range_demon_);
right_->WhenRange(range_demon_);
2020-10-29 14:25:39 +01:00
Demon* const target_demon = MakeConstraintDemon0(
solver(), this, &IsEqualCt::PropagateTarget, "PropagateTarget");
2012-07-04 22:05:58 +00:00
target_var_->WhenBound(target_demon);
}
void InitialPropagate() override {
2012-07-04 22:05:58 +00:00
if (target_var_->Bound()) {
PropagateTarget();
return;
}
2012-09-05 16:37:24 +00:00
if (left_->Min() > right_->Max() || left_->Max() < right_->Min()) {
2012-07-04 22:05:58 +00:00
target_var_->SetValue(0);
range_demon_->inhibit(solver());
2012-09-06 09:50:39 +00:00
} else if (left_->Bound()) {
if (right_->Bound()) {
target_var_->SetValue(left_->Min() == right_->Min());
} else if (right_->IsVar() && !right_->Var()->Contains(left_->Min())) {
range_demon_->inhibit(solver());
target_var_->SetValue(0);
}
} else if (right_->Bound() && left_->IsVar() &&
2012-09-06 09:50:39 +00:00
!left_->Var()->Contains(right_->Min())) {
range_demon_->inhibit(solver());
target_var_->SetValue(0);
2012-07-04 22:05:58 +00:00
}
}
void PropagateTarget() {
if (target_var_->Min() == 0) {
if (left_->Bound()) {
range_demon_->inhibit(solver());
2013-07-14 04:22:33 +00:00
if (right_->IsVar()) {
right_->Var()->RemoveValue(left_->Min());
} else {
solver()->AddConstraint(
solver()->MakeNonEquality(right_, left_->Min()));
}
2012-07-04 22:05:58 +00:00
} else if (right_->Bound()) {
range_demon_->inhibit(solver());
2013-07-14 04:22:33 +00:00
if (left_->IsVar()) {
left_->Var()->RemoveValue(right_->Min());
} else {
solver()->AddConstraint(
solver()->MakeNonEquality(left_, right_->Min()));
}
2012-07-04 22:05:58 +00:00
}
2020-10-22 23:36:58 +02:00
} else { // Var is true.
2012-07-04 22:05:58 +00:00
left_->SetRange(right_->Min(), right_->Max());
right_->SetRange(left_->Min(), left_->Max());
}
}
std::string DebugString() const override {
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
return absl::StrFormat("IsEqualCt(%s, %s, %s)", left_->DebugString(),
right_->DebugString(), target_var_->DebugString());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
void Accept(ModelVisitor* const visitor) const override {
2012-07-04 22:05:58 +00:00
visitor->BeginVisitConstraint(ModelVisitor::kIsEqual, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
right_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
target_var_);
visitor->EndVisitConstraint(ModelVisitor::kIsEqual, this);
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntExpr* const left_;
IntExpr* const right_;
Demon* range_demon_;
2012-07-04 22:05:58 +00:00
};
// IsDifferentCt
class IsDifferentCt : public CastConstraint {
2020-10-22 23:36:58 +02:00
public:
2020-10-29 14:25:39 +01:00
IsDifferentCt(Solver* const s, IntExpr* const l, IntExpr* const r,
IntVar* const b)
: CastConstraint(s, b), left_(l), right_(r), range_demon_(nullptr) {}
2012-07-04 22:05:58 +00:00
~IsDifferentCt() override {}
2012-07-04 22:05:58 +00:00
void Post() override {
range_demon_ = solver()->MakeConstraintInitialPropagateCallback(this);
2012-07-04 22:05:58 +00:00
left_->WhenRange(range_demon_);
right_->WhenRange(range_demon_);
2020-10-29 14:25:39 +01:00
Demon* const target_demon = MakeConstraintDemon0(
solver(), this, &IsDifferentCt::PropagateTarget, "PropagateTarget");
2012-07-04 22:05:58 +00:00
target_var_->WhenBound(target_demon);
}
void InitialPropagate() override {
2012-07-04 22:05:58 +00:00
if (target_var_->Bound()) {
PropagateTarget();
return;
}
2012-09-05 16:42:49 +00:00
if (left_->Min() > right_->Max() || left_->Max() < right_->Min()) {
2012-07-04 22:05:58 +00:00
target_var_->SetValue(1);
range_demon_->inhibit(solver());
2012-09-06 09:50:39 +00:00
} else if (left_->Bound()) {
if (right_->Bound()) {
target_var_->SetValue(left_->Min() != right_->Min());
} else if (right_->IsVar() && !right_->Var()->Contains(left_->Min())) {
range_demon_->inhibit(solver());
target_var_->SetValue(1);
}
} else if (right_->Bound() && left_->IsVar() &&
2012-09-06 09:50:39 +00:00
!left_->Var()->Contains(right_->Min())) {
range_demon_->inhibit(solver());
target_var_->SetValue(1);
2012-07-04 22:05:58 +00:00
}
}
void PropagateTarget() {
if (target_var_->Min() == 0) {
left_->SetRange(right_->Min(), right_->Max());
right_->SetRange(left_->Min(), left_->Max());
2020-10-22 23:36:58 +02:00
} else { // Var is true.
2012-07-04 22:05:58 +00:00
if (left_->Bound()) {
range_demon_->inhibit(solver());
2012-09-05 16:42:49 +00:00
solver()->AddConstraint(
solver()->MakeNonEquality(right_, left_->Min()));
2012-07-04 22:05:58 +00:00
} else if (right_->Bound()) {
range_demon_->inhibit(solver());
2012-09-05 16:42:49 +00:00
solver()->AddConstraint(
solver()->MakeNonEquality(left_, right_->Min()));
2012-07-04 22:05:58 +00:00
}
}
}
std::string DebugString() const override {
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
return absl::StrFormat("IsDifferentCt(%s, %s, %s)", left_->DebugString(),
right_->DebugString(), target_var_->DebugString());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
void Accept(ModelVisitor* const visitor) const override {
2012-07-04 22:05:58 +00:00
visitor->BeginVisitConstraint(ModelVisitor::kIsDifferent, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
right_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
target_var_);
visitor->EndVisitConstraint(ModelVisitor::kIsDifferent, this);
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntExpr* const left_;
IntExpr* const right_;
Demon* range_demon_;
2012-07-04 22:05:58 +00:00
};
class IsLessOrEqualCt : public CastConstraint {
2020-10-22 23:36:58 +02:00
public:
2020-10-29 14:25:39 +01:00
IsLessOrEqualCt(Solver* const s, IntExpr* const l, IntExpr* const r,
IntVar* const b)
: CastConstraint(s, b), left_(l), right_(r), demon_(nullptr) {}
2012-07-04 22:05:58 +00:00
~IsLessOrEqualCt() override {}
2012-07-04 22:05:58 +00:00
void Post() override {
2012-07-04 22:05:58 +00:00
demon_ = solver()->MakeConstraintInitialPropagateCallback(this);
left_->WhenRange(demon_);
right_->WhenRange(demon_);
target_var_->WhenBound(demon_);
}
void InitialPropagate() override {
2012-07-04 22:05:58 +00:00
if (target_var_->Bound()) {
if (target_var_->Min() == 0) {
2012-08-15 23:46:59 +00:00
right_->SetMax(left_->Max() - 1);
left_->SetMin(right_->Min() + 1);
2020-10-22 23:36:58 +02:00
} else { // Var is true.
2012-07-04 22:05:58 +00:00
right_->SetMin(left_->Min());
left_->SetMax(right_->Max());
}
} else if (right_->Min() >= left_->Max()) {
demon_->inhibit(solver());
target_var_->SetValue(1);
} else if (right_->Max() < left_->Min()) {
demon_->inhibit(solver());
target_var_->SetValue(0);
}
}
std::string DebugString() const override {
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
return absl::StrFormat("IsLessOrEqualCt(%s, %s, %s)", left_->DebugString(),
right_->DebugString(), target_var_->DebugString());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
void Accept(ModelVisitor* const visitor) const override {
2012-07-04 22:05:58 +00:00
visitor->BeginVisitConstraint(ModelVisitor::kIsLessOrEqual, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
right_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
target_var_);
visitor->EndVisitConstraint(ModelVisitor::kIsLessOrEqual, this);
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntExpr* const left_;
IntExpr* const right_;
Demon* demon_;
2012-07-04 22:05:58 +00:00
};
class IsLessCt : public CastConstraint {
2020-10-22 23:36:58 +02:00
public:
2020-10-29 14:25:39 +01:00
IsLessCt(Solver* const s, IntExpr* const l, IntExpr* const r, IntVar* const b)
: CastConstraint(s, b), left_(l), right_(r), demon_(nullptr) {}
2012-07-04 22:05:58 +00:00
~IsLessCt() override {}
2012-07-04 22:05:58 +00:00
void Post() override {
2012-07-04 22:05:58 +00:00
demon_ = solver()->MakeConstraintInitialPropagateCallback(this);
left_->WhenRange(demon_);
right_->WhenRange(demon_);
target_var_->WhenBound(demon_);
}
void InitialPropagate() override {
2012-07-04 22:05:58 +00:00
if (target_var_->Bound()) {
if (target_var_->Min() == 0) {
2012-08-15 23:17:20 +00:00
right_->SetMax(left_->Max());
left_->SetMin(right_->Min());
2020-10-22 23:36:58 +02:00
} else { // Var is true.
2012-07-04 22:05:58 +00:00
right_->SetMin(left_->Min() + 1);
left_->SetMax(right_->Max() - 1);
}
} else if (right_->Min() > left_->Max()) {
demon_->inhibit(solver());
target_var_->SetValue(1);
} else if (right_->Max() <= left_->Min()) {
demon_->inhibit(solver());
target_var_->SetValue(0);
}
}
std::string DebugString() const override {
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
return absl::StrFormat("IsLessCt(%s, %s, %s)", left_->DebugString(),
right_->DebugString(), target_var_->DebugString());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
void Accept(ModelVisitor* const visitor) const override {
2012-07-04 22:05:58 +00:00
visitor->BeginVisitConstraint(ModelVisitor::kIsLess, this);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
right_);
visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
target_var_);
visitor->EndVisitConstraint(ModelVisitor::kIsLess, this);
}
2020-10-22 23:36:58 +02:00
private:
2020-10-29 14:25:39 +01:00
IntExpr* const left_;
IntExpr* const right_;
Demon* demon_;
2012-07-04 22:05:58 +00:00
};
2020-10-22 23:36:58 +02:00
} // namespace
2010-09-15 12:42:33 +00:00
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeEquality(IntExpr* const l, IntExpr* const r) {
CHECK(l != nullptr) << "left expression nullptr, maybe a bad cast";
CHECK(r != nullptr) << "left expression nullptr, maybe a bad cast";
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, l->solver());
CHECK_EQ(this, r->solver());
2012-07-05 13:27:16 +00:00
if (l->Bound()) {
return MakeEquality(r, l->Min());
} else if (r->Bound()) {
return MakeEquality(l, r->Min());
} else {
return RevAlloc(new RangeEquality(this, l, r));
}
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeLessOrEqual(IntExpr* const l, IntExpr* const r) {
CHECK(l != nullptr) << "left expression nullptr, maybe a bad cast";
CHECK(r != nullptr) << "left expression nullptr, maybe a bad cast";
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, l->solver());
CHECK_EQ(this, r->solver());
2014-05-26 01:23:59 +00:00
if (l == r) {
return MakeTrueConstraint();
} else if (l->Bound()) {
2012-07-05 13:43:02 +00:00
return MakeGreaterOrEqual(r, l->Min());
} else if (r->Bound()) {
return MakeLessOrEqual(l, r->Min());
} else {
return RevAlloc(new RangeLessOrEqual(this, l, r));
}
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeGreaterOrEqual(IntExpr* const l, IntExpr* const r) {
return MakeLessOrEqual(r, l);
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeLess(IntExpr* const l, IntExpr* const r) {
CHECK(l != nullptr) << "left expression nullptr, maybe a bad cast";
CHECK(r != nullptr) << "left expression nullptr, maybe a bad cast";
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, l->solver());
CHECK_EQ(this, r->solver());
2012-07-05 13:43:02 +00:00
if (l->Bound()) {
return MakeGreater(r, l->Min());
} else if (r->Bound()) {
return MakeLess(l, r->Min());
} else {
return RevAlloc(new RangeLess(this, l, r));
}
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeGreater(IntExpr* const l, IntExpr* const r) {
return MakeLess(r, l);
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeNonEquality(IntExpr* const l, IntExpr* const r) {
CHECK(l != nullptr) << "left expression nullptr, maybe a bad cast";
CHECK(r != nullptr) << "left expression nullptr, maybe a bad cast";
2010-09-15 12:42:33 +00:00
CHECK_EQ(this, l->solver());
CHECK_EQ(this, r->solver());
2012-06-29 09:41:24 +00:00
if (l->Bound()) {
return MakeNonEquality(r, l->Min());
} else if (r->Bound()) {
return MakeNonEquality(l, r->Min());
}
return RevAlloc(new DiffVar(this, l->Var(), r->Var()));
2010-09-15 12:42:33 +00:00
}
2020-10-29 14:25:39 +01:00
IntVar* Solver::MakeIsEqualVar(IntExpr* const v1, IntExpr* const v2) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, v1->solver());
CHECK_EQ(this, v2->solver());
if (v1->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsEqualCstVar(v2, v1->Min());
2012-07-04 22:05:58 +00:00
} else if (v2->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsEqualCstVar(v1, v2->Min());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntExpr* cache = model_cache_->FindExprExprExpression(
v1, v2, ModelCache::EXPR_EXPR_IS_EQUAL);
if (cache == nullptr) {
cache = model_cache_->FindExprExprExpression(
v2, v1, ModelCache::EXPR_EXPR_IS_EQUAL);
}
if (cache != nullptr) {
2012-07-04 22:05:58 +00:00
return cache->Var();
} else {
2020-10-29 14:25:39 +01:00
IntVar* boolvar = nullptr;
IntExpr* reverse_cache = model_cache_->FindExprExprExpression(
v1, v2, ModelCache::EXPR_EXPR_IS_NOT_EQUAL);
if (reverse_cache == nullptr) {
reverse_cache = model_cache_->FindExprExprExpression(
v2, v1, ModelCache::EXPR_EXPR_IS_NOT_EQUAL);
2012-07-04 22:05:58 +00:00
}
if (reverse_cache != nullptr) {
boolvar = MakeDifference(1, reverse_cache)->Var();
} else {
std::string name1 = v1->name();
if (name1.empty()) {
name1 = v1->DebugString();
}
std::string name2 = v2->name();
if (name2.empty()) {
name2 = v2->DebugString();
}
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
boolvar =
MakeBoolVar(absl::StrFormat("IsEqualVar(%s, %s)", name1, name2));
AddConstraint(MakeIsEqualCt(v1, v2, boolvar));
model_cache_->InsertExprExprExpression(boolvar, v1, v2,
ModelCache::EXPR_EXPR_IS_EQUAL);
2012-07-04 22:05:58 +00:00
}
return boolvar;
}
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeIsEqualCt(IntExpr* const v1, IntExpr* const v2,
IntVar* b) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, v1->solver());
CHECK_EQ(this, v2->solver());
if (v1->Bound()) {
2012-09-05 16:37:24 +00:00
return MakeIsEqualCstCt(v2, v1->Min(), b);
2012-07-04 22:05:58 +00:00
} else if (v2->Bound()) {
2012-09-05 16:37:24 +00:00
return MakeIsEqualCstCt(v1, v2->Min(), b);
2012-07-04 22:05:58 +00:00
}
if (b->Bound()) {
if (b->Min() == 0) {
2012-09-05 16:37:24 +00:00
return MakeNonEquality(v1, v2);
2012-07-04 22:05:58 +00:00
} else {
2012-09-05 16:37:24 +00:00
return MakeEquality(v1, v2);
2012-07-04 22:05:58 +00:00
}
}
2012-09-05 16:37:24 +00:00
return RevAlloc(new IsEqualCt(this, v1, v2, b));
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntVar* Solver::MakeIsDifferentVar(IntExpr* const v1, IntExpr* const v2) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, v1->solver());
CHECK_EQ(this, v2->solver());
if (v1->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsDifferentCstVar(v2, v1->Min());
2012-07-04 22:05:58 +00:00
} else if (v2->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsDifferentCstVar(v1, v2->Min());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntExpr* cache = model_cache_->FindExprExprExpression(
v1, v2, ModelCache::EXPR_EXPR_IS_NOT_EQUAL);
if (cache == nullptr) {
cache = model_cache_->FindExprExprExpression(
v2, v1, ModelCache::EXPR_EXPR_IS_NOT_EQUAL);
}
2017-04-19 16:20:56 +02:00
if (cache != nullptr) {
2012-07-04 22:05:58 +00:00
return cache->Var();
} else {
2020-10-29 14:25:39 +01:00
IntVar* boolvar = nullptr;
IntExpr* reverse_cache = model_cache_->FindExprExprExpression(
v1, v2, ModelCache::EXPR_EXPR_IS_EQUAL);
if (reverse_cache == nullptr) {
reverse_cache = model_cache_->FindExprExprExpression(
v2, v1, ModelCache::EXPR_EXPR_IS_EQUAL);
2012-07-04 22:05:58 +00:00
}
if (reverse_cache != nullptr) {
boolvar = MakeDifference(1, reverse_cache)->Var();
} else {
std::string name1 = v1->name();
if (name1.empty()) {
name1 = v1->DebugString();
}
std::string name2 = v2->name();
if (name2.empty()) {
name2 = v2->DebugString();
}
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
boolvar =
MakeBoolVar(absl::StrFormat("IsDifferentVar(%s, %s)", name1, name2));
AddConstraint(MakeIsDifferentCt(v1, v2, boolvar));
2012-07-04 22:05:58 +00:00
}
model_cache_->InsertExprExprExpression(boolvar, v1, v2,
ModelCache::EXPR_EXPR_IS_NOT_EQUAL);
2012-07-04 22:05:58 +00:00
return boolvar;
}
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeIsDifferentCt(IntExpr* const v1, IntExpr* const v2,
IntVar* b) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, v1->solver());
CHECK_EQ(this, v2->solver());
if (v1->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsDifferentCstCt(v2, v1->Min(), b);
2012-07-04 22:05:58 +00:00
} else if (v2->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsDifferentCstCt(v1, v2->Min(), b);
2012-07-04 22:05:58 +00:00
}
2012-09-05 16:42:49 +00:00
return RevAlloc(new IsDifferentCt(this, v1, v2, b));
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntVar* Solver::MakeIsLessOrEqualVar(IntExpr* const left,
IntExpr* const right) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, left->solver());
CHECK_EQ(this, right->solver());
if (left->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsGreaterOrEqualCstVar(right, left->Min());
2012-07-04 22:05:58 +00:00
} else if (right->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsLessOrEqualCstVar(left, right->Min());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntExpr* const cache = model_cache_->FindExprExprExpression(
left, right, ModelCache::EXPR_EXPR_IS_LESS_OR_EQUAL);
if (cache != nullptr) {
2012-07-04 22:05:58 +00:00
return cache->Var();
} else {
std::string name1 = left->name();
2012-07-04 22:05:58 +00:00
if (name1.empty()) {
name1 = left->DebugString();
2012-07-04 22:05:58 +00:00
}
std::string name2 = right->name();
2012-07-04 22:05:58 +00:00
if (name2.empty()) {
name2 = right->DebugString();
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntVar* const boolvar =
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
MakeBoolVar(absl::StrFormat("IsLessOrEqual(%s, %s)", name1, name2));
2012-07-04 22:05:58 +00:00
AddConstraint(RevAlloc(new IsLessOrEqualCt(this, left, right, boolvar)));
model_cache_->InsertExprExprExpression(
boolvar, left, right, ModelCache::EXPR_EXPR_IS_LESS_OR_EQUAL);
2012-07-04 22:05:58 +00:00
return boolvar;
}
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeIsLessOrEqualCt(IntExpr* const left,
IntExpr* const right, IntVar* const b) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, left->solver());
CHECK_EQ(this, right->solver());
if (left->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsGreaterOrEqualCstCt(right, left->Min(), b);
2012-07-04 22:05:58 +00:00
} else if (right->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsLessOrEqualCstCt(left, right->Min(), b);
2012-07-04 22:05:58 +00:00
}
2012-09-05 16:42:49 +00:00
return RevAlloc(new IsLessOrEqualCt(this, left, right, b));
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntVar* Solver::MakeIsLessVar(IntExpr* const left, IntExpr* const right) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, left->solver());
CHECK_EQ(this, right->solver());
if (left->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsGreaterCstVar(right, left->Min());
2012-07-04 22:05:58 +00:00
} else if (right->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsLessCstVar(left, right->Min());
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntExpr* const cache = model_cache_->FindExprExprExpression(
left, right, ModelCache::EXPR_EXPR_IS_LESS);
if (cache != nullptr) {
2012-07-04 22:05:58 +00:00
return cache->Var();
} else {
std::string name1 = left->name();
2012-07-04 22:05:58 +00:00
if (name1.empty()) {
name1 = left->DebugString();
2012-07-04 22:05:58 +00:00
}
std::string name2 = right->name();
2012-07-04 22:05:58 +00:00
if (name2.empty()) {
name2 = right->DebugString();
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntVar* const boolvar =
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
MakeBoolVar(absl::StrFormat("IsLessOrEqual(%s, %s)", name1, name2));
2012-07-04 22:05:58 +00:00
AddConstraint(RevAlloc(new IsLessCt(this, left, right, boolvar)));
model_cache_->InsertExprExprExpression(boolvar, left, right,
ModelCache::EXPR_EXPR_IS_LESS);
2012-07-04 22:05:58 +00:00
return boolvar;
}
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeIsLessCt(IntExpr* const left, IntExpr* const right,
IntVar* const b) {
2012-07-04 22:05:58 +00:00
CHECK_EQ(this, left->solver());
CHECK_EQ(this, right->solver());
if (left->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsGreaterCstCt(right, left->Min(), b);
2012-07-04 22:05:58 +00:00
} else if (right->Bound()) {
2012-09-05 16:42:49 +00:00
return MakeIsLessCstCt(left, right->Min(), b);
2012-07-04 22:05:58 +00:00
}
2012-09-05 16:42:49 +00:00
return RevAlloc(new IsLessCt(this, left, right, b));
2012-07-04 22:05:58 +00:00
}
2020-10-29 14:25:39 +01:00
IntVar* Solver::MakeIsGreaterOrEqualVar(IntExpr* const left,
IntExpr* const right) {
2012-07-04 22:05:58 +00:00
return MakeIsLessOrEqualVar(right, left);
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeIsGreaterOrEqualCt(IntExpr* const left,
IntExpr* const right,
IntVar* const b) {
2012-07-04 22:05:58 +00:00
return MakeIsLessOrEqualCt(right, left, b);
}
2020-10-29 14:25:39 +01:00
IntVar* Solver::MakeIsGreaterVar(IntExpr* const left, IntExpr* const right) {
2012-07-04 22:05:58 +00:00
return MakeIsLessVar(right, left);
}
2020-10-29 14:25:39 +01:00
Constraint* Solver::MakeIsGreaterCt(IntExpr* const left, IntExpr* const right,
IntVar* const b) {
2012-07-04 22:05:58 +00:00
return MakeIsLessCt(right, left, b);
}
2020-10-22 23:36:58 +02:00
} // namespace operations_research