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,506 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ // It turns out that even in the competition there are formulas which are
6
+ // easy to satisfy by either setting all variables to the same truth value
7
+ // or by assigning variables to the same value and propagating it. In the
8
+ // latter situation this can be done either in the order of all variables
9
+ // (forward or backward) or in the order of all clauses. These lucky
10
+ // assignments can be tested initially in a kind of pre-solving step.
11
+
12
+ // This function factors out clean up code common among the 'lucky'
13
+ // functions for backtracking and resetting a potential conflict. One could
14
+ // also use exceptions here, but there are two different reasons for
15
+ // aborting early. The first kind of aborting is due to asynchronous
16
+ // termination and the second kind due to a situation in which it is clear
17
+ // that a particular function will not be successful (for instance a
18
+ // completely negative clause is found). The latter situation returns zero
19
+ // and will just abort the particular lucky function, while the former will
20
+ // abort all (by returning '-1').
21
+
22
+ int Internal::unlucky (int res) {
23
+ if (level > 0)
24
+ backtrack_without_updating_phases ();
25
+ if (conflict)
26
+ conflict = 0;
27
+ return res;
28
+ }
29
+
30
+ int Internal::trivially_false_satisfiable () {
31
+ LOG ("checking that all clauses contain a negative literal");
32
+ assert (!level);
33
+ int res = lucky_decide_assumptions ();
34
+ if (res)
35
+ return res;
36
+ for (const auto &c : clauses) {
37
+ if (terminated_asynchronously (100))
38
+ return unlucky (-1);
39
+ if (c->garbage)
40
+ continue;
41
+ if (c->redundant)
42
+ continue;
43
+ bool satisfied = false, found_negative_literal = false;
44
+ for (const auto &lit : *c) {
45
+ const signed char tmp = val (lit);
46
+ if (tmp > 0) {
47
+ satisfied = true;
48
+ break;
49
+ }
50
+ if (tmp < 0)
51
+ continue;
52
+ if (lit > 0)
53
+ continue;
54
+ found_negative_literal = true;
55
+ break;
56
+ }
57
+ if (satisfied || found_negative_literal)
58
+ continue;
59
+ LOG (c, "found purely positively");
60
+ return unlucky (0);
61
+ }
62
+ VERBOSE (1, "all clauses contain a negative literal");
63
+ for (auto idx : vars) {
64
+ if (terminated_asynchronously (10))
65
+ return unlucky (-1);
66
+ if (val (idx))
67
+ continue;
68
+ search_assume_decision (-idx);
69
+ if (propagate ())
70
+ continue;
71
+ assert (level > 0);
72
+ LOG ("propagation failed including redundant clauses");
73
+ return unlucky (0);
74
+ }
75
+ stats.lucky.constant.zero++;
76
+ return 10;
77
+ }
78
+
79
+ int Internal::trivially_true_satisfiable () {
80
+ LOG ("checking that all clauses contain a positive literal");
81
+ assert (!level);
82
+ int res = lucky_decide_assumptions ();
83
+ if (res)
84
+ return res;
85
+ for (const auto &c : clauses) {
86
+ if (terminated_asynchronously (100))
87
+ return unlucky (-1);
88
+ if (c->garbage)
89
+ continue;
90
+ if (c->redundant)
91
+ continue;
92
+ bool satisfied = false, found_positive_literal = false;
93
+ for (const auto &lit : *c) {
94
+ const signed char tmp = val (lit);
95
+ if (tmp > 0) {
96
+ satisfied = true;
97
+ break;
98
+ }
99
+ if (tmp < 0)
100
+ continue;
101
+ if (lit < 0)
102
+ continue;
103
+ found_positive_literal = true;
104
+ break;
105
+ }
106
+ if (satisfied || found_positive_literal)
107
+ continue;
108
+ LOG (c, "found purely negatively");
109
+ return unlucky (0);
110
+ }
111
+ VERBOSE (1, "all clauses contain a positive literal");
112
+ for (auto idx : vars) {
113
+ if (terminated_asynchronously (10))
114
+ return unlucky (-1);
115
+ if (val (idx))
116
+ continue;
117
+ search_assume_decision (idx);
118
+ if (propagate ())
119
+ continue;
120
+ assert (level > 0);
121
+ LOG ("propagation failed including redundant clauses");
122
+ return unlucky (0);
123
+ }
124
+ stats.lucky.constant.one++;
125
+ return 10;
126
+ }
127
+
128
+ /*------------------------------------------------------------------------*/
129
+ inline bool Internal::lucky_propagate_discrepency (int dec) {
130
+ search_assume_decision (dec);
131
+ bool no_conflict = propagate ();
132
+ if (no_conflict)
133
+ return false;
134
+ if (level > 1) {
135
+ conflict = nullptr;
136
+ backtrack_without_updating_phases (level - 1);
137
+ search_assume_decision (-dec);
138
+ no_conflict = propagate ();
139
+ if (no_conflict)
140
+ return false;
141
+ return true;
142
+ } else {
143
+ analyze ();
144
+ assert (!level);
145
+ no_conflict = propagate ();
146
+ if (!no_conflict) {
147
+ analyze ();
148
+ LOG ("lucky inconsistency backward assigning to true");
149
+ return true;
150
+ }
151
+ }
152
+ return false;
153
+ }
154
+
155
+ int Internal::forward_false_satisfiable () {
156
+ LOG ("checking increasing variable index false assignment");
157
+ assert (!unsat);
158
+ assert (!level);
159
+ int res = lucky_decide_assumptions ();
160
+ if (res)
161
+ return res;
162
+ for (auto idx : vars) {
163
+ START:
164
+ if (terminated_asynchronously (100))
165
+ return unlucky (-1);
166
+ if (val (idx))
167
+ continue;
168
+ if (lucky_propagate_discrepency (-idx)) {
169
+ if (unsat)
170
+ return 20;
171
+ else
172
+ return unlucky (0);
173
+ } else
174
+ goto START;
175
+ }
176
+ VERBOSE (1, "forward assuming variables false satisfies formula");
177
+ assert (satisfied ());
178
+ stats.lucky.forward.zero++;
179
+ return 10;
180
+ }
181
+
182
+ int Internal::forward_true_satisfiable () {
183
+ LOG ("checking increasing variable index true assignment");
184
+ assert (!unsat);
185
+ assert (!level);
186
+ int res = lucky_decide_assumptions ();
187
+ if (res)
188
+ return res;
189
+ for (auto idx : vars) {
190
+ START:
191
+ if (terminated_asynchronously (10))
192
+ return unlucky (-1);
193
+ if (val (idx))
194
+ continue;
195
+ if (lucky_propagate_discrepency (idx)) {
196
+ if (unsat)
197
+ return 20;
198
+ else
199
+ return unlucky (0);
200
+ } else
201
+ goto START;
202
+ }
203
+ VERBOSE (1, "forward assuming variables true satisfies formula");
204
+ assert (satisfied ());
205
+ stats.lucky.forward.one++;
206
+ return 10;
207
+ }
208
+
209
+ /*------------------------------------------------------------------------*/
210
+
211
+ int Internal::backward_false_satisfiable () {
212
+ LOG ("checking decreasing variable index false assignment");
213
+ assert (!unsat);
214
+ assert (!level);
215
+ int res = lucky_decide_assumptions ();
216
+ if (res)
217
+ return res;
218
+ for (auto it = vars.rbegin (); it != vars.rend (); ++it) {
219
+ int idx = *it;
220
+ START:
221
+ if (terminated_asynchronously (10))
222
+ return unlucky (-1);
223
+ if (val (idx))
224
+ continue;
225
+ if (lucky_propagate_discrepency (-idx)) {
226
+ if (unsat)
227
+ return 20;
228
+ else
229
+ return unlucky (0);
230
+ } else
231
+ goto START;
232
+ }
233
+ VERBOSE (1, "backward assuming variables false satisfies formula");
234
+ assert (satisfied ());
235
+ stats.lucky.backward.zero++;
236
+ return 10;
237
+ }
238
+
239
+ int Internal::backward_true_satisfiable () {
240
+ LOG ("checking decreasing variable index true assignment");
241
+ assert (!unsat);
242
+ assert (!level);
243
+ int res = lucky_decide_assumptions ();
244
+ if (res)
245
+ return res;
246
+ for (auto it = vars.rbegin (); it != vars.rend (); ++it) {
247
+ int idx = *it;
248
+ START:
249
+ if (terminated_asynchronously (10))
250
+ return unlucky (-1);
251
+ if (val (idx))
252
+ continue;
253
+ if (lucky_propagate_discrepency (idx)) {
254
+ if (unsat)
255
+ return 20;
256
+ else
257
+ return unlucky (0);
258
+ } else
259
+ goto START;
260
+ }
261
+ VERBOSE (1, "backward assuming variables true satisfies formula");
262
+ assert (satisfied ());
263
+ stats.lucky.backward.one++;
264
+ return 10;
265
+ }
266
+
267
+ /*------------------------------------------------------------------------*/
268
+
269
+ // The following two functions test if the formula is a satisfiable horn
270
+ // formula. Actually the test is slightly more general. It goes over all
271
+ // clauses and assigns the first positive literal to true and propagates.
272
+ // Already satisfied clauses are of course skipped. A reverse function
273
+ // is not implemented yet.
274
+
275
+ int Internal::positive_horn_satisfiable () {
276
+ LOG ("checking that all clauses are positive horn satisfiable");
277
+ assert (!level);
278
+ int res = lucky_decide_assumptions ();
279
+ if (res)
280
+ return res;
281
+ for (const auto &c : clauses) {
282
+ if (terminated_asynchronously (10))
283
+ return unlucky (-1);
284
+ if (c->garbage)
285
+ continue;
286
+ if (c->redundant)
287
+ continue;
288
+ int positive_literal = 0;
289
+ bool satisfied = false;
290
+ for (const auto &lit : *c) {
291
+ const signed char tmp = val (lit);
292
+ if (tmp > 0) {
293
+ satisfied = true;
294
+ break;
295
+ }
296
+ if (tmp < 0)
297
+ continue;
298
+ if (lit < 0)
299
+ continue;
300
+ positive_literal = lit;
301
+ break;
302
+ }
303
+ if (satisfied)
304
+ continue;
305
+ if (!positive_literal) {
306
+ LOG (c, "no positive unassigned literal in");
307
+ return unlucky (0);
308
+ }
309
+ assert (positive_literal > 0);
310
+ LOG (c, "found positive literal %d in", positive_literal);
311
+ search_assume_decision (positive_literal);
312
+ if (propagate ())
313
+ continue;
314
+ LOG ("propagation of positive literal %d leads to conflict",
315
+ positive_literal);
316
+ return unlucky (0);
317
+ }
318
+ for (auto idx : vars) {
319
+ if (terminated_asynchronously (10))
320
+ return unlucky (-1);
321
+ if (val (idx))
322
+ continue;
323
+ search_assume_decision (-idx);
324
+ if (propagate ())
325
+ continue;
326
+ LOG ("propagation of remaining literal %d leads to conflict", -idx);
327
+ return unlucky (0);
328
+ }
329
+ VERBOSE (1, "clauses are positive horn satisfied");
330
+ assert (!conflict);
331
+ assert (satisfied ());
332
+ stats.lucky.horn.positive++;
333
+ return 10;
334
+ }
335
+
336
+ int Internal::lucky_decide_assumptions () {
337
+ assert (!level);
338
+ assert (!constraint.size ());
339
+ int res = 0;
340
+ while ((size_t) level < assumptions.size ()) {
341
+ res = decide ();
342
+ if (res == 20) {
343
+ marked_failed = false;
344
+ return 20;
345
+ }
346
+ if (!propagate ()) {
347
+ break;
348
+ }
349
+ }
350
+
351
+ if (conflict) {
352
+ // analyze and learn from the conflict.
353
+ LOG (conflict, "setting assumption lead to conflict");
354
+ analyze_wrapper ();
355
+ backtrack (0);
356
+ assert (!conflict);
357
+ int res = 0;
358
+ while (!res) {
359
+ assert ((size_t) level <= assumptions.size ());
360
+ if (unsat)
361
+ res = 20;
362
+ else if (!propagate ()) {
363
+ analyze_wrapper ();
364
+ } else {
365
+ res = decide_wrapper ();
366
+ }
367
+ }
368
+ assert (res == 20);
369
+ return 20;
370
+ }
371
+ return 0;
372
+ }
373
+
374
+ int Internal::negative_horn_satisfiable () {
375
+ assert (!level);
376
+ LOG ("checking that all clauses are negative horn satisfiable");
377
+ int res = lucky_decide_assumptions ();
378
+ if (res)
379
+ return res;
380
+ for (const auto &c : clauses) {
381
+ if (terminated_asynchronously (10))
382
+ return unlucky (-1);
383
+ if (c->garbage)
384
+ continue;
385
+ if (c->redundant)
386
+ continue;
387
+ int negative_literal = 0;
388
+ bool satisfied = false;
389
+ for (const auto &lit : *c) {
390
+ const signed char tmp = val (lit);
391
+ if (tmp > 0) {
392
+ satisfied = true;
393
+ break;
394
+ }
395
+ if (tmp < 0)
396
+ continue;
397
+ if (lit > 0)
398
+ continue;
399
+ negative_literal = lit;
400
+ break;
401
+ }
402
+ if (satisfied)
403
+ continue;
404
+ if (!negative_literal) {
405
+ if (level > 0)
406
+ backtrack_without_updating_phases ();
407
+ LOG (c, "no negative unassigned literal in");
408
+ return unlucky (0);
409
+ }
410
+ assert (negative_literal < 0);
411
+ LOG (c, "found negative literal %d in", negative_literal);
412
+ search_assume_decision (negative_literal);
413
+ if (propagate ())
414
+ continue;
415
+ LOG ("propagation of negative literal %d leads to conflict",
416
+ negative_literal);
417
+ return unlucky (0);
418
+ }
419
+ for (auto idx : vars) {
420
+ if (terminated_asynchronously (10))
421
+ return unlucky (-1);
422
+ if (val (idx))
423
+ continue;
424
+ search_assume_decision (idx);
425
+ if (propagate ())
426
+ continue;
427
+ LOG ("propagation of remaining literal %d leads to conflict", idx);
428
+ return unlucky (0);
429
+ }
430
+ VERBOSE (1, "clauses are negative horn satisfied");
431
+ assert (!conflict);
432
+ assert (satisfied ());
433
+ stats.lucky.horn.negative++;
434
+ return 10;
435
+ }
436
+
437
+ /*------------------------------------------------------------------------*/
438
+
439
+ int Internal::lucky_phases () {
440
+ assert (!level);
441
+ require_mode (SEARCH);
442
+ if (!opts.lucky)
443
+ return 0;
444
+
445
+ if (!opts.luckyassumptions && !assumptions.empty ())
446
+ return 0;
447
+ // TODO: Some of the lucky assignments can also be found if there are
448
+ // constraint.
449
+ // External propagator assumes a CDCL loop, so lucky is not tried here.
450
+ if (!constraint.empty () || external_prop)
451
+ return 0;
452
+ if (!propagate ()) {
453
+ learn_empty_clause ();
454
+ return 20;
455
+ }
456
+
457
+ START (search);
458
+ START (lucky);
459
+ LOG ("starting lucky");
460
+ assert (!searching_lucky_phases);
461
+ searching_lucky_phases = true;
462
+ stats.lucky.tried++;
463
+ const int64_t active_before = stats.active;
464
+ int res = trivially_false_satisfiable ();
465
+ if (!res)
466
+ res = trivially_true_satisfiable ();
467
+ if (!res)
468
+ res = forward_false_satisfiable ();
469
+ if (!res)
470
+ res = forward_true_satisfiable ();
471
+ if (!res)
472
+ res = backward_false_satisfiable ();
473
+ if (!res)
474
+ res = backward_true_satisfiable ();
475
+ if (!res)
476
+ res = negative_horn_satisfiable ();
477
+ if (!res)
478
+ res = positive_horn_satisfiable ();
479
+ if (res < 0)
480
+ assert (termination_forced), res = 0;
481
+ if (res == 10)
482
+ stats.lucky.succeeded++;
483
+ report ('l', !res);
484
+ assert (searching_lucky_phases);
485
+
486
+ assert (res || !level);
487
+ if (res != 20) {
488
+ if (!propagate ()) {
489
+ LOG ("propagating units after elimination results in empty clause");
490
+ learn_empty_clause ();
491
+ }
492
+ }
493
+
494
+ const int64_t units = active_before - stats.active;
495
+
496
+ if (!res && units)
497
+ LOG ("lucky %" PRId64 " units", units);
498
+ searching_lucky_phases = false;
499
+
500
+ STOP (lucky);
501
+ STOP (search);
502
+
503
+ return res;
504
+ }
505
+
506
+ } // namespace CaDiCaL
@@ -0,0 +1,218 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ /*------------------------------------------------------------------------*/
6
+ #ifndef QUIET
7
+ /*------------------------------------------------------------------------*/
8
+
9
+ void Internal::print_prefix () { fputs (prefix.c_str (), stdout); }
10
+
11
+ void Internal::vmessage (const char *fmt, va_list &ap) {
12
+ #ifdef LOGGING
13
+ if (!opts.log)
14
+ #endif
15
+ if (opts.quiet)
16
+ return;
17
+ print_prefix ();
18
+ vprintf (fmt, ap);
19
+ fputc ('\n', stdout);
20
+ fflush (stdout);
21
+ }
22
+
23
+ void Internal::message (const char *fmt, ...) {
24
+ #ifdef LOGGING
25
+ if (!opts.log)
26
+ #endif
27
+ if (opts.quiet)
28
+ return;
29
+
30
+ va_list ap;
31
+ va_start (ap, fmt);
32
+ vmessage (fmt, ap);
33
+ va_end (ap);
34
+ }
35
+
36
+ void Internal::message () {
37
+ #ifdef LOGGING
38
+ if (!opts.log)
39
+ #endif
40
+ if (opts.quiet)
41
+ return;
42
+ print_prefix ();
43
+ fputc ('\n', stdout);
44
+ fflush (stdout);
45
+ }
46
+
47
+ /*------------------------------------------------------------------------*/
48
+
49
+ void Internal::vverbose (int level, const char *fmt, va_list &ap) {
50
+ #ifdef LOGGING
51
+ if (!opts.log)
52
+ #endif
53
+ if (opts.quiet || level > opts.verbose)
54
+ return;
55
+ print_prefix ();
56
+ vprintf (fmt, ap);
57
+ fputc ('\n', stdout);
58
+ fflush (stdout);
59
+ }
60
+
61
+ void Internal::verbose (int level, const char *fmt, ...) {
62
+ va_list ap;
63
+ va_start (ap, fmt);
64
+ vverbose (level, fmt, ap);
65
+ va_end (ap);
66
+ }
67
+
68
+ void Internal::verbose (int level) {
69
+ #ifdef LOGGING
70
+ if (!opts.log)
71
+ #endif
72
+ if (opts.quiet || level > opts.verbose)
73
+ return;
74
+ print_prefix ();
75
+ fputc ('\n', stdout);
76
+ fflush (stdout);
77
+ }
78
+
79
+ /*------------------------------------------------------------------------*/
80
+
81
+ void Internal::section (const char *title) {
82
+ #ifdef LOGGING
83
+ if (!opts.log)
84
+ #endif
85
+ if (opts.quiet)
86
+ return;
87
+ if (stats.sections++)
88
+ MSG ();
89
+ print_prefix ();
90
+ tout.blue ();
91
+ fputs ("--- [ ", stdout);
92
+ tout.blue (true);
93
+ fputs (title, stdout);
94
+ tout.blue ();
95
+ fputs (" ] ", stdout);
96
+ for (int i = strlen (title) + strlen (prefix.c_str ()) + 9; i < 78; i++)
97
+ fputc ('-', stdout);
98
+ tout.normal ();
99
+ fputc ('\n', stdout);
100
+ MSG ();
101
+ }
102
+
103
+ /*------------------------------------------------------------------------*/
104
+
105
+ void Internal::phase (const char *phase, const char *fmt, ...) {
106
+ #ifdef LOGGING
107
+ if (!opts.log)
108
+ #endif
109
+ if (opts.quiet || (!force_phase_messages && opts.verbose < 2))
110
+ return;
111
+ print_prefix ();
112
+ printf ("[%s] ", phase);
113
+ va_list ap;
114
+ va_start (ap, fmt);
115
+ vprintf (fmt, ap);
116
+ va_end (ap);
117
+ fputc ('\n', stdout);
118
+ fflush (stdout);
119
+ }
120
+
121
+ void Internal::phase (const char *phase, int64_t count, const char *fmt,
122
+ ...) {
123
+ #ifdef LOGGING
124
+ if (!opts.log)
125
+ #endif
126
+ if (opts.quiet || (!force_phase_messages && opts.verbose < 2))
127
+ return;
128
+ print_prefix ();
129
+ printf ("[%s-%" PRId64 "] ", phase, count);
130
+ va_list ap;
131
+ va_start (ap, fmt);
132
+ vprintf (fmt, ap);
133
+ va_end (ap);
134
+ fputc ('\n', stdout);
135
+ fflush (stdout);
136
+ }
137
+
138
+ /*------------------------------------------------------------------------*/
139
+ #endif // ifndef QUIET
140
+ /*------------------------------------------------------------------------*/
141
+
142
+ void Internal::warning (const char *fmt, ...) {
143
+ fflush (stdout);
144
+ terr.bold ();
145
+ fputs ("cadical: ", stderr);
146
+ terr.red (1);
147
+ fputs ("warning:", stderr);
148
+ terr.normal ();
149
+ fputc (' ', stderr);
150
+ va_list ap;
151
+ va_start (ap, fmt);
152
+ vfprintf (stderr, fmt, ap);
153
+ va_end (ap);
154
+ fputc ('\n', stderr);
155
+ fflush (stderr);
156
+ }
157
+
158
+ /*------------------------------------------------------------------------*/
159
+
160
+ void Internal::error_message_start () {
161
+ fflush (stdout);
162
+ terr.bold ();
163
+ fputs ("cadical: ", stderr);
164
+ terr.red (1);
165
+ fputs ("error:", stderr);
166
+ terr.normal ();
167
+ fputc (' ', stderr);
168
+ }
169
+
170
+ void Internal::error_message_end () {
171
+ fputc ('\n', stderr);
172
+ fflush (stderr);
173
+ // TODO add possibility to use call back instead.
174
+ exit (1);
175
+ }
176
+
177
+ void Internal::verror (const char *fmt, va_list &ap) {
178
+ error_message_start ();
179
+ vfprintf (stderr, fmt, ap);
180
+ error_message_end ();
181
+ }
182
+
183
+ void Internal::error (const char *fmt, ...) {
184
+ va_list ap;
185
+ va_start (ap, fmt);
186
+ verror (fmt, ap);
187
+ va_end (ap); // unreachable
188
+ }
189
+
190
+ /*------------------------------------------------------------------------*/
191
+
192
+ void fatal_message_start () {
193
+ fflush (stdout);
194
+ terr.bold ();
195
+ fputs ("cadical: ", stderr);
196
+ terr.red (1);
197
+ fputs ("fatal error:", stderr);
198
+ terr.normal ();
199
+ fputc (' ', stderr);
200
+ }
201
+
202
+ void fatal_message_end () {
203
+ fputc ('\n', stderr);
204
+ fflush (stderr);
205
+ abort ();
206
+ }
207
+
208
+ void fatal (const char *fmt, ...) {
209
+ fatal_message_start ();
210
+ va_list ap;
211
+ va_start (ap, fmt);
212
+ vfprintf (stderr, fmt, ap);
213
+ va_end (ap);
214
+ fatal_message_end ();
215
+ abort ();
216
+ }
217
+
218
+ } // namespace CaDiCaL