00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _cvc3__include__theory_arith_old_h_
00022 #define _cvc3__include__theory_arith_old_h_
00023
00024 #include "theory_arith.h"
00025 #include <set>
00026 #include <list>
00027
00028 namespace CVC3 {
00029
00030 class TheoryArithOld :public TheoryArith {
00031 CDList<Theorem> d_diseq;
00032 CDO<size_t> d_diseqIdx;
00033 CDMap<Expr, bool> diseqSplitAlready;
00034 ArithProofRules* d_rules;
00035 CDO<bool> d_inModelCreation;
00036
00037
00038 class FreeConst {
00039 private:
00040 Rational d_r;
00041 bool d_strict;
00042 public:
00043 FreeConst() { }
00044 FreeConst(const Rational& r, bool strict): d_r(r), d_strict(strict) { }
00045 const Rational& getConst() const { return d_r; }
00046 bool strict() const { return d_strict; }
00047 };
00048
00049 friend std::ostream& operator<<(std::ostream& os, const FreeConst& fc);
00050
00051
00052 class Ineq {
00053 private:
00054 Theorem d_ineq;
00055 bool d_rhs;
00056 const FreeConst* d_const;
00057
00058 Ineq() { }
00059 public:
00060
00061 Ineq(const Theorem& ineq, bool varOnRHS, const FreeConst& c):
00062 d_ineq(ineq), d_rhs(varOnRHS), d_const(&c) { }
00063
00064 const Theorem ineq() const { return d_ineq; }
00065
00066 const FreeConst& getConst() const { return *d_const; }
00067
00068 bool varOnRHS() const { return d_rhs; }
00069
00070 bool varOnLHS() const { return !d_rhs; }
00071
00072 operator Theorem() const { return d_ineq; }
00073 };
00074
00075 friend std::ostream& operator<<(std::ostream& os, const Ineq& ineq);
00076
00077
00078 ExprMap<CDList<Ineq> *> d_inequalitiesRightDB;
00079
00080
00081 ExprMap<CDList<Ineq> *> d_inequalitiesLeftDB;
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 CDMap<Expr, FreeConst> d_freeConstDB;
00092
00093
00094
00095
00096
00097
00098
00099 CDList<Theorem> d_buffer_0;
00100 CDList<Theorem> d_buffer_1;
00101 CDList<Theorem> d_buffer_2;
00102 CDList<Theorem> d_buffer_3;
00103
00104 CDO<size_t> d_bufferIdx_0;
00105 CDO<size_t> d_bufferIdx_1;
00106 CDO<size_t> d_bufferIdx_2;
00107 CDO<size_t> d_bufferIdx_3;
00108
00109 CDO<size_t> diff_logic_size;
00110
00111 const int* d_bufferThres;
00112
00113 const bool* d_splitSign;
00114
00115 const int* d_grayShadowThres;
00116
00117
00118
00119
00120
00121 CDMap<Expr, int> d_countRight;
00122
00123
00124
00125 CDMap<Expr, int> d_countLeft;
00126
00127
00128 CDMap<Expr, bool> d_sharedTerms;
00129 CDList<Expr> d_sharedTermsList;
00130
00131
00132 CDMap<Expr, bool> d_sharedVars;
00133
00134
00135
00136 class VarOrderGraph {
00137 ExprMap<std::vector<Expr> > d_edges;
00138 ExprMap<bool> d_cache;
00139 bool dfs(const Expr& e1, const Expr& e2);
00140 void dfs(const Expr& e1, std::vector<Expr>& output_list);
00141 public:
00142 void addEdge(const Expr& e1, const Expr& e2);
00143
00144 bool lessThan(const Expr& e1, const Expr& e2);
00145
00146
00147 void selectLargest(const std::vector<Expr>& v1, std::vector<Expr>& v2);
00148
00149
00150 void selectSmallest( std::vector<Expr>& v1, std::vector<Expr>& v2);
00151
00152 void getVerticesTopological(std::vector<Expr>& output_list);
00153 };
00154
00155 VarOrderGraph d_graph;
00156
00157
00158
00159
00160
00161 Theorem isIntegerThm(const Expr& e);
00162
00163
00164
00165 Theorem isIntegerDerive(const Expr& isIntE, const Theorem& thm);
00166
00167
00168 const Rational& freeConstIneq(const Expr& ineq, bool varOnRHS);
00169
00170
00171
00172
00173
00174
00175
00176 const FreeConst& updateSubsumptionDB(const Expr& ineq, bool varOnRHS,
00177 bool& subsumed);
00178
00179 bool kidsCanonical(const Expr& e);
00180
00181
00182 Theorem canon(const Expr& e);
00183
00184
00185
00186 Theorem canonSimplify(const Expr& e);
00187
00188
00189
00190
00191 Theorem canonSimplify(const Theorem& thm) {
00192 return transitivityRule(thm, canonSimplify(thm.getRHS()));
00193 }
00194
00195
00196 Theorem canonPred(const Theorem& thm);
00197
00198
00199
00200 Theorem canonPredEquiv(const Theorem& thm);
00201
00202
00203 Theorem doSolve(const Theorem& e);
00204
00205
00206 Theorem canonConjunctionEquiv(const Theorem& thm);
00207
00208
00209
00210 bool pickIntEqMonomial(const Expr& right, Expr& isolated, bool& nonlin);
00211
00212
00213 Theorem processRealEq(const Theorem& eqn);
00214
00215
00216 Theorem processIntEq(const Theorem& eqn);
00217
00218
00219 Theorem processSimpleIntEq(const Theorem& eqn);
00220
00221
00222 void processBuffer();
00223
00224
00225 Theorem isolateVariable(const Theorem& inputThm, bool& e1);
00226
00227
00228 void updateStats(const Rational& c, const Expr& var);
00229
00230
00231 void updateStats(const Expr& monomial);
00232
00233
00234 bool addToBuffer(const Theorem& thm, bool priority = false);
00235
00236
00237
00238 Expr computeNormalFactor(const Expr& rhs, bool normalizeConstants);
00239
00240
00241 Theorem normalize(const Expr& e);
00242
00243
00244
00245
00246
00247 Theorem normalize(const Theorem& thm);
00248
00249 Expr pickMonomial(const Expr& right);
00250
00251 void getFactors(const Expr& e, std::set<Expr>& factors);
00252
00253 public:
00254
00255 void separateMonomial(const Expr& e, Expr& c, Expr& var);
00256
00257
00258 bool isInteger(const Expr& e)
00259 { return
00260 isInt(e.getType()) ? true :
00261 (isReal(e.getType()) ? false : !(isIntegerThm(e).isNull())); }
00262
00263 private:
00264
00265 bool lessThanVar(const Expr& isolatedVar, const Expr& var2);
00266
00267
00268 bool isStale(const Expr& e);
00269
00270
00271 bool isStale(const Ineq& ineq);
00272
00273 void projectInequalities(const Theorem& theInequality,bool isolatedVarOnRHS);
00274
00275 void assignVariables(std::vector<Expr>&v);
00276
00277 void findRationalBound(const Expr& varSide, const Expr& ratSide,
00278 const Expr& var,
00279 Rational &r);
00280
00281 bool findBounds(const Expr& e, Rational& lub, Rational& glb);
00282
00283 Theorem normalizeProjectIneqs(const Theorem& ineqThm1,
00284 const Theorem& ineqThm2);
00285
00286
00287 Theorem solvedForm(const std::vector<Theorem>& solvedEqs);
00288
00289
00290
00291
00292 Theorem substAndCanonize(const Expr& t, ExprMap<Theorem>& subst);
00293
00294
00295
00296
00297
00298 Theorem substAndCanonize(const Theorem& eq, ExprMap<Theorem>& subst);
00299
00300
00301 void collectVars(const Expr& e, std::vector<Expr>& vars,
00302 std::set<Expr>& cache);
00303
00304
00305
00306
00307 void processFiniteInterval(const Theorem& alphaLEax,
00308 const Theorem& bxLEbeta);
00309
00310
00311 void processFiniteIntervals(const Expr& x);
00312
00313
00314 void setupRec(const Expr& e);
00315
00316 public:
00317 TheoryArithOld(TheoryCore* core);
00318 ~TheoryArithOld();
00319
00320
00321
00322 ArithProofRules* createProofRulesOld();
00323
00324
00325 void addSharedTerm(const Expr& e);
00326 void assertFact(const Theorem& e);
00327 void refineCounterExample();
00328 void computeModelBasic(const std::vector<Expr>& v);
00329 void computeModel(const Expr& e, std::vector<Expr>& vars);
00330 void checkSat(bool fullEffort);
00331 Theorem rewrite(const Expr& e);
00332 void setup(const Expr& e);
00333 void update(const Theorem& e, const Expr& d);
00334 Theorem solve(const Theorem& e);
00335 void checkAssertEqInvariant(const Theorem& e);
00336 void checkType(const Expr& e);
00337 Cardinality finiteTypeInfo(Expr& e, Unsigned& n,
00338 bool enumerate, bool computeSize);
00339 void computeType(const Expr& e);
00340 Type computeBaseType(const Type& t);
00341 void computeModelTerm(const Expr& e, std::vector<Expr>& v);
00342 Expr computeTypePred(const Type& t, const Expr& e);
00343 Expr computeTCC(const Expr& e);
00344 ExprStream& print(ExprStream& os, const Expr& e);
00345 Expr parseExprOp(const Expr& e);
00346
00347 private:
00348
00349
00350 ExprMap<Rational> maxCoefficientLeft;
00351 ExprMap<Rational> maxCoefficientRight;
00352
00353
00354 ExprMap<Rational> fixedMaxCoefficient;
00355
00356
00357
00358
00359
00360
00361 Rational currentMaxCoefficient(Expr var);
00362
00363
00364
00365
00366
00367
00368
00369
00370 void fixCurrentMaxCoefficient(Expr variable, Rational max);
00371
00372
00373
00374
00375 void selectSmallestByCoefficient(const std::vector<Expr>& input, std::vector<Expr>& output);
00376
00377
00378
00379
00380
00381 Theorem rafineInequalityToInteger(const Theorem& thm);
00382
00383
00384
00385
00386
00387 Theorem checkIntegerEquality(const Theorem& thm);
00388
00389
00390 CDMap<Expr, Theorem> bufferedInequalities;
00391
00392
00393 CDMap<Expr, Rational> termLowerBound;
00394 CDMap<Expr, Theorem> termLowerBoundThm;
00395
00396 CDMap<Expr, Rational> termUpperBound;
00397 CDMap<Expr, Theorem> termUpperBoundThm;
00398
00399
00400
00401
00402
00403
00404
00405
00406 CDMap<Expr, Expr> alreadyProjected;
00407
00408
00409
00410
00411
00412
00413 CDMap<Expr, bool> dontBuffer;
00414
00415
00416
00417
00418 CDO<bool> diffLogicOnly;
00419
00420
00421
00422
00423 Theorem inequalityToFind(const Theorem& inequalityThm, bool normalizeRHS);
00424
00425
00426 struct GraphEdge {
00427 Expr x;
00428 Expr y;
00429 Rational c;
00430 };
00431
00432
00433
00434
00435
00436
00437
00438
00439 int extractTermsFromInequality(const Expr& inequality,
00440 Rational& c1, Expr& t1,
00441 Rational& c2, Expr& t2);
00442
00443 void registerAtom(const Expr& e);
00444
00445 typedef ExprMap< std::set< std::pair<Rational, Expr> > > AtomsMap;
00446
00447
00448 AtomsMap formulaAtomLowerBound;
00449
00450
00451 AtomsMap formulaAtomUpperBound;
00452
00453
00454 ExprMap<bool> formulaAtoms;
00455
00456 class DifferenceLogicGraph {
00457
00458 public:
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 class EpsRational {
00474
00475 protected:
00476
00477
00478 typedef enum { FINITE, PLUS_INFINITY, MINUS_INFINITY } RationalType;
00479
00480
00481 RationalType type;
00482
00483
00484 Rational q;
00485
00486
00487 Rational k;
00488
00489
00490
00491
00492 EpsRational(RationalType type) : type(type) {}
00493
00494 public:
00495
00496
00497
00498
00499 inline bool isFinite() const { return type == FINITE; }
00500
00501
00502
00503
00504
00505
00506 inline bool isRational() const { return k == 0; }
00507
00508
00509
00510
00511
00512
00513 inline bool isInteger() const { return k == 0 && q.isInteger(); }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 inline Rational getFloor() const {
00527 if (q.isInteger()) {
00528 if (k >= 0) return q;
00529 else return q - 1;
00530 } else
00531
00532 return floor(q);
00533 }
00534
00535
00536
00537
00538
00539
00540
00541 inline Rational getRational() const { return q; }
00542
00543
00544
00545
00546
00547
00548 inline Rational getEpsilon() const { return k; }
00549
00550
00551 static const EpsRational PlusInfinity;
00552
00553 static const EpsRational MinusInfinity;
00554
00555 static const EpsRational Zero;
00556
00557
00558
00559 EpsRational() : type(FINITE), q(0), k(0) {}
00560
00561
00562 EpsRational(const EpsRational& r) : type(r.type), q(r.q), k(r.k) {}
00563
00564
00565
00566
00567
00568
00569 EpsRational(const Rational& q) : type(FINITE), q(q), k(0) {}
00570
00571
00572
00573
00574
00575
00576
00577
00578 EpsRational(const Rational& q, const Rational& k) : type(FINITE), q(q), k(k) {}
00579
00580
00581
00582
00583
00584
00585
00586 inline EpsRational operator + (const EpsRational& r) const {
00587 DebugAssert(type == FINITE, "EpsRational::operator +, adding to infinite number");
00588 DebugAssert(r.type == FINITE, "EpsRational::operator +, adding an infinite number");
00589 return EpsRational(q + r.q, k + r.k);
00590 }
00591
00592
00593
00594
00595
00596
00597
00598 inline EpsRational& operator += (const EpsRational& r) {
00599 DebugAssert(type == FINITE, "EpsRational::operator +, adding to infinite number");
00600 q = q + r.q;
00601 k = k + r.k;
00602 return *this;
00603 }
00604
00605
00606
00607
00608
00609
00610
00611 inline EpsRational operator - (const EpsRational& r) const {
00612 DebugAssert(type == FINITE, "EpsRational::operator -, subtracting from infinite number");
00613 DebugAssert(r.type == FINITE, "EpsRational::operator -, subtracting an infinite number");
00614 return EpsRational(q - r.q, k - r.k);
00615 }
00616
00617
00618
00619
00620 inline EpsRational operator - () {
00621 DebugAssert(type == FINITE, "EpsRational::operator -, subtracting from infinite number");
00622 q = -q;
00623 k = -k;
00624 return *this;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634 inline EpsRational operator * (const Rational& a) const {
00635 DebugAssert(type == FINITE, "EpsRational::operator *, multiplying an infinite number");
00636 return EpsRational(a * q, a * k);
00637 }
00638
00639
00640
00641
00642
00643
00644
00645 inline EpsRational operator / (const Rational& a) const {
00646 DebugAssert(type == FINITE, "EpsRational::operator *, dividing an infinite number");
00647 return EpsRational(q / a, k / a);
00648 }
00649
00650
00651
00652
00653 inline bool operator == (const EpsRational& r) const { return (q == r.q && k == r.k); }
00654
00655
00656
00657
00658 inline bool operator <= (const EpsRational& r) const {
00659 switch (r.type) {
00660 case FINITE:
00661 if (type == FINITE)
00662
00663 return (q < r.q || (q == r.q && k <= r.k));
00664 else
00665
00666 return type == MINUS_INFINITY;
00667 case PLUS_INFINITY:
00668
00669 return true;
00670 case MINUS_INFINITY:
00671
00672 return (type == MINUS_INFINITY);
00673 default:
00674
00675 FatalAssert(false, "EpsRational::operator <=, what kind of number is this????");
00676 }
00677 return false;
00678 }
00679
00680
00681
00682
00683 inline bool operator < (const EpsRational& r) const { return !(r <= *this); }
00684
00685
00686
00687
00688 inline bool operator > (const EpsRational& r) const { return !(*this <= r); }
00689
00690
00691
00692
00693
00694
00695 std::string toString() const {
00696 switch (type) {
00697 case FINITE:
00698 return "(" + q.toString() + ", " + k.toString() + ")";
00699 case PLUS_INFINITY:
00700 return "+inf";
00701 case MINUS_INFINITY:
00702 return "-inf";
00703 default:
00704 FatalAssert(false, "EpsRational::toString, what kind of number is this????");
00705 }
00706 return "hm, what am I?";
00707 }
00708 };
00709
00710 struct EdgeInfo {
00711
00712 EpsRational length;
00713
00714 int path_length_in_edges;
00715
00716 Expr in_path_vertex;
00717
00718 Theorem explanation;
00719
00720
00721 bool isDefined() const { return path_length_in_edges != 0; }
00722
00723 EdgeInfo(): path_length_in_edges(0) {}
00724 };
00725
00726
00727
00728
00729
00730 void getEdgeTheorems(const Expr& x, const Expr& y, const EdgeInfo& edgeInfo, std::vector<Theorem>& outputTheorems);
00731
00732
00733
00734
00735 EpsRational getEdgeWeight(const Expr& x, const Expr& y);
00736
00737
00738
00739
00740 bool hasIncoming(const Expr& x);
00741
00742
00743
00744
00745 bool hasOutgoing(const Expr& x);
00746
00747 protected:
00748
00749
00750 const int* d_pathLenghtThres;
00751
00752
00753 TheoryArithOld* arith;
00754
00755
00756 TheoryCore* core;
00757
00758
00759 ArithProofRules* rules;
00760
00761
00762 CDO<Theorem> unsat_theorem;
00763
00764
00765 CDO<Rational> biggestEpsilon;
00766
00767
00768 CDO<Rational> smallestPathDifference;
00769
00770
00771 typedef CDMap<Expr, EdgeInfo> Graph;
00772
00773
00774 Graph leGraph;
00775
00776 typedef ExprMap<CDList<Expr>*> EdgesList;
00777
00778
00779 EdgesList incomingEdges;
00780
00781 EdgesList outgoingEdges;
00782
00783
00784
00785
00786
00787
00788
00789
00790 Graph::ElementReference getEdge(const Expr& x, const Expr& y);
00791
00792
00793
00794
00795 bool tryUpdate(const Expr& x, const Expr& y, const Expr& z);
00796
00797 public:
00798
00799 void writeGraph(std::ostream& out);
00800
00801
00802
00803
00804 void getVariables(std::vector<Expr>& variables);
00805
00806 void setRules(ArithProofRules* rules) {
00807 this->rules = rules;
00808 }
00809
00810 void setArith(TheoryArithOld* arith) {
00811 this->arith = arith;
00812 }
00813
00814
00815
00816
00817 DifferenceLogicGraph(TheoryArithOld* arith, TheoryCore* core, ArithProofRules* rules, Context* context);
00818
00819
00820
00821
00822 ~DifferenceLogicGraph();
00823
00824
00825
00826
00827
00828
00829
00830
00831 Theorem getUnsatTheorem();
00832
00833
00834
00835
00836 bool isUnsat();
00837
00838 void computeModel();
00839
00840 Rational getValuation(const Expr& x);
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 void addEdge(const Expr& x, const Expr& y, const Rational& c, const Theorem& edge_thm);
00852
00853
00854
00855
00856 bool existsEdge(const Expr& x, const Expr& y);
00857
00858
00859
00860
00861 bool inCycle(const Expr& x);
00862
00863
00864
00865
00866 void expandSharedTerm(const Expr& x);
00867
00868 protected:
00869
00870
00871 CDMap<Expr, bool> varInCycle;
00872
00873 Expr sourceVertex;
00874
00875
00876
00877
00878
00879
00880
00881 void analyseConflict(const Expr& x, int kind);
00882 };
00883
00884
00885 DifferenceLogicGraph diffLogicGraph;
00886
00887 Expr zero;
00888
00889
00890 CDO<unsigned> shared_index_1;
00891
00892 CDO<unsigned> shared_index_2;
00893
00894 std::vector<Theorem> multiplicativeSignSplits;
00895
00896 int termDegree(const Expr& e);
00897
00898 bool canPickEqMonomial(const Expr& right);
00899
00900 private:
00901
00902
00903 CDMap<Expr, DifferenceLogicGraph::EpsRational> termUpperBounded;
00904 CDMap<Expr, DifferenceLogicGraph::EpsRational> termLowerBounded;
00905
00906
00907 CDMap<Expr, bool> termConstrainedBelow;
00908 CDMap<Expr, bool> termConstrainedAbove;
00909
00910 enum BoundsQueryType {
00911
00912 QueryWithCacheLeaves,
00913
00914 QueryWithCacheLeavesAndConstrainedComputation,
00915
00916 QueryWithCacheAll
00917 };
00918
00919
00920
00921
00922 bool isBounded(const Expr& t, BoundsQueryType queryType = QueryWithCacheLeaves);
00923 bool hasLowerBound(const Expr& t, BoundsQueryType queryType = QueryWithCacheLeaves) { return getLowerBound(t, queryType).isFinite(); }
00924 bool hasUpperBound(const Expr& t, BoundsQueryType queryType = QueryWithCacheLeaves) { return getUpperBound(t, queryType).isFinite(); }
00925
00926 bool isConstrained(const Expr& t, bool intOnly = true, BoundsQueryType queryType = QueryWithCacheLeaves);
00927 bool isConstrainedAbove(const Expr& t, BoundsQueryType queryType = QueryWithCacheLeaves);
00928 bool isConstrainedBelow(const Expr& t, BoundsQueryType queryType = QueryWithCacheLeaves);
00929
00930
00931
00932
00933 DifferenceLogicGraph::EpsRational getUpperBound(const Expr& t, BoundsQueryType queryType = QueryWithCacheLeaves);
00934
00935
00936
00937
00938 DifferenceLogicGraph::EpsRational getLowerBound(const Expr& t, BoundsQueryType queryType = QueryWithCacheLeaves);
00939
00940
00941
00942
00943 int computeTermBounds();
00944
00945 public:
00946
00947 void tryPropagate(const Expr& x, const Expr& y, const DifferenceLogicGraph::EdgeInfo& x_y_edge, int kind);
00948
00949 void addMultiplicativeSignSplit(const Theorem& case_split_thm);
00950
00951 bool addPairToArithOrder(const Expr& smaller, const Expr& bigger);
00952
00953 bool nonlinearSignSplit() const { return *d_splitSign; }
00954
00955
00956
00957
00958
00959 bool isNonlinearEq(const Expr& e);
00960
00961
00962
00963
00964 bool isNonlinearSumTerm(const Expr& term);
00965
00966
00967
00968
00969 bool isPowersEquality(const Expr& nonlinearEq, Expr& power1, Expr& power2);
00970
00971
00972
00973
00974 bool isPowerEquality(const Expr& nonlinearEq, Rational& constant, Expr& power1);
00975
00976 };
00977
00978 }
00979
00980 #endif