ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
compact.c
Go to the documentation of this file.
1#include "compact.h"
2#include "inline.h"
3#include "inlineheap.h"
4#include "print.h"
5#include "resize.h"
6
7#include <string.h>
8
10
11static void reimport_literal (kissat *solver, unsigned eidx,
12 unsigned mlit) {
13 import *import = &PEEK_STACK (solver->import, eidx);
16 LOG ("reimporting external variable %u as internal literal %u (was %u)",
17 eidx, mlit, import->lit);
18 import->lit = mlit;
19}
20
21unsigned kissat_compact_literals (kissat *solver, unsigned *mfixed_ptr) {
22 INC (compacted);
23#if !defined(KISSAT_QUIET) || !defined(KISSAT_NDEBUG)
24 const unsigned active = solver->active;
25#ifndef KISSAT_QUIET
26 const unsigned inactive = solver->vars - active;
27 kissat_phase (solver, "compact", GET (compacted),
28 "compacting garbage collection "
29 "(%u inactive variables %.2f%%)",
30 inactive, kissat_percent (inactive, solver->vars));
31#endif
32#endif
33#ifdef LOGGING
34 KISSAT_assert (!solver->compacting);
35 solver->compacting = true;
36#endif
37 unsigned mfixed = INVALID_LIT;
38 unsigned vars = 0;
39 for (all_variables (iidx)) {
40 const flags *const flags = FLAGS (iidx);
41 if (flags->eliminated)
42 continue;
43 const unsigned ilit = LIT (iidx);
44 unsigned mlit;
45 if (flags->fixed) {
46 const value value = kissat_fixed (solver, ilit);
48 if (mfixed == INVALID_LIT) {
49 mlit = mfixed = LIT (vars);
50 LOG2 ("first fixed %u mapped to %u assigned to %d", ilit, mfixed,
51 value);
52 if (value < 0)
53 mfixed = NOT (mfixed);
54 LOG2 ("all other fixed mapped to %u", mfixed);
55 vars++;
56 } else if (value < 0) {
57 mlit = NOT (mfixed);
58 LOG2 ("negatively fixed %u mapped to %u", ilit, mlit);
59 } else {
60 mlit = mfixed;
61 LOG2 ("positively fixed %u mapped to %u", ilit, mlit);
62 }
63 } else if (flags->active) {
65 mlit = LIT (vars);
66 LOG2 ("remapping %u to %u", ilit, mlit);
67 vars++;
68 } else {
69 const int elit = PEEK_STACK (solver->export_, iidx);
70 if (elit) {
71 const unsigned eidx = ABS (elit);
72 import *import = &PEEK_STACK (solver->import, eidx);
75 import->imported = false;
76 LOG2 ("external variable %d not imported anymore", eidx);
77 POKE_STACK (solver->export_, iidx, 0);
78 } else
79 LOG2 ("skipping inactive %u", ilit);
80 continue;
81 }
82 KISSAT_assert (mlit <= ilit);
83 KISSAT_assert (mlit != NOT (ilit));
84 if (mlit == ilit)
85 continue;
86 const int elit = PEEK_STACK (solver->export_, iidx);
87 const unsigned eidx = ABS (elit);
88 if (elit < 0)
89 mlit = NOT (mlit);
90 reimport_literal (solver, eidx, mlit);
91 }
92 *mfixed_ptr = mfixed;
93 LOG ("compacting to %u variables %.2f%% from %u", vars,
94 kissat_percent (vars, solver->vars), solver->vars);
95 KISSAT_assert (vars == active || vars == active + 1);
96 return vars;
97}
98
99static void compact_literal (kissat *solver, unsigned dst_lit,
100 unsigned src_lit) {
101 KISSAT_assert (dst_lit < src_lit);
102 KISSAT_assert (dst_lit != NOT (src_lit));
103 const unsigned dst_idx = IDX (dst_lit);
104 const unsigned src_idx = IDX (src_lit);
105 KISSAT_assert (dst_idx != src_idx);
106 LOG ("mapping old internal literal %u to %u", src_lit, dst_lit);
107 solver->assigned[dst_idx] = solver->assigned[src_idx];
108 solver->flags[dst_idx] = solver->flags[src_idx];
109
110 solver->phases.best[dst_idx] = solver->phases.best[src_idx];
111 solver->phases.saved[dst_idx] = solver->phases.saved[src_idx];
112 solver->phases.target[dst_idx] = solver->phases.target[src_idx];
113
114 const unsigned not_src_lit = NOT (src_lit);
115 const unsigned not_dst_lit = NOT (dst_lit);
116 solver->values[dst_lit] = solver->values[src_lit];
117 solver->values[not_dst_lit] = solver->values[not_src_lit];
118}
119
120static unsigned map_idx (kissat *solver, unsigned iidx) {
121 int elit = PEEK_STACK (solver->export_, iidx);
122 if (!elit)
123 return INVALID_IDX;
124 KISSAT_assert (elit);
125 const unsigned eidx = ABS (elit);
126 KISSAT_assert (eidx);
127 import *import = &PEEK_STACK (solver->import, eidx);
129 if (import->eliminated)
130 return INVALID_IDX;
131 const unsigned mlit = import->lit;
132 const unsigned midx = IDX (mlit);
133 KISSAT_assert (midx <= iidx);
134 return midx;
135}
136
137static void compact_queue (kissat *solver) {
138 LOG ("compacting queue");
139 links *links = solver->links, *l;
140 unsigned *p = &solver->queue.first, prev = DISCONNECT;
141 solver->queue.stamp = 0;
142 for (unsigned idx; !DISCONNECTED (idx = *p); p = &l->next) {
143 const unsigned midx = map_idx (solver, idx);
144 KISSAT_assert (midx != INVALID_IDX);
145 l = links + idx;
146 l->prev = prev;
147 l->stamp = ++solver->queue.stamp;
148 if (idx == solver->queue.search.idx) {
149 solver->queue.search.idx = midx;
150 solver->queue.search.stamp = l->stamp;
151 }
152 *p = prev = midx;
153 }
154 solver->queue.last = prev;
155 *p = DISCONNECT;
156 for (all_variables (idx)) {
157 const unsigned midx = map_idx (solver, idx);
158 if (midx == INVALID_IDX)
159 continue;
160 links[midx] = links[idx];
161 }
162}
163
164static void compact_stack (kissat *solver, unsigneds *stack) {
165 unsigned *q = BEGIN_STACK (*stack);
166 const unsigned *const end = END_STACK (*stack);
167 for (const unsigned *p = q; p != end; p++) {
168 const unsigned idx = *p;
169 const unsigned midx = map_idx (solver, idx);
170 if (midx == INVALID_IDX)
171 continue;
172 *q++ = midx;
173 }
174 SET_END_OF_STACK (*stack, q);
175 SHRINK_STACK (*stack);
176}
177
178static void compact_scores (kissat *solver, heap *old_scores,
179 unsigned vars) {
180 LOG ("compacting scores");
181
182 heap new_scores;
183 memset (&new_scores, 0, sizeof new_scores);
184 kissat_resize_heap (solver, &new_scores, vars);
185
186 if (old_scores->tainted) {
187 LOG ("copying scores of tainted old scores heap");
188 for (all_variables (idx)) {
189 const unsigned midx = map_idx (solver, idx);
190 if (midx == INVALID_IDX)
191 continue;
192 const double score = kissat_get_heap_score (old_scores, idx);
193 kissat_update_heap (solver, &new_scores, midx, score);
194 }
195 } else
196 LOG ("no need to copy scores of old untainted scores heap");
197
198 LOG ("now pushing mapped literals onto new heap");
199 for (all_stack (unsigned, idx, old_scores->stack)) {
200 const unsigned midx = map_idx (solver, idx);
201 if (midx == INVALID_IDX)
202 continue;
203 kissat_push_heap (solver, &new_scores, midx);
204 }
205
206 kissat_release_heap (solver, old_scores);
207 *old_scores = new_scores;
208}
209
210static void compact_trail (kissat *solver) {
211 LOG ("compacting trail");
212 const size_t size = SIZE_ARRAY (solver->trail);
213 for (size_t i = 0; i < size; i++) {
214 const unsigned ilit = PEEK_ARRAY (solver->trail, i);
215 const unsigned mlit = kissat_map_literal (solver, ilit, true);
216 KISSAT_assert (mlit != INVALID_LIT);
217 POKE_ARRAY (solver->trail, i, mlit);
218 const unsigned idx = IDX (ilit);
219 assigned *a = solver->assigned + idx;
220 if (!a->binary)
221 continue;
222 const unsigned other = a->reason;
224 const unsigned mother = kissat_map_literal (solver, other, true);
225 KISSAT_assert (mother != INVALID_LIT);
226 a->reason = mother;
227 }
228}
229
230static void compact_frames (kissat *solver) {
231 LOG ("compacting frames");
232 const size_t size = SIZE_STACK (solver->frames);
233 for (size_t level = 1; level < size; level++) {
234 frame *frame = &FRAME (level);
235 const unsigned ilit = frame->decision;
236 const unsigned mlit = kissat_map_literal (solver, ilit, true);
237 KISSAT_assert (mlit != INVALID_LIT);
238 frame->decision = mlit;
239 }
240}
241
242static void compact_export (kissat *solver, unsigned vars) {
243 LOG ("compacting export");
244 const size_t size = SIZE_STACK (solver->export_);
245 KISSAT_assert (size <= UINT_MAX);
246 KISSAT_assert (size == solver->vars);
247 for (unsigned iidx = 0; iidx < size; iidx++) {
248 const unsigned elit = PEEK_STACK (solver->export_, iidx);
249 if (!elit)
250 continue;
251 const unsigned midx = map_idx (solver, iidx);
252 if (midx == INVALID_IDX)
253 continue;
254 POKE_STACK (solver->export_, midx, elit);
255 }
256 RESIZE_STACK (solver->export_, vars);
257 SHRINK_STACK (solver->export_);
258#ifndef KISSAT_NDEBUG
259 KISSAT_assert (SIZE_STACK (solver->export_) == vars);
260 for (unsigned iidx = 0; iidx < vars; iidx++) {
261 const int elit = PEEK_STACK (solver->export_, iidx);
263 const unsigned eidx = ABS (elit);
264 const import *const import = &PEEK_STACK (solver->import, eidx);
266 if (import->eliminated)
267 continue;
268 unsigned mlit = import->lit;
269 if (elit < 0)
270 mlit = NOT (mlit);
271 const unsigned ilit = LIT (iidx);
272 KISSAT_assert (mlit == ilit);
273 }
274#endif
275}
276
277static void compact_units (kissat *solver, unsigned mfixed) {
278 LOG ("compacting units (first fixed %u)", mfixed);
279 KISSAT_assert (kissat_fixed (solver, mfixed) > 0);
280 for (all_stack (int, elit, solver->units)) {
281 const unsigned eidx = ABS (elit);
282 const unsigned mlit = elit < 0 ? NOT (mfixed) : mfixed;
283 const import *const import = &PEEK_STACK (solver->import, eidx);
286 const unsigned ilit = import->lit;
287 if (mlit != ilit)
288 reimport_literal (solver, eidx, mlit);
289 }
290}
291
292static void compact_best_and_target_values (kissat *solver, unsigned vars) {
293 const value *const best = solver->phases.best;
294 const value *const target = solver->phases.target;
295 const flags *const flags = solver->flags;
296
297 unsigned best_assigned = 0;
298 unsigned target_assigned = 0;
299
300 for (unsigned idx = 0; idx < vars; idx++) {
301 if (!flags[idx].active)
302 continue;
303 if (target[idx])
304 target_assigned++;
305 if (best[idx])
306 best_assigned++;
307 }
308
309 if (solver->target_assigned != target_assigned) {
310 LOG ("compacting target assigned from %u to %u",
311 solver->target_assigned, target_assigned);
312 solver->target_assigned = target_assigned;
313 }
314
315 if (solver->best_assigned != best_assigned) {
316 LOG ("compacting best assigned from %u to %u", solver->best_assigned,
317 best_assigned);
318 solver->best_assigned = best_assigned;
319 }
320}
321
323 unsigned mfixed) {
324 LOG ("finalizing compacting");
325 KISSAT_assert (vars <= solver->vars);
326#ifdef LOGGING
327 KISSAT_assert (solver->compacting);
328#endif
329 if (vars == solver->vars) {
330#ifdef LOGGING
331 solver->compacting = false;
332 LOG ("number of variables does not change");
333#endif
334 return;
335 }
336
337 unsigned reduced = solver->vars - vars;
338 LOG ("compacted number of variables from %u to %u", solver->vars, vars);
339
340 bool first = true;
341 for (all_variables (iidx)) {
342 flags *flags = FLAGS (iidx);
343 if (flags->fixed && first)
344 first = false;
345 else if (!flags->active)
346 POKE_STACK (solver->export_, iidx, 0);
347 }
348
349 compact_trail (solver);
350
351 for (all_variables (iidx)) {
352 const unsigned ilit = LIT (iidx);
353 const unsigned mlit = kissat_map_literal (solver, ilit, true);
354 if (mlit != INVALID_LIT && ilit != mlit)
355 compact_literal (solver, mlit, ilit);
356 }
357
358 if (mfixed != INVALID_LIT)
359 compact_units (solver, mfixed);
360
361 memset (solver->assigned + vars, 0, reduced * sizeof (assigned));
362 memset (solver->flags + vars, 0, reduced * sizeof (flags));
363 memset (solver->values + 2 * vars, 0, 2 * reduced * sizeof (value));
364 memset (solver->watches + 2 * vars, 0, 2 * reduced * sizeof (watches));
365
366 compact_queue (solver);
367 compact_stack (solver, &solver->sweep_schedule);
368 compact_scores (solver, SCORES, vars);
369 compact_frames (solver);
370 compact_export (solver, vars);
371 compact_best_and_target_values (solver, vars);
372
373 solver->vars = vars;
374#ifdef LOGGING
375 solver->compacting = false;
376#endif
378}
379
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define SIZE_ARRAY
Definition array.h:24
#define POKE_ARRAY
Definition array.h:48
#define PEEK_ARRAY
Definition array.h:47
#define BEGIN_STACK(S)
Definition stack.h:46
#define RESIZE_STACK(S, NEW_SIZE)
Definition stack.h:55
#define POKE_STACK(S, N, E)
Definition stack.h:32
#define all_stack(T, E, S)
Definition stack.h:94
#define SIZE_STACK(S)
Definition stack.h:19
#define SET_END_OF_STACK(S, P)
Definition stack.h:62
#define PEEK_STACK(S, N)
Definition stack.h:29
#define END_STACK(S)
Definition stack.h:48
#define INVALID_LIT
#define INC(NAME)
#define LOG(...)
ABC_NAMESPACE_IMPL_START typedef signed char value
#define FLAGS
unsigned kissat_compact_literals(kissat *solver, unsigned *mfixed_ptr)
Definition compact.c:21
void kissat_finalize_compacting(kissat *solver, unsigned vars, unsigned mfixed)
Definition compact.c:322
Cube * p
Definition exorList.c:222
#define FRAME(LEVEL)
Definition frames.h:33
ABC_NAMESPACE_IMPL_START void kissat_release_heap(kissat *solver, heap *heap)
Definition heap.c:10
void kissat_resize_heap(kissat *solver, heap *heap, unsigned new_size)
Definition heap.c:46
#define all_variables(IDX)
Definition internal.h:269
#define SCORES
Definition internal.h:262
#define KISSAT_assert(ignore)
Definition global.h:13
#define SHRINK_STACK(S)
Definition stack.h:44
#define solver
Definition kitten.c:211
#define LOG2(...)
Definition logging.h:352
unsigned long long size
Definition giaNewBdd.h:39
#define kissat_phase(...)
Definition print.h:48
#define DISCONNECT
Definition queue.h:7
#define DISCONNECTED(IDX)
Definition queue.h:8
void kissat_decrease_size(kissat *solver)
Definition resize.c:82
#define LIT(IDX)
Definition literal.h:31
#define INVALID_IDX
Definition literal.h:18
#define VALID_INTERNAL_LITERAL(LIT)
Definition literal.h:23
#define VALID_EXTERNAL_LITERAL(LIT)
Definition literal.h:25
#define IDX(LIT)
Definition literal.h:28
#define NOT(LIT)
Definition literal.h:33
#define GET(NAME)
Definition statistics.h:416
bool binary
Definition assign.h:23
unsigned reason
Definition assign.h:28
Definition flags.h:11
bool active
Definition flags.h:12
bool fixed
Definition flags.h:18
bool eliminated
Definition flags.h:16
Definition frames.h:15
unsigned decision
Definition frames.h:17
Definition heap.h:19
unsigneds stack
Definition heap.h:23
bool tainted
Definition heap.h:20
bool eliminated
Definition internal.h:52
bool imported
Definition internal.h:51
unsigned lit
Definition internal.h:49
char * memset()
#define ABS(a)
Definition util_old.h:250
vector watches
Definition watch.h:49