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.
- checksums.yaml +7 -0
- data/LICENSE.txt +26 -0
- data/README.md +101 -0
- data/ext/cadical/cadical/LICENSE +28 -0
- data/ext/cadical/cadical/README.md +65 -0
- data/ext/cadical/cadical/VERSION +1 -0
- data/ext/cadical/cadical/src/analyze.cpp +1360 -0
- data/ext/cadical/cadical/src/arena.cpp +30 -0
- data/ext/cadical/cadical/src/arena.hpp +105 -0
- data/ext/cadical/cadical/src/assume.cpp +616 -0
- data/ext/cadical/cadical/src/averages.cpp +34 -0
- data/ext/cadical/cadical/src/averages.hpp +37 -0
- data/ext/cadical/cadical/src/backbone.cpp +631 -0
- data/ext/cadical/cadical/src/backtrack.cpp +177 -0
- data/ext/cadical/cadical/src/backward.cpp +231 -0
- data/ext/cadical/cadical/src/bins.cpp +22 -0
- data/ext/cadical/cadical/src/bins.hpp +22 -0
- data/ext/cadical/cadical/src/block.cpp +824 -0
- data/ext/cadical/cadical/src/block.hpp +37 -0
- data/ext/cadical/cadical/src/cadical.cpp +1026 -0
- data/ext/cadical/cadical/src/cadical.hpp +1419 -0
- data/ext/cadical/cadical/src/ccadical.cpp +208 -0
- data/ext/cadical/cadical/src/ccadical.h +74 -0
- data/ext/cadical/cadical/src/checker.cpp +649 -0
- data/ext/cadical/cadical/src/checker.hpp +173 -0
- data/ext/cadical/cadical/src/clause.cpp +689 -0
- data/ext/cadical/cadical/src/clause.hpp +190 -0
- data/ext/cadical/cadical/src/collect.cpp +545 -0
- data/ext/cadical/cadical/src/compact.cpp +550 -0
- data/ext/cadical/cadical/src/condition.cpp +940 -0
- data/ext/cadical/cadical/src/config.cpp +101 -0
- data/ext/cadical/cadical/src/config.hpp +20 -0
- data/ext/cadical/cadical/src/congruence.cpp +7880 -0
- data/ext/cadical/cadical/src/congruence.hpp +757 -0
- data/ext/cadical/cadical/src/constrain.cpp +64 -0
- data/ext/cadical/cadical/src/contract.cpp +27 -0
- data/ext/cadical/cadical/src/contract.hpp +139 -0
- data/ext/cadical/cadical/src/cover.cpp +704 -0
- data/ext/cadical/cadical/src/cover.hpp +34 -0
- data/ext/cadical/cadical/src/decide.cpp +347 -0
- data/ext/cadical/cadical/src/decompose.cpp +738 -0
- data/ext/cadical/cadical/src/decompose.hpp +23 -0
- data/ext/cadical/cadical/src/deduplicate.cpp +275 -0
- data/ext/cadical/cadical/src/definition.cpp +283 -0
- data/ext/cadical/cadical/src/delay.hpp +38 -0
- data/ext/cadical/cadical/src/drattracer.cpp +153 -0
- data/ext/cadical/cadical/src/drattracer.hpp +55 -0
- data/ext/cadical/cadical/src/elim.cpp +1171 -0
- data/ext/cadical/cadical/src/elim.hpp +53 -0
- data/ext/cadical/cadical/src/elimfast.cpp +570 -0
- data/ext/cadical/cadical/src/ema.cpp +95 -0
- data/ext/cadical/cadical/src/ema.hpp +68 -0
- data/ext/cadical/cadical/src/extend.cpp +289 -0
- data/ext/cadical/cadical/src/external.cpp +1034 -0
- data/ext/cadical/cadical/src/external.hpp +487 -0
- data/ext/cadical/cadical/src/external_propagate.cpp +1316 -0
- data/ext/cadical/cadical/src/factor.cpp +1011 -0
- data/ext/cadical/cadical/src/factor.hpp +54 -0
- data/ext/cadical/cadical/src/file.cpp +506 -0
- data/ext/cadical/cadical/src/file.hpp +210 -0
- data/ext/cadical/cadical/src/flags.cpp +135 -0
- data/ext/cadical/cadical/src/flags.hpp +93 -0
- data/ext/cadical/cadical/src/flip.cpp +269 -0
- data/ext/cadical/cadical/src/format.cpp +89 -0
- data/ext/cadical/cadical/src/format.hpp +36 -0
- data/ext/cadical/cadical/src/frattracer.cpp +277 -0
- data/ext/cadical/cadical/src/frattracer.hpp +67 -0
- data/ext/cadical/cadical/src/gates.cpp +766 -0
- data/ext/cadical/cadical/src/heap.hpp +212 -0
- data/ext/cadical/cadical/src/idruptracer.cpp +566 -0
- data/ext/cadical/cadical/src/idruptracer.hpp +112 -0
- data/ext/cadical/cadical/src/instantiate.cpp +365 -0
- data/ext/cadical/cadical/src/instantiate.hpp +45 -0
- data/ext/cadical/cadical/src/internal.cpp +1265 -0
- data/ext/cadical/cadical/src/internal.hpp +1941 -0
- data/ext/cadical/cadical/src/inttypes.hpp +34 -0
- data/ext/cadical/cadical/src/ipasir.cpp +47 -0
- data/ext/cadical/cadical/src/ipasir.h +37 -0
- data/ext/cadical/cadical/src/kitten.c +2599 -0
- data/ext/cadical/cadical/src/kitten.h +97 -0
- data/ext/cadical/cadical/src/level.hpp +33 -0
- data/ext/cadical/cadical/src/lidruptracer.cpp +657 -0
- data/ext/cadical/cadical/src/lidruptracer.hpp +122 -0
- data/ext/cadical/cadical/src/limit.cpp +146 -0
- data/ext/cadical/cadical/src/limit.hpp +168 -0
- data/ext/cadical/cadical/src/logging.cpp +214 -0
- data/ext/cadical/cadical/src/logging.hpp +98 -0
- data/ext/cadical/cadical/src/lookahead.cpp +520 -0
- data/ext/cadical/cadical/src/lratchecker.cpp +833 -0
- data/ext/cadical/cadical/src/lratchecker.hpp +168 -0
- data/ext/cadical/cadical/src/lrattracer.cpp +200 -0
- data/ext/cadical/cadical/src/lrattracer.hpp +61 -0
- data/ext/cadical/cadical/src/lucky.cpp +506 -0
- data/ext/cadical/cadical/src/message.cpp +218 -0
- data/ext/cadical/cadical/src/message.hpp +65 -0
- data/ext/cadical/cadical/src/minimize.cpp +224 -0
- data/ext/cadical/cadical/src/mobical.cpp +5588 -0
- data/ext/cadical/cadical/src/occs.cpp +52 -0
- data/ext/cadical/cadical/src/occs.hpp +36 -0
- data/ext/cadical/cadical/src/options.cpp +359 -0
- data/ext/cadical/cadical/src/options.hpp +442 -0
- data/ext/cadical/cadical/src/parse.cpp +471 -0
- data/ext/cadical/cadical/src/parse.hpp +75 -0
- data/ext/cadical/cadical/src/phases.cpp +56 -0
- data/ext/cadical/cadical/src/phases.hpp +19 -0
- data/ext/cadical/cadical/src/probe.cpp +990 -0
- data/ext/cadical/cadical/src/profile.cpp +107 -0
- data/ext/cadical/cadical/src/profile.hpp +283 -0
- data/ext/cadical/cadical/src/proof.cpp +691 -0
- data/ext/cadical/cadical/src/proof.hpp +125 -0
- data/ext/cadical/cadical/src/propagate.cpp +584 -0
- data/ext/cadical/cadical/src/queue.cpp +90 -0
- data/ext/cadical/cadical/src/queue.hpp +74 -0
- data/ext/cadical/cadical/src/radix.hpp +180 -0
- data/ext/cadical/cadical/src/random.cpp +207 -0
- data/ext/cadical/cadical/src/random.h +44 -0
- data/ext/cadical/cadical/src/random.hpp +98 -0
- data/ext/cadical/cadical/src/range.hpp +125 -0
- data/ext/cadical/cadical/src/reap.cpp +127 -0
- data/ext/cadical/cadical/src/reap.hpp +28 -0
- data/ext/cadical/cadical/src/reduce.cpp +278 -0
- data/ext/cadical/cadical/src/reluctant.hpp +82 -0
- data/ext/cadical/cadical/src/rephase.cpp +402 -0
- data/ext/cadical/cadical/src/report.cpp +313 -0
- data/ext/cadical/cadical/src/resources.cpp +160 -0
- data/ext/cadical/cadical/src/resources.hpp +16 -0
- data/ext/cadical/cadical/src/restart.cpp +178 -0
- data/ext/cadical/cadical/src/restore.cpp +267 -0
- data/ext/cadical/cadical/src/score.cpp +51 -0
- data/ext/cadical/cadical/src/score.hpp +16 -0
- data/ext/cadical/cadical/src/shrink.cpp +507 -0
- data/ext/cadical/cadical/src/signal.cpp +136 -0
- data/ext/cadical/cadical/src/signal.hpp +33 -0
- data/ext/cadical/cadical/src/solution.cpp +50 -0
- data/ext/cadical/cadical/src/solver.cpp +1871 -0
- data/ext/cadical/cadical/src/stable.cpp +31 -0
- data/ext/cadical/cadical/src/stack.h +110 -0
- data/ext/cadical/cadical/src/stats.cpp +920 -0
- data/ext/cadical/cadical/src/stats.hpp +418 -0
- data/ext/cadical/cadical/src/subsume.cpp +645 -0
- data/ext/cadical/cadical/src/sweep.cpp +1960 -0
- data/ext/cadical/cadical/src/sweep.hpp +61 -0
- data/ext/cadical/cadical/src/terminal.cpp +38 -0
- data/ext/cadical/cadical/src/terminal.hpp +96 -0
- data/ext/cadical/cadical/src/ternary.cpp +450 -0
- data/ext/cadical/cadical/src/testing.hpp +24 -0
- data/ext/cadical/cadical/src/tier.cpp +189 -0
- data/ext/cadical/cadical/src/tracer.hpp +186 -0
- data/ext/cadical/cadical/src/transred.cpp +253 -0
- data/ext/cadical/cadical/src/unstable.cpp +29 -0
- data/ext/cadical/cadical/src/util.cpp +129 -0
- data/ext/cadical/cadical/src/util.hpp +181 -0
- data/ext/cadical/cadical/src/var.cpp +39 -0
- data/ext/cadical/cadical/src/var.hpp +22 -0
- data/ext/cadical/cadical/src/veripbtracer.cpp +427 -0
- data/ext/cadical/cadical/src/veripbtracer.hpp +106 -0
- data/ext/cadical/cadical/src/version.cpp +107 -0
- data/ext/cadical/cadical/src/version.hpp +13 -0
- data/ext/cadical/cadical/src/vivify.cpp +1893 -0
- data/ext/cadical/cadical/src/vivify.hpp +50 -0
- data/ext/cadical/cadical/src/walk.cpp +1088 -0
- data/ext/cadical/cadical/src/walk.hpp +91 -0
- data/ext/cadical/cadical/src/walk_full_occs.cpp +966 -0
- data/ext/cadical/cadical/src/warmup.cpp +403 -0
- data/ext/cadical/cadical/src/watch.cpp +126 -0
- data/ext/cadical/cadical/src/watch.hpp +77 -0
- data/ext/cadical/cadical_ext.c +778 -0
- data/ext/cadical/extconf.rb +26 -0
- data/lib/cadical/version.rb +3 -0
- data/lib/cadical.rb +12 -0
- metadata +218 -0
|
@@ -0,0 +1,757 @@
|
|
|
1
|
+
#ifndef _congruenc_hpp_INCLUDED
|
|
2
|
+
#define _congruenc_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
#include <array>
|
|
6
|
+
#include <cassert>
|
|
7
|
+
#include <cstddef>
|
|
8
|
+
#include <cstdint>
|
|
9
|
+
#include <queue>
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <sys/types.h>
|
|
12
|
+
#include <unordered_set>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
#include "clause.hpp"
|
|
16
|
+
#include "inttypes.hpp"
|
|
17
|
+
#include "util.hpp"
|
|
18
|
+
#include "watch.hpp"
|
|
19
|
+
|
|
20
|
+
namespace CaDiCaL {
|
|
21
|
+
|
|
22
|
+
typedef int64_t LRAT_ID;
|
|
23
|
+
|
|
24
|
+
// This implements the algorithm algorithm from SAT 2024.
|
|
25
|
+
//
|
|
26
|
+
// The idea is to:
|
|
27
|
+
// 0. handle binary clauses
|
|
28
|
+
// 1. detect gates and merge gates with same inputs ('lazy')
|
|
29
|
+
// 2. eagerly replace the equivalent literals and merge gates with same
|
|
30
|
+
// inputs
|
|
31
|
+
// 3. forward subsume
|
|
32
|
+
//
|
|
33
|
+
// In step 0 the normalization is fully lazy but we do not care about a
|
|
34
|
+
// normal form. Therefore we actually eagerly merge literals.
|
|
35
|
+
//
|
|
36
|
+
// In step 2 there is a subtility: we only replace with the equivalence
|
|
37
|
+
// chain as far as we propagated so far. This is the eager part. For LRAT we
|
|
38
|
+
// produce the equivalence up to the point we have propagated, no the full
|
|
39
|
+
// chain. This is important for merging literals. To merge literals we use
|
|
40
|
+
// union-find but we only compress paths when rewriting the literal, not
|
|
41
|
+
// before. The compression was not considered important in Kissat, but we do
|
|
42
|
+
// it aggressively as a mirror of the equivalences we have generated.
|
|
43
|
+
//
|
|
44
|
+
// We have two structures for merging:
|
|
45
|
+
// - the lazy ones contains alls merges, with functions like
|
|
46
|
+
// find_representative
|
|
47
|
+
//
|
|
48
|
+
// - the eager version that gets the merges one by one, with functions
|
|
49
|
+
// like find_eager_representatives
|
|
50
|
+
//
|
|
51
|
+
// The two structures are nicely separated and we only working on one of
|
|
52
|
+
// them except for:
|
|
53
|
+
//
|
|
54
|
+
// 1. When propagating one equivalence, we first important the
|
|
55
|
+
// equivalence from the lazy to the eager version, producing the full
|
|
56
|
+
// chain.
|
|
57
|
+
//
|
|
58
|
+
// 2. When merging the literals, we merge the literals given by the lazy
|
|
59
|
+
// structure, then we merge their representative in the eager version,
|
|
60
|
+
// updating only the lazy structure. We do not update the eager version.
|
|
61
|
+
//
|
|
62
|
+
// An important point: We cannot use internal->lrat_chain and
|
|
63
|
+
// internal->clause because in most places we can interrupt the
|
|
64
|
+
// transformation to learn a new clause representing an equivalence.
|
|
65
|
+
// However, we can only have 2 layers so we use this->lrat_chain and
|
|
66
|
+
// internal->lrat_chain when we really produce the proof.
|
|
67
|
+
struct Internal;
|
|
68
|
+
|
|
69
|
+
#define LD_MAX_ARITY 26
|
|
70
|
+
#define MAX_ARITY ((1 << LD_MAX_ARITY) - 1)
|
|
71
|
+
|
|
72
|
+
enum class Gate_Type : int8_t { And_Gate, XOr_Gate, ITE_Gate };
|
|
73
|
+
|
|
74
|
+
// Wrapper when we are looking for implication in if-then-else gates
|
|
75
|
+
struct lit_implication {
|
|
76
|
+
int first;
|
|
77
|
+
int second;
|
|
78
|
+
Clause *clause;
|
|
79
|
+
lit_implication (int f, int s, Clause *_id)
|
|
80
|
+
: first (f), second (s), clause (_id) {}
|
|
81
|
+
lit_implication (int f, int s) : first (f), second (s), clause (0) {}
|
|
82
|
+
lit_implication () : first (0), second (0), clause (nullptr) {}
|
|
83
|
+
void swap () { std::swap (first, second); }
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Wrapper when we are looking for equivalence for if-then-else-gate. They
|
|
87
|
+
// are produced by merging implication
|
|
88
|
+
struct lit_equivalence {
|
|
89
|
+
int first;
|
|
90
|
+
int second;
|
|
91
|
+
Clause *first_clause;
|
|
92
|
+
Clause *second_clause;
|
|
93
|
+
void check_invariant () const {
|
|
94
|
+
assert (second_clause);
|
|
95
|
+
assert (first_clause);
|
|
96
|
+
assert (std::find (begin (*first_clause), end (*first_clause), first) !=
|
|
97
|
+
end (*first_clause));
|
|
98
|
+
assert (std::find (begin (*second_clause), end (*second_clause),
|
|
99
|
+
second) != end (*second_clause));
|
|
100
|
+
assert (std::find (begin (*first_clause), end (*first_clause),
|
|
101
|
+
-second) != end (*first_clause));
|
|
102
|
+
assert (std::find (begin (*second_clause), end (*second_clause),
|
|
103
|
+
-first) != end (*second_clause));
|
|
104
|
+
}
|
|
105
|
+
lit_equivalence (int f, Clause *f_id, int s, Clause *s_id)
|
|
106
|
+
: first (f), second (s), first_clause (f_id), second_clause (s_id) {}
|
|
107
|
+
lit_equivalence (int f, int s)
|
|
108
|
+
: first (f), second (s), first_clause (nullptr),
|
|
109
|
+
second_clause (nullptr) {}
|
|
110
|
+
lit_equivalence ()
|
|
111
|
+
: first (0), second (0), first_clause (nullptr),
|
|
112
|
+
second_clause (nullptr) {}
|
|
113
|
+
lit_equivalence swap () {
|
|
114
|
+
std::swap (first, second);
|
|
115
|
+
std::swap (first_clause, second_clause);
|
|
116
|
+
return *this;
|
|
117
|
+
}
|
|
118
|
+
lit_equivalence negate_both () {
|
|
119
|
+
first = -first;
|
|
120
|
+
second = -second;
|
|
121
|
+
std::swap (first_clause, second_clause);
|
|
122
|
+
return *this;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
typedef std::vector<lit_implication> lit_implications;
|
|
127
|
+
typedef std::vector<lit_equivalence> lit_equivalences;
|
|
128
|
+
|
|
129
|
+
std::string string_of_gate (Gate_Type t);
|
|
130
|
+
|
|
131
|
+
struct LitClausePair {
|
|
132
|
+
int current_lit; // current literal from the gate
|
|
133
|
+
Clause *clause;
|
|
134
|
+
LitClausePair (int lit, Clause *cl) : current_lit (lit), clause (cl) {}
|
|
135
|
+
LitClausePair () : current_lit (0), clause (nullptr) {}
|
|
136
|
+
};
|
|
137
|
+
struct LitIdPair {
|
|
138
|
+
int lit; // current literal from the gate
|
|
139
|
+
LRAT_ID id;
|
|
140
|
+
LitIdPair (int l, LRAT_ID i) : lit (l), id (i) {}
|
|
141
|
+
LitIdPair () : lit (0), id (0) {}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/*------------------------------------------------------------------------*/
|
|
145
|
+
|
|
146
|
+
// Sorting the scheduled clauses is way faster if we compute and save the
|
|
147
|
+
// clause size in the schedule to avoid pointer access to clauses during
|
|
148
|
+
// sorting. This slightly increases the schedule size though.
|
|
149
|
+
|
|
150
|
+
struct ClauseSize {
|
|
151
|
+
size_t size;
|
|
152
|
+
Clause *clause;
|
|
153
|
+
ClauseSize (int s, Clause *c) : size (s), clause (c) {}
|
|
154
|
+
ClauseSize (Clause *c) : size (c->size), clause (c) {}
|
|
155
|
+
ClauseSize () {}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
struct smaller_clause_size_rank {
|
|
159
|
+
typedef size_t Type;
|
|
160
|
+
Type operator() (const ClauseSize &a) { return a.size; }
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/*------------------------------------------------------------------------*/
|
|
164
|
+
// There are many special cases for ITE gates and we have to keep track of
|
|
165
|
+
// them as it is a gate property (rewriting might not make it obvious
|
|
166
|
+
// anymore).
|
|
167
|
+
// a = (a ? t : e) results in no -t and no +e gate (a --> a = t == (-a v -a
|
|
168
|
+
// v t) & (-a v a v -t)) a = (-a ? t : e) results in no +t and no -e gate a
|
|
169
|
+
// = (c ? a : e) results in no t gate (none of them) a = (c ? t : a) results
|
|
170
|
+
// in no e gate (none of them)
|
|
171
|
+
//
|
|
172
|
+
// We also use it for AND gates:
|
|
173
|
+
// a = (a & b)
|
|
174
|
+
// false = (a & b)
|
|
175
|
+
//
|
|
176
|
+
// The latter version can only happen when converting ITE gates to AND
|
|
177
|
+
// gates.
|
|
178
|
+
//
|
|
179
|
+
// They have a peculiarity: being special can fix itself. To avoid
|
|
180
|
+
// one more special case, we rewrite the LHS in that case too to make sure
|
|
181
|
+
// it remains special.
|
|
182
|
+
//
|
|
183
|
+
enum Special_Gate {
|
|
184
|
+
NORMAL = 0,
|
|
185
|
+
NO_PLUS_THEN = (1 << 0),
|
|
186
|
+
NO_NEG_THEN = (1 << 1),
|
|
187
|
+
NO_THEN = NO_PLUS_THEN + NO_NEG_THEN,
|
|
188
|
+
NO_PLUS_ELSE = (1 << 2),
|
|
189
|
+
NO_NEG_ELSE = (1 << 3),
|
|
190
|
+
DEGENERATED_AND = (1 << 4), // a = (a & b)
|
|
191
|
+
DEGENERATED_AND_LHS_FALSE = (1 << 5), // false = (a & b)
|
|
192
|
+
NO_ELSE = NO_PLUS_ELSE + NO_NEG_ELSE,
|
|
193
|
+
COND_LHS = NO_NEG_THEN + NO_PLUS_ELSE,
|
|
194
|
+
UCOND_LHS = NO_PLUS_THEN + NO_NEG_ELSE,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
std::string special_gate_str (int8_t f);
|
|
198
|
+
|
|
199
|
+
inline bool ite_flags_no_then_clauses (int8_t flag) {
|
|
200
|
+
return (flag & NO_THEN) == NO_THEN;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
inline bool ite_flags_no_else_clauses (int8_t flag) {
|
|
204
|
+
return (flag & NO_ELSE) == NO_ELSE;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
inline bool ite_flags_neg_cond_lhs (int8_t flag) {
|
|
208
|
+
return (flag & UCOND_LHS) == UCOND_LHS;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
inline bool ite_flags_cond_lhs (int8_t flag) {
|
|
212
|
+
return (flag & COND_LHS) == COND_LHS;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// std::optional is C++17 sadly
|
|
216
|
+
struct my_dummy_optional {
|
|
217
|
+
LitClausePair content;
|
|
218
|
+
my_dummy_optional () : content (0, 0) {}
|
|
219
|
+
bool operator() () const { return content.current_lit; }
|
|
220
|
+
my_dummy_optional operator= (LitClausePair p) {
|
|
221
|
+
content = p;
|
|
222
|
+
return *this;
|
|
223
|
+
}
|
|
224
|
+
void reset () { content = LitClausePair (0, 0); }
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/*------------------------------------------------------------------------*/
|
|
228
|
+
|
|
229
|
+
// The core structure of this algorithm: the gate. It is composed of a
|
|
230
|
+
// left-hand side and an array of right-hand side.
|
|
231
|
+
//
|
|
232
|
+
// There are a few tags to help remembering the status of the gate (like
|
|
233
|
+
// deleted)
|
|
234
|
+
//
|
|
235
|
+
// To keep track of the proof we use two extra arrays:
|
|
236
|
+
// - `neg_lhs_ids' contains the long clause for AND gates. Otherwise, it is
|
|
237
|
+
// empty. TODO: change to std::option as it contains at most one element
|
|
238
|
+
// - `pos_lhs_ids' contains all the remaining gates.
|
|
239
|
+
//
|
|
240
|
+
// We keep the reasons with an index. This index depends on the gates:
|
|
241
|
+
|
|
242
|
+
// - AND-Gates and ITE-Gates: the index is the literal from the RHS
|
|
243
|
+
//
|
|
244
|
+
// - XOR-Gates: if you order the clauses by the order of the literals,
|
|
245
|
+
// each literal is either positive (bit '1') or negative (bit '0'). This
|
|
246
|
+
// gives a number that we can use.
|
|
247
|
+
//
|
|
248
|
+
// TODO Florian: I do not think that you have to changed anything, look at
|
|
249
|
+
// the 'Look at this first' in the CPP file.
|
|
250
|
+
//
|
|
251
|
+
// Important for the proofs: the LHS is not updated.
|
|
252
|
+
//
|
|
253
|
+
// TODO: we currently use a vector for the rhs, but we could also use FMA
|
|
254
|
+
// and inline the structure to avoid any indirection.
|
|
255
|
+
//
|
|
256
|
+
// One warning for degenerated gate: it is a monotone property on the
|
|
257
|
+
// defining clauses, but not on the LHS/RHS as the LHS is not rewritten:
|
|
258
|
+
// take 4 = AND 3 4 (degenerated with only the clause -4 3) with a rewriting
|
|
259
|
+
// 4 -> 1 (unchanged clause) and later 1 -> 3 (unchanged clause) but you do
|
|
260
|
+
// not know anymore from the gate that it is degenerated
|
|
261
|
+
struct Gate {
|
|
262
|
+
#ifdef LOGGING
|
|
263
|
+
uint64_t id;
|
|
264
|
+
#endif
|
|
265
|
+
int lhs;
|
|
266
|
+
Gate_Type tag;
|
|
267
|
+
bool garbage : 1;
|
|
268
|
+
bool indexed : 1;
|
|
269
|
+
bool marked : 1;
|
|
270
|
+
bool shrunken : 1;
|
|
271
|
+
vector<LitClausePair> pos_lhs_ids;
|
|
272
|
+
my_dummy_optional neg_lhs_ids;
|
|
273
|
+
int8_t degenerated_gate = Special_Gate::NORMAL;
|
|
274
|
+
vector<int> rhs;
|
|
275
|
+
|
|
276
|
+
size_t arity () const { return rhs.size (); }
|
|
277
|
+
|
|
278
|
+
bool operator== (Gate const &lhs) {
|
|
279
|
+
return tag == lhs.tag && rhs == lhs.rhs;
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
typedef vector<Gate *> GOccs;
|
|
284
|
+
|
|
285
|
+
struct GateEqualTo {
|
|
286
|
+
bool operator() (const Gate *const lhs, const Gate *const rhs) const {
|
|
287
|
+
return lhs->rhs == rhs->rhs && lhs->tag == rhs->tag;
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
struct CompactBinary {
|
|
292
|
+
Clause *clause;
|
|
293
|
+
LRAT_ID id;
|
|
294
|
+
int lit1, lit2;
|
|
295
|
+
CompactBinary (Clause *c, LRAT_ID i, int l1, int l2)
|
|
296
|
+
: clause (c), id (i), lit1 (l1), lit2 (l2) {}
|
|
297
|
+
CompactBinary () : clause (nullptr), id (0), lit1 (0), lit2 (0) {}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
struct Hash {
|
|
301
|
+
Hash (std::array<uint64_t, 16> &ncs) : nonces (ncs) {}
|
|
302
|
+
const std::array<uint64_t, 16> &nonces;
|
|
303
|
+
inline size_t operator() (const Gate *const g) const;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
struct Rewrite {
|
|
307
|
+
int src, dst;
|
|
308
|
+
LRAT_ID id1;
|
|
309
|
+
LRAT_ID id2;
|
|
310
|
+
|
|
311
|
+
Rewrite (int _src, int _dst, LRAT_ID _id1, LRAT_ID _id2)
|
|
312
|
+
: src (_src), dst (_dst), id1 (_id1), id2 (_id2) {}
|
|
313
|
+
Rewrite () : src (0), dst (0), id1 (0), id2 (0) {}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
struct Closure {
|
|
317
|
+
|
|
318
|
+
Closure (Internal *i);
|
|
319
|
+
~Closure () { delete dummy_search_gate; }
|
|
320
|
+
Gate *dummy_search_gate = nullptr;
|
|
321
|
+
|
|
322
|
+
Internal *const internal;
|
|
323
|
+
vector<Clause *> extra_clauses;
|
|
324
|
+
vector<CompactBinary> binaries;
|
|
325
|
+
std::vector<std::pair<size_t, size_t>> offsetsize;
|
|
326
|
+
bool full_watching = false;
|
|
327
|
+
std::array<uint64_t, 16> nonces;
|
|
328
|
+
typedef unordered_set<Gate *, Hash, GateEqualTo> GatesTable;
|
|
329
|
+
|
|
330
|
+
vector<bool> scheduled;
|
|
331
|
+
vector<signed char> marks;
|
|
332
|
+
vector<LitClausePair> mu1_ids, mu2_ids,
|
|
333
|
+
mu4_ids; // remember the ids and the literal. 2 and 4 are
|
|
334
|
+
// only used for lrat proofs, but we need 1 to
|
|
335
|
+
// promote binary clauses to irredundant
|
|
336
|
+
|
|
337
|
+
vector<int> lits; // result of definitions
|
|
338
|
+
vector<int> rhs; // stack for storing RHS
|
|
339
|
+
vector<int> unsimplified; // stack for storing unsimplified version (XOR,
|
|
340
|
+
// ITEs) for DRAT proof
|
|
341
|
+
vector<int> chain; // store clauses to be able to delete them properly
|
|
342
|
+
vector<int> clause; // storing partial clauses
|
|
343
|
+
vector<uint64_t>
|
|
344
|
+
glargecounts; // count for large clauses to complement internal->noccs
|
|
345
|
+
vector<uint64_t> gnew_largecounts; // count for large clauses to
|
|
346
|
+
// complement internal->noccs
|
|
347
|
+
GatesTable table;
|
|
348
|
+
std::array<lit_implications, 2> condbin;
|
|
349
|
+
std::array<lit_equivalences, 2> condeq;
|
|
350
|
+
|
|
351
|
+
std::vector<Clause *> new_unwatched_binary_clauses;
|
|
352
|
+
// LRAT proofs
|
|
353
|
+
vector<int> resolvent_analyzed;
|
|
354
|
+
mutable vector<LRAT_ID> lrat_chain; // storing LRAT chain
|
|
355
|
+
|
|
356
|
+
#ifdef LOGGING
|
|
357
|
+
uint64_t fresh_id;
|
|
358
|
+
#endif
|
|
359
|
+
|
|
360
|
+
uint64_t &new_largecounts (int lit);
|
|
361
|
+
uint64_t &largecounts (int lit);
|
|
362
|
+
|
|
363
|
+
void unmark_all ();
|
|
364
|
+
vector<int> representant; // union-find
|
|
365
|
+
vector<int> eager_representant; // union-find
|
|
366
|
+
vector<LRAT_ID> representant_id; // lrat version of union-find
|
|
367
|
+
vector<LRAT_ID> eager_representant_id; // lrat version of union-find
|
|
368
|
+
int &representative (int lit);
|
|
369
|
+
int representative (int lit) const;
|
|
370
|
+
LRAT_ID &representative_id (int lit);
|
|
371
|
+
LRAT_ID representative_id (int lit) const;
|
|
372
|
+
int &eager_representative (int lit);
|
|
373
|
+
int eager_representative (int lit) const;
|
|
374
|
+
LRAT_ID &eager_representative_id (int lit);
|
|
375
|
+
LRAT_ID eager_representative_id (int lit) const;
|
|
376
|
+
std::vector<char> lazy_propagated_idx;
|
|
377
|
+
char &lazy_propagated (int lit);
|
|
378
|
+
|
|
379
|
+
int find_lrat_representative_with_marks (int lit);
|
|
380
|
+
// representative in the union-find structure in the lazy equivalences
|
|
381
|
+
int find_representative (int lit);
|
|
382
|
+
// representative in the union-find structure in the lazy equivalences.
|
|
383
|
+
// only useful if you do not care about proofs like during forward
|
|
384
|
+
// subsumption.
|
|
385
|
+
int find_representative_and_compress_no_proofs (int lit);
|
|
386
|
+
int find_representative_already_compressed (int lit);
|
|
387
|
+
// find the representative and produce the binary clause representing the
|
|
388
|
+
// normalization from the literal to the result.
|
|
389
|
+
int find_representative_and_compress (int, bool update_eager = true);
|
|
390
|
+
// find the lazy representative for the `lit' and `-lit'
|
|
391
|
+
void find_representative_and_compress_both (int);
|
|
392
|
+
// find the eager representative
|
|
393
|
+
int find_eager_representative (int);
|
|
394
|
+
|
|
395
|
+
// compreses the path from lit to the representative with a new clause if
|
|
396
|
+
// needed. Save internal->lrat_chain to avoid any issue.
|
|
397
|
+
int find_eager_representative_and_compress (int);
|
|
398
|
+
// Import the path from the literal and its negation to the representative
|
|
399
|
+
// in the lazy graph to the eager part, producing the binary clauses.
|
|
400
|
+
void import_lazy_and_find_eager_representative_and_compress_both (
|
|
401
|
+
int); // generates clauses for -lit and lit
|
|
402
|
+
|
|
403
|
+
// returns the ID of the LRAT clause for the normalization from the
|
|
404
|
+
// literal lit to its argument, assuming that the representative was
|
|
405
|
+
// already compressed.
|
|
406
|
+
LRAT_ID find_representative_lrat (int lit);
|
|
407
|
+
// returns the ID of the LRAT clause for the eager normalization from the
|
|
408
|
+
// literal lit to its argument assuming that the representative was
|
|
409
|
+
// already compressed.
|
|
410
|
+
LRAT_ID find_eager_representative_lrat (int lit);
|
|
411
|
+
|
|
412
|
+
// Writes the LRAT chain required for the eager normalization to
|
|
413
|
+
// `lrat_chain`.
|
|
414
|
+
void produce_eager_representative_lrat (int lit);
|
|
415
|
+
// Writes the LRAT chain required for the lazy normalization to
|
|
416
|
+
// `lrat_chain`.
|
|
417
|
+
void produce_representative_lrat (int lit);
|
|
418
|
+
|
|
419
|
+
// learns a binary clause if not unit
|
|
420
|
+
Clause *maybe_add_binary_clause (int a, int b);
|
|
421
|
+
// add binary clause
|
|
422
|
+
Clause *add_binary_clause (int a, int b);
|
|
423
|
+
// add tmp clause
|
|
424
|
+
Clause *add_tmp_binary_clause (int a, int b);
|
|
425
|
+
// add clause taking core of tmp or full
|
|
426
|
+
Clause *learn_binary_tmp_or_full_clause (int a, int b);
|
|
427
|
+
|
|
428
|
+
// promotes a clause from redundant to irredundant. We do this for all
|
|
429
|
+
// clauses involved in gates to make sure that we produce correct result.
|
|
430
|
+
void promote_clause (Clause *);
|
|
431
|
+
|
|
432
|
+
// Merge functions. We actually need different several versions for LRAT
|
|
433
|
+
// in order to simplify the proof production.
|
|
434
|
+
//
|
|
435
|
+
// When merging binary clauses, we can simply produce the LRAT chain by
|
|
436
|
+
// (1) using the two binary clauses and (2) the reason clause from the
|
|
437
|
+
// literals to the representatives.
|
|
438
|
+
//
|
|
439
|
+
// The same approach does not work for merging gates because the
|
|
440
|
+
// representative might be also a representative of another literal
|
|
441
|
+
// (because of eager rewriting), requiring to resolve more than once on
|
|
442
|
+
// the same literal. An example of this are the two gates 4=-2&7 and
|
|
443
|
+
// 6=-2&1, the rewriting 7=1 and the equivalence 4=1. The simple road of
|
|
444
|
+
// merging 6 and 4 (requires resolving away 1) + adding the rewrite 4 to 1
|
|
445
|
+
// (requires adding 1) does not work.
|
|
446
|
+
//
|
|
447
|
+
// Therefore, we actually go for the more regular road and produce two
|
|
448
|
+
// equivalence: the merge from the LHS, followed by the actual equivalence
|
|
449
|
+
// (by combining it with the rewrite). In DRAT this is less important
|
|
450
|
+
// because the checker finds a chain and is less restricted than our LRAT
|
|
451
|
+
// chain.
|
|
452
|
+
bool merge_literals_equivalence (int lit, int other, Clause *c1,
|
|
453
|
+
Clause *c2);
|
|
454
|
+
bool merge_literals (Gate *g, Gate *h, int lit, int other,
|
|
455
|
+
const std::vector<LRAT_ID> & = {},
|
|
456
|
+
const std::vector<LRAT_ID> & = {});
|
|
457
|
+
bool merge_literals (int lit, int other,
|
|
458
|
+
const std::vector<LRAT_ID> & = {},
|
|
459
|
+
const std::vector<LRAT_ID> & = {});
|
|
460
|
+
// factoring out the merge w.r.t. both cases above
|
|
461
|
+
bool really_merge_literals (int lit, int other, int repr_lit,
|
|
462
|
+
int repr_other,
|
|
463
|
+
const std::vector<LRAT_ID> & = {},
|
|
464
|
+
const std::vector<LRAT_ID> & = {});
|
|
465
|
+
|
|
466
|
+
// proof production
|
|
467
|
+
vector<LitClausePair> lrat_chain_and_gate;
|
|
468
|
+
void push_lrat_id (const Clause *const c, int lit);
|
|
469
|
+
void push_lrat_unit (int lit);
|
|
470
|
+
|
|
471
|
+
// pushes the clause with the reasons to rewrite clause
|
|
472
|
+
// unless:
|
|
473
|
+
// - the rewriting is not necessary (resolvent_marked == 1)
|
|
474
|
+
// - it is overwritten by one of the arguments
|
|
475
|
+
void push_id_and_rewriting_lrat_unit (Clause *c, Rewrite rewrite1,
|
|
476
|
+
std::vector<LRAT_ID> &chain,
|
|
477
|
+
bool = true,
|
|
478
|
+
Rewrite rewrite2 = Rewrite (),
|
|
479
|
+
int execept_lhs = 0,
|
|
480
|
+
int except_lhs2 = 0);
|
|
481
|
+
void push_id_and_rewriting_lrat_full (Clause *c, Rewrite rewrite1,
|
|
482
|
+
std::vector<LRAT_ID> &chain,
|
|
483
|
+
bool = true,
|
|
484
|
+
Rewrite rewrite2 = Rewrite (),
|
|
485
|
+
int execept_lhs = 0,
|
|
486
|
+
int except_lhs2 = 0);
|
|
487
|
+
// TODO: does nothing except pushing on the stack, remove!
|
|
488
|
+
void push_id_on_chain (std::vector<LRAT_ID> &chain, Clause *c);
|
|
489
|
+
// TODO: does nothing except pushing on the stack, remove!
|
|
490
|
+
void push_id_on_chain (std::vector<LRAT_ID> &chain,
|
|
491
|
+
const std::vector<LitClausePair> &c);
|
|
492
|
+
void push_id_on_chain (std::vector<LRAT_ID> &chain,
|
|
493
|
+
const my_dummy_optional &c);
|
|
494
|
+
// TODO: does nothing except pushing on the stack, remove!
|
|
495
|
+
void push_id_on_chain (std::vector<LRAT_ID> &chain, Rewrite rewrite, int);
|
|
496
|
+
void update_and_gate_build_lrat_chain (
|
|
497
|
+
Gate *g, Gate *h, std::vector<LRAT_ID> &extra_reasons_lit,
|
|
498
|
+
std::vector<LRAT_ID> &extra_reasons_ulit, bool remove_units = true);
|
|
499
|
+
void update_and_gate_unit_build_lrat_chain (
|
|
500
|
+
Gate *g, int src, LRAT_ID id1, LRAT_ID id2, int dst,
|
|
501
|
+
std::vector<LRAT_ID> &extra_reasons_lit,
|
|
502
|
+
std::vector<LRAT_ID> &extra_reasons_ulit);
|
|
503
|
+
// occs
|
|
504
|
+
vector<GOccs> gtab;
|
|
505
|
+
GOccs &goccs (int lit);
|
|
506
|
+
void connect_goccs (Gate *g, int lit);
|
|
507
|
+
vector<Gate *> garbage;
|
|
508
|
+
void mark_garbage (Gate *);
|
|
509
|
+
// remove the gate from the table
|
|
510
|
+
bool remove_gate (Gate *);
|
|
511
|
+
bool remove_gate (GatesTable::iterator git);
|
|
512
|
+
void index_gate (Gate *);
|
|
513
|
+
|
|
514
|
+
// second counter for size, complements noccs
|
|
515
|
+
uint64_t &largecount (int lit);
|
|
516
|
+
|
|
517
|
+
// simplification
|
|
518
|
+
bool skip_and_gate (Gate *g);
|
|
519
|
+
bool skip_xor_gate (Gate *g);
|
|
520
|
+
void update_and_gate (Gate *g, GatesTable::iterator, int src, int dst,
|
|
521
|
+
LRAT_ID id1, LRAT_ID id2, int falsified = 0,
|
|
522
|
+
int clashing = 0);
|
|
523
|
+
void update_xor_gate (Gate *g, GatesTable::iterator);
|
|
524
|
+
void shrink_and_gate (Gate *g, int falsified = 0, int clashing = 0);
|
|
525
|
+
bool simplify_gate (Gate *g);
|
|
526
|
+
void simplify_and_gate (Gate *g);
|
|
527
|
+
void simplify_ite_gate (Gate *g);
|
|
528
|
+
Clause *simplify_xor_clause (int lhs, Clause *);
|
|
529
|
+
void simplify_xor_gate (Gate *g);
|
|
530
|
+
bool simplify_gates (int lit);
|
|
531
|
+
void simplify_and_sort_xor_lrat_clauses (const vector<LitClausePair> &,
|
|
532
|
+
vector<LitClausePair> &, int,
|
|
533
|
+
int except2 = 0, bool flip = 0);
|
|
534
|
+
void simplify_unit_xor_lrat_clauses (const vector<LitClausePair> &, int);
|
|
535
|
+
|
|
536
|
+
// rewriting
|
|
537
|
+
bool rewriting_lhs (Gate *g, int dst);
|
|
538
|
+
bool rewrite_gates (int dst, int src, LRAT_ID id1, LRAT_ID id2);
|
|
539
|
+
bool rewrite_gate (Gate *g, int dst, int src, LRAT_ID id1, LRAT_ID id2);
|
|
540
|
+
void rewrite_xor_gate (Gate *g, int dst, int src);
|
|
541
|
+
void rewrite_and_gate (Gate *g, int dst, int src, LRAT_ID id1,
|
|
542
|
+
LRAT_ID id2);
|
|
543
|
+
void rewrite_ite_gate (Gate *g, int dst, int src);
|
|
544
|
+
|
|
545
|
+
size_t units; // next trail position to propagate
|
|
546
|
+
bool propagate_unit (int lit);
|
|
547
|
+
bool propagate_units ();
|
|
548
|
+
size_t propagate_units_and_equivalences ();
|
|
549
|
+
bool propagate_equivalence (int lit);
|
|
550
|
+
|
|
551
|
+
// gates
|
|
552
|
+
void init_closure ();
|
|
553
|
+
void reset_closure ();
|
|
554
|
+
void reset_extraction ();
|
|
555
|
+
void reset_and_gate_extraction ();
|
|
556
|
+
void extract_and_gates (Closure &);
|
|
557
|
+
void extract_gates ();
|
|
558
|
+
void extract_and_gates_with_base_clause (Clause *c);
|
|
559
|
+
void init_and_gate_extraction ();
|
|
560
|
+
Gate *find_first_and_gate (Clause *base_clause, int lhs);
|
|
561
|
+
Gate *find_remaining_and_gate (Clause *base_clause, int lhs);
|
|
562
|
+
void extract_and_gates ();
|
|
563
|
+
|
|
564
|
+
Gate *find_and_lits (vector<int> &rhs, Gate *except = nullptr);
|
|
565
|
+
Gate *
|
|
566
|
+
find_gate_lits (vector<int> &rhs,
|
|
567
|
+
Gate_Type typ, // rhs unchanged but swapped back and forth
|
|
568
|
+
Gate *except = nullptr);
|
|
569
|
+
Gate *find_xor_lits (vector<int> &rhs);
|
|
570
|
+
// not const to normalize negations, also fixes the order of the LRAT
|
|
571
|
+
Gate *find_ite_gate (Gate *, bool &);
|
|
572
|
+
Gate *find_xor_gate (Gate *);
|
|
573
|
+
|
|
574
|
+
void reset_xor_gate_extraction ();
|
|
575
|
+
void init_xor_gate_extraction (std::vector<Clause *> &candidates);
|
|
576
|
+
LRAT_ID check_and_add_to_proof_chain (vector<int> &clause);
|
|
577
|
+
void add_xor_matching_proof_chain (Gate *g, int lhs1,
|
|
578
|
+
const vector<LitClausePair> &,
|
|
579
|
+
int lhs2, vector<LRAT_ID> &,
|
|
580
|
+
vector<LRAT_ID> &);
|
|
581
|
+
void add_xor_shrinking_proof_chain (Gate *g, int src);
|
|
582
|
+
void extract_xor_gates ();
|
|
583
|
+
void extract_xor_gates_with_base_clause (Clause *c);
|
|
584
|
+
Clause *find_large_xor_side_clause (std::vector<int> &lits);
|
|
585
|
+
|
|
586
|
+
void merge_condeq (int cond, lit_equivalences &condeq,
|
|
587
|
+
lit_equivalences ¬_condeq);
|
|
588
|
+
void find_conditional_equivalences (int lit, lit_implications &condbin,
|
|
589
|
+
lit_equivalences &condeq);
|
|
590
|
+
void copy_conditional_equivalences (int lit, lit_implications &condbin);
|
|
591
|
+
void check_ite_implied (int lhs, int cond, int then_lit, int else_lit);
|
|
592
|
+
void check_ite_gate_implied (Gate *g);
|
|
593
|
+
void check_and_gate_implied (Gate *g);
|
|
594
|
+
void check_ite_lrat_reasons (Gate *g);
|
|
595
|
+
void check_contained_module_rewriting (Clause *c, int lit, bool,
|
|
596
|
+
int except);
|
|
597
|
+
void delete_proof_chain ();
|
|
598
|
+
|
|
599
|
+
// ite gate extraction
|
|
600
|
+
void extract_ite_gates_of_literal (int);
|
|
601
|
+
void extract_ite_gates_of_variable (int idx);
|
|
602
|
+
void extract_condeq_pairs (int lit, lit_implications &condbin,
|
|
603
|
+
lit_equivalences &condeq);
|
|
604
|
+
void init_ite_gate_extraction (std::vector<ClauseSize> &candidates);
|
|
605
|
+
lit_implications::const_iterator find_lit_implication_second_literal (
|
|
606
|
+
int lit, lit_implications::const_iterator begin,
|
|
607
|
+
lit_implications::const_iterator end);
|
|
608
|
+
void search_condeq (int lit, int pos_lit,
|
|
609
|
+
lit_implications::const_iterator pos_begin,
|
|
610
|
+
lit_implications::const_iterator pos_end, int neg_lit,
|
|
611
|
+
lit_implications::const_iterator neg_begin,
|
|
612
|
+
lit_implications::const_iterator neg_end,
|
|
613
|
+
lit_equivalences &condeq);
|
|
614
|
+
void reset_ite_gate_extraction ();
|
|
615
|
+
void extract_ite_gates ();
|
|
616
|
+
|
|
617
|
+
void forward_subsume_matching_clauses ();
|
|
618
|
+
|
|
619
|
+
void extract_congruence ();
|
|
620
|
+
|
|
621
|
+
void add_ite_matching_proof_chain (Gate *g, Gate *h, int lhs1, int lhs2,
|
|
622
|
+
std::vector<LRAT_ID> &reasons1,
|
|
623
|
+
std::vector<LRAT_ID> &reasons2);
|
|
624
|
+
void add_ite_turned_and_binary_clauses (Gate *g);
|
|
625
|
+
Gate *new_and_gate (Clause *, int);
|
|
626
|
+
Gate *new_ite_gate (int lhs, int cond, int then_lit, int else_lit,
|
|
627
|
+
std::vector<LitClausePair> &&clauses);
|
|
628
|
+
Gate *new_xor_gate (const vector<LitClausePair> &, int);
|
|
629
|
+
// check
|
|
630
|
+
void check_xor_gate_implied (Gate const *const);
|
|
631
|
+
void check_ternary (int a, int b, int c);
|
|
632
|
+
void check_binary_implied (int a, int b);
|
|
633
|
+
void check_implied ();
|
|
634
|
+
|
|
635
|
+
// learn units. You can delay units if you want to learn several at once
|
|
636
|
+
// before propagation. Otherwise, propagate! If you need propagation even
|
|
637
|
+
// if nothing is set, use the second parameter.
|
|
638
|
+
//
|
|
639
|
+
// The function can also learn the empty clause if the unit is already
|
|
640
|
+
// set. Do not add the unit in the chain!
|
|
641
|
+
bool learn_congruence_unit (int unit, bool = false, bool = false);
|
|
642
|
+
bool fully_propagate ();
|
|
643
|
+
void learn_congruence_unit_falsifies_lrat_chain (Gate *g, int src,
|
|
644
|
+
int dst, int clashing,
|
|
645
|
+
int falsified, int unit);
|
|
646
|
+
void learn_congruence_unit_when_lhs_set (Gate *g, int src, LRAT_ID id1,
|
|
647
|
+
LRAT_ID id2, int dst);
|
|
648
|
+
|
|
649
|
+
void find_units ();
|
|
650
|
+
void find_equivalences ();
|
|
651
|
+
void subsume_clause (Clause *subsuming, Clause *subsumed);
|
|
652
|
+
bool find_subsuming_clause (Clause *c);
|
|
653
|
+
void produce_rewritten_clause_lrat_and_clean (vector<LitClausePair> &,
|
|
654
|
+
int execept_lhs = 0,
|
|
655
|
+
bool = true, bool = false);
|
|
656
|
+
void produce_rewritten_clause_lrat_and_clean (my_dummy_optional &,
|
|
657
|
+
int execept_lhs = 0,
|
|
658
|
+
bool = true);
|
|
659
|
+
|
|
660
|
+
// rewrite the clause using eager rewriting and rew1 and rew2, except for
|
|
661
|
+
// 2 literals Usage:
|
|
662
|
+
// - the except are used to ignore LHS of gates that have not and should
|
|
663
|
+
// not be rewritten.
|
|
664
|
+
// - TODO: except_lhs2 should never be used actually
|
|
665
|
+
// - the Rewrite are for additional rewrite to allow for lazy rewrites
|
|
666
|
+
// to be taken into account without being added to the eager rewriting
|
|
667
|
+
// (yet)
|
|
668
|
+
Clause *produce_rewritten_clause_lrat (Clause *c, int execept_lhs = 0,
|
|
669
|
+
bool remove_units = true,
|
|
670
|
+
bool = false);
|
|
671
|
+
void produce_rewritten_clause_lrat (vector<LitClausePair> &,
|
|
672
|
+
int execept_lhs = 0, bool = true);
|
|
673
|
+
void compute_rewritten_clause_lrat_simple (Clause *c, int except);
|
|
674
|
+
// variant where we update the indices after removing the tautologies and
|
|
675
|
+
// remove the tautological clauses
|
|
676
|
+
void produce_rewritten_clause_lrat_and_clean (
|
|
677
|
+
std::vector<LitClausePair> &litIds, int except_lhs,
|
|
678
|
+
size_t &old_position1, size_t &old_position2,
|
|
679
|
+
bool remove_units = true);
|
|
680
|
+
// binary extraction and ternary strengthening
|
|
681
|
+
void extract_binaries ();
|
|
682
|
+
bool find_binary (int, int) const;
|
|
683
|
+
|
|
684
|
+
Clause *new_tmp_clause (std::vector<int> &clause);
|
|
685
|
+
Clause *maybe_promote_tmp_binary_clause (Clause *);
|
|
686
|
+
void check_not_tmp_binary_clause (Clause *c);
|
|
687
|
+
Clause *new_clause ();
|
|
688
|
+
//
|
|
689
|
+
void sort_literals_by_var (vector<int> &rhs);
|
|
690
|
+
void sort_literals_by_var_except (vector<int> &rhs, int, int except2 = 0);
|
|
691
|
+
|
|
692
|
+
// schedule
|
|
693
|
+
queue<int> schedule;
|
|
694
|
+
void schedule_literal (int lit);
|
|
695
|
+
void add_clause_to_chain (std::vector<int>, LRAT_ID);
|
|
696
|
+
// proof. If delete_id is non-zero, then delete the clause instead of
|
|
697
|
+
// learning it
|
|
698
|
+
LRAT_ID simplify_and_add_to_proof_chain (vector<int> &unsimplified,
|
|
699
|
+
LRAT_ID delete_id = 0);
|
|
700
|
+
|
|
701
|
+
// we define our own wrapper as cadical has otherwise a non-compatible
|
|
702
|
+
// marking system
|
|
703
|
+
signed char &marked (int lit);
|
|
704
|
+
void set_mu1_reason (int lit, Clause *c);
|
|
705
|
+
void set_mu2_reason (int lit, Clause *c);
|
|
706
|
+
void set_mu4_reason (int lit, Clause *c);
|
|
707
|
+
LitClausePair marked_mu1 (int lit);
|
|
708
|
+
LitClausePair marked_mu2 (int lit);
|
|
709
|
+
LitClausePair marked_mu4 (int lit);
|
|
710
|
+
|
|
711
|
+
// XOR
|
|
712
|
+
uint32_t number_from_xor_reason_reversed (const std::vector<int> &rhs);
|
|
713
|
+
uint32_t number_from_xor_reason (const std::vector<int> &rhs, int,
|
|
714
|
+
int except2 = 0, bool flip = 0);
|
|
715
|
+
void gate_sort_lrat_reasons (std::vector<LitClausePair> &, int,
|
|
716
|
+
int except2 = 0, bool flip = 0);
|
|
717
|
+
void gate_sort_lrat_reasons (LitClausePair &, int, int except2 = 0,
|
|
718
|
+
bool flip = 0);
|
|
719
|
+
|
|
720
|
+
bool rewrite_ite_gate_to_and (Gate *g, int dst, int src, size_t c,
|
|
721
|
+
size_t d,
|
|
722
|
+
int cond_lit_to_learn_if_degenerated);
|
|
723
|
+
void produce_ite_merge_then_else_reasons (
|
|
724
|
+
Gate *g, int dst, int src, std::vector<LRAT_ID> &reasons_implication,
|
|
725
|
+
std::vector<LRAT_ID> &reasons_back);
|
|
726
|
+
void produce_ite_merge_lhs_then_else_reasons (
|
|
727
|
+
Gate *g, std::vector<LRAT_ID> &reasons_implication,
|
|
728
|
+
std::vector<LRAT_ID> &reasons_back,
|
|
729
|
+
std::vector<LRAT_ID> &reasons_unit, bool, bool &);
|
|
730
|
+
void produce_ite_merge_rhs_cond (Gate *g, int, int);
|
|
731
|
+
void rewrite_ite_gate_update_lrat_reasons (Gate *g, int src, int dst);
|
|
732
|
+
void simplify_ite_gate_produce_unit_lrat (Gate *g, int lit, size_t idx1,
|
|
733
|
+
size_t idx2);
|
|
734
|
+
void merge_and_gate_lrat_produce_lrat (
|
|
735
|
+
Gate *g, Gate *h, std::vector<LRAT_ID> &reasons_lrat,
|
|
736
|
+
std::vector<LRAT_ID> &reasons_lrat_back, bool remove_units = true);
|
|
737
|
+
// first index is a binary clause after unit propagation and the second
|
|
738
|
+
// has length 3
|
|
739
|
+
bool simplify_ite_gate_to_and (Gate *g, size_t idx1, size_t idx2,
|
|
740
|
+
int removed);
|
|
741
|
+
void merge_ite_gate_same_then_else_lrat (
|
|
742
|
+
std::vector<LitClausePair> &clauses,
|
|
743
|
+
std::vector<LRAT_ID> &reasons_implication,
|
|
744
|
+
std::vector<LRAT_ID> &reasons_back);
|
|
745
|
+
void simplify_ite_gate_then_else_set (
|
|
746
|
+
Gate *g, std::vector<LRAT_ID> &reasons_implication,
|
|
747
|
+
std::vector<LRAT_ID> &reasons_back, size_t idx1, size_t idx2);
|
|
748
|
+
|
|
749
|
+
void simplify_ite_gate_condition_set (
|
|
750
|
+
Gate *g, std::vector<LRAT_ID> &reasons_lrat,
|
|
751
|
+
std::vector<LRAT_ID> &reasons_back_lrat, size_t idx1, size_t idx2);
|
|
752
|
+
bool normalize_ite_lits_gate (Gate *rhs);
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
} // namespace CaDiCaL
|
|
756
|
+
|
|
757
|
+
#endif
|