ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_minimize.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
9// Functions for learned clause minimization. We only have the recursive
10// version, which actually really is implemented recursively. We also
11// played with a derecursified version, which however was more complex and
12// slower. The trick to keep potential stack exhausting recursion under
13// guards is to explicitly limit the recursion depth.
14
15// Instead of signatures as in the original implementation in MiniSAT and
16// our corresponding paper, we use the 'poison' idea of Allen Van Gelder to
17// mark unsuccessful removal attempts, then Donald Knuth's idea to abort
18// minimization if only one literal was seen on the level and a new idea of
19// also aborting if the earliest seen literal was assigned afterwards.
20
21bool Internal::minimize_literal (int lit, int depth) {
22 LOG ("attempt to minimize lit %d at depth %d", lit, depth);
23 CADICAL_assert (val (lit) > 0);
24 Flags &f = flags (lit);
25 Var &v = var (lit);
26 if (!v.level || f.removable || f.keep)
27 return true;
28 if (!v.reason || f.poison || v.level == level)
29 return false;
30 const Level &l = control[v.level];
31 if (!depth && l.seen.count < 2)
32 return false; // Don Knuth's idea
33 if (v.trail <= l.seen.trail)
34 return false; // new early abort
35 if (depth > opts.minimizedepth)
36 return false;
37 bool res = true;
39 if (opts.minimizeticks)
40 stats.ticks.search[stable]++;
41 if (v.reason == external_reason) {
42 CADICAL_assert (!opts.exteagerreasons);
44 if (!v.reason) {
46 return true;
47 }
48 }
50 const const_literal_iterator end = v.reason->end ();
52 for (i = v.reason->begin (); res && i != end; i++) {
53 const int other = *i;
54 if (other == lit)
55 continue;
56 res = minimize_literal (-other, depth + 1);
57 }
58 if (res)
59 f.removable = true;
60 else
61 f.poison = true;
62 minimized.push_back (lit);
63 if (!depth) {
64 LOG ("minimizing %d %s", lit, res ? "succeeded" : "failed");
65 }
66 return res;
67}
68
69// Sorting the clause before minimization with respect to the trail order
70// (literals with smaller trail height first) is necessary but natural and
71// might help to minimize the required recursion depth too.
72
76 typedef unsigned Type;
77 Type operator() (const int &a) const {
78 CADICAL_assert (internal->val (a));
79 return (unsigned) internal->var (a).trail;
80 }
81};
82
86 bool operator() (const int &a, const int &b) const {
87 return internal->var (a).trail < internal->var (b).trail;
88 }
89};
90
94 typedef uint64_t Type;
95 Type operator() (const int &a) const {
96 CADICAL_assert (internal->val (a));
97 Var &v = internal->var (a);
98 uint64_t res = v.level;
99 res <<= 32;
100 res |= v.trail;
101 return res;
102 }
103};
104
113
115 START (minimize);
116 LOG (clause, "minimizing first UIP clause");
117
118 external->check_learned_clause (); // check 1st UIP learned clause first
120
121 CADICAL_assert (minimized.empty ());
123 const auto end = clause.end ();
124 auto j = clause.begin (), i = j;
125 std::vector<int> stack;
126 for (; i != end; i++) {
127 if (minimize_literal (-*i)) {
128 if (lrat) {
129 CADICAL_assert (mini_chain.empty ());
130 calculate_minimize_chain (-*i, stack);
131 for (auto p : mini_chain) {
132 minimize_chain.push_back (p);
133 }
134 mini_chain.clear ();
135 }
136 stats.minimized++;
137 } else
138 flags (*j++ = *i).keep = true;
139 }
140 LOG ("minimized %zd literals", (size_t) (clause.end () - j));
141 if (j != end)
142 clause.resize (j - clause.begin ());
144 for (auto p = minimize_chain.rbegin (); p != minimize_chain.rend ();
145 p++) {
146 lrat_chain.push_back (*p);
147 }
148 minimize_chain.clear ();
149 STOP (minimize);
150}
151
152// go backwards in reason graph and add ids
153// mini_chain is in correct order so we have to add it to minimize_chain
154// and then reverse when we put it on lrat_chain
155//
156// We have to use the non-recursive as we cannot limit the depth like the
157// minimize version. Unlike the minimize version, we have to keep literals
158// on the stack in order to push its reason later.
159void Internal::calculate_minimize_chain (int lit, std::vector<int> &stack) {
160 CADICAL_assert (stack.empty ());
161 stack.push_back (vidx (lit));
162
163 while (!stack.empty ()) {
164 const int idx = stack.back ();
165 CADICAL_assert (idx);
166 stack.pop_back ();
167 if (idx < 0) {
168 Var &v = var (idx);
169 mini_chain.push_back (v.reason->id);
170 continue;
171 }
172 CADICAL_assert (idx);
173 Flags &f = flags (idx);
174 Var &v = var (idx);
175 if (f.keep || f.added || f.poison) {
176 continue;
177 }
178 if (!v.level) {
179 if (f.seen)
180 continue;
181 f.seen = true;
182 unit_analyzed.push_back (idx);
183 const int lit = val (idx) > 0 ? idx : -idx;
184 int64_t id = unit_id (lit);
185 unit_chain.push_back (id);
186 continue;
187 }
188 f.added = true;
190 const const_literal_iterator end = v.reason->end ();
192 LOG (v.reason, "LRAT chain for lit %d at depth %zd by going over", lit,
193 stack.size ());
194 stack.push_back (-idx);
195 for (i = v.reason->begin (); i != end; i++) {
196 const int other = *i;
197 if (other == idx)
198 continue;
199 stack.push_back (vidx (other));
200 }
201 }
202 CADICAL_assert (stack.empty ());
203}
204
205// Sort the literals in reverse assignment order (thus trail order) to
206// establish the base case of the recursive minimization algorithm in the
207// positive case (where a literal with 'keep' true is hit).
208//
210 MSORT (opts.radixsortlim, clause.begin (), clause.end (),
213}
214
216 LOG ("clearing %zd minimized literals", minimized.size ());
217 for (const auto &lit : minimized) {
218 Flags &f = flags (lit);
219 f.poison = f.removable = f.shrinkable = f.added = false;
220 }
221 for (const auto &lit : clause)
223 flags (lit).shrinkable =
224 flags (lit).added = false;
225 minimized.clear ();
226}
227
228} // namespace CaDiCaL
229
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define LOG(...)
Cube * p
Definition exorList.c:222
const char * flags()
const int * const_literal_iterator
Definition clause.hpp:18
#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
literal_iterator begin()
Definition clause.hpp:131
literal_iterator end()
Definition clause.hpp:132
bool removable
Definition flags.hpp:17
bool shrinkable
Definition flags.hpp:18
External * external
Definition internal.hpp:312
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
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)
signed char val(int lit) const
int64_t unit_id(int lit) const
Definition internal.hpp:434
bool minimize_literal(int lit, int depth=0)
vector< int64_t > unit_chain
Definition internal.hpp:213
vector< int > unit_analyzed
Definition internal.hpp:268
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
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
bool operator()(const int &a, const int &b) const