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,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