@@ -654,7 +654,6 @@ bool FailedLiteralProbing::DoOneRound(ProbingOptions options) {
654654 }
655655
656656 binary_clause_extracted_.assign (trail_.Index (), false );
657- subsumed_clauses_.clear ();
658657
659658 while (!time_limit_->LimitReached () &&
660659 time_limit_->GetElapsedDeterministicTime () <= limit) {
@@ -738,15 +737,7 @@ bool FailedLiteralProbing::DoOneRound(ProbingOptions options) {
738737
739738 if (!sat_solver_->ResetToLevelZero ()) return false ;
740739 if (!ProcessLiteralsToFix ()) return false ;
741- if (!subsumed_clauses_.empty ()) {
742- for (SatClause* clause : subsumed_clauses_) {
743- if (clause->size () == 0 ) continue ;
744- ++num_subsumed_;
745- clause_manager_->LazyDelete (clause,
746- DeletionSourceForStat::SUBSUMPTION_PROBING);
747- }
748- clause_manager_->CleanUpWatchers ();
749- }
740+ clause_manager_->CleanUpWatchers ();
750741
751742 // Display stats.
752743 const int num_fixed = sat_solver_->LiteralTrail ().Index ();
@@ -994,7 +985,31 @@ void FailedLiteralProbing::MaybeExtractImplication(const Literal last_decision,
994985 // of all literals in the reason for this propagation. And use this
995986 // as a reason for later hyber binary resolution. Like we do when
996987 // this clause subsumes the reason.
997- AddImplication (last_decision, l);
988+ ++num_new_binary_;
989+ DCHECK (assignment_.LiteralIsTrue (l));
990+ CHECK_NE (l.Variable (), last_decision.Variable ());
991+
992+ // We should never probe a redundant literal.
993+ //
994+ // TODO(user): We should be able to enforce that l is non-redundant either if
995+ // we made sure the clause database is cleaned up before FailedLiteralProbing
996+ // is called. This should maybe simplify the ChangeReason() handling.
997+ DCHECK (!implication_graph_->IsRedundant (last_decision));
998+
999+ ClauseId clause_id = kNoClauseId ;
1000+ if (lrat_proof_handler_ != nullptr ) {
1001+ clause_id = clause_id_generator_->GetNextId ();
1002+ tmp_clause_ids_.clear ();
1003+ sat_solver_->AppendClausesFixing ({l}, &tmp_clause_ids_, last_decision);
1004+ lrat_proof_handler_->AddInferredClause (
1005+ clause_id, {last_decision.Negated (), l}, tmp_clause_ids_);
1006+ }
1007+
1008+ // Each time we extract a binary clause, we change the reason in the trail.
1009+ // This is important as it will allow us to remove clauses that are now
1010+ // subsumed by this binary, even if it was a reason.
1011+ CHECK (implication_graph_->AddBinaryClauseAndChangeReason (
1012+ clause_id, l, last_decision.Negated ()));
9981013}
9991014
10001015// If we can extract a binary clause that subsume the reason clause, we do add
@@ -1006,6 +1021,7 @@ void FailedLiteralProbing::MaybeSubsumeWithBinaryClause(
10061021 const Literal last_decision, const Literal l) {
10071022 const int trail_index = trail_.Info (l.Variable ()).trail_index ;
10081023 if (trail_.AssignmentType (l.Variable ()) != clause_propagator_id_) return ;
1024+ SatClause* clause = clause_manager_->ReasonClause (trail_index);
10091025
10101026 bool subsumed = false ;
10111027 for (const Literal lit : trail_.Reason (l.Variable ())) {
@@ -1027,7 +1043,12 @@ void FailedLiteralProbing::MaybeSubsumeWithBinaryClause(
10271043 if (lit == last_decision.Negated ()) ++test;
10281044 }
10291045 CHECK_EQ (test, 2 );
1030- subsumed_clauses_.push_back (clause_manager_->ReasonClause (trail_index));
1046+
1047+ // Because of MaybeExtractImplication(), this shouldn't be a reason anymore.
1048+ CHECK (!clause_manager_->ClauseIsUsedAsReason (clause));
1049+ ++num_subsumed_;
1050+ clause_manager_->LazyDelete (clause,
1051+ DeletionSourceForStat::SUBSUMPTION_PROBING);
10311052}
10321053
10331054// Inspect the watcher list for last_decision, If we have a blocking
@@ -1043,34 +1064,21 @@ void FailedLiteralProbing::SubsumeWithBinaryClauseUsingBlockingLiteral(
10431064 const Literal last_decision) {
10441065 for (const auto & w :
10451066 clause_manager_->WatcherListOnFalse (last_decision.Negated ())) {
1046- if (assignment_.LiteralIsTrue (w.blocking_literal )) {
1047- if (w.clause ->IsRemoved ()) continue ;
1067+ if (! assignment_.LiteralIsTrue (w.blocking_literal )) continue ;
1068+ if (w.clause ->IsRemoved ()) continue ;
10481069
1049- // This should be enough for proof correctness.
1050- if (clause_manager_->ClauseIsUsedAsReason (w.clause )) {
1051- MaybeExtractImplication (last_decision, w.blocking_literal );
1052- }
1053- subsumed_clauses_.push_back (w.clause );
1054- }
1055- }
1056- }
1070+ // This should be enough for proof correctness.
1071+ if (clause_manager_->ClauseIsUsedAsReason (w.clause )) {
1072+ MaybeExtractImplication (last_decision, w.blocking_literal );
10571073
1058- void FailedLiteralProbing::AddImplication (const Literal last_decision,
1059- const Literal l) {
1060- ++num_new_binary_;
1061- DCHECK (assignment_.LiteralIsTrue (l));
1062- CHECK_NE (l.Variable (), last_decision.Variable ());
1074+ // It should have been replaced by a binary clause now.
1075+ CHECK (!clause_manager_->ClauseIsUsedAsReason (w.clause ));
1076+ }
10631077
1064- ClauseId clause_id = kNoClauseId ;
1065- if (lrat_proof_handler_ != nullptr ) {
1066- clause_id = clause_id_generator_->GetNextId ();
1067- tmp_clause_ids_.clear ();
1068- sat_solver_->AppendClausesFixing ({l}, &tmp_clause_ids_, last_decision);
1069- lrat_proof_handler_->AddInferredClause (
1070- clause_id, {last_decision.Negated (), l}, tmp_clause_ids_);
1078+ ++num_subsumed_;
1079+ clause_manager_->LazyDelete (w.clause ,
1080+ DeletionSourceForStat::SUBSUMPTION_PROBING);
10711081 }
1072- CHECK (implication_graph_->AddBinaryClause (clause_id, last_decision.Negated (),
1073- l));
10741082}
10751083
10761084// Adds 'not(literal)' to `to_fix_`, assuming that 'literal' directly implies
0 commit comments