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
00030
00031 #include "translator.h"
00032 #include "expr.h"
00033 #include "theory_arith.h"
00034
00035
00036 using namespace std;
00037
00038
00039 namespace CVCL {
00040
00041
00042 Expr Translator::preprocessRec(const Expr& e, ExprMap<Expr>& cache)
00043 {
00044 if (e.arity() == 0) return e;
00045 ExprMap<Expr>::iterator i(cache.find(e));
00046 if(i != cache.end()) {
00047 return (*i).second;
00048 }
00049
00050 Expr e2(e);
00051 vector<Expr> children;
00052 bool diff = false;
00053
00054 for(int k = 0; k < e.arity(); ++k) {
00055
00056 Expr child = preprocessRec(e[k], cache);
00057 if (child != e[k]) diff = true;
00058 children.push_back(child);
00059 }
00060 if (diff) {
00061 e2 = Expr(e.getOp(), children);
00062 }
00063
00064 switch (e2.getKind()) {
00065 case CONSTDEF:
00066 if (e2.arity() == 2) {
00067 cache[e] = e2[1];
00068 return e2[1];
00069 }
00070 break;
00071 case EQ:
00072 if (d_theoryArith->getBaseType(e[0]) != d_theoryArith->realType())
00073 break;
00074 case LT:
00075 case GT:
00076 case LE:
00077 case GE:
00078 case UMINUS:
00079 case PLUS:
00080 case MINUS:
00081 case MULT:
00082 case DIVIDE:
00083 case POW:
00084 case INTDIV:
00085 case MOD:
00086
00087 if (d_iteLiftArith) {
00088 diff = false;
00089 children.clear();
00090 vector<Expr> children2;
00091 Expr cond;
00092 for (int k = 0; k < e2.arity(); ++k) {
00093 if (e2[k].getKind() == ITE && !diff) {
00094 diff = true;
00095 cond = e2[k][0];
00096 children.push_back(e2[k][1]);
00097 children2.push_back(e2[k][2]);
00098 }
00099 else {
00100 children.push_back(e2[k]);
00101 children2.push_back(e2[k]);
00102 }
00103 }
00104 if (diff) {
00105 Expr thenpart = Expr(e2.getOp(), children);
00106 Expr elsepart = Expr(e2.getOp(), children2);
00107 e2 = cond.iteExpr(thenpart, elsepart);
00108 e2 = preprocessRec(e2, cache);
00109 cache[e] = e2;
00110 return e2;
00111 }
00112 }
00113
00114 if (d_convertToDiff && d_theoryArith->isAtomicArithFormula(e2)) {
00115 e2 = d_theoryArith->rewriteToDiff(e2);
00116 cache[e] = e2;
00117 return e2;
00118 }
00119
00120 break;
00121 default:
00122 break;
00123 }
00124 cache[e] = e2;
00125 return e2;
00126 }
00127
00128
00129 Expr Translator::preprocess(const Expr& e)
00130 {
00131 ExprMap<Expr> cache;
00132 return preprocessRec(e, cache);
00133 }
00134
00135
00136 }