ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
reorder.c
Go to the documentation of this file.
1#include "reorder.h"
2#include "backtrack.h"
3#include "bump.h"
4#include "inline.h"
5#include "inlineheap.h"
6#include "inlinequeue.h"
7#include "inlinevector.h"
8#include "internal.h"
9#include "logging.h"
10#include "print.h"
11#include "report.h"
12#include "sort.h"
13
15
17 if (!GET_OPTION (reorder))
18 return false;
19 if (!solver->stable && GET_OPTION (reorder) < 2)
20 return false;
21 if (solver->level)
22 return false;
23 return CONFLICTS >= solver->limits.reorder.conflicts;
24}
25
26static double *compute_weights (kissat *solver) {
27 double *weights = (double*)kissat_calloc (solver, LITS, sizeof *weights);
28 const unsigned max_size = GET_OPTION (reordermaxsize);
29 LOG ("limiting weight computation to maximum clause size %u", max_size);
30 KISSAT_assert (2 <= max_size);
31 double *table = (double*)kissat_nalloc (solver, max_size + 1, sizeof *table);
32 {
33 double weight = 1;
34 for (unsigned size = 2; size <= max_size; size++) {
35 LOG ("score table[%u] = %g", size, weight);
36 table[size] = weight, weight /= 2.0;
37 }
38 }
39 {
40 KISSAT_assert (!solver->level);
41 const signed char *const values = solver->values;
42 const clause *last = kissat_last_irredundant_clause (solver);
43 for (all_clauses (c)) {
44 if (last && c > last)
45 break;
46 if (c->redundant)
47 continue;
48 if (c->garbage)
49 continue;
50 unsigned size = 0;
51 int continue_with_next_clause = 0;
52 for (all_literals_in_clause (lit, c)) {
53 const signed char value = values[lit];
54 if (value > 0) {
55 continue_with_next_clause = 1;
56 break;
57 }
58 if (!value && size < max_size && ++size == max_size)
59 break;
60 }
61 if(continue_with_next_clause) {
62 continue;
63 }
64 const double weight = table[size];
66 weights[lit] += weight;
67 }
68 }
69 KISSAT_assert (solver->watching);
70 {
71 double weight = table[2];
72 kissat_dealloc (solver, table, max_size + 1, sizeof *table);
73 for (all_literals (lit)) {
74 const unsigned idx = IDX (lit);
75 if (!ACTIVE (idx))
76 continue;
79 if (!watch.type.binary)
80 continue;
81 const unsigned other = watch.type.lit;
82 if (other < lit)
83 continue;
84 const unsigned other_idx = IDX (other);
85 if (!ACTIVE (other_idx))
86 continue;
87 weights[lit] += weight;
88 weights[other] += weight;
89 }
90 }
91 }
92 for (all_variables (idx)) {
93 if (!ACTIVE (idx))
94 continue;
95 unsigned lit = LIT (idx), not_lit = NOT (lit);
96 double pos = weights[lit], neg = weights[not_lit];
97 double max_pos_neg = MAX (pos, neg);
98 double min_pos_neg = MIN (pos, neg);
99 double scaled_min_pos_neg = 2 * min_pos_neg;
100 double weight = max_pos_neg + scaled_min_pos_neg;
101 LOG ("computed weight %g "
102 "= %g + %g = max (%g, %g) + 2 * min (%g, %g) of %s",
103 weight, max_pos_neg, scaled_min_pos_neg, pos, neg, pos, neg,
104 LOGVAR (idx));
105 weights[idx] = weight;
106 }
107 return weights;
108}
109
110static bool less_focused_order (unsigned a, unsigned b, links *links,
111 double *weights) {
112 double u = weights[a], v = weights[b];
113 if (u < v)
114 return true;
115 if (u > v)
116 return false;
117 unsigned s = links[a].stamp, t = links[b].stamp;
118 return s < t;
119}
120
121static bool less_stable_order (unsigned a, unsigned b, heap *scores,
122 double *weights) {
123 double u = weights[a], v = weights[b];
124 if (u < v)
125 return true;
126 if (u > v)
127 return false;
128 double s = kissat_get_heap_score (scores, a);
129 double t = kissat_get_heap_score (scores, b);
130 if (s < t)
131 return true;
132 if (s > t)
133 return false;
134 return b < a;
135}
136
137#define LESS_FOCUSED_ORDER(A, B) less_focused_order (A, B, links, weights)
138
139#define LESS_STABLE_ORDER(A, B) less_stable_order (A, B, scores, weights)
140
141static void sort_active_variables_by_weight (kissat *solver,
142 unsigneds *sorted,
143 double *weights) {
144 INIT_STACK (*sorted);
145 for (all_variables (idx))
146 if (ACTIVE (idx))
147 PUSH_STACK (*sorted, idx);
148 if (solver->stable) {
149 heap *scores = SCORES;
150 SORT_STACK (unsigned, *sorted, LESS_STABLE_ORDER);
151#ifdef LOGGING
152 for (all_stack (unsigned, idx, *sorted))
153 if (ACTIVE (idx))
154 LOG ("reordered %s with weight %g score %g", LOGVAR (idx),
155 weights[idx], kissat_get_heap_score (scores, idx));
156#endif
157 } else {
158 struct links *links = solver->links;
159 SORT_STACK (unsigned, *sorted, LESS_FOCUSED_ORDER);
160#ifdef LOGGING
161 for (all_stack (unsigned, idx, *sorted))
162 if (ACTIVE (idx))
163 LOG ("reordered %s with weight %g stamp %u", LOGVAR (idx),
164 weights[idx], links[idx].stamp);
165#endif
166 }
167}
168
169static void reorder_focused (kissat *solver) {
170 INC (reordered_focused);
171 KISSAT_assert (!solver->stable);
172 double *weights = compute_weights (solver);
173 unsigneds sorted;
174 sort_active_variables_by_weight (solver, &sorted, weights);
175 kissat_dealloc (solver, weights, LITS, sizeof *weights);
176 for (all_stack (unsigned, idx, sorted)) {
177 KISSAT_assert (ACTIVE (idx));
178 kissat_move_to_front (solver, idx);
179 }
180 RELEASE_STACK (sorted);
181}
182
183static void reorder_stable (kissat *solver) {
184 INC (reordered_stable);
185 KISSAT_assert (solver->stable);
186 double *weights = compute_weights (solver);
188 unsigneds sorted;
189 sort_active_variables_by_weight (solver, &sorted, weights);
190 heap *scores = SCORES;
191 while (!EMPTY_STACK (sorted)) {
192 unsigned idx = POP_STACK (sorted);
193 KISSAT_assert (ACTIVE (idx));
194 const double old_score = kissat_get_heap_score (scores, idx);
195 const double weight = weights[idx];
196 const double new_score = old_score + weight;
197 LOG ("updating score of %s to %g = %g (old score) + %g (weight)",
198 LOGVAR (idx), new_score, old_score, weight);
199 kissat_update_heap (solver, scores, idx, new_score);
200 }
201 kissat_dealloc (solver, weights, LITS, sizeof *weights);
202 RELEASE_STACK (sorted);
203}
204
206 START (reorder);
207 INC (reordered);
208 KISSAT_assert (!solver->level);
209 kissat_phase (solver, "reorder", GET (reordered),
210 "reorder limit %" PRIu64 " hit a after %" PRIu64
211 " conflicts in %s mode ",
212 solver->limits.reorder.conflicts, CONFLICTS,
213 solver->stable ? "stable" : "focused");
214 if (solver->stable)
215 reorder_stable (solver);
216 else
217 reorder_focused (solver);
218 kissat_phase (solver, "reorder", GET (reordered),
219 "reordered decisions in %s search mode",
220 solver->stable ? "stable" : "focused");
221 UPDATE_CONFLICT_LIMIT (reorder, reordered, LINEAR, false);
222 REPORT (0, 'o');
223 STOP (reorder);
224}
225
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void * kissat_nalloc(kissat *solver, size_t n, size_t size)
Definition allocate.c:80
void * kissat_calloc(kissat *solver, size_t n, size_t size)
Definition allocate.c:97
void kissat_dealloc(kissat *solver, void *ptr, size_t n, size_t size)
Definition allocate.c:114
#define MAX(a, b)
Definition avl.h:23
void kissat_rescale_scores(kissat *solver)
Definition bump.c:30
#define POP_STACK(S)
Definition stack.h:37
#define all_stack(T, E, S)
Definition stack.h:94
#define EMPTY_STACK(S)
Definition stack.h:18
#define RELEASE_STACK(S)
Definition stack.h:71
#define PUSH_STACK(S, E)
Definition stack.h:39
#define INIT_STACK(S)
Definition stack.h:22
#define INC(NAME)
#define LOG(...)
ABC_NAMESPACE_IMPL_START typedef signed char value
#define ACTIVE
Definition espresso.h:129
bool pos
Definition globals.c:30
#define all_variables(IDX)
Definition internal.h:269
#define all_literals(LIT)
Definition internal.h:274
#define all_clauses(C)
Definition internal.h:279
#define SCORES
Definition internal.h:262
#define LITS
Definition internal.h:251
#define LINEAR(COUNT)
Definition kimits.h:108
#define UPDATE_CONFLICT_LIMIT(NAME, COUNT, SCALE_COUNT_FUNCTION, SCALE_DELTA)
Definition kimits.h:115
#define all_literals_in_clause(LIT, C)
Definition clause.h:47
#define KISSAT_assert(ignore)
Definition global.h:13
#define SORT_STACK(TYPE, S, LESS)
Definition sort.h:148
#define solver
Definition kitten.c:211
unsigned long long size
Definition giaNewBdd.h:39
#define GET_OPTION(N)
Definition options.h:295
#define kissat_phase(...)
Definition print.h:48
#define STOP(P)
Definition profile.hpp:158
#define START(P)
Definition profile.hpp:150
#define LESS_FOCUSED_ORDER(A, B)
Definition reorder.c:137
#define LESS_STABLE_ORDER(A, B)
Definition reorder.c:139
void kissat_reorder(kissat *solver)
Definition reorder.c:205
ABC_NAMESPACE_IMPL_START bool kissat_reordering(kissat *solver)
Definition reorder.c:16
#define REPORT(...)
Definition report.h:10
int lit
Definition satVec.h:130
#define LIT(IDX)
Definition literal.h:31
#define IDX(LIT)
Definition literal.h:28
#define NOT(LIT)
Definition literal.h:33
#define CONFLICTS
Definition statistics.h:335
#define GET(NAME)
Definition statistics.h:416
Definition heap.h:19
Definition watch.h:41
watch_type type
Definition watch.h:42
#define MIN(a, b)
Definition util_old.h:256
#define all_binary_blocking_watches(WATCH, WATCHES)
Definition watch.h:151
vector watches
Definition watch.h:49
#define WATCHES(LIT)
Definition watch.h:137