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,2599 @@
1
+ #include "kitten.h"
2
+ #include "random.h"
3
+ #include "stack.h"
4
+
5
+ #include <assert.h>
6
+ #include <inttypes.h>
7
+ #include <limits.h>
8
+ #include <stdarg.h>
9
+ #include <stdbool.h>
10
+ #include <stdint.h>
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+ #include <string.h>
14
+
15
+ typedef signed char value;
16
+
17
+ static void die (const char *fmt, ...) {
18
+ fputs ("kitten: error: ", stderr);
19
+ va_list ap;
20
+ va_start (ap, fmt);
21
+ vfprintf (stderr, fmt, ap);
22
+ va_end (ap);
23
+ fputc ('\n', stderr);
24
+ exit (1);
25
+ }
26
+
27
+ static inline void *kitten_calloc (size_t n, size_t size) {
28
+ void *res = calloc (n, size);
29
+ if (n && size && !res)
30
+ die ("out of memory allocating '%zu * %zu' bytes", n, size);
31
+ return res;
32
+ }
33
+
34
+ #define CALLOC(P, N) \
35
+ do { \
36
+ (P) = kitten_calloc (N, sizeof *(P)); \
37
+ } while (0)
38
+ #define DEALLOC(P, N) free (P)
39
+
40
+ #undef ENLARGE_STACK
41
+
42
+ #define ENLARGE_STACK(S) \
43
+ do { \
44
+ assert (FULL_STACK (S)); \
45
+ const size_t SIZE = SIZE_STACK (S); \
46
+ const size_t OLD_CAPACITY = CAPACITY_STACK (S); \
47
+ const size_t NEW_CAPACITY = OLD_CAPACITY ? 2 * OLD_CAPACITY : 1; \
48
+ const size_t BYTES = NEW_CAPACITY * sizeof *(S).begin; \
49
+ (S).begin = realloc ((S).begin, BYTES); \
50
+ if (!(S).begin) \
51
+ die ("out of memory reallocating '%zu' bytes", BYTES); \
52
+ (S).allocated = (S).begin + NEW_CAPACITY; \
53
+ (S).end = (S).begin + SIZE; \
54
+ } while (0)
55
+
56
+ // Beside allocators above also use stand alone statistics counters.
57
+
58
+ #define INC(NAME) \
59
+ do { \
60
+ statistics *statistics = &kitten->statistics; \
61
+ assert (statistics->NAME < UINT64_MAX); \
62
+ statistics->NAME++; \
63
+ } while (0)
64
+
65
+ #define ADD(NAME, DELTA) \
66
+ do { \
67
+ statistics *statistics = &kitten->statistics; \
68
+ assert (statistics->NAME <= UINT64_MAX - (DELTA)); \
69
+ statistics->NAME += (DELTA); \
70
+ } while (0)
71
+
72
+ #define KITTEN_TICKS (kitten->statistics.kitten_ticks)
73
+
74
+ #define INVALID UINT_MAX
75
+ #define MAX_VARS ((1u << 31) - 1)
76
+
77
+ #define CORE_FLAG (1u)
78
+ #define LEARNED_FLAG (2u)
79
+
80
+ // clang-format off
81
+
82
+ typedef struct kar kar;
83
+ typedef struct kink kink;
84
+ typedef struct klause klause;
85
+ typedef STACK (unsigned) klauses;
86
+ typedef unsigneds katches;
87
+
88
+ // clang-format on
89
+
90
+ struct kar {
91
+ unsigned level;
92
+ unsigned reason;
93
+ };
94
+
95
+ struct kink {
96
+ unsigned next;
97
+ unsigned prev;
98
+ uint64_t stamp;
99
+ };
100
+
101
+ struct klause {
102
+ unsigned aux;
103
+ unsigned size;
104
+ unsigned flags;
105
+ unsigned lits[1];
106
+ };
107
+
108
+ typedef struct statistics statistics;
109
+
110
+ struct statistics {
111
+ uint64_t learned;
112
+ uint64_t original;
113
+ uint64_t kitten_flip;
114
+ uint64_t kitten_flipped;
115
+ uint64_t kitten_sat;
116
+ uint64_t kitten_solved;
117
+ uint64_t kitten_conflicts;
118
+ uint64_t kitten_decisions;
119
+ uint64_t kitten_propagations;
120
+ uint64_t kitten_ticks;
121
+ uint64_t kitten_unknown;
122
+ uint64_t kitten_unsat;
123
+ };
124
+
125
+ typedef struct kimits kimits;
126
+
127
+ struct kimits {
128
+ uint64_t ticks;
129
+ };
130
+
131
+ struct kitten {
132
+ // First zero initialized field in 'clear_kitten' is 'status'.
133
+ //
134
+ int status;
135
+
136
+ #if defined(LOGGING)
137
+ bool logging;
138
+ #endif
139
+ bool antecedents;
140
+ bool learned;
141
+
142
+ unsigned level;
143
+ unsigned propagated;
144
+ unsigned unassigned;
145
+ unsigned inconsistent;
146
+ unsigned failing;
147
+
148
+ uint64_t generator;
149
+
150
+ size_t lits;
151
+ size_t evars;
152
+
153
+ size_t end_original_ref;
154
+
155
+ struct {
156
+ unsigned first, last;
157
+ uint64_t stamp;
158
+ unsigned search;
159
+ } queue;
160
+
161
+ // The 'size' field below is the first not zero reinitialized field
162
+ // by 'memset' in 'clear_kitten' (after 'kissat').
163
+
164
+ size_t size;
165
+ size_t esize;
166
+
167
+ kar *vars;
168
+ kink *links;
169
+ value *marks;
170
+ value *values;
171
+ bool *failed;
172
+ unsigned char *phases;
173
+ unsigned *import;
174
+ katches *watches;
175
+
176
+ unsigneds analyzed;
177
+ unsigneds assumptions;
178
+ unsigneds core;
179
+ unsigneds rcore;
180
+ unsigneds eclause;
181
+ unsigneds export;
182
+ unsigneds klause;
183
+ unsigneds klauses;
184
+ unsigneds resolved;
185
+ unsigneds trail;
186
+ unsigneds units;
187
+ unsigneds prime[2];
188
+
189
+ kimits limits;
190
+ int (*terminator) (void *);
191
+ void *terminator_data;
192
+ unsigneds clause;
193
+ uint64_t initialized;
194
+ statistics statistics;
195
+ };
196
+
197
+ /*------------------------------------------------------------------------*/
198
+
199
+ static inline bool is_core_klause (klause *c) {
200
+ return c->flags & CORE_FLAG;
201
+ }
202
+
203
+ static inline bool is_learned_klause (klause *c) {
204
+ return c->flags & LEARNED_FLAG;
205
+ }
206
+
207
+ static inline void set_core_klause (klause *c) { c->flags |= CORE_FLAG; }
208
+
209
+ static inline void unset_core_klause (klause *c) { c->flags &= ~CORE_FLAG; }
210
+
211
+ static inline klause *dereference_klause (kitten *kitten, unsigned ref) {
212
+ unsigned *res = BEGIN_STACK (kitten->klauses) + ref;
213
+ assert (res < END_STACK (kitten->klauses));
214
+ return (klause *) res;
215
+ }
216
+
217
+ static inline unsigned reference_klause (kitten *kitten, const klause *c) {
218
+ const unsigned *const begin = BEGIN_STACK (kitten->klauses);
219
+ const unsigned *p = (const unsigned *) c;
220
+ assert (begin <= p);
221
+ assert (p < END_STACK (kitten->klauses));
222
+ const unsigned res = p - begin;
223
+ return res;
224
+ }
225
+
226
+ /*------------------------------------------------------------------------*/
227
+
228
+ #define KATCHES(KIT) (kitten->watches[assert ((KIT) < kitten->lits), (KIT)])
229
+
230
+ #define all_klauses(C) \
231
+ klause *C = begin_klauses (kitten), *end_##C = end_klauses (kitten); \
232
+ (C) != end_##C; \
233
+ (C) = next_klause (kitten, C)
234
+
235
+ #define all_original_klauses(C) \
236
+ klause *C = begin_klauses (kitten), \
237
+ *end_##C = end_original_klauses (kitten); \
238
+ (C) != end_##C; \
239
+ (C) = next_klause (kitten, C)
240
+
241
+ #define all_learned_klauses(C) \
242
+ klause *C = begin_learned_klauses (kitten), \
243
+ *end_##C = end_klauses (kitten); \
244
+ (C) != end_##C; \
245
+ (C) = next_klause (kitten, C)
246
+
247
+ #define all_kits(KIT) \
248
+ size_t KIT = 0, KIT_##END = kitten->lits; \
249
+ KIT != KIT_##END; \
250
+ KIT++
251
+
252
+ #define BEGIN_KLAUSE(C) (C)->lits
253
+
254
+ #define END_KLAUSE(C) (BEGIN_KLAUSE (C) + (C)->size)
255
+
256
+ #define all_literals_in_klause(KIT, C) \
257
+ unsigned KIT, *KIT##_PTR = BEGIN_KLAUSE (C), \
258
+ *KIT##_END = END_KLAUSE (C); \
259
+ KIT##_PTR != KIT##_END && ((KIT = *KIT##_PTR), true); \
260
+ ++KIT##_PTR
261
+
262
+ #define all_antecedents(REF, C) \
263
+ unsigned REF, *REF##_PTR = antecedents (C), \
264
+ *REF##_END = REF##_PTR + (C)->aux; \
265
+ REF##_PTR != REF##_END && ((REF = *REF##_PTR), true); \
266
+ ++REF##_PTR
267
+
268
+ #ifdef LOGGING
269
+
270
+ #define logging (kitten->logging)
271
+
272
+ static void log_basic (kitten *, const char *, ...)
273
+ __attribute__ ((format (printf, 2, 3)));
274
+
275
+ static void log_basic (kitten *kitten, const char *fmt, ...) {
276
+ assert (logging);
277
+ printf ("c KITTEN %u ", kitten->level);
278
+ va_list ap;
279
+ va_start (ap, fmt);
280
+ vprintf (fmt, ap);
281
+ va_end (ap);
282
+ fputc ('\n', stdout);
283
+ fflush (stdout);
284
+ }
285
+
286
+ static void log_reference (kitten *, unsigned, const char *, ...)
287
+ __attribute__ ((format (printf, 3, 4)));
288
+
289
+ static void log_reference (kitten *kitten, unsigned ref, const char *fmt,
290
+ ...) {
291
+ klause *c = dereference_klause (kitten, ref);
292
+ assert (logging);
293
+ printf ("c KITTEN %u ", kitten->level);
294
+ va_list ap;
295
+ va_start (ap, fmt);
296
+ vprintf (fmt, ap);
297
+ va_end (ap);
298
+ if (is_learned_klause (c)) {
299
+ fputs (" learned", stdout);
300
+ if (c->aux)
301
+ printf ("[%u]", c->aux);
302
+ } else {
303
+ fputs (" original", stdout);
304
+ if (c->aux != INVALID)
305
+ printf ("[%u]", c->aux);
306
+ }
307
+ printf (" size %u clause[%u]", c->size, ref);
308
+ value *values = kitten->values;
309
+ kar *vars = kitten->vars;
310
+ for (all_literals_in_klause (lit, c)) {
311
+ printf (" %u", lit);
312
+ const value value = values[lit];
313
+ if (value)
314
+ printf ("@%u=%d", vars[lit / 2].level, (int) value);
315
+ }
316
+ fputc ('\n', stdout);
317
+ fflush (stdout);
318
+ }
319
+
320
+ static void log_literals (kitten *, unsigned *, unsigned, const char *, ...)
321
+ __attribute__ ((format (printf, 4, 5)));
322
+
323
+ static void log_literals (kitten *kitten, unsigned *lits, unsigned size,
324
+ const char *fmt, ...) {
325
+ assert (logging);
326
+ printf ("c KITTEN %u ", kitten->level);
327
+ va_list ap;
328
+ va_start (ap, fmt);
329
+ vprintf (fmt, ap);
330
+ va_end (ap);
331
+ value *values = kitten->values;
332
+ kar *vars = kitten->vars;
333
+ for (unsigned i = 0; i < size; i++) {
334
+ const unsigned lit = lits[i];
335
+ printf (" %u", lit);
336
+ const value value = values[lit];
337
+ if (value)
338
+ printf ("@%u=%d", vars[lit / 2].level, (int) value);
339
+ }
340
+ fputc ('\n', stdout);
341
+ fflush (stdout);
342
+ }
343
+
344
+ #define LOG(...) \
345
+ do { \
346
+ if (logging) \
347
+ log_basic (kitten, __VA_ARGS__); \
348
+ } while (0)
349
+
350
+ #define ROG(...) \
351
+ do { \
352
+ if (logging) \
353
+ log_reference (kitten, __VA_ARGS__); \
354
+ } while (0)
355
+
356
+ #define LOGLITS(...) \
357
+ do { \
358
+ if (logging) \
359
+ log_literals (kitten, __VA_ARGS__); \
360
+ } while (0)
361
+
362
+ #else
363
+
364
+ #define LOG(...) \
365
+ do { \
366
+ } while (0)
367
+ #define ROG(...) \
368
+ do { \
369
+ } while (0)
370
+ #define LOGLITS(...) \
371
+ do { \
372
+ } while (0)
373
+
374
+ #endif
375
+
376
+ static void check_queue (kitten *kitten) {
377
+ #ifdef CHECK_KITTEN
378
+ const unsigned vars = kitten->lits / 2;
379
+ unsigned found = 0, prev = INVALID;
380
+ kink *links = kitten->links;
381
+ uint64_t stamp = 0;
382
+ for (unsigned idx = kitten->queue.first, next; idx != INVALID;
383
+ idx = next) {
384
+ kink *link = links + idx;
385
+ assert (link->prev == prev);
386
+ assert (!found || stamp < link->stamp);
387
+ assert (link->stamp < kitten->queue.stamp);
388
+ stamp = link->stamp;
389
+ next = link->next;
390
+ prev = idx;
391
+ found++;
392
+ }
393
+ assert (found == vars);
394
+ unsigned next = INVALID;
395
+ found = 0;
396
+ for (unsigned idx = kitten->queue.last, prev; idx != INVALID;
397
+ idx = prev) {
398
+ kink *link = links + idx;
399
+ assert (link->next == next);
400
+ prev = link->prev;
401
+ next = idx;
402
+ found++;
403
+ }
404
+ assert (found == vars);
405
+ value *values = kitten->values;
406
+ bool first = true;
407
+ for (unsigned idx = kitten->queue.search, next; idx != INVALID;
408
+ idx = next) {
409
+ kink *link = links + idx;
410
+ next = link->next;
411
+ const unsigned lit = 2 * idx;
412
+ assert (first || values[lit]);
413
+ first = false;
414
+ }
415
+ #else
416
+ (void) kitten;
417
+ #endif
418
+ }
419
+
420
+ static void update_search (kitten *kitten, unsigned idx) {
421
+ if (kitten->queue.search == idx)
422
+ return;
423
+ kitten->queue.search = idx;
424
+ LOG ("search updated to %u stamped %" PRIu64, idx,
425
+ kitten->links[idx].stamp);
426
+ }
427
+
428
+ static void enqueue (kitten *kitten, unsigned idx) {
429
+ LOG ("enqueue %u", idx);
430
+ kink *links = kitten->links;
431
+ kink *l = links + idx;
432
+ const unsigned last = kitten->queue.last;
433
+ if (last == INVALID)
434
+ kitten->queue.first = idx;
435
+ else
436
+ links[last].next = idx;
437
+ l->prev = last;
438
+ l->next = INVALID;
439
+ kitten->queue.last = idx;
440
+ l->stamp = kitten->queue.stamp++;
441
+ LOG ("stamp %" PRIu64, l->stamp);
442
+ }
443
+
444
+ static void dequeue (kitten *kitten, unsigned idx) {
445
+ LOG ("dequeue %u", idx);
446
+ kink *links = kitten->links;
447
+ kink *l = links + idx;
448
+ const unsigned prev = l->prev;
449
+ const unsigned next = l->next;
450
+ if (prev == INVALID)
451
+ kitten->queue.first = next;
452
+ else
453
+ links[prev].next = next;
454
+ if (next == INVALID)
455
+ kitten->queue.last = prev;
456
+ else
457
+ links[next].prev = prev;
458
+ }
459
+
460
+ static void init_queue (kitten *kitten, size_t old_vars, size_t new_vars) {
461
+ for (size_t idx = old_vars; idx < new_vars; idx++) {
462
+ assert (!kitten->values[2 * idx]);
463
+ assert (kitten->unassigned < UINT_MAX);
464
+ kitten->unassigned++;
465
+ enqueue (kitten, idx);
466
+ }
467
+ LOG ("initialized decision queue from %zu to %zu", old_vars, new_vars);
468
+ update_search (kitten, kitten->queue.last);
469
+ check_queue (kitten);
470
+ }
471
+
472
+ static void initialize_kitten (kitten *kitten) {
473
+ kitten->queue.first = INVALID;
474
+ kitten->queue.last = INVALID;
475
+ kitten->inconsistent = INVALID;
476
+ kitten->failing = INVALID;
477
+ kitten->queue.search = INVALID;
478
+ kitten->terminator = 0;
479
+ kitten->terminator_data = 0;
480
+ kitten->limits.ticks = UINT64_MAX;
481
+ kitten->generator = kitten->initialized++;
482
+ }
483
+
484
+ static void clear_kitten (kitten *kitten) {
485
+ size_t bytes = (char *) &kitten->size - (char *) &kitten->status;
486
+ memset (&kitten->status, 0, bytes);
487
+ memset (&kitten->statistics, 0, sizeof (statistics));
488
+ initialize_kitten (kitten);
489
+ }
490
+
491
+ #define RESIZE1(P) \
492
+ do { \
493
+ void *OLD_PTR = (P); \
494
+ CALLOC ((P), new_size / 2); \
495
+ const size_t BYTES = old_vars * sizeof *(P); \
496
+ if ((P) && OLD_PTR) /* nullptr not allowed */ \
497
+ memcpy ((P), OLD_PTR, BYTES); \
498
+ void *NEW_PTR = (P); \
499
+ (P) = OLD_PTR; \
500
+ DEALLOC ((P), old_size / 2); \
501
+ (P) = NEW_PTR; \
502
+ } while (0)
503
+
504
+ #define RESIZE2(P) \
505
+ do { \
506
+ void *OLD_PTR = (P); \
507
+ CALLOC ((P), new_size); \
508
+ const size_t BYTES = old_lits * sizeof *(P); \
509
+ if ((P) && OLD_PTR) /* nullptr not allowed */ \
510
+ memcpy ((P), OLD_PTR, BYTES); \
511
+ void *NEW_PTR = (P); \
512
+ (P) = OLD_PTR; \
513
+ DEALLOC ((P), old_size); \
514
+ (P) = NEW_PTR; \
515
+ } while (0)
516
+
517
+ static void enlarge_internal (kitten *kitten, size_t lit) {
518
+ const size_t new_lits = (lit | 1) + 1;
519
+ const size_t old_lits = kitten->lits;
520
+ assert (old_lits <= lit);
521
+ assert (old_lits < new_lits);
522
+ assert ((lit ^ 1) < new_lits);
523
+ assert (lit < new_lits);
524
+ const size_t old_size = kitten->size;
525
+ const unsigned new_vars = new_lits / 2;
526
+ const unsigned old_vars = old_lits / 2;
527
+ if (old_size < new_lits) {
528
+ size_t new_size = old_size ? 2 * old_size : 2;
529
+ while (new_size <= lit)
530
+ new_size *= 2;
531
+ LOG ("internal literals resized to %zu from %zu (requested %zu)",
532
+ new_size, old_size, new_lits);
533
+
534
+ RESIZE1 (kitten->marks);
535
+ RESIZE1 (kitten->phases);
536
+ RESIZE2 (kitten->values);
537
+ RESIZE2 (kitten->failed);
538
+ RESIZE1 (kitten->vars);
539
+ RESIZE1 (kitten->links);
540
+ RESIZE2 (kitten->watches);
541
+
542
+ kitten->size = new_size;
543
+ }
544
+ kitten->lits = new_lits;
545
+ init_queue (kitten, old_vars, new_vars);
546
+ LOG ("internal literals activated until %zu literals", new_lits);
547
+ return;
548
+ }
549
+
550
+ static const char *status_to_string (int status) {
551
+ switch (status) {
552
+ case 10:
553
+ return "formula satisfied";
554
+ case 11:
555
+ return "formula satisfied and prime implicant computed";
556
+ case 20:
557
+ return "formula inconsistent";
558
+ case 21:
559
+ return "formula inconsistent and core computed";
560
+ default:
561
+ assert (!status);
562
+ return "formula unsolved";
563
+ }
564
+ }
565
+
566
+ static void invalid_api_usage (const char *fun, const char *fmt, ...) {
567
+ fprintf (stderr, "kitten: fatal error: invalid API usage in '%s': ", fun);
568
+ va_list ap;
569
+ va_start (ap, fmt);
570
+ vfprintf (stderr, fmt, ap);
571
+ va_end (ap);
572
+ fputc ('\n', stderr);
573
+ fflush (stderr);
574
+ abort ();
575
+ }
576
+
577
+ #define INVALID_API_USAGE(...) invalid_api_usage (__func__, __VA_ARGS__)
578
+
579
+ #define REQUIRE_INITIALIZED() \
580
+ do { \
581
+ if (!kitten) \
582
+ INVALID_API_USAGE ("solver argument zero"); \
583
+ } while (0)
584
+
585
+ #define REQUIRE_STATUS(EXPECTED) \
586
+ do { \
587
+ REQUIRE_INITIALIZED (); \
588
+ if (kitten->status != (EXPECTED)) \
589
+ INVALID_API_USAGE ("invalid status '%s' (expected '%s')", \
590
+ status_to_string (kitten->status), \
591
+ status_to_string (EXPECTED)); \
592
+ } while (0)
593
+
594
+ #define UPDATE_STATUS(STATUS) \
595
+ do { \
596
+ if (kitten->status != (STATUS)) \
597
+ LOG ("updating status from '%s' to '%s'", \
598
+ status_to_string (kitten->status), status_to_string (STATUS)); \
599
+ else \
600
+ LOG ("keeping status at '%s'", status_to_string (STATUS)); \
601
+ kitten->status = (STATUS); \
602
+ } while (0)
603
+
604
+ kitten *kitten_init (void) {
605
+ kitten *kitten;
606
+ CALLOC (kitten, 1);
607
+ initialize_kitten (kitten);
608
+ return kitten;
609
+ }
610
+
611
+ #ifdef LOGGING
612
+ void kitten_set_logging (kitten *kitten) { logging = true; }
613
+ #endif
614
+
615
+ void kitten_track_antecedents (kitten *kitten) {
616
+ REQUIRE_STATUS (0);
617
+
618
+ if (kitten->learned)
619
+ INVALID_API_USAGE ("can not start tracking antecedents after learning");
620
+
621
+ LOG ("enabling antecedents tracking");
622
+ kitten->antecedents = true;
623
+ }
624
+
625
+ void kitten_randomize_phases (kitten *kitten) {
626
+ REQUIRE_INITIALIZED ();
627
+
628
+ LOG ("randomizing phases");
629
+
630
+ unsigned char *phases = kitten->phases;
631
+ const unsigned vars = kitten->size / 2;
632
+
633
+ uint64_t random = kissat_next_random64 (&kitten->generator);
634
+
635
+ unsigned i = 0;
636
+ const unsigned rest = vars & ~63u;
637
+
638
+ while (i != rest) {
639
+ uint64_t *p = (uint64_t *) (phases + i);
640
+ p[0] = (random >> 0) & 0x0101010101010101;
641
+ p[1] = (random >> 1) & 0x0101010101010101;
642
+ p[2] = (random >> 2) & 0x0101010101010101;
643
+ p[3] = (random >> 3) & 0x0101010101010101;
644
+ p[4] = (random >> 4) & 0x0101010101010101;
645
+ p[5] = (random >> 5) & 0x0101010101010101;
646
+ p[6] = (random >> 6) & 0x0101010101010101;
647
+ p[7] = (random >> 7) & 0x0101010101010101;
648
+ random = kissat_next_random64 (&kitten->generator);
649
+ i += 64;
650
+ }
651
+
652
+ unsigned shift = 0;
653
+ while (i != vars)
654
+ phases[i++] = (random >> shift++) & 1;
655
+ }
656
+
657
+ void kitten_flip_phases (kitten *kitten) {
658
+ REQUIRE_INITIALIZED ();
659
+
660
+ LOG ("flipping phases");
661
+
662
+ unsigned char *phases = kitten->phases;
663
+ const unsigned vars = kitten->size / 2;
664
+
665
+ unsigned i = 0;
666
+ const unsigned rest = vars & ~7u;
667
+
668
+ while (i != rest) {
669
+ uint64_t *p = (uint64_t *) (phases + i);
670
+ *p ^= 0x0101010101010101;
671
+ i += 8;
672
+ }
673
+
674
+ while (i != vars)
675
+ phases[i++] ^= 1;
676
+ }
677
+
678
+ void kitten_no_ticks_limit (kitten *kitten) {
679
+ REQUIRE_INITIALIZED ();
680
+ LOG ("forcing no ticks limit");
681
+ kitten->limits.ticks = UINT64_MAX;
682
+ }
683
+
684
+ uint64_t kitten_current_ticks (kitten *kitten) {
685
+ REQUIRE_INITIALIZED ();
686
+ const uint64_t current = KITTEN_TICKS;
687
+ return current;
688
+ }
689
+
690
+ void kitten_set_ticks_limit (kitten *kitten, uint64_t delta) {
691
+ REQUIRE_INITIALIZED ();
692
+ const uint64_t current = KITTEN_TICKS;
693
+ uint64_t limit;
694
+ if (UINT64_MAX - delta <= current) {
695
+ LOG ("forcing unlimited ticks limit");
696
+ limit = UINT64_MAX;
697
+ } else {
698
+ limit = current + delta;
699
+ LOG ("new limit of %" PRIu64 " ticks after %" PRIu64, limit, delta);
700
+ }
701
+
702
+ kitten->limits.ticks = limit;
703
+ }
704
+
705
+ void kitten_no_terminator (kitten *kitten) {
706
+ REQUIRE_INITIALIZED ();
707
+ LOG ("removing terminator");
708
+ kitten->terminator = 0;
709
+ kitten->terminator_data = 0;
710
+ }
711
+
712
+ void kitten_set_terminator (kitten *kitten, void *data,
713
+ int (*terminator) (void *)) {
714
+ REQUIRE_INITIALIZED ();
715
+ LOG ("setting terminator");
716
+ kitten->terminator = terminator;
717
+ kitten->terminator_data = data;
718
+ }
719
+
720
+ static void shuffle_unsigned_array (kitten *kitten, size_t size,
721
+ unsigned *a) {
722
+ for (size_t i = 0; i < size; i++) {
723
+ const size_t j = kissat_pick_random (&kitten->generator, 0, i);
724
+ if (j == i)
725
+ continue;
726
+ const unsigned first = a[i];
727
+ const unsigned second = a[j];
728
+ a[i] = second;
729
+ a[j] = first;
730
+ }
731
+ }
732
+
733
+ static void shuffle_unsigned_stack (kitten *kitten, unsigneds *stack) {
734
+ const size_t size = SIZE_STACK (*stack);
735
+ unsigned *a = BEGIN_STACK (*stack);
736
+ shuffle_unsigned_array (kitten, size, a);
737
+ }
738
+
739
+ static void shuffle_katches (kitten *kitten) {
740
+ LOG ("shuffling watch lists");
741
+ for (size_t lit = 0; lit < kitten->lits; lit++)
742
+ shuffle_unsigned_stack (kitten, &KATCHES (lit));
743
+ }
744
+
745
+ static void shuffle_queue (kitten *kitten) {
746
+ LOG ("shuffling variable decision order");
747
+
748
+ const unsigned vars = kitten->lits / 2;
749
+ for (unsigned i = 0; i < vars; i++) {
750
+ const unsigned idx = kissat_pick_random (&kitten->generator, 0, vars);
751
+ dequeue (kitten, idx);
752
+ enqueue (kitten, idx);
753
+ }
754
+ update_search (kitten, kitten->queue.last);
755
+ }
756
+
757
+ static void shuffle_units (kitten *kitten) {
758
+ LOG ("shuffling units");
759
+ shuffle_unsigned_stack (kitten, &kitten->units);
760
+ }
761
+
762
+ void kitten_shuffle_clauses (kitten *kitten) {
763
+ REQUIRE_STATUS (0);
764
+ shuffle_queue (kitten);
765
+ shuffle_katches (kitten);
766
+ shuffle_units (kitten);
767
+ }
768
+
769
+ static inline unsigned *antecedents (klause *c) {
770
+ assert (is_learned_klause (c));
771
+ return c->lits + c->size;
772
+ }
773
+
774
+ static inline void watch_klause (kitten *kitten, unsigned lit,
775
+ unsigned ref) {
776
+ ROG (ref, "watching %u in", lit);
777
+ katches *watches = &KATCHES (lit);
778
+ PUSH_STACK (*watches, ref);
779
+ }
780
+
781
+ static inline void connect_new_klause (kitten *kitten, unsigned ref) {
782
+ ROG (ref, "new");
783
+
784
+ klause *c = dereference_klause (kitten, ref);
785
+
786
+ if (!c->size) {
787
+ if (kitten->inconsistent == INVALID) {
788
+ ROG (ref, "registering inconsistent empty");
789
+ kitten->inconsistent = ref;
790
+ } else
791
+ ROG (ref, "ignoring inconsistent empty");
792
+ } else if (c->size == 1) {
793
+ ROG (ref, "watching unit");
794
+ PUSH_STACK (kitten->units, ref);
795
+ } else {
796
+ watch_klause (kitten, c->lits[0], ref);
797
+ watch_klause (kitten, c->lits[1], ref);
798
+ }
799
+ }
800
+
801
+ static unsigned new_reference (kitten *kitten) {
802
+ size_t ref = SIZE_STACK (kitten->klauses);
803
+ if (ref >= INVALID) {
804
+ die ("maximum number of literals exhausted");
805
+ }
806
+ const unsigned res = (unsigned) ref;
807
+ assert (res != INVALID);
808
+ INC (kitten_ticks);
809
+ return res;
810
+ }
811
+
812
+ static void new_original_klause (kitten *kitten, unsigned id) {
813
+ unsigned res = new_reference (kitten);
814
+ unsigned size = SIZE_STACK (kitten->klause);
815
+ unsigneds *klauses = &kitten->klauses;
816
+ PUSH_STACK (*klauses, id);
817
+ PUSH_STACK (*klauses, size);
818
+ PUSH_STACK (*klauses, 0);
819
+ for (all_stack (unsigned, lit, kitten->klause))
820
+ PUSH_STACK (*klauses, lit);
821
+ connect_new_klause (kitten, res);
822
+ kitten->end_original_ref = SIZE_STACK (*klauses);
823
+ kitten->statistics.original++;
824
+ }
825
+
826
+ static void enlarge_external (kitten *kitten, size_t eidx) {
827
+ const size_t old_size = kitten->esize;
828
+ const unsigned old_evars = kitten->evars;
829
+ assert (old_evars <= eidx);
830
+ const unsigned new_evars = eidx + 1;
831
+ if (old_size <= eidx) {
832
+ size_t new_size = old_size ? 2 * old_size : 1;
833
+ while (new_size <= eidx)
834
+ new_size *= 2;
835
+ LOG ("external resizing to %zu variables from %zu (requested %u)",
836
+ new_size, old_size, new_evars);
837
+ unsigned *old_import = kitten->import;
838
+ CALLOC (kitten->import, new_size);
839
+ const size_t bytes = old_evars * sizeof *kitten->import;
840
+ if (kitten->import && old_import)
841
+ memcpy (kitten->import, old_import, bytes);
842
+ DEALLOC (old_import, old_size);
843
+ kitten->esize = new_size;
844
+ }
845
+ kitten->evars = new_evars;
846
+ LOG ("external variables enlarged to %u", new_evars);
847
+ }
848
+
849
+ static unsigned import_literal (kitten *kitten, unsigned elit) {
850
+ const unsigned eidx = elit / 2;
851
+ if (eidx >= kitten->evars)
852
+ enlarge_external (kitten, eidx);
853
+
854
+ unsigned iidx = kitten->import[eidx];
855
+ if (!iidx) {
856
+ iidx = SIZE_STACK (kitten->export);
857
+ PUSH_STACK (kitten->export, eidx);
858
+ kitten->import[eidx] = iidx + 1;
859
+ } else
860
+ iidx--;
861
+ unsigned ilit = 2 * iidx + (elit & 1);
862
+ LOG ("imported external literal %u as internal literal %u", elit, ilit);
863
+ if (ilit >= kitten->lits)
864
+ enlarge_internal (kitten, ilit);
865
+ return ilit;
866
+ }
867
+
868
+ static unsigned export_literal (kitten *kitten, unsigned ilit) {
869
+ const unsigned iidx = ilit / 2;
870
+ assert (iidx < SIZE_STACK (kitten->export));
871
+ const unsigned eidx = PEEK_STACK (kitten->export, iidx);
872
+ const unsigned elit = 2 * eidx + (ilit & 1);
873
+ return elit;
874
+ }
875
+
876
+ unsigned new_learned_klause (kitten *kitten) {
877
+ unsigned res = new_reference (kitten);
878
+ unsigneds *klauses = &kitten->klauses;
879
+ const size_t size = SIZE_STACK (kitten->klause);
880
+ assert (size <= UINT_MAX);
881
+ const size_t aux =
882
+ kitten->antecedents ? SIZE_STACK (kitten->resolved) : 0;
883
+ assert (aux <= UINT_MAX);
884
+ PUSH_STACK (*klauses, (unsigned) aux);
885
+ PUSH_STACK (*klauses, (unsigned) size);
886
+ PUSH_STACK (*klauses, LEARNED_FLAG);
887
+ for (all_stack (unsigned, lit, kitten->klause))
888
+ PUSH_STACK (*klauses, lit);
889
+ if (aux)
890
+ for (all_stack (unsigned, ref, kitten->resolved))
891
+ PUSH_STACK (*klauses, ref);
892
+ connect_new_klause (kitten, res);
893
+ kitten->learned = true;
894
+ kitten->statistics.learned++;
895
+ return res;
896
+ }
897
+
898
+ void kitten_clear (kitten *kitten) {
899
+ LOG ("clear kitten of size %zu", kitten->size);
900
+
901
+ assert (EMPTY_STACK (kitten->analyzed));
902
+ assert (EMPTY_STACK (kitten->eclause));
903
+ assert (EMPTY_STACK (kitten->resolved));
904
+
905
+ CLEAR_STACK (kitten->assumptions);
906
+ CLEAR_STACK (kitten->core);
907
+ CLEAR_STACK (kitten->klause);
908
+ CLEAR_STACK (kitten->klauses);
909
+ CLEAR_STACK (kitten->trail);
910
+ CLEAR_STACK (kitten->units);
911
+ CLEAR_STACK (kitten->clause);
912
+ CLEAR_STACK (kitten->prime[0]);
913
+ CLEAR_STACK (kitten->prime[1]);
914
+
915
+ for (all_kits (kit))
916
+ CLEAR_STACK (KATCHES (kit));
917
+
918
+ while (!EMPTY_STACK (kitten->export))
919
+ kitten->import[POP_STACK (kitten->export)] = 0;
920
+
921
+ const size_t lits = kitten->size;
922
+ const unsigned vars = lits / 2;
923
+
924
+ #ifndef NDEBUG
925
+ for (unsigned i = 0; i < vars; i++)
926
+ assert (!kitten->marks[i]);
927
+ #endif
928
+
929
+ if (kitten->phases)
930
+ memset (kitten->phases, 0, vars);
931
+ if (kitten->values)
932
+ memset (kitten->values, 0, lits);
933
+ if (kitten->failed)
934
+ memset (kitten->failed, 0, lits);
935
+ if (kitten->vars)
936
+ memset (kitten->vars, 0, vars);
937
+
938
+ clear_kitten (kitten);
939
+ }
940
+
941
+ void kitten_release (kitten *kitten) {
942
+ RELEASE_STACK (kitten->analyzed);
943
+ RELEASE_STACK (kitten->assumptions);
944
+ RELEASE_STACK (kitten->core);
945
+ RELEASE_STACK (kitten->eclause);
946
+ RELEASE_STACK (kitten->export);
947
+ RELEASE_STACK (kitten->klause);
948
+ RELEASE_STACK (kitten->klauses);
949
+ RELEASE_STACK (kitten->resolved);
950
+ RELEASE_STACK (kitten->trail);
951
+ RELEASE_STACK (kitten->units);
952
+ RELEASE_STACK (kitten->clause);
953
+ RELEASE_STACK (kitten->prime[0]);
954
+ RELEASE_STACK (kitten->prime[1]);
955
+
956
+ for (size_t lit = 0; lit < kitten->size; lit++)
957
+ RELEASE_STACK (kitten->watches[lit]);
958
+
959
+ const size_t lits = kitten->size;
960
+ const unsigned vars = lits / 2;
961
+ DEALLOC (kitten->marks, vars);
962
+ DEALLOC (kitten->phases, vars);
963
+ DEALLOC (kitten->values, lits);
964
+ DEALLOC (kitten->failed, lits);
965
+ DEALLOC (kitten->vars, vars);
966
+ DEALLOC (kitten->links, vars);
967
+ DEALLOC (kitten->watches, lits);
968
+ DEALLOC (kitten->import, kitten->esize);
969
+ (void) vars;
970
+
971
+ free (kitten);
972
+ }
973
+
974
+ static inline void move_to_front (kitten *kitten, unsigned idx) {
975
+ if (idx == kitten->queue.last)
976
+ return;
977
+ LOG ("move to front variable %u", idx);
978
+ dequeue (kitten, idx);
979
+ enqueue (kitten, idx);
980
+ assert (kitten->values[2 * idx]);
981
+ }
982
+
983
+ static inline void assign (kitten *kitten, unsigned lit, unsigned reason) {
984
+ #ifdef LOGGING
985
+ if (reason == INVALID)
986
+ LOG ("assign %u as decision", lit);
987
+ else
988
+ ROG (reason, "assign %u reason", lit);
989
+ #endif
990
+ value *values = kitten->values;
991
+ const unsigned not_lit = lit ^ 1;
992
+ assert (!values[lit]);
993
+ assert (!values[not_lit]);
994
+ values[lit] = 1;
995
+ values[not_lit] = -1;
996
+ const unsigned idx = lit / 2;
997
+ const unsigned sign = lit & 1;
998
+ kitten->phases[idx] = sign;
999
+ PUSH_STACK (kitten->trail, lit);
1000
+ kar *v = kitten->vars + idx;
1001
+ v->level = kitten->level;
1002
+ if (!v->level) {
1003
+ assert (reason != INVALID);
1004
+ klause *c = dereference_klause (kitten, reason);
1005
+ if (c->size > 1) {
1006
+ if (kitten->antecedents) {
1007
+ PUSH_STACK (kitten->resolved, reason);
1008
+ for (all_literals_in_klause (other, c))
1009
+ if (other != lit) {
1010
+ const unsigned other_idx = other / 2;
1011
+ const unsigned other_ref = kitten->vars[other_idx].reason;
1012
+ assert (other_ref != INVALID);
1013
+ PUSH_STACK (kitten->resolved, other_ref);
1014
+ }
1015
+ }
1016
+ PUSH_STACK (kitten->klause, lit);
1017
+ reason = new_learned_klause (kitten);
1018
+ CLEAR_STACK (kitten->resolved);
1019
+ CLEAR_STACK (kitten->klause);
1020
+ }
1021
+ }
1022
+ v->reason = reason;
1023
+ assert (kitten->unassigned);
1024
+ kitten->unassigned--;
1025
+ }
1026
+
1027
+ static inline unsigned propagate_literal (kitten *kitten, unsigned lit) {
1028
+ LOG ("propagating %u", lit);
1029
+ value *values = kitten->values;
1030
+ assert (values[lit] > 0);
1031
+ const unsigned not_lit = lit ^ 1;
1032
+ katches *watches = kitten->watches + not_lit;
1033
+ unsigned conflict = INVALID;
1034
+ unsigned *q = BEGIN_STACK (*watches);
1035
+ const unsigned *const end_watches = END_STACK (*watches);
1036
+ unsigned const *p = q;
1037
+ uint64_t ticks =
1038
+ (((const char *const) end_watches - (char *const) q) >> 7) + 1;
1039
+ while (p != end_watches) {
1040
+ const unsigned ref = *q++ = *p++;
1041
+ klause *c = dereference_klause (kitten, ref);
1042
+ assert (c->size > 1);
1043
+ unsigned *lits = c->lits;
1044
+ const unsigned other = lits[0] ^ lits[1] ^ not_lit;
1045
+ const value other_value = values[other];
1046
+ ticks++;
1047
+ if (other_value > 0)
1048
+ continue;
1049
+ value replacement_value = -1;
1050
+ unsigned replacement = INVALID;
1051
+ const unsigned *const end_lits = lits + c->size;
1052
+ unsigned *r;
1053
+ for (r = lits + 2; r != end_lits; r++) {
1054
+ replacement = *r;
1055
+ replacement_value = values[replacement];
1056
+ if (replacement_value >= 0)
1057
+ break;
1058
+ }
1059
+ if (replacement_value >= 0) {
1060
+ assert (replacement != INVALID);
1061
+ ROG (ref, "unwatching %u in", not_lit);
1062
+ lits[0] = other;
1063
+ lits[1] = replacement;
1064
+ *r = not_lit;
1065
+ watch_klause (kitten, replacement, ref);
1066
+ q--;
1067
+ } else if (other_value < 0) {
1068
+ ROG (ref, "conflict");
1069
+ INC (kitten_conflicts);
1070
+ conflict = ref;
1071
+ break;
1072
+ } else {
1073
+ assert (!other_value);
1074
+ assign (kitten, other, ref);
1075
+ }
1076
+ }
1077
+ while (p != end_watches)
1078
+ *q++ = *p++;
1079
+ SET_END_OF_STACK (*watches, q);
1080
+ ADD (kitten_ticks, ticks);
1081
+ return conflict;
1082
+ }
1083
+
1084
+ static inline unsigned propagate (kitten *kitten) {
1085
+ assert (kitten->inconsistent == INVALID);
1086
+ unsigned propagated = 0;
1087
+ unsigned conflict = INVALID;
1088
+ while (conflict == INVALID &&
1089
+ kitten->propagated < SIZE_STACK (kitten->trail)) {
1090
+ if (kitten->terminator &&
1091
+ kitten->terminator (kitten->terminator_data)) {
1092
+ break;
1093
+ }
1094
+ const unsigned lit = PEEK_STACK (kitten->trail, kitten->propagated);
1095
+ conflict = propagate_literal (kitten, lit);
1096
+ kitten->propagated++;
1097
+ propagated++;
1098
+ }
1099
+ ADD (kitten_propagations, propagated);
1100
+ return conflict;
1101
+ }
1102
+
1103
+ static void bump (kitten *kitten) {
1104
+ value *marks = kitten->marks;
1105
+ for (all_stack (unsigned, idx, kitten->analyzed)) {
1106
+ marks[idx] = 0;
1107
+ move_to_front (kitten, idx);
1108
+ }
1109
+ check_queue (kitten);
1110
+ }
1111
+
1112
+ static inline void unassign (kitten *kitten, value *values, unsigned lit) {
1113
+ const unsigned not_lit = lit ^ 1;
1114
+ assert (values[lit]);
1115
+ assert (values[not_lit]);
1116
+ const unsigned idx = lit / 2;
1117
+ #ifdef LOGGING
1118
+ kar *var = kitten->vars + idx;
1119
+ kitten->level = var->level;
1120
+ LOG ("unassign %u", lit);
1121
+ #endif
1122
+ values[lit] = values[not_lit] = 0;
1123
+ assert (kitten->unassigned < kitten->lits / 2);
1124
+ kitten->unassigned++;
1125
+ kink *links = kitten->links;
1126
+ kink *link = links + idx;
1127
+ if (link->stamp > links[kitten->queue.search].stamp)
1128
+ update_search (kitten, idx);
1129
+ }
1130
+
1131
+ static void backtrack (kitten *kitten, unsigned jump) {
1132
+ check_queue (kitten);
1133
+ assert (jump < kitten->level);
1134
+ LOG ("back%s to level %u",
1135
+ (kitten->level == jump + 1 ? "tracking" : "jumping"), jump);
1136
+ kar *vars = kitten->vars;
1137
+ value *values = kitten->values;
1138
+ unsigneds *trail = &kitten->trail;
1139
+ while (!EMPTY_STACK (*trail)) {
1140
+ const unsigned lit = TOP_STACK (*trail);
1141
+ const unsigned idx = lit / 2;
1142
+ const unsigned level = vars[idx].level;
1143
+ if (level == jump)
1144
+ break;
1145
+ (void) POP_STACK (*trail);
1146
+ unassign (kitten, values, lit);
1147
+ }
1148
+ kitten->propagated = SIZE_STACK (*trail);
1149
+ kitten->level = jump;
1150
+ check_queue (kitten);
1151
+ }
1152
+
1153
+ void completely_backtrack_to_root_level (kitten *kitten) {
1154
+ check_queue (kitten);
1155
+ LOG ("completely backtracking to level 0");
1156
+ value *values = kitten->values;
1157
+ unsigneds *trail = &kitten->trail;
1158
+ unsigneds *units = &kitten->units;
1159
+ #ifndef NDEBUG
1160
+ kar *vars = kitten->vars;
1161
+ #endif
1162
+ for (all_stack (unsigned, lit, *trail)) {
1163
+ assert (vars[lit / 2].level);
1164
+ unassign (kitten, values, lit);
1165
+ }
1166
+ CLEAR_STACK (*trail);
1167
+ for (all_stack (unsigned, ref, *units)) {
1168
+ klause *c = dereference_klause (kitten, ref);
1169
+ assert (c->size == 1);
1170
+ const unsigned unit = c->lits[0];
1171
+ const value value = values[unit];
1172
+ if (value <= 0)
1173
+ continue;
1174
+ unassign (kitten, values, unit);
1175
+ }
1176
+ kitten->propagated = 0;
1177
+ kitten->level = 0;
1178
+ check_queue (kitten);
1179
+ }
1180
+
1181
+ static void analyze (kitten *kitten, unsigned conflict) {
1182
+ assert (kitten->level);
1183
+ assert (kitten->inconsistent == INVALID);
1184
+ assert (EMPTY_STACK (kitten->analyzed));
1185
+ assert (EMPTY_STACK (kitten->resolved));
1186
+ assert (EMPTY_STACK (kitten->klause));
1187
+ PUSH_STACK (kitten->klause, INVALID);
1188
+ unsigned reason = conflict;
1189
+ value *marks = kitten->marks;
1190
+ const kar *const vars = kitten->vars;
1191
+ const unsigned level = kitten->level;
1192
+ unsigned const *p = END_STACK (kitten->trail);
1193
+ unsigned open = 0, jump = 0, size = 1, uip;
1194
+ for (;;) {
1195
+ assert (reason != INVALID);
1196
+ klause *c = dereference_klause (kitten, reason);
1197
+ assert (c);
1198
+ ROG (reason, "analyzing");
1199
+ PUSH_STACK (kitten->resolved, reason);
1200
+ for (all_literals_in_klause (lit, c)) {
1201
+ const unsigned idx = lit / 2;
1202
+ if (marks[idx])
1203
+ continue;
1204
+ assert (kitten->values[lit] < 0);
1205
+ LOG ("analyzed %u", lit);
1206
+ marks[idx] = true;
1207
+ PUSH_STACK (kitten->analyzed, idx);
1208
+ const kar *const v = vars + idx;
1209
+ const unsigned tmp = v->level;
1210
+ if (tmp < level) {
1211
+ if (tmp > jump) {
1212
+ jump = tmp;
1213
+ if (size > 1) {
1214
+ const unsigned other = PEEK_STACK (kitten->klause, 1);
1215
+ POKE_STACK (kitten->klause, 1, lit);
1216
+ lit = other;
1217
+ }
1218
+ }
1219
+ PUSH_STACK (kitten->klause, lit);
1220
+ size++;
1221
+ } else
1222
+ open++;
1223
+ }
1224
+ unsigned idx;
1225
+ do {
1226
+ assert (BEGIN_STACK (kitten->trail) < p);
1227
+ uip = *--p;
1228
+ } while (!marks[idx = uip / 2]);
1229
+ assert (open);
1230
+ if (!--open)
1231
+ break;
1232
+ reason = vars[idx].reason;
1233
+ }
1234
+ const unsigned not_uip = uip ^ 1;
1235
+ LOG ("first UIP %u jump level %u size %u", not_uip, jump, size);
1236
+ POKE_STACK (kitten->klause, 0, not_uip);
1237
+ bump (kitten);
1238
+ CLEAR_STACK (kitten->analyzed);
1239
+ const unsigned learned_ref = new_learned_klause (kitten);
1240
+ CLEAR_STACK (kitten->resolved);
1241
+ CLEAR_STACK (kitten->klause);
1242
+ backtrack (kitten, jump);
1243
+ assign (kitten, not_uip, learned_ref);
1244
+ }
1245
+
1246
+ static void failing (kitten *kitten) {
1247
+ assert (kitten->inconsistent == INVALID);
1248
+ assert (!EMPTY_STACK (kitten->assumptions));
1249
+ assert (EMPTY_STACK (kitten->analyzed));
1250
+ assert (EMPTY_STACK (kitten->resolved));
1251
+ assert (EMPTY_STACK (kitten->klause));
1252
+ LOG ("analyzing failing assumptions");
1253
+ const value *const values = kitten->values;
1254
+ const kar *const vars = kitten->vars;
1255
+ unsigned failed_clashing = INVALID;
1256
+ unsigned first_failed = INVALID;
1257
+ unsigned failed_unit = INVALID;
1258
+ for (all_stack (unsigned, lit, kitten->assumptions)) {
1259
+ if (values[lit] >= 0)
1260
+ continue;
1261
+ if (first_failed == INVALID)
1262
+ first_failed = lit;
1263
+ const unsigned failed_idx = lit / 2;
1264
+ const kar *const failed_var = vars + failed_idx;
1265
+ if (!failed_var->level) {
1266
+ failed_unit = lit;
1267
+ break;
1268
+ }
1269
+ if (failed_clashing == INVALID && failed_var->reason == INVALID)
1270
+ failed_clashing = lit;
1271
+ }
1272
+ unsigned failed;
1273
+ if (failed_unit != INVALID)
1274
+ failed = failed_unit;
1275
+ else if (failed_clashing != INVALID)
1276
+ failed = failed_clashing;
1277
+ else
1278
+ failed = first_failed;
1279
+ assert (failed != INVALID);
1280
+ const unsigned failed_idx = failed / 2;
1281
+ const kar *const failed_var = vars + failed_idx;
1282
+ const unsigned failed_reason = failed_var->reason;
1283
+ LOG ("first failed assumption %u", failed);
1284
+ kitten->failed[failed] = true;
1285
+
1286
+ if (failed_unit != INVALID) {
1287
+ assert (dereference_klause (kitten, failed_reason)->size == 1);
1288
+ LOG ("root-level falsified assumption %u", failed);
1289
+ kitten->failing = failed_reason;
1290
+ ROG (kitten->failing, "failing reason");
1291
+ return;
1292
+ }
1293
+
1294
+ const unsigned not_failed = failed ^ 1;
1295
+ if (failed_clashing != INVALID) {
1296
+ LOG ("clashing with negated assumption %u", not_failed);
1297
+ kitten->failed[not_failed] = true;
1298
+ assert (kitten->failing == INVALID);
1299
+ return;
1300
+ }
1301
+
1302
+ value *marks = kitten->marks;
1303
+ assert (!marks[failed_idx]);
1304
+ marks[failed_idx] = true;
1305
+ PUSH_STACK (kitten->analyzed, failed_idx);
1306
+ PUSH_STACK (kitten->klause, not_failed);
1307
+
1308
+ unsigneds work;
1309
+ INIT_STACK (work);
1310
+
1311
+ LOGLITS (BEGIN_STACK (kitten->trail), SIZE_STACK (kitten->trail),
1312
+ "trail");
1313
+
1314
+ assert (SIZE_STACK (kitten->trail));
1315
+ unsigned const *p = END_STACK (kitten->trail);
1316
+ unsigned open = 1;
1317
+ for (;;) {
1318
+ if (!open)
1319
+ break;
1320
+ open--;
1321
+ unsigned idx, uip;
1322
+ do {
1323
+ assert (BEGIN_STACK (kitten->trail) < p);
1324
+ uip = *--p;
1325
+ } while (!marks[idx = uip / 2]);
1326
+
1327
+ const kar *var = vars + idx;
1328
+ const unsigned reason = var->reason;
1329
+ if (reason == INVALID) {
1330
+ unsigned lit = 2 * idx;
1331
+ if (values[lit] < 0)
1332
+ lit ^= 1;
1333
+ LOG ("failed assumption %u", lit);
1334
+ assert (!kitten->failed[lit]);
1335
+ kitten->failed[lit] = true;
1336
+ const unsigned not_lit = lit ^ 1;
1337
+ PUSH_STACK (kitten->klause, not_lit);
1338
+ } else {
1339
+ ROG (reason, "analyzing");
1340
+ PUSH_STACK (kitten->resolved, reason);
1341
+ klause *c = dereference_klause (kitten, reason);
1342
+ for (all_literals_in_klause (other, c)) {
1343
+ const unsigned other_idx = other / 2;
1344
+ if (marks[other_idx])
1345
+ continue;
1346
+ assert (other_idx != idx);
1347
+ marks[other_idx] = true;
1348
+ assert (values[other]);
1349
+ if (vars[other_idx].level)
1350
+ open++;
1351
+ else
1352
+ PUSH_STACK (work, other_idx);
1353
+ PUSH_STACK (kitten->analyzed, other_idx);
1354
+
1355
+ LOG ("analyzing final literal %u", other ^ 1);
1356
+ }
1357
+ }
1358
+ }
1359
+ for (size_t next = 0; next < SIZE_STACK (work); next++) {
1360
+ const unsigned idx = PEEK_STACK (work, next);
1361
+ const kar *var = vars + idx;
1362
+ const unsigned reason = var->reason;
1363
+ if (reason == INVALID) {
1364
+ unsigned lit = 2 * idx;
1365
+ if (values[lit] < 0)
1366
+ lit ^= 1;
1367
+ LOG ("failed assumption %u", lit);
1368
+ assert (!kitten->failed[lit]);
1369
+ kitten->failed[lit] = true;
1370
+ const unsigned not_lit = lit ^ 1;
1371
+ PUSH_STACK (kitten->klause, not_lit);
1372
+ } else {
1373
+ ROG (reason, "analyzing unit");
1374
+ PUSH_STACK (kitten->resolved, reason);
1375
+ }
1376
+ }
1377
+
1378
+ // this is bfs not dfs so it does not work for lrat :/
1379
+ /*
1380
+ for (size_t next = 0; next < SIZE_STACK (kitten->analyzed); next++) {
1381
+ const unsigned idx = PEEK_STACK (kitten->analyzed, next);
1382
+ assert (marks[idx]);
1383
+ const kar *var = vars + idx;
1384
+ const unsigned reason = var->reason;
1385
+ if (reason == INVALID) {
1386
+ unsigned lit = 2 * idx;
1387
+ if (values[lit] < 0)
1388
+ lit ^= 1;
1389
+ LOG ("failed assumption %u", lit);
1390
+ assert (!kitten->failed[lit]);
1391
+ kitten->failed[lit] = true;
1392
+ const unsigned not_lit = lit ^ 1;
1393
+ PUSH_STACK (kitten->klause, not_lit);
1394
+ } else {
1395
+ ROG (reason, "analyzing");
1396
+ PUSH_STACK (kitten->resolved, reason);
1397
+ klause *c = dereference_klause (kitten, reason);
1398
+ for (all_literals_in_klause (other, c)) {
1399
+ const unsigned other_idx = other / 2;
1400
+ if (other_idx == idx)
1401
+ continue;
1402
+ if (marks[other_idx])
1403
+ continue;
1404
+ marks[other_idx] = true;
1405
+ PUSH_STACK (kitten->analyzed, other_idx);
1406
+ LOG ("analyzing final literal %u", other ^ 1);
1407
+ }
1408
+ }
1409
+ }
1410
+ */
1411
+
1412
+ for (all_stack (unsigned, idx, kitten->analyzed))
1413
+ assert (marks[idx]), marks[idx] = 0;
1414
+ CLEAR_STACK (kitten->analyzed);
1415
+
1416
+ RELEASE_STACK (work);
1417
+
1418
+ const size_t resolved = SIZE_STACK (kitten->resolved);
1419
+ assert (resolved);
1420
+
1421
+ if (resolved == 1) {
1422
+ kitten->failing = PEEK_STACK (kitten->resolved, 0);
1423
+ ROG (kitten->failing, "reusing as core");
1424
+ } else {
1425
+ kitten->failing = new_learned_klause (kitten);
1426
+ ROG (kitten->failing, "new core");
1427
+ }
1428
+
1429
+ CLEAR_STACK (kitten->resolved);
1430
+ CLEAR_STACK (kitten->klause);
1431
+ }
1432
+
1433
+ static void flush_trail (kitten *kitten) {
1434
+ unsigneds *trail = &kitten->trail;
1435
+ LOG ("flushing %zu root-level literals from trail", SIZE_STACK (*trail));
1436
+ assert (!kitten->level);
1437
+ kitten->propagated = 0;
1438
+ CLEAR_STACK (*trail);
1439
+ }
1440
+
1441
+ static int decide (kitten *kitten) {
1442
+ if (!kitten->level && !EMPTY_STACK (kitten->trail))
1443
+ flush_trail (kitten);
1444
+
1445
+ const value *const values = kitten->values;
1446
+ unsigned decision = INVALID;
1447
+ const size_t assumptions = SIZE_STACK (kitten->assumptions);
1448
+ while (kitten->level < assumptions) {
1449
+ unsigned assumption = PEEK_STACK (kitten->assumptions, kitten->level);
1450
+ value value = values[assumption];
1451
+ if (value < 0) {
1452
+ LOG ("found failing assumption %u", assumption);
1453
+ failing (kitten);
1454
+ return 20;
1455
+ } else if (value > 0) {
1456
+
1457
+ kitten->level++;
1458
+ LOG ("pseudo decision level %u for already satisfied assumption %u",
1459
+ kitten->level, assumption);
1460
+ } else {
1461
+ decision = assumption;
1462
+ LOG ("using assumption %u as decision", decision);
1463
+ break;
1464
+ }
1465
+ }
1466
+
1467
+ if (!kitten->unassigned)
1468
+ return 10;
1469
+
1470
+ if (KITTEN_TICKS >= kitten->limits.ticks) {
1471
+ LOG ("ticks limit %" PRIu64 " hit after %" PRIu64 " ticks",
1472
+ kitten->limits.ticks, KITTEN_TICKS);
1473
+ return -1;
1474
+ }
1475
+
1476
+ if (kitten->terminator && kitten->terminator (kitten->terminator_data)) {
1477
+ LOG ("terminator requested termination");
1478
+ return -1;
1479
+ }
1480
+
1481
+ if (decision == INVALID) {
1482
+ unsigned idx = kitten->queue.search;
1483
+ const kink *const links = kitten->links;
1484
+ for (;;) {
1485
+ assert (idx != INVALID);
1486
+ if (!values[2 * idx])
1487
+ break;
1488
+ idx = links[idx].prev;
1489
+ }
1490
+ update_search (kitten, idx);
1491
+ const unsigned phase = kitten->phases[idx];
1492
+ decision = 2 * idx + phase;
1493
+ LOG ("decision %u variable %u phase %u", decision, idx, phase);
1494
+ }
1495
+ INC (kitten_decisions);
1496
+ kitten->level++;
1497
+ assign (kitten, decision, INVALID);
1498
+ return 0;
1499
+ }
1500
+
1501
+ static void inconsistent (kitten *kitten, unsigned ref) {
1502
+ assert (ref != INVALID);
1503
+ assert (kitten->inconsistent == INVALID);
1504
+
1505
+ if (!kitten->antecedents) {
1506
+ kitten->inconsistent = ref;
1507
+ ROG (ref, "registering inconsistent virtually empty");
1508
+ return;
1509
+ }
1510
+
1511
+ unsigneds *analyzed = &kitten->analyzed;
1512
+ unsigneds *resolved = &kitten->resolved;
1513
+
1514
+ assert (EMPTY_STACK (*analyzed));
1515
+ assert (EMPTY_STACK (*resolved));
1516
+
1517
+ value *marks = kitten->marks;
1518
+ const kar *const vars = kitten->vars;
1519
+ unsigned next = 0;
1520
+
1521
+ for (;;) {
1522
+ assert (ref != INVALID);
1523
+ klause *c = dereference_klause (kitten, ref);
1524
+ assert (c);
1525
+ ROG (ref, "analyzing inconsistent");
1526
+ PUSH_STACK (*resolved, ref);
1527
+ for (all_literals_in_klause (lit, c)) {
1528
+ const unsigned idx = lit / 2;
1529
+ assert (!vars[idx].level);
1530
+ if (marks[idx])
1531
+ continue;
1532
+ assert (kitten->values[lit] < 0);
1533
+ LOG ("analyzed %u", lit);
1534
+ marks[idx] = true;
1535
+ PUSH_STACK (kitten->analyzed, idx);
1536
+ }
1537
+ if (next == SIZE_STACK (kitten->analyzed))
1538
+ break;
1539
+ const unsigned idx = PEEK_STACK (kitten->analyzed, next);
1540
+ next++;
1541
+ const kar *const v = vars + idx;
1542
+ assert (!v->level);
1543
+ ref = v->reason;
1544
+ }
1545
+ assert (EMPTY_STACK (kitten->klause));
1546
+ ref = new_learned_klause (kitten);
1547
+ ROG (ref, "registering final inconsistent empty");
1548
+ kitten->inconsistent = ref;
1549
+
1550
+ for (all_stack (unsigned, idx, *analyzed))
1551
+ marks[idx] = 0;
1552
+
1553
+ CLEAR_STACK (*analyzed);
1554
+ CLEAR_STACK (*resolved);
1555
+ }
1556
+
1557
+ static int propagate_units (kitten *kitten) {
1558
+ if (kitten->inconsistent != INVALID)
1559
+ return 20;
1560
+
1561
+ if (EMPTY_STACK (kitten->units)) {
1562
+ LOG ("no root level unit clauses");
1563
+ return 0;
1564
+ }
1565
+
1566
+ LOG ("propagating %zu root level unit clauses",
1567
+ SIZE_STACK (kitten->units));
1568
+
1569
+ const value *const values = kitten->values;
1570
+
1571
+ for (size_t next = 0; next < SIZE_STACK (kitten->units); next++) {
1572
+ const unsigned ref = PEEK_STACK (kitten->units, next);
1573
+ assert (ref != INVALID);
1574
+ klause *c = dereference_klause (kitten, ref);
1575
+ assert (c->size == 1);
1576
+ ROG (ref, "propagating unit");
1577
+ const unsigned unit = c->lits[0];
1578
+ const value value = values[unit];
1579
+ if (value > 0)
1580
+ continue;
1581
+ if (value < 0) {
1582
+ inconsistent (kitten, ref);
1583
+ return 20;
1584
+ }
1585
+ assign (kitten, unit, ref);
1586
+ }
1587
+ const unsigned conflict = propagate (kitten);
1588
+ if (conflict == INVALID)
1589
+ return 0;
1590
+ inconsistent (kitten, conflict);
1591
+ return 20;
1592
+ }
1593
+
1594
+ /*------------------------------------------------------------------------*/
1595
+
1596
+ static klause *begin_klauses (kitten *kitten) {
1597
+ return (klause *) BEGIN_STACK (kitten->klauses);
1598
+ }
1599
+
1600
+ static klause *end_original_klauses (kitten *kitten) {
1601
+ return (klause *) (BEGIN_STACK (kitten->klauses) +
1602
+ kitten->end_original_ref);
1603
+ }
1604
+
1605
+ static klause *end_klauses (kitten *kitten) {
1606
+ return (klause *) END_STACK (kitten->klauses);
1607
+ }
1608
+
1609
+ static klause *next_klause (kitten *kitten, klause *c) {
1610
+ assert (begin_klauses (kitten) <= c);
1611
+ assert (c < end_klauses (kitten));
1612
+ unsigned *res = c->lits + c->size;
1613
+ if (kitten->antecedents && is_learned_klause (c))
1614
+ res += c->aux;
1615
+ return (klause *) res;
1616
+ }
1617
+
1618
+ /*------------------------------------------------------------------------*/
1619
+
1620
+ static void reset_core (kitten *kitten) {
1621
+ LOG ("resetting core clauses");
1622
+ size_t reset = 0;
1623
+ for (all_klauses (c))
1624
+ if (is_core_klause (c))
1625
+ unset_core_klause (c), reset++;
1626
+ LOG ("reset %zu core clauses", reset);
1627
+ CLEAR_STACK (kitten->core);
1628
+ }
1629
+
1630
+ static void reset_assumptions (kitten *kitten) {
1631
+ LOG ("reset %zu assumptions", SIZE_STACK (kitten->assumptions));
1632
+ while (!EMPTY_STACK (kitten->assumptions)) {
1633
+ const unsigned assumption = POP_STACK (kitten->assumptions);
1634
+ kitten->failed[assumption] = false;
1635
+ }
1636
+ #ifndef NDEBUG
1637
+ for (size_t i = 0; i < kitten->size; i++)
1638
+ assert (!kitten->failed[i]);
1639
+ #endif
1640
+ CLEAR_STACK (kitten->assumptions);
1641
+ if (kitten->failing != INVALID) {
1642
+ ROG (kitten->failing, "reset failed assumption reason");
1643
+ kitten->failing = INVALID;
1644
+ }
1645
+ }
1646
+
1647
+ static void reset_incremental (kitten *kitten) {
1648
+ // if (kitten->level)
1649
+ completely_backtrack_to_root_level (kitten);
1650
+ if (!EMPTY_STACK (kitten->assumptions))
1651
+ reset_assumptions (kitten);
1652
+ else
1653
+ assert (kitten->failing == INVALID);
1654
+ if (kitten->status == 21)
1655
+ reset_core (kitten);
1656
+ UPDATE_STATUS (0);
1657
+ }
1658
+
1659
+ /*------------------------------------------------------------------------*/
1660
+
1661
+ static bool flip_literal (kitten *kitten, unsigned lit) {
1662
+ INC (kitten_flip);
1663
+ signed char *values = kitten->values;
1664
+ if (values[lit] < 0)
1665
+ lit ^= 1;
1666
+ LOG ("trying to flip value of satisfied literal %u", lit);
1667
+ assert (values[lit] > 0);
1668
+ katches *watches = kitten->watches + lit;
1669
+ unsigned *q = BEGIN_STACK (*watches);
1670
+ const unsigned *const end_watches = END_STACK (*watches);
1671
+ unsigned const *p = q;
1672
+ uint64_t ticks =
1673
+ (((const char *const) end_watches - (const char *const) q) >> 7) + 1;
1674
+ bool res = true;
1675
+ while (p != end_watches) {
1676
+ const unsigned ref = *q++ = *p++;
1677
+ klause *c = dereference_klause (kitten, ref);
1678
+ unsigned *lits = c->lits;
1679
+ const unsigned other = lits[0] ^ lits[1] ^ lit;
1680
+ const value other_value = values[other];
1681
+ ticks++;
1682
+ if (other_value > 0)
1683
+ continue;
1684
+ value replacement_value = -1;
1685
+ unsigned replacement = INVALID;
1686
+ const unsigned *const end_lits = lits + c->size;
1687
+ unsigned *r;
1688
+ for (r = lits + 2; r != end_lits; r++) {
1689
+ replacement = *r;
1690
+ assert (replacement != lit);
1691
+ replacement_value = values[replacement];
1692
+ assert (replacement_value);
1693
+ if (replacement_value > 0)
1694
+ break;
1695
+ }
1696
+ if (replacement_value > 0) {
1697
+ assert (replacement != INVALID);
1698
+ ROG (ref, "unwatching %u in", lit);
1699
+ lits[0] = other;
1700
+ lits[1] = replacement;
1701
+ *r = lit;
1702
+ watch_klause (kitten, replacement, ref);
1703
+ q--;
1704
+ } else {
1705
+ assert (replacement_value < 0);
1706
+ ROG (ref, "single satisfied");
1707
+ res = false;
1708
+ break;
1709
+ }
1710
+ }
1711
+ while (p != end_watches)
1712
+ *q++ = *p++;
1713
+ SET_END_OF_STACK (*watches, q);
1714
+ ADD (kitten_ticks, ticks);
1715
+ if (res) {
1716
+ LOG ("flipping value of %u", lit);
1717
+ values[lit] = -1;
1718
+ const unsigned not_lit = lit ^ 1;
1719
+ values[not_lit] = 1;
1720
+ INC (kitten_flipped);
1721
+ } else
1722
+ LOG ("failed to flip value of %u", lit);
1723
+ return res;
1724
+ }
1725
+
1726
+ /*------------------------------------------------------------------------*/
1727
+
1728
+ // this cadical specific clause addition avoids copying clauses multiple
1729
+ // times just to convert literals to unsigned representation.
1730
+ //
1731
+ static unsigned int2u (int lit) {
1732
+ assert (lit != 0);
1733
+ int idx = abs (lit) - 1;
1734
+ return (lit < 0) + 2u * (unsigned) idx;
1735
+ }
1736
+
1737
+ void kitten_assume (kitten *kitten, unsigned elit) {
1738
+ REQUIRE_INITIALIZED ();
1739
+ if (kitten->status)
1740
+ reset_incremental (kitten);
1741
+ const unsigned ilit = import_literal (kitten, elit);
1742
+ LOG ("registering assumption %u", ilit);
1743
+ PUSH_STACK (kitten->assumptions, ilit);
1744
+ }
1745
+
1746
+ void kitten_assume_signed (kitten *kitten, int elit) {
1747
+ unsigned kelit = int2u (elit);
1748
+ kitten_assume (kitten, kelit);
1749
+ }
1750
+
1751
+ void kitten_clause_with_id_and_exception (kitten *kitten, unsigned id,
1752
+ size_t size,
1753
+ const unsigned *elits,
1754
+ unsigned except) {
1755
+ REQUIRE_INITIALIZED ();
1756
+ if (kitten->status)
1757
+ reset_incremental (kitten);
1758
+ assert (EMPTY_STACK (kitten->klause));
1759
+ const unsigned *const end = elits + size;
1760
+ for (const unsigned *p = elits; p != end; p++) {
1761
+ const unsigned elit = *p;
1762
+ if (elit == except)
1763
+ continue;
1764
+ const unsigned ilit = import_literal (kitten, elit);
1765
+ assert (ilit < kitten->lits);
1766
+ const unsigned iidx = ilit / 2;
1767
+ if (kitten->marks[iidx])
1768
+ INVALID_API_USAGE ("variable '%u' of literal '%u' occurs twice",
1769
+ elit / 2, elit);
1770
+ kitten->marks[iidx] = true;
1771
+ PUSH_STACK (kitten->klause, ilit);
1772
+ }
1773
+ for (unsigned *p = kitten->klause.begin; p != kitten->klause.end; p++)
1774
+ kitten->marks[*p / 2] = false;
1775
+ new_original_klause (kitten, id);
1776
+ CLEAR_STACK (kitten->klause);
1777
+ }
1778
+
1779
+ void citten_clause_with_id_and_exception (kitten *kitten, unsigned id,
1780
+ size_t size, const int *elits,
1781
+ unsigned except) {
1782
+ REQUIRE_INITIALIZED ();
1783
+ if (kitten->status)
1784
+ reset_incremental (kitten);
1785
+ assert (EMPTY_STACK (kitten->klause));
1786
+ const int *const end = elits + size;
1787
+ for (const int *p = elits; p != end; p++) {
1788
+ const unsigned elit = int2u (*p); // this is the conversion
1789
+ if (elit == except)
1790
+ continue;
1791
+ const unsigned ilit = import_literal (kitten, elit);
1792
+ assert (ilit < kitten->lits);
1793
+ const unsigned iidx = ilit / 2;
1794
+ if (kitten->marks[iidx])
1795
+ INVALID_API_USAGE ("variable '%u' of literal '%u' occurs twice",
1796
+ elit / 2, elit);
1797
+ kitten->marks[iidx] = true;
1798
+ PUSH_STACK (kitten->klause, ilit);
1799
+ }
1800
+ for (unsigned *p = kitten->klause.begin; p != kitten->klause.end; p++)
1801
+ kitten->marks[*p / 2] = false;
1802
+ new_original_klause (kitten, id);
1803
+ CLEAR_STACK (kitten->klause);
1804
+ }
1805
+
1806
+ void citten_clause_with_id_and_equivalence (kitten *kitten, unsigned id,
1807
+ size_t size, const int *elits,
1808
+ unsigned lit, unsigned other) {
1809
+ REQUIRE_INITIALIZED ();
1810
+ if (kitten->status)
1811
+ reset_incremental (kitten);
1812
+ assert (EMPTY_STACK (kitten->klause));
1813
+ bool sat = false;
1814
+ const int *const end = elits + size;
1815
+ for (const int *p = elits; p != end; p++) {
1816
+ const unsigned elit = int2u (*p); // this is the conversion
1817
+ if (elit == (lit ^ 1u) || elit == (other ^ 1u))
1818
+ continue;
1819
+ if (elit == lit || elit == other) {
1820
+ sat = true;
1821
+ break;
1822
+ }
1823
+ const unsigned ilit = import_literal (kitten, elit);
1824
+ assert (ilit < kitten->lits);
1825
+ const unsigned iidx = ilit / 2;
1826
+ if (kitten->marks[iidx])
1827
+ INVALID_API_USAGE ("variable '%u' of literal '%u' occurs twice",
1828
+ elit / 2, elit);
1829
+ kitten->marks[iidx] = true;
1830
+ PUSH_STACK (kitten->klause, ilit);
1831
+ }
1832
+ for (unsigned *p = kitten->klause.begin; p != kitten->klause.end; p++)
1833
+ kitten->marks[*p / 2] = false;
1834
+ if (!sat)
1835
+ new_original_klause (kitten, id);
1836
+ CLEAR_STACK (kitten->klause);
1837
+ }
1838
+
1839
+ void kitten_clause (kitten *kitten, size_t size, unsigned *elits) {
1840
+ kitten_clause_with_id_and_exception (kitten, INVALID, size, elits,
1841
+ INVALID);
1842
+ }
1843
+
1844
+ void citten_clause_with_id (kitten *kitten, unsigned id, size_t size,
1845
+ int *elits) {
1846
+ citten_clause_with_id_and_exception (kitten, id, size, elits, INVALID);
1847
+ }
1848
+
1849
+ void kitten_unit (kitten *kitten, unsigned lit) {
1850
+ kitten_clause (kitten, 1, &lit);
1851
+ }
1852
+
1853
+ void kitten_binary (kitten *kitten, unsigned a, unsigned b) {
1854
+ unsigned clause[2] = {a, b};
1855
+ kitten_clause (kitten, 2, clause);
1856
+ }
1857
+
1858
+ int kitten_solve (kitten *kitten) {
1859
+ REQUIRE_INITIALIZED ();
1860
+ if (kitten->status)
1861
+ reset_incremental (kitten);
1862
+ else // if (kitten->level)
1863
+ completely_backtrack_to_root_level (kitten);
1864
+
1865
+ LOG ("starting solving under %zu assumptions",
1866
+ SIZE_STACK (kitten->assumptions));
1867
+
1868
+ INC (kitten_solved);
1869
+
1870
+ int res = propagate_units (kitten);
1871
+ while (!res) {
1872
+ const unsigned conflict = propagate (kitten);
1873
+ if (kitten->terminator &&
1874
+ kitten->terminator (kitten->terminator_data)) {
1875
+ LOG ("terminator requested termination");
1876
+ res = -1;
1877
+ break;
1878
+ }
1879
+ if (conflict != INVALID) {
1880
+ if (kitten->level)
1881
+ analyze (kitten, conflict);
1882
+ else {
1883
+ inconsistent (kitten, conflict);
1884
+ res = 20;
1885
+ }
1886
+ } else
1887
+ res = decide (kitten);
1888
+ }
1889
+
1890
+ if (res < 0)
1891
+ res = 0;
1892
+
1893
+ if (!res && !EMPTY_STACK (kitten->assumptions))
1894
+ reset_assumptions (kitten);
1895
+
1896
+ UPDATE_STATUS (res);
1897
+
1898
+ if (res == 10)
1899
+ INC (kitten_sat);
1900
+ else if (res == 20)
1901
+ INC (kitten_unsat);
1902
+ else
1903
+ INC (kitten_unknown);
1904
+
1905
+ LOG ("finished solving with result %d", res);
1906
+
1907
+ return res;
1908
+ }
1909
+
1910
+ int kitten_status (kitten *kitten) { return kitten->status; }
1911
+
1912
+ unsigned kitten_compute_clausal_core (kitten *kitten,
1913
+ uint64_t *learned_ptr) {
1914
+ REQUIRE_STATUS (20);
1915
+
1916
+ if (!kitten->antecedents)
1917
+ INVALID_API_USAGE ("antecedents not tracked");
1918
+
1919
+ LOG ("computing clausal core");
1920
+
1921
+ unsigneds *resolved = &kitten->resolved;
1922
+ assert (EMPTY_STACK (*resolved));
1923
+
1924
+ unsigned original = 0;
1925
+ uint64_t learned = 0;
1926
+
1927
+ unsigned reason_ref = kitten->inconsistent;
1928
+
1929
+ if (reason_ref == INVALID) {
1930
+ assert (!EMPTY_STACK (kitten->assumptions));
1931
+ reason_ref = kitten->failing;
1932
+ if (reason_ref == INVALID) {
1933
+ LOG ("assumptions mutually inconsistent");
1934
+ goto DONE;
1935
+ }
1936
+ }
1937
+
1938
+ PUSH_STACK (*resolved, reason_ref);
1939
+ unsigneds *core = &kitten->core;
1940
+ assert (EMPTY_STACK (*core));
1941
+
1942
+ while (!EMPTY_STACK (*resolved)) {
1943
+ const unsigned c_ref = POP_STACK (*resolved);
1944
+ if (c_ref == INVALID) {
1945
+ const unsigned d_ref = POP_STACK (*resolved);
1946
+ ROG (d_ref, "core[%zu]", SIZE_STACK (*core));
1947
+ PUSH_STACK (*core, d_ref);
1948
+ klause *d = dereference_klause (kitten, d_ref);
1949
+ assert (!is_core_klause (d));
1950
+ set_core_klause (d);
1951
+ if (is_learned_klause (d))
1952
+ learned++;
1953
+ else
1954
+ original++;
1955
+ } else {
1956
+ klause *c = dereference_klause (kitten, c_ref);
1957
+ if (is_core_klause (c))
1958
+ continue;
1959
+ PUSH_STACK (*resolved, c_ref);
1960
+ PUSH_STACK (*resolved, INVALID);
1961
+ ROG (c_ref, "analyzing antecedent core");
1962
+ if (!is_learned_klause (c))
1963
+ continue;
1964
+ for (all_antecedents (d_ref, c)) {
1965
+ klause *d = dereference_klause (kitten, d_ref);
1966
+ if (!is_core_klause (d))
1967
+ PUSH_STACK (*resolved, d_ref);
1968
+ }
1969
+ }
1970
+ }
1971
+
1972
+ DONE:
1973
+
1974
+ if (learned_ptr)
1975
+ *learned_ptr = learned;
1976
+
1977
+ LOG ("clausal core of %u original clauses", original);
1978
+ LOG ("clausal core of %" PRIu64 " learned clauses", learned);
1979
+ kitten->statistics.original = original;
1980
+ kitten->statistics.learned = 0;
1981
+ UPDATE_STATUS (21);
1982
+
1983
+ return original;
1984
+ }
1985
+
1986
+ void kitten_traverse_core_ids (kitten *kitten, void *state,
1987
+ void (*traverse) (void *, unsigned)) {
1988
+ REQUIRE_STATUS (21);
1989
+
1990
+ LOG ("traversing core of original clauses");
1991
+
1992
+ unsigned traversed = 0;
1993
+
1994
+ for (all_original_klauses (c)) {
1995
+ // only happens for 'true' incremental calls, i.e. if add happens after
1996
+ // solve
1997
+ if (is_learned_klause (c))
1998
+ continue;
1999
+ if (!is_core_klause (c))
2000
+ continue;
2001
+ ROG (reference_klause (kitten, c), "traversing");
2002
+ traverse (state, c->aux);
2003
+ traversed++;
2004
+ }
2005
+
2006
+ LOG ("traversed %u original core clauses", traversed);
2007
+ (void) traversed;
2008
+
2009
+ assert (kitten->status == 21);
2010
+ }
2011
+
2012
+ void kitten_traverse_core_clauses (kitten *kitten, void *state,
2013
+ void (*traverse) (void *, bool, size_t,
2014
+ const unsigned *)) {
2015
+ REQUIRE_STATUS (21);
2016
+
2017
+ LOG ("traversing clausal core");
2018
+
2019
+ unsigned traversed = 0;
2020
+
2021
+ for (all_stack (unsigned, c_ref, kitten->core)) {
2022
+ klause *c = dereference_klause (kitten, c_ref);
2023
+ assert (is_core_klause (c));
2024
+ const bool learned = is_learned_klause (c);
2025
+ unsigneds *eclause = &kitten->eclause;
2026
+ assert (EMPTY_STACK (*eclause));
2027
+ for (all_literals_in_klause (ilit, c)) {
2028
+ const unsigned elit = export_literal (kitten, ilit);
2029
+ PUSH_STACK (*eclause, elit);
2030
+ }
2031
+ const size_t size = SIZE_STACK (*eclause);
2032
+ const unsigned *elits = eclause->begin;
2033
+ ROG (reference_klause (kitten, c), "traversing");
2034
+ traverse (state, learned, size, elits);
2035
+ CLEAR_STACK (*eclause);
2036
+ traversed++;
2037
+ }
2038
+
2039
+ LOG ("traversed %u core clauses", traversed);
2040
+ (void) traversed;
2041
+
2042
+ assert (kitten->status == 21);
2043
+ }
2044
+
2045
+ void kitten_traverse_core_clauses_with_id (
2046
+ kitten *kitten, void *state,
2047
+ void (*traverse) (void *state, unsigned, bool learned, size_t,
2048
+ const unsigned *)) {
2049
+ REQUIRE_STATUS (21);
2050
+
2051
+ LOG ("traversing clausal core");
2052
+
2053
+ unsigned traversed = 0;
2054
+
2055
+ for (all_stack (unsigned, c_ref, kitten->core)) {
2056
+ klause *c = dereference_klause (kitten, c_ref);
2057
+ assert (is_core_klause (c));
2058
+ const bool learned = is_learned_klause (c);
2059
+ unsigneds *eclause = &kitten->eclause;
2060
+ assert (EMPTY_STACK (*eclause));
2061
+ for (all_literals_in_klause (ilit, c)) {
2062
+ const unsigned elit = export_literal (kitten, ilit);
2063
+ PUSH_STACK (*eclause, elit);
2064
+ }
2065
+ const size_t size = SIZE_STACK (*eclause);
2066
+ const unsigned *elits = eclause->begin;
2067
+ ROG (reference_klause (kitten, c), "traversing");
2068
+ unsigned ctag = learned ? 0 : c->aux;
2069
+ traverse (state, ctag, learned, size, elits);
2070
+ CLEAR_STACK (*eclause);
2071
+ traversed++;
2072
+ }
2073
+
2074
+ LOG ("traversed %u core clauses", traversed);
2075
+ (void) traversed;
2076
+
2077
+ assert (kitten->status == 21);
2078
+ }
2079
+
2080
+ void kitten_trace_core (kitten *kitten, void *state,
2081
+ void (*trace) (void *, unsigned, unsigned, bool,
2082
+ size_t, const unsigned *, size_t,
2083
+ const unsigned *)) {
2084
+ REQUIRE_STATUS (21);
2085
+
2086
+ LOG ("tracing clausal core");
2087
+
2088
+ unsigned traced = 0;
2089
+
2090
+ for (all_stack (unsigned, c_ref, kitten->core)) {
2091
+ klause *c = dereference_klause (kitten, c_ref);
2092
+ assert (is_core_klause (c));
2093
+ const bool learned = is_learned_klause (c);
2094
+ unsigneds *eclause = &kitten->eclause;
2095
+ assert (EMPTY_STACK (*eclause));
2096
+ for (all_literals_in_klause (ilit, c)) {
2097
+ const unsigned elit = export_literal (kitten, ilit);
2098
+ PUSH_STACK (*eclause, elit);
2099
+ }
2100
+ const size_t size = SIZE_STACK (*eclause);
2101
+ const unsigned *elits = eclause->begin;
2102
+
2103
+ unsigneds *resolved = &kitten->resolved;
2104
+ assert (EMPTY_STACK (*resolved));
2105
+ if (learned) {
2106
+ for (all_antecedents (ref, c)) {
2107
+ PUSH_STACK (*resolved, ref);
2108
+ }
2109
+ }
2110
+ const size_t rsize = SIZE_STACK (*resolved);
2111
+ const unsigned *rids = resolved->begin;
2112
+
2113
+ unsigned cid = reference_klause (kitten, c);
2114
+ unsigned ctag = learned ? 0 : c->aux;
2115
+ ROG (cid, "tracing");
2116
+ trace (state, cid, ctag, learned, size, elits, rsize, rids);
2117
+ CLEAR_STACK (*eclause);
2118
+ CLEAR_STACK (*resolved);
2119
+ traced++;
2120
+ }
2121
+
2122
+ LOG ("traced %u core clauses", traced);
2123
+ (void) traced;
2124
+
2125
+ assert (kitten->status == 21);
2126
+ }
2127
+
2128
+ void kitten_shrink_to_clausal_core (kitten *kitten) {
2129
+ REQUIRE_STATUS (21);
2130
+
2131
+ LOG ("shrinking formula to core of original clauses");
2132
+
2133
+ CLEAR_STACK (kitten->trail);
2134
+
2135
+ kitten->unassigned = kitten->lits / 2;
2136
+ kitten->propagated = 0;
2137
+ kitten->level = 0;
2138
+
2139
+ update_search (kitten, kitten->queue.last);
2140
+
2141
+ memset (kitten->values, 0, kitten->lits);
2142
+
2143
+ for (all_kits (lit))
2144
+ CLEAR_STACK (KATCHES (lit));
2145
+
2146
+ assert (kitten->inconsistent != INVALID);
2147
+ klause *inconsistent = dereference_klause (kitten, kitten->inconsistent);
2148
+ if (is_learned_klause (inconsistent) || inconsistent->size) {
2149
+ ROG (kitten->inconsistent, "resetting inconsistent");
2150
+ kitten->inconsistent = INVALID;
2151
+ } else
2152
+ ROG (kitten->inconsistent, "keeping inconsistent");
2153
+
2154
+ CLEAR_STACK (kitten->units);
2155
+
2156
+ klause *begin = begin_klauses (kitten), *q = begin;
2157
+ klause const *const end = end_original_klauses (kitten);
2158
+ #ifdef LOGGING
2159
+ unsigned original = 0;
2160
+ #endif
2161
+ for (klause *c = begin, *next; c != end; c = next) {
2162
+ next = next_klause (kitten, c);
2163
+ // assert (!is_learned_klause (c)); not necessarily true
2164
+ if (is_learned_klause (c))
2165
+ continue;
2166
+ if (!is_core_klause (c))
2167
+ continue;
2168
+ unset_core_klause (c);
2169
+ const unsigned dst = (unsigned *) q - (unsigned *) begin;
2170
+ const unsigned size = c->size;
2171
+ if (!size) {
2172
+ if (kitten->inconsistent != INVALID)
2173
+ kitten->inconsistent = dst;
2174
+ } else if (size == 1) {
2175
+ PUSH_STACK (kitten->units, dst);
2176
+ ROG (dst, "keeping");
2177
+ } else {
2178
+ watch_klause (kitten, c->lits[0], dst);
2179
+ watch_klause (kitten, c->lits[1], dst);
2180
+ }
2181
+ if (c == q)
2182
+ q = next;
2183
+ else {
2184
+ const size_t bytes = (char *) next - (char *) c;
2185
+ memmove (q, c, bytes);
2186
+ q = (klause *) ((char *) q + bytes);
2187
+ }
2188
+ #ifdef LOGGING
2189
+ original++;
2190
+ #endif
2191
+ }
2192
+ SET_END_OF_STACK (kitten->klauses, (unsigned *) q);
2193
+ kitten->end_original_ref = SIZE_STACK (kitten->klauses);
2194
+ LOG ("end of original clauses at %zu", kitten->end_original_ref);
2195
+ LOG ("%u original clauses left", original);
2196
+
2197
+ CLEAR_STACK (kitten->core);
2198
+
2199
+ UPDATE_STATUS (0);
2200
+ }
2201
+
2202
+ signed char kitten_signed_value (kitten *kitten, int selit) {
2203
+ REQUIRE_STATUS (10);
2204
+ const unsigned elit = int2u (selit);
2205
+ const unsigned eidx = elit / 2;
2206
+ if (eidx >= kitten->evars)
2207
+ return 0;
2208
+ unsigned iidx = kitten->import[eidx];
2209
+ if (!iidx)
2210
+ return 0;
2211
+ const unsigned ilit = 2 * (iidx - 1) + (elit & 1);
2212
+ return kitten->values[ilit];
2213
+ }
2214
+
2215
+ signed char kitten_value (kitten *kitten, unsigned elit) {
2216
+ REQUIRE_STATUS (10);
2217
+ const unsigned eidx = elit / 2;
2218
+ if (eidx >= kitten->evars)
2219
+ return 0;
2220
+ unsigned iidx = kitten->import[eidx];
2221
+ if (!iidx)
2222
+ return 0;
2223
+ const unsigned ilit = 2 * (iidx - 1) + (elit & 1);
2224
+ return kitten->values[ilit];
2225
+ }
2226
+
2227
+ signed char kitten_fixed (kitten *kitten, unsigned elit) {
2228
+ const unsigned eidx = elit / 2;
2229
+ if (eidx >= kitten->evars)
2230
+ return 0;
2231
+ unsigned iidx = kitten->import[eidx];
2232
+ if (!iidx)
2233
+ return 0;
2234
+ iidx--;
2235
+ const unsigned ilit = 2 * iidx + (elit & 1);
2236
+ signed char res = kitten->values[ilit];
2237
+ if (!res)
2238
+ return 0;
2239
+ kar *v = kitten->vars + iidx;
2240
+ if (v->level)
2241
+ return 0;
2242
+ return res;
2243
+ }
2244
+
2245
+ signed char kitten_fixed_signed (kitten *kitten, int elit) {
2246
+ unsigned kelit = int2u (elit);
2247
+ return kitten_fixed (kitten, kelit);
2248
+ }
2249
+
2250
+ bool kitten_flip_literal (kitten *kitten, unsigned elit) {
2251
+ REQUIRE_STATUS (10);
2252
+ const unsigned eidx = elit / 2;
2253
+ if (eidx >= kitten->evars)
2254
+ return false;
2255
+ unsigned iidx = kitten->import[eidx];
2256
+ if (!iidx)
2257
+ return false;
2258
+ const unsigned ilit = 2 * (iidx - 1) + (elit & 1);
2259
+ if (kitten_fixed (kitten, elit))
2260
+ return false;
2261
+ return flip_literal (kitten, ilit);
2262
+ }
2263
+
2264
+ bool kitten_flip_signed_literal (kitten *kitten, int elit) {
2265
+ REQUIRE_STATUS (10);
2266
+ unsigned kelit = int2u (elit);
2267
+ return kitten_flip_literal (kitten, kelit);
2268
+ }
2269
+
2270
+ bool kitten_failed (kitten *kitten, unsigned elit) {
2271
+ REQUIRE_STATUS (20);
2272
+ const unsigned eidx = elit / 2;
2273
+ if (eidx >= kitten->evars)
2274
+ return false;
2275
+ unsigned iidx = kitten->import[eidx];
2276
+ if (!iidx)
2277
+ return false;
2278
+ const unsigned ilit = 2 * (iidx - 1) + (elit & 1);
2279
+ return kitten->failed[ilit];
2280
+ }
2281
+
2282
+ // checks both watches for clauses with only one literal positively
2283
+ // assigned. if such a clause is found, return false. Otherwise fix watch
2284
+ // invariant and return true
2285
+ static bool prime_propagate (kitten *kitten, const unsigned idx,
2286
+ void *state, const bool ignoring,
2287
+ bool (*ignore) (void *, unsigned)) {
2288
+ unsigned lit = 2 * idx;
2289
+ unsigned conflict = INVALID;
2290
+ value *values = kitten->values;
2291
+ for (int i = 0; i < 2; i++) {
2292
+ if (conflict != INVALID)
2293
+ break;
2294
+ lit = lit ^ i;
2295
+ const unsigned not_lit = lit ^ 1;
2296
+ katches *watches = kitten->watches + not_lit;
2297
+ unsigned *q = BEGIN_STACK (*watches);
2298
+ const unsigned *const end_watches = END_STACK (*watches);
2299
+ unsigned const *p = q;
2300
+ uint64_t ticks =
2301
+ (((const char *const) end_watches - (const char *const) q) >> 7) +
2302
+ 1;
2303
+ while (p != end_watches) {
2304
+ const unsigned ref = *q++ = *p++;
2305
+ klause *c = dereference_klause (kitten, ref);
2306
+ if (is_learned_klause (c) || ignore (state, c->aux) == ignoring)
2307
+ continue;
2308
+ assert (c->size > 1);
2309
+ unsigned *lits = c->lits;
2310
+ const unsigned other = lits[0] ^ lits[1] ^ not_lit;
2311
+ const value other_value = values[other];
2312
+ ticks++;
2313
+ if (other_value > 0)
2314
+ continue;
2315
+ value replacement_value = -1;
2316
+ unsigned replacement = INVALID;
2317
+ const unsigned *const end_lits = lits + c->size;
2318
+ unsigned *r;
2319
+ for (r = lits + 2; r != end_lits; r++) {
2320
+ replacement = *r;
2321
+ replacement_value = values[replacement];
2322
+ if (replacement_value > 0)
2323
+ break;
2324
+ }
2325
+ if (replacement_value > 0) {
2326
+ assert (replacement != INVALID);
2327
+ ROG (ref, "unwatching %u in", not_lit);
2328
+ lits[0] = other;
2329
+ lits[1] = replacement;
2330
+ *r = not_lit;
2331
+ watch_klause (kitten, replacement, ref);
2332
+ q--;
2333
+ } else {
2334
+ ROG (ref, "idx %u forced prime by", idx);
2335
+ conflict = ref;
2336
+ break;
2337
+ }
2338
+ }
2339
+ while (p != end_watches)
2340
+ *q++ = *p++;
2341
+ SET_END_OF_STACK (*watches, q);
2342
+ ADD (kitten_ticks, ticks);
2343
+ }
2344
+ return conflict == INVALID;
2345
+ }
2346
+
2347
+ void kitten_add_prime_implicant (kitten *kitten, void *state, int side,
2348
+ void (*add_implicant) (void *, int, size_t,
2349
+ const unsigned *)) {
2350
+ REQUIRE_STATUS (11);
2351
+ // might be possible in some edge cases
2352
+ unsigneds *prime = &kitten->prime[side];
2353
+ unsigneds *prime2 = &kitten->prime[!side];
2354
+ assert (!EMPTY_STACK (*prime) || !EMPTY_STACK (*prime2));
2355
+ CLEAR_STACK (*prime2);
2356
+
2357
+ for (all_stack (unsigned, lit, *prime)) {
2358
+ const unsigned not_lit = lit ^ 1;
2359
+ const unsigned elit = export_literal (kitten, not_lit);
2360
+ PUSH_STACK (*prime2, elit);
2361
+ }
2362
+
2363
+ // adds a clause which will reset kitten status and backtrack
2364
+ add_implicant (state, side, SIZE_STACK (*prime2), BEGIN_STACK (*prime2));
2365
+ CLEAR_STACK (*prime);
2366
+ CLEAR_STACK (*prime2);
2367
+ }
2368
+
2369
+ // computes two prime implicants, only considering clauses based on ignore
2370
+ // return -1 if no prime implicant has been computed, otherwise returns
2371
+ // index of shorter implicant.
2372
+ // TODO does not work if flip has been called beforehand
2373
+ int kitten_compute_prime_implicant (kitten *kitten, void *state,
2374
+ bool (*ignore) (void *, unsigned)) {
2375
+ REQUIRE_STATUS (10);
2376
+
2377
+ value *values = kitten->values;
2378
+ kar *vars = kitten->vars;
2379
+ unsigneds unassigned;
2380
+ INIT_STACK (unassigned);
2381
+ bool limit_hit = 0;
2382
+ assert (EMPTY_STACK (kitten->prime[0]) && EMPTY_STACK (kitten->prime[1]));
2383
+ for (int i = 0; i < 2; i++) {
2384
+ const bool ignoring = i;
2385
+ for (all_stack (unsigned, lit, kitten->trail)) {
2386
+ if (KITTEN_TICKS >= kitten->limits.ticks) {
2387
+ LOG ("ticks limit %" PRIu64 " hit after %" PRIu64 " ticks",
2388
+ kitten->limits.ticks, KITTEN_TICKS);
2389
+ limit_hit = 1;
2390
+ break;
2391
+ }
2392
+ assert (values[lit] > 0);
2393
+ const unsigned idx = lit / 2;
2394
+ const unsigned ref = vars[idx].reason;
2395
+ assert (vars[idx].level);
2396
+ klause *c = 0;
2397
+ if (ref != INVALID)
2398
+ c = dereference_klause (kitten, ref);
2399
+ if (ref == INVALID || is_learned_klause (c) ||
2400
+ ignore (state, c->aux) == ignoring) {
2401
+ LOG ("non-prime candidate var %d", idx);
2402
+ if (prime_propagate (kitten, idx, state, ignoring, ignore)) {
2403
+ values[lit] = 0;
2404
+ values[lit ^ 1] = 0;
2405
+ PUSH_STACK (unassigned, lit);
2406
+ } else
2407
+ assert (values[lit] > 0);
2408
+ }
2409
+ }
2410
+ unsigneds *prime = &kitten->prime[i];
2411
+ // push on prime implicant stack.
2412
+ for (all_kits (lit)) {
2413
+ if (values[lit] > 0)
2414
+ PUSH_STACK (*prime, lit);
2415
+ }
2416
+ // reassign all literals on
2417
+ for (all_stack (unsigned, lit, unassigned)) {
2418
+ assert (!values[lit]);
2419
+ values[lit] = 1;
2420
+ values[lit ^ 1] = -1;
2421
+ }
2422
+ CLEAR_STACK (unassigned);
2423
+ }
2424
+ RELEASE_STACK (unassigned);
2425
+
2426
+ if (limit_hit) {
2427
+ CLEAR_STACK (kitten->prime[0]);
2428
+ CLEAR_STACK (kitten->prime[1]);
2429
+ return -1;
2430
+ }
2431
+ // the only case when one of the prime implicants is allowed to be empty
2432
+ // is if ignore returns always true or always false.
2433
+ assert (!EMPTY_STACK (kitten->prime[0]) ||
2434
+ !EMPTY_STACK (kitten->prime[1]));
2435
+ UPDATE_STATUS (11);
2436
+
2437
+ int res = SIZE_STACK (kitten->prime[0]) > SIZE_STACK (kitten->prime[1]);
2438
+ return res;
2439
+ }
2440
+
2441
+ static bool prime_propagate_blit (kitten *kitten, const unsigned idx,
2442
+ const unsigned blit) {
2443
+ unsigned lit = 2 * idx;
2444
+ unsigned conflict = INVALID;
2445
+ value *values = kitten->values;
2446
+ LOG ("prime propagating idx %u for blit %u", idx, blit);
2447
+ for (int i = 0; i < 2; i++) {
2448
+ if (conflict != INVALID)
2449
+ break;
2450
+ lit = lit ^ i;
2451
+ if (lit == blit)
2452
+ continue;
2453
+ const unsigned not_lit = lit ^ 1;
2454
+ katches *watches = kitten->watches + not_lit;
2455
+ unsigned *q = BEGIN_STACK (*watches);
2456
+ const unsigned *const end_watches = END_STACK (*watches);
2457
+ unsigned const *p = q;
2458
+ uint64_t ticks =
2459
+ (((const char *const) end_watches - (const char *const) q) >> 7) +
2460
+ 1;
2461
+ while (p != end_watches) {
2462
+ const unsigned ref = *q++ = *p++;
2463
+ klause *c = dereference_klause (kitten, ref);
2464
+ if (is_learned_klause (c))
2465
+ continue;
2466
+ ROG (ref, "checking with blit %u", blit);
2467
+ assert (c->size > 1);
2468
+ unsigned *lits = c->lits;
2469
+ const unsigned other = lits[0] ^ lits[1] ^ not_lit;
2470
+ const value other_value = values[other];
2471
+ ticks++;
2472
+ bool use = other == blit || not_lit == blit;
2473
+ if (other_value > 0)
2474
+ continue;
2475
+ value replacement_value = -1;
2476
+ unsigned replacement = INVALID;
2477
+ const unsigned *const end_lits = lits + c->size;
2478
+ unsigned *r;
2479
+ for (r = lits + 2; r != end_lits; r++) {
2480
+ replacement = *r;
2481
+ replacement_value = values[replacement];
2482
+ use = use || replacement == blit;
2483
+ if (replacement_value > 0)
2484
+ break;
2485
+ }
2486
+ if (replacement_value > 0) {
2487
+ assert (replacement != INVALID);
2488
+ ROG (ref, "unwatching %u in", not_lit);
2489
+ lits[0] = other;
2490
+ lits[1] = replacement;
2491
+ *r = not_lit;
2492
+ watch_klause (kitten, replacement, ref);
2493
+ q--;
2494
+ } else if (!use) {
2495
+ continue;
2496
+ } else {
2497
+ ROG (ref, "idx %u forced prime by", idx);
2498
+ conflict = ref;
2499
+ break;
2500
+ }
2501
+ }
2502
+ while (p != end_watches)
2503
+ *q++ = *p++;
2504
+ SET_END_OF_STACK (*watches, q);
2505
+ ADD (kitten_ticks, ticks);
2506
+ }
2507
+ return conflict == INVALID;
2508
+ }
2509
+
2510
+ static int compute_prime_implicant_for (kitten *kitten, unsigned blit) {
2511
+ value *values = kitten->values;
2512
+ #ifndef NDEBUG
2513
+ kar *vars = kitten->vars;
2514
+ #endif
2515
+ unsigneds unassigned;
2516
+ INIT_STACK (unassigned);
2517
+ bool limit_hit = false;
2518
+ assert (EMPTY_STACK (kitten->prime[0]) && EMPTY_STACK (kitten->prime[1]));
2519
+ for (int i = 0; i < 2; i++) {
2520
+ const unsigned block = blit ^ i;
2521
+ const bool ignoring = i;
2522
+ if (prime_propagate_blit (kitten, block / 2, block)) {
2523
+ value tmp = values[blit];
2524
+ assert (tmp);
2525
+ values[blit] = 0;
2526
+ values[blit ^ 1] = 0;
2527
+ PUSH_STACK (unassigned, tmp > 0 ? blit : blit ^ 1);
2528
+ PUSH_STACK (kitten->prime[ignoring], block); // will be negated!
2529
+ } else
2530
+ assert (false);
2531
+ for (all_stack (unsigned, lit, kitten->trail)) {
2532
+ if (KITTEN_TICKS >= kitten->limits.ticks) {
2533
+ LOG ("ticks limit %" PRIu64 " hit after %" PRIu64 " ticks",
2534
+ kitten->limits.ticks, KITTEN_TICKS);
2535
+ limit_hit = true;
2536
+ break;
2537
+ }
2538
+ if (!values[lit])
2539
+ continue;
2540
+ assert (values[lit]); // not true when flipping is involved
2541
+ const unsigned idx = lit / 2;
2542
+ assert (vars[idx].level);
2543
+ LOG ("non-prime candidate var %d", idx);
2544
+ if (prime_propagate_blit (kitten, idx, block)) {
2545
+ value tmp = values[lit];
2546
+ assert (tmp);
2547
+ values[lit] = 0;
2548
+ values[lit ^ 1] = 0;
2549
+ PUSH_STACK (unassigned, tmp > 0 ? lit : lit ^ 1);
2550
+ }
2551
+ }
2552
+ unsigneds *prime = &kitten->prime[i];
2553
+ // push on prime implicant stack.
2554
+ for (all_kits (lit)) {
2555
+ if (values[lit] > 0)
2556
+ PUSH_STACK (*prime, lit);
2557
+ }
2558
+ // reassign all literals on
2559
+ for (all_stack (unsigned, lit, unassigned)) {
2560
+ assert (!values[lit]);
2561
+ values[lit] = 1;
2562
+ values[lit ^ 1] = -1;
2563
+ }
2564
+ CLEAR_STACK (unassigned);
2565
+ }
2566
+ RELEASE_STACK (unassigned);
2567
+
2568
+ if (limit_hit) {
2569
+ CLEAR_STACK (kitten->prime[0]);
2570
+ CLEAR_STACK (kitten->prime[1]);
2571
+ return -1;
2572
+ }
2573
+ // the only case when one of the prime implicants is allowed to be empty
2574
+ // is if ignore returns always true or always false.
2575
+ assert (!EMPTY_STACK (kitten->prime[0]) ||
2576
+ !EMPTY_STACK (kitten->prime[1]));
2577
+ LOGLITS (BEGIN_STACK (kitten->prime[0]), SIZE_STACK (kitten->prime[0]),
2578
+ "first implicant %u", blit);
2579
+ LOGLITS (BEGIN_STACK (kitten->prime[1]), SIZE_STACK (kitten->prime[1]),
2580
+ "second implicant %u", blit ^ 1);
2581
+ UPDATE_STATUS (11);
2582
+
2583
+ int res = SIZE_STACK (kitten->prime[0]) > SIZE_STACK (kitten->prime[1]);
2584
+ return res;
2585
+ }
2586
+
2587
+ int kitten_flip_and_implicant_for_signed_literal (kitten *kitten,
2588
+ int elit) {
2589
+ REQUIRE_STATUS (10);
2590
+ unsigned kelit = int2u (elit);
2591
+ if (!kitten_flip_literal (kitten, kelit)) {
2592
+ return -2;
2593
+ }
2594
+ const unsigned eidx = kelit / 2;
2595
+ unsigned iidx = kitten->import[eidx];
2596
+ assert (iidx);
2597
+ const unsigned ilit = 2 * (iidx - 1) + (kelit & 1);
2598
+ return compute_prime_implicant_for (kitten, ilit);
2599
+ }