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,689 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ /*------------------------------------------------------------------------*/
6
+
7
+ // Signed marking or unmarking of a clause or the global 'clause'.
8
+
9
+ void Internal::mark (Clause *c) {
10
+ for (const auto &lit : *c)
11
+ mark (lit);
12
+ }
13
+
14
+ void Internal::mark2 (Clause *c) {
15
+ for (const auto &lit : *c)
16
+ mark2 (lit);
17
+ }
18
+
19
+ void Internal::unmark (Clause *c) {
20
+ for (const auto &lit : *c)
21
+ unmark (lit);
22
+ }
23
+
24
+ void Internal::mark_clause () {
25
+ for (const auto &lit : clause)
26
+ mark (lit);
27
+ }
28
+
29
+ void Internal::unmark_clause () {
30
+ for (const auto &lit : clause)
31
+ unmark (lit);
32
+ }
33
+
34
+ /*------------------------------------------------------------------------*/
35
+
36
+ // Mark the variables of an irredundant clause to 'have been removed', which
37
+ // will trigger these variables to be considered again in the next bounded
38
+ // variable elimination phase. This is called from 'mark_garbage' below.
39
+ // Note that 'mark_removed (int lit)' will also mark the blocking flag of
40
+ // '-lit' to trigger reconsidering blocking clauses on '-lit'.
41
+
42
+ void Internal::mark_removed (Clause *c, int except) {
43
+ LOG (c, "marking removed");
44
+ assert (!c->redundant);
45
+ for (const auto &lit : *c)
46
+ if (lit != except)
47
+ mark_removed (lit);
48
+ }
49
+
50
+ // Mark the variables of a (redundant or irredundant) clause to 'have been
51
+ // added', which triggers clauses with such a variables, to be considered
52
+ // both as a subsumed or subsuming clause in the next subsumption phase.
53
+ // This function is called from 'new_clause' below as well as in situations
54
+ // where a clause is shrunken (and thus needs to be at least considered
55
+ // again to subsume a larger clause). We also use this to tell
56
+ // 'ternary' preprocessing reconsider clauses on an added literal as well as
57
+ // trying to block clauses on it.
58
+
59
+ inline void Internal::mark_added (int lit, int size, bool redundant) {
60
+ mark_subsume (lit);
61
+ if (size == 3)
62
+ mark_ternary (lit);
63
+ if (!redundant)
64
+ mark_block (lit);
65
+ if ((!redundant || size == 2))
66
+ mark_factor (lit);
67
+ }
68
+
69
+ void Internal::mark_added (Clause *c) {
70
+ LOG (c, "marking added");
71
+ assert (likely_to_be_kept_clause (c));
72
+ for (const auto &lit : *c)
73
+ mark_added (lit, c->size, c->redundant);
74
+ }
75
+
76
+ /*------------------------------------------------------------------------*/
77
+
78
+ Clause *Internal::new_clause (bool red, int glue) {
79
+
80
+ assert (clause.size () <= (size_t) INT_MAX);
81
+ const int size = (int) clause.size ();
82
+ assert (size >= 2);
83
+
84
+ if (glue > size)
85
+ glue = size;
86
+
87
+ size_t bytes = Clause::bytes (size);
88
+ Clause *c = (Clause *) new char[bytes];
89
+ DeferDeleteArray<char> clause_delete ((char *) c);
90
+
91
+ c->id = ++clause_id;
92
+
93
+ c->conditioned = false;
94
+ c->covered = false;
95
+ c->enqueued = false;
96
+ c->frozen = false;
97
+ c->garbage = false;
98
+ c->gate = false;
99
+ c->hyper = false;
100
+ c->instantiated = false;
101
+ c->moved = false;
102
+ c->reason = false;
103
+ c->redundant = red;
104
+ c->transred = false;
105
+ c->subsume = false;
106
+ c->swept = false;
107
+ c->flushed = false;
108
+ c->vivified = false;
109
+ c->vivify = false;
110
+ c->used = 0;
111
+
112
+ c->glue = glue;
113
+ c->size = size;
114
+ c->pos = 2;
115
+
116
+ for (int i = 0; i < size; i++)
117
+ c->literals[i] = clause[i];
118
+
119
+ // Just checking that we did not mess up our sophisticated memory layout.
120
+ // This might be compiler dependent though. Crucial for correctness.
121
+ //
122
+ assert (c->bytes () == bytes);
123
+
124
+ stats.current.total++;
125
+ stats.added.total++;
126
+
127
+ if (red) {
128
+ stats.current.redundant++;
129
+ stats.added.redundant++;
130
+ } else {
131
+ stats.irrlits += size;
132
+ stats.current.irredundant++;
133
+ stats.added.irredundant++;
134
+ }
135
+
136
+ clauses.push_back (c);
137
+ clause_delete.release ();
138
+ LOG (c, "new pointer %p", (void *) c);
139
+
140
+ if (likely_to_be_kept_clause (c))
141
+ mark_added (c);
142
+
143
+ return c;
144
+ }
145
+
146
+ /*------------------------------------------------------------------------*/
147
+
148
+ void Internal::promote_clause (Clause *c, int new_glue) {
149
+ assert (c->redundant);
150
+ assert (new_glue);
151
+ const int tier1limit = tier1[false];
152
+ const int tier2limit = max (tier1limit, tier2[false]);
153
+ if (!c->redundant)
154
+ return;
155
+ if (c->hyper)
156
+ return;
157
+ int old_glue = c->glue;
158
+ if (new_glue >= old_glue)
159
+ return;
160
+ c->used = max_used;
161
+ if (old_glue > tier1limit && new_glue <= tier1limit) {
162
+ LOG (c, "promoting with new glue %d to tier1", new_glue);
163
+ stats.promoted1++;
164
+ } else if (old_glue > tier2limit && new_glue <= tier2limit) {
165
+ LOG (c, "promoting with new glue %d to tier2", new_glue);
166
+ stats.promoted2++;
167
+ } else if (old_glue <= tier2limit)
168
+ LOG (c, "keeping with new glue %d in tier2", new_glue);
169
+ else
170
+ LOG (c, "keeping with new glue %d in tier3", new_glue);
171
+ stats.improvedglue++;
172
+ c->glue = new_glue;
173
+ }
174
+ /*------------------------------------------------------------------------*/
175
+
176
+ void Internal::promote_clause_glue_only (Clause *c, int new_glue) {
177
+ assert (c->redundant);
178
+ assert (new_glue);
179
+ if (c->hyper)
180
+ return;
181
+ int old_glue = c->glue;
182
+ const int tier1limit = tier1[false];
183
+ const int tier2limit = max (tier1limit, tier2[false]);
184
+ if (new_glue >= old_glue)
185
+ return;
186
+ if (new_glue <= tier1limit) {
187
+ LOG (c, "promoting with new glue %d to tier1", new_glue);
188
+ stats.promoted1++;
189
+ } else if (old_glue > tier2limit && new_glue <= tier2limit) {
190
+ LOG (c, "promoting with new glue %d to tier2", new_glue);
191
+ stats.promoted2++;
192
+ } else if (old_glue <= tier2limit)
193
+ LOG (c, "keeping with new glue %d in tier2", new_glue);
194
+ else
195
+ LOG (c, "keeping with new glue %d in tier3", new_glue);
196
+ stats.improvedglue++;
197
+ c->glue = new_glue;
198
+ }
199
+
200
+ /*------------------------------------------------------------------------*/
201
+
202
+ // Shrinking a clause, e.g., removing one or more literals, requires to fix
203
+ // the 'pos' field, if it exists and points after the new last literal. We
204
+ // also have adjust the global statistics counter of irredundant literals
205
+ // for irredundant clauses, and also adjust the glue value of redundant
206
+ // clauses if the size becomes smaller than the glue. Also mark the
207
+ // literals in the resulting clause as 'added'. The result is the number of
208
+ // (aligned) removed bytes, resulting from shrinking the clause.
209
+ //
210
+ size_t Internal::shrink_clause (Clause *c, int new_size) {
211
+ if (opts.check && is_external_forgettable (c->id))
212
+ mark_garbage_external_forgettable (c->id);
213
+ assert (new_size >= 2);
214
+ int old_size = c->size;
215
+ assert (new_size < old_size);
216
+ #ifndef NDEBUG
217
+ for (int i = c->size; i < new_size; i++)
218
+ c->literals[i] = 0;
219
+ #endif
220
+
221
+ if (c->pos >= new_size)
222
+ c->pos = 2;
223
+
224
+ size_t old_bytes = c->bytes ();
225
+ c->size = new_size;
226
+ size_t new_bytes = c->bytes ();
227
+ size_t res = old_bytes - new_bytes;
228
+
229
+ if (c->redundant)
230
+ promote_clause_glue_only (c, min (c->size - 1, c->glue));
231
+ else {
232
+ int delta_size = old_size - new_size;
233
+ assert (stats.irrlits >= delta_size);
234
+ stats.irrlits -= delta_size;
235
+ }
236
+
237
+ if (likely_to_be_kept_clause (c))
238
+ mark_added (c);
239
+
240
+ return res;
241
+ }
242
+
243
+ // This is the 'raw' deallocation of a clause. If the clause is in the
244
+ // arena nothing happens. If the clause is not in the arena its memory is
245
+ // reclaimed immediately.
246
+
247
+ void Internal::deallocate_clause (Clause *c) {
248
+ char *p = (char *) c;
249
+ if (arena.contains (p))
250
+ return;
251
+ LOG (c, "deallocate pointer %p", (void *) c);
252
+ delete[] p;
253
+ }
254
+
255
+ void Internal::delete_clause (Clause *c) {
256
+ LOG (c, "delete pointer %p", (void *) c);
257
+ size_t bytes = c->bytes ();
258
+ stats.collected += bytes;
259
+ if (c->garbage) {
260
+ assert (stats.garbage.bytes >= (int64_t) bytes);
261
+ stats.garbage.bytes -= bytes;
262
+ assert (stats.garbage.clauses > 0);
263
+ stats.garbage.clauses--;
264
+ assert (stats.garbage.literals >= c->size);
265
+ stats.garbage.literals -= c->size;
266
+
267
+ // See the discussion in 'propagate' on avoiding to eagerly trace binary
268
+ // clauses as deleted (produce 'd ...' lines) as soon they are marked
269
+ // garbage. We avoid this and only trace them as deleted when they are
270
+ // actually deleted here. This allows the solver to propagate binary
271
+ // garbage clauses without producing incorrect 'd' lines. The effect
272
+ // from the proof perspective is that the deletion of these binary
273
+ // clauses occurs later in the proof file.
274
+ //
275
+ if (proof && c->size == 2 && !c->flushed) {
276
+ proof->delete_clause (c);
277
+ }
278
+ }
279
+ deallocate_clause (c);
280
+ }
281
+
282
+ // We want to eagerly update statistics as soon clauses are marked garbage.
283
+ // Otherwise 'report' for instance gives wrong numbers after 'subsume'
284
+ // before the next 'reduce'. Thus we factored out marking and accounting
285
+ // for garbage clauses.
286
+ //
287
+ // Eagerly deleting clauses instead is problematic, since references to
288
+ // these clauses need to be flushed, which is too costly to do eagerly.
289
+ //
290
+ // We also update garbage statistics at this point. This helps to
291
+ // determine whether the garbage collector should be called during for
292
+ // instance bounded variable elimination, which usually generates lots of
293
+ // garbage clauses.
294
+ //
295
+ // In order not to miss any update to these clause statistics we call
296
+ // 'check_clause_stats' after garbage collection in debugging mode.
297
+ //
298
+ void Internal::mark_garbage (Clause *c) {
299
+
300
+ assert (!c->garbage);
301
+
302
+ // Delay tracing deletion of binary clauses. See the discussion above in
303
+ // 'delete_clause' and also in 'propagate'.
304
+ //
305
+ if (proof && (c->size != 2 || !watching ())) {
306
+ c->flushed = true;
307
+ proof->delete_clause (c);
308
+ }
309
+
310
+ // Because of the internal model checking, external forgettable clauses
311
+ // must be marked as removed already upon mark_garbage, can not wait until
312
+ // actual deletion.
313
+ if (opts.check && is_external_forgettable (c->id))
314
+ mark_garbage_external_forgettable (c->id);
315
+
316
+ assert (stats.current.total > 0);
317
+ stats.current.total--;
318
+
319
+ size_t bytes = c->bytes ();
320
+ if (c->redundant) {
321
+ assert (stats.current.redundant > 0);
322
+ stats.current.redundant--;
323
+ } else {
324
+ assert (stats.current.irredundant > 0);
325
+ stats.current.irredundant--;
326
+ assert (stats.irrlits >= c->size);
327
+ stats.irrlits -= c->size;
328
+ mark_removed (c);
329
+ }
330
+ stats.garbage.bytes += bytes;
331
+ stats.garbage.clauses++;
332
+ stats.garbage.literals += c->size;
333
+ c->garbage = true;
334
+ c->used = 0;
335
+
336
+ LOG (c, "marked garbage pointer %p", (void *) c);
337
+ }
338
+
339
+ /*------------------------------------------------------------------------*/
340
+
341
+ // Almost the same function as 'search_assign' except that we do not pretend
342
+ // to learn a new unit clause (which was confusing in log files).
343
+
344
+ void Internal::assign_original_unit (int64_t id, int lit) {
345
+ assert (!level || opts.chrono);
346
+ assert (!unsat);
347
+ const int idx = vidx (lit);
348
+ assert (!vals[idx]);
349
+ assert (!flags (idx).eliminated ());
350
+ Var &v = var (idx);
351
+ v.level = 0;
352
+ v.trail = (int) trail.size ();
353
+ v.reason = 0;
354
+ const signed char tmp = sign (lit);
355
+ set_val (idx, tmp);
356
+ trail.push_back (lit);
357
+ num_assigned++;
358
+ const unsigned uidx = vlit (lit);
359
+ if (lrat || frat)
360
+ unit_clauses (uidx) = id;
361
+ LOG ("original unit assign %d", lit);
362
+ assert (num_assigned == trail.size () || level);
363
+ mark_fixed (lit);
364
+ if (level)
365
+ return;
366
+ if (propagate ())
367
+ return;
368
+ assert (conflict);
369
+ LOG ("propagation of original unit results in conflict");
370
+ learn_empty_clause ();
371
+ }
372
+
373
+ // New clause added through the API, e.g., while parsing a DIMACS file.
374
+ // Also used by external_propagate in various different modes.
375
+ // clause, original, lrat_chain and external->eclause are set.
376
+ // from_propagator and force_no_backtrack change the behaviour.
377
+ // sometimes the pointer to the new clause is needed, therefore it is
378
+ // made sure that newest_clause points to the new clause upon return.
379
+
380
+ void Internal::add_new_original_clause (int64_t id) {
381
+
382
+ if (!from_propagator && level && !opts.ilb) {
383
+ backtrack ();
384
+ } else if (changed_val) {
385
+ assert (val (changed_val));
386
+ int new_level = var (changed_val).level - 1;
387
+ assert (new_level >= 0);
388
+ backtrack (new_level);
389
+ }
390
+ assert (!changed_val);
391
+ LOG (original, "original clause");
392
+ assert (clause.empty ());
393
+ bool skip = false;
394
+ unordered_set<int> learned_levels;
395
+ size_t unassigned = 0;
396
+ newest_clause = 0;
397
+ if (unsat) {
398
+ LOG ("skipping clause since formula is already inconsistent");
399
+ skip = true;
400
+ } else {
401
+ assert (clause.empty ());
402
+ for (const auto &lit : original) {
403
+ int tmp = marked (lit);
404
+ if (tmp > 0) {
405
+ LOG ("removing duplicated literal %d", lit);
406
+ } else if (tmp < 0) {
407
+ LOG ("tautological since both %d and %d occur", -lit, lit);
408
+ skip = true;
409
+ } else {
410
+ mark (lit);
411
+ tmp = fixed (lit);
412
+ if (tmp < 0) {
413
+ LOG ("removing falsified literal %d", lit);
414
+ if (lrat) {
415
+ int elit = externalize (lit);
416
+ unsigned eidx = (elit > 0) + 2u * (unsigned) abs (elit);
417
+ if (!external->ext_units[eidx]) {
418
+ int64_t uid = unit_id (-lit);
419
+ lrat_chain.push_back (uid);
420
+ }
421
+ }
422
+ } else if (tmp > 0) {
423
+ LOG ("satisfied since literal %d true", lit);
424
+ skip = true;
425
+ } else {
426
+ clause.push_back (lit);
427
+ assert (flags (lit).status != Flags::UNUSED);
428
+ tmp = val (lit);
429
+ if (tmp)
430
+ learned_levels.insert (var (lit).level);
431
+ else
432
+ unassigned++;
433
+ }
434
+ }
435
+ }
436
+ for (const auto &lit : original)
437
+ unmark (lit);
438
+ }
439
+ if (skip) {
440
+ if (from_propagator) {
441
+ stats.ext_prop.elearn_conf++;
442
+
443
+ // In case it was a skipped external forgettable, we need to mark it
444
+ // immediately as removed
445
+
446
+ if (opts.check && is_external_forgettable (id))
447
+ mark_garbage_external_forgettable (id);
448
+ }
449
+ if (proof) {
450
+ proof->delete_external_original_clause (id, false, external->eclause);
451
+ }
452
+ } else {
453
+ int64_t new_id = id;
454
+ const size_t size = clause.size ();
455
+ if (original.size () > size) {
456
+ new_id = ++clause_id;
457
+ if (proof) {
458
+ if (lrat)
459
+ lrat_chain.push_back (id);
460
+ proof->add_derived_clause (new_id, false, clause, lrat_chain);
461
+ proof->delete_external_original_clause (id, false,
462
+ external->eclause);
463
+ }
464
+ external->check_learned_clause ();
465
+
466
+ if (from_propagator) {
467
+ // The original form of the added clause is immediately forgotten
468
+ // TODO: shall we save and check the simplified form? (one with
469
+ // new_id)
470
+ if (opts.check && is_external_forgettable (id))
471
+ mark_garbage_external_forgettable (id);
472
+ }
473
+ }
474
+ external->eclause.clear ();
475
+ lrat_chain.clear ();
476
+ if (!size) {
477
+ if (from_propagator)
478
+ stats.ext_prop.elearn_conf++;
479
+ assert (!unsat);
480
+ if (!original.size ())
481
+ VERBOSE (1, "found empty original clause");
482
+ else
483
+ VERBOSE (1, "found falsified original clause");
484
+ unsat = true;
485
+ conflict_id = new_id;
486
+ marked_failed = true;
487
+ conclusion.push_back (new_id);
488
+ } else if (size == 1) {
489
+ if (force_no_backtrack) {
490
+ assert (level);
491
+ const int idx = vidx (clause[0]);
492
+ assert (val (clause[0]) >= 0);
493
+ assert (!flags (idx).eliminated ());
494
+ Var &v = var (idx);
495
+ assert (val (clause[0]));
496
+ v.level = 0;
497
+ v.reason = 0;
498
+ did_external_prop = true;
499
+ const unsigned uidx = vlit (clause[0]);
500
+ if (lrat || frat)
501
+ unit_clauses (uidx) = new_id;
502
+ mark_fixed (clause[0]);
503
+ } else {
504
+ const int lit = clause[0];
505
+ assert (!val (lit) || var (lit).level);
506
+ if (val (lit) < 0)
507
+ backtrack (var (lit).level - 1);
508
+ assert (val (lit) >= 0);
509
+ handle_external_clause (0);
510
+ assign_original_unit (new_id, lit);
511
+ }
512
+ } else {
513
+ move_literals_to_watch ();
514
+ #ifndef NDEBUG
515
+ check_watched_literal_invariants ();
516
+ #endif
517
+ int glue = (int) (learned_levels.size () + unassigned);
518
+ assert (glue <= (int) clause.size ());
519
+ bool clause_redundancy = from_propagator && ext_clause_forgettable;
520
+ Clause *c = new_clause (clause_redundancy, glue);
521
+ c->id = new_id;
522
+ clause_id--;
523
+ watch_clause (c);
524
+ clause.clear ();
525
+ original.clear ();
526
+ handle_external_clause (c);
527
+ newest_clause = c;
528
+ }
529
+ }
530
+ clause.clear ();
531
+ lrat_chain.clear ();
532
+ }
533
+
534
+ // Add learned new clause during conflict analysis and watch it. Requires
535
+ // that the clause is at least of size 2, and the first two literals
536
+ // are assigned at the highest decision level.
537
+ //
538
+ Clause *Internal::new_learned_redundant_clause (int glue) {
539
+ assert (clause.size () > 1);
540
+ #ifndef NDEBUG
541
+ for (size_t i = 2; i < clause.size (); i++)
542
+ assert (var (clause[0]).level >= var (clause[i]).level),
543
+ assert (var (clause[1]).level >= var (clause[i]).level);
544
+ #endif
545
+ external->check_learned_clause ();
546
+ Clause *res = new_clause (true, glue);
547
+ if (proof) {
548
+ proof->add_derived_clause (res, lrat_chain);
549
+ }
550
+ assert (watching ());
551
+ watch_clause (res);
552
+ return res;
553
+ }
554
+
555
+ // Add hyper binary resolved clause during 'probing'.
556
+ //
557
+ Clause *Internal::new_hyper_binary_resolved_clause (bool red, int glue) {
558
+ external->check_learned_clause ();
559
+ Clause *res = new_clause (red, glue);
560
+ if (proof) {
561
+ proof->add_derived_clause (res, lrat_chain);
562
+ }
563
+ assert (watching ());
564
+ watch_clause (res);
565
+ return res;
566
+ }
567
+
568
+ // Add hyper ternary resolved clause during 'ternary'.
569
+ //
570
+ Clause *Internal::new_hyper_ternary_resolved_clause (bool red) {
571
+ external->check_learned_clause ();
572
+ size_t size = clause.size ();
573
+ Clause *res = new_clause (red, size);
574
+ if (proof) {
575
+ proof->add_derived_clause (res, lrat_chain);
576
+ }
577
+ assert (!watching ());
578
+ return res;
579
+ }
580
+
581
+ Clause *Internal::new_factor_clause (int witness) {
582
+ external->check_learned_clause ();
583
+ stats.factor_added++;
584
+ stats.literals_factored += clause.size ();
585
+ Clause *res = new_clause (false, 0);
586
+ if (proof) {
587
+ if (witness)
588
+ proof->add_derived_rat_clause (res, externalize (witness),
589
+ lrat_chain);
590
+ else
591
+ proof->add_derived_clause (res, lrat_chain);
592
+ }
593
+ assert (!watching ());
594
+ assert (occurring ());
595
+ for (const auto &lit : *res) {
596
+ occs (lit).push_back (res);
597
+ }
598
+ return res;
599
+ }
600
+
601
+ // Add hyper ternary resolved clause during 'congruence' and watch it
602
+ //
603
+ Clause *
604
+ Internal::new_hyper_ternary_resolved_clause_and_watch (bool red,
605
+ bool full_watching) {
606
+ external->check_learned_clause ();
607
+ size_t size = clause.size ();
608
+ Clause *res = new_clause (red, size);
609
+ if (proof) {
610
+ proof->add_derived_clause (res, lrat_chain);
611
+ }
612
+ if (full_watching) {
613
+ assert (watching ());
614
+ watch_clause (res);
615
+ }
616
+ return res;
617
+ }
618
+
619
+ // Add a new clause with same glue and redundancy as 'orig' but literals are
620
+ // assumed to be in 'clause' in 'decompose' and 'vivify'.
621
+ //
622
+ Clause *Internal::new_clause_as (const Clause *orig) {
623
+ external->check_learned_clause ();
624
+ const int new_glue = orig->glue;
625
+ Clause *res = new_clause (orig->redundant, new_glue);
626
+ if (proof) {
627
+ proof->add_derived_clause (res, lrat_chain);
628
+ }
629
+ assert (watching ());
630
+ watch_clause (res);
631
+ return res;
632
+ }
633
+
634
+ // Add resolved clause during resolution, e.g., bounded variable
635
+ // elimination, but do not connect its occurrences here.
636
+ //
637
+ Clause *Internal::new_resolved_irredundant_clause () {
638
+ external->check_learned_clause ();
639
+ if (proof) {
640
+ proof->add_derived_clause (clause_id + 1, false, clause, lrat_chain);
641
+ }
642
+ Clause *res = new_clause (false);
643
+ assert (!watching ());
644
+ return res;
645
+ }
646
+
647
+ void Internal::decay_clauses_upon_incremental_clauses () {
648
+ if (!opts.incdecay)
649
+ return;
650
+ if (!stats.searches)
651
+ return;
652
+ if (stats.conflicts < lim.incremental_decay)
653
+ return;
654
+
655
+ PHASE ("decay", stats.incremental_decay,
656
+ "decaying clauses with next decaying at conflict %" PRId64
657
+ "(after the next incremental call)",
658
+ lim.incremental_decay);
659
+
660
+ for (auto c : clauses) {
661
+ if (c->garbage)
662
+ continue;
663
+ if (!c->redundant)
664
+ continue;
665
+ if (c->id >= last.incremental_decay.last_id)
666
+ continue;
667
+ switch (opts.incdecay) {
668
+ case 1: // my intuition
669
+ ++c->glue;
670
+ break;
671
+ case 2: // Armin's idea
672
+ if (c->glue < tier1[false])
673
+ c->used = 1;
674
+ break;
675
+ case 3:
676
+ if (c->glue < tier1[false])
677
+ c->used = 1;
678
+ ++c->glue;
679
+ break;
680
+ default:
681
+ break;
682
+ }
683
+ }
684
+
685
+ lim.incremental_decay += stats.conflicts + opts.incdecayint;
686
+ ++stats.incremental_decay;
687
+ last.incremental_decay.last_id = clause_id;
688
+ }
689
+ } // namespace CaDiCaL