| [10] | 1 | // ********************************************************************* | 
|---|
 | 2 | // Copyright 2000-2004, Princeton University.  All rights reserved. | 
|---|
 | 3 | // By using this software the USER indicates that he or she has read, | 
|---|
 | 4 | // understood and will comply with the following: | 
|---|
 | 5 | // | 
|---|
 | 6 | // --- Princeton University hereby grants USER nonexclusive permission | 
|---|
 | 7 | // to use, copy and/or modify this software for internal, noncommercial, | 
|---|
 | 8 | // research purposes only. Any distribution, including commercial sale | 
|---|
 | 9 | // or license, of this software, copies of the software, its associated | 
|---|
 | 10 | // documentation and/or modifications of either is strictly prohibited | 
|---|
 | 11 | // without the prior consent of Princeton University.  Title to copyright | 
|---|
 | 12 | // to this software and its associated documentation shall at all times | 
|---|
 | 13 | // remain with Princeton University.  Appropriate copyright notice shall | 
|---|
 | 14 | // be placed on all software copies, and a complete copy of this notice | 
|---|
 | 15 | // shall be included in all copies of the associated documentation. | 
|---|
 | 16 | // No right is  granted to use in advertising, publicity or otherwise | 
|---|
 | 17 | // any trademark,  service mark, or the name of Princeton University. | 
|---|
 | 18 | // | 
|---|
 | 19 | // | 
|---|
 | 20 | // --- This software and any associated documentation is provided "as is" | 
|---|
 | 21 | // | 
|---|
 | 22 | // PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS | 
|---|
 | 23 | // OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A | 
|---|
 | 24 | // PARTICULAR PURPOSE, OR THAT  USE OF THE SOFTWARE, MODIFICATIONS, OR | 
|---|
 | 25 | // ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, | 
|---|
 | 26 | // TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. | 
|---|
 | 27 | // | 
|---|
 | 28 | // Princeton University shall not be liable under any circumstances for | 
|---|
 | 29 | // any direct, indirect, special, incidental, or consequential damages | 
|---|
 | 30 | // with respect to any claim by USER or any third party on account of | 
|---|
 | 31 | // or arising from the use, or inability to use, this software or its | 
|---|
 | 32 | // associated documentation, even if Princeton University has been advised | 
|---|
 | 33 | // of the possibility of those damages. | 
|---|
 | 34 | // ********************************************************************/ | 
|---|
 | 35 |  | 
|---|
 | 36 | #include <cstdlib> | 
|---|
 | 37 |  | 
|---|
 | 38 | #include <iostream> | 
|---|
 | 39 | #include <vector> | 
|---|
 | 40 | #include <set> | 
|---|
 | 41 |  | 
|---|
 | 42 | using namespace std; | 
|---|
 | 43 |  | 
|---|
 | 44 | #include "zchaff_dbase.h" | 
|---|
 | 45 |  | 
|---|
 | 46 | CDatabase::CDatabase(void) { | 
|---|
 | 47 |   _stats.mem_used_up                 = false; | 
|---|
 | 48 |   _stats.init_num_clauses            = 0; | 
|---|
 | 49 |   _stats.init_num_literals           = 0; | 
|---|
 | 50 |   _stats.num_added_clauses           = 0; | 
|---|
 | 51 |   _stats.num_added_literals          = 0; | 
|---|
 | 52 |   _stats.num_deleted_clauses         = 0; | 
|---|
 | 53 |   _stats.num_del_orig_cls            = 0; | 
|---|
 | 54 |   _stats.num_deleted_literals        = 0; | 
|---|
 | 55 |   _stats.num_enlarge                 = 0; | 
|---|
 | 56 |   _stats.num_compact                 = 0; | 
|---|
 | 57 |   _lit_pool_start = (CLitPoolElement *) malloc(sizeof(CLitPoolElement) * | 
|---|
 | 58 |                                                STARTUP_LIT_POOL_SIZE); | 
|---|
 | 59 |   _lit_pool_finish = _lit_pool_start; | 
|---|
 | 60 |   _lit_pool_end_storage = _lit_pool_start + STARTUP_LIT_POOL_SIZE; | 
|---|
 | 61 |   lit_pool_push_back(0);  // set the first element as a dummy element | 
|---|
 | 62 |   _params.mem_limit = 1024 * 1024 * 1024;  // that's 1 G | 
|---|
 | 63 |   variables()->resize(1);                  // var_id == 0 is never used. | 
|---|
 | 64 |   _allocated_gid                    = 0; | 
|---|
 | 65 | } | 
|---|
 | 66 |  | 
|---|
 | 67 | CDatabase::~CDatabase(void) { | 
|---|
 | 68 |   free(_lit_pool_start); | 
|---|
 | 69 | } | 
|---|
 | 70 |  | 
|---|
 | 71 | unsigned CDatabase::estimate_mem_usage(void) { | 
|---|
 | 72 |   unsigned mem_lit_pool = sizeof(CLitPoolElement) * (lit_pool_size() + | 
|---|
 | 73 |                                                      lit_pool_free_space()); | 
|---|
 | 74 |   unsigned mem_vars = sizeof(CVariable) * variables()->capacity(); | 
|---|
 | 75 |   unsigned mem_cls = sizeof(CClause) * clauses()->capacity(); | 
|---|
 | 76 |   unsigned mem_cls_queue = sizeof(int) * _unused_clause_idx.size(); | 
|---|
 | 77 |   unsigned mem_watched = 2 * num_clauses() * sizeof(CLitPoolElement *); | 
|---|
 | 78 |   unsigned mem_lit_clauses = 0; | 
|---|
 | 79 | #ifdef KEEP_LIT_CLAUSES | 
|---|
 | 80 |   mem_lit_clauses = num_literals() * sizeof(ClauseIdx); | 
|---|
 | 81 | #endif | 
|---|
 | 82 |   return (mem_lit_pool + mem_vars + mem_cls + | 
|---|
 | 83 |           mem_cls_queue + mem_watched + mem_lit_clauses); | 
|---|
 | 84 | } | 
|---|
 | 85 |  | 
|---|
 | 86 | unsigned CDatabase::mem_usage(void) { | 
|---|
 | 87 |   int mem_lit_pool = (lit_pool_size() + lit_pool_free_space()) * | 
|---|
 | 88 |                      sizeof(CLitPoolElement); | 
|---|
 | 89 |   int mem_vars = sizeof(CVariable) * variables()->capacity(); | 
|---|
 | 90 |   int mem_cls = sizeof(CClause) * clauses()->capacity(); | 
|---|
 | 91 |   int mem_cls_queue = sizeof(int) * _unused_clause_idx.size(); | 
|---|
 | 92 |   int mem_watched = 0, mem_lit_clauses = 0; | 
|---|
 | 93 |   for (unsigned i = 0, sz = variables()->size(); i < sz ;  ++i) { | 
|---|
 | 94 |     CVariable & v = variable(i); | 
|---|
 | 95 |     mem_watched        += v.watched(0).capacity() + v.watched(1).capacity(); | 
|---|
 | 96 | #ifdef KEEP_LIT_CLAUSES | 
|---|
 | 97 |     mem_lit_clauses += v.lit_clause(0).capacity() + v.lit_clause(1).capacity(); | 
|---|
 | 98 | #endif | 
|---|
 | 99 |   } | 
|---|
 | 100 |   mem_watched *= sizeof(CLitPoolElement*); | 
|---|
 | 101 |   mem_lit_clauses *= sizeof(ClauseIdx); | 
|---|
 | 102 |   return (mem_lit_pool + mem_vars + mem_cls + | 
|---|
 | 103 |           mem_cls_queue + mem_watched + mem_lit_clauses); | 
|---|
 | 104 | } | 
|---|
 | 105 |  | 
|---|
 | 106 | int CDatabase::alloc_gid(void) { | 
|---|
 | 107 |   for (unsigned i = 1; i <= WORD_WIDTH; ++i) { | 
|---|
 | 108 |     if (is_gid_allocated(i) == false) { | 
|---|
 | 109 |       _allocated_gid |= (1 << (i-1)); | 
|---|
 | 110 |       return i; | 
|---|
 | 111 |     } | 
|---|
 | 112 |   } | 
|---|
 | 113 |   warning(_POSITION_, "Not enough GID"); | 
|---|
 | 114 |   return VOLATILE_GID; | 
|---|
 | 115 | } | 
|---|
 | 116 |  | 
|---|
 | 117 | void CDatabase::free_gid(int gid) { | 
|---|
 | 118 |   assert(gid > 0 && "Can't free volatile or permanent group"); | 
|---|
 | 119 |   assert(gid <= WORD_WIDTH && "gid > WORD_WIDTH?"); | 
|---|
 | 120 |   if (!is_gid_allocated(gid)) { | 
|---|
 | 121 |     fatal(_POSITION_, "Can't free unallocated GID"); | 
|---|
 | 122 |   } | 
|---|
 | 123 |   _allocated_gid &= (~(1<< (gid-1))); | 
|---|
 | 124 | } | 
|---|
 | 125 |  | 
|---|
 | 126 | bool CDatabase::is_gid_allocated(int gid) { | 
|---|
 | 127 |   if (gid == VOLATILE_GID || gid == PERMANENT_GID) | 
|---|
 | 128 |     return true; | 
|---|
 | 129 |   assert(gid <= WORD_WIDTH && gid > 0); | 
|---|
 | 130 |   if (_allocated_gid & (1 << (gid -1))) | 
|---|
 | 131 |     return true; | 
|---|
 | 132 |   return false; | 
|---|
 | 133 | } | 
|---|
 | 134 |  | 
|---|
 | 135 | int CDatabase::merge_clause_group(int g2, int g1) { | 
|---|
 | 136 |   assert(g1 >0 && g2> 0 && "Can't merge with permanent or volatile group"); | 
|---|
 | 137 |   assert(g1 != g2); | 
|---|
 | 138 |   assert(is_gid_allocated(g1) && is_gid_allocated(g2)); | 
|---|
 | 139 |   for (unsigned i = 0, sz = clauses()->size(); i < sz; ++i) { | 
|---|
 | 140 |     if (clause(i).status() != DELETED_CL) { | 
|---|
 | 141 |       if (clause(i).gid(g1) == true) { | 
|---|
 | 142 |         clause(i).clear_gid(g1); | 
|---|
 | 143 |         clause(i).set_gid(g2); | 
|---|
 | 144 |       } | 
|---|
 | 145 |     } | 
|---|
 | 146 |   } | 
|---|
 | 147 |   free_gid(g1); | 
|---|
 | 148 |   return g2; | 
|---|
 | 149 | } | 
|---|
 | 150 |  | 
|---|
 | 151 | void CDatabase::mark_clause_deleted(CClause & cl) { | 
|---|
 | 152 |   ++_stats.num_deleted_clauses; | 
|---|
 | 153 |   _stats.num_deleted_literals += cl.num_lits(); | 
|---|
 | 154 |   CLAUSE_STATUS status = cl.status(); | 
|---|
 | 155 |   if (status == ORIGINAL_CL) | 
|---|
 | 156 |      _stats.num_del_orig_cls++; | 
|---|
 | 157 |   cl.set_status(DELETED_CL); | 
|---|
 | 158 |   for (unsigned i = 0; i < cl.num_lits(); ++i) { | 
|---|
 | 159 |     CLitPoolElement & l = cl.literal(i); | 
|---|
 | 160 |     --variable(l.var_index()).lits_count(l.var_sign()); | 
|---|
 | 161 |     l.val() = 0; | 
|---|
 | 162 |   } | 
|---|
 | 163 |   _unused_clause_idx.insert(&cl - &(*clauses()->begin())); | 
|---|
 | 164 | } | 
|---|
 | 165 |  | 
|---|
 | 166 | bool CDatabase::is_conflicting(ClauseIdx cl) { | 
|---|
 | 167 |   CLitPoolElement * lits = clause(cl).literals(); | 
|---|
 | 168 |   for (int i = 0, sz= clause(cl).num_lits(); i < sz;  ++i) { | 
|---|
 | 169 |     if (literal_value(lits[i]) != 0) | 
|---|
 | 170 |       return false; | 
|---|
 | 171 |   } | 
|---|
 | 172 |   return true; | 
|---|
 | 173 | } | 
|---|
 | 174 |  | 
|---|
 | 175 | bool CDatabase::is_satisfied(ClauseIdx cl) { | 
|---|
 | 176 |   CLitPoolElement * lits = clause(cl).literals(); | 
|---|
 | 177 |   for (int i = 0, sz = clause(cl).num_lits(); i < sz; ++i) { | 
|---|
 | 178 |     if (literal_value(lits[i]) == 1) | 
|---|
 | 179 |       return true; | 
|---|
 | 180 |   } | 
|---|
 | 181 |   return false; | 
|---|
 | 182 | } | 
|---|
 | 183 |  | 
|---|
 | 184 | bool CDatabase::is_unit(ClauseIdx cl) { | 
|---|
 | 185 |   int num_unassigned = 0; | 
|---|
 | 186 |   CLitPoolElement * lits = clause(cl).literals(); | 
|---|
 | 187 |   for (unsigned i = 0, sz= clause(cl).num_lits(); i < sz;  ++i) { | 
|---|
 | 188 |     int value = literal_value(lits[i]); | 
|---|
 | 189 |     if (value == 1) | 
|---|
 | 190 |       return false; | 
|---|
 | 191 |     else if (value != 0) | 
|---|
 | 192 |       ++num_unassigned; | 
|---|
 | 193 |   } | 
|---|
 | 194 |   return num_unassigned == 1; | 
|---|
 | 195 | } | 
|---|
 | 196 |  | 
|---|
 | 197 | int CDatabase::find_unit_literal(ClauseIdx cl) { | 
|---|
 | 198 |   // will return 0 if not unit | 
|---|
 | 199 |   int unit_lit = 0; | 
|---|
 | 200 |   for (int i = 0, sz = clause(cl).num_lits(); i < sz;  ++i) { | 
|---|
 | 201 |     int value = literal_value(clause(cl).literal(i)); | 
|---|
 | 202 |     if (value == 1) | 
|---|
 | 203 |       return 0; | 
|---|
 | 204 |     else if (value != 0) { | 
|---|
 | 205 |       if (unit_lit == 0) | 
|---|
 | 206 |         unit_lit = clause(cl).literals()[i].s_var(); | 
|---|
 | 207 |       else | 
|---|
 | 208 |         return 0; | 
|---|
 | 209 |     } | 
|---|
 | 210 |   } | 
|---|
 | 211 |   return unit_lit; | 
|---|
 | 212 | } | 
|---|
 | 213 |  | 
|---|
 | 214 | inline CLitPoolElement * CDatabase::lit_pool_begin(void) { | 
|---|
 | 215 |   return _lit_pool_start; | 
|---|
 | 216 | } | 
|---|
 | 217 |  | 
|---|
 | 218 | inline CLitPoolElement * CDatabase::lit_pool_end(void) { | 
|---|
 | 219 |   return _lit_pool_finish; | 
|---|
 | 220 | } | 
|---|
 | 221 |  | 
|---|
 | 222 | inline void CDatabase::lit_pool_incr_size(int size) { | 
|---|
 | 223 |   _lit_pool_finish += size; | 
|---|
 | 224 |   assert(_lit_pool_finish <= _lit_pool_end_storage); | 
|---|
 | 225 | } | 
|---|
 | 226 |  | 
|---|
 | 227 | inline void CDatabase::lit_pool_push_back(int value) { | 
|---|
 | 228 |   assert(_lit_pool_finish <= _lit_pool_end_storage); | 
|---|
 | 229 |   _lit_pool_finish->val() = value; | 
|---|
 | 230 |   ++_lit_pool_finish; | 
|---|
 | 231 | } | 
|---|
 | 232 |  | 
|---|
 | 233 | inline int CDatabase::lit_pool_size(void) { | 
|---|
 | 234 |   return _lit_pool_finish - _lit_pool_start; | 
|---|
 | 235 | } | 
|---|
 | 236 |  | 
|---|
 | 237 | inline int CDatabase::lit_pool_free_space(void) { | 
|---|
 | 238 |   return _lit_pool_end_storage - _lit_pool_finish; | 
|---|
 | 239 | } | 
|---|
 | 240 |  | 
|---|
 | 241 | inline double CDatabase::lit_pool_utilization(void) { | 
|---|
 | 242 |     // minus num_clauses() is because of spacing (i.e. clause indices) | 
|---|
 | 243 |   return (double)num_literals() / ((double) (lit_pool_size() - num_clauses())) ; | 
|---|
 | 244 | } | 
|---|
 | 245 |  | 
|---|
 | 246 | inline CLitPoolElement & CDatabase::lit_pool(int i) { | 
|---|
 | 247 |   return _lit_pool_start[i]; | 
|---|
 | 248 | } | 
|---|
 | 249 |  | 
|---|
 | 250 | void CDatabase::compact_lit_pool(void) { | 
|---|
 | 251 |   unsigned i, sz; | 
|---|
 | 252 |   int new_index = 1; | 
|---|
 | 253 |   // first do the compaction for the lit pool | 
|---|
 | 254 |   for (i = 1, sz = lit_pool_size(); i < sz;  ++i) { | 
|---|
 | 255 |     // begin with 1 because 0 position is always 0 | 
|---|
 | 256 |     if (!lit_pool(i).is_literal() && !lit_pool(i-1).is_literal()) { | 
|---|
 | 257 |       continue; | 
|---|
 | 258 |     } else { | 
|---|
 | 259 |       lit_pool(new_index) = lit_pool(i); | 
|---|
 | 260 |       ++new_index; | 
|---|
 | 261 |     } | 
|---|
 | 262 |   } | 
|---|
 | 263 |   _lit_pool_finish = lit_pool_begin() + new_index; | 
|---|
 | 264 |   // update all the pointers to the literals; | 
|---|
 | 265 |   // 1. clean up the watched pointers from variables | 
|---|
 | 266 |   for (i = 1, sz = variables()->size(); i < sz;  ++i) { | 
|---|
 | 267 |     variable(i).watched(0).clear(); | 
|---|
 | 268 |     variable(i).watched(1).clear(); | 
|---|
 | 269 |   } | 
|---|
 | 270 |   for (i = 1, sz = lit_pool_size(); i < sz;  ++i) { | 
|---|
 | 271 |     CLitPoolElement & lit = lit_pool(i); | 
|---|
 | 272 |     // 2. reinsert the watched pointers | 
|---|
 | 273 |     if (lit.is_literal()) { | 
|---|
 | 274 |       if (lit.is_watched()) { | 
|---|
 | 275 |          int var_idx = lit.var_index(); | 
|---|
 | 276 |          int sign = lit.var_sign(); | 
|---|
 | 277 |          variable(var_idx).watched(sign).push_back(& lit_pool(i)); | 
|---|
 | 278 |        } | 
|---|
 | 279 |     } else {  // lit is not literal | 
|---|
 | 280 |     // 3. update the clauses' first literal pointer | 
|---|
 | 281 |       int cls_idx = lit.get_clause_index(); | 
|---|
 | 282 |       clause(cls_idx).first_lit() = &lit_pool(i) - clause(cls_idx).num_lits(); | 
|---|
 | 283 |     } | 
|---|
 | 284 |   } | 
|---|
 | 285 |   ++_stats.num_compact; | 
|---|
 | 286 | } | 
|---|
 | 287 |  | 
|---|
 | 288 | bool CDatabase::enlarge_lit_pool(void) { | 
|---|
 | 289 |   // will return true if successful, otherwise false. | 
|---|
 | 290 |   unsigned i, sz; | 
|---|
 | 291 |   // if memory efficiency < 2/3, we do a compaction | 
|---|
 | 292 |   if (lit_pool_utilization() < 0.67) { | 
|---|
 | 293 |     compact_lit_pool(); | 
|---|
 | 294 |     return true; | 
|---|
 | 295 |   } | 
|---|
 | 296 |   // otherwise we have to enlarge it. | 
|---|
 | 297 |   // first, check if memory is running out | 
|---|
 | 298 |   int current_mem = estimate_mem_usage(); | 
|---|
 | 299 |   float grow_ratio = 1; | 
|---|
 | 300 |   if (current_mem < _params.mem_limit / 4) | 
|---|
 | 301 |     grow_ratio = 2; | 
|---|
 | 302 |   else if (current_mem < _params.mem_limit /2 ) | 
|---|
 | 303 |     grow_ratio = 1.5; | 
|---|
 | 304 |   else if (current_mem < _params.mem_limit * 0.8) | 
|---|
 | 305 |     grow_ratio = 1.2; | 
|---|
 | 306 |   if (grow_ratio < 1.2) { | 
|---|
 | 307 |     if (lit_pool_utilization() < 0.9) {  // still has some garbage | 
|---|
 | 308 |       compact_lit_pool(); | 
|---|
 | 309 |       return true; | 
|---|
 | 310 |     } | 
|---|
 | 311 |     else | 
|---|
 | 312 |       return false; | 
|---|
 | 313 |   } | 
|---|
 | 314 |   // second, make room for new lit pool. | 
|---|
 | 315 |   CLitPoolElement * old_start = _lit_pool_start; | 
|---|
 | 316 |   CLitPoolElement * old_finish = _lit_pool_finish; | 
|---|
 | 317 |   int old_size = _lit_pool_end_storage - _lit_pool_start; | 
|---|
 | 318 |   int new_size = (int)(old_size * grow_ratio); | 
|---|
 | 319 |   _lit_pool_start = (CLitPoolElement *) realloc(_lit_pool_start, | 
|---|
 | 320 |                                                 sizeof(CLitPoolElement) * | 
|---|
 | 321 |                                                 new_size); | 
|---|
 | 322 |   _lit_pool_finish = _lit_pool_start + (old_finish - old_start); | 
|---|
 | 323 |   _lit_pool_end_storage = _lit_pool_start + new_size; | 
|---|
 | 324 |  | 
|---|
 | 325 |   // update all the pointers | 
|---|
 | 326 |   int displacement = _lit_pool_start - old_start; | 
|---|
 | 327 |   for (i = 0; i < clauses()->size(); ++i) { | 
|---|
 | 328 |     if (clause(i).status() != DELETED_CL) | 
|---|
 | 329 |       clause(i).first_lit() += displacement; | 
|---|
 | 330 |   } | 
|---|
 | 331 |   for (i = 0, sz = variables()->size(); i < sz ;  ++i) { | 
|---|
 | 332 |     CVariable & v = variable(i); | 
|---|
 | 333 |     for (int j = 0; j < 2 ; ++j) { | 
|---|
 | 334 |       int k, sz1; | 
|---|
 | 335 |       vector<CLitPoolElement *> & watched = v.watched(j); | 
|---|
 | 336 |       for (k = 0, sz1 = watched.size(); k < sz1 ; ++k) { | 
|---|
 | 337 |         watched[k] += displacement; | 
|---|
 | 338 |       } | 
|---|
 | 339 |     } | 
|---|
 | 340 |   } | 
|---|
 | 341 |   ++_stats.num_enlarge; | 
|---|
 | 342 |   return true; | 
|---|
 | 343 | } | 
|---|
 | 344 |  | 
|---|
 | 345 | ClauseIdx CDatabase::get_free_clause_idx(void) { | 
|---|
 | 346 |   ClauseIdx new_cl; | 
|---|
 | 347 |   new_cl = _clauses.size(); | 
|---|
 | 348 |   _clauses.resize(new_cl + 1); | 
|---|
 | 349 |   clause(new_cl).set_id(_stats.num_added_clauses); | 
|---|
 | 350 |   return new_cl; | 
|---|
 | 351 | } | 
|---|
 | 352 |  | 
|---|
 | 353 | ClauseIdx CDatabase::add_clause(int * lits, int n_lits, int gflag) { | 
|---|
 | 354 |   int new_cl; | 
|---|
 | 355 |   // a. do we need to enlarge lits pool? | 
|---|
 | 356 |   while (lit_pool_free_space() <= n_lits + 1) { | 
|---|
 | 357 |     if (enlarge_lit_pool() == false) | 
|---|
 | 358 |       return -1;  // mem out, can't enlarge lit pool, because | 
|---|
 | 359 |       // ClauseIdx can't be -1, so it shows error. | 
|---|
 | 360 |   } | 
|---|
 | 361 |   // b. get a free cl index; | 
|---|
 | 362 |   new_cl = get_free_clause_idx(); | 
|---|
 | 363 |   // c. add the clause lits to lits pool | 
|---|
 | 364 |   CClause & cl = clause(new_cl); | 
|---|
 | 365 |   cl.init(lit_pool_end(), n_lits, gflag); | 
|---|
 | 366 |   lit_pool_incr_size(n_lits + 1); | 
|---|
 | 367 |   if (n_lits == 2) { | 
|---|
 | 368 |     ++variable(lits[0]>>1).two_lits_count(lits[0] & 0x1); | 
|---|
 | 369 |     ++variable(lits[1]>>1).two_lits_count(lits[1] & 0x1); | 
|---|
 | 370 |   } | 
|---|
 | 371 |   for (int i = 0; i < n_lits; ++i) { | 
|---|
 | 372 |     int var_idx = lits[i] >> 1; | 
|---|
 | 373 |     assert((unsigned)var_idx < variables()->size()); | 
|---|
 | 374 |     int var_sign = lits[i] & 0x1; | 
|---|
 | 375 |     cl.literal(i).set(var_idx, var_sign); | 
|---|
 | 376 |     ++variable(var_idx).lits_count(var_sign); | 
|---|
 | 377 | #ifdef KEEP_LIT_CLAUSES | 
|---|
 | 378 |     variable(var_idx).lit_clause(var_sign).push_back(new_cl); | 
|---|
 | 379 | #endif | 
|---|
 | 380 |   } | 
|---|
 | 381 |   // the element after the last one is the spacing element | 
|---|
 | 382 |   cl.literal(n_lits).set_clause_index(new_cl); | 
|---|
 | 383 |   // d. set the watched pointers | 
|---|
 | 384 |   if (cl.num_lits() > 1) { | 
|---|
 | 385 |     // add the watched literal. note: watched literal must be the last free var | 
|---|
 | 386 |     int max_idx = -1, max_dl = -1; | 
|---|
 | 387 |     int i, sz = cl.num_lits(); | 
|---|
 | 388 |     // set the first watched literal | 
|---|
 | 389 |     for (i = 0; i < sz; ++i) { | 
|---|
 | 390 |       int v_idx = cl.literal(i).var_index(); | 
|---|
 | 391 |       int v_sign = cl.literal(i).var_sign(); | 
|---|
 | 392 |       CVariable & v = variable(v_idx); | 
|---|
 | 393 |       if (literal_value(cl.literal(i)) != 0) { | 
|---|
 | 394 |         v.watched(v_sign).push_back(&cl.literal(i)); | 
|---|
 | 395 |         cl.literal(i).set_watch(1); | 
|---|
 | 396 |         break; | 
|---|
 | 397 |       } else { | 
|---|
 | 398 |         if (v.dlevel() > max_dl) { | 
|---|
 | 399 |           max_dl = v.dlevel(); | 
|---|
 | 400 |           max_idx = i; | 
|---|
 | 401 |         } | 
|---|
 | 402 |       } | 
|---|
 | 403 |     } | 
|---|
 | 404 |     if (i >= sz) {  // no unassigned literal. so watch literal with max dlevel | 
|---|
 | 405 |       int v_idx = cl.literal(max_idx).var_index(); | 
|---|
 | 406 |       int v_sign = cl.literal(max_idx).var_sign(); | 
|---|
 | 407 |       variable(v_idx).watched(v_sign).push_back(&cl.literal(max_idx)); | 
|---|
 | 408 |       cl.literal(max_idx).set_watch(1); | 
|---|
 | 409 |     } | 
|---|
 | 410 |  | 
|---|
 | 411 |     // set the second watched literal | 
|---|
 | 412 |     max_idx = -1; | 
|---|
 | 413 |     max_dl = -1; | 
|---|
 | 414 |     for (i = sz-1; i >= 0; --i) { | 
|---|
 | 415 |       if (cl.literal(i).is_watched()) | 
|---|
 | 416 |         continue;  // need to watch two different literals | 
|---|
 | 417 |       int v_idx = cl.literal(i).var_index(); | 
|---|
 | 418 |       int v_sign = cl.literal(i).var_sign(); | 
|---|
 | 419 |       CVariable & v = variable(v_idx); | 
|---|
 | 420 |       if (literal_value(cl.literal(i)) != 0) { | 
|---|
 | 421 |         v.watched(v_sign).push_back(&cl.literal(i)); | 
|---|
 | 422 |         cl.literal(i).set_watch(-1); | 
|---|
 | 423 |         break; | 
|---|
 | 424 |       } else { | 
|---|
 | 425 |         if (v.dlevel() > max_dl) { | 
|---|
 | 426 |           max_dl = v.dlevel(); | 
|---|
 | 427 |           max_idx = i; | 
|---|
 | 428 |         } | 
|---|
 | 429 |       } | 
|---|
 | 430 |     } | 
|---|
 | 431 |     if (i < 0) { | 
|---|
 | 432 |       int v_idx = cl.literal(max_idx).var_index(); | 
|---|
 | 433 |       int v_sign = cl.literal(max_idx).var_sign(); | 
|---|
 | 434 |       variable(v_idx).watched(v_sign).push_back(&cl.literal(max_idx)); | 
|---|
 | 435 |       cl.literal(max_idx).set_watch(-1); | 
|---|
 | 436 |     } | 
|---|
 | 437 |   } | 
|---|
 | 438 |   // update some statistics | 
|---|
 | 439 |   ++_stats.num_added_clauses; | 
|---|
 | 440 |   _stats.num_added_literals += n_lits; | 
|---|
 | 441 |   return new_cl; | 
|---|
 | 442 | } | 
|---|
 | 443 |  | 
|---|
 | 444 | void CDatabase::output_lit_pool_stats(void) { | 
|---|
 | 445 |   cout << "Lit_Pool Used " << lit_pool_size() << " Free " | 
|---|
 | 446 |        << lit_pool_free_space() | 
|---|
 | 447 |        << " Total " << lit_pool_size() + lit_pool_free_space() | 
|---|
 | 448 |        << " Num. Cl " << num_clauses() << " Num. Lit " << num_literals() | 
|---|
 | 449 |        << " Efficiency " <<  lit_pool_utilization() << endl; | 
|---|
 | 450 | } | 
|---|
 | 451 |  | 
|---|
 | 452 | void CDatabase::detail_dump_cl(ClauseIdx cl_idx, ostream & os) { | 
|---|
 | 453 |   os << "CL : " << cl_idx; | 
|---|
 | 454 |   CClause & cl = clause(cl_idx); | 
|---|
 | 455 |   if (cl.status() == DELETED_CL) | 
|---|
 | 456 |     os << "\t\t\t======removed====="; | 
|---|
 | 457 |   char value; | 
|---|
 | 458 |   for (unsigned i = 0; i < cl.num_lits(); ++i) { | 
|---|
 | 459 |     if (literal_value(cl.literal(i)) == 0) | 
|---|
 | 460 |       value = '0'; | 
|---|
 | 461 |     else if (literal_value(cl.literal(i)) == 1) | 
|---|
 | 462 |       value = '1'; | 
|---|
 | 463 |     else | 
|---|
 | 464 |       value = 'X'; | 
|---|
 | 465 |     os << cl.literal(i) << "(" << value << "@" | 
|---|
 | 466 |        << variable(cl.literal(i).var_index()).dlevel()<< ")  "; | 
|---|
 | 467 |   } | 
|---|
 | 468 |   os << endl; | 
|---|
 | 469 | } | 
|---|
 | 470 |  | 
|---|
 | 471 | void CDatabase::dump(ostream & os) { | 
|---|
 | 472 |   unsigned i; | 
|---|
 | 473 |   os << "Dump Database: " << endl; | 
|---|
 | 474 |   for (i = 0; i < _clauses.size(); ++i) | 
|---|
 | 475 |     detail_dump_cl(i); | 
|---|
 | 476 |   for (i = 1; i < _variables.size(); ++i) | 
|---|
 | 477 |     os << "VID " << i << ":\t" << variable(i); | 
|---|
 | 478 | } | 
|---|