ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_shrink.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4#include "reap.hpp"
5
7
8namespace CaDiCaL {
9
11#ifdef LOGGING
12 size_t reset = 0;
13#endif
14 for (const auto &lit : shrinkable) {
15 LOG ("resetting lit %i", lit);
16 Flags &f = flags (lit);
18 f.shrinkable = false;
19#ifdef LOGGING
20 ++reset;
21#endif
22 }
23 LOG ("resetting %zu shrinkable variables", reset);
24}
25
27 int blevel, std::vector<int>::size_type minimized_start) {
28#ifdef LOGGING
29 size_t marked = 0, reset = 0;
30#endif
31#ifndef CADICAL_NDEBUG
32 unsigned kept = 0, minireset = 0;
33 for (; minimized_start < minimized.size (); ++minimized_start) {
34 const int lit = minimized[minimized_start];
35 Flags &f = flags (lit);
36 const Var &v = var (lit);
37 if (v.level == blevel) {
39 ++minireset;
40 } else
41 ++kept;
42 }
43 (void) kept;
44 (void) minireset;
45#else
46 (void) blevel;
47 (void) minimized_start;
48#endif
49
50 for (const int lit : shrinkable) {
51 Flags &f = flags (lit);
54 f.shrinkable = false;
55#ifdef LOGGING
56 ++reset;
57#endif
58 if (f.removable)
59 continue;
60 f.removable = true;
61 minimized.push_back (lit);
62#ifdef LOGGING
63 ++marked;
64#endif
65 }
66 LOG ("resetting %zu shrinkable variables", reset);
67 LOG ("marked %zu removable variables", marked);
68}
69
70int inline Internal::shrink_literal (int lit, int blevel,
71 unsigned max_trail) {
72 CADICAL_assert (val (lit) < 0);
73
74 Flags &f = flags (lit);
75 Var &v = var (lit);
76 CADICAL_assert (v.level <= blevel);
77
78 if (!v.level) {
79 LOG ("skipping root level assigned %d", (lit));
80 return 0;
81 }
82
83 if (v.reason == external_reason) {
84 CADICAL_assert (!opts.exteagerreasons);
86 if (!v.reason) {
88 return 0;
89 }
90 }
92 if (f.shrinkable) {
93 LOG ("skipping already shrinkable literal %d", (lit));
94 return 0;
95 }
96
97 if (v.level < blevel) {
98 if (f.removable) {
99 LOG ("skipping removable thus shrinkable %d", (lit));
100 return 0;
101 }
102 const bool always_minimize_on_lower_blevel = (opts.shrink > 2);
103 if (always_minimize_on_lower_blevel && minimize_literal (-lit, 1)) {
104 LOG ("minimized thus shrinkable %d", (lit));
105 return 0;
106 }
107 LOG ("literal %d on lower blevel %u < %u not removable/shrinkable",
108 (lit), v.level, blevel);
109 return -1;
110 }
111
112 LOG ("marking %d as shrinkable", lit);
113 f.shrinkable = true;
114 f.poison = false;
115 shrinkable.push_back (lit);
116 if (opts.shrinkreap) {
117 CADICAL_assert (max_trail < trail.size ());
118 const unsigned dist = max_trail - v.trail;
119 reap.push (dist);
120 }
121 return 1;
122}
123
125 int uip, int blevel, std::vector<int>::reverse_iterator &rbegin_block,
126 std::vector<int>::reverse_iterator &rend_block,
127 std::vector<int>::size_type minimized_start, const int uip0) {
128 CADICAL_assert (clause[0] == uip0);
129
130 LOG ("UIP on level %u, uip: %i (replacing by %i)", blevel, uip, uip0);
131 CADICAL_assert (rend_block > rbegin_block);
132 CADICAL_assert (rend_block < clause.rend ());
133 unsigned block_shrunken = 0;
134 *rbegin_block = -uip;
135 Var &v = var (-uip);
136 Level &l = control[v.level];
137 l.seen.trail = v.trail;
138 l.seen.count = 1;
139
140 Flags &f = flags (-uip);
141 if (!f.seen) {
142 analyzed.push_back (-uip);
143 f.seen = true;
144 }
145
146 flags (-uip).keep = true;
147 for (auto p = rbegin_block + 1; p != rend_block; ++p) {
148 const int lit = *p;
149 if (lit == -uip0)
150 continue;
151 *p = uip0;
152 // if (lit == -uip) continue;
153 ++block_shrunken;
154 CADICAL_assert (clause[0] == uip0);
155 }
156 mark_shrinkable_as_removable (blevel, minimized_start);
157 CADICAL_assert (clause[0] == uip0);
158 return block_shrunken;
159}
160
162 const std::vector<int>::reverse_iterator &rbegin_block,
163 const std::vector<int>::reverse_iterator &rend_block,
164 unsigned &block_minimized, const int uip0) {
165 STOP (shrink);
166 START (minimize);
167 CADICAL_assert (rend_block > rbegin_block);
168 LOG ("no UIP found, now minimizing");
169 for (auto p = rbegin_block; p != rend_block; ++p) {
170 CADICAL_assert (p != clause.rend () - 1);
171 const int lit = *p;
172 if (opts.minimize && minimize_literal (-lit)) {
173 CADICAL_assert (!flags (lit).keep);
174 ++block_minimized;
175 *p = uip0;
176 } else {
177 flags (lit).keep = true;
178 CADICAL_assert (flags (lit).keep);
179 }
180 }
181 STOP (minimize);
182 START (shrink);
183}
184
186 const std::vector<int>::reverse_iterator &rbegin_block,
187 const std::vector<int>::reverse_iterator &rend_block, int blevel,
188 unsigned max_trail) {
189 CADICAL_assert (rbegin_block < rend_block);
190 for (auto p = rbegin_block; p != rend_block; ++p) {
191 CADICAL_assert (p != clause.rend () - 1);
192 CADICAL_assert (!flags (*p).keep);
193 const int lit = *p;
194 LOG ("pushing lit %i of blevel %i", lit, var (lit).level);
195#ifndef CADICAL_NDEBUG
196 int tmp =
197#endif
198 shrink_literal (lit, blevel, max_trail);
199 CADICAL_assert (tmp > 0);
200 }
201}
202
203unsigned inline Internal::shrink_next (int blevel, unsigned &open,
204 unsigned &max_trail) {
205 const auto &t = &trail;
206 if (opts.shrinkreap) {
207 CADICAL_assert (!reap.empty ());
208 const unsigned dist = reap.pop ();
209 --open;
210 CADICAL_assert (dist <= max_trail);
211 const unsigned pos = max_trail - dist;
212 CADICAL_assert (pos < t->size ());
213 const int uip = (*t)[pos];
214 CADICAL_assert (val (uip) > 0);
215 LOG ("trying to shrink literal %d at trail[%u] and level %d", uip, pos,
216 blevel);
217 return uip;
218 } else {
219 int uip;
220#ifndef CADICAL_NDEBUG
221 unsigned init_max_trail = max_trail;
222#endif
223 do {
224 CADICAL_assert (max_trail <= init_max_trail);
225 uip = (*t)[max_trail--];
226 } while (!flags (uip).shrinkable);
227 --open;
228 LOG ("open is now %d, uip = %d, level %d", open, uip, blevel);
229 return uip;
230 }
231 (void) blevel;
232}
233
234unsigned inline Internal::shrink_along_reason (int uip, int blevel,
235 bool resolve_large_clauses,
236 bool &failed_ptr,
237 unsigned max_trail) {
238 LOG ("shrinking along the reason of lit %i", uip);
239 unsigned open = 0;
240#ifndef CADICAL_NDEBUG
241 const Flags &f = flags (uip);
242#endif
243 const Var &v = var (uip);
244
246 CADICAL_assert (v.level == blevel);
248
249 if (opts.minimizeticks)
250 stats.ticks.search[stable]++;
251
252 if (resolve_large_clauses || v.reason->size == 2) {
253 const Clause &c = *v.reason;
254 LOG (v.reason, "resolving with reason");
255 for (int lit : c) {
256 if (lit == uip)
257 continue;
258 CADICAL_assert (val (lit) < 0);
259 int tmp = shrink_literal (lit, blevel, max_trail);
260 if (tmp < 0) {
261 failed_ptr = true;
262 break;
263 }
264 if (tmp > 0) {
265 ++open;
266 }
267 }
268 } else {
269 failed_ptr = true;
270 }
271 return open;
272}
273
274unsigned
275Internal::shrink_block (std::vector<int>::reverse_iterator &rbegin_lits,
276 std::vector<int>::reverse_iterator &rend_block,
277 int blevel, unsigned &open,
278 unsigned &block_minimized, const int uip0,
279 unsigned max_trail) {
280 CADICAL_assert (shrinkable.empty ());
281 CADICAL_assert (blevel <= this->level);
282 CADICAL_assert (open < clause.size ());
283 CADICAL_assert (rbegin_lits >= clause.rbegin ());
284 CADICAL_assert (rend_block < clause.rend ());
285 CADICAL_assert (rbegin_lits < rend_block);
286 CADICAL_assert (opts.shrink);
287
288#ifdef LOGGING
289
290 LOG ("trying to shrink %u literals on level %u", open, blevel);
291
292 const auto &t = &trail;
293
294 LOG ("maximum trail position %zd on level %u", t->size (), blevel);
295 if (opts.shrinkreap)
296 LOG ("shrinking up to %u", max_trail);
297#endif
298
299 const bool resolve_large_clauses = (opts.shrink > 1);
300 bool failed = false;
301 unsigned block_shrunken = 0;
302 std::vector<int>::size_type minimized_start = minimized.size ();
303 int uip = uip0;
304 unsigned max_trail2 = max_trail;
305
306 if (!failed) {
307 push_literals_of_block (rbegin_lits, rend_block, blevel, max_trail);
308 CADICAL_assert (!opts.shrinkreap || reap.size () == open);
309
310 CADICAL_assert (open > 0);
311 while (!failed) {
312 CADICAL_assert (!opts.shrinkreap || reap.size () == open);
313 uip = shrink_next (blevel, open, max_trail);
314 if (open == 0) {
315 break;
316 }
317 open += shrink_along_reason (uip, blevel, resolve_large_clauses,
318 failed, max_trail2);
319 CADICAL_assert (open >= 1);
320 }
321
322 if (!failed)
323 LOG ("shrinking found UIP %i on level %i (open: %d)", uip, blevel,
324 open);
325 else
326 LOG ("shrinking failed on level %i", blevel);
327 }
328
329 if (failed)
330 reset_shrinkable (), shrunken_block_no_uip (rbegin_lits, rend_block,
331 block_minimized, uip0);
332 else
333 block_shrunken = shrunken_block_uip (uip, blevel, rbegin_lits,
334 rend_block, minimized_start, uip0);
335
336 if (opts.shrinkreap)
337 reap.clear ();
338 shrinkable.clear ();
339 return block_shrunken;
340}
341
342// Smaller level and trail. Comparing literals on their level is necessary
343// for chronological backtracking, since trail order might in this case not
344// respect level order.
345
349 typedef uint64_t Type;
351 Var &v = internal->var (a);
352 uint64_t res = v.level;
353 res <<= 32;
354 res |= v.trail;
355 return ~res;
356 }
357};
358
362 bool operator() (const int &a, const int &b) const {
365 }
366};
367
368// Finds the beginning of the block (rend_block, non-included) ending at
369// rend_block (included). Then tries to shrinks and minimizes literals the
370// block
371std::vector<int>::reverse_iterator Internal::minimize_and_shrink_block (
372 std::vector<int>::reverse_iterator &rbegin_block,
373 unsigned &total_shrunken, unsigned &total_minimized, const int uip0)
374
375{
376 LOG ("shrinking block");
377 CADICAL_assert (rbegin_block < clause.rend () - 1);
378 int blevel;
379 unsigned open = 0;
380 unsigned max_trail;
381
382 // find begining of block;
383 std::vector<int>::reverse_iterator rend_block;
384 {
385 CADICAL_assert (rbegin_block <= clause.rend ());
386 const int lit = *rbegin_block;
387 const int idx = vidx (lit);
388 blevel = vtab[idx].level;
389 max_trail = vtab[idx].trail;
390 LOG ("Block at level %i (first lit: %i)", blevel, lit);
391
392 rend_block = rbegin_block;
393 bool finished;
394 do {
395 CADICAL_assert (rend_block < clause.rend () - 1);
396 const int lit = *(++rend_block);
397 const int idx = vidx (lit);
398 finished = (blevel != vtab[idx].level);
399 if (!finished && (unsigned) vtab[idx].trail > max_trail)
400 max_trail = vtab[idx].trail;
401 ++open;
402 LOG (
403 "testing if lit %i is on the same level (of lit: %i, global: %i)",
404 lit, vtab[idx].level, blevel);
405
406 } while (!finished);
407 }
408 CADICAL_assert (open > 0);
409 CADICAL_assert (open < clause.size ());
410 CADICAL_assert (rbegin_block < clause.rend ());
411 CADICAL_assert (rend_block < clause.rend ());
412
413 unsigned block_shrunken = 0, block_minimized = 0;
414 if (open < 2) {
415 flags (*rbegin_block).keep = true;
416 minimized.push_back (*rbegin_block);
417 } else
418 block_shrunken = shrink_block (rbegin_block, rend_block, blevel, open,
419 block_minimized, uip0, max_trail);
420
421 LOG ("shrunken %u literals on level %u (including %u minimized)",
422 block_shrunken, blevel, block_minimized);
423
424 total_shrunken += block_shrunken;
425 total_minimized += block_minimized;
426
427 return rend_block;
428}
429
431 CADICAL_assert (opts.minimize || opts.shrink > 0);
432 LOG (clause, "shrink first UIP clause");
433
434 START (shrink);
435 external->check_learned_clause (); // check 1st UIP learned clause first
436 MSORT (opts.radixsortlim, clause.begin (), clause.end (),
438 unsigned total_shrunken = 0;
439 unsigned total_minimized = 0;
440
441 LOG (clause, "shrink first UIP clause (CADICAL_asserting lit: %i)", clause[0]);
442
443 auto rend_lits = clause.rend () - 1;
444 auto rend_block = clause.rbegin ();
445 const int uip0 = clause[0];
446
447 // for direct LRAT we remember how the clause used to look
448 vector<int> old_clause_lrat;
450 if (lrat)
451 for (auto &i : clause)
452 old_clause_lrat.push_back (i);
453
454 while (rend_block != rend_lits) {
455 rend_block = minimize_and_shrink_block (rend_block, total_shrunken,
456 total_minimized, uip0);
457 }
458
459 LOG (clause,
460 "post shrink pass (with uips, not removed) first UIP clause");
461 LOG (old_clause_lrat, "(used for lratdirect) before shrink: clause");
462#if defined(LOGGING) || !defined(CADICAL_NDEBUG)
463 const unsigned old_size = clause.size ();
464#endif
465 std::vector<int> stack;
466 {
467 std::vector<int>::size_type i = 1;
468 for (std::vector<int>::size_type j = 1; j < clause.size (); ++j) {
469 CADICAL_assert (i <= j);
470 clause[i] = clause[j];
471 if (lrat) {
472 CADICAL_assert (j < old_clause_lrat.size ());
473 CADICAL_assert (mini_chain.empty ());
474 if (clause[j] != old_clause_lrat[j]) {
475 calculate_minimize_chain (-old_clause_lrat[j], stack);
476 for (auto p : mini_chain) {
477 minimize_chain.push_back (p);
478 }
479 mini_chain.clear ();
480 }
481 }
482 if (clause[j] == uip0) {
483 continue;
484 }
485 CADICAL_assert (flags (clause[i]).keep);
486 ++i;
487 LOG ("keeping literal %i", clause[j]);
488 }
489 clause.resize (i);
490 }
491 CADICAL_assert (old_size ==
492 (unsigned) clause.size () + total_shrunken + total_minimized);
493 LOG (clause, "after shrinking first UIP clause");
494 LOG ("clause shrunken by %zd literals (including %u minimized)",
495 old_size - clause.size (), total_minimized);
496
497 stats.shrunken += total_shrunken;
498 stats.minishrunken += total_minimized;
499 STOP (shrink);
500
501 START (minimize);
503 for (auto p = minimize_chain.rbegin (); p != minimize_chain.rend ();
504 p++) {
505 lrat_chain.push_back (*p);
506 }
507 minimize_chain.clear ();
508 STOP (minimize);
509}
510
511} // namespace CaDiCaL
512
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define LOG(...)
bool pos
Definition globals.c:30
Cube * p
Definition exorList.c:222
const char * flags()
#define STOP(P)
Definition profile.hpp:158
#define START(P)
Definition profile.hpp:150
#define MSORT(LIMIT, FIRST, LAST, RANK, LESS)
Definition radix.hpp:173
int lit
Definition satVec.h:130
bool removable
Definition flags.hpp:17
bool shrinkable
Definition flags.hpp:18
unsigned shrunken_block_uip(int, int, std::vector< int >::reverse_iterator &, std::vector< int >::reverse_iterator &, std::vector< int >::size_type, const int)
void mark_shrinkable_as_removable(int, std::vector< int >::size_type)
External * external
Definition internal.hpp:312
vector< int > analyzed
Definition internal.hpp:267
Var & var(int lit)
Definition internal.hpp:452
vector< int64_t > lrat_chain
Definition internal.hpp:210
int vidx(int lit) const
Definition internal.hpp:395
Flags & flags(int lit)
Definition internal.hpp:454
vector< int > trail
Definition internal.hpp:259
void shrunken_block_no_uip(const std::vector< int >::reverse_iterator &, const std::vector< int >::reverse_iterator &, unsigned &, const int)
vector< Var > vtab
Definition internal.hpp:231
void calculate_minimize_chain(int lit, std::vector< int > &stack)
Clause * learn_external_reason_clause(int lit, int falsified_elit=0, bool no_backtrack=false)
int shrink_literal(int, int, unsigned)
signed char val(int lit) const
signed char marked(int lit) const
Definition internal.hpp:478
bool minimize_literal(int lit, int depth=0)
std::vector< int >::reverse_iterator minimize_and_shrink_block(std::vector< int >::reverse_iterator &, unsigned int &, unsigned int &, const int)
void push_literals_of_block(const std::vector< int >::reverse_iterator &, const std::vector< int >::reverse_iterator &, int, unsigned)
unsigned shrink_along_reason(int, int, bool, bool &, unsigned)
unsigned shrink_block(std::vector< int >::reverse_iterator &, std::vector< int >::reverse_iterator &, int, unsigned &, unsigned &, const int, unsigned)
vector< int64_t > minimize_chain
Definition internal.hpp:212
vector< int > shrinkable
Definition internal.hpp:271
vector< int > minimized
Definition internal.hpp:270
Clause * external_reason
Definition internal.hpp:245
vector< Level > control
Definition internal.hpp:282
unsigned shrink_next(int, unsigned &, unsigned &)
vector< int64_t > mini_chain
Definition internal.hpp:211
vector< int > clause
Definition internal.hpp:260
struct CaDiCaL::Level::@023147271015376226021074167111310127126167046351 seen
int level
Definition var.hpp:19
int trail
Definition var.hpp:20
Clause * reason
Definition var.hpp:21
bool operator()(const int &a, const int &b) const
unsigned size
Definition vector.h:35