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 #ifndef _cvcl__include__theory_arith_h_
00030 #define _cvcl__include__theory_arith_h_
00031
00032 #include "theory.h"
00033 #include "type.h"
00034 #include "cdlist.h"
00035 #include "cdmap.h"
00036 #include "expr_map.h"
00037 #include <set>
00038
00039 namespace CVCL {
00040
00041 class ArithProofRules;
00042
00043 typedef enum {
00044 REAL = 3000,
00045 INT,
00046 SUBRANGE,
00047
00048 UMINUS,
00049 PLUS,
00050 MINUS,
00051 MULT,
00052 DIVIDE,
00053 POW,
00054 INTDIV,
00055 MOD,
00056 LT,
00057 LE,
00058 GT,
00059 GE,
00060 IS_INTEGER,
00061 NEGINF,
00062 POSINF,
00063 DARK_SHADOW,
00064 GRAY_SHADOW
00065 } ArithKinds;
00066
00067
00068 typedef enum {
00069 NOT_USED = 0,
00070 TERMS_ONLY,
00071 DIFF_ONLY,
00072 LINEAR,
00073 NONLINEAR
00074 } ArithLang;
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 class TheoryArith :public Theory {
00088 VCL* d_vcl;
00089 size_t d_grayShadowMMIndex;
00090 Type d_realType;
00091 Type d_intType;
00092 CDList<Theorem> d_diseq;
00093 CDO<size_t> d_diseqIdx;
00094 ArithProofRules* d_rules;
00095 CDO<bool> d_inModelCreation;
00096 bool d_realUsed;
00097 bool d_intUsed;
00098 bool d_intConstUsed;
00099 ArithLang d_langUsed;
00100
00101 class FreeConst {
00102 private:
00103 Rational d_r;
00104 bool d_strict;
00105 public:
00106 FreeConst() { }
00107 FreeConst(const Rational& r, bool strict): d_r(r), d_strict(strict) { }
00108 const Rational& getConst() const { return d_r; }
00109 bool strict() const { return d_strict; }
00110 };
00111
00112 friend std::ostream& operator<<(std::ostream& os, const FreeConst& fc);
00113
00114 class Ineq {
00115 private:
00116 Theorem d_ineq;
00117 bool d_rhs;
00118 const FreeConst* d_const;
00119
00120 Ineq() { }
00121 public:
00122
00123 Ineq(const Theorem& ineq, bool varOnRHS, const FreeConst& c):
00124 d_ineq(ineq), d_rhs(varOnRHS), d_const(&c) { }
00125
00126 const Theorem& ineq() const { return d_ineq; }
00127
00128 const FreeConst& getConst() const { return *d_const; }
00129
00130 bool varOnRHS() const { return d_rhs; }
00131
00132 bool varOnLHS() const { return !d_rhs; }
00133
00134 operator Theorem() const { return d_ineq; }
00135 };
00136
00137 friend std::ostream& operator<<(std::ostream& os, const Ineq& ineq);
00138
00139 ExprMap<CDList<Ineq> *> d_inequalitiesRightDB;
00140
00141 ExprMap<CDList<Ineq> *> d_inequalitiesLeftDB;
00142
00143
00144
00145
00146
00147
00148
00149
00150 CDMap<Expr, FreeConst> d_freeConstDB;
00151
00152 CDList<Theorem> d_buffer;
00153 CDO<size_t> d_bufferIdx;
00154 const int* d_bufferThres;
00155
00156
00157
00158 CDMap<Expr, int> d_countRight;
00159
00160
00161 CDMap<Expr, int> d_countLeft;
00162
00163 CDMap<Expr, bool> d_sharedTerms;
00164
00165 CDMap<Expr, bool> d_sharedVars;
00166
00167
00168 class VarOrderGraph {
00169 ExprMap<std::vector<Expr> > d_edges;
00170 ExprMap<bool> d_cache;
00171 bool dfs(const Expr& e1, const Expr& e2);
00172 public:
00173 void addEdge(const Expr& e1, const Expr& e2);
00174
00175 bool lessThan(const Expr& e1, const Expr& e2);
00176
00177
00178 void selectLargest(const std::vector<Expr>& v1, std::vector<Expr>& v2);
00179
00180
00181 void selectSmallest( std::vector<Expr>& v1, std::vector<Expr>& v2);
00182
00183 };
00184
00185 VarOrderGraph d_graph;
00186
00187
00188
00189
00190 Theorem isIntegerThm(const Expr& e);
00191
00192
00193 Theorem isIntegerDerive(const Expr& isIntE, const Theorem& thm);
00194
00195 bool isInteger(const Expr& e) { return !(isIntegerThm(e).isNull()); }
00196
00197 const Rational& freeConstIneq(const Expr& ineq, bool varOnRHS);
00198
00199
00200
00201
00202
00203
00204 const FreeConst& updateSubsumptionDB(const Expr& ineq, bool varOnRHS,
00205 bool& subsumed);
00206
00207 bool kidsCanonical(const Expr& e);
00208
00209 Theorem canon(const Expr& e);
00210
00211
00212 Theorem canon(const Theorem& thm) {
00213 return transitivityRule(thm, canon(thm.getRHS()));
00214 }
00215
00216
00217 Theorem canonSimplify(const Expr& e);
00218
00219
00220
00221 Theorem canonSimplify(const Theorem& thm) {
00222 return transitivityRule(thm, canonSimplify(thm.getRHS()));
00223 }
00224
00225 Theorem canonPred(const Theorem& thm);
00226
00227
00228 Theorem canonPredEquiv(const Theorem& thm);
00229
00230 Theorem doSolve(const Theorem& e);
00231
00232 Theorem canonConjunctionEquiv(const Theorem& thm);
00233
00234
00235 Expr pickIntEqMonomial(const Expr& right);
00236
00237 Theorem processRealEq(const Theorem& eqn);
00238
00239 Theorem processIntEq(const Theorem& eqn);
00240
00241 Theorem processSimpleIntEq(const Theorem& eqn);
00242
00243 void processBuffer();
00244
00245 Theorem isolateVariable(const Theorem& inputThm, bool& e1);
00246
00247 void updateStats(const Rational& c, const Expr& var);
00248
00249 void updateStats(const Expr& monomial);
00250
00251 void addToBuffer(const Theorem& thm);
00252
00253
00254 Expr computeNormalFactor(const Expr& rhs);
00255
00256 Theorem normalize(const Expr& e);
00257
00258
00259
00260
00261 Theorem normalize(const Theorem& thm);
00262 Expr pickMonomial(const Expr& right);
00263 public:
00264
00265 void separateMonomial(const Expr& e, Expr& c, Expr& var);
00266 private:
00267 bool lessThanVar(const Expr& isolatedVar, const Expr& var2);
00268
00269 bool isStale(const Expr& e);
00270
00271 bool isStale(const Ineq& ineq);
00272 void projectInequalities(const Theorem& theInequality,bool isolatedVarOnRHS);
00273 void assignVariables(std::vector<Expr>&v);
00274 void findRationalBound(const Expr& varSide, const Expr& ratSide,
00275 const Expr& var,
00276 Rational &r);
00277 bool findBounds(const Expr& e, Rational& lub, Rational& glb);
00278
00279 Theorem normalizeProjectIneqs(const Theorem& ineqThm1,
00280 const Theorem& ineqThm2);
00281
00282 Theorem solvedForm(const std::vector<Theorem>& solvedEqs);
00283
00284
00285
00286 Theorem substAndCanonize(const Expr& t, ExprMap<Theorem>& subst);
00287
00288
00289
00290
00291 Theorem substAndCanonize(const Theorem& eq, ExprMap<Theorem>& subst);
00292
00293 void collectVars(const Expr& e, std::vector<Expr>& vars,
00294 std::set<Expr>& cache);
00295
00296
00297
00298 void processFiniteInterval(const Theorem& alphaLEax,
00299 const Theorem& bxLEbeta);
00300
00301 void processFiniteIntervals(const Expr& x);
00302
00303 void setupRec(const Expr& e);
00304
00305 bool isSyntacticRational(const Expr& e);
00306
00307 bool isSyntacticUMinusVar(const Expr& e, Expr& var);
00308 public:
00309 TheoryArith(VCL* vcl);
00310 ~TheoryArith();
00311
00312
00313 bool realUsed() { return d_realUsed; }
00314
00315 bool intUsed() { return d_intUsed || (d_intConstUsed && !d_realUsed); }
00316
00317 ArithLang getLangUsed() { return d_langUsed; }
00318
00319 bool theoryUsed()
00320 { return d_realUsed || d_intUsed || d_intConstUsed || (d_langUsed != NOT_USED); }
00321
00322
00323
00324
00325 ArithProofRules* createProofRules(VCL* vcl);
00326
00327
00328 void addSharedTerm(const Expr& e);
00329 void assertFact(const Theorem& e);
00330 void refineCounterExample();
00331 void computeModelBasic(const std::vector<Expr>& v);
00332 void computeModel(const Expr& e, std::vector<Expr>& vars);
00333 void checkSat(bool fullEffort);
00334 Theorem rewrite(const Expr& e);
00335 void setup(const Expr& e);
00336 void update(const Theorem& e, const Expr& d);
00337 Theorem solve(const Theorem& e);
00338 void computeType(const Expr& e);
00339 Type computeBaseType(const Type& t);
00340 void computeModelTerm(const Expr& e, std::vector<Expr>& v);
00341 Expr computeTypePred(const Type& t, const Expr& e);
00342 Expr computeTCC(const Expr& e);
00343 ExprStream& print(ExprStream& os, const Expr& e);
00344 virtual Expr parseExprOp(const Expr& e);
00345
00346
00347 Type realType() { return d_realType; }
00348 Type intType() { return d_intType;}
00349 Type subrangeType(const Expr& l, const Expr& r)
00350 { return Type(newExpr(getEM(), SUBRANGE, l, r)); }
00351 Expr rat(Rational r) { return newRatExpr(d_realType.getExpr().getEM(), r); }
00352
00353
00354 Expr darkShadow(const Expr& lhs, const Expr& rhs) {
00355 return newExpr(getEM(), DARK_SHADOW, lhs, rhs);
00356 }
00357
00358
00359
00360 Expr grayShadow(const Expr& v, const Expr& e,
00361 const Rational& c1, const Rational& c2);
00362
00363 const Rational& getC1(const Expr& grayShadow);
00364
00365 const Rational& getC2(const Expr& grayShadow);
00366
00367 const Expr& getV(const Expr& grayShadow);
00368
00369 const Expr& getE(const Expr& grayShadow);
00370
00371 bool isGrayShadow(const Expr& e)
00372 { return e.getMMIndex() == d_grayShadowMMIndex; }
00373 };
00374
00375
00376 inline bool isReal(Type t) { return t.getExpr().getKind() == REAL; }
00377 inline bool isInt(Type t) { return t.getExpr().getKind() == INT; }
00378
00379
00380 inline bool isRational(const Expr& e) { return e.isRational(); }
00381 inline bool isUMinus(const Expr& e) { return e.getKind() == UMINUS; }
00382 inline bool isPlus(const Expr& e) { return e.getKind() == PLUS; }
00383 inline bool isMinus(const Expr& e) { return e.getKind() == MINUS; }
00384 inline bool isMult(const Expr& e) { return e.getKind() == MULT; }
00385 inline bool isDivide(const Expr& e) { return e.getKind() == DIVIDE; }
00386 inline bool isLT(const Expr& e) { return e.getKind() == LT; }
00387 inline bool isLE(const Expr& e) { return e.getKind() == LE; }
00388 inline bool isGT(const Expr& e) { return e.getKind() == GT; }
00389 inline bool isGE(const Expr& e) { return e.getKind() == GE; }
00390 inline bool isDarkShadow(const Expr& e) { return e.getKind() == DARK_SHADOW;}
00391 inline bool isIneq(const Expr& e)
00392 { return isLT(e) || isLE(e) || isGT(e) || isGE(e); }
00393 inline bool isIntPred(const Expr& e) { return e.getKind() == IS_INTEGER; }
00394
00395
00396 inline Expr uminusExpr(const Expr& child)
00397 { return newExpr(child.getEM(), UMINUS, child); }
00398 inline Expr plusExpr(const Expr& left, const Expr& right)
00399 { return newExpr(left.getEM(), PLUS, left, right); }
00400 inline Expr plusExpr(const std::vector<Expr>& children) {
00401 DebugAssert(children.size() > 0, "plusExpr()");
00402 return newExpr(children[0].getEM(), PLUS, children);
00403 }
00404 inline Expr minusExpr(const Expr& left, const Expr& right)
00405 { return newExpr(left.getEM(), MINUS, left, right); }
00406 inline Expr multExpr(const Expr& left, const Expr& right)
00407 { return newExpr(left.getEM(), MULT, left, right); }
00408
00409
00410 inline Expr multExpr(const std::vector<Expr>& children) {
00411 DebugAssert(children.size() > 0, "multExpr()");
00412 return newExpr(children[0].getEM(), MULT, children);
00413 }
00414
00415 inline Expr powExpr(const Expr& pow, const Expr & base)
00416 { return newExpr(pow.getEM(), POW, pow, base);}
00417
00418 inline Expr divideExpr(const Expr& left, const Expr& right)
00419 { return newExpr(left.getEM(), DIVIDE, left, right); }
00420 inline Expr ltExpr(const Expr& left, const Expr& right)
00421 { return newExpr(left.getEM(), LT, left, right); }
00422 inline Expr leExpr(const Expr& left, const Expr& right)
00423 { return newExpr(left.getEM(), LE, left, right); }
00424 inline Expr gtExpr(const Expr& left, const Expr& right)
00425 { return newExpr(left.getEM(), GT, left, right); }
00426 inline Expr geExpr(const Expr& left, const Expr& right)
00427 { return newExpr(left.getEM(), GE, left, right); }
00428
00429 inline Expr operator-(const Expr& child)
00430 { return uminusExpr(child); }
00431 inline Expr operator+(const Expr& left, const Expr& right)
00432 { return plusExpr(left, right); }
00433 inline Expr operator-(const Expr& left, const Expr& right)
00434 { return minusExpr(left, right); }
00435 inline Expr operator*(const Expr& left, const Expr& right)
00436 { return multExpr(left, right); }
00437 inline Expr operator/(const Expr& left, const Expr& right)
00438 { return divideExpr(left, right); }
00439
00440 }
00441
00442 #endif