CVC3
|
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