27#include "absl/container/flat_hash_map.h"
28#include "absl/flags/flag.h"
29#include "absl/log/check.h"
30#include "absl/log/log.h"
31#include "absl/strings/str_cat.h"
32#include "absl/strings/str_join.h"
33#include "absl/types/span.h"
48ABSL_FLAG(std::string, cp_model_drat_output,
".\\drat.txt",
49 "File name for the generated DRAT proof, if DRAT output is enabled.");
50ABSL_FLAG(std::string, cp_model_lrat_output_prefix,
".\\lrat",
51 "File name prefix for the generated LRAT proof files, if LRAT output "
52 "is enabled. One file is created for each worker.");
54ABSL_FLAG(std::string, cp_model_drat_output,
"/tmp/drat.txt",
55 "File name for the generated DRAT proof, if DRAT output is enabled.");
56ABSL_FLAG(std::string, cp_model_lrat_output_prefix,
"/tmp/lrat",
57 "File name prefix for the generated LRAT proof files, if LRAT output "
58 "is enabled. One file is created for each worker.");
66 ofstream_(filename_,
std::ios::binary),
68 if (!ofstream_.good()) {
69 LOG(FATAL) <<
"Failed to open LRAT output file: " << filename;
74 WriteDeletedClauseIds();
79 absl::Span<const Literal> clause) {
80 WriteDeletedClauseIds();
84 for (
const Literal literal : clause) {
87 CHECK(writer_.WriteRecord(step));
91 absl::Span<const Literal> clause,
92 absl::Span<const ClauseId> unit_ids,
93 absl::Span<const LratChecker::RatIds> rat,
95 WriteDeletedClauseIds();
99 for (
const Literal literal : clause) {
102 for (
const ClauseId unit_id : unit_ids) {
108 for (
const ClauseId unit_id : rat_ids.unit_ids) {
113 CHECK(writer_.WriteRecord(step));
117 WriteDeletedClauseIds();
121 for (
const Literal literal : clause) {
124 CHECK(writer_.WriteRecord(step));
128 deleted_clause_ids_.push_back(
id);
131void LratWriter::WriteDeletedClauseIds() {
132 if (deleted_clause_ids_.empty())
return;
135 deleted_clause_ids_.begin(), deleted_clause_ids_.end());
137 deleted_clause_ids_.clear();
141void IndicesToLiterals(absl::Span<const int> literal_indices,
142 std::vector<Literal>* literals) {
144 literals->reserve(literal_indices.size());
145 for (
const int lit : literal_indices) {
146 literals->push_back(Literal(LiteralIndex(lit)));
156 lrat_checker_ = std::make_unique<LratChecker>(model);
163 if (lrat_checker_ !=
nullptr) {
167 LOG(FATAL) <<
"LRAT error: " << lrat_checker_->error_message();
169 lrat_checker_->AddStats();
171 proof_status_->NewSubsolverProofStatus(status, lrat_checker_ !=
nullptr,
177 if (proof_filenames.empty())
return true;
178 merged_proof_filename_ =
179 absl::StrCat(absl::GetFlag(FLAGS_cp_model_lrat_output_prefix),
".txt");
180 merged_proof_file_.open(merged_proof_filename_);
181 if (!merged_proof_file_.good()) {
182 return Error(absl::StrCat(
"failed to open LRAT output file: ",
183 merged_proof_filename_));
185 if (!ReadPresolveProof(proof_filenames[0]))
return false;
187 const int num_workers = proof_filenames.size() - 1;
188 std::vector<std::ifstream> inputs(num_workers);
189 std::vector<std::unique_ptr<RecordReader>> readers(num_workers);
190 last_read_steps_.resize(num_workers);
191 local_to_global_ids_.resize(num_workers);
192 exported_local_ids_.resize(num_workers);
193 for (
int i = 0;
i < num_workers; ++
i) {
194 const std::string& filename = proof_filenames[
i + 1];
195 inputs[
i].open(filename, std::ios::binary);
196 if (!inputs[
i].good()) {
197 return Error(absl::StrCat(
"failed to open LRAT input file: ", filename));
199 readers[
i] = std::make_unique<RecordReader>(&inputs[
i]);
200 if (!readers[
i]->ReadRecord(&last_read_steps_[
i])) {
201 last_read_steps_[
i].Clear();
205 std::vector<Literal> clause;
207 bool at_least_one_step_read =
false;
208 int worker_with_missing_import = -1;
209 for (
int i = 0;
i < num_workers; ++
i) {
210 const std::string& filename = proof_filenames[
i + 1];
212 bool missing_import =
false;
220 std::sort(clause.begin(), clause.end());
221 auto it = shared_clause_ids_.find(clause);
222 if (it != shared_clause_ids_.end()) {
223 local_to_global_ids_[
i][local_id] = it->second;
225 missing_import =
true;
230 if (!RemapInferredClause(
i, filename,
241 SortAndAddSharedClause(
243 exported_local_ids_[
i].insert(
249 auto it = local_to_global_ids_[
i].find(local_id);
250 if (it == local_to_global_ids_[
i].
end()) {
251 return Error(absl::StrCat(
"unknown exported clause ID ", local_id,
254 const GlobalId global_id = it->second;
256 SortAndAddSharedClause(global_id, clause);
257 exported_local_ids_[
i].insert(local_id);
261 for (
const int64_t clause_id :
263 const ClauseId local_id(clause_id);
264 if (exported_local_ids_[
i].contains(local_id)) {
269 local_to_global_ids_[
i].erase(local_id);
274 return Error(absl::StrCat(
"unknown step type ", step.
step_case(),
277 if (missing_import) {
278 worker_with_missing_import =
i;
280 if (!readers[
i]->ReadRecord(&last_read_steps_[
i])) {
281 last_read_steps_[
i].Clear();
283 at_least_one_step_read =
true;
287 if (!at_least_one_step_read) {
288 if (worker_with_missing_import >= 0) {
290 last_read_steps_[worker_with_missing_import].imported_clause();
292 IndicesToLiterals(missing_import.
literals(), &clause);
294 absl::StrCat(
"imported clause not found in ",
295 proof_filenames[worker_with_missing_import + 1],
297 ", literals=", absl::StrJoin(clause,
",")));
305bool LratMerger::ReadPresolveProof(
const std::string& filename) {
306 std::ifstream
input(filename, std::ios::binary);
308 return Error(absl::StrCat(
"failed to open LRAT input file: ", filename));
310 RecordReader reader(&
input);
312 std::vector<Literal> clause;
313 absl::flat_hash_map<GlobalId, std::vector<Literal>> shared_clauses;
314 GlobalId max_global_id(0);
315 while (reader.ReadRecord(&step)) {
316 switch (step.step_case()) {
318 GlobalId global_id(step.imported_clause().clause_id());
319 max_global_id = std::max(max_global_id, global_id);
320 IndicesToLiterals(step.imported_clause().literals(), &clause);
321 std::sort(clause.begin(), clause.end());
322 shared_clauses[global_id] = clause;
323 if (lrat_checker_ !=
nullptr &&
324 !lrat_checker_->AddProblemClause(ClauseId(global_id.value()),
331 GlobalId global_id(step.inferred_clause().clause_id());
332 max_global_id = std::max(max_global_id, global_id);
333 IndicesToLiterals(step.inferred_clause().literals(), &clause);
334 std::sort(clause.begin(), clause.end());
335 shared_clauses[global_id] = clause;
336 if (!WriteInferredClause(step.inferred_clause()))
return false;
344 for (
const int64_t clause_id : step.deleted_clauses().clause_ids()) {
345 const GlobalId global_id(clause_id);
346 auto it = shared_clauses.find(global_id);
347 if (it != shared_clauses.end()) {
348 shared_clauses.erase(it);
353 return Error(absl::StrCat(
"unknown proof step type ", step.step_case(),
357 for (
const auto& [global_id, clause] : shared_clauses) {
358 shared_clause_ids_.insert({clause, global_id});
360 next_global_id_ = ++max_global_id;
364void LratMerger::SortAndAddSharedClause(GlobalId
id,
365 std::vector<Literal>& literals) {
366 std::sort(literals.begin(), literals.end());
367 shared_clause_ids_.insert({literals,
id});
370bool LratMerger::RemapInferredClause(
int worker_index,
371 const std::string& filename,
373 const GlobalId global_id = NextGlobalId();
374 ClauseId local_id = ClauseId(inferred_clause.clause_id());
375 local_to_global_ids_[worker_index][local_id] = global_id;
377 inferred_clause.set_clause_id(global_id.value());
378 if (!RemapClauseIds(worker_index, filename,
379 inferred_clause.mutable_unit_ids())) {
383 *inferred_clause.mutable_rat_infos()) {
384 local_id = ClauseId(rat_info.resolvant_id());
385 auto it = local_to_global_ids_[worker_index].find(local_id);
386 if (it == local_to_global_ids_[worker_index].
end()) {
388 absl::StrCat(
"unknown clause ID ", local_id,
" in ", filename));
390 rat_info.set_resolvant_id(it->second.value());
391 if (!RemapClauseIds(worker_index, filename, rat_info.mutable_unit_ids())) {
398bool LratMerger::RemapClauseIds(
399 int worker_index,
const std::string& filename,
400 google::protobuf::RepeatedField<int64_t>* clause_ids) {
401 for (
int i = 0;
i < clause_ids->size(); ++
i) {
402 const ClauseId local_id = ClauseId(clause_ids->Get(
i));
403 auto it = local_to_global_ids_[worker_index].find(local_id);
404 if (it == local_to_global_ids_[worker_index].
end()) {
406 absl::StrCat(
"unknown clause ID ", local_id,
" in ", filename));
408 clause_ids->Set(
i, it->second.value());
413bool LratMerger::WriteInferredClause(
415 if (lrat_checker_ !=
nullptr) {
417 IndicesToLiterals(inferred_clause.literals(), &tmp_clause_);
418 tmp_unit_ids_.clear();
419 tmp_unit_ids_.reserve(inferred_clause.unit_ids_size());
420 for (
const int64_t
id : inferred_clause.unit_ids()) {
421 tmp_unit_ids_.push_back(ClauseId(
id));
423 tmp_rat_ids_.clear();
424 tmp_rat_ids_.reserve(inferred_clause.rat_infos_size());
426 inferred_clause.rat_infos()) {
427 tmp_rat_ids_.push_back(
428 {ClauseId(rat_info.resolvant_id()),
429 std::vector<ClauseId>(rat_info.unit_ids().begin(),
430 rat_info.unit_ids().end())});
432 if (!lrat_checker_->AddInferredClause(ClauseId(inferred_clause.clause_id()),
433 tmp_clause_, tmp_unit_ids_,
438 merged_proof_file_ << inferred_clause.clause_id();
439 for (
const int lit : inferred_clause.literals()) {
440 merged_proof_file_ <<
" " << Literal(LiteralIndex(lit)).SignedValue();
442 merged_proof_file_ <<
" 0";
443 for (
const int unit_id : inferred_clause.unit_ids()) {
444 merged_proof_file_ <<
" " << unit_id;
447 inferred_clause.rat_infos()) {
448 merged_proof_file_ <<
" " << -rat_info.resolvant_id();
449 for (
const int unit_id : rat_info.unit_ids()) {
450 merged_proof_file_ <<
" " << unit_id;
453 merged_proof_file_ <<
" 0\n";
457bool LratMerger::Error(std::string_view message)
const {
458 if (debug_crash_on_error_) {
459 LOG(FATAL) <<
"LRAT merge error: " << message;
461 LOG(ERROR) <<
"LRAT merge error: " << message;
466bool LratMerger::LratError()
const {
467 if (debug_crash_on_error_) {
468 LOG(FATAL) <<
"LRAT error: " << lrat_checker_->error_message();
474std::vector<Literal> SortClauseForDrat(absl::Span<const Literal> clause) {
478 std::vector<Literal> sorted_clause(clause.begin(), clause.end());
479 std::sort(sorted_clause.begin(), sorted_clause.end(),
481 return std::abs(a.SignedValue()) > std::abs(b.SignedValue());
483 return sorted_clause;
501 return std::unique_ptr<LratProofHandler>(
502 new LratProofHandler(params, id_generator, proof_status, stats));
505LratProofHandler::LratProofHandler(
508 : id_(shared_lrat_proof_status->NewSubSolverId()),
509 id_generator_(id_generator),
510 proof_status_(shared_lrat_proof_status) {
512 lrat_checker_ = std::make_unique<LratChecker>(stats);
515 lrat_writer_ = std::make_unique<LratWriter>(absl::StrCat(
516 absl::GetFlag(FLAGS_cp_model_lrat_output_prefix), id_,
".bin"));
519 drat_checker_ = std::make_unique<DratChecker>();
522 File* drat_output = nullptr;
523 CHECK_OK(file::Open(absl::GetFlag(FLAGS_cp_model_drat_output),
"w",
524 &drat_output, file::Defaults()));
525 drat_writer_ = std::make_unique<DratWriter>(
533 absl::Span<const Literal> clause) {
534 VLOG(2) <<
"AddProblemClause: id=" <<
id
535 <<
" literals=" << absl::StrJoin(clause,
",");
536 if (all_problem_clauses_loaded_ && debug_crash_on_error_) {
537 LOG(FATAL) <<
"LRAT error: problem clauses must not be added after "
538 "EndProblemClauses()";
540 if (lrat_checker_ !=
nullptr &&
541 !lrat_checker_->AddProblemClause(
id, clause)) {
542 return LratError(
"In AddProblemClause.");
544 if (drat_checker_ !=
nullptr) {
545 drat_checker_->AddProblemClause(SortClauseForDrat(clause));
547 if (lrat_writer_ !=
nullptr) {
548 lrat_writer_->AddImportedClause(
id, clause);
554 all_problem_clauses_loaded_ =
true;
555 if (drat_checker_ !=
nullptr) {
556 for (
const auto& clause : clauses_inferred_during_problem_loading_) {
557 drat_checker_->AddInferredClause(clause);
559 clauses_inferred_during_problem_loading_.clear();
564 ClauseId
id, absl::Span<const Literal> clause,
565 absl::Span<const ClauseId> unit_ids,
566 absl::Span<const LratChecker::RatIds> rat,
bool exported) {
567 VLOG(2) <<
"AddInferredClause: id=" <<
id
568 <<
" literals=" << absl::StrJoin(clause,
",")
569 <<
" unit_ids=" << absl::StrJoin(unit_ids,
",") <<
" rat={"
570 << absl::StrJoin(rat,
" ") <<
"}";
571 if (lrat_checker_ !=
nullptr &&
572 !lrat_checker_->AddInferredClause(
id, clause, unit_ids, rat)) {
573 return LratError(absl::StrCat(
"AddInferredClause: id=",
id,
574 "\nliterals=", absl::StrJoin(clause,
","),
575 "\nunit_ids=", absl::StrJoin(unit_ids,
","),
576 "\nrat={", absl::StrJoin(rat,
" "),
"}"));
578 if (drat_checker_ !=
nullptr) {
579 if (all_problem_clauses_loaded_) {
580 drat_checker_->AddInferredClause(SortClauseForDrat(clause));
582 clauses_inferred_during_problem_loading_.push_back(
583 SortClauseForDrat(clause));
586 if (lrat_writer_ !=
nullptr) {
587 lrat_writer_->AddInferredClause(
id, clause, unit_ids, rat, exported);
589 if (drat_writer_ !=
nullptr) {
590 drat_writer_->AddClause(clause);
596 absl::Span<const Literal> clause) {
597 VLOG(2) <<
"AddImportedClause: id=" <<
id
598 <<
" literals=" << absl::StrJoin(clause,
",");
599 if (lrat_checker_ !=
nullptr &&
600 !lrat_checker_->AddProblemClause(
id, clause)) {
601 return LratError(
"In AddImportedClause");
603 if (drat_checker_ !=
nullptr) {
604 LOG(ERROR) <<
"Imported clauses are not supported by the DRAT checker.";
607 if (lrat_writer_ !=
nullptr) {
608 lrat_writer_->AddImportedClause(
id, clause);
614 absl::Span<const Literal> clause) {
615 VLOG(2) <<
"AddAssumedClause: id=" <<
id
616 <<
" literals=" << absl::StrJoin(clause,
",");
617 if (debug_crash_on_error_) {
618 LOG(FATAL) <<
"LRAT error: assumed clauses are not supposed to happen";
620 ++num_assumed_clauses_;
621 if (lrat_checker_ !=
nullptr &&
622 !lrat_checker_->AddProblemClause(
id, clause)) {
623 return LratError(
"In AddAssumedClause");
625 if (drat_checker_ !=
nullptr) {
628 LOG(ERROR) <<
"Assumed clauses are not supported by the DRAT checker.";
635 absl::Span<const Literal> clause) {
636 VLOG(2) <<
"ExportClause: id=" <<
id
637 <<
" literals=" << absl::StrJoin(clause,
",");
638 if (lrat_writer_ !=
nullptr) {
639 lrat_writer_->ExportClause(
id, clause);
645 absl::Span<const Literal> clause) {
648 pinned_clause_id_ = id;
649 if (drat_checker_ !=
nullptr || drat_writer_ !=
nullptr) {
650 pinned_clause_.assign(clause.begin(), clause.end());
652 delete_pinned_clause_ =
false;
657 DCHECK_EQ(pinned_clause_id_,
id);
659 if (delete_pinned_clause_) {
665 absl::Span<const Literal> clause) {
666 if (pinned_clause_id_ ==
id) {
667 delete_pinned_clause_ =
true;
670 VLOG(2) <<
"DeleteClause: id=" <<
id
671 <<
" literals=" << absl::StrJoin(clause,
",");
672 if (lrat_checker_ !=
nullptr) {
673 lrat_checker_->DeleteClauses({
id});
675 if (drat_checker_ !=
nullptr) {
676 drat_checker_->DeleteClause(clause);
678 if (lrat_writer_ !=
nullptr) {
679 lrat_writer_->DeleteClause(
id);
681 if (drat_writer_ !=
nullptr) {
682 drat_writer_->DeleteClause(clause);
687 if (lrat_checker_ !=
nullptr) {
688 if (lrat_checker_->Valid()) {
698 if (lrat_checker_ !=
nullptr) {
702 LOG(FATAL) <<
"LRAT error: " << lrat_checker_->error_message();
706 drat_checker_->Check(max_drat_time_in_seconds_);
708 LOG(FATAL) <<
"DRAT check failed";
714bool LratProofHandler::LratError(absl::string_view message)
const {
715 if (debug_crash_on_error_) {
716 LOG(FATAL) <<
"LRAT error: " << message
717 <<
"\nChecker_error:" << lrat_checker_->error_message();
725 const bool valid = model_is_unsat ?
Check() :
Valid();
726 proof_status_->NewSubsolverProofStatus(
730 if (lrat_checker_ !=
nullptr) {
731 lrat_checker_->AddStats();
733 if (lrat_writer_ !=
nullptr) {
734 proof_status_->NewProofFile(lrat_writer_->filename());
739 absl::Span<const Literal> new_clause,
740 absl::Span<const ClauseId> ids_for_proof,
742 CHECK_EQ(ids_for_proof.size(), clauses_for_proof.
size());
743 CHECK(!clauses_for_proof.
empty());
746 const auto error = [&,
this](absl::string_view message) {
747 if (debug_crash_on_error_) {
748 LOG(INFO) <<
"Proving " << new_clause;
749 for (
int i = 0;
i < ids_for_proof.size(); ++
i) {
750 LOG(INFO) <<
"input id= " << ids_for_proof[
i]
751 <<
" clause=" << clauses_for_proof[
i];
753 LOG(FATAL) << message;
755 VLOG(2) <<
"Proving " << new_clause;
756 for (
int i = 0;
i < ids_for_proof.size(); ++
i) {
757 VLOG(2) <<
"input id= " << ids_for_proof[
i]
758 <<
" clause=" << clauses_for_proof[
i];
768 absl::flat_hash_map<BooleanVariable, int> to_dense_index;
769 std::vector<Literal> dense_index_to_literal;
770 dense_index_to_literal.assign(new_clause.begin(), new_clause.end());
771 for (
const Literal lit : new_clause) {
772 const auto [it, inserted] =
773 to_dense_index.insert({lit.Variable(), to_dense_index.size()});
775 return error(
"Duplicate variable in new clause");
780 std::vector<Literal> relevant_literals;
781 for (
int i = 0;
i < clauses_for_proof.
size(); ++
i) {
782 for (
const Literal lit : clauses_for_proof[
i]) {
783 const auto [it, inserted] =
784 to_dense_index.insert({lit.Variable(), to_dense_index.size()});
786 relevant_literals.push_back(lit);
794 if (to_dense_index.size() > 6) {
795 return error(
"Too many variables");
804 const int n = to_dense_index.size() - new_clause.size();
805 CHECK_EQ(n, relevant_literals.size());
806 const int num_intermediates = 1 << (n + 1);
807 std::vector<ClauseId> ids(num_intermediates,
kNoClauseId);
809 VLOG(2) <<
"Starting proof n= " << n <<
" " << num_intermediates;
813 for (
int i = 0;
i < clauses_for_proof.
size(); ++
i) {
818 for (
const Literal lit : clauses_for_proof[
i]) {
819 const int dense_index = to_dense_index[lit.Variable()];
820 if (dense_index < new_clause.size()) {
823 if (lit != new_clause[dense_index]) {
828 k = std::max(k, dense_index);
829 mask |= 1 << dense_index;
830 if (lit == relevant_literals[dense_index - new_clause.size()]) {
831 base_index |= 1 << dense_index;
838 if (clauses_for_proof[
i].size() == new_clause.
size()) {
839 return ids_for_proof[
i];
844 const ClauseId new_id = id_generator_->GetNextId();
846 return error(
"failed trivial inclusion proof");
852 mask >>= new_clause.size();
853 base_index >>= new_clause.size();
854 k = k + 1 - new_clause.size();
856 VLOG(2) << k <<
" " << std::bitset<8>(mask) <<
" "
857 << std::bitset<8>(base_index);
860 for (
int m = 0; m < (1 << n); ++m) {
861 if ((m & mask) != base_index)
continue;
862 const int index = m | base_index;
863 for (
int j = k; j <= n; ++j) {
864 if (index >> j == 0) {
865 VLOG(2) <<
"Included in " << j <<
" "
866 << std::bitset<8>((1 << j) | index);
867 ids[(1 << j) | index] = ids_for_proof[
i];
874 std::vector<Literal> tmp_clause;
875 tmp_clause.assign(new_clause.begin(), new_clause.end());
876 std::vector<bool> id_need_deletion(num_intermediates,
false);
877 for (
int k = n; --k >= 0;) {
878 for (
int m = 0; m < (1 << k); ++m) {
879 const int index = (1 << k) | m;
883 tmp_clause.resize(new_clause.size());
884 for (
int i = 0;
i < k; ++
i) {
885 tmp_clause.push_back(relevant_literals[
i]);
886 if (((index >>
i) & 1) == 0) {
887 tmp_clause.back() = tmp_clause.back().Negated();
892 const int higher1 = index ^ ((0b11) << k);
893 const int higher2 = index ^ ((0b10) << k);
894 const ClauseId id1 = ids[higher1];
895 const ClauseId id2 = ids[higher2];
898 absl::StrCat(
"missing higher level clauses in the resolution.",
899 " index: ", std::bitset<8>(index).to_string(),
900 " higher1: ", std::bitset<8>(higher1).to_string(),
901 " higher2: ", std::bitset<8>(higher2).to_string()));
904 ids[index] = id_generator_->GetNextId();
906 VLOG(2) <<
"temporary !! " << ids[index] <<
" " << tmp_clause;
907 id_need_deletion[index] =
true;
910 return error(
"Failed resolution step");
914 DCHECK_EQ(new_clause, tmp_clause);
915 VLOG(2) <<
"Proven " << new_clause <<
"!";
919 if (id_need_deletion[higher1]) {
920 tmp_clause.push_back(relevant_literals[k].Negated());
921 VLOG(2) <<
"deleting: " << id1 <<
" " << tmp_clause;
923 tmp_clause.pop_back();
925 if (id_need_deletion[higher2]) {
926 tmp_clause.push_back(relevant_literals[k]);
927 VLOG(2) <<
"deleting: " << id2 <<
" " << tmp_clause;
929 tmp_clause.pop_back();
::int64_t clause_ids(int index) const
::google::protobuf::RepeatedField<::int64_t > *PROTOBUF_NONNULL mutable_clause_ids()
::int32_t literals(int index) const
::int64_t clause_id() const
void add_literals(::int32_t value)
void set_clause_id(::int64_t value)
void add_literals(::int32_t value)
::int32_t literals(int index) const
void set_clause_id(::int64_t value)
::int64_t clause_id() const
void set_resolvant_id(::int64_t value)
void add_unit_ids(::int64_t value)
void set_exported(bool value)
void set_clause_id(::int64_t value)
void add_unit_ids(::int64_t value)
::operations_research::sat::LratInferredClause_RatInfo *PROTOBUF_NONNULL add_rat_infos()
::int64_t clause_id() const
int literals_size() const
::int32_t literals(int index) const
LratInferredClause_RatInfo RatInfo
void add_literals(::int32_t value)
bool Merge(absl::Span< const std::string > proof_filenames)
void DeleteClause(ClauseId id, absl::Span< const Literal > clause)
bool ExportClause(ClauseId id, absl::Span< const Literal > clause)
bool AddProblemClause(ClauseId id, absl::Span< const Literal > clause)
DratChecker::Status Check()
void Close(bool model_is_unsat)
int64_t num_assumed_clauses() const
ClauseId AddAndProveInferredClauseByEnumeration(absl::Span< const Literal > new_clause, absl::Span< const ClauseId > ids_for_proof, const CompactVectorVector< int, Literal > &clauses_for_proof)
static std::unique_ptr< LratProofHandler > MaybeCreate(Model *model)
bool AddInferredClause(ClauseId id, absl::Span< const Literal > clause, absl::Span< const ClauseId > unit_ids, bool exported=false)
bool AddImportedClause(ClauseId id, absl::Span< const Literal > clause)
DratChecker::Status Valid() const
void PinClause(ClauseId id, absl::Span< const Literal > clause)
void UnpinClause(ClauseId id)
bool lrat_check_enabled() const
bool AddAssumedClause(ClauseId id, absl::Span< const Literal > clause)
bool drat_check_enabled() const
StepCase step_case() const
const ::operations_research::sat::LratDeletedClauses & deleted_clauses() const
const ::operations_research::sat::LratImportedClause & imported_clause() const
const ::operations_research::sat::LratInferredClause & inferred_clause() const
::operations_research::sat::LratImportedClause *PROTOBUF_NONNULL mutable_imported_clause()
::operations_research::sat::LratDeletedClauses *PROTOBUF_NONNULL mutable_deleted_clauses()
::operations_research::sat::LratExportedClause *PROTOBUF_NONNULL mutable_exported_clause()
const ::operations_research::sat::LratExportedClause & exported_clause() const
::operations_research::sat::LratInferredClause *PROTOBUF_NONNULL mutable_inferred_clause()
LratWriter(std::string_view filename)
void AddInferredClause(ClauseId id, absl::Span< const Literal > clause, absl::Span< const ClauseId > unit_ids, absl::Span< const LratChecker::RatIds > rat, bool exported=false)
void ExportClause(ClauseId id, absl::Span< const Literal > clause)
void DeleteClause(ClauseId id)
void AddImportedClause(ClauseId id, absl::Span< const Literal > clause)
std::string_view filename() const
bool WriteRecord(const google::protobuf::MessageLite &record)
double max_drat_time_in_seconds() const
bool output_lrat_proof() const
bool check_lrat_proof() const
bool check_drat_proof() const
bool output_drat_proof() const
bool check_merged_lrat_proof() const
bool debug_crash_if_lrat_check_fails() const
ABSL_FLAG(std::string, cp_model_drat_output, "/tmp/drat.txt", "File name for the generated DRAT proof, if DRAT output is enabled.")
constexpr ClauseId kNoClauseId(0)
ClosedInterval::Iterator end(ClosedInterval interval)
static int input(yyscan_t yyscanner)