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;
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;
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();
467 candidates_for_removal.push_back(
Literal(to_remove));
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()]) {
490 candidates_for_removal.push_back(l);
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_
640 parents_.resize(size);
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();
676 sizes_.assign(size, 0);
677 for (LiteralIndex i(0); i < size; ++i) {
678 if (parents_[i] == i)
continue;
679 sizes_[parents_[i]]++;
683 starts_.resize(size + 1);
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_
920void 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();
955void 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_;
1046bool 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; }));
1133 while (!time_limit_->
LimitReached() && !queue_.IsEmpty()) {
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_
1197bool 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();
1225bool 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();
1249int BoundedVariableElimination::NumClausesContaining(Literal l) {
1250 return literal_to_num_clauses_[l.Index()] +
1255void BoundedVariableElimination::UpdatePriorityQueue(BooleanVariable
var) {
1257 const int priority = -NumClausesContaining(Literal(
var,
true)) -
1258 NumClausesContaining(Literal(
var,
false));
1259 if (queue_.Contains(
var.value())) {
1260 queue_.ChangePriority({
var, priority});
1262 queue_.Add({
var, priority});
1266void 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());
1285void 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]);
1292 literal_to_clauses_[
literal.Index()].clear();
1295void 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()]++;
1306 literal_to_clauses_[l.Index()].push_back(
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());
1314template <
bool score_only,
bool with_binary_only>
1315bool 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]);
1472bool 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);
#define LOG_IF(severity, condition)
#define DCHECK_NE(val1, val2)
#define CHECK_EQ(val1, val2)
#define CHECK_NE(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
void push_back(const value_type &x)
void Set(IntegerType index)
bool LimitReached()
Returns true when the external limit is true, or the deterministic time is over the deterministic lim...
double GetElapsedDeterministicTime() const
Returns the elapsed deterministic time since the construction of this object.
void AdvanceDeterministicTime(double deterministic_duration)
Advances the deterministic time.
int64_t NumImplicationOnVariableRemoval(BooleanVariable var)
bool Propagate(Trail *trail) final
bool ComputeTransitiveReduction(bool log_info=false)
void RemoveBooleanVariable(BooleanVariable var, std::deque< std::vector< Literal > > *postsolve_clauses)
Literal RepresentativeOf(Literal l) const
int64_t num_redundant_literals() const
const std::vector< Literal > & DirectImplications(Literal literal)
bool IsRedundant(Literal l) const
bool DetectEquivalences(bool log_info=false)
void CleanupAllRemovedVariables()
bool FindFailedLiteralAroundVar(BooleanVariable var, bool *is_unsat)
void RemoveFixedVariables()
bool IsRemoved(Literal l) const
int64_t num_implications() const
int64_t literal_size() const
int DirectImplicationsEstimatedSize(Literal literal) const
void DoOneRound(bool log_info)
bool DoOneRound(bool log_info)
bool PresolveLoop(SatPresolveOptions options)
bool MoreFixedVariableToClean() const
bool RemoveFixedAndEquivalentVariables(bool log_info)
bool LevelZeroPropagate()
bool MoreRedundantVariableToClean() const
bool SubsumeAndStrenghtenRound(bool log_info)
bool DetectEquivalencesAndStamp(bool use_transitive_reduction, bool log_info)
LiteralIndex NegatedIndex() const
LiteralIndex Index() const
ABSL_MUST_USE_RESULT bool InprocessingFixLiteral(Literal true_literal)
void InprocessingRemoveClause(SatClause *clause)
SatClause * InprocessingAddClause(absl::Span< const Literal > new_clause)
bool IsRemovable(SatClause *const clause) const
ABSL_MUST_USE_RESULT bool InprocessingRewriteClause(SatClause *clause, absl::Span< const Literal > new_clause)
int64_t num_watched_clauses() const
const std::vector< SatClause * > & AllClausesInCreationOrder() const
void DeleteRemovedClauses()
int64_t literal_size() const
absl::Span< const Literal > AsSpan() const
void MaybeEnablePhaseSaving(bool save_phase)
::PROTOBUF_NAMESPACE_ID::int32 presolve_bve_clause_weight() const
::PROTOBUF_NAMESPACE_ID::int32 presolve_bve_threshold() const
void MinimizeSomeClauses(int decisions_budget)
int CurrentDecisionLevel() const
bool DoOneRound(bool log_info)
bool ComputeStampsForNextRound(bool log_info)
bool ImplicationIsInTree(Literal a, Literal b) const
void SampleTreeAndFillParent()
bool LiteralIsAssigned(Literal literal) const
bool VariableIsAssigned(BooleanVariable var) const
bool LiteralIsTrue(Literal literal) const
bool LiteralIsFalse(Literal literal) const
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
const LiteralIndex kNoLiteralIndex(-1)
bool FailedLiteralProbingRound(ProbingOptions options, Model *model)
Collection of objects used to extend the Constraint Solver library.
#define RETURN_IF_FALSE(f)
std::deque< std::vector< Literal > > clauses
void AddClauseWithSpecialLiteral(Literal literal, absl::Span< const Literal > clause)
double deterministic_limit
bool extract_binary_clauses
bool use_transitive_reduction
bool extract_binary_clauses_in_probing
double deterministic_time_limit
#define VLOG_IS_ON(verboselevel)