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,95 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
|
|
3
|
+
namespace CaDiCaL {
|
|
4
|
+
|
|
5
|
+
// Updating an exponential moving average is placed here since we want to
|
|
6
|
+
// log both updates and phases of initialization, thus need 'LOG'.
|
|
7
|
+
//
|
|
8
|
+
// We now use initialization bias correction as in the ADAM method
|
|
9
|
+
// [KingmaBa-ICLR'15] instead of our ad-hoc initialization method used
|
|
10
|
+
// before. Our old variant used exponentially decreasing alphas:
|
|
11
|
+
//
|
|
12
|
+
// 1,
|
|
13
|
+
// 1/2, 1/2,
|
|
14
|
+
// 1/4, 1/4, 1/4, 1/4
|
|
15
|
+
// 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8,
|
|
16
|
+
// ...
|
|
17
|
+
// 2^-n, ..., 2^-n 'n' times
|
|
18
|
+
// alpha, alpha, ... now 'alpha' forever.
|
|
19
|
+
//
|
|
20
|
+
// where 2^-n is the smallest negative power of two above 'alpha'
|
|
21
|
+
//
|
|
22
|
+
// This old method is better than the initializations described in our
|
|
23
|
+
// [BiereFroehlich-POS'15] paper and actually faster than the ADAM method,
|
|
24
|
+
// but less precise. We consider this old method obsolete now but it
|
|
25
|
+
// could still be useful for implementations relying on integers instead
|
|
26
|
+
// of floating points because it only needs shifts and integer arithmetic.
|
|
27
|
+
//
|
|
28
|
+
// Our new method for unbiased initialization of the exponential averages
|
|
29
|
+
// works as follows. First the biased moving average is computed as usual.
|
|
30
|
+
// Note that (as already before) we use the simpler equation
|
|
31
|
+
//
|
|
32
|
+
// new_biased = old_biased + alpha * (y - old_biased);
|
|
33
|
+
//
|
|
34
|
+
// which in principle (and thus easy to remember) can be implemented as
|
|
35
|
+
//
|
|
36
|
+
// biased += alpha * (y - biased);
|
|
37
|
+
//
|
|
38
|
+
// The original formulation in the ADAM paper (with 'alpha = 1 - beta') is
|
|
39
|
+
//
|
|
40
|
+
// new_biased = beta * old_biased + (1 - beta) * y
|
|
41
|
+
//
|
|
42
|
+
// To show that these are equivalent (modulo floating point issues)
|
|
43
|
+
// consider the following equivalent expressions:
|
|
44
|
+
//
|
|
45
|
+
// old_biased + alpha * (y - old_biased)
|
|
46
|
+
// old_biased + alpha * y - alpha * old_biased
|
|
47
|
+
// (1 - alpha) * old_biased + alpha * y
|
|
48
|
+
// beta * old_biased + (1 - beta) * y
|
|
49
|
+
//
|
|
50
|
+
// The real new idea taken from the ADAM paper is however to fix the biased
|
|
51
|
+
// moving average with a correction term '1.0 / (1.0 - pow (beta, updated))'
|
|
52
|
+
// by multiplication to obtain an unbiased moving average (called simply
|
|
53
|
+
// 'value' in our 'code'). In order to avoid computing 'pow' every time, we
|
|
54
|
+
// use 'exp' which is multiplied in every update with 'beta'.
|
|
55
|
+
|
|
56
|
+
void EMA::update (Internal *internal, double y, const char *name) {
|
|
57
|
+
#ifdef LOGGING
|
|
58
|
+
updated++;
|
|
59
|
+
const double old_value = value;
|
|
60
|
+
#endif
|
|
61
|
+
const double old_biased = biased;
|
|
62
|
+
const double delta = y - old_biased;
|
|
63
|
+
const double scaled_delta = alpha * delta;
|
|
64
|
+
const double new_biased = old_biased + scaled_delta;
|
|
65
|
+
LOG ("update %" PRIu64 " of biased %s EMA %g with %g (delta %g) "
|
|
66
|
+
"yields %g (scaled delta %g)",
|
|
67
|
+
updated, name, old_biased, y, delta, new_biased, scaled_delta);
|
|
68
|
+
biased = new_biased;
|
|
69
|
+
const double old_exp = exp;
|
|
70
|
+
double new_exp, div, new_value;
|
|
71
|
+
if (old_exp) {
|
|
72
|
+
new_exp = old_exp * beta;
|
|
73
|
+
assert (new_exp < 1);
|
|
74
|
+
exp = new_exp;
|
|
75
|
+
div = 1 - new_exp;
|
|
76
|
+
assert (div > 0);
|
|
77
|
+
new_value = new_biased / div;
|
|
78
|
+
} else {
|
|
79
|
+
new_value = new_biased;
|
|
80
|
+
#ifdef LOGGING
|
|
81
|
+
new_exp = 0;
|
|
82
|
+
div = 1;
|
|
83
|
+
#endif
|
|
84
|
+
}
|
|
85
|
+
value = new_value;
|
|
86
|
+
LOG ("update %" PRIu64 " of corrected %s EMA %g with %g (delta %g) "
|
|
87
|
+
"yields %g (exponent %g, divisor %g)",
|
|
88
|
+
updated, name, old_value, y, delta, new_value, new_exp, div);
|
|
89
|
+
#ifndef LOGGING
|
|
90
|
+
(void) internal;
|
|
91
|
+
(void) name;
|
|
92
|
+
#endif
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
} // namespace CaDiCaL
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#ifndef _ema_hpp_INCLUDED
|
|
2
|
+
#define _ema_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
#include <cstdint>
|
|
5
|
+
|
|
6
|
+
namespace CaDiCaL {
|
|
7
|
+
|
|
8
|
+
struct Internal;
|
|
9
|
+
|
|
10
|
+
// This is a more complex generic exponential moving average class to
|
|
11
|
+
// support more robust initialization (see comments in the 'update'
|
|
12
|
+
// implementation).
|
|
13
|
+
|
|
14
|
+
struct EMA {
|
|
15
|
+
|
|
16
|
+
#ifdef LOGGING
|
|
17
|
+
uint64_t updated;
|
|
18
|
+
#endif
|
|
19
|
+
double value; // unbiased (corrected) moving average
|
|
20
|
+
double biased; // biased initialized moving average
|
|
21
|
+
double alpha; // input scaling with 'alpha = 1 - beta'
|
|
22
|
+
double beta; // decay of 'biased' with 'beta = 1 - alpha'
|
|
23
|
+
double exp; // 'exp = pow (beta, updated)'
|
|
24
|
+
|
|
25
|
+
EMA ()
|
|
26
|
+
:
|
|
27
|
+
#ifdef LOGGING
|
|
28
|
+
updated (0),
|
|
29
|
+
#endif
|
|
30
|
+
value (0), biased (0), alpha (0), beta (0), exp (0) {
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
EMA (double a)
|
|
34
|
+
:
|
|
35
|
+
#ifdef LOGGING
|
|
36
|
+
updated (0),
|
|
37
|
+
#endif
|
|
38
|
+
value (0), biased (0), alpha (a), beta (1 - a), exp (!!beta) {
|
|
39
|
+
assert (beta >= 0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
operator double () const { return value; }
|
|
43
|
+
void update (Internal *, double y, const char *name);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
} // namespace CaDiCaL
|
|
47
|
+
|
|
48
|
+
/*------------------------------------------------------------------------*/
|
|
49
|
+
|
|
50
|
+
// Compact average update and initialization macros for better logging.
|
|
51
|
+
|
|
52
|
+
#define UPDATE_AVERAGE(A, Y) \
|
|
53
|
+
do { \
|
|
54
|
+
A.update (internal, (Y), #A); \
|
|
55
|
+
} while (0)
|
|
56
|
+
|
|
57
|
+
#define INIT_EMA(E, WINDOW) \
|
|
58
|
+
do { \
|
|
59
|
+
assert ((WINDOW) >= 1); \
|
|
60
|
+
double ALPHA = 1.0 / (double) (WINDOW); \
|
|
61
|
+
E = EMA (ALPHA); \
|
|
62
|
+
LOG ("init " #E " EMA target alpha %g window %d", ALPHA, \
|
|
63
|
+
(int) WINDOW); \
|
|
64
|
+
} while (0)
|
|
65
|
+
|
|
66
|
+
/*------------------------------------------------------------------------*/
|
|
67
|
+
|
|
68
|
+
#endif
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
|
|
3
|
+
namespace CaDiCaL {
|
|
4
|
+
|
|
5
|
+
void External::push_zero_on_extension_stack () {
|
|
6
|
+
extension.push_back (0);
|
|
7
|
+
LOG ("pushing 0 on extension stack");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
void External::push_id_on_extension_stack (int64_t id) {
|
|
11
|
+
const uint32_t higher_bits = static_cast<int> (id << 32);
|
|
12
|
+
const uint32_t lower_bits = (id & (((int64_t) 1 << 32) - 1));
|
|
13
|
+
extension.push_back (higher_bits);
|
|
14
|
+
extension.push_back (lower_bits);
|
|
15
|
+
LOG ("pushing id %" PRIu64 " = %d + %d", id, higher_bits, lower_bits);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
void External::push_clause_literal_on_extension_stack (int ilit) {
|
|
19
|
+
assert (ilit);
|
|
20
|
+
const int elit = internal->externalize (ilit);
|
|
21
|
+
const int eidx = abs (elit);
|
|
22
|
+
const bool is_extension_var = ervars[eidx];
|
|
23
|
+
Flags &f = internal->flags (ilit);
|
|
24
|
+
if (is_extension_var) {
|
|
25
|
+
f.factored_but_on_reconstruction_stack = true;
|
|
26
|
+
LOG ("marking lit %s as tainted", LOGLIT (ilit));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
assert (elit);
|
|
30
|
+
extension.push_back (elit);
|
|
31
|
+
LOG ("pushing clause literal %d on extension stack (internal %d)", elit,
|
|
32
|
+
ilit);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
void External::push_witness_literal_on_extension_stack (int ilit) {
|
|
36
|
+
assert (ilit);
|
|
37
|
+
const int elit = internal->externalize (ilit);
|
|
38
|
+
assert (elit);
|
|
39
|
+
extension.push_back (elit);
|
|
40
|
+
LOG ("pushing witness literal %d on extension stack (internal %d)", elit,
|
|
41
|
+
ilit);
|
|
42
|
+
if (marked (witness, elit))
|
|
43
|
+
return;
|
|
44
|
+
LOG ("marking witness %d", elit);
|
|
45
|
+
mark (witness, elit);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// The extension stack allows to reconstruct a satisfying assignment for the
|
|
49
|
+
// original formula after removing eliminated clauses. This was pioneered
|
|
50
|
+
// by Niklas Soerensson in MiniSAT and for instance is described in our
|
|
51
|
+
// inprocessing paper, published at IJCAR'12. This first function adds a
|
|
52
|
+
// clause to this stack. First the blocking or eliminated literal is added,
|
|
53
|
+
// and then the rest of the clause.
|
|
54
|
+
|
|
55
|
+
void External::push_clause_on_extension_stack (Clause *c) {
|
|
56
|
+
internal->stats.weakened++;
|
|
57
|
+
internal->stats.weakenedlen += c->size;
|
|
58
|
+
push_zero_on_extension_stack ();
|
|
59
|
+
push_id_on_extension_stack (c->id);
|
|
60
|
+
push_zero_on_extension_stack ();
|
|
61
|
+
for (const auto &lit : *c)
|
|
62
|
+
push_clause_literal_on_extension_stack (lit);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
void External::push_clause_on_extension_stack (Clause *c, int pivot) {
|
|
66
|
+
push_zero_on_extension_stack ();
|
|
67
|
+
push_witness_literal_on_extension_stack (pivot);
|
|
68
|
+
push_clause_on_extension_stack (c);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
void External::push_binary_clause_on_extension_stack (int64_t id, int pivot,
|
|
72
|
+
int other) {
|
|
73
|
+
internal->stats.weakened++;
|
|
74
|
+
internal->stats.weakenedlen += 2;
|
|
75
|
+
push_zero_on_extension_stack ();
|
|
76
|
+
push_witness_literal_on_extension_stack (pivot);
|
|
77
|
+
push_zero_on_extension_stack ();
|
|
78
|
+
push_id_on_extension_stack (id);
|
|
79
|
+
push_zero_on_extension_stack ();
|
|
80
|
+
push_clause_literal_on_extension_stack (pivot);
|
|
81
|
+
push_clause_literal_on_extension_stack (other);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/*------------------------------------------------------------------------*/
|
|
85
|
+
|
|
86
|
+
void External::push_external_clause_and_witness_on_extension_stack (
|
|
87
|
+
const vector<int> &c, const vector<int> &w, int64_t id) {
|
|
88
|
+
assert (id);
|
|
89
|
+
extension.push_back (0);
|
|
90
|
+
for (const auto &elit : w) {
|
|
91
|
+
assert (elit != INT_MIN);
|
|
92
|
+
init (abs (elit));
|
|
93
|
+
extension.push_back (elit);
|
|
94
|
+
mark (witness, elit);
|
|
95
|
+
}
|
|
96
|
+
extension.push_back (0);
|
|
97
|
+
const uint32_t higher_bits = static_cast<int> (id << 32);
|
|
98
|
+
const uint32_t lower_bits = (id & (((int64_t) 1 << 32) - 1));
|
|
99
|
+
extension.push_back (higher_bits);
|
|
100
|
+
extension.push_back (lower_bits);
|
|
101
|
+
extension.push_back (0);
|
|
102
|
+
for (const auto &elit : c) {
|
|
103
|
+
assert (elit != INT_MIN);
|
|
104
|
+
init (abs (elit));
|
|
105
|
+
extension.push_back (elit);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/*------------------------------------------------------------------------*/
|
|
110
|
+
|
|
111
|
+
// This is the actual extension process. It goes backward over the clauses
|
|
112
|
+
// on the extension stack and flips the assignment of one of the blocking
|
|
113
|
+
// literals in the conditional autarky stored before the clause. In the
|
|
114
|
+
// original algorithm for witness construction for variable elimination and
|
|
115
|
+
// blocked clause removal the conditional autarky consists of a single
|
|
116
|
+
// literal from the removed clause, while in general the autarky witness can
|
|
117
|
+
// contain an arbitrary set of literals. We are using the more general
|
|
118
|
+
// witness reconstruction here which for instance would also work for
|
|
119
|
+
// super-blocked or set-blocked clauses.
|
|
120
|
+
|
|
121
|
+
void External::extend () {
|
|
122
|
+
|
|
123
|
+
assert (!extended);
|
|
124
|
+
START (extend);
|
|
125
|
+
internal->stats.extensions++;
|
|
126
|
+
|
|
127
|
+
PHASE ("extend", internal->stats.extensions,
|
|
128
|
+
"mapping internal %d assignments to %d assignments",
|
|
129
|
+
internal->max_var, max_var);
|
|
130
|
+
|
|
131
|
+
#ifndef QUIET
|
|
132
|
+
int64_t updated = 0;
|
|
133
|
+
#endif
|
|
134
|
+
for (unsigned i = 1; i <= (unsigned) max_var; i++) {
|
|
135
|
+
const int ilit = e2i[i];
|
|
136
|
+
if (!ilit)
|
|
137
|
+
continue;
|
|
138
|
+
if (i >= vals.size ())
|
|
139
|
+
vals.resize (i + 1, false);
|
|
140
|
+
vals[i] = (internal->val (ilit) > 0);
|
|
141
|
+
#ifndef QUIET
|
|
142
|
+
updated++;
|
|
143
|
+
#endif
|
|
144
|
+
}
|
|
145
|
+
PHASE ("extend", internal->stats.extensions,
|
|
146
|
+
"updated %" PRId64 " external assignments", updated);
|
|
147
|
+
PHASE ("extend", internal->stats.extensions,
|
|
148
|
+
"extending through extension stack of size %zd",
|
|
149
|
+
extension.size ());
|
|
150
|
+
const auto begin = extension.begin ();
|
|
151
|
+
auto i = extension.end ();
|
|
152
|
+
#ifndef QUIET
|
|
153
|
+
int64_t flipped = 0;
|
|
154
|
+
#endif
|
|
155
|
+
while (i != begin) {
|
|
156
|
+
bool satisfied = false;
|
|
157
|
+
int lit;
|
|
158
|
+
assert (i != begin);
|
|
159
|
+
while ((lit = *--i)) {
|
|
160
|
+
if (satisfied)
|
|
161
|
+
continue;
|
|
162
|
+
if (ival (lit) == lit)
|
|
163
|
+
satisfied = true;
|
|
164
|
+
assert (i != begin);
|
|
165
|
+
}
|
|
166
|
+
assert (i != begin);
|
|
167
|
+
LOG ("id=%" PRId64, ((int64_t) *i << 32) + *(i - 1));
|
|
168
|
+
assert (*i || *(i - 1));
|
|
169
|
+
--i;
|
|
170
|
+
assert (i != begin);
|
|
171
|
+
--i;
|
|
172
|
+
assert (i != begin);
|
|
173
|
+
assert (!*i);
|
|
174
|
+
--i;
|
|
175
|
+
assert (i != begin);
|
|
176
|
+
if (satisfied)
|
|
177
|
+
while (*--i)
|
|
178
|
+
assert (i != begin);
|
|
179
|
+
else {
|
|
180
|
+
while ((lit = *--i)) {
|
|
181
|
+
const int tmp = ival (lit); // not 'signed char'!!!
|
|
182
|
+
if (tmp != lit) {
|
|
183
|
+
LOG ("flipping blocking literal %d", lit);
|
|
184
|
+
assert (lit);
|
|
185
|
+
assert (lit != INT_MIN);
|
|
186
|
+
size_t idx = abs (lit);
|
|
187
|
+
if (idx >= vals.size ())
|
|
188
|
+
vals.resize (idx + 1, false);
|
|
189
|
+
vals[idx] = !vals[idx];
|
|
190
|
+
internal->stats.extended++;
|
|
191
|
+
#ifndef QUIET
|
|
192
|
+
flipped++;
|
|
193
|
+
#endif
|
|
194
|
+
}
|
|
195
|
+
assert (i != begin);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
PHASE ("extend", internal->stats.extensions,
|
|
200
|
+
"flipped %" PRId64 " literals during extension", flipped);
|
|
201
|
+
extended = true;
|
|
202
|
+
LOG ("extended");
|
|
203
|
+
STOP (extend);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/*------------------------------------------------------------------------*/
|
|
207
|
+
|
|
208
|
+
bool External::traverse_witnesses_backward (WitnessIterator &it) {
|
|
209
|
+
if (internal->unsat)
|
|
210
|
+
return true;
|
|
211
|
+
vector<int> clause, witness;
|
|
212
|
+
const auto begin = extension.begin ();
|
|
213
|
+
auto i = extension.end ();
|
|
214
|
+
while (i != begin) {
|
|
215
|
+
int lit;
|
|
216
|
+
while ((lit = *--i))
|
|
217
|
+
clause.push_back (lit);
|
|
218
|
+
assert (!lit);
|
|
219
|
+
--i;
|
|
220
|
+
const int64_t id =
|
|
221
|
+
((int64_t) * (i - 1) << 32) + static_cast<int64_t> (*i);
|
|
222
|
+
assert (id);
|
|
223
|
+
i -= 2;
|
|
224
|
+
assert (!*i);
|
|
225
|
+
assert (i != begin);
|
|
226
|
+
while ((lit = *--i))
|
|
227
|
+
witness.push_back (lit);
|
|
228
|
+
reverse (clause.begin (), clause.end ());
|
|
229
|
+
reverse (witness.begin (), witness.end ());
|
|
230
|
+
LOG (clause, "traversing clause");
|
|
231
|
+
if (!it.witness (clause, witness, id))
|
|
232
|
+
return false;
|
|
233
|
+
clause.clear ();
|
|
234
|
+
witness.clear ();
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
bool External::traverse_witnesses_forward (WitnessIterator &it) {
|
|
240
|
+
if (internal->unsat)
|
|
241
|
+
return true;
|
|
242
|
+
vector<int> clause, witness;
|
|
243
|
+
const auto end = extension.end ();
|
|
244
|
+
auto i = extension.begin ();
|
|
245
|
+
if (i != end) {
|
|
246
|
+
int lit = *i++;
|
|
247
|
+
do {
|
|
248
|
+
assert (!lit), (void) lit;
|
|
249
|
+
while ((lit = *i++))
|
|
250
|
+
witness.push_back (lit);
|
|
251
|
+
assert (!lit);
|
|
252
|
+
assert (i != end);
|
|
253
|
+
assert (!*i);
|
|
254
|
+
const int64_t id =
|
|
255
|
+
((int64_t) *i << 32) + static_cast<int64_t> (*(i + 1));
|
|
256
|
+
assert (id > 0);
|
|
257
|
+
i += 3;
|
|
258
|
+
assert (*i);
|
|
259
|
+
assert (i != end);
|
|
260
|
+
while (i != end && (lit = *i++))
|
|
261
|
+
clause.push_back (lit);
|
|
262
|
+
if (!it.witness (clause, witness, id))
|
|
263
|
+
return false;
|
|
264
|
+
clause.clear ();
|
|
265
|
+
witness.clear ();
|
|
266
|
+
} while (i != end);
|
|
267
|
+
}
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/*------------------------------------------------------------------------*/
|
|
272
|
+
|
|
273
|
+
void External::conclude_sat () {
|
|
274
|
+
if (!internal->proof || concluded)
|
|
275
|
+
return;
|
|
276
|
+
concluded = true;
|
|
277
|
+
if (!extended)
|
|
278
|
+
extend ();
|
|
279
|
+
vector<int> model;
|
|
280
|
+
for (int idx = 1; idx <= max_var; idx++) {
|
|
281
|
+
if (ervars[idx])
|
|
282
|
+
continue;
|
|
283
|
+
const int lit = ival (idx);
|
|
284
|
+
model.push_back (lit);
|
|
285
|
+
}
|
|
286
|
+
internal->proof->conclude_sat (model);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
} // namespace CaDiCaL
|