Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
Solver.h
Go to the documentation of this file.
1/****************************************************************************************[Solver.h]
2Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3Copyright (c) 2007-2010, Niklas Sorensson
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6associated documentation files (the "Software"), to deal in the Software without restriction,
7including without limitation the rights to use, copy, modify, merge, publish, distribute,
8sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all copies or
12substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19**************************************************************************************************/
20
21#pragma once
22
28
29
30#pragma GCC visibility push(default)
31namespace Minisat {
32namespace Internal {
33
34//=================================================================================================
35// Solver -- the main class:
36
37class Solver {
38public:
39
40 // Constructor/Destructor:
41 //
43 virtual ~Solver();
44
45 // Problem specification:
46 //
47 Var newVar (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
48
49 bool addClause (const vec<Lit>& ps); // Add a clause to the solver.
50 bool addEmptyClause(); // Add the empty clause, making the solver contradictory.
51 bool addClause (Lit p); // Add a unit clause to the solver.
52 bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
53 bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
54 bool addClause_( vec<Lit>& ps); // Add a clause to the solver without making superflous internal copy. Will
55 // change the passed vector 'ps'.
56
57
61
62 struct SolverStatus {
63 unsigned long long int restarts;
64 unsigned long long int conflicts;
65 unsigned long long int decisions;
66 unsigned long long int propagations;
67 unsigned long long int conflict_literals;
68 bool timeout;
70 };
71
72 // Solving:
73 //
74 bool simplify (); // Removes already satisfied clauses.
75 bool solve (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions.
76 lbool solveLimited (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions (With resource constraints).
77 bool solve (); // Search without assumptions.
78 bool solve (double t, SolverStatus& st); // Search without assumptions and MAX time. //HEDTKE
79 bool solve (Lit p); // Search for a model that respects a single assumption.
80 bool solve (Lit p, Lit q); // Search for a model that respects two assumptions.
81 bool solve (Lit p, Lit q, Lit r); // Search for a model that respects three assumptions.
82 bool okay () const; // FALSE means solver is in a conflicting state
83
84 void toDimacs (std::ostream &out, const vec<Lit>& assumps); // Write CNF to file in DIMACS-format.
85 void toDimacs (const char *file, const vec<Lit>& assumps);
86 void toDimacs (std::ostream &out, Clause& c, vec<Var>& map, Var& max);
87
88 // Convenience versions of 'toDimacs()':
89 void toDimacs (const char* file);
90 void toDimacs (const char* file, Lit p);
91 void toDimacs (const char* file, Lit p, Lit q);
92 void toDimacs (const char* file, Lit p, Lit q, Lit r);
93
94 // Variable mode:
95 //
96 void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
97 void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
98
99 // Read state:
100 //
101 lbool value (Var x) const; // The current value of a variable.
102 lbool value (Lit p) const; // The current value of a literal.
103 lbool modelValue (Var x) const; // The value of a variable in the last model. The last call to solve must have been satisfiable.
104 lbool modelValue (Lit p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable.
105 int nAssigns () const; // The current number of assigned literals.
106 int nClauses () const; // The current number of original clauses.
107 int nLearnts () const; // The current number of learnt clauses.
108 int nVars () const; // The current number of variables.
109 int nFreeVars () const;
110
111 // Resource contraints:
112 //
113 void setConfBudget(int64_t x);
114 void setPropBudget(int64_t x);
115 void budgetOff();
116 void interrupt(); // Trigger a (potentially asynchronous) interruption of the solver.
117 void clearInterrupt(); // Clear interrupt indicator flag.
118
119 // Memory managment:
120 //
121 virtual void garbageCollect();
122 void checkGarbage(double gf);
123 void checkGarbage();
124
125 // Extra results: (read-only member variable)
126 //
127 vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
128 vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions),
129 // this vector represent the final conflict clause expressed in the assumptions.
130
131 // Mode of operation:
132 //
134 double var_decay;
139 int ccmin_mode; // Controls conflict clause minimization (0=none, 1=basic, 2=deep).
140 int phase_saving; // Controls the level of phase saving (0=none, 1=limited, 2=full).
141 bool rnd_pol; // Use random polarities for branching heuristics.
142 bool rnd_init_act; // Initialize variable activities with a small random value.
143 double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered.
144
145 int restart_first; // The initial restart limit. (default 100)
146 double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.5)
147 double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3)
148 double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1)
149
152
153 // Statistics: (read-only member variable)
154 //
157
158protected:
159
160 // Helper structures:
161 //
162 struct VarData { CRef reason; int level; };
163 static inline VarData mkVarData(CRef cr, int l){ VarData d = {cr, l}; return d; }
164
165 struct Watcher {
168 Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {}
169 bool operator==(const Watcher& w) const { return cref == w.cref; }
170 bool operator!=(const Watcher& w) const { return cref != w.cref; }
171 };
172
174 {
176 WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
177 bool operator()(const Watcher& w) const { return ca[w.cref].mark() == 1; }
178 };
179
180 struct VarOrderLt {
182 bool operator () (Var x, Var y) const { return activity[x] > activity[y]; }
183 VarOrderLt(const vec<double>& act) : activity(act) { }
184 };
185
186 // Solver state:
187 //
188 bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
189 vec<CRef> clauses; // List of problem clauses.
190 vec<CRef> learnts; // List of learnt clauses.
191 double cla_inc; // Amount to bump next clause with.
192 vec<double> activity; // A heuristic measurement of the activity of a variable.
193 double var_inc; // Amount to bump next variable with.
195 watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
196 vec<lbool> assigns; // The current assignments.
197 vec<char> polarity; // The preferred polarity of each variable.
198 vec<char> decision; // Declares if a variable is eligible for selection in the decision heuristic.
199 vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
200 vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
201 vec<VarData> vardata; // Stores reason and level for each variable.
202 int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
203 int simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'.
204 int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'.
205 vec<Lit> assumptions; // Current set of assumptions provided to solve by the user.
206 Heap<VarOrderLt> order_heap; // A priority queue of variables ordered with respect to the variable activity.
207 double progress_estimate;// Set by 'search()'.
208 bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'.
209
211
212 // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
213 // used, exept 'seen' wich is used in several places.
214 //
219
223
224 // Resource contraints:
225 //
226 int64_t conflict_budget; // -1 means no budget.
227 int64_t propagation_budget; // -1 means no budget.
229
230 // Main internal methods:
231 //
232 void insertVarOrder (Var x); // Insert a variable in the decision order priority queue.
233 Lit pickBranchLit (); // Return the next decision variable.
234 void newDecisionLevel (); // Begins a new decision level.
235 void uncheckedEnqueue (Lit p, CRef from = CRef_Undef); // Enqueue a literal. Assumes value of literal is undefined.
236 bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise.
237 CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause.
238 void cancelUntil (int level); // Backtrack until a certain level.
239 void analyze (CRef confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
240 void analyzeFinal (Lit p, vec<Lit>& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION?
241 bool litRedundant (Lit p, uint32_t abstract_levels); // (helper method for 'analyze()')
242 lbool search (int nof_conflicts); // Search for a given number of conflicts.
243 lbool search (int nof_conflicts, double& time); // Search for a given number of conflicts with MAX time. //HEDTKE
244 lbool solve_ (); // Main solve method (assumptions given in 'assumptions').
245 lbool solve_ (double& t); // Main solve method (assumptions given in 'assumptions') with MAX time. //HEDTKE
246 void reduceDB (); // Reduce the set of learnt clauses.
247 void removeSatisfied (vec<CRef>& cs); // Shrink 'cs' to contain only non-satisfied clauses.
249
250 // Maintaining Variable/Clause activity:
251 //
252 void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
253 void varBumpActivity (Var v, double inc); // Increase a variable with the current 'bump' value.
254 void varBumpActivity (Var v); // Increase a variable with the current 'bump' value.
255 void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead.
256 void claBumpActivity (Clause& c); // Increase a clause with the current 'bump' value.
257
258 // Operations on clauses:
259 //
260 void attachClause (CRef cr); // Attach a clause to watcher lists.
261 void detachClause (CRef cr, bool strict = false); // Detach a clause to watcher lists.
262 void removeClause (CRef cr); // Detach and free a clause.
263 bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state.
264 bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state.
265
267
268 // Misc:
269 //
270 int decisionLevel () const; // Gives the current decisionlevel.
271 uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
272 CRef reason (Var x) const;
273 int level (Var x) const;
274 double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
275 bool withinBudget () const;
276
277 // Static helpers:
278 //
279
280 // Returns a random float 0 <= x < 1. Seed must never be 0.
281 static inline double drand(double& seed) {
282 seed *= 1389796;
283 int q = (int)(seed / 2147483647);
284 seed -= (double)q * 2147483647;
285 return seed / 2147483647; }
286
287 // Returns a random integer 0 <= x < size. Seed must never be 0.
288 static inline int irand(double& seed, int size) {
289 return (int)(drand(seed) * size); }
290};
291
292
293//=================================================================================================
294// Implementation of inline methods:
295
296inline CRef Solver::reason(Var x) const { return vardata[x].reason; }
297inline int Solver::level (Var x) const { return vardata[x].level; }
298
300 if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x); }
301
302inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); }
304inline void Solver::varBumpActivity(Var v, double inc) {
305 if ( (activity[v] += inc) > 1e100 ) {
306 // Rescale:
307 for (int i = 0; i < nVars(); i++)
308 activity[i] *= 1e-100;
309 var_inc *= 1e-100; }
310
311 // Update order_heap with respect to new activity:
312 if (order_heap.inHeap(v))
313 order_heap.decrease(v); }
314
317 if ( (c.activity() += (float)cla_inc) > 1e20f ) {
318 // Rescale:
319 for (int i = 0; i < learnts.size(); i++)
320 ca[learnts[i]].activity() *= 1e-20f;
321 cla_inc *= 1e-20; } }
322
323inline void Solver::checkGarbage(void){ return checkGarbage(garbage_frac); }
324inline void Solver::checkGarbage(double gf){
325 if (ca.wasted() > ca.size() * gf)
326 garbageCollect(); }
327
328// NOTE: enqueue does not set the ok flag! (only public methods do)
329inline bool Solver::enqueue (Lit p, CRef from) { return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true); }
330inline bool Solver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
331inline bool Solver::addEmptyClause () { add_tmp.clear(); return addClause_(add_tmp); }
332inline bool Solver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
333inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
334inline bool Solver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
335inline bool Solver::locked (const Clause& c) const { return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c; }
337
338inline int Solver::decisionLevel () const { return trail_lim.size(); }
339inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); }
340inline lbool Solver::value (Var x) const { return assigns[x]; }
341inline lbool Solver::value (Lit p) const { return assigns[var(p)] ^ sign(p); }
342inline lbool Solver::modelValue (Var x) const { return model[x]; }
343inline lbool Solver::modelValue (Lit p) const { return model[var(p)] ^ sign(p); }
344inline int Solver::nAssigns () const { return trail.size(); }
345inline int Solver::nClauses () const { return clauses.size(); }
346inline int Solver::nLearnts () const { return learnts.size(); }
347inline int Solver::nVars () const { return vardata.size(); }
348inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
349inline void Solver::setPolarity (Var v, bool b) { polarity[v] = b; }
350inline void Solver::setDecisionVar(Var v, bool b)
351{
352 if ( b && !decision[v]) dec_vars++;
353 else if (!b && decision[v]) dec_vars--;
354
355 decision[v] = b;
357}
358inline void Solver::setConfBudget(int64_t x){ conflict_budget = conflicts + x; }
360inline void Solver::interrupt(){ asynch_interrupt = true; }
363inline bool Solver::withinBudget() const {
364 return !asynch_interrupt &&
365 (conflict_budget < 0 || conflicts < (uint64_t)conflict_budget) &&
367
368// FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a
369// pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or
370// all calls to solve must return an 'lbool'. I'm not yet sure which I prefer.
371inline bool Solver::solve () { budgetOff(); assumptions.clear(); return solve_() == l_True; }
372inline bool Solver::solve (double t, SolverStatus& st) {
373 budgetOff();
374 assumptions.clear();
375 lbool solver_value = solve_(t);
376 st.restarts = starts;
377#if 0
380#endif
381 st.conflicts = conflicts;
382 st.decisions = decisions;
385 st.timeout = (solver_value == l_Timeout);
386 if (st.timeout) {
387 st.answer = A_UNDEF;
388 } else if (solver_value == l_True) {
389 st.answer = A_TRUE;
390 } else {
391 st.answer = A_FALSE;
392 }
393 return (solver_value == l_True);
394} //HEDTKE
395
396inline bool Solver::solve (Lit p) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_() == l_True; }
397inline bool Solver::solve (Lit p, Lit q) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_() == l_True; }
398inline bool Solver::solve (Lit p, Lit q, Lit r) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_() == l_True; }
399inline bool Solver::solve (const vec<Lit>& assumps){ budgetOff(); assumps.copyTo(assumptions); return solve_() == l_True; }
400inline lbool Solver::solveLimited (const vec<Lit>& assumps){ assumps.copyTo(assumptions); return solve_(); }
401inline bool Solver::okay () const { return ok; }
402
403inline void Solver::toDimacs (const char* file){ vec<Lit> as; toDimacs(file, as); }
404inline void Solver::toDimacs (const char* file, Lit p){ vec<Lit> as; as.push(p); toDimacs(file, as); }
405inline void Solver::toDimacs (const char* file, Lit p, Lit q){ vec<Lit> as; as.push(p); as.push(q); toDimacs(file, as); }
406inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ vec<Lit> as; as.push(p); as.push(q); as.push(r); toDimacs(file, as); }
407
408
409//=================================================================================================
410// Debug etc:
411
412
413//=================================================================================================
414} // namespace Internal
415} // namespace Minisat
416#pragma GCC visibility pop
#define l_Timeout
Definition SolverTypes.h:89
#define l_True
Definition SolverTypes.h:86
#define l_Undef
Definition SolverTypes.h:88
#define l_False
Definition SolverTypes.h:87
lbool search(int nof_conflicts, double &time)
bool addClause(const vec< Lit > &ps)
Definition Solver.h:330
ClauseAllocator ca
Definition Solver.h:210
void varBumpActivity(Var v, double inc)
Definition Solver.h:304
void insertVarOrder(Var x)
Definition Solver.h:299
void toDimacs(std::ostream &out, Clause &c, vec< Var > &map, Var &max)
void setConfBudget(int64_t x)
Definition Solver.h:358
int level(Var x) const
Definition Solver.h:297
bool satisfied(const Clause &c) const
vec< double > activity
Definition Solver.h:192
vec< Lit > analyze_stack
Definition Solver.h:216
bool withinBudget() const
Definition Solver.h:363
void analyze(CRef confl, vec< Lit > &out_learnt, int &out_btlevel)
void attachClause(CRef cr)
int nFreeVars() const
Definition Solver.h:348
void setDecisionVar(Var v, bool b)
Definition Solver.h:350
void toDimacs(const char *file, const vec< Lit > &assumps)
int decisionLevel() const
Definition Solver.h:338
CRef reason(Var x) const
Definition Solver.h:296
vec< Lit > analyze_toclear
Definition Solver.h:217
void relocAll(ClauseAllocator &to)
void toDimacs(std::ostream &out, const vec< Lit > &assumps)
Var newVar(bool polarity=true, bool dvar=true)
lbool modelValue(Var x) const
Definition Solver.h:342
static VarData mkVarData(CRef cr, int l)
Definition Solver.h:163
lbool value(Var x) const
Definition Solver.h:340
static double drand(double &seed)
Definition Solver.h:281
double progressEstimate() const
bool enqueue(Lit p, CRef from=CRef_Undef)
Definition Solver.h:329
bool locked(const Clause &c) const
Definition Solver.h:335
static int irand(double &seed, int size)
Definition Solver.h:288
OccLists< Lit, vec< Watcher >, WatcherDeleted > watches
Definition Solver.h:195
Heap< VarOrderLt > order_heap
Definition Solver.h:206
void setPropBudget(int64_t x)
Definition Solver.h:359
void claBumpActivity(Clause &c)
Definition Solver.h:316
void removeSatisfied(vec< CRef > &cs)
void cancelUntil(int level)
virtual void garbageCollect()
vec< VarData > vardata
Definition Solver.h:201
void removeClause(CRef cr)
void setPolarity(Var v, bool b)
Definition Solver.h:349
uint32_t abstractLevel(Var x) const
Definition Solver.h:339
lbool solveLimited(const vec< Lit > &assumps)
Definition Solver.h:400
vec< lbool > assigns
Definition Solver.h:196
void detachClause(CRef cr, bool strict=false)
void analyzeFinal(Lit p, vec< Lit > &out_conflict)
void uncheckedEnqueue(Lit p, CRef from=CRef_Undef)
lbool search(int nof_conflicts)
bool litRedundant(Lit p, uint32_t abstract_levels)
bool addClause_(vec< Lit > &ps)
lbool solve_(double &t)
int size(void) const
Definition Vec.h:64
void push(void)
Definition Vec.h:74
void copyTo(vec< T > &copy) const
Definition Vec.h:91
RegionAllocator< uint32_t >::Ref CRef
bool sign(Lit p)
Definition SolverTypes.h:61
const CRef CRef_Undef
unsigned long long int restarts
Definition Solver.h:63
unsigned long long int decisions
Definition Solver.h:65
unsigned long long int conflicts
Definition Solver.h:64
unsigned long long int propagations
Definition Solver.h:66
unsigned long long int conflict_literals
Definition Solver.h:67
bool operator()(Var x, Var y) const
Definition Solver.h:182
const vec< double > & activity
Definition Solver.h:181
VarOrderLt(const vec< double > &act)
Definition Solver.h:183
WatcherDeleted(const ClauseAllocator &_ca)
Definition Solver.h:176
bool operator()(const Watcher &w) const
Definition Solver.h:177
bool operator==(const Watcher &w) const
Definition Solver.h:169
bool operator!=(const Watcher &w) const
Definition Solver.h:170