ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
SolverTypes.h
Go to the documentation of this file.
1/***********************************************************************************[SolverTypes.h]
2 Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
3 CRIL - Univ. Artois, France
4 LRI - Univ. Paris Sud, France
5
6Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions and copyrights of
7Glucose are exactly the same as Minisat on which it is based on. (see below).
8
9---------------
10Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
11Copyright (c) 2007-2010, Niklas Sorensson
12
13Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
14associated documentation files (the "Software"), to deal in the Software without restriction,
15including without limitation the rights to use, copy, modify, merge, publish, distribute,
16sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in all copies or
20substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
23NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
26OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27**************************************************************************************************/
28
29
30#ifndef Glucose_SolverTypes_h
31#define Glucose_SolverTypes_h
32
33#include <assert.h>
34
36#include "sat/glucose/Alg.h"
37#include "sat/glucose/Vec.h"
38#include "sat/glucose/Map.h"
39#include "sat/glucose/Alloc.h"
40
42
43namespace Gluco {
44
45//=================================================================================================
46// Variables, literals, lifted booleans, clauses:
47
48
49// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
50// so that they can be used as array indices.
51
52typedef int Var;
53#define var_Undef (-1)
54
55
56struct Lit {
57 int x;
58
59 // Use this as a constructor:
60 friend Lit mkLit(Var var, bool sign);
61 bool operator == (Lit p) const { return x == p.x; }
62 bool operator != (Lit p) const { return x != p.x; }
63 bool operator < (Lit p) const { return x < p.x; } // '<' makes p, ~p adjacent in the ordering.
64};
65
66
67inline Lit mkLit (Var var, bool sign = false) { Lit p; p.x = var + var + (int)sign; return p; }
68inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; }
69inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; }
70inline bool sign (Lit p) { return p.x & 1; }
71inline int var (Lit p) { return p.x >> 1; }
72
73// Mapping Literals to and from compact integers suitable for array indexing:
74inline int toInt (Var v) { return v; }
75inline int toInt (Lit p) { return p.x; }
76inline Lit toLit (int i) { Lit p; p.x = i; return p; }
77
78//const Lit lit_Undef = mkLit(var_Undef, false); // }- Useful special constants.
79//const Lit lit_Error = mkLit(var_Undef, true ); // }
80
81const Lit lit_Undef = { -2 }; // }- Useful special constants.
82const Lit lit_Error = { -1 }; // }
83
84
85//=================================================================================================
86// Lifted booleans:
87//
88// NOTE: this implementation is optimized for the case when comparisons between values are mostly
89// between one variable and one constant. Some care had to be taken to make sure that gcc
90// does enough constant propagation to produce sensible code, and this appears to be somewhat
91// fragile unfortunately.
92
93#define l_True (Gluco::lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants.
94#define l_False (Gluco::lbool((uint8_t)1))
95#define l_Undef (Gluco::lbool((uint8_t)2))
96
97class lbool {
98 uint8_t value;
99
100public:
101 explicit lbool(uint8_t v) : value(v) { }
102
103 lbool() : value(0) { }
104 explicit lbool(bool x) : value(!x) { }
105
106 bool operator == (lbool b) const { return (((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value))) != 0; }
107 bool operator != (lbool b) const { return !(*this == b); }
108 lbool operator ^ (bool b) const { return lbool((uint8_t)(value^(uint8_t)b)); }
109
111 uint8_t sel = (this->value << 1) | (b.value << 3);
112 uint8_t v = (0xF7F755F4 >> sel) & 3;
113 return lbool(v); }
114
116 uint8_t sel = (this->value << 1) | (b.value << 3);
117 uint8_t v = (0xFCFCF400 >> sel) & 3;
118 return lbool(v); }
119
120 friend int toInt (lbool l);
121 friend lbool toLbool(int v);
122};
123inline int toInt (lbool l) { return l.value; }
124inline lbool toLbool(int v) { return lbool((uint8_t)v); }
125
126//=================================================================================================
127// Clause -- a simple class for representing a clause:
128
129class Clause;
131
132class Clause {
133 struct {
134 unsigned mark : 2;
135 unsigned learnt : 1;
136 unsigned has_extra : 1;
137 unsigned reloced : 1;
138 unsigned lbd : 26;
139 unsigned canbedel : 1;
140 unsigned size : 32;
141 unsigned szWithoutSelectors : 32;
142
143 } header;
144 union { Lit lit; float act; uint32_t abs; CRef rel; } data[0];
145
146 friend class ClauseAllocator;
147
148 // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
149 template<class V>
150 Clause(const V& ps, bool use_extra, bool learnt) {
151 header.mark = 0;
152 header.learnt = learnt;
153 header.has_extra = use_extra;
154 header.reloced = 0;
155 header.size = ps.size();
156 header.lbd = 0;
157 header.canbedel = 1;
158 for (int i = 0; i < ps.size(); i++)
159 data[i].lit = ps[i];
160
161 if (header.has_extra){
162 if (header.learnt)
163 data[header.size].act = 0;
164 else
165 calcAbstraction(); }
166 }
167
168public:
170 assert(header.has_extra);
172 for (int i = 0; i < size(); i++)
173 abstraction |= 1 << (var(data[i].lit) & 31);
174 data[header.size].abs = abstraction; }
175
176
177 int size () const { return header.size; }
178 void shrink (int i) { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; }
179 void pop () { shrink(1); }
180 bool learnt () const { return header.learnt; }
181 bool has_extra () const { return header.has_extra; }
182 uint32_t mark () const { return header.mark; }
183 void mark (uint32_t m) { header.mark = m; }
184 const Lit& last () const { return data[header.size-1].lit; }
185
186 bool reloced () const { return header.reloced; }
187 CRef relocation () const { return data[0].rel; }
188 void relocate (CRef c) { header.reloced = 1; data[0].rel = c; }
189
190 // NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for
191 // subsumption operations to behave correctly.
192 Lit& operator [] (int i) { return data[i].lit; }
193 Lit operator [] (int i) const { return data[i].lit; }
194 operator const Lit* (void) const { return (Lit*)data; }
195
196 float& activity () { assert(header.has_extra); return data[header.size].act; }
197 uint32_t abstraction () const { assert(header.has_extra); return data[header.size].abs; }
198
199 Lit subsumes (const Clause& other) const;
200 void strengthen (Lit p);
201 void setLBD(int i) {header.lbd = i;}
202 // unsigned int& lbd () { return header.lbd; }
203 unsigned int lbd () const { return header.lbd; }
204 void setCanBeDel(bool b) {header.canbedel = b;}
205 bool canBeDel() {return header.canbedel;}
206 void setSizeWithoutSelectors (unsigned int n) {header.szWithoutSelectors = n; }
207 unsigned int sizeWithoutSelectors () const { return header.szWithoutSelectors; }
208
209};
210
211
212//=================================================================================================
213// ClauseAllocator -- a simple class for allocating memory for clauses:
214
215
217class ClauseAllocator : public RegionAllocator<uint32_t>
218{
219 static int clauseWord32Size(int size, bool has_extra){
220 return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); }
221 public:
223
226
230
231 template<class Lits>
232 CRef alloc(const Lits& ps, bool learnt = false)
233 {
234 assert(sizeof(Lit) == sizeof(uint32_t));
235 assert(sizeof(float) == sizeof(uint32_t));
236 bool use_extra = learnt | extra_clause_field;
237
238 CRef cid = RegionAllocator<uint32_t>::alloc(clauseWord32Size(ps.size(), use_extra));
239 new (lea(cid)) Clause(ps, use_extra, learnt);
240
241 return cid;
242 }
243
244 // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
248 const Clause* lea (Ref r) const { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
250
251 void free_(CRef cid)
252 {
253 Clause& c = operator[](cid);
254 RegionAllocator<uint32_t>::free_(clauseWord32Size(c.size(), c.has_extra()));
255 }
256
258 {
259 Clause& c = operator[](cr);
260
261 if (c.reloced()) { cr = c.relocation(); return; }
262
263 cr = to.alloc(c, c.learnt());
264 c.relocate(cr);
265
266 // Copy extra data-fields:
267 // (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?)
268 to[cr].mark(c.mark());
269 if (to[cr].learnt()) {
270 to[cr].activity() = c.activity();
271 to[cr].setLBD(c.lbd());
272 to[cr].setSizeWithoutSelectors(c.sizeWithoutSelectors());
273 to[cr].setCanBeDel(c.canBeDel());
274 }
275 else if (to[cr].has_extra()) to[cr].calcAbstraction();
276 }
277};
278
279
280//=================================================================================================
281// OccLists -- a class for maintaining occurence lists with lazy deletion:
282
283template<class Idx, class Vec, class Deleted>
285{
286 vec<Vec> occs;
287 vec<char> dirty;
288 vec<Idx> dirties;
289 Deleted deleted;
290
291 public:
292 OccLists(const Deleted& d) : deleted(d) {}
293
294 void init (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); }
295 // Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
296 Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
297 Vec& lookup (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; }
298
299 void cleanAll ();
300 void clean (const Idx& idx);
301 void smudge (const Idx& idx){
302 if (dirty[toInt(idx)] == 0){
303 dirty[toInt(idx)] = 1;
304 dirties.push(idx);
305 }
306 }
307
308 void clear(bool free = true){
309 if(free){
310 occs .clear(free);
311 dirty .clear(free);
312 dirties.clear(free);
313 } else {
314 occs .shrink_(occs .size());
315 dirty .shrink_(dirty .size());
316 dirties.shrink_(dirties.size());
317 }
318 }
319};
320
321
322template<class Idx, class Vec, class Deleted>
324{
325 for (int i = 0; i < dirties.size(); i++)
326 // Dirties may contain duplicates so check here if a variable is already cleaned:
327 if (dirty[toInt(dirties[i])])
328 clean(dirties[i]);
329 dirties.clear();
330}
331
332
333template<class Idx, class Vec, class Deleted>
335{
336 Vec& vec = occs[toInt(idx)];
337 int i, j;
338 for (i = j = 0; i < vec.size(); i++)
339 if (!deleted(vec[i]))
340 vec[j++] = vec[i];
341 vec.shrink(i - j);
342 dirty[toInt(idx)] = 0;
343}
344
345
346//=================================================================================================
347// CMap -- a class for mapping clauses to values:
348
349
350template<class T>
351class CMap
352{
353 struct CRefHash {
354 uint32_t operator()(CRef cr) const { return (uint32_t)cr; } };
355
356 typedef Map<CRef, T, CRefHash> HashTable;
357 HashTable map;
358
359 public:
360 // Size-operations:
361 void clear () { map.clear(); }
362 int size () const { return map.elems(); }
363
364
365 // Insert/Remove/Test mapping:
366 void insert (CRef cr, const T& t){ map.insert(cr, t); }
367 void growTo (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility
368 void remove (CRef cr) { map.remove(cr); }
369 bool has (CRef cr, T& t) { return map.peek(cr, t); }
370
371 // Vector interface (the clause 'c' must already exist):
372 const T& operator [] (CRef cr) const { return map[cr]; }
373 T& operator [] (CRef cr) { return map[cr]; }
374
375 // Iteration (not transparent at all at the moment):
376 int bucket_count() const { return map.bucket_count(); }
377 const vec<typename HashTable::Pair>& bucket(int i) const { return map.bucket(i); }
378
379 // Move contents to other map:
380 void moveTo(CMap& other){ map.moveTo(other.map); }
381
382 // TMP debug:
383 void debug(){
384 printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); }
385};
386
387
388/*_________________________________________________________________________________________________
389|
390| subsumes : (other : const Clause&) -> Lit
391|
392| Description:
393| Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other'
394| by subsumption resolution.
395|
396| Result:
397| lit_Error - No subsumption or simplification
398| lit_Undef - Clause subsumes 'other'
399| p - The literal p can be deleted from 'other'
400|________________________________________________________________________________________________@*/
401inline Lit Clause::subsumes(const Clause& other) const
402{
403 //if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0)
404 //if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0))
405 assert(!header.learnt); assert(!other.header.learnt);
406 assert(header.has_extra); assert(other.header.has_extra);
407 if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0)
408 return lit_Error;
409
410 Lit ret = lit_Undef;
411 const Lit* c = (const Lit*)(*this);
412 const Lit* d = (const Lit*)other;
413
414 for (unsigned i = 0; i < header.size; i++) {
415 // search for c[i] or ~c[i]
416 for (unsigned j = 0; j < other.header.size; j++)
417 if (c[i] == d[j])
418 goto ok;
419 else if (ret == lit_Undef && c[i] == ~d[j]){
420 ret = c[i];
421 goto ok;
422 }
423
424 // did not find it
425 return lit_Error;
426 ok:;
427 }
428
429 return ret;
430}
431
433{
434 remove(*this, p);
436}
437
438//=================================================================================================
439}
440
442
443#endif
unsigned int uint32_t
Definition Fxch.h:32
ABC_NAMESPACE_HEADER_START typedef unsigned char uint8_t
Definition Fxch.h:31
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
void growTo(CRef cr, const T &t)
void moveTo(CMap &other)
const T & operator[](CRef cr) const
bool has(CRef cr, T &t)
int bucket_count() const
const vec< typename HashTable::Pair > & bucket(int i) const
int size() const
void insert(CRef cr, const T &t)
void remove(CRef cr)
Clause & operator[](Ref r)
Clause * lea(Ref r)
void moveTo(ClauseAllocator &to)
const Clause & operator[](Ref r) const
Ref ael(const Clause *t)
void free_(CRef cid)
const Clause * lea(Ref r) const
CRef alloc(const Lits &ps, bool learnt=false)
void reloc(CRef &cr, ClauseAllocator &to)
ClauseAllocator(uint32_t start_cap)
void calcAbstraction()
CRef relocation() const
unsigned canbedel
bool reloced() const
uint32_t mark() const
unsigned int lbd() const
friend class ClauseAllocator
void setSizeWithoutSelectors(unsigned int n)
unsigned size
bool learnt() const
unsigned has_extra
unsigned int sizeWithoutSelectors() const
unsigned learnt
const Lit & last() const
float & activity()
bool has_extra() const
void setLBD(int i)
Lit subsumes(const Clause &other) const
void strengthen(Lit p)
unsigned szWithoutSelectors
void mark(uint32_t m)
Lit & operator[](int i)
void relocate(CRef c)
void shrink(int i)
unsigned reloced
uint32_t abstraction() const
void setCanBeDel(bool b)
unsigned mark
int size() const
OccLists(const Deleted &d)
Vec & lookup(const Idx &idx)
void clear(bool free=true)
void clean(const Idx &idx)
Vec & operator[](const Idx &idx)
void smudge(const Idx &idx)
void init(const Idx &idx)
Ref ael(const T *t)
Definition Alloc.h:71
void free_(int size)
Definition Alloc.h:62
RegionAllocator(uint32_t start_cap=1024 *1024)
Definition Alloc.h:50
T * lea(Ref r)
Definition Alloc.h:69
T & operator[](Ref r)
Definition Alloc.h:66
void moveTo(RegionAllocator &to)
Definition Alloc.h:74
Ref alloc(int size)
Definition Alloc.h:114
lbool(bool x)
bool operator==(lbool b) const
lbool(uint8_t v)
friend int toInt(lbool l)
bool operator!=(lbool b) const
lbool operator||(lbool b) const
friend lbool toLbool(int v)
lbool operator^(bool b) const
lbool operator&&(lbool b) const
int size(void) const
Definition Vec.h:65
void shrink(int nelems)
Definition Vec.h:66
Cube * p
Definition exorList.c:222
Definition Alg.h:28
int toInt(Var v)
Definition SolverTypes.h:74
const Lit lit_Error
Definition SolverTypes.h:82
RegionAllocator< uint32_t >::Ref CRef
const Lit lit_Undef
Definition SolverTypes.h:81
int var(Lit p)
Definition SolverTypes.h:71
lbool toLbool(int v)
Lit operator^(Lit p, bool b)
Definition SolverTypes.h:69
bool sign(Lit p)
Definition SolverTypes.h:70
int Var
Definition SolverTypes.h:52
Lit operator~(Lit p)
Definition SolverTypes.h:68
const CRef CRef_Undef
Lit toLit(int i)
Definition SolverTypes.h:76
Lit mkLit(Var var, bool sign=false)
Definition SolverTypes.h:67
#define false
Definition place_base.h:29
signed char lbool
Definition satVec.h:135
friend Lit mkLit(Var var, bool sign)
Definition SolverTypes.h:60
bool operator<(Lit p) const
Definition SolverTypes.h:63
bool operator==(Lit p) const
Definition SolverTypes.h:61
bool operator!=(Lit p) const
Definition SolverTypes.h:62
#define assert(ex)
Definition util_old.h:213
VOID_HACK free()