preprocess.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file expr_transform.cpp
00004  * 
00005  * Author: Ying Hu, Clark Barrett
00006  * 
00007  * Created: Jun 05 2003
00008  *
00009  * <hr>
00010  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00011  * Junior University and by New York University. 
00012  *
00013  * License to use, copy, modify, sell and/or distribute this software
00014  * and its documentation for any purpose is hereby granted without
00015  * royalty, subject to the terms and conditions defined in the \ref
00016  * LICENSE file provided with this distribution.  In particular:
00017  *
00018  * - The above copyright notice and this permission notice must appear
00019  * in all copies of the software and related documentation.
00020  *
00021  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00022  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00023  * 
00024  * <hr>
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; }  // compare
00073 static size_t hf(const Expr x) { 
00074         return x.getEM()->hash(x);; }                             // hash
00075 static size_t mf(const Expr x, const Expr y) { return x==y; }             // match
00076 
00077 static void update_queue(Queue *q, Expr e, CareSet *cs_prime){
00078   CareSet **cs=q->Fetch(e);
00079 
00080   // if there is already an entry for this expr,
00081   // AND the new careset with the old careset
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   // initialize
00105   if (init_st) {
00106     if (memoize) delete memoize;
00107     memoize = new Table();
00108     st = init_st;
00109   }
00110   
00111   // atomic expressions don't change
00112   if(e.isNull() || e.isBoolConst()
00113      || e.isString() || e.isRational())
00114     return reflexivityRule(e);
00115   
00116   // has the result been memoized
00117   ExprMap<Theorem>::iterator i = memoize->find(e);
00118   if(i != memoize->end()) { // Found cached result
00119     return (*i).second;
00120   }
00121   
00122   // do substitution
00123   i = st->find(e);
00124   if (i != st->end()) {
00125     return transitivityRule((*i).second, substitute((*i).second.getRHS())); //get the theorem stored by simplifying, and do substitute recursively
00126   }
00127   
00128   // build new expr with all sub-exprs substituted
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     //DebugAssert(thm.getRHS()==thm1.getLHS(), "preprocess: transitivity rule1: " + tmp.toString());
00149     thm = transitivityRule(thm, thm1);
00150     tmp = thm.getRHS();
00151     thm1 = rewriteIteElse(tmp, substitute(tmp[2]));
00152     //DebugAssert(thm.getRHS()==thm1.getLHS(), "preprocess: transitivity rule2: " + tmp.toString());
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   // go through all the exprs in reverse topological order
00166   // and build up the substitution table
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     // free up memory so that we don't run out of the stuff
00179     delete p->Data();
00180     p->Data() = NULL;
00181     
00182     // simplify an ite if its ifpart belongs to the care set
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           // e1[0] |- e1[0] ==> e1[0] IFF TRUE
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 { //v==FALSE
00203           // e1[0] IFF FALSE |- e1[0] IFF FALSE
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     // add children to the queue, updating their caresets
00218     // in the case of an ite-expr
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       // add if-part==TRUE to the care-set for the then-part
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       // add if-part==FALSE to the care-set for the else-part
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   // perform all the substituations
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(); // 2 ^ 30 = 1073741824
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 

Generated on Thu Apr 13 16:57:32 2006 for CVC Lite by  doxygen 1.4.4