00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef __SAT_SOLVER__
00041 #define __SAT_SOLVER__
00042
00043 #include <sys/time.h>
00044 #include <sys/resource.h>
00045
00046 #include "xchaff_utils.h"
00047 #include "xchaff_dbase.h"
00048
00049 #ifndef __SAT_STATUS__
00050 #define __SAT_STATUS__
00051 enum SAT_StatusT {
00052 UNDETERMINED,
00053 UNSATISFIABLE,
00054 SATISFIABLE,
00055 TIME_OUT,
00056 MEM_OUT,
00057 ABORTED
00058 };
00059 #endif
00060
00061 enum SAT_DeductionT {
00062 CONFLICT,
00063 NO_CONFLICT
00064 };
00065
00066 typedef void(*HookFunPtrT)(void *) ;
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 struct CSolverParameters {
00077 float time_limit;
00078
00079 int decision_strategy;
00080 int preprocess_strategy;
00081
00082 bool allow_clause_deletion;
00083 int clause_deletion_interval;
00084 int max_unrelevance;
00085 int min_num_clause_lits_for_delete;
00086 int max_conflict_clause_length;
00087 int bubble_init_step;
00088
00089 int verbosity;
00090 int randomness;
00091
00092 bool allow_restart;
00093 float next_restart_time;
00094 float restart_time_increment;
00095 float restart_time_incr_incr;
00096 int next_restart_backtrack;
00097 int restart_backtrack_incr;
00098 int restart_backtrack_incr_incr;
00099 int restart_randomness;
00100 int base_randomness;
00101
00102 bool back_track_complete;
00103 int conflict_analysis_method;
00104 bool allow_multiple_conflict;
00105 bool allow_multiple_conflict_clause;
00106 };
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 struct CSolverStats {
00117 bool is_solver_started;
00118 int outcome;
00119
00120 bool is_mem_out;
00121
00122 long start_cpu_time;
00123 long last_cpu_time;
00124 long finish_cpu_time;
00125 long start_world_time;
00126 long finish_world_time;
00127
00128 long long total_bubble_move;
00129
00130 int num_decisions;
00131 int num_backtracks;
00132 int max_dlevel;
00133 int num_implications;
00134 int num_free_variables;
00135 };
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 class CSolver:public CDatabase
00148 {
00149 protected:
00150 int _dlevel;
00151 vector<vector<int> *> _assignment_stack;
00152 queue<pair<int,ClauseIdx> > _implication_queue;
00153 CSolverParameters _params;
00154 CSolverStats _stats;
00155
00156 vector<pair<int,pair< HookFunPtrT, int> > > _hooks;
00157
00158
00159 int _max_score_pos;
00160 vector<int> _last_var_lits_count[2];
00161 vector<pair<int,int> >_var_order;
00162
00163
00164 int _num_marked;
00165 vector<ClauseIdx> _conflicts;
00166 vector<int> _conflict_lits;
00167
00168
00169 void (*_dlevel_hook)(void *, int);
00170 int (*_decision_hook)(void *, bool *);
00171 void (*_assignment_hook)(void *, int, int);
00172 void (*_deduction_hook)(void *);
00173 void *_dlevel_hook_cookie;
00174 void *_decision_hook_cookie;
00175 void *_assignment_hook_cookie;
00176 void *_deduction_hook_cookie;
00177
00178
00179 vector<ClauseIdx> _addedUnitClauses;
00180
00181 protected:
00182 void real_solve(void);
00183
00184 int preprocess(bool allowNewClauses);
00185
00186 int deduce(void);
00187
00188 bool decide_next_branch(void);
00189
00190 int analyze_conflicts(void);
00191 int conflict_analysis_grasp (void);
00192 int conflict_analysis_zchaff (void);
00193
00194 void back_track(int level);
00195
00196 void init(void);
00197
00198 void mark_vars_at_level(ClauseIdx cl,
00199 int var_idx,
00200 int dl);
00201
00202 int find_max_clause_dlevel(ClauseIdx cl);
00203
00204
00205 void set_var_value(int var,
00206 int value,
00207 ClauseIdx ante,
00208 int dl);
00209 void set_var_value_not_current_dl(int v,
00210 vector<CLitPoolElement *> & neg_ht_clauses);
00211 void set_var_value_with_current_dl(int v,
00212 vector<CLitPoolElement*> & neg_ht_clauses);
00213 void unset_var_value(int var);
00214
00215 void run_periodic_functions (void);
00216
00217 void update_var_stats(void);
00218
00219 bool time_out(void);
00220
00221 void delete_unrelevant_clauses(void);
00222 public:
00223
00224 CSolver() ;
00225 ~CSolver();
00226
00227 void set_time_limit(float t)
00228 { _params.time_limit = t; }
00229 void set_mem_limit(int s) {
00230 CDatabase::set_mem_limit(s);
00231 }
00232 void set_decision_strategy(int s)
00233 { _params.decision_strategy = s; }
00234 void set_preprocess_strategy(int s)
00235 { _params.preprocess_strategy = s; }
00236 void enable_cls_deletion(bool allow)
00237 { _params.allow_clause_deletion = allow; }
00238 void set_cls_del_interval(int n)
00239 { _params.clause_deletion_interval = n; }
00240 void set_max_unrelevance(int n )
00241 { _params.max_unrelevance = n; }
00242 void set_min_num_clause_lits_for_delete(int n)
00243 { _params.min_num_clause_lits_for_delete = n; }
00244 void set_max_conflict_clause_length(int l)
00245 { _params.max_conflict_clause_length = l; }
00246 void set_allow_multiple_conflict( bool b = false) {
00247 _params.allow_multiple_conflict = b ;
00248 }
00249 void set_allow_multiple_conflict_clause( bool b = false) {
00250 _params.allow_multiple_conflict_clause = b;
00251 }
00252 void set_randomness(int n) {
00253 _params.base_randomness = n;
00254 }
00255 void set_random_seed(int seed) {
00256 if (seed < 0)
00257 srand ( current_world_time() );
00258 else
00259 srand (seed);
00260 }
00261
00262
00263 void RegisterDLevelHook(void (*f)(void *, int), void *cookie)
00264 { _dlevel_hook = f; _dlevel_hook_cookie = cookie; }
00265 void RegisterDecisionHook(int (*f)(void *, bool *), void *cookie)
00266 { _decision_hook = f; _decision_hook_cookie = cookie; }
00267 void RegisterAssignmentHook(void (*f)(void *, int, int), void *cookie)
00268 { _assignment_hook = f; _assignment_hook_cookie = cookie; }
00269 void RegisterDeductionHook(void (*f)(void *), void *cookie)
00270 { _deduction_hook = f;
00271 _deduction_hook_cookie = cookie; }
00272
00273 int outcome () { return _stats.outcome; }
00274 int num_decisions() { return _stats.num_decisions; }
00275 int & num_free_variables() {
00276 return _stats.num_free_variables;
00277 }
00278 int max_dlevel() { return _stats.max_dlevel; }
00279 int num_implications() { return _stats.num_implications; }
00280 long long total_bubble_move(void) { return _stats.total_bubble_move; }
00281
00282 char * version(void){
00283 return "Z2001.2.17";
00284 }
00285
00286 int current_cpu_time(void) {
00287 struct rusage ru;
00288 getrusage(RUSAGE_SELF, &ru);
00289 return ( ru.ru_utime.tv_sec*1000 +
00290 ru.ru_utime.tv_usec/1000+
00291 ru.ru_stime.tv_sec*1000 +
00292 ru.ru_stime.tv_usec/1000 );
00293 }
00294
00295 int current_world_time(void) {
00296 struct timeval tv;
00297 struct timezone tz;
00298 gettimeofday(&tv,&tz);
00299 return (tv.tv_sec * 1000 + tv.tv_usec/1000) ;
00300 }
00301
00302 float elapsed_cpu_time() {
00303 int current = current_cpu_time();
00304 int diff = current - _stats.last_cpu_time;
00305 _stats.last_cpu_time = current;
00306 return diff/1000.0;
00307 }
00308
00309 float total_run_time() {
00310 if (!_stats.is_solver_started) return 0;
00311 return (current_cpu_time() -
00312 _stats.start_cpu_time)/1000.0 ;
00313 }
00314
00315 float cpu_run_time() {
00316 return (_stats.finish_cpu_time -
00317 _stats.start_cpu_time)/1000.0 ;
00318 }
00319
00320 float world_run_time() {
00321 return (_stats.finish_world_time -
00322 _stats.start_world_time) / 1000.0 ;
00323 }
00324
00325 int estimate_mem_usage() {
00326 return CDatabase::estimate_mem_usage();
00327 }
00328 int mem_usage(void) {
00329 int mem_dbase = CDatabase::mem_usage();
00330 int mem_assignment = 0;
00331 for (int i=0; i< _stats.max_dlevel; ++i)
00332 mem_assignment += _assignment_stack[i]->capacity() * sizeof(int);
00333 mem_assignment += sizeof(vector<int>)* _assignment_stack.size();
00334 return mem_dbase + mem_assignment;
00335 }
00336 int & dlevel() { return _dlevel; }
00337
00338
00339 void add_hook( HookFunPtrT fun, int interval) {
00340 pair<HookFunPtrT, int> a(fun, interval);
00341 _hooks.push_back(pair<int, pair<HookFunPtrT, int> > (0, a));
00342 }
00343
00344 void queue_implication (int lit, ClauseIdx ante_clause) {
00345 CHECK (cout << "\t\t\t\t\t\tQueueing " << (lit&0x01?" -":" +") << (lit>>1) ;
00346 cout << " because of " << ante_clause << endl; );
00347 _implication_queue.push(pair<int, ClauseIdx>(lit, ante_clause));
00348 }
00349
00350 int add_variables(int new_vars);
00351
00352 ClauseIdx add_clause(vector<int>& lits, bool addConflicts=true);
00353
00354 void verify_integrity(void);
00355
00356
00357 void restart (void){
00358 if (_params.verbosity > 1 )
00359 cout << "Restarting ... " << endl;
00360 if (dlevel() > 1) {
00361
00362 for (unsigned i=1; i<variables().size(); ++i) {
00363 variable(i).score(0) = 0;
00364 variable(i).score(1) = 0;
00365 _last_var_lits_count[0][i] = 0;
00366 _last_var_lits_count[1][i] = 0;
00367 }
00368 update_var_stats();
00369 back_track(1);
00370 }
00371 }
00372
00373 int solve(bool allowNewClauses);
00374 int continueCheck();
00375
00376 void dump_assignment_stack(ostream & os = cout);
00377
00378 void output_current_stats(void);
00379
00380 void dump(ostream & os = cout ) {
00381 CDatabase::dump(os);
00382 dump_assignment_stack(os);
00383 }
00384 };
00385 #endif
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416