25 IntegerVariable target,
26 const std::vector<IntegerVariable>& vars,
27 const std::vector<Literal>& selectors,
29 : enforcement_literal_(enforcement_literal),
32 selectors_(selectors),
41 const
Literal enforcement_literal_;
42 const IntegerVariable target_;
43 const std::vector<IntegerVariable> vars_;
44 const std::vector<
Literal> selectors_;
50 std::vector<
Literal> literal_reason_;
60 const auto add_var_non_selection_to_reason = [&](
int i) {
62 literal_reason_.push_back(selectors_[i]);
64 const auto add_var_selection_to_reason = [&](
int i) {
66 literal_reason_.push_back(selectors_[i].Negated());
76 enforcement_lit.
Index()) {
83 if (i_lit.bound > integer_trail_->
UpperBound(i_lit.var)) {
84 integer_reason_.push_back(
88 literal_reason_, integer_reason_);
94 if (!integer_trail_->
Enqueue(i_lit, literal_reason_, integer_reason_)) {
102 const int num_vars =
vars_.size();
103 const IntegerValue target_min = integer_trail_->
LowerBound(target_);
104 const IntegerValue target_max = integer_trail_->
UpperBound(target_);
111 int num_possible_vars = 0;
112 int num_selected_vars = 0;
113 int min_of_selected_maxes_index = -1;
114 int first_selected = -1;
115 for (
int i = 0; i < num_vars; ++i) {
118 const IntegerVariable
var =
vars_[i];
119 const IntegerValue var_min = integer_trail_->
LowerBound(
var);
120 const IntegerValue var_max = integer_trail_->
UpperBound(
var);
122 min_of_mins =
std::min(min_of_mins, var_min);
127 if (var_max < min_of_selected_maxes) {
128 min_of_selected_maxes = var_max;
129 min_of_selected_maxes_index = i;
131 if (first_selected == -1) {
137 max_of_possible_maxes =
std::max(max_of_possible_maxes, var_max);
141 if (min_of_mins > target_min) {
142 literal_reason_.clear();
143 integer_reason_.clear();
144 for (
int i = 0; i < num_vars; ++i) {
146 add_var_non_selection_to_reason(i);
148 integer_reason_.push_back(
152 if (!push_bound(enforcement_literal_,
158 if (num_selected_vars > 0 && min_of_selected_maxes < target_max) {
160 DCHECK_NE(min_of_selected_maxes_index, -1);
162 literal_reason_.clear();
163 integer_reason_.clear();
164 add_var_selection_to_reason(min_of_selected_maxes_index);
166 vars_[min_of_selected_maxes_index], min_of_selected_maxes));
169 literal_reason_, integer_reason_)) {
175 if (num_possible_vars > 0 && num_selected_vars == 0) {
176 if (target_max > max_of_possible_maxes) {
177 literal_reason_.clear();
178 integer_reason_.clear();
180 for (
int i = 0; i < num_vars; ++i) {
182 add_var_non_selection_to_reason(i);
184 integer_reason_.push_back(
189 enforcement_literal_,
197 if (!assignment.
LiteralIsTrue(enforcement_literal_))
return true;
204 if (num_possible_vars > 0) {
205 DCHECK_GT(num_possible_vars + num_selected_vars, 1);
208 if (num_selected_vars != 1)
return true;
212 const IntegerVariable unique_selected_var =
vars_[first_selected];
215 if (target_min > integer_trail_->
LowerBound(unique_selected_var)) {
216 literal_reason_.clear();
217 integer_reason_.clear();
218 for (
int i = 0; i < num_vars; ++i) {
219 if (i != first_selected) {
220 add_var_non_selection_to_reason(i);
222 add_var_selection_to_reason(i);
225 integer_reason_.push_back(
229 literal_reason_, integer_reason_)) {
234 if (target_max < integer_trail_->
UpperBound(unique_selected_var)) {
235 literal_reason_.clear();
236 integer_reason_.clear();
237 for (
int i = 0; i < num_vars; ++i) {
238 if (i != first_selected) {
239 add_var_non_selection_to_reason(i);
241 add_var_selection_to_reason(i);
244 integer_reason_.push_back(
248 literal_reason_, integer_reason_)) {
257 const int id = watcher->
Register(
this);
258 for (
int t = 0; t < vars_.size(); ++t) {
270 Literal enforcement_literal, IntegerVariable target,
271 const std::vector<IntegerVariable>& vars,
272 const std::vector<Literal>& selectors) {
273 CHECK_EQ(vars.size(), selectors.size());
277 for (
int i = 0; i < vars.size(); ++i) {
278 std::vector<Literal> conditions = {enforcement_literal};
279 conditions.push_back(selectors[i]);
285 enforcement_literal, target, vars, selectors,
model);
287 model->TakeOwnership(constraint);
292 Literal enforcement_literal, IntegerVariable target,
293 const std::vector<IntegerVariable>& vars,
294 const std::vector<Literal>& selectors) {
295 CHECK_EQ(vars.size(), selectors.size());
297 std::vector<IntegerVariable> negations;
298 for (
const IntegerVariable
var : vars) {
302 enforcement_literal,
NegationOf(target), negations, selectors));
307 IntervalVariable span,
const std::vector<IntervalVariable>& intervals) {
314 if (target_helper.IsAbsent(0)) {
315 for (
int t = 0; t < task_helper.NumTasks(); ++t) {
316 if (task_helper.IsOptional(t)) {
318 target_helper.PresenceLiteral(0).Negated(),
319 task_helper.PresenceLiteral(t));
320 }
else if (task_helper.IsPresent(t)) {
330 std::vector<Literal> presence_literals;
331 std::vector<IntegerVariable> starts;
332 std::vector<IntegerVariable> ends;
333 std::vector<Literal> clause;
334 bool at_least_one_interval_is_present =
false;
338 for (
int t = 0; t < task_helper.NumTasks(); ++t) {
339 if (task_helper.IsAbsent(t))
continue;
341 if (task_helper.IsOptional(t)) {
342 const Literal task_lit = task_helper.PresenceLiteral(t);
343 presence_literals.push_back(task_lit);
344 clause.push_back(task_lit);
346 if (target_helper.IsOptional(0)) {
349 target_helper.PresenceLiteral(0));
353 presence_literals.push_back(true_literal);
354 at_least_one_interval_is_present =
true;
356 starts.push_back(task_helper.StartVars()[t]);
357 ends.push_back(task_helper.EndVars()[t]);
360 if (!at_least_one_interval_is_present) {
362 if (target_helper.IsOptional(0)) {
363 clause.push_back(target_helper.PresenceLiteral(0).Negated());
369 const Literal enforcement_literal =
370 target_helper.IsOptional(0)
371 ? target_helper.PresenceLiteral(0)
374 target_helper.StartVars().front(),
375 starts, presence_literals));
377 target_helper.EndVars().front(),
378 ends, presence_literals));