ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_extend.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
10 extension.push_back (0);
11 LOG ("pushing 0 on extension stack");
12}
13
15 const uint32_t higher_bits = static_cast<int> (id << 32);
16 const uint32_t lower_bits = (id & (((int64_t) 1 << 32) - 1));
17 extension.push_back (higher_bits);
18 extension.push_back (lower_bits);
19 LOG ("pushing id %" PRIu64 " = %d + %d", id, higher_bits, lower_bits);
20}
21
23 CADICAL_assert (ilit);
24 const int elit = internal->externalize (ilit);
25 CADICAL_assert (elit);
26 extension.push_back (elit);
27 LOG ("pushing clause literal %d on extension stack (internal %d)", elit,
28 ilit);
29}
30
32 CADICAL_assert (ilit);
33 const int elit = internal->externalize (ilit);
34 CADICAL_assert (elit);
35 extension.push_back (elit);
36 LOG ("pushing witness literal %d on extension stack (internal %d)", elit,
37 ilit);
38 if (marked (witness, elit))
39 return;
40 LOG ("marking witness %d", elit);
41 mark (witness, elit);
42}
43
44// The extension stack allows to reconstruct a satisfying assignment for the
45// original formula after removing eliminated clauses. This was pioneered
46// by Niklas Soerensson in MiniSAT and for instance is described in our
47// inprocessing paper, published at IJCAR'12. This first function adds a
48// clause to this stack. First the blocking or eliminated literal is added,
49// and then the rest of the clause.
50
52 internal->stats.weakened++;
53 internal->stats.weakenedlen += c->size;
57 for (const auto &lit : *c)
59}
60
66
79
80/*------------------------------------------------------------------------*/
81
83 const vector<int> &c, const vector<int> &w, int64_t id) {
84 CADICAL_assert (id);
85 extension.push_back (0);
86 for (const auto &elit : w) {
87 CADICAL_assert (elit != INT_MIN);
88 init (abs (elit));
89 extension.push_back (elit);
90 mark (witness, elit);
91 }
92 extension.push_back (0);
93 const uint32_t higher_bits = static_cast<int> (id << 32);
94 const uint32_t lower_bits = (id & (((int64_t) 1 << 32) - 1));
95 extension.push_back (higher_bits);
96 extension.push_back (lower_bits);
97 extension.push_back (0);
98 for (const auto &elit : c) {
99 CADICAL_assert (elit != INT_MIN);
100 init (abs (elit));
101 extension.push_back (elit);
102 }
103}
104
105/*------------------------------------------------------------------------*/
106
107// This is the actual extension process. It goes backward over the clauses
108// on the extension stack and flips the assignment of one of the blocking
109// literals in the conditional autarky stored before the clause. In the
110// original algorithm for witness construction for variable elimination and
111// blocked clause removal the conditional autarky consists of a single
112// literal from the removed clause, while in general the autarky witness can
113// contain an arbitrary set of literals. We are using the more general
114// witness reconstruction here which for instance would also work for
115// super-blocked or set-blocked clauses.
116
118
120 START (extend);
121 internal->stats.extensions++;
122
123 PHASE ("extend", internal->stats.extensions,
124 "mapping internal %d assignments to %d assignments",
125 internal->max_var, max_var);
126
127#ifndef CADICAL_QUIET
128 int64_t updated = 0;
129#endif
130 for (unsigned i = 1; i <= (unsigned) max_var; i++) {
131 const int ilit = e2i[i];
132 if (!ilit)
133 continue;
134 if (i >= vals.size ())
135 vals.resize (i + 1, false);
136 vals[i] = (internal->val (ilit) > 0);
137#ifndef CADICAL_QUIET
138 updated++;
139#endif
140 }
141 PHASE ("extend", internal->stats.extensions,
142 "updated %" PRId64 " external assignments", updated);
143 PHASE ("extend", internal->stats.extensions,
144 "extending through extension stack of size %zd",
145 extension.size ());
146 const auto begin = extension.begin ();
147 auto i = extension.end ();
148#ifndef CADICAL_QUIET
149 int64_t flipped = 0;
150#endif
151 while (i != begin) {
152 bool satisfied = false;
153 int lit;
154 CADICAL_assert (i != begin);
155 while ((lit = *--i)) {
156 if (satisfied)
157 continue;
158 if (ival (lit) == lit)
159 satisfied = true;
160 CADICAL_assert (i != begin);
161 }
162 CADICAL_assert (i != begin);
163 LOG ("id=%" PRId64, ((int64_t) *i << 32) + *(i - 1));
164 CADICAL_assert (*i || *(i - 1));
165 --i;
166 CADICAL_assert (i != begin);
167 --i;
168 CADICAL_assert (i != begin);
169 CADICAL_assert (!*i);
170 --i;
171 CADICAL_assert (i != begin);
172 if (satisfied)
173 while (*--i)
174 CADICAL_assert (i != begin);
175 else {
176 while ((lit = *--i)) {
177 const int tmp = ival (lit); // not 'signed char'!!!
178 if (tmp != lit) {
179 LOG ("flipping blocking literal %d", lit);
181 CADICAL_assert (lit != INT_MIN);
182 size_t idx = abs (lit);
183 if (idx >= vals.size ())
184 vals.resize (idx + 1, false);
185 vals[idx] = !vals[idx];
186 internal->stats.extended++;
187#ifndef CADICAL_QUIET
188 flipped++;
189#endif
190 }
191 CADICAL_assert (i != begin);
192 }
193 }
194 }
195 PHASE ("extend", internal->stats.extensions,
196 "flipped %" PRId64 " literals during extension", flipped);
197 extended = true;
198 LOG ("extended");
199 STOP (extend);
200}
201
202/*------------------------------------------------------------------------*/
203
205 if (internal->unsat)
206 return true;
208 const auto begin = extension.begin ();
209 auto i = extension.end ();
210 while (i != begin) {
211 int lit;
212 while ((lit = *--i))
213 clause.push_back (lit);
215 --i;
216 const int64_t id =
217 ((int64_t) * (i - 1) << 32) + static_cast<int64_t> (*i);
218 CADICAL_assert (id);
219 i -= 2;
220 CADICAL_assert (!*i);
221 CADICAL_assert (i != begin);
222 while ((lit = *--i))
223 witness.push_back (lit);
224 reverse (clause.begin (), clause.end ());
225 reverse (witness.begin (), witness.end ());
226 LOG (clause, "traversing clause");
227 if (!it.witness (clause, witness, id))
228 return false;
229 clause.clear ();
230 witness.clear ();
231 }
232 return true;
233}
234
236 if (internal->unsat)
237 return true;
239 const auto end = extension.end ();
240 auto i = extension.begin ();
241 if (i != end) {
242 int lit = *i++;
243 do {
244 CADICAL_assert (!lit), (void) lit;
245 while ((lit = *i++))
246 witness.push_back (lit);
248 CADICAL_assert (i != end);
249 CADICAL_assert (!*i);
250 const int64_t id =
251 ((int64_t) *i << 32) + static_cast<int64_t> (*(i + 1));
252 CADICAL_assert (id > 0);
253 i += 3;
254 CADICAL_assert (*i);
255 CADICAL_assert (i != end);
256 while (i != end && (lit = *i++))
257 clause.push_back (lit);
258 if (!it.witness (clause, witness, id))
259 return false;
260 clause.clear ();
261 witness.clear ();
262 } while (i != end);
263 }
264 return true;
265}
266
267/*------------------------------------------------------------------------*/
268
270 if (!internal->proof || concluded)
271 return;
272 concluded = true;
273 if (!extended)
274 extend ();
275 vector<int> model;
276 for (int idx = 1; idx <= max_var; idx++) {
277 if (ervars[idx])
278 continue;
279 const int lit = ival (idx);
280 model.push_back (lit);
281 }
282 internal->proof->conclude_sat (model);
283}
284
285} // namespace CaDiCaL
286
unsigned int uint32_t
Definition Fxch.h:32
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define LOG(...)
virtual bool witness(const std::vector< int > &clause, const std::vector< int > &witness, int64_t id=0)=0
#define PHASE(...)
Definition message.hpp:52
#define STOP(P)
Definition profile.hpp:158
#define START(P)
Definition profile.hpp:150
int lit
Definition satVec.h:130
bool traverse_witnesses_backward(WitnessIterator &)
void push_witness_literal_on_extension_stack(int ilit)
bool traverse_witnesses_forward(WitnessIterator &)
bool marked(const vector< bool > &map, int elit) const
Definition external.hpp:216
int ival(int elit) const
Definition external.hpp:325
vector< bool > witness
Definition external.hpp:87
void push_id_on_extension_stack(int64_t id)
void push_external_clause_and_witness_on_extension_stack(const vector< int > &clause, const vector< int > &witness, int64_t id)
vector< int > extension
Definition external.hpp:85
void push_zero_on_extension_stack()
vector< bool > vals
Definition external.hpp:66
void push_clause_literal_on_extension_stack(int ilit)
Internal * internal
Definition external.hpp:61
vector< int > e2i
Definition external.hpp:67
void push_binary_clause_on_extension_stack(int64_t id, int witness, int other)
void init(int new_max_var, bool extension=false)
void push_clause_on_extension_stack(Clause *)
vector< bool > ervars
Definition external.hpp:90
signed char mark
Definition value.h:8