OR-Tools  8.1
drat_checker.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 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 
15 
16 #include <algorithm>
17 #include <fstream>
18 
19 #include "absl/strings/numbers.h"
20 #include "absl/strings/str_split.h"
21 #include "absl/time/clock.h"
22 #include "ortools/base/hash.h"
23 #include "ortools/base/stl_util.h"
25 
26 namespace operations_research {
27 namespace sat {
28 
29 DratChecker::Clause::Clause(int first_literal_index, int num_literals)
30  : first_literal_index(first_literal_index), num_literals(num_literals) {}
31 
32 std::size_t DratChecker::ClauseHash::operator()(
33  const ClauseIndex clause_index) const {
34  size_t hash = 0;
35  for (Literal literal : checker->Literals(checker->clauses_[clause_index])) {
36  hash = util_hash::Hash(literal.Index().value(), hash);
37  }
38  return hash;
39 }
40 
41 bool DratChecker::ClauseEquiv::operator()(
42  const ClauseIndex clause_index1, const ClauseIndex clause_index2) const {
43  return checker->Literals(checker->clauses_[clause_index1]) ==
44  checker->Literals(checker->clauses_[clause_index2]);
45 }
46 
48  : first_infered_clause_index_(kNoClauseIndex),
49  clause_set_(0, ClauseHash(this), ClauseEquiv(this)),
50  num_variables_(0) {}
51 
52 bool DratChecker::Clause::IsDeleted(ClauseIndex clause_index) const {
53  return deleted_index <= clause_index;
54 }
55 
56 void DratChecker::AddProblemClause(absl::Span<const Literal> clause) {
57  DCHECK_EQ(first_infered_clause_index_, kNoClauseIndex);
58  const ClauseIndex clause_index = AddClause(clause);
59 
60  const auto it = clause_set_.find(clause_index);
61  if (it != clause_set_.end()) {
62  clauses_[*it].num_copies += 1;
63  RemoveLastClause();
64  } else {
65  clause_set_.insert(clause_index);
66  }
67 }
68 
69 void DratChecker::AddInferedClause(absl::Span<const Literal> clause) {
70  const ClauseIndex infered_clause_index = AddClause(clause);
71  if (first_infered_clause_index_ == kNoClauseIndex) {
72  first_infered_clause_index_ = infered_clause_index;
73  }
74 
75  const auto it = clause_set_.find(infered_clause_index);
76  if (it != clause_set_.end()) {
77  clauses_[*it].num_copies += 1;
78  if (*it >= first_infered_clause_index_ && !clause.empty()) {
79  CHECK_EQ(clauses_[*it].rat_literal_index, clause[0].Index());
80  }
81  RemoveLastClause();
82  } else {
83  clauses_[infered_clause_index].rat_literal_index =
84  clause.empty() ? kNoLiteralIndex : clause[0].Index();
85  clause_set_.insert(infered_clause_index);
86  }
87 }
88 
89 ClauseIndex DratChecker::AddClause(absl::Span<const Literal> clause) {
90  const int first_literal_index = literals_.size();
91  literals_.insert(literals_.end(), clause.begin(), clause.end());
92  // Sort the input clause in strictly increasing order (by sorting and then
93  // removing the duplicate literals).
94  std::sort(literals_.begin() + first_literal_index, literals_.end());
95  literals_.erase(
96  std::unique(literals_.begin() + first_literal_index, literals_.end()),
97  literals_.end());
98 
99  for (int i = first_literal_index + 1; i < literals_.size(); ++i) {
100  CHECK(literals_[i] != literals_[i - 1].Negated());
101  }
102  clauses_.push_back(
103  Clause(first_literal_index, literals_.size() - first_literal_index));
104  if (!clause.empty()) {
105  num_variables_ =
106  std::max(num_variables_, literals_.back().Variable().value() + 1);
107  }
108  return ClauseIndex(clauses_.size() - 1);
109 }
110 
111 void DratChecker::DeleteClause(absl::Span<const Literal> clause) {
112  // Temporarily add 'clause' to find if it has been previously added.
113  const auto it = clause_set_.find(AddClause(clause));
114  if (it != clause_set_.end()) {
115  Clause& existing_clause = clauses_[*it];
116  existing_clause.num_copies -= 1;
117  if (existing_clause.num_copies == 0) {
118  DCHECK(existing_clause.deleted_index == std::numeric_limits<int>::max());
119  existing_clause.deleted_index = clauses_.size() - 1;
120  if (clauses_.back().num_literals >= 2) {
121  clauses_[ClauseIndex(clauses_.size() - 2)].deleted_clauses.push_back(
122  *it);
123  }
124  clause_set_.erase(it);
125  }
126  } else {
127  LOG(WARNING) << "Couldn't find deleted clause";
128  }
129  // Delete 'clause' and its literals.
130  RemoveLastClause();
131 }
132 
133 void DratChecker::RemoveLastClause() {
134  literals_.resize(clauses_.back().first_literal_index);
135  clauses_.pop_back();
136 }
137 
138 // See Algorithm of Fig. 8 in 'Trimming while Checking Clausal Proofs'.
139 DratChecker::Status DratChecker::Check(double max_time_in_seconds) {
140  // First check that the last infered clause is empty (this implies there
141  // should be at least one infered clause), and mark it as needed for the
142  // proof.
143  if (clauses_.empty() || first_infered_clause_index_ == kNoClauseIndex ||
144  clauses_.back().num_literals != 0) {
145  return Status::INVALID;
146  }
147  clauses_.back().is_needed_for_proof = true;
148 
149  // Checks the infered clauses in reversed order. The advantage of this order
150  // is that when checking a clause, one can mark all the clauses that are used
151  // to check it. In turn, only these marked clauses need to be checked (and so
152  // on recursively). By contrast, a forward iteration needs to check all the
153  // clauses.
154  const int64 start_time_nanos = absl::GetCurrentTimeNanos();
155  TimeLimit time_limit(max_time_in_seconds);
156  Init();
157  for (ClauseIndex i(clauses_.size() - 1); i >= first_infered_clause_index_;
158  --i) {
159  if (time_limit.LimitReached()) {
160  return Status::UNKNOWN;
161  }
162  const Clause& clause = clauses_[i];
163  // Start watching the literals of the clauses that were deleted just after
164  // this one, and which are now no longer deleted.
165  for (const ClauseIndex j : clause.deleted_clauses) {
166  WatchClause(j);
167  }
168  if (!clause.is_needed_for_proof) {
169  continue;
170  }
171  // 'clause' must have either the Reverse Unit Propagation (RUP) property:
172  if (HasRupProperty(i, Literals(clause))) {
173  continue;
174  }
175  // or the Reverse Asymetric Tautology (RAT) property. This property is
176  // defined by the fact that all clauses which contain the negation of
177  // the RAT literal of 'clause', after resolution with 'clause', must have
178  // the RUP property.
179  // Note from 'DRAT-trim: Efficient Checking and Trimming Using Expressive
180  // Clausal Proofs': "[in order] to access to all clauses containing the
181  // negation of the resolution literal, one could build a literal-to-clause
182  // lookup table of the original formula and update it after each lemma
183  // addition and deletion step. However, these updates can be expensive and
184  // the lookup table potentially doubles the memory usage of the tool.
185  // Since most lemmas emitted by state-of-the-art SAT solvers can be
186  // validated using the RUP check, such a lookup table has been omitted."
187  if (clause.rat_literal_index == kNoLiteralIndex) return Status::INVALID;
188  ++num_rat_checks_;
189  std::vector<Literal> resolvent;
190  for (ClauseIndex j(0); j < i; ++j) {
191  if (!clauses_[j].IsDeleted(i) &&
192  ContainsLiteral(Literals(clauses_[j]),
193  Literal(clause.rat_literal_index).Negated())) {
194  // Check that the resolvent has the RUP property.
195  if (!Resolve(Literals(clause), Literals(clauses_[j]),
196  Literal(clause.rat_literal_index), &tmp_assignment_,
197  &resolvent) ||
198  !HasRupProperty(i, resolvent)) {
199  return Status::INVALID;
200  }
201  }
202  }
203  }
204  LogStatistics(absl::GetCurrentTimeNanos() - start_time_nanos);
205  return Status::VALID;
206 }
207 
208 std::vector<std::vector<Literal>> DratChecker::GetUnsatSubProblem() const {
209  return GetClausesNeededForProof(ClauseIndex(0), first_infered_clause_index_);
210 }
211 
212 std::vector<std::vector<Literal>> DratChecker::GetOptimizedProof() const {
213  return GetClausesNeededForProof(first_infered_clause_index_,
214  ClauseIndex(clauses_.size()));
215 }
216 
217 std::vector<std::vector<Literal>> DratChecker::GetClausesNeededForProof(
218  ClauseIndex begin, ClauseIndex end) const {
219  std::vector<std::vector<Literal>> result;
220  for (ClauseIndex i = begin; i < end; ++i) {
221  const Clause& clause = clauses_[i];
222  if (clause.is_needed_for_proof) {
223  const absl::Span<const Literal>& literals = Literals(clause);
224  result.emplace_back(literals.begin(), literals.end());
225  if (clause.rat_literal_index != kNoLiteralIndex) {
226  const int rat_literal_clause_index =
227  std::find(literals.begin(), literals.end(),
228  Literal(clause.rat_literal_index)) -
229  literals.begin();
230  std::swap(result.back()[0], result.back()[rat_literal_clause_index]);
231  }
232  }
233  }
234  return result;
235 }
236 
237 absl::Span<const Literal> DratChecker::Literals(const Clause& clause) const {
238  return absl::Span<const Literal>(
239  literals_.data() + clause.first_literal_index, clause.num_literals);
240 }
241 
242 void DratChecker::Init() {
243  assigned_.clear();
244  assignment_.Resize(num_variables_);
245  assignment_source_.resize(num_variables_, kNoClauseIndex);
246  high_priority_literals_to_assign_.clear();
247  low_priority_literals_to_assign_.clear();
248  watched_literals_.clear();
249  watched_literals_.resize(2 * num_variables_);
250  single_literal_clauses_.clear();
251  unit_stack_.clear();
252  tmp_assignment_.Resize(num_variables_);
253  num_rat_checks_ = 0;
254 
255  for (ClauseIndex clause_index(0); clause_index < clauses_.size();
256  ++clause_index) {
257  Clause& clause = clauses_[clause_index];
258  if (clause.num_literals >= 2) {
259  // Don't watch the literals of the deleted clauses right away, instead
260  // watch them when these clauses become 'undeleted' in backward checking.
261  if (clause.deleted_index == std::numeric_limits<int>::max()) {
262  WatchClause(clause_index);
263  }
264  } else if (clause.num_literals == 1) {
265  single_literal_clauses_.push_back(clause_index);
266  }
267  }
268 }
269 
270 void DratChecker::WatchClause(ClauseIndex clause_index) {
271  const Literal* clause_literals =
272  literals_.data() + clauses_[clause_index].first_literal_index;
273  watched_literals_[clause_literals[0].Index()].push_back(clause_index);
274  watched_literals_[clause_literals[1].Index()].push_back(clause_index);
275 }
276 
277 bool DratChecker::HasRupProperty(ClauseIndex num_clauses,
278  absl::Span<const Literal> clause) {
279  ClauseIndex conflict = kNoClauseIndex;
280  for (const Literal literal : clause) {
281  conflict =
282  AssignAndPropagate(num_clauses, literal.Negated(), kNoClauseIndex);
283  if (conflict != kNoClauseIndex) {
284  break;
285  }
286  }
287 
288  for (const ClauseIndex clause_index : single_literal_clauses_) {
289  const Clause& clause = clauses_[clause_index];
290  // TODO(user): consider ignoring the deletion of single literal clauses
291  // as done in drat-trim.
292  if (clause_index < num_clauses && !clause.IsDeleted(num_clauses)) {
293  if (clause.is_needed_for_proof) {
294  high_priority_literals_to_assign_.push_back(
295  {literals_[clause.first_literal_index], clause_index});
296  } else {
297  low_priority_literals_to_assign_.push_back(
298  {literals_[clause.first_literal_index], clause_index});
299  }
300  }
301  }
302 
303  while (!(high_priority_literals_to_assign_.empty() &&
304  low_priority_literals_to_assign_.empty()) &&
305  conflict == kNoClauseIndex) {
306  std::vector<LiteralToAssign>& stack =
307  high_priority_literals_to_assign_.empty()
308  ? low_priority_literals_to_assign_
309  : high_priority_literals_to_assign_;
310  const LiteralToAssign literal_to_assign = stack.back();
311  stack.pop_back();
312  if (assignment_.LiteralIsAssigned(literal_to_assign.literal)) {
313  // If the literal to assign to true is already assigned to false, we found
314  // a conflict, with the source clause of this previous assignment.
315  if (assignment_.LiteralIsFalse(literal_to_assign.literal)) {
316  conflict = literal_to_assign.source_clause_index;
317  break;
318  } else {
319  continue;
320  }
321  }
322  DCHECK(literal_to_assign.source_clause_index != kNoClauseIndex);
323  unit_stack_.push_back(literal_to_assign.source_clause_index);
324  conflict = AssignAndPropagate(num_clauses, literal_to_assign.literal,
325  literal_to_assign.source_clause_index);
326  }
327  if (conflict != kNoClauseIndex) {
328  MarkAsNeededForProof(&clauses_[conflict]);
329  }
330 
331  for (const Literal literal : assigned_) {
332  assignment_.UnassignLiteral(literal);
333  }
334  assigned_.clear();
335  high_priority_literals_to_assign_.clear();
336  low_priority_literals_to_assign_.clear();
337  unit_stack_.clear();
338 
339  return conflict != kNoClauseIndex;
340 }
341 
342 ClauseIndex DratChecker::AssignAndPropagate(ClauseIndex num_clauses,
343  Literal literal,
344  ClauseIndex source_clause_index) {
345  assigned_.push_back(literal);
346  assignment_.AssignFromTrueLiteral(literal);
347  assignment_source_[literal.Variable()] = source_clause_index;
348 
349  const Literal false_literal = literal.Negated();
350  std::vector<ClauseIndex>& watched = watched_literals_[false_literal.Index()];
351  int new_watched_size = 0;
352  ClauseIndex conflict_index = kNoClauseIndex;
353  for (const ClauseIndex clause_index : watched) {
354  if (clause_index >= num_clauses) {
355  // Stop watching the literals of clauses which cannot possibly be
356  // necessary to check the rest of the proof.
357  continue;
358  }
359  Clause& clause = clauses_[clause_index];
360  DCHECK(!clause.IsDeleted(num_clauses));
361  if (conflict_index != kNoClauseIndex) {
362  watched[new_watched_size++] = clause_index;
363  continue;
364  }
365 
366  Literal* clause_literals = literals_.data() + clause.first_literal_index;
367  const Literal other_watched_literal(LiteralIndex(
368  clause_literals[0].Index().value() ^
369  clause_literals[1].Index().value() ^ false_literal.Index().value()));
370  if (assignment_.LiteralIsTrue(other_watched_literal)) {
371  watched[new_watched_size++] = clause_index;
372  continue;
373  }
374 
375  bool new_watched_literal_found = false;
376  for (int i = 2; i < clause.num_literals; ++i) {
377  if (!assignment_.LiteralIsFalse(clause_literals[i])) {
378  clause_literals[0] = other_watched_literal;
379  clause_literals[1] = clause_literals[i];
380  clause_literals[i] = false_literal;
381  watched_literals_[clause_literals[1].Index()].push_back(clause_index);
382  new_watched_literal_found = true;
383  break;
384  }
385  }
386 
387  if (!new_watched_literal_found) {
388  if (assignment_.LiteralIsFalse(other_watched_literal)) {
389  // 'clause' is falsified with 'assignment_', we found a conflict.
390  // TODO(user): test moving the rest of the vector here and
391  // returning right away.
392  conflict_index = clause_index;
393  } else {
394  DCHECK(!assignment_.LiteralIsAssigned(other_watched_literal));
395  // 'clause' is unit, push its unit literal on
396  // 'literals_to_assign_high_priority' or
397  // 'literals_to_assign_low_priority' to assign it to true and propagate
398  // it in a later call to AssignAndPropagate().
399  if (clause.is_needed_for_proof) {
400  high_priority_literals_to_assign_.push_back(
401  {other_watched_literal, clause_index});
402  } else {
403  low_priority_literals_to_assign_.push_back(
404  {other_watched_literal, clause_index});
405  }
406  }
407  watched[new_watched_size++] = clause_index;
408  }
409  }
410  watched.resize(new_watched_size);
411  return conflict_index;
412 }
413 
414 void DratChecker::MarkAsNeededForProof(Clause* clause) {
415  const auto mark_clause_and_sources = [&](Clause* clause) {
416  clause->is_needed_for_proof = true;
417  for (const Literal literal : Literals(*clause)) {
418  const ClauseIndex source_clause_index =
419  assignment_source_[literal.Variable()];
420  if (source_clause_index != kNoClauseIndex) {
421  clauses_[source_clause_index].tmp_is_needed_for_proof_step = true;
422  }
423  }
424  };
425  mark_clause_and_sources(clause);
426  for (int i = unit_stack_.size() - 1; i >= 0; --i) {
427  Clause& unit_clause = clauses_[unit_stack_[i]];
428  if (unit_clause.tmp_is_needed_for_proof_step) {
429  mark_clause_and_sources(&unit_clause);
430  // We can clean this flag here without risking missing clauses needed for
431  // the proof, because the clauses needed for a clause C are always lower
432  // than C in the stack.
433  unit_clause.tmp_is_needed_for_proof_step = false;
434  }
435  }
436 }
437 
438 void DratChecker::LogStatistics(int64 duration_nanos) const {
439  int problem_clauses_needed_for_proof = 0;
440  int infered_clauses_needed_for_proof = 0;
441  for (ClauseIndex i(0); i < clauses_.size(); ++i) {
442  if (clauses_[i].is_needed_for_proof) {
443  if (i < first_infered_clause_index_) {
444  ++problem_clauses_needed_for_proof;
445  } else {
446  ++infered_clauses_needed_for_proof;
447  }
448  }
449  }
450  LOG(INFO) << problem_clauses_needed_for_proof
451  << " problem clauses needed for proof, out of "
452  << first_infered_clause_index_;
453  LOG(INFO) << infered_clauses_needed_for_proof
454  << " infered clauses needed for proof, out of "
455  << clauses_.size() - first_infered_clause_index_;
456  LOG(INFO) << num_rat_checks_ << " RAT infered clauses";
457  LOG(INFO) << "verification time: " << 1e-9 * duration_nanos << " s";
458 }
459 
460 bool ContainsLiteral(absl::Span<const Literal> clause, Literal literal) {
461  return std::find(clause.begin(), clause.end(), literal) != clause.end();
462 }
463 
464 bool Resolve(absl::Span<const Literal> clause,
465  absl::Span<const Literal> other_clause,
466  Literal complementary_literal, VariablesAssignment* assignment,
467  std::vector<Literal>* resolvent) {
468  DCHECK(ContainsLiteral(clause, complementary_literal));
469  DCHECK(ContainsLiteral(other_clause, complementary_literal.Negated()));
470  resolvent->clear();
471 
472  for (const Literal literal : clause) {
473  if (literal != complementary_literal) {
474  // Temporary assignment used to do the checks below in linear time.
475  assignment->AssignFromTrueLiteral(literal);
476  resolvent->push_back(literal);
477  }
478  }
479 
480  bool result = true;
481  for (const Literal other_literal : other_clause) {
482  if (other_literal != complementary_literal.Negated()) {
483  if (assignment->LiteralIsFalse(other_literal)) {
484  result = false;
485  break;
486  } else if (!assignment->LiteralIsAssigned(other_literal)) {
487  resolvent->push_back(other_literal);
488  }
489  }
490  }
491 
492  // Revert the temporary assignment done above.
493  for (const Literal literal : clause) {
494  if (literal != complementary_literal) {
495  assignment->UnassignLiteral(literal);
496  }
497  }
498  return result;
499 }
500 
501 bool AddProblemClauses(const std::string& file_path,
502  DratChecker* drat_checker) {
503  int line_number = 0;
504  int num_variables = 0;
505  int num_clauses = 0;
506  std::vector<Literal> literals;
507  std::ifstream file(file_path);
508  std::string line;
509  bool result = true;
510  while (std::getline(file, line)) {
511  line_number++;
512  std::vector<absl::string_view> words =
513  absl::StrSplit(line, absl::ByAnyChar(" \t"), absl::SkipWhitespace());
514  if (words.empty() || words[0] == "c") {
515  // Ignore empty and comment lines.
516  continue;
517  }
518  if (words[0] == "p") {
519  if (num_clauses > 0 || words.size() != 4 || words[1] != "cnf" ||
520  !absl::SimpleAtoi(words[2], &num_variables) || num_variables <= 0 ||
521  !absl::SimpleAtoi(words[3], &num_clauses) || num_clauses <= 0) {
522  LOG(ERROR) << "Invalid content '" << line << "' at line " << line_number
523  << " of " << file_path;
524  result = false;
525  break;
526  }
527  continue;
528  }
529  literals.clear();
530  for (int i = 0; i < words.size(); ++i) {
531  int signed_value;
532  if (!absl::SimpleAtoi(words[i], &signed_value) ||
533  std::abs(signed_value) > num_variables ||
534  (signed_value == 0 && i != words.size() - 1)) {
535  LOG(ERROR) << "Invalid content '" << line << "' at line " << line_number
536  << " of " << file_path;
537  result = false;
538  break;
539  }
540  if (signed_value != 0) {
541  literals.push_back(Literal(signed_value));
542  }
543  }
544  drat_checker->AddProblemClause(literals);
545  }
546  file.close();
547  return result;
548 }
549 
550 bool AddInferedAndDeletedClauses(const std::string& file_path,
551  DratChecker* drat_checker) {
552  int line_number = 0;
553  bool ends_with_empty_clause = false;
554  std::vector<Literal> literals;
555  std::ifstream file(file_path);
556  std::string line;
557  bool result = true;
558  while (std::getline(file, line)) {
559  line_number++;
560  std::vector<absl::string_view> words =
561  absl::StrSplit(line, absl::ByAnyChar(" \t"), absl::SkipWhitespace());
562  bool delete_clause = !words.empty() && words[0] == "d";
563  literals.clear();
564  for (int i = (delete_clause ? 1 : 0); i < words.size(); ++i) {
565  int signed_value;
566  if (!absl::SimpleAtoi(words[i], &signed_value) ||
567  (signed_value == 0 && i != words.size() - 1)) {
568  LOG(ERROR) << "Invalid content '" << line << "' at line " << line_number
569  << " of " << file_path;
570  result = false;
571  break;
572  }
573  if (signed_value != 0) {
574  literals.push_back(Literal(signed_value));
575  }
576  }
577  if (delete_clause) {
578  drat_checker->DeleteClause(literals);
579  ends_with_empty_clause = false;
580  } else {
581  drat_checker->AddInferedClause(literals);
582  ends_with_empty_clause = literals.empty();
583  }
584  }
585  if (!ends_with_empty_clause) {
586  drat_checker->AddInferedClause({});
587  }
588  file.close();
589  return result;
590 }
591 
592 bool PrintClauses(const std::string& file_path, SatFormat format,
593  const std::vector<std::vector<Literal>>& clauses,
594  int num_variables) {
595  std::ofstream output_stream(file_path, std::ofstream::out);
596  if (format == DIMACS) {
597  output_stream << "p cnf " << num_variables << " " << clauses.size() << "\n";
598  }
599  for (const auto& clause : clauses) {
600  for (Literal literal : clause) {
601  output_stream << literal.SignedValue() << " ";
602  }
603  output_stream << "0\n";
604  }
605  output_stream.close();
606  return output_stream.good();
607 }
608 
609 } // namespace sat
610 } // namespace operations_research
INFO
const int INFO
Definition: log_severity.h:31
operations_research::sat::DratChecker::DratChecker
DratChecker()
Definition: drat_checker.cc:47
absl::StrongVector::push_back
void push_back(const value_type &x)
Definition: strong_vector.h:158
max
int64 max
Definition: alldiff_cst.cc:139
operations_research::sat::VariablesAssignment::AssignFromTrueLiteral
void AssignFromTrueLiteral(Literal literal)
Definition: sat_base.h:133
time_limit.h
LOG
#define LOG(severity)
Definition: base/logging.h:420
absl::StrongVector::size
size_type size() const
Definition: strong_vector.h:147
ERROR
const int ERROR
Definition: log_severity.h:32
operations_research::sat::kNoLiteralIndex
const LiteralIndex kNoLiteralIndex(-1)
operations_research::sat::DratChecker::AddInferedClause
void AddInferedClause(absl::Span< const Literal > clause)
Definition: drat_checker.cc:69
hash
int64 hash
Definition: matrix_utils.cc:60
value
int64 value
Definition: demon_profiler.cc:43
operations_research::sat::VariablesAssignment::UnassignLiteral
void UnassignLiteral(Literal literal)
Definition: sat_base.h:140
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::sat::VariablesAssignment::LiteralIsTrue
bool LiteralIsTrue(Literal literal) const
Definition: sat_base.h:150
WARNING
const int WARNING
Definition: log_severity.h:31
operations_research::sat::UNKNOWN
@ UNKNOWN
Definition: cp_model.pb.h:223
operations_research::sat::DratChecker::AddProblemClause
void AddProblemClause(absl::Span< const Literal > clause)
Definition: drat_checker.cc:56
operations_research::sat::DratChecker::Check
Status Check(double max_time_in_seconds)
Definition: drat_checker.cc:139
int64
int64_t int64
Definition: integral_types.h:34
operations_research::sat::Literal::Negated
Literal Negated() const
Definition: sat_base.h:91
operations_research::TimeLimit
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:105
operations_research::sat::DratChecker::DeleteClause
void DeleteClause(absl::Span< const Literal > clause)
Definition: drat_checker.cc:111
operations_research::sat::Literal::SignedValue
int SignedValue() const
Definition: sat_base.h:87
operations_research::sat::ContainsLiteral
bool ContainsLiteral(absl::Span< const Literal > clause, Literal literal)
Definition: drat_checker.cc:460
operations_research::sat::VariablesAssignment::Resize
void Resize(int num_variables)
Definition: sat_base.h:126
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2103
operations_research::sat::AddProblemClauses
bool AddProblemClauses(const std::string &file_path, DratChecker *drat_checker)
Definition: drat_checker.cc:501
absl::StrongVector::pop_back
void pop_back()
Definition: strong_vector.h:168
CHECK_EQ
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:697
operations_research::sat::Resolve
bool Resolve(absl::Span< const Literal > clause, absl::Span< const Literal > other_clause, Literal complementary_literal, VariablesAssignment *assignment, std::vector< Literal > *resolvent)
Definition: drat_checker.cc:464
operations_research::sat::Literal::Index
LiteralIndex Index() const
Definition: sat_base.h:84
drat_checker.h
operations_research::sat::DratChecker::GetOptimizedProof
std::vector< std::vector< Literal > > GetOptimizedProof() const
Definition: drat_checker.cc:212
operations_research::sat::DratChecker::Status
Status
Definition: drat_checker.h:76
DCHECK
#define DCHECK(condition)
Definition: base/logging.h:884
operations_research::sat::DIMACS
@ DIMACS
Definition: drat_checker.h:327
operations_research::sat::kNoClauseIndex
const ClauseIndex kNoClauseIndex(-1)
absl::StrongVector::clear
void clear()
Definition: strong_vector.h:170
operations_research::sat::Literal
Definition: sat_base.h:64
operations_research::sat::AddInferedAndDeletedClauses
bool AddInferedAndDeletedClauses(const std::string &file_path, DratChecker *drat_checker)
Definition: drat_checker.cc:550
stl_util.h
operations_research::sat::DratChecker::GetUnsatSubProblem
std::vector< std::vector< Literal > > GetUnsatSubProblem() const
Definition: drat_checker.cc:208
file
Definition: file.cc:141
absl::StrongVector::back
reference back()
Definition: strong_vector.h:174
DCHECK_EQ
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:885
hash.h
absl::StrongVector::resize
void resize(size_type new_size)
Definition: strong_vector.h:150
operations_research::sat::SatFormat
SatFormat
Definition: drat_checker.h:326
operations_research::glop::Index
int32 Index
Definition: lp_types.h:37
literal
Literal literal
Definition: optimization.cc:84
operations_research::sat::VariablesAssignment
Definition: sat_base.h:122
absl::StrongVector::empty
bool empty() const
Definition: strong_vector.h:156
CHECK
#define CHECK(condition)
Definition: base/logging.h:495
util_hash::Hash
uint64 Hash(uint64 num, uint64 c)
Definition: hash.h:150
operations_research::sat::VariablesAssignment::LiteralIsAssigned
bool LiteralIsAssigned(Literal literal) const
Definition: sat_base.h:153
operations_research::sat::VariablesAssignment::LiteralIsFalse
bool LiteralIsFalse(Literal literal) const
Definition: sat_base.h:147
operations_research::sat::PrintClauses
bool PrintClauses(const std::string &file_path, SatFormat format, const std::vector< std::vector< Literal >> &clauses, int num_variables)
Definition: drat_checker.cc:592
operations_research::sat::DratChecker
Definition: drat_checker.h:40