19#include "absl/types/span.h"
30 int unassigned_index = -1;
31 for (
int i = 0;
i < literals_.size(); ++
i) {
39 if (unassigned_index != -1)
return true;
45 if (unassigned_index != -1) {
46 literal_reason_.clear();
47 for (
int i = 0;
i < literals_.size(); ++
i) {
48 if (
i == unassigned_index)
continue;
50 literal_reason_.push_back(
53 const Literal u = literals_[unassigned_index];
60 if (sum == value_)
return true;
65 for (
int i = 0;
i < literals_.size(); ++
i) {
74 const int id = watcher->
Register(
this);
75 for (
const Literal& l : literals_) {
82 IntegerVariable target_var,
const absl::Span<const AffineExpression> exprs,
83 const absl::Span<const Literal> selectors,
84 const absl::Span<const Literal> enforcements,
Model*
model)
85 : target_var_(target_var),
86 enforcements_(enforcements.begin(), enforcements.
end()),
87 selectors_(selectors.begin(), selectors.
end()),
88 exprs_(exprs.begin(), exprs.
end()),
93 int id, IntegerValue propagation_slack, IntegerVariable ,
94 int , std::vector<Literal>* literals_reason,
95 std::vector<int>* trail_indices_reason) {
96 literals_reason->clear();
97 trail_indices_reason->clear();
99 const int first_non_false = id;
100 const IntegerValue target_min = propagation_slack;
102 for (
const Literal l : enforcements_) {
103 literals_reason->push_back(l.Negated());
105 for (
int i = 0;
i < first_non_false; ++
i) {
114 literals_reason->push_back(selectors_[
i]);
117 absl::MakeSpan(exprs_).subspan(first_non_false), target_min,
118 trail_indices_reason);
124 for (
const Literal l : enforcements_) {
132 const IntegerValue current_min = integer_trail_->
LowerBound(target_var_);
135 int first_non_false = 0;
136 const int size = exprs_.size();
137 for (
int i = 0;
i <
size; ++
i) {
142 if (
i != first_non_false) {
143 std::swap(selectors_[
i], selectors_[first_non_false]);
144 std::swap(exprs_[
i], exprs_[first_non_false]);
151 if (
min < target_min) {
155 if (target_min <= current_min)
return true;
168 first_non_false, target_min,
this);
173 const int id = watcher->
Register(
this);
177 if (!e.IsConstant()) {
bool LiteralIsFalse(Literal literal) const
bool LiteralIsTrue(Literal literal) const
void RegisterWith(GenericLiteralWatcher *watcher)
void WatchLiteral(Literal l, int id, int watch_index=-1)
void WatchLowerBound(IntegerVariable var, int id, int watch_index=-1)
int Register(PropagatorInterface *propagator)
Registers a propagator and returns its unique ids.
void Explain(int id, IntegerValue propagation_slack, IntegerVariable var_to_explain, int trail_index, std::vector< Literal > *literals_reason, std::vector< int > *trail_indices_reason) final
For LazyReasonInterface.
void RegisterWith(GenericLiteralWatcher *watcher)
GreaterThanAtLeastOneOfPropagator(IntegerVariable target_var, absl::Span< const AffineExpression > exprs, absl::Span< const Literal > selectors, absl::Span< const Literal > enforcements, Model *model)
IntegerValue LowerBound(IntegerVariable i) const
Returns the current lower/upper bound of the given integer variable.
void AddAllGreaterThanConstantReason(absl::Span< AffineExpression > exprs, IntegerValue target_min, std::vector< int > *indices) const
ABSL_MUST_USE_RESULT bool EnqueueWithLazyReason(IntegerLiteral i_lit, int id, IntegerValue propagation_slack, LazyReasonInterface *explainer)
Lazy reason API.
void EnqueueLiteral(Literal literal, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason)
IntegerValue LevelZeroLowerBound(IntegerVariable var) const
Returns globally valid lower/upper bound on the given integer variable.
std::vector< Literal > * MutableConflict()
const VariablesAssignment & Assignment() const
bool LiteralIsFalse(Literal literal) const
bool LiteralIsTrue(Literal literal) const
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
In SWIG mode, we don't want anything besides these top-level includes.
std::optional< int64_t > end
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)