Adding support for reading wrong assumptions
[satlib.git] / zchaff64 / zchaff_solver.cpp
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 <iostream>
37 #include <algorithm>
38 #include <fstream>
39 #include <vector>
40 #include <map>
41 #include <set>
42 #include <queue>
43
44 using namespace std;
45
46 #include "zchaff_solver.h"
47
48 // #define VERIFY_ON
49
50 #ifdef VERIFY_ON
51 ofstream verify_out("resolve_trace");
52 #endif
53
54 void CSolver::re_init_stats(void) {
55   _stats.is_mem_out           = false;
56   _stats.outcome              = UNDETERMINED;
57   _stats.next_restart         = _params.restart.first_restart;
58   _stats.restart_incr         = _params.restart.backtrack_incr;
59   _stats.next_cls_deletion    = _params.cls_deletion.interval;
60   _stats.next_var_score_decay = _params.decision.decay_period;
61   _stats.current_randomness   = _params.decision.base_randomness;
62
63   _stats.total_bubble_move            = 0;
64   _stats.num_decisions                = 0;
65   _stats.num_decisions_stack_conf     = 0;
66   _stats.num_decisions_vsids          = 0;
67   _stats.num_decisions_shrinking      = 0;
68   _stats.num_backtracks               = 0;
69   _stats.max_dlevel                   = 0;
70   _stats.num_implications             = 0;
71   _stats.num_restarts                 = 0;
72   _stats.num_del_orig_cls             = 0;
73   _stats.num_shrinkings               = 0;
74   _stats.start_cpu_time               = get_cpu_time();
75   _stats.finish_cpu_time              = 0;
76   _stats.random_seed                  = 0;
77 }
78
79 void CSolver::init_stats(void) {
80   re_init_stats();
81
82   _stats.been_reset                   = true;
83   _stats.num_free_variables           = 0;
84   _stats.num_free_branch_vars         = 0;
85 }
86
87 void CSolver::init_parameters(void) {
88   _params.verbosity                           = 0;
89   _params.time_limit                          = 3600 * 24;  // a day
90   _params.shrinking.size                      = 95;
91   _params.shrinking.enable                    = true;
92   _params.shrinking.upper_bound               = 800;
93   _params.shrinking.lower_bound               = 600;
94   _params.shrinking.upper_delta               = -5;
95   _params.shrinking.lower_delta               = 10;
96   _params.shrinking.window_width              = 20;
97   _params.shrinking.bound_update_frequency    = 20;
98
99   _params.decision.base_randomness            = 0;
100   _params.decision.decay_period               = 40;
101   _params.decision.bubble_init_step           = 0x400;
102
103   _params.cls_deletion.enable                 = true ;
104   _params.cls_deletion.head_activity          = 500;
105   _params.cls_deletion.tail_activity          = 10;
106   _params.cls_deletion.head_num_lits          = 6;
107   _params.cls_deletion.tail_num_lits          = 45;
108   _params.cls_deletion.tail_vs_head           = 16;
109   _params.cls_deletion.interval               = 600;
110
111   _params.restart.enable                      = true;
112   _params.restart.interval                    = 700;
113   _params.restart.first_restart               = 7000;
114   _params.restart.backtrack_incr              = 700;
115 }
116
117 CSolver::CSolver(void) {
118   init_parameters();
119   init_stats();
120   _dlevel                       = 0;
121   _force_terminate              = false;
122   _implication_id               = 0;
123   _num_marked                   = 0;
124   _num_in_new_cl                = 0;
125   _outside_constraint_hook      = NULL;
126   _sat_hook                     = NULL;
127 }
128
129 CSolver::~CSolver(void) {
130   while (!_assignment_stack.empty()) {
131     delete _assignment_stack.back();
132     _assignment_stack.pop_back();
133   }
134 }
135
136 void CSolver::set_time_limit(float t) {
137   _params.time_limit = t;
138 }
139
140 float CSolver::elapsed_cpu_time(void) {
141   return get_cpu_time() - _stats.start_cpu_time;
142 }
143
144 float CSolver::cpu_run_time(void) {
145   return (_stats.finish_cpu_time - _stats.start_cpu_time);
146 }
147
148 void CSolver::set_variable_number(int n) {
149   assert(num_variables() == 0);
150   CDatabase::set_variable_number(n);
151   _stats.num_free_variables = num_variables();
152   while (_assignment_stack.size() <= num_variables())
153     _assignment_stack.push_back(new vector<int>);
154   assert(_assignment_stack.size() == num_variables() + 1);
155 }
156
157 int CSolver::add_variable(void) {
158   int num = CDatabase::add_variable();
159   ++_stats.num_free_variables;
160   while (_assignment_stack.size() <= num_variables())
161     _assignment_stack.push_back(new vector<int>);
162   assert(_assignment_stack.size() == num_variables() + 1);
163   return num;
164 }
165
166 void CSolver::set_mem_limit(int s) {
167   CDatabase::set_mem_limit(s);
168 }
169
170 void CSolver::set_randomness(int n) {
171   _params.decision.base_randomness = n;
172 }
173
174 void CSolver::set_random_seed(int seed) {
175   srand(seed);
176 }
177
178 void CSolver::enable_cls_deletion(bool allow) {
179   _params.cls_deletion.enable = allow;
180 }
181
182 void CSolver::add_hook(HookFunPtrT fun, int interval) {
183   pair<HookFunPtrT, int> a(fun, interval);
184   _hooks.push_back(pair<int, pair<HookFunPtrT, int> > (0, a));
185 }
186
187 void CSolver::run_periodic_functions(void) {
188   // a. restart
189   if (_params.restart.enable && _stats.num_backtracks > _stats.next_restart &&
190       _shrinking_cls.empty()) {
191     _stats.next_restart = _stats.num_backtracks + _stats.restart_incr;
192     delete_unrelevant_clauses();
193     restart();
194     if (_stats.num_restarts % 5 == 1)
195       compact_lit_pool();
196     cout << "\rDecision: " << _assignment_stack[0]->size() << "/"
197          <<num_variables() << "\tTime: " << get_cpu_time() -
198            _stats.start_cpu_time << "/" << _params.time_limit << flush;
199   }
200
201   // b. decay variable score
202   if (_stats.num_backtracks > _stats.next_var_score_decay) {
203     _stats.next_var_score_decay = _stats.num_backtracks +
204                                   _params.decision.decay_period;
205     decay_variable_score();
206   }
207
208   // c. run hook functions
209   for (unsigned i = 0; i< _hooks.size(); ++i) {
210     pair<int, pair<HookFunPtrT, int> > & hook = _hooks[i];
211     if (_stats.num_decisions >= hook.first) {
212       hook.first += hook.second.second;
213       hook.second.first((void *) this);
214     }
215   }
216 }
217
218 void CSolver::init_solve(void) {
219   CDatabase::init_stats();
220   re_init_stats();
221   _stats.been_reset = false;
222
223   assert(_conflicts.empty());
224   assert(_conflict_lits.empty());
225   assert(_num_marked == 0);
226   assert(_num_in_new_cl == 0);
227   assert(_dlevel == 0);
228
229   for (unsigned i = 0, sz = variables()->size(); i < sz; ++i) {
230     variable(i).score(0) = variable(i).lits_count(0);
231     variable(i).score(1) = variable(i).lits_count(1);
232   }
233
234   _ordered_vars.resize(num_variables());
235   update_var_score();
236
237   set_random_seed(_stats.random_seed);
238
239   top_unsat_cls = clauses()->size() - 1;
240
241   _stats.shrinking_benefit = 0;
242   _shrinking_cls.clear();
243   _stats.shrinking_cls_length = 0;
244 }
245
246 void CSolver::set_var_value(int v, int value, ClauseIdx ante, int dl) {
247     assert(value == 0 || value == 1);
248     CVariable & var = variable(v);
249     assert(var.value() == UNKNOWN);
250     assert(dl == dlevel());
251
252     var.set_dlevel(dl);
253     var.set_value(value);
254     var.antecedent() = ante;
255     var.assgn_stack_pos() = _assignment_stack[dl]->size();
256     _assignment_stack[dl]->push_back(v * 2 + !value);
257     set_var_value_BCP(v, value);
258
259     ++_stats.num_implications ;
260     if (var.is_branchable())
261         --num_free_variables();
262 }
263
264 void CSolver::set_var_value_BCP(int v, int value) {
265   vector<CLitPoolElement *> & watchs = variable(v).watched(value);
266   for (vector <CLitPoolElement *>::iterator itr = watchs.begin();
267        itr != watchs.end(); ++itr) {
268     ClauseIdx cl_idx;
269     CLitPoolElement * other_watched = *itr;
270     CLitPoolElement * watched = *itr;
271     int dir = watched->direction();
272     CLitPoolElement * ptr = watched;
273     while (true) {
274       ptr += dir;
275       if (ptr->val() <= 0) {  // reached one end of the clause
276         if (dir == 1)  // reached the right end, i.e. spacing element is cl_id
277           cl_idx = ptr->get_clause_index();
278         if (dir == watched->direction()) {  // we haven't go both directions.
279           ptr = watched;
280           dir = -dir;                     // change direction, go the other way
281           continue;
282         }
283         // otherwise, we have already go through the whole clause
284         int the_value = literal_value(*other_watched);
285         if (the_value == 0)  // a conflict
286           _conflicts.push_back(cl_idx);
287         else if (the_value != 1)  // i.e. unknown
288           queue_implication(other_watched->s_var(), cl_idx);
289         break;
290       }
291       if (ptr->is_watched()) {  // literal is the other watched lit, skip it.
292         other_watched = ptr;
293         continue;
294       }
295       if (literal_value(*ptr) == 0)  // literal value is 0, keep going
296         continue;
297       // now the literal's value is either 1 or unknown, watch it instead
298       int v1 = ptr->var_index();
299       int sign = ptr->var_sign();
300       variable(v1).watched(sign).push_back(ptr);
301       ptr->set_watch(dir);
302       // remove the original watched literal from watched list
303       watched->unwatch();
304       *itr = watchs.back();  // copy the last element in it's place
305       watchs.pop_back();     // remove the last element
306       --itr;                 // do this so with don't skip one during traversal
307       break;
308     }
309   }
310 }
311
312 void CSolver::unset_var_value(int v) {
313   if (v == 0)
314     return;
315   CVariable & var = variable(v);
316   var.set_value(UNKNOWN);
317   var.set_antecedent(NULL_CLAUSE);
318   var.set_dlevel(-1);
319   var.assgn_stack_pos() = -1;
320
321   if (var.is_branchable()) {
322     ++num_free_variables();
323     if (var.var_score_pos() < _max_score_pos)
324       _max_score_pos = var.var_score_pos();
325   }
326 }
327
328 void CSolver::dump_assignment_stack(ostream & os ) {
329   os << "Assignment Stack:  ";
330   for (int i = 0; i <= dlevel(); ++i) {
331     os << "(" <<i << ":";
332     for (unsigned j = 0; j < (*_assignment_stack[i]).size(); ++j) {
333       os << ((*_assignment_stack[i])[j]&0x1?"-":"+")
334          << ((*_assignment_stack[i])[j] >> 1) << " ";
335     }
336     os << ") " << endl;
337   }
338   os << endl;
339 }
340
341 void CSolver::dump_implication_queue(ostream & os) {
342   _implication_queue.dump(os);
343 }
344
345 void CSolver::delete_clause_group(int gid) {
346   assert(is_gid_allocated(gid));
347
348   if (_stats.been_reset == false)
349     reset();  // if delete some clause, then implication queue are invalidated
350
351   for (vector<CClause>::iterator itr = clauses()->begin();
352        itr != clauses()->end(); ++itr) {
353     CClause & cl = *itr;
354     if (cl.status() != DELETED_CL) {
355       if (cl.gid(gid) == true) {
356         mark_clause_deleted(cl);
357       }
358     }
359   }
360
361   // delete the index from variables
362   for (vector<CVariable>::iterator itr = variables()->begin();
363          itr != variables()->end(); ++itr) {
364     for (unsigned i = 0; i < 2; ++i) {  // for each phase
365       // delete the lit index from the vars
366 #ifdef KEEP_LIT_CLAUSES
367       vector<ClauseIdx> & lit_clauses = (*itr).lit_clause(i);
368       for (vector<ClauseIdx>::iterator itr1 = lit_clauses.begin();
369            itr1 != lit_clauses.end(); ++itr1) {
370         if (clause(*itr1).status() == DELETED_CL) {
371           *itr1 = lit_clauses.back();
372           lit_clauses.pop_back();
373           --itr1;
374         }
375       }
376 #endif
377       // delete the watched index from the vars
378       vector<CLitPoolElement *> & watched = (*itr).watched(i);
379       for (vector<CLitPoolElement *>::iterator itr1 = watched.begin();
380            itr1 != watched.end(); ++itr1) {
381         if ((*itr1)->val() <= 0) {
382           *itr1 = watched.back();
383           watched.pop_back();
384           --itr1;
385         }
386       }
387     }
388   }
389   free_gid(gid);
390 }
391
392 void CSolver::reset(void) {
393   if (_stats.been_reset)
394     return;
395   if (num_variables() == 0)
396     return;
397   back_track(0);
398   _conflicts.clear();
399   while (!_implication_queue.empty())
400     _implication_queue.pop();
401
402   _stats.outcome = UNDETERMINED;
403   _stats.been_reset = true;
404 }
405
406 void CSolver::delete_unrelevant_clauses(void) {
407   unsigned original_del_cls = num_deleted_clauses();
408   int num_conf_cls = num_clauses() - init_num_clauses() + num_del_orig_cls();
409   int head_count = num_conf_cls / _params.cls_deletion.tail_vs_head;
410   int count = 0;
411   for (vector<CClause>::iterator itr = clauses()->begin();
412                                  itr != clauses()->end() - 1; ++itr) {
413     CClause & cl = *itr;
414     if (cl.status() != CONFLICT_CL) {
415       continue;
416     }
417     bool cls_sat_at_dl_0 = false;
418     for (int i = 0, sz = cl.num_lits(); i < sz; ++i) {
419       if (literal_value(cl.literal(i)) == 1 &&
420           variable(cl.literal(i).var_index()).dlevel() == 0) {
421         cls_sat_at_dl_0 = true;
422         break;
423       }
424     }
425     if (cls_sat_at_dl_0) {
426       int val_0_lits = 0, val_1_lits = 0, unknown_lits = 0;
427       for (unsigned i = 0; i < cl.num_lits(); ++i) {
428         int lit_value = literal_value(cl.literal(i));
429         if (lit_value == 0)
430           ++val_0_lits;
431         if (lit_value == 1)
432           ++val_1_lits;
433         if (lit_value == UNKNOWN)
434           ++unknown_lits;
435         if (unknown_lits + val_1_lits > 1) {
436           mark_clause_deleted(cl);
437           break;
438         }
439       }
440       continue;
441     }
442
443     count++;
444     int max_activity = _params.cls_deletion.head_activity -
445                        (_params.cls_deletion.head_activity -
446                         _params.cls_deletion.tail_activity) *
447                        count/num_conf_cls;
448     int max_conf_cls_size;
449
450     if (head_count > 0) {
451       max_conf_cls_size = _params.cls_deletion.head_num_lits;
452       --head_count;
453     } else {
454       max_conf_cls_size = _params.cls_deletion.tail_num_lits;
455     }
456
457     if (cl.activity() > max_activity)
458       continue;
459
460     int val_0_lits = 0, val_1_lits = 0, unknown_lits = 0, lit_value;
461     for (unsigned i = 0; i < cl.num_lits(); ++i) {
462       lit_value = literal_value(cl.literal(i));
463       if (lit_value == 0)
464         ++val_0_lits;
465       else if (lit_value == 1)
466         ++val_1_lits;
467       else
468         ++unknown_lits;
469       if ((unknown_lits > max_conf_cls_size)) {
470         mark_clause_deleted(cl);
471         break;
472       }
473     }
474   }
475
476   // if none were recently marked for deletion...
477   if (original_del_cls == num_deleted_clauses())
478     return;
479
480   // delete the index from variables
481   for (vector<CVariable>::iterator itr = variables()->begin();
482        itr != variables()->end(); ++itr) {
483     for (unsigned i = 0; i < 2; ++i) {  // for each phase
484       // delete the lit index from the vars
485 #ifdef KEEP_LIT_CLAUSES
486       vector<ClauseIdx> & lit_clauses = (*itr).lit_clause(i);
487       for (vector<ClauseIdx>::iterator itr1 = lit_clauses.begin();
488            itr1 != lit_clauses.end(); ++itr1) {
489         if (clause(*itr1).status() == DELETED_CL) {
490           *itr1 = lit_clauses.back();
491           lit_clauses.pop_back();
492           --itr1;
493         }
494       }
495 #endif
496       // delete the watched index from the vars
497       vector<CLitPoolElement *> & watched = (*itr).watched(i);
498       for (vector<CLitPoolElement *>::iterator itr1 = watched.begin();
499            itr1 != watched.end(); ++itr1) {
500         if ((*itr1)->val() <= 0) {
501           *itr1 = watched.back();
502           watched.pop_back();
503           --itr1;
504         }
505       }
506     }
507   }
508
509   for (unsigned i = 1, sz = variables()->size(); i < sz; ++i) {
510     if (variable(i).dlevel() != 0) {
511       variable(i).score(0) = variable(i).lits_count(0);
512       variable(i).score(1) = variable(i).lits_count(1);
513       if (variable(i).lits_count(0) == 0 && variable(i).value() == UNKNOWN) {
514         queue_implication(i * 2 + 1, NULL_CLAUSE);
515       }
516       else if (variable(i).lits_count(1) == 0 &&
517                variable(i).value() == UNKNOWN) {
518         queue_implication(i * 2, NULL_CLAUSE);
519       }
520     } else {
521       variable(i).score(0) = 0;
522       variable(i).score(1) = 0;
523     }
524   }
525   update_var_score();
526 }
527
528 bool CSolver::time_out(void) {
529   return (get_cpu_time() - _stats.start_cpu_time> _params.time_limit);
530 }
531
532 void CSolver::adjust_variable_order(int * lits, int n_lits) {
533   // note lits are signed vars, not CLitPoolElements
534   for (int i = 0; i < n_lits; ++i) {
535     int var_idx = lits[i] >> 1;
536     CVariable & var = variable(var_idx);
537     assert(var.value() != UNKNOWN);
538     int orig_score = var.score();
539     ++variable(var_idx).score(lits[i] & 0x1);
540     int new_score = var.score();
541     if (orig_score == new_score)
542       continue;
543     int pos = var.var_score_pos();
544     int orig_pos = pos;
545     assert(_ordered_vars[pos].first == & var);
546     assert(_ordered_vars[pos].second == orig_score);
547     int bubble_step = _params.decision.bubble_init_step;
548     for (pos = orig_pos ; pos >= 0; pos -= bubble_step) {
549       if (_ordered_vars[pos].second >= new_score)
550         break;
551     }
552     pos += bubble_step;
553     for (bubble_step = bubble_step >> 1; bubble_step > 0;
554          bubble_step = bubble_step >> 1) {
555       if (pos - bubble_step >= 0 &&
556           _ordered_vars[pos - bubble_step].second < new_score)
557         pos -= bubble_step;
558     }
559     // now found the position, do a swap
560     _ordered_vars[orig_pos] = _ordered_vars[pos];
561     _ordered_vars[orig_pos].first->set_var_score_pos(orig_pos);
562     _ordered_vars[pos].first = & var;
563     _ordered_vars[pos].second = new_score;
564     _ordered_vars[pos].first->set_var_score_pos(pos);
565     _stats.total_bubble_move += orig_pos - pos;
566   }
567 }
568
569 void CSolver::decay_variable_score(void) {
570   unsigned i, sz;
571   for (i = 1, sz = variables()->size(); i < sz; ++i) {
572     CVariable & var = variable(i);
573     var.score(0) /= 2;
574     var.score(1) /= 2;
575   }
576   for (i = 0, sz = _ordered_vars.size(); i < sz; ++i) {
577     _ordered_vars[i].second = _ordered_vars[i].first->score();
578   }
579 }
580
581 bool CSolver::decide_next_branch(void) {
582   if (dlevel() > 0)
583     assert(_assignment_stack[dlevel()]->size() > 0);
584   if (!_implication_queue.empty()) {
585     // some hook function did a decision, so skip my own decision making.
586     // if the front of implication queue is 0, that means it's finished
587     // because var index start from 1, so 2 *vid + sign won't be 0.
588     // else it's a valid decision.
589     return (_implication_queue.front().lit != 0);
590   }
591   int s_var = 0;
592   if (_params.shrinking.enable) {
593     while (!_shrinking_cls.empty()) {
594       s_var = _shrinking_cls.begin()->second;
595       _shrinking_cls.erase(_shrinking_cls.begin());
596       if (variable(s_var >> 1).value() == UNKNOWN) {
597         _stats.num_decisions++;
598         _stats.num_decisions_shrinking++;
599         ++dlevel();
600         queue_implication(s_var ^ 0x1, NULL_CLAUSE);
601         return true;
602       }
603     }
604   }
605
606   if (_outside_constraint_hook != NULL)
607      _outside_constraint_hook(this);
608
609   if (!_implication_queue.empty())
610      return (_implication_queue.front().lit != 0);
611
612   ++_stats.num_decisions;
613   if (num_free_variables() == 0)  // no more free vars
614      return false;
615
616   bool cls_sat = true;
617   int i, sz, var_idx, score, max_score = -1;
618
619   for (; clause(top_unsat_cls).status() != ORIGINAL_CL; --top_unsat_cls) {
620     CClause &cl=clause(top_unsat_cls);
621     if (cl.status() != CONFLICT_CL)
622       continue;
623     cls_sat = false;
624     if (cl.sat_lit_idx() < (int)cl.num_lits() &&
625         literal_value(cl.literal(cl.sat_lit_idx())) == 1)
626       cls_sat = true;
627     if (!cls_sat) {
628       max_score = -1;
629       for (i = 0, sz = cl.num_lits(); i < sz; ++i) {
630         var_idx = cl.literal(i).var_index();
631         if (literal_value(cl.literal(i)) == 1) {
632           cls_sat = true;
633           cl.sat_lit_idx() = i;
634           break;
635         }
636         else if (variable(var_idx).value() == UNKNOWN) {
637           score = variable(var_idx).score();
638           if (score > max_score) {
639             max_score = score;
640             s_var = var_idx * 2;
641           }
642         }
643       }
644     }
645     if (!cls_sat)
646       break;
647   }
648   if (!cls_sat && max_score != -1) {
649     ++dlevel();
650     if (dlevel() > _stats.max_dlevel)
651       _stats.max_dlevel = dlevel();
652     CVariable& v = variable(s_var >> 1);
653     if (v.score(0) < v.score(1))
654       s_var += 1;
655     else if (v.score(0) == v.score(1)) {
656       if (v.two_lits_count(0) > v.two_lits_count(1))
657         s_var+=1;
658       else if (v.two_lits_count(0) == v.two_lits_count(1))
659         s_var+=rand()%2;
660     }
661     assert(s_var >= 2);
662     queue_implication(s_var, NULL_CLAUSE);
663     ++_stats.num_decisions_stack_conf;
664     return true;
665   }
666
667   for (unsigned i = _max_score_pos; i < _ordered_vars.size(); ++i) {
668     CVariable & var = *_ordered_vars[i].first;
669     if (var.value() == UNKNOWN && var.is_branchable()) {
670       // move th max score position pointer
671       _max_score_pos = i;
672       // make some randomness happen
673       if (--_stats.current_randomness < _params.decision.base_randomness)
674         _stats.current_randomness = _params.decision.base_randomness;
675       int randomness = _stats.current_randomness;
676       if (randomness >= num_free_variables())
677         randomness = num_free_variables() - 1;
678       int skip = rand() % (1 + randomness);
679       int index = i;
680       while (skip > 0) {
681         ++index;
682       if (_ordered_vars[index].first->value() == UNKNOWN &&
683           _ordered_vars[index].first->is_branchable())
684         --skip;
685       }
686       CVariable * ptr = _ordered_vars[index].first;
687       assert(ptr->value() == UNKNOWN && ptr->is_branchable());
688       int sign = 0;
689       if (ptr->score(0) < ptr->score(1))
690         sign += 1;
691       else if (ptr->score(0) == ptr->score(1)) {
692         if (ptr->two_lits_count(0) > ptr->two_lits_count(1))
693           sign += 1;
694         else if (ptr->two_lits_count(0) == ptr->two_lits_count(1))
695           sign += rand() % 2;
696       }
697       int var_idx = ptr - &(*variables()->begin());
698       s_var = var_idx + var_idx + sign;
699       break;
700     }
701   }
702   assert(s_var >= 2);  // there must be a free var somewhere
703   ++dlevel();
704   if (dlevel() > _stats.max_dlevel)
705     _stats.max_dlevel = dlevel();
706   ++_stats.num_decisions_vsids;
707   _implication_id = 0;
708   queue_implication(s_var, NULL_CLAUSE);
709   return true;
710 }
711
712 int CSolver::preprocess(void) {
713   assert(dlevel() == 0);
714
715   // 1. detect all the unused variables
716   vector<int> un_used;
717   for (unsigned i = 1, sz = variables()->size(); i < sz; ++i) {
718     CVariable & v = variable(i);
719     if (v.lits_count(0) == 0 && v.lits_count(1) == 0) {
720       un_used.push_back(i);
721       queue_implication(i+i, NULL_CLAUSE);
722       int r = deduce();
723       assert(r == NO_CONFLICT);
724     }
725   }
726   if (_params.verbosity > 1 && un_used.size() > 0) {
727     cout << un_used.size() << " Variables are defined but not used " << endl;
728     if (_params.verbosity > 2) {
729       for (unsigned i = 0; i< un_used.size(); ++i)
730          cout << un_used[i] << " ";
731       cout << endl;
732     }
733   }
734
735   // 2. detect all variables with only one phase occuring (i.e. pure literals)
736   vector<int> uni_phased;
737   for (unsigned i = 1, sz = variables()->size(); i < sz; ++i) {
738     CVariable & v = variable(i);
739     if (v.value() != UNKNOWN)
740       continue;
741     if (v.lits_count(0) == 0) {  // no positive phased lits.
742       queue_implication(i+i+1, NULL_CLAUSE);
743       uni_phased.push_back(-i);
744     }
745     else if (v.lits_count(1) == 0) {  // no negative phased lits.
746       queue_implication(i+i, NULL_CLAUSE);
747       uni_phased.push_back(i);
748     }
749   }
750   if (_params.verbosity > 1 && uni_phased.size() > 0) {
751     cout << uni_phased.size() << " Variables only appear in one phase." <<endl;
752     if (_params.verbosity > 2) {
753       for (unsigned i = 0; i< uni_phased.size(); ++i)
754         cout << uni_phased[i] << " ";
755       cout <<endl;
756     }
757   }
758
759   // 3. Unit clauses
760   for (unsigned i = 0, sz = clauses()->size(); i < sz; ++i) {
761     if (clause(i).status() != DELETED_CL &&
762         clause(i).num_lits() == 1 &&
763         variable(clause(i).literal(0).var_index()).value() == UNKNOWN)
764       queue_implication(clause(i).literal(0).s_var(), i);
765   }
766
767   if (deduce() == CONFLICT) {
768     cout << " CONFLICT during preprocess " <<endl;
769 #ifdef VERIFY_ON
770     for (unsigned i = 1; i < variables()->size(); ++i) {
771       if (variable(i).value() != UNKNOWN) {
772         assert(variable(i).dlevel() <= 0);
773         int ante = variable(i).antecedent();
774         int ante_id = 0;
775         if (ante >= 0) {
776           ante_id = clause(ante).id();
777           verify_out << "VAR: " << i
778                      << " L: " << variable(i).assgn_stack_pos()
779                      << " V: " << variable(i).value()
780                      << " A: " << ante_id
781                      << " Lits:";
782           for (unsigned j = 0; j < clause(ante).num_lits(); ++j)
783             verify_out <<" " <<  clause(ante).literal(j).s_var();
784           verify_out << endl;
785          }
786        }
787     }
788     verify_out << "CONF: " << clause(_conflicts[0]).id() << " ==";
789     for (unsigned i = 0; i < clause(_conflicts[0]).num_lits(); ++i) {
790       int svar = clause(_conflicts[0]).literal(i).s_var();
791       verify_out << " " << svar;
792     }
793     verify_out << endl;
794 #endif
795     return CONFLICT;
796   }
797   if (_params.verbosity > 1) {
798     cout << _assignment_stack[0]->size() << " vars set during preprocess; "
799          << endl;
800   }
801   return NO_CONFLICT;
802 }
803
804 void CSolver::mark_var_unbranchable(int vid) {
805   if (variable(vid).is_branchable()) {
806     variable(vid).disable_branch();
807     if (variable(vid).value() == UNKNOWN)
808       --num_free_variables();
809   }
810 }
811
812 void CSolver::mark_var_branchable(int vid) {
813   CVariable & var = variable(vid);
814   if (!var.is_branchable()) {
815     var.enable_branch();
816     if (var.value() == UNKNOWN) {
817       ++num_free_variables();
818       if (var.var_score_pos() < _max_score_pos)
819         _max_score_pos = var.var_score_pos();
820     }
821   }
822 }
823
824 ClauseIdx CSolver::add_orig_clause(int * lits, int n_lits, int gid) {
825   int cid = add_clause_with_gid(lits, n_lits, gid);
826   if (cid >= 0) {
827     clause(cid).set_status(ORIGINAL_CL);
828     clause(cid).activity() = 0;
829   }
830   return cid;
831 }
832
833 ClauseIdx CSolver::add_clause_with_gid(int * lits, int n_lits, int gid) {
834   unsigned gflag;
835   if (gid == PERMANENT_GID )
836     gflag = 0;
837   else if (gid == VOLATILE_GID) {
838     gflag = (~0x0);
839   } else {
840     assert(gid <= WORD_WIDTH && gid > 0);
841     gflag = (1 << (gid- 1));
842   }
843   ClauseIdx cid = add_clause(lits, n_lits, gflag);
844   if (cid < 0) {
845     _stats.is_mem_out = true;
846     _stats.outcome = MEM_OUT;
847   }
848   return cid;
849 }
850
851 ClauseIdx CSolver::add_conflict_clause(int * lits, int n_lits, int gflag) {
852   ClauseIdx cid = add_clause(lits, n_lits, gflag);
853   if (cid >= 0) {
854     clause(cid).set_status(CONFLICT_CL);
855     clause(cid).activity() = 0;
856   } else {
857     _stats.is_mem_out = true;
858     _stats.outcome = MEM_OUT;
859   }
860   return cid;
861 }
862
863 void CSolver::real_solve(void) {
864   while (_stats.outcome == UNDETERMINED) {
865     run_periodic_functions();
866     if (decide_next_branch()) {
867       while (deduce() == CONFLICT) {
868         int blevel;
869         blevel = analyze_conflicts();
870         if (blevel < 0) {
871           _stats.outcome = UNSATISFIABLE;
872           return;
873         }
874       }
875     } else {
876       if (_sat_hook != NULL && _sat_hook(this))
877         continue;
878       _stats.outcome = SATISFIABLE;
879       return;
880     }
881     if (time_out()) {
882       _stats.outcome = TIME_OUT;
883       return;
884     }
885     if (_force_terminate) {
886       _stats.outcome = ABORTED;
887       return;
888     }
889     if (_stats.is_mem_out) {
890       _stats.outcome = MEM_OUT;
891        return;
892     }
893   }
894 }
895
896 int CSolver::solve(void) {
897   if (_stats.outcome == UNDETERMINED) {
898     init_solve();
899
900     if (preprocess() == CONFLICT)
901       _stats.outcome = UNSATISFIABLE;
902     else  // the real search
903       real_solve();
904     cout << endl;
905     _stats.finish_cpu_time = get_cpu_time();
906   }
907   return _stats.outcome;
908 }
909
910 void CSolver::back_track(int blevel) {
911   assert(blevel <= dlevel());
912   for (int i = dlevel(); i >= blevel; --i) {
913     vector<int> & assignments = *_assignment_stack[i];
914     for (int j = assignments.size() - 1 ; j >= 0; --j)
915       unset_var_value(assignments[j]>>1);
916     assignments.clear();
917   }
918   dlevel() = blevel - 1;
919   if (dlevel() < 0 )
920     dlevel() = 0;
921   ++_stats.num_backtracks;
922 }
923
924 int CSolver::deduce(void) {
925   while (!_implication_queue.empty()) {
926     const CImplication & imp = _implication_queue.front();
927     int lit = imp.lit;
928     int vid = lit>>1;
929     ClauseIdx cl = imp.antecedent;
930     _implication_queue.pop();
931     CVariable & var = variable(vid);
932     if (var.value() == UNKNOWN) {  // an implication
933       set_var_value(vid, !(lit & 0x1), cl, dlevel());
934     }
935     else if (var.value() == (unsigned)(lit & 0x1)) {
936       // a conflict
937       // note: literal & 0x1 == 1 means the literal is in negative phase
938       // when a conflict occure at not current dlevel, we need to backtrack
939       // to resolve the problem.
940       // conflict analysis will only work if the conflict occure at
941       // the top level (current dlevel)
942       _conflicts.push_back(cl);
943       break;
944     } else {
945       // so the variable have been assigned before
946       // update its antecedent with a shorter one
947       if (var.antecedent() != NULL_CLAUSE &&
948           clause(cl).num_lits() < clause(var.antecedent()).num_lits())
949         var.antecedent() = cl;
950       assert(var.dlevel() <= dlevel());
951     }
952   }
953   // if loop exited because of a conflict, we need to clean implication queue
954   while (!_implication_queue.empty())
955     _implication_queue.pop();
956   return (_conflicts.size() ? CONFLICT : NO_CONFLICT);
957 }
958
959 void CSolver::verify_integrity(void) {
960   for (unsigned i = 1; i < variables()->size(); ++i) {
961     if (variable(i).value() != UNKNOWN) {
962       int pos = variable(i).assgn_stack_pos();
963       int value = variable(i).value();
964       int dlevel = variable(i).dlevel();
965       assert((*_assignment_stack[dlevel])[pos] == (int) (i+i+1-value));
966     }
967   }
968   for (unsigned i = 0; i < clauses()->size(); ++i) {
969     if (clause(i).status() == DELETED_CL)
970       continue;
971     CClause & cl = clause(i);
972     int num_0 = 0;
973     int num_1 = 0;
974     int num_unknown = 0;
975     int watched[2];
976     int watch_index = 0;
977     watched[1] = watched[0] = 0;
978     for (unsigned j = 0; j < cl.num_lits(); ++j) {
979       CLitPoolElement lit = cl.literal(j);
980       int vid = lit.var_index();
981       if (variable(vid).value() == UNKNOWN) {
982         ++num_unknown;
983       } else {
984         if (literal_value(lit) == 0)
985           ++num_0;
986         else
987           ++num_1;
988       }
989       if (lit.is_watched()) {
990         watched[watch_index] = lit.s_var();
991         ++watch_index;
992       }
993     }
994     if (watch_index == 0) {
995       assert(cl.num_lits() == 1);
996       continue;
997     }
998     assert(watch_index == 2);
999     for (unsigned j = 0; j < cl.num_lits(); ++j) {
1000       CLitPoolElement lit = cl.literal(j);
1001       int vid1 = (watched[0]>>1);
1002       if (variable(vid1).value() == (unsigned)(watched[0] & 0x1)) {
1003         if (!lit.is_watched()) {
1004           assert(literal_value(lit) == 0);
1005           assert(variable(lit.var_index()).dlevel() <=
1006                   variable(vid1).dlevel());
1007         }
1008       }
1009       int vid2 = (watched[1]>>1);
1010       if (variable(vid2).value() == (unsigned)(watched[1] & 0x1)) {
1011         if (!lit.is_watched()) {
1012           assert(literal_value(lit) == 0);
1013           assert(variable(lit.var_index()).dlevel() <=
1014                   variable(vid1).dlevel());
1015         }
1016       }
1017     }
1018   }
1019 }
1020
1021 void CSolver::mark_vars(ClauseIdx cl, int var_idx) {
1022   assert(_resolvents.empty() || var_idx != -1);
1023 #ifdef VERIFY_ON
1024   _resolvents.push_back(clause(cl).id());
1025 #endif
1026   for (CLitPoolElement* itr = clause(cl).literals(); (*itr).val() > 0; ++itr) {
1027     int v = (*itr).var_index();
1028     if (v == var_idx)
1029       continue;
1030     else if (variable(v).dlevel() == dlevel()) {
1031       if (!variable(v).is_marked()) {
1032         variable(v).set_marked();
1033         ++_num_marked;
1034         if (_mark_increase_score) {
1035           int tmp = itr->s_var();
1036           adjust_variable_order(&tmp, 1);
1037         }
1038       }
1039     } else {
1040       assert(variable(v).dlevel() < dlevel());
1041       if (variable(v).new_cl_phase() == UNKNOWN) {  // it's not in the new cl
1042         // We can remove the variable assigned at dlevel 0 if
1043         // we are nog going to use incremental SAT.
1044         // if(variable(v).dlevel()){
1045           ++_num_in_new_cl;
1046           variable(v).set_new_cl_phase((*itr).var_sign());
1047           _conflict_lits.push_back((*itr).s_var());
1048         // }
1049        } else {
1050          // if this variable is already in the new clause, it must
1051          // have the same phase
1052          assert(variable(v).new_cl_phase() == (*itr).var_sign());
1053        }
1054     }
1055   }
1056 }
1057
1058 int CSolver::analyze_conflicts(void) {
1059   assert(!_conflicts.empty());
1060   assert(_conflict_lits.size() == 0);
1061   assert(_implication_queue.empty());
1062   assert(_num_marked == 0);
1063   if (dlevel() == 0) {  // already at level 0. Conflict means unsat.
1064 #ifdef VERIFY_ON
1065     for (unsigned i = 1; i < variables()->size(); ++i) {
1066       if (variable(i).value() != UNKNOWN) {
1067         assert(variable(i).dlevel() <= 0);
1068         int ante = variable(i).antecedent();
1069         int ante_id = 0;
1070         if (ante >= 0) {
1071           ante_id = clause(ante).id();
1072           assert(clause(ante).status() != DELETED_CL);
1073           verify_out << "VAR: " << i
1074                      << " L: " << variable(i).assgn_stack_pos()
1075                      << " V: " << variable(i).value()
1076                      << " A: " << ante_id
1077                      << " Lits:";
1078           for (unsigned j = 0; j < clause(ante).num_lits(); ++j)
1079             verify_out << " " << clause(ante).literal(j).s_var();
1080           verify_out << endl;
1081         }
1082       }
1083     }
1084     ClauseIdx shortest;
1085     shortest = _conflicts.back();
1086     unsigned len = clause(_conflicts.back()).num_lits();
1087     while (!_conflicts.empty()) {
1088       if (clause(_conflicts.back()).num_lits() < len) {
1089         shortest = _conflicts.back();
1090         len = clause(_conflicts.back()).num_lits();
1091       }
1092       _conflicts.pop_back();
1093     }
1094     verify_out << "CONF: " << clause(shortest).id() << " ==";
1095     for (unsigned i = 0; i < clause(shortest).num_lits(); ++i) {
1096       int svar = clause(shortest).literal(i).s_var();
1097       verify_out << " " << svar;
1098     }
1099     verify_out << endl;
1100 #endif
1101     _conflicts.clear();
1102     back_track(0);
1103     return -1;
1104   }
1105   return  conflict_analysis_firstUIP();
1106 }
1107
1108 // when all the literals involved are in _conflict_lits
1109 // call this function to finish the adding clause and backtrack
1110
1111 int CSolver::finish_add_conf_clause(int gflag) {
1112   ClauseIdx added_cl = add_conflict_clause(&(*_conflict_lits.begin()),
1113                                            _conflict_lits.size(), gflag);
1114   if (added_cl < 0) {  // memory out.
1115     _stats.is_mem_out = true;
1116     _conflicts.clear();
1117     assert(_implication_queue.empty());
1118     return 1;
1119   }
1120
1121   top_unsat_cls = clauses()->size() - 1;
1122
1123 #ifdef VERIFY_ON
1124   verify_out << "CL: " <<  clause(added_cl).id() << " <=";
1125   for (unsigned i = 0; i< _resolvents.size(); ++i)
1126         verify_out << " " <<  _resolvents[i];
1127     verify_out << endl;
1128     _resolvents.clear();
1129 #endif
1130
1131   adjust_variable_order(&(*_conflict_lits.begin()), _conflict_lits.size());
1132
1133   if (_params.shrinking.enable) {
1134     _shrinking_cls.clear();
1135     if (_stats.shrinking_cls_length != 0) {
1136       int benefit = _stats.shrinking_cls_length - _conflict_lits.size();
1137       _stats.shrinking_benefit += benefit;
1138       _stats.shrinking_cls_length = 0;
1139       _recent_shrinkings.push(benefit);
1140       if (_recent_shrinkings.size() > _params.shrinking.window_width) {
1141         _stats.shrinking_benefit -= _recent_shrinkings.front();
1142         _recent_shrinkings.pop();
1143       }
1144     }
1145     if (_conflict_lits.size() > _params.shrinking.size) {
1146       _shrinking_cls.clear();
1147       for (unsigned i = 0, sz = _conflict_lits.size(); i < sz; ++i) {
1148         _shrinking_cls.insert(pair<int, int>
1149                  (variable(_conflict_lits[i]>>1).dlevel(), _conflict_lits[i]));
1150       }
1151       int prev_dl = _shrinking_cls.begin()->first;
1152       multimap<int, int>::iterator itr, itr_del;
1153       int last_dl = _shrinking_cls.rbegin()->first;
1154
1155       bool found_gap = false;
1156       for (itr = _shrinking_cls.begin(); itr->first != last_dl;) {
1157         if (itr->first - prev_dl > 2) {
1158           found_gap = true;
1159           break;
1160         }
1161         prev_dl = itr->first;
1162         itr_del = itr;
1163         ++itr;
1164         _shrinking_cls.erase(itr_del);
1165       }
1166       if (found_gap && _shrinking_cls.size() > 0 && prev_dl < dlevel() - 1) {
1167         _stats.shrinking_cls_length = _conflict_lits.size();
1168         ++_stats.num_shrinkings;
1169         back_track(prev_dl + 1);
1170         _conflicts.clear();
1171 #ifdef VERIFY_ON
1172         _resolvents.clear();
1173 #endif
1174         _num_in_new_cl = 0;
1175         for (unsigned i = 0, sz = _conflict_lits.size(); i < sz; ++i)
1176           variable(_conflict_lits[i]>>1).set_new_cl_phase(UNKNOWN);
1177         _conflict_lits.clear();
1178         if (_stats.num_shrinkings %
1179             _params.shrinking.bound_update_frequency == 0 &&
1180             _recent_shrinkings.size() == _params.shrinking.window_width) {
1181           if (_stats.shrinking_benefit > _params.shrinking.upper_bound)
1182             _params.shrinking.size += _params.shrinking.upper_delta;
1183           else if (_stats.shrinking_benefit < _params.shrinking.lower_bound)
1184             _params.shrinking.size += _params.shrinking.lower_delta;
1185         }
1186         return prev_dl;
1187       }
1188     }
1189   }
1190   int back_dl = 0;
1191   int unit_lit = -1;
1192
1193   for (unsigned i = 0; i < clause(added_cl).num_lits(); ++i) {
1194     int vid = clause(added_cl).literal(i).var_index();
1195     int sign =clause(added_cl).literal(i).var_sign();
1196     assert(variable(vid).value() != UNKNOWN);
1197     assert(literal_value(clause(added_cl).literal(i)) == 0);
1198     int dl = variable(vid).dlevel();
1199     if (dl < dlevel()) {
1200       if (dl > back_dl)
1201         back_dl = dl;
1202     } else {
1203       assert(unit_lit == -1);
1204       unit_lit = vid + vid + sign;
1205     }
1206   }
1207   if (back_dl == 0) {
1208     _stats.next_restart = _stats.num_backtracks + _stats.restart_incr;
1209     _stats.next_cls_deletion = _stats.num_backtracks +
1210                                _params.cls_deletion.interval;
1211   }
1212
1213   back_track(back_dl + 1);
1214   queue_implication(unit_lit, added_cl);
1215
1216   // after resolve the first conflict, others must also be resolved
1217   // for (unsigned i = 1; i < _conflicts.size(); ++i)
1218   //   assert(!is_conflicting(_conflicts[i]));
1219
1220   _conflicts.clear();
1221
1222   while (!_conflict_lits.empty()) {
1223     int svar = _conflict_lits.back();
1224     _conflict_lits.pop_back();
1225     CVariable & var = variable(svar >> 1);
1226     assert(var.new_cl_phase() == (unsigned)(svar & 0x1));
1227     --_num_in_new_cl;
1228     var.set_new_cl_phase(UNKNOWN);
1229   }
1230   assert(_num_in_new_cl == 0);
1231   return back_dl;
1232 }
1233
1234 int CSolver::conflict_analysis_firstUIP(void) {
1235   int min_conf_id = _conflicts[0];
1236   int min_conf_length = -1;
1237   ClauseIdx cl;
1238   unsigned gflag;
1239   _mark_increase_score = false;
1240   if (_conflicts.size() > 1) {
1241     for (vector<ClauseIdx>::iterator ci = _conflicts.begin();
1242          ci != _conflicts.end(); ci++) {
1243       assert(_num_in_new_cl == 0);
1244       assert(dlevel() > 0);
1245       cl = *ci;
1246       mark_vars(cl, -1);
1247       // current dl must be the conflict cl.
1248       vector <int> & assignments = *_assignment_stack[dlevel()];
1249       // now add conflict lits, and unassign vars
1250       for (int i = assignments.size() - 1; i >= 0; --i) {
1251         int assigned = assignments[i];
1252         if (variable(assigned >> 1).is_marked()) {
1253           // this variable is involved in the conflict clause or its antecedent
1254           variable(assigned>>1).clear_marked();
1255           --_num_marked;
1256           ClauseIdx ante_cl = variable(assigned>>1).get_antecedent();
1257           if ( _num_marked == 0 ) {
1258             // the first UIP encountered, conclude add clause
1259             assert(variable(assigned>>1).new_cl_phase() == UNKNOWN);
1260             // add this assignment's reverse, e.g. UIP
1261             _conflict_lits.push_back(assigned ^ 0x1);
1262             ++_num_in_new_cl;
1263             variable(assigned>>1).set_new_cl_phase((assigned^0x1)&0x1);
1264             break;
1265           } else {
1266             assert(ante_cl != NULL_CLAUSE);
1267             mark_vars(ante_cl, assigned >> 1);
1268           }
1269         }
1270       }
1271       if (min_conf_length == -1 ||
1272           (int)_conflict_lits.size() < min_conf_length) {
1273         min_conf_length = _conflict_lits.size();
1274         min_conf_id = cl;
1275       }
1276
1277       for (vector<int>::iterator vi = _conflict_lits.begin(); vi !=
1278            _conflict_lits.end(); ++vi) {
1279         int s_var = *vi;
1280         CVariable & var = variable(s_var >> 1);
1281         assert(var.new_cl_phase() == (unsigned)(s_var & 0x1));
1282         var.set_new_cl_phase(UNKNOWN);
1283       }
1284       _num_in_new_cl = 0;
1285       _conflict_lits.clear();
1286 #ifdef VERIFY_ON
1287       _resolvents.clear();
1288 #endif
1289     }
1290   }
1291
1292   assert(_num_marked == 0);
1293   cl = min_conf_id;
1294   clause(cl).activity() += 5;
1295   _mark_increase_score = true;
1296   mark_vars(cl, -1);
1297   gflag = clause(cl).gflag();
1298   vector <int> & assignments = *_assignment_stack[dlevel()];
1299   for (int i = assignments.size() - 1; i >= 0; --i) {
1300     int assigned = assignments[i];
1301     if (variable(assigned >> 1).is_marked()) {
1302       variable(assigned>>1).clear_marked();
1303       --_num_marked;
1304       ClauseIdx ante_cl = variable(assigned>>1).get_antecedent();
1305       if ( _num_marked == 0 ) {
1306         _conflict_lits.push_back(assigned ^ 0x1);
1307         ++_num_in_new_cl;
1308         variable(assigned >> 1).set_new_cl_phase((assigned ^ 0x1) & 0x1);
1309         break;
1310       } else {
1311         gflag |= clause(ante_cl).gflag();
1312         mark_vars(ante_cl, assigned >> 1);
1313         clause(ante_cl).activity() += 5;
1314       }
1315     }
1316   }
1317   return finish_add_conf_clause(gflag);
1318 }
1319
1320 void CSolver::print_cls(ostream & os) {
1321   for (unsigned i = 0; i < clauses()->size(); ++i) {
1322     CClause & cl = clause(i);
1323     if (cl.status() == DELETED_CL)
1324       continue;
1325     if (cl.status() == ORIGINAL_CL) {
1326       os <<"0 ";
1327     } else {
1328       assert(cl.status() == CONFLICT_CL);
1329       os << "A ";
1330     }
1331     for (unsigned j = 1; j < 33; ++j)
1332       os << (cl.gid(j) ? 1 : 0);
1333     os << "\t";
1334     for (unsigned j = 0; j < cl.num_lits(); ++j) {
1335       os << (cl.literal(j).var_sign() ? "-":"")
1336          << cl.literal(j).var_index() << " ";
1337     }
1338     os <<"0" <<  endl;
1339   }
1340 }
1341
1342 int CSolver::mem_usage(void) {
1343   int mem_dbase = CDatabase::mem_usage();
1344   int mem_assignment = 0;
1345   for (int i = 0; i < _stats.max_dlevel; ++i)
1346     mem_assignment += _assignment_stack[i]->capacity() * sizeof(int);
1347   mem_assignment += sizeof(vector<int>)* _assignment_stack.size();
1348   return mem_dbase + mem_assignment;
1349 }
1350
1351 void CSolver::clean_up_dbase(void) {
1352   assert(dlevel() == 0);
1353
1354   int mem_before = mem_usage();
1355   // 1. remove all the learned clauses
1356   for (vector<CClause>::iterator itr = clauses()->begin();
1357        itr != clauses()->end() - 1; ++itr) {
1358     CClause & cl = * itr;
1359     if (cl.status() != ORIGINAL_CL)
1360       mark_clause_deleted(cl);
1361   }
1362   // delete_unrelevant_clauses() is specialized using berkmin deletion strategy
1363
1364   // 2. free up the mem for the vectors if possible
1365   for (unsigned i = 0; i < variables()->size(); ++i) {
1366     for (unsigned j = 0; j < 2; ++j) {  // both phase
1367       vector<CLitPoolElement *> watched;
1368       vector<CLitPoolElement *> & old_watched = variable(i).watched(j);
1369       watched.reserve(old_watched.size());
1370       for (vector<CLitPoolElement *>::iterator itr = old_watched.begin();
1371            itr != old_watched.end(); ++itr)
1372         watched.push_back(*itr);
1373         // because watched is a temp mem allocation, it will get deleted
1374         // out of the scope, but by swap it with the old_watched, the
1375         // contents are reserved.
1376         old_watched.swap(watched);
1377 #ifdef KEEP_LIT_CLAUSES
1378         vector<int> lits_cls;
1379         vector<int> & old_lits_cls = variable(i).lit_clause(j);
1380         lits_cls.reserve(old_lits_cls.size());
1381         for (vector<int>::iterator itr1 = old_lits_cls.begin(); itr1 !=
1382             old_lits_cls.end(); ++itr1)
1383           lits_cls.push_back(*itr1);
1384         old_lits_cls.swap(lits_cls);
1385 #endif
1386     }
1387   }
1388
1389   int mem_after = mem_usage();
1390   if (_params.verbosity > 0) {
1391     cout << "Database Cleaned, releasing (approximately) "
1392          << mem_before - mem_after << " Bytes" << endl;
1393   }
1394 }
1395
1396 void CSolver::update_var_score(void) {
1397   for (unsigned i = 1, sz = variables()->size(); i < sz; ++i) {
1398     _ordered_vars[i-1].first = & variable(i);
1399     _ordered_vars[i-1].second = variable(i).score();
1400   }
1401   ::stable_sort(_ordered_vars.begin(), _ordered_vars.end(), cmp_var_stat);
1402   for (unsigned i = 0, sz =  _ordered_vars.size(); i < sz; ++i)
1403     _ordered_vars[i].first->set_var_score_pos(i);
1404   _max_score_pos = 0;
1405 }
1406
1407 void CSolver::restart(void) {
1408   _stats.num_restarts += 1;
1409   if (_params.verbosity > 1 )
1410     cout << "Restarting ... " << endl;
1411   if (dlevel() > 0)
1412     back_track(1);
1413   assert(dlevel() == 0);
1414 }
1415
1416 // this function can be called within a solving process. i.e. not after
1417 // solve() terminate
1418 int CSolver::add_clause_incr(int * lits, int num_lits, int gid) {
1419   // Do not mess up with shrinking.
1420   assert(!_params.shrinking.enable || _shrinking_cls.empty());
1421   unsigned gflag;
1422   _stats.outcome = UNDETERMINED;
1423
1424   if (gid == PERMANENT_GID)
1425     gflag = 0;
1426   else if (gid == VOLATILE_GID) {
1427     gflag = ~0x0;
1428   } else {
1429     assert(gid <= WORD_WIDTH && gid > 0);
1430     gflag = (1 << (gid - 1));
1431   }
1432
1433   int cl = add_clause(lits, num_lits, gflag);
1434   if (cl < 0)
1435     return -1;
1436   clause(cl).set_status(ORIGINAL_CL);
1437
1438   if (clause(cl).num_lits() == 1) {
1439     int var_idx = clause(cl).literal(0).var_index();
1440     if (literal_value(clause(cl).literal(0)) == 0 &&
1441         variable(var_idx).dlevel() == 0) {
1442       back_track(0);
1443       if (preprocess() == CONFLICT)
1444         _stats.outcome = UNSATISFIABLE;
1445     } else {
1446       if (dlevel() > 0)
1447         back_track(1);
1448       queue_implication(clause(cl).literal(0).s_var(), cl);
1449     }
1450     return cl;
1451   }
1452
1453   for (unsigned i = 0, sz = clause(cl).num_lits(); i < sz; ++i) {
1454     int var_idx = lits[i] >> 1;
1455     int value = variable(var_idx).value();
1456     if (value == UNKNOWN)
1457       continue;
1458     if (variable(var_idx).dlevel() == 0 &&
1459         variable(var_idx).antecedent() == -1 &&
1460         literal_value(clause(cl).literal(i)) == 0) {
1461       back_track(0);
1462       if (preprocess() == CONFLICT)
1463         _stats.outcome = UNSATISFIABLE;
1464       return cl;
1465     }
1466   }
1467
1468   int max_level = 0;
1469   int max_level2 = 0;
1470   int unit_lit = 0;
1471   int unknown_count = 0;
1472   int num_sat = 0;
1473   int sat_dlevel = -1, max_lit = 0;
1474   bool already_sat = false;
1475
1476   for (unsigned i = 0, sz = clause(cl).num_lits();
1477        unknown_count < 2 && i < sz; ++i) {
1478     int var_idx = lits[i] / 2;
1479     int value = variable(var_idx).value();
1480     if (value == UNKNOWN) {
1481       unit_lit = clause(cl).literal(i).s_var();
1482       ++unknown_count;
1483     } else {
1484       int dl = variable(var_idx).dlevel();
1485       if (dl >= max_level) {
1486         max_level2 = max_level;
1487         max_level = dl;
1488         max_lit = clause(cl).literal(i).s_var();
1489       }
1490       else if (dl > max_level2)
1491         max_level2 = dl;
1492       if (literal_value(clause(cl).literal(i)) == 1) {
1493         already_sat = true;
1494         ++num_sat;
1495         sat_dlevel = dl;
1496       }
1497     }
1498   }
1499   if (unknown_count == 0) {
1500     if (already_sat) {
1501       assert(sat_dlevel > -1);
1502       if (num_sat == 1 && sat_dlevel == max_level && max_level > max_level2) {
1503         back_track(max_level2 + 1);
1504         assert(max_lit > 1);
1505         queue_implication(max_lit, cl);
1506       }
1507     } else {
1508       assert(is_conflicting(cl));
1509       if (max_level > max_level2) {
1510         back_track(max_level2 + 1);
1511         assert(max_lit > 1);
1512         queue_implication(max_lit, cl);
1513       } else {
1514         back_track(max_level);
1515         if (max_level == 0 && preprocess() == CONFLICT)
1516           _stats.outcome = UNSATISFIABLE;
1517       }
1518     }
1519   }
1520   else if (unknown_count == 1) {
1521     if (!already_sat) {
1522       if (max_level < dlevel())
1523         back_track(max_level + 1);
1524       queue_implication(unit_lit, cl);
1525     }
1526   }
1527   return cl;
1528 }