ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_decide.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
9// This function determines the next decision variable on the queue, without
10// actually removing it from the decision queue, e.g., calling it multiple
11// times without any assignment will return the same result. This is of
12// course used below in 'decide' but also in 'reuse_trail' to determine the
13// largest decision level to backtrack to during 'restart' without changing
14// the assigned variables (if 'opts.restartreusetrail' is non-zero).
15
17 int64_t searched = 0;
18 int res = queue.unassigned;
19 while (val (res))
20 res = link (res).prev, searched++;
21 if (searched) {
22 stats.searched += searched;
24 }
25 LOG ("next queue decision variable %d bumped %" PRId64 "", res,
26 bumped (res));
27 return res;
28}
29
30// This function determines the best decision with respect to score.
31//
33 int res = 0;
34 for (;;) {
35 res = scores.front ();
36 if (!val (res))
37 break;
38 (void) scores.pop_front ();
39 }
40 LOG ("next decision variable %d with score %g", res, score (res));
41 return res;
42}
43
50
51/*------------------------------------------------------------------------*/
52
53// Implements phase saving as well using a target phase during
54// stabilization unless decision phase is forced to the initial value
55// of a phase is forced through the 'phase' option.
56
57int Internal::decide_phase (int idx, bool target) {
58 const int initial_phase = opts.phase ? 1 : -1;
59 int phase = 0;
61 phase = phases.saved[idx];
62 if (!phase)
63 phase = phases.forced[idx]; // swapped with opts.forcephase case!
64 if (!phase && opts.forcephase)
65 phase = initial_phase;
66 if (!phase && target)
67 phase = phases.target[idx];
68 if (!phase)
69 phase = phases.saved[idx];
70
71 // The following should not be necessary and in some version we had even
72 // a hard 'COVER' CADICAL_assertion here to check for this. Unfortunately it
73 // triggered for some users and we could not get to the root cause of
74 // 'phase' still not being set here. The logic for phase and target
75 // saving is pretty complex, particularly in combination with local
76 // search, and to avoid running in such an issue in the future again, we
77 // now use this 'defensive' code here, even though such defensive code is
78 // considered bad programming practice.
79 //
80 if (!phase)
81 phase = initial_phase;
82
83 return phase * idx;
84}
85
86// The likely phase of an variable used in 'collect' for optimizing
87// co-location of clauses likely accessed together during search.
88
89int Internal::likely_phase (int idx) { return decide_phase (idx, false); }
90
91/*------------------------------------------------------------------------*/
92
93// adds new level to control and trail
94//
96 level++;
97 control.push_back (Level (lit, trail.size ()));
98}
99
100/*------------------------------------------------------------------------*/
101
103 if ((size_t) level < assumptions.size () + (!!constraint.size ()))
104 return false;
105 if (num_assigned < (size_t) max_var)
106 return false;
107 CADICAL_assert (num_assigned == (size_t) max_var);
108 if (propagated < trail.size ())
109 return false;
110 size_t assigned = num_assigned;
111 return (assigned == (size_t) max_var);
112}
113
114bool Internal::better_decision (int lit, int other) {
115 int lit_idx = abs (lit);
116 int other_idx = abs (other);
117 if (stable)
118 return stab[lit_idx] > stab[other_idx];
119 else
120 return btab[lit_idx] > btab[other_idx];
121}
122
123// Search for the next decision and assign it to the saved phase. Requires
124// that not all variables are assigned.
125
128 START (decide);
129 int res = 0;
130 if ((size_t) level < assumptions.size ()) {
131 const int lit = assumptions[level];
133 const signed char tmp = val (lit);
134 if (tmp < 0) {
135 LOG ("assumption %d falsified", lit);
136 res = 20;
137 } else if (tmp > 0) {
138 LOG ("assumption %d already satisfied", lit);
139 new_trail_level (0);
140 LOG ("added pseudo decision level");
142 } else {
143 LOG ("deciding assumption %d", lit);
145 }
146 } else if ((size_t) level == assumptions.size () && constraint.size ()) {
147
148 int satisfied_lit = 0; // The literal satisfying the constrain.
149 int unassigned_lit = 0; // Highest score unassigned literal.
150 int previous_lit = 0; // Move satisfied literals to the front.
151
152 const size_t size_constraint = constraint.size ();
153
154#ifndef CADICAL_NDEBUG
155 unsigned sum = 0;
156 for (auto lit : constraint)
157 sum += lit;
158#endif
159 for (size_t i = 0; i != size_constraint; i++) {
160
161 // Get literal and move 'constraint[i] = constraint[i-1]'.
162
163 int lit = constraint[i];
164 constraint[i] = previous_lit;
165 previous_lit = lit;
166
167 const signed char tmp = val (lit);
168 if (tmp < 0) {
169 LOG ("constraint literal %d falsified", lit);
170 continue;
171 }
172
173 if (tmp > 0) {
174 LOG ("constraint literal %d satisfied", lit);
175 satisfied_lit = lit;
176 break;
177 }
178
179 CADICAL_assert (!tmp);
180 LOG ("constraint literal %d unassigned", lit);
181
182 if (!unassigned_lit || better_decision (lit, unassigned_lit))
183 unassigned_lit = lit;
184 }
185
186 if (satisfied_lit) {
187
188 constraint[0] = satisfied_lit; // Move satisfied to the front.
189
190 LOG ("literal %d satisfies constraint and "
191 "is implied by assumptions",
192 satisfied_lit);
193
194 new_trail_level (0);
195 LOG ("added pseudo decision level for constraint");
197
198 } else {
199
200 // Just move all the literals back. If we found an unsatisfied
201 // literal then it will be satisfied (most likely) at the next
202 // decision and moved then to the first position.
203
204 if (size_constraint) {
205
206 for (size_t i = 0; i + 1 != size_constraint; i++)
207 constraint[i] = constraint[i + 1];
208
209 constraint[size_constraint - 1] = previous_lit;
210 }
211
212 if (unassigned_lit) {
213
214 LOG ("deciding %d to satisfy constraint", unassigned_lit);
215 search_assume_decision (unassigned_lit);
216
217 } else {
218
219 LOG ("failing constraint");
220 unsat_constraint = true;
221 res = 20;
222 }
223 }
224
225#ifndef CADICAL_NDEBUG
226 for (auto lit : constraint)
227 sum -= lit;
228 CADICAL_assert (!sum); // Checksum of literal should not change!
229#endif
230
231 } else {
232
233 int decision = ask_decision ();
234 if ((size_t) level < assumptions.size () ||
235 ((size_t) level == assumptions.size () && constraint.size ())) {
236 // Forced backtrack below pseudo decision levels.
237 // So one of the two branches above will handle it.
238 STOP (decide);
239 res = decide (); // STARTS and STOPS profiling
240 START (decide);
241 } else {
242 stats.decisions++;
243 if (!decision) {
244 int idx = next_decision_variable ();
245 const bool target = (opts.target > 1 || (stable && opts.target));
246 decision = decide_phase (idx, target);
247 }
248 search_assume_decision (decision);
249 }
250 }
251 if (res)
252 marked_failed = false;
253 STOP (decide);
254 return res;
255}
256} // namespace CaDiCaL
257
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define LOG(...)
#define STOP(P)
Definition profile.hpp:158
#define START(P)
Definition profile.hpp:150
int lit
Definition satVec.h:130
int next_decision_variable_with_best_score()
void update_queue_unassigned(int idx)
Definition internal.hpp:652
void new_trail_level(int lit)
vector< int > constraint
Definition internal.hpp:262
vector< int > trail
Definition internal.hpp:259
void phase(int lit)
Link & link(int lit)
Definition internal.hpp:453
bool better_decision(int lit, int other)
int decide_phase(int idx, bool target)
void search_assume_decision(int decision)
signed char val(int lit) const
int likely_phase(int idx)
bool use_scores() const
Definition internal.hpp:471
vector< int > assumptions
Definition internal.hpp:261
bool assumed(int lit)
int next_decision_variable_on_queue()
vector< int64_t > btab
Definition internal.hpp:234
double & score(int lit)
Definition internal.hpp:457
vector< Level > control
Definition internal.hpp:282
vector< double > stab
Definition internal.hpp:230
ScoreSchedule scores
Definition internal.hpp:229
int64_t & bumped(int lit)
Definition internal.hpp:455