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 "cdmap.h"
00034
00035 namespace CVCL {
00036
00037 class VCL;
00038 class ArithProofRules;
00039
00040 typedef enum {
00041 REAL = 3000,
00042 INT,
00043 SUBRANGE,
00044
00045 UMINUS,
00046 PLUS,
00047 MINUS,
00048 MULT,
00049 DIVIDE,
00050 POW,
00051 INTDIV,
00052 MOD,
00053 LT,
00054 LE,
00055 GT,
00056 GE,
00057 IS_INTEGER,
00058 NEGINF,
00059 POSINF,
00060 DARK_SHADOW,
00061 GRAY_SHADOW
00062 } ArithKinds;
00063
00064
00065 typedef enum {
00066 NOT_USED = 0,
00067 TERMS_ONLY,
00068 DIFF_ONLY,
00069 LINEAR,
00070 NONLINEAR
00071 } ArithLang;
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 class TheoryArith :public Theory {
00085 Type d_realType;
00086 Type d_intType;
00087 CDList<Theorem> d_diseq;
00088 CDO<size_t> d_diseqIdx;
00089 ArithProofRules* d_rules;
00090 CDO<bool> d_inModelCreation;
00091 bool d_realUsed;
00092 bool d_intUsed;
00093 bool d_intConstUsed;
00094 ArithLang d_langUsed;
00095 std::string d_convertToDiff;
00096 Expr d_zeroVar;
00097
00098
00099 class FreeConst {
00100 private:
00101 Rational d_r;
00102 bool d_strict;
00103 public:
00104 FreeConst() { }
00105 FreeConst(const Rational& r, bool strict): d_r(r), d_strict(strict) { }
00106 const Rational& getConst() const { return d_r; }
00107 bool strict() const { return d_strict; }
00108 };
00109
00110 friend std::ostream& operator<<(std::ostream& os, const FreeConst& fc);
00111
00112 class Ineq {
00113 private:
00114 Theorem d_ineq;
00115 bool d_rhs;
00116 const FreeConst* d_const;
00117
00118 Ineq() { }
00119 public:
00120
00121 Ineq(const Theorem& ineq, bool varOnRHS, const FreeConst& c):
00122 d_ineq(ineq), d_rhs(varOnRHS), d_const(&c) { }
00123
00124 const Theorem& ineq() const { return d_ineq; }
00125
00126 const FreeConst& getConst() const { return *d_const; }
00127
00128 bool varOnRHS() const { return d_rhs; }
00129
00130 bool varOnLHS() const { return !d_rhs; }
00131
00132 operator Theorem() const { return d_ineq; }
00133 };
00134
00135 friend std::ostream& operator<<(std::ostream& os, const Ineq& ineq);
00136
00137 ExprMap<CDList<Ineq> *> d_inequalitiesRightDB;
00138
00139 ExprMap<CDList<Ineq> *> d_inequalitiesLeftDB;
00140
00141
00142
00143
00144
00145
00146
00147
00148 CDMap<Expr, FreeConst> d_freeConstDB;
00149
00150 CDList<Theorem> d_buffer;
00151 CDO<size_t> d_bufferIdx;
00152 const int* d_bufferThres;
00153
00154
00155
00156 CDMap<Expr, int> d_countRight;
00157
00158
00159 CDMap<Expr, int> d_countLeft;
00160
00161 CDMap<Expr, bool> d_sharedTerms;
00162
00163 CDMap<Expr, bool> d_sharedVars;
00164
00165
00166 class VarOrderGraph {
00167 ExprMap<std::vector<Expr> > d_edges;
00168 ExprMap<bool> d_cache;
00169 bool dfs(const Expr& e1, const Expr& e2);
00170 public:
00171 void addEdge(const Expr& e1, const Expr& e2);
00172
00173 bool lessThan(const Expr& e1, const Expr& e2);
00174
00175
00176 void selectLargest(const std::vector<Expr>& v1, std::vector<Expr>& v2);
00177
00178
00179 void selectSmallest( std::vector<Expr>& v1, std::vector<Expr>& v2);
00180
00181 };
00182
00183 VarOrderGraph d_graph;
00184
00185
00186
00187
00188 Theorem isIntegerThm(const Expr& e);
00189
00190
00191 Theorem isIntegerDerive(const Expr& isIntE, const Theorem& thm);
00192
00193 bool isInteger(const Expr& e) { return !(isIntegerThm(e).isNull()); }
00194
00195 const Rational& freeConstIneq(const Expr& ineq, bool varOnRHS);
00196
00197
00198
00199
00200
00201
00202 const FreeConst& updateSubsumptionDB(const Expr& ineq, bool varOnRHS,
00203 bool& subsumed);
00204
00205 bool kidsCanonical(const Expr& e);
00206
00207 Theorem canon(const Expr& e);
00208
00209 Theorem canonRec(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
00306 bool isSyntacticRational(const Expr& e, Rational& r);
00307
00308 void printRational(ExprStream& os, const Expr& parent, const Expr& e,
00309 const Rational& r, bool checkLhs = true);
00310
00311 bool isSyntacticUMinusVar(const Expr& e, Expr& var);
00312
00313 void printPlus(ExprStream& os, const Expr& parent, const Expr& e);
00314
00315 void printMinus(ExprStream& os, const Expr& parent, const Expr& e);
00316
00317 void printLhs(ExprStream& os, const Expr& e);
00318
00319 bool isAtomicArithTerm(const Expr& e);
00320
00321 public:
00322 TheoryArith(VCL* vcl, TheoryCore* core);
00323 ~TheoryArith();
00324
00325
00326 bool realUsed() { return d_realUsed; }
00327
00328 bool intUsed() { return d_intUsed || (d_intConstUsed && !d_realUsed); }
00329
00330 ArithLang getLangUsed() { return d_langUsed; }
00331
00332 bool theoryUsed()
00333 { return d_realUsed || d_intUsed || d_intConstUsed || (d_langUsed != NOT_USED); }
00334
00335 Expr rewriteToDiff(const Expr& e);
00336
00337 bool isAtomicArithFormula(const Expr& e);
00338
00339
00340
00341 ArithProofRules* createProofRules();
00342
00343
00344 void addSharedTerm(const Expr& e);
00345 void assertFact(const Theorem& e);
00346 void refineCounterExample();
00347 void computeModelBasic(const std::vector<Expr>& v);
00348 void computeModel(const Expr& e, std::vector<Expr>& vars);
00349 void checkSat(bool fullEffort);
00350 Theorem rewrite(const Expr& e);
00351 void setup(const Expr& e);
00352 void update(const Theorem& e, const Expr& d);
00353 Theorem solve(const Theorem& e);
00354 void checkType(const Expr& e);
00355 void computeType(const Expr& e);
00356 Type computeBaseType(const Type& t);
00357 void computeModelTerm(const Expr& e, std::vector<Expr>& v);
00358 Expr computeTypePred(const Type& t, const Expr& e);
00359 Expr computeTCC(const Expr& e);
00360 ExprStream& print(ExprStream& os, const Expr& e);
00361 virtual Expr parseExprOp(const Expr& e);
00362
00363
00364 Type realType() { return d_realType; }
00365 Type intType() { return d_intType;}
00366 Type subrangeType(const Expr& l, const Expr& r)
00367 { return Type(Expr(SUBRANGE, l, r)); }
00368 Expr rat(Rational r) { return getEM()->newRatExpr(r); }
00369
00370
00371 Expr darkShadow(const Expr& lhs, const Expr& rhs) {
00372 return Expr(DARK_SHADOW, lhs, rhs);
00373 }
00374
00375
00376
00377 Expr grayShadow(const Expr& v, const Expr& e,
00378 const Rational& c1, const Rational& c2) {
00379 return Expr(GRAY_SHADOW, v, e, rat(c1), rat(c2));
00380 }
00381 };
00382
00383
00384 inline bool isReal(Type t) { return t.getExpr().getKind() == REAL; }
00385 inline bool isInt(Type t) { return t.getExpr().getKind() == INT; }
00386
00387
00388 inline bool isRational(const Expr& e) { return e.isRational(); }
00389 inline bool isIntegerConst(const Expr& e)
00390 { return e.isRational() && e.getRational().isInteger(); }
00391 inline bool isUMinus(const Expr& e) { return e.getKind() == UMINUS; }
00392 inline bool isPlus(const Expr& e) { return e.getKind() == PLUS; }
00393 inline bool isMinus(const Expr& e) { return e.getKind() == MINUS; }
00394 inline bool isMult(const Expr& e) { return e.getKind() == MULT; }
00395 inline bool isDivide(const Expr& e) { return e.getKind() == DIVIDE; }
00396 inline bool isLT(const Expr& e) { return e.getKind() == LT; }
00397 inline bool isLE(const Expr& e) { return e.getKind() == LE; }
00398 inline bool isGT(const Expr& e) { return e.getKind() == GT; }
00399 inline bool isGE(const Expr& e) { return e.getKind() == GE; }
00400 inline bool isDarkShadow(const Expr& e) { return e.getKind() == DARK_SHADOW;}
00401 inline bool isGrayShadow(const Expr& e) { return e.getKind() == GRAY_SHADOW;}
00402 inline bool isIneq(const Expr& e)
00403 { return isLT(e) || isLE(e) || isGT(e) || isGE(e); }
00404 inline bool isIntPred(const Expr& e) { return e.getKind() == IS_INTEGER; }
00405
00406
00407 inline Expr uminusExpr(const Expr& child)
00408 { return Expr(UMINUS, child); }
00409 inline Expr plusExpr(const Expr& left, const Expr& right)
00410 { return Expr(PLUS, left, right); }
00411 inline Expr plusExpr(const std::vector<Expr>& children) {
00412 DebugAssert(children.size() > 0, "plusExpr()");
00413 return Expr(PLUS, children);
00414 }
00415 inline Expr minusExpr(const Expr& left, const Expr& right)
00416 { return Expr(MINUS, left, right); }
00417 inline Expr multExpr(const Expr& left, const Expr& right)
00418 { return Expr(MULT, left, right); }
00419
00420
00421 inline Expr multExpr(const std::vector<Expr>& children) {
00422 DebugAssert(children.size() > 0, "multExpr()");
00423 return Expr(MULT, children);
00424 }
00425
00426 inline Expr powExpr(const Expr& pow, const Expr & base)
00427 { return Expr(POW, pow, base);}
00428
00429 inline Expr divideExpr(const Expr& left, const Expr& right)
00430 { return Expr(DIVIDE, left, right); }
00431 inline Expr ltExpr(const Expr& left, const Expr& right)
00432 { return Expr(LT, left, right); }
00433 inline Expr leExpr(const Expr& left, const Expr& right)
00434 { return Expr(LE, left, right); }
00435 inline Expr gtExpr(const Expr& left, const Expr& right)
00436 { return Expr(GT, left, right); }
00437 inline Expr geExpr(const Expr& left, const Expr& right)
00438 { return Expr(GE, left, right); }
00439
00440 inline Expr operator-(const Expr& child)
00441 { return uminusExpr(child); }
00442 inline Expr operator+(const Expr& left, const Expr& right)
00443 { return plusExpr(left, right); }
00444 inline Expr operator-(const Expr& left, const Expr& right)
00445 { return minusExpr(left, right); }
00446 inline Expr operator*(const Expr& left, const Expr& right)
00447 { return multExpr(left, right); }
00448 inline Expr operator/(const Expr& left, const Expr& right)
00449 { return divideExpr(left, right); }
00450
00451 }
00452
00453 #endif