Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
drat_proof_handler.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_SAT_DRAT_PROOF_HANDLER_H_
15#define OR_TOOLS_SAT_DRAT_PROOF_HANDLER_H_
16
17#include <memory>
18#include <vector>
19
20#if !defined(__PORTABLE_PLATFORM__)
21#include "ortools/base/file.h"
22#endif // !defined(__PORTABLE_PLATFORM__)
23#include "absl/types/span.h"
28
29namespace operations_research {
30namespace sat {
31
32// DRAT is a SAT proof format that allows a simple program to check that the
33// problem is really UNSAT. The description of the format and a checker are
34// available at: // http://www.cs.utexas.edu/~marijn/drat-trim/
35//
36// Note that DRAT proofs are often huge (can be GB), and take about as much time
37// to check as it takes for the solver to find the proof in the first place!
38//
39// This class is used to build the SAT proof, and can either save it to disk,
40// and/or store it in memory (in which case the proof can be checked when it is
41// complete).
43 public:
44 // Use this constructor to store the DRAT proof in memory. The proof will not
45 // be written to disk, and can be checked with Check() when it is complete.
47 // Use this constructor to write the DRAT proof to disk, and to optionally
48 // store it in memory as well (in which case the proof can be checked with
49 // Check() when it is complete).
50 DratProofHandler(bool in_binary_format, File* output, bool check = false);
51 ~DratProofHandler() = default;
52
53 // During the presolve step, variable get deleted and the set of non-deleted
54 // variable is remaped in a dense set. This allows to keep track of that and
55 // always output the DRAT clauses in term of the original variables. Must be
56 // called before adding or deleting clauses AddClause() or DeleteClause().
57 //
58 // TODO(user): This is exactly the same mecanism as in the SatPostsolver
59 // class. Factor out the code.
60 void ApplyMapping(const util_intops::StrongVector<BooleanVariable,
61 BooleanVariable>& mapping);
62
63 // This need to be called when new variables are created.
64 void SetNumVariables(int num_variables);
65 void AddOneVariable();
66
67 // Adds a clause of the UNSAT problem. This must be called before any call to
68 // AddClause() or DeleteClause(), in order to be able to check the DRAT proof
69 // with the Check() method when it is complete.
70 void AddProblemClause(absl::Span<const Literal> clause);
71
72 // Writes a new clause to the DRAT output. The output clause is sorted so that
73 // newer variables always comes first. This is needed because in the DRAT
74 // format, the clause is checked for the RAT property with only its first
75 // literal. Must not be called after Check().
76 void AddClause(absl::Span<const Literal> clause);
77
78 // Writes a "deletion" information about a clause that has been added before
79 // to the DRAT output. Note that it is also possible to delete a clause from
80 // the problem. Must not be called after Check().
81 //
82 // Because of a limitation a the DRAT-trim tool, it seems the order of the
83 // literals during addition and deletion should be EXACTLY the same. Because
84 // of this we get warnings for problem clauses.
85 void DeleteClause(absl::Span<const Literal> clause);
86
87 // Returns VALID if the DRAT proof is correct, INVALID if it is not correct,
88 // or UNKNOWN if proof checking was not enabled (by choosing the right
89 // constructor) or timed out. This requires the problem clauses to be
90 // specified with AddProblemClause(), before the proof itself.
91 //
92 // WARNING: no new clause must be added or deleted after this method has been
93 // called.
94 DratChecker::Status Check(double max_time_in_seconds);
95
96 private:
97 void MapClause(absl::Span<const Literal> clause);
98
99 // We need to keep track of the variable newly created.
100 int variable_index_;
101
102 // Temporary vector used for sorting the outputted clauses.
103 std::vector<Literal> values_;
104
105 // This mapping will be applied to all clause passed to AddClause() or
106 // DeleteClause() so that they are in term of the original problem.
108
109 std::unique_ptr<DratChecker> drat_checker_;
110 std::unique_ptr<DratWriter> drat_writer_;
111};
112
113} // namespace sat
114} // namespace operations_research
115
116#endif // OR_TOOLS_SAT_DRAT_PROOF_HANDLER_H_
Definition file.h:30
DratChecker::Status Check(double max_time_in_seconds)
void AddProblemClause(absl::Span< const Literal > clause)
void ApplyMapping(const util_intops::StrongVector< BooleanVariable, BooleanVariable > &mapping)
void AddClause(absl::Span< const Literal > clause)
void DeleteClause(absl::Span< const Literal > clause)
void SetNumVariables(int num_variables)
This need to be called when new variables are created.
In SWIG mode, we don't want anything besides these top-level includes.