首页 > 其他分享 >cadical代码解读02_传播函数

cadical代码解读02_传播函数

时间:2023-04-25 18:45:18浏览次数:35  
标签:02 lit const level int assert 解读 reason cadical

所在文件propagate.cpp

传播函数代码分析

  1 static Clause decision_reason_clause;
  2 static Clause * decision_reason = &decision_reason_clause;  //注意此处声明了两个静态量
  3 
  4 inline int Internal::assignment_level (int lit, Clause * reason) {
  5   assert (opts.chrono);
  6   if (!reason) return level;
  7 
  8   int res = 0;
  9 
 10   for (const auto & other : *reason) {
 11     if (other == lit) continue;
 12     assert (val (other));
 13     int tmp = var (other).level;
 14     if (tmp > res) res = tmp;
 15   }
 16   return res;
 17 }
 18 
 19 /*------------------------------------------------------------------------*/
 20 
 21 inline void Internal::search_assign (int lit, Clause * reason) {
 22 
 23   if (level) require_mode (SEARCH);
 24 
 25   const int idx = vidx (lit);
 26   assert (!vals[idx]);
 27   assert (!flags (idx).eliminated () || reason == decision_reason);
 28   Var & v = var (idx);
 29   int lit_level;
 30 
 31   if (!reason) lit_level = 0;   // unit
 32   else if (reason == decision_reason) lit_level = level, reason = 0;
 33   else if (opts.chrono) lit_level = assignment_level (lit, reason);
 34   else lit_level = level;
 35   if (!lit_level) reason = 0;
 36 
 37   v.level = lit_level;
 38   v.trail = (int) trail.size ();
 39   v.reason = reason;
 40   if (!lit_level) learn_unit_clause (lit);  // increases 'stats.fixed'
 41   const signed char tmp = sign (lit);
 42   vals[idx] = tmp;
 43   vals[-idx] = -tmp;
 44   assert (val (lit) > 0);
 45   assert (val (-lit) < 0);
 46   if (!searching_lucky_phases)
 47     phases.saved[idx] = tmp;                // phase saving during search
 48   trail.push_back (lit);
 49 #ifdef LOGGING
 50   if (!lit_level) LOG ("root-level unit assign %d @ 0", lit);
 51   else LOG (reason, "search assign %d @ %d", lit, lit_level);
 52 #endif
 53 
 54   if (watching ()) {
 55     const Watches & ws = watches (-lit);
 56     if (!ws.empty ()) {
 57       const Watch & w = ws[0];
 58       __builtin_prefetch (&w, 0, 1);
 59     }
 60   }
 61 }
 62 /*------------------------------------------------------------------------*/
 63 void Internal::assign_unit (int lit) {
 64   assert (!level);
 65   search_assign (lit, 0);
 66 }
 67 
 68 void Internal::search_assume_decision (int lit) {
 69   require_mode (SEARCH);
 70   assert (propagated == trail.size ());
 71   level++;
 72   control.push_back (Level (lit, trail.size ()));
 73   LOG ("search decide %d", lit);
 74   search_assign (lit, decision_reason);
 75 }
 76 
 77 void Internal::search_assign_driving (int lit, Clause * c) {
 78   require_mode (SEARCH);
 79   search_assign (lit, c);
 80 }
 81 /*------------------------------------------------------------------------*/
 82 bool Internal::propagate () {
 83 
 84   if (level) require_mode (SEARCH);
 85   assert (!unsat);
 86 
 87   START (propagate);
 88   //
 89   int64_t before = propagated;
 90 
 91   while (!conflict && propagated != trail.size ()) {
 92 
 93     const int lit = -trail[propagated++];
 94     LOG ("propagating %d", -lit);
 95     Watches & ws = watches (lit);
 96 
 97     const const_watch_iterator eow = ws.end ();
 98     watch_iterator j = ws.begin ();
 99     const_watch_iterator i = j;
100 
101     while (i != eow) {
102       const Watch w = *j++ = *i++;
103       const signed char b = val (w.blit);
104 
105       if (b > 0) continue;                // blocking literal satisfied
106 
107       if (w.binary ()) {
108         if (b < 0) conflict = w.clause;          // but continue ...
109         else search_assign (w.blit, w.clause);
110 
111       } else {
112 
113         if (conflict) break; // Stop if there was a binary conflict already.
114 
115         if (w.clause->garbage) { j--; continue; }
116 
117         literal_iterator lits = w.clause->begin ();
118 
119         const int other = lits[0] ^ lits[1] ^ lit;
120         const signed char u = val (other); // value of the other watch
121 
122         if (u > 0) j[-1].blit = other; // satisfied, just replace blit
123         else {
124           const int size = w.clause->size;
125           const literal_iterator middle = lits + w.clause->pos;
126           const const_literal_iterator end = lits + size;
127           literal_iterator k = middle;
128 
129           // Find replacement watch 'r' at position 'k' with value 'v'.
130 
131           int r = 0;
132           signed char v = -1;
133 
134           while (k != end && (v = val (r = *k)) < 0)
135             k++;
136 
137           if (v < 0) {  // need second search starting at the head?
138             k = lits + 2;
139             assert (w.clause->pos <= size);
140             while (k != middle && (v = val (r = *k)) < 0)
141               k++;
142           }
143 
144           w.clause->pos = k - lits;  // always save position
145 
146           assert (lits + 2 <= k), assert (k <= w.clause->end ());
147 
148           if (v > 0) {
149             j[-1].blit = r;
150 
151           } else if (!v) {
152 
153             // Found new unassigned replacement literal to be watched.
154 
155             LOG (w.clause, "unwatch %d in", lit);
156 
157             lits[0] = other;
158             lits[1] = r;
159             *k = lit;
160 
161             watch_literal (r, lit, w.clause);
162 
163             j--;  // Drop this watch from the watch list of 'lit'.
164 
165           } else if (!u) {
166 
167             assert (v < 0);
168            
169             search_assign (other, w.clause);
170 
171             if (opts.chrono > 1) {
172 
173               const int other_level = var (other).level;
174 
175               if (other_level > var (lit).level) {
176 
177                 assert (size > 2);
178 
179                 int pos, s = 0;
180 
181                 for (pos = 2; pos < size; pos++)
182                   if (var (s = lits[pos]).level == other_level)
183                     break;
184 
185                 assert (s);
186                 assert (pos < size);
187 
188                 LOG (w.clause, "unwatch %d in", lit);
189                 lits[pos] = lit;
190                 lits[0] = other;
191                 lits[1] = s;
192                 watch_literal (s, other, w.clause);
193 
194                 j--;  // Drop this watch from the watch list of 'lit'.
195               }
196             }
197           } else {
198 
199             assert (u < 0);
200             assert (v < 0);
201 
202             conflict = w.clause;
203             break;
204           }
205         }
206       }
207     }
208 
209     if (j != i) {
210 
211       while (i != eow)
212         *j++ = *i++;
213 
214       ws.resize (j - ws.begin ());
215     }
216   }
217 
218   if (searching_lucky_phases) {
219 
220     if (conflict)
221       LOG (conflict, "ignoring lucky conflict");
222 
223   } else {
224 
225     stats.propagations.search += propagated - before;
226 
227     if (!conflict) no_conflict_until = propagated;
228     else {
229       if (stable) stats.stabconflicts++;
230       stats.conflicts++;
231       LOG (conflict, "conflict");
232       no_conflict_until = control[level].trail;
233     }
234   }
235 
236   STOP (propagate);
237   return !conflict;
238 }

 

标签:02,lit,const,level,int,assert,解读,reason,cadical
From: https://www.cnblogs.com/yuweng1689/p/17353523.html

相关文章

  • 2022CSP游记
    目录CSP-J20227:458:158:278:389:129:2310:3411:57中午CSP-S20222:274:156:12估分普及提高自查出分废物鸭子菜菜菜CSP-J2022废了7:45跟随校车到了考场,纪中考点不给矿泉水可还行老朋友都见到了LJHDZRLAFZWTWTCZHWYWJ....WTC已经是ISIJ的金牌了,当年我还跟他是一个......
  • 山东省集 2023.4.24 HeRen 场 T2
    简要题意数轴上有\(n\)个点,给定其坐标\(x_i\)。给定\(d\),你可以将任意多个点的坐标增加\(2d\)。给定\(a,b\),接下来你可以放置若干个区间在数轴上,设某个区间\([l,r]\),其代价是\(a+b(r-l)\)。所有点都要被你放置的区间覆盖,求最小代价。数据范围:\(1\len,d,x_i\le......
  • 2023年4月25日周二
    计划了解调试功能,mock功能如何实现的知道接口怎么回事,尝试或明白一个接口怎么写精简代码学习angular框架回顾上一周的博客接口中的请求头是怎么回事执行08点59分  查重09点07分  完全重头跑一次代码09点34分  回顾上一周的博客10点02分  跑代码,修改界......
  • 2021牛客OI赛前集训营-提高组(第二场)第三题 树数树题解
    题目描述牛牛有一棵\(n\)个点的有根树,根为\(1\)。我们称一个长度为\(m\)的序列\(a\)是好的,当且仅当:\(\foralli\in(1,m]\),\(a_i\)为\(a_{i−1}\)的祖先或\(a_{i−1}\)是\(ai\)的祖先\(\forall1\leqi\ltj\leqm,a_i\neqa_j\)你需要帮助牛牛求出最长的......
  • 2021牛客OI赛前集训营-提高组(第三场) 第二题 交替 题解与结论证明
    题目描述一个长度为\(n\)的数组\(A\),每秒都会变成一个长度为\(n−1\)新数组\(A'\),其变化规则如下:若当前数组\(A\)的长度\(n\)为偶数,则对于新数组\(A'\)的每一个位置\(i(1≤i<n)\)来说,\(A'[i]=A[i]+A[i+1]\)若当前数组\(A\)的长度\(n\)为奇数,则对于......
  • 代码随想录算法训练营第六天 | 242.有效的字母异位词 、349. 两个数组的交集 、 202.
    ......
  • 苹果Mac电脑安装AutoCAD 2024卡死无响应解决方法
    期待已久的AutoCAD2024已经更新了,许多朋友第一时间卸载电脑上的AutoCAD2023,转手下载了最新版的AutoCAD2024,但是安装的时候发现双击包内的InstallAutodeskAutoCAD2024 安装程序后总是会出现程序卡死无响应的情况,不管是重启电脑,还是重新从官网下载安装包都不行。AutoCAD2024......
  • FTDT2020 安装
    参考视频:Nestor_呐等的个人空间_哔哩哔哩_bilibili从百度网盘下载解压:1解压_SolidSQUAD_,复制ANSYSInc文件夹到C:\ProgramFiles\2解压Ansys.Lumerical.2020.R2.Win64.iso,双击LumericalInstaller.exe运行安装,点击install3安装完成,退出向导,不要启动程序4_将SolidSQUAD_,文件L......
  • 【SD集训】20230425 T2 差(difference) 题解 CF1500F 【Cupboards Jumps】
    大家可以猜猜看为什么有两个标题,因为这个原因本文就不设密码了,被He_ren的原题创到了。吐槽一下,He_ren甚至出原题还用脚造数据,虽然数据确实比较难造。不过那两个\(O(n^2)\)老哥好像都没最后将所有数调整成非负,遗憾20。有人场切*3500却没过签到题,我不说是谁。题目描述......
  • 02-2 空气动力学基础:动量、热量、质量传递的比拟,球体在大空间的传质过程
    比拟对照三种传递之间在数学上有着很大的相似,不仅有着外在的相似,而是有着内在的相似。分子运动扩散与湍流扩散分子运动扩散其中l为分子平均自由程,w为分子平均运动速度湍流扩散其中l为湍流自由程,w'为脉动速度。因此经常将流场单独研究,而将温度场和浓度场放在一起研究。......