53 LiteralIndex is_present,
54 bool add_linear_relation) {
56 const IntervalVariable
i(starts_.size());
57 starts_.push_back(start);
59 sizes_.push_back(size);
60 is_present_.push_back(is_present);
62 std::vector<Literal> enforcement_literals;
64 enforcement_literals.push_back(
Literal(is_present));
67 if (add_linear_relation) {
98 auto it = disjunctive_precedences_.find({a,
b});
99 if (it != disjunctive_precedences_.end())
return it->second.Index();
101 std::vector<Literal> enforcement_literals;
103 enforcement_literals.push_back(a.
is_present.value());
105 if (
b.is_present.has_value()) {
106 enforcement_literals.push_back(
b.is_present.value());
109 auto remove_fixed = [assignment =
110 &assignment_](std::vector<Literal>& literals) {
112 for (
const Literal l : literals) {
115 if (assignment->LiteralIsTrue(l))
continue;
116 if (assignment->LiteralIsFalse(l))
return false;
117 literals[new_size++] = l;
119 literals.resize(new_size);
123 if (sat_solver_->CurrentDecisionLevel() == 0) {
129 if (integer_trail_->UpperBound(a.
start) < integer_trail_->LowerBound(
b.end)) {
130 if (sat_solver_->CurrentDecisionLevel() == 0) {
138 if (integer_trail_->UpperBound(
b.start) < integer_trail_->LowerBound(a.
end)) {
139 if (sat_solver_->CurrentDecisionLevel() == 0) {
147 const BooleanVariable boolean_var = sat_solver_->NewBooleanVariable();
149 disjunctive_precedences_.insert({{a,
b}, a_before_b});
150 disjunctive_precedences_.insert({{
b, a}, a_before_b.
Negated()});
153 if (enforcement_literals.empty()) {
155 precedences_.insert({{a.
end,
b.start}, a_before_b});
156 precedences_.insert({{
b.end, a.
start}, a_before_b.
Negated()});
159 enforcement_literals.push_back(a_before_b);
161 enforcement_literals.pop_back();
163 enforcement_literals.push_back(a_before_b.
Negated());
165 enforcement_literals.pop_back();
169 if (sat_solver_->CurrentDecisionLevel() == 0) {
175 for (
const Literal l : enforcement_literals) {
176 implications_->AddBinaryClause(l, a_before_b);
184 if (precedences_.contains({x, y}))
return false;
188 if (integer_trail_->UpperBound(x) <= integer_trail_->LowerBound(y)) {
191 if (integer_trail_->LowerBound(x) > integer_trail_->UpperBound(y)) {
196 const BooleanVariable boolean_var = sat_solver_->NewBooleanVariable();
200 precedences_.insert({{x, y}, x_before_y});
220 const std::vector<IntervalVariable>& variables,
221 bool register_as_disjunctive_helper) {
222 const auto it = helper_repository_.find(variables);
223 if (it != helper_repository_.end())
return it->second;
224 std::vector<AffineExpression> starts;
225 std::vector<AffineExpression> ends;
226 std::vector<AffineExpression> sizes;
227 std::vector<LiteralIndex> reason_for_presence;
229 const int num_variables = variables.size();
230 starts.reserve(num_variables);
231 ends.reserve(num_variables);
232 sizes.reserve(num_variables);
233 reason_for_presence.reserve(num_variables);
235 for (
const IntervalVariable
i : variables) {
241 sizes.push_back(
Size(
i));
242 starts.push_back(
Start(
i));
243 ends.push_back(
End(
i));
247 std::move(starts), std::move(ends), std::move(sizes),
248 std::move(reason_for_presence), model_);
250 helper_repository_[variables] = helper;
251 model_->TakeOwnership(helper);
252 if (register_as_disjunctive_helper) {
253 disjunctive_helpers_.push_back(helper);
259 const std::vector<IntervalVariable>& x_variables,
260 const std::vector<IntervalVariable>& y_variables) {
262 no_overlap_2d_helper_repository_.find({x_variables, y_variables});
263 if (it != no_overlap_2d_helper_repository_.end())
return it->second;
265 std::vector<AffineExpression> x_starts;
266 std::vector<AffineExpression> x_ends;
267 std::vector<AffineExpression> x_sizes;
268 std::vector<LiteralIndex> x_reason_for_presence;
270 for (
const IntervalVariable
i : x_variables) {
276 x_sizes.push_back(
Size(
i));
277 x_starts.push_back(
Start(
i));
278 x_ends.push_back(
End(
i));
280 std::vector<AffineExpression> y_starts;
281 std::vector<AffineExpression> y_ends;
282 std::vector<AffineExpression> y_sizes;
283 std::vector<LiteralIndex> y_reason_for_presence;
285 for (
const IntervalVariable
i : y_variables) {
291 y_sizes.push_back(
Size(
i));
292 y_starts.push_back(
Start(
i));
293 y_ends.push_back(
End(
i));
296 std::move(x_starts), std::move(x_ends), std::move(x_sizes),
297 std::move(x_reason_for_presence), std::move(y_starts), std::move(y_ends),
298 std::move(y_sizes), std::move(y_reason_for_presence), model_);
300 no_overlap_2d_helper_repository_[{x_variables, y_variables}] = helper;
301 model_->TakeOwnership(helper);
307 absl::Span<const AffineExpression> demands) {
308 const std::pair<SchedulingConstraintHelper*, std::vector<AffineExpression>>
310 std::vector<AffineExpression>(demands.begin(), demands.end())};
311 const auto it = demand_helper_repository_.find(key);
312 if (it != demand_helper_repository_.end())
return it->second;
316 model_->TakeOwnership(demand_helper);
317 demand_helper_repository_[key] = demand_helper;
318 return demand_helper;