[10] | 1 | // ********************************************************************* |
---|
| 2 | // Copyright 2000-2004, Princeton University. All rights reserved. |
---|
| 3 | // By using this software the USER indicates that he or she has read, |
---|
| 4 | // understood and will comply with the following: |
---|
| 5 | // |
---|
| 6 | // --- Princeton University hereby grants USER nonexclusive permission |
---|
| 7 | // to use, copy and/or modify this software for internal, noncommercial, |
---|
| 8 | // research purposes only. Any distribution, including commercial sale |
---|
| 9 | // or license, of this software, copies of the software, its associated |
---|
| 10 | // documentation and/or modifications of either is strictly prohibited |
---|
| 11 | // without the prior consent of Princeton University. Title to copyright |
---|
| 12 | // to this software and its associated documentation shall at all times |
---|
| 13 | // remain with Princeton University. Appropriate copyright notice shall |
---|
| 14 | // be placed on all software copies, and a complete copy of this notice |
---|
| 15 | // shall be included in all copies of the associated documentation. |
---|
| 16 | // No right is granted to use in advertising, publicity or otherwise |
---|
| 17 | // any trademark, service mark, or the name of Princeton University. |
---|
| 18 | // |
---|
| 19 | // |
---|
| 20 | // --- This software and any associated documentation is provided "as is" |
---|
| 21 | // |
---|
| 22 | // PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS |
---|
| 23 | // OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A |
---|
| 24 | // PARTICULAR PURPOSE, OR THAT USE OF THE SOFTWARE, MODIFICATIONS, OR |
---|
| 25 | // ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, |
---|
| 26 | // TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. |
---|
| 27 | // |
---|
| 28 | // Princeton University shall not be liable under any circumstances for |
---|
| 29 | // any direct, indirect, special, incidental, or consequential damages |
---|
| 30 | // with respect to any claim by USER or any third party on account of |
---|
| 31 | // or arising from the use, or inability to use, this software or its |
---|
| 32 | // associated documentation, even if Princeton University has been advised |
---|
| 33 | // of the possibility of those damages. |
---|
| 34 | // ********************************************************************* |
---|
| 35 | |
---|
| 36 | #ifndef __SAT_SOLVER__ |
---|
| 37 | #define __SAT_SOLVER__ |
---|
| 38 | |
---|
| 39 | #include "zchaff_version.h" |
---|
| 40 | #include "zchaff_dbase.h" |
---|
| 41 | |
---|
| 42 | #ifndef _SAT_STATUS_ |
---|
| 43 | #define _SAT_STATUS_ |
---|
| 44 | |
---|
| 45 | enum SAT_StatusT { |
---|
| 46 | UNDETERMINED, |
---|
| 47 | UNSATISFIABLE, |
---|
| 48 | SATISFIABLE, |
---|
| 49 | TIME_OUT, |
---|
| 50 | MEM_OUT, |
---|
| 51 | ABORTED |
---|
| 52 | }; |
---|
| 53 | #endif |
---|
| 54 | |
---|
| 55 | enum SAT_DeductionT { |
---|
| 56 | CONFLICT, |
---|
| 57 | NO_CONFLICT |
---|
| 58 | }; |
---|
| 59 | |
---|
| 60 | class CSolver; |
---|
| 61 | |
---|
| 62 | typedef void(*HookFunPtrT)(void *) ; |
---|
| 63 | typedef void(*OutsideConstraintHookPtrT)(CSolver * solver); |
---|
| 64 | typedef bool(*SatHookPtrT)(CSolver * solver); |
---|
| 65 | |
---|
| 66 | // **Struct******************************************************************** |
---|
| 67 | // |
---|
| 68 | // Synopsis [Sat solver parameters ] |
---|
| 69 | // |
---|
| 70 | // Description [] |
---|
| 71 | // |
---|
| 72 | // SeeAlso [] |
---|
| 73 | // |
---|
| 74 | // **************************************************************************** |
---|
| 75 | |
---|
| 76 | struct CSolverParameters { |
---|
| 77 | float time_limit; |
---|
| 78 | int verbosity; |
---|
| 79 | |
---|
| 80 | struct { |
---|
| 81 | unsigned size; |
---|
| 82 | int enable; |
---|
| 83 | int upper_bound; |
---|
| 84 | int lower_bound; |
---|
| 85 | int upper_delta; |
---|
| 86 | int lower_delta; |
---|
| 87 | int bound_update_frequency; |
---|
| 88 | unsigned window_width; |
---|
| 89 | } shrinking; |
---|
| 90 | |
---|
| 91 | struct { |
---|
| 92 | int base_randomness; |
---|
| 93 | int bubble_init_step; |
---|
| 94 | int decay_period; |
---|
| 95 | } decision; |
---|
| 96 | |
---|
| 97 | struct { |
---|
| 98 | bool enable; |
---|
| 99 | unsigned interval; |
---|
| 100 | unsigned head_activity; |
---|
| 101 | unsigned tail_activity; |
---|
| 102 | unsigned head_num_lits; |
---|
| 103 | unsigned tail_num_lits; |
---|
| 104 | int tail_vs_head; |
---|
| 105 | } cls_deletion; |
---|
| 106 | |
---|
| 107 | struct { |
---|
| 108 | bool enable; |
---|
| 109 | int interval; |
---|
| 110 | int first_restart; |
---|
| 111 | int backtrack_incr; |
---|
| 112 | } restart; |
---|
| 113 | }; |
---|
| 114 | |
---|
| 115 | // **Struct******************************************************************** |
---|
| 116 | // |
---|
| 117 | // Synopsis [Sat solver statistics ] |
---|
| 118 | // |
---|
| 119 | // Description [] |
---|
| 120 | // |
---|
| 121 | // SeeAlso [] |
---|
| 122 | // |
---|
| 123 | // **************************************************************************** |
---|
| 124 | |
---|
| 125 | struct CSolverStats { |
---|
| 126 | bool been_reset; // when delete clause in incremental solving, |
---|
| 127 | // must reset. |
---|
| 128 | SAT_StatusT outcome; |
---|
| 129 | bool is_mem_out; // this flag will be set if memory out |
---|
| 130 | double start_cpu_time; |
---|
| 131 | double finish_cpu_time; |
---|
| 132 | int current_randomness; |
---|
| 133 | int next_restart; |
---|
| 134 | int restart_incr; |
---|
| 135 | int next_cls_deletion; |
---|
| 136 | int next_var_score_decay; |
---|
| 137 | int num_free_variables; |
---|
| 138 | int num_free_branch_vars; |
---|
| 139 | long64 total_bubble_move; |
---|
| 140 | int num_decisions; |
---|
| 141 | int num_decisions_stack_conf; |
---|
| 142 | int num_decisions_vsids; |
---|
| 143 | int num_decisions_shrinking; |
---|
| 144 | int num_shrinkings; |
---|
| 145 | int shrinking_benefit; |
---|
| 146 | int shrinking_cls_length; |
---|
| 147 | int num_backtracks; |
---|
| 148 | int max_dlevel; |
---|
| 149 | int random_seed; |
---|
| 150 | long64 num_implications; |
---|
| 151 | int num_restarts; |
---|
| 152 | int num_del_orig_cls; |
---|
| 153 | }; |
---|
| 154 | |
---|
| 155 | // **Class********************************************************************* |
---|
| 156 | // |
---|
| 157 | // Synopsis [Sat Solver] |
---|
| 158 | // |
---|
| 159 | // Description [This class contains the process and datastructrues to solve |
---|
| 160 | // the Sat problem.] |
---|
| 161 | // |
---|
| 162 | // SeeAlso [] |
---|
| 163 | // |
---|
| 164 | // **************************************************************************** |
---|
| 165 | |
---|
| 166 | inline bool cmp_var_stat(const pair<CVariable *, int> & v1, |
---|
| 167 | const pair<CVariable *, int> & v2) { |
---|
| 168 | return v1.second >= v2.second; |
---|
| 169 | } |
---|
| 170 | |
---|
| 171 | struct cmp_var_assgn_pos { |
---|
| 172 | bool operator() (CVariable * v1, CVariable * v2) { |
---|
| 173 | if (v1->dlevel() > v2->dlevel()) |
---|
| 174 | return true; |
---|
| 175 | else if (v1->dlevel() < v2->dlevel()) |
---|
| 176 | return false; |
---|
| 177 | else if (v1->assgn_stack_pos() > v2->assgn_stack_pos()) |
---|
| 178 | return true; |
---|
| 179 | return false; |
---|
| 180 | } |
---|
| 181 | }; |
---|
| 182 | |
---|
| 183 | struct CImplication { |
---|
| 184 | int lit; |
---|
| 185 | int antecedent; |
---|
| 186 | }; |
---|
| 187 | |
---|
| 188 | struct ImplicationQueue:queue<CImplication> { |
---|
| 189 | void dump(ostream & os) { |
---|
| 190 | queue<CImplication> temp(*this); |
---|
| 191 | os << "Implication Queue Previous: " ; |
---|
| 192 | while (!temp.empty()) { |
---|
| 193 | CImplication a = temp.front(); |
---|
| 194 | os << "(" << ((a.lit & 0x1) ? "-" : "+") << (a.lit >> 1) |
---|
| 195 | << ":" << a.antecedent << ") "; |
---|
| 196 | temp.pop(); |
---|
| 197 | } |
---|
| 198 | } |
---|
| 199 | }; |
---|
| 200 | |
---|
| 201 | class CSolver:public CDatabase { |
---|
| 202 | protected: |
---|
| 203 | int _id; // the id of the solver, in case |
---|
| 204 | // we need to distinguish |
---|
| 205 | bool _force_terminate; |
---|
| 206 | CSolverParameters _params; // parameters for the solver |
---|
| 207 | CSolverStats _stats; // statistics and states |
---|
| 208 | |
---|
| 209 | int _dlevel; // current decision elvel |
---|
| 210 | vector<vector<int>*>_assignment_stack; |
---|
| 211 | queue<int> _recent_shrinkings; |
---|
| 212 | bool _mark_increase_score; // used in mark_vars during |
---|
| 213 | // multiple conflict analysis |
---|
| 214 | long64 _implication_id; |
---|
| 215 | ImplicationQueue _implication_queue; |
---|
| 216 | |
---|
| 217 | // hook function run after certain number of decisions |
---|
| 218 | vector<pair<int, pair<HookFunPtrT, int> > > _hooks; |
---|
| 219 | OutsideConstraintHookPtrT _outside_constraint_hook; |
---|
| 220 | SatHookPtrT _sat_hook; // hook function run after a satisfiable |
---|
| 221 | // solution found, return true to continue |
---|
| 222 | // solving and false to terminate as satisfiable |
---|
| 223 | |
---|
| 224 | // these are for decision making |
---|
| 225 | int _max_score_pos; // index the unassigned var with |
---|
| 226 | // max score |
---|
| 227 | vector<pair<CVariable*, int> > _ordered_vars; // pair's first pointing to |
---|
| 228 | // the var, second is the score. |
---|
| 229 | |
---|
| 230 | // these are for conflict analysis |
---|
| 231 | int _num_marked; // used when constructing learned clause |
---|
| 232 | int _num_in_new_cl; // used when constructing learned clause |
---|
| 233 | vector<ClauseIdx> _conflicts; // the conflicting clauses |
---|
| 234 | vector<int> _conflict_lits; // used when constructing learned clause |
---|
| 235 | vector<int> _resolvents; |
---|
| 236 | multimap<int, int> _shrinking_cls; |
---|
| 237 | |
---|
| 238 | protected: |
---|
| 239 | void re_init_stats(void); |
---|
| 240 | void init_stats(void); |
---|
| 241 | void init_parameters(void); |
---|
| 242 | void init_solve(void); |
---|
| 243 | void real_solve(void); |
---|
| 244 | void restart(void); |
---|
| 245 | int preprocess(void); |
---|
| 246 | int deduce(void); |
---|
| 247 | void run_periodic_functions(void); |
---|
| 248 | |
---|
| 249 | // for decision making |
---|
| 250 | bool decide_next_branch(void); |
---|
| 251 | void decay_variable_score(void) ; |
---|
| 252 | void adjust_variable_order(int * lits, int n_lits); |
---|
| 253 | void update_var_score(void); |
---|
| 254 | |
---|
| 255 | // for conflict analysis |
---|
| 256 | ClauseIdx add_conflict_clause(int * lits, int n_lits, int gflag); |
---|
| 257 | int analyze_conflicts(void); |
---|
| 258 | ClauseIdx finish_add_conf_clause(int gflag); |
---|
| 259 | int conflict_analysis_firstUIP(void); |
---|
| 260 | void mark_vars(ClauseIdx cl, int var_idx); |
---|
| 261 | void back_track(int level); |
---|
| 262 | |
---|
| 263 | // for bcp |
---|
| 264 | void set_var_value(int var, int value, ClauseIdx ante, int dl); |
---|
| 265 | void set_var_value_BCP(int v, int value); |
---|
| 266 | void unset_var_value(int var); |
---|
| 267 | |
---|
| 268 | // misc functions |
---|
| 269 | bool time_out(void); |
---|
| 270 | void delete_unrelevant_clauses(void); |
---|
| 271 | ClauseIdx add_clause_with_gid(int * lits, int n_lits, int gid = 0); |
---|
| 272 | |
---|
| 273 | public: |
---|
| 274 | // constructors and destructors |
---|
| 275 | CSolver(void); |
---|
| 276 | ~CSolver(void); |
---|
| 277 | |
---|
| 278 | // member access function |
---|
| 279 | void set_time_limit(float t); |
---|
| 280 | void set_mem_limit(int s); |
---|
| 281 | void enable_cls_deletion(bool allow); |
---|
| 282 | void set_randomness(int n) ; |
---|
| 283 | void set_random_seed(int seed); |
---|
| 284 | |
---|
| 285 | void set_variable_number(int n); |
---|
| 286 | int add_variable(void) ; |
---|
| 287 | void mark_var_branchable(int vid); |
---|
| 288 | void mark_var_unbranchable(int vid); |
---|
| 289 | |
---|
| 290 | inline int & dlevel(void) { |
---|
| 291 | return _dlevel; |
---|
| 292 | } |
---|
| 293 | |
---|
| 294 | inline int outcome(void) { |
---|
| 295 | return _stats.outcome; |
---|
| 296 | } |
---|
| 297 | |
---|
| 298 | inline int num_decisions(void) { |
---|
| 299 | return _stats.num_decisions; |
---|
| 300 | } |
---|
| 301 | |
---|
| 302 | inline int num_decisions_stack_conf(void) { |
---|
| 303 | return _stats.num_decisions_stack_conf; |
---|
| 304 | } |
---|
| 305 | |
---|
| 306 | inline int num_decisions_vsids(void) { |
---|
| 307 | return _stats.num_decisions_vsids; |
---|
| 308 | } |
---|
| 309 | |
---|
| 310 | inline int num_decisions_shrinking(void) { |
---|
| 311 | return _stats.num_decisions_shrinking; |
---|
| 312 | } |
---|
| 313 | |
---|
| 314 | inline int num_shrinkings(void) { |
---|
| 315 | return _stats.num_shrinkings; |
---|
| 316 | } |
---|
| 317 | |
---|
| 318 | inline int & num_free_variables(void) { |
---|
| 319 | return _stats.num_free_variables; |
---|
| 320 | } |
---|
| 321 | |
---|
| 322 | inline int max_dlevel(void) { |
---|
| 323 | return _stats.max_dlevel; |
---|
| 324 | } |
---|
| 325 | |
---|
| 326 | inline int random_seed(void) { |
---|
| 327 | return _stats.random_seed; |
---|
| 328 | } |
---|
| 329 | |
---|
| 330 | inline long64 num_implications(void) { |
---|
| 331 | return _stats.num_implications; |
---|
| 332 | } |
---|
| 333 | |
---|
| 334 | inline long64 total_bubble_move(void) { |
---|
| 335 | return _stats.total_bubble_move; |
---|
| 336 | } |
---|
| 337 | |
---|
| 338 | inline const char * version(void) { |
---|
| 339 | return __ZCHAFF_VERSION__; |
---|
| 340 | } |
---|
| 341 | |
---|
| 342 | float elapsed_cpu_time(void); |
---|
| 343 | float cpu_run_time(void) ; |
---|
| 344 | int estimate_mem_usage(void) { |
---|
| 345 | return CDatabase::estimate_mem_usage(); |
---|
| 346 | } |
---|
| 347 | |
---|
| 348 | int mem_usage(void); |
---|
| 349 | |
---|
| 350 | void queue_implication(int lit, ClauseIdx ante_clause) { |
---|
| 351 | CImplication i; |
---|
| 352 | i.lit = lit; |
---|
| 353 | i.antecedent = ante_clause; |
---|
| 354 | _implication_queue.push(i); |
---|
| 355 | } |
---|
| 356 | |
---|
| 357 | // top level function |
---|
| 358 | inline int id(void) { |
---|
| 359 | return _id; |
---|
| 360 | } |
---|
| 361 | |
---|
| 362 | inline void set_id(int i) { |
---|
| 363 | _id = i; |
---|
| 364 | } |
---|
| 365 | |
---|
| 366 | inline void force_terminate(void) { |
---|
| 367 | _force_terminate = true; |
---|
| 368 | } |
---|
| 369 | |
---|
| 370 | inline void unset_force_terminate(void) { |
---|
| 371 | _force_terminate = false; |
---|
| 372 | } |
---|
| 373 | |
---|
| 374 | // for incremental SAT |
---|
| 375 | int add_clause_incr(int * lits, int n_lits, int gid = 0); |
---|
| 376 | |
---|
| 377 | void make_decision(int lit) { |
---|
| 378 | ++dlevel(); |
---|
| 379 | queue_implication(lit, NULL_CLAUSE); |
---|
| 380 | } |
---|
| 381 | |
---|
| 382 | void add_hook(HookFunPtrT fun, int interval); |
---|
| 383 | |
---|
| 384 | inline void add_outside_constraint_hook(OutsideConstraintHookPtrT fun) { |
---|
| 385 | _outside_constraint_hook = fun; |
---|
| 386 | } |
---|
| 387 | |
---|
| 388 | inline void add_sat_hook(SatHookPtrT fun) { |
---|
| 389 | _sat_hook = fun; |
---|
| 390 | } |
---|
| 391 | |
---|
| 392 | void verify_integrity(void); |
---|
| 393 | void delete_clause_group(int gid); |
---|
| 394 | void reset(void); |
---|
| 395 | int solve(void); |
---|
| 396 | ClauseIdx add_orig_clause(int * lits, int n_lits, int gid = 0); |
---|
| 397 | void clean_up_dbase(void); |
---|
| 398 | void dump_assignment_stack(ostream & os = cout); |
---|
| 399 | void dump_implication_queue(ostream & os = cout); |
---|
| 400 | |
---|
| 401 | void print_cls(ostream & os = cout); |
---|
| 402 | void dump(ostream & os = cout ) { |
---|
| 403 | CDatabase::dump(os); |
---|
| 404 | dump_assignment_stack(os); |
---|
| 405 | } |
---|
| 406 | void add_outside_clauses(void); |
---|
| 407 | }; |
---|
| 408 | #endif |
---|