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,34 @@
|
|
|
1
|
+
#ifndef _cover_hpp_INCLUDED
|
|
2
|
+
#define _cover_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
/*------------------------------------------------------------------------*/
|
|
5
|
+
|
|
6
|
+
// This header only provides the 'COVER' macro for testing. It is unrelated
|
|
7
|
+
// to 'cover.cpp' which implements covered clause elimination (CCE), but we
|
|
8
|
+
// wanted to use the name base name in both cases. More explanation on CCE
|
|
9
|
+
// is provided in 'cover.cpp'.
|
|
10
|
+
|
|
11
|
+
/*------------------------------------------------------------------------*/
|
|
12
|
+
|
|
13
|
+
// Coverage goal, used similar to 'assert' (but with flipped condition) and
|
|
14
|
+
// also included even if 'NDEBUG' is defined (in optimizing compilation).
|
|
15
|
+
//
|
|
16
|
+
// This should in essence not be used in production code.
|
|
17
|
+
//
|
|
18
|
+
// There seems to be no problem overloading the name 'COVER' of this macro
|
|
19
|
+
// with the constant 'COVER' of 'Internal::Mode' (surprisingly).
|
|
20
|
+
|
|
21
|
+
#define COVER(COND) \
|
|
22
|
+
do { \
|
|
23
|
+
if (!(COND)) \
|
|
24
|
+
break; \
|
|
25
|
+
fprintf (stderr, \
|
|
26
|
+
"%scadical%s: %s:%d: %s: Coverage goal %s`%s'%s reached.\n", \
|
|
27
|
+
terr.bold_code (), terr.normal_code (), __FUNCTION__, \
|
|
28
|
+
__LINE__, __FILE__, terr.green_code (), #COND, \
|
|
29
|
+
terr.normal_code ()); \
|
|
30
|
+
fflush (stderr); \
|
|
31
|
+
abort (); \
|
|
32
|
+
} while (0)
|
|
33
|
+
|
|
34
|
+
#endif
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
|
|
3
|
+
namespace CaDiCaL {
|
|
4
|
+
|
|
5
|
+
// This function determines the next decision variable on the queue, without
|
|
6
|
+
// actually removing it from the decision queue, e.g., calling it multiple
|
|
7
|
+
// times without any assignment will return the same result. This is of
|
|
8
|
+
// course used below in 'decide' but also in 'reuse_trail' to determine the
|
|
9
|
+
// largest decision level to backtrack to during 'restart' without changing
|
|
10
|
+
// the assigned variables (if 'opts.restartreusetrail' is non-zero).
|
|
11
|
+
|
|
12
|
+
int Internal::next_decision_variable_on_queue () {
|
|
13
|
+
int64_t searched = 0;
|
|
14
|
+
int res = queue.unassigned;
|
|
15
|
+
while (val (res))
|
|
16
|
+
res = link (res).prev, searched++;
|
|
17
|
+
if (searched) {
|
|
18
|
+
stats.searched += searched;
|
|
19
|
+
update_queue_unassigned (res);
|
|
20
|
+
}
|
|
21
|
+
LOG ("next queue decision variable %d bumped %" PRId64 "", res,
|
|
22
|
+
bumped (res));
|
|
23
|
+
return res;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// This function determines the best decision with respect to score.
|
|
27
|
+
//
|
|
28
|
+
int Internal::next_decision_variable_with_best_score () {
|
|
29
|
+
int res = 0;
|
|
30
|
+
for (;;) {
|
|
31
|
+
res = scores.front ();
|
|
32
|
+
if (!val (res))
|
|
33
|
+
break;
|
|
34
|
+
(void) scores.pop_front ();
|
|
35
|
+
}
|
|
36
|
+
LOG ("next decision variable %d with score %g", res, score (res));
|
|
37
|
+
return res;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
void Internal::start_random_sequence () {
|
|
41
|
+
if (!opts.randec)
|
|
42
|
+
return;
|
|
43
|
+
|
|
44
|
+
assert (!stable || opts.randecstable);
|
|
45
|
+
assert (stable || opts.randecfocused);
|
|
46
|
+
assert (!randomized_deciding);
|
|
47
|
+
|
|
48
|
+
const uint64_t count = ++stats.randec.random_decision_phases;
|
|
49
|
+
const unsigned length = opts.randeclength * log (count + 10);
|
|
50
|
+
VERBOSE (3,
|
|
51
|
+
"starting random decision sequence "
|
|
52
|
+
"at %" PRId64 " conflicts for %u conflicts",
|
|
53
|
+
stats.conflicts, length);
|
|
54
|
+
randomized_deciding = length;
|
|
55
|
+
|
|
56
|
+
const double delta = stats.randec.random_decision_phases *
|
|
57
|
+
log (stats.randec.random_decision_phases);
|
|
58
|
+
lim.random_decision = stats.conflicts + delta * opts.randecint;
|
|
59
|
+
VERBOSE (3,
|
|
60
|
+
"next random decision sequence "
|
|
61
|
+
"at %" PRId64 " conflicts current conflict: %" PRId64
|
|
62
|
+
" conflicts",
|
|
63
|
+
lim.random_decision, stats.conflicts);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
int Internal::next_random_decision () {
|
|
67
|
+
assert (max_var);
|
|
68
|
+
if (!opts.randec)
|
|
69
|
+
return 0;
|
|
70
|
+
if (stable && !opts.randecstable)
|
|
71
|
+
return 0;
|
|
72
|
+
if (!stable && !opts.randecfocused)
|
|
73
|
+
return 0;
|
|
74
|
+
if (stats.conflicts < lim.random_decision)
|
|
75
|
+
return 0;
|
|
76
|
+
if (satisfied ())
|
|
77
|
+
return 0;
|
|
78
|
+
|
|
79
|
+
if (!randomized_deciding) {
|
|
80
|
+
if (level > (int) assumptions.size () + !!constraint.size ()) {
|
|
81
|
+
LOG ("random decision delayed because too deep");
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
start_random_sequence ();
|
|
85
|
+
}
|
|
86
|
+
LOG ("searching for random decision");
|
|
87
|
+
Random random (internal->opts.seed);
|
|
88
|
+
random += stats.decisions;
|
|
89
|
+
++stats.randec.random_decisions;
|
|
90
|
+
for (;;) {
|
|
91
|
+
int idx = 1 + (random.next () % max_var);
|
|
92
|
+
LOG ("trying lit %s", LOGLIT (idx));
|
|
93
|
+
/*
|
|
94
|
+
// Kissat filters out active literals but we cannot do that because
|
|
95
|
+
// eliminated variables are not actively removed.
|
|
96
|
+
if (!flags (idx).active())
|
|
97
|
+
continue;
|
|
98
|
+
*/
|
|
99
|
+
if (val (idx))
|
|
100
|
+
continue;
|
|
101
|
+
return idx;
|
|
102
|
+
}
|
|
103
|
+
assert (false);
|
|
104
|
+
__builtin_unreachable ();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
int Internal::next_decision_variable () {
|
|
108
|
+
int res = next_random_decision ();
|
|
109
|
+
if (res) {
|
|
110
|
+
LOG ("randomized decision %s", LOGLIT (res));
|
|
111
|
+
return res;
|
|
112
|
+
}
|
|
113
|
+
if (use_scores ())
|
|
114
|
+
return next_decision_variable_with_best_score ();
|
|
115
|
+
else
|
|
116
|
+
return next_decision_variable_on_queue ();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/*------------------------------------------------------------------------*/
|
|
120
|
+
|
|
121
|
+
// Implements phase saving as well using a target phase during
|
|
122
|
+
// stabilization unless decision phase is forced to the initial value
|
|
123
|
+
// of a phase is forced through the 'phase' option.
|
|
124
|
+
|
|
125
|
+
int Internal::decide_phase (int idx, bool target) {
|
|
126
|
+
const int initial_phase = opts.phase ? 1 : -1;
|
|
127
|
+
int phase = 0;
|
|
128
|
+
if (force_saved_phase) {
|
|
129
|
+
phase = phases.saved[idx];
|
|
130
|
+
LOG ("trying force_saved_phase, i.e., %d", phase);
|
|
131
|
+
}
|
|
132
|
+
assert (force_saved_phase || !phase);
|
|
133
|
+
if (!phase) {
|
|
134
|
+
phase = phases.forced[idx]; // swapped with opts.forcephase case!
|
|
135
|
+
LOG ("trying forced phase, i.e., %d", phase);
|
|
136
|
+
}
|
|
137
|
+
if (!phase && opts.forcephase) {
|
|
138
|
+
phase = initial_phase;
|
|
139
|
+
LOG ("trying initial phase, i.e., %d", phase);
|
|
140
|
+
}
|
|
141
|
+
if (!phase && target) {
|
|
142
|
+
phase = phases.target[idx];
|
|
143
|
+
}
|
|
144
|
+
if (!phase) {
|
|
145
|
+
// ported from kissat where it does not seem very useful
|
|
146
|
+
if (opts.stubbornIOfocused && opts.rephase == 2)
|
|
147
|
+
switch ((stats.rephased.total >> 1) & 7) {
|
|
148
|
+
case 1:
|
|
149
|
+
phase = initial_phase;
|
|
150
|
+
break;
|
|
151
|
+
case 5: // kissat has 3 but 5 looks better
|
|
152
|
+
phase = -initial_phase;
|
|
153
|
+
break;
|
|
154
|
+
default:
|
|
155
|
+
phase = phases.saved[idx];
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
else
|
|
159
|
+
phase = phases.saved[idx];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// The following should not be necessary and in some version we had even
|
|
163
|
+
// a hard 'COVER' assertion here to check for this. Unfortunately it
|
|
164
|
+
// triggered for some users and we could not get to the root cause of
|
|
165
|
+
// 'phase' still not being set here. The logic for phase and target
|
|
166
|
+
// saving is pretty complex, particularly in combination with local
|
|
167
|
+
// search, and to avoid running in such an issue in the future again, we
|
|
168
|
+
// now use this 'defensive' code here, even though such defensive code is
|
|
169
|
+
// considered bad programming practice.
|
|
170
|
+
//
|
|
171
|
+
if (!phase)
|
|
172
|
+
phase = initial_phase;
|
|
173
|
+
|
|
174
|
+
return phase * idx;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// The likely phase of an variable used in 'collect' for optimizing
|
|
178
|
+
// co-location of clauses likely accessed together during search.
|
|
179
|
+
|
|
180
|
+
int Internal::likely_phase (int idx) { return decide_phase (idx, false); }
|
|
181
|
+
|
|
182
|
+
/*------------------------------------------------------------------------*/
|
|
183
|
+
|
|
184
|
+
// adds new level to control and trail
|
|
185
|
+
//
|
|
186
|
+
void Internal::new_trail_level (int lit) {
|
|
187
|
+
level++;
|
|
188
|
+
control.push_back (Level (lit, trail.size ()));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/*------------------------------------------------------------------------*/
|
|
192
|
+
|
|
193
|
+
bool Internal::satisfied () {
|
|
194
|
+
if ((size_t) level < assumptions.size () + (!!constraint.size ()))
|
|
195
|
+
return false;
|
|
196
|
+
if (num_assigned < (size_t) max_var)
|
|
197
|
+
return false;
|
|
198
|
+
assert (num_assigned == (size_t) max_var);
|
|
199
|
+
if (propagated < trail.size ())
|
|
200
|
+
return false;
|
|
201
|
+
size_t assigned = num_assigned;
|
|
202
|
+
return (assigned == (size_t) max_var);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
bool Internal::better_decision (int lit, int other) {
|
|
206
|
+
int lit_idx = abs (lit);
|
|
207
|
+
int other_idx = abs (other);
|
|
208
|
+
if (stable)
|
|
209
|
+
return stab[lit_idx] > stab[other_idx];
|
|
210
|
+
else
|
|
211
|
+
return btab[lit_idx] > btab[other_idx];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Search for the next decision and assign it to the saved phase. Requires
|
|
215
|
+
// that not all variables are assigned.
|
|
216
|
+
|
|
217
|
+
int Internal::decide () {
|
|
218
|
+
assert (!satisfied ());
|
|
219
|
+
START (decide);
|
|
220
|
+
int res = 0;
|
|
221
|
+
if ((size_t) level < assumptions.size ()) {
|
|
222
|
+
const int lit = assumptions[level];
|
|
223
|
+
assert (assumed (lit));
|
|
224
|
+
const signed char tmp = val (lit);
|
|
225
|
+
if (tmp < 0) {
|
|
226
|
+
LOG ("assumption %d falsified", lit);
|
|
227
|
+
res = 20;
|
|
228
|
+
} else if (tmp > 0) {
|
|
229
|
+
LOG ("assumption %d already satisfied", lit);
|
|
230
|
+
new_trail_level (0);
|
|
231
|
+
LOG ("added pseudo decision level");
|
|
232
|
+
notify_decision ();
|
|
233
|
+
} else {
|
|
234
|
+
LOG ("deciding assumption %d", lit);
|
|
235
|
+
search_assume_decision (lit);
|
|
236
|
+
}
|
|
237
|
+
} else if ((size_t) level == assumptions.size () && constraint.size ()) {
|
|
238
|
+
|
|
239
|
+
int satisfied_lit = 0; // The literal satisfying the constrain.
|
|
240
|
+
int unassigned_lit = 0; // Highest score unassigned literal.
|
|
241
|
+
int previous_lit = 0; // Move satisfied literals to the front.
|
|
242
|
+
|
|
243
|
+
const size_t size_constraint = constraint.size ();
|
|
244
|
+
|
|
245
|
+
#ifndef NDEBUG
|
|
246
|
+
unsigned sum = 0;
|
|
247
|
+
for (auto lit : constraint)
|
|
248
|
+
sum += lit;
|
|
249
|
+
#endif
|
|
250
|
+
for (size_t i = 0; i != size_constraint; i++) {
|
|
251
|
+
|
|
252
|
+
// Get literal and move 'constraint[i] = constraint[i-1]'.
|
|
253
|
+
|
|
254
|
+
int lit = constraint[i];
|
|
255
|
+
constraint[i] = previous_lit;
|
|
256
|
+
previous_lit = lit;
|
|
257
|
+
|
|
258
|
+
const signed char tmp = val (lit);
|
|
259
|
+
if (tmp < 0) {
|
|
260
|
+
LOG ("constraint literal %d falsified", lit);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (tmp > 0) {
|
|
265
|
+
LOG ("constraint literal %d satisfied", lit);
|
|
266
|
+
satisfied_lit = lit;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
assert (!tmp);
|
|
271
|
+
LOG ("constraint literal %d unassigned", lit);
|
|
272
|
+
|
|
273
|
+
if (!unassigned_lit || better_decision (lit, unassigned_lit))
|
|
274
|
+
unassigned_lit = lit;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (satisfied_lit) {
|
|
278
|
+
|
|
279
|
+
constraint[0] = satisfied_lit; // Move satisfied to the front.
|
|
280
|
+
|
|
281
|
+
LOG ("literal %d satisfies constraint and "
|
|
282
|
+
"is implied by assumptions",
|
|
283
|
+
satisfied_lit);
|
|
284
|
+
|
|
285
|
+
new_trail_level (0);
|
|
286
|
+
LOG ("added pseudo decision level for constraint");
|
|
287
|
+
notify_decision ();
|
|
288
|
+
|
|
289
|
+
} else {
|
|
290
|
+
|
|
291
|
+
// Just move all the literals back. If we found an unsatisfied
|
|
292
|
+
// literal then it will be satisfied (most likely) at the next
|
|
293
|
+
// decision and moved then to the first position.
|
|
294
|
+
|
|
295
|
+
if (size_constraint) {
|
|
296
|
+
|
|
297
|
+
for (size_t i = 0; i + 1 != size_constraint; i++)
|
|
298
|
+
constraint[i] = constraint[i + 1];
|
|
299
|
+
|
|
300
|
+
constraint[size_constraint - 1] = previous_lit;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (unassigned_lit) {
|
|
304
|
+
|
|
305
|
+
LOG ("deciding %d to satisfy constraint", unassigned_lit);
|
|
306
|
+
search_assume_decision (unassigned_lit);
|
|
307
|
+
|
|
308
|
+
} else {
|
|
309
|
+
|
|
310
|
+
LOG ("failing constraint");
|
|
311
|
+
unsat_constraint = true;
|
|
312
|
+
res = 20;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
#ifndef NDEBUG
|
|
317
|
+
for (auto lit : constraint)
|
|
318
|
+
sum -= lit;
|
|
319
|
+
assert (!sum); // Checksum of literal should not change!
|
|
320
|
+
#endif
|
|
321
|
+
|
|
322
|
+
} else {
|
|
323
|
+
|
|
324
|
+
int decision = ask_decision ();
|
|
325
|
+
if ((size_t) level < assumptions.size () ||
|
|
326
|
+
((size_t) level == assumptions.size () && constraint.size ())) {
|
|
327
|
+
// Forced backtrack below pseudo decision levels.
|
|
328
|
+
// So one of the two branches above will handle it.
|
|
329
|
+
STOP (decide);
|
|
330
|
+
res = decide (); // STARTS and STOPS profiling
|
|
331
|
+
START (decide);
|
|
332
|
+
} else {
|
|
333
|
+
stats.decisions++;
|
|
334
|
+
if (!decision) {
|
|
335
|
+
int idx = next_decision_variable ();
|
|
336
|
+
const bool target = (opts.target > 1 || (stable && opts.target));
|
|
337
|
+
decision = decide_phase (idx, target);
|
|
338
|
+
}
|
|
339
|
+
search_assume_decision (decision);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (res)
|
|
343
|
+
marked_failed = false;
|
|
344
|
+
STOP (decide);
|
|
345
|
+
return res;
|
|
346
|
+
}
|
|
347
|
+
} // namespace CaDiCaL
|