19 #include "absl/container/inlined_vector.h" 32 clauses.emplace_back(clause.begin(), clause.end());
33 for (
int i = 0; i < clause.size(); ++i) {
43 #define RETURN_IF_FALSE(f) \ 44 if (!(f)) return false; 54 double probing_time = 0.0;
86 !implication_graph_->
IsDag()) {
92 !implication_graph_->
IsDag()) {
99 blocked_clause_simplifier_->
DoOneRound(log_round_info);
105 const double time_left =
107 if (time_left <= 0)
break;
109 probing_options.
log_info = log_round_info;
117 !implication_graph_->
IsDag()) {
129 <<
" num_fixed: " << trail_->
Index()
137 <<
" non-probing time: " << (
wall_timer.
Get() - probing_time);
149 double probing_time = 0.0;
153 if (total_dtime_ > 0.1 * start_dtime)
return true;
169 probing_options.
log_info = log_round_info;
190 blocked_clause_simplifier_->
DoOneRound(log_round_info);
197 <<
" num_fixed: " << trail_->
Index()
204 <<
" non-probing time: " << (
wall_timer.
Get() - probing_time);
210 #undef RETURN_IF_FALSE 213 const int64_t new_num_fixed_variables = trail_->
Index();
214 return last_num_fixed_variables_ < new_num_fixed_variables;
218 const int64_t new_num_redundant_literals =
220 return last_num_redundant_literals_ < new_num_redundant_literals;
235 if (!implication_graph_->
IsDag()) {
241 if (use_transitive_reduction) {
268 const int64_t new_num_redundant_literals =
270 const int64_t new_num_fixed_variables = trail_->
Index();
271 if (last_num_redundant_literals_ == new_num_redundant_literals &&
272 last_num_fixed_variables_ == new_num_fixed_variables) {
275 last_num_fixed_variables_ = new_num_fixed_variables;
276 last_num_redundant_literals_ = new_num_redundant_literals;
282 int64_t num_removed_literals = 0;
283 int64_t num_inspected_literals = 0;
287 std::vector<Literal> new_clause;
290 const int num_literals(sat_solver_->
NumVariables() * 2);
296 bool removed =
false;
297 bool need_rewrite =
false;
300 for (
const Literal l : clause->AsSpan()) {
307 num_removed_literals += clause->size();
317 num_inspected_literals += clause->size();
318 if (removed || !need_rewrite)
continue;
319 num_inspected_literals += clause->size();
323 for (
const Literal l : clause->AsSpan()) {
330 num_removed_literals += clause->size();
334 marked[r.
Index()] =
true;
335 new_clause.push_back(r);
339 for (
const Literal l : new_clause) marked[l.Index()] =
false;
340 if (removed)
continue;
342 num_removed_literals += clause->size() - new_clause.size();
349 const double dtime = static_cast<double>(num_inspected_literals) * 1e-8;
351 LOG_IF(
INFO, log_info) <<
"Cleanup. num_removed_literals: " 352 << num_removed_literals <<
" dtime: " << dtime
366 int64_t num_subsumed_clauses = 0;
367 int64_t num_removed_literals = 0;
368 int64_t num_inspected_signatures = 0;
369 int64_t num_inspected_literals = 0;
373 std::vector<Literal> new_clause;
385 std::vector<SatClause*> clauses =
387 std::sort(clauses.begin(), clauses.end(),
391 const LiteralIndex num_literals(sat_solver_->
NumVariables() * 2);
397 num_literals.value());
400 std::vector<uint64_t> signatures(clauses.size());
402 std::vector<Literal> candidates_for_removal;
403 for (
int clause_index = 0; clause_index < clauses.size(); ++clause_index) {
404 SatClause* clause = clauses[clause_index];
410 if (num_inspected_literals + num_inspected_signatures > 1e9) {
425 uint64_t signature = 0;
426 marked.SparseClearAll();
428 marked.Set(l.Index());
429 signature |= (uint64_t{1} << (l.Variable().value() % 64));
435 bool removed =
false;
436 candidates_for_removal.
clear();
437 const uint64_t mask = ~signature;
439 num_inspected_signatures += one_watcher[l.Index()].size();
440 for (
const int i : one_watcher[l.Index()]) {
441 if ((mask & signatures[i]) != 0)
continue;
443 bool subsumed =
true;
444 bool stengthen =
true;
446 num_inspected_literals += clauses[i]->size();
447 for (
const Literal o : clauses[i]->AsSpan()) {
448 if (!marked[o.Index()]) {
451 to_remove = o.NegatedIndex();
459 ++num_subsumed_clauses;
460 num_removed_literals += clause->
size();
472 if (removed)
continue;
476 num_inspected_signatures += one_watcher[l.NegatedIndex()].size();
477 for (
const int i : one_watcher[l.NegatedIndex()]) {
478 if ((mask & signatures[i]) != 0)
continue;
480 bool stengthen =
true;
481 num_inspected_literals += clauses[i]->size();
482 for (
const Literal o : clauses[i]->AsSpan()) {
483 if (o == l.Negated())
continue;
484 if (!marked[o.Index()]) {
501 if (!candidates_for_removal.
empty()) {
504 new_clause.push_back(l);
508 for (
const Literal l : new_clause) {
509 if (l == candidates_for_removal[0])
continue;
510 new_clause[new_size++] = l;
512 CHECK_EQ(new_size + 1, new_clause.size());
513 new_clause.resize(new_size);
515 num_removed_literals += clause->
size() - new_clause.size();
519 if (clause->
size() == 0)
continue;
524 signature |= (uint64_t{1} << (l.Variable().value() % 64));
545 if (one_watcher[l.Index()].size() < min_size) {
546 min_size = one_watcher[l.Index()].size();
547 min_literal = l.Index();
557 signatures[clause_index] = signature;
558 one_watcher[min_literal].push_back(clause_index);
566 const double dtime = static_cast<double>(num_inspected_signatures) * 1e-8 +
567 static_cast<double>(num_inspected_literals) * 5e-9;
569 LOG_IF(
INFO, log_info) <<
"Subsume. num_removed_literals: " 570 << num_removed_literals
571 <<
" num_subsumed: " << num_subsumed_clauses
572 <<
" dtime: " << dtime
582 num_subsumed_clauses_ = 0;
583 num_removed_literals_ = 0;
586 if (implication_graph_->
literal_size() == 0)
return true;
589 if (!stamps_are_already_computed_) {
598 stamps_are_already_computed_ =
false;
605 LOG_IF(
INFO, log_info) <<
"Stamping. num_removed_literals: " 606 << num_removed_literals_
607 <<
" num_subsumed: " << num_subsumed_clauses_
608 <<
" num_fixed: " << num_fixed_ <<
" dtime: " << dtime_
619 if (implication_graph_->
literal_size() == 0)
return true;
626 stamps_are_already_computed_ =
true;
632 <<
" num_fixed: " << num_fixed_ <<
" dtime: " << dtime_
641 for (LiteralIndex i(0); i < size; ++i) {
654 const auto& children_of_not_l =
656 if (children_of_not_l.empty())
continue;
657 for (
int num_tries = 0; num_tries < 10; ++num_tries) {
659 children_of_not_l[absl::Uniform<int>(*random_, 0,
660 children_of_not_l.size())]
662 if (implication_graph_->
IsRedundant(candidate))
continue;
663 if (i == candidate.
Index())
continue;
666 parents_[i] = candidate.
Index();
677 for (LiteralIndex i(0); i < size; ++i) {
678 if (parents_[i] == i)
continue;
679 sizes_[parents_[i]]++;
684 starts_[LiteralIndex(0)] = 0;
685 for (LiteralIndex i(1); i <= size; ++i) {
686 starts_[i] = starts_[i - 1] + sizes_[i - 1];
690 children_.resize(size);
691 for (LiteralIndex i(0); i < size; ++i) {
692 if (parents_[i] == i)
continue;
693 children_[starts_[parents_[i]]++] = i;
697 for (LiteralIndex i(0); i < size; ++i) {
698 starts_[i] -= sizes_[i];
702 CHECK_EQ(starts_[LiteralIndex(0)], 0);
703 for (LiteralIndex i(1); i <= size; ++i) {
704 CHECK_EQ(starts_[i], starts_[i - 1] + sizes_[i - 1]);
710 first_stamps_.
resize(size);
711 last_stamps_.
resize(size);
712 marked_.
assign(size,
false);
713 for (LiteralIndex i(0); i < size; ++i) {
714 if (parents_[i] != i)
continue;
716 const LiteralIndex tree_root = i;
717 dfs_stack_.push_back(i);
718 while (!dfs_stack_.empty()) {
719 const LiteralIndex top = dfs_stack_.back();
721 dfs_stack_.pop_back();
722 last_stamps_[top] = stamp++;
725 first_stamps_[top] = stamp++;
730 if (marked_[
Literal(top).NegatedIndex()] &&
731 first_stamps_[
Literal(top).NegatedIndex()] >=
732 first_stamps_[tree_root]) {
735 LiteralIndex lca = top;
736 while (first_stamps_[lca] > first_stamp) {
745 const int end = starts_[top + 1];
746 for (
int j = starts_[top]; j < end; ++j) {
748 DCHECK(!marked_[children_[j]]);
749 dfs_stack_.push_back(children_[j]);
763 bool operator<(
const Entry& o)
const {
return start < o.start; }
765 std::vector<int> to_remove;
766 std::vector<Literal> new_clause;
767 std::vector<Entry> entries;
771 const auto span = clause->AsSpan();
772 if (span.empty())
continue;
781 for (
int i = 0; i < span.size(); ++i) {
787 entries.push_back({i,
false, first_stamps_[span[i].Index()],
788 last_stamps_[span[i].Index()]});
789 entries.push_back({i,
true, first_stamps_[span[i].NegatedIndex()],
790 last_stamps_[span[i].NegatedIndex()]});
792 if (clause->empty())
continue;
795 if (!entries.empty()) {
796 const double n = static_cast<double>(entries.size());
797 dtime_ += 1.5e-8 * n * std::log(n);
798 std::sort(entries.begin(), entries.end());
804 for (
const Entry& e : entries) {
805 if (e.end < top_entry.end) {
807 const Literal lhs = top_entry.is_negated ? span[top_entry.i].Negated()
809 const Literal rhs = e.is_negated ? span[e.i].
Negated() : span[e.i];
812 if (top_entry.is_negated != e.is_negated) {
814 if (top_entry.i == e.i) {
816 if (top_entry.is_negated) {
825 span[top_entry.i].Negated())) {
828 to_remove.push_back(top_entry.i);
837 if (top_entry.is_negated) {
838 num_subsumed_clauses_++;
844 if (top_entry.is_negated) {
846 to_remove.push_back(e.i);
855 to_remove.push_back(top_entry.i);
863 if (clause->empty())
continue;
866 if (!to_remove.empty() || entries.size() < span.size()) {
869 int to_remove_index = 0;
870 for (
int i = 0; i < span.size(); ++i) {
871 if (to_remove_index < to_remove.size() &&
872 i == to_remove[to_remove_index]) {
881 new_clause.push_back(span[i]);
883 num_removed_literals_ += span.size() - new_clause.size();
897 num_blocked_clauses_ = 0;
898 num_inspected_literals_ = 0;
900 InitializeForNewRound();
902 while (!time_limit_->
LimitReached() && !queue_.empty()) {
903 const Literal l = queue_.front();
904 in_queue_[l.
Index()] =
false;
910 literal_to_clauses_.
clear();
912 dtime_ += 1e-8 * num_inspected_literals_;
915 LOG_IF(
INFO, log_info) <<
"Blocked clause. num_blocked_clauses: " 916 << num_blocked_clauses_ <<
" dtime: " << dtime_
920 void BlockedClauseSimplifier::InitializeForNewRound() {
928 clauses_.push_back(c);
930 const int num_literals = clause_manager_->
literal_size();
934 in_queue_.
assign(num_literals,
true);
935 for (LiteralIndex l(0); l < num_literals; ++l) {
936 queue_.push_back(Literal(l));
939 marked_.
resize(num_literals);
941 std::all_of(marked_.
begin(), marked_.
end(), [](
bool b) {
return !
b; }));
945 literal_to_clauses_.
clear();
946 literal_to_clauses_.
resize(num_literals);
947 for (ClauseIndex i(0); i < clauses_.size(); ++i) {
948 for (
const Literal l : clauses_[i]->AsSpan()) {
949 literal_to_clauses_[l.Index()].
push_back(i);
951 num_inspected_literals_ += clauses_[i]->size();
955 void BlockedClauseSimplifier::ProcessLiteral(Literal current_literal) {
957 if (implication_graph_->
IsRemoved(current_literal))
return;
972 const std::vector<Literal>& implications =
974 for (
const Literal l : implications) {
975 if (l == current_literal)
continue;
977 marked_[l.Index()] =
true;
983 std::vector<ClauseIndex> clauses_to_process;
984 for (
const ClauseIndex i : literal_to_clauses_[current_literal.Index()]) {
985 if (clauses_[i]->empty())
continue;
991 if (num_binary > 0) {
992 if (clauses_[i]->size() <= num_binary)
continue;
993 int num_with_negation_marked = 0;
994 for (
const Literal l : clauses_[i]->AsSpan()) {
995 if (l == current_literal)
continue;
996 if (marked_[l.NegatedIndex()]) {
997 ++num_with_negation_marked;
1000 num_inspected_literals_ += clauses_[i]->size();
1001 if (num_with_negation_marked < num_binary)
continue;
1003 clauses_to_process.push_back(i);
1007 for (
const Literal l : implications) {
1008 marked_[l.Index()] =
false;
1019 for (
const ClauseIndex i : clauses_to_process) {
1020 const auto c = clauses_[i]->AsSpan();
1021 if (ClauseIsBlocked(current_literal, c)) {
1028 for (
const Literal l : c) {
1029 if (!in_queue_[l.NegatedIndex()]) {
1030 in_queue_[l.NegatedIndex()] =
true;
1031 queue_.push_back(l.Negated());
1039 ++num_blocked_clauses_;
1046 bool BlockedClauseSimplifier::ClauseIsBlocked(
1047 Literal current_literal, absl::Span<const Literal> clause) {
1048 bool is_blocked =
true;
1049 for (
const Literal l : clause) marked_[l.Index()] =
true;
1053 for (
const ClauseIndex i :
1054 literal_to_clauses_[current_literal.NegatedIndex()]) {
1055 if (clauses_[i]->empty())
continue;
1056 bool some_marked =
false;
1057 for (
const Literal l : clauses_[i]->AsSpan()) {
1059 ++num_inspected_literals_;
1061 if (l == current_literal.Negated())
continue;
1062 if (marked_[l.NegatedIndex()]) {
1073 for (
const Literal l : clause) marked_[l.Index()] =
false;
1082 num_inspected_literals_ = 0;
1083 num_eliminated_variables_ = 0;
1084 num_literals_diff_ = 0;
1085 num_clauses_diff_ = 0;
1086 num_simplifications_ = 0;
1087 num_blocked_clauses_ = 0;
1098 clauses_.push_back(c);
1100 const int num_literals = clause_manager_->
literal_size();
1101 const int num_variables = num_literals / 2;
1103 literal_to_clauses_.
clear();
1104 literal_to_clauses_.
resize(num_literals);
1105 literal_to_num_clauses_.
assign(num_literals, 0);
1106 for (ClauseIndex i(0); i < clauses_.size(); ++i) {
1107 for (
const Literal l : clauses_[i]->AsSpan()) {
1108 literal_to_clauses_[l.Index()].
push_back(i);
1109 literal_to_num_clauses_[l.Index()]++;
1111 num_inspected_literals_ += clauses_[i]->size();
1114 const int saved_trail_index = trail_->
Index();
1115 propagation_index_ = trail_->
Index();
1117 need_to_be_updated_.clear();
1118 in_need_to_be_updated_.
resize(num_variables);
1119 queue_.
Reserve(num_variables);
1120 for (BooleanVariable v(0); v < num_variables; ++v) {
1123 UpdatePriorityQueue(v);
1126 marked_.
resize(num_literals);
1128 std::all_of(marked_.
begin(), marked_.
end(), [](
bool b) {
return !
b; }));
1134 const BooleanVariable top = queue_.
Top().var;
1142 bool is_unsat =
false;
1143 if (!Propagate())
return false;
1145 if (!Propagate())
return false;
1147 if (is_unsat)
return false;
1149 if (!CrossProduct(top))
return false;
1151 for (
const BooleanVariable v : need_to_be_updated_) {
1152 in_need_to_be_updated_[v] =
false;
1155 if (v != top) UpdatePriorityQueue(v);
1157 in_need_to_be_updated_.
clear();
1158 need_to_be_updated_.clear();
1167 bool remove =
false;
1168 for (
const Literal l : c->AsSpan()) {
1178 literal_to_clauses_.
clear();
1179 literal_to_num_clauses_.
clear();
1181 dtime_ += 1e-8 * num_inspected_literals_;
1186 << trail_->
Index() - saved_trail_index
1187 <<
" num_simplified_literals: " << num_simplifications_
1188 <<
" num_blocked_clauses_: " << num_blocked_clauses_
1189 <<
" num_eliminations: " << num_eliminated_variables_
1190 <<
" num_literals_diff: " << num_literals_diff_
1191 <<
" num_clause_diff: " << num_clauses_diff_
1192 <<
" dtime: " << dtime_
1197 bool BoundedVariableElimination::RemoveLiteralFromClause(
1199 num_literals_diff_ -= sat_clause->
size();
1203 literal_to_num_clauses_[l.Index()]--;
1207 num_clauses_diff_--;
1211 resolvant_.push_back(l);
1216 if (sat_clause->
empty()) {
1217 --num_clauses_diff_;
1218 for (
const Literal l : resolvant_) literal_to_num_clauses_[l.Index()]--;
1220 num_literals_diff_ += sat_clause->
size();
1225 bool BoundedVariableElimination::Propagate() {
1226 for (; propagation_index_ < trail_->
Index(); ++propagation_index_) {
1228 if (!implication_graph_->
Propagate(trail_))
return false;
1230 const Literal l = (*trail_)[propagation_index_];
1231 for (
const ClauseIndex
index : literal_to_clauses_[l.Index()]) {
1232 if (clauses_[
index]->empty())
continue;
1233 num_clauses_diff_--;
1234 num_literals_diff_ -= clauses_[
index]->size();
1237 literal_to_clauses_[l.Index()].
clear();
1238 for (
const ClauseIndex
index : literal_to_clauses_[l.NegatedIndex()]) {
1239 if (clauses_[
index]->empty())
continue;
1240 if (!RemoveLiteralFromClause(l.Negated(), clauses_[
index]))
return false;
1242 literal_to_clauses_[l.NegatedIndex()].
clear();
1249 int BoundedVariableElimination::NumClausesContaining(Literal l) {
1250 return literal_to_num_clauses_[l.Index()] +
1255 void BoundedVariableElimination::UpdatePriorityQueue(BooleanVariable
var) {
1257 const int priority = -NumClausesContaining(Literal(
var,
true)) -
1258 NumClausesContaining(Literal(
var,
false));
1262 queue_.
Add({
var, priority});
1266 void BoundedVariableElimination::DeleteClause(SatClause* sat_clause) {
1267 const auto clause = sat_clause->AsSpan();
1269 num_clauses_diff_--;
1270 num_literals_diff_ -= clause.size();
1273 for (
const Literal l : clause) {
1274 literal_to_num_clauses_[l.Index()]--;
1275 if (!in_need_to_be_updated_[l.Variable()]) {
1276 in_need_to_be_updated_[l.Variable()] =
true;
1277 need_to_be_updated_.push_back(l.Variable());
1285 void BoundedVariableElimination::DeleteAllClausesContaining(Literal
literal) {
1286 for (
const ClauseIndex i : literal_to_clauses_[
literal.Index()]) {
1287 const auto clause = clauses_[i]->AsSpan();
1288 if (clause.empty())
continue;
1290 DeleteClause(clauses_[i]);
1295 void BoundedVariableElimination::AddClause(absl::Span<const Literal> clause) {
1297 if (pt ==
nullptr)
return;
1299 num_clauses_diff_++;
1300 num_literals_diff_ += clause.size();
1302 const ClauseIndex
index(clauses_.size());
1303 clauses_.push_back(pt);
1304 for (
const Literal l : clause) {
1305 literal_to_num_clauses_[l.Index()]++;
1307 if (!in_need_to_be_updated_[l.Variable()]) {
1308 in_need_to_be_updated_[l.Variable()] =
true;
1309 need_to_be_updated_.push_back(l.Variable());
1314 template <
bool score_only,
bool with_binary_only>
1315 bool BoundedVariableElimination::ResolveAllClauseContaining(Literal lit) {
1318 const std::vector<Literal>& implications =
1320 auto& clause_containing_lit = literal_to_clauses_[lit.Index()];
1321 for (
int i = 0; i < clause_containing_lit.size(); ++i) {
1322 const ClauseIndex clause_index = clause_containing_lit[i];
1323 const auto clause = clauses_[clause_index]->AsSpan();
1324 if (clause.empty())
continue;
1326 if (!score_only) resolvant_.clear();
1327 for (
const Literal l : clause) {
1328 if (!score_only && l != lit) resolvant_.push_back(l);
1329 marked_[l.Index()] =
true;
1331 num_inspected_literals_ += clause.size() + implications.size();
1335 bool clause_can_be_simplified =
false;
1336 const int64_t saved_score = new_score_;
1339 for (
const Literal l : implications) {
1341 if (marked_[l.NegatedIndex()])
continue;
1342 if (marked_[l.Index()]) {
1343 clause_can_be_simplified =
true;
1347 new_score_ += clause_weight + clause.size();
1349 resolvant_.push_back(l);
1350 AddClause(resolvant_);
1351 resolvant_.pop_back();
1357 if (!with_binary_only && !clause_can_be_simplified) {
1358 auto& clause_containing_not_lit = literal_to_clauses_[lit.NegatedIndex()];
1359 for (
int j = 0; j < clause_containing_not_lit.size(); ++j) {
1360 if (score_only && new_score_ > score_threshold_)
break;
1361 const ClauseIndex other_index = clause_containing_not_lit[j];
1362 const auto other = clauses_[other_index]->AsSpan();
1363 if (other.empty())
continue;
1364 bool trivial =
false;
1366 for (
const Literal l : other) {
1368 ++num_inspected_literals_;
1369 if (l == lit.Negated())
continue;
1370 if (marked_[l.NegatedIndex()]) {
1374 if (!marked_[l.Index()]) {
1376 if (!score_only) resolvant_.push_back(l);
1380 if (!score_only) resolvant_.resize(resolvant_.size() - extra_size);
1386 if (score_only && clause.size() + extra_size <= other.size()) {
1387 CHECK_EQ(clause.size() + extra_size, other.size());
1388 ++num_simplifications_;
1392 score_threshold_ -= clause_weight + other.size();
1394 if (extra_size == 0) {
1398 DeleteClause(clauses_[other_index]);
1400 if (!RemoveLiteralFromClause(lit.Negated(),
1401 clauses_[other_index])) {
1405 clause_containing_not_lit.back());
1406 clause_containing_not_lit.pop_back();
1412 if (extra_size == 0) {
1413 clause_can_be_simplified =
true;
1418 if (clause.size() - 1 + extra_size > 100) {
1419 new_score_ = score_threshold_ + 1;
1423 new_score_ += clause_weight + clause.size() - 1 + extra_size;
1425 AddClause(resolvant_);
1426 resolvant_.resize(resolvant_.size() - extra_size);
1433 for (
const Literal l : clause) marked_[l.Index()] =
false;
1436 if (clause_can_be_simplified) {
1437 ++num_simplifications_;
1440 new_score_ = saved_score;
1441 score_threshold_ -= clause_weight + clause.size();
1443 if (!RemoveLiteralFromClause(lit, clauses_[clause_index]))
return false;
1444 std::swap(clause_containing_lit[i], clause_containing_lit.back());
1445 clause_containing_lit.pop_back();
1449 if (score_only && new_score_ > score_threshold_)
return true;
1461 if (score_only && !with_binary_only && !clause_can_be_simplified &&
1462 new_score_ == saved_score) {
1463 ++num_blocked_clauses_;
1464 score_threshold_ -= clause_weight + clause.size();
1466 DeleteClause(clauses_[clause_index]);
1472 bool BoundedVariableElimination::CrossProduct(BooleanVariable
var) {
1475 const Literal lit(
var,
true);
1476 const Literal not_lit(
var,
false);
1478 const int s1 = NumClausesContaining(lit);
1479 const int s2 = NumClausesContaining(not_lit);
1480 if (s1 == 0 && s2 == 0)
return true;
1481 if (s1 > 0 && s2 == 0) {
1482 num_eliminated_variables_++;
1484 DeleteAllClausesContaining(lit);
1487 if (s1 == 0 && s2 > 0) {
1488 num_eliminated_variables_++;
1490 DeleteAllClausesContaining(not_lit);
1498 num_eliminated_variables_++;
1522 (clause_weight + 2);
1523 for (
const ClauseIndex i : literal_to_clauses_[lit.Index()]) {
1524 const auto c = clauses_[i]->AsSpan();
1525 if (!c.empty()) score += clause_weight + c.size();
1527 for (
const ClauseIndex i : literal_to_clauses_[not_lit.Index()]) {
1528 const auto c = clauses_[i]->AsSpan();
1529 if (!c.empty()) score += clause_weight + c.size();
1540 score_threshold_ = score;
1542 (clause_weight + 2);
1543 if (new_score_ > score_threshold_)
return true;
1544 if (!ResolveAllClauseContaining<
true,
1548 if (new_score_ > score_threshold_)
return true;
1549 if (!ResolveAllClauseContaining<
true,
1553 if (new_score_ > score_threshold_)
return true;
1556 if (new_score_ > 0) {
1557 if (!ResolveAllClauseContaining<
false,
1561 if (!ResolveAllClauseContaining<
false,
1567 ++num_eliminated_variables_;
1569 DeleteAllClausesContaining(lit);
1570 DeleteAllClausesContaining(not_lit);
bool PresolveLoop(SatPresolveOptions options)
std::deque< std::vector< Literal > > clauses
absl::Span< const Literal > AsSpan() const
bool Propagate(Trail *trail) final
bool LiteralIsFalse(Literal literal) const
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
bool LiteralIsTrue(Literal literal) const
LiteralIndex Index() const
Literal RepresentativeOf(Literal l) const
bool DoOneRound(bool log_info)
bool RemoveFixedAndEquivalentVariables(bool log_info)
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
bool extract_binary_clauses_in_probing
bool ComputeTransitiveReduction(bool log_info=false)
void CleanupAllRemovedVariables()
int64_t num_implications() const
bool DoOneRound(bool log_info)
void RemoveFixedVariables()
bool ComputeStampsForNextRound(bool log_info)
void AddClauseWithSpecialLiteral(Literal literal, absl::Span< const Literal > clause)
bool ImplicationIsInTree(Literal a, Literal b) const
void InprocessingRemoveClause(SatClause *clause)
bool IsRedundant(Literal l) const
bool Contains(int index) const
bool DetectEquivalences(bool log_info=false)
void resize(size_type new_size)
LiteralIndex NegatedIndex() const
int64_t literal_size() const
#define DCHECK_NE(val1, val2)
void Add(Element element)
bool VariableIsAssigned(BooleanVariable var) const
bool use_transitive_reduction
void DeleteRemovedClauses()
bool LiteralIsAssigned(Literal literal) const
bool LevelZeroPropagate()
void push_back(const value_type &x)
void RemoveBooleanVariable(BooleanVariable var, std::deque< std::vector< Literal >> *postsolve_clauses)
void SampleTreeAndFillParent()
#define RETURN_IF_FALSE(f)
bool IsRemovable(SatClause *const clause) const
const std::vector< Literal > & DirectImplications(Literal literal)
bool MoreFixedVariableToClean() const
int64_t num_watched_clauses() const
void MinimizeSomeClauses(int decisions_budget)
#define CHECK_EQ(val1, val2)
const std::vector< SatClause * > & AllClausesInCreationOrder() const
::PROTOBUF_NAMESPACE_ID::int32 presolve_bve_threshold() const
int64_t NumImplicationOnVariableRemoval(BooleanVariable var)
bool FailedLiteralProbingRound(ProbingOptions options, Model *model)
void ChangePriority(Element element)
#define LOG_IF(severity, condition)
#define DCHECK(condition)
double GetElapsedDeterministicTime() const
Returns the elapsed deterministic time since the construction of this object.
::PROTOBUF_NAMESPACE_ID::int32 presolve_bve_clause_weight() const
bool LimitReached()
Returns true when the external limit is true, or the deterministic time is over the deterministic lim...
#define DCHECK_EQ(val1, val2)
void MaybeEnablePhaseSaving(bool save_phase)
void AdvanceDeterministicTime(double deterministic_duration)
Advances the deterministic time.
double deterministic_limit
bool FindFailedLiteralAroundVar(BooleanVariable var, bool *is_unsat)
int CurrentDecisionLevel() const
Collection of objects used to extend the Constraint Solver library.
bool extract_binary_clauses
void assign(size_type n, const value_type &val)
bool MoreRedundantVariableToClean() const
bool DetectEquivalencesAndStamp(bool use_transitive_reduction, bool log_info)
const LiteralIndex kNoLiteralIndex(-1)
SatClause * InprocessingAddClause(absl::Span< const Literal > new_clause)
#define VLOG_IS_ON(verboselevel)
bool IsRemoved(Literal l) const
ABSL_MUST_USE_RESULT bool InprocessingFixLiteral(Literal true_literal)
int DirectImplicationsEstimatedSize(Literal literal) const
void DoOneRound(bool log_info)
int64_t num_redundant_literals() const
double deterministic_time_limit
int64_t literal_size() const
#define CHECK_NE(val1, val2)
ABSL_MUST_USE_RESULT bool InprocessingRewriteClause(SatClause *clause, absl::Span< const Literal > new_clause)
bool SubsumeAndStrenghtenRound(bool log_info)