CVC3

xchaff_solver.h

Go to the documentation of this file.
00001 /* =========FOR INTERNAL USE ONLY. NO DISTRIBUTION PLEASE ========== */
00002 
00003 /*********************************************************************
00004  Copyright 2000-2001, Princeton University.  All rights reserved.
00005  By using this software the USER indicates that he or she has read,
00006  understood and will comply with the following:
00007 
00008  --- Princeton University hereby grants USER nonexclusive permission
00009  to use, copy and/or modify this software for internal, noncommercial,
00010  research purposes only. Any distribution, including commercial sale
00011  or license, of this software, copies of the software, its associated
00012  documentation and/or modifications of either is strictly prohibited
00013  without the prior consent of Princeton University.  Title to copyright
00014  to this software and its associated documentation shall at all times
00015  remain with Princeton University.  Appropriate copyright notice shall
00016  be placed on all software copies, and a complete copy of this notice
00017  shall be included in all copies of the associated documentation.
00018  No right is  granted to use in advertising, publicity or otherwise
00019  any trademark,  service mark, or the name of Princeton University.
00020 
00021 
00022  --- This software and any associated documentation is provided "as is"
00023 
00024  PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS
00025  OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A
00026  PARTICULAR PURPOSE, OR THAT  USE OF THE SOFTWARE, MODIFICATIONS, OR
00027  ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS,
00028  TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY.
00029 
00030  Princeton University shall not be liable under any circumstances for
00031  any direct, indirect, special, incidental, or consequential damages
00032  with respect to any claim by USER or any third party on account of
00033  or arising from the use, or inability to use, this software or its
00034  associated documentation, even if Princeton University has been advised
00035  of the possibility of those damages.
00036 *********************************************************************/
00037 
00038 
00039 
00040 #ifndef __SAT_SOLVER__
00041 #define __SAT_SOLVER__
00042 
00043 #include <sys/time.h>
00044 #include <sys/resource.h>
00045 #include <stdlib.h>
00046 
00047 #include "xchaff_utils.h"
00048 #include "xchaff_dbase.h"
00049 
00050 #ifndef __SAT_STATUS__
00051 #define __SAT_STATUS__
00052 enum SAT_StatusT {
00053     UNDETERMINED,
00054     UNSATISFIABLE,
00055     SATISFIABLE,
00056     TIME_OUT,
00057     MEM_OUT,
00058     ABORTED
00059 };
00060 #endif
00061 
00062 enum SAT_DeductionT {
00063     CONFLICT,
00064     NO_CONFLICT
00065 };
00066 
00067 typedef void(*HookFunPtrT)(void *) ;
00068 /**Struct**********************************************************************
00069 
00070   Synopsis    [Sat solver parameters ]
00071 
00072   Description []
00073 
00074   SeeAlso     []
00075 
00076 ******************************************************************************/
00077 struct CSolverParameters {
00078     float   time_limit;
00079 
00080     int   decision_strategy;
00081     int   preprocess_strategy;
00082 
00083     bool  allow_clause_deletion;
00084     int         clause_deletion_interval;
00085     int   max_unrelevance;
00086     int   min_num_clause_lits_for_delete;
00087     int   max_conflict_clause_length;
00088     int   bubble_init_step;
00089 
00090     int   verbosity;
00091     int   randomness;
00092 
00093     bool  allow_restart;
00094     float next_restart_time;
00095     float restart_time_increment;
00096     float restart_time_incr_incr;
00097     int   next_restart_backtrack;
00098     int   restart_backtrack_incr;
00099     int   restart_backtrack_incr_incr;
00100     int   restart_randomness;
00101     int   base_randomness;
00102 
00103     bool  back_track_complete;
00104     int   conflict_analysis_method;
00105     bool  allow_multiple_conflict;
00106     bool  allow_multiple_conflict_clause;
00107 };
00108 /**Struct**********************************************************************
00109 
00110   Synopsis    [Sat solver statistics ]
00111 
00112   Description []
00113 
00114   SeeAlso     []
00115 
00116 ******************************************************************************/
00117 struct CSolverStats {
00118     bool  is_solver_started;
00119     int   outcome;
00120 
00121     bool  is_mem_out;   //this flag will be set if memory out
00122 
00123     long  start_cpu_time;
00124     long  last_cpu_time;
00125     long  finish_cpu_time;
00126     long  start_world_time;
00127     long  finish_world_time;
00128 
00129     long    total_bubble_move;
00130 
00131     int   num_decisions;
00132     int   num_backtracks;
00133     int   max_dlevel;
00134     int   num_implications;
00135     int   num_free_variables;
00136 };
00137 
00138 /**Class**********************************************************************
00139 
00140   Synopsis    [Sat Solver]
00141 
00142   Description [This class contains the process and datastructrues to solve
00143                the Sat problem.]
00144 
00145   SeeAlso     []
00146 
00147 ******************************************************************************/
00148 class CSolver:public CDatabase
00149 {
00150 protected:
00151     int       _dlevel;    //current decision elvel
00152     vector<vector<int> *>   _assignment_stack;
00153     queue<pair<int,ClauseIdx> > _implication_queue;
00154     CSolverParameters     _params;
00155     CSolverStats        _stats;
00156 
00157     vector<pair<int,pair< HookFunPtrT, int> > > _hooks;
00158 
00159 //these are for decision making
00160     int       _max_score_pos;
00161     vector<int>     _last_var_lits_count[2];
00162     vector<pair<int,int> >_var_order;
00163 
00164 //these are for conflict analysis
00165     int     _num_marked;  //used when constructing conflict clauses
00166     vector<ClauseIdx>   _conflicts; //the conflict clauses
00167     vector<long>  _conflict_lits; //used when constructing conflict clauses
00168 
00169 //these are for the extended API
00170     void (*_dlevel_hook)(void *, int);
00171     int  (*_decision_hook)(void *, bool *);
00172     void (*_assignment_hook)(void *, int, int);
00173     void (*_deduction_hook)(void *);
00174     void *_dlevel_hook_cookie;
00175     void *_decision_hook_cookie;
00176     void *_assignment_hook_cookie;
00177     void *_deduction_hook_cookie;
00178 
00179 //needed to support dynamic adding of unit clauses
00180     vector<ClauseIdx> _addedUnitClauses;
00181 
00182 protected:
00183     void real_solve(void);
00184 
00185     int preprocess(bool allowNewClauses);
00186 
00187     int deduce(void);
00188 
00189     bool decide_next_branch(void);
00190 
00191     int analyze_conflicts(void);
00192     int conflict_analysis_grasp (void);
00193     int conflict_analysis_zchaff (void);
00194 
00195     void back_track(int level);
00196 
00197     void init(void);
00198 //for conflict analysis
00199     void mark_vars_at_level(ClauseIdx cl,
00200           int var_idx,
00201           int dl);
00202 
00203     int find_max_clause_dlevel(ClauseIdx cl); //the max dlevel of all the assigned lits in this clause
00204 
00205 //for bcp
00206     void set_var_value(int var,
00207            int value,
00208            ClauseIdx ante,
00209            int dl);
00210     void set_var_value_not_current_dl(int v,
00211               vector<CLitPoolElement *> & neg_ht_clauses);
00212     void set_var_value_with_current_dl(int v,
00213                vector<CLitPoolElement*> & neg_ht_clauses);
00214     void unset_var_value(int var);
00215 
00216     void run_periodic_functions (void);
00217 //misc functions
00218     void update_var_stats(void);
00219 
00220     bool time_out(void);
00221 
00222     void delete_unrelevant_clauses(void);
00223 public:
00224 //constructors and destructors
00225     CSolver() ;
00226     ~CSolver();
00227 //member access function
00228     void set_time_limit(float t)
00229   { _params.time_limit = t; }
00230     void set_mem_limit(int s)   {
00231   CDatabase::set_mem_limit(s);
00232     }
00233     void set_decision_strategy(int s)
00234   { _params.decision_strategy = s; }
00235     void set_preprocess_strategy(int s)
00236   { _params.preprocess_strategy = s; }
00237     void enable_cls_deletion(bool allow)
00238   { _params.allow_clause_deletion = allow; }
00239     void set_cls_del_interval(int n)
00240   { _params.clause_deletion_interval = n; }
00241     void set_max_unrelevance(int n )
00242   { _params.max_unrelevance = n; }
00243     void set_min_num_clause_lits_for_delete(int n)
00244   { _params.min_num_clause_lits_for_delete = n; }
00245     void set_max_conflict_clause_length(int l)
00246   { _params.max_conflict_clause_length = l; }
00247     void set_allow_multiple_conflict( bool b = false) {
00248   _params.allow_multiple_conflict = b ;
00249     }
00250     void set_allow_multiple_conflict_clause( bool b = false) {
00251   _params.allow_multiple_conflict_clause = b;
00252     }
00253     void set_randomness(int n) {
00254   _params.base_randomness = n;
00255     }
00256     void set_random_seed(int seed) {
00257   if (seed < 0)
00258       srand ( current_world_time() );
00259   else
00260       srand (seed);
00261     }
00262 
00263 //these are for the extended API
00264     void RegisterDLevelHook(void (*f)(void *, int), void *cookie)
00265          { _dlevel_hook = f; _dlevel_hook_cookie = cookie; }
00266     void RegisterDecisionHook(int (*f)(void *, bool *), void *cookie)
00267          { _decision_hook = f; _decision_hook_cookie = cookie; }
00268     void RegisterAssignmentHook(void (*f)(void *, int, int), void *cookie)
00269          { _assignment_hook = f; _assignment_hook_cookie = cookie; }
00270     void RegisterDeductionHook(void (*f)(void *), void *cookie)
00271          { _deduction_hook = f;
00272            _deduction_hook_cookie = cookie; }
00273 
00274     int outcome ()  { return _stats.outcome; }
00275     int num_decisions() { return _stats.num_decisions; }
00276     int & num_free_variables() {
00277   return _stats.num_free_variables;
00278     }
00279     int max_dlevel()  { return _stats.max_dlevel; }
00280     int num_implications() { return _stats.num_implications; }
00281     long total_bubble_move(void) {  return _stats.total_bubble_move; }
00282 
00283     const char * version(void){
00284   return "Z2001.2.17";
00285     }
00286 
00287     int current_cpu_time(void) {
00288   struct rusage ru;
00289   getrusage(RUSAGE_SELF, &ru);
00290   return ( ru.ru_utime.tv_sec*1000 +
00291      ru.ru_utime.tv_usec/1000+
00292      ru.ru_stime.tv_sec*1000 +
00293      ru.ru_stime.tv_usec/1000 );
00294     }
00295 
00296     int current_world_time(void) {
00297   struct timeval tv;
00298   struct timezone tz;
00299   gettimeofday(&tv,&tz);
00300   return (tv.tv_sec * 1000 + tv.tv_usec/1000) ;
00301     }
00302 
00303     float elapsed_cpu_time() {
00304   int current = current_cpu_time();
00305   int diff = current - _stats.last_cpu_time;
00306   _stats.last_cpu_time = current;
00307   return diff/1000.0;
00308     }
00309 
00310     float total_run_time() {
00311       if (!_stats.is_solver_started) return 0;
00312       return (current_cpu_time() -
00313         _stats.start_cpu_time)/1000.0 ;
00314     }
00315 
00316     float cpu_run_time() {
00317   return (_stats.finish_cpu_time -
00318     _stats.start_cpu_time)/1000.0 ;
00319     }
00320 
00321     float world_run_time() {
00322   return (_stats.finish_world_time -
00323     _stats.start_world_time) / 1000.0 ;
00324     }
00325 
00326     int estimate_mem_usage() {
00327   return CDatabase::estimate_mem_usage();
00328     }
00329     int mem_usage(void) {
00330   int mem_dbase = CDatabase::mem_usage();
00331   int mem_assignment = 0;
00332   for (int i=0; i< _stats.max_dlevel; ++i)
00333       mem_assignment += _assignment_stack[i]->capacity() * sizeof(int);
00334   mem_assignment += sizeof(vector<int>)* _assignment_stack.size();
00335   return mem_dbase + mem_assignment;
00336     }
00337     int & dlevel() { return _dlevel; }
00338 
00339 //top level function
00340     void add_hook( HookFunPtrT fun, int interval) {
00341   pair<HookFunPtrT, int> a(fun, interval);
00342   _hooks.push_back(pair<int, pair<HookFunPtrT, int> > (0, a));
00343     }
00344 
00345     void queue_implication (int lit, ClauseIdx ante_clause) {
00346   CHECK (cout << "\t\t\t\t\t\tQueueing " << (lit&0x01?" -":" +") << (lit>>1) ;
00347          cout << " because of  " << ante_clause << endl; );
00348   _implication_queue.push(pair<int, ClauseIdx>(lit, ante_clause));
00349     }
00350 
00351     int add_variables(int new_vars);
00352 
00353     ClauseIdx add_clause(vector<long>& lits, bool addConflicts=true);
00354 
00355     void verify_integrity(void);
00356 
00357 //    ClauseIdx add_clause_with_order_adjustment(int * lits, int n_lits);
00358     void restart (void){
00359   if (_params.verbosity > 1 )
00360       cout << "Restarting ... " << endl;
00361   if (dlevel() > 1) {
00362       //clean up the original var_stats.
00363       for (unsigned i=1; i<variables().size(); ++i) {
00364     variable(i).score(0) = 0;
00365     variable(i).score(1) = 0;
00366     _last_var_lits_count[0][i] = 0;
00367     _last_var_lits_count[1][i] = 0;
00368       }
00369       update_var_stats();
00370       back_track(1); //backtrack to level 0. restart.
00371   }
00372     }
00373 
00374     int solve(bool allowNewClauses);
00375     int continueCheck();
00376 
00377     void dump_assignment_stack(ostream & os = cout);
00378 
00379     void output_current_stats(void);
00380 
00381     void dump(ostream & os = cout ) {
00382   CDatabase::dump(os);
00383   dump_assignment_stack(os);
00384     }
00385 };
00386 #endif
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 
00417