ruby-minisat 1.14.2 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -21
  3. data/Gemfile +4 -0
  4. data/LICENSE +3 -2
  5. data/README.md +42 -0
  6. data/Rakefile +1 -48
  7. data/examples/shikaku.rb +2 -2
  8. data/ext/minisat/extconf.rb +19 -4
  9. data/ext/minisat/minisat-wrap.cpp +11 -5
  10. data/ext/minisat/minisat.c +17 -3
  11. data/ext/minisat/minisat.h +1 -1
  12. data/minisat/minisat-2.2.0.tar.gz +0 -0
  13. data/minisat/{MiniSat_v1.14 → minisat}/LICENSE +2 -1
  14. data/minisat/minisat/README +24 -0
  15. data/minisat/minisat/core/Dimacs.h +89 -0
  16. data/minisat/minisat/core/Main.cc +192 -0
  17. data/minisat/minisat/core/Solver.cc +923 -0
  18. data/minisat/minisat/core/Solver.h +373 -0
  19. data/minisat/minisat/core/SolverTypes.h +407 -0
  20. data/minisat/minisat/mtl/Alg.h +84 -0
  21. data/minisat/minisat/mtl/Alloc.h +131 -0
  22. data/minisat/minisat/mtl/Heap.h +148 -0
  23. data/minisat/minisat/mtl/IntTypes.h +42 -0
  24. data/minisat/minisat/mtl/Map.h +193 -0
  25. data/minisat/minisat/mtl/Queue.h +69 -0
  26. data/minisat/{MiniSat_v1.14 → minisat/mtl}/Sort.h +14 -47
  27. data/minisat/minisat/mtl/Vec.h +130 -0
  28. data/minisat/minisat/mtl/XAlloc.h +45 -0
  29. data/minisat/minisat/mtl/config.mk +6 -0
  30. data/minisat/minisat/mtl/template.mk +107 -0
  31. data/minisat/minisat/simp/Main.cc +211 -0
  32. data/minisat/minisat/simp/SimpSolver.cc +717 -0
  33. data/minisat/minisat/simp/SimpSolver.h +197 -0
  34. data/minisat/minisat/utils/Options.cc +91 -0
  35. data/minisat/minisat/utils/Options.h +386 -0
  36. data/minisat/minisat/utils/ParseUtils.h +122 -0
  37. data/minisat/minisat/utils/System.cc +95 -0
  38. data/minisat/minisat/utils/System.h +60 -0
  39. data/ruby-minisat.gemspec +21 -0
  40. metadata +94 -75
  41. data/README.rdoc +0 -56
  42. data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
  43. data/minisat/MiniSat_v1.14/Global.h +0 -274
  44. data/minisat/MiniSat_v1.14/Heap.h +0 -100
  45. data/minisat/MiniSat_v1.14/Main.C +0 -244
  46. data/minisat/MiniSat_v1.14/Makefile +0 -88
  47. data/minisat/MiniSat_v1.14/README +0 -30
  48. data/minisat/MiniSat_v1.14/Solver.C +0 -781
  49. data/minisat/MiniSat_v1.14/Solver.h +0 -206
  50. data/minisat/MiniSat_v1.14/Solver.o +0 -0
  51. data/minisat/MiniSat_v1.14/SolverTypes.h +0 -130
  52. data/minisat/MiniSat_v1.14/TODO +0 -73
  53. data/minisat/MiniSat_v1.14/VarOrder.h +0 -96
@@ -0,0 +1,373 @@
1
+ /****************************************************************************************[Solver.h]
2
+ Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3
+ Copyright (c) 2007-2010, Niklas Sorensson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction,
7
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or
12
+ substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+ **************************************************************************************************/
20
+
21
+ #ifndef Minisat_Solver_h
22
+ #define Minisat_Solver_h
23
+
24
+ #include "mtl/Vec.h"
25
+ #include "mtl/Heap.h"
26
+ #include "mtl/Alg.h"
27
+ #include "utils/Options.h"
28
+ #include "core/SolverTypes.h"
29
+
30
+
31
+ namespace Minisat {
32
+
33
+ //=================================================================================================
34
+ // Solver -- the main class:
35
+
36
+ class Solver {
37
+ public:
38
+
39
+ // Constructor/Destructor:
40
+ //
41
+ Solver();
42
+ virtual ~Solver();
43
+
44
+ // Problem specification:
45
+ //
46
+ Var newVar (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
47
+
48
+ bool addClause (const vec<Lit>& ps); // Add a clause to the solver.
49
+ bool addEmptyClause(); // Add the empty clause, making the solver contradictory.
50
+ bool addClause (Lit p); // Add a unit clause to the solver.
51
+ bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
52
+ bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
53
+ bool addClause_( vec<Lit>& ps); // Add a clause to the solver without making superflous internal copy. Will
54
+ // change the passed vector 'ps'.
55
+
56
+ // Solving:
57
+ //
58
+ bool simplify (); // Removes already satisfied clauses.
59
+ bool solve (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions.
60
+ lbool solveLimited (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions (With resource constraints).
61
+ bool solve (); // Search without assumptions.
62
+ bool solve (Lit p); // Search for a model that respects a single assumption.
63
+ bool solve (Lit p, Lit q); // Search for a model that respects two assumptions.
64
+ bool solve (Lit p, Lit q, Lit r); // Search for a model that respects three assumptions.
65
+ bool okay () const; // FALSE means solver is in a conflicting state
66
+
67
+ void toDimacs (FILE* f, const vec<Lit>& assumps); // Write CNF to file in DIMACS-format.
68
+ void toDimacs (const char *file, const vec<Lit>& assumps);
69
+ void toDimacs (FILE* f, Clause& c, vec<Var>& map, Var& max);
70
+
71
+ // Convenience versions of 'toDimacs()':
72
+ void toDimacs (const char* file);
73
+ void toDimacs (const char* file, Lit p);
74
+ void toDimacs (const char* file, Lit p, Lit q);
75
+ void toDimacs (const char* file, Lit p, Lit q, Lit r);
76
+
77
+ // Variable mode:
78
+ //
79
+ void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
80
+ void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
81
+
82
+ // Read state:
83
+ //
84
+ lbool value (Var x) const; // The current value of a variable.
85
+ lbool value (Lit p) const; // The current value of a literal.
86
+ lbool modelValue (Var x) const; // The value of a variable in the last model. The last call to solve must have been satisfiable.
87
+ lbool modelValue (Lit p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable.
88
+ int nAssigns () const; // The current number of assigned literals.
89
+ int nClauses () const; // The current number of original clauses.
90
+ int nLearnts () const; // The current number of learnt clauses.
91
+ int nVars () const; // The current number of variables.
92
+ int nFreeVars () const;
93
+
94
+ // Resource contraints:
95
+ //
96
+ void setConfBudget(int64_t x);
97
+ void setPropBudget(int64_t x);
98
+ void budgetOff();
99
+ void interrupt(); // Trigger a (potentially asynchronous) interruption of the solver.
100
+ void clearInterrupt(); // Clear interrupt indicator flag.
101
+
102
+ // Memory managment:
103
+ //
104
+ virtual void garbageCollect();
105
+ void checkGarbage(double gf);
106
+ void checkGarbage();
107
+
108
+ // Extra results: (read-only member variable)
109
+ //
110
+ vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
111
+ vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions),
112
+ // this vector represent the final conflict clause expressed in the assumptions.
113
+
114
+ // Mode of operation:
115
+ //
116
+ int verbosity;
117
+ double var_decay;
118
+ double clause_decay;
119
+ double random_var_freq;
120
+ double random_seed;
121
+ bool luby_restart;
122
+ int ccmin_mode; // Controls conflict clause minimization (0=none, 1=basic, 2=deep).
123
+ int phase_saving; // Controls the level of phase saving (0=none, 1=limited, 2=full).
124
+ bool rnd_pol; // Use random polarities for branching heuristics.
125
+ bool rnd_init_act; // Initialize variable activities with a small random value.
126
+ double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered.
127
+
128
+ int restart_first; // The initial restart limit. (default 100)
129
+ double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.5)
130
+ double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3)
131
+ double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1)
132
+
133
+ int learntsize_adjust_start_confl;
134
+ double learntsize_adjust_inc;
135
+
136
+ // Statistics: (read-only member variable)
137
+ //
138
+ uint64_t solves, starts, decisions, rnd_decisions, propagations, conflicts;
139
+ uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals;
140
+
141
+ protected:
142
+
143
+ // Helper structures:
144
+ //
145
+ struct VarData { CRef reason; int level; };
146
+ static inline VarData mkVarData(CRef cr, int l){ VarData d = {cr, l}; return d; }
147
+
148
+ struct Watcher {
149
+ CRef cref;
150
+ Lit blocker;
151
+ Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {}
152
+ bool operator==(const Watcher& w) const { return cref == w.cref; }
153
+ bool operator!=(const Watcher& w) const { return cref != w.cref; }
154
+ };
155
+
156
+ struct WatcherDeleted
157
+ {
158
+ const ClauseAllocator& ca;
159
+ WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
160
+ bool operator()(const Watcher& w) const { return ca[w.cref].mark() == 1; }
161
+ };
162
+
163
+ struct VarOrderLt {
164
+ const vec<double>& activity;
165
+ bool operator () (Var x, Var y) const { return activity[x] > activity[y]; }
166
+ VarOrderLt(const vec<double>& act) : activity(act) { }
167
+ };
168
+
169
+ // Solver state:
170
+ //
171
+ bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
172
+ vec<CRef> clauses; // List of problem clauses.
173
+ vec<CRef> learnts; // List of learnt clauses.
174
+ double cla_inc; // Amount to bump next clause with.
175
+ vec<double> activity; // A heuristic measurement of the activity of a variable.
176
+ double var_inc; // Amount to bump next variable with.
177
+ OccLists<Lit, vec<Watcher>, WatcherDeleted>
178
+ watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
179
+ vec<lbool> assigns; // The current assignments.
180
+ vec<char> polarity; // The preferred polarity of each variable.
181
+ vec<char> decision; // Declares if a variable is eligible for selection in the decision heuristic.
182
+ vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
183
+ vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
184
+ vec<VarData> vardata; // Stores reason and level for each variable.
185
+ int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
186
+ int simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'.
187
+ int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'.
188
+ vec<Lit> assumptions; // Current set of assumptions provided to solve by the user.
189
+ Heap<VarOrderLt> order_heap; // A priority queue of variables ordered with respect to the variable activity.
190
+ double progress_estimate;// Set by 'search()'.
191
+ bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'.
192
+
193
+ ClauseAllocator ca;
194
+
195
+ // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
196
+ // used, exept 'seen' wich is used in several places.
197
+ //
198
+ vec<char> seen;
199
+ vec<Lit> analyze_stack;
200
+ vec<Lit> analyze_toclear;
201
+ vec<Lit> add_tmp;
202
+
203
+ double max_learnts;
204
+ double learntsize_adjust_confl;
205
+ int learntsize_adjust_cnt;
206
+
207
+ // Resource contraints:
208
+ //
209
+ int64_t conflict_budget; // -1 means no budget.
210
+ int64_t propagation_budget; // -1 means no budget.
211
+ bool asynch_interrupt;
212
+
213
+ // Main internal methods:
214
+ //
215
+ void insertVarOrder (Var x); // Insert a variable in the decision order priority queue.
216
+ Lit pickBranchLit (); // Return the next decision variable.
217
+ void newDecisionLevel (); // Begins a new decision level.
218
+ void uncheckedEnqueue (Lit p, CRef from = CRef_Undef); // Enqueue a literal. Assumes value of literal is undefined.
219
+ bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise.
220
+ CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause.
221
+ void cancelUntil (int level); // Backtrack until a certain level.
222
+ void analyze (CRef confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
223
+ void analyzeFinal (Lit p, vec<Lit>& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION?
224
+ bool litRedundant (Lit p, uint32_t abstract_levels); // (helper method for 'analyze()')
225
+ lbool search (int nof_conflicts); // Search for a given number of conflicts.
226
+ lbool solve_ (); // Main solve method (assumptions given in 'assumptions').
227
+ void reduceDB (); // Reduce the set of learnt clauses.
228
+ void removeSatisfied (vec<CRef>& cs); // Shrink 'cs' to contain only non-satisfied clauses.
229
+ void rebuildOrderHeap ();
230
+
231
+ // Maintaining Variable/Clause activity:
232
+ //
233
+ void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
234
+ void varBumpActivity (Var v, double inc); // Increase a variable with the current 'bump' value.
235
+ void varBumpActivity (Var v); // Increase a variable with the current 'bump' value.
236
+ void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead.
237
+ void claBumpActivity (Clause& c); // Increase a clause with the current 'bump' value.
238
+
239
+ // Operations on clauses:
240
+ //
241
+ void attachClause (CRef cr); // Attach a clause to watcher lists.
242
+ void detachClause (CRef cr, bool strict = false); // Detach a clause to watcher lists.
243
+ void removeClause (CRef cr); // Detach and free a clause.
244
+ bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state.
245
+ bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state.
246
+
247
+ void relocAll (ClauseAllocator& to);
248
+
249
+ // Misc:
250
+ //
251
+ int decisionLevel () const; // Gives the current decisionlevel.
252
+ uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
253
+ CRef reason (Var x) const;
254
+ int level (Var x) const;
255
+ double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
256
+ bool withinBudget () const;
257
+
258
+ // Static helpers:
259
+ //
260
+
261
+ // Returns a random float 0 <= x < 1. Seed must never be 0.
262
+ static inline double drand(double& seed) {
263
+ seed *= 1389796;
264
+ int q = (int)(seed / 2147483647);
265
+ seed -= (double)q * 2147483647;
266
+ return seed / 2147483647; }
267
+
268
+ // Returns a random integer 0 <= x < size. Seed must never be 0.
269
+ static inline int irand(double& seed, int size) {
270
+ return (int)(drand(seed) * size); }
271
+ };
272
+
273
+
274
+ //=================================================================================================
275
+ // Implementation of inline methods:
276
+
277
+ inline CRef Solver::reason(Var x) const { return vardata[x].reason; }
278
+ inline int Solver::level (Var x) const { return vardata[x].level; }
279
+
280
+ inline void Solver::insertVarOrder(Var x) {
281
+ if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x); }
282
+
283
+ inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); }
284
+ inline void Solver::varBumpActivity(Var v) { varBumpActivity(v, var_inc); }
285
+ inline void Solver::varBumpActivity(Var v, double inc) {
286
+ if ( (activity[v] += inc) > 1e100 ) {
287
+ // Rescale:
288
+ for (int i = 0; i < nVars(); i++)
289
+ activity[i] *= 1e-100;
290
+ var_inc *= 1e-100; }
291
+
292
+ // Update order_heap with respect to new activity:
293
+ if (order_heap.inHeap(v))
294
+ order_heap.decrease(v); }
295
+
296
+ inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); }
297
+ inline void Solver::claBumpActivity (Clause& c) {
298
+ if ( (c.activity() += cla_inc) > 1e20 ) {
299
+ // Rescale:
300
+ for (int i = 0; i < learnts.size(); i++)
301
+ ca[learnts[i]].activity() *= 1e-20;
302
+ cla_inc *= 1e-20; } }
303
+
304
+ inline void Solver::checkGarbage(void){ return checkGarbage(garbage_frac); }
305
+ inline void Solver::checkGarbage(double gf){
306
+ if (ca.wasted() > ca.size() * gf)
307
+ garbageCollect(); }
308
+
309
+ // NOTE: enqueue does not set the ok flag! (only public methods do)
310
+ inline bool Solver::enqueue (Lit p, CRef from) { return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true); }
311
+ inline bool Solver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
312
+ inline bool Solver::addEmptyClause () { add_tmp.clear(); return addClause_(add_tmp); }
313
+ inline bool Solver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
314
+ inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
315
+ inline 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); }
316
+ inline 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; }
317
+ inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); }
318
+
319
+ inline int Solver::decisionLevel () const { return trail_lim.size(); }
320
+ inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); }
321
+ inline lbool Solver::value (Var x) const { return assigns[x]; }
322
+ inline lbool Solver::value (Lit p) const { return assigns[var(p)] ^ sign(p); }
323
+ inline lbool Solver::modelValue (Var x) const { return model[x]; }
324
+ inline lbool Solver::modelValue (Lit p) const { return model[var(p)] ^ sign(p); }
325
+ inline int Solver::nAssigns () const { return trail.size(); }
326
+ inline int Solver::nClauses () const { return clauses.size(); }
327
+ inline int Solver::nLearnts () const { return learnts.size(); }
328
+ inline int Solver::nVars () const { return vardata.size(); }
329
+ inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
330
+ inline void Solver::setPolarity (Var v, bool b) { polarity[v] = b; }
331
+ inline void Solver::setDecisionVar(Var v, bool b)
332
+ {
333
+ if ( b && !decision[v]) dec_vars++;
334
+ else if (!b && decision[v]) dec_vars--;
335
+
336
+ decision[v] = b;
337
+ insertVarOrder(v);
338
+ }
339
+ inline void Solver::setConfBudget(int64_t x){ conflict_budget = conflicts + x; }
340
+ inline void Solver::setPropBudget(int64_t x){ propagation_budget = propagations + x; }
341
+ inline void Solver::interrupt(){ asynch_interrupt = true; }
342
+ inline void Solver::clearInterrupt(){ asynch_interrupt = false; }
343
+ inline void Solver::budgetOff(){ conflict_budget = propagation_budget = -1; }
344
+ inline bool Solver::withinBudget() const {
345
+ return !asynch_interrupt &&
346
+ (conflict_budget < 0 || conflicts < (uint64_t)conflict_budget) &&
347
+ (propagation_budget < 0 || propagations < (uint64_t)propagation_budget); }
348
+
349
+ // FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a
350
+ // pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or
351
+ // all calls to solve must return an 'lbool'. I'm not yet sure which I prefer.
352
+ inline bool Solver::solve () { budgetOff(); assumptions.clear(); return solve_() == l_True; }
353
+ inline bool Solver::solve (Lit p) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_() == l_True; }
354
+ inline bool Solver::solve (Lit p, Lit q) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_() == l_True; }
355
+ inline 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; }
356
+ inline bool Solver::solve (const vec<Lit>& assumps){ budgetOff(); assumps.copyTo(assumptions); return solve_() == l_True; }
357
+ inline lbool Solver::solveLimited (const vec<Lit>& assumps){ assumps.copyTo(assumptions); return solve_(); }
358
+ inline bool Solver::okay () const { return ok; }
359
+
360
+ inline void Solver::toDimacs (const char* file){ vec<Lit> as; toDimacs(file, as); }
361
+ inline void Solver::toDimacs (const char* file, Lit p){ vec<Lit> as; as.push(p); toDimacs(file, as); }
362
+ inline void Solver::toDimacs (const char* file, Lit p, Lit q){ vec<Lit> as; as.push(p); as.push(q); toDimacs(file, as); }
363
+ inline 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); }
364
+
365
+
366
+ //=================================================================================================
367
+ // Debug etc:
368
+
369
+
370
+ //=================================================================================================
371
+ }
372
+
373
+ #endif
@@ -0,0 +1,407 @@
1
+ /***********************************************************************************[SolverTypes.h]
2
+ Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3
+ Copyright (c) 2007-2010, Niklas Sorensson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction,
7
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or
12
+ substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+ **************************************************************************************************/
20
+
21
+
22
+ #ifndef Minisat_SolverTypes_h
23
+ #define Minisat_SolverTypes_h
24
+
25
+ #include <assert.h>
26
+
27
+ #include "mtl/IntTypes.h"
28
+ #include "mtl/Alg.h"
29
+ #include "mtl/Vec.h"
30
+ #include "mtl/Map.h"
31
+ #include "mtl/Alloc.h"
32
+
33
+ namespace Minisat {
34
+
35
+ //=================================================================================================
36
+ // Variables, literals, lifted booleans, clauses:
37
+
38
+
39
+ // NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
40
+ // so that they can be used as array indices.
41
+
42
+ typedef int Var;
43
+ #define var_Undef (-1)
44
+
45
+
46
+ struct Lit {
47
+ int x;
48
+
49
+ // Use this as a constructor:
50
+ friend Lit mkLit(Var var, bool sign = false);
51
+
52
+ bool operator == (Lit p) const { return x == p.x; }
53
+ bool operator != (Lit p) const { return x != p.x; }
54
+ bool operator < (Lit p) const { return x < p.x; } // '<' makes p, ~p adjacent in the ordering.
55
+ };
56
+
57
+
58
+ inline Lit mkLit (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; }
59
+ inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; }
60
+ inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; }
61
+ inline bool sign (Lit p) { return p.x & 1; }
62
+ inline int var (Lit p) { return p.x >> 1; }
63
+
64
+ // Mapping Literals to and from compact integers suitable for array indexing:
65
+ inline int toInt (Var v) { return v; }
66
+ inline int toInt (Lit p) { return p.x; }
67
+ inline Lit toLit (int i) { Lit p; p.x = i; return p; }
68
+
69
+ //const Lit lit_Undef = mkLit(var_Undef, false); // }- Useful special constants.
70
+ //const Lit lit_Error = mkLit(var_Undef, true ); // }
71
+
72
+ const Lit lit_Undef = { -2 }; // }- Useful special constants.
73
+ const Lit lit_Error = { -1 }; // }
74
+
75
+
76
+ //=================================================================================================
77
+ // Lifted booleans:
78
+ //
79
+ // NOTE: this implementation is optimized for the case when comparisons between values are mostly
80
+ // between one variable and one constant. Some care had to be taken to make sure that gcc
81
+ // does enough constant propagation to produce sensible code, and this appears to be somewhat
82
+ // fragile unfortunately.
83
+
84
+ #define l_True (lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants.
85
+ #define l_False (lbool((uint8_t)1))
86
+ #define l_Undef (lbool((uint8_t)2))
87
+
88
+ class lbool {
89
+ uint8_t value;
90
+
91
+ public:
92
+ explicit lbool(uint8_t v) : value(v) { }
93
+
94
+ lbool() : value(0) { }
95
+ explicit lbool(bool x) : value(!x) { }
96
+
97
+ bool operator == (lbool b) const { return ((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value)); }
98
+ bool operator != (lbool b) const { return !(*this == b); }
99
+ lbool operator ^ (bool b) const { return lbool((uint8_t)(value^(uint8_t)b)); }
100
+
101
+ lbool operator && (lbool b) const {
102
+ uint8_t sel = (this->value << 1) | (b.value << 3);
103
+ uint8_t v = (0xF7F755F4 >> sel) & 3;
104
+ return lbool(v); }
105
+
106
+ lbool operator || (lbool b) const {
107
+ uint8_t sel = (this->value << 1) | (b.value << 3);
108
+ uint8_t v = (0xFCFCF400 >> sel) & 3;
109
+ return lbool(v); }
110
+
111
+ friend int toInt (lbool l);
112
+ friend lbool toLbool(int v);
113
+ };
114
+ inline int toInt (lbool l) { return l.value; }
115
+ inline lbool toLbool(int v) { return lbool((uint8_t)v); }
116
+
117
+ //=================================================================================================
118
+ // Clause -- a simple class for representing a clause:
119
+
120
+ class Clause;
121
+ typedef RegionAllocator<uint32_t>::Ref CRef;
122
+
123
+ class Clause {
124
+ struct {
125
+ unsigned mark : 2;
126
+ unsigned learnt : 1;
127
+ unsigned has_extra : 1;
128
+ unsigned reloced : 1;
129
+ unsigned size : 27; } header;
130
+ union { Lit lit; float act; uint32_t abs; CRef rel; } data[0];
131
+
132
+ friend class ClauseAllocator;
133
+
134
+ // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
135
+ template<class V>
136
+ Clause(const V& ps, bool use_extra, bool learnt) {
137
+ header.mark = 0;
138
+ header.learnt = learnt;
139
+ header.has_extra = use_extra;
140
+ header.reloced = 0;
141
+ header.size = ps.size();
142
+
143
+ for (int i = 0; i < ps.size(); i++)
144
+ data[i].lit = ps[i];
145
+
146
+ if (header.has_extra){
147
+ if (header.learnt)
148
+ data[header.size].act = 0;
149
+ else
150
+ calcAbstraction(); }
151
+ }
152
+
153
+ public:
154
+ void calcAbstraction() {
155
+ assert(header.has_extra);
156
+ uint32_t abstraction = 0;
157
+ for (int i = 0; i < size(); i++)
158
+ abstraction |= 1 << (var(data[i].lit) & 31);
159
+ data[header.size].abs = abstraction; }
160
+
161
+
162
+ int size () const { return header.size; }
163
+ void shrink (int i) { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; }
164
+ void pop () { shrink(1); }
165
+ bool learnt () const { return header.learnt; }
166
+ bool has_extra () const { return header.has_extra; }
167
+ uint32_t mark () const { return header.mark; }
168
+ void mark (uint32_t m) { header.mark = m; }
169
+ const Lit& last () const { return data[header.size-1].lit; }
170
+
171
+ bool reloced () const { return header.reloced; }
172
+ CRef relocation () const { return data[0].rel; }
173
+ void relocate (CRef c) { header.reloced = 1; data[0].rel = c; }
174
+
175
+ // NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for
176
+ // subsumption operations to behave correctly.
177
+ Lit& operator [] (int i) { return data[i].lit; }
178
+ Lit operator [] (int i) const { return data[i].lit; }
179
+ operator const Lit* (void) const { return (Lit*)data; }
180
+
181
+ float& activity () { assert(header.has_extra); return data[header.size].act; }
182
+ uint32_t abstraction () const { assert(header.has_extra); return data[header.size].abs; }
183
+
184
+ Lit subsumes (const Clause& other) const;
185
+ void strengthen (Lit p);
186
+ };
187
+
188
+
189
+ //=================================================================================================
190
+ // ClauseAllocator -- a simple class for allocating memory for clauses:
191
+
192
+
193
+ const CRef CRef_Undef = RegionAllocator<uint32_t>::Ref_Undef;
194
+ class ClauseAllocator : public RegionAllocator<uint32_t>
195
+ {
196
+ static int clauseWord32Size(int size, bool has_extra){
197
+ return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); }
198
+ public:
199
+ bool extra_clause_field;
200
+
201
+ ClauseAllocator(uint32_t start_cap) : RegionAllocator<uint32_t>(start_cap), extra_clause_field(false){}
202
+ ClauseAllocator() : extra_clause_field(false){}
203
+
204
+ void moveTo(ClauseAllocator& to){
205
+ to.extra_clause_field = extra_clause_field;
206
+ RegionAllocator<uint32_t>::moveTo(to); }
207
+
208
+ template<class Lits>
209
+ CRef alloc(const Lits& ps, bool learnt = false)
210
+ {
211
+ assert(sizeof(Lit) == sizeof(uint32_t));
212
+ assert(sizeof(float) == sizeof(uint32_t));
213
+ bool use_extra = learnt | extra_clause_field;
214
+
215
+ CRef cid = RegionAllocator<uint32_t>::alloc(clauseWord32Size(ps.size(), use_extra));
216
+ new (lea(cid)) Clause(ps, use_extra, learnt);
217
+
218
+ return cid;
219
+ }
220
+
221
+ // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
222
+ Clause& operator[](Ref r) { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
223
+ const Clause& operator[](Ref r) const { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
224
+ Clause* lea (Ref r) { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
225
+ const Clause* lea (Ref r) const { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
226
+ Ref ael (const Clause* t){ return RegionAllocator<uint32_t>::ael((uint32_t*)t); }
227
+
228
+ void free(CRef cid)
229
+ {
230
+ Clause& c = operator[](cid);
231
+ RegionAllocator<uint32_t>::free(clauseWord32Size(c.size(), c.has_extra()));
232
+ }
233
+
234
+ void reloc(CRef& cr, ClauseAllocator& to)
235
+ {
236
+ Clause& c = operator[](cr);
237
+
238
+ if (c.reloced()) { cr = c.relocation(); return; }
239
+
240
+ cr = to.alloc(c, c.learnt());
241
+ c.relocate(cr);
242
+
243
+ // Copy extra data-fields:
244
+ // (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?)
245
+ to[cr].mark(c.mark());
246
+ if (to[cr].learnt()) to[cr].activity() = c.activity();
247
+ else if (to[cr].has_extra()) to[cr].calcAbstraction();
248
+ }
249
+ };
250
+
251
+
252
+ //=================================================================================================
253
+ // OccLists -- a class for maintaining occurence lists with lazy deletion:
254
+
255
+ template<class Idx, class Vec, class Deleted>
256
+ class OccLists
257
+ {
258
+ vec<Vec> occs;
259
+ vec<char> dirty;
260
+ vec<Idx> dirties;
261
+ Deleted deleted;
262
+
263
+ public:
264
+ OccLists(const Deleted& d) : deleted(d) {}
265
+
266
+ void init (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); }
267
+ // Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
268
+ Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
269
+ Vec& lookup (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; }
270
+
271
+ void cleanAll ();
272
+ void clean (const Idx& idx);
273
+ void smudge (const Idx& idx){
274
+ if (dirty[toInt(idx)] == 0){
275
+ dirty[toInt(idx)] = 1;
276
+ dirties.push(idx);
277
+ }
278
+ }
279
+
280
+ void clear(bool free = true){
281
+ occs .clear(free);
282
+ dirty .clear(free);
283
+ dirties.clear(free);
284
+ }
285
+ };
286
+
287
+
288
+ template<class Idx, class Vec, class Deleted>
289
+ void OccLists<Idx,Vec,Deleted>::cleanAll()
290
+ {
291
+ for (int i = 0; i < dirties.size(); i++)
292
+ // Dirties may contain duplicates so check here if a variable is already cleaned:
293
+ if (dirty[toInt(dirties[i])])
294
+ clean(dirties[i]);
295
+ dirties.clear();
296
+ }
297
+
298
+
299
+ template<class Idx, class Vec, class Deleted>
300
+ void OccLists<Idx,Vec,Deleted>::clean(const Idx& idx)
301
+ {
302
+ Vec& vec = occs[toInt(idx)];
303
+ int i, j;
304
+ for (i = j = 0; i < vec.size(); i++)
305
+ if (!deleted(vec[i]))
306
+ vec[j++] = vec[i];
307
+ vec.shrink(i - j);
308
+ dirty[toInt(idx)] = 0;
309
+ }
310
+
311
+
312
+ //=================================================================================================
313
+ // CMap -- a class for mapping clauses to values:
314
+
315
+
316
+ template<class T>
317
+ class CMap
318
+ {
319
+ struct CRefHash {
320
+ uint32_t operator()(CRef cr) const { return (uint32_t)cr; } };
321
+
322
+ typedef Map<CRef, T, CRefHash> HashTable;
323
+ HashTable map;
324
+
325
+ public:
326
+ // Size-operations:
327
+ void clear () { map.clear(); }
328
+ int size () const { return map.elems(); }
329
+
330
+
331
+ // Insert/Remove/Test mapping:
332
+ void insert (CRef cr, const T& t){ map.insert(cr, t); }
333
+ void growTo (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility
334
+ void remove (CRef cr) { map.remove(cr); }
335
+ bool has (CRef cr, T& t) { return map.peek(cr, t); }
336
+
337
+ // Vector interface (the clause 'c' must already exist):
338
+ const T& operator [] (CRef cr) const { return map[cr]; }
339
+ T& operator [] (CRef cr) { return map[cr]; }
340
+
341
+ // Iteration (not transparent at all at the moment):
342
+ int bucket_count() const { return map.bucket_count(); }
343
+ const vec<typename HashTable::Pair>& bucket(int i) const { return map.bucket(i); }
344
+
345
+ // Move contents to other map:
346
+ void moveTo(CMap& other){ map.moveTo(other.map); }
347
+
348
+ // TMP debug:
349
+ void debug(){
350
+ printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); }
351
+ };
352
+
353
+
354
+ /*_________________________________________________________________________________________________
355
+ |
356
+ | subsumes : (other : const Clause&) -> Lit
357
+ |
358
+ | Description:
359
+ | Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other'
360
+ | by subsumption resolution.
361
+ |
362
+ | Result:
363
+ | lit_Error - No subsumption or simplification
364
+ | lit_Undef - Clause subsumes 'other'
365
+ | p - The literal p can be deleted from 'other'
366
+ |________________________________________________________________________________________________@*/
367
+ inline Lit Clause::subsumes(const Clause& other) const
368
+ {
369
+ //if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0)
370
+ //if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0))
371
+ assert(!header.learnt); assert(!other.header.learnt);
372
+ assert(header.has_extra); assert(other.header.has_extra);
373
+ if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0)
374
+ return lit_Error;
375
+
376
+ Lit ret = lit_Undef;
377
+ const Lit* c = (const Lit*)(*this);
378
+ const Lit* d = (const Lit*)other;
379
+
380
+ for (unsigned i = 0; i < header.size; i++) {
381
+ // search for c[i] or ~c[i]
382
+ for (unsigned j = 0; j < other.header.size; j++)
383
+ if (c[i] == d[j])
384
+ goto ok;
385
+ else if (ret == lit_Undef && c[i] == ~d[j]){
386
+ ret = c[i];
387
+ goto ok;
388
+ }
389
+
390
+ // did not find it
391
+ return lit_Error;
392
+ ok:;
393
+ }
394
+
395
+ return ret;
396
+ }
397
+
398
+ inline void Clause::strengthen(Lit p)
399
+ {
400
+ remove(*this, p);
401
+ calcAbstraction();
402
+ }
403
+
404
+ //=================================================================================================
405
+ }
406
+
407
+ #endif