00001
00002
00003
00004
00005
00006
00007
00008 #ifndef CONSTRAINTSOLVER_H_
00009 #define CONSTRAINTSOLVER_H_
00010
00011
00012 #include "CNode.h"
00013 #include <map>
00014 #include <set>
00015 #include <vector>
00016
00017
00018 enum atom_op_type
00019 {
00020 ATOM_EQ,
00021 ATOM_NEQ,
00022 ATOM_LEQ,
00023 ATOM_LT,
00024 ATOM_GT,
00025 ATOM_GEQ,
00026 ATOM_MOD
00027 };
00028
00029 using namespace std;
00030
00031 typedef pair<CNode*, CNode*> constraint_type;
00032 typedef int c_id;
00033
00034 class VariableTerm;
00035
00036
00037 using namespace __gnu_cxx;
00038
00039 struct cnode_eq
00040 {
00041 bool operator()(const CNode *const l1, const CNode*const l2) const
00042 {
00043 return *(CNode*)l1==*(CNode*)l2;
00044 }
00045 };
00046
00047 struct fun_bg
00048 {
00049 CNode* key;
00050 Term* quantified_var;
00051 CNode* nc_val;
00052 CNode* sc_val;
00053 };
00054
00055 class AccessPath;
00056 class IndexVarManager;
00057 class Constraint;
00058 class FunctionTerm;
00059
00060
00061 class ConstraintSolver {
00062 friend class Constraint;
00063 friend class Term;
00064 private:
00065 map<c_id, constraint_type> constraints;
00066 map<constraint_type, c_id > reverse_constraints;
00067 int id_count;
00068
00069
00070 bool bg_false;
00071
00072
00073
00074
00075
00076
00077 CNode *general_background;
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 map<CNode*, pair<CNode*, CNode*> > background;
00090
00091
00092
00093
00094
00095 map<int, Term*> fn_to_qvars;
00096 set<int> fn_ids;
00097
00098
00099 map<CNode*, CNode*> nc_reps;
00100 map<CNode*, CNode*> sc_reps;
00101
00102
00103
00104
00105 set<CNode*> bg_keys;
00106
00107
00108 vector<pair<int, string> > hardest;
00109
00110 vector<pair<int, string> > hardest_eliminate_overapproximate;
00111
00112 vector<pair<int, string> > hardest_eliminate_underapproximate;
00113
00114 bool bg_enabled;
00115
00116
00117
00118
00119 public:
00120 ConstraintSolver();
00121 virtual ~ConstraintSolver();
00122 void clear();
00123 void clear_local_data();
00124 void clear_stats();
00125
00126 int num_sat_queries;
00127 int num_bg_queries;
00128 int solve_time;
00129
00130 int eq_time;
00131 int num_eqs;
00132
00133 int bg_simp_time;
00134
00135
00136 int num_eliminate_over_queries;
00137 int num_eliminate_under_queries;
00138 int eliminate_over_time;
00139 int eliminate_under_time;
00140
00141
00142
00143 string stats_to_string();
00144
00145
00146 private:
00147 c_id get_true_constraint();
00148 c_id get_false_constraint();
00149 c_id get_atom(Term* t1, Term* t2, atom_op_type op);
00150 c_id get_constraint_from_cnode(CNode* n);
00151 c_id get_constraint_from_string(string & s);
00152
00153 c_id nc(c_id id);
00154 c_id sc(c_id id);
00155 CNode* get_nc(c_id& id);
00156 CNode* get_sc(c_id& id);
00157
00158 bool is_sat(c_id & id);
00159 bool is_sat_discard(c_id & id);
00160
00161 inline CNode* is_sat(CNode* node,
00162 simplification_level level, bool use_nc,
00163 void* assignments = NULL);
00164
00165 inline CNode* is_sat(CNode* node, CNode* assumption,
00166 simplification_level level, bool use_nc,
00167 void* assignments = NULL);
00168
00169 bool is_valid(c_id id);
00170 bool is_valid_discard(c_id id);
00171 inline CNode* is_valid(CNode* node, simplification_level level);
00172 bool implies(c_id c1, c_id c2);
00173
00174 c_id and_constraint(c_id id1, c_id id2);
00175 c_id or_constraint(c_id id1, c_id id2);
00176 c_id not_constraint(c_id id);
00177 c_id make_ncsc(c_id nc, c_id sc);
00178
00179 void clear_bg();
00180
00181 string constraint_to_string(c_id id);
00182
00183
00184
00185
00186 bool is_equal(c_id id1, c_id id2);
00187
00188
00189
00190
00191 bool is_equivalent(c_id id1, c_id id2);
00192 bool is_precise(c_id id) const;
00193
00194 bool implies(CNode* n1, CNode* n2);
00195
00196 c_id get_id(constraint_type& c);
00197
00198
00199 void get_free_vars(c_id id, set<Term*>& vars);
00200
00201 void get_terms(c_id id, set<Term*>& terms, bool include_nested_terms);
00202
00203
00204
00205
00206
00207
00208 c_id eliminate_evar(c_id id, VariableTerm* var);
00209 c_id eliminate_evars(c_id id, set<VariableTerm*>& vars);
00210
00211
00212
00213
00214 c_id eliminate_uvar(c_id id, VariableTerm* var);
00215 c_id eliminate_uvars(c_id id, set<VariableTerm*>& vars);
00216
00217 c_id divide(c_id id, long int c, Term* t);
00218
00219
00220
00221
00222
00223 c_id eliminate_free_var(c_id id, VariableTerm* var);
00224 c_id eliminate_free_vars(c_id id, set<VariableTerm*>& vars);
00225 CNode* eliminate_free_var_nc(CNode* nc, VariableTerm* v);
00226 CNode* eliminate_free_var_sc(CNode* sc, VariableTerm* v);
00227
00228
00229 bool get_assignment(c_id it, set<pair<string, string> > & assignments);
00230
00231 bool get_assignment(c_id it, map<Term*, SatValue> & assignments);
00232
00233
00234 bool contains_inequality(c_id id);
00235
00236
00237
00238
00239 Term* find_equality(c_id id, Term* t);
00240
00241 void find_equalities(c_id id, Term* t, set<Term*> & eqs);
00242
00243 c_id replace_constraint(c_id old_id, c_id to_replace, c_id replacement);
00244
00245
00246
00247
00248
00249 bool has_equality_relation(c_id id, Term* t1, Term* t2);
00250
00251
00252 void get_disjunctive_equalities(c_id id, Term* var,
00253 map<Term*, Constraint> & equalities);
00254
00255
00256 c_id replace_term(c_id old_id, Term* to_replace, Term*
00257 replacement);
00258 c_id replace_terms(c_id old_id, map<Term*, Term*>& replacements);
00259
00260 c_id replace_terms(c_id old_id, Term* (*sub_func)(Term* t, void* data),
00261 void* my_data)
00262 {
00263 constraint_type ct = constraints[old_id];
00264 CNode* nc= ct.first;
00265 CNode* sc = ct.second;
00266 CNode* new_nc = nc->substitute(sub_func, my_data);
00267 if(nc == sc) {
00268 if(nc == new_nc) return old_id;
00269 constraint_type ct(new_nc, new_nc);
00270 return get_id(ct);
00271 }
00272
00273 CNode* new_sc = sc->substitute(sub_func, my_data);
00274 ct = constraint_type(new_nc, new_sc);
00275 return get_id(ct);
00276 }
00277
00278 bool contains_term(c_id id, Term* t);
00279 bool contains_term(c_id id, set<Term*>& terms);
00280
00281 c_id replace_constraints(c_id old_id, map<Constraint, Constraint>& replacements);
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void add_axiom(c_id key_id, c_id value_id, bool check_function_term);
00295
00296
00297 void replace_term_in_axioms(Term* old_t, Term* new_t);
00298
00299
00300
00301
00302
00303 void set_background_knowledge(c_id id);
00304
00305
00306
00307
00308 CNode* eliminate_var(CNode* n, VariableTerm* var,
00309 simplification_level level, bool over);
00310
00311 CNode* eliminate_var(CNode* n, vector<VariableTerm*> & vars,
00312 simplification_level level, bool over);
00313
00314 void add_to_hardest(vector<pair<int, string> > & hardest, int time,
00315 const string& cur);
00316
00317 string get_hardest(vector<pair<int, string> > & hardest);
00318
00319 c_id assume(c_id id, c_id other);
00320
00321 string bg_to_string();
00322 c_id get_general_background();
00323
00324 int nc_size(c_id id);
00325 int sc_size(c_id id);
00326
00327 c_id propagate_background(c_id id);
00328
00329
00330
00331
00332
00333 void disable_background();
00334
00335 int msa(set<VariableTerm*> & msa, c_id id, map<VariableTerm*, int>& costs);
00336 int msa(set<VariableTerm*> & msa, c_id id, set<c_id>& bg,
00337 map<VariableTerm*, int>& costs);
00338
00339 pair<CNode*, CNode*> get_cnodes(c_id id);
00340
00341 private:
00342
00343 bool is_mod_term(Term* t);
00344
00345
00346 bool is_valid_mod_term(Term* t);
00347
00348
00349
00350
00351
00352
00353
00354
00355 CNode* include_background_dependencies(CNode* bg_value, bool use_nc = true);
00356
00357
00358
00359
00360
00361 CNode* get_background_dependencies(CNode* node, bool use_nc = true);
00362
00363 void get_relevant_axioms(CNode* constraint, set<CNode*>& relevant_axioms);
00364
00365
00366
00367
00368 void add_background(CNode* key, CNode* nc, CNode* sc);
00369
00370
00371
00372
00373
00374 void add_to_rep_map(CNode* key, CNode* nc, CNode* sc);
00375
00376 CNode* simplify(CNode* c);
00377
00378
00379
00380
00381
00382
00383 void instantiate_axioms(CNode* c, map<CNode*, CNode*>& axioms,
00384 map<CNode*, CNode*> & instantiated_axioms);
00385
00386
00387 c_id get_new_id(c_id old_id);
00388
00389
00390 void to_dnf(c_id c, set<c_id> & dnf);
00391
00392
00393
00394
00395
00396
00397
00398
00399 };
00400
00401 #endif