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,471 @@
1
+ #include "internal.hpp"
2
+
3
+ /*------------------------------------------------------------------------*/
4
+
5
+ namespace CaDiCaL {
6
+
7
+ /*------------------------------------------------------------------------*/
8
+
9
+ // Parse error.
10
+
11
+ #define PER(...) \
12
+ do { \
13
+ internal->error_message.init ( \
14
+ "%s:%" PRIu64 ": parse error: ", file->name (), \
15
+ (uint64_t) file->lineno ()); \
16
+ return internal->error_message.append (__VA_ARGS__); \
17
+ } while (0)
18
+
19
+ /*------------------------------------------------------------------------*/
20
+
21
+ // Parsing utilities.
22
+
23
+ inline int Parser::parse_char () { return file->get (); }
24
+
25
+ // Return an non zero error string if a parse error occurred.
26
+
27
+ inline const char *Parser::parse_string (const char *str, char prev) {
28
+ for (const char *p = str; *p; p++)
29
+ if (parse_char () == *p)
30
+ prev = *p;
31
+ else if (*p == ' ')
32
+ PER ("expected space after '%c'", prev);
33
+ else
34
+ PER ("expected '%c' after '%c'", *p, prev);
35
+ return 0;
36
+ }
37
+
38
+ inline const char *Parser::parse_positive_int (int &ch, int &res,
39
+ const char *name) {
40
+ assert (isdigit (ch));
41
+ res = ch - '0';
42
+ while (isdigit (ch = parse_char ())) {
43
+ int digit = ch - '0';
44
+ if (INT_MAX / 10 < res || INT_MAX - digit < 10 * res)
45
+ PER ("too large '%s' in header", name);
46
+ res = 10 * res + digit;
47
+ }
48
+ return 0;
49
+ }
50
+
51
+ inline const char *Parser::parse_positive_uint64_t (int &ch, uint64_t &res,
52
+ const char *name) {
53
+ assert (isdigit (ch));
54
+ res = ch - '0';
55
+ while (isdigit (ch = parse_char ())) {
56
+ int digit = ch - '0';
57
+ if (UINT64_MAX / 10 < res || UINT64_MAX - digit < 10 * res)
58
+ PER ("too large '%s' in header", name);
59
+ res = 10 * res + digit;
60
+ }
61
+ return 0;
62
+ }
63
+ static const char *cube_token = "unexpected 'a' in CNF";
64
+
65
+ inline const char *Parser::parse_lit (int &ch, int &lit, int &vars,
66
+ int strict) {
67
+ if (ch == 'a')
68
+ return cube_token;
69
+ int sign = 0;
70
+ if (ch == '-') {
71
+ if (!isdigit (ch = parse_char ()))
72
+ PER ("expected digit after '-'");
73
+ sign = -1;
74
+ } else if (!isdigit (ch))
75
+ PER ("expected digit or '-'");
76
+ else
77
+ sign = 1;
78
+ lit = ch - '0';
79
+ while (isdigit (ch = parse_char ())) {
80
+ int digit = ch - '0';
81
+ if (INT_MAX / 10 < lit || INT_MAX - digit < 10 * lit)
82
+ PER ("literal too large");
83
+ lit = 10 * lit + digit;
84
+ }
85
+ if (ch == '\r')
86
+ ch = parse_char ();
87
+ if (ch != 'c' && ch != ' ' && ch != '\t' && ch != '\n' && ch != EOF)
88
+ PER ("expected white space after '%d'", sign * lit);
89
+ if (lit > vars) {
90
+ if (strict != FORCED)
91
+ PER ("literal %d exceeds maximum variable %d", sign * lit, vars);
92
+ else
93
+ vars = lit;
94
+ }
95
+ lit *= sign;
96
+ return 0;
97
+ }
98
+
99
+ /*------------------------------------------------------------------------*/
100
+
101
+ // Parsing CNF in DIMACS format.
102
+
103
+ const char *Parser::parse_dimacs_non_profiled (int &vars, int strict) {
104
+
105
+ #ifndef QUIET
106
+ double start = internal->time ();
107
+ #endif
108
+
109
+ bool found_inccnf_header = false;
110
+ int ch = 0, declared = 0;
111
+ uint64_t clauses = 0;
112
+
113
+ vars = 0;
114
+
115
+ // First read comments before header with possibly embedded options.
116
+ //
117
+ for (;;) {
118
+ ch = parse_char ();
119
+ if (strict != STRICT)
120
+ if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r')
121
+ continue;
122
+ if (ch != 'c')
123
+ break;
124
+ string buf;
125
+ while ((ch = parse_char ()) != '\n')
126
+ if (ch == EOF)
127
+ PER ("unexpected end-of-file in header comment");
128
+ else if (ch != '\r')
129
+ buf.push_back (ch);
130
+ const char *o;
131
+ for (o = buf.c_str (); *o && *o != '-'; o++)
132
+ ;
133
+ if (!*o)
134
+ continue;
135
+ PHASE ("parse-dimacs", "found option '%s'", o);
136
+ if (*o)
137
+ solver->set_long_option (o);
138
+ }
139
+
140
+ if (ch != 'p')
141
+ PER ("expected 'c' or 'p'");
142
+
143
+ ch = parse_char ();
144
+ if (strict == STRICT) {
145
+ if (ch != ' ')
146
+ PER ("expected space after 'p'");
147
+ ch = parse_char ();
148
+ } else if (ch != ' ' && ch != '\t')
149
+ PER ("expected white space after 'p'");
150
+ else {
151
+ do
152
+ ch = parse_char ();
153
+ while (ch == ' ' || ch == '\t');
154
+ }
155
+
156
+ // Now read 'p cnf <var> <clauses>' header of DIMACS file
157
+ // or 'p inccnf' of incremental 'INCCNF' file.
158
+ //
159
+ if (ch == 'c') {
160
+ assert (!found_inccnf_header);
161
+ if (strict == STRICT) {
162
+ const char *err = parse_string ("nf ", 'c');
163
+ if (err)
164
+ return err;
165
+ ch = parse_char ();
166
+ if (!isdigit (ch))
167
+ PER ("expected digit after 'p cnf '");
168
+ err = parse_positive_int (ch, vars, "<max-var>");
169
+ if (err)
170
+ return err;
171
+ if (ch != ' ')
172
+ PER ("expected ' ' after 'p cnf %d'", vars);
173
+ if (!isdigit (ch = parse_char ()))
174
+ PER ("expected digit after 'p cnf %d '", vars);
175
+ err = parse_positive_uint64_t (ch, clauses, "<num-clauses>");
176
+ if (err)
177
+ return err;
178
+ if (ch != '\n')
179
+ PER ("expected new-line after 'p cnf %d %" PRIu64 "'", vars,
180
+ clauses);
181
+ } else {
182
+ if (parse_char () != 'n')
183
+ PER ("expected 'n' after 'p c'");
184
+ if (parse_char () != 'f')
185
+ PER ("expected 'f' after 'p cn'");
186
+ ch = parse_char ();
187
+ if (!isspace (ch))
188
+ PER ("expected space after 'p cnf'");
189
+ do
190
+ ch = parse_char ();
191
+ while (isspace (ch));
192
+ if (!isdigit (ch))
193
+ PER ("expected digit after 'p cnf '");
194
+ const char *err = parse_positive_int (ch, vars, "<max-var>");
195
+ if (err)
196
+ return err;
197
+ if (!isspace (ch))
198
+ PER ("expected space after 'p cnf %d'", vars);
199
+ do
200
+ ch = parse_char ();
201
+ while (isspace (ch));
202
+ if (!isdigit (ch))
203
+ PER ("expected digit after 'p cnf %d '", vars);
204
+ err = parse_positive_uint64_t (ch, clauses, "<num-clauses>");
205
+ if (err)
206
+ return err;
207
+ while (ch != '\n') {
208
+ if (ch != '\r' && !isspace (ch))
209
+ PER ("expected new-line after 'p cnf %d %" PRIu64 "'", vars,
210
+ clauses);
211
+ ch = parse_char ();
212
+ }
213
+ }
214
+
215
+ MSG ("found %s'p cnf %d %" PRIu64 "'%s header", tout.green_code (),
216
+ vars, clauses, tout.normal_code ());
217
+
218
+ if (vars) {
219
+ assert (vars > 0);
220
+ solver->resize (vars);
221
+ declared = vars;
222
+ }
223
+
224
+ internal->reserve_ids (clauses);
225
+
226
+ } else if (!parse_inccnf_too)
227
+ PER ("expected 'c' after 'p '");
228
+ else if (ch == 'i') {
229
+ found_inccnf_header = true;
230
+ const char *err = parse_string ("nccnf", 'i');
231
+ if (err)
232
+ return err;
233
+ ch = parse_char ();
234
+ if (strict == STRICT) {
235
+ if (ch != '\n')
236
+ PER ("expected new-line after 'p inccnf'");
237
+ } else {
238
+ while (ch != '\n') {
239
+ if (ch != '\r' && !isspace (ch))
240
+ PER ("expected new-line after 'p inccnf'");
241
+ ch = parse_char ();
242
+ }
243
+ }
244
+
245
+ MSG ("found %s'p inccnf'%s header", tout.green_code (),
246
+ tout.normal_code ());
247
+
248
+ // Cube & Conquer 'inccnf' format is not compatible with factor:
249
+ internal->opts.factor = 0;
250
+
251
+ strict = FORCED;
252
+ } else
253
+ PER ("expected 'c' or 'i' after 'p '");
254
+
255
+ if (parse_inccnf_too)
256
+ *parse_inccnf_too = false;
257
+
258
+ // Now read body of DIMACS part.
259
+ //
260
+ int lit = 0;
261
+ uint64_t parsed = 0;
262
+ while ((ch = parse_char ()) != EOF) {
263
+ if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r')
264
+ continue;
265
+ if (ch == 'c') {
266
+ while ((ch = parse_char ()) != '\n' && ch != EOF)
267
+ ;
268
+ if (ch == EOF)
269
+ break;
270
+ continue;
271
+ }
272
+ if (ch == 'a' && found_inccnf_header)
273
+ break;
274
+ const char *err = parse_lit (ch, lit, vars, strict);
275
+ if (err)
276
+ return err;
277
+ if (ch == 'c') {
278
+ while ((ch = parse_char ()) != '\n')
279
+ if (ch == EOF)
280
+ PER ("unexpected end-of-file in comment");
281
+ }
282
+ if (vars > declared) {
283
+ assert (strict == FORCED);
284
+ const int more_vars = vars - declared;
285
+ assert (more_vars > 0);
286
+ const int start = solver->declare_more_variables (more_vars);
287
+ assert (vars == start + more_vars - 1);
288
+ declared = vars;
289
+ #ifdef NDEBUG
290
+ (void) start;
291
+ #endif
292
+ }
293
+ solver->add (lit);
294
+ if (!found_inccnf_header && !lit && parsed++ >= clauses &&
295
+ strict != FORCED)
296
+ PER ("too many clauses");
297
+ }
298
+
299
+ if (lit)
300
+ PER ("last clause without terminating '0'");
301
+
302
+ if (!found_inccnf_header && parsed < clauses && strict != FORCED)
303
+ PER ("clause missing");
304
+
305
+ #ifndef QUIET
306
+ double end = internal->time ();
307
+ MSG ("parsed %" PRIu64 " clauses in %.2f seconds %s time", parsed,
308
+ end - start, internal->opts.realtime ? "real" : "process");
309
+ #endif
310
+
311
+ #ifndef QUIET
312
+ start = end;
313
+ size_t num_cubes = 0;
314
+ #endif
315
+ if (ch == 'a') {
316
+ assert (parse_inccnf_too);
317
+ assert (found_inccnf_header);
318
+ if (!*parse_inccnf_too)
319
+ *parse_inccnf_too = true;
320
+ for (;;) {
321
+ ch = parse_char ();
322
+ if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r')
323
+ continue;
324
+ if (ch == 'c') {
325
+ while ((ch = parse_char ()) != '\n' && ch != EOF)
326
+ ;
327
+ if (ch == EOF)
328
+ break;
329
+ continue;
330
+ }
331
+ const char *err = parse_lit (ch, lit, vars, strict);
332
+ if (err == cube_token)
333
+ PER ("two 'a' in a row");
334
+ else if (err)
335
+ return err;
336
+ if (ch == 'c') {
337
+ while ((ch = parse_char ()) != '\n')
338
+ if (ch == EOF)
339
+ PER ("unexpected end-of-file in comment");
340
+ }
341
+ if (cubes)
342
+ cubes->push_back (lit);
343
+ if (!lit) {
344
+ #ifndef QUIET
345
+ num_cubes++;
346
+ #endif
347
+ for (;;) {
348
+ ch = parse_char ();
349
+ if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r')
350
+ continue;
351
+ if (ch == 'c') {
352
+ while ((ch = parse_char ()) != '\n' && ch != EOF)
353
+ ;
354
+ if (ch == EOF)
355
+ break;
356
+ }
357
+ if (ch == EOF)
358
+ break;
359
+ if (ch != 'a')
360
+ PER ("expected 'a' or end-of-file after zero");
361
+ lit = INT_MIN;
362
+ break;
363
+ }
364
+ if (ch == EOF)
365
+ break;
366
+ }
367
+ }
368
+ if (lit)
369
+ PER ("last cube without terminating '0'");
370
+ }
371
+ #ifndef QUIET
372
+ if (found_inccnf_header) {
373
+ double end = internal->time ();
374
+ MSG ("parsed %zd cubes in %.2f seconds %s time", num_cubes, end - start,
375
+ internal->opts.realtime ? "real" : "process");
376
+ }
377
+ #endif
378
+ return 0;
379
+ }
380
+
381
+ /*------------------------------------------------------------------------*/
382
+
383
+ // Parsing solution in competition output format.
384
+
385
+ const char *Parser::parse_solution_non_profiled () {
386
+ external->solution = new signed char[external->max_var + 1u];
387
+ external->solution_size = external->max_var;
388
+ clear_n (external->solution, external->max_var + 1u);
389
+ int ch;
390
+ for (;;) {
391
+ ch = parse_char ();
392
+ if (ch == EOF)
393
+ PER ("missing 's' line");
394
+ else if (ch == 'c') {
395
+ while ((ch = parse_char ()) != '\n')
396
+ if (ch == EOF)
397
+ PER ("unexpected end-of-file in comment");
398
+ } else if (ch == 's')
399
+ break;
400
+ else
401
+ PER ("expected 'c' or 's'");
402
+ }
403
+ const char *err = parse_string (" SATISFIABLE", 's');
404
+ if (err)
405
+ return err;
406
+ if ((ch = parse_char ()) == '\r')
407
+ ch = parse_char ();
408
+ if (ch != '\n')
409
+ PER ("expected new-line after 's SATISFIABLE'");
410
+ #ifndef QUIET
411
+ int count = 0;
412
+ #endif
413
+ for (;;) {
414
+ ch = parse_char ();
415
+ if (ch != 'v')
416
+ PER ("expected 'v' at start-of-line");
417
+ if ((ch = parse_char ()) != ' ')
418
+ PER ("expected ' ' after 'v'");
419
+ int lit = 0;
420
+ ch = parse_char ();
421
+ do {
422
+ if (ch == ' ' || ch == '\t') {
423
+ ch = parse_char ();
424
+ continue;
425
+ }
426
+ err = parse_lit (ch, lit, external->max_var, false);
427
+ if (err)
428
+ return err;
429
+ if (ch == 'c')
430
+ PER ("unexpected comment");
431
+ if (!lit)
432
+ break;
433
+ if (external->solution[abs (lit)])
434
+ PER ("variable %d occurs twice", abs (lit));
435
+ LOG ("solution %d", lit);
436
+ external->solution[abs (lit)] = sign (lit);
437
+ #ifndef QUIET
438
+ count++;
439
+ #endif
440
+ if (ch == '\r')
441
+ ch = parse_char ();
442
+ } while (ch != '\n');
443
+ if (!lit)
444
+ break;
445
+ }
446
+ MSG ("parsed %d values %.2f%%", count,
447
+ percent (count, external->max_var));
448
+ return 0;
449
+ }
450
+
451
+ /*------------------------------------------------------------------------*/
452
+
453
+ // Wrappers to profile parsing and at the same time use the convenient
454
+ // implicit 'return' in PER in the non-profiled versions.
455
+
456
+ const char *Parser::parse_dimacs (int &vars, int strict) {
457
+ assert (strict == FORCED || strict == RELAXED || strict == STRICT);
458
+ START (parse);
459
+ const char *err = parse_dimacs_non_profiled (vars, strict);
460
+ STOP (parse);
461
+ return err;
462
+ }
463
+
464
+ const char *Parser::parse_solution () {
465
+ START (parse);
466
+ const char *err = parse_solution_non_profiled ();
467
+ STOP (parse);
468
+ return err;
469
+ }
470
+
471
+ } // namespace CaDiCaL
@@ -0,0 +1,75 @@
1
+ #ifndef _parse_hpp_INCLUDED
2
+ #define _parse_hpp_INCLUDED
3
+
4
+ #include <cassert>
5
+ #include <cstdint>
6
+ #include <vector>
7
+
8
+ namespace CaDiCaL {
9
+
10
+ // Factors out common functions for parsing of DIMACS and solution files.
11
+
12
+ class File;
13
+ struct External;
14
+ struct Internal;
15
+
16
+ class Parser {
17
+
18
+ Solver *solver;
19
+ Internal *internal;
20
+ External *external;
21
+ File *file;
22
+
23
+ void perr (const char *fmt, ...) CADICAL_ATTRIBUTE_FORMAT (2, 3);
24
+ int parse_char ();
25
+
26
+ enum {
27
+ FORCED = 0, // Force reading even if header is broken.
28
+ RELAXED = 1, // Relaxed white space treatment in header.
29
+ STRICT = 2, // Strict white space and header compliance.
30
+ };
31
+
32
+ const char *parse_string (const char *str, char prev);
33
+ const char *parse_positive_int (int &ch, int &res, const char *name);
34
+ const char *parse_positive_uint64_t (int &ch, uint64_t &res,
35
+ const char *name);
36
+ const char *parse_lit (int &ch, int &lit, int &vars, int strict);
37
+ const char *parse_dimacs_non_profiled (int &vars, int strict);
38
+ const char *parse_solution_non_profiled ();
39
+
40
+ bool *parse_inccnf_too;
41
+ vector<int> *cubes;
42
+
43
+ public:
44
+ // Parse a DIMACS CNF or ICNF file.
45
+ //
46
+ // Return zero if successful. Otherwise parse error.
47
+ Parser (Solver *s, File *f, bool *i, vector<int> *c)
48
+ : solver (s), internal (s->internal), external (s->external),
49
+ file (f), parse_inccnf_too (i), cubes (c) {}
50
+
51
+ // Parse a DIMACS file. Return zero if successful. Otherwise a parse
52
+ // error is return. The parsed clauses are added to the solver and the
53
+ // maximum variable index found is returned in the 'vars' argument. The
54
+ // 'strict' argument can be '0' in which case the numbers in the header
55
+ // can be arbitrary, e.g., 'p cnf 0 0' all the time, without producing a
56
+ // parse error. Only for this setting the parsed literals are not checked
57
+ // to overflow the maximum variable index of the header. The strictest
58
+ // form of parsing is enforced for the value '2' of 'strict', in which
59
+ // case the header can not have additional white space, while a value of
60
+ // '1' exactly relaxes this, e.g., 'p cnf \t 1 3 \r\n' becomes legal.
61
+ //
62
+ const char *parse_dimacs (int &vars, int strict);
63
+
64
+ // Parse a solution file as used in the SAT competition, e.g., with
65
+ // comment lines 'c ...', a status line 's ...' and value lines 'v ...'.
66
+ // Returns zero if successful. Otherwise a string is returned describing
67
+ // the parse error. The parsed solution is saved in 'solution' and can be
68
+ // accessed with 'sol (int lit)'. We use it for checking learned clauses.
69
+ //
70
+ const char *parse_solution ();
71
+ };
72
+
73
+ } // namespace CaDiCaL
74
+
75
+ #endif
@@ -0,0 +1,56 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ void Internal::copy_phases (vector<signed char> &dst) {
6
+ START (copy);
7
+ for (auto i : vars) {
8
+ const signed char tmp = phases.saved[i];
9
+ if (tmp)
10
+ dst[i] = tmp;
11
+ }
12
+ STOP (copy);
13
+ }
14
+
15
+ void Internal::save_assigned_phases (vector<signed char> &dst) {
16
+ START (copy);
17
+ for (auto i : vars) {
18
+ if (vals[i])
19
+ dst[i] = vals[i];
20
+ }
21
+ STOP (copy);
22
+ }
23
+
24
+ void Internal::clear_phases (vector<signed char> &dst) {
25
+ START (copy);
26
+ for (auto i : vars)
27
+ dst[i] = 0;
28
+ STOP (copy);
29
+ }
30
+
31
+ void Internal::phase (int lit) {
32
+ const int idx = vidx (lit);
33
+ signed char old_forced_phase = phases.forced[idx];
34
+ signed char new_forced_phase = sign (lit);
35
+ if (old_forced_phase == new_forced_phase) {
36
+ LOG ("forced phase remains at %d", old_forced_phase * idx);
37
+ return;
38
+ }
39
+ if (old_forced_phase)
40
+ LOG ("overwriting old forced phase %d", old_forced_phase * idx);
41
+ LOG ("new forced phase %d", new_forced_phase * idx);
42
+ phases.forced[idx] = new_forced_phase;
43
+ }
44
+
45
+ void Internal::unphase (int lit) {
46
+ const int idx = vidx (lit);
47
+ signed char old_forced_phase = phases.forced[idx];
48
+ if (!old_forced_phase) {
49
+ LOG ("forced phase of %d already reset", lit);
50
+ return;
51
+ }
52
+ LOG ("clearing old forced phase %d", old_forced_phase * idx);
53
+ phases.forced[idx] = 0;
54
+ }
55
+
56
+ } // namespace CaDiCaL
@@ -0,0 +1,19 @@
1
+ #ifndef _phases_hpp_INCLUDED
2
+ #define _phases_hpp_INCLUDED
3
+
4
+ #include <vector>
5
+
6
+ namespace CaDiCaL {
7
+
8
+ struct Phases {
9
+
10
+ std::vector<signed char> best; // The current largest trail phase.
11
+ std::vector<signed char> forced; // Forced through 'phase'.
12
+ std::vector<signed char> prev; // Previous during local search.
13
+ std::vector<signed char> saved; // The actual saved phase.
14
+ std::vector<signed char> target; // The current target phase.
15
+ };
16
+
17
+ } // namespace CaDiCaL
18
+
19
+ #endif