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,616 @@
1
+ #include "internal.hpp"
2
+ #include "options.hpp"
3
+
4
+ namespace CaDiCaL {
5
+
6
+ // Failed literal handling as pioneered by MiniSAT. This first function
7
+ // adds an assumption literal onto the assumption stack.
8
+
9
+ void Internal::assume (int lit) {
10
+ if (level && !opts.ilb)
11
+ backtrack ();
12
+ else if (val (lit) < 0)
13
+ backtrack (max (0, var (lit).level - 1));
14
+ Flags &f = flags (lit);
15
+ const unsigned char bit = bign (lit);
16
+ if (f.assumed & bit) {
17
+ LOG ("ignoring already assumed %d", lit);
18
+ return;
19
+ }
20
+ LOG ("assume %d", lit);
21
+ f.assumed |= bit;
22
+ assumptions.push_back (lit);
23
+ freeze (lit);
24
+ }
25
+
26
+ // for LRAT we actually need to implement recursive DFS
27
+ // for non-lrat use BFS. TODO: maybe derecursify to avoid stack overflow
28
+ //
29
+ void Internal::assume_analyze_literal (int lit) {
30
+ assert (lit);
31
+ Flags &f = flags (lit);
32
+ if (f.seen)
33
+ return;
34
+ f.seen = true;
35
+ analyzed.push_back (lit);
36
+ Var &v = var (lit);
37
+ assert (val (lit) < 0);
38
+ if (v.reason == external_reason) {
39
+ v.reason = wrapped_learn_external_reason_clause (-lit);
40
+ assert (v.reason || !v.level);
41
+ }
42
+ assert (v.reason != external_reason);
43
+ if (!v.level) {
44
+ int64_t id = unit_id (-lit);
45
+ lrat_chain.push_back (id);
46
+ return;
47
+ }
48
+ if (v.reason) {
49
+ assert (v.level);
50
+ LOG (v.reason, "analyze reason");
51
+ for (const auto &other : *v.reason) {
52
+ assume_analyze_literal (other);
53
+ }
54
+ lrat_chain.push_back (v.reason->id);
55
+ return;
56
+ }
57
+ assert (assumed (-lit));
58
+ LOG ("failed assumption %d", -lit);
59
+ clause.push_back (lit);
60
+ }
61
+
62
+ void Internal::assume_analyze_reason (int lit, Clause *reason) {
63
+ assert (reason);
64
+ assert (lrat_chain.empty ());
65
+ assert (reason != external_reason);
66
+ assert (lrat);
67
+ for (const auto &other : *reason)
68
+ if (other != lit)
69
+ assume_analyze_literal (other);
70
+ lrat_chain.push_back (reason->id);
71
+ }
72
+
73
+ // Find all failing assumptions starting from the one on the assumption
74
+ // stack with the lowest decision level. This goes back to MiniSAT and is
75
+ // called 'analyze_final' there.
76
+
77
+ void Internal::failing () {
78
+
79
+ START (analyze);
80
+
81
+ LOG ("analyzing failing assumptions");
82
+
83
+ assert (analyzed.empty ());
84
+ assert (clause.empty ());
85
+ assert (lrat_chain.empty ());
86
+ assert (!marked_failed);
87
+ assert (!conflict_id);
88
+
89
+ if (!unsat_constraint) {
90
+ // Search for failing assumptions in the (internal) assumption stack.
91
+
92
+ // There are in essence three cases: (1) An assumption is falsified on
93
+ // the root-level and then 'failed_unit' is set to that assumption, (2)
94
+ // two clashing assumptions are assumed and then 'failed_clashing' is
95
+ // set to the second assumed one, or otherwise (3) there is a failing
96
+ // assumption 'first_failed' with minimum (non-zero) decision level
97
+ // 'failed_level'.
98
+
99
+ int failed_unit = 0;
100
+ int failed_clashing = 0;
101
+ int first_failed = 0;
102
+ int failed_level = INT_MAX;
103
+ int efailed = 0;
104
+
105
+ for (auto &elit : external->assumptions) {
106
+ int lit = external->e2i[abs (elit)];
107
+ if (elit < 0)
108
+ lit = -lit;
109
+ if (val (lit) >= 0)
110
+ continue;
111
+ const Var &v = var (lit);
112
+ if (!v.level) {
113
+ failed_unit = lit;
114
+ efailed = elit;
115
+ break;
116
+ }
117
+ if (failed_clashing)
118
+ continue;
119
+ if (v.reason == external_reason) {
120
+ Var &ev = var (lit);
121
+ ev.reason = learn_external_reason_clause (-lit);
122
+ if (!ev.reason) {
123
+ ev.level = 0;
124
+ failed_unit = lit;
125
+ efailed = elit;
126
+ break;
127
+ }
128
+ ev.level = 0;
129
+ // Recalculate assignment level
130
+ for (const auto &other : *ev.reason) {
131
+ if (other == -lit)
132
+ continue;
133
+ assert (val (other));
134
+ int tmp = var (other).level;
135
+ if (tmp > ev.level)
136
+ ev.level = tmp;
137
+ }
138
+ if (!ev.level) {
139
+ failed_unit = lit;
140
+ efailed = elit;
141
+ break;
142
+ }
143
+ }
144
+ assert (v.reason != external_reason);
145
+ if (!v.reason) {
146
+ failed_clashing = lit;
147
+ efailed = elit;
148
+ } else if (!first_failed || v.level < failed_level) {
149
+ first_failed = lit;
150
+ efailed = elit;
151
+ failed_level = v.level;
152
+ }
153
+ }
154
+
155
+ assert (clause.empty ());
156
+
157
+ // Get the 'failed' assumption from one of the three cases.
158
+ int failed;
159
+ if (failed_unit)
160
+ failed = failed_unit;
161
+ else if (failed_clashing)
162
+ failed = failed_clashing;
163
+ else
164
+ failed = first_failed;
165
+ assert (failed);
166
+ assert (efailed);
167
+
168
+ // In any case mark literal 'failed' as failed assumption.
169
+ {
170
+ Flags &f = flags (failed);
171
+ const unsigned bit = bign (failed);
172
+ assert (!(f.failed & bit));
173
+ f.failed |= bit;
174
+ }
175
+
176
+ // First case (1).
177
+ if (failed_unit) {
178
+ assert (failed == failed_unit);
179
+ LOG ("root-level falsified assumption %d", failed);
180
+ if (proof) {
181
+ if (lrat) {
182
+ unsigned eidx = (efailed > 0) + 2u * (unsigned) abs (efailed);
183
+ assert ((size_t) eidx < external->ext_units.size ());
184
+ const int64_t id = external->ext_units[eidx];
185
+ if (id) {
186
+ lrat_chain.push_back (id);
187
+ } else {
188
+ int64_t id = unit_id (-failed_unit);
189
+ lrat_chain.push_back (id);
190
+ }
191
+ }
192
+ proof->add_assumption_clause (++clause_id, -efailed, lrat_chain);
193
+ conclusion.push_back (clause_id);
194
+ lrat_chain.clear ();
195
+ }
196
+ goto DONE;
197
+ }
198
+
199
+ // Second case (2).
200
+ if (failed_clashing) {
201
+ assert (failed == failed_clashing);
202
+ LOG ("clashing assumptions %d and %d", failed, -failed);
203
+ Flags &f = flags (-failed);
204
+ const unsigned bit = bign (-failed);
205
+ assert (!(f.failed & bit));
206
+ f.failed |= bit;
207
+ if (proof) {
208
+ vector<int> clash = {externalize (failed), externalize (-failed)};
209
+ proof->add_assumption_clause (++clause_id, clash, lrat_chain);
210
+ conclusion.push_back (clause_id);
211
+ }
212
+ goto DONE;
213
+ }
214
+
215
+ // Fall through to third case (3).
216
+ LOG ("starting with assumption %d falsified on minimum decision level "
217
+ "%d",
218
+ first_failed, failed_level);
219
+
220
+ assert (first_failed);
221
+ assert (failed_level > 0);
222
+
223
+ // The 'analyzed' stack serves as working stack for a BFS through the
224
+ // implication graph until decisions, which are all assumptions, or
225
+ // units are reached. This is simpler than corresponding code in
226
+ // 'analyze'.
227
+ {
228
+ LOG ("failed assumption %d", first_failed);
229
+ Flags &f = flags (first_failed);
230
+ assert (!f.seen);
231
+ f.seen = true;
232
+ assert (f.failed & bign (first_failed));
233
+ analyzed.push_back (-first_failed);
234
+ clause.push_back (-first_failed);
235
+ }
236
+ } else {
237
+ // unsat_constraint
238
+ // The assumptions necessary to fail each literal in the constraint are
239
+ // collected.
240
+ for (auto lit : constraint) {
241
+ lit *= -1;
242
+ assert (lit != INT_MIN);
243
+ flags (lit).seen = true;
244
+ analyzed.push_back (lit);
245
+ }
246
+ }
247
+
248
+ {
249
+ // used for unsat_constraint lrat
250
+ vector<vector<int64_t>> constraint_chains;
251
+ vector<vector<int>> constraint_clauses;
252
+ vector<int> sum_constraints;
253
+ vector<int> econstraints;
254
+ for (auto &elit : external->constraint) {
255
+ int lit = external->e2i[abs (elit)];
256
+ if (elit < 0)
257
+ lit = -lit;
258
+ if (!lit)
259
+ continue;
260
+ Flags &f = flags (lit);
261
+ if (f.seen)
262
+ continue;
263
+ if (std::find (econstraints.begin (), econstraints.end (), elit) !=
264
+ econstraints.end ())
265
+ continue;
266
+ econstraints.push_back (elit);
267
+ }
268
+
269
+ // no LRAT do bfs as it was before
270
+ if (!lrat) {
271
+ size_t next = 0;
272
+ while (next < analyzed.size ()) {
273
+ const int lit = analyzed[next++];
274
+ assert (val (lit) > 0);
275
+ Var &v = var (lit);
276
+ if (!v.level)
277
+ continue;
278
+ if (v.reason == external_reason) {
279
+ v.reason = wrapped_learn_external_reason_clause (lit);
280
+ if (!v.reason) {
281
+ v.level = 0;
282
+ continue;
283
+ }
284
+ }
285
+ assert (v.reason != external_reason);
286
+ if (v.reason) {
287
+ assert (v.level);
288
+ LOG (v.reason, "analyze reason");
289
+ for (const auto &other : *v.reason) {
290
+ Flags &f = flags (other);
291
+ if (f.seen)
292
+ continue;
293
+ f.seen = true;
294
+ assert (val (other) < 0);
295
+ analyzed.push_back (-other);
296
+ }
297
+ } else {
298
+ assert (assumed (lit));
299
+ LOG ("failed assumption %d", lit);
300
+ clause.push_back (-lit);
301
+ Flags &f = flags (lit);
302
+ const unsigned bit = bign (lit);
303
+ assert (!(f.failed & bit));
304
+ f.failed |= bit;
305
+ }
306
+ }
307
+ clear_analyzed_literals ();
308
+ } else if (!unsat_constraint) { // LRAT for case (3)
309
+ assert (clause.size () == 1);
310
+ const int lit = clause[0];
311
+ Var &v = var (lit);
312
+ assert (v.reason);
313
+ if (v.reason == external_reason) { // does this even happen?
314
+ v.reason = wrapped_learn_external_reason_clause (lit);
315
+ }
316
+ assert (v.reason != external_reason);
317
+ if (v.reason)
318
+ assume_analyze_reason (lit, v.reason);
319
+ else {
320
+ int64_t id = unit_id (lit);
321
+ lrat_chain.push_back (id);
322
+ }
323
+ for (auto &lit : clause) {
324
+ Flags &f = flags (lit);
325
+ const unsigned bit = bign (-lit);
326
+ if (!(f.failed & bit))
327
+ f.failed |= bit;
328
+ }
329
+ clear_analyzed_literals ();
330
+ } else { // LRAT for unsat_constraint
331
+ assert (clause.empty ());
332
+ clear_analyzed_literals ();
333
+ for (auto lit : constraint) {
334
+ // make sure nothing gets marked failed twice
335
+ // also might shortcut the case where
336
+ // lrat_chain is empty because clause is tautological
337
+ assert (lit != INT_MIN);
338
+ assume_analyze_literal (lit);
339
+ vector<int64_t> empty;
340
+ vector<int> empty2;
341
+ constraint_chains.push_back (empty);
342
+ constraint_clauses.push_back (empty2);
343
+ for (auto ign : clause) {
344
+ constraint_clauses.back ().push_back (ign);
345
+ Flags &f = flags (ign);
346
+ const unsigned bit = bign (-ign);
347
+ if (!(f.failed & bit)) {
348
+ sum_constraints.push_back (ign);
349
+ assert (!(f.failed & bit));
350
+ f.failed |= bit;
351
+ }
352
+ }
353
+ clause.clear ();
354
+ clear_analyzed_literals ();
355
+ for (auto p : lrat_chain) {
356
+ constraint_chains.back ().push_back (p);
357
+ }
358
+ lrat_chain.clear ();
359
+ }
360
+ for (auto &lit : sum_constraints)
361
+ clause.push_back (lit);
362
+ }
363
+ clear_analyzed_literals ();
364
+
365
+ // Doing clause minimization here does not do anything because
366
+ // the clause already contains only one literal of each level
367
+ // and minimization can never reduce the number of levels
368
+
369
+ VERBOSE (1, "found %zd failed assumptions %.0f%%", clause.size (),
370
+ percent (clause.size (), assumptions.size ()));
371
+
372
+ // We do not actually need to learn this clause, since the conflict is
373
+ // forced already by some other clauses. There is also no bumping
374
+ // of variables nor clauses necessary. But we still want to check
375
+ // correctness of the claim that the determined subset of failing
376
+ // assumptions are a high-level core or equivalently their negations
377
+ // form a unit-implied clause.
378
+ //
379
+ if (!unsat_constraint) {
380
+ external->check_learned_clause ();
381
+ if (proof) {
382
+ vector<int> eclause;
383
+ for (auto &lit : clause)
384
+ eclause.push_back (externalize (lit));
385
+ proof->add_assumption_clause (++clause_id, eclause, lrat_chain);
386
+ conclusion.push_back (clause_id);
387
+ }
388
+ } else {
389
+ assert (!lrat || (constraint.size () == constraint_clauses.size () &&
390
+ constraint.size () == constraint_chains.size ()));
391
+ for (auto p = constraint.rbegin (); p != constraint.rend (); p++) {
392
+ const auto &lit = *p;
393
+ if (lrat) {
394
+ clause.clear ();
395
+ for (auto &ign : constraint_clauses.back ())
396
+ clause.push_back (ign);
397
+ constraint_clauses.pop_back ();
398
+ }
399
+ clause.push_back (-lit);
400
+ external->check_learned_clause ();
401
+ if (proof) {
402
+ if (lrat) {
403
+ for (auto p : constraint_chains.back ()) {
404
+ lrat_chain.push_back (p);
405
+ }
406
+ constraint_chains.pop_back ();
407
+ LOG (lrat_chain, "assume proof chain with constraints");
408
+ }
409
+ vector<int> eclause;
410
+ for (auto &lit : clause)
411
+ eclause.push_back (externalize (lit));
412
+ proof->add_assumption_clause (++clause_id, eclause, lrat_chain);
413
+ conclusion.push_back (clause_id);
414
+ lrat_chain.clear ();
415
+ }
416
+ clause.pop_back ();
417
+ }
418
+ if (proof) {
419
+ for (auto &elit : econstraints) {
420
+ if (lrat) {
421
+ unsigned eidx = (elit > 0) + 2u * (unsigned) abs (elit);
422
+ assert ((size_t) eidx < external->ext_units.size ());
423
+ const int64_t id = external->ext_units[eidx];
424
+ if (id) {
425
+ lrat_chain.push_back (id);
426
+ } else {
427
+ int lit = external->e2i[abs (elit)];
428
+ if (elit < 0)
429
+ lit = -lit;
430
+ int64_t id = unit_id (-lit);
431
+ lrat_chain.push_back (id);
432
+ }
433
+ }
434
+ proof->add_assumption_clause (++clause_id, -elit, lrat_chain);
435
+ conclusion.push_back (clause_id);
436
+ lrat_chain.clear ();
437
+ }
438
+ }
439
+ }
440
+ lrat_chain.clear ();
441
+ clause.clear ();
442
+ }
443
+
444
+ DONE:
445
+
446
+ STOP (analyze);
447
+ }
448
+
449
+ bool Internal::failed (int lit) {
450
+ if (!marked_failed) {
451
+ if (!conflict_id)
452
+ failing ();
453
+ marked_failed = true;
454
+ }
455
+ conclude_unsat ();
456
+ Flags &f = flags (lit);
457
+ const unsigned bit = bign (lit);
458
+ return (f.failed & bit) != 0;
459
+ }
460
+
461
+ void Internal::conclude_unsat () {
462
+ if (!proof || concluded)
463
+ return;
464
+ concluded = true;
465
+ if (!marked_failed) {
466
+ assert (conclusion.empty ());
467
+ if (!conflict_id)
468
+ failing ();
469
+ marked_failed = true;
470
+ }
471
+ ConclusionType con;
472
+ if (conflict_id)
473
+ con = CONFLICT;
474
+ else if (unsat_constraint)
475
+ con = CONSTRAINT;
476
+ else
477
+ con = ASSUMPTIONS;
478
+ proof->conclude_unsat (con, conclusion);
479
+ }
480
+
481
+ void Internal::reset_concluded () {
482
+ if (proof)
483
+ proof->reset_assumptions ();
484
+ if (concluded) {
485
+ LOG ("reset concluded");
486
+ concluded = false;
487
+ }
488
+ if (conflict_id) {
489
+ assert (conclusion.size () == 1);
490
+ return;
491
+ }
492
+ conclusion.clear ();
493
+ }
494
+
495
+ // Add the start of each incremental phase (leaving the state
496
+ // 'UNSATISFIABLE' actually) we reset all assumptions.
497
+
498
+ void Internal::reset_assumptions () {
499
+ for (const auto &lit : assumptions) {
500
+ Flags &f = flags (lit);
501
+ const unsigned char bit = bign (lit);
502
+ f.assumed &= ~bit;
503
+ f.failed &= ~bit;
504
+ melt (lit);
505
+ }
506
+ LOG ("cleared %zd assumptions", assumptions.size ());
507
+ assumptions.clear ();
508
+ marked_failed = true;
509
+ }
510
+
511
+ struct sort_assumptions_positive_rank {
512
+ Internal *internal;
513
+
514
+ // Decision level could be 'INT_MAX' and thus 'level + 1' could overflow.
515
+ // Therefore we carefully have to use 'unsigned' for levels below.
516
+
517
+ const unsigned max_level;
518
+
519
+ sort_assumptions_positive_rank (Internal *s)
520
+ : internal (s), max_level (s->level + 1u) {}
521
+
522
+ typedef uint64_t Type;
523
+
524
+ // Set assumptions first, then sorted by position on the trail
525
+ // unset literals are sorted by literal value.
526
+
527
+ Type operator() (const int &a) const {
528
+ const int val = internal->val (a);
529
+ const bool assigned = (val != 0);
530
+ const Var &v = internal->var (a);
531
+ uint64_t res = (assigned ? (unsigned) v.level : max_level);
532
+ res <<= 32;
533
+ res |= (assigned ? v.trail : abs (a));
534
+ return res;
535
+ }
536
+ };
537
+
538
+ struct sort_assumptions_smaller {
539
+ Internal *internal;
540
+ sort_assumptions_smaller (Internal *s) : internal (s) {}
541
+ bool operator() (const int &a, const int &b) const {
542
+ return sort_assumptions_positive_rank (internal) (a) <
543
+ sort_assumptions_positive_rank (internal) (b);
544
+ }
545
+ };
546
+
547
+ // Sort the assumptions by the current position on the trail and backtrack
548
+ // to the first place where the assumptions and the current trail differ.
549
+
550
+ void Internal::sort_and_reuse_assumptions () {
551
+ assert (opts.ilb >= 1);
552
+ if (assumptions.empty ()) {
553
+ if (opts.ilb == 1) {
554
+ LOG ("no assumptions, reusing nothing (ilb == 1)");
555
+ backtrack (0);
556
+ } else { // reuse full trail
557
+ LOG ("no assumptions, reusing everything (ilb == 2)");
558
+ return;
559
+ }
560
+ }
561
+ MSORT (opts.radixsortlim, assumptions.begin (), assumptions.end (),
562
+ sort_assumptions_positive_rank (this),
563
+ sort_assumptions_smaller (this));
564
+
565
+ unsigned max_level = 0;
566
+ // assumptions are sorted by level, with unset at the end
567
+ for (auto lit : assumptions) {
568
+ if (val (lit))
569
+ max_level = var (lit).level;
570
+ else
571
+ break;
572
+ }
573
+
574
+ const unsigned size = min (level + 1u, max_level + 1);
575
+ assert ((size_t) level == control.size () - 1);
576
+ LOG (assumptions, "sorted assumptions");
577
+ int target = 0;
578
+ for (unsigned i = 1, j = 0; i < size;) {
579
+ const Level &l = control[i];
580
+ const int lit = l.decision;
581
+ const int alit = assumptions[j];
582
+ const int lev = i;
583
+ target = lev;
584
+ if (val (alit) > 0 &&
585
+ var (alit).level < lev) { // we can ignore propagated assumptions
586
+ LOG ("ILB skipping propagation %d", alit);
587
+ ++j;
588
+ continue;
589
+ }
590
+ if (!lit) { // skip fake decisions
591
+ target = lev - 1;
592
+ break;
593
+ }
594
+ ++i, ++j;
595
+ assert (var (lit).level == lev);
596
+ if (l.decision == alit) {
597
+ continue;
598
+ }
599
+ target = lev - 1;
600
+ LOG ("first different literal %d on the trail and %d from the "
601
+ "assumptions",
602
+ lit, alit);
603
+ break;
604
+ }
605
+ if (opts.ilb == 1 &&
606
+ (size_t) target > assumptions.size ()) // reusing only assumptions
607
+ target = assumptions.size ();
608
+ if (target < level)
609
+ backtrack_without_updating_phases (target);
610
+ LOG ("assumptions allow for reuse of trail up to level %d", level);
611
+ if ((size_t) level > assumptions.size ())
612
+ stats.assumptionsreused += assumptions.size ();
613
+ else
614
+ stats.assumptionsreused += level;
615
+ }
616
+ } // namespace CaDiCaL
@@ -0,0 +1,34 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ void Internal::init_averages () {
6
+
7
+ LOG ("initializing averages");
8
+
9
+ INIT_EMA (averages.current.jump, opts.emajump);
10
+ INIT_EMA (averages.current.level, opts.emalevel);
11
+ INIT_EMA (averages.current.size, opts.emasize);
12
+
13
+ INIT_EMA (averages.current.glue.fast, opts.emagluefast);
14
+ INIT_EMA (averages.current.glue.slow, opts.emaglueslow);
15
+
16
+ INIT_EMA (averages.current.decisions, opts.emadecisions);
17
+
18
+ INIT_EMA (averages.current.trail.fast, opts.ematrailfast);
19
+ INIT_EMA (averages.current.trail.slow, opts.ematrailslow);
20
+
21
+ assert (!averages.swapped);
22
+ }
23
+
24
+ void Internal::swap_averages () {
25
+ LOG ("saving current averages");
26
+ swap (averages.current, averages.saved);
27
+ if (!averages.swapped)
28
+ init_averages ();
29
+ else
30
+ LOG ("swapping in previously saved averages");
31
+ averages.swapped++;
32
+ }
33
+
34
+ } // namespace CaDiCaL
@@ -0,0 +1,37 @@
1
+ #ifndef _averages_hpp_INCLUDED
2
+ #define _averages_hpp_INCLUDED
3
+
4
+ #include "ema.hpp" // alphabetically after 'averages.hpp'
5
+
6
+ namespace CaDiCaL {
7
+
8
+ struct Averages {
9
+
10
+ int64_t swapped;
11
+
12
+ struct {
13
+
14
+ struct {
15
+ EMA fast; // average fast (small window) moving glucose level
16
+ EMA slow; // average slow (large window) moving glucose level
17
+ } glue;
18
+
19
+ struct {
20
+ EMA fast; // average fast (small window) moving trail level
21
+ EMA slow; // average slow (large window) moving trail level
22
+ } trail;
23
+
24
+ EMA decisions;
25
+
26
+ EMA size; // average learned clause size
27
+ EMA jump; // average (potential non-chronological) back-jump level
28
+ EMA level; // average back track level after conflict
29
+
30
+ } current, saved;
31
+
32
+ Averages () : swapped (0) {}
33
+ };
34
+
35
+ } // namespace CaDiCaL
36
+
37
+ #endif