310 std::vector<Literal>* conflict,
311 std::vector<Literal>* reason_used_to_infer_the_conflict,
312 std::vector<SatClause*>* subsumed_clauses) {
313 const int old_conflict_size = conflict->size();
314 if (old_conflict_size > 0) {
315 comparison_old_sum_of_literals_ += old_conflict_size;
316 comparison_old_num_subsumed_ += subsumed_clauses->size();
320 reason_used_to_infer_the_conflict->clear();
321 subsumed_clauses->clear();
324 const IntegerReason& starting_conflict = integer_trail_->IntegerConflict();
325 if (starting_conflict.
empty())
return;
329 const int num_i_vars = integer_trail_->NumIntegerVariables().value();
331 int_data_.resize(num_i_vars);
333 tmp_bool_index_seen_.ClearAndResize(trail_->Index() + 1);
337 AddToQueue(
GlobalTrailIndex{trail_->CurrentDecisionLevel(), trail_->Index()},
338 starting_conflict, subsumed_clauses);
339 std::make_heap(tmp_queue_.begin(), tmp_queue_.end());
343 int64_t work_done = 0;
344 bool uip_found =
false;
345 while (!tmp_queue_.empty()) {
353 std::pop_heap(tmp_queue_.begin(), tmp_queue_.end());
354 tmp_queue_.pop_back();
356 const bool is_only_one_left_at_top_level =
357 tmp_queue_.empty() || tmp_queue_.front().level < top_index.
level;
361 integer_trail_->IntegerLiteralAtIndex(top_index.
integer_index);
362 IntegerVariableData& data = int_data_[i_lit.
var];
363 const IntegerValue bound_to_explain = data.bound;
364 CHECK(data.in_queue);
366 CHECK_LE(data.bound, i_lit.
bound);
369 if (data.bound <= tmp_var_to_settled_lb_[i_lit.
var] ||
370 data.bound <= integer_trail_->LevelZeroLowerBound(i_lit.
var) ||
371 data.int_index_in_queue < num_i_vars) {
372 data.in_queue =
false;
377 const int previous_index =
379 if (data.bound < i_lit.
bound) {
380 if (previous_index >= 0) {
382 integer_trail_->IntegerLiteralAtIndex(previous_index);
383 if (data.bound <= previous_i_lit.
bound) {
386 data.int_index_in_queue = previous_index;
387 tmp_queue_.push_back(
388 integer_trail_->GlobalIndexAt(data.int_index_in_queue));
391 integer_trail_->IntegerLiteralAtIndex(data.int_index_in_queue)
393 std::push_heap(tmp_queue_.begin(), tmp_queue_.end());
399 data.int_index_in_queue = previous_index;
400 data.in_queue =
false;
408 data.int_index_in_queue = previous_index;
409 data.in_queue =
false;
414 if (is_only_one_left_at_top_level || uip_found) {
417 IntegerValue associated_bound;
418 const LiteralIndex lit_index =
419 integer_encoder_->SearchForLiteralAtOrAfter(
423 associated_bound >= bound_to_explain &&
424 associated_bound <= i_lit.
bound) {
427 IntegerValue test_bound;
428 const LiteralIndex test_index =
429 integer_encoder_->SearchForLiteralAtOrBefore(i_lit, &test_bound);
431 CHECK_LE(associated_bound, test_bound);
435 const auto& info = trail_->Info(lit.
Variable());
436 if (trail_->Assignment().LiteralIsTrue(lit) &&
437 info.level == top_index.
level) {
440 if (tmp_bool_index_seen_[info.trail_index]) {
442 ++num_associated_literal_use_;
446 tmp_bool_index_seen_.Set(info.trail_index);
449 subsumed_clauses->clear();
453 ++num_associated_literal_use_;
455 ++num_associated_literal_fail_;
457 }
else if (params_.create_1uip_boolean_during_icr() &&
458 top_index.
level > sat_solver_->AssumptionLevel() &&
459 is_only_one_left_at_top_level && !uip_found) {
465 integer_encoder_->GetOrCreateAssociatedLiteral(
470 if (!trail_->Assignment().LiteralIsAssigned(new_lit)) {
472 trail_->EnqueueSearchDecision(new_lit);
476 CHECK(trail_->Assignment().LiteralIsTrue(new_lit))
477 << associated_bound <<
" " << bound_to_explain <<
" "
478 << i_lit.
bound <<
" " << lit_index <<
" new " << new_lit;
480 const auto& info = trail_->Info(new_lit.
Variable());
481 CHECK_GE(info.level, top_index.
level);
482 CHECK_EQ((*trail_)[info.trail_index], new_lit);
485 tmp_bool_index_seen_.Set(info.trail_index);
486 subsumed_clauses->clear();
490 ++num_created_1uip_bool_;
499 if (top_index.
level <= sat_solver_->AssumptionLevel()) {
504 if (is_only_one_left_at_top_level) {
505 if (top_index.
level < trail_->CurrentDecisionLevel()) {
506 ++num_conflicts_at_wrong_level_;
515 if (params_.binary_minimization_algorithm() !=
517 if (conflict->empty()) {
522 implications_->GetAllImpliedLiterals(literal)) {
524 integer_encoder_->GetIntegerLiterals(l)) {
530 tmp_var_to_settled_lb_[i_lit.var] =
531 std::max(tmp_var_to_settled_lb_[i_lit.var], i_lit.bound);
532 ++num_associated_integer_for_literals_in_conflict_;
539 if (implications_->LiteralIsImplied(literal)) {
540 ++num_binary_minimization_;
548 conflict->push_back(literal.
Negated());
554 integer_encoder_->GetIntegerLiterals(literal)) {
558 tmp_var_to_settled_lb_[i_lit.var] =
559 std::max(tmp_var_to_settled_lb_[i_lit.var], i_lit.bound);
560 ++num_associated_integer_for_literals_in_conflict_;
567 CHECK_NE(trail_->Info(literal.
Variable()).type,
569 << DebugGlobalIndex(top_index)
570 <<
" before: " << DebugGlobalIndex(tmp_queue_.front());
571 reason_used_to_infer_the_conflict->push_back(literal);
575 integer_trail_->IntegerLiteralAtIndex(top_index.
integer_index);
576 if (tmp_var_to_settled_lb_[i_lit.
var] >= i_lit.
bound)
continue;
579 std::optional<IntegerValue> needed_bound;
581 const IntegerVariable var =
582 integer_trail_->IntegerLiteralAtIndex(top_index.
integer_index).var;
583 needed_bound = RelaxBoundIfHoles(var, int_data_[var].bound);
590 const int old_size = tmp_queue_.size();
591 AddToQueue(top_index,
592 integer_trail_->GetIntegerReason(top_index, needed_bound),
594 for (
int i = old_size + 1;
i <= tmp_queue_.size(); ++
i) {
595 std::push_heap(tmp_queue_.begin(), tmp_queue_.begin() +
i);
604 if (trail_->AssignmentType(literal.
Variable()) ==
605 clauses_propagator_->PropagatorId()) {
608 subsumed_clauses->push_back(clause);
613 num_conflict_literals_ += conflict->size();
614 FilterSubsumedClauses(conflict, subsumed_clauses);
616 if (old_conflict_size > 0) {
617 if (conflict->size() < old_conflict_size) {
618 ++comparison_num_win_;
619 }
else if (conflict->size() > old_conflict_size) {
620 ++comparison_num_loose_;
622 ++comparison_num_same_;