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,189 @@
1
+ #include "internal.hpp"
2
+ #include "util.hpp"
3
+ #include <string>
4
+
5
+ namespace CaDiCaL {
6
+
7
+ void Internal::recompute_tier () {
8
+ if (!opts.recomputetier)
9
+ return;
10
+
11
+ ++stats.tierecomputed;
12
+ const int64_t delta =
13
+ stats.tierecomputed >= 16 ? 1u << 16 : (1u << stats.tierecomputed);
14
+ lim.recompute_tier = stats.conflicts + delta;
15
+ LOG ("rescheduling in %" PRId64 " at %" PRId64 " (conflicts at %" PRId64
16
+ ")",
17
+ delta, lim.recompute_tier, stats.conflicts);
18
+ #ifndef NDEBUG
19
+ uint64_t total_used = 0;
20
+ for (auto u : stats.used[stable])
21
+ total_used += u;
22
+ assert (total_used == stats.bump_used[stable]);
23
+ #endif
24
+
25
+ if (!stats.bump_used[stable]) {
26
+ tier1[stable] = opts.reducetier1glue;
27
+ tier2[stable] = opts.reducetier2glue;
28
+ LOG ("tier1 limit = %d", tier1[stable]);
29
+ LOG ("tier2 limit = %d", tier2[stable]);
30
+ return;
31
+ } else {
32
+ uint64_t accumulated_tier1_limit =
33
+ stats.bump_used[stable] * opts.tier1limit / 100;
34
+ uint64_t accumulated_tier2_limit =
35
+ stats.bump_used[stable] * opts.tier2limit / 100;
36
+ tier1[stable] = 1;
37
+ tier2[stable] = 1;
38
+ uint64_t accumulated_used = stats.used[stable][0];
39
+ size_t glue = 1;
40
+ for (; glue < stats.used[stable].size (); ++glue) {
41
+ const uint64_t u = stats.used[stable][glue];
42
+ accumulated_used += u;
43
+ if (accumulated_used >= accumulated_tier1_limit) {
44
+ tier1[stable] = glue;
45
+ break;
46
+ }
47
+ }
48
+ for (; glue < stats.used[stable].size (); ++glue) {
49
+ const uint64_t u = stats.used[stable][glue];
50
+ accumulated_used += u;
51
+ if (accumulated_used >= accumulated_tier2_limit) {
52
+ tier2[stable] = glue;
53
+ break;
54
+ }
55
+ }
56
+ }
57
+
58
+ assert (tier1[stable] > 0);
59
+
60
+ assert (tier1[stable]);
61
+ assert (tier2[stable]);
62
+
63
+ if (tier1[stable] < opts.tier1minglue) {
64
+ LOG ("tier1 limit of %d is too low, setting %d instead", tier1[stable],
65
+ opts.tier1minglue);
66
+ tier1[stable] = opts.tier1minglue;
67
+ }
68
+ if (tier2[stable] < opts.tier2minglue) {
69
+ LOG ("tier2 limit of %d is too low, setting %d instead", tier2[stable],
70
+ opts.tier2minglue);
71
+ tier2[stable] = opts.tier2minglue;
72
+ }
73
+ if (tier1[stable] >= tier2[stable])
74
+ tier2[stable] = tier1[stable] + 1;
75
+ assert (tier2[stable] > tier1[stable]);
76
+
77
+ PHASE ("retiered", stats.tierecomputed,
78
+ "tier1 limit = %d in %s mode, tier2 limit = %d in %s mode",
79
+ tier1[stable], stable ? "stable" : "focused", tier2[stable],
80
+ stable ? "stable" : "focused");
81
+ }
82
+
83
+ void Internal::print_tier_usage_statistics () {
84
+ recompute_tier ();
85
+
86
+ for (auto stable : {false, true}) {
87
+ unsigned total_used = 0;
88
+ for (size_t glue = 0; glue < stats.used[stable].size (); ++glue)
89
+ total_used += stats.used[stable][glue];
90
+
91
+ const std::string mode = stable ? "stable" : "focused";
92
+ const size_t tier1 = internal->tier1[stable];
93
+ const size_t tier2 = internal->tier2[stable];
94
+ if (tier1 > tier2 && opts.reducetier1glue > opts.reducetier2glue) {
95
+ MSG ("tier1 > tier 2 due to the options, giving up");
96
+ break;
97
+ }
98
+ assert (tier1 <= tier2);
99
+ unsigned prefix, suffix;
100
+ unsigned span = tier2 - tier1 + 1;
101
+ const unsigned max_printed = 5;
102
+ assert (max_printed & 1), assert (max_printed / 2 > 0);
103
+ if (span > max_printed) {
104
+ prefix = tier1 + max_printed / 2 - 1;
105
+ suffix = tier2 - max_printed / 2 + 1;
106
+ } else
107
+ prefix = UINT_MAX, suffix = 0;
108
+
109
+ uint64_t accumulated_middle = 0;
110
+ int glue_digits = 1, clauses_digits = 1;
111
+ for (unsigned glue = 0; glue <= stats.used[stable].size (); glue++) {
112
+ if (glue < tier1)
113
+ continue;
114
+ uint64_t used = stats.used[stable][glue];
115
+ int tmp_glue = 0, tmp_clauses = 0;
116
+ if (glue <= prefix || suffix <= glue) {
117
+ tmp_glue = glue;
118
+ tmp_clauses = used;
119
+ } else {
120
+ accumulated_middle += used;
121
+ if (glue + 1 == suffix) {
122
+ tmp_glue = (prefix + 1) + (glue) + 1;
123
+ tmp_clauses = (accumulated_middle);
124
+ }
125
+ }
126
+ if (tmp_glue > glue_digits)
127
+ glue_digits = tmp_glue;
128
+ if (tmp_clauses > clauses_digits)
129
+ clauses_digits = tmp_clauses;
130
+ if (glue == tier2)
131
+ break;
132
+ }
133
+
134
+ accumulated_middle = 0;
135
+ uint64_t accumulated = 0;
136
+ std::string output;
137
+ for (unsigned glue = 0; glue <= stats.used[stable].size (); glue++) {
138
+ uint64_t used = stats.used[stable][glue];
139
+ accumulated += used;
140
+ if (glue < tier1)
141
+ continue;
142
+ if (glue <= prefix || suffix <= glue + 1) {
143
+ output += mode + " glue ";
144
+ }
145
+ if (glue <= prefix || suffix <= glue) {
146
+ std::string glue_str = std::to_string (glue);
147
+ output += glue_str;
148
+ output += " used " + std::to_string (used);
149
+ output +=
150
+ " clauses " +
151
+ std::to_string (percent (used, total_used)).substr (0, 5) + "%";
152
+ output += " accumulated " +
153
+ std::to_string (percent (accumulated, total_used))
154
+ .substr (0, 5) +
155
+ "%";
156
+ if (glue == tier1)
157
+ output += " tier1";
158
+ if (glue == tier2)
159
+ output += " tier2";
160
+ MSG ("%s", output.c_str ());
161
+ output.clear ();
162
+ } else {
163
+ accumulated_middle += used;
164
+ if (glue + 1 == suffix) {
165
+ std::string glue_str = std::to_string (prefix + 1) + "-" +
166
+ std::to_string (suffix - 1);
167
+ output +=
168
+ glue_str + " used " + std::to_string (accumulated_middle);
169
+ output +=
170
+ " clauses " +
171
+ std::to_string (percent (accumulated_middle, total_used))
172
+ .substr (0, 5) +
173
+ "%";
174
+ output += " accumulated " +
175
+ std::to_string (percent (accumulated, total_used))
176
+ .substr (0, 5) +
177
+ "%";
178
+ MSG ("%s", output.c_str ());
179
+ output.clear ();
180
+ }
181
+ }
182
+ if (glue == tier2)
183
+ break;
184
+ }
185
+
186
+ LINE ();
187
+ }
188
+ }
189
+ } // namespace CaDiCaL
@@ -0,0 +1,186 @@
1
+ #ifndef _tracer_hpp_INCLUDED
2
+ #define _tracer_hpp_INCLUDED
3
+
4
+ #include <cstdint>
5
+ #include <vector>
6
+
7
+ namespace CaDiCaL {
8
+
9
+ struct Internal;
10
+
11
+ enum ConclusionType { CONFLICT = 1, ASSUMPTIONS = 2, CONSTRAINT = 4 };
12
+
13
+ // Proof tracer class to observer all possible proof events,
14
+ // such as added or deleted clauses.
15
+ // An implementation can decide on which events to act.
16
+ //
17
+ class Tracer {
18
+
19
+ public:
20
+ Tracer () {}
21
+ virtual ~Tracer () {}
22
+
23
+ /*------------------------------------------------------------------------*/
24
+ /* */
25
+ /* Basic Events */
26
+ /* */
27
+ /*------------------------------------------------------------------------*/
28
+
29
+ // Notify the tracer that a original clause has been added.
30
+ // Includes ID and whether the clause is redundant or irredundant
31
+ // Arguments: ID, redundant, clause, restored
32
+ //
33
+ virtual void add_original_clause (int64_t, bool, const std::vector<int> &,
34
+ bool = false) {}
35
+
36
+ // Notify the observer that a new clause has been derived.
37
+ // Includes ID and whether the clause is redundant or irredundant
38
+ // If antecedents are derived they will be included here.
39
+ // If witness != 0 it is a RAT clause.
40
+ // Arguments: ID, redundant, clause, witness, antecedents
41
+ //
42
+ virtual void add_derived_clause (int64_t, bool, int,
43
+ const std::vector<int> &,
44
+ const std::vector<int64_t> &) {}
45
+
46
+ // Notify the observer that a clause is deleted.
47
+ // Includes ID and redundant/irredundant
48
+ // Arguments: ID, redundant, clause
49
+ //
50
+ virtual void delete_clause (int64_t, bool, const std::vector<int> &) {}
51
+
52
+ // Notify the observer that a clause is deleted.
53
+ // Includes ID and redundant/irredundant
54
+ // Arguments: ID, redundant, clause
55
+ //
56
+ virtual void demote_clause (uint64_t, const std::vector<int> &) {}
57
+
58
+ // Notify the observer to remember that the clause might be restored later
59
+ // Arguments: ID, clause
60
+ //
61
+ virtual void weaken_minus (int64_t, const std::vector<int> &) {}
62
+
63
+ // Notify the observer that a clause is strengthened
64
+ // Arguments: ID
65
+ //
66
+ virtual void strengthen (int64_t) {}
67
+
68
+ // Notify the observer that the solve call ends with status StatusType
69
+ // If the status is UNSAT and an empty clause has been derived, the second
70
+ // argument will contain its id.
71
+ // Note that the empty clause is already added through add_derived_clause
72
+ // and finalized with finalize_clause
73
+ // Arguments: int, ID
74
+ //
75
+ virtual void report_status (int, int64_t) {}
76
+
77
+ /*------------------------------------------------------------------------*/
78
+ /* */
79
+ /* Specifically non-incremental */
80
+ /* */
81
+ /*------------------------------------------------------------------------*/
82
+
83
+ // Notify the observer that a clause is finalized.
84
+ // Arguments: ID, clause
85
+ //
86
+ virtual void finalize_clause (int64_t, const std::vector<int> &) {}
87
+
88
+ // Notify the observer that the proof begins with a set of reserved ids
89
+ // for original clauses. Given ID is the first derived clause ID.
90
+ // Arguments: ID
91
+ //
92
+ virtual void begin_proof (int64_t) {}
93
+
94
+ /*------------------------------------------------------------------------*/
95
+ /* */
96
+ /* Specifically incremental */
97
+ /* */
98
+ /*------------------------------------------------------------------------*/
99
+
100
+ // Notify the observer that an assumption has been added
101
+ // Arguments: assumption_literal
102
+ //
103
+ virtual void solve_query () {}
104
+
105
+ // Notify the observer that an assumption has been added
106
+ // Arguments: assumption_literal
107
+ //
108
+ virtual void add_assumption (int) {}
109
+
110
+ // Notify the observer that a constraint has been added
111
+ // Arguments: constraint_clause
112
+ //
113
+ virtual void add_constraint (const std::vector<int> &) {}
114
+
115
+ // Notify the observer that assumptions and constraints are reset
116
+ //
117
+ virtual void reset_assumptions () {}
118
+
119
+ // Notify the observer that this clause could be derived, which
120
+ // is the negation of a core of failing assumptions/constraints.
121
+ // If antecedents are derived they will be included here.
122
+ // Arguments: ID, clause, antecedents
123
+ //
124
+ virtual void add_assumption_clause (int64_t, const std::vector<int> &,
125
+ const std::vector<int64_t> &) {}
126
+
127
+ // Notify the observer that conclude unsat was requested.
128
+ // will give either the id of the empty clause, the id of a failing
129
+ // assumption clause or the ids of the failing constrain clauses
130
+ // Arguments: conclusion_type, clause_ids
131
+ //
132
+ virtual void conclude_unsat (ConclusionType,
133
+ const std::vector<int64_t> &) {}
134
+
135
+ // Notify the observer that conclude sat was requested.
136
+ // will give the complete model as a vector.
137
+ //
138
+ virtual void conclude_sat (const std::vector<int> &) {}
139
+
140
+ // Notify the observer that conclude unknown was requested.
141
+ // will give the current trail as a vector.
142
+ //
143
+ virtual void conclude_unknown (const std::vector<int> &) {}
144
+
145
+ // Notify the observer that two literals are equivalent
146
+ //
147
+ // You receive literals, not variables. You can also get notified
148
+ // multiple times. You can also get notified of BVA variables, aka
149
+ // variables you did not declare.
150
+ virtual void notify_equivalence (int, int) {}
151
+ };
152
+
153
+ /*--------------------------------------------------------------------------*/
154
+
155
+ // Following tracers for internal use.
156
+
157
+ struct InternalTracer : public Tracer {
158
+ public:
159
+ InternalTracer () {}
160
+ virtual ~InternalTracer () {}
161
+
162
+ virtual void connect_internal (Internal *) {}
163
+ };
164
+
165
+ class StatTracer : public InternalTracer {
166
+ public:
167
+ StatTracer () {}
168
+ virtual ~StatTracer () {}
169
+
170
+ virtual void print_stats () {}
171
+ };
172
+
173
+ class FileTracer : public InternalTracer {
174
+
175
+ public:
176
+ FileTracer () {}
177
+ virtual ~FileTracer () {}
178
+
179
+ virtual bool closed () = 0;
180
+ virtual void close (bool print = false) = 0;
181
+ virtual void flush (bool print = false) = 0;
182
+ };
183
+
184
+ } // namespace CaDiCaL
185
+
186
+ #endif
@@ -0,0 +1,253 @@
1
+ #include "internal.hpp"
2
+
3
+ namespace CaDiCaL {
4
+
5
+ // Implement transitive reduction in the binary implication graph. This is
6
+ // important for hyper binary resolution, which has the risk to produce too
7
+ // many hyper binary resolvents otherwise. This algorithm only works on
8
+ // binary clauses and is usually pretty fast. It will also find some failed
9
+ // literals (in the binary implication graph).
10
+
11
+ void Internal::transred () {
12
+ if (!opts.transred)
13
+ return;
14
+ if (unsat)
15
+ return;
16
+ if (terminated_asynchronously ())
17
+ return;
18
+ if (!stats.current.redundant && !stats.current.irredundant)
19
+ return;
20
+
21
+ assert (opts.transred);
22
+ assert (!level);
23
+
24
+ START_SIMPLIFIER (transred, TRANSRED);
25
+ stats.transreds++;
26
+
27
+ // Transitive reduction can not be run to completion for larger formulas
28
+ // with many binary clauses. We bound it in the same way as 'probe_core'.
29
+ //
30
+ int64_t limit = stats.propagations.search;
31
+ limit -= last.transred.propagations;
32
+ limit *= 1e-3 * opts.transredeffort;
33
+ if (limit < opts.transredmineff)
34
+ limit = opts.transredmineff;
35
+ if (limit > opts.transredmaxeff)
36
+ limit = opts.transredmaxeff;
37
+
38
+ PHASE ("transred", stats.transreds,
39
+ "transitive reduction limit of %" PRId64 " propagations", limit);
40
+
41
+ const auto end = clauses.end ();
42
+ auto i = clauses.begin ();
43
+
44
+ // Find first clause not checked for being transitive yet.
45
+ //
46
+ for (; i != end; i++) {
47
+ Clause *c = *i;
48
+ if (c->garbage)
49
+ continue;
50
+ if (c->size != 2)
51
+ continue;
52
+ if (c->redundant && c->hyper)
53
+ continue;
54
+ if (!c->transred)
55
+ break;
56
+ }
57
+
58
+ // If all candidate clauses have been checked reschedule all.
59
+ //
60
+ if (i == end) {
61
+
62
+ PHASE ("transred", stats.transreds,
63
+ "rescheduling all clauses since no clauses to check left");
64
+ for (i = clauses.begin (); i != end; i++) {
65
+ Clause *c = *i;
66
+ if (c->transred)
67
+ c->transred = false;
68
+ }
69
+ i = clauses.begin ();
70
+ }
71
+
72
+ // Move watches of binary clauses to the front. Thus we can stop iterating
73
+ // watches as soon a long clause is found during watch traversal.
74
+ //
75
+ sort_watches ();
76
+
77
+ // This working stack plays the same role as the 'trail' during standard
78
+ // propagation.
79
+ //
80
+ vector<int> work;
81
+
82
+ int64_t propagations = 0, units = 0, removed = 0;
83
+
84
+ while (!unsat && i != end && !terminated_asynchronously () &&
85
+ propagations < limit) {
86
+ Clause *c = *i++;
87
+
88
+ // A clause is a candidate for being transitive if it is binary, and not
89
+ // the result of hyper binary resolution. The reason for excluding
90
+ // those, is that they come in large numbers, most of them are reduced
91
+ // away anyhow and further are non-transitive at the point they are
92
+ // added (see the code in 'hyper_binary_resolve' in 'prope.cpp' and
93
+ // also check out our CPAIOR paper on tree-based look ahead).
94
+ //
95
+ if (c->garbage)
96
+ continue;
97
+ if (c->size != 2)
98
+ continue;
99
+ if (c->redundant && c->hyper)
100
+ continue;
101
+ if (c->transred)
102
+ continue; // checked before?
103
+ c->transred = true; // marked as checked
104
+
105
+ LOG (c, "checking transitive reduction of");
106
+
107
+ // Find a different path from 'src' to 'dst' in the binary implication
108
+ // graph, not using 'c'. Since this is the same as checking whether
109
+ // there is a path from '-dst' to '-src', we can do the reverse search
110
+ // if the number of watches of '-dst' is larger than those of 'src'.
111
+ //
112
+ int src = -c->literals[0];
113
+ int dst = c->literals[1];
114
+ if (val (src) || val (dst))
115
+ continue;
116
+ if (watches (-src).size () < watches (dst).size ()) {
117
+ int tmp = dst;
118
+ dst = -src;
119
+ src = -tmp;
120
+ }
121
+
122
+ LOG ("searching path from %d to %d", src, dst);
123
+
124
+ // If the candidate clause is irredundant then we can not use redundant
125
+ // binary clauses in the implication graph. See our inprocessing rules
126
+ // paper, why this restriction is required.
127
+ //
128
+ const bool irredundant = !c->redundant;
129
+
130
+ assert (work.empty ());
131
+ mark (src);
132
+ work.push_back (src);
133
+ LOG ("transred assign %d", src);
134
+
135
+ bool transitive = false; // found path from 'src' to 'dst'?
136
+ bool failed = false; // 'src' failed literal?
137
+
138
+ size_t j = 0; // 'propagated' in BFS
139
+
140
+ assert (lrat_chain.empty ());
141
+ assert (mini_chain.empty ());
142
+ vector<int> parents;
143
+
144
+ while (!transitive && !failed && j < work.size ()) {
145
+ const int lit = work[j++];
146
+ assert (marked (lit) > 0);
147
+ LOG ("transred propagating %d", lit);
148
+ propagations++;
149
+ const Watches &ws = watches (-lit);
150
+ const const_watch_iterator eow = ws.end ();
151
+ const_watch_iterator k;
152
+ for (k = ws.begin (); !transitive && !failed && k != eow; k++) {
153
+ const Watch &w = *k;
154
+ if (!w.binary ())
155
+ break; // since we sorted watches above
156
+ Clause *d = w.clause;
157
+ if (d == c)
158
+ continue;
159
+ if (irredundant && d->redundant)
160
+ continue;
161
+ if (d->garbage)
162
+ continue;
163
+ const int other = w.blit;
164
+ if (other == dst)
165
+ transitive = true; // 'dst' reached
166
+ else {
167
+ const int tmp = marked (other);
168
+ if (tmp > 0)
169
+ continue;
170
+ else if (tmp < 0) {
171
+ if (lrat) {
172
+ parents.push_back (lit);
173
+ mini_chain.push_back (d->id);
174
+ work.push_back (other);
175
+ }
176
+ LOG ("found both %d and %d reachable", -other, other);
177
+ failed = true;
178
+ } else {
179
+ if (lrat) {
180
+ parents.push_back (lit);
181
+ mini_chain.push_back (d->id);
182
+ }
183
+ mark (other);
184
+ work.push_back (other);
185
+ LOG ("transred assign %d", other);
186
+ }
187
+ }
188
+ }
189
+ }
190
+
191
+ int failed_lit = work.back ();
192
+ int next_pos = 0;
193
+ int next_neg = 0;
194
+
195
+ // Unassign all assigned literals (same as '[bp]acktrack').
196
+ //
197
+ while (!work.empty ()) {
198
+ const int lit = work.back ();
199
+ work.pop_back ();
200
+ if (lrat && failed && !work.empty ()) {
201
+ assert (!parents.empty () && !mini_chain.empty ());
202
+ LOG ("transred LRAT current lit %d next pos %d next neg %d", lit,
203
+ next_pos, next_neg);
204
+ if (lit == failed_lit || lit == next_pos) {
205
+ lrat_chain.push_back (mini_chain.back ());
206
+ next_pos = parents.back ();
207
+ } else if (lit == -failed_lit || lit == next_neg) {
208
+ lrat_chain.push_back (mini_chain.back ());
209
+ next_neg = parents.back ();
210
+ }
211
+ parents.pop_back ();
212
+ mini_chain.pop_back ();
213
+ }
214
+ unmark (lit);
215
+ }
216
+ mini_chain.clear ();
217
+ assert (mini_chain.empty ());
218
+ if (lrat && failed) {
219
+ reverse (lrat_chain.begin (), lrat_chain.end ());
220
+ }
221
+
222
+ if (transitive) {
223
+ removed++;
224
+ stats.transitive++;
225
+ LOG (c, "transitive redundant");
226
+ mark_garbage (c);
227
+ } else if (failed) {
228
+ units++;
229
+ LOG ("found failed literal %d during transitive reduction", src);
230
+ stats.failed++;
231
+ stats.transredunits++;
232
+ assign_unit (-src);
233
+ if (!propagate ()) {
234
+ VERBOSE (1, "propagating new unit results in conflict");
235
+ learn_empty_clause ();
236
+ }
237
+ }
238
+ lrat_chain.clear ();
239
+ }
240
+
241
+ last.transred.propagations = stats.propagations.search;
242
+ stats.propagations.transred += propagations;
243
+ erase_vector (work);
244
+
245
+ PHASE ("transred", stats.transreds,
246
+ "removed %" PRId64 " transitive clauses, found %" PRId64 " units",
247
+ removed, units);
248
+
249
+ STOP_SIMPLIFIER (transred, TRANSRED);
250
+ report ('t', !opts.reportall && !(removed + units));
251
+ }
252
+
253
+ } // namespace CaDiCaL
@@ -0,0 +1,29 @@
1
+ #ifdef PROFILE_MODE
2
+ #include "internal.hpp"
3
+
4
+ namespace CaDiCaL {
5
+
6
+ bool Internal::propagate_unstable () {
7
+ assert (!stable);
8
+ START (propunstable);
9
+ bool res = propagate ();
10
+ STOP (propunstable);
11
+ return res;
12
+ }
13
+
14
+ void Internal::analyze_unstable () {
15
+ assert (!stable);
16
+ START (analyzeunstable);
17
+ analyze ();
18
+ STOP (analyzeunstable);
19
+ }
20
+
21
+ int Internal::decide_unstable () {
22
+ assert (!stable);
23
+ return decide ();
24
+ }
25
+
26
+ }; // namespace CaDiCaL
27
+ #else
28
+ int unstable_if_no_profile_mode;
29
+ #endif