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,833 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ /*------------------------------------------------------------------------*/
6
+
7
+ inline unsigned LratChecker::l2u (int lit) {
8
+ assert (lit);
9
+ assert (lit != INT_MIN);
10
+ unsigned res = 2 * (abs (lit) - 1);
11
+ if (lit < 0)
12
+ res++;
13
+ return res;
14
+ }
15
+
16
+ signed char &LratChecker::mark (int lit) {
17
+ const unsigned u = l2u (lit);
18
+ assert (u < marks.size ());
19
+ return marks[u];
20
+ }
21
+
22
+ signed char &LratChecker::checked_lit (int lit) {
23
+ const unsigned u = l2u (lit);
24
+ assert (u < checked_lits.size ());
25
+ return checked_lits[u];
26
+ }
27
+
28
+ /*------------------------------------------------------------------------*/
29
+
30
+ LratCheckerClause *LratChecker::new_clause () {
31
+ const size_t size = imported_clause.size ();
32
+ assert (size <= UINT_MAX);
33
+ const int off = size ? 1 : 0;
34
+ const size_t bytes =
35
+ sizeof (LratCheckerClause) + (size - off) * sizeof (int);
36
+ LratCheckerClause *res = (LratCheckerClause *) new char[bytes];
37
+ res->garbage = false;
38
+ res->next = 0;
39
+ res->hash = last_hash;
40
+ res->id = last_id;
41
+ res->size = size;
42
+ res->used = false;
43
+ res->tautological = false;
44
+ int *literals = res->literals, *p = literals;
45
+ #ifndef NDEBUG
46
+ for (auto &b : checked_lits)
47
+ assert (!b); // = false;
48
+ #endif
49
+ for (const auto &lit : imported_clause) {
50
+ *p++ = lit;
51
+ checked_lit (-lit) = true;
52
+ if (checked_lit (lit)) {
53
+ LOG (imported_clause, "LRAT CHECKER clause tautological");
54
+ res->tautological = true;
55
+ }
56
+ }
57
+ for (const auto &lit : imported_clause)
58
+ checked_lit (-lit) = false;
59
+ num_clauses++;
60
+
61
+ return res;
62
+ }
63
+
64
+ void LratChecker::delete_clause (LratCheckerClause *c) {
65
+ assert (c);
66
+ if (!c->garbage) {
67
+ assert (num_clauses);
68
+ num_clauses--;
69
+ } else {
70
+ assert (num_garbage);
71
+ num_garbage--;
72
+ }
73
+ delete[] (char *) c;
74
+ }
75
+
76
+ void LratChecker::enlarge_clauses () {
77
+ assert (num_clauses == size_clauses);
78
+ const uint64_t new_size_clauses = size_clauses ? 2 * size_clauses : 1;
79
+ LOG ("LRAT CHECKER enlarging clauses of checker from %" PRIu64
80
+ " to %" PRIu64,
81
+ (uint64_t) size_clauses, (uint64_t) new_size_clauses);
82
+ LratCheckerClause **new_clauses;
83
+ new_clauses = new LratCheckerClause *[new_size_clauses];
84
+ clear_n (new_clauses, new_size_clauses);
85
+ for (uint64_t i = 0; i < size_clauses; i++) {
86
+ for (LratCheckerClause *c = clauses[i], *next; c; c = next) {
87
+ next = c->next;
88
+ const uint64_t h = reduce_hash (c->hash, new_size_clauses);
89
+ c->next = new_clauses[h];
90
+ new_clauses[h] = c;
91
+ }
92
+ }
93
+ delete[] clauses;
94
+ clauses = new_clauses;
95
+ size_clauses = new_size_clauses;
96
+ }
97
+
98
+ // Probably not necessary since we have no watches.
99
+ //
100
+ void LratChecker::collect_garbage_clauses () {
101
+
102
+ stats.collections++;
103
+
104
+ LOG ("LRAT CHECKER collecting %" PRIu64 " garbage clauses %.0f%%",
105
+ num_garbage, percent (num_garbage, num_clauses));
106
+
107
+ for (LratCheckerClause *c = garbage, *next; c; c = next)
108
+ next = c->next, delete_clause (c);
109
+
110
+ assert (!num_garbage);
111
+ garbage = 0;
112
+ }
113
+
114
+ /*------------------------------------------------------------------------*/
115
+
116
+ LratChecker::LratChecker (Internal *i)
117
+ : internal (i), size_vars (0), concluded (false), num_clauses (0),
118
+ num_finalized (0), num_garbage (0), size_clauses (0), clauses (0),
119
+ garbage (0), last_hash (0), last_id (0), current_id (0) {
120
+
121
+ // Initialize random number table for hash function.
122
+ //
123
+ Random random (42);
124
+ for (unsigned n = 0; n < num_nonces; n++) {
125
+ uint64_t nonce = random.next ();
126
+ if (!(nonce & 1))
127
+ nonce++;
128
+ assert (nonce), assert (nonce & 1);
129
+ nonces[n] = nonce;
130
+ }
131
+
132
+ memset (&stats, 0, sizeof (stats)); // Initialize statistics.
133
+ }
134
+
135
+ void LratChecker::connect_internal (Internal *i) {
136
+ internal = i;
137
+ LOG ("connected to internal");
138
+ }
139
+
140
+ LratChecker::~LratChecker () {
141
+ LOG ("LRAT CHECKER delete");
142
+ for (size_t i = 0; i < size_clauses; i++)
143
+ for (LratCheckerClause *c = clauses[i], *next; c; c = next)
144
+ next = c->next, delete_clause (c);
145
+ for (LratCheckerClause *c = garbage, *next; c; c = next)
146
+ next = c->next, delete_clause (c);
147
+ delete[] clauses;
148
+ }
149
+
150
+ /*------------------------------------------------------------------------*/
151
+
152
+ void LratChecker::enlarge_vars (int64_t idx) {
153
+
154
+ assert (0 < idx), assert (idx <= INT_MAX);
155
+
156
+ int64_t new_size_vars = size_vars ? 2 * size_vars : 2;
157
+ while (idx >= new_size_vars)
158
+ new_size_vars *= 2;
159
+ LOG ("LRAT CHECKER enlarging variables of checker from %" PRId64
160
+ " to %" PRId64 "",
161
+ size_vars, new_size_vars);
162
+
163
+ marks.resize (2 * new_size_vars);
164
+ checked_lits.resize (2 * new_size_vars);
165
+
166
+ assert (idx < new_size_vars);
167
+ size_vars = new_size_vars;
168
+ }
169
+
170
+ inline void LratChecker::import_literal (int lit) {
171
+ assert (lit);
172
+ assert (lit != INT_MIN);
173
+ int idx = abs (lit);
174
+ if (idx >= size_vars)
175
+ enlarge_vars (idx);
176
+ imported_clause.push_back (lit);
177
+ }
178
+
179
+ void LratChecker::import_clause (const vector<int> &c) {
180
+ for (const auto &lit : c)
181
+ import_literal (lit);
182
+ }
183
+
184
+ /*------------------------------------------------------------------------*/
185
+
186
+ uint64_t LratChecker::reduce_hash (uint64_t hash, uint64_t size) {
187
+ assert (size > 0);
188
+ unsigned shift = 32;
189
+ uint64_t res = hash;
190
+ while ((((uint64_t) 1) << shift) > size) {
191
+ res ^= res >> shift;
192
+ shift >>= 1;
193
+ }
194
+ res &= size - 1;
195
+ assert (res < size);
196
+ return res;
197
+ }
198
+
199
+ uint64_t LratChecker::compute_hash (const int64_t id) {
200
+ assert (id > 0);
201
+ unsigned j = id % num_nonces;
202
+ uint64_t tmp = nonces[j] * (uint64_t) id;
203
+ return last_hash = tmp;
204
+ }
205
+
206
+ LratCheckerClause **LratChecker::find (const int64_t id) {
207
+ stats.searches++;
208
+ LratCheckerClause **res, *c;
209
+ const uint64_t hash = compute_hash (id);
210
+ const uint64_t h = reduce_hash (hash, size_clauses);
211
+ for (res = clauses + h; (c = *res); res = &c->next) {
212
+ if (c->hash == hash && c->id == id) {
213
+ break;
214
+ }
215
+ stats.collisions++;
216
+ }
217
+ return res;
218
+ }
219
+
220
+ void LratChecker::insert () {
221
+ stats.insertions++;
222
+ if (num_clauses == size_clauses)
223
+ enlarge_clauses ();
224
+ const uint64_t h = reduce_hash (compute_hash (last_id), size_clauses);
225
+ LratCheckerClause *c = new_clause ();
226
+ c->next = clauses[h];
227
+ clauses[h] = c;
228
+ }
229
+
230
+ /*------------------------------------------------------------------------*/
231
+
232
+ // "strict" resolution check instead of rup check
233
+ bool LratChecker::check_resolution (vector<int64_t> proof_chain) {
234
+ if (proof_chain.empty ()) {
235
+ LOG ("LRAT CHECKER resolution check skipped clause is tautological");
236
+ return true;
237
+ }
238
+ // LOG (imported_clause, "LRAT CHECKER checking clause with resolution");
239
+ #ifndef NDEBUG
240
+ for (auto &b : checked_lits)
241
+ assert (!b); // = false;
242
+ #endif
243
+ if (!proof_chain.size () || proof_chain.back () < 0)
244
+ return false;
245
+ LratCheckerClause *c = *find (proof_chain.back ());
246
+ assert (c);
247
+ for (int *i = c->literals; i < c->literals + c->size; i++) {
248
+ int lit = *i;
249
+ checked_lit (lit) = true;
250
+ assert (!checked_lit (-lit));
251
+ }
252
+ for (auto p = proof_chain.end () - 2; p >= proof_chain.begin (); p--) {
253
+ auto &id = *p;
254
+ c = *find (id);
255
+ assert (c); // since this is checked in check already
256
+ for (int *i = c->literals; i < c->literals + c->size; i++) {
257
+ int lit = *i;
258
+ if (!checked_lit (-lit))
259
+ checked_lit (lit) = true;
260
+ else
261
+ checked_lit (-lit) = false;
262
+ }
263
+ }
264
+ for (const auto &lit : imported_clause) {
265
+ if (checked_lit (-lit)) {
266
+ LOG ("LRAT CHECKER resolution failed, resolved literal %d in learned "
267
+ "clause",
268
+ lit);
269
+ for (auto &b : checked_lits)
270
+ b = false; // clearing checking bits
271
+ return false;
272
+ }
273
+ if (!checked_lit (lit)) {
274
+ // learned clause is subsumed by resolvents
275
+ checked_lit (lit) = true;
276
+ }
277
+ checked_lit (-lit) = true;
278
+ }
279
+ bool failed = false;
280
+ for (int64_t lit = 1; lit < size_vars; lit++) {
281
+ bool ok = checked_lit (lit) && checked_lit (-lit);
282
+ ok = ok || (!checked_lit (lit) && !checked_lit (-lit));
283
+ checked_lit (lit) = checked_lit (-lit) = false;
284
+ if (!ok && !failed) {
285
+ LOG ("LRAT CHECKER resolution failed, learned clause does not match "
286
+ "on "
287
+ "variable %" PRId64,
288
+ lit);
289
+ failed = true;
290
+ }
291
+ }
292
+
293
+ return !failed;
294
+ }
295
+
296
+ /*------------------------------------------------------------------------*/
297
+
298
+ bool LratChecker::check (vector<int64_t> proof_chain) {
299
+ LOG (imported_clause, "LRAT CHECKER checking clause");
300
+ stats.checks++;
301
+ #ifndef NDEBUG
302
+ for (auto &b : checked_lits)
303
+ assert (!b); // = false;
304
+ #endif
305
+ bool taut = false;
306
+ for (const auto &lit : imported_clause) { // tautological clauses
307
+ checked_lit (-lit) = true;
308
+ if (checked_lit (lit)) {
309
+ LOG (imported_clause, "LRAT CHECKER clause tautological");
310
+ assert (!proof_chain.size ()); // would be unnecessary hence a bug
311
+ taut = true;
312
+ }
313
+ }
314
+ // we assume that we can have RUP and ER clauses. One side of the ER
315
+ // clauses are pure, i.e. without any chain, the long clause is blocked,
316
+ // so the chain consists only of negative ids. Therefore these checks are
317
+ // enough to distiguish between RUP and ER
318
+ if (taut || !proof_chain.size () || proof_chain.back () < 0) {
319
+ for (const auto &lit : imported_clause) { // tautological clauses
320
+ checked_lit (-lit) = false;
321
+ }
322
+ return taut;
323
+ }
324
+
325
+ vector<LratCheckerClause *> used_clauses;
326
+ bool checking = false;
327
+ for (auto &id : proof_chain) {
328
+ LratCheckerClause *c = *find (id);
329
+ if (!c) {
330
+ LOG ("LRAT CHECKER LRAT failed. Did not find clause with id %" PRIu64,
331
+ id);
332
+ break;
333
+ }
334
+ if (c->tautological) {
335
+ LOG ("LRAT CHECKER LRAT failed. Clause with id %" PRId64
336
+ " is tautological",
337
+ id);
338
+ break;
339
+ }
340
+ used_clauses.push_back (c);
341
+ if (c->used) {
342
+ LOG ("LRAT CHECKER LRAT failed. Id %" PRId64
343
+ " was used multiple times",
344
+ id);
345
+ break;
346
+ } else
347
+ c->used = true;
348
+ int unit = 0;
349
+ for (int *i = c->literals; i < c->literals + c->size; i++) {
350
+ int lit = *i;
351
+ if (checked_lit (-lit))
352
+ continue;
353
+ if (unit && unit != lit) {
354
+ unit = INT_MIN; // multiple unfalsified literals
355
+ break;
356
+ }
357
+ unit = lit; // potential unit
358
+ }
359
+ if (unit == INT_MIN) {
360
+ LOG ("LRAT CHECKER check failed, found non unit clause %" PRId64, id);
361
+ break;
362
+ }
363
+ if (!unit) {
364
+ LOG ("LRAT CHECKER check succeded, clause falsified %" PRId64, id);
365
+ checking = true;
366
+ break;
367
+ }
368
+ // LOG ("LRAT CHECKER found unit clause %" PRIu64 ", assign %d", id,
369
+ // unit);
370
+ checked_lit (unit) = true;
371
+ }
372
+ for (auto &lc : used_clauses) {
373
+ lc->used = false;
374
+ }
375
+ for (auto &b : checked_lits)
376
+ b = false;
377
+ if (!checking) {
378
+ LOG ("LRAT CHECKER failed, no conflict found");
379
+ return false; // check failed because no empty clause was found
380
+ }
381
+ return true;
382
+ }
383
+
384
+ bool LratChecker::check_blocked (vector<int64_t> proof_chain) {
385
+ for (const auto &lit : imported_clause) {
386
+ checked_lit (-lit) = true;
387
+ mark (-lit) = true;
388
+ }
389
+ for (size_t i = 0; i < size_clauses; i++) {
390
+ for (LratCheckerClause *c = clauses[i], *next; c; c = next) {
391
+ next = c->next;
392
+ if (c->garbage)
393
+ continue;
394
+ // if c is part of the proof chain its id occurs negatively there.
395
+ if (std::find (proof_chain.begin (), proof_chain.end (), -c->id) !=
396
+ proof_chain.end ()) {
397
+ // clause needs to be blocked
398
+ unsigned count = 0;
399
+ vector<int> candidates;
400
+ for (unsigned i = 0; i < c->size; i++) {
401
+ const int lit = c->literals[i];
402
+ if (checked_lit (lit)) {
403
+ count++;
404
+ }
405
+ if (mark (lit)) {
406
+ candidates.push_back (lit);
407
+ }
408
+ }
409
+ if (count < 2) {
410
+ // check failed
411
+ for (const auto &lit : imported_clause) {
412
+ checked_lit (-lit) = false;
413
+ mark (-lit) = false;
414
+ }
415
+ return false;
416
+ } else {
417
+ // all literals outside of candidates are not valid RAT candidates
418
+ for (auto &lit : imported_clause) {
419
+ if (mark (-lit) &&
420
+ std::find (candidates.begin (), candidates.end (), -lit) ==
421
+ candidates.end ()) {
422
+ mark (-lit) = false;
423
+ }
424
+ }
425
+ }
426
+ } else {
427
+ // any literal contained in the clause is not a valid RAT candidate
428
+ for (unsigned i = 0; i < c->size; i++) {
429
+ const int lit = c->literals[i];
430
+ if (checked_lit (lit)) {
431
+ mark (lit) = false;
432
+ }
433
+ }
434
+ }
435
+ }
436
+ }
437
+ bool success = false;
438
+ for (const auto &lit : imported_clause) {
439
+ if (mark (-lit))
440
+ success = true;
441
+ checked_lit (-lit) = mark (-lit) = false;
442
+ }
443
+ return success;
444
+ }
445
+
446
+ /*------------------------------------------------------------------------*/
447
+
448
+ void LratChecker::add_original_clause (int64_t id, bool,
449
+ const vector<int> &c, bool restore) {
450
+ START (checking);
451
+ LOG (c, "LRAT CHECKER addition of original clause[%" PRId64 "]", id);
452
+ if (restore)
453
+ restore_clause (id, c);
454
+ stats.added++;
455
+ stats.original++;
456
+ import_clause (c);
457
+ last_id = id;
458
+ if (!restore && id == 1 + current_id)
459
+ current_id = id;
460
+
461
+ if (size_clauses && !restore) {
462
+ LratCheckerClause **p = find (id), *d = *p;
463
+ if (d) {
464
+ fatal_message_start ();
465
+ fputs ("different clause with id ", stderr);
466
+ fprintf (stderr, "%" PRId64, id);
467
+ fputs (" already present\n", stderr);
468
+ fatal_message_end ();
469
+ }
470
+ }
471
+ assert (id);
472
+ insert ();
473
+ imported_clause.clear ();
474
+ STOP (checking);
475
+ }
476
+
477
+ void LratChecker::add_derived_clause (int64_t id, bool, int w,
478
+ const vector<int> &c,
479
+ const vector<int64_t> &proof_chain) {
480
+ START (checking);
481
+ LOG (c, "LRAT CHECKER addition of derived %d clause[%" PRId64 "]", w, id);
482
+ assert (!w || c[0] == w);
483
+ if (w)
484
+ stats.rat++;
485
+ stats.added++;
486
+ stats.derived++;
487
+ import_clause (c);
488
+ last_id = id;
489
+ assert (id == current_id + 1);
490
+ assert (!w || w == c[0]);
491
+ current_id = id;
492
+ if (size_clauses) {
493
+ LratCheckerClause **p = find (id), *d = *p;
494
+ if (d) {
495
+ fatal_message_start ();
496
+ fputs ("different clause with id ", stderr);
497
+ fprintf (stderr, "%" PRId64, id);
498
+ fputs (" already present\n", stderr);
499
+ fatal_message_end ();
500
+ }
501
+ }
502
+ assert (id);
503
+ bool failed = true;
504
+ if (check (proof_chain) && check_resolution (proof_chain)) {
505
+ failed = false;
506
+ } else if (check_blocked (proof_chain)) {
507
+ failed = false;
508
+ }
509
+ if (failed) {
510
+ LOG (proof_chain, "LRAT CHECKER check failed with chain");
511
+ #ifdef LOGGING
512
+ for (const auto &pid : proof_chain) {
513
+ const int64_t aid = abs (pid);
514
+ LratCheckerClause **p = find (aid), *d = *p;
515
+ LOG (d->literals, d->size, "clause[%" PRId64 "]", pid);
516
+ }
517
+ #endif
518
+ fatal_message_start ();
519
+ fputs ("failed to check derived clause:\n", stderr);
520
+ for (const auto &lit : imported_clause)
521
+ fprintf (stderr, "%d ", lit);
522
+ fputc ('0', stderr);
523
+ fatal_message_end ();
524
+ } else
525
+ insert ();
526
+ imported_clause.clear ();
527
+ STOP (checking);
528
+ }
529
+
530
+ void LratChecker::add_assumption_clause (int64_t id, const vector<int> &c,
531
+ const vector<int64_t> &chain) {
532
+ for (auto &lit : c) {
533
+ if (std::find (assumptions.begin (), assumptions.end (), -lit) !=
534
+ assumptions.end ())
535
+ continue;
536
+ if (std::find (constraint.begin (), constraint.end (), -lit) !=
537
+ constraint.end ())
538
+ continue;
539
+ fatal_message_start ();
540
+ fputs ("clause contains non assumptions or constraint literals\n",
541
+ stderr);
542
+ fatal_message_end ();
543
+ }
544
+ add_derived_clause (id, true, 0, c, chain);
545
+ delete_clause (id, true, c);
546
+ assumption_clauses.push_back (id);
547
+ }
548
+
549
+ void LratChecker::add_assumption (int a) { assumptions.push_back (a); }
550
+
551
+ void LratChecker::add_constraint (const vector<int> &c) {
552
+ constraint.clear ();
553
+ for (auto &lit : c) {
554
+ assert (lit);
555
+ if (std::find (constraint.begin (), constraint.end (), lit) !=
556
+ constraint.end ())
557
+ continue;
558
+ constraint.push_back (lit);
559
+ }
560
+ }
561
+
562
+ void LratChecker::reset_assumptions () {
563
+ assumption_clauses.clear ();
564
+ assumptions.clear ();
565
+ concluded = false;
566
+ // constraint.clear ();
567
+ }
568
+
569
+ void LratChecker::conclude_unsat (ConclusionType conclusion,
570
+ const vector<int64_t> &ids) {
571
+ if (concluded) {
572
+ fatal_message_start ();
573
+ fputs ("already concluded\n", stderr);
574
+ fatal_message_end ();
575
+ }
576
+ concluded = true;
577
+ if (conclusion == CONFLICT) {
578
+ LratCheckerClause **p = find (ids.back ()), *d = *p;
579
+ if (!d || d->size) {
580
+ fatal_message_start ();
581
+ fputs ("empty clause not in proof\n", stderr);
582
+ fatal_message_end ();
583
+ }
584
+ return;
585
+ } else if (conclusion == ASSUMPTIONS) {
586
+ if (ids.size () != 1 || assumption_clauses.size () != 1) {
587
+ fatal_message_start ();
588
+ fputs ("expected exactly one assumption clause\n", stderr);
589
+ fatal_message_end ();
590
+ }
591
+ if (ids.back () != assumption_clauses.back ()) {
592
+ fatal_message_start ();
593
+ fputs ("conclusion is not an assumption clause\n", stderr);
594
+ fatal_message_end ();
595
+ }
596
+ return;
597
+ } else {
598
+ assert (conclusion == CONSTRAINT);
599
+ if (constraint.size () != ids.size ()) {
600
+ fatal_message_start ();
601
+ fputs ("not complete conclusion given for constraint\n", stderr);
602
+ fputs ("The constraint contains the literals: ", stderr);
603
+ for (auto c : constraint) {
604
+ fprintf (stderr, "%d ", c);
605
+ }
606
+
607
+ fputs ("\nThe ids are: ", stderr);
608
+ for (auto c : ids) {
609
+ fprintf (stderr, "%" PRId64 " ", c);
610
+ }
611
+ fatal_message_end ();
612
+ }
613
+ for (auto &id : ids) {
614
+ if (std::find (assumption_clauses.begin (), assumption_clauses.end (),
615
+ id) != assumption_clauses.end ())
616
+ continue;
617
+ fatal_message_start ();
618
+ fputs ("assumption clause for constraint missing\n", stderr);
619
+ fatal_message_end ();
620
+ }
621
+ }
622
+ }
623
+
624
+ /*------------------------------------------------------------------------*/
625
+
626
+ void LratChecker::delete_clause (int64_t id, bool, const vector<int> &c) {
627
+ START (checking);
628
+ LOG (c, "LRAT CHECKER checking deletion of clause[%" PRId64 "]", id);
629
+ stats.deleted++;
630
+ import_clause (c);
631
+ last_id = id;
632
+ LratCheckerClause **p = find (id), *d = *p;
633
+ if (d) {
634
+ for (const auto &lit : imported_clause)
635
+ mark (lit) = true;
636
+ const int *dp = d->literals;
637
+ for (unsigned i = 0; i < d->size; i++) {
638
+ int lit = *(dp + i);
639
+ if (!mark (lit)) { // should never happen since ids
640
+ fatal_message_start (); // are unique.
641
+ fputs ("deleted clause not in proof:\n", stderr);
642
+ for (const auto &lit : imported_clause)
643
+ fprintf (stderr, "%d ", lit);
644
+ fputc ('0', stderr);
645
+ fatal_message_end ();
646
+ }
647
+ }
648
+ for (const auto &lit : imported_clause)
649
+ mark (lit) = false;
650
+
651
+ // Remove from hash table, mark as garbage, connect to garbage list.
652
+ num_garbage++;
653
+ assert (num_clauses);
654
+ num_clauses--;
655
+ *p = d->next;
656
+ d->next = garbage;
657
+ garbage = d;
658
+ d->garbage = true;
659
+
660
+ // If there are enough garbage clauses collect them.
661
+ // TODO: probably can just delete clause directly without
662
+ // specific garbage collection phase.
663
+ if (num_garbage > 0.5 * max ((size_t) size_clauses, (size_t) size_vars))
664
+ collect_garbage_clauses ();
665
+ } else {
666
+ fatal_message_start ();
667
+ fputs ("deleted clause not in proof:\n", stderr);
668
+ for (const auto &lit : imported_clause)
669
+ fprintf (stderr, "%d ", lit);
670
+ fputc ('0', stderr);
671
+ fatal_message_end ();
672
+ }
673
+ imported_clause.clear ();
674
+ STOP (checking);
675
+ }
676
+
677
+ /*------------------------------------------------------------------------*/
678
+
679
+ void LratChecker::weaken_minus (int64_t id, const vector<int> &c) {
680
+ LOG (c, "LRAT CHECKER saving clause[%" PRId64 "] to restore later", id);
681
+ import_clause (c);
682
+
683
+ assert (id <= current_id);
684
+ last_id = id;
685
+ LratCheckerClause **p = find (id), *d = *p;
686
+ if (d) {
687
+ for (const auto &lit : imported_clause)
688
+ mark (lit) = true;
689
+ const int *dp = d->literals;
690
+ for (unsigned i = 0; i < d->size; i++) {
691
+ int lit = *(dp + i);
692
+ if (!mark (lit)) { // should never happen since ids
693
+ fatal_message_start (); // are unique.
694
+ fputs ("deleted clause not in proof:\n", stderr);
695
+ for (const auto &lit : imported_clause)
696
+ fprintf (stderr, "%d ", lit);
697
+ fputc ('0', stderr);
698
+ fatal_message_end ();
699
+ }
700
+ }
701
+ for (const auto &lit : imported_clause)
702
+ mark (lit) = false;
703
+ } else {
704
+ fatal_message_start ();
705
+ fputs ("weakened clause not in proof:\n", stderr);
706
+ for (const auto &lit : imported_clause)
707
+ fprintf (stderr, "%d ", lit);
708
+ fputc ('0', stderr);
709
+ fatal_message_end ();
710
+ }
711
+ imported_clause.clear ();
712
+
713
+ vector<int> e = c;
714
+ sort (begin (e), end (e));
715
+ clauses_to_reconstruct[id] = e;
716
+ }
717
+
718
+ void LratChecker::restore_clause (int64_t id, const vector<int> &c) {
719
+ LOG (c, "LRAT CHECKER check of restoration of clause[%" PRId64 "]", id);
720
+ if (clauses_to_reconstruct.find (id) == end (clauses_to_reconstruct)) {
721
+ fatal_message_start ();
722
+ fputs ("restoring clauses not deleted previously:\n", stderr);
723
+ for (const auto &lit : c)
724
+ fprintf (stderr, "%d ", lit);
725
+ fputc ('0', stderr);
726
+ fatal_message_end ();
727
+ }
728
+ vector<int> e = c;
729
+ sort (begin (e), end (e));
730
+ const vector<int> &d = clauses_to_reconstruct.find (id)->second;
731
+ bool eq = true;
732
+ if (c.size () != d.size ()) {
733
+ eq = false;
734
+ }
735
+
736
+ for (std::vector<int>::size_type i = 0; i < e.size () && eq; ++i) {
737
+ eq = (e[i] == d[i]);
738
+ }
739
+
740
+ if (!eq) {
741
+ fatal_message_start ();
742
+ fputs ("restoring clause that is different than the one imported:\n",
743
+ stderr);
744
+ for (const auto &lit : c)
745
+ fprintf (stderr, "%d ", lit);
746
+ fputc ('0', stderr);
747
+ fputs ("vs:\n", stderr);
748
+ for (const auto &lit : d)
749
+ fprintf (stderr, "%d ", lit);
750
+ fputc ('0', stderr);
751
+ fatal_message_end ();
752
+ }
753
+
754
+ clauses_to_reconstruct.erase (id);
755
+ }
756
+
757
+ void LratChecker::finalize_clause (int64_t id, const vector<int> &c) {
758
+ START (checking);
759
+ LOG (c, "LRAT CHECKER checking finalize of clause[%" PRId64 "]", id);
760
+ stats.finalized++;
761
+ num_finalized++;
762
+ import_clause (c);
763
+ assert (id <= current_id);
764
+ last_id = id;
765
+ LratCheckerClause **p = find (id), *d = *p;
766
+ if (d) {
767
+ for (const auto &lit : imported_clause)
768
+ mark (lit) = true;
769
+ const int *dp = d->literals;
770
+ for (unsigned i = 0; i < d->size; i++) {
771
+ int lit = *(dp + i);
772
+ if (!mark (lit)) { // should never happen since ids
773
+ fatal_message_start (); // are unique.
774
+ fputs ("deleted clause not in proof:\n", stderr);
775
+ for (const auto &lit : imported_clause)
776
+ fprintf (stderr, "%d ", lit);
777
+ fputc ('0', stderr);
778
+ fatal_message_end ();
779
+ }
780
+ }
781
+ for (const auto &lit : imported_clause)
782
+ mark (lit) = false;
783
+
784
+ } else {
785
+ fatal_message_start ();
786
+ fputs ("deleted clause not in proof:\n", stderr);
787
+ for (const auto &lit : imported_clause)
788
+ fprintf (stderr, "%d ", lit);
789
+ fputc ('0', stderr);
790
+ fatal_message_end ();
791
+ }
792
+ imported_clause.clear ();
793
+ STOP (checking);
794
+ }
795
+
796
+ // check if all clauses have been deleted
797
+ void LratChecker::report_status (int, int64_t) {
798
+ START (checking);
799
+ if (num_finalized == num_clauses) {
800
+ num_finalized = 0;
801
+ LOG ("LRAT CHECKER successful finalize check, all clauses have been "
802
+ "deleted");
803
+ } else {
804
+ fatal_message_start ();
805
+ fputs ("finalize check failed ", stderr);
806
+ fprintf (stderr, "%" PRIu64, num_clauses);
807
+ fputs (" are not finalized", stderr);
808
+ fatal_message_end ();
809
+ }
810
+ STOP (checking);
811
+ }
812
+
813
+ /*------------------------------------------------------------------------*/
814
+
815
+ void LratChecker::dump () {
816
+ int max_var = 0;
817
+ for (uint64_t i = 0; i < size_clauses; i++)
818
+ for (LratCheckerClause *c = clauses[i]; c; c = c->next)
819
+ for (unsigned i = 0; i < c->size; i++)
820
+ if (abs (c->literals[i]) > max_var)
821
+ max_var = abs (c->literals[i]);
822
+ printf ("p cnf %d %" PRIu64 "\n", max_var, num_clauses);
823
+ for (uint64_t i = 0; i < size_clauses; i++)
824
+ for (LratCheckerClause *c = clauses[i]; c; c = c->next) {
825
+ for (unsigned i = 0; i < c->size; i++)
826
+ printf ("%d ", c->literals[i]);
827
+ printf ("0\n");
828
+ }
829
+ }
830
+
831
+ void LratChecker::begin_proof (int64_t id) { current_id = id; }
832
+
833
+ } // namespace CaDiCaL