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,631 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
#include "message.hpp"
|
|
3
|
+
#include "util.hpp"
|
|
4
|
+
|
|
5
|
+
namespace CaDiCaL {
|
|
6
|
+
|
|
7
|
+
inline void Internal::backbone_lrat_for_units (int lit, Clause *reason) {
|
|
8
|
+
if (!lrat)
|
|
9
|
+
return;
|
|
10
|
+
if (level)
|
|
11
|
+
return; // not decision level 0
|
|
12
|
+
LOG ("backbone building chain for units");
|
|
13
|
+
assert (lrat_chain.empty ());
|
|
14
|
+
assert (reason);
|
|
15
|
+
for (auto &reason_lit : *reason) {
|
|
16
|
+
if (lit == reason_lit)
|
|
17
|
+
continue;
|
|
18
|
+
assert (val (reason_lit));
|
|
19
|
+
if (!val (reason_lit))
|
|
20
|
+
continue;
|
|
21
|
+
const int signed_reason_lit = val (reason_lit) * reason_lit;
|
|
22
|
+
int64_t id = unit_id (signed_reason_lit);
|
|
23
|
+
lrat_chain.push_back (id);
|
|
24
|
+
}
|
|
25
|
+
lrat_chain.push_back (reason->id);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
inline bool Internal::backbone_propagate (int64_t &ticks) {
|
|
29
|
+
require_mode (BACKBONE);
|
|
30
|
+
assert (!unsat);
|
|
31
|
+
START (propagate);
|
|
32
|
+
int64_t before = propagated2 = propagated;
|
|
33
|
+
for (;;) {
|
|
34
|
+
if (propagated2 != trail.size ()) {
|
|
35
|
+
const int lit = -trail[propagated2++];
|
|
36
|
+
LOG ("backbone propagating %d over binary clauses", -lit);
|
|
37
|
+
Watches &ws = watches (lit);
|
|
38
|
+
ticks +=
|
|
39
|
+
1 + cache_lines (ws.size (), sizeof (const_watch_iterator *));
|
|
40
|
+
for (const auto &w : ws) {
|
|
41
|
+
if (!w.binary ())
|
|
42
|
+
continue;
|
|
43
|
+
const signed char b = val (w.blit);
|
|
44
|
+
if (b > 0)
|
|
45
|
+
continue;
|
|
46
|
+
if (b < 0)
|
|
47
|
+
conflict = w.clause; // but continue
|
|
48
|
+
else {
|
|
49
|
+
ticks++;
|
|
50
|
+
build_chain_for_units (w.blit, w.clause, 0);
|
|
51
|
+
backbone_assign (w.blit, w.clause);
|
|
52
|
+
lrat_chain.clear ();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} else if (!conflict && propagated != trail.size ()) {
|
|
56
|
+
const int lit = -trail[propagated++];
|
|
57
|
+
LOG ("backbone propagating %d over large clauses", -lit);
|
|
58
|
+
Watches &ws = watches (lit);
|
|
59
|
+
const const_watch_iterator eow = ws.end ();
|
|
60
|
+
const_watch_iterator i = ws.begin ();
|
|
61
|
+
ticks += 1 + cache_lines (ws.size (), sizeof (*i));
|
|
62
|
+
watch_iterator j = ws.begin ();
|
|
63
|
+
while (i != eow) {
|
|
64
|
+
const Watch w = *j++ = *i++;
|
|
65
|
+
if (w.binary ())
|
|
66
|
+
continue;
|
|
67
|
+
if (val (w.blit) > 0)
|
|
68
|
+
continue;
|
|
69
|
+
ticks++;
|
|
70
|
+
if (w.clause->garbage) {
|
|
71
|
+
j--;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
literal_iterator lits = w.clause->begin ();
|
|
75
|
+
const int other = lits[0] ^ lits[1] ^ lit;
|
|
76
|
+
const signed char u = val (other);
|
|
77
|
+
if (u > 0)
|
|
78
|
+
j[-1].blit = other;
|
|
79
|
+
else {
|
|
80
|
+
const int size = w.clause->size;
|
|
81
|
+
const const_literal_iterator end = lits + size;
|
|
82
|
+
const literal_iterator middle = lits + w.clause->pos;
|
|
83
|
+
literal_iterator k = middle;
|
|
84
|
+
signed char v = -1;
|
|
85
|
+
int r = 0;
|
|
86
|
+
while (k != end && (v = val (r = *k)) < 0)
|
|
87
|
+
k++;
|
|
88
|
+
if (v < 0) {
|
|
89
|
+
k = lits + 2;
|
|
90
|
+
assert (w.clause->pos <= size);
|
|
91
|
+
while (k != middle && (v = val (r = *k)) < 0)
|
|
92
|
+
k++;
|
|
93
|
+
}
|
|
94
|
+
w.clause->pos = k - lits;
|
|
95
|
+
assert (lits + 2 <= k), assert (k <= w.clause->end ());
|
|
96
|
+
if (v > 0)
|
|
97
|
+
j[-1].blit = r;
|
|
98
|
+
else if (!v) {
|
|
99
|
+
LOG (w.clause, "unwatch %d in", r);
|
|
100
|
+
lits[0] = other;
|
|
101
|
+
lits[1] = r;
|
|
102
|
+
*k = lit;
|
|
103
|
+
ticks++;
|
|
104
|
+
watch_literal (r, lit, w.clause);
|
|
105
|
+
j--;
|
|
106
|
+
} else if (!u) {
|
|
107
|
+
ticks++;
|
|
108
|
+
assert (v < 0);
|
|
109
|
+
build_chain_for_units (other, w.clause, 0);
|
|
110
|
+
backbone_assign_any (other, w.clause);
|
|
111
|
+
lrat_chain.clear ();
|
|
112
|
+
} else {
|
|
113
|
+
if (w.clause == ignore) {
|
|
114
|
+
LOG ("ignoring conflict due to clause to vivify");
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
assert (u < 0);
|
|
118
|
+
assert (v < 0);
|
|
119
|
+
conflict = w.clause;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (j != i) {
|
|
125
|
+
while (i != eow)
|
|
126
|
+
*j++ = *i++;
|
|
127
|
+
ws.resize (j - ws.begin ());
|
|
128
|
+
}
|
|
129
|
+
} else
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
int64_t delta = propagated2 - before;
|
|
133
|
+
stats.propagations.backbone += delta;
|
|
134
|
+
if (conflict)
|
|
135
|
+
LOG (conflict, "conflict");
|
|
136
|
+
STOP (propagate);
|
|
137
|
+
return !conflict;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
inline void Internal::backbone_propagate2 (int64_t &ticks) {
|
|
141
|
+
require_mode (BACKBONE);
|
|
142
|
+
assert (propagated2 <= trail.size ());
|
|
143
|
+
int64_t before = propagated2;
|
|
144
|
+
while (propagated2 != trail.size ()) {
|
|
145
|
+
const int lit = -trail[propagated2++];
|
|
146
|
+
LOG ("probe propagating %d over binary clauses", -lit);
|
|
147
|
+
Watches &ws = watches (lit);
|
|
148
|
+
ticks += 1 + cache_lines (ws.size (), sizeof (const_watch_iterator *));
|
|
149
|
+
for (const auto &w : ws) {
|
|
150
|
+
if (!w.binary ())
|
|
151
|
+
break;
|
|
152
|
+
const signed char b = val (w.blit);
|
|
153
|
+
if (b > 0)
|
|
154
|
+
continue;
|
|
155
|
+
ticks++;
|
|
156
|
+
if (b < 0) {
|
|
157
|
+
conflict = w.clause; // no need to continue
|
|
158
|
+
break;
|
|
159
|
+
} else {
|
|
160
|
+
assert (lrat_chain.empty ());
|
|
161
|
+
backbone_lrat_for_units (w.blit, w.clause);
|
|
162
|
+
backbone_assign (w.blit, w.clause);
|
|
163
|
+
lrat_chain.clear ();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
int64_t delta = propagated2 - before;
|
|
169
|
+
stats.propagations.backbone += delta;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
void Internal::schedule_backbone_cands (std::vector<int> &candidates) {
|
|
173
|
+
|
|
174
|
+
unsigned not_rescheduled = 0;
|
|
175
|
+
for (auto v : vars) {
|
|
176
|
+
const Flags f = flags (v);
|
|
177
|
+
if (!f.active ())
|
|
178
|
+
continue;
|
|
179
|
+
if (f.backbone0) {
|
|
180
|
+
LOG ("scheduling backbone literal candidate %s", LOGLIT (v));
|
|
181
|
+
candidates.push_back (v);
|
|
182
|
+
} else
|
|
183
|
+
++not_rescheduled;
|
|
184
|
+
if (f.backbone1) {
|
|
185
|
+
LOG ("scheduling backbone literal candidate %s", LOGLIT (-v));
|
|
186
|
+
candidates.push_back (-v);
|
|
187
|
+
} else
|
|
188
|
+
++not_rescheduled;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (not_rescheduled) {
|
|
192
|
+
for (auto v : vars) {
|
|
193
|
+
const Flags f = flags (v);
|
|
194
|
+
if (!f.active ())
|
|
195
|
+
continue;
|
|
196
|
+
if (!f.backbone0) {
|
|
197
|
+
LOG ("scheduling backbone literal candidate %s", LOGLIT (v));
|
|
198
|
+
candidates.push_back (v);
|
|
199
|
+
}
|
|
200
|
+
if (!f.backbone1) {
|
|
201
|
+
LOG ("scheduling backbone literal candidate %s", LOGLIT (-v));
|
|
202
|
+
candidates.push_back (-v);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
assert (candidates.size () <= 2 * (size_t) max_var);
|
|
207
|
+
|
|
208
|
+
VERBOSE (3,
|
|
209
|
+
"backbone schedule %zu backbone candidates in total %f "
|
|
210
|
+
"(rescheduled: %f%%)",
|
|
211
|
+
candidates.size (), percent (candidates.size (), 2 * max_var),
|
|
212
|
+
percent (not_rescheduled, 2 * max_var));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
int Internal::backbone_analyze (Clause *, int64_t &ticks) {
|
|
216
|
+
assert (conflict);
|
|
217
|
+
assert (conflict->size == 2);
|
|
218
|
+
analyzed.push_back (std::abs (conflict->literals[0]));
|
|
219
|
+
flags (conflict->literals[0]).seen = true;
|
|
220
|
+
analyzed.push_back (std::abs (conflict->literals[1]));
|
|
221
|
+
flags (conflict->literals[1]).seen = true;
|
|
222
|
+
LOG (conflict, "analyzing conflict");
|
|
223
|
+
if (lrat)
|
|
224
|
+
lrat_chain.push_back (conflict->id);
|
|
225
|
+
conflict = nullptr;
|
|
226
|
+
|
|
227
|
+
for (auto t = trail.rbegin ();;) {
|
|
228
|
+
assert (t < trail.rend ());
|
|
229
|
+
int lit = *t++;
|
|
230
|
+
LOG ("analyzing %s", LOGLIT (lit));
|
|
231
|
+
if (!flags (lit).seen)
|
|
232
|
+
continue;
|
|
233
|
+
Clause *reason = var (lit).reason;
|
|
234
|
+
LOG (reason, "resolving with reason of %s", LOGLIT (lit));
|
|
235
|
+
assert (reason), assert (reason != decision_reason);
|
|
236
|
+
++ticks;
|
|
237
|
+
const int other = reason->literals[0] ^ reason->literals[1] ^ lit;
|
|
238
|
+
Flags &f_o = flags (other);
|
|
239
|
+
if (lrat)
|
|
240
|
+
lrat_chain.push_back (reason->id);
|
|
241
|
+
if (!f_o.seen) {
|
|
242
|
+
f_o.seen = true;
|
|
243
|
+
analyzed.push_back (other);
|
|
244
|
+
} else {
|
|
245
|
+
LOG ("backbone UIP %s", LOGLIT (other));
|
|
246
|
+
for (auto lit : analyzed)
|
|
247
|
+
flags (lit).seen = false;
|
|
248
|
+
analyzed.clear ();
|
|
249
|
+
if (lrat)
|
|
250
|
+
reverse (begin (lrat_chain), end (lrat_chain));
|
|
251
|
+
return other;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
inline void Internal::backbone_unit_reassign (int lit) {
|
|
257
|
+
#ifdef LOGGING
|
|
258
|
+
LOG ("reassigning %s to level 0", LOGLIT (lit));
|
|
259
|
+
assert (val (lit) > 0);
|
|
260
|
+
assert (val (-lit) < 0);
|
|
261
|
+
#else
|
|
262
|
+
(void) lit;
|
|
263
|
+
#endif
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
inline void Internal::backbone_unit_assign (int lit) {
|
|
268
|
+
LOG ("assigning %s to level 0", LOGLIT (lit));
|
|
269
|
+
require_mode (BACKBONE);
|
|
270
|
+
const int idx = vidx (lit);
|
|
271
|
+
assert (!vals[idx]);
|
|
272
|
+
Var &v = var (idx);
|
|
273
|
+
v.level = 0; // required to reuse decisions
|
|
274
|
+
v.trail = (int) trail.size (); // used in 'vivify_better_watch'
|
|
275
|
+
assert ((int) num_assigned < max_var);
|
|
276
|
+
num_assigned++;
|
|
277
|
+
v.reason = 0; // for conflict analysis
|
|
278
|
+
learn_unit_clause (lit);
|
|
279
|
+
lrat_chain.clear ();
|
|
280
|
+
const signed char tmp = sign (lit);
|
|
281
|
+
vals[idx] = tmp;
|
|
282
|
+
vals[-idx] = -tmp;
|
|
283
|
+
assert (val (lit) > 0);
|
|
284
|
+
assert (val (-lit) < 0);
|
|
285
|
+
trail.push_back (lit);
|
|
286
|
+
LOG ("backbone assign %d to level 0", lit);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
inline void Internal::backbone_assign_any (int lit, Clause *reason) {
|
|
290
|
+
require_mode (BACKBONE);
|
|
291
|
+
const int idx = vidx (lit);
|
|
292
|
+
assert (!vals[idx]);
|
|
293
|
+
assert (!flags (idx).eliminated () || !reason);
|
|
294
|
+
assert (reason == decision_reason || !reason || reason->size >= 2);
|
|
295
|
+
Var &v = var (idx);
|
|
296
|
+
v.level = level; // required to reuse decisions
|
|
297
|
+
v.trail = (int) trail.size (); // used in 'vivify_better_watch'
|
|
298
|
+
assert ((int) num_assigned < max_var);
|
|
299
|
+
num_assigned++;
|
|
300
|
+
v.reason = level ? reason : 0; // for conflict analysis
|
|
301
|
+
if (!level)
|
|
302
|
+
learn_unit_clause (lit);
|
|
303
|
+
const signed char tmp = sign (lit);
|
|
304
|
+
vals[idx] = tmp;
|
|
305
|
+
vals[-idx] = -tmp;
|
|
306
|
+
assert (val (lit) > 0);
|
|
307
|
+
assert (val (-lit) < 0);
|
|
308
|
+
trail.push_back (lit);
|
|
309
|
+
LOG (reason, "backbone assign %d", lit);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
inline void Internal::backbone_assign (int lit, Clause *reason) {
|
|
313
|
+
require_mode (BACKBONE);
|
|
314
|
+
const int idx = vidx (lit);
|
|
315
|
+
assert (!vals[idx]);
|
|
316
|
+
assert (!flags (idx).eliminated () || !reason);
|
|
317
|
+
assert (reason == decision_reason || !reason || reason->size == 2);
|
|
318
|
+
Var &v = var (idx);
|
|
319
|
+
v.level = level; // required to reuse decisions
|
|
320
|
+
v.trail = (int) trail.size (); // used in 'vivify_better_watch'
|
|
321
|
+
assert ((int) num_assigned < max_var);
|
|
322
|
+
num_assigned++;
|
|
323
|
+
v.reason = level ? reason : 0; // for conflict analysis
|
|
324
|
+
if (!level)
|
|
325
|
+
learn_unit_clause (lit);
|
|
326
|
+
const signed char tmp = sign (lit);
|
|
327
|
+
vals[idx] = tmp;
|
|
328
|
+
vals[-idx] = -tmp;
|
|
329
|
+
assert (val (lit) > 0);
|
|
330
|
+
assert (val (-lit) < 0);
|
|
331
|
+
trail.push_back (lit);
|
|
332
|
+
LOG (reason, "backbone assign %d", lit);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
void Internal::backbone_decision (int lit) {
|
|
336
|
+
require_mode (BACKBONE);
|
|
337
|
+
assert (propagated2 == trail.size ());
|
|
338
|
+
new_trail_level (lit);
|
|
339
|
+
notify_decision ();
|
|
340
|
+
LOG ("search decide %d", lit);
|
|
341
|
+
backbone_assign (lit, decision_reason);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
unsigned Internal::compute_backbone_round (std::vector<int> &candidates,
|
|
345
|
+
std::vector<int> &units,
|
|
346
|
+
const int64_t ticks_limit,
|
|
347
|
+
int64_t &ticks,
|
|
348
|
+
unsigned inconsistent) {
|
|
349
|
+
assert (!conflict);
|
|
350
|
+
auto p = begin (candidates);
|
|
351
|
+
auto q = p;
|
|
352
|
+
const auto end = std::end (candidates);
|
|
353
|
+
size_t failed = 0;
|
|
354
|
+
++stats.backbone.rounds;
|
|
355
|
+
|
|
356
|
+
LOG (candidates, "candidates: ");
|
|
357
|
+
ticks += 1 + cache_lines (candidates.size (),
|
|
358
|
+
sizeof (std::vector<int>::iterator *));
|
|
359
|
+
while (p != end) {
|
|
360
|
+
assert (p < end);
|
|
361
|
+
assert (q <= p);
|
|
362
|
+
assert (!conflict);
|
|
363
|
+
const int probe = (*q = *p);
|
|
364
|
+
++stats.backbone.probes;
|
|
365
|
+
|
|
366
|
+
++p, ++q;
|
|
367
|
+
const signed char v = val (probe);
|
|
368
|
+
if (v > 0) {
|
|
369
|
+
q--;
|
|
370
|
+
LOG ("removing satisfied backbone probe %s", LOGLIT (probe));
|
|
371
|
+
if (probe < 0)
|
|
372
|
+
flags (probe).backbone1 = false;
|
|
373
|
+
else
|
|
374
|
+
flags (probe).backbone0 = false;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (v < 0) {
|
|
379
|
+
if (var (probe).level)
|
|
380
|
+
LOG ("skipping falsified backbone probe %s", LOGLIT (probe));
|
|
381
|
+
else {
|
|
382
|
+
LOG ("removing root-level falsified backbone probe %s",
|
|
383
|
+
LOGLIT (probe));
|
|
384
|
+
q--;
|
|
385
|
+
}
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
if (ticks >= ticks_limit)
|
|
389
|
+
break;
|
|
390
|
+
backbone_decision (probe);
|
|
391
|
+
backbone_propagate2 (ticks);
|
|
392
|
+
if (!conflict) {
|
|
393
|
+
LOG (candidates,
|
|
394
|
+
"propagating backbone probe %s successful; candidates:",
|
|
395
|
+
LOGLIT (probe));
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
++failed;
|
|
400
|
+
++stats.backbone.units;
|
|
401
|
+
int uip = backbone_analyze (conflict, ticks);
|
|
402
|
+
backtrack_without_updating_phases (level - 1);
|
|
403
|
+
backbone_unit_assign (uip);
|
|
404
|
+
++stats.units;
|
|
405
|
+
assert (!conflict);
|
|
406
|
+
if (external->learner)
|
|
407
|
+
external->export_learned_unit_clause (uip);
|
|
408
|
+
|
|
409
|
+
backbone_propagate2 (ticks);
|
|
410
|
+
if (conflict) {
|
|
411
|
+
LOG ("propagating backbone forced %s failed", LOGLIT (uip));
|
|
412
|
+
inconsistent = uip;
|
|
413
|
+
// we have to give up on the current conflict
|
|
414
|
+
conflict = nullptr;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
units.push_back (uip);
|
|
418
|
+
}
|
|
419
|
+
while (p != end)
|
|
420
|
+
*q++ = *p++;
|
|
421
|
+
assert (q <= end);
|
|
422
|
+
candidates.resize (q - begin (candidates));
|
|
423
|
+
LOG (candidates, "candidates: ");
|
|
424
|
+
|
|
425
|
+
if (!inconsistent) {
|
|
426
|
+
LOG ("flushing satisfied probe candidates");
|
|
427
|
+
auto p = begin (candidates);
|
|
428
|
+
auto q = p;
|
|
429
|
+
const auto end = std::end (candidates);
|
|
430
|
+
|
|
431
|
+
while (p != end) {
|
|
432
|
+
const int probe = (*q++ = *p++);
|
|
433
|
+
const signed char v = val (probe);
|
|
434
|
+
if (v > 0) {
|
|
435
|
+
q--;
|
|
436
|
+
LOG ("removing satisfied backbone probe %s", LOGLIT (probe));
|
|
437
|
+
if (probe < 0)
|
|
438
|
+
flags (probe).backbone1 = false;
|
|
439
|
+
else
|
|
440
|
+
flags (probe).backbone0 = false;
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (v < 0) {
|
|
445
|
+
LOG ("keeping falsified probe %s", LOGLIT (probe));
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
assert (!v);
|
|
449
|
+
LOG ("keeping unassigned probe %s", LOGLIT (probe));
|
|
450
|
+
}
|
|
451
|
+
candidates.resize (q - begin (candidates));
|
|
452
|
+
}
|
|
453
|
+
LOG (candidates, "candidates after !inconsistent: ");
|
|
454
|
+
if (level)
|
|
455
|
+
backtrack_without_updating_phases ();
|
|
456
|
+
if (!inconsistent && !units.empty ()) {
|
|
457
|
+
for (auto l : units) {
|
|
458
|
+
backbone_unit_reassign (l);
|
|
459
|
+
}
|
|
460
|
+
units.clear ();
|
|
461
|
+
if (!backbone_propagate (ticks)) {
|
|
462
|
+
LOG (conflict, "final repropagation yielded conflict");
|
|
463
|
+
learn_empty_clause ();
|
|
464
|
+
}
|
|
465
|
+
} else {
|
|
466
|
+
if (!backbone_propagate (ticks)) {
|
|
467
|
+
learn_empty_clause ();
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
LOG (candidates, "candidates end of loop: ");
|
|
471
|
+
|
|
472
|
+
LOG (candidates, "candidates end of backbone_round: ");
|
|
473
|
+
return failed;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
void Internal::keep_backbone_candidates (
|
|
477
|
+
const std::vector<int> &candidates) {
|
|
478
|
+
size_t remain = 0;
|
|
479
|
+
size_t prioritized = 0;
|
|
480
|
+
for (auto v : candidates) {
|
|
481
|
+
const Flags &f = flags (v);
|
|
482
|
+
if (!f.active ())
|
|
483
|
+
continue;
|
|
484
|
+
++remain;
|
|
485
|
+
if (v < 0)
|
|
486
|
+
prioritized += f.backbone1;
|
|
487
|
+
else
|
|
488
|
+
prioritized += f.backbone0;
|
|
489
|
+
}
|
|
490
|
+
assert (prioritized <= remain);
|
|
491
|
+
if (!remain) {
|
|
492
|
+
#ifndef NDEBUG
|
|
493
|
+
for (auto v : candidates) {
|
|
494
|
+
const Flags &f = flags (v);
|
|
495
|
+
if (!f.active ())
|
|
496
|
+
continue;
|
|
497
|
+
assert (!f.backbone0);
|
|
498
|
+
assert (!f.backbone1);
|
|
499
|
+
}
|
|
500
|
+
#endif
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
if (prioritized == remain) {
|
|
504
|
+
LOG ("keeping all remaining backbones");
|
|
505
|
+
} else if (!prioritized) {
|
|
506
|
+
for (auto v : candidates) {
|
|
507
|
+
Flags &f = flags (v);
|
|
508
|
+
if (!f.active ())
|
|
509
|
+
continue;
|
|
510
|
+
++remain;
|
|
511
|
+
if (v < 0) {
|
|
512
|
+
assert (!f.backbone1);
|
|
513
|
+
f.backbone1 = true;
|
|
514
|
+
} else {
|
|
515
|
+
assert (!f.backbone0);
|
|
516
|
+
f.backbone0 = true;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
unsigned Internal::compute_backbone () {
|
|
523
|
+
size_t failed = 0;
|
|
524
|
+
|
|
525
|
+
int64_t ticks = 0;
|
|
526
|
+
backbone_propagate2 (ticks);
|
|
527
|
+
assert (!conflict);
|
|
528
|
+
|
|
529
|
+
std::vector<int> candidates, units;
|
|
530
|
+
unsigned inconsistent = 0;
|
|
531
|
+
assert (!conflict);
|
|
532
|
+
|
|
533
|
+
++stats.backbone.phases;
|
|
534
|
+
schedule_backbone_cands (candidates);
|
|
535
|
+
|
|
536
|
+
const size_t max_rounds = opts.backbonemaxrounds;
|
|
537
|
+
size_t round_limit = opts.backbonerounds;
|
|
538
|
+
round_limit *= stats.backbone.phases;
|
|
539
|
+
if (round_limit > max_rounds)
|
|
540
|
+
round_limit = max_rounds;
|
|
541
|
+
|
|
542
|
+
SET_EFFORT_LIMIT (totalticks, backbone, false);
|
|
543
|
+
int64_t ticks_limit = totalticks - stats.ticks.backbone;
|
|
544
|
+
PHASE ("backbone", stats.backbone.phases,
|
|
545
|
+
"backbone limit of %" PRId64 " ticks", ticks_limit);
|
|
546
|
+
size_t rounds = 0;
|
|
547
|
+
for (; ++rounds;) {
|
|
548
|
+
if (rounds >= round_limit) {
|
|
549
|
+
LOG ("backround round limit %zu rounds", rounds);
|
|
550
|
+
break;
|
|
551
|
+
}
|
|
552
|
+
if (ticks >= ticks_limit) {
|
|
553
|
+
LOG ("backround round limit %" PRIu64 " ticks", ticks);
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
VERBOSE (3,
|
|
557
|
+
"backbone round %zu of %zu with %" PRId64
|
|
558
|
+
" ticks (%f %% done) with %zu failed so far",
|
|
559
|
+
rounds, max_rounds, ticks, percent (ticks, ticks_limit),
|
|
560
|
+
failed);
|
|
561
|
+
size_t new_failed = compute_backbone_round (
|
|
562
|
+
candidates, units, ticks_limit, ticks, inconsistent);
|
|
563
|
+
failed += new_failed;
|
|
564
|
+
if (inconsistent)
|
|
565
|
+
break;
|
|
566
|
+
if (candidates.empty ())
|
|
567
|
+
break;
|
|
568
|
+
if (unsat)
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (inconsistent && !unsat) {
|
|
573
|
+
LOG ("using forced unit %s by repropagating at level 0",
|
|
574
|
+
LOGLIT (inconsistent));
|
|
575
|
+
backtrack_without_updating_phases ();
|
|
576
|
+
propagate ();
|
|
577
|
+
learn_empty_clause ();
|
|
578
|
+
}
|
|
579
|
+
if (unsat) {
|
|
580
|
+
PHASE ("backbone", stats.backbone.phases,
|
|
581
|
+
"inconsistent binary clauses");
|
|
582
|
+
} else {
|
|
583
|
+
PHASE ("backbone", stats.backbone.phases,
|
|
584
|
+
"found %zu backbone literals %zu round in %" PRId64 " ticks",
|
|
585
|
+
failed, rounds, ticks);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
keep_backbone_candidates (candidates);
|
|
589
|
+
if (level) {
|
|
590
|
+
backtrack_without_updating_phases ();
|
|
591
|
+
if (!backbone_propagate (ticks)) {
|
|
592
|
+
learn_empty_clause ();
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
stats.ticks.backbone += ticks;
|
|
596
|
+
return failed;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
void Internal::binary_clauses_backbone () {
|
|
600
|
+
if (unsat)
|
|
601
|
+
return;
|
|
602
|
+
if (!opts.backbone)
|
|
603
|
+
return;
|
|
604
|
+
if (level)
|
|
605
|
+
backtrack_without_updating_phases ();
|
|
606
|
+
propagated2 = 0; // TODO: why?
|
|
607
|
+
if (!propagate ()) {
|
|
608
|
+
LOG ("propagation after connecting watches in inconsistency");
|
|
609
|
+
learn_empty_clause ();
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
for (auto lit : lits) {
|
|
614
|
+
Watches &w = watches (lit);
|
|
615
|
+
std::stable_partition (begin (w), end (w),
|
|
616
|
+
[] (Watch w) { return w.binary (); });
|
|
617
|
+
}
|
|
618
|
+
assert (propagated2 <= trail.size ());
|
|
619
|
+
private_steps = true;
|
|
620
|
+
|
|
621
|
+
assert (watching ());
|
|
622
|
+
START_SIMPLIFIER (backbone, BACKBONE);
|
|
623
|
+
int failed = compute_backbone ();
|
|
624
|
+
assert (!level);
|
|
625
|
+
private_steps = false;
|
|
626
|
+
|
|
627
|
+
report ('k', !failed);
|
|
628
|
+
STOP_SIMPLIFIER (backbone, BACKBONE);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
} // namespace CaDiCaL
|