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,61 @@
1
+ #ifndef _sweep_hpp_INCLUDED
2
+ #define _sweep_hpp_INCLUDED
3
+
4
+ namespace CaDiCaL {
5
+
6
+ struct Internal;
7
+
8
+ struct sweep_proof_clause {
9
+ unsigned sweep_id; // index for sweeper.clauses
10
+ int64_t cad_id; // cadical id
11
+ unsigned kit_id; // kitten id
12
+ bool learned;
13
+ vector<int> literals;
14
+ vector<unsigned> chain; // lrat
15
+ };
16
+
17
+ struct sweep_blocked_clause {
18
+ int blit;
19
+ int64_t id;
20
+ vector<int> literals;
21
+ };
22
+
23
+ struct sweep_binary {
24
+ int lit;
25
+ int other;
26
+ int64_t id;
27
+ };
28
+
29
+ struct Sweeper {
30
+ Sweeper (Internal *internal);
31
+ ~Sweeper ();
32
+ Internal *internal;
33
+ Random random;
34
+ vector<unsigned> depths;
35
+ int *reprs;
36
+ vector<int> next, prev;
37
+ int first, last, blit;
38
+ unsigned encoded;
39
+ unsigned save;
40
+ vector<int> vars;
41
+ vector<Clause *> clauses;
42
+ vector<sweep_blocked_clause> blocked_clauses;
43
+ bool flush_blocked_clauses;
44
+ vector<int> blockable;
45
+ vector<int> clause;
46
+ vector<int> propagate;
47
+ vector<int> backbone;
48
+ vector<int> partition;
49
+ vector<bool> prev_units;
50
+ vector<sweep_binary> binaries;
51
+ vector<sweep_proof_clause> core[2];
52
+ uint64_t current_ticks;
53
+ struct {
54
+ uint64_t ticks;
55
+ unsigned clauses, depth, vars;
56
+ } limit;
57
+ };
58
+
59
+ } // namespace CaDiCaL
60
+
61
+ #endif
@@ -0,0 +1,38 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ Terminal::Terminal (FILE *f) : file (f), reset_on_exit (false) {
6
+ assert (file);
7
+ int fd = fileno (f);
8
+ assert (fd == 1 || fd == 2);
9
+ use_colors = connected = isatty (fd);
10
+ }
11
+
12
+ void Terminal::force_colors () { use_colors = connected = true; }
13
+ void Terminal::force_no_colors () { use_colors = false; }
14
+ void Terminal::force_reset_on_exit () { reset_on_exit = true; }
15
+
16
+ void Terminal::reset () {
17
+ if (!connected)
18
+ return;
19
+ erase_until_end_of_line ();
20
+ cursor (true);
21
+ normal ();
22
+ fflush (file);
23
+ }
24
+
25
+ void Terminal::disable () {
26
+ reset ();
27
+ connected = use_colors = false;
28
+ }
29
+
30
+ Terminal::~Terminal () {
31
+ if (reset_on_exit)
32
+ reset ();
33
+ }
34
+
35
+ Terminal tout (stdout);
36
+ Terminal terr (stderr);
37
+
38
+ } // namespace CaDiCaL
@@ -0,0 +1,96 @@
1
+ #ifndef _terminal_hpp_INCLUDED
2
+ #define _terminal_hpp_INCLUDED
3
+
4
+ namespace CaDiCaL {
5
+
6
+ class Terminal {
7
+
8
+ FILE *file; // 'stdout' or 'stderr'
9
+ bool connected; // Connected to terminal.
10
+ bool use_colors; // Use colors.
11
+ bool reset_on_exit; // Reset on exit.
12
+
13
+ void escape () {
14
+ assert (connected);
15
+ fputs ("\033[", file);
16
+ }
17
+
18
+ void color (int color, bool bright) {
19
+ if (!use_colors)
20
+ return;
21
+ assert (connected);
22
+ escape ();
23
+ fputc (bright ? '1' : '0', file);
24
+ fprintf (file, ";%dm", color);
25
+ fflush (file);
26
+ }
27
+
28
+ void code (const char *str) {
29
+ if (!connected)
30
+ return;
31
+ escape ();
32
+ fputs (str, file);
33
+ fflush (file);
34
+ }
35
+
36
+ public:
37
+ Terminal (FILE *file);
38
+ ~Terminal ();
39
+
40
+ void disable (); // Assume disconnected in any case.
41
+ void force_colors ();
42
+ void force_no_colors ();
43
+ void force_reset_on_exit ();
44
+
45
+ bool colors () { return use_colors; }
46
+
47
+ operator bool () const { return connected; }
48
+
49
+ void red (bool bright = false) { color (31, bright); }
50
+ void green (bool bright = false) { color (32, bright); }
51
+ void yellow (bool bright = false) { color (33, bright); }
52
+ void blue (bool bright = false) { color (34, bright); }
53
+ void magenta (bool bright = false) { color (35, bright); }
54
+ void black (bool bright = false) { color (90, bright); }
55
+ void cyan (bool bright = false) { color (96, bright); }
56
+
57
+ void bold () { code ("1m"); }
58
+ void normal () { code ("0m"); }
59
+ void inverse () { code ("7m"); }
60
+ void underline () { code ("4m"); }
61
+
62
+ #define MODIFY(CODE) (use_colors ? "\033[" CODE "m" : "")
63
+
64
+ const char *bright_magenta_code () { return MODIFY ("1;35"); }
65
+ const char *magenta_code () { return MODIFY ("0;35"); }
66
+ const char *blue_code () { return MODIFY ("0;34"); }
67
+ const char *bright_blue_code () { return MODIFY ("1;34"); }
68
+ const char *yellow_code () { return MODIFY ("0;33"); }
69
+ const char *bright_yellow_code () { return MODIFY ("1;33"); }
70
+ const char *green_code () { return MODIFY ("0;32"); }
71
+ const char *red_code () { return MODIFY ("0;31"); }
72
+ const char *cyan_code () { return MODIFY ("0;96"); }
73
+ const char *bright_red_code () { return MODIFY ("1;31"); }
74
+ const char *normal_code () { return MODIFY ("0"); }
75
+ const char *bold_code () { return MODIFY ("1"); }
76
+
77
+ void cursor (bool on) { code (on ? "?25h" : "?25l"); }
78
+
79
+ void erase_until_end_of_line () { code ("K"); }
80
+
81
+ void erase_line_if_connected_otherwise_new_line () {
82
+ if (connected)
83
+ code ("1G");
84
+ else
85
+ fputc ('\n', file), fflush (file);
86
+ }
87
+
88
+ void reset ();
89
+ };
90
+
91
+ extern Terminal tout; // Terminal of 'stdout' (file descriptor '1')
92
+ extern Terminal terr; // Terminal of 'stderr' (file descriptor '2')
93
+
94
+ } // namespace CaDiCaL
95
+
96
+ #endif
@@ -0,0 +1,450 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ /*------------------------------------------------------------------------*/
6
+
7
+ // This procedure can be used to produce all possible hyper ternary
8
+ // resolvents from ternary clauses. In contrast to hyper binary resolution
9
+ // we would only try to produce ternary clauses from ternary clauses, i.e.,
10
+ // do not consider quaternary clauses as antecedents. Of course if a binary
11
+ // clause is generated we keep it too. In any case we have to make sure
12
+ // though that we do not add clauses which are already in the formula or are
13
+ // subsumed by a binary clause in the formula. This procedure simulates
14
+ // structural hashing for multiplexer (if-then-else) and binary XOR gates in
15
+ // combination with equivalent literal substitution ('decompose') if run
16
+ // until to completion (which in the current implementation is too costly
17
+ // though and would need to be interleaved more eagerly with equivalent
18
+ // literal substitution). For more information see our CPAIOR'13 paper.
19
+
20
+ /*------------------------------------------------------------------------*/
21
+
22
+ // Check whether a binary clause consisting of the permutation of the given
23
+ // literals already exists.
24
+
25
+ bool Internal::ternary_find_binary_clause (int a, int b) {
26
+ assert (occurring ());
27
+ assert (active (a));
28
+ assert (active (b));
29
+ size_t s = occs (a).size ();
30
+ size_t t = occs (b).size ();
31
+ int lit = s < t ? a : b;
32
+ if (opts.ternaryocclim < (int) occs (lit).size ())
33
+ return true;
34
+ for (const auto &c : occs (lit)) {
35
+ if (c->size != 2)
36
+ continue;
37
+ const int *lits = c->literals;
38
+ if (lits[0] == a && lits[1] == b)
39
+ return true;
40
+ if (lits[0] == b && lits[1] == a)
41
+ return true;
42
+ }
43
+ return false;
44
+ }
45
+
46
+ /*------------------------------------------------------------------------*/
47
+
48
+ // Check whether a ternary clause consisting of the permutation of the given
49
+ // literals already exists or is subsumed by an existing binary clause.
50
+
51
+ bool Internal::ternary_find_ternary_clause (int a, int b, int c) {
52
+ assert (occurring ());
53
+ assert (active (a));
54
+ assert (active (b));
55
+ assert (active (c));
56
+ size_t r = occs (a).size ();
57
+ size_t s = occs (b).size ();
58
+ size_t t = occs (c).size ();
59
+ int lit;
60
+ if (r < s)
61
+ lit = (t < r) ? c : a;
62
+ else
63
+ lit = (t < s) ? c : b;
64
+ if (opts.ternaryocclim < (int) occs (lit).size ())
65
+ return true;
66
+ for (const auto &d : occs (lit)) {
67
+ const int *lits = d->literals;
68
+ if (d->size == 2) {
69
+ if (lits[0] == a && lits[1] == b)
70
+ return true;
71
+ if (lits[0] == b && lits[1] == a)
72
+ return true;
73
+ if (lits[0] == a && lits[1] == c)
74
+ return true;
75
+ if (lits[0] == c && lits[1] == a)
76
+ return true;
77
+ if (lits[0] == b && lits[1] == c)
78
+ return true;
79
+ if (lits[0] == c && lits[1] == b)
80
+ return true;
81
+ } else {
82
+ assert (d->size == 3);
83
+ if (lits[0] == a && lits[1] == b && lits[2] == c)
84
+ return true;
85
+ if (lits[0] == a && lits[1] == c && lits[2] == b)
86
+ return true;
87
+ if (lits[0] == b && lits[1] == a && lits[2] == c)
88
+ return true;
89
+ if (lits[0] == b && lits[1] == c && lits[2] == a)
90
+ return true;
91
+ if (lits[0] == c && lits[1] == a && lits[2] == b)
92
+ return true;
93
+ if (lits[0] == c && lits[1] == b && lits[2] == a)
94
+ return true;
95
+ }
96
+ }
97
+ return false;
98
+ }
99
+
100
+ /*------------------------------------------------------------------------*/
101
+
102
+ // Try to resolve the two ternary clauses on the given pivot (assumed to
103
+ // occur positively in the first clause, negatively in the second). If the
104
+ // resolvent has four literals, is tautological, already exists or in the
105
+ // case of a ternary resolvent is subsumed by an existing binary clause then
106
+ // 'false' is returned. The global 'clause' contains the resolvent and
107
+ // needs to be cleared in any case.
108
+
109
+ bool Internal::hyper_ternary_resolve (Clause *c, int pivot, Clause *d) {
110
+ LOG ("hyper binary resolving on pivot %d", pivot);
111
+ LOG (c, "1st antecedent");
112
+ LOG (d, "2nd antecedent");
113
+ stats.ternres++;
114
+ assert (c->size == 3);
115
+ assert (d->size == 3);
116
+ assert (clause.empty ());
117
+ for (const auto &lit : *c)
118
+ if (lit != pivot)
119
+ clause.push_back (lit);
120
+ for (const auto &lit : *d) {
121
+ if (lit == -pivot)
122
+ continue;
123
+ if (lit == clause[0])
124
+ continue;
125
+ if (lit == -clause[0])
126
+ return false;
127
+ if (lit == clause[1])
128
+ continue;
129
+ if (lit == -clause[1])
130
+ return false;
131
+ clause.push_back (lit);
132
+ }
133
+ size_t size = clause.size ();
134
+ if (size > 3)
135
+ return false;
136
+ if (size == 2 && ternary_find_binary_clause (clause[0], clause[1]))
137
+ return false;
138
+ if (size == 3 &&
139
+ ternary_find_ternary_clause (clause[0], clause[1], clause[2]))
140
+ return false;
141
+ return true;
142
+ }
143
+
144
+ /*------------------------------------------------------------------------*/
145
+
146
+ // Produce all ternary resolvents on literal 'pivot' and increment the
147
+ // 'steps' counter by the number of clauses containing 'pivot' which are
148
+ // used during this process. The reason for choosing this metric to measure
149
+ // the effort spent in 'ternary' is that it should be similar to one
150
+ // propagation step during search.
151
+
152
+ void Internal::ternary_lit (int pivot, int64_t &steps, int64_t &htrs) {
153
+ LOG ("starting hyper ternary resolutions on pivot %d", pivot);
154
+ steps -= 1 + cache_lines (occs (pivot).size (), sizeof (Clause *));
155
+ for (const auto &c : occs (pivot)) {
156
+ if (steps < 0)
157
+ break;
158
+ if (htrs < 0)
159
+ break;
160
+ if (c->garbage)
161
+ continue;
162
+ if (c->size != 3) {
163
+ assert (c->size == 2);
164
+ continue;
165
+ }
166
+ if (--steps < 0)
167
+ break;
168
+ bool assigned = false;
169
+ for (const auto &lit : *c)
170
+ if (val (lit)) {
171
+ assigned = true;
172
+ break;
173
+ }
174
+ if (assigned)
175
+ continue;
176
+ steps -= 1 + cache_lines (occs (-pivot).size (), sizeof (Clause *));
177
+ for (const auto &d : occs (-pivot)) {
178
+ if (htrs < 0)
179
+ break;
180
+ if (--steps < 0)
181
+ break;
182
+ if (d->garbage)
183
+ continue;
184
+ if (d->size != 3) {
185
+ assert (d->size == 2);
186
+ continue;
187
+ }
188
+ for (const auto &lit : *d)
189
+ if (val (lit)) {
190
+ assigned = true;
191
+ break;
192
+ }
193
+ if (assigned)
194
+ continue;
195
+ assert (clause.empty ());
196
+ htrs--;
197
+ if (hyper_ternary_resolve (c, pivot, d)) {
198
+ size_t size = clause.size ();
199
+ bool red = (size == 3 || (c->redundant && d->redundant));
200
+ if (lrat) {
201
+ assert (lrat_chain.empty ());
202
+ lrat_chain.push_back (c->id);
203
+ lrat_chain.push_back (d->id);
204
+ }
205
+ Clause *r = new_hyper_ternary_resolved_clause (red);
206
+ if (red)
207
+ r->hyper = true;
208
+ lrat_chain.clear ();
209
+ clause.clear ();
210
+ LOG (r, "hyper ternary resolved");
211
+ stats.htrs++;
212
+ for (const auto &lit : *r)
213
+ occs (lit).push_back (r);
214
+ if (size == 2) {
215
+ LOG ("hyper ternary resolvent subsumes both antecedents");
216
+ mark_garbage (c);
217
+ mark_garbage (d);
218
+ stats.htrs2++;
219
+ break;
220
+ } else {
221
+ assert (r->size == 3);
222
+ stats.htrs3++;
223
+ }
224
+ } else {
225
+ LOG (clause, "ignoring size %zd resolvent", clause.size ());
226
+ clause.clear ();
227
+ }
228
+ }
229
+ }
230
+ }
231
+
232
+ /*------------------------------------------------------------------------*/
233
+
234
+ // Same as 'ternary_lit' but pick the phase of the variable based on the
235
+ // number of positive and negative occurrence.
236
+
237
+ void Internal::ternary_idx (int idx, int64_t &steps, int64_t &htrs) {
238
+ assert (0 < idx);
239
+ assert (idx <= max_var);
240
+ steps -= 3;
241
+ if (!active (idx))
242
+ return;
243
+ if (!flags (idx).ternary)
244
+ return;
245
+ int pos = occs (idx).size ();
246
+ int neg = occs (-idx).size ();
247
+ if (pos <= opts.ternaryocclim && neg <= opts.ternaryocclim) {
248
+ LOG ("index %d has %zd positive and %zd negative occurrences", idx,
249
+ occs (idx).size (), occs (-idx).size ());
250
+ int pivot = (neg < pos ? -idx : idx);
251
+ ternary_lit (pivot, steps, htrs);
252
+ }
253
+ flags (idx).ternary = false;
254
+ }
255
+
256
+ /*------------------------------------------------------------------------*/
257
+
258
+ // One round of ternary resolution over all variables. As in 'block' and
259
+ // 'elim' we maintain a persistent global flag 'ternary' for each variable,
260
+ // which records, whether a ternary clause containing it was added. Then we
261
+ // can focus on those variables for which we have not tried ternary
262
+ // resolution before and nothing changed for them since then. This works
263
+ // across multiple calls to 'ternary' as well as 'ternary_round' since this
264
+ // 'ternary' variable flag is updated during adding (ternary) resolvents.
265
+ // This function goes over each variable just once.
266
+
267
+ bool Internal::ternary_round (int64_t &steps_limit, int64_t &htrs_limit) {
268
+
269
+ assert (!unsat);
270
+
271
+ #ifndef QUIET
272
+ int64_t bincon = 0;
273
+ int64_t terncon = 0;
274
+ #endif
275
+
276
+ init_occs ();
277
+
278
+ steps_limit -= 1 + cache_lines (clauses.size (), sizeof (Clause *));
279
+ for (const auto &c : clauses) {
280
+ steps_limit--;
281
+ if (c->garbage)
282
+ continue;
283
+ if (c->size > 3)
284
+ continue;
285
+ bool assigned = false, marked = false;
286
+ for (const auto &lit : *c) {
287
+ if (val (lit)) {
288
+ assigned = true;
289
+ break;
290
+ }
291
+ if (flags (lit).ternary)
292
+ marked = true;
293
+ }
294
+ if (assigned)
295
+ continue;
296
+ if (c->size == 2) {
297
+ #ifndef QUIET
298
+ bincon++;
299
+ #endif
300
+ } else {
301
+ assert (c->size == 3);
302
+ if (!marked)
303
+ continue;
304
+ #ifndef QUIET
305
+ terncon++;
306
+ #endif
307
+ }
308
+
309
+ for (const auto &lit : *c)
310
+ occs (lit).push_back (c);
311
+ }
312
+
313
+ PHASE ("ternary", stats.ternary,
314
+ "connected %" PRId64 " ternary %.0f%% "
315
+ "and %" PRId64 " binary clauses %.0f%%",
316
+ terncon, percent (terncon, clauses.size ()), bincon,
317
+ percent (bincon, clauses.size ()));
318
+
319
+ // Try ternary resolution on all variables once.
320
+ //
321
+ for (auto idx : vars) {
322
+ if (terminated_asynchronously ())
323
+ break;
324
+ if (steps_limit < 0)
325
+ break;
326
+ if (htrs_limit < 0)
327
+ break;
328
+ ternary_idx (idx, steps_limit, htrs_limit);
329
+ }
330
+
331
+ // Gather some statistics for the verbose messages below and also
332
+ // determine whether new variables have been marked and it would make
333
+ // sense to run another round of ternary resolution over those variables.
334
+ //
335
+ int remain = 0;
336
+ for (auto idx : vars) {
337
+ if (!active (idx))
338
+ continue;
339
+ if (!flags (idx).ternary)
340
+ continue;
341
+ remain++;
342
+ }
343
+ if (remain)
344
+ PHASE ("ternary", stats.ternary, "%d variables remain %.0f%%", remain,
345
+ percent (remain, max_var));
346
+ else
347
+ PHASE ("ternary", stats.ternary, "completed hyper ternary resolution");
348
+
349
+ reset_occs ();
350
+ assert (!unsat);
351
+
352
+ return remain; // Are there variables that should be tried again?
353
+ }
354
+
355
+ /*------------------------------------------------------------------------*/
356
+
357
+ bool Internal::ternary () {
358
+
359
+ if (!opts.ternary)
360
+ return false;
361
+ if (unsat)
362
+ return false;
363
+ if (terminated_asynchronously ())
364
+ return false;
365
+
366
+ // No new ternary clauses added since last time?
367
+ //
368
+ if (last.ternary.marked == stats.mark.ternary)
369
+ return false;
370
+
371
+ SET_EFFORT_LIMIT (limit, ternary, true);
372
+
373
+ START_SIMPLIFIER (ternary, TERNARY);
374
+ stats.ternary++;
375
+
376
+ assert (!level);
377
+
378
+ assert (!unsat);
379
+ if (watching ())
380
+ reset_watches ();
381
+
382
+ // The number of clauses derived through ternary resolution can grow
383
+ // substantially, particularly for random formulas. Thus we limit the
384
+ // number of added clauses too (actually the number of 'htrs').
385
+ //
386
+ int64_t htrs_limit = stats.current.redundant + stats.current.irredundant;
387
+ htrs_limit *= opts.ternarymaxadd;
388
+ htrs_limit /= 100;
389
+
390
+ // approximation of ternary ticks.
391
+ // TODO: count with ternary.ticks directly.
392
+ int64_t steps_limit = stats.ticks.ternary - limit;
393
+ stats.ticks.ternary = limit;
394
+
395
+ // With 'stats.ternary' we actually count the number of calls to
396
+ // 'ternary_round' and not the number of calls to 'ternary'. But before
397
+ // the first round we want to show the limit on the number of steps and
398
+ // thus we increase counter for the first round here and skip increasing
399
+ // it in the loop below.
400
+ //
401
+ PHASE ("ternary", stats.ternary,
402
+ "will run a maximum of %d rounds "
403
+ "limited to %" PRId64 " steps and %" PRId64 " clauses",
404
+ opts.ternaryrounds, steps_limit, htrs_limit);
405
+
406
+ bool resolved_binary_clause = false;
407
+ bool completed = false;
408
+
409
+ for (int round = 0;
410
+ !terminated_asynchronously () && round < opts.ternaryrounds;
411
+ round++) {
412
+ if (htrs_limit < 0)
413
+ break;
414
+ if (steps_limit < 0)
415
+ break;
416
+ if (round)
417
+ stats.ternary++;
418
+ int old_htrs2 = stats.htrs2;
419
+ int old_htrs3 = stats.htrs3;
420
+ completed = ternary_round (steps_limit, htrs_limit);
421
+ int delta_htrs2 = stats.htrs2 - old_htrs2;
422
+ int delta_htrs3 = stats.htrs3 - old_htrs3;
423
+ PHASE ("ternary", stats.ternary,
424
+ "derived %d ternary and %d binary resolvents", delta_htrs3,
425
+ delta_htrs2);
426
+ report ('3', !opts.reportall && !(delta_htrs2 + delta_htrs2));
427
+ if (delta_htrs2)
428
+ resolved_binary_clause = true;
429
+ if (!delta_htrs3)
430
+ break;
431
+ }
432
+
433
+ assert (!occurring ());
434
+ assert (!unsat);
435
+ init_watches ();
436
+ connect_watches ();
437
+ if (!propagate ()) {
438
+ LOG ("propagation after connecting watches results in inconsistency");
439
+ learn_empty_clause ();
440
+ }
441
+
442
+ if (completed)
443
+ last.ternary.marked = stats.mark.ternary;
444
+
445
+ STOP_SIMPLIFIER (ternary, TERNARY);
446
+
447
+ return resolved_binary_clause;
448
+ }
449
+
450
+ } // namespace CaDiCaL
@@ -0,0 +1,24 @@
1
+ #ifndef _testing_hpp_INCLUDED
2
+ #define _testing_hpp_INCLUDED
3
+
4
+ // This class provides access to 'internal' which should only be used for
5
+ // internal testing and not for any other purpose as 'internal' is supposed
6
+ // to be hidden.
7
+
8
+ #include "cadical.hpp"
9
+
10
+ namespace CaDiCaL {
11
+
12
+ class Testing {
13
+ Solver *solver;
14
+
15
+ public:
16
+ Testing (Solver &s) : solver (&s) {}
17
+ Testing (Solver *s) : solver (s) {}
18
+ Internal *internal () { return solver->internal; }
19
+ External *external () { return solver->external; }
20
+ };
21
+
22
+ } // namespace CaDiCaL
23
+
24
+ #endif