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 #include "expr_transform.h"
00031 #include "theory_core.h"
00032 #include "dictionary.h"
00033 #include "hash.h"
00034
00035
00036 using namespace std;
00037 using namespace CVCL;
00038
00039
00040 Theorem ExprTransform::preprocess(const Expr& e)
00041 {
00042 Theorem thm1;
00043 if(d_vcl->getFlags()["pp-pushneg"].getBool())
00044 thm1 = pushNegation(e);
00045 else
00046 thm1 = d_core->reflexivityRule(e);
00047 thm1 = d_core->transitivityRule(thm1, d_core->simplifyThm(thm1.getRHS(), true));
00048 if(d_vcl->getFlags()["ite-ify"].getBool())
00049 thm1 = d_core->transitivityRule(thm1,ite_convert(thm1.getRHS()));
00050 if(d_vcl->getFlags()["pp-ite"].getBool())
00051 return d_core->transitivityRule(thm1,ite_simplify(thm1.getRHS()));
00052 return thm1;
00053 }
00054
00055
00056 Theorem ExprTransform::preprocess(const Theorem& thm)
00057 {
00058 return d_core->iffMP(thm, preprocess(thm.getExpr()));
00059 }
00060
00061
00062
00063
00064 typedef Hash_Table<Expr, Expr> CareSet;
00065 typedef Hash_Ptr<Expr, Expr> CareSetPtr;
00066 typedef Dict<Expr, CareSet*> Queue;
00067 typedef Dict_Ptr<Expr, CareSet*> QueuePtr;
00068
00069 typedef ExprMap<Theorem> Table;
00070
00071 static int cf(Expr x, Expr y) {
00072 return (x.getIndex() < y.getIndex()) ? -1 : (x.getIndex() == y.getIndex()) ? 0 : 1; }
00073 static size_t hf(const Expr x) {
00074 return x.getEM()->hash(x);; }
00075 static size_t mf(const Expr x, const Expr y) { return x==y; }
00076
00077 static void update_queue(Queue *q, Expr e, CareSet *cs_prime){
00078 CareSet **cs=q->Fetch(e);
00079
00080
00081
00082
00083 if (cs) {
00084 CareSetPtr p(*cs);
00085 while (p!=NULL) {
00086 if (!cs_prime->Fetch(p->Key()) ||
00087 (*cs_prime)[p->Key()]!=p->Data()) {
00088 Expr key=p->Key();
00089 ++p;
00090 (*cs)->Delete(key);
00091 }
00092 else
00093 ++p;
00094 }
00095 }
00096 else
00097 q->Insert(e, new CareSet(*cs_prime));
00098 }
00099
00100 Theorem ExprTransform::substitute(Expr e, Table *init_st) {
00101 static Table *memoize;
00102 static Table *st;
00103
00104
00105 if (init_st) {
00106 if (memoize) delete memoize;
00107 memoize = new Table();
00108 st = init_st;
00109 }
00110
00111
00112 if(e.isNull() || e.isBoolConst()
00113 || e.isString() || e.isRational())
00114 return reflexivityRule(e);
00115
00116
00117 ExprMap<Theorem>::iterator i = memoize->find(e);
00118 if(i != memoize->end()) {
00119 return (*i).second;
00120 }
00121
00122
00123 i = st->find(e);
00124 if (i != st->end()) {
00125 return transitivityRule((*i).second, substitute((*i).second.getRHS()));
00126 }
00127
00128
00129 Theorem thm;
00130 if(e.getKind() != ITE)
00131 thm = reflexivityRule(e);
00132 else{
00133 vector<Theorem> thms;
00134 vector<unsigned> changed;
00135 Expr tmp;
00136 thm = substitute(e[0]);
00137 if(thm.getRHS() == e[0]){
00138 thm = reflexivityRule(e);
00139 tmp = e;
00140 }
00141 else{
00142 thms.push_back(thm);
00143 changed.push_back(0);
00144 thm = substitutivityRule(e, changed, thms);
00145 tmp = thm.getRHS();
00146 }
00147 Theorem thm1 = rewriteIteThen(tmp, substitute(tmp[1]));
00148
00149 thm = transitivityRule(thm, thm1);
00150 tmp = thm.getRHS();
00151 thm1 = rewriteIteElse(tmp, substitute(tmp[2]));
00152
00153 thm = transitivityRule(thm, thm1);
00154 }
00155
00156 (*memoize)[e] = thm;
00157 return thm;
00158 }
00159
00160 Theorem ExprTransform::ite_simplify(Expr e){
00161
00162 Queue q(cf);
00163 Table st;
00164
00165
00166
00167 q.Insert(e, new CareSet(hf, mf));
00168 for (QueuePtr p(&q); p!=NULL; ++p) {
00169
00170 Expr e = Expr(p->Key());
00171
00172 if(e.isNull() || e.isBoolConst() || e.isVar()
00173 || e.isString() || e.isRational() || e.isApply())
00174 continue;
00175
00176 CareSet cs(*p->Data());
00177
00178
00179 delete p->Data();
00180 p->Data() = NULL;
00181
00182
00183 if (e.getKind()==ITE) {
00184 const Expr e1 = Expr(e);
00185 Expr *v = cs.Fetch(e1[0]);
00186 if (v) {
00187 vector<Theorem> thms;
00188 vector<unsigned> changed;
00189 if((*v).isTrue()){
00190
00191 Theorem thm0 = iffTrue(assumpRule(e1[0]));
00192 thms.push_back(thm0);
00193 changed.push_back(0);
00194 thm0 = substitutivityRule(e1, changed, thms);
00195 Theorem thm1 = d_commonRules->rewriteIteTrue(thm0.getRHS());
00196 thm0 = transitivityRule(thm0, thm1);
00197 st[e1] = thm0;
00198 if(e1[1].getKind() != TRUE && e1[1].getKind() != FALSE)
00199 update_queue(&q, e1[1], &cs);
00200 continue;
00201 }
00202 else {
00203
00204 Theorem thm0 = assumpRule(e1[0].iffExpr(d_em->falseExpr()));
00205 thms.push_back(thm0);
00206 changed.push_back(0);
00207 thm0 = substitutivityRule(e1, changed, thms);
00208 Theorem thm1 = d_commonRules->rewriteIteFalse(thm0.getRHS());
00209 thm0 = transitivityRule(thm0, thm1);
00210 st[e1] = thm0;
00211 if(e1[2].getKind() != TRUE && e1[2].getKind() != FALSE)
00212 update_queue(&q, e1[2], &cs);
00213 continue;
00214 }
00215 }
00216 }
00217
00218
00219 if (e.getKind()==ITE) {
00220 CareSet cs_prime(cs);
00221 const Expr ite = Expr(e);
00222 if(ite[0].getKind() != TRUE && ite[0].getKind() != FALSE)
00223 update_queue(&q, ite[0], &cs);
00224
00225 cs_prime.Insert(ite[0], d_em->trueExpr());
00226 if(ite[1].getKind() != TRUE && ite[1].getKind() != FALSE)
00227 update_queue(&q, ite[1], &cs_prime);
00228
00229 cs_prime[ite[0]]=d_em->falseExpr();
00230 if(ite[2].getKind() != TRUE && ite[2].getKind() != FALSE)
00231 update_queue(&q, ite[2], &cs_prime);
00232 }
00233 }
00234
00235
00236 return substitute(e, &st);
00237 }
00238
00239 Theorem ExprTransform::ite_convert(const Expr& e){
00240 switch(e.getKind()){
00241 case TRUE:
00242 case FALSE:
00243 return reflexivityRule(e); break;
00244 case ITE:
00245 {
00246 Theorem thm0 = ite_convert(e[0]);
00247 Theorem thm1 = ite_convert(e[1]);
00248 Theorem thm2 = ite_convert(e[2]);
00249 vector<Theorem> thms;
00250 thms.push_back(thm0);
00251 thms.push_back(thm1);
00252 thms.push_back(thm2);
00253
00254 return substitutivityRule(e.getOp(), thms);
00255 }
00256 break;
00257 case NOT:
00258 {
00259 Theorem thm = ite_convert(e[0]);
00260 vector<Theorem> thms;
00261 thms.push_back(thm);
00262 thm = substitutivityRule(e.getOp(), thms);
00263 return transitivityRule(thm, NotToIte(thm.getRHS()));
00264 }
00265 break;
00266 case AND:
00267 {
00268 DebugAssert(e.arity() > 0, "Expected non-empty AND");
00269 const vector<Expr>& kids = e.getKids();
00270 unsigned i(0), ar(kids.size());
00271 vector<Theorem> thms;
00272 for(; i < ar; i++){
00273 thms.push_back(ite_convert(kids[i]));
00274 }
00275 Theorem thm = substitutivityRule(e.getOp(), thms);
00276 thm = transitivityRule(thm, AndToIte(thm.getRHS()));
00277 return thm;
00278 }
00279 break;
00280 case OR:
00281 {
00282 DebugAssert(e.arity() > 0, "Expected non-empty OR");
00283 const vector<Expr>& kids = e.getKids();
00284 unsigned i(0), ar(kids.size());
00285 vector<Theorem> thms;
00286 for(; i < ar; i++){
00287 thms.push_back(ite_convert(kids[i]));
00288 }
00289 Theorem thm = substitutivityRule(e.getOp(), thms);
00290 return transitivityRule(thm, OrToIte(thm.getRHS()));
00291 }
00292 break;
00293 case IMPLIES:
00294 {
00295 vector<Theorem> thms;
00296 thms.push_back(ite_convert(e[0]));
00297 thms.push_back(ite_convert(e[1]));
00298 Theorem thm = substitutivityRule(e.getOp(), thms);
00299 return transitivityRule(thm, ImpToIte(thm.getRHS()));
00300 }
00301 break;
00302 case IFF:
00303 {
00304 vector<Theorem> thms;
00305 thms.push_back(ite_convert(e[0]));
00306 thms.push_back(ite_convert(e[1]));
00307 Theorem thm = substitutivityRule(e.getOp(), thms);
00308 return transitivityRule(thm, IffToIte(thm.getRHS()));
00309 }
00310 break;
00311 default:
00312 return reflexivityRule(e);
00313 }
00314 }
00315
00316 Expr ExprTransform::ite_reorder(const Expr& e){
00317 switch(e.getKind()){
00318 case TRUE:
00319 case FALSE:
00320 return e; break;
00321 case ITE:
00322 {
00323 int x = random();
00324 if(x < 1073741824)
00325 return ite_reorder(e[0]).iteExpr(ite_reorder(e[1]), ite_reorder(e[2]));
00326 if(e[0].isTrue()){
00327 return ite_reorder(e[1]);
00328 }
00329 else if(e[0].isFalse()){
00330 return ite_reorder(e[2]);
00331 }
00332 else if(e[1].isTrue())
00333 return ite_reorder(e[2]).iteExpr(e[1], ite_reorder(e[0]));
00334 else if(e[1].isFalse() && e[2].isTrue())
00335 return ite_reorder(e[0]).iteExpr(e[1], e[2]);
00336 else if(e[1].isFalse()){
00337 Expr e0 = ite_reorder(e[2]);
00338 if(e0.isTrue())
00339 return getNeg(ite_reorder(e[0]));
00340 else if(e0.isFalse())
00341 return e[1];
00342 else
00343 return getNeg(e0).iteExpr(e[1], getNeg(ite_reorder(e[0])));
00344 }
00345 else if(e[2].isTrue()){
00346 Expr e0 = ite_reorder(e[1]);
00347 if(e0.isTrue())
00348 return e[2];
00349 else if(e0.isFalse())
00350 return getNeg(ite_reorder(e[0])) ;
00351 else
00352 return getNeg(e0).iteExpr(getNeg(ite_reorder(e[0])), e[2]);
00353 }
00354 else if(e[2].isFalse()){
00355 Expr e0 = ite_reorder(e[1]);
00356 if(e0.isTrue())
00357 return ite_reorder(e[0]);
00358 else if(e0.isFalse())
00359 return e[2];
00360 else
00361 return e0.iteExpr(ite_reorder(e[0]), e[2]);
00362 }
00363 else{
00364 Expr e0 = getNeg(ite_reorder(e[0]));
00365 if(e0.isTrue())
00366 return ite_reorder(e[2]);
00367 else if(e0.isFalse())
00368 return ite_reorder(e[1]);
00369 else
00370 return e0.iteExpr(ite_reorder(e[2]), ite_reorder(e[1]));
00371 }
00372 }
00373 break;
00374 default:
00375 return e;
00376 }
00377 }
00378
00379 Expr ExprTransform::getNeg(const Expr& e){
00380 switch(e.getKind()){
00381 case TRUE:
00382 return d_em->falseExpr(); break;
00383 case FALSE:
00384 return d_em->trueExpr(); break;
00385 case ITE:
00386 {
00387 if(e[1].isFalse() && e[2].isTrue())
00388 return e[0];
00389 else
00390 return e.iteExpr(d_em->falseExpr(), d_em->trueExpr());
00391 }
00392 break;
00393 default:
00394 return e.iteExpr(d_em->falseExpr(), d_em->trueExpr());
00395 }
00396 }
00397
00398