theory_quant.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file theory_quant.cpp
00004  * 
00005  * Author: Daniel Wichs
00006  * 
00007  * Created: Wednesday July 2, 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 "theory_quant.h"
00031 #include "typecheck_exception.h"
00032 #include "parser_exception.h"
00033 #include "smtlib_exception.h"
00034 #include "quant_proof_rules.h"
00035 #include "theory_core.h"
00036 #include "command_line_flags.h"
00037 
00038 
00039 using namespace std;
00040 using namespace CVCL;
00041 
00042 
00043 
00044 ///////////////////////////////////////////////////////////////////////////////
00045 // TheoryQuant Public Methods                                                //
00046 ///////////////////////////////////////////////////////////////////////////////
00047 
00048 
00049 TheoryQuant::TheoryQuant(TheoryCore* core) //!< Constructor
00050   : Theory(core, "Quantified Expressions"),
00051     d_univs(core->getCM()->getCurrentContext()),
00052     d_savedTermsPos(core->getCM()->getCurrentContext(), 0, 0),
00053     d_univsSavedPos(core->getCM()->getCurrentContext(), 0, 0),
00054     d_univsPosFull(core->getCM()->getCurrentContext(), 0, 0),
00055     d_univsContextPos(core->getCM()->getCurrentContext(), 0, 0),
00056     d_instCount(core->getCM()->getCurrentContext(), 0,0),
00057     d_contextTerms(core->getCM()->getCurrentContext()),
00058     d_contextCache(core->getCM()->getCurrentContext()),
00059     d_maxQuantInst(&(core->getFlags()["max-quant-inst"].getInt())),
00060     d_useNew(&(core->getFlags()["quant-new"].getBool())),
00061     d_useLazyInst(&(core->getFlags()["quant-lazy"].getBool())),
00062     d_useSemMatch(&(core->getFlags()["quant-sem-match"].getBool())),
00063     d_useAtomSem(&(core->getFlags()["quant-const-match"].getBool())),
00064     d_allInstCount(core->getStatistics().counter("quantifier instantiations")),
00065     d_instRound(core->getCM()->getCurrentContext(), 0,0)
00066 {
00067   IF_DEBUG(d_univs.setName("CDList[TheoryQuant::d_univs]"));
00068   vector<int> kinds;
00069 
00070   d_instCount = 0;
00071 
00072   d_rules=createProofRules();
00073   kinds.push_back(EXISTS);
00074   kinds.push_back(FORALL);
00075   registerTheory(this, kinds);
00076 }
00077 
00078 //! Destructor
00079 TheoryQuant::~TheoryQuant() {
00080      if(d_rules != NULL) delete d_rules;
00081      for(std::map<Type, CDList<size_t>* ,TypeComp>::iterator 
00082            it = d_contextMap.begin(), iend = d_contextMap.end(); 
00083          it!= iend; ++it)
00084        delete it->second;
00085 }
00086 
00087 void TheoryQuant::setup(const Expr& e) {}
00088 void TheoryQuant::update(const Theorem& e, const Expr& d) {}
00089 
00090 void TheoryQuant::enqueueInst(const Theorem thm)
00091 {
00092   enqueueFact(thm);
00093   d_allInstCount++;
00094   d_instThisRound++;
00095 }
00096     
00097 
00098 bool canGetHead(const Expr& e)
00099 {
00100   return (e.getKind() == UFUNC || e.getKind() == 2001); 
00101   //I do not like 2001, but do we have another way to test if a term is an array?
00102 }
00103 
00104 //! get the head string of function and array
00105 std::string TheoryQuant::getHead(const Expr& e)
00106 {
00107   if (e.getKind() == UFUNC)
00108     return e.getOp().getExpr().getName();
00109   
00110   if (e.getKind() == 2001) 
00111     {
00112       std::string eStr = e.toString();
00113       size_t pos1 = eStr.find('[');
00114       size_t pos2 = eStr.find('(');
00115       if (std::string::npos == pos1)
00116         {
00117           cout<<"I do not know how this happen in get head"<<endl;
00118           return "";
00119         }
00120       else
00121         return eStr.substr(0,(pos1<pos2?pos1:pos2));
00122     }
00123   
00124   cout <<"cannot get the term head of "<<e.toString()<<endl;
00125   return "";
00126 }
00127 
00128 static void recursiveGetSubTerm(const Expr& e, std::vector<Expr> & res) {
00129  
00130   if(e.getFlag())
00131    return;
00132 
00133   if(e.isClosure())
00134     return recursiveGetSubTerm(e.getBody(),res); 
00135 
00136   //  if (e.isApply() || ( e.isTerm() && (!e.isVar())  )
00137   if  ( e.isTerm() && (!e.isVar()) && (e.getKind()!=RATIONAL_EXPR) )
00138   // if  ( (!e.isVar()) && (e.getKind()!=RATIONAL_EXPR) )
00139     {
00140       res.push_back(e);
00141     }
00142    
00143   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
00144     {   
00145       recursiveGetSubTerm(*i,res);
00146     }
00147   
00148   e.setFlag();
00149   return ;
00150 }
00151 
00152 
00153 std::vector<Expr> getSubTerms(const Expr& e)
00154 {
00155   e.clearFlags();
00156   std::vector<Expr> res;
00157   recursiveGetSubTerm(e,res);
00158   e.clearFlags();
00159   TRACE("getsub","e is ", e.toString(),"");
00160   TRACE("getsub","have ", res.size()," subterms");
00161   return res;
00162 }
00163 
00164 //! get the bound vars in term e,
00165 static void recursiveGetBoundVars(const Expr& e, std::set<Expr>& result) {
00166  
00167   if(e.getFlag())
00168    return ;
00169   
00170   if(e.isClosure())
00171     return recursiveGetBoundVars(e.getBody(),result); 
00172   
00173   if  (BOUND_VAR == e.getKind() ){
00174     result.insert(e);
00175   }
00176   else 
00177     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i){        
00178       recursiveGetBoundVars(*i,result);
00179     }
00180   
00181   e.setFlag();
00182   return ;
00183 }
00184 
00185 //! get bound vars in term e, 
00186 std::set<Expr>  getBoundVars(const Expr& e)
00187 {
00188   e.clearFlags();
00189   std::set<Expr> result;  
00190   recursiveGetBoundVars(e,result);
00191   e.clearFlags();
00192   return result;
00193 }
00194 
00195 bool isGoodTrigger(const Expr& e, const std::vector<Expr>& bVarsThm)
00196 {
00197   if(!canGetHead(e))
00198     return false;
00199 
00200   const std::set<Expr>& bvs = getBoundVars(e);
00201   if (bvs.size() >= bVarsThm.size())
00202     {
00203       for(size_t i=0; i<bVarsThm.size(); i++)
00204         {
00205           if (bvs.find(bVarsThm[i]) == bvs.end())
00206             return false;
00207         }
00208       return true;
00209     }
00210   else return false;
00211 }
00212 
00213 
00214 void TheoryQuant::setupTriggers(const Theorem& thm)
00215 {
00216   const Expr & e = thm.getExpr();
00217   TRACE("triggers","====================","","");
00218   TRACE("triggers","setup  ",e.toString(),"");
00219  
00220   if  (0 == d_univsTriggers[e].size())
00221     {
00222       const std::vector<Expr>& bVarsThm = e.getVars(); 
00223       const std::vector<Expr> & subterms = getSubTerms(e);
00224       for( std::vector<Expr>::const_iterator i = subterms.begin(),iend=subterms.end(); i!=iend;i++)
00225         {
00226           if(isGoodTrigger(*i,bVarsThm))  
00227             {
00228               bool notfound = true;
00229               for(size_t index=0;index<d_univsTriggers[e].size();index++)
00230                 { 
00231                   if (i->subExprOf(d_univsTriggers[e][index]))
00232                     {
00233                       (d_univsTriggers[e][index])=*i;
00234                       notfound=false;
00235                     }
00236                 }
00237               if (notfound)                 
00238                 d_univsTriggers[e].push_back(*i);
00239             }
00240         }
00241        
00242       for (size_t  i=0; i< d_univsTriggers[e].size();i++)
00243         {
00244           TRACE("triggers", "triggers:", d_univsTriggers[e][i].toString(),"");
00245           TRACE("triggers","------------","","");
00246         }
00247     }
00248 }
00249 
00250 /*! \brief Theory interface function to assert quantified formulas
00251  *
00252  * pushes in negations and converts to either universally or existentially 
00253  * quantified theorems. Universals are stored in a database while 
00254  * existentials are enqueued to be handled by the search engine.
00255  */
00256 
00257 void TheoryQuant::assertFact(const Theorem& e)
00258 {
00259   TRACE("quant", "assertFact => ", e.toString(), "{");
00260   Theorem rule, result;
00261   const Expr& expr = e.getExpr();
00262   // Ignore existentials
00263   if(expr.isExists()) {
00264     TRACE("quant", "assertFact => (ignoring existential) }", "", "");
00265     return;
00266   }
00267   DebugAssert(expr.isForall()
00268               || (expr.isNot() && (expr[0].isExists() || expr[0].isForall())),
00269               "Theory of quantifiers cannot handle expression "
00270               + expr.toString());
00271 
00272   if(expr.isNot()) {//find the right rule to eliminate negation
00273     if(expr[0].isForall()) {
00274         rule = d_rules->rewriteNotForall(expr);
00275       }
00276     else if(expr[0].isExists()) {
00277         rule = d_rules->rewriteNotExists(expr);
00278       }
00279     result = iffMP(e, rule);
00280   }
00281   else
00282     result = e;
00283   
00284   result = d_rules->boundVarElim(result); //eliminate useless bound variables
00285   
00286   if(result.getExpr().isExists()) 
00287   {
00288     TRACE("quant", "assertFact => enqueuing: ", result.toString(), "}");
00289     enqueueFact(result);
00290   }
00291   else if(result.getExpr().isForall())
00292   {
00293     TRACE("quant", "assertFact => storing: ", result.toString(), "}");
00294     d_univs.push_back(result);
00295     if(*d_useNew)
00296       setupTriggers(result);
00297     //    cout<<"use naieve:"<<(false==*d_useNaiveInst)<<endl;
00298   }
00299   else { //quantifier got eliminated in boundVarElim
00300     TRACE("quant", "assertFact => enqueueing: ", result.toString(), "}");
00301     enqueueFact(result);
00302   }
00303 
00304 }
00305 
00306 void TheoryQuant::recGoodSemMatch(const Expr& e,
00307                                   const std::vector<Expr>& bVars,
00308                                   std::vector<Expr>& newInst,
00309                                   std::set<std::vector<Expr> >& instSet)
00310 {
00311   size_t curPos = newInst.size();
00312   if (bVars.size() == curPos)    {
00313     Expr simpleExpr = simplifyExpr(e.substExpr(bVars,newInst));
00314     if (simpleExpr.hasFind()){
00315       std::vector<Expr> temp = newInst;
00316       instSet.insert(temp);
00317       TRACE("quant yeting", "new inst found for ", e.toString()+" ==> ", simpleExpr.toString());
00318     };
00319   }
00320   else {
00321     Type t = getBaseType(bVars[curPos]);
00322     std::vector<Expr> tyExprs= d_typeExprMap[t];
00323     if (0 == tyExprs.size())  {
00324       //      cout <<"Cannot handle type of "<<t.toString()<<endl;;
00325       return;//has some problem
00326     }
00327     else{
00328       for (size_t i=0;i<tyExprs.size();i++){
00329         newInst.push_back(tyExprs[i]);
00330         recGoodSemMatch(e,bVars,newInst,instSet);
00331         newInst.pop_back();
00332       }
00333     }
00334   }
00335 }
00336 
00337 
00338 bool TheoryQuant::recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env)
00339 {
00340   TRACE("quant match", "gterm "+gterm.toString()," e "+vterm.toString(),"");
00341   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
00342   if (BOUND_VAR == vterm.getKind())
00343     {
00344       ExprMap<Expr>::iterator p = env.find(vterm);
00345       if ( p != env.end())
00346         {
00347           if (simplifyExpr(gterm) != simplifyExpr(p->second))
00348             { //TRACE ("match", (vterm.toString()+" bounded to more than one ground term"), "","");
00349               //cout<< "match" + vterm.toString()+" bounded to more than one ground term";
00350               return false; 
00351             }
00352           else
00353             return true;
00354         }
00355       else
00356         {
00357           env[vterm] = gterm;
00358           return true;
00359         }
00360     }
00361   else
00362     {
00363       if(simplifyExpr(vterm) == simplifyExpr(gterm))
00364         {
00365           return true;
00366         }
00367       else          
00368         if ( (vterm.arity() != gterm.arity()) || (vterm.getKind() != gterm.getKind() )) 
00369           //problem, should test whether vterm and gterm has the same kind
00370           //problem again, should test they have the same head?
00371           {
00372                     TRACE("quant match","different sub terms found, arity not same","gterm "+gterm.toString(), "vterm "+vterm.toString());
00373             return false;
00374           }
00375         else
00376           {
00377             if(canGetHead(vterm) && canGetHead(gterm)) //still problem here, should test cangethead here?
00378               {
00379                 if (getHead(vterm) != getHead(gterm))
00380                   return false;
00381               }
00382             for(int i=0;i<vterm.arity();i++)
00383               {
00384                 if (false == recSynMatch(gterm[i],vterm[i],env))
00385                   return false;
00386               }
00387             return true;
00388           }
00389     }
00390 }
00391 
00392 /*
00393 
00394 std::string TheoryQuant::getHead(const Expr& e)
00395 {
00396   TRACE("quant gethead", e.toString(),"","");
00397   //  TRACE("quant gethead", "e kind ",e.getKind()<<endl;
00398   TRACE("quant gethead", "e kind name ", getEM()->getKindName(e.getKind()), "");
00399   
00400   const int kind = e.getKind();
00401 
00402   if (e.isApply())
00403     return getHead(e.getFun());
00404   else if ( 2001 == kind ) 
00405     {
00406       return getHead(e[0]);
00407     }
00408   else if ( ID == kind || UCONST == kind)
00409     {
00410       return e.toString();
00411     }
00412   else if (BOUND_VAR == kind) 
00413     {
00414       return "";
00415     }
00416   else
00417     {
00418       cout<<"error in get head"<<endl;
00419       return NULL;
00420     }
00421 }
00422 
00423 */
00424 
00425 void TheoryQuant::goodSynMatch(const Expr& e,
00426                                const std::vector<Expr> & boundVars,
00427                                std::set<std::vector<Expr> >& instSet,
00428                                size_t tBegin)
00429 {
00430   const CDList<Expr>& allterms = theoryCore()->getTerms();
00431   for (size_t i=tBegin; i<allterms.size(); i++)
00432     {
00433       Expr gterm = allterms[i];
00434       if (0 == gterm.arity() )
00435         continue;
00436 
00437       if(canGetHead(gterm) && (getHead(gterm) == getHead(e)) )
00438       {
00439         ExprMap<Expr> env;
00440         env.clear();
00441         bool found = recSynMatch(gterm,e,env); 
00442         if(found)
00443           {
00444             TRACE("quant yeting", "found one",gterm.toString()+" to " , e.toString());
00445             std::vector<Expr> inst;
00446             DebugAssert((boundVars.size() == env.size()),"bound var size != env.size()");
00447             for(size_t i=0; i<boundVars.size(); i++)
00448               {
00449                 ExprMap<Expr>::iterator p = env.find(boundVars[i]);
00450                 DebugAssert((p!=env.end()),"bound var cannot be found");
00451                 inst.push_back(p->second);
00452               }
00453             instSet.insert(inst);
00454           }
00455       }
00456     }
00457 }
00458 
00459 
00460 bool TheoryQuant::hasGoodSynInst(const Expr& trig,
00461                                  std::vector<Expr> & boundVars,
00462                                  std::set<std::vector<Expr> >& instSet,
00463                                  size_t tBegin)
00464 {
00465   const std::set<Expr>& bvs = getBoundVars(trig);
00466   
00467   boundVars.clear();
00468   for(std::set<Expr>::iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
00469     boundVars.push_back(*i);
00470   
00471   instSet.clear();
00472 
00473   goodSynMatch(trig,boundVars,instSet,tBegin);
00474    
00475   if (instSet.size() > 0)
00476     return true;
00477   else
00478     return false;    
00479 }
00480 
00481 
00482 
00483 bool inStrCache(std::set<std::string> cache, std::string str)
00484 {
00485   return (cache.find(str) != cache.end());
00486 } 
00487 
00488 //! find if a good instantiation can be get from a term e
00489 //! if found, return boundVars used and inseSet of all good instantiations 
00490 bool TheoryQuant::hasGoodSemInst(const Expr& e,
00491                               std::vector<Expr> & boundVars,
00492                               std::set<std::vector<Expr> >& instSet,
00493                               size_t tBegin)
00494 {
00495   const std::set<Expr> bvs = getBoundVars(e);
00496   
00497   boundVars.clear();
00498   for(std::set<Expr>::iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
00499     boundVars.push_back(*i);
00500   
00501   std::vector<Expr> newInst;
00502   instSet.clear();
00503   if(inStrCache(cacheHead,getHead(e)))
00504      recGoodSemMatch(e,boundVars,newInst,instSet);
00505    
00506   if (instSet.size() > 0)
00507     return true;
00508   else
00509     return false;    
00510 }
00511 
00512 
00513 void genInstSetThm(const std::vector<Expr>&  bVarsThm,
00514                    const std::vector<Expr>& bVarsTerm,
00515                    const std::set<std::vector<Expr> >& termInst,
00516                    std::set<std::vector<Expr> >& instSetThm)
00517 {
00518   std::vector<int> bVmap;
00519 
00520   for(size_t i=0; i< bVarsThm.size(); ++i)
00521     {
00522       bVmap.push_back(-1);
00523       for (size_t j=0; j<bVarsTerm.size(); j++)
00524         {
00525           if (bVarsThm[i] == bVarsTerm[j])
00526             if(bVmap[i] != -1)
00527               {
00528                 cout <<"I do not expect here";
00529               }
00530             else
00531               bVmap[i]=j;             
00532         }
00533     }
00534 
00535   for(size_t i=0; i< bVarsThm.size(); ++i)
00536     if( -1 == bVmap[i])
00537       {
00538         //      cout<<"well, -1 found"<<endl;;
00539         return;
00540       }
00541 
00542   for(std::set<std::vector<Expr> > ::iterator i=termInst.begin(),
00543         iend=termInst.end();i!=iend; i++)
00544     {
00545       std::vector<Expr> buf;
00546       buf.clear();
00547       for(size_t j=0; j< bVarsThm.size(); ++j)
00548         {
00549           buf.push_back((*i)[bVmap[j]]);
00550           // cout <<"j="<<j<<" "<< ((*i)[bVmap[j]]).toString()<<endl;
00551         }
00552       //      cout <<"end of one"<<endl;;
00553       instSetThm.insert(buf);
00554     }
00555 }
00556         
00557 void TheoryQuant::synInst(const Theorem & univ, size_t tBegin)
00558 {
00559   const Expr& quantExpr = univ.getExpr();
00560   TRACE("quant inst", "now dealing with ", quantExpr.toString() , " ");
00561   const std::vector<Expr>& bVarsThm = quantExpr.getVars();
00562   const std::vector<Expr>& triggers = d_univsTriggers[quantExpr];
00563   std::set<std::vector<Expr> > instSetThm;
00564 
00565   for( std::vector<Expr>::const_iterator i= triggers.begin(), iend=triggers.end();i!=iend;++i) 
00566     {
00567       std::set<std::vector<Expr> > termInst;
00568       std::vector<Expr> bVarsTrig;
00569       const Expr& trig = *i;
00570        //later, we can add some conditions to handle
00571       //terms like (+ a b)
00572       TRACE("quant inst","handle trigger", trig.toString(),"");
00573       termInst.clear();
00574       bVarsTrig.clear();
00575       if(hasGoodSynInst(trig,bVarsTrig,termInst,tBegin))
00576         {
00577           genInstSetThm(bVarsThm,bVarsTrig,termInst,instSetThm);
00578           //here, bVarsThm and bVarsTerm are not the same, most of the time, I think,
00579           //even they contain the same elements, the order of the elements maybe different.
00580         }
00581     }
00582    
00583   if(0 == instSetThm.size()) 
00584     {
00585       TRACE("quant yeting","sorry, no instantiation found","","");
00586     }
00587   else  
00588     {
00589       for(std::set<std::vector<Expr> >::iterator i=instSetThm.begin(), iend=instSetThm.end(); i!=iend; ++i) 
00590         {
00591           Theorem t = d_rules->universalInst(univ,*i);
00592           enqueueInst(t);
00593           TRACE("quant yeting inst", "instantiating", univ.toString(), "|"+(t.toString()));  
00594         }
00595     } 
00596 }
00597 
00598 void TheoryQuant::semInst(const Theorem & univ, size_t tBegin)
00599 {
00600   const Expr& quantExpr = univ.getExpr();
00601   TRACE("quant inst", "now dealing with ", quantExpr.toString() , " ");
00602   const std::vector<Expr>& bVarsThm = quantExpr.getVars();
00603   const std::vector<Expr>& triggers = d_univsTriggers[quantExpr];
00604   std::set<std::vector<Expr> > instSetThm;
00605 
00606   for( std::vector<Expr>::const_iterator i= triggers.begin(), iend=triggers.end();i!=iend;++i) 
00607     {
00608       std::set<std::vector<Expr> > termInst;
00609       std::vector<Expr> bVarsTrig;
00610       const Expr& trig = *i;
00611        //later, we can add some conditions to handle
00612       //terms like (+ a b)
00613       TRACE("quant inst","handle trigger", trig.toString(),"");
00614       termInst.clear();
00615       bVarsTrig.clear();
00616       if(hasGoodSemInst(trig,bVarsTrig,termInst,tBegin))
00617         {
00618           genInstSetThm(bVarsThm,bVarsTrig,termInst,instSetThm);
00619           //here, bVarsThm and bVarsTerm are not the same, most of the time, I think,
00620           //even they contain the same elements, the order of the elements maybe different.
00621         }
00622     }
00623    
00624   if(0 == instSetThm.size()) 
00625     {
00626       TRACE("quant yeting","sorry, no instantiation found","","");
00627     }
00628   else  
00629     {
00630       for(std::set<std::vector<Expr> >::iterator i=instSetThm.begin(), iend=instSetThm.end(); i!=iend; ++i) 
00631         {
00632           Theorem t = d_rules->universalInst(univ,*i);
00633           enqueueInst(t);
00634           TRACE("quant yeting inst", "instantiating", univ.toString(), "|"+(t.toString()));  
00635         }
00636     } 
00637 }
00638 
00639 void TheoryQuant::checkSat(bool fullEffort)
00640 {
00641   d_instThisRound = 0;
00642   if (!(*d_useNew))
00643     naiveCheckSat(fullEffort);
00644   else if (*d_useSemMatch)
00645     semCheckSat(fullEffort);
00646   else synCheckSat(fullEffort);
00647   
00648   if( (*d_useNew) && (0 == d_instThisRound) && fullEffort )
00649     {
00650       naiveCheckSat(fullEffort);
00651     }
00652      
00653 }
00654 
00655 void TheoryQuant::synCheckSat(bool fullEffort)
00656 {
00657 
00658   //  cout << theoryCore()->getCM()->scopeLevel()<<endl;  
00659   size_t uSize = d_univs.size() ;
00660 
00661   if (0 == uSize )
00662     return;
00663 
00664   if((*d_useLazyInst) && (!fullEffort) )
00665     return;
00666 
00667   if(fullEffort) 
00668     {
00669       setIncomplete("Quantifier instantiation");
00670     }
00671 
00672   if (d_callThisRound > 30)
00673     return;
00674   
00675   const CDList<Expr>& allterms = theoryCore()->getTerms();
00676   size_t tSize = allterms.size();
00677   
00678   TRACE("quant",uSize, " uSize and univsSavedPOS " , d_univsSavedPos);
00679   TRACE("quant",tSize, " tSize and TermsSavedPos ",d_savedTermsPos);
00680 
00681   if ( (uSize == d_univsSavedPos) && (tSize == d_savedTermsPos) )
00682     return;
00683   
00684   if ( (uSize > d_univsSavedPos) && (tSize > d_savedTermsPos) )
00685     {
00686       for(size_t id=d_univsSavedPos; id<uSize; id++) 
00687         {
00688           synInst(d_univs[id],0);
00689         }
00690       for(size_t id=0; id<d_univsSavedPos; id++) 
00691         {
00692           synInst(d_univs[id],d_savedTermsPos);
00693         }
00694     }
00695   
00696   else if ( (uSize == d_univsSavedPos) && (tSize > d_savedTermsPos) )
00697     {
00698       for(size_t id=0 ; id<uSize; id++) 
00699         {
00700           synInst(d_univs[id],d_savedTermsPos);
00701         }
00702     }
00703   
00704   else if ( (uSize > d_univsSavedPos) && (tSize == d_savedTermsPos) )
00705     {
00706       for(size_t id=d_univsSavedPos ; id<uSize; id++) 
00707         {
00708           synInst(d_univs[id],0);
00709         }
00710     }
00711   else 
00712     cout <<" I do not believe this"<<endl;;
00713   
00714   d_univsSavedPos.set(uSize);
00715   d_savedTermsPos.set(tSize);
00716 
00717   if(d_instRound==theoryCore()->getCM()->scopeLevel())
00718     d_callThisRound++;
00719   else
00720     {
00721       d_callThisRound=0;
00722       d_instRound.set(theoryCore()->getCM()->scopeLevel());
00723     }
00724 
00725   TRACE("quant","this round; ",d_callThisRound,"");
00726   return;
00727  
00728 }
00729 
00730 
00731 void TheoryQuant::semCheckSat(bool fullEffort)
00732 {
00733   size_t uSize = d_univs.size() ;
00734   
00735   if (0 == uSize )
00736     return;
00737 
00738   if((*d_useLazyInst) && (!fullEffort) )
00739     return;
00740 
00741   if(fullEffort) 
00742     {
00743       setIncomplete("Quantifier instantiation");
00744     }
00745 
00746   if (d_callThisRound > 30)
00747     return;
00748 
00749   
00750   const CDList<Expr>& allterms = theoryCore()->getTerms();
00751   size_t tSize = allterms.size();
00752   
00753   TRACE("quant",uSize, " uSize and univsSavedPOS " , d_univsSavedPos);
00754   TRACE("quant",tSize, " tSize and TermsSavedPos ",d_savedTermsPos);
00755 
00756   if ( (uSize == d_univsSavedPos) && (tSize == d_savedTermsPos) )
00757     return;
00758 
00759   d_typeExprMap.clear();
00760   cacheHead.clear();
00761   for (size_t i=0; i<tSize; i++)
00762     {
00763       Expr term = allterms[i];
00764       //      cout << "dealing "<<term.toString()<<" of  type "<<getBaseType(term).toString()<<endl;;
00765       if (*d_useAtomSem)
00766         {
00767           if (0 ==term.arity())
00768             {     
00769               Type t = getBaseType(term);
00770               (d_typeExprMap[t]).push_back(term);
00771             }
00772         }
00773       else
00774         {      Type t = getBaseType(term);
00775               (d_typeExprMap[t]).push_back(term);
00776         }
00777       if(canGetHead(term))
00778         cacheHead.insert(getHead(term));
00779     }
00780   
00781   if ( (uSize > d_univsSavedPos) && (tSize > d_savedTermsPos) )
00782     {
00783       for(size_t id=d_univsSavedPos; id<uSize; id++) 
00784         {
00785           semInst(d_univs[id],0);
00786         }
00787       for(size_t id=0; id<d_univsSavedPos; id++) 
00788         {
00789           semInst(d_univs[id],d_savedTermsPos);
00790         }
00791     }
00792   
00793   else if ( (uSize == d_univsSavedPos) && (tSize > d_savedTermsPos) )
00794     {
00795       for(size_t id=0 ; id<uSize; id++) 
00796         {
00797           semInst(d_univs[id],d_savedTermsPos);
00798         }
00799     }
00800   
00801   else if ( (uSize > d_univsSavedPos) && (tSize == d_savedTermsPos) )
00802     {
00803       for(size_t id=d_univsSavedPos ; id<uSize; id++) 
00804         {
00805           semInst(d_univs[id],0);
00806         }
00807     }
00808   else
00809     cout <<" I do not believe this"<<endl;;
00810   
00811   d_univsSavedPos.set(uSize);
00812   d_savedTermsPos.set(tSize);
00813   if(d_instRound==theoryCore()->getCM()->scopeLevel())
00814     d_callThisRound++;
00815   else
00816     {
00817       d_callThisRound=0;
00818       d_instRound.set(theoryCore()->getCM()->scopeLevel());
00819     }
00820   TRACE("quant","this round; ",d_callThisRound,"");
00821   return;
00822 }
00823 
00824 
00825 
00826 void TheoryQuant::naiveCheckSat(bool fullEffort)
00827 {
00828   TRACE("quant", "checkSat ", fullEffort, "{");
00829   IF_DEBUG(int instCount = d_instCount);
00830   size_t uSize = d_univs.size(), stSize = d_savedTerms.size();
00831   if(fullEffort && uSize > 0) {
00832     // First of all, this algorithm is incomplete
00833     setIncomplete("Quantifier instantiation");
00834     
00835     if(d_instCount>=*d_maxQuantInst)
00836       return;
00837     //first attempt to instantiate with the saved terms
00838     //only do this if there are new saved terms or new theroems and 
00839     // at least some saved terms
00840     bool savedOnly = ((uSize > d_univsSavedPos.get()  && stSize > 0) ||
00841                       (stSize > d_savedTermsPos.get()));
00842     int origCount = d_instCount;
00843     if(savedOnly)
00844       {
00845         TRACE("quant", "checkSat [saved insts]: univs size = ", uSize , " ");
00846         for(size_t i=0, pos = d_univsSavedPos.get(); i<uSize; i++) {
00847           if(d_instCount>= *d_maxQuantInst)
00848             break;
00849           else
00850             instantiate(d_univs[i], i>=pos, true,  d_savedTermsPos.get());
00851         }
00852         d_univsSavedPos.set(d_univs.size());
00853         d_savedTermsPos.set(stSize);
00854       }
00855     if(!savedOnly || d_instCount == origCount)
00856       { //instantiate with context dependent assertions terms
00857         TRACE("quant", "checkSat [context insts]: univs size = ", uSize , " ");
00858         const CDList<Expr>& assertions = theoryCore()->getTerms();
00859         int origSize = d_contextTerms.size();
00860 //      for(size_t i=0; i<uSize; i++)
00861 //        assertions.push_back(d_univs[i].getExpr());
00862         //build the map of all terms grouped into vectors by types
00863         mapTermsByType(assertions);
00864         for(size_t i=0, pos = d_univsContextPos.get(); i<uSize; i++) {
00865           if(d_instCount>= *d_maxQuantInst)
00866             break;
00867           else
00868             instantiate(d_univs[i], i>=pos, false, origSize);
00869         }
00870         d_univsContextPos.set(d_univs.size());
00871       }
00872     TRACE("quant terse", "checkSat total insts: ",
00873           d_instCount, ", new "+int2string(d_instCount - instCount));
00874   }
00875   TRACE("quant", "checkSat total insts: ", d_instCount, " ");
00876   TRACE("quant", "checkSat new insts: ", d_instCount - instCount, " ");
00877   TRACE("quant", "checkSat effort:",  fullEffort, " }");
00878 
00879 }
00880 
00881 
00882 /*! \brief Queues up all possible instantiations of bound
00883  * variables.
00884  *
00885  * The savedMap boolean indicates whether to use savedMap or
00886  * d_contextMap the all boolean indicates weather to use all
00887  * instantiation or only new ones and newIndex is the index where
00888  * new instantiations begin.
00889  */
00890 void TheoryQuant::instantiate(Theorem univ, bool all, bool savedMap, 
00891                               size_t newIndex)
00892 {
00893   
00894   if(!all && ((savedMap &&  newIndex == d_savedTerms.size())
00895               ||(!savedMap && newIndex == d_contextTerms.size())))
00896     return;
00897 
00898   TRACE("quant", "instanitate", all , "{");
00899   std::vector<Expr> varReplacements;
00900   recInstantiate(univ, all, savedMap, newIndex, varReplacements);
00901   TRACE("quant", "instanitate", "", "}");
00902   
00903 }
00904 
00905  //! does most of the work of the instantiate function.
00906 void TheoryQuant::recInstantiate(Theorem& univ, bool all, bool savedMap,
00907                                  size_t newIndex, 
00908                                  std::vector<Expr>& varReplacements)
00909 {
00910   Expr quantExpr = univ.getExpr();
00911   const vector<Expr>& boundVars = quantExpr.getVars();
00912   
00913   size_t curPos = varReplacements.size(); 
00914   TRACE("quant", "recInstantiate: ", boundVars.size() - curPos, "");
00915   //base case: a full vector of instantiations exists
00916   if(curPos == boundVars.size()) {
00917     if(!all)
00918       return;
00919     Theorem t = d_rules->universalInst(univ, varReplacements);
00920     d_insts[t.getExpr()] = varReplacements;
00921     TRACE("quant", "recInstantiate => " , t.toString(), "");
00922     if(d_instCount< *d_maxQuantInst) {
00923       d_instCount=d_instCount+1;
00924       enqueueInst(t);
00925     }
00926     return;
00927   }
00928   //recursively add all possible instantiations in the next 
00929   //available space of the vector
00930   else {
00931     Type t = getBaseType(boundVars[curPos]);
00932     int iendC=0, iendS=0, iend;
00933     std::vector<size_t>* typeVec = NULL; // = d_savedMap[t];
00934     CDList<size_t>* typeList = NULL; // = *d_contextMap[t];
00935     if(d_savedMap.count(t) > 0) {
00936       typeVec = &(d_savedMap[t]);
00937       iendS = typeVec->size();
00938       TRACE("quant", "adding from savedMap: ", iendS, "");
00939     }
00940     if(!savedMap) {
00941       if(d_contextMap.count(t) > 0) {
00942         typeList = d_contextMap[t];
00943         iendC = typeList->size();
00944         TRACE("quant", "adding from contextMap:", iendC , "");
00945       }
00946     }
00947     iend = iendC + iendS;
00948     for(int i =0; i<iend; i++) {
00949       TRACE("quant", "I must have gotten here!", "", "");
00950       size_t index;
00951       if(i<iendS){
00952         index = (*typeVec)[i];
00953         varReplacements.push_back(d_savedTerms[index]);
00954       }
00955       else {
00956         index = (*typeList)[i-iendS];
00957         varReplacements.push_back(d_contextTerms[index]);
00958       }
00959       if((index <  newIndex) || (!savedMap && i<iendS))
00960         recInstantiate(univ, all, savedMap, newIndex,  varReplacements);
00961       else
00962         recInstantiate(univ, true, savedMap, newIndex,  varReplacements);
00963       varReplacements.pop_back();   
00964     }
00965 
00966 
00967   }
00968 }
00969 
00970 /*! \brief categorizes all the terms contained in a vector of  expressions by
00971  * type.
00972  *
00973  * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
00974  */
00975 void TheoryQuant::mapTermsByType(const CDList<Expr>& terms)
00976 {
00977   Expr trExpr=trueExpr(), flsExpr = falseExpr();
00978   Type boolT = boolType();
00979   if(d_contextMap.count(boolT) == 0)
00980     {
00981       d_contextMap[boolT] =
00982         new CDList<size_t>(theoryCore()->getCM()->getCurrentContext());
00983       size_t pos = d_contextTerms.size();
00984       d_contextTerms.push_back(trExpr);
00985       d_contextTerms.push_back(flsExpr);
00986       (*d_contextMap[boolT]).push_back(pos);
00987       (*d_contextMap[boolT]).push_back(pos+1);
00988     }
00989   for(size_t i=0; i<terms.size(); i++)
00990     recursiveMap(terms[i]);
00991   // Add all our saved universals to the pool
00992   for(size_t i=0; i<d_univs.size(); i++)
00993     recursiveMap(d_univs[i].getExpr());
00994 }
00995 
00996 /*! \brief categorizes all the terms contained in an expressions by
00997  * type. 
00998  *
00999  * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
01000  * returns true if the expression does not contain bound variables, false
01001  * otherwise.
01002  */
01003 bool TheoryQuant::recursiveMap(const Expr& e)
01004 {
01005   if(d_contextCache.count(e)>0) {
01006     return(d_contextCache[e]);
01007   }
01008   if(e.arity()>0)  {
01009     for(Expr::iterator it = e.begin(), iend = e.end(); it!=iend; ++it)
01010       //maps the children and returns a bool
01011       if(recursiveMap(*it) == false) {
01012         d_contextCache[e] = false;
01013       }
01014   }
01015   else if(e.getKind() == EXISTS || e.getKind() == FORALL){
01016     //maps the body
01017     if(recursiveMap(e.getBody())==false) {
01018       d_contextCache[e]=false;
01019     }
01020   }
01021   //found a bound variable in the children
01022   if(d_contextCache.count(e)>0) {
01023     return false;
01024   }
01025   
01026   if(d_savedCache.count(e) > 0) {
01027     return true;
01028   }
01029   
01030   Type type = getBaseType(e);
01031   
01032   if(!type.isBool() && !(e.getKind()==BOUND_VAR)){
01033      TRACE("quant", "recursiveMap: found ", 
01034            e.toString() + " of type " + type.toString(), "");
01035     int pos = d_contextTerms.size();
01036     d_contextTerms.push_back(e);
01037     if(d_contextMap.count(type)==0)
01038       d_contextMap[type] =
01039         new CDList<size_t>(theoryCore()->getCM()->getCurrentContext());
01040     (*d_contextMap[type]).push_back(pos);
01041   }
01042 
01043   if(e.getKind() == BOUND_VAR) {
01044     d_contextCache[e] = false;
01045     return false;
01046   }
01047   else {
01048     d_contextCache[e] = true;
01049     return true;
01050   }
01051   //need  to implement: 
01052   //insert all instantiations if type is finite and reasonable
01053   //also need to implement instantiations of subtypes
01054 }
01055 
01056 /*!\brief Used to notify the quantifier algorithm of possible 
01057  * instantiations that were used in proving a context inconsistent.
01058  */
01059 void TheoryQuant::notifyInconsistent(const Theorem& thm)
01060 {
01061   // Reset the instantiation count
01062   // d_instCount = 0;
01063 
01064   if(d_univs.size() == 0)
01065     return;
01066   DebugAssert(thm.getExpr().getKind()== FALSE, "notifyInconsistent called with"
01067         " theorem: " + thm.toString() + " which is not a derivation of false");
01068   TRACE("quant", "notifyInconsistent: { " , thm.toString(), "}");
01069   thm.clearAllFlags();
01070   findInstAssumptions(thm);
01071   TRACE("quant terse", "notifyInconsistent: savedTerms size = ",
01072         d_savedTerms.size(), "");
01073   TRACE("quant terse", "last term: ", 
01074         d_savedTerms.size()? d_savedTerms.back() : Expr(), "");
01075 }
01076 /*! \brief A recursive function used to find instantiated universals
01077  * in the hierarchy of assumptions.
01078  */
01079 void TheoryQuant::findInstAssumptions(const Theorem& thm)
01080 {
01081   if(thm.isFlagged() || thm.isNull())
01082     return;
01083   thm.setFlag();
01084   const Expr& e = thm.getExpr();
01085   if(d_insts.count(e) > 0) {
01086     vector<Expr>& insts = d_insts[e];
01087     int pos;
01088     for(vector<Expr>::iterator it = insts.begin(), iend = insts.end(); it!=iend
01089           ; ++it)
01090       {
01091         if(d_savedCache.count(*it) ==  0) {
01092           TRACE("quant", "notifyInconsistent: found:", (*it).toString(), "");
01093           d_savedCache[*it] = true;
01094           pos = d_savedTerms.size();
01095           d_savedTerms.push_back(*it);
01096           d_savedMap[getBaseType(*it)].push_back(pos);
01097         }
01098       }
01099   }
01100   if(thm.isAssump())
01101     return;
01102   const Assumptions& a = thm.getAssumptionsRef();
01103   for(Assumptions::iterator it =a.begin(), iend = a.end(); it!=iend; ++it){
01104     findInstAssumptions(*it);
01105   }
01106 }
01107 
01108 //! computes the type of a quantified term. Always a  boolean.
01109 void TheoryQuant::computeType(const Expr& e)
01110 {
01111   switch (e.getKind()) {
01112   case FORALL:
01113   case EXISTS: {
01114     if(!e.getBody().getType().isBool())
01115       throw TypecheckException("Type mismatch for expression:\n\n   "
01116                               + e.getBody().toString()
01117                               + "\n\nhas the following type:\n\n  "
01118                               + e.getBody().getType().toString()
01119                               + "\n\nbut the expected type is Boolean:\n\n  ");
01120     else
01121       
01122       e.setType(e.getBody().getType());
01123     break;
01124   }
01125   default:
01126     DebugAssert(false,"Unexpected kind in Quantifier Theory: " 
01127                 + e.toString());
01128     break;
01129   }
01130 }
01131 
01132 /*!
01133  * TCC(forall x.phi(x)) = (forall x. TCC(phi(x)))
01134  *                         OR (exists x. TCC(phi(x)) & !phi(x))
01135  * TCC(exists x.phi(x)) = (forall x. TCC(phi(x)))
01136  *                         OR (exists x. TCC(phi(x)) & phi(x))
01137  */
01138 
01139 
01140 Expr TheoryQuant::computeTCC(const Expr& e) {
01141   DebugAssert(e.isQuantifier(), "Unexpected expression in Quantifier Theory: " 
01142               + e.toString());
01143 
01144   bool forall(e.getKind() == FORALL);
01145   const Expr& phi = e.getBody();
01146   Expr tcc_phi = getTCC(phi);
01147   Expr forall_tcc = getEM()->newClosureExpr(FORALL, e.getVars(), tcc_phi);
01148   Expr exists_tcc = getEM()->newClosureExpr(EXISTS, e.getVars(),
01149                                             tcc_phi && (forall? !phi : phi));
01150   return (forall_tcc || exists_tcc);  
01151 }
01152 
01153 
01154 ExprStream&
01155 TheoryQuant::print(ExprStream& os, const Expr& e) {
01156   switch(os.lang()) {
01157   case PRESENTATION_LANG: {
01158     switch(e.getKind()){
01159     case FORALL:
01160     case EXISTS: {
01161       if(!e.isQuantifier()) {
01162         e.printAST(os);
01163         break;
01164       }
01165       os << "(" << push << ((e.getKind() == FORALL)? "FORALL" : "EXISTS")
01166          << space << push;
01167       const vector<Expr>& vars = e.getVars();
01168       bool first(true);
01169       os << "(" << push;
01170       for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
01171           i!=iend; ++i) {
01172         if(first) first = false;
01173         else os << push << "," << pop << space;
01174         os << *i;
01175         // The quantifier may be in a raw parsed form, in which case
01176         // the type is not assigned yet
01177         if(i->isVar())
01178           os << ":" << space << pushdag << (*i).getType() << popdag;
01179       }
01180       os << push << "): " << pushdag << push
01181          << e.getBody() << push << ")";
01182     }
01183       break;
01184     default:
01185       e.printAST(os);
01186       break;
01187     }
01188     break;
01189   }
01190   case SMTLIB_LANG: {
01191     d_theoryUsed = true;
01192     switch(e.getKind()){
01193       case FORALL:
01194       case EXISTS: {
01195         if(!e.isQuantifier()) {
01196           e.printAST(os);
01197           break;
01198         }
01199         os << "(" << push << ((e.getKind() == FORALL)? "forall" : "exists")
01200            << space;
01201         const vector<Expr>& vars = e.getVars();
01202         bool first(true);
01203         //      os << "(" << push;
01204         for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
01205             i!=iend; ++i) {
01206           if(first) first = false;
01207           else os << space;
01208           os << "(" << push << *i;
01209           // The quantifier may be in a raw parsed form, in which case
01210           // the type is not assigned yet
01211           if(i->isVar())
01212             os << space << pushdag << (*i).getType() << popdag;
01213           os << push << ")" << pop << pop;
01214         }
01215         os << pushdag
01216            << e.getBody() << push << ")";
01217         break;
01218       }
01219       default:
01220         throw SmtlibException("TheoryQuant::print: SMTLIB_LANG: Unexpected expression: "
01221                               +getEM()->getKindName(e.getKind()));
01222         break;
01223     }
01224     break;
01225   } // End of SMTLIB_LANG
01226   case LISP_LANG: {
01227     switch(e.getKind()){
01228     case FORALL:
01229     case EXISTS: {
01230       if(!e.isQuantifier()) {
01231         e.printAST(os);
01232         break;
01233       }
01234       os << "(" << push << ((e.getKind() == FORALL)? "FORALL" : "EXISTS")
01235          << space;
01236       const vector<Expr>& vars = e.getVars();
01237       bool first(true);
01238       os << "(" << push;
01239       for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
01240           i!=iend; ++i) {
01241         if(first) first = false;
01242         else os << space;
01243         os << "(" << push << *i;
01244         // The quantifier may be in a raw parsed form, in which case
01245         // the type is not assigned yet
01246         if(i->isVar())
01247           os << space << pushdag << (*i).getType() << popdag;
01248         os << push << ")" << pop << pop;
01249       }
01250       os << push << ")" << pop << pop << pushdag
01251          << e.getBody() << push << ")";
01252     }
01253       break;
01254     default:
01255       e.printAST(os);
01256       break;
01257     }
01258     break;
01259   }
01260   default:
01261     e.printAST(os);
01262     break;
01263   }
01264   return os;
01265 }
01266 
01267 ///////////////////////////////////////////////////////////////////////////////
01268 //parseExprOp:
01269 //translating special Exprs to regular EXPR??
01270 ///////////////////////////////////////////////////////////////////////////////
01271 Expr
01272 TheoryQuant::parseExprOp(const Expr& e) {
01273   TRACE("parser", "TheoryQuant::parseExprOp(", e, ")");
01274   // If the expression is not a list, it must have been already
01275   // parsed, so just return it as is.
01276   if(RAW_LIST != e.getKind()) return e;
01277 
01278   DebugAssert(e.arity() > 0,
01279               "TheoryQuant::parseExprOp:\n e = "+e.toString());
01280   
01281   const Expr& c1 = e[0][0];
01282   const string& opName(c1.getString());
01283   int kind = getEM()->getKind(opName);
01284   switch(kind) {
01285   case FORALL:
01286   case EXISTS: { // (OP ((v1 ... vn tp1) ...) body)
01287     if(!(e.arity() == 3 && e[1].getKind() == RAW_LIST && e[1].arity() > 0))
01288       throw ParserException("Bad "+opName+" expression: "+e.toString());
01289     // Iterate through the groups of bound variables
01290     vector<pair<string,Type> > vars; // temporary stack of bound variables
01291     for(Expr::iterator i=e[1].begin(), iend=e[1].end(); i!=iend; ++i) {
01292       if(i->getKind() != RAW_LIST || i->arity() < 2)
01293         throw ParserException("Bad variable declaration block in "+opName
01294                             +" expression: "+i->toString()
01295                             +"\n e = "+e.toString());
01296       // Iterate through individual bound vars in the group.  The
01297       // last element is the type, which we have to rebuild and
01298       // parse, since it is used in the creation of bound variables.
01299       Type tp(parseExpr((*i)[i->arity()-1]));
01300       for(int j=0, jend=i->arity()-1; j<jend; ++j) {
01301         if((*i)[j].getKind() != ID)
01302           throw ParserException("Bad variable declaration in "+opName+""
01303                               " expression: "+(*i)[j].toString()+
01304                               "\n e = "+e.toString());
01305         vars.push_back(pair<string,Type>((*i)[j][0].getString(), tp));
01306       }
01307     }
01308     // Create all the bound vars and save them in a vector
01309     vector<Expr> boundVars;
01310     for(vector<pair<string,Type> >::iterator i=vars.begin(), iend=vars.end();
01311         i!=iend; ++i)
01312       boundVars.push_back(addBoundVar(i->first, i->second));
01313     // Rebuild the body
01314     Expr body(parseExpr(e[2]));
01315     // Build the resulting Expr as (OP (vars) body)
01316     Expr res = getEM()->newClosureExpr((kind == FORALL) ? FORALL : EXISTS,
01317                                        boundVars, body);
01318     return res;
01319     break;
01320   }
01321 //       vector<Expr> bvarDecls, bvars;
01322 //       Expr bvarDeclsExpr;
01323 //       for(Expr::iterator i = e[1].begin(), iend=e[1].end(); i!=iend; ++i) {
01324 //         bvars = i->getKids();
01325 //      bvars.insert(bvars.begin(), Expr(e.getEM(), ID, Expr(e.getEM(), STRING_EXPR, "VARDECL")));
01326 //      bvarDecls.push_back(Expr(e.getEM(), RAW_LIST, bvars));
01327 //      }
01328 //       bvarDeclsExpr = Expr(e.getEM(), RAW_LIST, bvarDecls);
01329 //       return Expr(e.getEM(), kind, parseExpr(bvarDeclsExpr), parseExpr(e[2]));
01330 //     }
01331   default:
01332     DebugAssert(false,
01333                 "TheoryQuant::parseExprOp: invalid command or expression: " + e.toString());
01334     break;
01335   }
01336   return e;
01337 }

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