abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SolverTypes.h
Go to the documentation of this file.
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 "IntTypes.h"
28 #include "Alg.h"
29 #include "Vec.h"
30 #include "Map.h"
31 #include "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 
102  uint8_t sel = (this->value << 1) | (b.value << 3);
103  uint8_t v = (0xF7F755F4 >> sel) & 3;
104  return lbool(v); }
105 
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;
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:
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 
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:
200 
201  ClauseAllocator(uint32_t start_cap) : RegionAllocator<uint32_t>(start_cap), extra_clause_field(false){}
203 
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):
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);
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 {
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>
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>
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 
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 
399 {
400  remove(*this, p);
401  calcAbstraction();
402 }
403 
404 //=================================================================================================
405 }
406 
407 #endif
RegionAllocator< uint32_t >::Ref CRef
Definition: SolverTypes.h:120
void relocate(CRef c)
Definition: SolverTypes.h:173
void insert(CRef cr, const T &t)
Definition: SolverTypes.h:332
void insert(const K &k, const D &d)
Definition: Map.h:133
Ref alloc(int size)
Definition: Alloc.h:111
const vec< Pair > & bucket(int i) const
Definition: Map.h:187
int elems() const
Definition: Map.h:171
VOID_HACK free()
T * lea(Ref r)
Definition: Alloc.h:66
const Clause & operator[](Ref r) const
Definition: SolverTypes.h:223
char lbool
Definition: satVec.h:133
lbool operator||(lbool b) const
Definition: SolverTypes.h:106
static Llb_Mgr_t * p
Definition: llb3Image.c:950
OccLists(const Deleted &d)
Definition: SolverTypes.h:264
void clean(const Idx &idx)
Definition: SolverTypes.h:300
Clause(const V &ps, bool use_extra, bool learnt)
Definition: SolverTypes.h:136
uint32_t mark() const
Definition: SolverTypes.h:167
bool operator==(Lit p) const
Definition: SolverTypes.h:52
Ref ael(const T *t)
Definition: Alloc.h:68
void mark(uint32_t m)
Definition: SolverTypes.h:168
int size() const
Definition: SolverTypes.h:162
int var(Lit p)
Definition: SolverTypes.h:62
void strengthen(Lit p)
Definition: SolverTypes.h:398
CRef relocation() const
Definition: SolverTypes.h:172
void clear(bool free=true)
Definition: SolverTypes.h:280
void moveTo(Map &other)
Definition: Map.h:175
Map< CRef, T, CRefHash > HashTable
Definition: SolverTypes.h:322
union Minisat::Clause::@62 data[0]
CRef alloc(const Lits &ps, bool learnt=false)
Definition: SolverTypes.h:209
bool sign(Lit p)
Definition: SolverTypes.h:61
#define false
Definition: place_base.h:29
Lit mkLit(Var var, bool sign)
Definition: SolverTypes.h:58
unsigned learnt
Definition: SolverTypes.h:126
int lit
Definition: satVec.h:130
Lit operator~(Lit p)
Definition: SolverTypes.h:59
lbool(uint8_t v)
Definition: SolverTypes.h:92
Vec & operator[](const Idx &idx)
Definition: SolverTypes.h:268
Ref ael(const Clause *t)
Definition: SolverTypes.h:226
void push(void)
Definition: Vec.h:73
const Lit & last() const
Definition: SolverTypes.h:169
float & activity()
Definition: SolverTypes.h:181
void shrink(int i)
Definition: SolverTypes.h:163
bool has(CRef cr, T &t)
Definition: SolverTypes.h:335
Clause * lea(Ref r)
Definition: SolverTypes.h:224
friend lbool toLbool(int v)
Definition: SolverTypes.h:115
Lit & operator[](int i)
Definition: SolverTypes.h:177
vec< Idx > dirties
Definition: SolverTypes.h:260
unsigned reloced
Definition: SolverTypes.h:128
const CRef CRef_Undef
Definition: SolverTypes.h:193
uint32_t abstraction() const
Definition: SolverTypes.h:182
Lit operator^(Lit p, bool b)
Definition: SolverTypes.h:60
bool peek(const K &k, D &d) const
Definition: Map.h:134
bool operator==(lbool b) const
Definition: SolverTypes.h:97
void moveTo(RegionAllocator &to)
Definition: Alloc.h:71
friend Lit mkLit(Var var, bool sign=false)
Definition: SolverTypes.h:58
vec< char > dirty
Definition: SolverTypes.h:259
int size() const
Definition: SolverTypes.h:328
void shrink(int nelems)
Definition: Vec.h:64
const vec< typename HashTable::Pair > & bucket(int i) const
Definition: SolverTypes.h:343
int bucket_count() const
Definition: Map.h:172
Clause & operator[](Ref r)
Definition: SolverTypes.h:222
vec< Vec > occs
Definition: SolverTypes.h:258
void clear(bool dealloc=false)
Definition: Vec.h:121
unsigned has_extra
Definition: SolverTypes.h:127
void _free(int size)
Definition: Alloc.h:60
void reloc(CRef &cr, ClauseAllocator &to)
Definition: SolverTypes.h:234
uint32_t operator()(CRef cr) const
Definition: SolverTypes.h:320
lbool operator^(bool b) const
Definition: SolverTypes.h:99
bool learnt() const
Definition: SolverTypes.h:165
lbool toLbool(int v)
Definition: SolverTypes.h:115
bool operator!=(Lit p) const
Definition: SolverTypes.h:53
int bucket_count() const
Definition: SolverTypes.h:342
static int clauseWord32Size(int size, bool has_extra)
Definition: SolverTypes.h:196
void init(const Idx &idx)
Definition: SolverTypes.h:266
bool operator<(Lit p) const
Definition: SolverTypes.h:54
friend int toInt(lbool l)
Definition: SolverTypes.h:114
void smudge(const Idx &idx)
Definition: SolverTypes.h:273
T & operator[](Ref r)
Definition: Alloc.h:63
void remove(const K &k)
Definition: Map.h:154
void moveTo(ClauseAllocator &to)
Definition: SolverTypes.h:204
bool has_extra() const
Definition: SolverTypes.h:166
struct Minisat::Clause::@61 header
void clear()
Definition: Map.h:165
bool operator!=(lbool b) const
Definition: SolverTypes.h:98
int Var
Definition: SolverTypes.h:42
const Lit lit_Error
Definition: SolverTypes.h:73
uint8_t value
Definition: SolverTypes.h:89
Lit subsumes(const Clause &other) const
Definition: SolverTypes.h:367
void growTo(CRef cr, const T &t)
Definition: SolverTypes.h:333
const Lit lit_Undef
Definition: SolverTypes.h:72
void calcAbstraction()
Definition: SolverTypes.h:154
#define assert(ex)
Definition: util_old.h:213
ClauseAllocator(uint32_t start_cap)
Definition: SolverTypes.h:201
bool reloced() const
Definition: SolverTypes.h:171
void growTo(int size)
Definition: Vec.h:113
void _free(CRef cid)
Definition: SolverTypes.h:228
Lit toLit(int i)
Definition: SolverTypes.h:67
const T & operator[](CRef cr) const
Definition: SolverTypes.h:338
lbool operator&&(lbool b) const
Definition: SolverTypes.h:101
int toInt(Var v)
Definition: SolverTypes.h:65
void moveTo(CMap &other)
Definition: SolverTypes.h:346
lbool(bool x)
Definition: SolverTypes.h:95
const Clause * lea(Ref r) const
Definition: SolverTypes.h:225
HashTable map
Definition: SolverTypes.h:323
Vec & lookup(const Idx &idx)
Definition: SolverTypes.h:269