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/glucose2/Alg.h"
37#include "sat/glucose2/Vec.h"
38#include "sat/glucose2/Map.h"
39#include "sat/glucose2/Alloc.h"
40
42
44
45namespace Gluco2 {
46
47//=================================================================================================
48// Variables, literals, lifted booleans, clauses:
49
50
51// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
52// so that they can be used as array indices.
53
54typedef int Var;
55#define var_Undef (-1)
56
57
58struct Lit {
59 int x;
60
61 // Use this as a constructor:
62 friend Lit mkLit(Var var, bool sign);
63 bool operator == (Lit p) const { return x == p.x; }
64 bool operator != (Lit p) const { return x != p.x; }
65 bool operator < (Lit p) const { return x < p.x; } // '<' makes p, ~p adjacent in the ordering.
66};
67
68
69inline Lit mkLit (Var var, bool sign = false) { Lit p; p.x = var + var + (int)sign; return p; }
70inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; }
71inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; }
72inline bool sign (Lit p) { return p.x & 1; }
73inline int var (Lit p) { return p.x >> 1; }
74
75// Mapping Literals to and from compact integers suitable for array indexing:
76inline int toInt (Var v) { return v; }
77inline int toInt (Lit p) { return p.x; }
78inline Lit toLit (int i) { Lit p; p.x = i; return p; }
79
80//const Lit lit_Undef = mkLit(var_Undef, false); // }- Useful special constants.
81//const Lit lit_Error = mkLit(var_Undef, true ); // }
82
83const Lit lit_Undef = { -2 }; // }- Useful special constants.
84const Lit lit_Error = { -1 }; // }
85
86
87//=================================================================================================
88// Lifted booleans:
89//
90// NOTE: this implementation is optimized for the case when comparisons between values are mostly
91// between one variable and one constant. Some care had to be taken to make sure that gcc
92// does enough constant propagation to produce sensible code, and this appears to be somewhat
93// fragile unfortunately.
94
95#define l_True (Gluco2::lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants.
96#define l_False (Gluco2::lbool((uint8_t)1))
97#define l_Undef (Gluco2::lbool((uint8_t)2))
98
99class lbool {
100 uint8_t value;
101
102public:
103 explicit lbool(uint8_t v) : value(v) { }
104
105 lbool() : value(0) { }
106 explicit lbool(bool x) : value(!x) { }
107
108 bool operator == (lbool b) const { return (((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value))) != 0; }
109 bool operator != (lbool b) const { return !(*this == b); }
110 lbool operator ^ (bool b) const { return lbool((uint8_t)(value^(uint8_t)b)); }
111
113 uint8_t sel = (this->value << 1) | (b.value << 3);
114 uint8_t v = (0xF7F755F4 >> sel) & 3;
115 return lbool(v); }
116
118 uint8_t sel = (this->value << 1) | (b.value << 3);
119 uint8_t v = (0xFCFCF400 >> sel) & 3;
120 return lbool(v); }
121
122 friend int toInt (lbool l);
123 friend lbool toLbool(int v);
124};
125inline int toInt (lbool l) { return l.value; }
126inline lbool toLbool(int v) { return lbool((uint8_t)v); }
127
128//=================================================================================================
129// Clause -- a simple class for representing a clause:
130
131class Clause;
133
134class Clause {
135 struct {
136 unsigned mark : 2;
137 unsigned learnt : 1;
138 unsigned has_extra : 1;
139 unsigned reloced : 1;
140 unsigned lbd : 26;
141 unsigned canbedel : 1;
142 unsigned size : 32;
143 unsigned szWithoutSelectors : 32;
144
145 } header;
146 union { Lit lit; float act; uint32_t abs; CRef rel; } data[0];
147
148 friend class ClauseAllocator;
149
150 #ifdef CGLUCOSE_EXP
151 friend class Solver;
152 #endif
153
154 // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
155 template<class V>
156 Clause(const V& ps, bool use_extra, bool learnt) {
157 header.mark = 0;
158 header.learnt = learnt;
159 header.has_extra = use_extra;
160 header.reloced = 0;
161 header.size = ps.size();
162 header.lbd = 0;
163 header.canbedel = 1;
164 for (int i = 0; i < ps.size(); i++)
165 data[i].lit = ps[i];
166
167 if (header.has_extra){
168 if (header.learnt)
169 data[header.size].act = 0;
170 else
171 calcAbstraction(); }
172 }
173
174public:
176 assert(header.has_extra);
178 for (int i = 0; i < size(); i++)
179 abstraction |= 1 << (var(data[i].lit) & 31);
180 data[header.size].abs = abstraction; }
181
182
183 int size () const { return header.size; }
184 void shrink (int i) { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; }
185 void pop () { shrink(1); }
186 bool learnt () const { return header.learnt; }
187 bool has_extra () const { return header.has_extra; }
188 uint32_t mark () const { return header.mark; }
189 void mark (uint32_t m) { header.mark = m; }
190 const Lit& last () const { return data[header.size-1].lit; }
191
192 bool reloced () const { return header.reloced; }
193 CRef relocation () const { return data[0].rel; }
194 void relocate (CRef c) { header.reloced = 1; data[0].rel = c; }
195
196 // NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for
197 // subsumption operations to behave correctly.
198 Lit& operator [] (int i) { return data[i].lit; }
199 Lit operator [] (int i) const { return data[i].lit; }
200 operator const Lit* (void) const { return (Lit*)data; }
201
202 float& activity () { assert(header.has_extra); return data[header.size].act; }
203 uint32_t abstraction () const { assert(header.has_extra); return data[header.size].abs; }
204
205 Lit subsumes (const Clause& other) const;
206 void strengthen (Lit p);
207 void setLBD(int i) {header.lbd = i;}
208 // unsigned int& lbd () { return header.lbd; }
209 unsigned int lbd () const { return header.lbd; }
210 void setCanBeDel(bool b) {header.canbedel = b;}
211 bool canBeDel() {return header.canbedel;}
212 void setSizeWithoutSelectors (unsigned int n) {header.szWithoutSelectors = n; }
213 unsigned int sizeWithoutSelectors () const { return header.szWithoutSelectors; }
214
215};
216
217
218//=================================================================================================
219// ClauseAllocator -- a simple class for allocating memory for clauses:
220
221
223class ClauseAllocator : public RegionAllocator<uint32_t>
224{
225 static int clauseWord32Size(int size, bool has_extra){
226 return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); }
227 public:
229
232
236
237 template<class Lits>
238 CRef alloc(const Lits& ps, bool learnt = false)
239 {
240 assert(sizeof(Lit) == sizeof(uint32_t));
241 assert(sizeof(float) == sizeof(uint32_t));
242 bool use_extra = learnt | extra_clause_field;
243
244 CRef cid = RegionAllocator<uint32_t>::alloc(clauseWord32Size(ps.size(), use_extra));
245 new (lea(cid)) Clause(ps, use_extra, learnt);
246
247 return cid;
248 }
249
250 // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
254 const Clause* lea (Ref r) const { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
256
257 void free_(CRef cid)
258 {
259 Clause& c = operator[](cid);
260 RegionAllocator<uint32_t>::free_(clauseWord32Size(c.size(), c.has_extra()));
261 }
262
264 {
265 Clause& c = operator[](cr);
266
267 if (c.reloced()) { cr = c.relocation(); return; }
268
269 cr = to.alloc(c, c.learnt());
270 c.relocate(cr);
271
272 // Copy extra data-fields:
273 // (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?)
274 to[cr].mark(c.mark());
275 if (to[cr].learnt()) {
276 to[cr].activity() = c.activity();
277 to[cr].setLBD(c.lbd());
278 to[cr].setSizeWithoutSelectors(c.sizeWithoutSelectors());
279 to[cr].setCanBeDel(c.canBeDel());
280 }
281 else if (to[cr].has_extra()) to[cr].calcAbstraction();
282 }
283};
284
285
286//=================================================================================================
287// OccLists -- a class for maintaining occurence lists with lazy deletion:
288
289template<class Idx, class Vec, class Deleted>
291{
292 vec<Vec> occs;
293 vec<char> dirty;
294 vec<Idx> dirties;
295 Deleted deleted;
296
297 public:
298 OccLists(const Deleted& d) : deleted(d) {}
299
300 void init (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); }
301 void prelocate (const int num){ occs.prelocate(num); dirty.prelocate(num); }
302 // Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
303 Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
304 Vec& lookup (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; }
305
306 void cleanAll ();
307 void clean (const Idx& idx);
308 void smudge (const Idx& idx){
309 if (dirty[toInt(idx)] == 0){
310 dirty[toInt(idx)] = 1;
311 dirties.push(idx);
312 }
313 }
314
315 void clear(bool free = true){
316 if(free){
317 occs .clear(free);
318 dirty .clear(free);
319 dirties.clear(free);
320 } else {
321 occs .shrink (occs .size());
322 dirty .shrink_(dirty .size());
323 dirties.shrink_(dirties.size());
324 }
325 }
326};
327
328
329template<class Idx, class Vec, class Deleted>
331{
332 for (int i = 0; i < dirties.size(); i++)
333 // Dirties may contain duplicates so check here if a variable is already cleaned:
334 if (dirty[toInt(dirties[i])])
335 clean(dirties[i]);
336 dirties.shrink_( dirties.size() );
337}
338
339
340template<class Idx, class Vec, class Deleted>
342{
343 Vec& vec = occs[toInt(idx)];
344 int i, j;
345 for (i = j = 0; i < vec.size(); i++)
346 if (!deleted(vec[i]))
347 vec[j++] = vec[i];
348 vec.shrink_(i - j);
349 dirty[toInt(idx)] = 0;
350}
351
352
353//=================================================================================================
354// CMap -- a class for mapping clauses to values:
355
356
357template<class T>
358class CMap
359{
360 struct CRefHash {
361 uint32_t operator()(CRef cr) const { return (uint32_t)cr; } };
362
363 typedef Map<CRef, T, CRefHash> HashTable;
364 HashTable map;
365
366 public:
367 // Size-operations:
368 void clear () { map.clear(); }
369 int size () const { return map.elems(); }
370
371
372 // Insert/Remove/Test mapping:
373 void insert (CRef cr, const T& t){ map.insert(cr, t); }
374 void growTo (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility
375 void remove (CRef cr) { map.remove(cr); }
376 bool has (CRef cr, T& t) { return map.peek(cr, t); }
377
378 // Vector interface (the clause 'c' must already exist):
379 const T& operator [] (CRef cr) const { return map[cr]; }
380 T& operator [] (CRef cr) { return map[cr]; }
381
382 // Iteration (not transparent at all at the moment):
383 int bucket_count() const { return map.bucket_count(); }
384 const vec<typename HashTable::Pair>& bucket(int i) const { return map.bucket(i); }
385
386 // Move contents to other map:
387 void moveTo(CMap& other){ map.moveTo(other.map); }
388
389 // TMP debug:
390 void debug(){
391 printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); }
392};
393
394
395/*_________________________________________________________________________________________________
396|
397| subsumes : (other : const Clause&) -> Lit
398|
399| Description:
400| Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other'
401| by subsumption resolution.
402|
403| Result:
404| lit_Error - No subsumption or simplification
405| lit_Undef - Clause subsumes 'other'
406| p - The literal p can be deleted from 'other'
407|________________________________________________________________________________________________@*/
408inline Lit Clause::subsumes(const Clause& other) const
409{
410 //if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0)
411 //if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0))
412 assert(!header.learnt); assert(!other.header.learnt);
413 assert(header.has_extra); assert(other.header.has_extra);
414 if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0)
415 return lit_Error;
416
417 Lit ret = lit_Undef;
418 const Lit* c = (const Lit*)(*this);
419 const Lit* d = (const Lit*)other;
420
421 for (unsigned i = 0; i < header.size; i++) {
422 // search for c[i] or ~c[i]
423 for (unsigned j = 0; j < other.header.size; j++)
424 if (c[i] == d[j])
425 goto ok;
426 else if (ret == lit_Undef && c[i] == ~d[j]){
427 ret = c[i];
428 goto ok;
429 }
430
431 // did not find it
432 return lit_Error;
433 ok:;
434 }
435
436 return ret;
437}
438
440{
441 remove(*this, p);
443}
444
445//=================================================================================================
446}
447
449
450#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 moveTo(CMap &other)
void growTo(CRef cr, const T &t)
void remove(CRef cr)
int bucket_count() const
const T & operator[](CRef cr) const
const vec< typename HashTable::Pair > & bucket(int i) const
bool has(CRef cr, T &t)
int size() const
void insert(CRef cr, const T &t)
void moveTo(ClauseAllocator &to)
Clause & operator[](Ref r)
const Clause * lea(Ref r) const
CRef alloc(const Lits &ps, bool learnt=false)
ClauseAllocator(uint32_t start_cap)
Ref ael(const Clause *t)
const Clause & operator[](Ref r) const
Clause * lea(Ref r)
void reloc(CRef &cr, ClauseAllocator &to)
Lit & operator[](int i)
bool has_extra() const
uint32_t mark() const
void strengthen(Lit p)
unsigned int sizeWithoutSelectors() const
void setSizeWithoutSelectors(unsigned int n)
unsigned canbedel
unsigned has_extra
uint32_t abstraction() const
void shrink(int i)
friend class ClauseAllocator
bool learnt() const
unsigned learnt
unsigned int lbd() const
bool reloced() const
void relocate(CRef c)
Lit subsumes(const Clause &other) const
unsigned szWithoutSelectors
void setCanBeDel(bool b)
int size() const
const Lit & last() const
void mark(uint32_t m)
void setLBD(int i)
float & activity()
unsigned reloced
void calcAbstraction()
CRef relocation() const
OccLists(const Deleted &d)
void init(const Idx &idx)
Vec & lookup(const Idx &idx)
void clear(bool free=true)
void clean(const Idx &idx)
void smudge(const Idx &idx)
void prelocate(const int num)
Vec & operator[](const Idx &idx)
Ref ael(const T *t)
Definition Alloc.h:71
RegionAllocator(uint32_t start_cap=1024 *1024)
Definition Alloc.h:50
void moveTo(RegionAllocator &to)
Definition Alloc.h:74
T & operator[](Ref r)
Definition Alloc.h:66
Ref alloc(int size)
Definition Alloc.h:114
void free_(int size)
Definition Alloc.h:62
lbool operator||(lbool b) const
bool operator==(lbool b) const
friend int toInt(lbool l)
lbool operator&&(lbool b) const
friend lbool toLbool(int v)
lbool operator^(bool b) const
bool operator!=(lbool b) const
lbool(uint8_t v)
void shrink_(int nelems)
Definition Vec.h:67
int size(void) const
Definition Vec.h:65
Cube * p
Definition exorList.c:222
Definition Alg.h:28
Lit mkLit(Var var, bool sign=false)
Definition SolverTypes.h:69
bool sign(Lit p)
Definition SolverTypes.h:72
int var(Lit p)
Definition SolverTypes.h:73
lbool toLbool(int v)
const CRef CRef_Undef
Lit operator~(Lit p)
Definition SolverTypes.h:70
Lit operator^(Lit p, bool b)
Definition SolverTypes.h:71
int Var
Definition SolverTypes.h:54
const Lit lit_Undef
Definition SolverTypes.h:83
RegionAllocator< uint32_t >::Ref CRef
int toInt(Var v)
Definition SolverTypes.h:76
Lit toLit(int i)
Definition SolverTypes.h:78
const Lit lit_Error
Definition SolverTypes.h:84
#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:64
bool operator<(Lit p) const
Definition SolverTypes.h:65
bool operator==(Lit p) const
Definition SolverTypes.h:63
#define assert(ex)
Definition util_old.h:213
VOID_HACK free()