cadical 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +26 -0
  3. data/README.md +101 -0
  4. data/ext/cadical/cadical/LICENSE +28 -0
  5. data/ext/cadical/cadical/README.md +65 -0
  6. data/ext/cadical/cadical/VERSION +1 -0
  7. data/ext/cadical/cadical/src/analyze.cpp +1360 -0
  8. data/ext/cadical/cadical/src/arena.cpp +30 -0
  9. data/ext/cadical/cadical/src/arena.hpp +105 -0
  10. data/ext/cadical/cadical/src/assume.cpp +616 -0
  11. data/ext/cadical/cadical/src/averages.cpp +34 -0
  12. data/ext/cadical/cadical/src/averages.hpp +37 -0
  13. data/ext/cadical/cadical/src/backbone.cpp +631 -0
  14. data/ext/cadical/cadical/src/backtrack.cpp +177 -0
  15. data/ext/cadical/cadical/src/backward.cpp +231 -0
  16. data/ext/cadical/cadical/src/bins.cpp +22 -0
  17. data/ext/cadical/cadical/src/bins.hpp +22 -0
  18. data/ext/cadical/cadical/src/block.cpp +824 -0
  19. data/ext/cadical/cadical/src/block.hpp +37 -0
  20. data/ext/cadical/cadical/src/cadical.cpp +1026 -0
  21. data/ext/cadical/cadical/src/cadical.hpp +1419 -0
  22. data/ext/cadical/cadical/src/ccadical.cpp +208 -0
  23. data/ext/cadical/cadical/src/ccadical.h +74 -0
  24. data/ext/cadical/cadical/src/checker.cpp +649 -0
  25. data/ext/cadical/cadical/src/checker.hpp +173 -0
  26. data/ext/cadical/cadical/src/clause.cpp +689 -0
  27. data/ext/cadical/cadical/src/clause.hpp +190 -0
  28. data/ext/cadical/cadical/src/collect.cpp +545 -0
  29. data/ext/cadical/cadical/src/compact.cpp +550 -0
  30. data/ext/cadical/cadical/src/condition.cpp +940 -0
  31. data/ext/cadical/cadical/src/config.cpp +101 -0
  32. data/ext/cadical/cadical/src/config.hpp +20 -0
  33. data/ext/cadical/cadical/src/congruence.cpp +7880 -0
  34. data/ext/cadical/cadical/src/congruence.hpp +757 -0
  35. data/ext/cadical/cadical/src/constrain.cpp +64 -0
  36. data/ext/cadical/cadical/src/contract.cpp +27 -0
  37. data/ext/cadical/cadical/src/contract.hpp +139 -0
  38. data/ext/cadical/cadical/src/cover.cpp +704 -0
  39. data/ext/cadical/cadical/src/cover.hpp +34 -0
  40. data/ext/cadical/cadical/src/decide.cpp +347 -0
  41. data/ext/cadical/cadical/src/decompose.cpp +738 -0
  42. data/ext/cadical/cadical/src/decompose.hpp +23 -0
  43. data/ext/cadical/cadical/src/deduplicate.cpp +275 -0
  44. data/ext/cadical/cadical/src/definition.cpp +283 -0
  45. data/ext/cadical/cadical/src/delay.hpp +38 -0
  46. data/ext/cadical/cadical/src/drattracer.cpp +153 -0
  47. data/ext/cadical/cadical/src/drattracer.hpp +55 -0
  48. data/ext/cadical/cadical/src/elim.cpp +1171 -0
  49. data/ext/cadical/cadical/src/elim.hpp +53 -0
  50. data/ext/cadical/cadical/src/elimfast.cpp +570 -0
  51. data/ext/cadical/cadical/src/ema.cpp +95 -0
  52. data/ext/cadical/cadical/src/ema.hpp +68 -0
  53. data/ext/cadical/cadical/src/extend.cpp +289 -0
  54. data/ext/cadical/cadical/src/external.cpp +1034 -0
  55. data/ext/cadical/cadical/src/external.hpp +487 -0
  56. data/ext/cadical/cadical/src/external_propagate.cpp +1316 -0
  57. data/ext/cadical/cadical/src/factor.cpp +1011 -0
  58. data/ext/cadical/cadical/src/factor.hpp +54 -0
  59. data/ext/cadical/cadical/src/file.cpp +506 -0
  60. data/ext/cadical/cadical/src/file.hpp +210 -0
  61. data/ext/cadical/cadical/src/flags.cpp +135 -0
  62. data/ext/cadical/cadical/src/flags.hpp +93 -0
  63. data/ext/cadical/cadical/src/flip.cpp +269 -0
  64. data/ext/cadical/cadical/src/format.cpp +89 -0
  65. data/ext/cadical/cadical/src/format.hpp +36 -0
  66. data/ext/cadical/cadical/src/frattracer.cpp +277 -0
  67. data/ext/cadical/cadical/src/frattracer.hpp +67 -0
  68. data/ext/cadical/cadical/src/gates.cpp +766 -0
  69. data/ext/cadical/cadical/src/heap.hpp +212 -0
  70. data/ext/cadical/cadical/src/idruptracer.cpp +566 -0
  71. data/ext/cadical/cadical/src/idruptracer.hpp +112 -0
  72. data/ext/cadical/cadical/src/instantiate.cpp +365 -0
  73. data/ext/cadical/cadical/src/instantiate.hpp +45 -0
  74. data/ext/cadical/cadical/src/internal.cpp +1265 -0
  75. data/ext/cadical/cadical/src/internal.hpp +1941 -0
  76. data/ext/cadical/cadical/src/inttypes.hpp +34 -0
  77. data/ext/cadical/cadical/src/ipasir.cpp +47 -0
  78. data/ext/cadical/cadical/src/ipasir.h +37 -0
  79. data/ext/cadical/cadical/src/kitten.c +2599 -0
  80. data/ext/cadical/cadical/src/kitten.h +97 -0
  81. data/ext/cadical/cadical/src/level.hpp +33 -0
  82. data/ext/cadical/cadical/src/lidruptracer.cpp +657 -0
  83. data/ext/cadical/cadical/src/lidruptracer.hpp +122 -0
  84. data/ext/cadical/cadical/src/limit.cpp +146 -0
  85. data/ext/cadical/cadical/src/limit.hpp +168 -0
  86. data/ext/cadical/cadical/src/logging.cpp +214 -0
  87. data/ext/cadical/cadical/src/logging.hpp +98 -0
  88. data/ext/cadical/cadical/src/lookahead.cpp +520 -0
  89. data/ext/cadical/cadical/src/lratchecker.cpp +833 -0
  90. data/ext/cadical/cadical/src/lratchecker.hpp +168 -0
  91. data/ext/cadical/cadical/src/lrattracer.cpp +200 -0
  92. data/ext/cadical/cadical/src/lrattracer.hpp +61 -0
  93. data/ext/cadical/cadical/src/lucky.cpp +506 -0
  94. data/ext/cadical/cadical/src/message.cpp +218 -0
  95. data/ext/cadical/cadical/src/message.hpp +65 -0
  96. data/ext/cadical/cadical/src/minimize.cpp +224 -0
  97. data/ext/cadical/cadical/src/mobical.cpp +5588 -0
  98. data/ext/cadical/cadical/src/occs.cpp +52 -0
  99. data/ext/cadical/cadical/src/occs.hpp +36 -0
  100. data/ext/cadical/cadical/src/options.cpp +359 -0
  101. data/ext/cadical/cadical/src/options.hpp +442 -0
  102. data/ext/cadical/cadical/src/parse.cpp +471 -0
  103. data/ext/cadical/cadical/src/parse.hpp +75 -0
  104. data/ext/cadical/cadical/src/phases.cpp +56 -0
  105. data/ext/cadical/cadical/src/phases.hpp +19 -0
  106. data/ext/cadical/cadical/src/probe.cpp +990 -0
  107. data/ext/cadical/cadical/src/profile.cpp +107 -0
  108. data/ext/cadical/cadical/src/profile.hpp +283 -0
  109. data/ext/cadical/cadical/src/proof.cpp +691 -0
  110. data/ext/cadical/cadical/src/proof.hpp +125 -0
  111. data/ext/cadical/cadical/src/propagate.cpp +584 -0
  112. data/ext/cadical/cadical/src/queue.cpp +90 -0
  113. data/ext/cadical/cadical/src/queue.hpp +74 -0
  114. data/ext/cadical/cadical/src/radix.hpp +180 -0
  115. data/ext/cadical/cadical/src/random.cpp +207 -0
  116. data/ext/cadical/cadical/src/random.h +44 -0
  117. data/ext/cadical/cadical/src/random.hpp +98 -0
  118. data/ext/cadical/cadical/src/range.hpp +125 -0
  119. data/ext/cadical/cadical/src/reap.cpp +127 -0
  120. data/ext/cadical/cadical/src/reap.hpp +28 -0
  121. data/ext/cadical/cadical/src/reduce.cpp +278 -0
  122. data/ext/cadical/cadical/src/reluctant.hpp +82 -0
  123. data/ext/cadical/cadical/src/rephase.cpp +402 -0
  124. data/ext/cadical/cadical/src/report.cpp +313 -0
  125. data/ext/cadical/cadical/src/resources.cpp +160 -0
  126. data/ext/cadical/cadical/src/resources.hpp +16 -0
  127. data/ext/cadical/cadical/src/restart.cpp +178 -0
  128. data/ext/cadical/cadical/src/restore.cpp +267 -0
  129. data/ext/cadical/cadical/src/score.cpp +51 -0
  130. data/ext/cadical/cadical/src/score.hpp +16 -0
  131. data/ext/cadical/cadical/src/shrink.cpp +507 -0
  132. data/ext/cadical/cadical/src/signal.cpp +136 -0
  133. data/ext/cadical/cadical/src/signal.hpp +33 -0
  134. data/ext/cadical/cadical/src/solution.cpp +50 -0
  135. data/ext/cadical/cadical/src/solver.cpp +1871 -0
  136. data/ext/cadical/cadical/src/stable.cpp +31 -0
  137. data/ext/cadical/cadical/src/stack.h +110 -0
  138. data/ext/cadical/cadical/src/stats.cpp +920 -0
  139. data/ext/cadical/cadical/src/stats.hpp +418 -0
  140. data/ext/cadical/cadical/src/subsume.cpp +645 -0
  141. data/ext/cadical/cadical/src/sweep.cpp +1960 -0
  142. data/ext/cadical/cadical/src/sweep.hpp +61 -0
  143. data/ext/cadical/cadical/src/terminal.cpp +38 -0
  144. data/ext/cadical/cadical/src/terminal.hpp +96 -0
  145. data/ext/cadical/cadical/src/ternary.cpp +450 -0
  146. data/ext/cadical/cadical/src/testing.hpp +24 -0
  147. data/ext/cadical/cadical/src/tier.cpp +189 -0
  148. data/ext/cadical/cadical/src/tracer.hpp +186 -0
  149. data/ext/cadical/cadical/src/transred.cpp +253 -0
  150. data/ext/cadical/cadical/src/unstable.cpp +29 -0
  151. data/ext/cadical/cadical/src/util.cpp +129 -0
  152. data/ext/cadical/cadical/src/util.hpp +181 -0
  153. data/ext/cadical/cadical/src/var.cpp +39 -0
  154. data/ext/cadical/cadical/src/var.hpp +22 -0
  155. data/ext/cadical/cadical/src/veripbtracer.cpp +427 -0
  156. data/ext/cadical/cadical/src/veripbtracer.hpp +106 -0
  157. data/ext/cadical/cadical/src/version.cpp +107 -0
  158. data/ext/cadical/cadical/src/version.hpp +13 -0
  159. data/ext/cadical/cadical/src/vivify.cpp +1893 -0
  160. data/ext/cadical/cadical/src/vivify.hpp +50 -0
  161. data/ext/cadical/cadical/src/walk.cpp +1088 -0
  162. data/ext/cadical/cadical/src/walk.hpp +91 -0
  163. data/ext/cadical/cadical/src/walk_full_occs.cpp +966 -0
  164. data/ext/cadical/cadical/src/warmup.cpp +403 -0
  165. data/ext/cadical/cadical/src/watch.cpp +126 -0
  166. data/ext/cadical/cadical/src/watch.hpp +77 -0
  167. data/ext/cadical/cadical_ext.c +778 -0
  168. data/ext/cadical/extconf.rb +26 -0
  169. data/lib/cadical/version.rb +3 -0
  170. data/lib/cadical.rb +12 -0
  171. metadata +218 -0
@@ -0,0 +1,631 @@
1
+ #include "internal.hpp"
2
+ #include "message.hpp"
3
+ #include "util.hpp"
4
+
5
+ namespace CaDiCaL {
6
+
7
+ inline void Internal::backbone_lrat_for_units (int lit, Clause *reason) {
8
+ if (!lrat)
9
+ return;
10
+ if (level)
11
+ return; // not decision level 0
12
+ LOG ("backbone building chain for units");
13
+ assert (lrat_chain.empty ());
14
+ assert (reason);
15
+ for (auto &reason_lit : *reason) {
16
+ if (lit == reason_lit)
17
+ continue;
18
+ assert (val (reason_lit));
19
+ if (!val (reason_lit))
20
+ continue;
21
+ const int signed_reason_lit = val (reason_lit) * reason_lit;
22
+ int64_t id = unit_id (signed_reason_lit);
23
+ lrat_chain.push_back (id);
24
+ }
25
+ lrat_chain.push_back (reason->id);
26
+ }
27
+
28
+ inline bool Internal::backbone_propagate (int64_t &ticks) {
29
+ require_mode (BACKBONE);
30
+ assert (!unsat);
31
+ START (propagate);
32
+ int64_t before = propagated2 = propagated;
33
+ for (;;) {
34
+ if (propagated2 != trail.size ()) {
35
+ const int lit = -trail[propagated2++];
36
+ LOG ("backbone propagating %d over binary clauses", -lit);
37
+ Watches &ws = watches (lit);
38
+ ticks +=
39
+ 1 + cache_lines (ws.size (), sizeof (const_watch_iterator *));
40
+ for (const auto &w : ws) {
41
+ if (!w.binary ())
42
+ continue;
43
+ const signed char b = val (w.blit);
44
+ if (b > 0)
45
+ continue;
46
+ if (b < 0)
47
+ conflict = w.clause; // but continue
48
+ else {
49
+ ticks++;
50
+ build_chain_for_units (w.blit, w.clause, 0);
51
+ backbone_assign (w.blit, w.clause);
52
+ lrat_chain.clear ();
53
+ }
54
+ }
55
+ } else if (!conflict && propagated != trail.size ()) {
56
+ const int lit = -trail[propagated++];
57
+ LOG ("backbone propagating %d over large clauses", -lit);
58
+ Watches &ws = watches (lit);
59
+ const const_watch_iterator eow = ws.end ();
60
+ const_watch_iterator i = ws.begin ();
61
+ ticks += 1 + cache_lines (ws.size (), sizeof (*i));
62
+ watch_iterator j = ws.begin ();
63
+ while (i != eow) {
64
+ const Watch w = *j++ = *i++;
65
+ if (w.binary ())
66
+ continue;
67
+ if (val (w.blit) > 0)
68
+ continue;
69
+ ticks++;
70
+ if (w.clause->garbage) {
71
+ j--;
72
+ continue;
73
+ }
74
+ literal_iterator lits = w.clause->begin ();
75
+ const int other = lits[0] ^ lits[1] ^ lit;
76
+ const signed char u = val (other);
77
+ if (u > 0)
78
+ j[-1].blit = other;
79
+ else {
80
+ const int size = w.clause->size;
81
+ const const_literal_iterator end = lits + size;
82
+ const literal_iterator middle = lits + w.clause->pos;
83
+ literal_iterator k = middle;
84
+ signed char v = -1;
85
+ int r = 0;
86
+ while (k != end && (v = val (r = *k)) < 0)
87
+ k++;
88
+ if (v < 0) {
89
+ k = lits + 2;
90
+ assert (w.clause->pos <= size);
91
+ while (k != middle && (v = val (r = *k)) < 0)
92
+ k++;
93
+ }
94
+ w.clause->pos = k - lits;
95
+ assert (lits + 2 <= k), assert (k <= w.clause->end ());
96
+ if (v > 0)
97
+ j[-1].blit = r;
98
+ else if (!v) {
99
+ LOG (w.clause, "unwatch %d in", r);
100
+ lits[0] = other;
101
+ lits[1] = r;
102
+ *k = lit;
103
+ ticks++;
104
+ watch_literal (r, lit, w.clause);
105
+ j--;
106
+ } else if (!u) {
107
+ ticks++;
108
+ assert (v < 0);
109
+ build_chain_for_units (other, w.clause, 0);
110
+ backbone_assign_any (other, w.clause);
111
+ lrat_chain.clear ();
112
+ } else {
113
+ if (w.clause == ignore) {
114
+ LOG ("ignoring conflict due to clause to vivify");
115
+ continue;
116
+ }
117
+ assert (u < 0);
118
+ assert (v < 0);
119
+ conflict = w.clause;
120
+ break;
121
+ }
122
+ }
123
+ }
124
+ if (j != i) {
125
+ while (i != eow)
126
+ *j++ = *i++;
127
+ ws.resize (j - ws.begin ());
128
+ }
129
+ } else
130
+ break;
131
+ }
132
+ int64_t delta = propagated2 - before;
133
+ stats.propagations.backbone += delta;
134
+ if (conflict)
135
+ LOG (conflict, "conflict");
136
+ STOP (propagate);
137
+ return !conflict;
138
+ }
139
+
140
+ inline void Internal::backbone_propagate2 (int64_t &ticks) {
141
+ require_mode (BACKBONE);
142
+ assert (propagated2 <= trail.size ());
143
+ int64_t before = propagated2;
144
+ while (propagated2 != trail.size ()) {
145
+ const int lit = -trail[propagated2++];
146
+ LOG ("probe propagating %d over binary clauses", -lit);
147
+ Watches &ws = watches (lit);
148
+ ticks += 1 + cache_lines (ws.size (), sizeof (const_watch_iterator *));
149
+ for (const auto &w : ws) {
150
+ if (!w.binary ())
151
+ break;
152
+ const signed char b = val (w.blit);
153
+ if (b > 0)
154
+ continue;
155
+ ticks++;
156
+ if (b < 0) {
157
+ conflict = w.clause; // no need to continue
158
+ break;
159
+ } else {
160
+ assert (lrat_chain.empty ());
161
+ backbone_lrat_for_units (w.blit, w.clause);
162
+ backbone_assign (w.blit, w.clause);
163
+ lrat_chain.clear ();
164
+ }
165
+ }
166
+ }
167
+
168
+ int64_t delta = propagated2 - before;
169
+ stats.propagations.backbone += delta;
170
+ }
171
+
172
+ void Internal::schedule_backbone_cands (std::vector<int> &candidates) {
173
+
174
+ unsigned not_rescheduled = 0;
175
+ for (auto v : vars) {
176
+ const Flags f = flags (v);
177
+ if (!f.active ())
178
+ continue;
179
+ if (f.backbone0) {
180
+ LOG ("scheduling backbone literal candidate %s", LOGLIT (v));
181
+ candidates.push_back (v);
182
+ } else
183
+ ++not_rescheduled;
184
+ if (f.backbone1) {
185
+ LOG ("scheduling backbone literal candidate %s", LOGLIT (-v));
186
+ candidates.push_back (-v);
187
+ } else
188
+ ++not_rescheduled;
189
+ }
190
+
191
+ if (not_rescheduled) {
192
+ for (auto v : vars) {
193
+ const Flags f = flags (v);
194
+ if (!f.active ())
195
+ continue;
196
+ if (!f.backbone0) {
197
+ LOG ("scheduling backbone literal candidate %s", LOGLIT (v));
198
+ candidates.push_back (v);
199
+ }
200
+ if (!f.backbone1) {
201
+ LOG ("scheduling backbone literal candidate %s", LOGLIT (-v));
202
+ candidates.push_back (-v);
203
+ }
204
+ }
205
+ }
206
+ assert (candidates.size () <= 2 * (size_t) max_var);
207
+
208
+ VERBOSE (3,
209
+ "backbone schedule %zu backbone candidates in total %f "
210
+ "(rescheduled: %f%%)",
211
+ candidates.size (), percent (candidates.size (), 2 * max_var),
212
+ percent (not_rescheduled, 2 * max_var));
213
+ }
214
+
215
+ int Internal::backbone_analyze (Clause *, int64_t &ticks) {
216
+ assert (conflict);
217
+ assert (conflict->size == 2);
218
+ analyzed.push_back (std::abs (conflict->literals[0]));
219
+ flags (conflict->literals[0]).seen = true;
220
+ analyzed.push_back (std::abs (conflict->literals[1]));
221
+ flags (conflict->literals[1]).seen = true;
222
+ LOG (conflict, "analyzing conflict");
223
+ if (lrat)
224
+ lrat_chain.push_back (conflict->id);
225
+ conflict = nullptr;
226
+
227
+ for (auto t = trail.rbegin ();;) {
228
+ assert (t < trail.rend ());
229
+ int lit = *t++;
230
+ LOG ("analyzing %s", LOGLIT (lit));
231
+ if (!flags (lit).seen)
232
+ continue;
233
+ Clause *reason = var (lit).reason;
234
+ LOG (reason, "resolving with reason of %s", LOGLIT (lit));
235
+ assert (reason), assert (reason != decision_reason);
236
+ ++ticks;
237
+ const int other = reason->literals[0] ^ reason->literals[1] ^ lit;
238
+ Flags &f_o = flags (other);
239
+ if (lrat)
240
+ lrat_chain.push_back (reason->id);
241
+ if (!f_o.seen) {
242
+ f_o.seen = true;
243
+ analyzed.push_back (other);
244
+ } else {
245
+ LOG ("backbone UIP %s", LOGLIT (other));
246
+ for (auto lit : analyzed)
247
+ flags (lit).seen = false;
248
+ analyzed.clear ();
249
+ if (lrat)
250
+ reverse (begin (lrat_chain), end (lrat_chain));
251
+ return other;
252
+ }
253
+ }
254
+ }
255
+
256
+ inline void Internal::backbone_unit_reassign (int lit) {
257
+ #ifdef LOGGING
258
+ LOG ("reassigning %s to level 0", LOGLIT (lit));
259
+ assert (val (lit) > 0);
260
+ assert (val (-lit) < 0);
261
+ #else
262
+ (void) lit;
263
+ #endif
264
+ return;
265
+ }
266
+
267
+ inline void Internal::backbone_unit_assign (int lit) {
268
+ LOG ("assigning %s to level 0", LOGLIT (lit));
269
+ require_mode (BACKBONE);
270
+ const int idx = vidx (lit);
271
+ assert (!vals[idx]);
272
+ Var &v = var (idx);
273
+ v.level = 0; // required to reuse decisions
274
+ v.trail = (int) trail.size (); // used in 'vivify_better_watch'
275
+ assert ((int) num_assigned < max_var);
276
+ num_assigned++;
277
+ v.reason = 0; // for conflict analysis
278
+ learn_unit_clause (lit);
279
+ lrat_chain.clear ();
280
+ const signed char tmp = sign (lit);
281
+ vals[idx] = tmp;
282
+ vals[-idx] = -tmp;
283
+ assert (val (lit) > 0);
284
+ assert (val (-lit) < 0);
285
+ trail.push_back (lit);
286
+ LOG ("backbone assign %d to level 0", lit);
287
+ }
288
+
289
+ inline void Internal::backbone_assign_any (int lit, Clause *reason) {
290
+ require_mode (BACKBONE);
291
+ const int idx = vidx (lit);
292
+ assert (!vals[idx]);
293
+ assert (!flags (idx).eliminated () || !reason);
294
+ assert (reason == decision_reason || !reason || reason->size >= 2);
295
+ Var &v = var (idx);
296
+ v.level = level; // required to reuse decisions
297
+ v.trail = (int) trail.size (); // used in 'vivify_better_watch'
298
+ assert ((int) num_assigned < max_var);
299
+ num_assigned++;
300
+ v.reason = level ? reason : 0; // for conflict analysis
301
+ if (!level)
302
+ learn_unit_clause (lit);
303
+ const signed char tmp = sign (lit);
304
+ vals[idx] = tmp;
305
+ vals[-idx] = -tmp;
306
+ assert (val (lit) > 0);
307
+ assert (val (-lit) < 0);
308
+ trail.push_back (lit);
309
+ LOG (reason, "backbone assign %d", lit);
310
+ }
311
+
312
+ inline void Internal::backbone_assign (int lit, Clause *reason) {
313
+ require_mode (BACKBONE);
314
+ const int idx = vidx (lit);
315
+ assert (!vals[idx]);
316
+ assert (!flags (idx).eliminated () || !reason);
317
+ assert (reason == decision_reason || !reason || reason->size == 2);
318
+ Var &v = var (idx);
319
+ v.level = level; // required to reuse decisions
320
+ v.trail = (int) trail.size (); // used in 'vivify_better_watch'
321
+ assert ((int) num_assigned < max_var);
322
+ num_assigned++;
323
+ v.reason = level ? reason : 0; // for conflict analysis
324
+ if (!level)
325
+ learn_unit_clause (lit);
326
+ const signed char tmp = sign (lit);
327
+ vals[idx] = tmp;
328
+ vals[-idx] = -tmp;
329
+ assert (val (lit) > 0);
330
+ assert (val (-lit) < 0);
331
+ trail.push_back (lit);
332
+ LOG (reason, "backbone assign %d", lit);
333
+ }
334
+
335
+ void Internal::backbone_decision (int lit) {
336
+ require_mode (BACKBONE);
337
+ assert (propagated2 == trail.size ());
338
+ new_trail_level (lit);
339
+ notify_decision ();
340
+ LOG ("search decide %d", lit);
341
+ backbone_assign (lit, decision_reason);
342
+ }
343
+
344
+ unsigned Internal::compute_backbone_round (std::vector<int> &candidates,
345
+ std::vector<int> &units,
346
+ const int64_t ticks_limit,
347
+ int64_t &ticks,
348
+ unsigned inconsistent) {
349
+ assert (!conflict);
350
+ auto p = begin (candidates);
351
+ auto q = p;
352
+ const auto end = std::end (candidates);
353
+ size_t failed = 0;
354
+ ++stats.backbone.rounds;
355
+
356
+ LOG (candidates, "candidates: ");
357
+ ticks += 1 + cache_lines (candidates.size (),
358
+ sizeof (std::vector<int>::iterator *));
359
+ while (p != end) {
360
+ assert (p < end);
361
+ assert (q <= p);
362
+ assert (!conflict);
363
+ const int probe = (*q = *p);
364
+ ++stats.backbone.probes;
365
+
366
+ ++p, ++q;
367
+ const signed char v = val (probe);
368
+ if (v > 0) {
369
+ q--;
370
+ LOG ("removing satisfied backbone probe %s", LOGLIT (probe));
371
+ if (probe < 0)
372
+ flags (probe).backbone1 = false;
373
+ else
374
+ flags (probe).backbone0 = false;
375
+ continue;
376
+ }
377
+
378
+ if (v < 0) {
379
+ if (var (probe).level)
380
+ LOG ("skipping falsified backbone probe %s", LOGLIT (probe));
381
+ else {
382
+ LOG ("removing root-level falsified backbone probe %s",
383
+ LOGLIT (probe));
384
+ q--;
385
+ }
386
+ continue;
387
+ }
388
+ if (ticks >= ticks_limit)
389
+ break;
390
+ backbone_decision (probe);
391
+ backbone_propagate2 (ticks);
392
+ if (!conflict) {
393
+ LOG (candidates,
394
+ "propagating backbone probe %s successful; candidates:",
395
+ LOGLIT (probe));
396
+ continue;
397
+ }
398
+
399
+ ++failed;
400
+ ++stats.backbone.units;
401
+ int uip = backbone_analyze (conflict, ticks);
402
+ backtrack_without_updating_phases (level - 1);
403
+ backbone_unit_assign (uip);
404
+ ++stats.units;
405
+ assert (!conflict);
406
+ if (external->learner)
407
+ external->export_learned_unit_clause (uip);
408
+
409
+ backbone_propagate2 (ticks);
410
+ if (conflict) {
411
+ LOG ("propagating backbone forced %s failed", LOGLIT (uip));
412
+ inconsistent = uip;
413
+ // we have to give up on the current conflict
414
+ conflict = nullptr;
415
+ break;
416
+ }
417
+ units.push_back (uip);
418
+ }
419
+ while (p != end)
420
+ *q++ = *p++;
421
+ assert (q <= end);
422
+ candidates.resize (q - begin (candidates));
423
+ LOG (candidates, "candidates: ");
424
+
425
+ if (!inconsistent) {
426
+ LOG ("flushing satisfied probe candidates");
427
+ auto p = begin (candidates);
428
+ auto q = p;
429
+ const auto end = std::end (candidates);
430
+
431
+ while (p != end) {
432
+ const int probe = (*q++ = *p++);
433
+ const signed char v = val (probe);
434
+ if (v > 0) {
435
+ q--;
436
+ LOG ("removing satisfied backbone probe %s", LOGLIT (probe));
437
+ if (probe < 0)
438
+ flags (probe).backbone1 = false;
439
+ else
440
+ flags (probe).backbone0 = false;
441
+ continue;
442
+ }
443
+
444
+ if (v < 0) {
445
+ LOG ("keeping falsified probe %s", LOGLIT (probe));
446
+ continue;
447
+ }
448
+ assert (!v);
449
+ LOG ("keeping unassigned probe %s", LOGLIT (probe));
450
+ }
451
+ candidates.resize (q - begin (candidates));
452
+ }
453
+ LOG (candidates, "candidates after !inconsistent: ");
454
+ if (level)
455
+ backtrack_without_updating_phases ();
456
+ if (!inconsistent && !units.empty ()) {
457
+ for (auto l : units) {
458
+ backbone_unit_reassign (l);
459
+ }
460
+ units.clear ();
461
+ if (!backbone_propagate (ticks)) {
462
+ LOG (conflict, "final repropagation yielded conflict");
463
+ learn_empty_clause ();
464
+ }
465
+ } else {
466
+ if (!backbone_propagate (ticks)) {
467
+ learn_empty_clause ();
468
+ }
469
+ }
470
+ LOG (candidates, "candidates end of loop: ");
471
+
472
+ LOG (candidates, "candidates end of backbone_round: ");
473
+ return failed;
474
+ }
475
+
476
+ void Internal::keep_backbone_candidates (
477
+ const std::vector<int> &candidates) {
478
+ size_t remain = 0;
479
+ size_t prioritized = 0;
480
+ for (auto v : candidates) {
481
+ const Flags &f = flags (v);
482
+ if (!f.active ())
483
+ continue;
484
+ ++remain;
485
+ if (v < 0)
486
+ prioritized += f.backbone1;
487
+ else
488
+ prioritized += f.backbone0;
489
+ }
490
+ assert (prioritized <= remain);
491
+ if (!remain) {
492
+ #ifndef NDEBUG
493
+ for (auto v : candidates) {
494
+ const Flags &f = flags (v);
495
+ if (!f.active ())
496
+ continue;
497
+ assert (!f.backbone0);
498
+ assert (!f.backbone1);
499
+ }
500
+ #endif
501
+ return;
502
+ }
503
+ if (prioritized == remain) {
504
+ LOG ("keeping all remaining backbones");
505
+ } else if (!prioritized) {
506
+ for (auto v : candidates) {
507
+ Flags &f = flags (v);
508
+ if (!f.active ())
509
+ continue;
510
+ ++remain;
511
+ if (v < 0) {
512
+ assert (!f.backbone1);
513
+ f.backbone1 = true;
514
+ } else {
515
+ assert (!f.backbone0);
516
+ f.backbone0 = true;
517
+ }
518
+ }
519
+ }
520
+ }
521
+
522
+ unsigned Internal::compute_backbone () {
523
+ size_t failed = 0;
524
+
525
+ int64_t ticks = 0;
526
+ backbone_propagate2 (ticks);
527
+ assert (!conflict);
528
+
529
+ std::vector<int> candidates, units;
530
+ unsigned inconsistent = 0;
531
+ assert (!conflict);
532
+
533
+ ++stats.backbone.phases;
534
+ schedule_backbone_cands (candidates);
535
+
536
+ const size_t max_rounds = opts.backbonemaxrounds;
537
+ size_t round_limit = opts.backbonerounds;
538
+ round_limit *= stats.backbone.phases;
539
+ if (round_limit > max_rounds)
540
+ round_limit = max_rounds;
541
+
542
+ SET_EFFORT_LIMIT (totalticks, backbone, false);
543
+ int64_t ticks_limit = totalticks - stats.ticks.backbone;
544
+ PHASE ("backbone", stats.backbone.phases,
545
+ "backbone limit of %" PRId64 " ticks", ticks_limit);
546
+ size_t rounds = 0;
547
+ for (; ++rounds;) {
548
+ if (rounds >= round_limit) {
549
+ LOG ("backround round limit %zu rounds", rounds);
550
+ break;
551
+ }
552
+ if (ticks >= ticks_limit) {
553
+ LOG ("backround round limit %" PRIu64 " ticks", ticks);
554
+ break;
555
+ }
556
+ VERBOSE (3,
557
+ "backbone round %zu of %zu with %" PRId64
558
+ " ticks (%f %% done) with %zu failed so far",
559
+ rounds, max_rounds, ticks, percent (ticks, ticks_limit),
560
+ failed);
561
+ size_t new_failed = compute_backbone_round (
562
+ candidates, units, ticks_limit, ticks, inconsistent);
563
+ failed += new_failed;
564
+ if (inconsistent)
565
+ break;
566
+ if (candidates.empty ())
567
+ break;
568
+ if (unsat)
569
+ break;
570
+ }
571
+
572
+ if (inconsistent && !unsat) {
573
+ LOG ("using forced unit %s by repropagating at level 0",
574
+ LOGLIT (inconsistent));
575
+ backtrack_without_updating_phases ();
576
+ propagate ();
577
+ learn_empty_clause ();
578
+ }
579
+ if (unsat) {
580
+ PHASE ("backbone", stats.backbone.phases,
581
+ "inconsistent binary clauses");
582
+ } else {
583
+ PHASE ("backbone", stats.backbone.phases,
584
+ "found %zu backbone literals %zu round in %" PRId64 " ticks",
585
+ failed, rounds, ticks);
586
+ }
587
+
588
+ keep_backbone_candidates (candidates);
589
+ if (level) {
590
+ backtrack_without_updating_phases ();
591
+ if (!backbone_propagate (ticks)) {
592
+ learn_empty_clause ();
593
+ }
594
+ }
595
+ stats.ticks.backbone += ticks;
596
+ return failed;
597
+ }
598
+
599
+ void Internal::binary_clauses_backbone () {
600
+ if (unsat)
601
+ return;
602
+ if (!opts.backbone)
603
+ return;
604
+ if (level)
605
+ backtrack_without_updating_phases ();
606
+ propagated2 = 0; // TODO: why?
607
+ if (!propagate ()) {
608
+ LOG ("propagation after connecting watches in inconsistency");
609
+ learn_empty_clause ();
610
+ return;
611
+ }
612
+
613
+ for (auto lit : lits) {
614
+ Watches &w = watches (lit);
615
+ std::stable_partition (begin (w), end (w),
616
+ [] (Watch w) { return w.binary (); });
617
+ }
618
+ assert (propagated2 <= trail.size ());
619
+ private_steps = true;
620
+
621
+ assert (watching ());
622
+ START_SIMPLIFIER (backbone, BACKBONE);
623
+ int failed = compute_backbone ();
624
+ assert (!level);
625
+ private_steps = false;
626
+
627
+ report ('k', !failed);
628
+ STOP_SIMPLIFIER (backbone, BACKBONE);
629
+ }
630
+
631
+ } // namespace CaDiCaL