cadical 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +26 -0
  3. data/README.md +101 -0
  4. data/ext/cadical/cadical/LICENSE +28 -0
  5. data/ext/cadical/cadical/README.md +65 -0
  6. data/ext/cadical/cadical/VERSION +1 -0
  7. data/ext/cadical/cadical/src/analyze.cpp +1360 -0
  8. data/ext/cadical/cadical/src/arena.cpp +30 -0
  9. data/ext/cadical/cadical/src/arena.hpp +105 -0
  10. data/ext/cadical/cadical/src/assume.cpp +616 -0
  11. data/ext/cadical/cadical/src/averages.cpp +34 -0
  12. data/ext/cadical/cadical/src/averages.hpp +37 -0
  13. data/ext/cadical/cadical/src/backbone.cpp +631 -0
  14. data/ext/cadical/cadical/src/backtrack.cpp +177 -0
  15. data/ext/cadical/cadical/src/backward.cpp +231 -0
  16. data/ext/cadical/cadical/src/bins.cpp +22 -0
  17. data/ext/cadical/cadical/src/bins.hpp +22 -0
  18. data/ext/cadical/cadical/src/block.cpp +824 -0
  19. data/ext/cadical/cadical/src/block.hpp +37 -0
  20. data/ext/cadical/cadical/src/cadical.cpp +1026 -0
  21. data/ext/cadical/cadical/src/cadical.hpp +1419 -0
  22. data/ext/cadical/cadical/src/ccadical.cpp +208 -0
  23. data/ext/cadical/cadical/src/ccadical.h +74 -0
  24. data/ext/cadical/cadical/src/checker.cpp +649 -0
  25. data/ext/cadical/cadical/src/checker.hpp +173 -0
  26. data/ext/cadical/cadical/src/clause.cpp +689 -0
  27. data/ext/cadical/cadical/src/clause.hpp +190 -0
  28. data/ext/cadical/cadical/src/collect.cpp +545 -0
  29. data/ext/cadical/cadical/src/compact.cpp +550 -0
  30. data/ext/cadical/cadical/src/condition.cpp +940 -0
  31. data/ext/cadical/cadical/src/config.cpp +101 -0
  32. data/ext/cadical/cadical/src/config.hpp +20 -0
  33. data/ext/cadical/cadical/src/congruence.cpp +7880 -0
  34. data/ext/cadical/cadical/src/congruence.hpp +757 -0
  35. data/ext/cadical/cadical/src/constrain.cpp +64 -0
  36. data/ext/cadical/cadical/src/contract.cpp +27 -0
  37. data/ext/cadical/cadical/src/contract.hpp +139 -0
  38. data/ext/cadical/cadical/src/cover.cpp +704 -0
  39. data/ext/cadical/cadical/src/cover.hpp +34 -0
  40. data/ext/cadical/cadical/src/decide.cpp +347 -0
  41. data/ext/cadical/cadical/src/decompose.cpp +738 -0
  42. data/ext/cadical/cadical/src/decompose.hpp +23 -0
  43. data/ext/cadical/cadical/src/deduplicate.cpp +275 -0
  44. data/ext/cadical/cadical/src/definition.cpp +283 -0
  45. data/ext/cadical/cadical/src/delay.hpp +38 -0
  46. data/ext/cadical/cadical/src/drattracer.cpp +153 -0
  47. data/ext/cadical/cadical/src/drattracer.hpp +55 -0
  48. data/ext/cadical/cadical/src/elim.cpp +1171 -0
  49. data/ext/cadical/cadical/src/elim.hpp +53 -0
  50. data/ext/cadical/cadical/src/elimfast.cpp +570 -0
  51. data/ext/cadical/cadical/src/ema.cpp +95 -0
  52. data/ext/cadical/cadical/src/ema.hpp +68 -0
  53. data/ext/cadical/cadical/src/extend.cpp +289 -0
  54. data/ext/cadical/cadical/src/external.cpp +1034 -0
  55. data/ext/cadical/cadical/src/external.hpp +487 -0
  56. data/ext/cadical/cadical/src/external_propagate.cpp +1316 -0
  57. data/ext/cadical/cadical/src/factor.cpp +1011 -0
  58. data/ext/cadical/cadical/src/factor.hpp +54 -0
  59. data/ext/cadical/cadical/src/file.cpp +506 -0
  60. data/ext/cadical/cadical/src/file.hpp +210 -0
  61. data/ext/cadical/cadical/src/flags.cpp +135 -0
  62. data/ext/cadical/cadical/src/flags.hpp +93 -0
  63. data/ext/cadical/cadical/src/flip.cpp +269 -0
  64. data/ext/cadical/cadical/src/format.cpp +89 -0
  65. data/ext/cadical/cadical/src/format.hpp +36 -0
  66. data/ext/cadical/cadical/src/frattracer.cpp +277 -0
  67. data/ext/cadical/cadical/src/frattracer.hpp +67 -0
  68. data/ext/cadical/cadical/src/gates.cpp +766 -0
  69. data/ext/cadical/cadical/src/heap.hpp +212 -0
  70. data/ext/cadical/cadical/src/idruptracer.cpp +566 -0
  71. data/ext/cadical/cadical/src/idruptracer.hpp +112 -0
  72. data/ext/cadical/cadical/src/instantiate.cpp +365 -0
  73. data/ext/cadical/cadical/src/instantiate.hpp +45 -0
  74. data/ext/cadical/cadical/src/internal.cpp +1265 -0
  75. data/ext/cadical/cadical/src/internal.hpp +1941 -0
  76. data/ext/cadical/cadical/src/inttypes.hpp +34 -0
  77. data/ext/cadical/cadical/src/ipasir.cpp +47 -0
  78. data/ext/cadical/cadical/src/ipasir.h +37 -0
  79. data/ext/cadical/cadical/src/kitten.c +2599 -0
  80. data/ext/cadical/cadical/src/kitten.h +97 -0
  81. data/ext/cadical/cadical/src/level.hpp +33 -0
  82. data/ext/cadical/cadical/src/lidruptracer.cpp +657 -0
  83. data/ext/cadical/cadical/src/lidruptracer.hpp +122 -0
  84. data/ext/cadical/cadical/src/limit.cpp +146 -0
  85. data/ext/cadical/cadical/src/limit.hpp +168 -0
  86. data/ext/cadical/cadical/src/logging.cpp +214 -0
  87. data/ext/cadical/cadical/src/logging.hpp +98 -0
  88. data/ext/cadical/cadical/src/lookahead.cpp +520 -0
  89. data/ext/cadical/cadical/src/lratchecker.cpp +833 -0
  90. data/ext/cadical/cadical/src/lratchecker.hpp +168 -0
  91. data/ext/cadical/cadical/src/lrattracer.cpp +200 -0
  92. data/ext/cadical/cadical/src/lrattracer.hpp +61 -0
  93. data/ext/cadical/cadical/src/lucky.cpp +506 -0
  94. data/ext/cadical/cadical/src/message.cpp +218 -0
  95. data/ext/cadical/cadical/src/message.hpp +65 -0
  96. data/ext/cadical/cadical/src/minimize.cpp +224 -0
  97. data/ext/cadical/cadical/src/mobical.cpp +5588 -0
  98. data/ext/cadical/cadical/src/occs.cpp +52 -0
  99. data/ext/cadical/cadical/src/occs.hpp +36 -0
  100. data/ext/cadical/cadical/src/options.cpp +359 -0
  101. data/ext/cadical/cadical/src/options.hpp +442 -0
  102. data/ext/cadical/cadical/src/parse.cpp +471 -0
  103. data/ext/cadical/cadical/src/parse.hpp +75 -0
  104. data/ext/cadical/cadical/src/phases.cpp +56 -0
  105. data/ext/cadical/cadical/src/phases.hpp +19 -0
  106. data/ext/cadical/cadical/src/probe.cpp +990 -0
  107. data/ext/cadical/cadical/src/profile.cpp +107 -0
  108. data/ext/cadical/cadical/src/profile.hpp +283 -0
  109. data/ext/cadical/cadical/src/proof.cpp +691 -0
  110. data/ext/cadical/cadical/src/proof.hpp +125 -0
  111. data/ext/cadical/cadical/src/propagate.cpp +584 -0
  112. data/ext/cadical/cadical/src/queue.cpp +90 -0
  113. data/ext/cadical/cadical/src/queue.hpp +74 -0
  114. data/ext/cadical/cadical/src/radix.hpp +180 -0
  115. data/ext/cadical/cadical/src/random.cpp +207 -0
  116. data/ext/cadical/cadical/src/random.h +44 -0
  117. data/ext/cadical/cadical/src/random.hpp +98 -0
  118. data/ext/cadical/cadical/src/range.hpp +125 -0
  119. data/ext/cadical/cadical/src/reap.cpp +127 -0
  120. data/ext/cadical/cadical/src/reap.hpp +28 -0
  121. data/ext/cadical/cadical/src/reduce.cpp +278 -0
  122. data/ext/cadical/cadical/src/reluctant.hpp +82 -0
  123. data/ext/cadical/cadical/src/rephase.cpp +402 -0
  124. data/ext/cadical/cadical/src/report.cpp +313 -0
  125. data/ext/cadical/cadical/src/resources.cpp +160 -0
  126. data/ext/cadical/cadical/src/resources.hpp +16 -0
  127. data/ext/cadical/cadical/src/restart.cpp +178 -0
  128. data/ext/cadical/cadical/src/restore.cpp +267 -0
  129. data/ext/cadical/cadical/src/score.cpp +51 -0
  130. data/ext/cadical/cadical/src/score.hpp +16 -0
  131. data/ext/cadical/cadical/src/shrink.cpp +507 -0
  132. data/ext/cadical/cadical/src/signal.cpp +136 -0
  133. data/ext/cadical/cadical/src/signal.hpp +33 -0
  134. data/ext/cadical/cadical/src/solution.cpp +50 -0
  135. data/ext/cadical/cadical/src/solver.cpp +1871 -0
  136. data/ext/cadical/cadical/src/stable.cpp +31 -0
  137. data/ext/cadical/cadical/src/stack.h +110 -0
  138. data/ext/cadical/cadical/src/stats.cpp +920 -0
  139. data/ext/cadical/cadical/src/stats.hpp +418 -0
  140. data/ext/cadical/cadical/src/subsume.cpp +645 -0
  141. data/ext/cadical/cadical/src/sweep.cpp +1960 -0
  142. data/ext/cadical/cadical/src/sweep.hpp +61 -0
  143. data/ext/cadical/cadical/src/terminal.cpp +38 -0
  144. data/ext/cadical/cadical/src/terminal.hpp +96 -0
  145. data/ext/cadical/cadical/src/ternary.cpp +450 -0
  146. data/ext/cadical/cadical/src/testing.hpp +24 -0
  147. data/ext/cadical/cadical/src/tier.cpp +189 -0
  148. data/ext/cadical/cadical/src/tracer.hpp +186 -0
  149. data/ext/cadical/cadical/src/transred.cpp +253 -0
  150. data/ext/cadical/cadical/src/unstable.cpp +29 -0
  151. data/ext/cadical/cadical/src/util.cpp +129 -0
  152. data/ext/cadical/cadical/src/util.hpp +181 -0
  153. data/ext/cadical/cadical/src/var.cpp +39 -0
  154. data/ext/cadical/cadical/src/var.hpp +22 -0
  155. data/ext/cadical/cadical/src/veripbtracer.cpp +427 -0
  156. data/ext/cadical/cadical/src/veripbtracer.hpp +106 -0
  157. data/ext/cadical/cadical/src/version.cpp +107 -0
  158. data/ext/cadical/cadical/src/version.hpp +13 -0
  159. data/ext/cadical/cadical/src/vivify.cpp +1893 -0
  160. data/ext/cadical/cadical/src/vivify.hpp +50 -0
  161. data/ext/cadical/cadical/src/walk.cpp +1088 -0
  162. data/ext/cadical/cadical/src/walk.hpp +91 -0
  163. data/ext/cadical/cadical/src/walk_full_occs.cpp +966 -0
  164. data/ext/cadical/cadical/src/warmup.cpp +403 -0
  165. data/ext/cadical/cadical/src/watch.cpp +126 -0
  166. data/ext/cadical/cadical/src/watch.hpp +77 -0
  167. data/ext/cadical/cadical_ext.c +778 -0
  168. data/ext/cadical/extconf.rb +26 -0
  169. data/lib/cadical/version.rb +3 -0
  170. data/lib/cadical.rb +12 -0
  171. metadata +218 -0
@@ -0,0 +1,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