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.
- checksums.yaml +7 -0
- data/LICENSE.txt +26 -0
- data/README.md +101 -0
- data/ext/cadical/cadical/LICENSE +28 -0
- data/ext/cadical/cadical/README.md +65 -0
- data/ext/cadical/cadical/VERSION +1 -0
- data/ext/cadical/cadical/src/analyze.cpp +1360 -0
- data/ext/cadical/cadical/src/arena.cpp +30 -0
- data/ext/cadical/cadical/src/arena.hpp +105 -0
- data/ext/cadical/cadical/src/assume.cpp +616 -0
- data/ext/cadical/cadical/src/averages.cpp +34 -0
- data/ext/cadical/cadical/src/averages.hpp +37 -0
- data/ext/cadical/cadical/src/backbone.cpp +631 -0
- data/ext/cadical/cadical/src/backtrack.cpp +177 -0
- data/ext/cadical/cadical/src/backward.cpp +231 -0
- data/ext/cadical/cadical/src/bins.cpp +22 -0
- data/ext/cadical/cadical/src/bins.hpp +22 -0
- data/ext/cadical/cadical/src/block.cpp +824 -0
- data/ext/cadical/cadical/src/block.hpp +37 -0
- data/ext/cadical/cadical/src/cadical.cpp +1026 -0
- data/ext/cadical/cadical/src/cadical.hpp +1419 -0
- data/ext/cadical/cadical/src/ccadical.cpp +208 -0
- data/ext/cadical/cadical/src/ccadical.h +74 -0
- data/ext/cadical/cadical/src/checker.cpp +649 -0
- data/ext/cadical/cadical/src/checker.hpp +173 -0
- data/ext/cadical/cadical/src/clause.cpp +689 -0
- data/ext/cadical/cadical/src/clause.hpp +190 -0
- data/ext/cadical/cadical/src/collect.cpp +545 -0
- data/ext/cadical/cadical/src/compact.cpp +550 -0
- data/ext/cadical/cadical/src/condition.cpp +940 -0
- data/ext/cadical/cadical/src/config.cpp +101 -0
- data/ext/cadical/cadical/src/config.hpp +20 -0
- data/ext/cadical/cadical/src/congruence.cpp +7880 -0
- data/ext/cadical/cadical/src/congruence.hpp +757 -0
- data/ext/cadical/cadical/src/constrain.cpp +64 -0
- data/ext/cadical/cadical/src/contract.cpp +27 -0
- data/ext/cadical/cadical/src/contract.hpp +139 -0
- data/ext/cadical/cadical/src/cover.cpp +704 -0
- data/ext/cadical/cadical/src/cover.hpp +34 -0
- data/ext/cadical/cadical/src/decide.cpp +347 -0
- data/ext/cadical/cadical/src/decompose.cpp +738 -0
- data/ext/cadical/cadical/src/decompose.hpp +23 -0
- data/ext/cadical/cadical/src/deduplicate.cpp +275 -0
- data/ext/cadical/cadical/src/definition.cpp +283 -0
- data/ext/cadical/cadical/src/delay.hpp +38 -0
- data/ext/cadical/cadical/src/drattracer.cpp +153 -0
- data/ext/cadical/cadical/src/drattracer.hpp +55 -0
- data/ext/cadical/cadical/src/elim.cpp +1171 -0
- data/ext/cadical/cadical/src/elim.hpp +53 -0
- data/ext/cadical/cadical/src/elimfast.cpp +570 -0
- data/ext/cadical/cadical/src/ema.cpp +95 -0
- data/ext/cadical/cadical/src/ema.hpp +68 -0
- data/ext/cadical/cadical/src/extend.cpp +289 -0
- data/ext/cadical/cadical/src/external.cpp +1034 -0
- data/ext/cadical/cadical/src/external.hpp +487 -0
- data/ext/cadical/cadical/src/external_propagate.cpp +1316 -0
- data/ext/cadical/cadical/src/factor.cpp +1011 -0
- data/ext/cadical/cadical/src/factor.hpp +54 -0
- data/ext/cadical/cadical/src/file.cpp +506 -0
- data/ext/cadical/cadical/src/file.hpp +210 -0
- data/ext/cadical/cadical/src/flags.cpp +135 -0
- data/ext/cadical/cadical/src/flags.hpp +93 -0
- data/ext/cadical/cadical/src/flip.cpp +269 -0
- data/ext/cadical/cadical/src/format.cpp +89 -0
- data/ext/cadical/cadical/src/format.hpp +36 -0
- data/ext/cadical/cadical/src/frattracer.cpp +277 -0
- data/ext/cadical/cadical/src/frattracer.hpp +67 -0
- data/ext/cadical/cadical/src/gates.cpp +766 -0
- data/ext/cadical/cadical/src/heap.hpp +212 -0
- data/ext/cadical/cadical/src/idruptracer.cpp +566 -0
- data/ext/cadical/cadical/src/idruptracer.hpp +112 -0
- data/ext/cadical/cadical/src/instantiate.cpp +365 -0
- data/ext/cadical/cadical/src/instantiate.hpp +45 -0
- data/ext/cadical/cadical/src/internal.cpp +1265 -0
- data/ext/cadical/cadical/src/internal.hpp +1941 -0
- data/ext/cadical/cadical/src/inttypes.hpp +34 -0
- data/ext/cadical/cadical/src/ipasir.cpp +47 -0
- data/ext/cadical/cadical/src/ipasir.h +37 -0
- data/ext/cadical/cadical/src/kitten.c +2599 -0
- data/ext/cadical/cadical/src/kitten.h +97 -0
- data/ext/cadical/cadical/src/level.hpp +33 -0
- data/ext/cadical/cadical/src/lidruptracer.cpp +657 -0
- data/ext/cadical/cadical/src/lidruptracer.hpp +122 -0
- data/ext/cadical/cadical/src/limit.cpp +146 -0
- data/ext/cadical/cadical/src/limit.hpp +168 -0
- data/ext/cadical/cadical/src/logging.cpp +214 -0
- data/ext/cadical/cadical/src/logging.hpp +98 -0
- data/ext/cadical/cadical/src/lookahead.cpp +520 -0
- data/ext/cadical/cadical/src/lratchecker.cpp +833 -0
- data/ext/cadical/cadical/src/lratchecker.hpp +168 -0
- data/ext/cadical/cadical/src/lrattracer.cpp +200 -0
- data/ext/cadical/cadical/src/lrattracer.hpp +61 -0
- data/ext/cadical/cadical/src/lucky.cpp +506 -0
- data/ext/cadical/cadical/src/message.cpp +218 -0
- data/ext/cadical/cadical/src/message.hpp +65 -0
- data/ext/cadical/cadical/src/minimize.cpp +224 -0
- data/ext/cadical/cadical/src/mobical.cpp +5588 -0
- data/ext/cadical/cadical/src/occs.cpp +52 -0
- data/ext/cadical/cadical/src/occs.hpp +36 -0
- data/ext/cadical/cadical/src/options.cpp +359 -0
- data/ext/cadical/cadical/src/options.hpp +442 -0
- data/ext/cadical/cadical/src/parse.cpp +471 -0
- data/ext/cadical/cadical/src/parse.hpp +75 -0
- data/ext/cadical/cadical/src/phases.cpp +56 -0
- data/ext/cadical/cadical/src/phases.hpp +19 -0
- data/ext/cadical/cadical/src/probe.cpp +990 -0
- data/ext/cadical/cadical/src/profile.cpp +107 -0
- data/ext/cadical/cadical/src/profile.hpp +283 -0
- data/ext/cadical/cadical/src/proof.cpp +691 -0
- data/ext/cadical/cadical/src/proof.hpp +125 -0
- data/ext/cadical/cadical/src/propagate.cpp +584 -0
- data/ext/cadical/cadical/src/queue.cpp +90 -0
- data/ext/cadical/cadical/src/queue.hpp +74 -0
- data/ext/cadical/cadical/src/radix.hpp +180 -0
- data/ext/cadical/cadical/src/random.cpp +207 -0
- data/ext/cadical/cadical/src/random.h +44 -0
- data/ext/cadical/cadical/src/random.hpp +98 -0
- data/ext/cadical/cadical/src/range.hpp +125 -0
- data/ext/cadical/cadical/src/reap.cpp +127 -0
- data/ext/cadical/cadical/src/reap.hpp +28 -0
- data/ext/cadical/cadical/src/reduce.cpp +278 -0
- data/ext/cadical/cadical/src/reluctant.hpp +82 -0
- data/ext/cadical/cadical/src/rephase.cpp +402 -0
- data/ext/cadical/cadical/src/report.cpp +313 -0
- data/ext/cadical/cadical/src/resources.cpp +160 -0
- data/ext/cadical/cadical/src/resources.hpp +16 -0
- data/ext/cadical/cadical/src/restart.cpp +178 -0
- data/ext/cadical/cadical/src/restore.cpp +267 -0
- data/ext/cadical/cadical/src/score.cpp +51 -0
- data/ext/cadical/cadical/src/score.hpp +16 -0
- data/ext/cadical/cadical/src/shrink.cpp +507 -0
- data/ext/cadical/cadical/src/signal.cpp +136 -0
- data/ext/cadical/cadical/src/signal.hpp +33 -0
- data/ext/cadical/cadical/src/solution.cpp +50 -0
- data/ext/cadical/cadical/src/solver.cpp +1871 -0
- data/ext/cadical/cadical/src/stable.cpp +31 -0
- data/ext/cadical/cadical/src/stack.h +110 -0
- data/ext/cadical/cadical/src/stats.cpp +920 -0
- data/ext/cadical/cadical/src/stats.hpp +418 -0
- data/ext/cadical/cadical/src/subsume.cpp +645 -0
- data/ext/cadical/cadical/src/sweep.cpp +1960 -0
- data/ext/cadical/cadical/src/sweep.hpp +61 -0
- data/ext/cadical/cadical/src/terminal.cpp +38 -0
- data/ext/cadical/cadical/src/terminal.hpp +96 -0
- data/ext/cadical/cadical/src/ternary.cpp +450 -0
- data/ext/cadical/cadical/src/testing.hpp +24 -0
- data/ext/cadical/cadical/src/tier.cpp +189 -0
- data/ext/cadical/cadical/src/tracer.hpp +186 -0
- data/ext/cadical/cadical/src/transred.cpp +253 -0
- data/ext/cadical/cadical/src/unstable.cpp +29 -0
- data/ext/cadical/cadical/src/util.cpp +129 -0
- data/ext/cadical/cadical/src/util.hpp +181 -0
- data/ext/cadical/cadical/src/var.cpp +39 -0
- data/ext/cadical/cadical/src/var.hpp +22 -0
- data/ext/cadical/cadical/src/veripbtracer.cpp +427 -0
- data/ext/cadical/cadical/src/veripbtracer.hpp +106 -0
- data/ext/cadical/cadical/src/version.cpp +107 -0
- data/ext/cadical/cadical/src/version.hpp +13 -0
- data/ext/cadical/cadical/src/vivify.cpp +1893 -0
- data/ext/cadical/cadical/src/vivify.hpp +50 -0
- data/ext/cadical/cadical/src/walk.cpp +1088 -0
- data/ext/cadical/cadical/src/walk.hpp +91 -0
- data/ext/cadical/cadical/src/walk_full_occs.cpp +966 -0
- data/ext/cadical/cadical/src/warmup.cpp +403 -0
- data/ext/cadical/cadical/src/watch.cpp +126 -0
- data/ext/cadical/cadical/src/watch.hpp +77 -0
- data/ext/cadical/cadical_ext.c +778 -0
- data/ext/cadical/extconf.rb +26 -0
- data/lib/cadical/version.rb +3 -0
- data/lib/cadical.rb +12 -0
- 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
|