ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
minimize.c
Go to the documentation of this file.
1#include "minimize.h"
2#include "inline.h"
3
5
6static inline int minimized_index (kissat *solver, bool minimizing,
7 assigned *a, unsigned lit, unsigned idx,
8 unsigned depth) {
9#if !defined(LOGGING) && defined(KISSAT_NDEBUG)
10 (void) lit;
11#endif
12#ifdef KISSAT_NDEBUG
13 (void) idx;
14#endif
15 KISSAT_assert (IDX (lit) == idx);
16 KISSAT_assert (solver->assigned + idx == a);
17 if (!a->level) {
18 LOG2 ("skipping root level literal %s", LOGLIT (lit));
19 return 1;
20 }
21 if (a->removable && depth) {
22 LOG2 ("skipping removable literal %s", LOGLIT (lit));
23 return 1;
24 }
26 if (a->reason == DECISION_REASON) {
27 LOG2 ("can not remove decision literal %s", LOGLIT (lit));
28 return -1;
29 }
30 if (a->poisoned) {
31 LOG2 ("can not remove poisoned literal %s", LOGLIT (lit));
32 return -1;
33 }
34 if (minimizing || !depth) {
35 frame *frame = &FRAME (a->level);
36 if (frame->used <= 1) {
37 LOG2 ("can not remove singleton frame literal %s", LOGLIT (lit));
38 return -1;
39 }
40 }
41 return 0;
42}
43
44static bool minimize_literal (kissat *, bool, assigned *, unsigned lit,
45 unsigned depth);
46
47static inline bool minimize_reference (kissat *solver, bool minimizing,
49 unsigned lit, unsigned depth) {
50 const unsigned next_depth = (depth == UINT_MAX) ? depth : depth + 1;
51 const unsigned not_lit = NOT (lit);
52 clause *c = kissat_dereference_clause (solver, ref);
53 if (GET_OPTION (minimizeticks))
54 INC (search_ticks);
55 for (all_literals_in_clause (other, c))
56 if (other != not_lit &&
57 !minimize_literal (solver, minimizing, assigned, other, next_depth))
58 return false;
59 return true;
60}
61
62static inline bool minimize_binary (kissat *solver, bool minimizing,
63 assigned *assigned, unsigned lit,
64 unsigned depth) {
65 const size_t saved = SIZE_STACK (solver->minimize);
66 bool res;
67 for (unsigned next = lit;;) {
68 const unsigned next_idx = IDX (next);
69 struct assigned *a = assigned + next_idx;
70 int tmp = minimized_index (solver, minimizing, a, next, next_idx, 1);
71 if (tmp) {
72 res = (tmp > 0);
73 break;
74 }
75 PUSH_STACK (solver->minimize, next_idx);
76 if (!a->binary) {
77 const unsigned next_depth = (depth == UINT_MAX) ? depth : depth + 1;
78 res = minimize_reference (solver, minimizing, assigned, a->reason,
79 next, next_depth);
80 break;
81 }
82 next = a->reason;
83 }
84 unsigned *begin = BEGIN_STACK (solver->minimize) + saved;
85 const unsigned *const end = END_STACK (solver->minimize);
86 KISSAT_assert (begin <= end);
87 if (res)
88 for (const unsigned *p = begin; p != end; p++)
89 kissat_push_removable (solver, assigned, *p);
90 else
91 for (const unsigned *p = begin; p != end; p++)
92 kissat_push_poisoned (solver, assigned, *p);
93 SET_END_OF_STACK (solver->minimize, begin);
94 return res;
95}
96
97static bool minimize_literal (kissat *solver, bool minimizing,
98 assigned *assigned, unsigned lit,
99 unsigned depth) {
100 LOG ("trying to minimize literal %s at recursion depth %d", LOGLIT (lit),
101 depth);
102 KISSAT_assert (VALUE (lit) < 0);
103 KISSAT_assert (depth || EMPTY_STACK (solver->minimize));
104 KISSAT_assert (GET_OPTION (minimizedepth) > 0);
105 if (depth >= (unsigned) GET_OPTION (minimizedepth))
106 return false;
107 const unsigned idx = IDX (lit);
108 struct assigned *a = assigned + idx;
109 int tmp = minimized_index (solver, minimizing, a, lit, idx, depth);
110 if (tmp > 0)
111 return true;
112 if (tmp < 0)
113 return false;
114#ifdef LOGGING
115 const unsigned not_lit = NOT (lit);
116#endif
117 bool res;
118 if (a->binary) {
119 const unsigned other = a->reason;
120 LOGBINARY2 (not_lit, other, "minimizing along %s reason",
121 LOGLIT (not_lit));
122 res = minimize_binary (solver, minimizing, assigned, other, depth);
123 } else {
124 const reference ref = a->reason;
125 LOGREF2 (ref, "minimizing along %s reason", LOGLIT (not_lit));
126 res =
127 minimize_reference (solver, minimizing, assigned, ref, lit, depth);
128 }
129 if (!depth)
130 return res;
131 if (!res)
132 kissat_push_poisoned (solver, assigned, idx);
133 else if (!a->removable)
134 kissat_push_removable (solver, assigned, idx);
135 return res;
136}
137
139 bool lit_in_clause) {
140 KISSAT_assert (EMPTY_STACK (solver->minimize));
141 return minimize_literal (solver, false, solver->assigned, lit,
142 !lit_in_clause);
143}
144
146 LOG ("reset %zu poisoned variables", SIZE_STACK (solver->poisoned));
147 assigned *assigned = solver->assigned;
148 for (all_stack (unsigned, idx, solver->poisoned)) {
149 KISSAT_assert (idx < VARS);
150 struct assigned *a = assigned + idx;
152 a->poisoned = false;
153 }
154 CLEAR_STACK (solver->poisoned);
155}
156
158 START (minimize);
159
160 KISSAT_assert (EMPTY_STACK (solver->minimize));
161 KISSAT_assert (EMPTY_STACK (solver->removable));
162 KISSAT_assert (EMPTY_STACK (solver->poisoned));
163 KISSAT_assert (!EMPTY_STACK (solver->clause));
164
165 unsigned *lits = BEGIN_STACK (solver->clause);
166 unsigned *end = END_STACK (solver->clause);
167
168 assigned *assigned = solver->assigned;
169#ifndef KISSAT_NDEBUG
170 KISSAT_assert (lits < end);
171 const unsigned not_uip = lits[0];
172 KISSAT_assert (assigned[IDX (not_uip)].level == solver->level);
173#endif
174 for (const unsigned *p = lits; p != end; p++)
175 kissat_push_removable (solver, assigned, IDX (*p));
176
177 if (GET_OPTION (shrink) > 2) {
178 STOP (minimize);
179 return;
180 }
181
182 unsigned minimized = 0;
183
184 for (unsigned *p = end; --p > lits;) {
185 const unsigned lit = *p;
186 KISSAT_assert (lit != not_uip);
187 if (minimize_literal (solver, true, assigned, lit, 0)) {
188 LOG ("minimized literal %s", LOGLIT (lit));
189 *p = INVALID_LIT;
190 minimized++;
191 } else
192 LOG ("keeping literal %s", LOGLIT (lit));
193 }
194
195 unsigned *q = lits;
196 for (const unsigned *p = lits; p != end; p++) {
197 const unsigned lit = *p;
198 if (lit != INVALID_LIT)
199 *q++ = lit;
200 }
201 KISSAT_assert (q + minimized == end);
202 SET_END_OF_STACK (solver->clause, q);
203 LOG ("clause minimization removed %u literals", minimized);
204
205 KISSAT_assert (!solver->probing);
206 ADD (literals_minimized, minimized);
207
208 LOGTMP ("minimized learned");
209
211
212 STOP (minimize);
213}
214
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define DECISION_REASON
Definition assign.h:9
#define UNIT_REASON
Definition assign.h:10
#define BEGIN_STACK(S)
Definition stack.h:46
#define all_stack(T, E, S)
Definition stack.h:94
#define SIZE_STACK(S)
Definition stack.h:19
#define EMPTY_STACK(S)
Definition stack.h:18
#define SET_END_OF_STACK(S, P)
Definition stack.h:62
#define CLEAR_STACK(S)
Definition stack.h:50
#define PUSH_STACK(S, E)
Definition stack.h:39
#define END_STACK(S)
Definition stack.h:48
#define INVALID_LIT
#define ADD(NAME, DELTA)
#define INC(NAME)
#define LOG(...)
Cube * p
Definition exorList.c:222
#define FRAME(LEVEL)
Definition frames.h:33
#define VARS
Definition internal.h:250
#define all_literals_in_clause(LIT, C)
Definition clause.h:47
#define KISSAT_assert(ignore)
Definition global.h:13
#define solver
Definition kitten.c:211
#define LOG2(...)
Definition logging.h:352
#define LOGTMP(...)
Definition logging.h:463
#define LOGBINARY2(...)
Definition logging.h:445
#define LOGREF2(...)
Definition logging.h:436
#define LOGLIT(...)
Definition logging.hpp:99
void kissat_reset_poisoned(kissat *solver)
Definition minimize.c:145
bool kissat_minimize_literal(kissat *solver, unsigned lit, bool lit_in_clause)
Definition minimize.c:138
void kissat_minimize_clause(kissat *solver)
Definition minimize.c:157
unsigned short ref
Definition giaNewBdd.h:38
#define GET_OPTION(N)
Definition options.h:295
#define STOP(P)
Definition profile.hpp:158
#define START(P)
Definition profile.hpp:150
ABC_NAMESPACE_HEADER_START typedef unsigned reference
Definition reference.h:9
int lit
Definition satVec.h:130
#define IDX(LIT)
Definition literal.h:28
#define NOT(LIT)
Definition literal.h:33
bool binary
Definition assign.h:23
bool removable
Definition assign.h:25
bool poisoned
Definition assign.h:24
unsigned reason
Definition assign.h:28
unsigned level
Definition assign.h:19
Definition frames.h:15
unsigned used
Definition frames.h:19
#define VALUE(LIT)
Definition value.h:10