Constraints.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "klee/Constraints.h"
00011
00012 #include "klee/util/ExprPPrinter.h"
00013 #include "klee/util/ExprVisitor.h"
00014
00015 #include <iostream>
00016 #include <map>
00017
00018 using namespace klee;
00019
00020 class ExprReplaceVisitor : public ExprVisitor {
00021 private:
00022 ref<Expr> src, dst;
00023
00024 public:
00025 ExprReplaceVisitor(ref<Expr> _src, ref<Expr> _dst) : src(_src), dst(_dst) {}
00026
00027 Action visitExpr(const Expr &e) {
00028 if (e == *src.get()) {
00029 return Action::changeTo(dst);
00030 } else {
00031 return Action::doChildren();
00032 }
00033 }
00034
00035 Action visitExprPost(const Expr &e) {
00036 if (e == *src.get()) {
00037 return Action::changeTo(dst);
00038 } else {
00039 return Action::doChildren();
00040 }
00041 }
00042 };
00043
00044 class ExprReplaceVisitor2 : public ExprVisitor {
00045 private:
00046 const std::map< ref<Expr>, ref<Expr> > &replacements;
00047
00048 public:
00049 ExprReplaceVisitor2(const std::map< ref<Expr>, ref<Expr> > &_replacements)
00050 : ExprVisitor(true),
00051 replacements(_replacements) {}
00052
00053 Action visitExprPost(const Expr &e) {
00054 std::map< ref<Expr>, ref<Expr> >::const_iterator it =
00055 replacements.find(ref<Expr>((Expr*) &e));
00056 if (it!=replacements.end()) {
00057 return Action::changeTo(it->second);
00058 } else {
00059 return Action::doChildren();
00060 }
00061 }
00062 };
00063
00064 bool ConstraintManager::rewriteConstraints(ExprVisitor &visitor) {
00065 ConstraintManager::constraints_ty old;
00066 bool changed = false;
00067
00068 constraints.swap(old);
00069 for (ConstraintManager::constraints_ty::iterator
00070 it = old.begin(), ie = old.end(); it != ie; ++it) {
00071 ref<Expr> &ce = *it;
00072 ref<Expr> e = visitor.visit(ce);
00073
00074 if (e!=ce) {
00075 addConstraintInternal(e);
00076 changed = true;
00077 } else {
00078 constraints.push_back(ce);
00079 }
00080 }
00081
00082 return changed;
00083 }
00084
00085 void ConstraintManager::simplifyForValidConstraint(ref<Expr> e) {
00086
00087 }
00088
00089 ref<Expr> ConstraintManager::simplifyExpr(ref<Expr> e) const {
00090 if (isa<ConstantExpr>(e))
00091 return e;
00092
00093 std::map< ref<Expr>, ref<Expr> > equalities;
00094
00095 for (ConstraintManager::constraints_ty::const_iterator
00096 it = constraints.begin(), ie = constraints.end(); it != ie; ++it) {
00097 if (const EqExpr *ee = dyn_cast<EqExpr>(*it)) {
00098 if (isa<ConstantExpr>(ee->left)) {
00099 equalities.insert(std::make_pair(ee->right,
00100 ee->left));
00101 } else {
00102 equalities.insert(std::make_pair(*it,
00103 ConstantExpr::alloc(1, Expr::Bool)));
00104 }
00105 } else {
00106 equalities.insert(std::make_pair(*it,
00107 ConstantExpr::alloc(1, Expr::Bool)));
00108 }
00109 }
00110
00111 return ExprReplaceVisitor2(equalities).visit(e);
00112 }
00113
00114 void ConstraintManager::addConstraintInternal(ref<Expr> e) {
00115
00116
00117
00118
00119
00120
00121
00122
00123 switch (e->getKind()) {
00124 case Expr::Constant:
00125 assert(cast<ConstantExpr>(e)->getConstantValue() &&
00126 "attempt to add invalid (false) constraint");
00127 break;
00128
00129
00130 case Expr::And: {
00131 BinaryExpr *be = cast<BinaryExpr>(e);
00132 addConstraintInternal(be->left);
00133 addConstraintInternal(be->right);
00134 break;
00135 }
00136
00137 case Expr::Eq: {
00138 BinaryExpr *be = cast<BinaryExpr>(e);
00139 if (isa<ConstantExpr>(be->left)) {
00140 ExprReplaceVisitor visitor(be->right, be->left);
00141 rewriteConstraints(visitor);
00142 }
00143 constraints.push_back(e);
00144 break;
00145 }
00146
00147 default:
00148 constraints.push_back(e);
00149 break;
00150 }
00151 }
00152
00153 void ConstraintManager::addConstraint(ref<Expr> e) {
00154 e = simplifyExpr(e);
00155 addConstraintInternal(e);
00156 }