CaDiCal2019学习笔记(4)


 

phases.hpp

 1 typedef signed char Phase;
 2 
 3 struct Phases {
 4 
 5   Phase * saved;        // The actual saved phase.
 6   Phase * target;       // The current target phase.
 7   Phase * best;         // The current largest trail phase.
 8   Phase * prev;         // Previous during local search.
 9   Phase * min;          // The current minimum unsatisfied phase.
10 
11   Phases () : saved (0), target (0), best (0), prev (0), min (0) { }
12 };
声明了Phases类型,似乎变元用作节点时,拥有这个属性可以链接很多求解进程中的过程量(前世今生^_^)

phases.cpp

 1 #include "internal.hpp"
 2 
 3 namespace CaDiCaL {
 4 
 5 void Internal::copy_phases (Phase * & dst) {
 6   assert (sizeof (Phase) == 1);
 7   memcpy (dst, vals, max_var + 1);
 8 }
 9 
10 void Internal::clear_phases (Phase * & dst) {
11   assert (sizeof (Phase) == 1);
12   memset (dst, 0, max_var + 1);
13 }
14 
15 }
对internal.hpp中声明的类型Internal相应成员函数的实现,操作了该类的数据成员vals.

 

让我们看看internal.h中的相关代码:

155   signed char * vals;           // assignment [-max_var,max_var]
156   signed char * marks;          // signed marks [1,max_var]
157   Phases phases;                // saved, target and best phases
231   // Enlarge tables.
232   //
233   void enlarge_vals (size_t new_vsize);
234   void enlarge (int new_max_var);
476   // Functions to set and reset certain 'phases'.
477   //
478   void clear_phases (Phase * &);    // reset to zero
479   void copy_phases (Phase * &);     // copy 'vals' to 'argument'  //phases.ccp line 5.
891   // Get the value of an internal literal: -1=false, 0=unassigned, 1=true.
892   // We use a redundant table for both negative and positive literals.  This
893   // allows a branch-less check for the value of literal and is considered
894   // substantially faster than negating the result if the argument is
895   // negative.  We also avoid taking the absolute value.
896   //
897   int val (int lit) const {
898     assert (-max_var <= lit), assert (lit), assert (lit <= max_var);
899     return vals[lit];
900   }

 

902 // As 'val' but restricted to the root-level value of a literal.
903   // It is not that time critical and also needs to check the decision level
904   // of the variable anyhow.
905   //
906   int fixed (int lit) {
907     assert (-max_var <= lit), assert (lit), assert (lit <= max_var);
908     int idx = vidx (lit), res = vals[idx];
909     if (res && vtab[idx].level) res = 0;
910     if (lit < 0) res = -res;
911     return res;
912   }
 

 

对应在internal.cpp中的相关代码:

 1 Internal::~Internal () {
 2   for (const auto & c : clauses)
 3     delete_clause (c);
 4   if (proof) delete proof;
 5   if (tracer) delete tracer;
 6   if (checker) delete checker;
 7   if (vtab) DELETE_ONLY (vtab, Var, vsize);
 8   if (ltab) DELETE_ONLY (ltab, Link, vsize);
 9   if (ftab) DELETE_ONLY (ftab, Flags, vsize);
10   if (btab) DELETE_ONLY (btab, long, vsize);
11   if (stab) DELETE_ONLY (stab, double, vsize);
12   if (ptab) DELETE_ONLY (ptab, int, 2*vsize);
13   if (big) RELEASE_DELETE (big, Bins, 2*vsize);
14   if (vals) { vals -= vsize; DELETE_ONLY (vals, signed_char, 2*vsize); }
15   if (marks) DELETE_ONLY (marks, signed_char, vsize);
16   if (phases.saved) DELETE_ONLY (phases.saved, Phase, vsize);
17   if (phases.target) DELETE_ONLY (phases.target, Phase, vsize);
18   if (phases.best) DELETE_ONLY (phases.best, Phase, vsize);
19   if (phases.prev) DELETE_ONLY (phases.prev, Phase, vsize);
20   if (phases.min) DELETE_ONLY (phases.min, Phase, vsize);
21   if (i2e) DELETE_ONLY (i2e, int, vsize);
22   if (frozentab) DELETE_ONLY (frozentab, unsigned, vsize);
23   if (otab) reset_occs ();
24   if (ntab) reset_noccs ();
25   if (wtab) reset_watches ();
26 }
 1 void Internal::enlarge_vals (size_t new_vsize) {
 2   signed_char * new_vals;
 3   NEW_ZERO (new_vals, signed_char, 2*new_vsize);
 4   new_vals += new_vsize;
 5   if (vals) memcpy (new_vals - max_var, vals - max_var, 2*max_var + 1);
 6   vals -= vsize;
 7   DELETE_ONLY (vals, signed_char, 2*vsize);
 8   vals = new_vals;
 9 }
10 
11 void Internal::enlarge (int new_max_var) {
12   assert (!level);
13   size_t new_vsize = vsize ? 2*vsize : 1 + (size_t) new_max_var;
14   while (new_vsize <= (size_t) new_max_var) new_vsize *= 2;
15   LOG ("enlarge internal size from %ld to new size %ld", vsize, new_vsize);
16   // Ordered in the size of allocated memory (larger block first).
17   assert (!vsize || !otab);
18   if (!vsize || wtab)
19   ENLARGE_ZERO (wtab, Watches, 2*vsize, 2*new_vsize);
20   ENLARGE_ONLY (vtab, Var, vsize, new_vsize);
21   ENLARGE_ONLY (ltab, Link, vsize, new_vsize);
22   ENLARGE_ZERO (btab, long, vsize, new_vsize);
23   ENLARGE_ZERO (stab, double, vsize, new_vsize);
24   ENLARGE_ONLY (ptab, int, 2*vsize, 2*new_vsize);
25   ENLARGE_ONLY (i2e, int, vsize, new_vsize);
26   enlarge_vals (new_vsize);
27   ENLARGE_ZERO (frozentab, unsigned, vsize, new_vsize);
28   ENLARGE_ONLY (phases.saved, Phase, vsize, new_vsize);
29   ENLARGE_ZERO (phases.target, Phase, vsize, new_vsize);
30   ENLARGE_ZERO (phases.best, Phase, vsize, new_vsize);
31   ENLARGE_ZERO (phases.prev, Phase, vsize, new_vsize);
32   ENLARGE_ZERO (phases.min, Phase, vsize, new_vsize);
33   ENLARGE_ZERO (marks, signed_char, vsize, new_vsize);
34   ENLARGE_ONLY (ftab, Flags, vsize, new_vsize);
35   vsize = new_vsize;
36 }
37 
38 void Internal::init (int new_max_var) {
39   if (new_max_var <= max_var) return;
40   if (level) backtrack ();
41   LOG ("initializing %d internal variables from %d to %d",
42     new_max_var - max_var, max_var + 1, new_max_var);
43   if ((size_t) new_max_var >= vsize) enlarge (new_max_var);
44   signed_char val = opts.phase ? 1 : -1;
45   for (int i = max_var + 1; i <= new_max_var; i++)
46     phases.saved[i] = val;
47 #ifndef NDEBUG
48   for (int i = -new_max_var; i < -max_var; i++) assert (!vals[i]);
49   for (int i = max_var + 1; i <= new_max_var; i++) assert (!vals[i]);
50   for (int i = max_var + 1; i <= new_max_var; i++) assert (!frozentab[i]);
51   for (int i = max_var + 1; i <= new_max_var; i++) assert (!marks[i]);
52   for (int i = max_var + 1; i <= new_max_var; i++) assert (!btab[i]);
53 #endif
54   for (int i = 2*(max_var + 1); i <= 2*new_max_var+1; i++) ptab[i] = -1;
55   for (int i = max_var + 1; i <= new_max_var; i++) ftab[i].init ();
56   assert (!btab[0]);
57   int old_max_var = max_var;
58   max_var = new_max_var;
59   init_queue (old_max_var, new_max_var);
60   init_scores (old_max_var, new_max_var);
61   int initialized = new_max_var - old_max_var;
62   stats.vars += initialized;
63   stats.unused += initialized;
64   stats.inactive += initialized;
65   LOG ("finished initializing %d internal variables", initialized);
66 }
67 
68 void Internal::add_original_lit (int lit) {
69   assert (abs (lit) <= max_var);
70   if (lit) {
71     original.push_back (lit);
72   } else {
73     if (proof) proof->add_original_clause (original);
74     add_new_original_clause ();
75     original.clear ();
76   }
77 }
 

顺便了解一下在CaDiCal中CDCL实现过程

 1 // This is the main CDCL loop with interleaved inprocessing.
 2 
 3 int Internal::cdcl_loop_with_inprocessing () {
 4 
 5   int res = 0;
 6 
 7   START (search);
 8 
 9   if (stable) { START (stable);   report ('['); }
10   else        { START (unstable); report ('{'); }
11 
12   while (!res) {
13          if (unsat) res = 20;
14     else if (!propagate ()) analyze ();      // propagate and analyze
15     else if (iterating) iterate ();          // report learned unit
16     else if (satisfied ()) res = 10;         // found model
17     else if (terminating ()) break;          // limit hit or sync abort
18     else if (restarting ()) restart ();      // restart by backtracking
19     else if (rephasing ()) rephase ();       // reset variable phases
20     else if (reducing ()) reduce ();         // collect useless clauses
21     else if (probing ()) probe ();           // failed literal probing
22     else if (subsuming ()) subsume ();       // subsumption algorithm
23     else if (eliminating ()) elim ();        // variable elimination
24     else if (compacting ()) compact ();      // collect variables
25     else res = decide ();                    // next decision
26   }
27 
28   if (stable) { STOP (stable);   report (']'); }
29   else        { STOP (unstable); report ('}'); }
30 
31   STOP (search);
32 
33   return res;
34 }
使用while循环将CDCL主要求解过程(传播、冲突分析、重启、相位保留/选择、化简、随机局部探索、学习子句集的缩减管理等)串起来形成算法。

 

posted on 2020-04-14 16:17  海阔凭鱼跃越  阅读(114)  评论(0编辑  收藏  举报