ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_flip.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
9bool Internal::flip (int lit) {
10
11 // Do not try to flip inactive literals except for unused variables.
12
13 if (!active (lit) && !flags (lit).unused ())
14 return false;
15
16 /*
17 if (flags (lit).unused ()) {
18 CADICAL_assert (lit <= max_var);
19 mark_active (lit);
20 set_val (lit, 1);
21 return true;
22 }
23 */
24
25 // TODO: Unused case is not handled yet.
26 // if (flags (lit).unused ()) return false;
27
28 // Need to reestablish proper watching invariants as if there are no
29 // blocking literals as flipping in principle does not work with them.
30
31 if (propergated < trail.size ())
32 propergate ();
33
34 LOG ("trying to flip %d", lit);
35
36 const int idx = vidx (lit);
37 const signed char original_value = vals[idx];
38 CADICAL_assert (original_value);
39 lit = original_value < 0 ? -idx : idx;
40 CADICAL_assert (val (lit) > 0);
41
42 // Here we go over all the clauses in which 'lit' is watched by 'lit' and
43 // check whether assigning 'lit' to false would break watching invariants
44 // or even make the clause false. We also try to find replacement
45 // watches in case this fixes the watching invariant. This code is very
46 // similar to propagation of a literal in 'Internal::propagate'.
47
48 bool res = true;
49
50 Watches &ws = watches (lit);
51 const const_watch_iterator eow = ws.end ();
52 watch_iterator bow = ws.begin ();
53
54 // We first go over binary watches/clauses first as this is cheaper and
55 // has higher chance of failure and we can not use blocking literals.
56
57 for (const_watch_iterator i = bow; i != eow; i++) {
58 const Watch w = *i;
59 if (!w.binary ())
60 continue;
61 const signed char b = val (w.blit);
62 if (b > 0)
63 continue;
64 CADICAL_assert (b < 0);
65 res = false;
66 break;
67 }
68
69 if (res) {
71 watch_iterator j = bow;
72
73 while (i != eow) {
74
75 const Watch w = *j++ = *i++;
76
77 if (w.binary ())
78 continue;
79
80 if (w.clause->garbage) {
81 j--;
82 continue;
83 }
84
86
87 const int other = lits[0] ^ lits[1] ^ lit;
88 const signed char u = val (other);
89 if (u > 0)
90 continue;
91
92 const int size = w.clause->size;
93 const literal_iterator middle = lits + w.clause->pos;
94 const const_literal_iterator end = lits + size;
95 literal_iterator k = middle;
96
97 int r = 0;
98 signed char v = -1;
99 while (k != end && (v = val (r = *k)) < 0)
100 k++;
101 if (v < 0) {
102 k = lits + 2;
103 CADICAL_assert (w.clause->pos <= size);
104 while (k != middle && (v = val (r = *k)) < 0)
105 k++;
106 }
107
108 if (v < 0) {
109 res = false;
110 break;
111 }
112
113 CADICAL_assert (v > 0);
114 CADICAL_assert (lits + 2 <= k), CADICAL_assert (k <= w.clause->end ());
115 w.clause->pos = k - lits;
116 lits[0] = other, lits[1] = r, *k = lit;
117 watch_literal (r, lit, w.clause);
118 j--;
119 }
120
121 if (j != i) {
122
123 while (i != eow)
124 *j++ = *i++;
125
126 ws.resize (j - ws.begin ());
127 }
128 }
129#ifdef LOGGING
130 if (res)
131 LOG ("literal %d can be flipped", lit);
132 else
133 LOG ("literal %d can not be flipped", lit);
134#endif
135
136 if (res) {
137
138 const int idx = vidx (lit);
139 const signed char original_value = vals[idx];
140 CADICAL_assert (original_value);
141 lit = original_value < 0 ? -idx : idx;
142 CADICAL_assert (val (lit) > 0);
143
144 LOG ("flipping value of %d = 1 to %d = -1", lit, lit);
145
146 set_val (idx, -original_value);
147 CADICAL_assert (val (-lit) > 0);
148 CADICAL_assert (val (lit) < 0);
149
150 Var &v = var (idx);
152 trail[v.trail] = -lit;
153 if (opts.ilb) {
154 if (!tainted_literal)
156 else {
158 if (v.level < var (tainted_literal).level) {
160 }
161 }
162 }
163 } else
164 LOG ("flipping value of %d failed", lit);
165
166 return res;
167}
168
170
171 // Can not check inactive literals except for unused variables.
172
173 if (!active (lit) && !flags (lit).unused ())
174 return false;
175
176 /*
177 if (flags (lit).unused ()) {
178 CADICAL_assert (lit <= max_var);
179 mark_active (lit);
180 return true;
181 }
182 */
183 // TODO: Unused case is not handled yet
184 // if (flags (lit).unused ()) return false;
185
186 // Need to reestablish proper watching invariants as if there are no
187 // blocking literals as flipping in principle does not work with them.
188
189 if (propergated < trail.size ())
190 propergate ();
191
192 LOG ("checking whether %d is flippable", lit);
193
194 const int idx = vidx (lit);
195 const signed char original_value = vals[idx];
196 CADICAL_assert (original_value);
197 lit = original_value < 0 ? -idx : idx;
198 CADICAL_assert (val (lit) > 0);
199
200 // Here we go over all the clauses in which 'lit' is watched by 'lit' and
201 // check whether assigning 'lit' to false would break watching invariants
202 // or even make the clause false. In contrast to 'flip' we do not try to
203 // find replacement literals but do use blocking literals'. Therefore we
204 // also do not split the traversal code into two parts.
205
206 bool res = true;
207
208 Watches &ws = watches (lit);
209 const const_watch_iterator eow = ws.end ();
210 for (watch_iterator i = ws.begin (); i != eow; i++) {
211
212 const Watch w = *i;
213 const signed char b = val (w.blit);
214 if (b > 0)
215 continue;
216 CADICAL_assert (b < 0);
217
218 if (w.binary ()) {
219 res = false;
220 break;
221 }
222
223 if (w.clause->garbage)
224 continue;
225
227
228 const int other = lits[0] ^ lits[1] ^ lit;
229 const signed char u = val (other);
230 if (u > 0) {
231 i->blit = other;
232 continue;
233 }
234
235 const int size = w.clause->size;
236 const literal_iterator middle = lits + w.clause->pos;
237 const const_literal_iterator end = lits + size;
238 literal_iterator k = middle;
239
240 int r = 0;
241 signed char v = -1;
242 while (k != end && (v = val (r = *k)) < 0)
243 k++;
244 if (v < 0) {
245 k = lits + 2;
246 CADICAL_assert (w.clause->pos <= size);
247 while (k != middle && (v = val (r = *k)) < 0)
248 k++;
249 }
250
251 if (v < 0) {
252 res = false;
253 break;
254 }
255
256 CADICAL_assert (v > 0);
257 CADICAL_assert (lits + 2 <= k);
258 CADICAL_assert (k <= w.clause->end ());
259 w.clause->pos = k - lits;
260 i->blit = r;
261 }
262
263#ifdef LOGGING
264 if (res)
265 LOG ("literal %d can be flipped", lit);
266 else
267 LOG ("literal %d can not be flipped", lit);
268#endif
269
270 return res;
271}
272
273} // namespace CaDiCaL
274
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define LOG(...)
Watches::const_iterator const_watch_iterator
Definition watch.hpp:48
int * literal_iterator
Definition clause.hpp:17
const int * const_literal_iterator
Definition clause.hpp:18
vector< Watch > Watches
Definition watch.hpp:45
Watches::iterator watch_iterator
Definition watch.hpp:47
int lit
Definition satVec.h:130
literal_iterator begin()
Definition clause.hpp:131
void watch_literal(int lit, int blit, Clause *c)
Definition internal.hpp:623
Var & var(int lit)
Definition internal.hpp:452
int vidx(int lit) const
Definition internal.hpp:395
Flags & flags(int lit)
Definition internal.hpp:454
vector< int > trail
Definition internal.hpp:259
const Sange lits
Definition internal.hpp:325
signed char val(int lit) const
void set_val(int lit, signed char val)
bool active(int lit)
Definition internal.hpp:360
signed char * vals
Definition internal.hpp:221
bool flippable(int lit)
bool flip(int lit)
int level
Definition var.hpp:19
int trail
Definition var.hpp:20
bool binary() const
Definition watch.hpp:42
Clause * clause
Definition watch.hpp:35
vector watches
Definition watch.h:49