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,507 @@
1
+ #include "internal.hpp"
2
+ #include "reap.hpp"
3
+
4
+ namespace CaDiCaL {
5
+
6
+ void Internal::reset_shrinkable () {
7
+ #ifdef LOGGING
8
+ size_t reset = 0;
9
+ #endif
10
+ for (const auto &lit : shrinkable) {
11
+ LOG ("resetting lit %i", lit);
12
+ Flags &f = flags (lit);
13
+ assert (f.shrinkable);
14
+ f.shrinkable = false;
15
+ #ifdef LOGGING
16
+ ++reset;
17
+ #endif
18
+ }
19
+ LOG ("resetting %zu shrinkable variables", reset);
20
+ }
21
+
22
+ void Internal::mark_shrinkable_as_removable (
23
+ int blevel, std::vector<int>::size_type minimized_start) {
24
+ #ifdef LOGGING
25
+ size_t marked = 0, reset = 0;
26
+ #endif
27
+ #ifndef NDEBUG
28
+ unsigned kept = 0, minireset = 0;
29
+ for (; minimized_start < minimized.size (); ++minimized_start) {
30
+ const int lit = minimized[minimized_start];
31
+ Flags &f = flags (lit);
32
+ const Var &v = var (lit);
33
+ if (v.level == blevel) {
34
+ assert (!f.poison);
35
+ ++minireset;
36
+ } else
37
+ ++kept;
38
+ }
39
+ (void) kept;
40
+ (void) minireset;
41
+ #else
42
+ (void) blevel;
43
+ (void) minimized_start;
44
+ #endif
45
+
46
+ for (const int lit : shrinkable) {
47
+ Flags &f = flags (lit);
48
+ assert (f.shrinkable);
49
+ assert (!f.poison);
50
+ f.shrinkable = false;
51
+ #ifdef LOGGING
52
+ ++reset;
53
+ #endif
54
+ if (f.removable)
55
+ continue;
56
+ f.removable = true;
57
+ minimized.push_back (lit);
58
+ #ifdef LOGGING
59
+ ++marked;
60
+ #endif
61
+ }
62
+ LOG ("resetting %zu shrinkable variables", reset);
63
+ LOG ("marked %zu removable variables", marked);
64
+ }
65
+
66
+ int inline Internal::shrink_literal (int lit, int blevel,
67
+ unsigned max_trail) {
68
+ assert (val (lit) < 0);
69
+
70
+ Flags &f = flags (lit);
71
+ Var &v = var (lit);
72
+ assert (v.level <= blevel);
73
+
74
+ if (!v.level) {
75
+ LOG ("skipping root level assigned %d", (lit));
76
+ return 0;
77
+ }
78
+
79
+ if (v.reason == external_reason) {
80
+ assert (!opts.exteagerreasons);
81
+ v.reason = learn_external_reason_clause (-lit, 0, true);
82
+ if (!v.reason) {
83
+ assert (!v.level);
84
+ return 0;
85
+ }
86
+ }
87
+ assert (v.reason != external_reason);
88
+ if (f.shrinkable) {
89
+ LOG ("skipping already shrinkable literal %d", (lit));
90
+ return 0;
91
+ }
92
+
93
+ if (v.level < blevel) {
94
+ if (f.removable) {
95
+ LOG ("skipping removable thus shrinkable %d", (lit));
96
+ return 0;
97
+ }
98
+ const bool always_minimize_on_lower_blevel = (opts.shrink > 2);
99
+ if (always_minimize_on_lower_blevel && minimize_literal (-lit, 1)) {
100
+ LOG ("minimized thus shrinkable %d", (lit));
101
+ return 0;
102
+ }
103
+ LOG ("literal %d on lower blevel %u < %u not removable/shrinkable",
104
+ (lit), v.level, blevel);
105
+ return -1;
106
+ }
107
+
108
+ LOG ("marking %d as shrinkable", lit);
109
+ f.shrinkable = true;
110
+ f.poison = false;
111
+ shrinkable.push_back (lit);
112
+ if (opts.shrinkreap) {
113
+ assert (max_trail < trail.size ());
114
+ const unsigned dist = max_trail - v.trail;
115
+ reap.push (dist);
116
+ }
117
+ return 1;
118
+ }
119
+
120
+ unsigned Internal::shrunken_block_uip (
121
+ int uip, int blevel, std::vector<int>::reverse_iterator &rbegin_block,
122
+ std::vector<int>::reverse_iterator &rend_block,
123
+ std::vector<int>::size_type minimized_start, const int uip0) {
124
+ assert (clause[0] == uip0);
125
+
126
+ LOG ("UIP on level %u, uip: %i (replacing by %i)", blevel, uip, uip0);
127
+ assert (rend_block > rbegin_block);
128
+ assert (rend_block < clause.rend ());
129
+ unsigned block_shrunken = 0;
130
+ *rbegin_block = -uip;
131
+ Var &v = var (-uip);
132
+ Level &l = control[v.level];
133
+ l.seen.trail = v.trail;
134
+ l.seen.count = 1;
135
+
136
+ Flags &f = flags (-uip);
137
+ if (!f.seen) {
138
+ analyzed.push_back (-uip);
139
+ f.seen = true;
140
+ }
141
+
142
+ flags (-uip).keep = true;
143
+ for (auto p = rbegin_block + 1; p != rend_block; ++p) {
144
+ const int lit = *p;
145
+ if (lit == -uip0)
146
+ continue;
147
+ *p = uip0;
148
+ // if (lit == -uip) continue;
149
+ ++block_shrunken;
150
+ assert (clause[0] == uip0);
151
+ }
152
+ mark_shrinkable_as_removable (blevel, minimized_start);
153
+ assert (clause[0] == uip0);
154
+ return block_shrunken;
155
+ }
156
+
157
+ void inline Internal::shrunken_block_no_uip (
158
+ const std::vector<int>::reverse_iterator &rbegin_block,
159
+ const std::vector<int>::reverse_iterator &rend_block,
160
+ unsigned &block_minimized, const int uip0) {
161
+ STOP (shrink);
162
+ START (minimize);
163
+ assert (rend_block > rbegin_block);
164
+ LOG ("no UIP found, now minimizing");
165
+ for (auto p = rbegin_block; p != rend_block; ++p) {
166
+ assert (p != clause.rend () - 1);
167
+ const int lit = *p;
168
+ if (opts.minimize && minimize_literal (-lit)) {
169
+ assert (!flags (lit).keep);
170
+ ++block_minimized;
171
+ *p = uip0;
172
+ } else {
173
+ flags (lit).keep = true;
174
+ assert (flags (lit).keep);
175
+ }
176
+ }
177
+ STOP (minimize);
178
+ START (shrink);
179
+ }
180
+
181
+ void Internal::push_literals_of_block (
182
+ const std::vector<int>::reverse_iterator &rbegin_block,
183
+ const std::vector<int>::reverse_iterator &rend_block, int blevel,
184
+ unsigned max_trail) {
185
+ assert (rbegin_block < rend_block);
186
+ for (auto p = rbegin_block; p != rend_block; ++p) {
187
+ assert (p != clause.rend () - 1);
188
+ assert (!flags (*p).keep);
189
+ const int lit = *p;
190
+ LOG ("pushing lit %i of blevel %i", lit, var (lit).level);
191
+ #ifndef NDEBUG
192
+ int tmp =
193
+ #endif
194
+ shrink_literal (lit, blevel, max_trail);
195
+ assert (tmp > 0);
196
+ }
197
+ }
198
+
199
+ unsigned inline Internal::shrink_next (int blevel, unsigned &open,
200
+ unsigned &max_trail) {
201
+ const auto &t = &trail;
202
+ (void) blevel;
203
+ if (opts.shrinkreap) {
204
+ assert (!reap.empty ());
205
+ const unsigned dist = reap.pop ();
206
+ --open;
207
+ assert (dist <= max_trail);
208
+ const unsigned pos = max_trail - dist;
209
+ assert (pos < t->size ());
210
+ const int uip = (*t)[pos];
211
+ assert (val (uip) > 0);
212
+ LOG ("trying to shrink literal %d at trail[%u] and level %d", uip, pos,
213
+ blevel);
214
+ return uip;
215
+ } else {
216
+ int uip;
217
+ #ifndef NDEBUG
218
+ unsigned init_max_trail = max_trail;
219
+ #endif
220
+ do {
221
+ assert (max_trail <= init_max_trail);
222
+ uip = (*t)[max_trail--];
223
+ } while (!flags (uip).shrinkable);
224
+ --open;
225
+ LOG ("open is now %d, uip = %d, level %d", open, uip, blevel);
226
+ return uip;
227
+ }
228
+ }
229
+
230
+ unsigned inline Internal::shrink_along_reason (int uip, int blevel,
231
+ bool resolve_large_clauses,
232
+ bool &failed_ptr,
233
+ unsigned max_trail) {
234
+ LOG ("shrinking along the reason of lit %i", uip);
235
+ unsigned open = 0;
236
+ #ifndef NDEBUG
237
+ const Flags &f = flags (uip);
238
+ #endif
239
+ const Var &v = var (uip);
240
+
241
+ assert (f.shrinkable);
242
+ assert (v.level == blevel);
243
+ assert (v.reason);
244
+
245
+ if (opts.minimizeticks)
246
+ stats.ticks.search[stable]++;
247
+
248
+ if (resolve_large_clauses || v.reason->size == 2) {
249
+ const Clause &c = *v.reason;
250
+ LOG (v.reason, "resolving with reason");
251
+ for (int lit : c) {
252
+ if (lit == uip)
253
+ continue;
254
+ assert (val (lit) < 0);
255
+ int tmp = shrink_literal (lit, blevel, max_trail);
256
+ if (tmp < 0) {
257
+ failed_ptr = true;
258
+ break;
259
+ }
260
+ if (tmp > 0) {
261
+ ++open;
262
+ }
263
+ }
264
+ } else {
265
+ failed_ptr = true;
266
+ }
267
+ return open;
268
+ }
269
+
270
+ unsigned
271
+ Internal::shrink_block (std::vector<int>::reverse_iterator &rbegin_lits,
272
+ std::vector<int>::reverse_iterator &rend_block,
273
+ int blevel, unsigned &open,
274
+ unsigned &block_minimized, const int uip0,
275
+ unsigned max_trail) {
276
+ assert (shrinkable.empty ());
277
+ assert (blevel <= this->level);
278
+ assert (open < clause.size ());
279
+ assert (rbegin_lits >= clause.rbegin ());
280
+ assert (rend_block < clause.rend ());
281
+ assert (rbegin_lits < rend_block);
282
+ assert (opts.shrink);
283
+
284
+ #ifdef LOGGING
285
+
286
+ LOG ("trying to shrink %u literals on level %u", open, blevel);
287
+
288
+ const auto &t = &trail;
289
+
290
+ LOG ("maximum trail position %zd on level %u", t->size (), blevel);
291
+ if (opts.shrinkreap)
292
+ LOG ("shrinking up to %u", max_trail);
293
+ #endif
294
+
295
+ const bool resolve_large_clauses = (opts.shrink > 1);
296
+ bool failed = false;
297
+ unsigned block_shrunken = 0;
298
+ std::vector<int>::size_type minimized_start = minimized.size ();
299
+ int uip = uip0;
300
+ unsigned max_trail2 = max_trail;
301
+
302
+ if (!failed) {
303
+ push_literals_of_block (rbegin_lits, rend_block, blevel, max_trail);
304
+ assert (!opts.shrinkreap || reap.size () == open);
305
+
306
+ assert (open > 0);
307
+ while (!failed) {
308
+ assert (!opts.shrinkreap || reap.size () == open);
309
+ uip = shrink_next (blevel, open, max_trail);
310
+ if (open == 0) {
311
+ break;
312
+ }
313
+ open += shrink_along_reason (uip, blevel, resolve_large_clauses,
314
+ failed, max_trail2);
315
+ assert (open >= 1);
316
+ }
317
+
318
+ if (!failed)
319
+ LOG ("shrinking found UIP %i on level %i (open: %d)", uip, blevel,
320
+ open);
321
+ else
322
+ LOG ("shrinking failed on level %i", blevel);
323
+ }
324
+
325
+ if (failed)
326
+ reset_shrinkable (), shrunken_block_no_uip (rbegin_lits, rend_block,
327
+ block_minimized, uip0);
328
+ else
329
+ block_shrunken = shrunken_block_uip (uip, blevel, rbegin_lits,
330
+ rend_block, minimized_start, uip0);
331
+
332
+ if (opts.shrinkreap)
333
+ reap.clear ();
334
+ shrinkable.clear ();
335
+ return block_shrunken;
336
+ }
337
+
338
+ // Smaller level and trail. Comparing literals on their level is necessary
339
+ // for chronological backtracking, since trail order might in this case not
340
+ // respect level order.
341
+
342
+ struct shrink_trail_negative_rank {
343
+ Internal *internal;
344
+ shrink_trail_negative_rank (Internal *s) : internal (s) {}
345
+ typedef uint64_t Type;
346
+ Type operator() (int a) {
347
+ Var &v = internal->var (a);
348
+ uint64_t res = v.level;
349
+ res <<= 32;
350
+ res |= v.trail;
351
+ return ~res;
352
+ }
353
+ };
354
+
355
+ struct shrink_trail_larger {
356
+ Internal *internal;
357
+ shrink_trail_larger (Internal *s) : internal (s) {}
358
+ bool operator() (const int &a, const int &b) const {
359
+ return shrink_trail_negative_rank (internal) (a) <
360
+ shrink_trail_negative_rank (internal) (b);
361
+ }
362
+ };
363
+
364
+ // Finds the beginning of the block (rend_block, non-included) ending at
365
+ // rend_block (included). Then tries to shrinks and minimizes literals the
366
+ // block
367
+ std::vector<int>::reverse_iterator Internal::minimize_and_shrink_block (
368
+ std::vector<int>::reverse_iterator &rbegin_block,
369
+ unsigned &total_shrunken, unsigned &total_minimized, const int uip0)
370
+
371
+ {
372
+ LOG ("shrinking block");
373
+ assert (rbegin_block < clause.rend () - 1);
374
+ int blevel;
375
+ unsigned open = 0;
376
+ unsigned max_trail;
377
+
378
+ // find begining of block;
379
+ std::vector<int>::reverse_iterator rend_block;
380
+ {
381
+ assert (rbegin_block <= clause.rend ());
382
+ const int lit = *rbegin_block;
383
+ const int idx = vidx (lit);
384
+ blevel = vtab[idx].level;
385
+ max_trail = vtab[idx].trail;
386
+ LOG ("Block at level %i (first lit: %i)", blevel, lit);
387
+
388
+ rend_block = rbegin_block;
389
+ bool finished;
390
+ do {
391
+ assert (rend_block < clause.rend () - 1);
392
+ const int lit = *(++rend_block);
393
+ const int idx = vidx (lit);
394
+ finished = (blevel != vtab[idx].level);
395
+ if (!finished && (unsigned) vtab[idx].trail > max_trail)
396
+ max_trail = vtab[idx].trail;
397
+ ++open;
398
+ LOG (
399
+ "testing if lit %i is on the same level (of lit: %i, global: %i)",
400
+ lit, vtab[idx].level, blevel);
401
+
402
+ } while (!finished);
403
+ }
404
+ assert (open > 0);
405
+ assert (open < clause.size ());
406
+ assert (rbegin_block < clause.rend ());
407
+ assert (rend_block < clause.rend ());
408
+
409
+ unsigned block_shrunken = 0, block_minimized = 0;
410
+ if (open < 2) {
411
+ flags (*rbegin_block).keep = true;
412
+ minimized.push_back (*rbegin_block);
413
+ } else
414
+ block_shrunken = shrink_block (rbegin_block, rend_block, blevel, open,
415
+ block_minimized, uip0, max_trail);
416
+
417
+ LOG ("shrunken %u literals on level %u (including %u minimized)",
418
+ block_shrunken, blevel, block_minimized);
419
+
420
+ total_shrunken += block_shrunken;
421
+ total_minimized += block_minimized;
422
+
423
+ return rend_block;
424
+ }
425
+
426
+ void Internal::shrink_and_minimize_clause () {
427
+ assert (opts.minimize || opts.shrink > 0);
428
+ LOG (clause, "shrink first UIP clause");
429
+
430
+ START (shrink);
431
+ external->check_learned_clause (); // check 1st UIP learned clause first
432
+ MSORT (opts.radixsortlim, clause.begin (), clause.end (),
433
+ shrink_trail_negative_rank (this), shrink_trail_larger (this));
434
+ unsigned total_shrunken = 0;
435
+ unsigned total_minimized = 0;
436
+
437
+ LOG (clause, "shrink first UIP clause (asserting lit: %i)", clause[0]);
438
+
439
+ auto rend_lits = clause.rend () - 1;
440
+ auto rend_block = clause.rbegin ();
441
+ const int uip0 = clause[0];
442
+
443
+ // for direct LRAT we remember how the clause used to look
444
+ vector<int> old_clause_lrat;
445
+ assert (minimize_chain.empty ());
446
+ if (lrat)
447
+ for (auto &i : clause)
448
+ old_clause_lrat.push_back (i);
449
+
450
+ while (rend_block != rend_lits) {
451
+ rend_block = minimize_and_shrink_block (rend_block, total_shrunken,
452
+ total_minimized, uip0);
453
+ }
454
+
455
+ LOG (clause,
456
+ "post shrink pass (with uips, not removed) first UIP clause");
457
+ LOG (old_clause_lrat, "(used for lratdirect) before shrink: clause");
458
+ #if defined(LOGGING) || !defined(NDEBUG)
459
+ const unsigned old_size = clause.size ();
460
+ #endif
461
+ std::vector<int> stack;
462
+ {
463
+ std::vector<int>::size_type i = 1;
464
+ for (std::vector<int>::size_type j = 1; j < clause.size (); ++j) {
465
+ assert (i <= j);
466
+ clause[i] = clause[j];
467
+ if (lrat) {
468
+ assert (j < old_clause_lrat.size ());
469
+ assert (mini_chain.empty ());
470
+ if (clause[j] != old_clause_lrat[j]) {
471
+ calculate_minimize_chain (-old_clause_lrat[j], stack);
472
+ for (auto p : mini_chain) {
473
+ minimize_chain.push_back (p);
474
+ }
475
+ mini_chain.clear ();
476
+ }
477
+ }
478
+ if (clause[j] == uip0) {
479
+ continue;
480
+ }
481
+ assert (flags (clause[i]).keep);
482
+ ++i;
483
+ LOG ("keeping literal %i", clause[j]);
484
+ }
485
+ clause.resize (i);
486
+ }
487
+ assert (old_size ==
488
+ (unsigned) clause.size () + total_shrunken + total_minimized);
489
+ LOG (clause, "after shrinking first UIP clause");
490
+ LOG ("clause shrunken by %zd literals (including %u minimized)",
491
+ old_size - clause.size (), total_minimized);
492
+
493
+ stats.shrunken += total_shrunken;
494
+ stats.minishrunken += total_minimized;
495
+ STOP (shrink);
496
+
497
+ START (minimize);
498
+ clear_minimized_literals ();
499
+ for (auto p = minimize_chain.rbegin (); p != minimize_chain.rend ();
500
+ p++) {
501
+ lrat_chain.push_back (*p);
502
+ }
503
+ minimize_chain.clear ();
504
+ STOP (minimize);
505
+ }
506
+
507
+ } // namespace CaDiCaL
@@ -0,0 +1,136 @@
1
+ #include "signal.hpp"
2
+ #include "cadical.hpp"
3
+ #include "resources.hpp"
4
+
5
+ /*------------------------------------------------------------------------*/
6
+
7
+ #include <cassert>
8
+ #include <csignal>
9
+
10
+ /*------------------------------------------------------------------------*/
11
+
12
+ extern "C" {
13
+ #include <unistd.h>
14
+ }
15
+
16
+ /*------------------------------------------------------------------------*/
17
+
18
+ // Signal handlers for printing statistics even if solver is interrupted.
19
+
20
+ namespace CaDiCaL {
21
+
22
+ static volatile bool caught_signal = false;
23
+ static Handler *signal_handler;
24
+
25
+ #ifndef _WIN32
26
+
27
+ static volatile bool caught_alarm = false;
28
+ static volatile bool alarm_set = false;
29
+ static int alarm_time = -1;
30
+
31
+ void Handler::catch_alarm () { catch_signal (SIGALRM); }
32
+
33
+ #endif
34
+
35
+ #define SIGNALS \
36
+ SIGNAL (SIGABRT) \
37
+ SIGNAL (SIGINT) \
38
+ SIGNAL (SIGSEGV) \
39
+ SIGNAL (SIGTERM)
40
+
41
+ #define SIGNAL(SIG) static void (*SIG##_handler) (int);
42
+ SIGNALS
43
+ #undef SIGNAL
44
+
45
+ #ifndef _WIN32
46
+
47
+ static void (*SIGALRM_handler) (int);
48
+
49
+ void Signal::reset_alarm () {
50
+ if (!alarm_set)
51
+ return;
52
+ (void) signal (SIGALRM, SIGALRM_handler);
53
+ SIGALRM_handler = 0;
54
+ caught_alarm = false;
55
+ alarm_set = false;
56
+ alarm_time = -1;
57
+ }
58
+
59
+ #endif
60
+
61
+ void Signal::reset () {
62
+ signal_handler = 0;
63
+ #define SIGNAL(SIG) \
64
+ (void) signal (SIG, SIG##_handler); \
65
+ SIG##_handler = 0;
66
+ SIGNALS
67
+ #undef SIGNAL
68
+ #ifndef _WIN32
69
+ reset_alarm ();
70
+ #endif
71
+ caught_signal = false;
72
+ }
73
+
74
+ const char *Signal::name (int sig) {
75
+ #define SIGNAL(SIG) \
76
+ if (sig == SIG) \
77
+ return #SIG;
78
+ SIGNALS
79
+ #undef SIGNAL
80
+ #ifndef _WIN32
81
+ if (sig == SIGALRM)
82
+ return "SIGALRM";
83
+ #endif
84
+ return "UNKNOWN";
85
+ }
86
+
87
+ // TODO printing is not reentrant and might lead to deadlock if the signal
88
+ // is raised during another print attempt (and locked IO is used). To avoid
89
+ // this we have to either run our own low-level printing routine here or in
90
+ // 'Message' or just dump those statistics somewhere else were we have
91
+ // exclusive access to. All these solutions are painful and not elegant.
92
+
93
+ static void catch_signal (int sig) {
94
+ #ifndef _WIN32
95
+ if (sig == SIGALRM && absolute_real_time () >= alarm_time) {
96
+ if (!caught_alarm) {
97
+ caught_alarm = true;
98
+ if (signal_handler)
99
+ signal_handler->catch_alarm ();
100
+ }
101
+ Signal::reset_alarm ();
102
+ } else
103
+ #endif
104
+ {
105
+ if (!caught_signal) {
106
+ caught_signal = true;
107
+ if (signal_handler)
108
+ signal_handler->catch_signal (sig);
109
+ }
110
+ Signal::reset ();
111
+ ::raise (sig);
112
+ }
113
+ }
114
+
115
+ void Signal::set (Handler *h) {
116
+ signal_handler = h;
117
+ #define SIGNAL(SIG) SIG##_handler = signal (SIG, catch_signal);
118
+ SIGNALS
119
+ #undef SIGNAL
120
+ }
121
+
122
+ #ifndef _WIN32
123
+
124
+ void Signal::alarm (int seconds) {
125
+ assert (seconds >= 0);
126
+ assert (!alarm_set);
127
+ assert (alarm_time < 0);
128
+ SIGALRM_handler = signal (SIGALRM, catch_signal);
129
+ alarm_set = true;
130
+ alarm_time = absolute_real_time () + seconds;
131
+ ::alarm (seconds);
132
+ }
133
+
134
+ #endif
135
+
136
+ } // namespace CaDiCaL
@@ -0,0 +1,33 @@
1
+ #ifndef _signal_hpp_INCLUDED
2
+ #define _signal_hpp_INCLUDED
3
+
4
+ namespace CaDiCaL {
5
+
6
+ // Helper class for handling signals in applications.
7
+
8
+ class Handler {
9
+ public:
10
+ Handler () {}
11
+ virtual ~Handler () {}
12
+ virtual void catch_signal (int sig) = 0;
13
+ #ifndef _WIN32
14
+ virtual void catch_alarm ();
15
+ #endif
16
+ };
17
+
18
+ class Signal {
19
+
20
+ public:
21
+ static void set (Handler *);
22
+ static void reset ();
23
+ #ifndef _WIN32
24
+ static void alarm (int seconds);
25
+ static void reset_alarm ();
26
+ #endif
27
+
28
+ static const char *name (int sig);
29
+ };
30
+
31
+ } // namespace CaDiCaL
32
+
33
+ #endif