00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "expr_transform.h"
00023 #include "theory_core.h"
00024 #include "command_line_flags.h"
00025 #include "core_proof_rules.h"
00026
00027
00028 using namespace std;
00029 using namespace CVC3;
00030
00031
00032 ExprTransform::ExprTransform(TheoryCore* core) : d_core(core)
00033 {
00034 d_commonRules = d_core->getCommonRules();
00035 d_rules = d_core->getCoreRules();
00036 }
00037
00038
00039 Theorem ExprTransform::smartSimplify(const Expr& e, ExprMap<bool>& cache)
00040 {
00041 ExprMap<bool>::iterator it;
00042 vector<Expr> operatorStack;
00043 vector<int> childStack;
00044 Expr e2;
00045
00046 operatorStack.push_back(e);
00047 childStack.push_back(0);
00048
00049 while (!operatorStack.empty()) {
00050 DebugAssert(operatorStack.size() == childStack.size(), "Invariant violated");
00051 if (childStack.back() < operatorStack.back().arity()) {
00052 e2 = operatorStack.back()[childStack.back()++];
00053 it = cache.find(e2);
00054 if (it != cache.end() || e2.hasFind() ||
00055 e2.validSimpCache() || e2.arity() == 0) continue;
00056 if (operatorStack.size() >= 5000) {
00057 smartSimplify(e2, cache);
00058 cache[e2] = true;
00059 }
00060 else {
00061 operatorStack.push_back(e2);
00062 childStack.push_back(0);
00063 }
00064 }
00065 else {
00066 cache[operatorStack.back()] = true;
00067 operatorStack.pop_back();
00068 childStack.pop_back();
00069 }
00070 }
00071 DebugAssert(childStack.empty(), "Invariant violated");
00072 return d_core->simplify(e);
00073 }
00074
00075
00076 Theorem ExprTransform::preprocess(const Expr& e)
00077 {
00078 Theorem thm1;
00079 if (d_core->getFlags()["pp-pushneg"].getBool())
00080 thm1 = pushNegation(e);
00081 else
00082 thm1 = d_commonRules->reflexivityRule(e);
00083 ExprMap<bool> cache;
00084 thm1 = d_commonRules->transitivityRule(thm1, smartSimplify(thm1.getRHS(), cache));
00085 return thm1;
00086 }
00087
00088
00089 Theorem ExprTransform::preprocess(const Theorem& thm)
00090 {
00091 return d_commonRules->iffMP(thm, preprocess(thm.getExpr()));
00092 }
00093
00094
00095
00096 Theorem ExprTransform::pushNegation(const Expr& e) {
00097 if(e.isTerm()) return d_commonRules->reflexivityRule(e);
00098 Theorem res(pushNegationRec(e, false));
00099 d_pushNegCache.clear();
00100 return res;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 Theorem ExprTransform::pushNegationRec(const Expr& e, bool neg) {
00111 TRACE("pushNegation", "pushNegationRec(", e,
00112 ", neg=" + string(neg? "true":"false") + ") {");
00113 DebugAssert(!e.isTerm(), "pushNegationRec: not boolean e = "+e.toString());
00114 ExprMap<Theorem>::iterator i = d_pushNegCache.find(neg? !e : e);
00115 if(i != d_pushNegCache.end()) {
00116 TRACE("pushNegation", "pushNegationRec [cached] => ", (*i).second, "}");
00117 return (*i).second;
00118 }
00119
00120 Theorem res(d_core->reflexivityRule((neg)? !e : e));
00121 if(neg) {
00122 switch(e.getKind()) {
00123 case TRUE_EXPR: res = d_commonRules->rewriteNotTrue(!e); break;
00124 case FALSE_EXPR: res = d_commonRules->rewriteNotFalse(!e); break;
00125 case NOT:
00126 res = pushNegationRec(d_commonRules->rewriteNotNot(!e), false);
00127 break;
00128 case AND:
00129 res = pushNegationRec(d_rules->rewriteNotAnd(!e), false);
00130 break;
00131 case OR:
00132 res = pushNegationRec(d_rules->rewriteNotOr(!e), false);
00133 break;
00134 case IMPLIES: {
00135 vector<Theorem> thms;
00136 thms.push_back(d_rules->rewriteImplies(e));
00137 res = pushNegationRec
00138 (d_commonRules->substitutivityRule(NOT, thms), true);
00139 break;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 case ITE:
00149 res = pushNegationRec(d_rules->rewriteNotIte(!e), false);
00150 break;
00151
00152
00153
00154 case LETDECL: {
00155 vector<Theorem> thms;
00156 thms.push_back(d_rules->rewriteLetDecl(e));
00157 res = pushNegationRec
00158 (d_commonRules->substitutivityRule(NOT, thms), true);
00159 break;
00160 }
00161 default:
00162 res = d_commonRules->reflexivityRule(!e);
00163 }
00164 } else {
00165 switch(e.getKind()) {
00166 case NOT: res = pushNegationRec(e[0], true); break;
00167 case AND:
00168 case OR:
00169 case IFF:
00170 case ITE: {
00171 Op op = e.getOp();
00172 vector<Theorem> thms;
00173 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
00174 thms.push_back(pushNegationRec(*i, false));
00175 res = d_commonRules->substitutivityRule(op, thms);
00176 break;
00177 }
00178 case IMPLIES:
00179 res = pushNegationRec(d_rules->rewriteImplies(e), false);
00180 break;
00181 case LETDECL:
00182 res = pushNegationRec(d_rules->rewriteLetDecl(e), false);
00183 break;
00184 default:
00185 res = d_commonRules->reflexivityRule(e);
00186 }
00187 }
00188 TRACE("pushNegation", "pushNegationRec => ", res, "}");
00189 d_pushNegCache[neg? !e : e] = res;
00190 return res;
00191 }
00192
00193
00194 Theorem ExprTransform::pushNegationRec(const Theorem& thm, bool neg) {
00195 DebugAssert(thm.isRewrite(), "pushNegationRec(Theorem): bad theorem: "
00196 + thm.toString());
00197 Expr e(thm.getRHS());
00198 if(neg) {
00199 DebugAssert(e.isNot(),
00200 "pushNegationRec(Theorem, neg = true): bad Theorem: "
00201 + thm.toString());
00202 e = e[0];
00203 }
00204 return d_commonRules->transitivityRule(thm, pushNegationRec(e, neg));
00205 }
00206
00207
00208 Theorem ExprTransform::pushNegation1(const Expr& e) {
00209 TRACE("pushNegation1", "pushNegation1(", e, ") {");
00210 DebugAssert(e.isNot(), "pushNegation1("+e.toString()+")");
00211 Theorem res;
00212 switch(e[0].getKind()) {
00213 case TRUE_EXPR: res = d_commonRules->rewriteNotTrue(e); break;
00214 case FALSE_EXPR: res = d_commonRules->rewriteNotFalse(e); break;
00215 case NOT:
00216 res = d_commonRules->rewriteNotNot(e);
00217 break;
00218 case AND:
00219 res = d_rules->rewriteNotAnd(e);
00220 break;
00221 case OR:
00222 res = d_rules->rewriteNotOr(e);
00223 break;
00224 case IMPLIES: {
00225 vector<Theorem> thms;
00226 thms.push_back(d_rules->rewriteImplies(e[0]));
00227 res = d_commonRules->substitutivityRule(e.getOp(), thms);
00228 res = d_commonRules->transitivityRule(res, d_rules->rewriteNotOr(res.getRHS()));
00229 break;
00230 }
00231 case ITE:
00232 res = d_rules->rewriteNotIte(e);
00233 break;
00234
00235
00236 case LETDECL: {
00237 vector<Theorem> thms;
00238 thms.push_back(d_rules->rewriteLetDecl(e[0]));
00239 res = d_commonRules->substitutivityRule(e.getOp(), thms);
00240 res = d_commonRules->transitivityRule(res, pushNegation1(res.getRHS()));
00241 break;
00242 }
00243 default:
00244 res = d_commonRules->reflexivityRule(e);
00245 }
00246 TRACE("pushNegation1", "pushNegation1 => ", res.getExpr(), " }");
00247 return res;
00248 }