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.
- checksums.yaml +7 -0
- data/.gitignore +18 -21
- data/Gemfile +4 -0
- data/LICENSE +3 -2
- data/README.md +42 -0
- data/Rakefile +1 -48
- data/examples/shikaku.rb +2 -2
- data/ext/minisat/extconf.rb +19 -4
- data/ext/minisat/minisat-wrap.cpp +11 -5
- data/ext/minisat/minisat.c +17 -3
- data/ext/minisat/minisat.h +1 -1
- data/minisat/minisat-2.2.0.tar.gz +0 -0
- data/minisat/{MiniSat_v1.14 → minisat}/LICENSE +2 -1
- data/minisat/minisat/README +24 -0
- data/minisat/minisat/core/Dimacs.h +89 -0
- data/minisat/minisat/core/Main.cc +192 -0
- data/minisat/minisat/core/Solver.cc +923 -0
- data/minisat/minisat/core/Solver.h +373 -0
- data/minisat/minisat/core/SolverTypes.h +407 -0
- data/minisat/minisat/mtl/Alg.h +84 -0
- data/minisat/minisat/mtl/Alloc.h +131 -0
- data/minisat/minisat/mtl/Heap.h +148 -0
- data/minisat/minisat/mtl/IntTypes.h +42 -0
- data/minisat/minisat/mtl/Map.h +193 -0
- data/minisat/minisat/mtl/Queue.h +69 -0
- data/minisat/{MiniSat_v1.14 → minisat/mtl}/Sort.h +14 -47
- data/minisat/minisat/mtl/Vec.h +130 -0
- data/minisat/minisat/mtl/XAlloc.h +45 -0
- data/minisat/minisat/mtl/config.mk +6 -0
- data/minisat/minisat/mtl/template.mk +107 -0
- data/minisat/minisat/simp/Main.cc +211 -0
- data/minisat/minisat/simp/SimpSolver.cc +717 -0
- data/minisat/minisat/simp/SimpSolver.h +197 -0
- data/minisat/minisat/utils/Options.cc +91 -0
- data/minisat/minisat/utils/Options.h +386 -0
- data/minisat/minisat/utils/ParseUtils.h +122 -0
- data/minisat/minisat/utils/System.cc +95 -0
- data/minisat/minisat/utils/System.h +60 -0
- data/ruby-minisat.gemspec +21 -0
- metadata +94 -75
- data/README.rdoc +0 -56
- data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
- data/minisat/MiniSat_v1.14/Global.h +0 -274
- data/minisat/MiniSat_v1.14/Heap.h +0 -100
- data/minisat/MiniSat_v1.14/Main.C +0 -244
- data/minisat/MiniSat_v1.14/Makefile +0 -88
- data/minisat/MiniSat_v1.14/README +0 -30
- data/minisat/MiniSat_v1.14/Solver.C +0 -781
- data/minisat/MiniSat_v1.14/Solver.h +0 -206
- data/minisat/MiniSat_v1.14/Solver.o +0 -0
- data/minisat/MiniSat_v1.14/SolverTypes.h +0 -130
- data/minisat/MiniSat_v1.14/TODO +0 -73
- 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
|