OR-Tools  9.3
sat_solver.h
Go to the documentation of this file.
1// Copyright 2010-2021 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// This file implements a SAT solver.
15// see http://en.wikipedia.org/wiki/Boolean_satisfiability_problem
16// for more detail.
17// TODO(user): Expand.
18
19#ifndef OR_TOOLS_SAT_SAT_SOLVER_H_
20#define OR_TOOLS_SAT_SAT_SOLVER_H_
21
22#include <cstdint>
23#include <functional>
24#include <limits>
25#include <memory>
26#include <string>
27#include <utility>
28#include <vector>
29
30#include "absl/container/flat_hash_map.h"
31#include "absl/strings/string_view.h"
32#include "absl/types/span.h"
33#include "ortools/base/hash.h"
36#include "ortools/base/macros.h"
37#include "ortools/base/timer.h"
38#include "ortools/sat/clause.h"
40#include "ortools/sat/model.h"
42#include "ortools/sat/restart.h"
45#include "ortools/sat/sat_parameters.pb.h"
46#include "ortools/util/bitset.h"
48#include "ortools/util/stats.h"
51
52namespace operations_research {
53namespace sat {
54
55// A constant used by the EnqueueDecision*() API.
56const int kUnsatTrailIndex = -1;
57
58// The main SAT solver.
59// It currently implements the CDCL algorithm. See
60// http://en.wikipedia.org/wiki/Conflict_Driven_Clause_Learning
61class SatSolver {
62 public:
63 SatSolver();
64 explicit SatSolver(Model* model);
65 ~SatSolver();
66
67 // TODO(user): Remove. This is temporary for accessing the model deep within
68 // some old code that didn't use the Model object.
69 Model* model() { return model_; }
70
71 // Parameters management. Note that calling SetParameters() will reset the
72 // value of many heuristics. For instance:
73 // - The restart strategy will be reinitialized.
74 // - The random seed and random generator will be reset to the value given in
75 // parameters.
76 // - The global TimeLimit singleton will be reset and time will be
77 // counted from this call.
78 void SetParameters(const SatParameters& parameters);
79 const SatParameters& parameters() const;
80
81 // Increases the number of variables of the current problem.
82 //
83 // TODO(user): Rename to IncreaseNumVariablesTo() until we support removing
84 // variables...
85 void SetNumVariables(int num_variables);
86 int NumVariables() const { return num_variables_.value(); }
87 BooleanVariable NewBooleanVariable() {
88 const int num_vars = NumVariables();
89
90 // We need to be able to encode the variable as a literal.
92 SetNumVariables(num_vars + 1);
93 return BooleanVariable(num_vars);
94 }
95
96 // Fixes a variable so that the given literal is true. This can be used to
97 // solve a subproblem where some variables are fixed. Note that it is more
98 // efficient to add such unit clause before all the others.
99 // Returns false if the problem is detected to be UNSAT.
100 bool AddUnitClause(Literal true_literal);
101
102 // Same as AddProblemClause() below, but for small clauses.
105
106 // Adds a clause to the problem. Returns false if the problem is detected to
107 // be UNSAT.
108 //
109 // TODO(user): Rename this to AddClause(), also get rid of the specialized
110 // AddUnitClause(), AddBinaryClause() and AddTernaryClause() since they
111 // just end up calling this?
112 bool AddProblemClause(absl::Span<const Literal> literals);
113
114 // Adds a pseudo-Boolean constraint to the problem. Returns false if the
115 // problem is detected to be UNSAT. If the constraint is always true, this
116 // detects it and does nothing.
117 //
118 // Note(user): There is an optimization if the same constraint is added
119 // consecutively (even if the bounds are different). This is particularly
120 // useful for an optimization problem when we want to constrain the objective
121 // of the problem more and more. Just re-adding such constraint is relatively
122 // efficient.
123 //
124 // OVERFLOW: The sum of the absolute value of all the coefficients
125 // in the constraint must not overflow. This is currently CHECKed().
126 // TODO(user): Instead of failing, implement an error handling code.
127 bool AddLinearConstraint(bool use_lower_bound, Coefficient lower_bound,
128 bool use_upper_bound, Coefficient upper_bound,
129 std::vector<LiteralWithCoeff>* cst);
130
131 // Returns true if the model is UNSAT. Note that currently the status is
132 // "sticky" and once this happen, nothing else can be done with the solver.
133 //
134 // Thanks to this function, a client can safely ignore the return value of any
135 // Add*() functions. If one of them return false, then IsModelUnsat() will
136 // return true.
137 //
138 // TODO(user): Rename to ModelIsUnsat().
139 bool IsModelUnsat() const { return model_is_unsat_; }
140
141 // Adds and registers the given propagator with the sat solver. Note that
142 // during propagation, they will be called in the order they were added.
143 void AddPropagator(SatPropagator* propagator);
144 void AddLastPropagator(SatPropagator* propagator);
145 void TakePropagatorOwnership(std::unique_ptr<SatPropagator> propagator) {
146 owned_propagators_.push_back(std::move(propagator));
147 }
148
149 // Wrapper around the same functions in SatDecisionPolicy.
150 //
151 // TODO(user): Clean this up by making clients directly talk to
152 // SatDecisionPolicy.
154 decision_policy_->SetAssignmentPreference(literal, weight);
155 }
156 std::vector<std::pair<Literal, double>> AllPreferences() const {
157 return decision_policy_->AllPreferences();
158 }
160 return decision_policy_->ResetDecisionHeuristic();
161 }
163 const std::vector<std::pair<Literal, double>>& prefs) {
164 decision_policy_->ResetDecisionHeuristic();
165 for (const std::pair<Literal, double>& p : prefs) {
166 decision_policy_->SetAssignmentPreference(p.first, p.second);
167 }
168 }
169
170 // Solves the problem and returns its status.
171 // An empty problem is considered to be SAT.
172 //
173 // Note that the conflict limit applies only to this function and starts
174 // counting from the time it is called.
175 //
176 // This will restart from the current solver configuration. If a previous call
177 // to Solve() was interrupted by a conflict or time limit, calling this again
178 // will resume the search exactly as it would have continued.
179 //
180 // Note that this will use the TimeLimit singleton, so the time limit
181 // will be counted since the last time TimeLimit was reset, not from
182 // the start of this function.
183 enum Status {
188 };
189 Status Solve();
190
191 // Same as Solve(), but with a given time limit. Note that this will not
192 // update the TimeLimit singleton, but only the passed object instead.
194
195 // Simple interface to solve a problem under the given assumptions. This
196 // simply ask the solver to solve a problem given a set of variables fixed to
197 // a given value (the assumptions). Compared to simply calling AddUnitClause()
198 // and fixing the variables once and for all, this allow to backtrack over the
199 // assumptions and thus exploit the incrementally between subsequent solves.
200 //
201 // This function backtrack over all the current decision, tries to enqueue the
202 // given assumptions, sets the assumption level accordingly and finally calls
203 // Solve().
204 //
205 // If, given these assumptions, the model is UNSAT, this returns the
206 // ASSUMPTIONS_UNSAT status. INFEASIBLE is reserved for the case where the
207 // model is proven to be unsat without any assumptions.
208 //
209 // If ASSUMPTIONS_UNSAT is returned, it is possible to get a "core" of unsat
210 // assumptions by calling GetLastIncompatibleDecisions().
212 const std::vector<Literal>& assumptions);
213
214 // Changes the assumption level. All the decisions below this level will be
215 // treated as assumptions by the next Solve(). Note that this may impact some
216 // heuristics, like the LBD value of a clause.
217 void SetAssumptionLevel(int assumption_level);
218
219 // Returns the current assumption level. Note that if a solve was done since
220 // the last SetAssumptionLevel(), then the returned level may be lower than
221 // the one that was set. This is because some assumptions may now be
222 // consequences of others before them due to the newly learned clauses.
223 int AssumptionLevel() const { return assumption_level_; }
224
225 // This can be called just after SolveWithAssumptions() returned
226 // ASSUMPTION_UNSAT or after EnqueueDecisionAndBacktrackOnConflict() leaded
227 // to a conflict. It returns a subsequence (in the correct order) of the
228 // previously enqueued decisions that cannot be taken together without making
229 // the problem UNSAT.
230 std::vector<Literal> GetLastIncompatibleDecisions();
231
232 // Advanced usage. The next 3 functions allow to drive the search from outside
233 // the solver.
234
235 // Takes a new decision (the given true_literal must be unassigned) and
236 // propagates it. Returns the trail index of the first newly propagated
237 // literal. If there is a conflict and the problem is detected to be UNSAT,
238 // returns kUnsatTrailIndex.
239 //
240 // Important: In the presence of assumptions, this also returns
241 // kUnsatTrailIndex on ASSUMPTION_UNSAT. One can know the difference with
242 // IsModelUnsat().
243 //
244 // A client can determine if there is a conflict by checking if the
245 // CurrentDecisionLevel() was increased by 1 or not.
246 //
247 // If there is a conflict, the given decision is not applied and:
248 // - The conflict is learned.
249 // - The decisions are potentially backtracked to the first decision that
250 // propagates more variables because of the newly learned conflict.
251 // - The returned value is equal to trail_->Index() after this backtracking
252 // and just before the new propagation (due to the conflict) which is also
253 // performed by this function.
255
256 // This function starts by calling EnqueueDecisionAndBackjumpOnConflict(). If
257 // there is no conflict, it stops there. Otherwise, it tries to reapply all
258 // the decisions that were backjumped over until the first one that can't be
259 // taken because it is incompatible. Note that during this process, more
260 // conflicts may happen and the trail may be backtracked even further.
261 //
262 // In any case, the new decisions stack will be the largest valid "prefix"
263 // of the old stack. Note that decisions that are now consequence of the ones
264 // before them will no longer be decisions.
265 //
266 // Note(user): This function can be called with an already assigned literal.
268
269 // Tries to enqueue the given decision and performs the propagation.
270 // Returns true if no conflict occurred. Otherwise, returns false and restores
271 // the solver to the state just before this was called.
272 //
273 // Note(user): With this function, the solver doesn't learn anything.
274 bool EnqueueDecisionIfNotConflicting(Literal true_literal);
275
276 // Restores the state to the given target decision level. The decision at that
277 // level and all its propagation will not be undone. But all the trail after
278 // this will be cleared. Calling this with 0 will revert all the decisions and
279 // only the fixed variables will be left on the trail.
280 void Backtrack(int target_level);
281
282 // Advanced usage. This is meant to restore the solver to a "proper" state
283 // after a solve was interrupted due to a limit reached.
284 //
285 // Without assumption (i.e. if AssumptionLevel() is 0), this will revert all
286 // decisions and make sure that all the fixed literals are propagated. In
287 // presence of assumptions, this will either backtrack to the assumption level
288 // or re-enqueue any assumptions that may have been backtracked over due to
289 // conflits resolution. In both cases, the propagation is finished.
290 //
291 // Note that this may prove the model to be UNSAT or ASSUMPTION_UNSAT in which
292 // case it will return false.
294
295 // Advanced usage. Finish the progation if it was interrupted. Note that this
296 // might run into conflict and will propagate again until a fixed point is
297 // reached or the model was proven UNSAT. Returns IsModelUnsat().
298 bool FinishPropagation();
299
300 // Like Backtrack(0) but make sure the propagation is finished and return
301 // false if unsat was detected. This also removes any assumptions level.
302 bool ResetToLevelZero();
303
304 // Changes the assumptions level and the current solver assumptions. Returns
305 // false if the model is UNSAT or ASSUMPTION_UNSAT, true otherwise.
306 //
307 // This uses the "new" assumptions handling, where all assumptions are
308 // enqueued at once at decision level 1 before we start to propagate. This has
309 // many advantages. In particular, because we propagate with the binary
310 // implications first, if we ever have assumption => not(other_assumptions) we
311 // are guaranteed to find it and returns a core of size 2.
312 //
313 // Paper: "Speeding Up Assumption-Based SAT", Randy Hickey and Fahiem Bacchus
314 // http://www.maxhs.org/docs/Hickey-Bacchus2019_Chapter_SpeedingUpAssumption-BasedSAT.pdf
315 bool ResetWithGivenAssumptions(const std::vector<Literal>& assumptions);
316
317 // Advanced usage. If the decision level is smaller than the assumption level,
318 // this will try to reapply all assumptions. Returns true if this was doable,
319 // otherwise returns false in which case the model is either UNSAT or
320 // ASSUMPTION_UNSAT.
322
323 // Helper functions to get the correct status when one of the functions above
324 // returns false.
327 }
328
329 // Extract the current problem clauses. The Output type must support the two
330 // functions:
331 // - void AddBinaryClause(Literal a, Literal b);
332 // - void AddClause(absl::Span<const Literal> clause);
333 //
334 // TODO(user): also copy the removable clauses?
335 template <typename Output>
336 void ExtractClauses(Output* out) {
338 Backtrack(0);
339 if (!FinishPropagation()) return;
340
341 // It is important to process the newly fixed variables, so they are not
342 // present in the clauses we export.
343 if (num_processed_fixed_variables_ < trail_->Index()) {
345 }
346 clauses_propagator_->DeleteRemovedClauses();
347
348 // Note(user): Putting the binary clauses first help because the presolver
349 // currently process the clauses in order.
350 out->SetNumVariables(NumVariables());
351 binary_implication_graph_->ExtractAllBinaryClauses(out);
352 for (SatClause* clause : clauses_propagator_->AllClausesInCreationOrder()) {
353 if (!clauses_propagator_->IsRemovable(clause)) {
354 out->AddClause(clause->AsSpan());
355 }
356 }
357 }
358
359 // Functions to manage the set of learned binary clauses.
360 // Only clauses added/learned when TrackBinaryClause() is true are managed.
361 void TrackBinaryClauses(bool value) { track_binary_clauses_ = value; }
362 bool AddBinaryClauses(const std::vector<BinaryClause>& clauses);
363 const std::vector<BinaryClause>& NewlyAddedBinaryClauses();
365
366 struct Decision {
368 Decision(int i, Literal l) : trail_index(i), literal(l) {}
369 int trail_index = 0;
371 };
372
373 // Note that the Decisions() vector is always of size NumVariables(), and that
374 // only the first CurrentDecisionLevel() entries have a meaning.
375 const std::vector<Decision>& Decisions() const { return decisions_; }
376 int CurrentDecisionLevel() const { return current_decision_level_; }
377 const Trail& LiteralTrail() const { return *trail_; }
378 const VariablesAssignment& Assignment() const { return trail_->Assignment(); }
379
380 // Some statistics since the creation of the solver.
381 int64_t num_branches() const;
382 int64_t num_failures() const;
383 int64_t num_propagations() const;
384
385 // Note that we count the number of backtrack to level zero from a positive
386 // level. Those can corresponds to actual restarts, or conflicts that learn
387 // unit clauses or any other reason that trigger such backtrack.
388 int64_t num_restarts() const;
389
390 // A deterministic number that should be correlated with the time spent in
391 // the Solve() function. The order of magnitude should be close to the time
392 // in seconds.
393 double deterministic_time() const;
394
395 // Only used for debugging. Save the current assignment in debug_assignment_.
396 // The idea is that if we know that a given assignment is satisfiable, then
397 // all the learned clauses or PB constraints must be satisfiable by it. In
398 // debug mode, and after this is called, all the learned clauses are tested to
399 // satisfy this saved assignment.
400 void SaveDebugAssignment();
401
402 // Returns true iff the loaded problem only contains clauses.
403 bool ProblemIsPureSat() const { return problem_is_pure_sat_; }
404
405 void SetDratProofHandler(DratProofHandler* drat_proof_handler) {
406 drat_proof_handler_ = drat_proof_handler;
407 clauses_propagator_->SetDratProofHandler(drat_proof_handler_);
408 binary_implication_graph_->SetDratProofHandler(drat_proof_handler_);
409 }
410
411 // This function is here to deal with the case where a SAT/CP model is found
412 // to be trivially UNSAT while the user is constructing the model. Instead of
413 // having to test the status of all the lines adding a constraint, one can
414 // just check if the solver is not UNSAT once the model is constructed. Note
415 // that we usually log a warning on the first constraint that caused a
416 // "trival" unsatisfiability.
417 void NotifyThatModelIsUnsat() { model_is_unsat_ = true; }
418
419 // Adds a clause at any level of the tree and propagate any new deductions.
420 // Returns false if the model becomes UNSAT. Important: We currently do not
421 // support adding a clause that is already falsified at a positive decision
422 // level. Doing that will cause a check fail.
423 //
424 // TODO(user): Backjump and propagate on a falsified clause? this is currently
425 // not needed.
426 bool AddClauseDuringSearch(absl::Span<const Literal> literals);
427
428 // Performs propagation of the recently enqueued elements.
429 // Mainly visible for testing.
430 bool Propagate();
431
432 // This must be called at level zero. It will spend the given num decision and
433 // use propagation to try to minimize some clauses from the database.
434 void MinimizeSomeClauses(int decisions_budget);
435
436 // Sets the export function to the shared clauses manager.
437 void SetShareBinaryClauseCallback(const std::function<void(Literal, Literal)>&
438 shared_binary_clauses_callback) {
439 shared_binary_clauses_callback_ = shared_binary_clauses_callback;
440 }
441
442 // Advance the given time limit with all the deterministic time that was
443 // elapsed since last call.
445 const double current = deterministic_time();
447 current - deterministic_time_at_last_advanced_time_limit_);
448 deterministic_time_at_last_advanced_time_limit_ = current;
449 }
450
451 // Simplifies the problem when new variables are assigned at level 0.
453
454 int64_t NumFixedVariables() const {
455 if (!decisions_.empty()) return decisions_[0].trail_index;
457 return trail_->Index();
458 }
459
460 private:
461 // Calls Propagate() and returns true if no conflict occurred. Otherwise,
462 // learns the conflict, backtracks, enqueues the consequence of the learned
463 // conflict and returns false.
464 //
465 // When handling assumptions, this might return false without backtracking
466 // in case of ASSUMPTIONS_UNSAT.
467 bool PropagateAndStopAfterOneConflictResolution();
468
469 // All Solve() functions end up calling this one.
470 Status SolveInternal(TimeLimit* time_limit);
471
472 // Adds a binary clause to the BinaryImplicationGraph and to the
473 // BinaryClauseManager when track_binary_clauses_ is true.
474 //
475 // If export_clause is true, then we will also export_clause that to a
476 // potential shared_binary_clauses_callback_.
477 void AddBinaryClauseInternal(Literal a, Literal b, bool export_clause);
478
479 // See SaveDebugAssignment(). Note that these functions only consider the
480 // variables at the time the debug_assignment_ was saved. If new variables
481 // were added since that time, they will be considered unassigned.
482 bool ClauseIsValidUnderDebugAssignment(
483 const std::vector<Literal>& clause) const;
484 bool PBConstraintIsValidUnderDebugAssignment(
485 const std::vector<LiteralWithCoeff>& cst, const Coefficient rhs) const;
486
487 // Logs the given status if parameters_.log_search_progress() is true.
488 // Also returns it.
489 Status StatusWithLog(Status status);
490
491 // Main function called from SolveWithAssumptions() or from Solve() with an
492 // assumption_level of 0 (meaning no assumptions).
493 Status SolveInternal(int assumption_level);
494
495 // Applies the previous decisions (which are still on decisions_), in order,
496 // starting from the one at the current decision level. Stops at the one at
497 // decisions_[level] or on the first decision already propagated to "false"
498 // and thus incompatible.
499 //
500 // Note that during this process, conflicts may arise which will lead to
501 // backjumps. In this case, we will simply keep reapplying decisions from the
502 // last one backtracked over and so on.
503 //
504 // Returns FEASIBLE if no conflict occurred, INFEASIBLE if the model was
505 // proven unsat and ASSUMPTION_UNSAT otherwise. In the last case the first non
506 // taken old decision will be propagated to false by the ones before.
507 //
508 // first_propagation_index will be filled with the trail index of the first
509 // newly propagated literal, or with -1 if INFEASIBLE is returned.
510 Status ReapplyDecisionsUpTo(int level, int* first_propagation_index);
511
512 // Returns false if the thread memory is over the limit.
513 bool IsMemoryLimitReached() const;
514
515 // Sets model_is_unsat_ to true and return false.
516 bool SetModelUnsat();
517
518 // Returns the decision level of a given variable.
519 int DecisionLevel(BooleanVariable var) const {
520 return trail_->Info(var).level;
521 }
522
523 // Returns the relevant pointer if the given variable was propagated by the
524 // constraint in question. This is used to bump the activity of the learned
525 // clauses or pb constraints.
526 SatClause* ReasonClauseOrNull(BooleanVariable var) const;
527 UpperBoundedLinearConstraint* ReasonPbConstraintOrNull(
528 BooleanVariable var) const;
529
530 // This does one step of a pseudo-Boolean resolution:
531 // - The variable var has been assigned to l at a given trail_index.
532 // - The reason for var propagates it to l.
533 // - The conflict propagates it to not(l)
534 // The goal of the operation is to combine the two constraints in order to
535 // have a new conflict at a lower trail_index.
536 //
537 // Returns true if the reason for var was a normal clause. In this case,
538 // the *slack is updated to its new value.
539 bool ResolvePBConflict(BooleanVariable var,
540 MutableUpperBoundedLinearConstraint* conflict,
541 Coefficient* slack);
542
543 // Returns true iff the clause is the reason for an assigned variable.
544 //
545 // TODO(user): With our current data structures, we could also return true
546 // for clauses that were just used as a reason (like just before an untrail).
547 // This may be beneficial, but should properly be defined so that we can
548 // have the same behavior if we change the implementation.
549 bool ClauseIsUsedAsReason(SatClause* clause) const {
550 const BooleanVariable var = clause->PropagatedLiteral().Variable();
551 return trail_->Info(var).trail_index < trail_->Index() &&
552 (*trail_)[trail_->Info(var).trail_index].Variable() == var &&
553 ReasonClauseOrNull(var) == clause;
554 }
555
556 // Add a problem clause. The clause is assumed to be "cleaned", that is no
557 // duplicate variables (not strictly required) and not empty.
558 bool AddProblemClauseInternal(absl::Span<const Literal> literals);
559
560 // This is used by all the Add*LinearConstraint() functions. It detects
561 // infeasible/trivial constraints or clause constraints and takes the proper
562 // action.
563 bool AddLinearConstraintInternal(const std::vector<LiteralWithCoeff>& cst,
564 Coefficient rhs, Coefficient max_value);
565
566 // Makes sure a pseudo boolean constraint is in canonical form.
567 void CanonicalizeLinear(std::vector<LiteralWithCoeff>* cst,
568 Coefficient* bound_shift, Coefficient* max_value);
569
570 // Adds a learned clause to the problem. This should be called after
571 // Backtrack(). The backtrack is such that after it is applied, all the
572 // literals of the learned close except one will be false. Thus the last one
573 // will be implied True. This function also Enqueue() the implied literal.
574 //
575 // Returns the LBD of the clause.
576 int AddLearnedClauseAndEnqueueUnitPropagation(
577 const std::vector<Literal>& literals, bool is_redundant);
578
579 // Creates a new decision which corresponds to setting the given literal to
580 // True and Enqueue() this change.
581 void EnqueueNewDecision(Literal literal);
582
583 // Returns true if everything has been propagated.
584 //
585 // TODO(user): This test is fast but not exhaustive, especially regarding the
586 // integer propagators. Fix.
587 bool PropagationIsDone() const;
588
589 // Update the propagators_ list with the relevant propagators.
590 void InitializePropagators();
591
592 // Unrolls the trail until a given point. This unassign the assigned variables
593 // and add them to the priority queue with the correct weight.
594 void Untrail(int target_trail_index);
595
596 // Output to the DRAT proof handler any newly fixed variables.
597 void ProcessNewlyFixedVariablesForDratProof();
598
599 // Returns the maximum trail_index of the literals in the given clause.
600 // All the literals must be assigned. Returns -1 if the clause is empty.
601 int ComputeMaxTrailIndex(absl::Span<const Literal> clause) const;
602
603 // Computes what is known as the first UIP (Unique implication point) conflict
604 // clause starting from the failing clause. For a definition of UIP and a
605 // comparison of the different possible conflict clause computation, see the
606 // reference below.
607 //
608 // The conflict will have only one literal at the highest decision level, and
609 // this literal will always be the first in the conflict vector.
610 //
611 // L Zhang, CF Madigan, MH Moskewicz, S Malik, "Efficient conflict driven
612 // learning in a boolean satisfiability solver" Proceedings of the 2001
613 // IEEE/ACM international conference on Computer-aided design, Pages 279-285.
614 // http://www.cs.tau.ac.il/~msagiv/courses/ATP/iccad2001_final.pdf
615 void ComputeFirstUIPConflict(
616 int max_trail_index, std::vector<Literal>* conflict,
617 std::vector<Literal>* reason_used_to_infer_the_conflict,
618 std::vector<SatClause*>* subsumed_clauses);
619
620 // Fills literals with all the literals in the reasons of the literals in the
621 // given input. The output vector will have no duplicates and will not contain
622 // the literals already present in the input.
623 void ComputeUnionOfReasons(const std::vector<Literal>& input,
624 std::vector<Literal>* literals);
625
626 // Do the full pseudo-Boolean constraint analysis. This calls multiple
627 // time ResolvePBConflict() on the current conflict until we have a conflict
628 // that allow us to propagate more at a lower decision level. This level
629 // is the one returned in backjump_level.
630 void ComputePBConflict(int max_trail_index, Coefficient initial_slack,
631 MutableUpperBoundedLinearConstraint* conflict,
632 int* backjump_level);
633
634 // Applies some heuristics to a conflict in order to minimize its size and/or
635 // replace literals by other literals from lower decision levels. The first
636 // function choose which one of the other functions to call depending on the
637 // parameters.
638 //
639 // Precondidtion: is_marked_ should be set to true for all the variables of
640 // the conflict. It can also contains false non-conflict variables that
641 // are implied by the negation of the 1-UIP conflict literal.
642 void MinimizeConflict(
643 std::vector<Literal>* conflict,
644 std::vector<Literal>* reason_used_to_infer_the_conflict);
645 void MinimizeConflictExperimental(std::vector<Literal>* conflict);
646 void MinimizeConflictSimple(std::vector<Literal>* conflict);
647 void MinimizeConflictRecursively(std::vector<Literal>* conflict);
648
649 // Utility function used by MinimizeConflictRecursively().
650 bool CanBeInferedFromConflictVariables(BooleanVariable variable);
651
652 // To be used in DCHECK(). Verifies some property of the conflict clause:
653 // - There is an unique literal with the highest decision level.
654 // - This literal appears in the first position.
655 // - All the other literals are of smaller decision level.
656 // - Ther is no literal with a decision level of zero.
657 bool IsConflictValid(const std::vector<Literal>& literals);
658
659 // Given the learned clause after a conflict, this computes the correct
660 // backtrack level to call Backtrack() with.
661 int ComputeBacktrackLevel(const std::vector<Literal>& literals);
662
663 // The LBD (Literal Blocks Distance) is the number of different decision
664 // levels at which the literals of the clause were assigned. Note that we
665 // ignore the decision level 0 whereas the definition in the paper below
666 // doesn't:
667 //
668 // G. Audemard, L. Simon, "Predicting Learnt Clauses Quality in Modern SAT
669 // Solver" in Twenty-first International Joint Conference on Artificial
670 // Intelligence (IJCAI'09), july 2009.
671 // http://www.ijcai.org/papers09/Papers/IJCAI09-074.pdf
672 //
673 // IMPORTANT: All the literals of the clause must be assigned, and the first
674 // literal must be of the highest decision level. This will be the case for
675 // all the reason clauses.
676 template <typename LiteralList>
677 int ComputeLbd(const LiteralList& literals);
678
679 // Checks if we need to reduce the number of learned clauses and do
680 // it if needed. Also updates the learned clause limit for the next cleanup.
681 void CleanClauseDatabaseIfNeeded();
682
683 // Activity management for clauses. This work the same way at the ones for
684 // variables, but with different parameters.
685 void BumpReasonActivities(const std::vector<Literal>& literals);
686 void BumpClauseActivity(SatClause* clause);
687 void RescaleClauseActivities(double scaling_factor);
688 void UpdateClauseActivityIncrement();
689
690 std::string DebugString(const SatClause& clause) const;
691 std::string StatusString(Status status) const;
692 std::string RunningStatisticsString() const;
693
694 // Marks as "non-deletable" all clauses that were used to infer the given
695 // variable. The variable must be currently assigned.
696 void KeepAllClauseUsedToInfer(BooleanVariable variable);
697
698 // Use propagation to try to minimize the given clause. This is really similar
699 // to MinimizeCoreWithPropagation(). It must be called when the current
700 // decision level is zero. Note that because this do a small tree search, it
701 // will impact the variable/clauses activities and may add new conflicts.
702 void TryToMinimizeClause(SatClause* clause);
703
704 // This is used by the old non-model constructor.
705 Model* model_;
706 std::unique_ptr<Model> owned_model_;
707
708 BooleanVariable num_variables_ = BooleanVariable(0);
709
710 // Internal propagators. We keep them here because we need more than the
711 // SatPropagator interface for them.
712 BinaryImplicationGraph* binary_implication_graph_;
713 LiteralWatchers* clauses_propagator_;
714 PbConstraints* pb_constraints_;
715
716 // Ordered list of propagators used by Propagate()/Untrail().
717 std::vector<SatPropagator*> propagators_;
718 std::vector<SatPropagator*> non_empty_propagators_;
719
720 // Ordered list of propagators added with AddPropagator().
721 std::vector<SatPropagator*> external_propagators_;
722 SatPropagator* last_propagator_ = nullptr;
723
724 // For the old, non-model interface.
725 std::vector<std::unique_ptr<SatPropagator>> owned_propagators_;
726
727 // Keep track of all binary clauses so they can be exported.
728 bool track_binary_clauses_;
729 BinaryClauseManager binary_clauses_;
730
731 // Pointers to singleton Model objects.
732 Trail* trail_;
733 TimeLimit* time_limit_;
734 SatParameters* parameters_;
735 RestartPolicy* restart_;
736 SatDecisionPolicy* decision_policy_;
737 SolverLogger* logger_;
738
739 // Used for debugging only. See SaveDebugAssignment().
740 VariablesAssignment debug_assignment_;
741
742 // The stack of decisions taken by the solver. They are stored in [0,
743 // current_decision_level_). The vector is of size num_variables_ so it can
744 // store all the decisions. This is done this way because in some situation we
745 // need to remember the previously taken decisions after a backtrack.
746 int current_decision_level_ = 0;
747 std::vector<Decision> decisions_;
748
749 // The trail index after the last Backtrack() call or before the last
750 // EnqueueNewDecision() call.
751 int last_decision_or_backtrack_trail_index_ = 0;
752
753 // The assumption level. See SolveWithAssumptions().
754 int assumption_level_ = 0;
755 std::vector<Literal> assumptions_;
756
757 // The size of the trail when ProcessNewlyFixedVariables() was last called.
758 // Note that the trail contains only fixed literals (that is literals of
759 // decision levels 0) before this point.
760 int num_processed_fixed_variables_ = 0;
761 double deterministic_time_of_last_fixed_variables_cleanup_ = 0.0;
762
763 // Used in ProcessNewlyFixedVariablesForDratProof().
764 int drat_num_processed_fixed_variables_ = 0;
765
766 // Tracks various information about the solver progress.
767 struct Counters {
768 int64_t num_branches = 0;
769 int64_t num_failures = 0;
770 int64_t num_restarts = 0;
771
772 // Minimization stats.
773 int64_t num_minimizations = 0;
774 int64_t num_literals_removed = 0;
775
776 // PB constraints.
777 int64_t num_learned_pb_literals = 0;
778
779 // Clause learning /deletion stats.
780 int64_t num_literals_learned = 0;
781 int64_t num_literals_forgotten = 0;
782 int64_t num_subsumed_clauses = 0;
783
784 // TryToMinimizeClause() stats.
785 int64_t minimization_num_clauses = 0;
786 int64_t minimization_num_decisions = 0;
787 int64_t minimization_num_true = 0;
788 int64_t minimization_num_subsumed = 0;
789 int64_t minimization_num_removed_literals = 0;
790 };
791 Counters counters_;
792
793 // Solver information.
794 WallTimer timer_;
795
796 // This is set to true if the model is found to be UNSAT when adding new
797 // constraints.
798 bool model_is_unsat_ = false;
799
800 // Increment used to bump the variable activities.
801 double clause_activity_increment_;
802
803 // This counter is decremented each time we learn a clause that can be
804 // deleted. When it reaches zero, a clause cleanup is triggered.
805 int num_learned_clause_before_cleanup_ = 0;
806
807 // Temporary members used during conflict analysis.
808 SparseBitset<BooleanVariable> is_marked_;
809 SparseBitset<BooleanVariable> is_independent_;
810 SparseBitset<BooleanVariable> tmp_mark_;
811 std::vector<int> min_trail_index_per_level_;
812
813 // Temporary members used by CanBeInferedFromConflictVariables().
814 std::vector<BooleanVariable> dfs_stack_;
815 std::vector<BooleanVariable> variable_to_process_;
816
817 // Temporary member used when adding clauses.
818 std::vector<Literal> literals_scratchpad_;
819
820 // A boolean vector used to temporarily mark decision levels.
821 DEFINE_STRONG_INDEX_TYPE(SatDecisionLevel);
822 SparseBitset<SatDecisionLevel> is_level_marked_;
823
824 // Temporary vectors used by EnqueueDecisionAndBackjumpOnConflict().
825 std::vector<Literal> learned_conflict_;
826 std::vector<Literal> reason_used_to_infer_the_conflict_;
827 std::vector<Literal> extra_reason_literals_;
828 std::vector<SatClause*> subsumed_clauses_;
829
830 // When true, temporarily disable the deletion of clauses that are not needed
831 // anymore. This is a hack for TryToMinimizeClause() because we use
832 // propagation in this function which might trigger a clause database
833 // deletion, but we still want the pointer to the clause we wants to minimize
834 // to be valid until the end of that function.
835 bool block_clause_deletion_ = false;
836
837 // "cache" to avoid inspecting many times the same reason during conflict
838 // analysis.
839 VariableWithSameReasonIdentifier same_reason_identifier_;
840
841 // Boolean used to include/exclude constraints from the core computation.
842 bool is_relevant_for_core_computation_;
843
844 // The current pseudo-Boolean conflict used in PB conflict analysis.
845 MutableUpperBoundedLinearConstraint pb_conflict_;
846
847 // The deterministic time when the time limit was updated.
848 // As the deterministic time in the time limit has to be advanced manually,
849 // it is necessary to keep track of the last time the time was advanced.
850 double deterministic_time_at_last_advanced_time_limit_ = 0;
851
852 // This is true iff the loaded problem only contains clauses.
853 bool problem_is_pure_sat_;
854
855 DratProofHandler* drat_proof_handler_;
856
857 mutable StatsGroup stats_;
858
859 std::function<void(Literal, Literal)> shared_binary_clauses_callback_ =
860 nullptr;
861
862 DISALLOW_COPY_AND_ASSIGN(SatSolver);
863};
864
865// Tries to minimize the given UNSAT core with a really simple heuristic.
866// The idea is to remove literals that are consequences of others in the core.
867// We already know that in the initial order, no literal is propagated by the
868// one before it, so we just look for propagation in the reverse order.
869//
870// Important: The given SatSolver must be the one that just produced the given
871// core.
872//
873// TODO(user): One should use MinimizeCoreWithPropagation() instead.
874void MinimizeCore(SatSolver* solver, std::vector<Literal>* core);
875
876// ============================================================================
877// Model based functions.
878//
879// TODO(user): move them in another file, and unit-test them.
880// ============================================================================
881
882inline std::function<void(Model*)> BooleanLinearConstraint(
883 int64_t lower_bound, int64_t upper_bound,
884 std::vector<LiteralWithCoeff>* cst) {
885 return [=](Model* model) {
886 model->GetOrCreate<SatSolver>()->AddLinearConstraint(
887 /*use_lower_bound=*/true, Coefficient(lower_bound),
888 /*use_upper_bound=*/true, Coefficient(upper_bound), cst);
889 };
890}
891
892inline std::function<void(Model*)> CardinalityConstraint(
893 int64_t lower_bound, int64_t upper_bound,
894 const std::vector<Literal>& literals) {
895 return [=](Model* model) {
896 std::vector<LiteralWithCoeff> cst;
897 cst.reserve(literals.size());
898 for (int i = 0; i < literals.size(); ++i) {
899 cst.emplace_back(literals[i], 1);
900 }
901 model->GetOrCreate<SatSolver>()->AddLinearConstraint(
902 /*use_lower_bound=*/true, Coefficient(lower_bound),
903 /*use_upper_bound=*/true, Coefficient(upper_bound), &cst);
904 };
905}
906
907inline std::function<void(Model*)> ExactlyOneConstraint(
908 const std::vector<Literal>& literals) {
909 return [=](Model* model) {
910 std::vector<LiteralWithCoeff> cst;
911 cst.reserve(literals.size());
912 for (const Literal l : literals) {
913 cst.emplace_back(l, Coefficient(1));
914 }
915 model->GetOrCreate<SatSolver>()->AddLinearConstraint(
916 /*use_lower_bound=*/true, Coefficient(1),
917 /*use_upper_bound=*/true, Coefficient(1), &cst);
918 };
919}
920
921inline std::function<void(Model*)> AtMostOneConstraint(
922 const std::vector<Literal>& literals) {
923 return [=](Model* model) {
924 std::vector<LiteralWithCoeff> cst;
925 cst.reserve(literals.size());
926 for (const Literal l : literals) {
927 cst.emplace_back(l, Coefficient(1));
928 }
929 model->GetOrCreate<SatSolver>()->AddLinearConstraint(
930 /*use_lower_bound=*/false, Coefficient(0),
931 /*use_upper_bound=*/true, Coefficient(1), &cst);
932 };
933}
934
935inline std::function<void(Model*)> ClauseConstraint(
936 absl::Span<const Literal> literals) {
937 return [=](Model* model) {
938 std::vector<LiteralWithCoeff> cst;
939 cst.reserve(literals.size());
940 for (const Literal l : literals) {
941 cst.emplace_back(l, Coefficient(1));
942 }
943 model->GetOrCreate<SatSolver>()->AddLinearConstraint(
944 /*use_lower_bound=*/true, Coefficient(1),
945 /*use_upper_bound=*/false, Coefficient(1), &cst);
946 };
947}
948
949// a => b.
950inline std::function<void(Model*)> Implication(Literal a, Literal b) {
951 return [=](Model* model) {
952 model->GetOrCreate<SatSolver>()->AddBinaryClause(a.Negated(), b);
953 };
954}
955
956// a == b.
957inline std::function<void(Model*)> Equality(Literal a, Literal b) {
958 return [=](Model* model) {
959 model->GetOrCreate<SatSolver>()->AddBinaryClause(a.Negated(), b);
960 model->GetOrCreate<SatSolver>()->AddBinaryClause(a, b.Negated());
961 };
962}
963
964// r <=> (at least one literal is true). This is a reified clause.
965inline std::function<void(Model*)> ReifiedBoolOr(
966 const std::vector<Literal>& literals, Literal r) {
967 return [=](Model* model) {
968 std::vector<Literal> clause;
969 for (const Literal l : literals) {
970 model->Add(Implication(l, r)); // l => r.
971 clause.push_back(l);
972 }
973
974 // All false => r false.
975 clause.push_back(r.Negated());
976 model->Add(ClauseConstraint(clause));
977 };
978}
979
980// enforcement_literals => clause.
981inline std::function<void(Model*)> EnforcedClause(
982 absl::Span<const Literal> enforcement_literals,
983 absl::Span<const Literal> clause) {
984 return [=](Model* model) {
985 std::vector<Literal> tmp;
986 for (const Literal l : enforcement_literals) {
987 tmp.push_back(l.Negated());
988 }
989 for (const Literal l : clause) {
990 tmp.push_back(l);
991 }
992 model->Add(ClauseConstraint(tmp));
993 };
994}
995
996// r <=> (all literals are true).
997//
998// Note(user): we could have called ReifiedBoolOr() with everything negated.
999inline std::function<void(Model*)> ReifiedBoolAnd(
1000 const std::vector<Literal>& literals, Literal r) {
1001 return [=](Model* model) {
1002 std::vector<Literal> clause;
1003 for (const Literal l : literals) {
1004 model->Add(Implication(r, l)); // r => l.
1005 clause.push_back(l.Negated());
1006 }
1007
1008 // All true => r true.
1009 clause.push_back(r);
1010 model->Add(ClauseConstraint(clause));
1011 };
1012}
1013
1014// r <=> (a <= b).
1015inline std::function<void(Model*)> ReifiedBoolLe(Literal a, Literal b,
1016 Literal r) {
1017 return [=](Model* model) {
1018 // r <=> (a <= b) is the same as r <=> not(a=1 and b=0).
1019 // So r <=> a=0 OR b=1.
1020 model->Add(ReifiedBoolOr({a.Negated(), b}, r));
1021 };
1022}
1023
1024// This checks that the variable is fixed.
1025inline std::function<int64_t(const Model&)> Value(Literal l) {
1026 return [=](const Model& model) {
1027 const Trail* trail = model.Get<Trail>();
1029 return trail->Assignment().LiteralIsTrue(l);
1030 };
1031}
1032
1033// This checks that the variable is fixed.
1034inline std::function<int64_t(const Model&)> Value(BooleanVariable b) {
1035 return [=](const Model& model) {
1036 const Trail* trail = model.Get<Trail>();
1038 return trail->Assignment().LiteralIsTrue(Literal(b, true));
1039 };
1040}
1041
1042// This can be used to enumerate all the solutions. After each SAT call to
1043// Solve(), calling this will reset the solver and exclude the current solution
1044// so that the next call to Solve() will give a new solution or UNSAT is there
1045// is no more new solutions.
1046inline std::function<void(Model*)> ExcludeCurrentSolutionAndBacktrack() {
1047 return [=](Model* model) {
1048 SatSolver* sat_solver = model->GetOrCreate<SatSolver>();
1049
1050 // Note that we only exclude the current decisions, which is an efficient
1051 // way to not get the same SAT assignment.
1052 const int current_level = sat_solver->CurrentDecisionLevel();
1053 std::vector<Literal> clause_to_exclude_solution;
1054 clause_to_exclude_solution.reserve(current_level);
1055 for (int i = 0; i < current_level; ++i) {
1056 clause_to_exclude_solution.push_back(
1057 sat_solver->Decisions()[i].literal.Negated());
1058 }
1059 sat_solver->Backtrack(0);
1060 model->Add(ClauseConstraint(clause_to_exclude_solution));
1061 };
1062}
1063
1064// Returns a string representation of a SatSolver::Status.
1066inline std::ostream& operator<<(std::ostream& os, SatSolver::Status status) {
1067 os << SatStatusString(status);
1068 return os;
1069}
1070
1071} // namespace sat
1072} // namespace operations_research
1073
1074#endif // OR_TOOLS_SAT_SAT_SOLVER_H_
int64_t max
Definition: alldiff_cst.cc:140
#define CHECK(condition)
Definition: base/logging.h:495
#define CHECK_LT(val1, val2)
Definition: base/logging.h:706
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:703
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:106
void AdvanceDeterministicTime(double deterministic_duration)
Advances the deterministic time.
Definition: time_limit.h:227
void ExtractAllBinaryClauses(Output *out) const
Definition: clause.h:650
void SetDratProofHandler(DratProofHandler *drat_proof_handler)
Definition: clause.h:671
BooleanVariable Variable() const
Definition: sat_base.h:83
void SetDratProofHandler(DratProofHandler *drat_proof_handler)
Definition: clause.h:242
bool IsRemovable(SatClause *const clause) const
Definition: clause.h:222
const std::vector< SatClause * > & AllClausesInCreationOrder() const
Definition: clause.h:214
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:42
std::vector< std::pair< Literal, double > > AllPreferences() const
void SetAssignmentPreference(Literal literal, double weight)
bool AddLinearConstraint(bool use_lower_bound, Coefficient lower_bound, bool use_upper_bound, Coefficient upper_bound, std::vector< LiteralWithCoeff > *cst)
Definition: sat_solver.cc:343
bool EnqueueDecisionIfNotConflicting(Literal true_literal)
Definition: sat_solver.cc:976
void SetNumVariables(int num_variables)
Definition: sat_solver.cc:85
std::vector< std::pair< Literal, double > > AllPreferences() const
Definition: sat_solver.h:156
bool AddTernaryClause(Literal a, Literal b, Literal c)
Definition: sat_solver.cc:193
void AddLastPropagator(SatPropagator *propagator)
Definition: sat_solver.cc:445
const SatParameters & parameters() const
Definition: sat_solver.cc:131
bool AddClauseDuringSearch(absl::Span< const Literal > literals)
Definition: sat_solver.cc:157
Status SolveWithTimeLimit(TimeLimit *time_limit)
Definition: sat_solver.cc:1072
Status ResetAndSolveWithGivenAssumptions(const std::vector< Literal > &assumptions)
Definition: sat_solver.cc:1047
void AddPropagator(SatPropagator *propagator)
Definition: sat_solver.cc:437
BooleanVariable NewBooleanVariable()
Definition: sat_solver.h:87
const VariablesAssignment & Assignment() const
Definition: sat_solver.h:378
const std::vector< BinaryClause > & NewlyAddedBinaryClauses()
Definition: sat_solver.cc:1032
const std::vector< Decision > & Decisions() const
Definition: sat_solver.h:375
bool AddBinaryClauses(const std::vector< BinaryClause > &clauses)
Definition: sat_solver.cc:1022
const Trail & LiteralTrail() const
Definition: sat_solver.h:377
void SetAssumptionLevel(int assumption_level)
Definition: sat_solver.cc:1060
void AdvanceDeterministicTime(TimeLimit *limit)
Definition: sat_solver.h:444
void SetShareBinaryClauseCallback(const std::function< void(Literal, Literal)> &shared_binary_clauses_callback)
Definition: sat_solver.h:437
void SetDratProofHandler(DratProofHandler *drat_proof_handler)
Definition: sat_solver.h:405
void MinimizeSomeClauses(int decisions_budget)
Definition: sat_solver.cc:1350
void SetAssignmentPreference(Literal literal, double weight)
Definition: sat_solver.h:153
void ResetDecisionHeuristicAndSetAllPreferences(const std::vector< std::pair< Literal, double > > &prefs)
Definition: sat_solver.h:162
int EnqueueDecisionAndBackjumpOnConflict(Literal true_literal)
Definition: sat_solver.cc:536
void SetParameters(const SatParameters &parameters)
Definition: sat_solver.cc:136
bool AddBinaryClause(Literal a, Literal b)
Definition: sat_solver.cc:189
int EnqueueDecisionAndBacktrackOnConflict(Literal true_literal)
Definition: sat_solver.cc:963
void Backtrack(int target_level)
Definition: sat_solver.cc:991
std::vector< Literal > GetLastIncompatibleDecisions()
Definition: sat_solver.cc:1375
void TakePropagatorOwnership(std::unique_ptr< SatPropagator > propagator)
Definition: sat_solver.h:145
bool ResetWithGivenAssumptions(const std::vector< Literal > &assumptions)
Definition: sat_solver.cc:587
bool AddProblemClause(absl::Span< const Literal > literals)
Definition: sat_solver.cc:202
bool AddUnitClause(Literal true_literal)
Definition: sat_solver.cc:185
const VariablesAssignment & Assignment() const
Definition: sat_base.h:383
const AssignmentInfo & Info(BooleanVariable var) const
Definition: sat_base.h:384
bool VariableIsAssigned(BooleanVariable var) const
Definition: sat_base.h:161
bool LiteralIsTrue(Literal literal) const
Definition: sat_base.h:153
int64_t b
int64_t a
SharedClausesManager * clauses
ModelSharedTimeLimit * time_limit
int64_t value
IntVar * var
Definition: expr_array.cc:1874
absl::Status status
Definition: g_gurobi.cc:35
double upper_bound
double lower_bound
GRBmodel * model
std::tuple< int64_t, int64_t, const double > Coefficient
std::function< void(Model *)> Equality(IntegerVariable v, int64_t value)
Definition: integer.h:1721
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition: cp_model.cc:89
std::function< void(Model *)> ReifiedBoolOr(const std::vector< Literal > &literals, Literal r)
Definition: sat_solver.h:965
std::function< void(Model *)> ClauseConstraint(absl::Span< const Literal > literals)
Definition: sat_solver.h:935
std::function< void(Model *)> EnforcedClause(absl::Span< const Literal > enforcement_literals, absl::Span< const Literal > clause)
Definition: sat_solver.h:981
std::function< void(Model *)> ReifiedBoolLe(Literal a, Literal b, Literal r)
Definition: sat_solver.h:1015
std::function< void(Model *)> Implication(const std::vector< Literal > &enforcement_literals, IntegerLiteral i)
Definition: integer.h:1734
void MinimizeCore(SatSolver *solver, std::vector< Literal > *core)
Definition: sat_solver.cc:2655
std::string SatStatusString(SatSolver::Status status)
Definition: sat_solver.cc:2638
std::function< void(Model *)> AtMostOneConstraint(const std::vector< Literal > &literals)
Definition: sat_solver.h:921
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1683
std::function< void(Model *)> ReifiedBoolAnd(const std::vector< Literal > &literals, Literal r)
Definition: sat_solver.h:999
std::function< void(Model *)> CardinalityConstraint(int64_t lower_bound, int64_t upper_bound, const std::vector< Literal > &literals)
Definition: sat_solver.h:892
std::function< void(Model *)> BooleanLinearConstraint(int64_t lower_bound, int64_t upper_bound, std::vector< LiteralWithCoeff > *cst)
Definition: sat_solver.h:882
std::function< void(Model *)> ExactlyOneConstraint(const std::vector< Literal > &literals)
Definition: sat_solver.h:907
std::function< void(Model *)> ExcludeCurrentSolutionAndBacktrack()
Definition: sat_solver.h:1046
const int kUnsatTrailIndex
Definition: sat_solver.h:56
Collection of objects used to extend the Constraint Solver library.
Literal literal
Definition: optimization.cc:89
int64_t weight
Definition: pack.cc:510
static int input(yyscan_t yyscanner)