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<long>  _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<long>& 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