114 auto it = disjunctive_precedences_.find({a,
b});
115 if (it != disjunctive_precedences_.end())
return it->second.Index();
117 std::vector<Literal> enforcement_literals;
119 enforcement_literals.push_back(a.
is_present.value());
121 if (
b.is_present.has_value()) {
122 enforcement_literals.push_back(
b.is_present.value());
125 auto remove_fixed_at_root_level =
126 [assignment = &assignment_,
127 sat_solver_ = sat_solver_](std::vector<Literal>& literals) {
129 for (
const Literal l : literals) {
130 if (assignment->LiteralIsAssigned(l)) {
131 const bool is_fixed =
132 sat_solver_->LiteralTrail().Info(l.Variable()).level == 0;
135 if (is_fixed && assignment->LiteralIsTrue(l))
continue;
136 if (is_fixed && assignment->LiteralIsFalse(l))
return false;
138 literals[new_size++] = l;
140 literals.resize(new_size);
144 if (!remove_fixed_at_root_level(enforcement_literals))
return kNoLiteralIndex;
148 const auto [expr_b_before_a, ub_b_before_a] =
155 const auto [expr_a_before_b, ub_a_before_b] =
161 if (enforcement_literals.empty() &&
163 a_before_b_root_status == b_before_a_root_status) {
166 sat_solver_->NotifyThatModelIsUnsat();
171 if (!enforcement_literals.empty() ||
178 const RelationStatus b_before_a_status = linear2_bounds_->GetStatus(
186 if (!enforcement_literals.empty() ||
193 const RelationStatus a_before_b_status = linear2_bounds_->GetStatus(
208 if (enforcement_literals.empty()) {
219 reified_precedences_->AddBoundEncodingIfNonTrivial(
220 Literal(a_before_b_index).Negated(), expr_b_before_a, ub_b_before_a);
226 reified_precedences_->AddBoundEncodingIfNonTrivial(
227 Literal(a_before_b_index), expr_a_before_b, ub_a_before_b);
230 reified_precedences_->AddBoundEncodingIfNonTrivial(
231 Literal(a_before_b_index).Negated(), expr_b_before_a, ub_b_before_a);
234 implications_->AddImplication(
Literal(a_before_b_index),
235 Literal(b_before_a_index).Negated());
236 implications_->AddImplication(
Literal(a_before_b_index).Negated(),
240 a_before_b =
Literal(a_before_b_index);
242 const BooleanVariable boolean_var = sat_solver_->NewBooleanVariable();
243 a_before_b =
Literal(boolean_var,
true);
246 disjunctive_precedences_.insert({{a,
b}, a_before_b});
247 disjunctive_precedences_.insert({{
b, a}, a_before_b.
Negated()});
249 enforcement_literals.push_back(a_before_b);
251 enforcement_literals.pop_back();
253 enforcement_literals.push_back(a_before_b.
Negated());
255 enforcement_literals.pop_back();
259 if (!remove_fixed_at_root_level(enforcement_literals))
return kNoLiteralIndex;
263 for (
const Literal l : enforcement_literals) {
264 implications_->AddBinaryClause(l, a_before_b);
273 auto reified_bound = reified_precedences_->GetEncodedBound(expr, ub);
274 if (std::holds_alternative<ReifiedLinear2Bounds::ReifiedBoundType>(
276 const auto bound_type =
277 std::get<ReifiedLinear2Bounds::ReifiedBoundType>(reified_bound);
285 if (std::holds_alternative<Literal>(reified_bound)) {
290 if (std::holds_alternative<IntegerLiteral>(reified_bound)) {
291 if (integer_encoder_->GetAssociatedLiteral(
298 integer_encoder_->GetOrCreateAssociatedLiteral(
299 std::get<IntegerLiteral>(reified_bound));
304 const BooleanVariable boolean_var = sat_solver_->NewBooleanVariable();
306 reified_precedences_->AddBoundEncodingIfNonTrivial(x_before_y, expr, ub);
318 auto reified_bound = reified_precedences_->GetEncodedBound(expr, ub);
319 if (std::holds_alternative<IntegerLiteral>(reified_bound)) {
320 return integer_encoder_->GetAssociatedLiteral(
321 std::get<IntegerLiteral>(reified_bound));
323 if (std::holds_alternative<Literal>(reified_bound)) {
324 return std::get<Literal>(reified_bound).Index();
326 if (std::holds_alternative<ReifiedLinear2Bounds::ReifiedBoundType>(
328 const auto bound_type =
329 std::get<ReifiedLinear2Bounds::ReifiedBoundType>(reified_bound);
331 return integer_encoder_->GetTrueLiteral().Index();
334 return integer_encoder_->GetTrueLiteral().NegatedIndex();
358 std::vector<Literal> enforcement_literals,
359 const std::vector<IntervalVariable>& variables,
360 bool register_as_disjunctive_helper) {
361 std::sort(enforcement_literals.begin(), enforcement_literals.end());
362 const auto it = helper_repository_.find({enforcement_literals, variables});
363 if (it != helper_repository_.end())
return it->second;
364 std::vector<AffineExpression> starts;
365 std::vector<AffineExpression> ends;
366 std::vector<AffineExpression> sizes;
367 std::vector<LiteralIndex> reason_for_presence;
369 const int num_variables = variables.size();
370 starts.reserve(num_variables);
371 ends.reserve(num_variables);
372 sizes.reserve(num_variables);
373 reason_for_presence.reserve(num_variables);
375 for (
const IntervalVariable
i : variables) {
381 sizes.push_back(
Size(
i));
382 starts.push_back(
Start(
i));
383 ends.push_back(
End(
i));
387 std::move(starts), std::move(ends), std::move(sizes),
388 std::move(reason_for_presence), model_);
390 enforcement_literals);
391 helper_repository_[{enforcement_literals, variables}] = helper;
392 model_->TakeOwnership(helper);
393 if (register_as_disjunctive_helper) {
394 disjunctive_helpers_.push_back(helper);
400 std::vector<Literal> enforcement_literals,
401 const std::vector<IntervalVariable>& x_variables,
402 const std::vector<IntervalVariable>& y_variables) {
403 std::sort(enforcement_literals.begin(), enforcement_literals.end());
404 const auto it = no_overlap_2d_helper_repository_.find(
405 {enforcement_literals, x_variables, y_variables});
406 if (it != no_overlap_2d_helper_repository_.end())
return it->second;
408 std::vector<AffineExpression> x_starts;
409 std::vector<AffineExpression> x_ends;
410 std::vector<AffineExpression> x_sizes;
411 std::vector<LiteralIndex> x_reason_for_presence;
413 for (
const IntervalVariable
i : x_variables) {
419 x_sizes.push_back(
Size(
i));
420 x_starts.push_back(
Start(
i));
421 x_ends.push_back(
End(
i));
423 std::vector<AffineExpression> y_starts;
424 std::vector<AffineExpression> y_ends;
425 std::vector<AffineExpression> y_sizes;
426 std::vector<LiteralIndex> y_reason_for_presence;
428 for (
const IntervalVariable
i : y_variables) {
434 y_sizes.push_back(
Size(
i));
435 y_starts.push_back(
Start(
i));
436 y_ends.push_back(
End(
i));
439 std::move(x_starts), std::move(x_ends), std::move(x_sizes),
440 std::move(x_reason_for_presence), std::move(y_starts), std::move(y_ends),
441 std::move(y_sizes), std::move(y_reason_for_presence), model_);
443 enforcement_literals);
444 no_overlap_2d_helper_repository_[{enforcement_literals, x_variables,
445 y_variables}] = helper;
446 model_->TakeOwnership(helper);