theory_quant.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file theory_quant.cpp
00004  *
00005  * Author: Daniel Wichs, Yeting Ge
00006  *
00007  * Created: Wednesday July 2, 2003
00008  *
00009  * <hr>
00010  *
00011  * License to use, copy, modify, sell and/or distribute this software
00012  * and its documentation for any purpose is hereby granted without
00013  * royalty, subject to the terms and conditions defined in the \ref
00014  * LICENSE file provided with this distribution.
00015  *
00016  * <hr>
00017  *
00018  */
00019 /*****************************************************************************/
00020 #include "theory_quant.h"
00021 #include "theory_arith.h"
00022 #include "theory_array.h"
00023 #include "typecheck_exception.h"
00024 #include "parser_exception.h"
00025 #include "smtlib_exception.h"
00026 #include "quant_proof_rules.h"
00027 #include "theory_core.h"
00028 #include "command_line_flags.h"
00029 #include "vcl.h"
00030 #include<string>
00031 #include<string.h>
00032 #include <algorithm>
00033 #include "assumptions.h"
00034 
00035 using namespace std;
00036 using namespace CVC3;
00037 
00038 ///////////////////////////////////////////////////////////////////////////////
00039 // TheoryQuant Public Methods                                                 //
00040 ///////////////////////////////////////////////////////////////////////////////
00041 
00042 static const Expr null_expr;
00043 const int FOUND_FALSE = 1;
00044 
00045 Trigger::Trigger(TheoryCore* core, Expr e, Polarity pol, std::set<Expr> boundVars){
00046   trig=e ;
00047   polarity=pol;
00048   head=null_expr;
00049   hasRWOp=false;
00050   hasTrans=false;
00051   hasT2=false;
00052   isSimple=false;
00053   isSuperSimple=false;
00054   isMulti=false;
00055   multiIndex = 99999;
00056   multiId = 99999;
00057   for(std::set<Expr>::const_iterator i=boundVars.begin(),iend=boundVars.end(); i!=iend; ++i)
00058     bvs.push_back(*i);
00059 }
00060 
00061 bool Trigger::isPos(){
00062   return (Pos==polarity||PosNeg==polarity);
00063 }
00064 
00065 bool Trigger::isNeg(){
00066   return (Neg==polarity || PosNeg==polarity);
00067 }
00068 
00069 std::vector<Expr> Trigger::getBVs(){
00070   return bvs;
00071 }
00072 
00073 Expr Trigger::getEx(){
00074   return trig;
00075 }
00076 
00077 void Trigger::setHead(Expr h){
00078   head=h;
00079 }
00080 
00081 Expr Trigger::getHead(){
00082   return head;
00083 }
00084 
00085 void Trigger::setRWOp(bool b){
00086   hasRWOp =b ;
00087 }
00088 
00089 bool Trigger::hasRW(){
00090   return hasRWOp;
00091 }
00092 
00093 void Trigger::setTrans(bool b){
00094   hasTrans =b ;
00095 }
00096 
00097 bool Trigger::hasTr(){
00098   return hasTrans;
00099 }
00100 
00101 void Trigger::setTrans2(bool b){
00102   hasT2 =b ;
00103 }
00104 
00105 bool Trigger::hasTr2(){
00106   return hasT2;
00107 }
00108 
00109 void Trigger::setSimp(){
00110   isSimple =true ;
00111 }
00112 
00113 bool Trigger::isSimp(){
00114   return isSimple;
00115 }
00116 
00117 void Trigger::setSuperSimp(){
00118   isSuperSimple =true ;
00119 }
00120 
00121 bool Trigger::isSuperSimp(){
00122   return isSuperSimple;
00123 }
00124 
00125 void Trigger::setMultiTrig(){
00126   isMulti = true ;
00127 }
00128 
00129 bool Trigger::isMultiTrig(){
00130   return isMulti;
00131 }
00132 
00133 
00134 dynTrig::dynTrig(Trigger t, ExprMap<Expr> b, size_t id)
00135   :trig(t),
00136    univ_id(id),
00137    binds(b)
00138 {}
00139 
00140 TheoryQuant::TheoryQuant(TheoryCore* core) //!< Constructor
00141   : Theory(core, "Quantified Expressions"),
00142     d_univs(core->getCM()->getCurrentContext()),
00143     d_rawUnivs(core->getCM()->getCurrentContext()),
00144     d_arrayTrigs(core->getCM()->getCurrentContext()),
00145     d_lastArrayPos(core->getCM()->getCurrentContext(), 0 , 0),
00146     d_lastPredsPos(core->getCM()->getCurrentContext(), 0, 0),
00147     d_lastTermsPos(core->getCM()->getCurrentContext(), 0, 0),
00148     d_lastPartPredsPos(core->getCM()->getCurrentContext(), 0, 0),
00149     d_lastPartTermsPos(core->getCM()->getCurrentContext(), 0, 0),
00150     d_univsPartSavedPos(core->getCM()->getCurrentContext(), 0, 0),
00151     d_lastPartLevel(core->getCM()->getCurrentContext(), 0, 0),
00152     d_partCalled(core->getCM()->getCurrentContext(),false,0),
00153     d_maxILReached(core->getCM()->getCurrentContext(),false,0),
00154     d_usefulGterms(core->getCM()->getCurrentContext()),
00155     d_lastUsefulGtermsPos(core->getCM()->getCurrentContext(), 0, 0),
00156     d_savedTermsPos(core->getCM()->getCurrentContext(), 0, 0),
00157     d_univsSavedPos(core->getCM()->getCurrentContext(), 0, 0),
00158     d_rawUnivsSavedPos(core->getCM()->getCurrentContext(), 0, 0),
00159     d_univsPosFull(core->getCM()->getCurrentContext(), 0, 0),
00160     d_univsContextPos(core->getCM()->getCurrentContext(), 0, 0),
00161     d_instCount(core->getCM()->getCurrentContext(), 0,0),
00162     d_contextTerms(core->getCM()->getCurrentContext()),
00163     d_contextCache(core->getCM()->getCurrentContext()),
00164     d_maxQuantInst(&(core->getFlags()["max-quant-inst"].getInt())),
00165     d_useNew(&(core->getFlags()["quant-new"].getBool())),
00166     d_useLazyInst(&(core->getFlags()["quant-lazy"].getBool())),
00167     d_useSemMatch(&(core->getFlags()["quant-sem-match"].getBool())),
00168     d_useCompleteInst(&(core->getFlags()["quant-complete-inst"].getBool())),
00169     d_translate(&(core->getFlags()["translate"].getBool())),
00170     //    d_usePart(&(core->getFlags()["quant-inst-part"].getBool())),
00171     //    d_useMult(&(core->getFlags()["quant-inst-mult"].getBool())),
00172     d_useInstLCache(&(core->getFlags()["quant-inst-lcache"].getBool())),
00173     d_useInstGCache(&(core->getFlags()["quant-inst-gcache"].getBool())),
00174     d_useInstThmCache(&(core->getFlags()["quant-inst-tcache"].getBool())),
00175     d_useInstTrue(&(core->getFlags()["quant-inst-true"].getBool())),
00176     d_usePullVar(&(core->getFlags()["quant-pullvar"].getBool())),
00177     d_useExprScore(&(core->getFlags()["quant-score"].getBool())),
00178     d_maxIL(&(core->getFlags()["quant-max-IL"].getInt())),
00179     d_useTrans(&(core->getFlags()["quant-trans3"].getBool())),
00180     d_useTrans2(&(core->getFlags()["quant-trans2"].getBool())),
00181     d_useManTrig(&(core->getFlags()["quant-man-trig"].getBool())),
00182     d_useGFact(&(core->getFlags()["quant-gfact"].getBool())),
00183     d_gfactLimit(&(core->getFlags()["quant-glimit"].getInt())),
00184     d_usePolarity(&(core->getFlags()["quant-polarity"].getBool())),
00185     d_useNewEqu(&(core->getFlags()["quant-eqnew"].getBool())),
00186     d_maxNaiveCall(&(core->getFlags()["quant-naive-num"].getInt())),
00187     d_useNaiveInst(&(core->getFlags()["quant-naive-inst"].getBool())),
00188     d_curMaxExprScore(core->getCM()->getCurrentContext(), (core->getFlags()["quant-max-score"].getInt()),0),
00189     d_arrayIndic(core->getCM()->getCurrentContext()),
00190     d_exprLastUpdatedPos(core->getCM()->getCurrentContext(),0 ,0),
00191     d_trans_found(core->getCM()->getCurrentContext()),
00192     d_trans2_found(core->getCM()->getCurrentContext()),
00193     null_cdlist(core->getCM()->getCurrentContext()),
00194     d_eqsUpdate(core->getCM()->getCurrentContext()),
00195     d_lastEqsUpdatePos(core->getCM()->getCurrentContext(), 0, 0),
00196     d_eqs(core->getCM()->getCurrentContext()),
00197     d_eqs_pos(core->getCM()->getCurrentContext(), 0, 0),
00198     d_allInstCount(core->getStatistics().counter("quantifier instantiations")),
00199     d_allInstCount2(core->getStatistics().counter("quantifier instantiations2")),
00200     d_totalInstCount(core->getStatistics().counter("quant total instantiations")),
00201     d_trueInstCount(core->getStatistics().counter("quant true instantiations")),
00202     d_abInstCount(core->getStatistics().counter("quant abandoned instantiations")),
00203     d_instHistory(core->getCM()->getCurrentContext()),
00204     d_alltrig_list(core->getCM()->getCurrentContext())
00205 {
00206   IF_DEBUG(d_univs.setName("CDList[TheoryQuant::d_univs]");)
00207   vector<int> kinds;
00208   d_instCount = 0;
00209   d_cacheThmPos=0;
00210   d_trans_num=0;
00211   d_trans2_num=0;
00212   d_rules=createProofRules();
00213   kinds.push_back(EXISTS);
00214   kinds.push_back(FORALL);
00215   registerTheory(this, kinds);
00216   d_partCalled=false;
00217   d_offset_multi_trig=2;
00218   d_initMaxScore=(theoryCore()->getFlags()["quant-max-score"].getInt());
00219   for(size_t i=0; i<MAX_TRIG_BVS; i++){
00220     d_mybvs[i] = getEM()->newBoundVarExpr("_genbv", int2string(i), Type::anyType(getEM()));
00221   }
00222   core->addNotifyEq(this, null_expr);
00223   defaultReadExpr = theoryCore()->getEM()->newStringExpr("read");
00224   defaultWriteExpr = theoryCore()->getEM()->newStringExpr("write");
00225   defaultPlusExpr= theoryCore()->getEM()->newStringExpr("+");
00226   defaultMinusExpr= theoryCore()->getEM()->newStringExpr("-");
00227   defaultMultExpr= theoryCore()->getEM()->newStringExpr("*");
00228   defaultDivideExpr= theoryCore()->getEM()->newStringExpr("/");
00229   defaultPowExpr= theoryCore()->getEM()->newStringExpr("pow");
00230 
00231 }
00232 
00233 //! Destructor
00234 TheoryQuant::~TheoryQuant() {
00235   if(d_rules != NULL) delete d_rules;
00236   for(std::map<Type, CDList<size_t>* ,TypeComp>::iterator
00237   it = d_contextMap.begin(), iend = d_contextMap.end();
00238       it!= iend; ++it) {
00239     delete it->second;
00240      free(it->second);
00241   }
00242 
00243 }
00244 std::string vectorExpr2string(const std::vector<Expr> & vec){
00245   std::string buf;
00246   for(size_t i=0; i<vec.size(); i++){
00247     buf.append(vec[i].toString());
00248     buf.append(" # ");
00249   }
00250   return buf;
00251 }
00252 
00253 
00254 Theorem TheoryQuant::rewrite(const Expr& e){
00255   //  return reflexivityRule(e);
00256   // should combined with packvar, rewriet_not_all, etc,
00257   if(e.isForall() || e.isExists() ){
00258     Theorem resThm =  d_rules->normalizeQuant(e);
00259     //    Expr newE = resThm.getRHS();
00260     return resThm;
00261   }
00262   else{
00263     if (e.isNot() && e[0].isForall()){
00264       //      cout<<vectorExpr2string(e[0].getVars()) << endl;
00265     }
00266     else {
00267       //      cout<<e<<endl;
00268     }
00269     return reflexivityRule(e);
00270   }
00271 }
00272 
00273 
00274 int inline TheoryQuant::getExprScore(const Expr& e){
00275   return theoryCore()->getQuantLevelForTerm(e);
00276 }
00277 
00278 bool isSysPred(const Expr& e){
00279   return ( isLE(e) || isLT(e) || isGE(e) || isGT(e) || e.isEq());
00280 }
00281 
00282 bool canGetHead(const Expr& e){
00283   //  return (e.getKind() == APPLY || e.getKind() == READ || e.getKind() == WRITE);
00284   return (e.getKind() == APPLY 
00285     || e.getKind() == READ 
00286     || e.getKind() == WRITE
00287     || isPlus(e) 
00288     || isMinus(e) 
00289     || isMult(e)
00290     || isDivide(e)
00291     || isPow(e)
00292     );
00293 }
00294 
00295 bool isSimpleTrig(const Expr& t){
00296   if(!canGetHead(t)) return false;
00297   for(int i = 0; i < t.arity(); i++){
00298     if (t[i].arity()>0 && t[i].containsBoundVar()) return false;
00299     if (BOUND_VAR == t[i].getKind()){
00300       for(int j = 0; j < i; j++){
00301   if(t[i] == t[j]) return false;
00302       }
00303     }
00304   }
00305   return true;
00306 }
00307 
00308 bool isSuperSimpleTrig(const Expr& t){
00309   if(!isSimpleTrig(t)) return false;
00310   if(t.getKind() == READ || t.getKind() == WRITE){
00311     return false; //in case var1[var2]
00312   }
00313   for(int i = 0; i < t.arity(); i++){
00314     if (t[i].arity()>0 ) return false;
00315     if (BOUND_VAR != t[i].getKind()){
00316       return false;
00317     }
00318   }
00319   return true;
00320 }
00321 
00322 
00323 bool usefulInMatch(const Expr& e){
00324   if(e.arity() == 0){
00325     TRACE("usefulInMatch", e.toString()+": ",e.arity(), "");
00326     TRACE("usefulInMatch", e.isRational(), "", "");
00327   }
00328   return ( canGetHead(e) || (isSysPred(e) && (!e.isEq()) ) );
00329 }
00330 
00331 void TheoryQuant::setup(const Expr& e) {}
00332 
00333 int TheoryQuant::help(int i) {
00334   return d_curMaxExprScore;
00335 }
00336 
00337 void TheoryQuant::debug(int i){
00338   
00339   cout<<"in debug " << endl;
00340   cout << "max expr score " << d_curMaxExprScore << endl;
00341   cout << "all gterms " << endl;
00342   for(size_t gtermIndex =0; gtermIndex <  d_usefulGterms.size() ; gtermIndex++){
00343     cout << gtermIndex << " :: " << getExprScore(d_usefulGterms[gtermIndex]) << " | " << d_usefulGterms[gtermIndex] << endl;
00344   }
00345   cout << " =============  all terms ========================== " << endl;
00346   const CDList<Expr>&  allterms = theoryCore()->getTerms();
00347   for(size_t gtermIndex =0; gtermIndex <  allterms.size() ; gtermIndex++){
00348     const Expr& curGterm = allterms[gtermIndex];
00349     cout << gtermIndex << " :: " << getExprScore(curGterm) << " | " << curGterm << endl;
00350     cout << "--- ";
00351     if (curGterm.isApply() && curGterm.hasRep()){
00352       Expr curRep = curGterm.getRep().getRHS() ;
00353       if(curRep != curGterm){
00354   cout<<"DIFF " <<curRep << endl;
00355       }
00356     }
00357     else {
00358       cout << "No Rep" ;
00359     }
00360     cout << endl ;
00361 
00362     cout << "=== ";
00363     if (curGterm.isApply() && curGterm.hasSig()){
00364       Expr curSig = curGterm.getSig().getRHS() ;
00365       if(curSig != curGterm){
00366   cout<<"DIFF " <<curSig << endl;
00367       }
00368     }
00369     else {
00370       cout << "No Sig" ;
00371     }
00372     cout << endl ;
00373 
00374 
00375   }
00376   cout << " =============  all preds  ========================== " << endl;
00377   const CDList<Expr>&  allpreds = theoryCore()->getPredicates();
00378   for(size_t gtermIndex =0; gtermIndex <  allpreds.size() ; gtermIndex++){
00379     const Expr& curGterm = allpreds[gtermIndex];
00380     cout << gtermIndex << " :: " << getExprScore(curGterm) << " | " << curGterm << endl;
00381     cout << "--- ";
00382     if (curGterm.isApply() && curGterm.hasRep()){
00383       Expr curRep = curGterm.getRep().getRHS() ;
00384       if(curRep != curGterm){
00385   cout<<"DIFF " <<curRep << endl;
00386       }
00387     }
00388     else {
00389       cout << "No Rep" ;
00390     }
00391     cout << endl ;
00392 
00393     cout << "=== ";
00394     if (curGterm.isApply() && curGterm.hasSig()){
00395       Expr curSig = curGterm.getSig().getRHS() ;
00396       if(curSig != curGterm){
00397   cout<<"DIFF " <<curSig << endl;
00398       }
00399     }
00400     else {
00401       cout << "No Sig" ;
00402     }
00403     cout << endl ;
00404   }
00405 
00406   cout<<"let us try more"<<endl;
00407 
00408   //  checkSat(true);
00409   
00410 }
00411 
00412 void TheoryQuant::update(const Theorem& t, const Expr& e) {
00413 
00414   TRACE("quant update", "eqs updated: ",  t.getExpr(), "");
00415 
00416   //  if(! (*d_useNewEqu)) return;
00417   //  cout<<" ===== eqs in update =================== " <<endl;
00418 
00419   d_eqsUpdate.push_back(t);
00420 
00421   return;
00422 
00423   const Expr& leftTerm = t.getLHS();
00424   const Expr& rightTerm = t.getRHS();
00425   /*
00426   NotifyList* leftUpList = leftTerm.getNotify();
00427 
00428   cout<<"left term is " << leftTerm << endl;
00429 
00430   if(NULL == leftUpList) return;
00431 
00432 
00433   cout<<"the left notify list" <<endl;
00434   NotifyList& l = *leftUpList;
00435   for(size_t i=0,iend=l.size(); i<iend; ++i) {
00436     if(l.getTheory(i)->getName() == "Uninterpreted Functions"){
00437     cout << "[" << l.getTheory(i)->getName() << ", " << l.getExpr(i) << "] " << l.getExpr(i).getSig().isNull() << endl;
00438     }
00439   }
00440 
00441   const Expr& rightTerm = t.getRHS();
00442   cout<<"right term is " << rightTerm << endl;
00443   NotifyList* rightUpList = rightTerm.getNotify();
00444   if(NULL == rightUpList) return;
00445 
00446   cout<<"the right notify list" << endl;
00447 
00448   NotifyList& ll = *rightUpList;
00449   for(size_t i=0,iend=ll.size(); i<iend; ++i) {
00450     if(ll.getTheory(i)->getName() == "Uninterpreted Functions"){
00451     cout << "[" << ll.getTheory(i)->getName() << ", " << ll.getExpr(i) << "] " << ll.getExpr(i).getSig().isNull() << endl;
00452     }
00453   }
00454 
00455 
00456 //   cout<<"------------" << leftTerm << " # " << rightTerm <<endl;
00457 //   cout<<"$$$$$$$$$$$$" << leftTerm.hasFind() << " # " << rightTerm.hasFind() <<endl;
00458 //   if(theoryOf(leftTerm)->getName() == "Uninterpreted Functions"){
00459 //     cout<<"%%%%%%%%%%%%" << (leftTerm.getSig()).isNull() << " # " << (rightTerm.getSig()).isNull() <<endl;
00460 //   }
00461 //   else{
00462 //     cout<<"tttt" <<theoryOf(leftTerm)->getName()<<endl;
00463 //   }
00464 */
00465   if(false)
00466   {
00467     CDList<Expr>& backL = backList(leftTerm);
00468     CDList<Expr>& forwL = forwList(rightTerm);
00469 
00470     size_t backLen = backL.size();
00471     size_t forwLen = forwL.size();
00472     for(size_t i =0; i < backLen; i++){
00473       for(size_t j =0; j < forwLen; j++){
00474   //  cout<<backL[i] << " # " << leftTerm << " # " << forwL[j] << endl;
00475       }
00476     }
00477   }
00478   {
00479     CDList<Expr>& backL = backList(rightTerm);
00480     CDList<Expr>& forwL = forwList(leftTerm);
00481     size_t backLen = backL.size();
00482     size_t forwLen = forwL.size();
00483     for(size_t i = 0; i < backLen; i++){
00484       for(size_t j = 0; j < forwLen; j++){
00485   //  cout<<backL[i] << " # " << rightTerm << " # " << forwL[j] << endl;
00486       }
00487     }
00488   }
00489 
00490 }
00491 
00492 
00493 std::string TheoryQuant::exprMap2string(const ExprMap<Expr>& vec){
00494   string result;
00495 //   for( ExprMap<Expr>::iterator i = vec.begin(), iend = vec.end(); i != iend; i++){
00496 //     result.append((i->first).toString());
00497 //     result.append(" # ");
00498 //     result.append((i->second).toString());
00499 //     result.append("\n");
00500 //   }
00501 //   result.append("------ end map ------\n");
00502   return result;
00503 }
00504 
00505 
00506 
00507 std::string TheoryQuant::exprMap2stringSimplify(const ExprMap<Expr>& vec){
00508   string result;
00509 //   for( ExprMap<Expr>::iterator i = vec.begin(), iend = vec.end(); i != iend; i++){
00510 //     result.append((i->first).toString());
00511 //     result.append(" # ");
00512 //     result.append((simplifyExpr(i->second)).toString());
00513 //     result.append("\n");
00514 //   }
00515   result.append("------ end map ------\n");
00516   return result;
00517 }
00518 
00519 std::string TheoryQuant::exprMap2stringSig(const ExprMap<Expr>& vec){
00520   string result;
00521 //     for( ExprMap<Expr>::iterator i = vec.begin(), iend = vec.end(); i != iend; i++){
00522 //     result.append((i->first).toString());
00523 //     result.append(" # ");
00524 //     Expr isecond = i->second;
00525 //     if(simplifyExpr(isecond) == isecond && isecond.isApply() && isecond.hasSig()){
00526 //       result.append((isecond.getSig().getRHS()).toString());
00527 //     }
00528 //     else{
00529 //       //      result.append(isecond.toString());
00530 //     }
00531 //     result.append("\n");
00532 //   }
00533   result.append("------ end map ------\n");
00534   return result;
00535 }
00536 
00537 
00538 void TheoryQuant::simplifyExprMap(ExprMap<Expr>& orgExprMap){
00539   ExprMap<Expr> newExprMap;
00540   for( ExprMap<Expr>::iterator i = orgExprMap.begin(), iend = orgExprMap.end(); i != iend; i++){
00541     newExprMap[(*i).first] = simplifyExpr((*i).second);
00542   }
00543   orgExprMap = newExprMap;
00544 }
00545 
00546 void TheoryQuant::simplifyVectorExprMap(vector<ExprMap<Expr> >& orgVectorExprMap){
00547   std::vector<ExprMap<Expr> > newVectorExprMap;
00548   for( size_t orgVectorIndex = 0; orgVectorIndex < orgVectorExprMap.size(); orgVectorIndex++){
00549     ExprMap<Expr> curExprMap = orgVectorExprMap[orgVectorIndex];
00550     simplifyExprMap(curExprMap);
00551     newVectorExprMap.push_back(curExprMap);
00552   }
00553   orgVectorExprMap = newVectorExprMap;
00554 }
00555 
00556 static void recursiveGetSubTrig(const Expr& e, std::vector<Expr> & res) {
00557   if(e.getFlag())
00558    return;
00559 
00560   if(e.isClosure())
00561     return recursiveGetSubTrig(e.getBody(),res);
00562 
00563   if (e.isApply()|| isSysPred(e)){
00564     res.push_back(e);
00565   }
00566   else
00567     if ( e.isTerm() && (!e.isVar()) && (e.getKind()!=RATIONAL_EXPR) ) {
00568   res.push_back(e);
00569       }
00570 
00571   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)    {
00572       recursiveGetSubTrig(*i,res);
00573     }
00574 
00575   e.setFlag();
00576   return ;
00577 }
00578 
00579 std::vector<Expr> getSubTrig(const Expr& e){
00580   e.clearFlags();
00581   std::vector<Expr> res;
00582   recursiveGetSubTrig(e,res);
00583   e.clearFlags();
00584   TRACE("getsub","e is ", e.toString(),"");
00585   TRACE("getsub","have ", res.size()," subterms");
00586   return res;
00587 }
00588 
00589 static void recGetSubTerms(const Expr& e, std::vector<Expr> & res) {
00590   if(e.getFlag())
00591    return;
00592 
00593   if(e.isClosure())
00594     return recGetSubTerms(e.getBody(),res);
00595 
00596   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)  {
00597     recGetSubTerms(*i,res);
00598   }
00599 
00600   res.push_back(e);
00601 
00602   e.setFlag();
00603   return ;
00604 }
00605 
00606 const std::vector<Expr>& TheoryQuant::getSubTerms(const Expr& e){
00607   //the last item in res is e itself
00608   ExprMap<std::vector<Expr> >::iterator iter= d_subTermsMap.find(e);
00609   if( d_subTermsMap.end() == iter){
00610     e.clearFlags();
00611     std::vector<Expr> res;
00612     recGetSubTerms(e,res);
00613     e.clearFlags();
00614 
00615     TRACE("getsubs", "getsubs, e is: ", e, "");
00616     TRACE("getsubs", "e has ", res.size(), " subterms");
00617 
00618     d_subTermsMap[e] = res;
00619     return d_subTermsMap[e];
00620   }
00621   else{
00622     return (*iter).second;
00623   }
00624 }
00625 
00626 void TheoryQuant::enqueueInst(const Theorem& univ, const vector<Expr>& bind, const Expr& gterm){
00627   static int max_score =-1;
00628 
00629   bool partInst=false;
00630   if(bind.size() < univ.getExpr().getVars().size()){
00631     partInst=false;
00632     TRACE("sendinst","partinst",partInst,"");
00633   }
00634 
00635   Expr bind_expr(RAW_LIST, bind, getEM());
00636 
00637   if (*d_useInstLCache){
00638     const Expr& e = univ.getExpr();
00639     ExprMap<CDMap<Expr,bool>*>::iterator iterCache = d_bindHistory.find(e);
00640     if (iterCache != d_bindHistory.end()){
00641       CDMap<Expr,bool>* cache = (*iterCache).second;
00642       if(cache->find(bind_expr) !=cache->end()){
00643   return ;
00644       }
00645       else{
00646   (*cache)[bind_expr] = true;
00647       }
00648     }
00649     else{
00650       CDMap<Expr,bool>* new_cache = new(true) CDMap<Expr,bool> (theoryCore()->getCM()->getCurrentContext());
00651       (*new_cache)[bind_expr] = true;
00652       d_bindHistory[e] = new_cache;
00653     }
00654 
00655   }
00656 
00657   Theorem thm ;
00658   if(null_expr == gterm ){//it is from naive instantiation or multi-inst
00659     TRACE("sendinst","gterm",gterm,"");
00660     if(partInst) {
00661       thm = d_rules->partialUniversalInst(univ, bind, 0);
00662     }
00663     else{
00664       //      thm = d_rules->universalInst(univ, bind, 0);
00665       thm = d_rules->universalInst(univ, bind, 0, gterm);
00666     }
00667   }
00668   else{
00669     int gscore = theoryCore()->getQuantLevelForTerm(gterm);
00670     if(gscore > max_score){
00671       max_score = gscore;
00672       //      cout<<"max score "<<max_score<<endl;
00673     }
00674     if(partInst) {
00675       thm = d_rules->partialUniversalInst(univ, bind, gscore);
00676     }
00677     else{
00678       //      thm = d_rules->universalInst(univ, bind, gscore);
00679       thm = d_rules->universalInst(univ, bind, gscore, gterm);
00680     }
00681   }
00682 
00683   d_totalInstCount++;
00684   d_totalThmCount[thm.getExpr()]++;
00685   Theorem simpThm = simplify(thm.getExpr());
00686 
00687   if(*d_useInstTrue){
00688     Expr res = simpThm.getRHS();
00689     if(res.isTrue()){
00690       d_trueInstCount++;
00691       return;
00692     }
00693     if(res.isFalse() ){
00694       d_thmCount[thm.getExpr()]++;
00695       //      enqueueSE(thm);
00696       //      if(*d_useGFact || d_totalThmCount[thm.getExpr()] > *d_gfactLimit){
00697       if(*d_useGFact || d_thmCount[thm.getExpr()] > *d_gfactLimit){
00698   //      if(*d_useGFact || ){
00699   //  addGlobalLemma(thm, -1);
00700   enqueueFact(thm);
00701       }
00702       else{
00703   enqueueFact(thm);
00704       }
00705       //
00706       //      cout<<"false found "<<endl;
00707       //      setInconsistent(simpThm);
00708       d_allInstCount++;
00709       d_instThisRound++;
00710 
00711       throw FOUND_FALSE;
00712     }
00713   }
00714 
00715   d_simplifiedThmQueue.push(thm);
00716 
00717   TRACE("quant sendinst", "= gterm:",gterm, "");
00718   //  TRACE("quant sendinst", "= IL: ", theoryCore()->getQuantLevelForTerm(gterm), "");
00719   TRACE("quant sendinst", "= add fact simp: ", simplifyExpr(thm.getExpr()), "");
00720   TRACE("quant sendinst", "= add fact org: ", thm.getExpr(), "");
00721   TRACE("quant sendinst", "= add fact from: ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
00722 }
00723 
00724 
00725 //void TheoryQuant::enqueueInst(size_t univ_id , const std::vector<Expr>& bind, const Expr& gterm){
00726 void TheoryQuant::enqueueInst(size_t univ_id , const std::vector<Expr>& orgBind, const Expr& gterm){
00727   //  static int max_score =-1;
00728   TRACE("quant sendinst", "= begin univ id: ", univ_id, "");
00729   TRACE("quant sendinst", "= begin bind: ", vectorExpr2string(orgBind), "");
00730   TRACE("quant sendinst", "= begin gterm: ", gterm, "");
00731   const Theorem& univ = d_univs[univ_id];
00732 
00733   //  static vector<Theorem> storage ;
00734   //  storage.push_back(univ);
00735 
00736   bool partInst=false;
00737   if(orgBind.size() < univ.getExpr().getVars().size()){
00738     partInst=false;
00739     TRACE("sendinst","partinst",partInst,"");
00740   }
00741 
00742   vector<Expr> simpBind(orgBind);
00743   for(size_t orgBindIndex = 0; orgBindIndex < orgBind.size(); orgBindIndex++){
00744     simpBind [orgBindIndex] = simplifyExpr(orgBind[orgBindIndex]);
00745   }
00746 
00747   Expr orgBindList(RAW_LIST, orgBind, getEM());
00748   Expr simpBindList(RAW_LIST, simpBind, getEM());
00749 
00750 //   if(orgBindList != simpBindList){
00751 //     cout<<"debugerror" << endl;
00752 //     cout<< "-orgBind " << vectorExpr2string(orgBind) << endl;
00753 //     cout<< "-simpBind " << vectorExpr2string(simpBind) << endl;
00754 //   }
00755 
00756   vector<Expr> bind(simpBind);
00757   Expr bind_expr(simpBindList);
00758 
00759 //   vector<Expr> bind(orgBind);
00760 //   Expr bind_expr(orgBindList);
00761 
00762   TRACE("quant sendinst", "==add fact from= ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
00763 
00764   if (*d_useInstLCache){
00765     const Expr& e = univ.getExpr();
00766     ExprMap<CDMap<Expr,bool>*>::iterator iterCache = d_bindHistory.find(e);
00767     if (iterCache != d_bindHistory.end()){
00768       CDMap<Expr,bool>* cache = (*iterCache).second;
00769       if(cache->find(bind_expr) != cache->end()){
00770   //  cout<<"return inst 1"<<endl;
00771   return ;
00772       }
00773       else{
00774   (*cache)[bind_expr] = true;
00775       }
00776     }
00777     else{
00778       CDMap<Expr,bool>* new_cache = new(true) CDMap<Expr,bool> (theoryCore()->getCM()->getCurrentContext());
00779       (*new_cache)[bind_expr] = true;
00780       d_bindHistory[e] = new_cache;
00781     }
00782   }
00783 
00784   if (*d_useInstGCache){
00785     const Expr& e = univ.getExpr();
00786     ExprMap<std::hash_map<Expr,bool>*>::iterator iterCache = d_bindGlobalHistory.find(e);
00787     if (iterCache != d_bindGlobalHistory.end()){
00788       std::hash_map<Expr,bool>* cache = (*iterCache).second;
00789       if(cache->find(bind_expr) != cache->end()){
00790   //  cout<<"return inst 1"<<endl;
00791 
00792   //  int gscore = theoryCore()->getQuantLevelForTerm(gterm);
00793   //  Theorem local_thm = d_rules->universalInst(univ, bind, gscore);
00794   /*
00795   if(!(simplifyExpr(local_thm.getExpr())).isTrue()){
00796     cout<<"en?" <<endl;
00797     TRACE("quant sendinst", "==add fact simp =", simplifyExpr(local_thm.getExpr()), "");
00798     TRACE("quant sendinst", "==add fact org =", local_thm.getExpr(), "");
00799     TRACE("quant sendinst", "==add fact from= ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
00800     TRACE("quant sendinst", "== end === ", "=========", "============");
00801     }
00802   */
00803   d_allInstCount2++;
00804   return ;
00805       }
00806       /*
00807       else{
00808   (*cache)[bind_expr] = true;
00809 
00810   d_allInstCount2++;
00811       }
00812     }
00813     else{
00814       std::hash_map<Expr,bool>* new_cache = new std::hash_map<Expr,bool> ;
00815       (*new_cache)[bind_expr] = true;
00816       d_bindGlobalHistory[e] = new_cache;
00817       d_allInstCount2++;
00818       */
00819     }
00820   }
00821 
00822   Theorem thm ;
00823 
00824   if (*d_useInstThmCache){
00825     const Expr& e = univ.getExpr();
00826     ExprMap<std::hash_map<Expr,Theorem>* >::iterator iterCache = d_bindGlobalThmHistory.find(e);
00827     if (iterCache != d_bindGlobalThmHistory.end()){
00828       std::hash_map<Expr,Theorem>* cache = (*iterCache).second;
00829       std::hash_map<Expr,Theorem>::iterator thm_iter = cache->find(bind_expr);
00830 
00831       if(thm_iter != cache->end()){
00832   thm = thm_iter->second;
00833       }
00834       else{
00835   {
00836     if(null_expr == gterm ){//it is from naive instantiation or multi-inst
00837       TRACE("sendinst","gterm",gterm,"");
00838       if(partInst) {
00839         thm = d_rules->partialUniversalInst(univ, bind, 0);
00840       }
00841       else{
00842         //        thm = d_rules->universalInst(univ, bind, 0);
00843         thm = d_rules->universalInst(univ, bind, 0, gterm);
00844       }
00845     }
00846     else{
00847       int gscore = theoryCore()->getQuantLevelForTerm(gterm);
00848       if(partInst) {
00849         thm = d_rules->partialUniversalInst(univ, bind, gscore);
00850       }
00851       else{
00852         //        thm = d_rules->universalInst(univ, bind, gscore);
00853         thm = d_rules->universalInst(univ, bind, gscore, gterm);
00854       }
00855     }
00856   }
00857 
00858   (*cache)[bind_expr] = thm;
00859   d_allInstCount2++;
00860       }
00861     }
00862     else{
00863       {
00864   if(null_expr == gterm ){//it is from naive instantiation or multi-inst
00865     TRACE("sendinst","gterm",gterm,"");
00866     if(partInst) {
00867       thm = d_rules->partialUniversalInst(univ, bind, 0);
00868     }
00869     else{
00870       //      thm = d_rules->universalInst(univ, bind, 0);
00871       thm = d_rules->universalInst(univ, bind, 0, gterm);
00872     }
00873   }
00874   else{
00875     int gscore = theoryCore()->getQuantLevelForTerm(gterm);
00876     if(partInst) {
00877       thm = d_rules->partialUniversalInst(univ, bind, gscore);
00878     }
00879     else{
00880       //      thm = d_rules->universalInst(univ, bind, gscore);
00881       thm = d_rules->universalInst(univ, bind, gscore, gterm);
00882     }
00883   }
00884       }
00885 
00886       std::hash_map<Expr,Theorem>* new_cache = new std::hash_map<Expr,Theorem> ;
00887       (*new_cache)[bind_expr] = thm;
00888       d_bindGlobalThmHistory[e] = new_cache;
00889       d_allInstCount2++;
00890     }
00891   }
00892   else{
00893     if(null_expr == gterm ){//it is from naive instantiation or multi-inst
00894       TRACE("sendinst","gterm",gterm,"");
00895       if(partInst) {
00896   thm = d_rules->partialUniversalInst(univ, bind, 0);
00897       }
00898       else{
00899   //thm = d_rules->universalInst(univ, bind, 0);
00900   thm = d_rules->universalInst(univ, bind, 0, gterm);
00901       }
00902     }
00903     else{
00904       int gscore = theoryCore()->getQuantLevelForTerm(gterm);
00905             /*
00906   if(gscore > max_score){
00907   max_score = gscore;
00908   cout<<"max score "<<max_score<<endl;
00909   }
00910       */
00911       if(partInst) {
00912   thm = d_rules->partialUniversalInst(univ, bind, gscore);
00913       }
00914       else{
00915   //  thm = d_rules->universalInst(univ, bind, gscore);
00916   thm = d_rules->universalInst(univ, bind, gscore, gterm);
00917       }
00918     }
00919   }
00920 
00921   d_totalInstCount++;
00922   d_totalThmCount[thm.getExpr()]++;
00923   Theorem simpThm = simplify(thm.getExpr());
00924 
00925   if(*d_useInstTrue){
00926     Expr res = simpThm.getRHS();
00927     if(res.isTrue()){
00928       d_trueInstCount++;
00929       
00930 //        cout<<"return because true"<<endl;
00931 //        cout<<"true thm expr: " <<thm.getExpr()<<endl;
00932 //        cout<<"true thm: " <<thm<<endl;
00933       
00934 //        cout<<"return inst 2"<<endl;
00935       return;
00936     }
00937     if(res.isFalse() ){
00938       d_thmCount[thm.getExpr()]++;
00939       //      if(*d_useGFact || d_totalThmCount[thm.getExpr()] > *d_gfactLimit ){
00940 
00941       if(*d_useGFact || d_thmCount[thm.getExpr()] > *d_gfactLimit ){
00942 
00943   //      if(*d_useGFact){
00944   //  addGlobalLemma(thm, -1);
00945   enqueueFact(thm);
00946       }
00947       else{
00948   enqueueFact(thm);
00949       }
00950       //      enqueueSE(thm);
00951       //
00952       //      setInconsistent(simpThm);
00953       d_allInstCount++;
00954       d_instThisRound++;
00955       //      cout<<"false found 2"<<endl;
00956       /*
00957       if (*d_useInstGCache){
00958   sendInstNew();
00959       }
00960       */
00961       //      cout<<"return inst 3"<<endl;
00962       throw FOUND_FALSE;
00963     }
00964   }
00965 
00966   d_simplifiedThmQueue.push(thm);
00967   d_gUnivQueue.push(univ);
00968   d_gBindQueue.push(bind_expr);
00969 
00970   //  cout<<"enqueue inst"<<thm << endl;
00971   TRACE("quant sendinst", "=gterm: ",gterm, "");
00972   /*
00973   if(true || 0 == theoryCore()->getQuantLevelForTerm(gterm)){
00974     cout<<"gterm" << gterm <<endl;;
00975     cout<<"IL=== "<<theoryCore()->getQuantLevelForTerm(gterm)<<endl;;
00976   }
00977   */
00978   
00979   //  cout << "gterm: " <<  gterm << endl;
00980   TRACE("quant sendinst", "= add fact simp: ", simplifyExpr(thm.getExpr()), "");
00981   TRACE("quant sendinst", "= add fact org: ", thm.getExpr(), "");
00982   TRACE("quant sendinst", "= add fact from:  ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
00983   TRACE("quant sendinst", "= end === ", "=========", "============");
00984 }
00985 
00986 
00987 void TheoryQuant::enqueueInst(const Theorem& univ, Trigger& trig,  const std::vector<Expr>& binds,  const Expr& gterm) {
00988   return enqueueInst(univ,binds,gterm);
00989 }
00990 
00991 int TheoryQuant::sendInstNew(){
00992   int resNum = 0 ;
00993 
00994   while(!d_simplifiedThmQueue.empty()){
00995     const Theorem thm = d_simplifiedThmQueue.front();
00996     d_simplifiedThmQueue.pop();
00997 
00998     d_allInstCount++;
00999     d_instThisRound++;
01000     resNum++;
01001     if (*d_useInstGCache){
01002       const Theorem & univ = d_gUnivQueue.front();
01003       const Expr & bind = d_gBindQueue.front();
01004 
01005       const Expr& e = univ.getExpr();
01006       ExprMap<std::hash_map<Expr,bool>*>::iterator iterCache = d_bindGlobalHistory.find(e);
01007       if (iterCache != d_bindGlobalHistory.end()){
01008   std::hash_map<Expr,bool>* cache = (*iterCache).second;
01009   (*cache)[bind] = true;
01010       }
01011       else{
01012   std::hash_map<Expr,bool>* new_cache = new std::hash_map<Expr,bool> ;
01013   (*new_cache)[bind] = true;
01014   d_bindGlobalHistory[e] = new_cache;
01015       }
01016     }
01017     d_thmCount[thm.getExpr()]++;
01018     //    if(*d_useGFact || d_totalThmCount[thm.getExpr()] > *d_gfactLimit ){
01019     if(*d_useGFact || d_thmCount[thm.getExpr()] > *d_gfactLimit ){
01020       //      addGlobalLemma(thm, -1);
01021       enqueueFact(thm);
01022     }
01023     else{
01024       enqueueFact(thm);
01025     }
01026     //    enqueueSE(thm);
01027     //
01028   }
01029 
01030   return resNum;
01031 }
01032 
01033 void TheoryQuant::addNotify(const Expr& e){}
01034 
01035 int recursiveExprScore(const Expr& e) {
01036   int res=0;
01037   DebugAssert(!(e.isClosure()), "exprScore called on closure");
01038 
01039   if(e.arity()== 0){
01040     res = 0;
01041   }
01042   else{
01043     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)  {
01044       res += recursiveExprScore(*i);
01045     }
01046   }
01047   res++;
01048   return res;
01049 }
01050 
01051 
01052 int exprScore(const Expr& e){
01053   return recursiveExprScore(e);
01054 }
01055 
01056 Expr TheoryQuant::getHeadExpr(const Expr& e){
01057   if (e.getKind() == APPLY){
01058     return e.getOp().getExpr();
01059   }
01060 
01061   if ( READ == e.getKind() ){
01062     return defaultReadExpr;
01063   }
01064   if ( WRITE == e.getKind() ){
01065     return defaultWriteExpr;
01066   }
01067   if (isPlus(e)){
01068     return defaultPlusExpr;
01069   }
01070   if (isMinus(e)){
01071     return defaultMinusExpr;
01072   }
01073   if (isMult(e)){
01074     return defaultMultExpr;
01075   }
01076   if (isDivide(e)){
01077     return defaultDivideExpr;
01078   }
01079   if (isPow(e)){
01080     return defaultPowExpr;
01081   }
01082 
01083 //   if ( READ == e.getKind() || WRITE == e.getKind() )  {
01084 //     int kind = e[0].getKind();
01085 //     if (UCONST==kind) {
01086 //       return e[0];
01087 //     }
01088 //     else if (APPLY==kind || UFUNC == kind || READ == kind || WRITE == kind){
01089 //       return getHeadExpr(e[0]);
01090 //     }
01091 //     else if(e[0].isSkolem()){
01092 //       return e[0];
01093 //     }
01094 //   }
01095 
01096   return null_expr;
01097 }
01098 
01099 Expr  TheoryQuant::getHead(const Expr& e) {
01100   return getHeadExpr(e);
01101 }
01102 
01103 //! get the bound vars in term e,
01104 static bool recursiveGetBoundVars(const Expr& e, std::set<Expr>& result) {
01105   bool res(false);
01106   if(e.getFlag()){
01107     return e.containsBoundVar();
01108   }
01109   else if(e.isClosure()){
01110     res = recursiveGetBoundVars(e.getBody(),result);
01111   }
01112   else if (BOUND_VAR == e.getKind() ){
01113     result.insert(e);
01114     e.setContainsBoundVar();
01115     res = true;
01116   }
01117   else {
01118     res = false;
01119     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i){
01120       if(recursiveGetBoundVars(*i,result)){
01121   res = true;
01122       }
01123     }
01124   }
01125 
01126   e.setFlag();
01127 
01128   if(res) {
01129     e.setContainsBoundVar();
01130   }
01131 
01132   return res;
01133 }
01134 
01135 
01136 //! get bound vars in term e,
01137 std::set<Expr>  getBoundVars(const Expr& e){
01138 
01139   //  static ExprMap<std::set<Expr> > bvsCache;
01140 
01141   //  static std::map<Expr, std::set<Expr> > bvsCache;
01142   //  std::map<Expr, std::set<Expr> >::iterator iterCache = bvsCache.find(e);
01143 
01144   //ExprMap<std::set<Expr> >::iterator iterCache = bvsCache.find(e);
01145 
01146   //  if (iterCache != bvsCache.end()){
01147   //    //    return iterCache->second;
01148   //    return (*iterCache).second;
01149   //  }
01150 
01151   e.clearFlags();
01152   std::set<Expr> result ;
01153   recursiveGetBoundVars(e,result);
01154   e.clearFlags();
01155   //  bvsCache[e]=result;
01156   return  result;
01157 }
01158 
01159 void findPolarity(const Expr& e, ExprMap<Polarity>& res, Polarity  pol){
01160   if(!e.getType().isBool()) return;
01161   //now a AND b will be given a polarity too, this is not necessary.
01162   if(res.count(e)>0){
01163     if ((Neg == res[e] && Pos == pol) || (Neg == res[e] && Pos == pol) ){
01164       res[e]=PosNeg;
01165     }
01166   }
01167   else{
01168     res[e]=pol;
01169   }
01170 
01171   TRACE("find-polarity", e, "has ", (int)pol);
01172  
01173   if(PosNeg==pol){
01174     for(int i=0; i<e.arity(); i++){
01175       findPolarity(e[i], res, pol);
01176     }
01177   }
01178   else{
01179     Polarity neg_pol=Ukn;
01180     if(Pos == pol) {
01181       neg_pol = Neg;
01182     }
01183     else if(Neg == pol){
01184       neg_pol = Pos;
01185     }
01186 
01187     if(e.isImpl()){
01188       findPolarity(e[0], res, neg_pol);
01189       findPolarity(e[1], res, pol);
01190     }
01191     else if(e.isAnd() || e.isOr()){
01192       for(int i=0; i<e.arity(); i++){
01193   findPolarity(e[i], res, pol);
01194       }
01195     }
01196     else if(e.isNot()){
01197       findPolarity(e[0], res, neg_pol);
01198     }
01199     else if(e.isITE()){
01200       findPolarity(e[0], res, PosNeg);
01201       findPolarity(e[1], res, pol);
01202       findPolarity(e[2], res, pol);
01203     }
01204     else if(e.isClosure()){
01205       findPolarity(e.getBody(), res, pol);
01206     }
01207     else if(e.isIff()){
01208       findPolarity(e[0], res, PosNeg);
01209       findPolarity(e[1], res, PosNeg);
01210     }
01211     else if(e.isXor()){
01212       findPolarity(e[0], res, neg_pol);
01213       findPolarity(e[1], res, neg_pol);
01214     }
01215     else if(e.isAtomicFormula()){
01216       return;
01217     }
01218     else{
01219       //      DebugAssert(false, "Error in find polarity in "+e.toString());
01220     }
01221   }
01222 }
01223 
01224 bool isUniterpFunc(const Expr & e){
01225   if ( e.isApply() && e.getOpKind() == UFUNC){
01226     return true;
01227   }
01228   return false;
01229 }
01230 //   if (e.getKind() == READ || e.getKind() == WRITE){
01231 //     return true;
01232 //   }
01233 //   return false;
01234 // }
01235 
01236 bool isGround(const Expr& e){
01237   //be careful, this function must be called after some calls to getBoundVar() because containsBoundVar() will be set only in getBoundVar() method.
01238   //if e contains a closed quantifier, e is not ground. 
01239   return ! e.containsBoundVar();
01240 }
01241 
01242 Expr CompleteInstPreProcessor::pullVarOut(const Expr& thm_expr){
01243 
01244   const Expr outBody = thm_expr.getBody();
01245 
01246 //   if(((outBody.isAnd() && outBody[1].isForall()) ||
01247 //        (outBody.isImpl() && outBody[1].isForall()) ||
01248 //        (outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists()) )){
01249 //     return t1;
01250 //   }
01251 
01252   if (thm_expr.isForall()){
01253     if((outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists())){
01254       
01255       vector<Expr> bVarsOut = thm_expr.getVars();
01256       
01257       const Expr innerExists =outBody[0][1];
01258       const Expr innerBody = innerExists.getBody();
01259       vector<Expr> bVarsIn = innerExists.getVars();
01260       
01261       for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){
01262   bVarsOut.push_back(*i);
01263       }
01264       
01265       Expr newbody;
01266       
01267       newbody=(outBody[0][0].notExpr()).orExpr(innerBody.notExpr());
01268       
01269       Expr newQuantExpr;
01270       newQuantExpr = d_theoryCore->getEM()->newClosureExpr(FORALL, bVarsOut, newbody);
01271       
01272       return newQuantExpr ;
01273     }
01274     
01275     else if ((outBody.isAnd() && outBody[1].isForall()) ||
01276        (outBody.isImpl() && outBody[1].isForall())){
01277       
01278       vector<Expr> bVarsOut = thm_expr.getVars();
01279       
01280       const Expr innerForall=outBody[1];
01281       const Expr innerBody = innerForall.getBody();
01282       vector<Expr> bVarsIn = innerForall.getVars();
01283       
01284       for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){
01285   bVarsOut.push_back(*i);
01286       }
01287       
01288       
01289       Expr newbody;
01290       if(outBody.isAnd()){
01291   newbody=outBody[0].andExpr(innerBody);
01292       }
01293       else if(outBody.isImpl()){
01294   newbody=outBody[0].impExpr(innerBody);
01295       }
01296       
01297       Expr newQuantExpr;
01298       newQuantExpr = d_theoryCore->getEM()->newClosureExpr(FORALL, bVarsOut, newbody);
01299       
01300       return(newQuantExpr);
01301     }
01302     return thm_expr; // case cannot be handled now. 
01303   }
01304   
01305   else if (thm_expr.isExists()){
01306     if ((outBody.isAnd() && outBody[1].isExists()) ||
01307   (outBody.isImpl() && outBody[1].isExists())){
01308       
01309       vector<Expr> bVarsOut = thm_expr.getVars();
01310       
01311       const Expr innerExists = outBody[1];
01312       const Expr innerBody = innerExists.getBody();
01313       vector<Expr> bVarsIn = innerExists.getVars();
01314       
01315       for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){
01316   bVarsOut.push_back(*i);
01317       }
01318       
01319       Expr newbody;
01320       if(outBody.isAnd()){
01321   newbody=outBody[0].andExpr(innerBody);
01322       }
01323       else if(outBody.isImpl()){
01324   newbody=outBody[0].impExpr(innerBody);
01325       }
01326       
01327       Expr newQuantExpr;
01328       newQuantExpr = d_theoryCore->getEM()->newClosureExpr(EXISTS, bVarsOut, newbody);
01329       
01330       return newQuantExpr;
01331     }
01332   }
01333   return thm_expr; 
01334 }
01335 
01336 
01337 CompleteInstPreProcessor::CompleteInstPreProcessor(TheoryCore * core, QuantProofRules* quant_rule):
01338   d_theoryCore(core),
01339   d_quant_rules(quant_rule)
01340 {}
01341 
01342 // collect all uninterpreted pedidates in assert
01343 void CompleteInstPreProcessor::collectHeads(const Expr& assert, set<Expr>& heads){
01344   if ( ! assert.getType().isBool()){
01345     return;
01346   }
01347   else if ( ! assert.isAbsAtomicFormula()){
01348     for (int i = 0 ; i < assert.arity(); i++){
01349       collectHeads(assert[i], heads);    
01350     }
01351     return;
01352   }
01353   else if (assert.isClosure()){
01354     collectHeads(assert.getBody(), heads);    
01355   }
01356   else if (assert.isAtomicFormula()){
01357     if (isUniterpFunc(assert)){
01358       heads.insert(assert.getOp().getExpr());
01359     }
01360   }
01361   else{
01362     //    cout << " error in collect heads" << endl;
01363   }
01364 }
01365 
01366 bool CompleteInstPreProcessor::isMacro(const Expr& assert){
01367   if (d_is_macro_def.count(assert) > 0 ) {
01368     return true;
01369   }
01370 
01371   if (assert.isForall()){
01372     Expr body = assert.getBody();
01373     if (body.isIff()){
01374       Expr right = body[0];
01375       Expr left = body[1];
01376       if ((isUniterpFunc(right) && left.isForall())
01377     || (right.isForall() && isUniterpFunc(left) )){
01378       Expr macro_lhs ;
01379       Expr macro_def;
01380       if (isUniterpFunc(right)){
01381         macro_lhs = right;
01382         macro_def = left;
01383       }
01384       else{
01385         macro_lhs = left;
01386         macro_def = right;
01387       }
01388       
01389       Expr test_def_exists = d_theoryCore->getEM()->newClosureExpr(EXISTS, assert.getVars(), macro_def);
01390       
01391       Expr test_def_sko = d_theoryCore->getCommonRules()->skolemize(test_def_exists);
01392 
01393       if (isGoodQuant(test_def_sko)){
01394         Expr macro_head = macro_lhs.getOp().getExpr();
01395         set<Expr> heads_set;
01396         collectHeads(macro_def, heads_set);
01397         if (heads_set.count(macro_head) <= 0 ){
01398     d_is_macro_def[assert] = true;
01399     d_macro_quant[macro_head] = assert;
01400     d_macro_def[macro_head] = macro_def;
01401     d_macro_lhs[macro_head] = macro_lhs;
01402     return true;
01403         }
01404       }
01405       else {
01406         //     cout << "NOT good DEF" << def<< endl;
01407       }
01408       }
01409     }
01410   }
01411   return false;
01412 }
01413 
01414 bool CompleteInstPreProcessor::hasMacros(const vector<Expr>& asserts){
01415   bool has_macros = false;
01416   for (size_t i = 0 ; i < asserts.size(); i++){
01417     if (isMacro(asserts[i])){
01418       has_macros = true;
01419     }
01420   }
01421   return has_macros;
01422 }
01423 
01424 
01425 Expr CompleteInstPreProcessor::substMacro(const Expr& old){
01426   Expr head = old.getOp().getExpr();
01427   
01428   DebugAssert(d_macro_lhs.count(head)>0, "macro lhs not found");
01429   DebugAssert(d_macro_def.count(head)>0, "macro def not found");
01430   DebugAssert(d_macro_quant.count(head)>0, "macro quant not found");
01431 
01432   Expr macro_lhs = d_macro_lhs[head];
01433   Expr macro_def = d_macro_def[head];
01434   Expr macro_quant = d_macro_quant[head];
01435 
01436   DebugAssert(head == macro_lhs.getOp().getExpr(), "impossible in substMacro");
01437   
01438   ExprMap<Expr> binding;
01439   for (int i = 0; i < macro_lhs.arity(); i++){
01440     if (macro_lhs[i].isBoundVar()){
01441       binding[macro_lhs[i]] = old[i];
01442     }
01443   }
01444   
01445   vector<Expr> quant_vars = macro_quant.getVars();
01446   
01447   vector<Expr> gterms;
01448   for (size_t i = 0 ; i < binding.size(); i++){
01449     gterms.push_back(binding[quant_vars[i]]);
01450   }
01451   
01452   return macro_def.substExpr(quant_vars,gterms);
01453 }
01454 
01455 Expr CompleteInstPreProcessor::simplifyEq(const Expr& assert){
01456   if ( ! assert.getType().isBool()){
01457     return assert;
01458   }
01459   else if ( ! assert.isAbsAtomicFormula()){
01460     vector<Expr> children ;
01461     for (int i = 0 ; i < assert.arity(); i++){
01462       children.push_back(simplifyEq(assert[i]));
01463     }
01464     return Expr(assert.getOp(),children);
01465   }
01466   else if (assert.isClosure()){
01467     Expr new_body = simplifyEq(assert.getBody());
01468     if (assert.isForall()){
01469       d_theoryCore->getEM()->newClosureExpr(FORALL, assert.getVars(), new_body);    
01470     }
01471     else if (assert.isExists()){
01472       d_theoryCore->getEM()->newClosureExpr(EXISTS, assert.getVars(), new_body);    
01473     }
01474     else{
01475       DebugAssert(false, "impossible case in recInstMacros");
01476     }
01477   }
01478   else if (assert.isAtomicFormula()){
01479     if (assert.isEq() && assert[0] == assert[1]){
01480       return d_theoryCore->trueExpr();
01481     }
01482     else {
01483       return assert;
01484     }
01485   }
01486   cout <<assert<<endl;
01487   DebugAssert(false, "impossible case in simplifyEq");
01488   return assert;
01489 }
01490 
01491 
01492 Expr CompleteInstPreProcessor::recInstMacros(const Expr& assert){
01493   if ( ! assert.getType().isBool()){
01494     return assert;
01495   }
01496   else if ( ! assert.isAbsAtomicFormula()){
01497     vector<Expr> children ;
01498     for (int i = 0 ; i < assert.arity(); i++){
01499       children.push_back(recInstMacros(assert[i]));
01500     }
01501     return Expr(assert.getOp(),children);
01502   }
01503   else if (assert.isClosure()){
01504     Expr new_body = recInstMacros(assert.getBody());
01505     if (assert.isForall()){
01506       d_theoryCore->getEM()->newClosureExpr(FORALL, assert.getVars(), new_body);    
01507     }
01508     else if (assert.isExists()){
01509       d_theoryCore->getEM()->newClosureExpr(EXISTS, assert.getVars(), new_body);    
01510     }
01511     else{
01512       DebugAssert(false, "impossible case in recInstMacros");
01513     }
01514   }
01515   else if (assert.isAtomicFormula()){
01516 
01517     if (isUniterpFunc(assert)){
01518       Expr assert_op = assert.getOp().getExpr();
01519       if ( d_macro_def.count(assert_op) > 0 ){
01520   return substMacro(assert);
01521       }
01522       else{
01523   return assert;
01524       }
01525     }
01526     else {
01527       return assert;
01528     }
01529   }
01530 
01531   DebugAssert(false, "impossible case in recInstMacors");
01532   return assert;
01533 
01534 }
01535 
01536 // if assert is a macro quant, then replace it with macro_quant_sub
01537 Expr CompleteInstPreProcessor::instMacros(const Expr& assert, const Expr macro_quant_sub ){
01538 
01539   if (isMacro(assert)){
01540     return macro_quant_sub;
01541   }
01542   
01543   return recInstMacros(assert);
01544 }
01545 
01546 //if bound vars only appear as argument of uninterpreted function/predidate and array reads/writes. 
01547 bool CompleteInstPreProcessor::isShield(const Expr& e){
01548   if (isGround(e)){
01549     return true;
01550   }
01551   else if (isUniterpFunc(e) && e.arity() > 0 ){
01552     for (int i = 0; i<e.arity(); i++){
01553       //      if ( ! ( isShield(e[i]) || e[i].isBoundVar())){
01554       if ( e[i].containsBoundVar() &&  ( ! e[i].isBoundVar() )){ //no nested   
01555   return false;
01556       }
01557     }
01558     return true;
01559   }
01560   else if (e.getKind() == READ){
01561     if ( isShield(e[0]) 
01562    //  && (e[1].isBoundVar()  || isShield(e[1])){
01563    && (e[1].isBoundVar() || isGround(e[1]))){
01564       return true;
01565     }
01566     else {
01567       return false;
01568     }
01569   }
01570   else if (e.getKind() == WRITE){
01571     if ( isShield( e[0] ) 
01572       //   && (e[1].isBoundVar() || isShield(e[1]))
01573    && (e[1].isBoundVar() || isGround( e[1] ))
01574    && ( isGround( e[2] ))){
01575       return true;
01576     }
01577     else {
01578       return false;
01579     }
01580   }
01581   else if (e.arity() > 0 ){
01582     for (int i = 0; i<e.arity(); i++){
01583       if (!isShield(e[i])){
01584   return false;
01585       }
01586     }
01587     return true;
01588   }
01589   else if (e.arity () == 0){
01590     return true;
01591   }
01592   DebugAssert(false, "impossible case in isShield");
01593   return false;
01594 }
01595 
01596 void findPolarityAtomic(const Expr& e, ExprMap<Polarity>& res, Polarity  pol){
01597   if(!e.getType().isBool()) return;
01598   //now a AND b will be given a polarity too, this is not necessary.
01599   if(res.count(e)>0){
01600     if ((Neg == res[e] && Pos == pol) || (Neg == res[e] && Pos == pol) ){
01601       res[e]=PosNeg;
01602     }
01603   }
01604   else{
01605     res[e]=pol;
01606   }
01607 
01608   //  cout <<"finding " << e << endl;
01609 
01610   if(PosNeg == pol){
01611     for(int i=0; i<e.arity(); i++){
01612       findPolarityAtomic(e[i], res, pol);
01613     }
01614   }
01615   else{
01616     Polarity neg_pol=Ukn;
01617     if(Pos == pol) {
01618       neg_pol = Neg;
01619     }
01620     else if(Neg == pol){
01621       neg_pol = Pos;
01622     }
01623 
01624     if(e.isImpl()){
01625       findPolarityAtomic(e[0], res, neg_pol);
01626       findPolarityAtomic(e[1], res, pol);
01627     }
01628     else if(e.isAnd() || e.isOr()){
01629       for(int i=0; i<e.arity(); i++){
01630   findPolarityAtomic(e[i], res, pol);
01631       }
01632     }
01633     else if(e.isNot()){
01634       findPolarityAtomic(e[0], res, neg_pol);
01635     }
01636     else if(e.isITE()){
01637       findPolarityAtomic(e[0], res, PosNeg);
01638       findPolarityAtomic(e[1], res, pol);
01639       findPolarityAtomic(e[2], res, pol);
01640     }
01641     else if(e.isClosure()){
01642       //      cout << " found closure " << endl;
01643       //      cout << e << endl;
01644       //findPolarityAtomic(e.getBody(), res, pol);
01645     }
01646     else if(e.isIff()){
01647       findPolarityAtomic(e[0], res, PosNeg);
01648       findPolarityAtomic(e[1], res, PosNeg);
01649     }
01650     else if(e.isXor()){
01651       findPolarityAtomic(e[0], res, neg_pol);
01652       findPolarityAtomic(e[1], res, neg_pol);
01653     }
01654     else if(e.isAtomicFormula()){
01655       return;
01656     }
01657     else{
01658       DebugAssert(false, "Error in find polarity in "+e.toString());
01659     }
01660   }
01661 }
01662 
01663 Expr CompleteInstPreProcessor::recSkolemize(const Expr& e, ExprMap<Polarity>& pol_map){
01664 
01665   if ( ! e.getType().isBool()){
01666     return e;
01667   }
01668   else if (e.isClosure()){
01669     if (e.isForall()) {
01670       return e;
01671     } 
01672     else if (e.isExists() && Pos == pol_map[e]){
01673       Expr new_body = recSkolemize(e.getBody(), pol_map);
01674       Expr new_quant = d_theoryCore->getEM()->newClosureExpr(EXISTS, e.getVars(), new_body);
01675       return d_theoryCore->getCommonRules()->skolemize(new_quant);
01676     }
01677   }
01678   else if (e.arity() > 0 ) {
01679     vector<Expr> children; 
01680     for (int i = 0 ; i < e.arity(); i++){
01681       Expr new_child = recSkolemize(e[i], pol_map);
01682       if (new_child.isNot() && new_child[0].isNot()){
01683   children.push_back(new_child[0][0]); //(not not expr) --> expr 
01684       }
01685       else{
01686   children.push_back(new_child);
01687       }
01688     }
01689     Expr new_expr = Expr(e.getOp(), children);
01690     if (new_expr.isNot() && new_expr[0].isNot()){
01691       return new_expr[0][0];
01692     }
01693     else {
01694       return new_expr;
01695     }
01696   }
01697 
01698   return e;
01699 }
01700 
01701 Expr CompleteInstPreProcessor::simplifyQuant(const Expr& e){
01702   //put all quant into postive form
01703   Expr pos_expr = rewriteNot(e);
01704   TRACE("simp-quant", e , "\n ---rewriteNot---> \n", pos_expr);
01705 
01706   Expr next_expr;
01707   if(e.isForall()){
01708     Theorem atoa = d_theoryCore->getCommonRules()->assumpRule(pos_expr);
01709     Theorem packVarThm = d_quant_rules->packVar(atoa);
01710     next_expr = packVarThm.getExpr();
01711   }
01712   else{
01713     next_expr = pos_expr;
01714   }
01715   //skolemize all postive exists, because we only care for satisfiablility now. 
01716   ExprMap<Polarity> pol_map;
01717   //  findPolarity(pos_expr, pol_map, Pos);
01718   findPolarity(next_expr, pol_map, Pos);
01719   //  Expr ret = recSkolemize(pos_expr, pol_map);
01720   Expr ret = recSkolemize(next_expr, pol_map);
01721   TRACE("simp-quant", e , "\n ---skolemize---> \n", ret);
01722   return ret;
01723 }
01724 
01725 
01726 Expr CompleteInstPreProcessor::rewriteNot(const Expr& e){
01727   ExprMap<Polarity> pol_map;
01728   findPolarity(e, pol_map, Pos);
01729   set<Expr> t = getBoundVars(e); //set containsBoundVar flag
01730   return recRewriteNot(e, pol_map);
01731 }
01732 
01733 Expr CompleteInstPreProcessor::recRewriteNot(const Expr & e,  ExprMap<Polarity>& pol_map){
01734   if ( ! e.getType().isBool()){
01735     return e;
01736   }
01737 
01738   if (isGround(e)){
01739     return e;
01740   }
01741 
01742   if (e.isClosure()){
01743     DebugAssert(pol_map.find(e) != pol_map.end(), "cannot find polarity" );
01744     if ( Neg == pol_map[e]){
01745       Expr body = recRewriteNot(e.getBody(), pol_map);
01746       Expr new_body = body.notExpr();
01747       Kind new_kind = e.isForall() ? EXISTS : FORALL;
01748       Expr new_quant = d_theoryCore->getEM()->newClosureExpr(new_kind,e.getVars(),new_body);
01749       Expr new_expr = new_quant.notExpr();
01750       return new_expr;
01751     }
01752     else { 
01753       //it is too much to deal with the case PosNeg == pol_map[e]
01754       //becasue PosNeg will be introduced for IFF and IF, 
01755       return e;
01756     }
01757   }
01758   else if (e.arity() > 0 ) {
01759     vector<Expr> children; 
01760     
01761     for (int i = 0 ; i < e.arity(); i++){
01762       Expr new_child = recRewriteNot(e[i], pol_map);
01763       if (new_child.isNot() && new_child[0].isNot()){
01764   children.push_back(new_child[0][0]); //(not not expr) --> expr 
01765       }
01766       else{
01767   children.push_back(new_child);
01768       }
01769     }
01770     
01771     Expr new_expr = Expr(e.getOp(), children);
01772     if (new_expr.isNot() && new_expr[0].isNot()){
01773       return new_expr[0][0];
01774     }
01775     else {
01776       return new_expr;
01777     }
01778   }
01779   else if (0 == e.arity() ){
01780     return e;
01781   }
01782 
01783   DebugAssert(false, "impossible in rewriteNot");
01784   return e;
01785 }
01786 
01787 void CompleteInstPreProcessor::addIndex(const Expr& e){
01788   if ( ! isInt(e.getType())) return;
01789   d_allIndex.insert(d_theoryCore->simplifyExpr(e));
01790 }
01791 
01792 Expr CompleteInstPreProcessor::plusOne(const Expr& e){
01793   Expr one = d_theoryCore->getEM()->newRatExpr(1);
01794   return Expr(PLUS, e, one);
01795 }
01796 
01797 Expr CompleteInstPreProcessor::minusOne(const Expr& e){
01798   Expr one = d_theoryCore->getEM()->newRatExpr(1);
01799   return Expr(MINUS, e, one);
01800 }
01801 
01802 void CompleteInstPreProcessor::collect_shield_index(const Expr& e){
01803   if (isUniterpFunc(e) && e.arity() > 0 ){
01804     for (int i = 0; i<e.arity(); i++){
01805       if ( isGround(e[i])){
01806   addIndex(e[i]);
01807       }
01808     }
01809   }
01810   else if (e.getKind() == READ){
01811     collect_shield_index(e[0]);
01812     if (isGround(e[1])){
01813       addIndex(e[1]);
01814     }
01815   }
01816   else if (e.getKind() == WRITE){
01817     collect_shield_index(e[0]);
01818     if ( isGround( e[1] )){
01819       addIndex(e[1]);
01820       addIndex(plusOne(e[1]));
01821       addIndex(minusOne(e[1]));
01822     }
01823   }
01824   else if (e.arity() > 0 ){
01825     for (int i = 0; i<e.arity(); i++){
01826       collect_shield_index(e[i]);
01827     }
01828   }
01829 }
01830 
01831 void CompleteInstPreProcessor::collect_forall_index(const Expr& forall_quant){
01832   ExprMap<Polarity> cur_expr_pol;
01833   findPolarity(forall_quant, cur_expr_pol, Pos);
01834   
01835   for (ExprMap<Polarity>::iterator i = cur_expr_pol.begin(), iend = cur_expr_pol.end(); i != iend ; i++){
01836     Expr cur_expr = i->first;
01837     Polarity pol = i->second; 
01838     
01839     if (isLE(cur_expr)){
01840       const Expr& left = cur_expr[0];
01841       const Expr& right = cur_expr[1];
01842       if (left.isBoundVar() && isGround(right)){
01843   if (Pos == pol || PosNeg == pol){
01844     addIndex(plusOne(right));
01845   }
01846   if (Neg == pol || PosNeg == pol){
01847     addIndex(right);
01848   }
01849       }
01850       else if (right.isBoundVar() && isGround(left)){
01851   if (Pos == pol || PosNeg == pol){
01852     addIndex(plusOne(left));
01853   }
01854   if (Neg == pol || PosNeg == pol){
01855     addIndex(left);
01856   }
01857       }
01858       else if (left.isBoundVar() && right.isBoundVar()){
01859   //do nothing
01860       }
01861       //well, neither left nor right is a bound var. 
01862       else if (isShield(left) && isShield(right)){
01863   collect_shield_index(left);
01864   collect_shield_index(right);
01865       }
01866       else{
01867   cout << " foall is " << forall_quant << endl; 
01868   DebugAssert(false, "impossible case in collect index ");
01869       } 
01870     }
01871     else if (cur_expr.isEq()){
01872       const Expr& left = cur_expr[0];
01873       const Expr& right = cur_expr[1];
01874       if (left.isBoundVar() && isGround(right)){
01875   if (Pos == pol || PosNeg == pol){
01876     addIndex(minusOne(right));
01877     addIndex(plusOne(right));
01878   }
01879   if (Neg == pol || PosNeg == pol){
01880     addIndex(minusOne(right));
01881   }
01882       }
01883       else if (right.isBoundVar() && isGround(left)){
01884   if (Pos == pol || PosNeg == pol){
01885     addIndex(minusOne(left));
01886     addIndex(plusOne(left));
01887   }
01888   if (Neg == pol || PosNeg == pol){
01889     addIndex(left);
01890   }
01891       }
01892       else if (left.isBoundVar() && right.isBoundVar()){
01893   DebugAssert(false, "impossible case collect index");
01894       }
01895       //well, neither left nor right is a bound var. 
01896       else if (isShield(left) && isShield(right)){
01897   collect_shield_index(left);
01898   collect_shield_index(right);
01899       }
01900       else{
01901   DebugAssert(false, "impossible case in collect index");
01902       } 
01903     }
01904     else if (isLT(cur_expr)){
01905       const Expr& left = cur_expr[0];
01906       const Expr& right = cur_expr[1];
01907       if (left.isBoundVar() && isGround(right)){
01908   if (Pos == pol || PosNeg == pol){
01909     addIndex(plusOne(right));
01910   }
01911   if (Neg == pol || PosNeg == pol){
01912     addIndex(right);
01913   }
01914       }
01915       else if (right.isBoundVar() && isGround(left)){
01916   if (Pos == pol || PosNeg == pol){
01917     addIndex(plusOne(left));
01918   }
01919   if (Neg == pol || PosNeg == pol){
01920     addIndex(left);
01921   }
01922       }
01923       else if (left.isBoundVar() && right.isBoundVar()){
01924   //do nothing
01925       }
01926       //well, neither left nor right is a bound var. 
01927       else if (isShield(left) && isShield(right)){
01928   collect_shield_index(left);
01929   collect_shield_index(right);
01930       }
01931       else{
01932   DebugAssert(false,  "impossible case in collect index");
01933       } 
01934     }
01935     else{
01936       collect_shield_index(cur_expr);
01937     }
01938   }
01939 }
01940 
01941 
01942 void CompleteInstPreProcessor::collectIndex(const Expr& assert){
01943   //  cout <<"BEGIN COLLECTING " << assert << endl;        
01944   //must be called after isGoodForCompleteInst;
01945   if(isGround(assert)){
01946     collect_shield_index(assert);
01947     return;
01948   }
01949   
01950 
01951   ExprMap<Polarity> cur_expr_pol;
01952   findPolarityAtomic(assert, cur_expr_pol, Pos);
01953   
01954   for(ExprMap<Polarity>::iterator i = cur_expr_pol.begin(), iend = cur_expr_pol.end(); i != iend; i++) {
01955 
01956     const Expr& cur_expr = i->first;
01957     Polarity pol = i->second;
01958     //    cout <<"NOW COLLECTING " << cur_expr << endl;        
01959     if (cur_expr.isAtomicFormula()){
01960       if (cur_expr.containsBoundVar()){
01961   DebugAssert(false, "error in collecting ");
01962   return;
01963       }
01964       collect_shield_index(cur_expr);
01965     }
01966     else if (cur_expr.isForall()){
01967       if (Pos != pol){
01968   DebugAssert(false, "error in polarity ");
01969   return;
01970       }
01971       Expr newQuant = pullVarOut(cur_expr);
01972       collect_forall_index(newQuant);
01973       //      cout <<"PUSH FORALL" << cur_expr << endl;
01974       d_quant_equiv_map[cur_expr] = newQuant;
01975     }
01976     else if (cur_expr.isExists()){
01977       if (Pos != pol){
01978   DebugAssert(false, "error in polarity " );
01979   return;
01980       }
01981       Expr newQuant = pullVarOut(cur_expr);
01982       Expr sko_expr = d_theoryCore->getCommonRules()->skolemize(newQuant);
01983       collect_forall_index(sko_expr);
01984       //      cout <<"PUSH EXISTS" << cur_expr << endl;
01985       d_quant_equiv_map[cur_expr] = sko_expr;
01986     }
01987   }   
01988   return;
01989 }
01990 
01991 
01992 bool CompleteInstPreProcessor::isGood(const Expr& assert){
01993   //  cout << " in isgood " << assert << endl;
01994   const std::set<Expr>& bvs = getBoundVars(assert);
01995   if (bvs.size() <= 0 ) {
01996     //    d_gnd_cache.push_back(e);
01997     //    cout << " return in isgood because no bound vars" << assert << endl;
01998     return true; //this is a ground formula, 
01999   }
02000 
02001   ExprMap<Polarity> cur_expr_pol;
02002   findPolarityAtomic(assert, cur_expr_pol, Pos);
02003 
02004   for(ExprMap<Polarity>::iterator i = cur_expr_pol.begin(),
02005   iend = cur_expr_pol.end();
02006       i != iend; i++) {
02007     
02008     const Expr& cur_expr = i->first;
02009     Polarity pol = i->second;
02010     
02011     //    cout <<"isgood cur expr " << cur_expr << endl;
02012 
02013     if(cur_expr.isForall()) {
02014       if (Pos == pol){
02015   if( isGoodQuant(cur_expr)){
02016   }
02017   else{
02018     d_all_good = false;
02019     return false;
02020   }
02021       }
02022       else {
02023   DebugAssert(false, "error, Neg polarity in isGood ");
02024   return false;
02025       }
02026     }
02027     else if (cur_expr.isExists()){
02028       DebugAssert(false, "error, found exists in is good");
02029       if (Neg == pol || PosNeg == pol){
02030   DebugAssert(false, "error, neg polarity in isGood ");
02031   return false;
02032       }
02033     }
02034   }
02035   return true;
02036 }   
02037  
02038     //    if (cur_expr.isClosure()){ 
02039       
02040 //       if( Pos == pol){
02041 //  Theorem newQuant;
02042 //  newQuant = (d_rules->pullVarOut(d_rules->addNewConst(cur_expr))).getExpr();
02043 //  if (cur_expr.isExists()){
02044 //    Expr t = getCommonRules()->skolemize(newQuant);
02045 //    d_quant_equiv_map[cur_expr] = t;
02046 //    d_gnd_cache.push_Back(t); //used later by isGoodQuant and collectIndex
02047 //  }
02048 //  else if (cur_expr.isForall()){
02049 
02050 //    if( isGoodQuantCompleteInst()){
02051 //      d_quant_equiv_map[cur_expr] = newQuant;
02052 //    }
02053 //    else{
02054 //      d_all_good = false;
02055 //      return false;
02056 //    }
02057 //  }
02058 //       }
02059 //       else{
02060 //  cout << "cannot deal with neg polarity now " << endl;
02061 //       }
02062 //     }
02063 //     else if (cur_expr.isAtomicFormula()){
02064 //       findPolarity(cur_expr, d_expr_pol, Pos); //used later by isGoodQuant and collectIndex
02065 //     }
02066 //   }
02067 //  return true;
02068 //}
02069 
02070 bool CompleteInstPreProcessor::isGoodQuant(const Expr& e){
02071   //  cout << " test is good quant" << endl;
02072   //  const std::set<Expr>& bvs = getBoundVars(e);
02073 
02074   //  if (bvs.size() <= 0 ) {
02075   //    return true; //this is a ground formula, 
02076   //  }
02077 
02078   //  if (e.getVars().size() != bvs.size()){
02079   //    return false; // we can do more on this case later.
02080   //  }
02081   
02082   vector<Expr> bvs = e.getVars();
02083   
02084   for (vector<Expr>::iterator i = bvs.begin(), iend = bvs.end(); i != iend; i++){
02085     if ( ! isInt(i->getType() ) ){
02086       return false; //now only inteter can be handled
02087     }
02088   }
02089 
02090 //   if (e.isExists()){
02091 //     return true;
02092 //   }
02093 
02094 //  findPolarity(newQuant, d_expr_pol, Pos); //used later by isGoodQuant and collectIndex  
02095   ExprMap<Polarity> body_pol ;
02096   findPolarity(e, body_pol, Pos);
02097 
02098   for(ExprMap<Polarity>::iterator i = body_pol.begin(), iend = body_pol.end(); i != iend; i++) {
02099     if ((i->first).isAtomicFormula()){
02100       const Expr& cur_expr = i->first;
02101       Polarity pol = i->second;
02102 
02103       //      cout <<" good " << cur_expr << endl;
02104       if (!cur_expr.containsBoundVar()){
02105   continue; // this is a ground term, no need to do anything
02106       }
02107       else if (isShield(cur_expr)){
02108   continue; // this is good 
02109       }
02110       else if (isLE(cur_expr) || isLT(cur_expr) || cur_expr.isEq()){
02111   const Expr& left = cur_expr[0];
02112   const Expr& right = cur_expr[1];
02113   if (left.isBoundVar() && !right.containsBoundVar()){
02114     continue; //good case
02115   }
02116   else if (right.isBoundVar() && !left.containsBoundVar()){
02117     continue;
02118   }
02119   else if (left.isBoundVar() && right.isBoundVar()){
02120     if (Neg == pol && isLE(cur_expr)){
02121       continue;
02122     }
02123   }
02124   //well, neither left nor right is a bound var. 
02125   else if (isShield(left) && isShield(right)){
02126     continue;
02127   }
02128   //  cout << "RETURN 1 " << cur_expr << endl;
02129   return false; 
02130       }
02131       else{
02132   //  cout << "RETURN 2 " << cur_expr << endl;
02133   return false;
02134       }
02135     }
02136   }   
02137   return true;
02138 }
02139 
02140 class recCompleteInster{
02141   const Expr& d_body;
02142   const std::vector<Expr>& d_bvs;
02143   std::vector<Expr> d_buff;
02144   const std::set<Expr>& d_all_index;
02145   Expr d_result;
02146   void inst_helper(int num_vars);
02147 public:
02148   recCompleteInster(const Expr&, const std::vector<Expr>&, std::set<Expr>& , Expr);
02149   Expr inst();
02150 };
02151 
02152 recCompleteInster::recCompleteInster(const Expr& body, const std::vector<Expr>& bvs, std::set<Expr>& all_index, Expr res): d_body(body),d_bvs(bvs), d_all_index(all_index),d_result(res){}
02153 
02154 Expr recCompleteInster::inst(){
02155   d_buff.resize(d_bvs.size());
02156   //  cout << "there are " << d_all_index.size() << " gterms" << endl;
02157   inst_helper(d_bvs.size());  
02158   return d_result;
02159 }
02160 
02161 void recCompleteInster::inst_helper(int num_vars){
02162   if (1 == num_vars){
02163     for (set<Expr>::const_iterator i = d_all_index.begin(), iend = d_all_index.end();  i != iend; i++ ){
02164       d_buff[num_vars-1] = *i;
02165       d_result = d_result.andExpr(d_body.substExpr(d_bvs,d_buff));
02166     }
02167   }
02168   else{
02169     for (set<Expr>::const_iterator i = d_all_index.begin(), iend = d_all_index.end();  i != iend; i++ ){
02170       d_buff[num_vars-1] = *i;
02171       inst_helper(num_vars-1);
02172     }
02173   }
02174 }
02175 
02176 Expr CompleteInstPreProcessor::inst(const Expr& assert){
02177   if(isGround(assert)){
02178     return assert;
02179   }
02180   else  if (assert.isExists()){
02181     DebugAssert(d_quant_equiv_map.count(assert) > 0,"assert not found" ) ;
02182     return d_quant_equiv_map[assert];
02183   }
02184   else if( ! assert.isForall()){
02185     if (assert.arity() > 0){
02186       vector<Expr> children;      
02187       for (int i = 0 ; i < assert.arity(); i++){
02188   Expr rep_child;
02189   rep_child = inst(assert[i]);
02190   children.push_back(rep_child);
02191       }
02192       return Expr(assert.getOp(), children);
02193     }
02194     else{
02195       DebugAssert(false, "error in inst");
02196       return assert;
02197     }
02198   }
02199   
02200   DebugAssert(assert.isForall(), "not a forall");
02201   DebugAssert(d_quant_equiv_map.count(assert) > 0, "assert not found" ) ;
02202   Expr forall = d_quant_equiv_map[assert];
02203 
02204   const vector<Expr>& bvs = forall.getVars(); 
02205   const Expr body = forall.getBody();
02206   vector<Expr> and_list;
02207 
02208   if(d_allIndex.size() == 0){
02209     addIndex(d_theoryCore->getEM()->newRatExpr(0));
02210   }
02211 
02212   if(bvs.size() == 1 ) {
02213     //    getBoundVars(body);
02214     for (set<Expr>::const_iterator i = d_allIndex.begin(), iend = d_allIndex.end(); 
02215    i != iend; i++ ){
02216       vector<Expr> inst_st;
02217      
02218       inst_st.push_back(*i);
02219 
02220 //       if(body.substExprQuant(bvs,inst_st) != body.substExpr(bvs,inst_st)){
02221 //  cout << "old " << body.substExpr(bvs,inst_st) << endl ;
02222 //  cout << "new " << body.substExprQuant(bvs,inst_st) << endl; 
02223 //       }
02224   
02225       //and_list.push_back(body.substExprQuant(bvs,inst_st));
02226       and_list.push_back(body.substExpr(bvs,inst_st));
02227     }
02228     return Expr(AND,and_list);
02229   }
02230   else if (bvs.size() == 2 ){
02231     //    getBoundVars(body);
02232     for (set<Expr>::const_iterator i = d_allIndex.begin(), iend = d_allIndex.end(); 
02233    i != iend; i++ ){
02234       for (set<Expr>::const_iterator j = d_allIndex.begin(), jend = d_allIndex.end(); 
02235      j != jend; j++ ){
02236   vector<Expr> inst_st;
02237   inst_st.push_back(*i);
02238   inst_st.push_back(*j);
02239   
02240   //  cout << "== " << inst_st[0] << " " << inst_st[1] << endl;
02241 
02242 //  if(body.substExprQuant(bvs,inst_st) != body.substExpr(bvs,inst_st)){
02243 //    cout << "old " << body.substExpr(bvs,inst_st) << endl ;
02244 //    cout << "new " << body.substExprQuant(bvs,inst_st) << endl; 
02245 //  }
02246 
02247   //and_list.push_back(body.substExprQuant(bvs,inst_st));
02248   and_list.push_back(body.substExpr(bvs,inst_st));
02249   //  cout << "INST: " <<  body.substExpr(bvs,inst_st) << endl;
02250       }
02251     }
02252     //    cout << "we have " << and_list.size() << " ands " << endl;
02253     return Expr(AND,and_list);
02254   }
02255   //  else if ( 0 < bvs.size()  && bvs.size() <= 5 ){
02256   else{
02257     Expr init_expr = d_theoryCore->trueExpr();
02258     //    cout <<"we have " << bvs.size() << endl;
02259     recCompleteInster inster(body, bvs, d_allIndex, init_expr);
02260     //    cout<<inster.inst();
02261     return inster.inst();
02262   }
02263 //   else{
02264 //     DebugAssert(false, "More than five vars, too many.");
02265 //   }
02266   return assert;
02267 }
02268 
02269 void flatAnds(const Expr& ands, vector<Expr>& results){
02270   if (ands.isAnd()){
02271     for(Expr::iterator i=ands.begin(), iend=ands.end(); i!=iend; ++i)    {
02272       flatAnds(*i,results);
02273     }
02274   }
02275   else if (ands.isNot() && ands[0].isOr()){
02276     for(Expr::iterator i=ands[0].begin(), iend=ands[0].end(); i!=iend; ++i)    {
02277       if(i->isNot()){
02278   flatAnds((*i)[0], results);
02279       }
02280       else{
02281   flatAnds(i->notExpr(), results);
02282       }
02283     }
02284   }
02285   else{
02286     results.push_back(ands);
02287   }
02288 }
02289 
02290 Theorem TheoryQuant::theoryPreprocess(const Expr& e){
02291   //  cout<<"theory process " << e << endl;
02292 
02293   if ( ! theoryCore()->getFlags()["quant-complete-inst"].getBool()){
02294     return reflexivityRule(e);
02295   }
02296   
02297   const std::set<Expr>& bvs = getBoundVars(e);
02298   if (bvs.size() <= 0){
02299     return reflexivityRule(e);
02300   }
02301 
02302   std::vector<Expr> assertList;
02303   flatAnds(e, assertList);
02304   
02305   CompleteInstPreProcessor comp_inst_proc(theoryCore(), d_rules);
02306 
02307   if (comp_inst_proc.hasMacros(assertList)){
02308     for(size_t i = 0; i < assertList.size();i++){
02309       //    cout << "== assert: " << i << " : " << assertList[i] << endl;
02310       assertList[i] = comp_inst_proc.instMacros(assertList[i], trueExpr().notExpr().notExpr());
02311     }
02312   }
02313 
02314   for(size_t i = 0; i < assertList.size() ; i++){
02315     //    cout << "BEFORE: " << assertList[i] << endl; 
02316     assertList[i] = comp_inst_proc.simplifyQuant(assertList[i]);
02317     //    cout << "AFTER: " << assertList[i] << endl; 
02318   }
02319   
02320   for(size_t i = 0; i < assertList.size() ; i++){
02321     if ( ! comp_inst_proc.isGood(assertList[i])){
02322       //      cout << " no good " << endl;
02323       //      cout << " because of " <<  assertList[i] << endl;
02324       return reflexivityRule(e);
02325     }
02326   }
02327   
02328   for(size_t i = 0; i < assertList.size() ; i++){
02329     //    cout << "collecting " << assertList[i] << endl;
02330     comp_inst_proc.collectIndex(assertList[i]);
02331   }
02332 
02333   vector<Expr> new_asserts; 
02334   for(size_t i = 0; i < assertList.size() ; i++){
02335     Expr new_asser = comp_inst_proc.inst(assertList[i]);
02336     getBoundVars(new_asser);
02337     if (new_asser.containsBoundVar()){
02338       return reflexivityRule(e);
02339     }
02340     else{
02341       new_asserts.push_back(new_asser);
02342     }
02343   }
02344     
02345 
02346   //  vector<Expr> all_index; 
02347   //  for(size_t i = 0; i < assertList.size() ; i++){
02348   //    collectIndex(assertList[i], all_index);
02349   //  }
02350   
02351   
02352 //   set<Expr> inst_index;
02353 //   for(size_t i = 0; i < all_index.size() ; i++){
02354 //     if (isInt(all_index[i].getType())){
02355 //       inst_index.insert(all_index[i]);
02356 //     }
02357 //     else{
02358 //       cout <<"strange" << all_index[i] << endl;
02359 //     }
02360 //   }
02361 
02362 //   int j(0);
02363 //   for(set<Expr>::iterator i = inst_index.begin(), iend = inst_index.end();
02364 //       i != iend; i++){
02365 //     cout << "i=" << j++ << " " << *i << endl;
02366 //   }
02367   
02368 
02369 //   for(size_t i = 0; i < assertList.size() ; i++){
02370 //     Expr& cur_expr = assertList[i];
02371 //     if(cur_expr.isForall()){
02372 //       Expr new_inst = instIndex(cur_expr, inst_index);
02373 //       assertList[i] = new_inst;
02374 //       //      cout << "new inst " << new_inst << endl;
02375 //     }
02376 //   }
02377   
02378 //   for(size_t i = 0; i < assertList.size() ; i++){
02379 //     //    cout << "AFTER i=" << i << " " << assertList[i] << endl;
02380 //   }
02381 
02382   for(size_t i = 0; i < new_asserts.size() ; i++){
02383     new_asserts[i] = comp_inst_proc.simplifyEq(new_asserts[i]);
02384   }
02385 
02386   for(size_t i = 0; i < new_asserts.size() ; i++){
02387     //cout << ":assumption "  << new_asserts[i] << endl;
02388     //    cout << "NEW" << comp_inst_proc.inst(assertList[i]) << endl;
02389   }
02390 
02391   
02392   //this is really a bad way, add a new proof rule here
02393   Expr res = Expr(AND, new_asserts);
02394   Theorem ret_thm = d_rules->addNewConst(e.iffExpr(res));
02395   //  cout << "NEW THM " << ret_thm << endl;
02396   return ret_thm;
02397 }
02398 
02399 
02400 
02401 
02402 bool isGoodSysPredTrigger(const Expr& e){
02403   if(!isSysPred(e)) return false;
02404   if(usefulInMatch(e[0]) || usefulInMatch(e[1])) return true;
02405   return false;
02406 }
02407 
02408 bool isGoodFullTrigger(const Expr& e, const std::vector<Expr>& bVarsThm){
02409   if( !usefulInMatch(e))
02410     return false;
02411 
02412   const std::set<Expr>& bvs = getBoundVars(e);
02413 
02414   if (bvs.size() >= bVarsThm.size()){
02415      for(size_t i=0; i<bVarsThm.size(); i++)  {
02416        if (bvs.find(bVarsThm[i]) == bvs.end()){
02417    return false;
02418        }
02419      }
02420      return true;
02421   }
02422   else {
02423     return false;
02424   }
02425 }
02426 
02427 bool isGoodMultiTrigger(const Expr& e, const std::vector<Expr>& bVarsThm, int offset){
02428   if( !usefulInMatch(e) )
02429     return false;
02430 
02431   int bvar_missing = 0;
02432   const std::set<Expr>& bvs = getBoundVars(e);
02433 
02434   if(bvs.size() <= 0) return false;
02435 
02436   for(size_t i=0; i<bVarsThm.size(); i++) {
02437     if (bvs.find(bVarsThm[i]) == bvs.end()){
02438       bvar_missing++; // found one bound var missing in the e.
02439     }
02440   }
02441 
02442   if (0 == bvar_missing){ //it is a full triggers
02443     return false;
02444   }
02445 
02446   if(bvar_missing <= offset){
02447     if(isSysPred(e)){
02448       if (isGoodSysPredTrigger(e)) {
02449   return true;
02450       }
02451       else {
02452   return false;
02453       }
02454     }
02455     else {
02456       return true;
02457     }
02458   }
02459   return false;
02460 }
02461 
02462 bool isGoodPartTrigger(const Expr& e, const std::vector<Expr>& bVarsThm){
02463   if( !usefulInMatch(e) )
02464     return false;
02465 
02466   size_t bvar_missing = 0;
02467   const std::set<Expr>& bvs = getBoundVars(e);
02468 
02469   for(size_t i=0; i<bVarsThm.size(); i++) {
02470     if (bvs.find(bVarsThm[i]) == bvs.end()){
02471       bvar_missing++; // found one bound var missing in the e.
02472     }
02473   }
02474 
02475   if (0 == bvar_missing){ //it is a full triggers
02476     return false;
02477   }
02478 
02479   if(0 == bvs.size()){
02480     return false;
02481   }
02482 
02483   if(bvar_missing < bVarsThm.size()){
02484     if(isSysPred(e)){
02485       if (isGoodSysPredTrigger(e)) {
02486   return true;
02487       }
02488       else {
02489   return false;
02490       }
02491     }
02492     else {
02493       return true;
02494     }
02495   }
02496   return false;
02497 }
02498 
02499 
02500 static bool recursiveGetPartTriggers(const Expr& e, std::vector<Expr>& res) {
02501   if(e.getFlag())
02502    return false;
02503 
02504   if(e.isClosure())
02505     return recursiveGetPartTriggers(e.getBody(), res);
02506 
02507   if(0 == e.arity()){
02508     if(BOUND_VAR == e.getKind()){
02509       return false;
02510     }
02511     else{
02512       return true;
02513     }
02514   }
02515 
02516   bool good=true;
02517   bool no_bound =true;
02518 
02519   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
02520     if(BOUND_VAR == i->getKind()){
02521       no_bound=false;
02522       continue;
02523     }
02524     bool temp = recursiveGetPartTriggers(*i,res);
02525     if(false == temp) {
02526       good=false;
02527     }
02528   }
02529 
02530   e.setFlag();
02531 
02532   if(good && no_bound) {
02533     return true;
02534   }
02535   else if(good && !no_bound){
02536     res.push_back(e);
02537     return false;
02538   }
02539   else{
02540     return false;
02541   }
02542 }
02543 
02544 
02545 std::vector<Expr> getPartTriggers(const Expr& e){
02546   e.clearFlags();
02547   std::vector<Expr> res;
02548   recursiveGetPartTriggers(e,res);
02549   e.clearFlags();
02550   return res;
02551 }
02552 
02553 int trigInitScore(const Expr& e){
02554   if( isSysPred(e) && !isGoodSysPredTrigger(e)){
02555     return 1;
02556   }
02557   else {
02558     return 0;
02559   }
02560 }
02561 
02562 
02563 void TheoryQuant::arrayIndexName(const Expr& e){
02564   std::vector<Expr> res;
02565 
02566   const std::vector<Expr>& subs=getSubTerms(e);
02567 
02568   for(size_t i=0; i<subs.size(); i++){
02569     int kind = subs[i].getKind();
02570     if (READ == kind || WRITE == kind){
02571       const Expr& name = subs[i][0];
02572       const Expr& index = subs[i][1];
02573       if(getBoundVars(name).size() <= 0 && (getBoundVars(index).size() <=0)){
02574   std::vector<Expr> tp = d_arrayIndic[name];
02575   tp.push_back(index);
02576   d_arrayIndic[name]=tp;
02577       }
02578       else {
02579       }
02580     }
02581   }
02582 }
02583 
02584 void TheoryQuant::registerTrig(ExprMap<ExprMap<std::vector<dynTrig>* >* >& cur_trig_map,
02585              Trigger trig,
02586              const std::vector<Expr> thmBVs,
02587              size_t univ_id){
02588   {
02589     if(trig.hasRWOp){
02590       ExprMap<Expr> bv_map;
02591       dynTrig newDynTrig(trig, bv_map,univ_id);
02592       d_arrayTrigs.push_back(newDynTrig);
02593     }
02594   }
02595 
02596   ExprMap<Expr> bv_map;
02597   /*
02598   for(size_t i = 0; i<thmBVs.size(); i++){
02599     bv_map[thmBVs[i]] = null_expr;
02600   }
02601   */
02602 
02603 //temp fix,
02604    for(size_t i = 0; i<thmBVs.size(); i++){
02605      bv_map[thmBVs[i]] = thmBVs[i];
02606    }
02607 
02608 
02609 
02610   const Expr& trig_ex = trig.getEx();
02611 
02612   Expr genTrig = trig_ex;
02613   //  Expr genTrig = generalTrig(trig_ex, bv_map);
02614 
02615   dynTrig newDynTrig(trig,bv_map,univ_id);
02616 
02617   Expr head = trig.getHead();
02618 
02619   ExprMap<ExprMap<vector<dynTrig>* >* >::iterator iter = cur_trig_map.find(head);
02620   if(cur_trig_map.end() == iter){
02621     ExprMap<vector<dynTrig>* >* new_cd_map= new  ExprMap<vector<dynTrig>* > ;
02622     cur_trig_map[head] = new_cd_map;
02623     vector<dynTrig>* new_dyntrig_list = new vector<dynTrig>;
02624     (*new_cd_map)[genTrig] = new_dyntrig_list;
02625     (*new_dyntrig_list).push_back(newDynTrig);
02626   }
02627   else{
02628     ExprMap<vector<dynTrig>* >* cd_map = iter->second;
02629     ExprMap<vector<dynTrig>* >::iterator iter_map = cd_map->find(genTrig);
02630     if(cd_map->end() == iter_map){
02631       vector<dynTrig>* new_dyntrig_list = new vector<dynTrig>;
02632       (*cd_map)[genTrig] = new_dyntrig_list;
02633       (*new_dyntrig_list).push_back(newDynTrig);
02634     }
02635     else{
02636       //      cout<<"never happen here" << endl;
02637       //      (*((*cd_map)[generalTrig])).push_back(newDynTrig);
02638       (*(iter_map->second)).push_back(newDynTrig);
02639     }
02640   }
02641 }
02642 
02643 /*
02644 void TheoryQuant::registerTrigReal(Trigger trig, const std::vector<Expr> thmBVs, size_t univ_id){
02645   cout<<"register: "<<trig.getEx()<<endl;
02646   ExprMap<Expr> bv_map;
02647   for(size_t i = 0; i<thmBVs.size(); i++){
02648     bv_map[thmBVs[i]] = null_expr;
02649   }
02650   const Expr& trig_ex = trig.getEx();
02651 
02652   Expr genTrig = generalTrig(trig_ex, bv_map);
02653 
02654   dynTrig newDynTrig(trig,bv_map,univ_id);
02655 
02656   Expr head = trig.getHead();
02657 
02658   ExprMap<CDMap<Expr, CDList<dynTrig>* >* >::iterator iter = d_allmap_trigs.find(head);
02659   if(d_allmap_trigs.end() == iter){
02660     CDMap<Expr, CDList<dynTrig>* >* new_cd_map=
02661       new(true) CDMap<Expr, CDList<dynTrig>* > (theoryCore()->getCM()->getCurrentContext());
02662     d_allmap_trigs[head] = new_cd_map;
02663     CDList<dynTrig>* new_dyntrig_list = new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
02664     (*new_cd_map)[genTrig] = new_dyntrig_list;
02665     (*new_dyntrig_list).push_back(newDynTrig);
02666   }
02667   else{
02668     CDMap<Expr, CDList<dynTrig>* >* cd_map = iter->second;
02669     CDMap<Expr, CDList<dynTrig>* >::iterator iter_map = cd_map->find(genTrig);
02670     if(cd_map->end() == iter_map){
02671       CDList<dynTrig>* new_dyntrig_list = new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
02672       (*cd_map)[genTrig] = new_dyntrig_list;
02673       (*new_dyntrig_list).push_back(newDynTrig);
02674     }
02675     else{
02676       //      (*((*cd_map)[generalTrig])).push_back(newDynTrig);
02677       (*((*iter_map).second)).push_back(newDynTrig);
02678       cout<<"once more"<<endl;
02679     }
02680   }
02681 
02682 }
02683 */
02684 
02685 /*
02686 Expr TheoryQuant::generalTrig(const Expr& trig, ExprMap<Expr>& bvs){
02687   //temp fix
02688   return trig;
02689 
02690   Expr newtrig = trig;
02691   getBoundVars(newtrig);
02692 
02693 
02694   size_t count =0 ;
02695   Expr res = recGeneralTrig(trig, bvs, count);
02696   getBoundVars(res);
02697   return res;
02698 
02699 }
02700 
02701 
02702 Expr TheoryQuant::recGeneralTrig(const Expr& trig, ExprMap<Expr>& bvs, size_t& mybvs_count){
02703 
02704   if (!trig.containsBoundVar()) return trig;
02705   if (BOUND_VAR == trig.getKind()){
02706     if (bvs.find(trig) != bvs.end()){
02707       const Expr& ubv = bvs[trig];
02708       if(null_expr ==ubv){
02709   Expr new_bv = d_mybvs[mybvs_count++];
02710   bvs[trig] = new_bv ;
02711   if((mybvs_count) >= MAX_TRIG_BVS ){
02712     //    cout<< "general trig error" <<endl;
02713   }
02714   else{
02715     return new_bv;
02716   }
02717       }
02718       else{
02719   return bvs[trig];
02720       }
02721     }
02722     else{
02723       return d_mybvs[0];
02724     }
02725   }
02726   else{
02727     vector<Expr> children;
02728       for(Expr::iterator i=trig.begin(), iend=trig.end(); i!=iend; ++i){
02729   Expr repChild;
02730   if(i->containsBoundVar()){
02731     repChild = recGeneralTrig(*i, bvs, mybvs_count);
02732   }
02733   else{
02734     repChild = *i;
02735   }
02736   children.push_back(repChild);
02737       }
02738       return Expr(trig.getOp(), children);
02739   }
02740 }
02741 
02742 */
02743 //this function is used to check if two triggers can match with eath other
02744 bool TheoryQuant::canMatch(const Expr& t1, const Expr& t2, ExprMap<Expr>& env){
02745   if(getBaseType(t1) != getBaseType(t2)) return false;
02746 
02747   if (BOUND_VAR == t1.getKind() || BOUND_VAR == t2.getKind()) {
02748     return true;
02749   }
02750 
02751   if ( (t1.arity() != t2.arity()) || (t1.getKind() != t2.getKind() )) {
02752     return false;
02753   }
02754   if (canGetHead(t1) && canGetHead(t2)) {
02755     if ( getHead(t1) != getHead(t2) ){
02756       return false;
02757     }
02758     for(int i=0; i<t1.arity(); i++){
02759       if (false == canMatch(t1[i], t2[i] , env))
02760   return false;
02761     }
02762     return true;
02763   }
02764   else{
02765     return false;
02766   }
02767 }
02768 
02769 bool TheoryQuant::isTransLike (const vector<Expr>& cur_trig){
02770   if(!(*d_useTrans)){
02771     return false;
02772   }
02773   if(3==cur_trig.size()){
02774     const Expr& t1=cur_trig[0];
02775     const Expr& t2=cur_trig[1];
02776     const Expr& t3=cur_trig[2];
02777     if ( canGetHead(t1) && canGetHead(t2) && canGetHead(t3) &&
02778    (getHead(t1) == getHead(t2)) &&  (getHead(t2) == getHead(t3))){
02779       const std::set<Expr>& ts1 = getBoundVars(t1);
02780       const std::set<Expr>& ts2 = getBoundVars(t2);
02781       const std::set<Expr>& ts3 = getBoundVars(t3);
02782       if ( 2==ts1.size() && 2==ts2.size() && 2==ts2.size() &&
02783      (ts1 != ts2) && (ts2 != ts3) && (ts3 != ts1)){
02784   std::set<Expr> all;
02785   for(set<Expr>::const_iterator i=ts1.begin(), iend = ts1.end(); i != iend; i++){
02786     all.insert(*i);
02787   }
02788   for(set<Expr>::const_iterator i=ts2.begin(), iend = ts2.end(); i != iend; i++){
02789     all.insert(*i);
02790   }
02791   for(set<Expr>::const_iterator i=ts3.begin(), iend = ts3.end(); i != iend; i++){
02792     all.insert(*i);
02793   }
02794   bool res = true;
02795   if(3==all.size()){
02796     for(set<Expr>::const_iterator i=all.begin(), iend = all.end(); i != iend; i++){
02797       if(!i->isVar()) {
02798         res = false;
02799         break;
02800       }
02801     }
02802     if(res) {
02803     }
02804     return res;
02805   }
02806       }
02807     }
02808   }
02809   return false;
02810 }
02811 
02812 bool TheoryQuant::isTrans2Like (const std::vector<Expr>& all_terms, const Expr& tr2){
02813   if(!(*d_useTrans2)){
02814     return false;
02815   }
02816   for(size_t i = 0; i < all_terms.size(); i++){
02817     if(all_terms[i].isEq()){
02818       const Expr& cur = all_terms[i];
02819       if(cur[0] != cur[1] && ( (cur[0]==tr2[0] && cur[1]==tr2[1]) || (cur[0]==tr2[1] && cur[1]==tr2[0]))){
02820   return true;
02821       }
02822     }
02823   }
02824   return false;
02825 }
02826 
02827 
02828 bool goodMultiTriggers(const std::vector<Expr>& exprs, const std::vector<Expr> bVars){
02829   ExprMap<bool> bvar_found;
02830 
02831   for( std::vector<Expr>::const_iterator i = bVars.begin(),  iend= bVars.end();  i!=iend; i++) {
02832     bvar_found[*i]=false;
02833   }
02834 
02835   for (size_t  i=0; i< exprs.size();i++){
02836     const std::set<Expr> & bv_in_trig = getBoundVars(exprs[i]);
02837     for(std::set<Expr>::const_iterator j=bv_in_trig.begin(), jend = bv_in_trig.end();  j != jend; j++){
02838       if(bvar_found.find(*j) != bvar_found.end()){
02839   bvar_found[*j]=true;
02840       }
02841     }
02842   }
02843 
02844   for( std::vector<Expr>::const_iterator i = bVars.begin(), iend= bVars.end();  i!=iend;  i++) {
02845     if(false == bvar_found[*i]){
02846       return false ;
02847     }
02848   }
02849   return true;
02850 }
02851 
02852 
02853 inline size_t locVar(const vector<Expr>& bvsThm, const Expr& bv){
02854   for(size_t i=0, iend = bvsThm.size(); i < iend; i++){
02855     if (bvsThm[i] == bv){
02856       return i;
02857     }
02858   }
02859   return 999; //this number should be big enough
02860 }
02861 
02862 
02863 void TheoryQuant::setupTriggers(ExprMap<ExprMap<vector<dynTrig>* >*>& trig_maps, const Theorem& thm, size_t univs_id){
02864 
02865   //  static std::vector<Expr> libQuant;
02866   const Expr& e = thm.getExpr();
02867 
02868   TRACE("triggers", "setup : "+int2string(e.getIndex()),  " | " , e.toString());
02869 
02870   d_univs.push_back(thm);
02871   const std::vector<Expr>& bVarsThm = e.getVars();
02872   if  (d_hasTriggers.count(e) > 0 ) {
02873 
02874     if(d_fullTrigs.count(e)>0){
02875       std::vector<Trigger>& new_trigs = d_fullTrigs[e];
02876       for(size_t i=0; i<new_trigs.size(); i++){
02877   registerTrig(trig_maps, new_trigs[i], bVarsThm, univs_id);
02878       }
02879     }
02880     //    if(0 == new_trigs.size() && d_multTrigs.count(e) > 0){
02881     if( d_multTrigs.count(e) > 0){
02882       std::vector<Trigger>& new_mult_trigs = d_multTrigs[e];
02883       for(size_t j=0; j<new_mult_trigs.size(); j++){
02884   registerTrig(trig_maps, new_mult_trigs[j], bVarsThm, univs_id);
02885       }
02886     }
02887     return;
02888   }
02889 
02890   if  (*d_useManTrig  ) {
02891     if(e.getTriggers().size() > 0) {
02892       //      cout<<"manual trig found"<<endl;
02893       //      cout<<vectorExpr2string(e.getTriggers())<<endl;
02894     }
02895   }
02896 
02897   d_hasTriggers[e]=true;
02898 
02899   TRACE("triggers-new", "setup : "+int2string(e.getIndex()),  " | " , e.toString());
02900   //  libQuant.push_back(e);
02901 
02902   //  const std::vector<Expr>& subterms = getSubTrig(e);
02903   const std::vector<Expr> subterms = getSubTrig(e);
02904 
02905 
02906 // #ifdef _CVC3_DEBUG_MODE
02907 //   if( CVC3::debugger.trace("triggers")  ){
02908 //     cout<<"===========all sub terms =========="<<endl;
02909 //     for (size_t i=0; i<subterms.size(); i++){
02910 //       const Expr& sub = subterms[i];
02911 //       cout<<"i="<< i << " : " << findExpr(sub) << " | " << sub << " and type is " << sub.getType()
02912 //    << " and kind is " << sub.getEM()->getKindName(sub.getKind()) << endl;
02913 //     }
02914 //   }
02915 // #endif
02916 
02917   ExprMap<Polarity> exprPol;
02918   findPolarity(e, exprPol, Pos);
02919 
02920   {// for full triggers
02921     std::vector<Expr> trig_list;
02922     std::vector<Expr> trig_cadt;
02923     for(std::vector<Expr>::const_iterator i = subterms.begin(),iend=subterms.end(); i!=iend; i++){
02924       if(isGoodFullTrigger(*i, bVarsThm)) {
02925   trig_cadt.push_back(*i);
02926       }
02927     }
02928 
02929 
02930     if(*d_useManTrig && e.getTriggers().size() > 0  ){
02931       std::vector<std::vector<Expr> > man_trigs = e.getTriggers();
02932       for(std::vector<std::vector<Expr> >::const_iterator i=man_trigs.begin(), iend=man_trigs.end(); i != iend; i++){
02933   //  if(1 == i->arity()){
02934   if(1 == i->size()){
02935     trig_list.push_back((*i)[0]);
02936     //    cout<<"full manual pushed "<<(*i)[0] << endl;
02937   }
02938   //  else if(2 == i->arity()){
02939   else if(2 == i->size()){
02940     if (isGoodFullTrigger((*i)[0], bVarsThm) && isGoodFullTrigger((*i)[1], bVarsThm)){
02941       trig_list.push_back((*i)[0]);
02942       trig_list.push_back((*i)[1]);
02943       break; // it must be trans2like
02944     }
02945   }
02946       }
02947     }
02948     else{
02949       for(size_t iter =0; iter < trig_cadt.size(); iter++) {
02950   Expr* i = &(trig_cadt[iter]);
02951   bool notfound = true;
02952 
02953   for(size_t index=0; index< trig_list.size(); index++){
02954     if (i->subExprOf(trig_list[index])) {
02955       trig_list[index]=*i;
02956       notfound=false;
02957       break;
02958     }
02959     if (trig_list[index].subExprOf(*i)) {
02960       notfound=false;
02961       break;
02962     }
02963   }
02964   if (notfound) {
02965     trig_list.push_back(*i);
02966   }
02967       }
02968     }
02969 
02970     std::vector<Trigger> trig_ex;
02971 
02972     for (size_t  i=0; i< trig_list.size();i++){
02973       const Expr& cur = trig_list[i];
02974       const std::set<Expr> cur_bvs = getBoundVars(cur);
02975       int score = trigInitScore(cur);
02976       if(score > 0) continue;
02977 
02978       //1. test trans2
02979       //2. test whether a trigger can trig a bigger instance of itself, now we have no actions for such case because we use expr score and dynamic loop prevention.
02980 
02981       for(size_t j=0; j< trig_cadt.size(); j++){
02982   if (trig_list[i] == trig_cadt[j]) continue;
02983   ExprMap<Expr> null;
02984   if (canMatch(trig_list[i], trig_cadt[j], null)){
02985     if(exprScore(trig_list[i]) < exprScore(trig_cadt[j])){
02986     }
02987     else if(*d_useTrans2 &&
02988       trig_list.size() == 2 &&
02989       trig_list[i].arity() == 2 &&
02990       BOUND_VAR == trig_list[i][0].getKind() &&
02991       BOUND_VAR == trig_list[i][1].getKind() &&
02992       BOUND_VAR == trig_cadt[j][0].getKind() &&
02993       BOUND_VAR == trig_cadt[j][1].getKind() &&
02994       isTrans2Like(subterms, trig_list[i])
02995       ){
02996 
02997       score =0; //useless, to delete;
02998       d_trans2_num++;
02999 
03000       DebugAssert(d_trans2_num<=1, "more than 2 trans2 found");
03001       TRACE("triggers",  "trans2 found ", trig_list[i], "");
03002 
03003       Trigger t(theoryCore(), cur, Neg, cur_bvs);
03004       t.setTrans2(true);
03005       t.setHead(getHeadExpr(cur));
03006       if(isSimpleTrig(cur)){
03007         t.setSimp();
03008       }
03009       if(isSuperSimpleTrig(cur)){
03010         t.setSuperSimp();
03011       }
03012       d_fullTrigs[e].push_back(t);
03013       registerTrig(trig_maps,t, bVarsThm, univs_id);
03014       return;
03015     }
03016     else{
03017       score =0;
03018     }
03019   }
03020       }
03021 
03022       Polarity pol= Ukn;
03023 
03024       if(cur.getType().isBool()){
03025   DebugAssert(exprPol.count(e)>0,"unknown polarity:"+cur.toString());
03026   pol = exprPol[cur];
03027       }
03028 
03029       Trigger* t;
03030       Trigger* t_ex; //so, if a pred is PosNeg, we actually put two triggers into the list, one pos and the other neg
03031 
03032       if(PosNeg == pol && *d_usePolarity){
03033   t = new Trigger(theoryCore(), cur, Pos, cur_bvs);
03034   t_ex = new Trigger(theoryCore(), cur, Neg, cur_bvs);
03035   if(isSimpleTrig(cur)){
03036     t->setSimp();
03037     t_ex->setSimp();
03038   }
03039   if(isSuperSimpleTrig(cur)){
03040     t->setSuperSimp();
03041     t_ex->setSuperSimp();
03042   }
03043 
03044       }
03045       else{
03046   t = new Trigger(theoryCore(), cur, pol, cur_bvs);
03047   if(isSimpleTrig(cur)){
03048     t->setSimp();
03049   }
03050   if(isSuperSimpleTrig(cur)){
03051     t->setSuperSimp();
03052   }
03053   t_ex = NULL;
03054       }
03055 
03056       if(canGetHead(cur)) {
03057   t->setHead(getHeadExpr(cur));
03058   if(NULL != t_ex){
03059     t_ex->setHead(getHeadExpr(cur));
03060   }
03061       }
03062       else{
03063   if(!isSysPred(cur)){
03064     //    cout<<"cur " << cur <<endl;
03065     //    DebugAssert(false, "why this is a trigger");
03066   }
03067       }
03068 
03069       t->setRWOp(false);
03070 
03071       if(READ == cur.getKind() || WRITE == cur.getKind()){
03072   arrayIndexName(cur);
03073       }
03074 
03075       if(READ == cur.getKind() && WRITE== cur[0].getKind() && 1 == bVarsThm.size() ){
03076   //  cout<<t->trig<<endl;
03077   t->setRWOp(true);
03078   if(t_ex != NULL) t_ex->setRWOp(true);
03079       }
03080 
03081       if(t_ex != NULL)  {
03082   trig_ex.push_back(*t_ex);
03083       }
03084 
03085       d_fullTrigs[e].push_back(*t);
03086       registerTrig(trig_maps,*t, bVarsThm, univs_id);
03087 
03088       TRACE("triggers", "new:full triggers:", cur.toString(),"");
03089       TRACE("triggers", "new:full trigger score:", score,"");
03090       TRACE("triggers", "new:full trigger pol:", pol,"");
03091     }
03092 
03093     if(e.getTriggers().size() > 0) {
03094       //      cout<<"#### manual_trig: ";
03095       //      cout<<vectorExpr2string(e.getTriggers())<<endl;
03096     }
03097 
03098 
03099     for(size_t i=0; i<trig_ex.size(); i++){
03100       d_fullTrigs[e].push_back(trig_ex[i]);
03101       registerTrig(trig_maps,trig_ex[i], bVarsThm, univs_id);
03102       TRACE("triggers", "new extra :full triggers:", trig_ex[i].getEx().toString(),"");
03103     }
03104 
03105     if(d_fullTrigs[e].size() == 0){
03106       TRACE("triggers warning", "no full trig: ", e , "");
03107     }
03108   }
03109 
03110   //  if(0 == d_fullTrigs[e].size() && *d_useMult )
03111   if(0 == d_fullTrigs[e].size())
03112     {  //setup multriggers
03113       std::vector<Expr>& cur_trig = d_multTriggers[e];
03114       if(*d_useManTrig && e.getTriggers().size() > 0 ){
03115   std::vector<std::vector<Expr> > man_trig = e.getTriggers();
03116   int count(0);
03117   for(std::vector<std::vector<Expr> >::const_iterator i = man_trig.begin(), iend = man_trig.end(); i != iend; i++){
03118     //    if (i->arity() > 1) count++;
03119     if (i->size() > 1) count++;
03120     //    cout << "count" << count << " " <<  *i << endl;
03121   }
03122 
03123   if(count > 1){
03124     //cout<<"en, cannot handle this now"<<endl;
03125 
03126   }
03127   //  if(man_trig[count-1].arity() != 2){
03128   if(man_trig[count-1].size() != 2){
03129 
03130     //    cout<<man_trig[count-1]<<endl;
03131     //    cout<<"sorry, only two exprs are handled now"<<endl;
03132     //cout<<man_trig[count-1]<<endl;
03133     //cout<<"sorry, only two exprs are handled now"<<endl;
03134 
03135   }
03136 
03137   for(std::vector<Expr>::const_iterator j = man_trig[count-1].begin(), jend = man_trig[count-1].end(); j != jend; ++j){
03138     cur_trig.push_back(*j);
03139   }
03140       }
03141       else{
03142   for( std::vector<Expr>::const_iterator i = subterms.begin(),  iend=subterms.end();  i!=iend;  i++) {
03143     if(isGoodMultiTrigger(*i, bVarsThm, d_offset_multi_trig))  {
03144       bool notfound = true;
03145       for(size_t index=0; index<d_multTriggers[e].size(); index++){
03146         if (i->subExprOf(d_multTriggers[e][index]))    {
03147     (d_multTriggers[e][index])=*i;
03148     notfound=false;
03149         }
03150       }
03151       if (notfound){
03152         d_multTriggers[e].push_back(*i);
03153       }
03154     }
03155   }
03156 
03157   if (goodMultiTriggers(cur_trig, bVarsThm)){
03158     //  cout<<"good multi triggers"<<endl;
03159     TRACE("multi-triggers", "good set of multi triggers","","");
03160     for (size_t  i=0; i< d_multTriggers[e].size();i++){
03161       //    cout<<"multi-triggers" <<d_multTriggers[e][i]<<endl;
03162       TRACE("multi-triggers", "multi-triggers:", d_multTriggers[e][i].toString(),"");
03163     }
03164   }
03165   else{
03166     cur_trig.clear();
03167     //    cout<<"bad multi triggers"<<endl;
03168     TRACE("multi-triggers", "bad set of multi triggers","","");
03169     return;
03170   }
03171 
03172       }
03173 
03174       //special code for transitive pred,
03175       {
03176   if(isTransLike(cur_trig)){
03177     d_trans_num++;
03178     DebugAssert(d_trans_num <= 1, "more than one trans found");
03179 
03180     Expr ex = cur_trig[0];
03181 
03182     Trigger* trans_trig = new Trigger(theoryCore(), ex, Neg, getBoundVars(ex));
03183     trans_trig->setHead(getHeadExpr(ex));
03184     if(isSimpleTrig(ex)){
03185       trans_trig->setSimp();
03186     }
03187     if(isSuperSimpleTrig(ex)){
03188       trans_trig->setSuperSimp();
03189     }
03190 
03191     trans_trig->setTrans(true);
03192 
03193     d_fullTrigs[e].push_back(*trans_trig);
03194     registerTrig(trig_maps,*trans_trig, bVarsThm, univs_id);
03195     cur_trig.clear();
03196     TRACE("triggers", " trans like found ", ex, "");
03197     d_transThm = thm;
03198   }
03199       }
03200 
03201       //enhanced multi-triggers
03202       //      if(cur_trig.size() >0 && !(*d_useManTrig)){
03203       if(cur_trig.size() >0 ){
03204   //  if(cur_trig.size() >0 ){
03205   std::vector<Expr> posList, negList;
03206   for(size_t k=0; k<cur_trig.size(); k++){
03207     const Expr& cur_item = cur_trig[k];
03208     if (cur_item.getType().isBool()){
03209       Polarity pol = exprPol[cur_item];
03210       if(PosNeg == pol || Pos == pol){
03211         posList.push_back(cur_item);
03212       }
03213       if(PosNeg == pol || Neg == pol){
03214         negList.push_back(cur_item);
03215       }
03216     }
03217   }
03218   if (goodMultiTriggers(posList, bVarsThm)){
03219     TRACE("multi-triggers", "good set of multi triggers pos","","");
03220     for (size_t  i=0; i< posList.size();i++){
03221       TRACE("multi-triggers", "multi-triggers:", posList[i].toString(),"");
03222     }
03223     cur_trig.clear();
03224     for(size_t m=0; m<posList.size(); m++){
03225       cur_trig.push_back(posList[m]);
03226     }
03227   }
03228   if (goodMultiTriggers(negList, bVarsThm) && negList.size() < cur_trig.size()){
03229     TRACE("multi-triggers", "good set of multi triggers neg","","");
03230     for (size_t  i=0; i< negList.size();i++){
03231       TRACE("multi-triggers", "multi-triggers:", negList[i].toString(),"");
03232     }
03233     cur_trig.clear();
03234     for(size_t m=0; m<negList.size(); m++){
03235       cur_trig.push_back(negList[m]);
03236     }
03237   }
03238       }
03239 
03240       {//new way of multi trigger
03241 
03242   if(!(*d_useManTrig) || e.getTriggers().size() <= 0){
03243   //  if(!(*d_useManTrig)){
03244     if( 3 == cur_trig.size() ||  4 == cur_trig.size() || 5 == cur_trig.size() || 6 == cur_trig.size()  ){
03245       for(size_t i = 0; i < cur_trig.size(); i++){
03246         for(size_t j = 0; j < i; j++){
03247     vector<Expr> tempList;
03248     tempList.clear();
03249     tempList.push_back(cur_trig[i]);
03250     tempList.push_back(cur_trig[j]);
03251     //        cout<<i<<" | "<<j<<endl;
03252     //        cout<<vectorExpr2string(tempList)<<endl;
03253     if (goodMultiTriggers(tempList, bVarsThm)){
03254       cur_trig.clear();
03255       cur_trig.push_back(tempList[0]);
03256       cur_trig.push_back(tempList[1]);
03257       break;
03258         }
03259         }
03260       }
03261     }
03262   }
03263 
03264   if(cur_trig.size() != 2){
03265     if( 0 == cur_trig.size()){
03266       return;
03267     }
03268     //    FatalAssert(false, "unsupported multi-triggers");
03269     //    cout<<"e: "<<e<<endl;
03270     //    cout<<cur_trig.size()<<endl;
03271     //    cout<<bVarsThm.size()<<endl;
03272 
03273     //    cout<<vectorExpr2string(bVarsThm)<<endl;
03274     //    for(size_t i =0; i<cur_trig.size(); i++){
03275     //      cout<<cur_trig[i]<<endl;
03276     //    }
03277     return;
03278   }
03279 
03280   //  cout<<"== new multi-trig ==" << endl;
03281   for(size_t i = 0 ; i<cur_trig.size(); i++){
03282     set<Expr> bvs = getBoundVars(cur_trig[i]);
03283     Trigger trig(theoryCore(), cur_trig[i], Ukn, bvs); //
03284     //    cout<<"new way of multi-trig"<<cur_trig[i]<<endl;
03285     trig.setHead(getHead(cur_trig[i]));
03286     trig.setMultiTrig();
03287     trig.multiIndex = i;
03288     trig.multiId=d_all_multTrigsInfo.size();
03289     d_multTrigs[e].push_back(trig);
03290     registerTrig(trig_maps, trig, bVarsThm, univs_id);
03291   }
03292 
03293   {
03294     multTrigsInfo multTrigs;
03295     for(size_t i =0, iend = d_multTrigs[e].size(); i<iend; i++){
03296       const std::vector<Expr>& one_set_bvs = d_multTrigs[e][i].bvs;
03297       std::vector<size_t> one_set_pos;
03298 
03299       for(size_t v = 0, vend = one_set_bvs.size(); v<vend; v++){
03300         size_t loc = locVar(bVarsThm, one_set_bvs[v]);
03301         if( 999 != loc ){
03302     one_set_pos.push_back(loc);
03303         }
03304       }
03305 
03306       sort(one_set_pos.begin(), one_set_pos.end());
03307 
03308       for(size_t v = 0, vend = one_set_pos.size(); v<vend; v++){
03309       }
03310 
03311       multTrigs.var_pos.push_back(one_set_pos);
03312     }//setup pos of all multi tirggers
03313 
03314     //now we only consider two multi triggers
03315     vector<size_t> common;
03316     std::vector<size_t>& tar1 = multTrigs.var_pos[0];
03317     std::vector<size_t>& tar2 = multTrigs.var_pos[1];
03318     vector<size_t>::iterator t1(tar1.begin()), t2(tar2.begin());
03319     while(t1 != tar1.end() && t2!= tar2.end()){
03320       size_t pos1 = *t1;
03321       size_t pos2 = *t2;
03322       if( pos1  == pos2 ) {
03323         common.push_back(pos1);
03324         t1=tar1.erase(t1);
03325         t2=tar2.erase(t2);
03326       }
03327       else if( pos1 > pos2 ){
03328         t2++;
03329       }
03330       else {
03331         t1++;
03332       }
03333     }
03334     multTrigs.common_pos.push_back(common);
03335 
03336     size_t multi_size = d_multTrigs[e].size(); //should be 2
03337     for(size_t i =0; i< multi_size; i++){
03338       multTrigs.var_binds_found.push_back(new (true) CDMap<Expr, bool> (theoryCore()->getCM()->getCurrentContext()));
03339     }
03340     multTrigs.uncomm_list.push_back(new ExprMap<CDList<Expr>* >);
03341     multTrigs.uncomm_list.push_back(new ExprMap<CDList<Expr>* >);
03342     multTrigs.univThm = thm;
03343     multTrigs.univ_id = univs_id;
03344     d_multitrigs_maps[e] = multTrigs;
03345     d_all_multTrigsInfo.push_back(multTrigs);
03346   }
03347       }
03348     }
03349 
03350   /*
03351   //setup partial triggers
03352   if(*d_usePart)    {
03353     std::vector<Trigger> trig_ex;
03354 
03355     trig_ex.clear();
03356     for( std::vector<Expr>::const_iterator i = subterms.begin(),  iend=subterms.end();  i!=iend;  i++) {
03357       if(isGoodPartTrigger(*i, bVarsThm))  {
03358   bool notfound = true;
03359   for(size_t index=0; index<d_partTriggers[e].size(); index++){
03360     if (i->subExprOf(d_partTriggers[e][index]))    {
03361       (d_partTriggers[e][index])=*i;
03362       notfound=false;
03363     }
03364   }
03365   if (notfound)
03366     d_partTriggers[e].push_back(*i);
03367       }
03368     }
03369 
03370     for (size_t  i=0; i< d_partTriggers[e].size();i++){
03371       TRACE("triggers", "partial triggers:", d_partTriggers[e][i].toString(),"");
03372     }
03373 
03374     for (size_t  i=0; i< d_partTriggers[e].size();i++){
03375       Polarity pol= Ukn;
03376       const Expr& cur = d_partTriggers[e][i];
03377       const std::set<Expr> cur_bvs = getBoundVars(cur);
03378       if(cur.getType().isBool()){
03379   DebugAssert(exprPol.count(e)>0,"unknown polarity:"+cur.toString());
03380   pol = exprPol[cur];
03381       }
03382 
03383       Trigger* t;
03384       Trigger* t_ex; //so, if a pred is PosNeg, we actually put two triggers into the list, one pos and the other neg
03385 
03386       if(PosNeg == pol && *d_usePolarity){
03387   t = new Trigger(theoryCore(), cur, Pos, cur_bvs);
03388   t_ex = new Trigger(theoryCore(), cur, Neg, cur_bvs);
03389       }
03390       else{
03391   t = new Trigger(theoryCore(), cur, pol, cur_bvs);
03392   t_ex = NULL;
03393       }
03394 
03395       if(canGetHead(cur)) {
03396   t->setHead(getHeadExpr(cur));
03397       }
03398 
03399       if(t_ex != NULL)  trig_ex.push_back(*t_ex);
03400 
03401       d_partTrigs[e].push_back(*t);
03402 
03403       TRACE("triggers", "new:part trigger pol:", pol,cur.toString());
03404     }
03405 
03406     for(size_t i=0; i<trig_ex.size(); i++){
03407       d_partTrigs[e].push_back(trig_ex[i]);
03408       TRACE("triggers", "new extra :part triggers:", trig_ex[i].getEx().toString(),"");
03409     }
03410   }
03411   */
03412 }
03413 
03414 
03415 //! test if a sub-term contains more bounded vars than quantified by out-most quantifier.
03416 int hasMoreBVs(const Expr& thm){
03417   DebugAssert(thm.isForall(), "hasMoreBVS called by non-forall exprs");
03418 
03419   const std::vector<Expr>& bvsOutmost = thm.getVars();
03420   const std::set<Expr>& bvs = getBoundVars(thm);
03421 
03422   return int(bvs.size()-bvsOutmost.size());
03423 
03424 }
03425 
03426 /*! \brief Theory interface function to assert quantified formulas
03427  *
03428  * pushes in negations and converts to either universally or existentially
03429  * quantified theorems. Universals are stored in a database while
03430  * existentials are enqueued to be handled by the search engine.
03431  */
03432 
03433 //static ExprMap<bool> found_exist;
03434 
03435 void TheoryQuant::assertFact(const Theorem& thm){
03436 
03437   if(d_maxILReached){
03438     return;
03439   }
03440   if(*d_translate) return;
03441 
03442   TRACE("quant assertfact", "assertFact => ", thm.toString(), "{");
03443   Theorem rule, result;
03444   const Expr& expr = thm.getExpr();
03445 
03446   // Ignore existentials
03447   if(expr.isExists()) {
03448     TRACE("quant assertfact", "assertFact => (ignoring existential) }", expr.toString(), "");
03449     return;
03450   }
03451 
03452   DebugAssert(expr.isForall() || (expr.isNot() && (expr[0].isExists() || expr[0].isForall())),
03453         "Theory of quantifiers cannot handle expression "
03454        + expr.toString());
03455 
03456  if(expr.isNot()) {//find the right rule to eliminate negation
03457    if(expr[0].isForall()) {
03458      rule = d_rules->rewriteNotForall(expr);
03459    }
03460    else if(expr[0].isExists()) {
03461      rule = d_rules->rewriteNotExists(expr);
03462    }
03463    result = iffMP(thm, rule);
03464  }
03465  else{
03466    result = thm;
03467  }
03468 
03469  result = d_rules->boundVarElim(result); //eliminate useless bound variables
03470 
03471 
03472  if(result.getExpr().isForall()){
03473    if(*d_useNew){
03474 
03475      if(result.getExpr().getBody().isForall()){ // if it is of the form forall x. forall. y
03476        result=d_rules->packVar(result);
03477      }
03478      result = d_rules->boundVarElim(result); //eliminate useless bound variables
03479      
03480      //      int nBVs = hasMoreBVs(result.getExpr());
03481      //      if( nBVs >= 1){
03482      // d_hasMoreBVs[result.getExpr()]=true;
03483      //      }
03484 
03485      if(result.getExpr().isForall()){
03486        d_rawUnivs.push_back(result);
03487      }
03488      else{
03489        enqueueFact(result);
03490      }
03491      return;
03492      /* -------------------------------------- */
03493      //      int nBVs = hasMoreBVs(result.getExpr());
03494 
03495      /*
03496 
03497      if(0 == nBVs){//good
03498      TRACE("quant assertfact", "assertFact => forall enqueueing: ", result.toString(), "}");
03499         d_univs.push_back(result);
03500   setupTriggers(result, d_univs.size()-1);
03501       }
03502       else if(1== nBVs){
03503   d_hasMoreBVs[result.getExpr()]=true;
03504   const Expr& body = result.getExpr().getBody();
03505 
03506   if(*d_usePullVar){
03507     if((body.isAnd() && body[1].isForall()) || (body.isImpl() && body[1].isForall()) ){
03508       result=d_rules->pullVarOut(result);
03509 
03510       TRACE("quant assertfact", "assertFact => pull-var enqueueing: ", result.toString(), "}");
03511 
03512       d_univs.push_back(result);
03513       setupTriggers(result,  d_univs.size()-1);
03514     }
03515   }
03516   else{
03517     TRACE("quant assertfact", "debug:not recognized case", result.toString(), thm.toString());
03518 
03519     d_univs.push_back(result);
03520     setupTriggers(result,  d_univs.size()-1);
03521     return;
03522   }
03523       }
03524       else{
03525   d_hasMoreBVs[result.getExpr()]=true;
03526   d_univs.push_back(result);
03527   setupTriggers(result,  d_univs.size()-1);
03528   return;
03529       }
03530       */
03531    }
03532    else{
03533 
03534      TRACE("quant assertfact", "assertFact => old-fashoin enqueueing: ", result.toString(), "}");
03535      //      cout<<"error"<<endl;
03536      d_univs.push_back(result);
03537    }
03538  }
03539  else { //quantifier got eliminated or is an existantial formula
03540    TRACE("quant assertfact", "assertFact => non-forall enqueueing: ", result.toString(), "}");
03541    if(*d_useGFact || true ){
03542      //      addGlobalLemma(result, -1);
03543      enqueueFact(result);
03544    }
03545    else{
03546      enqueueFact(result);
03547      //    enqueueSE(result);
03548    }
03549    /*
03550      {
03551      Expr expr = result.getExpr();
03552      if(expr.isNot()) {
03553      expr = expr[0];
03554      }  ;
03555      if (expr.isExists()){
03556      if(found_exist.find(expr) != found_exist.end()) {
03557      //   cout<<"again " << expr<<endl;
03558      return;
03559      }
03560      else  found_exist[expr]=true;
03561      }
03562      }
03563    */
03564 
03565    //
03566  }
03567 }
03568 
03569 void TheoryQuant::recGoodSemMatch(const Expr& e,
03570           const std::vector<Expr>& bVars,
03571           std::vector<Expr>& newInst,
03572           std::set<std::vector<Expr> >& instSet)
03573 {
03574   size_t curPos = newInst.size();
03575   if (bVars.size() == curPos)    {
03576     Expr simpleExpr = simplifyExpr(e.substExpr(bVars,newInst));
03577     if (simpleExpr.hasFind()){
03578       std::vector<Expr> temp = newInst;
03579       instSet.insert(temp);
03580       TRACE("quant yeting", "new inst found for ", e.toString()+" ==> ", simpleExpr.toString());
03581     };
03582   }
03583   else {
03584     Type t = getBaseType(bVars[curPos]);
03585     std::vector<Expr> tyExprs= d_typeExprMap[t];
03586     if (0 == tyExprs.size())  {
03587       return;//has some problem
03588     }
03589     else{
03590       for (size_t i=0;i<tyExprs.size();i++){
03591   newInst.push_back(tyExprs[i]);
03592   recGoodSemMatch(e,bVars,newInst,instSet);
03593   newInst.pop_back();
03594       }
03595     }
03596   }
03597 }
03598 
03599 
03600 bool isIntx(const Expr& e, const Rational& x){
03601   if(e.isRational() && e.getRational()==x)
03602     return true;
03603   else return false;
03604 }
03605 
03606 
03607 Expr getLeft(const Expr& e){
03608   if(e.getKind()!= PLUS) return null_expr;
03609   if(e.arity() != 3) return null_expr;
03610   Expr const_expr, minus ,pos;
03611   int numMinus=0, numPos=0, numConst=0;;
03612   for(int i=0; i<e.arity(); i++){
03613     if((e[i]).getKind() == MULT){
03614       if(isIntx(e[i][0], -1)){
03615   numMinus++;
03616   minus=e[i][1];
03617       }
03618       else{
03619   numPos++;
03620   pos=e[i];
03621       }
03622     }
03623     else if(e[i].isRational())      {
03624       const_expr = e[i];
03625       numConst++;
03626     }
03627     else{
03628       numPos++;
03629       pos=e[i];
03630     }
03631   }
03632   if(1==numPos && 1==numConst && 1==numMinus){
03633     return minus;
03634   }
03635   else{
03636     return null_expr;
03637   }
03638 }
03639 
03640 Expr getRight(const Expr& e){
03641   if(e.getKind()!= PLUS) return null_expr;
03642   if(e.arity() != 3) return null_expr;
03643   Expr const_expr, minus ,pos;
03644   int numMinus=0, numPos=0, numConst=0;;
03645 
03646   for(int i=0; i<e.arity(); i++){
03647     if((e[i]).getKind() == MULT){
03648       if(isIntx(e[i][0], -1)){
03649   numMinus++;
03650   minus=e[i][1];
03651       }
03652       else{
03653   numPos++;
03654   pos=e[i];
03655       }
03656     }
03657     else if(e[i].isRational())      {
03658       const_expr = e[i];
03659       numConst++;
03660     }
03661     else{
03662       numPos++;
03663       pos=e[i];
03664     }
03665   }
03666 
03667   if(1==numPos && 1==numConst && 1==numMinus){
03668     if(isIntx(const_expr,0)){
03669       return pos;
03670     }
03671     else{
03672       //      return null_expr;
03673       return Expr(PLUS, const_expr, pos);
03674     }
03675   }
03676   else{
03677     return null_expr;
03678   }
03679   return null_expr;
03680 }
03681 
03682 inline void TheoryQuant::add_parent(const Expr& parent){
03683   ExprMap<CDList<Expr>* >::iterator iter;
03684   for(int i=0; i< parent.arity(); i++){
03685     const Expr& child = parent[i];
03686     iter = d_parent_list.find(child);
03687     if(d_parent_list.end() == iter){
03688       d_parent_list[child] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
03689       d_parent_list[child]->push_back(parent);
03690     }
03691     else{
03692       iter->second->push_back(parent);
03693     }
03694   }
03695 }
03696 
03697 void TheoryQuant::collectChangedTerms(CDList<Expr>& changed){
03698   ExprMap<bool> eqs_hash;
03699   ExprMap<bool> changed_hash;
03700   /*
03701   {
03702     for(ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.begin(), iter_end=d_eq_list.end();
03703   iter != iter_end; iter++){
03704       CDList<Expr>* cur_eqs = iter->second;
03705       int begin_pos;
03706       Expr head = iter->first;
03707       if(d_eq_pos.find(head) == d_eq_pos.end()){
03708   begin_pos=0;
03709   d_eq_pos[head]= new(true) CDO<size_t>(theoryCore()->getCM()->getCurrentContext(), 0, 0);
03710 
03711       }
03712       else{
03713   begin_pos = *(d_eq_pos[head]);
03714       }
03715       for(size_t i=begin_pos; i<cur_eqs->size(); i++){
03716   eqs_hash[(*cur_eqs)[i]]=true;
03717       }
03718       (d_eq_pos[head])->set(cur_eqs->size());
03719     }
03720     }*/
03721   for(size_t i=d_eqs_pos; i<d_eqs.size(); i++){
03722     eqs_hash[d_eqs[i]]=true;
03723   }
03724   d_eqs_pos.set(d_eqs.size());
03725   {
03726     for(ExprMap<bool>::iterator iter = eqs_hash.begin(), iter_end = eqs_hash.end(); iter != iter_end; iter++){
03727       const Expr& cur_ex = iter->first;
03728       ExprMap<CDList<Expr>* >::iterator iter_parent = d_parent_list.find(cur_ex);
03729       if(d_parent_list.end() != iter_parent){
03730   CDList<Expr>* cur_parents = iter_parent->second;
03731   for(size_t i=0; i<cur_parents->size(); i++){
03732     changed_hash[(*cur_parents)[i]]=true;
03733   }
03734       }
03735     }
03736   }
03737   {
03738     for(ExprMap<bool>::iterator iter = changed_hash.begin(), iter_end = changed_hash.end(); iter != iter_end; iter++){
03739       changed.push_back(iter->first);
03740     }
03741   }
03742 }
03743 
03744 /*
03745 inline bool TheoryQuant::matchChild(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
03746   cout<<"error, should not be called, matchChild" << endl;
03747   if(gterm.arity() != vterm.arity()) {
03748     return false;
03749   }
03750   for(int i = 0 ; i< gterm.arity(); i++){ //we should make the matching "flat"
03751     const Expr& cur_v = vterm[i];
03752     const Expr& cur_g = gterm[i];
03753     if(BOUND_VAR == cur_v.getKind()){
03754       ExprMap<Expr>::iterator p = env.find(cur_v);
03755       if ( p != env.end()){
03756   if (simplifyExpr(cur_g) != simplifyExpr(p->second)){
03757     return false;
03758   }
03759       }
03760       else {
03761   env[cur_v] = simplifyExpr(cur_g);
03762       }
03763     }
03764     else if (!cur_v.containsBoundVar()){
03765       if(simplifyExpr(cur_v) != simplifyExpr(cur_g)){
03766   return false;
03767       }
03768     }
03769     else{
03770       if (false == recSynMatch(cur_g, cur_v, env)){
03771   return false;
03772       }
03773     }
03774   }
03775   return true;
03776 }
03777 
03778 inline void TheoryQuant::matchChild(const Expr& gterm, const Expr& vterm, vector<ExprMap<Expr> >& binds){
03779   cout<<"-error, should not be called more, matchChild" << endl;
03780   ExprMap<Expr> env;
03781   if(gterm.arity() != vterm.arity()) {
03782     return;
03783   }
03784 
03785   for(int i = 0 ; i< gterm.arity(); i++){
03786     const Expr& cur_v = vterm[i];
03787     const Expr& cur_g = gterm[i];
03788     if(BOUND_VAR == cur_v.getKind()){
03789       ExprMap<Expr>::iterator p = env.find(cur_v);
03790       if ( p != env.end()){
03791   if (simplifyExpr(cur_g) != simplifyExpr(p->second)){
03792     return;
03793   }
03794       }
03795       else {
03796   env[cur_v] = simplifyExpr(cur_g);
03797       }
03798     }
03799     else if (!cur_v.containsBoundVar()){
03800       if(simplifyExpr(cur_v) != simplifyExpr(cur_g)){
03801   return ;
03802       }
03803     }
03804     else{
03805       if (false == recSynMatch(cur_g, cur_v, env)){
03806   return;
03807       }
03808     }
03809   }
03810   binds.push_back(env);
03811   return;
03812 }
03813 */
03814 
03815 /* multMatchChild
03816   input : partial bindings in binds
03817   output: successful bindings in binds
03818 */
03819 inline bool TheoryQuant::multMatchChild(const Expr& gterm, const Expr& vterm, vector<ExprMap<Expr> >& binds, bool top){
03820   if(gterm.arity() != vterm.arity()) {
03821     TRACE("multmatch", "not same kind", gterm , vterm);
03822     return false;
03823   }
03824 
03825   //  if (binds.size()>1) {cout<<"match child >1 " <<endl;};
03826 
03827   vector<Expr> allGterms;
03828   allGterms.push_back(gterm);
03829 
03830 
03831  if(!gterm.getSig().isNull() ){
03832     Expr gtermSig = gterm.getSig().getRHS();
03833     if(!top && gterm.hasFind() && !gterm.isAtomicFormula() ) {
03834       Expr curCandidateGterm = gterm.getEqNext().getRHS();
03835       while (curCandidateGterm != gterm){
03836   if(getHead(curCandidateGterm) == getHead(gterm) 
03837      && !curCandidateGterm.getSig().isNull() 
03838      &&   curCandidateGterm.getSig().getRHS() != gtermSig
03839      && getExprScore(curCandidateGterm) <= d_curMaxExprScore
03840      ){
03841     allGterms.push_back(curCandidateGterm);
03842   }
03843   curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
03844       }
03845     }
03846   }
03847 
03848 
03849   vector<ExprMap<Expr> > returnBinds;
03850   for(size_t curGtermIndex =0; curGtermIndex < allGterms.size(); curGtermIndex++)
03851   {
03852     vector<ExprMap<Expr> > currentBinds(binds);
03853 
03854     if(0 == currentBinds.size()){//we need something to work on, even it is empty
03855       ExprMap<Expr> emptyEnv;
03856       currentBinds.push_back(emptyEnv);
03857     }
03858 
03859     Expr gterm = allGterms[curGtermIndex]; //be careful, this gterm hides the gterm in the beginning. fix this soon
03860 
03861     vector<ExprMap<Expr> > nextBinds;
03862 
03863     for(int i = 0 ; i< gterm.arity(); i++){
03864       const Expr& curVterm = vterm[i];
03865       const Expr& curGterm = gterm[i];
03866 
03867       for(size_t curEnvIndex =0; curEnvIndex < currentBinds.size(); curEnvIndex++){
03868   //maybe we should exchange the iteration of ith child and curentBinds.
03869   ExprMap<Expr>& curEnv(currentBinds[curEnvIndex]);
03870   if(BOUND_VAR == curVterm.getKind()){
03871     ExprMap<Expr>::iterator iterVterm = curEnv.find(curVterm);
03872     if ( iterVterm != curEnv.end()){
03873       if (simplifyExpr(curGterm) == simplifyExpr(iterVterm->second)){
03874         nextBinds.push_back(curEnv); //success, record the good binding
03875       } //else do nothing
03876     }
03877     else {
03878       curEnv[curVterm] = simplifyExpr(curGterm);
03879       nextBinds.push_back(curEnv); // success, record the good binding
03880     }
03881   }
03882   else if (!curVterm.containsBoundVar()){
03883     if(simplifyExpr(curVterm) == simplifyExpr(curGterm)){
03884       nextBinds.push_back(curEnv); // sueecess, record the good
03885     } //else do nothing
03886   }
03887   else{
03888     vector<ExprMap<Expr> > newBinds;
03889     newBinds.push_back(curEnv);
03890     bool goodChild = recMultMatch(curGterm, curVterm, newBinds);
03891     if(goodChild){
03892       for(vector<ExprMap<Expr> >::iterator i = newBinds.begin(), iend = newBinds.end(); i != iend; i++){
03893         nextBinds.push_back(*i);
03894       }
03895     }
03896   }
03897       }
03898       currentBinds = nextBinds; //nextBinds are good bindings
03899       nextBinds.clear();
03900     }
03901     for(size_t curBindsIndex=0; curBindsIndex < currentBinds.size(); curBindsIndex++){
03902       returnBinds.push_back(currentBinds[curBindsIndex]);
03903     }
03904 
03905   }
03906 
03907   //  binds = currentBinds;
03908   binds = returnBinds;
03909   return (binds.size() > 0) ? true : false;
03910 }
03911 
03912 
03913 //multMatchTop can be called anywhere
03914 inline bool TheoryQuant::multMatchTop(const Expr& gterm, const Expr& vterm, vector<ExprMap<Expr> >& binds){
03915   vector<ExprMap<Expr> > currentBinds(binds);
03916 
03917   if(0 == currentBinds.size()){//we need something to work on, even it is empty
03918     ExprMap<Expr> emptyEnv;
03919     currentBinds.push_back(emptyEnv);
03920   }
03921 
03922   vector<ExprMap<Expr> > nextBinds;
03923 
03924   const Expr& curVterm = vterm;
03925   const Expr& curGterm = gterm;
03926 
03927   for(size_t curEnvIndex =0; curEnvIndex < currentBinds.size(); curEnvIndex++){
03928     ExprMap<Expr>& curEnv(currentBinds[curEnvIndex]);
03929     vector<ExprMap<Expr> > newBinds;
03930     newBinds.push_back(curEnv);
03931     bool goodChild = recMultMatch(curGterm, curVterm, newBinds);
03932     if(goodChild){
03933       for(vector<ExprMap<Expr> >::iterator i = newBinds.begin(), iend = newBinds.end(); i != iend; i++){
03934   nextBinds.push_back(*i);
03935       }
03936     }
03937   }
03938   binds = nextBinds; //nextBinds stores the good bindings
03939   return (binds.size() > 0) ? true : false;
03940 }
03941 
03942 
03943 //match a gterm against all the trigs in d_allmap_trigs
03944 void TheoryQuant::matchListOld(const CDList<Expr>& glist, size_t gbegin, size_t gend){
03945   for(size_t g_index = gbegin; g_index < gend; g_index++){
03946 
03947     const Expr& gterm = glist[g_index];
03948     //    cout<<"matching old "<<gterm<<endl;
03949     if(gterm.isEq()){
03950       continue; // we do not match with equality
03951     }
03952 
03953      if(gterm.getSig().isNull() ){
03954        if ( ! ( (gterm.hasFind() && !canGetHead(gterm.getFind().getRHS())) || gterm.getType().isBool() )  ){
03955 //   cout<<"gterm skipped " << gterm << endl;
03956 //   cout<<"Find? " << (gterm.hasFind() ? gterm.getFind().getExpr().toString() : "NO " ) << endl;
03957 //   cout<<"Rep?  " << (gterm.hasRep() ? gterm.getRep().getExpr().toString() : "NO " ) << endl;
03958    continue;
03959        }
03960      }
03961 
03962     Expr head = getHead(gterm);
03963 
03964     ExprMap<CDMap<Expr, CDList<dynTrig>* > *>::iterator iter = d_allmap_trigs.find(head);
03965     if(d_allmap_trigs.end() == iter) continue;
03966     CDMap<Expr, CDList<dynTrig>*>* cd_map = iter->second;
03967 
03968 //     if(cd_map->size()>10){
03969 //       cout<<"map size1:"<<cd_map->size()<<endl;
03970 //       cout<<head<<endl;
03971 //     }
03972 
03973     CDMap<Expr, CDList<dynTrig>*>::iterator iter_trig = (*cd_map).begin();
03974     CDMap<Expr, CDList<dynTrig>*>::iterator iter_trig_end = (*cd_map).end();
03975 
03976     for(;iter_trig != iter_trig_end; iter_trig++){
03977       CDList<dynTrig>* cur_list = (*iter_trig).second;
03978       if(1 == cur_list->size() || null_expr == head || gterm.getType().isBool() ){
03979   for(size_t cur_index =0; cur_index < cur_list->size(); cur_index++){
03980 
03981     const Trigger& cur_trig = (*cur_list)[cur_index].trig;
03982     size_t univ_id = (*cur_list)[cur_index].univ_id;
03983     vector<ExprMap<Expr> > binds;
03984     const Expr& vterm = cur_trig.trig;
03985     if(vterm.getKind() != gterm.getKind()) continue;
03986 
03987 
03988 //    if(*d_useNewEqu){
03989 //      if  ( d_allout && cur_trig.isSuperSimple ) continue; //delete this after test yeting
03990 //    }
03991 
03992     if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans && !cur_trig.isMulti) continue;
03993       //      if  ( d_allout && cur_trig.isSimple ) continue;
03994 
03995     newTopMatch(gterm, vterm, binds, cur_trig);
03996 
03997     for(size_t i=0; i<binds.size(); i++){
03998       ExprMap<Expr>& cur_map = binds[i];
03999       vector<Expr> bind_vec;
04000       const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
04001       for(size_t j=0; j< bVarsThm.size(); j++){
04002         bind_vec.push_back(cur_map[bVarsThm[j]]);
04003       }
04004       synNewInst(univ_id, bind_vec, gterm, cur_trig);
04005     }
04006   }
04007       }
04008       else if ( cur_list->size() > 1){
04009 
04010   const Trigger& cur_trig = (*cur_list)[0].trig;//here we have a polarity problem
04011 
04012   const Expr& general_vterm = (*iter_trig).first;
04013 
04014   //  cout<<"matching new trig case 2:"<<general_vterm<<endl;
04015 
04016   if(general_vterm.getKind() != gterm.getKind()) continue;
04017   vector<ExprMap<Expr> > binds;
04018 
04019 //  if(*d_useNewEqu){
04020 //    if  ( d_allout && cur_trig.isSuperSimple ) continue; //delete this after test yeting
04021 //  }
04022   if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans && !cur_trig.isMulti) continue;
04023   //if  ( d_allout && cur_trig.isSimple ) continue;
04024 
04025   newTopMatch(gterm, general_vterm, binds, cur_trig);
04026 
04027   for(size_t bindsIndex = 0 ; bindsIndex < binds.size() ; bindsIndex++){
04028     //    cout<<"i = " << bindsIndex << " : " << exprMap2string(binds[bindsIndex]) << endl ;
04029   }
04030 
04031   if(binds.size() <= 0) continue;
04032 
04033   for(size_t trig_index = 0; trig_index< cur_list->size(); trig_index++){
04034     size_t univ_id = (*cur_list)[trig_index].univ_id;
04035     const ExprMap<Expr>& trig_map = (*cur_list)[trig_index].binds;
04036     const Trigger& ind_cur_trig = (*cur_list)[trig_index].trig;
04037     for(size_t i=0; i<binds.size(); i++){
04038       ExprMap<Expr>& cur_map = binds[i];
04039       vector<Expr> bind_vec;
04040       const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
04041       for(size_t j=0; j< bVarsThm.size(); j++){
04042         const Expr& inter=(*(trig_map.find(bVarsThm[j]))).second;
04043         const Expr& inter2 = cur_map[inter];
04044         bind_vec.push_back(inter2);
04045       }
04046       //      cout<<"==++ for instantiation " << d_univs[univ_id] <<endl;
04047       //      cout<<"==--  bings " << vectorExpr2string(bind_vec) <<endl;
04048       synNewInst(univ_id, bind_vec, gterm, ind_cur_trig);
04049     }
04050     //    cout<<"==** end \n";
04051   }
04052       }
04053       else{
04054   FatalAssert(false, "error in matchlistold");
04055       }
04056     }//end of for each trig begins with head
04057   }//end of each gterm
04058 }
04059 
04060 void TheoryQuant::delNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs){
04061   //return;
04062   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator i = new_trigs.begin();
04063   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator iend = new_trigs.end();
04064   for(; i!=iend; i++){
04065     ExprMap<std::vector<dynTrig>*>* cur_new_cd_map = i->second;
04066     ExprMap<vector<dynTrig>* >::iterator j = cur_new_cd_map->begin();
04067     ExprMap<vector<dynTrig>* >::iterator jend = cur_new_cd_map->end();
04068       for(; j!=jend; j++){
04069   Expr general_trig = j->first;
04070   vector<dynTrig>* trigs = j->second;
04071   delete trigs;
04072       }
04073       delete cur_new_cd_map;
04074     }
04075   new_trigs.clear();
04076 }
04077 
04078 
04079 void TheoryQuant::combineOldNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs){
04080   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator i = new_trigs.begin();
04081   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator iend = new_trigs.end();
04082   for(; i!=iend; i++){
04083     ExprMap<std::vector<dynTrig>*>* cur_new_cd_map = i->second;
04084     Expr head = i->first;
04085     ExprMap<CDMap<Expr, CDList<dynTrig>* >* >::iterator old_iter = d_allmap_trigs.find(head);
04086     if(d_allmap_trigs.end() == old_iter){
04087       CDMap<Expr, CDList<dynTrig>* >* old_cd_map =
04088   //  new(true) CDMap<Expr, CDList<dynTrig>* > (theoryCore()->getCM()->getCurrentContext());
04089   new(false) CDMap<Expr, CDList<dynTrig>* > (theoryCore()->getCM()->getCurrentContext());
04090       d_allmap_trigs[head] = old_cd_map;
04091       ExprMap<vector<dynTrig>* >::iterator j = cur_new_cd_map->begin();
04092       ExprMap<vector<dynTrig>* >::iterator jend = cur_new_cd_map->end();
04093       for(; j!=jend; j++){
04094   Expr general_trig = j->first;
04095   vector<dynTrig>* trigs = j->second;
04096   CDList<dynTrig>* old_cd_list =
04097     //new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
04098     new(false) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
04099   (*old_cd_map)[general_trig] = old_cd_list;
04100   for(size_t k=0; k<trigs->size(); k++){
04101     (*old_cd_list).push_back((*trigs)[k]);
04102     //    cout<<"combined 1 "<<(*trigs)[k].trig.getEx()<<endl;
04103   }
04104   //  delete trigs;
04105       }
04106       //      delete cur_new_cd_map;
04107     }
04108     else{
04109       CDMap<Expr, CDList<dynTrig>* >* old_cd_map = old_iter->second;
04110       ExprMap<std::vector<dynTrig>*>::iterator j = cur_new_cd_map->begin();
04111       ExprMap<std::vector<dynTrig>*>::iterator jend = cur_new_cd_map->end();
04112       for(; j!=jend; j++){
04113   Expr general_trig = j->first;
04114   vector<dynTrig>* trigs = j->second;
04115   CDMap<Expr, CDList<dynTrig>* >::iterator old_trigs_iter = old_cd_map->find(general_trig);
04116   CDList<dynTrig>* old_cd_list;
04117   if(old_cd_map->end() == old_trigs_iter){
04118    old_cd_list =
04119      //new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
04120      new(false) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
04121    (*old_cd_map)[general_trig] = old_cd_list;
04122   }
04123   else{
04124     old_cd_list = (*old_trigs_iter).second;
04125   }
04126   for(size_t k=0; k<trigs->size(); k++){
04127     (*old_cd_list).push_back((*trigs)[k]);
04128     //    cout<<"combined 2 "<<(*trigs)[k].trig.getEx()<<endl;
04129   }
04130   //  delete trigs;
04131       }
04132       //      delete cur_new_cd_map;
04133     }
04134   }
04135   delNewTrigs(new_trigs);
04136   new_trigs.clear();
04137 }
04138 
04139 //match a gterm against all the trigs in d_allmap_trigs
04140 void TheoryQuant::matchListNew(ExprMap<ExprMap<vector<dynTrig>*>*>& new_trigs,
04141              const CDList<Expr>& glist,
04142              size_t gbegin,
04143              size_t gend){
04144   //return;
04145   //  if(!d_allout) return;
04146   for(size_t g_index = gbegin; g_index<gend; g_index++){
04147 
04148     const Expr& gterm = glist[g_index];
04149     //    cout<<"matching new "<<gterm<<endl;
04150     if(gterm.isEq()){
04151       continue; // we do not match with equality
04152     }
04153 
04154     if(gterm.getSig().isNull()){
04155       //add the code as in matchlistold
04156 
04157 //      continue;
04158     }
04159 
04160     Expr head = getHead(gterm);
04161 
04162     ExprMap<ExprMap<vector<dynTrig>* > *>::iterator iter = new_trigs.find(head);
04163     if(new_trigs.end() == iter) continue;
04164     ExprMap<vector<dynTrig>*>* cd_map = iter->second;
04165 //     if(cd_map->size()>10){
04166 //       cout<<"map size2:"<<cd_map->size()<<endl;
04167 //       cout<<head<<endl;
04168 //     }
04169 
04170     ExprMap<vector<dynTrig>*>::iterator iter_trig = (*cd_map).begin();
04171     ExprMap<vector<dynTrig>*>::iterator iter_trig_end = (*cd_map).end();
04172 
04173     for(;iter_trig != iter_trig_end; iter_trig++){
04174 
04175       vector<dynTrig>* cur_list = (*iter_trig).second;
04176       if(1 == cur_list->size() || null_expr == head ||  gterm.getType().isBool() ){
04177   for(size_t cur_index =0; cur_index < cur_list->size(); cur_index++){
04178     const Trigger& cur_trig = (*cur_list)[cur_index].trig;
04179 
04180 //    if(*d_useNewEqu){
04181 //    if  ( d_allout &&  cur_trig.isSuperSimple ) continue; //delete this after test yeting
04182 //    }
04183 
04184     if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans) continue;
04185 
04186     size_t univ_id = (*cur_list)[cur_index].univ_id;
04187     vector<ExprMap<Expr> > binds;
04188     const Expr& vterm = cur_trig.trig;
04189     if(vterm.getKind() != gterm.getKind()) continue;
04190     newTopMatch(gterm, vterm, binds, cur_trig);
04191     for(size_t i=0; i<binds.size(); i++){
04192       ExprMap<Expr>& cur_map = binds[i];
04193       vector<Expr> bind_vec;
04194       const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
04195       for(size_t j=0; j< bVarsThm.size(); j++){
04196         bind_vec.push_back(cur_map[bVarsThm[j]]);
04197       }
04198       synNewInst(univ_id, bind_vec, gterm, cur_trig);
04199     }
04200   }
04201       }
04202       else if ( cur_list->size() > 1){
04203 
04204   const Trigger& cur_trig = (*cur_list)[0].trig;//here we have a polarity problem
04205 
04206 //  if(*d_useNewEqu){
04207 //    if  ( d_allout &&  cur_trig.isSuperSimple ) continue; //delete this after test yeting
04208 //  }
04209 
04210 //  if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans) continue;
04211 
04212   const Expr& general_vterm = (*iter_trig).first;
04213   if(general_vterm.getKind() != gterm.getKind()) continue;
04214   vector<ExprMap<Expr> > binds;
04215   newTopMatch(gterm, general_vterm, binds, cur_trig);
04216 
04217   if(binds.size() <= 0) continue;
04218   for(size_t trig_index = 0; trig_index< cur_list->size(); trig_index++){
04219     size_t univ_id = (*cur_list)[trig_index].univ_id;
04220     const Trigger& ind_cur_trig = (*cur_list)[trig_index].trig;
04221     const ExprMap<Expr>& trig_map = (*cur_list)[trig_index].binds;
04222 
04223     for(size_t i=0; i<binds.size(); i++){
04224       ExprMap<Expr>& cur_map = binds[i];
04225       vector<Expr> bind_vec;
04226       const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
04227       for(size_t j=0; j< bVarsThm.size(); j++){
04228         const Expr& inter=(*(trig_map.find(bVarsThm[j]))).second;
04229         const Expr& inter2 = cur_map[inter];
04230         bind_vec.push_back(inter2);
04231       }
04232       synNewInst(univ_id, bind_vec, gterm, ind_cur_trig);
04233     }
04234   }
04235       }
04236       else{
04237   FatalAssert(false, "error in matchlistnew");
04238       }
04239     }//end of for each trig begins with head
04240   }// end of each gterm
04241 }
04242 
04243 
04244 
04245 //void TheoryQuant::newTopMatchNoSig(const Expr& gtermOrg,
04246 void TheoryQuant::newTopMatchNoSig(const Expr& gterm,
04247            const Expr& vterm,
04248            vector<ExprMap<Expr> >& binds,
04249            const Trigger& trig){
04250 
04251   //  cout<<"matching " << gterm << endl << "----" << endl << vterm << endl;
04252 
04253   if(trig.isSuperSimple){
04254     ExprMap<Expr>  cur_bind;
04255     for(int i = vterm.arity()-1; i>=0 ; i--){
04256       cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
04257     }
04258     binds.push_back(cur_bind);
04259     return;
04260   }
04261 
04262   if(trig.isSimple){
04263     ExprMap<Expr>  cur_bind;
04264     for(int i = vterm.arity()-1; i>=0 ; i--){
04265       if(BOUND_VAR != vterm[i].getKind()){
04266   if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
04267     return ;
04268   }
04269       }
04270       else{
04271   if(getBaseType(vterm[i]) == (getBaseType(gterm[i]))){
04272     cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
04273   }
04274   else return;
04275       }
04276     }
04277     binds.push_back(cur_bind);
04278     return;
04279   }
04280 
04281   if(!isSysPred(vterm)){ //then gterm cannot be a syspred
04282     if(!gterm.getType().isBool()){
04283       //      res2= recSynMatch(gterm, vterm, env);
04284       multMatchChild(gterm, vterm, binds, true);
04285       return;
04286     }
04287 
04288     //    DebugAssert(falseExpr()==findExpr(gterm) || trueExpr()==findExpr(gterm), " why ");
04289 
04290     multMatchChild(gterm, vterm, binds, true);
04291     return;
04292 
04293     if(!*d_usePolarity){
04294       //      return recSynMatch(gterm, vterm, env);
04295       multMatchChild(gterm, vterm, binds);
04296       return;
04297     }
04298 
04299     const bool gtrue = (trueExpr()==findExpr(gterm));
04300     //    const bool gtrue = (trueExpr()==simplifyExpr(gterm));
04301     if(gtrue ){
04302       if((Neg==trig.polarity || PosNeg==trig.polarity)) {
04303   //  return recSynMatch(gterm, vterm, env);
04304   multMatchChild(gterm, vterm, binds);
04305   return;
04306       }
04307       else{
04308   //  cout<<"returned 1"<<endl;
04309   return;
04310       }
04311     }
04312     const bool gfalse = (falseExpr()==findExpr(gterm));
04313     //const bool gfalse = (falseExpr()==simplifyExpr(gterm));
04314     if(gfalse){
04315       if((Pos==trig.polarity || PosNeg==trig.polarity)) {
04316   //  return recSynMatch(gterm, vterm, env);
04317   multMatchChild(gterm, vterm, binds); //it is possible that we need binds here, not a single bind
04318   return;
04319       }
04320       else{
04321   //  cout<<"returned 2"<<endl;
04322   return;
04323       }
04324     }
04325 
04326 //     cout<<"impossible here in new top match"<<endl;
04327 //     cout<<"vterm "<<vterm<<endl;
04328 //     cout<<"gterm " <<gterm<<endl;
04329 //     cout<<trig.polarity<<endl;
04330 //     cout<<"gtrue and gfalse: " << gtrue<<" |and| " <<gfalse<<endl;
04331 //     return;
04332     multMatchChild(gterm, vterm, binds);
04333 
04334     return;
04335   }
04336   else{ // must be syspreds
04337     //we can move the work to split vterm into left and right into setuptriggers
04338     Expr gl = getLeft(gterm[1]);
04339     Expr gr = getRight(gterm[1]);
04340 
04341     if(null_expr == gr || null_expr == gl){
04342       gl = gterm[0];
04343       gr = gterm[1];
04344     }
04345 
04346     Expr vr, vl;
04347     Expr tvr, tvl;
04348 
04349     tvr=null_expr;
04350     tvl=null_expr;
04351 
04352     if(isGE(vterm) || isGT(vterm)){
04353       vr = vterm[0];
04354       vl = vterm[1];
04355     }
04356     else if(isLE(vterm) || isLT(vterm)){
04357       vr = vterm[1];
04358       vl = vterm[0];
04359     }
04360     else{
04361       FatalAssert(false, "impossilbe in toppred");
04362     }
04363 
04364     if(isIntx(vl,0)){
04365       tvl = getLeft(vr);
04366       tvr = getRight(vr);
04367     }
04368     else if(isIntx(vr,0)) {
04369       tvl = getLeft(vl);
04370       tvr = getRight(vl);
04371     }
04372 
04373     if( (null_expr != tvl) && (null_expr != tvr)){
04374       vl = tvl;
04375       vr = tvr;
04376     }
04377 
04378 
04379     const bool gtrue = (trueExpr()==findExpr(gterm));
04380     const bool gfalse = (falseExpr()==findExpr(gterm));
04381 
04382     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
04383 
04384     //    DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
04385 
04386     if(!*d_usePolarity){
04387       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
04388   return;
04389       }
04390       else{
04391   return;
04392       }
04393     }
04394     if((Neg==trig.polarity || PosNeg==trig.polarity)) {
04395       if (( gtrue ) )  {
04396   if (multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
04397     return;
04398   }
04399   else{
04400     return;
04401   }
04402       }
04403       else {
04404   if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
04405     return;
04406   }
04407   else{
04408     return;
04409   }
04410       }
04411     }
04412     else if((Pos==trig.polarity || PosNeg==trig.polarity)) {
04413       if (( gfalse )) {
04414   if(multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
04415     return;
04416   }
04417   else{
04418     return;
04419   }
04420       }
04421       else {
04422   if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
04423     return;
04424   }
04425   else{
04426     return;
04427   }
04428       }
04429     }
04430     else {
04431       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
04432   // it is possible that cur_bind will be binds
04433   return;
04434       }
04435       else{
04436   return;
04437       }
04438       return;
04439     }
04440   }
04441 }
04442 
04443 
04444 
04445 // std::string exprChild2string(const Expr& expr){
04446 //   std::string result;
04447 //   result.append("head is: ");
04448 //   result.append(getHead(expr).toString());
04449 //   result.append("\n");
04450 //   for(int i = 0; i < expr.arity(); i++){
04451 //     result.append(int2string(i));
04452 //     result.append(": ");
04453 //     result.append(expr[i].toString());
04454 //     result.append("\n");
04455 //   }
04456 //   result.append("---- end ---- \n");
04457 //   return result;
04458 // }
04459 
04460 //wrap function for newTopMatch, for test only
04461 void TheoryQuant::newTopMatch(const Expr& gtermOrg,
04462             const Expr& vterm,
04463             vector<ExprMap<Expr> >& binds,
04464             const Trigger& trig){
04465 
04466   //return   newTopMatchSig(gtermOrg,vterm, binds, trig);
04467 
04468   return   newTopMatchNoSig(gtermOrg,vterm, binds, trig);
04469 
04470 //   cout<<"gterm org: " << gtermOrg << endl;
04471 //   cout<<"vterm org: " << vterm << endl;
04472 
04473 //   if(isPow(gtermOrg)){
04474 //     if(isIntx(gtermOrg[0],2)){
04475 //       vector<Expr> mults;
04476 //       mults.push_back(gtermOrg[1]);
04477 //       mults.push_back(gtermOrg[1]);
04478 //       cout<<"new expr" << multExpr(mults) << endl;;
04479 //     }
04480 //     else{
04481 //       cout <<"cannot do this"<<endl;
04482 //     }
04483 
04484 //   }
04485 
04486   vector<ExprMap<Expr> > oldBinds;
04487   newTopMatchNoSig(gtermOrg,vterm, oldBinds, trig);
04488   vector<ExprMap<Expr> > newBinds;
04489   newTopMatchSig(gtermOrg,vterm, newBinds, trig);
04490 
04491   vector<ExprMap<Expr> > oldBindsBack(oldBinds);
04492   vector<ExprMap<Expr> > newBindsBack(newBinds);
04493 
04494   simplifyVectorExprMap(oldBinds);
04495   simplifyVectorExprMap(newBinds);
04496 
04497   if (false && oldBinds != newBinds){
04498 
04499     cout<<"let us see" << endl;
04500     cout<< "===gterm is    : " << gtermOrg << endl ;;
04501 //     cout<< exprChild2string(gtermOrg) << endl;
04502 //     cout<< exprChild2string(gtermOrg[0]) << endl;
04503 //     cout<< exprChild2string(gtermOrg[1]) << endl;
04504     if(gtermOrg.isApply() && gtermOrg.hasSig()){
04505       Expr sig = gtermOrg.getSig().getRHS();
04506       cout << "\n---gterm sig is: " << sig << endl;
04507 //       cout << exprChild2string(sig) << endl;
04508 //       cout << exprChild2string(sig[0]) << endl;
04509 //       cout << exprChild2string(sig[1]) << endl;
04510     }
04511     //    cout << "vterm is " << vterm << endl << exprChild2string(vterm) << endl;
04512 //     cout << exprChild2string(vterm[0]) << endl;
04513 //     cout << exprChild2string(vterm[1]) << endl;
04514 
04515     for(size_t oldBindsIndex = 0; oldBindsIndex < oldBinds.size(); oldBindsIndex++){
04516       cout << "--O- " << oldBindsIndex << endl;
04517       cout << exprMap2string(oldBindsBack[oldBindsIndex]) << endl;
04518       cout << exprMap2string(oldBinds[oldBindsIndex]) << endl;
04519       cout << exprMap2stringSimplify(oldBinds[oldBindsIndex]) << endl;
04520       cout << exprMap2stringSig(oldBinds[oldBindsIndex]) << endl;
04521     }
04522 
04523     for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
04524       cout << "--N- " << newBindsIndex << endl;
04525       cout << exprMap2string(newBindsBack[newBindsIndex]) << endl;
04526       cout << exprMap2string(newBinds[newBindsIndex]) << endl;
04527       cout << exprMap2stringSimplify(newBinds[newBindsIndex]) << endl;
04528       cout << exprMap2stringSig(newBinds[newBindsIndex]) << endl;
04529     }
04530 
04531   }
04532 
04533 
04534     //binds = newBinds;
04535   //  cout<<"newbinds size" << newBinds.size() << endl;
04536   binds = oldBinds;
04537   return;
04538 }
04539 
04540 void TheoryQuant::newTopMatchSig(const Expr& gtermOrg,
04541          const Expr& vterm,
04542          vector<ExprMap<Expr> >& binds,
04543          const Trigger& trig){
04544 
04545   //  cout<<"matching " << gterm << endl << "----" << endl << vterm << endl;
04546   Expr gterm;
04547   if(gtermOrg.isApply() && gtermOrg.hasSig()){
04548     gterm = gtermOrg.getSig().getRHS();
04549   }
04550   else{
04551     gterm = gtermOrg;
04552   }
04553 
04554 
04555   if(trig.isSuperSimple){
04556     ExprMap<Expr>  cur_bind;
04557     for(int i = vterm.arity()-1; i>=0 ; i--){
04558       cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
04559     }
04560     binds.push_back(cur_bind);
04561     return;
04562   }
04563 
04564   if(trig.isSimple){
04565     ExprMap<Expr>  cur_bind;
04566     for(int i = vterm.arity()-1; i>=0 ; i--){
04567       if(BOUND_VAR != vterm[i].getKind()){
04568   if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
04569     return ;
04570   }
04571       }
04572       else{
04573   if (getBaseType(vterm[i])==getBaseType(gterm[i])){
04574     cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
04575   }
04576   else return;
04577       }
04578     }
04579     binds.push_back(cur_bind);
04580     return;
04581   }
04582 
04583   if(!isSysPred(vterm)){ //then gterm cannot be a syspred
04584     if(!gterm.getType().isBool()){
04585       //      res2= recSynMatch(gterm, vterm, env);
04586       multMatchChild(gterm, vterm, binds);
04587       return;
04588     }
04589 
04590 
04591     //    DebugAssert(falseExpr()==findExpr(gterm) || trueExpr()==findExpr(gterm), " why ");
04592 
04593     //    multMatchChild(gterm, vterm, binds);
04594     //    return;
04595 
04596     // when man trig is enabled, we should not use polarity because the manual triggers do not have polairities.
04597     // should I fix this?
04598     if(!*d_usePolarity || d_useManTrig){
04599       //      return recSynMatch(gterm, vterm, env);
04600       multMatchChild(gterm, vterm, binds);
04601       return;
04602     }
04603 
04604     const bool gtrue = (trueExpr()==findExpr(gterm));
04605     //    const bool gtrue = (trueExpr()==simplifyExpr(gterm));
04606     if(gtrue ){
04607       if((Neg==trig.polarity || PosNeg==trig.polarity)) {
04608   //  return recSynMatch(gterm, vterm, env);
04609   multMatchChild(gterm, vterm, binds);
04610   return;
04611       }
04612       else{
04613   //  cout<<"returned 1"<<endl;
04614   return;
04615       }
04616     }
04617     const bool gfalse = (falseExpr()==findExpr(gterm));
04618     //const bool gfalse = (falseExpr()==simplifyExpr(gterm));
04619     if(gfalse){
04620       if((Pos==trig.polarity || PosNeg==trig.polarity)) {
04621   //  return recSynMatch(gterm, vterm, env);
04622   multMatchChild(gterm, vterm, binds); //it is possible that we need binds here, not a single bind
04623   return;
04624       }
04625       else{
04626   //  cout<<"returned 2"<<endl;
04627   return;
04628       }
04629     }
04630 
04631 
04632     FatalAssert(false, "impossible");
04633     cout<<"impossible here in new top match"<<endl;
04634     cout<<"vterm "<<vterm<<endl;
04635     cout<<"gterm " <<gterm<<endl;
04636     cout<<trig.polarity<<endl;
04637     cout<<"gtrue and gfalse: " << gtrue<<" |and| " <<gfalse<<endl;
04638     return;
04639     multMatchChild(gterm, vterm, binds);
04640 
04641     return;
04642   }
04643   else{ // must be syspreds
04644     //we can move the work to split vterm into left and right into setuptriggers
04645     Expr gl = getLeft(gterm[1]);
04646     Expr gr = getRight(gterm[1]);
04647 
04648     if(null_expr == gr || null_expr == gl){
04649       gl = gterm[0];
04650       gr = gterm[1];
04651     }
04652 
04653     Expr vr, vl;
04654     Expr tvr, tvl;
04655 
04656     tvr=null_expr;
04657     tvl=null_expr;
04658 
04659     if(isGE(vterm) || isGT(vterm)){
04660       vr = vterm[0];
04661       vl = vterm[1];
04662     }
04663     else if(isLE(vterm) || isLT(vterm)){
04664       vr = vterm[1];
04665       vl = vterm[0];
04666     }
04667     else{
04668       FatalAssert(false, "impossilbe in toppred");
04669     }
04670 
04671     if(isIntx(vl,0)){
04672       tvl = getLeft(vr);
04673       tvr = getRight(vr);
04674     }
04675     else if(isIntx(vr,0)) {
04676       tvl = getLeft(vl);
04677       tvr = getRight(vl);
04678     }
04679 
04680     if( (null_expr != tvl) && (null_expr != tvr)){
04681       vl = tvl;
04682       vr = tvr;
04683     }
04684 
04685 
04686     const bool gtrue = (trueExpr()==findExpr(gterm));
04687     const bool gfalse = (falseExpr()==findExpr(gterm));
04688 
04689     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
04690 
04691     //    DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
04692 
04693     if(!*d_usePolarity){
04694       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
04695   return;
04696       }
04697       else{
04698   return;
04699       }
04700     }
04701     if((Neg==trig.polarity || PosNeg==trig.polarity)) {
04702       if (( gtrue ) )  {
04703   if (multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
04704     return;
04705   }
04706   else{
04707     return;
04708   }
04709       }
04710       else {
04711   if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
04712     return;
04713   }
04714   else{
04715     return;
04716   }
04717       }
04718     }
04719     else if((Pos==trig.polarity || PosNeg==trig.polarity)) {
04720       if (( gfalse )) {
04721   if(multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
04722     return;
04723   }
04724   else{
04725     return;
04726   }
04727       }
04728       else {
04729   if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
04730     return;
04731   }
04732   else{
04733     return;
04734   }
04735       }
04736     }
04737     else {
04738       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
04739   // it is possible that cur_bind will be binds
04740   return;
04741       }
04742       else{
04743   return;
04744       }
04745       return;
04746     }
04747   }
04748 }
04749 
04750 
04751 /*
04752 void TheoryQuant::newTopMatchBackupOnly(const Expr& gterm,
04753           const Expr& vterm,
04754           vector<ExprMap<Expr> >& binds,
04755           const Trigger& trig){
04756   cout<<"-error should not be called more,  newTopMatchBackupOnly" << endl;
04757   ExprMap<Expr>  cur_bind;
04758   //  cout<<"matching " << gterm << " +++ " <<vterm<<endl;
04759   if(trig.isSuperSimple){
04760     for(int i = vterm.arity()-1; i>=0 ; i--){
04761       cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
04762     }
04763     binds.push_back(cur_bind);
04764     return;
04765   }
04766 
04767   if(trig.isSimple){
04768     for(int i = vterm.arity()-1; i>=0 ; i--){
04769       if(BOUND_VAR != vterm[i].getKind()){
04770   if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
04771     return ;
04772   }
04773       }
04774       else{
04775   cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
04776       }
04777     }
04778     binds.push_back(cur_bind);
04779     return;
04780   }
04781 
04782 
04783   if(!isSysPred(vterm)){ //then gterm cannot be a syspred
04784     if(!gterm.getType().isBool()){
04785       //      res2= recSynMatch(gterm, vterm, env);
04786       matchChild(gterm, vterm, binds);
04787       return;
04788     }
04789 
04790     matchChild(gterm, vterm, binds);
04791     return;
04792 
04793 
04794     if(!*d_usePolarity){
04795       //      return recSynMatch(gterm, vterm, env);
04796       matchChild(gterm, vterm, binds);
04797       return;
04798     }
04799 
04800     const bool gtrue = (trueExpr()==findExpr(gterm));
04801     //    const bool gtrue = (trueExpr()==simplifyExpr(gterm));
04802     if(gtrue ){
04803       if((Neg==trig.polarity || PosNeg==trig.polarity)) {
04804   //  return recSynMatch(gterm, vterm, env);
04805   matchChild(gterm, vterm, binds);
04806   return;
04807       }
04808       else{
04809   //  cout<<"returned 1"<<endl;
04810   return;
04811       }
04812     }
04813     const bool gfalse = (falseExpr()==findExpr(gterm));
04814     //const bool gfalse = (falseExpr()==simplifyExpr(gterm));
04815     if(gfalse){
04816       if((Pos==trig.polarity || PosNeg==trig.polarity)) {
04817   //  return recSynMatch(gterm, vterm, env);
04818   matchChild(gterm, vterm, binds); //it is possible that we need binds here, not a single bind
04819   return;
04820       }
04821       else{
04822   //  cout<<"returned 2"<<endl;
04823   return;
04824       }
04825     }
04826 
04827 
04828 //     cout<<"immpossible here in new top match"<<endl;
04829 //     cout<<"vterm "<<vterm<<endl;
04830 //     cout<<trig.polarity<<endl;
04831 //     cout<<gtrue<<" | " <<gfalse<<endl;
04832 //     cout<<"gterm " <<gterm<<endl;
04833 //     cout<<"gterm " <<simplifyExpr(gterm)<<endl;
04834 
04835     matchChild(gterm, vterm, binds);
04836     return;
04837 
04838     return;
04839   }
04840   else{ // must be syspreds
04841     //we can move the work to split vterm into left and right into setuptriggers
04842     Expr gl = getLeft(gterm[1]);
04843     Expr gr = getRight(gterm[1]);
04844 
04845     if(null_expr == gr || null_expr == gl){
04846       gl = gterm[0];
04847       gr = gterm[1];
04848     }
04849 
04850     Expr vr, vl;
04851     Expr tvr, tvl;
04852 
04853     tvr=null_expr;
04854     tvl=null_expr;
04855 
04856     if(isGE(vterm) || isGT(vterm)){
04857       vr = vterm[0];
04858       vl = vterm[1];
04859     }
04860     else if(isLE(vterm) || isLT(vterm)){
04861       vr = vterm[1];
04862       vl = vterm[0];
04863     }
04864     else{
04865       FatalAssert(false, "impossilbe in toppred");
04866     }
04867 
04868     if(isIntx(vl,0)){
04869       tvl = getLeft(vr);
04870       tvr = getRight(vr);
04871     }
04872     else if(isIntx(vr,0)) {
04873       tvl = getLeft(vl);
04874       tvr = getRight(vl);
04875     }
04876 
04877     if( (null_expr != tvl) && (null_expr != tvr)){
04878       vl = tvl;
04879       vr = tvr;
04880     }
04881 
04882 
04883     const bool gtrue = (trueExpr()==findExpr(gterm));
04884     const bool gfalse = (falseExpr()==findExpr(gterm));
04885 
04886     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
04887 
04888     //    DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
04889 
04890     if(!*d_usePolarity){
04891       if((recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind))){
04892   binds.push_back(cur_bind); // it is possible that cur_bind will be binds
04893   return;
04894       }
04895       else{
04896   return;
04897       }
04898     }
04899     if((Neg==trig.polarity || PosNeg==trig.polarity)) {
04900       if (( gtrue ) )  {
04901   if (recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind)){
04902     binds.push_back(cur_bind);
04903     return;
04904   }
04905   else{
04906     return;
04907   }
04908       }
04909       else {
04910   if(recSynMatch(gl, vr, cur_bind) && recSynMatch(gr, vl, cur_bind)){
04911     binds.push_back(cur_bind);
04912     return;
04913   }
04914   else{
04915     return;
04916   }
04917       }
04918     }
04919     else if((Pos==trig.polarity || PosNeg==trig.polarity)) {
04920       if (( gfalse )) {
04921   if(recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind)){
04922     binds.push_back(cur_bind);
04923     return;
04924   }
04925   else{
04926     return;
04927   }
04928       }
04929       else {
04930   if(recSynMatch(gl, vr, cur_bind) && recSynMatch(gr, vl, cur_bind)){
04931     binds.push_back(cur_bind);
04932     return;
04933   }
04934   else{
04935     return;
04936   }
04937       }
04938     }
04939     else {
04940       //      FatalAssert(false, "impossible polarity for trig");
04941   //DebugAssert(false, "impossible polarity for trig");
04942 //      res = false;
04943       if((recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind))){
04944   binds.push_back(cur_bind); // it is possible that cur_bind will be binds
04945   return;
04946       }
04947       else{
04948   return;
04949       }
04950 
04951       return;
04952     }
04953   }
04954 }
04955 */
04956 
04957 /*
04958 bool TheoryQuant::synMatchTopPred(const Expr& gterm, Trigger trig, ExprMap<Expr>& env){
04959 
04960 
04961   Expr vterm = trig.getEx();
04962 
04963   TRACE("quant toppred", "top pred: gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
04964 
04965   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
04966   DebugAssert ((BOUND_VAR != vterm.getKind()),"top pred match "+gterm.toString()+" has bound var");
04967 
04968   if(gterm.isEq() || vterm.isEq()){
04969     return false; // we do not match with equality
04970   }
04971 
04972   bool res2=false;
04973 
04974   if(vterm.arity() != gterm.arity()) return false;
04975 
04976   if(trig.isSuperSimp()){
04977     if(trig.getHead() == getHead(gterm) ){
04978       for(int i = vterm.arity()-1; i>=0 ; i--){
04979   env[vterm[i]] = simplifyExpr(gterm[i]);
04980       }
04981       return true;
04982     }
04983     return false;
04984   }
04985 
04986 
04987 
04988   if(trig.isSimp()){
04989     if(trig.getHead() == getHead(gterm) ){
04990        for(int i = vterm.arity()-1; i>=0 ; i--){
04991   if(BOUND_VAR != vterm[i].getKind()){
04992     if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
04993       return false;
04994     }
04995   }
04996        }
04997       for(int i = vterm.arity()-1; i>=0 ; i--){
04998   if(BOUND_VAR == vterm[i].getKind()){
04999     if(d_allout){
05000       env[vterm[i]] = simplifyExpr(gterm[i]);
05001     }
05002     else {
05003       env[vterm[i]] = simplifyExpr(gterm[i]);
05004     }
05005   }
05006       }
05007       return true;
05008     }
05009     else{
05010       return false;
05011     }
05012   }
05013 
05014   if(!(isSysPred(vterm) && isSysPred(gterm))){
05015     if(isSysPred(vterm) || isSysPred(gterm)) {
05016       return false;
05017     }
05018     if(!usefulInMatch(gterm)){
05019       return false;
05020     }
05021     if(trig.getHead() != getHead(gterm)){
05022       return false;
05023     }
05024 
05025     if(!gterm.getType().isBool()){
05026       //      res2= recSynMatch(gterm, vterm, env);
05027       res2= matchChild(gterm, vterm, env);
05028       return res2;
05029     }
05030 
05031     if(!*d_usePolarity){
05032       //      return recSynMatch(gterm, vterm, env);
05033       return matchChild(gterm, vterm, env);
05034     }
05035 
05036     const bool gtrue = (trueExpr()==findExpr(gterm));
05037     if(gtrue ){
05038       if(trig.isNeg()) {
05039   //  return recSynMatch(gterm, vterm, env);
05040   return matchChild(gterm, vterm, env);
05041       }
05042       else{
05043   return false;
05044       }
05045     }
05046     const bool gfalse = (falseExpr()==findExpr(gterm));
05047     if(gfalse){
05048       if (trig.isPos()){
05049   //  return recSynMatch(gterm, vterm, env);
05050   return matchChild(gterm, vterm, env);
05051       }
05052       else{
05053   return false;
05054       }
05055     }
05056     else {
05057       return false;
05058     }
05059   }
05060   else{
05061     DebugAssert((2==gterm.arity() && 2==vterm.arity()), "impossible situation in top pred");
05062     DebugAssert(!((isLE(gterm) || isLT(gterm)) && !isIntx(gterm[0],0)), "canonical form changed");
05063 
05064 #ifdef _CVC3_DEBUG_MODE
05065     if( CVC3::debugger.trace("quant toppred")  ){
05066       cout << "toppred gterm, vterm" << gterm << "::" << vterm << endl;
05067       cout << findExpr(gterm) << "::" << trig.isPos() << "|" << trig.isNeg() << endl;
05068     }
05069 #endif
05070 
05071 
05072     Expr gl = getLeft(gterm[1]);
05073     Expr gr = getRight(gterm[1]);
05074 
05075     if(null_expr == gr || null_expr == gl){
05076       gl = gterm[0];
05077       gr = gterm[1];
05078     }
05079 
05080     Expr vr, vl;
05081     Expr tvr, tvl;
05082 
05083     tvr=null_expr;
05084     tvl=null_expr;
05085 
05086     if(isGE(vterm) || isGT(vterm)){
05087       vr = vterm[0];
05088       vl = vterm[1];
05089     }
05090     else if(isLE(vterm) || isLT(vterm)){
05091       vr = vterm[1];
05092       vl = vterm[0];
05093     }
05094     else{
05095       DebugAssert(false, "impossilbe in toppred");
05096     }
05097 
05098     if(isIntx(vl,0)){
05099       tvl = getLeft(vr);
05100       tvr = getRight(vr);
05101     }
05102     else if(isIntx(vr,0)) {
05103       tvl = getLeft(vl);
05104       tvr = getRight(vl);
05105     }
05106 
05107     if( (null_expr != tvl) && (null_expr != tvr)){
05108       vl = tvl;
05109       vr = tvr;
05110     }
05111 
05112 
05113     const bool gtrue = (trueExpr()==findExpr(gterm));
05114     const bool gfalse = (falseExpr()==findExpr(gterm));
05115 
05116     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
05117 
05118     bool res;
05119 
05120     DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
05121 
05122     if(!*d_usePolarity){
05123       return (recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
05124     }
05125 
05126     if(trig.isNeg()){
05127       if (( gtrue ) )  {
05128   res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
05129       }
05130       else {
05131   res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
05132       }
05133     }
05134     else if(trig.isPos()){
05135       if (( gfalse )) {
05136   res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
05137       }
05138       else {
05139   res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
05140       }
05141     }
05142     else {
05143       DebugAssert(false, "impossible polarity for trig");
05144       res = false;
05145     }
05146 
05147 #ifdef _CVC3_DEBUG_MODE
05148     if( CVC3::debugger.trace("quant toppred")  ){
05149       cout<<"res| "<< res << " | " << gtrue << " | " << gfalse << endl;
05150     }
05151 #endif
05152     return res;
05153   }
05154 }
05155 */
05156 
05157 /*
05158   Idealy, once a successful mathing is found here, the search should continue to check if there are more matchings.  For example, suppose vterm is f(g(x)) and gterm is f(a), and a=g(c)=g(d), c!=d.  The algorithm used now will only return the matching x=c.  There is no reason to leave x=d out.  However, testing of all quantified cases in SMT LIB, as of 11/28/2007, shows that the above senario never happens.  So, the search algorithm here returns once a successful matching is found
05159   This is not true for set1.smt
05160 */
05161 
05162 bool cmpExpr( Expr e1, Expr e2){
05163 
05164   if(e1.isNull()) return true;
05165   if(e2.isNull()) return false;
05166   return (e1.getIndex() < e2.getIndex());
05167 }
05168 
05169 /*
05170   recMultMatch:
05171       syntax match, will return multiple bindings if possible
05172       must be called by multMatchChild or multMatchTop
05173       requires binds.size() == 1;
05174 
05175   input: one partial (empty) bindings in binds.
05176   output: successful bindings in binds
05177 */
05178 
05179 bool TheoryQuant::recMultMatchDebug(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
05180   //bool TheoryQuant::recMultMatch(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
05181   TRACE("quant match", gterm , " VS ", vterm);
05182   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
05183   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found in recMultMatch");
05184   DebugAssert (binds.size() == 1, "binds.size() > 1");
05185 
05186 
05187   if (BOUND_VAR == vterm.getKind() )  {
05188     ExprMap<Expr>& curEnv = binds[0]; //curEnv is both input and output
05189     ExprMap<Expr>::iterator iterVterm = curEnv.find(vterm);
05190     if ( iterVterm != curEnv.end()){
05191       return (simplifyExpr(gterm) == simplifyExpr(iterVterm->second)) ? true : false ;
05192     }
05193     else {
05194       curEnv[vterm] = simplifyExpr(gterm);
05195       return true;
05196     }
05197   }
05198   else if (!vterm.containsBoundVar()){
05199     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
05200   }
05201   else{ //let's do matching
05202     if(canGetHead(vterm)){
05203       Expr vhead = getHead(vterm);
05204       if(vterm.isAtomicFormula()){ //we do not want to match predicate up to equality here.  why? //more, if all pridicate is equilvent to true or false, we can just match the vterm with true or flase, we do not need a special case in theory, but the way here is more efficient for the current impelemention.
05205 
05206   // anoher problem is the interaction between matching and term's signature, I need to figure this out.
05207 
05208   if (canGetHead(gterm)) {
05209     if ( vhead != getHead(gterm) ){
05210       return false;
05211     }
05212     return multMatchChild(gterm, vterm, binds);
05213   }
05214   else{
05215     return false;
05216   }
05217       }
05218       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
05219   return multMatchChild(gterm, vterm, binds);
05220       }
05221 
05222       //      cout<<"-- begin multi equality matching -- " << endl;
05223       //      cout<<"vterm: " << vterm << endl;
05224       //      cout<<"gterm: " << gterm << endl;
05225 
05226       ExprMap<Expr> orginalEnv = binds[0];
05227       vector<ExprMap<Expr> > candidateNewEnvs;
05228       bool newwayResult(false);
05229 
05230       if(*d_useNewEqu){
05231   vector<Expr> candidateGterms;
05232   {
05233     Expr curCandidateGterm = gterm.getEqNext().getRHS();
05234     while (curCandidateGterm != gterm){
05235       DebugAssert(simplifyExpr(curCandidateGterm) == simplifyExpr(gterm), "curCandidateGterm != gterm");
05236             //      cout<<"pushed candidate gterm " << getExprScore(curCandidateGterm) << " # " << curCandidateGterm << endl;
05237       if(getExprScore(curCandidateGterm) <= d_curMaxExprScore || true){
05238         candidateGterms.push_back(curCandidateGterm);
05239       }
05240       curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
05241     }
05242   }
05243   //  std::sort(candidateGterms.begin(), candidateGterms.end());
05244   //  for(int curGtermIndex = candidateGterms.size()-1; curGtermIndex >=0 ; curGtermIndex--){
05245   for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
05246     const Expr& curGterm = candidateGterms[curGtermIndex];
05247     if(getHead(curGterm) == vhead){
05248       vector<ExprMap<Expr> > newBinds;
05249       newBinds.push_back(orginalEnv);
05250       bool res =  multMatchChild(curGterm, vterm, newBinds);
05251       if (res)  {
05252               //        cout << "found new match: " << endl;
05253               //        cout << "curGterm: " <<  curGterm << endl;
05254               //        cout << "simplified Gterm: " << simplifyExpr(gterm) << endl;
05255               //        cout << "simplified curGterm: " << simplifyExpr(curGterm) << endl;
05256         for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
05257     candidateNewEnvs.push_back(newBinds[newBindsIndex]);
05258         }
05259               //        cout << "pushed newEnvs " << newBinds.size() << endl;
05260       }
05261     }
05262   }
05263 
05264   if (candidateNewEnvs.size() >= 1){
05265           //    cout<<"found more matcings: " << candidateNewEnvs.size() << endl;
05266     newwayResult = true;
05267   }
05268   else{
05269     newwayResult = false;
05270   }
05271       } //end of new way of matching
05272       // let's do matching in the old way
05273 
05274       vector<ExprMap<Expr> > candidateOldEnvs;
05275 
05276       if( d_same_head_expr.count(vhead) > 0 ) {
05277   const Expr& findGterm = simplifyExpr(gterm);
05278   //if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
05279   CDList<Expr>* gls = d_same_head_expr[vhead];
05280   for(size_t i = 0; i < gls->size(); i++){
05281     const Expr& curGterm = (*gls)[i];
05282     if(getExprScore(curGterm)> d_curMaxExprScore){
05283       continue;
05284     }
05285           //    cout<<"same head term " << curGterm << endl;
05286     if (simplifyExpr(curGterm) == findGterm){
05287       DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
05288 
05289       vector<ExprMap<Expr> > newBinds ;
05290       newBinds.push_back(orginalEnv);
05291       bool goodMatching(false);
05292       goodMatching = multMatchChild(curGterm, vterm, newBinds);
05293 
05294       if(goodMatching){
05295               //        cout << "old curGterm: " << curGterm << endl;
05296               //        cout << "old simplifed  curGterm: " << simplifyExpr(curGterm) << endl;
05297         for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
05298     candidateOldEnvs.push_back(newBinds[newBindsIndex]);
05299         }
05300               //        cout << "pushed oldEnvs " << newBinds.size() << endl;
05301       }
05302     }
05303   }//end of same head list
05304       }
05305 
05306       bool oldwayResult(false);
05307 
05308       if(candidateOldEnvs.size() >= 1){
05309   oldwayResult = true;
05310       }
05311       else{
05312   oldwayResult = false;
05313       }
05314 
05315       //      cout<<"new env size" << candidateNewEnvs.size() << endl;
05316       //      cout<<"old env size" << candidateOldEnvs.size() << endl;
05317       if( candidateNewEnvs.size() != candidateOldEnvs.size()){
05318         ;
05319         //  cout<<"found error?" << endl;
05320       }
05321 
05322       if(oldwayResult != newwayResult){
05323         ;
05324         //  cout << "-found bug in multMatch " << endl;
05325       }
05326 
05327       // binds = candidateNewEnvs;
05328       binds = candidateOldEnvs;
05329 
05330       return oldwayResult;
05331     }
05332     else{
05333       if( (gterm.getKind() == vterm.getKind()) &&
05334     (gterm.arity() == vterm.arity()) &&
05335     gterm.arity()>0 ){
05336         //  cout<<"why"<<endl;
05337   return multMatchChild(gterm, vterm, binds);
05338       }
05339       else {
05340   return false;
05341       }
05342     }
05343   }
05344   return false;
05345 }
05346 
05347 bool TheoryQuant::recMultMatchOldWay(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
05348   //bool TheoryQuant::recMultMatch(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
05349   TRACE("quant match",  "==recMultMatch\n", "---"+gterm.toString(), "\n+++"+vterm.toString());
05350   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
05351   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found in recMultMatch");
05352   DebugAssert (binds.size() == 1, "binds.size() > 1");
05353 
05354 
05355   if (BOUND_VAR == vterm.getKind() )  {
05356     ExprMap<Expr>& curEnv = binds[0]; //curEnv is both input and output
05357     ExprMap<Expr>::iterator iterVterm = curEnv.find(vterm);
05358     if ( iterVterm != curEnv.end()){
05359       return (simplifyExpr(gterm) == simplifyExpr(iterVterm->second)) ? true : false ;
05360     }
05361     else {
05362       curEnv[vterm] = simplifyExpr(gterm);
05363       return true;
05364     }
05365   }
05366   else if (!vterm.containsBoundVar()){
05367     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
05368   }
05369   else{ //let's do matching
05370     if(canGetHead(vterm)){
05371       Expr vhead = getHead(vterm);
05372       if(vterm.isAtomicFormula()){ //we do not want to match predicate up to equality here.  why?
05373   if (canGetHead(gterm)) {
05374     if ( vhead != getHead(gterm) ){
05375       return false;
05376     }
05377     return multMatchChild(gterm, vterm, binds);
05378   }
05379   else{
05380     return false;
05381   }
05382       }
05383       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
05384   return multMatchChild(gterm, vterm, binds);
05385       }
05386 
05387       TRACE("quant multmatch", "-- begin multi equality matching -- ", "" ,"");
05388       TRACE("quant multmatch", "vterm: " ,  vterm, "");
05389       TRACE("quant multmatch", "gterm: " ,  gterm, "");
05390 
05391       ExprMap<Expr> orginalEnv = binds[0];
05392 
05393       vector<ExprMap<Expr> > candidateOldEnvs;
05394 
05395       if( d_same_head_expr.count(vhead) > 0 ) {
05396   const Expr& findGterm = simplifyExpr(gterm);
05397   TRACE("quant multmatch", "simp gterm: " ,  simplifyExpr(gterm), "");
05398   //if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
05399   CDList<Expr>* gls = d_same_head_expr[vhead];
05400   for(size_t i = 0; i < gls->size(); i++){
05401     const Expr& curGterm = (*gls)[i];
05402       if(getExprScore(curGterm)> d_curMaxExprScore){
05403         continue;
05404       }
05405     TRACE("quant multmatch", "same head term ", curGterm, "");
05406     TRACE("quant multmatch", "simp same head term ", simplifyExpr(curGterm), "");
05407     if (simplifyExpr(curGterm) == findGterm){
05408       DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
05409       vector<ExprMap<Expr> > newBinds ;
05410       newBinds.push_back(orginalEnv);
05411       bool goodMatching(false);
05412       goodMatching = multMatchChild(curGterm, vterm, newBinds);
05413 
05414       if(goodMatching){
05415         TRACE("quant multmatch", "old curGterm: ", curGterm, "");
05416         TRACE("quant multmatch", "old simplifed  curGterm: ", simplifyExpr(curGterm), "");
05417         for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
05418     candidateOldEnvs.push_back(newBinds[newBindsIndex]);
05419         }
05420         TRACE("quant multmatch", "pushed oldEnvs " , newBinds.size(), "");
05421       }
05422     }
05423   }//end of same head list
05424       }
05425 
05426       bool oldwayResult(false);
05427 
05428       if(candidateOldEnvs.size() >= 1){
05429   oldwayResult = true;
05430       }
05431       else{
05432   oldwayResult = false;
05433       }
05434 
05435       TRACE("quant multmatch", "old env size" ,candidateOldEnvs.size(), "");
05436       binds = candidateOldEnvs;
05437       return oldwayResult;
05438     }
05439     else{
05440       if( (gterm.getKind() == vterm.getKind()) &&
05441     (gterm.arity() == vterm.arity()) &&
05442     gterm.arity()>0 ){
05443   return multMatchChild(gterm, vterm, binds);
05444       }
05445       else {
05446   return false;
05447       }
05448     }
05449   }
05450   return false;
05451 }
05452 
05453 
05454 
05455 //bool TheoryQuant::recMultMatchNewWay(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
05456 bool TheoryQuant::recMultMatch(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
05457   TRACE("quant match", gterm , " VS ", vterm);
05458   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
05459   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found in recMultMatch");
05460   DebugAssert (binds.size() == 1, "binds.size() > 1");
05461 
05462   if (BOUND_VAR == vterm.getKind() )  {
05463     ExprMap<Expr>& curEnv = binds[0]; //curEnv is both input and output
05464     ExprMap<Expr>::iterator iterVterm = curEnv.find(vterm);
05465     if ( iterVterm != curEnv.end()){
05466       return (simplifyExpr(gterm) == simplifyExpr(iterVterm->second)) ? true : false ;
05467     }
05468     else {
05469       curEnv[vterm] = simplifyExpr(gterm);
05470       return true;
05471     }
05472   }
05473   else if (!vterm.containsBoundVar()){
05474     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
05475   }
05476   else{ //let's do matching
05477     if(canGetHead(vterm)){
05478       Expr vhead = getHead(vterm);
05479       if(vterm.isAtomicFormula()){ //we do not want to match predicate up to equality here.  why?
05480   if (canGetHead(gterm)) {
05481     if ( vhead != getHead(gterm) ){
05482       return false;
05483     }
05484     return multMatchChild(gterm, vterm, binds);
05485   }
05486   else{
05487     return false;
05488   }
05489       }
05490       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
05491   //well, what if gterm and vterm cannot match later, but vterm can match some guys in the equivalent class of gterm?
05492   return multMatchChild(gterm, vterm, binds);
05493       }
05494 
05495       TRACE("quant multmatch", "-- begin multi equality matching -- ", "" ,"");
05496       TRACE("qunat multmatch", "vterm: " ,  vterm, "");
05497       TRACE("qunat multmatch", "gterm: " ,  gterm, "");
05498 
05499       ExprMap<Expr> orginalEnv = binds[0];
05500       vector<ExprMap<Expr> > candidateNewEnvs;
05501       bool newwayResult(false);
05502 
05503       if(*d_useNewEqu){
05504   vector<Expr> candidateGterms;
05505   {
05506     if(!gterm.hasFind()) {
05507       return false;
05508     }
05509     Expr curCandidateGterm = gterm.getEqNext().getRHS();
05510     while (curCandidateGterm != gterm){
05511       DebugAssert(simplifyExpr(curCandidateGterm) == simplifyExpr(gterm), "curCandidateGterm != gterm");
05512       TRACE("quant multmatch", "pushed candidate gterm ", getExprScore(curCandidateGterm),  " # " + curCandidateGterm.toString());
05513       //maybe we should not check the score here, but we need check sig .
05514       if(getExprScore(curCandidateGterm) <= d_curMaxExprScore || true ){
05515         candidateGterms.push_back(curCandidateGterm);
05516       }
05517       curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
05518     }
05519   }
05520   for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
05521     const Expr& curGterm = candidateGterms[curGtermIndex];
05522     if(getHead(curGterm) == vhead){
05523       vector<ExprMap<Expr> > newBinds;
05524       newBinds.push_back(orginalEnv);
05525       bool res =  multMatchChild(curGterm, vterm, newBinds, true);
05526       if (res)  {
05527         TRACE("quant multmatch", "found new match: ", "" ,"");
05528         TRACE("quant multmatch", "curGterm: ",  curGterm , "");
05529         TRACE("quant multmatch", "simplified Gterm: ", simplifyExpr(gterm), "" );
05530         TRACE("quant multmatch", "simplified curGterm: ",  simplifyExpr(curGterm), "");
05531         for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
05532     candidateNewEnvs.push_back(newBinds[newBindsIndex]);
05533         }
05534         TRACE("quant multmathc", "pushed newEnvs ", newBinds.size(), "");
05535       }
05536     }
05537   }
05538 
05539   if (candidateNewEnvs.size() >= 1){
05540     TRACE("quant multmacht", "found more matcings: " , candidateNewEnvs.size(), "");
05541     newwayResult = true;
05542   }
05543   else{
05544     newwayResult = false;
05545   }
05546       } //end of new way of matching
05547 
05548       TRACE("quant multmatch", "new env size " , candidateNewEnvs.size(), "");
05549       binds = candidateNewEnvs;
05550       return newwayResult;
05551     }
05552     else{
05553       if  ( (gterm.getKind() == vterm.getKind()) &&
05554       (gterm.arity() == vterm.arity()) &&
05555       gterm.arity()>0 )
05556   {
05557     return multMatchChild(gterm, vterm, binds);
05558   }
05559       else {
05560   return false;
05561       }
05562     }
05563   }
05564   return false;
05565 }
05566 
05567 
05568 /*
05569 bool TheoryQuant::recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
05570   cout << "-error: should not be called, recSynMatch" << endl;
05571   TRACE("quant match", gterm , " VS ", vterm);
05572   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
05573   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found");
05574 
05575   if (BOUND_VAR == vterm.getKind() )  {
05576     ExprMap<Expr>::iterator p = env.find(vterm);
05577     if ( p != env.end()){
05578       return (simplifyExpr(gterm) == simplifyExpr(p->second)) ? true : false ;
05579     }
05580     else {
05581       env[vterm] = simplifyExpr(gterm);
05582       return true;
05583     }
05584   }
05585   else if (!vterm.containsBoundVar()){
05586     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
05587   }
05588   else{ //let's do matching
05589     if(canGetHead(vterm)){
05590       Expr vhead = getHead(vterm);
05591       if(vterm.isAtomicFormula()){ //we do not want to match predicate up to equality here.  why?
05592   if (canGetHead(gterm)) {
05593     if ( vhead != getHead(gterm) ){
05594       return false;
05595     }
05596     return matchChild(gterm, vterm, env);
05597   }
05598   else{
05599     return false;
05600   }
05601       }
05602       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
05603   return matchChild(gterm, vterm, env);
05604       }
05605 
05606       if(!*d_useEqu){
05607   return false;
05608       }
05609 
05610       cout<<"-- begin equality matching -- " << endl;
05611       cout<<"vterm: " << vterm << endl;
05612       cout<<"gterm: " << gterm << endl;
05613 
05614       ExprMap<Expr> orginalEnv = env;
05615 
05616       vector<ExprMap<Expr> > candidateNewEnvs;
05617 
05618       //      if(*d_useNewEqu){
05619 
05620   vector<Expr> candidateGterms;
05621   {
05622     Expr curCandidateGterm = gterm.getEqNext().getRHS();
05623     while (curCandidateGterm != gterm){
05624       DebugAssert(simplifyExpr(curCandidateGterm) == simplifyExpr(gterm), "curCandidateGterm != gterm");
05625       cout<<"pushed candidate gterm " << curCandidateGterm << endl;
05626       candidateGterms.push_back(curCandidateGterm);
05627       curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
05628     }
05629   }
05630   std::sort(candidateGterms.begin(), candidateGterms.end());
05631   //  for(int curGtermIndex = candidateGterms.size()-1; curGtermIndex >=0 ; curGtermIndex--){
05632   for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
05633     const Expr& curGterm = candidateGterms[curGtermIndex];
05634     if(getHead(curGterm) == vhead){
05635       ExprMap<Expr> newEnv = orginalEnv;
05636       bool res =  matchChild(curGterm, vterm, newEnv);
05637       if (res)  {
05638         cout << "found new match: " << endl;
05639         cout << "curGterm: " <<  curGterm << endl;
05640         cout << "simplified Gterm: " << simplifyExpr(gterm) << endl;
05641         cout << "simplified curGterm: " << simplifyExpr(curGterm) << endl;
05642         candidateNewEnvs.push_back(newEnv);
05643       }
05644     }
05645   }
05646 
05647   ExprMap<Expr> newwayEnv;
05648   bool newwayResult(false);
05649 
05650   if (candidateNewEnvs.size() >= 1){
05651     cout<<"found more matcings: " << candidateNewEnvs.size() << endl;
05652     newwayEnv = candidateNewEnvs[0]; // we have a choice here
05653     //    newwayEnv = candidateNewEnvs.back(); // we have a choice here
05654     newwayResult = true;
05655   }
05656   else{
05657     newwayResult = false;
05658   }
05659   //      } //end of new way of matching
05660       // let's do matching in the old way
05661 
05662       vector<ExprMap<Expr> > candidateOldEnvs;
05663 
05664       if( d_same_head_expr.count(vhead) > 0 ) {
05665   const Expr& findGterm = simplifyExpr(gterm);
05666   //if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
05667   CDList<Expr>* gls = d_same_head_expr[vhead];
05668   for(size_t i = 0; i < gls->size(); i++){
05669     cout<<"same head term " << (*gls)[i] << endl;
05670     if (simplifyExpr((*gls)[i]) == findGterm){
05671       DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
05672 
05673       ExprMap<Expr> curEnv = orginalEnv;
05674       const Expr& curGterm = (*gls)[i];
05675 
05676       bool goodMatching(false);
05677       goodMatching = matchChild(curGterm, vterm, curEnv);
05678 
05679       if(goodMatching){
05680         cout << "old curGterm: " << curGterm << endl;
05681         cout << "old simplifed  curGterm: " << simplifyExpr(curGterm) << endl;
05682         candidateOldEnvs.push_back(curEnv);
05683 ;
05684       }
05685     }
05686   }//end of same head list
05687       }
05688 
05689       ExprMap<Expr> oldwayEnv;
05690       bool oldwayResult(false);
05691 
05692       if(candidateOldEnvs.size() >= 1){
05693   oldwayResult = true;
05694   oldwayEnv = candidateOldEnvs[0];
05695       }
05696       else{
05697   oldwayResult = false;
05698       }
05699 
05700       cout<<"new env size" << candidateNewEnvs.size() << endl;
05701       cout<<"old env size" << candidateOldEnvs.size() << endl;
05702       if( candidateNewEnvs.size() != candidateOldEnvs.size()){
05703   cout<<"found error?" << endl;
05704       }
05705 
05706       if(oldwayResult != newwayResult){
05707   cout<<"found bug" << endl;
05708   cout<<"oldway result: " << oldwayResult << endl;
05709   cout<<"newway result: " << newwayResult << endl;
05710       }
05711 
05712       if(false == oldwayResult ) return false;
05713 
05714       if(newwayEnv != oldwayEnv){
05715   bool notFound(true);
05716   int foundIndex(-1);
05717   for(size_t i = 0; i <candidateNewEnvs.size(); i++){
05718     if (candidateNewEnvs[i] == oldwayEnv){
05719       foundIndex = i;
05720       cout<<"found env " << i << endl;
05721       notFound = false;
05722     }
05723   }
05724   if (notFound){
05725     cout<<"found strange env" << endl;;
05726     cout<<gterm << " " << gterm.getIndex()<<endl;
05727     cout<<vterm << " " << vterm.getIndex()<<endl;
05728     cout<<exprMap2string(newwayEnv)<<endl;
05729     cout<<exprMap2string(oldwayEnv)<<endl;
05730   }
05731       }
05732       //env = oldwayEnv;
05733       env = newwayEnv;
05734       return true;
05735     }
05736     else{
05737       if( (gterm.getKind() == vterm.getKind()) &&
05738     (gterm.arity() == vterm.arity()) &&
05739     gterm.arity()>0 ){
05740   return matchChild(gterm, vterm, env);
05741       }
05742       else {
05743   return false;
05744       }
05745     }
05746   }
05747   return false;
05748 }
05749 
05750 */
05751 
05752 /*
05753 //the following is not used anymore, the code is here for refreence.
05754 bool TheoryQuant::recSynMatchBackupOnly(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
05755   cout<<"-error: should not be called: recSynMatchBackupOnly " << endl;
05756   TRACE("quant match", "gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
05757   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
05758 
05759   if (BOUND_VAR == vterm.getKind() )  {
05760     TRACE("quant match", "bound var found;", vterm.toString(),"");
05761     ExprMap<Expr>::iterator p = env.find(vterm);
05762     if ( p != env.end()){
05763       if (simplifyExpr(gterm) != simplifyExpr(p->second)){
05764   return false;
05765       }
05766       else
05767   return true;
05768     }
05769     else {
05770       env[vterm] = simplifyExpr(gterm);
05771       return true;
05772     }
05773   }
05774   else if (!vterm.containsBoundVar()){
05775     //    return true;
05776     //    cout<<"vterm and gterm"<<vterm << " # " <<gterm<<endl;
05777     if(simplifyExpr(vterm) == simplifyExpr(gterm)) {
05778       return true;
05779     }
05780     else{
05781       return false;
05782     }
05783   }
05784 
05785   else if(false && isSysPred(vterm) && isSysPred(gterm)){
05786 
05787     TRACE("quant syspred"," vterm, gterm ", vterm.toString()+" :|: ", gterm.toString());
05788     TRACE("quant syspred"," simplified vterm, gterm ", simplifyExpr(vterm).toString()+" :|: ", simplifyExpr(gterm).toString());
05789     FatalAssert(false, "should not be here in synmatch");
05790     exit(3);
05791   }
05792   else{ //let's do matching
05793     if(canGetHead(vterm)){
05794       Expr vhead = getHead(vterm);
05795       TRACE("quant match", "head vterm:", getHead(vterm), "");
05796       if(vterm.isAtomicFormula()){
05797   if (canGetHead(gterm)) {
05798     if ( vhead != getHead(gterm) ){
05799       return false;
05800     }
05801     return matchChild(gterm, vterm, env);
05802     //      for(int i=vterm.arity()-1; i >= 0; i--){
05803     //        if (false == recSynMatch(gterm[i], vterm[i] , env))
05804     //    return false;
05805     //      }
05806     //      return true;
05807   }
05808   else{
05809     return false;
05810   }
05811       }
05812       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
05813   //    if(gterm.arity() != vterm.arity()){
05814   //      return false;
05815   //    }
05816   //    for(int i=vterm.arity()-1; i >= 0; i--){
05817   //      if (false == recSynMatch(gterm[i], vterm[i] , env)) {
05818   //        return false;
05819   //      }
05820 //    }
05821 //    return true;
05822   return matchChild(gterm, vterm, env);
05823       }
05824 
05825       if(!*d_useEqu){
05826   return false;
05827       }
05828 
05829       cout<<"-- begin equality matching -- " << endl;
05830       cout<<"vterm: " << vterm << endl;
05831       cout<<"gterm: " << gterm << endl;
05832       bool newwayResult(false);
05833       bool oldwayResult(false);
05834       ExprMap<Expr> orgEnv = env;
05835       ExprMap<Expr> newwayEnv;
05836       ExprMap<Expr> oldwayEnv;
05837 
05838       vector<ExprMap<Expr> > candidateEnv; // here just for test
05839       if(*d_useNewEqu){
05840 //  int debug1= vterm.getIndex();
05841 //  int debug2= gterm.getIndex();
05842 //  if(debug1 == 311 && debug2 == 361){
05843 //    cout<<"begin here" << endl;
05844 //  }
05845 
05846 
05847   Expr cur_next = gterm.getEqNext().getRHS();
05848   Expr vhead = getHead(vterm);
05849   TRACE("quant newequ", "gterm: " ,gterm, "");
05850   TRACE("quant newequ", "v: " , vterm, "" );
05851   //
05852     Idealy, once a successful mathing is found here, the search should continue to checkif there are more matchings.  For example, suppose vterm is f(g(x)) and gterm is f(a), and a=g(c)=g(d), c!=d.  The algorithm used now will only return the matching x=c.  There is no reason to leave x=d out.  However, testing of all quantified cases in SMT LIB, as of 11/28/2007, shows that the above senario never happens.  So, the search algorithm here returns once a successful matching is found
05853     //    This is not true for set1.smt
05854   //  vector<ExprMap<Expr> > candidateEnv;
05855   vector<Expr> candidateGterms;
05856 
05857   while (cur_next != gterm){
05858     if(simplifyExpr(cur_next) != simplifyExpr(gterm)){
05859       cout<<" impossible"<<endl;
05860     }
05861     cout<<"pushed candidate gterm " << cur_next << endl;
05862     candidateGterms.push_back(cur_next);
05863     cur_next = cur_next.getEqNext().getRHS();
05864   }
05865 
05866   //  for(int curGtermIndex = candidateGterms.size()-1; curGtermIndex >=0 ; curGtermIndex--){
05867   for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
05868     Expr curGterm = candidateGterms[curGtermIndex];
05869     if(getHead(curGterm) == vhead){
05870       TRACE("quant newequ", " matched good", "", "");
05871       ExprMap<Expr> newEnv = orgEnv;
05872       bool res =  matchChild(curGterm, vterm, newEnv);
05873       TRACE("quant newequ", "final result: ",res ,"");
05874       if (res)  {
05875         env=newEnv;
05876         //  return res;
05877         cout << "found new match: " << endl;
05878         cout << "curGterm: " <<  curGterm << endl;
05879         cout << "simplified Gterm: " << simplifyExpr(gterm) << endl;
05880         cout << "simplified curGterm: " << simplifyExpr(curGterm) << endl;
05881         newwayEnv = newEnv;
05882         newwayResult = res; //break;;
05883         candidateEnv.push_back(newEnv);
05884       }
05885     }
05886   }
05887 
05888 
05889 
05890   while (cur_next != gterm) {
05891     TRACE("quant newequ", "g: " ,cur_next, "");
05892     TRACE("quant newequ", "vhead: ", vhead, "");
05893     TRACE("quant newequ", "g head: ", getHead(cur_next), "");
05894     TRACE("quant newequ", "g score: ", getExprScore(cur_next), "");
05895     //      if(getExprScore(cur_next)>15) continue;
05896 
05897     if(getHead(cur_next) == vhead){
05898 
05899       TRACE("quant newequ", " matched good", "", "");
05900       ExprMap<Expr> newEnv = env;
05901       bool res =  matchChild(cur_next, vterm, newEnv);
05902       TRACE("quant newequ", "final result: ",res ,"");
05903       if (res)  {
05904         env=newEnv;
05905         //  return res;
05906         newwayEnv = newEnv;
05907         newwayResult = res; //break;;
05908         candidateEnv.push_back(newEnv);
05909       }
05910     }
05911     cur_next = cur_next.getEqNext().getRHS();
05912   }
05913 
05914 
05915 //  if(candidateEnv.size() == 1){
05916 //    env = candidateEnv[0];
05917 //    return true;
05918 //  }
05919 //  else if (candidateEnv.size() > 1){
05920 //    env = candidateEnv[0];
05921 //    return true;
05922 //    cout<<"found more matcings" << endl;
05923 //  }
05924 
05925 
05926   if (candidateEnv.size() > 1){
05927     cout<<"found more matcings" << endl;
05928     //    newwayEnv = candidateEnv[0];
05929   }
05930 
05931   TRACE("quant newequ", " not matched ", vterm, gterm);
05932     //    return false;
05933   if(newwayResult) {
05934   }
05935   else{
05936   newwayResult = false ;
05937   }
05938       }
05939 
05940       vector<ExprMap<Expr> > candidateOldEnv; //for test only
05941       //      else { //else we use old equ algorithm
05942   env = orgEnv;
05943   //  cout<<"==============================="<<endl;
05944   //  cout<<gterm<<" # " <<vterm<<endl;
05945 
05946   if(false)
05947     { //
05948     //    std::set<Expr> eq_set;
05949     std::map<Expr,bool> eq_set;
05950     eq_set.clear();
05951     eq_set[gterm]=true;
05952 
05953     std::queue<Expr> eq_queue;
05954 
05955     ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.find(gterm);
05956 
05957     if(iter != d_eq_list.end()){
05958       for(size_t len =0; len< iter->second->size(); len++){
05959         eq_queue.push((*(iter->second))[len]);
05960       }
05961       int count =0;
05962       while(eq_queue.size()>0){
05963         count++;
05964         const Expr& cur = eq_queue.front();
05965         eq_queue.pop();
05966         if(eq_set.find(cur) == eq_set.end()){
05967     if(canGetHead(cur) && getHead(cur) == vhead){
05968 //              cout<<"VTERM: "<<vterm<<endl;
05969 //              cout<<"FOUND: "<<cur<<endl;
05970 //              cout<<"GTERM:  "<<gterm<<endl;
05971       //      cout<<"--good match: " << count << "  // " << gterm << " # " << cur << endl;
05972       //      cout<<"===good simple: " << count << "  // " << simplifyExpr(gterm) << " # " << simplifyExpr(cur) << endl;
05973 
05974       if(simplifyExpr(cur) != simplifyExpr(gterm)){
05975         // return false;
05976         //        return matchChild(cur, vterm, env);
05977         //        cout<<"en? "<<gterm<<" # " <<cur <<" # " <<vterm<<endl;
05978       }
05979       else{
05980         //        cout<<"--good match: " << count << "  // " << gterm << " # " << cur << endl;
05981         //        cout<<"===good simple: " << count << "  // " << simplifyExpr(gterm) << " # " << simplifyExpr(cur) << endl;
05982         //        return matchChild(cur, vterm, env);
05983       }
05984     }
05985 
05986     eq_set[cur]=true;
05987     ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.find(cur);
05988 
05989     if(iter != d_eq_list.end()){
05990       for(size_t len =0; len< iter->second->size(); len++){
05991         eq_queue.push((*(iter->second))[len]);
05992       }
05993     }
05994         }
05995       }
05996     }
05997     //    return false;
05998   }
05999 
06000   if( d_same_head_expr.count(vhead) > 0 ) {
06001     const Expr& findGterm = simplifyExpr(gterm);
06002     //if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
06003     TRACE("quant match", "find gterm:", findGterm.toString(),"");
06004     CDList<Expr>* gls = d_same_head_expr[vhead];
06005     if (false)
06006       { int count =0;
06007         for(size_t i = 0; i<gls->size(); i++){
06008         if (simplifyExpr((*gls)[i]) == findGterm){
06009         count++;
06010         }
06011         }
06012         if(count>1){
06013         cout<<"count " << count << " # " << gls->size() << " | "<<gterm<<endl;
06014         for(size_t i = 0; i<gls->size(); i++){
06015         if (simplifyExpr((*gls)[i]) == findGterm){
06016         cout<<"eq "<<(*gls)[i]<<endl;
06017         }
06018         }
06019         }
06020         }
06021 
06022     for(size_t i = 0; i<gls->size(); i++){
06023       cout<<"same head term " << (*gls)[i] << endl;
06024       if (simplifyExpr((*gls)[i]) == findGterm){
06025         env = orgEnv;
06026         oldwayResult = true;
06027         TRACE("quant match", "find matched gterm:", (*gls)[i].toString(),"");
06028         DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
06029 
06030         const Expr& newgterm = (*gls)[i];
06031         for(int child=vterm.arity()-1; child >= 0 ; child--){
06032     if (false == recSynMatch(newgterm[child], vterm[child] , env)){
06033       TRACE("quant match", "match false", (*gls)[i][child].toString(), vterm[child].toString());
06034       //        return false;
06035       oldwayEnv = env; oldwayResult = false; break;
06036     }
06037         }
06038         TRACE("quant match", "good match, return true:", gterm, vterm.toString());
06039         //        cout<<"quant good match: " <<i<<" // "<<gterm << " # "<<vterm<<endl;
06040         //        cout<<"quant simple: " <<i<<" // "<<simplifyExpr(gterm) << " # "<<vterm<<endl;
06041     //    return true;
06042         //problem
06043         if(oldwayResult){
06044     cout << "old curGterm: " << newgterm << endl;
06045     cout << "old simplifed  curGterm: " << simplifyExpr(newgterm) << endl;
06046     oldwayResult = true; oldwayEnv = env; //break;
06047     candidateOldEnv.push_back(oldwayEnv);
06048         }
06049         else{
06050     oldwayResult = false;
06051         }
06052       }
06053     }//end of for
06054     //  do not forget this    return false;
06055 
06056   }
06057   else  {
06058     oldwayResult = false;
06059     //      return false;//end of if
06060   }
06061   //      }
06062 
06063   cout<<"new env size" << candidateEnv.size() << endl;
06064   cout<<"old env size" << candidateOldEnv.size() << endl;
06065   if( candidateEnv.size() != candidateOldEnv.size()){
06066     cout<<"error?" << endl;
06067   }
06068   if(newwayEnv != oldwayEnv && oldwayResult == newwayResult){
06069   bool notFound(true);
06070   int foundIndex(-1);
06071   for(size_t i = 0; i <candidateEnv.size(); i++){
06072     if (candidateEnv[i] == oldwayEnv){
06073       foundIndex = i;
06074       cout<<"found env " << i << endl;
06075       notFound = false;
06076     }
06077   }
06078   if (notFound){
06079     cout<<"found strange env" << endl;;
06080     cout<<"new way find " << candidateEnv.size()<<endl;
06081     cout<<gterm << " " << gterm.getIndex()<<endl;
06082     cout<<vterm << " " << vterm.getIndex()<<endl;
06083     cout << "oldEnv" << candidateOldEnv.size() << endl;
06084     cout<<exprMap2string(newwayEnv)<<endl;
06085     cout<<exprMap2string(oldwayEnv)<<endl;
06086 
06087   }
06088       }
06089       if(oldwayResult != newwayResult){
06090   cout<<"found strange" << endl;
06091   cout<<gterm << " " << gterm.getIndex()<<endl;
06092   cout<<vterm << " " << vterm.getIndex()<<endl;
06093       }
06094       else{
06095   //  env = newwayEnv;
06096   return oldwayResult;
06097       }
06098 
06099     }
06100     else{
06101       TRACE("quant match more", "match more", gterm.toString()+" # ", vterm.toString());
06102       if( (gterm.getKind() == vterm.getKind()) &&
06103     (gterm.arity() == vterm.arity()) &&
06104     gterm.arity()>0 ){
06105   //      for(int child=0; child < vterm.arity() ; child++){
06106   //        if (false == recSynMatch(gterm[child], vterm[child] , env)){
06107   //          TRACE("quant match", "match false", gterm[child].toString(), vterm[child].toString());
06108 //          return false;
06109 //        }
06110 //      }
06111 //      return true;
06112 //      if( gterm.getKind() == PLUS || gterm.getKind() == MINUS){
06113 //        cout<<"g v"<<gterm<< " # " <<vterm<<endl;
06114 //      }
06115 
06116   return matchChild(gterm, vterm, env);
06117       }
06118       else {
06119 //      if( gterm.getKind() == PLUS || gterm.getKind() == MINUS){
06120 //      static bool gvfound = false;
06121 //        if(!gvfound){
06122 //        cout<<"g v 1"<<endl;
06123 //        gvfound =true;
06124 //      }
06125       //gterm<< " # " <<vterm<<endl;
06126     //  }
06127   return false;
06128       }
06129     }
06130   }
06131 }
06132 */
06133 
06134 /*
06135 
06136 bool TheoryQuant::synMatchTopPred(const Expr& gterm, Trigger trig, ExprMap<Expr>& env){
06137 
06138   const Expr vterm = trig.getEx();
06139 
06140   TRACE("quant toppred", "top pred: gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
06141 
06142   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
06143   DebugAssert ((BOUND_VAR != vterm.getKind()),"top pred match "+gterm.toString()+" has bound var");
06144 
06145   if(gterm.isEq() || vterm.isEq()){
06146     return false; // we do not match with equality
06147   }
06148 
06149   bool res2=false;
06150 
06151   //  if(vterm.arity() != gterm.arity()) return false;
06152 
06153   if(trig.isSimp()){
06154     if(trig.getHead() == getHead(gterm) ){
06155       for(int i = vterm.arity()-1; i>=0 ; i--){
06156   if(BOUND_VAR != vterm[i].getKind()){
06157     if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
06158       return false;
06159     }
06160   }
06161       }
06162       for(int i = vterm.arity()-1; i>=0 ; i--){
06163   if(BOUND_VAR == vterm[i].getKind()){
06164     if(d_allout){
06165       env[vterm[i]] = simplifyExpr(gterm[i]);
06166     }
06167     else {
06168       env[vterm[i]] = simplifyExpr(gterm[i]);
06169     }
06170   }
06171       }
06172       return true;
06173     }
06174     else{
06175       return false;
06176     }
06177   }
06178 
06179   if(!(isSysPred(vterm) && isSysPred(gterm))){
06180     if(isSysPred(vterm) || isSysPred(gterm)) {
06181       return false;
06182     }
06183     if(!usefulInMatch(gterm)){
06184       return false;
06185     }
06186     if(trig.getHead() != getHead(gterm)){
06187       return false;
06188     }
06189 
06190     if(!gterm.getType().isBool()){
06191       res2= recSynMatch(gterm, vterm, env);
06192       return res2;
06193     }
06194 
06195     if(!*d_usePolarity){
06196       return recSynMatch(gterm, vterm, env);
06197     }
06198 
06199     const bool gtrue = (trueExpr()==findExpr(gterm));
06200     if(gtrue ){
06201       if(trig.isNeg()) {
06202   return recSynMatch(gterm, vterm, env);
06203       }
06204       else{
06205   return false;
06206       }
06207     }
06208     const bool gfalse = (falseExpr()==findExpr(gterm));
06209     if(gfalse){
06210       if (trig.isPos()){
06211   return recSynMatch(gterm, vterm, env);
06212       }
06213       else{
06214   return false;
06215       }
06216     }
06217     else {
06218       return false;
06219     }
06220   }
06221   else{
06222     DebugAssert((2==gterm.arity() && 2==vterm.arity()), "impossible situation in top pred");
06223     DebugAssert(!((isLE(gterm) || isLT(gterm)) && !isIntx(gterm[0],0)), "canonical form changed");
06224 
06225 #ifdef _CVC3_DEBUG_MODE
06226     if( CVC3::debugger.trace("quant toppred")  ){
06227       cout << "toppred gterm, vterm" << gterm << "::" << vterm << endl;
06228       cout << findExpr(gterm) << "::" << trig.isPos() << "|" << trig.isNeg() << endl;
06229     }
06230 #endif
06231 
06232 
06233     Expr gl = getLeft(gterm[1]);
06234     Expr gr = getRight(gterm[1]);
06235 
06236     if(null_expr == gr || null_expr == gl){
06237       gl = gterm[0];
06238       gr = gterm[1];
06239     }
06240 
06241     Expr vr, vl;
06242     Expr tvr, tvl;
06243 
06244     tvr=null_expr;
06245     tvl=null_expr;
06246 
06247     if(isGE(vterm) || isGT(vterm)){
06248       vr = vterm[0];
06249       vl = vterm[1];
06250     }
06251     else if(isLE(vterm) || isLT(vterm)){
06252       vr = vterm[1];
06253       vl = vterm[0];
06254     }
06255     else{
06256       DebugAssert(false, "impossilbe in toppred");
06257     }
06258 
06259     if(isIntx(vl,0)){
06260       tvl = getLeft(vr);
06261       tvr = getRight(vr);
06262     }
06263     else if(isIntx(vr,0)) {
06264       tvl = getLeft(vl);
06265       tvr = getRight(vl);
06266     }
06267 
06268     if( (null_expr != tvl) && (null_expr != tvr)){
06269       vl = tvl;
06270       vr = tvr;
06271     }
06272 
06273 
06274     const bool gtrue = (trueExpr()==findExpr(gterm));
06275     const bool gfalse = (falseExpr()==findExpr(gterm));
06276 
06277     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
06278 
06279     bool res;
06280 
06281     DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
06282 
06283     if(!*d_usePolarity){
06284       return (recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
06285     }
06286 
06287     if(trig.isNeg()){
06288       if (( gtrue ) )  {
06289   res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
06290       }
06291       else {
06292   res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
06293       }
06294     }
06295     else if(trig.isPos()){
06296       if (( gfalse )) {
06297   res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
06298       }
06299       else {
06300   res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
06301       }
06302     }
06303     else {
06304       DebugAssert(false, "impossible polarity for trig");
06305       res = false;
06306     }
06307 
06308 #ifdef _CVC3_DEBUG_MODE
06309     if( CVC3::debugger.trace("quant toppred")  ){
06310       cout<<"res| "<< res << " | " << gtrue << " | " << gfalse << endl;
06311     }
06312 #endif
06313     return res;
06314   }
06315 }
06316 
06317 bool TheoryQuant::recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
06318   TRACE("quant match", "gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
06319   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
06320 
06321   if (BOUND_VAR == vterm.getKind())  {
06322     TRACE("quant match", "bound var found;", vterm.toString(),"");
06323     ExprMap<Expr>::iterator p = env.find(vterm);
06324     if ( p != env.end()){
06325       if (simplifyExpr(gterm) != simplifyExpr(p->second)){
06326   return false;
06327       }
06328       else
06329   return true;
06330     }
06331     else {
06332       env[vterm] = simplifyExpr(gterm);
06333       return true;
06334     }
06335   }
06336   else if (!vterm.containsBoundVar()){
06337     if(simplifyExpr(vterm) == simplifyExpr(gterm)) {
06338       return true;
06339     }
06340     else{
06341       return false;
06342     }
06343   }
06344 
06345   else if(false && isSysPred(vterm) && isSysPred(gterm)){
06346 
06347     TRACE("quant syspred"," vterm, gterm ", vterm.toString()+" :|: ", gterm.toString());
06348     TRACE("quant syspred"," simplified vterm, gterm ", simplifyExpr(vterm).toString()+" :|: ", simplifyExpr(gterm).toString());
06349     FatalAssert(false, "should not be here in synmatch");
06350     exit(3);
06351   }
06352   else{
06353       if(canGetHead(vterm)){
06354   Expr vhead = getHead(vterm);
06355   TRACE("quant match", "head vterm:", getHead(vterm), "");
06356   if(vterm.isAtomicFormula()){
06357     if (canGetHead(gterm)) {
06358       if ( vhead != getHead(gterm) ){
06359         return false;
06360       }
06361       for(int i=vterm.arity()-1; i >= 0; i--){
06362         if (false == recSynMatch(gterm[i], vterm[i] , env))
06363     return false;
06364       }
06365       return true;
06366     }
06367     else{
06368       return false;
06369     }
06370   }
06371   if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
06372     if(gterm.arity() != vterm.arity()){
06373       return false;
06374     }
06375     for(int i=vterm.arity()-1; i >= 0; i--){
06376       if (false == recSynMatch(gterm[i], vterm[i] , env)) {
06377         return false;
06378       }
06379     }
06380     return true;
06381   }
06382 
06383   if(false && !*d_useEqu){
06384     return false;
06385   }
06386 
06387   if( d_same_head_expr.count(vhead) > 0 ) {
06388     const Expr& findGterm = simplifyExpr(gterm);
06389     //if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
06390     TRACE("quant match", "find gterm:", findGterm.toString(),"");
06391     CDList<Expr>* gls = d_same_head_expr[vhead];
06392     for(size_t i = 0; i<gls->size(); i++){
06393       if (simplifyExpr((*gls)[i]) == findGterm){
06394         TRACE("quant match", "find matched gterm:", (*gls)[i].toString(),"");
06395         DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
06396 
06397         for(int child=vterm.arity()-1; child >= 0 ; child--){
06398     const Expr& newgterm = (*gls)[i];
06399     if (false == recSynMatch(newgterm[child], vterm[child] , env)){
06400       TRACE("quant match", "match false", (*gls)[i][child].toString(), vterm[child].toString());
06401       return false;
06402     }
06403         }
06404         TRACE("quant match", "good match, return true:", gterm, vterm.toString());
06405         return true;
06406       }
06407     }//end of for
06408     return false;
06409   }
06410   else  {
06411     return false;//end of if
06412   }
06413       }
06414       else{
06415   TRACE("quant match more", "match more", gterm.toString()+" # ", vterm.toString());
06416   if( (gterm.getKind() == vterm.getKind()) &&
06417       (gterm.arity() == vterm.arity()) &&
06418       gterm.arity()>0 ){
06419     for(int child=0; child < vterm.arity() ; child++){
06420       if (false == recSynMatch(gterm[child], vterm[child] , env)){
06421         TRACE("quant match", "match false", gterm[child].toString(), vterm[child].toString());
06422         return false;
06423       }
06424     }
06425     return true;
06426   }
06427   else  return false;
06428       }
06429   }
06430 }
06431 
06432 */
06433 
06434 /*
06435 void TheoryQuant::goodSynMatch(const Expr& e,
06436              const std::vector<Expr> & boundVars,
06437              std::vector<std::vector<Expr> >& instBinds,
06438              std::vector<Expr>& instGterms,
06439              const CDList<Expr>& allterms,
06440              size_t tBegin){
06441   for (size_t i=tBegin; i<allterms.size(); i++)    {
06442     Expr gterm = allterms[i];
06443     if (0 == gterm.arity() )
06444       continue;
06445     TRACE("quant matching", gterm.toString(), "||", e.toString()) ;
06446     //    if( usefulInMatch(gterm) && possibleMatch(gterm,e))   {
06447     if(usefulInMatch(gterm))   {
06448       ExprMap<Expr> env;
06449       env.clear();
06450       bool found = recSynMatch(gterm,e,env);
06451       if(found){
06452 
06453   TRACE("quant matching found", " good:",gterm.toString()+" to " , e.toString());
06454   TRACE("quant matching found", " simplified good:",simplifyExpr(gterm).toString()+" to " , simplifyExpr(e).toString());
06455   std::vector<Expr> inst;
06456 
06457   DebugAssert((boundVars.size() == env.size()),"bound var size != env.size()");
06458 
06459   for(size_t i=0; i<boundVars.size(); i++) {
06460     ExprMap<Expr>::iterator p = env.find(boundVars[i]);
06461     DebugAssert((p!=env.end()),"bound var cannot be found");
06462     inst.push_back(p->second);
06463   }
06464   instBinds.push_back(inst);
06465   instGterms.push_back(gterm);
06466       }
06467       else{
06468   TRACE("quant matching", "bad one",gterm.toString()+" to " , e.toString());
06469       }
06470     }
06471   }
06472 }
06473 
06474 */
06475 /*
06476 void TheoryQuant::goodSynMatchNewTrig(const Trigger& trig,
06477               const std::vector<Expr> & boundVars,
06478               std::vector<std::vector<Expr> >& instBinds,
06479               std::vector<Expr>& instGterms,
06480               const CDList<Expr>& allterms,
06481               size_t tBegin){
06482   for (size_t i=tBegin; i<allterms.size(); i++)    {
06483     Expr gterm (allterms[i]);
06484     //    TRACE("quant matching", gterm.toString(), "||", trig.getEx().toString()) ;
06485     if(usefulInMatch(gterm)) {
06486       ExprMap<Expr> env;
06487       env.clear();
06488       bool found = synMatchTopPred(gterm,trig,env);
06489       if(found){
06490   //TRACE("quant matching found", " top good:",gterm.toString()+" to " , trig.getEx().toString());
06491   std::vector<Expr> inst;
06492   inst.clear();
06493   DebugAssert((boundVars.size() <= env.size()),"bound var size != env.size()");
06494 
06495   for(size_t i=0; i<boundVars.size(); i++) {
06496     ExprMap<Expr>::iterator p = env.find(boundVars[i]);
06497     DebugAssert((p!=env.end()),"bound var cannot be found");
06498     inst.push_back(p->second);
06499   }
06500 
06501   instBinds.push_back(inst);
06502   instGterms.push_back(gterm);
06503       }
06504       else{
06505   //  TRACE("quant matching", "bad one",gterm.toString()+" to ", trig.getEx().toString());
06506       }
06507     }
06508   }
06509 }
06510 */
06511 
06512 /*
06513 bool TheoryQuant::hasGoodSynInstNewTrigOld(Trigger& trig,
06514              std::vector<Expr> & boundVars,
06515              std::vector<std::vector<Expr> >& instBinds,
06516              std::vector<Expr>& instGterms,
06517              const CDList<Expr>& allterms,
06518              size_t tBegin){
06519 
06520   const std::set<Expr>& bvs = getBoundVars(trig.getEx());
06521 
06522   boundVars.clear();
06523   for(std::set<Expr>::const_iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
06524     boundVars.push_back(*i);
06525 
06526   instBinds.clear();
06527   goodSynMatchNewTrig(trig, boundVars, instBinds, instGterms, allterms, tBegin);
06528 
06529   if (instBinds.size() > 0)
06530     return true;
06531   else
06532     return false;
06533 }
06534 
06535 
06536 bool TheoryQuant::hasGoodSynInstNewTrig(Trigger& trig,
06537           const std::vector<Expr>& boundVars,
06538           std::vector<std::vector<Expr> >& instBinds,
06539           std::vector<Expr>& instGterms,
06540           const CDList<Expr>& allterms,
06541           size_t tBegin){
06542 //   boundVars=trig.getBVs();
06543 //   const std::set<Expr>& bvs = getBoundVars(trig.getEx());
06544 
06545 //   boundVars.clear();
06546 //   for(std::set<Expr>::const_iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
06547 //     boundVars.push_back(*i);
06548 
06549   instBinds.clear();
06550   goodSynMatchNewTrig(trig, boundVars, instBinds, instGterms, allterms, tBegin);
06551 
06552   if (instBinds.size() > 0)
06553     return true;
06554   else
06555     return false;
06556 }
06557 */
06558 int TheoryQuant::loc_gterm(const std::vector<Expr>& border,
06559          const Expr& vterm,
06560          int pos){
06561   const std::vector<Expr>& order = d_mtrigs_bvorder[vterm];
06562   const Expr& var = order[pos];
06563   for(size_t i=0; i<border.size(); i++){
06564     if (border[i] == var) return i;
06565   }
06566 
06567   DebugAssert(false, "internal error in loc_germ");
06568   return -1;
06569 }
06570 
06571 /*
06572 void  TheoryQuant::recSearchCover(const std::vector<Expr>& border,
06573           const std::vector<Expr>& mtrigs,
06574           int cur_depth,
06575           std::vector<std::vector<Expr> >& instSet,
06576           std::vector<Expr>& cur_inst
06577           ){
06578   int max_dep = mtrigs.size();
06579 
06580   if(cur_depth >= max_dep) return;
06581 
06582   Expr cur_vterm = mtrigs[cur_depth]; //get the current vterm
06583   if(d_mtrigs_inst.count(cur_vterm) <=0) return;
06584   CDList<std::vector<Expr> >* gterm_list = d_mtrigs_inst[cur_vterm]; // get the list of ground term found for cur_vterm
06585   for(size_t i=0; i< gterm_list->size(); i++){
06586     const std::vector<Expr>& cur_gterm = (*gterm_list)[i];
06587     std::vector<Expr> new_inst(border.size()); //get a new inst array
06588 
06589     for(size_t j=0; j< border.size(); j++){
06590       new_inst[j]=cur_inst[j]; //copy to cur_int to new_inst
06591     }
06592 
06593     bool has_problem = false;//next, try to put the cur gterm into new_inst
06594     for(size_t j=0; j< cur_gterm.size(); j++){
06595       int cur_loc_gterm = loc_gterm(border, cur_vterm, j);
06596 
06597       if( null_expr == new_inst[cur_loc_gterm]){
06598   new_inst[cur_loc_gterm] = cur_gterm[j];
06599       }
06600       else if (new_inst[cur_loc_gterm] != cur_gterm[j]){
06601   has_problem = true;
06602   break;
06603       }
06604 
06605     }
06606 
06607     if (has_problem){
06608       continue;
06609     }
06610 
06611     bool finished = true;
06612     for(size_t j=0; j< border.size() ;j++){
06613       if(null_expr == new_inst[j]){
06614   finished = false;
06615   break;
06616       }
06617     }
06618 
06619     if(finished){
06620       std::vector<Expr> good_inst;
06621       for(size_t j=0; j<border.size(); j++){
06622   good_inst.push_back(new_inst[j]);
06623       }
06624       instSet.push_back(good_inst);
06625     }
06626     else{
06627       recSearchCover(border,
06628          mtrigs,
06629          cur_depth+1,
06630          instSet,
06631          new_inst);
06632     }
06633   }//end of for
06634 }
06635 */
06636 /*
06637 void  TheoryQuant::searchCover(const Expr& thm,
06638              const std::vector<Expr>& border,
06639              std::vector<std::vector<Expr> >& instSet
06640              ){
06641   std::vector<Expr> dumy(border.size()) ; //use dynamic array here
06642   for(size_t j=0; j< border.size() ;j++){
06643     dumy[j]=null_expr;
06644   }
06645   const std::vector<Expr>& mtrigs = d_multTriggers[thm];
06646   recSearchCover(border, mtrigs, 0, instSet, dumy);
06647 }
06648 
06649 */
06650 /*
06651 bool TheoryQuant::hasGoodSynMultiInst(const Expr& thm,
06652               std::vector<Expr> & boundVars,
06653               std::vector<std::vector<Expr> >& instSet,
06654               const CDList<Expr>& allterms,
06655               size_t tBegin){
06656 
06657   const std::set<Expr>& bvs = getBoundVars(thm);
06658 
06659   boundVars.clear();
06660   for(std::set<Expr>::const_iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
06661     boundVars.push_back(*i);
06662 
06663   instSet.clear();
06664 
06665   bool new_match = false;
06666   //assumption: every trig is different
06667   //this is not true later, fix this asap
06668   const std::vector<Expr>& mtrigs = d_multTriggers[thm];
06669 
06670   for(std::vector<Expr>::const_iterator i= mtrigs.begin(), iend = mtrigs.end(); i != iend; i++){
06671 
06672     if(d_mtrigs_bvorder[*i].empty()){ //setup an order
06673       const std::set<Expr>& trig_bvs = getBoundVars(*i);
06674       for(std::set<Expr>::const_iterator j= trig_bvs.begin(), jend = trig_bvs.end();
06675     j != jend;
06676     j++){
06677   d_mtrigs_bvorder[*i].push_back(*j);
06678       }
06679     }
06680 
06681     const std::vector<Expr>& trig_bvorder = d_mtrigs_bvorder[*i];
06682     //    std::set<std::vector<Expr> > trig_insts;
06683     std::vector<std::vector<Expr> > trig_insts;
06684     trig_insts.clear();
06685 
06686     std::vector<Expr> gtms;
06687     goodSynMatch(*i, trig_bvorder, trig_insts, gtms, allterms, tBegin);
06688 
06689     if (trig_insts.size() > 0){
06690       new_match=true;
06691       if(d_mtrigs_inst.count(*i) <= 0){
06692   d_mtrigs_inst[*i] = new(true) CDList<std::vector<Expr> > (theoryCore()->getCM()->getCurrentContext());
06693       }
06694       for(std::vector<std::vector<Expr> >::const_iterator j = trig_insts.begin(), jend = trig_insts.end();
06695     j != jend;
06696     j++){
06697 
06698   d_mtrigs_inst[*i]->push_back(*j);
06699   for(std::vector<Expr>::const_iterator k = j->begin(), kend = j->end();
06700       k != kend;
06701       k++){
06702   }
06703       }
06704     }
06705   } // end of for
06706 
06707   for(std::vector<Expr>::const_iterator i= mtrigs.begin(), iend = mtrigs.end(); i != iend; i++){
06708     if (d_mtrigs_inst.count(*i) <=0 ) continue;
06709     for(CDList<std::vector<Expr> >::const_iterator j = d_mtrigs_inst[*i]->begin(),
06710     jend = d_mtrigs_inst[*i]->end();
06711     j != jend;
06712     j++){
06713 
06714       for(std::vector<Expr>::const_iterator k = j->begin(), kend = j->end();
06715     k != kend;
06716     k++){
06717       }
06718     }
06719   }
06720   {//code for search a cover
06721     if(new_match){
06722       searchCover(thm, boundVars, instSet);
06723     }
06724   }
06725 
06726   if(instSet.size() > 0 ) {
06727     return true;
06728   }
06729   else {
06730     return false;
06731   }
06732 
06733 }
06734 
06735 */
06736 /*
06737 
06738 bool inStrCache(std::set<std::string> cache, std::string str){
06739   return (cache.find(str) != cache.end());
06740 }
06741 */
06742 /*
06743 bool TheoryQuant::hasGoodSemInst(const Expr& e,
06744          std::vector<Expr> & boundVars,
06745          std::set<std::vector<Expr> >& instSet,
06746          size_t tBegin){
06747   return false;
06748 }
06749 
06750 */
06751 /*
06752 void genPartInstSetThm(const std::vector<Expr>&  bVarsThm,
06753            std::vector<Expr>& bVarsTerm,
06754            const std::vector<std::vector<Expr> >& termInst,
06755            std::vector<std::vector<Expr> >& instSetThm){
06756   ExprMap<bool> bVmap;
06757 
06758   for(size_t i=0; i< bVarsThm.size(); ++i)    {
06759     bVmap[bVarsThm[i]]=true;
06760   }
06761 
06762   std::vector<Expr> tempBVterm;
06763   std::vector<int> locTerm;
06764 
06765   for (size_t j=0; j<bVarsTerm.size(); j++){
06766     if (bVmap.count(bVarsTerm[j]) > 0){
06767       locTerm.push_back(1);
06768       tempBVterm.push_back(bVarsTerm[j]);
06769     }
06770     else{
06771       locTerm.push_back(0);
06772     }
06773   }
06774 
06775   DebugAssert(locTerm.size() == bVarsTerm.size(), "locTerm.size !- bVarsTerm.size()");
06776 
06777   for(std::vector<std::vector<Expr> >::const_iterator i=termInst.begin(),
06778   iend=termInst.end();i!=iend; i++)  {
06779     std::vector<Expr> buf;
06780     buf.clear();
06781     for(size_t j=0; j< bVarsTerm.size(); ++j){
06782       if(locTerm[j])
06783   buf.push_back((*i)[j]);
06784     }
06785     instSetThm.push_back(buf);
06786   }
06787   bVarsTerm=tempBVterm;
06788 }
06789 */
06790 
06791 /*
06792 void genInstSetThm(const std::vector<Expr>& bVarsThm,
06793        const std::vector<Expr>& bVarsTerm,
06794        const std::vector<std::vector<Expr> >& termInst,
06795        std::vector<std::vector<Expr> >& instSetThm){
06796 
06797   std::vector<int> bVmap;
06798 
06799   for(size_t i=0; i< bVarsThm.size(); ++i)    {
06800     bVmap.push_back(-1);
06801     for (size_t j=0; j<bVarsTerm.size(); j++){
06802       if (bVarsThm[i] == bVarsTerm[j]){
06803   DebugAssert(bVmap[i] == -1, "bVmap[1] != -1");
06804   bVmap[i]=j;
06805       }
06806     }
06807   }
06808 
06809   for(size_t i=0; i< bVarsThm.size(); ++i)
06810     if( -1 == bVmap[i])  {
06811       return;
06812     }
06813 
06814   for(std::vector<std::vector<Expr> >::const_iterator i=termInst.begin(),
06815   iend=termInst.end();i!=iend; i++)  {
06816     std::vector<Expr> buf;
06817     buf.clear();
06818     for(size_t j=0; j< bVarsThm.size(); ++j){
06819       buf.push_back((*i)[bVmap[j]]);
06820     }
06821     instSetThm.push_back(buf);
06822   }
06823 }
06824 */
06825 
06826 /*
06827 void TheoryQuant::synInst(const Theorem & univ, const CDList<Expr>& allterms, size_t tBegin ){
06828   if(d_useFullTrig){
06829     synFullInst(univ, allterms, tBegin);
06830   }
06831 
06832   if(d_useMultTrig){
06833     synMultInst(univ, allterms, tBegin);
06834   }
06835 
06836   if(d_usePartTrig){
06837     synPartInst(univ, allterms, tBegin);
06838   }
06839 }
06840 */
06841 
06842 inline bool TheoryQuant::transFound(const Expr& comb){
06843   return (d_trans_found.count(comb) > 0);
06844 }
06845 
06846 inline void TheoryQuant::setTransFound(const Expr& comb){
06847   d_trans_found[comb] = true;
06848 }
06849 
06850 inline bool TheoryQuant::trans2Found(const Expr& comb){
06851   return (d_trans2_found.count(comb) > 0);
06852 }
06853 
06854 inline void TheoryQuant::setTrans2Found(const Expr& comb){
06855   d_trans2_found[comb] = true;
06856 }
06857 
06858 
06859 inline CDList<Expr> & TheoryQuant::backList(const Expr& ex){
06860   if(d_trans_back.count(ex)>0){
06861     return *d_trans_back[ex];
06862   }
06863   else{
06864     return null_cdlist;
06865   }
06866 }
06867 
06868 inline CDList<Expr> & TheoryQuant::forwList(const Expr& ex){
06869   if(d_trans_forw.count(ex)>0){
06870     return *d_trans_forw[ex];
06871   }
06872   else{
06873     return null_cdlist;
06874   }
06875 }
06876 
06877 inline void  TheoryQuant::pushBackList(const Expr& node, Expr ex){
06878   if(d_trans_back.count(node)>0){
06879     d_trans_back[node]->push_back(ex);
06880   }
06881   else{
06882     d_trans_back[node] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext());
06883     d_trans_back[node]->push_back(ex);
06884   }
06885 }
06886 
06887 inline void  TheoryQuant::pushForwList(const Expr& node, Expr ex){
06888   if(d_trans_forw.count(node)>0){
06889     d_trans_forw[node]->push_back(ex);
06890   }
06891   else{
06892     d_trans_forw[node] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext());
06893     d_trans_forw[node]->push_back(ex);
06894   }
06895 }
06896 
06897 /*
06898 void TheoryQuant::synFullInst(const Theorem & univ, const CDList<Expr>& allterms, size_t tBegin ){
06899 
06900   const Expr& quantExpr = univ.getExpr();
06901   //  const std::vector<Expr>& bVarsThm = quantExpr.getVars();
06902   std::vector<Expr> bVarsThm = quantExpr.getVars();
06903 
06904   TRACE("quant inst", "try full inst with:|", quantExpr.toString() , " ");
06905 
06906   std::vector<std::vector<Expr> > instBindsThm; //set of instantiations for the thm,
06907   std::vector<std::vector<Expr> > instBindsTerm; //bindings, in the order of bVarsTrig
06908   std::vector<Expr > instGterms; //instGterms are gterms matched, instBindsTerm and instGterms must have the same length
06909   std::vector<Expr> bVarsTrig;
06910 
06911   if(*d_useTrigNew){
06912     std::vector<Trigger>& new_trigs=d_fullTrigs[quantExpr];
06913     for( size_t i= 0; i<new_trigs.size(); i++)  {
06914       Trigger& trig = new_trigs[i];
06915       //      if( 0 != trig.getPri()) continue;
06916       TRACE("quant inst","try new full trigger:|", trig.getEx().toString(),"");
06917 
06918       instBindsTerm.clear();
06919       bVarsTrig.clear();
06920       instBindsThm.clear();
06921       instGterms.clear();
06922 
06923       {//code for trans2
06924   if(trig.hasTr2()){
06925     //if(hasGoodSynInstNewTrig(trig, bVarsTrig, instBindsTerm, instGterms, allterms, tBegin)) {
06926     if(hasGoodSynInstNewTrig(trig, trig.getBVs(), instBindsTerm, instGterms, allterms, tBegin)) {
06927       for(size_t j=0; j<instBindsTerm.size(); j++){
06928         DebugAssert(2 == instBindsTerm[j].size(), "internal error in trans2");
06929 
06930         Expr& gterm = instGterms[j];
06931 
06932         if(simplifyExpr(instBindsTerm[j][0]) != simplifyExpr(instBindsTerm[j][1])){
06933     Expr comb = Expr(RAW_LIST,instBindsTerm[j][0],instBindsTerm[j][1]);
06934     if(!trans2Found(comb)){
06935       setTrans2Found(comb);
06936 
06937       TRACE("quant trans","new trans2: ", vectorExpr2string(instBindsTerm[j]), "");
06938 
06939       Expr comb_rev = Expr(RAW_LIST,instBindsTerm[j][1],instBindsTerm[j][0]);
06940       if(trans2Found(comb_rev)){
06941         Expr sr(instBindsTerm[j][0]);
06942         Expr dt(instBindsTerm[j][1]);
06943 
06944         vector<Expr> bind;
06945         bind.clear();
06946         bind.push_back(sr);
06947         bind.push_back(dt);
06948 
06949         enqueueInst(univ, bind, gterm);
06950         TRACE("quant inst", "trans pred rule2 ", univ.toString(), " | with bind: "+vectorExpr2string(bind));          TRACE("quant trans", "trans2 ", vectorExpr2string(bind), "");
06951       }
06952     }
06953         }
06954       }
06955     }
06956     return;
06957   }
06958       }
06959 
06960       {//code for trans pred
06961   if(trig.hasTr()){
06962     //    if(hasGoodSynInstNewTrig(trig, bVarsTrig, instBindsTerm, instGterms, allterms, tBegin)) {
06963     if(hasGoodSynInstNewTrig(trig, trig.getBVs(), instBindsTerm, instGterms, allterms, tBegin)) {
06964       for(size_t j=0; j<instBindsTerm.size(); j++){
06965         DebugAssert(2 == instBindsTerm[j].size(), "internal error in trans");
06966 
06967         Expr& gterm = instGterms[j];
06968 
06969         if(simplifyExpr(instBindsTerm[j][0]) != simplifyExpr(instBindsTerm[j][1])){
06970 
06971     Expr comb = Expr(RAW_LIST,instBindsTerm[j][0],instBindsTerm[j][1]);
06972 
06973     if(!transFound(comb)){
06974       setTransFound(comb);
06975 
06976       TRACE("quant trans","new: ", vectorExpr2string(instBindsTerm[j]), "");
06977 
06978       Expr sr(instBindsTerm[j][0]);
06979       Expr dt(instBindsTerm[j][1]);
06980 
06981       const CDList<Expr>& dtForw = forwList(dt);
06982       const CDList<Expr>& srBack = backList(sr);
06983 
06984       for(size_t k=0; k<dtForw.size(); k++){
06985         vector<Expr> bind;
06986         bind.clear();
06987         bind.push_back(sr);
06988         bind.push_back(dt);
06989         bind.push_back(dtForw[k]);
06990 
06991         enqueueInst(univ, bind, gterm);
06992 
06993         TRACE("quant inst", "trans pred rule", univ.toString(), " | with bind: "+vectorExpr2string(bind));
06994         TRACE("quant trans", "trans res forw: ", vectorExpr2string(bind), "");
06995       }
06996 
06997       for(size_t k=0; k<srBack.size(); k++){
06998         vector<Expr> bind;
06999         bind.clear();
07000         bind.push_back(srBack[k]);
07001         bind.push_back(sr);
07002         bind.push_back(dt);
07003 
07004         enqueueInst(univ, bind, gterm);
07005         TRACE("quant inst", "trans pred rule ", univ.toString(), " | with bind: "+vectorExpr2string(bind));
07006           TRACE("quant trans", "trans res back: ", vectorExpr2string(bind), "");
07007       }
07008 
07009       pushForwList(sr,dt);
07010       pushBackList(dt,sr);
07011     }
07012         }
07013       }
07014     }
07015     return;
07016   }
07017       }
07018 
07019       bool univsHasMoreBVs ;
07020 
07021       univsHasMoreBVs = (d_hasMoreBVs.count(quantExpr) > 0);
07022 
07023       //      if ( !d_allout || !trig.isSimp() || univsHasMoreBVs || *d_useLazyInst){
07024       //      if ( !d_allout || !trig.isSimp() || univsHasMoreBVs || true){
07025       if  ( !d_allout || !trig.isSuperSimp() || univsHasMoreBVs ){
07026       //      if ( !d_allout || !trig.isSimp() || univsHasMoreBVs ){
07027       */
07028   /*
07029   if(hasGoodSynInstNewTrigOld(trig, bVarsTrig, instBindsTerm, instGterms, allterms, tBegin)) {
07030     genInstSetThm(bVarsThm, bVarsTrig, instBindsTerm, instBindsThm);
07031     for (size_t j = 0; j<instBindsTerm.size(); j++){
07032       const Expr& gterm = instGterms[j];
07033       const std::vector<Expr>& binds = instBindsThm[j];
07034       enqueueInst(univ, trig, binds, gterm);
07035       TRACE("quant inst", "insert full inst", univ.toString(), " | with bind: "+vectorExpr2string(binds));
07036     }
07037   }
07038   */
07039 /*
07040   bVarsTrig=trig.getBVs();//vVarsTrig is used later, do not forget this.
07041   if(hasGoodSynInstNewTrig(trig, bVarsThm, instBindsTerm, instGterms, allterms, tBegin)) {
07042       for (size_t j = 0; j<instBindsTerm.size(); j++){
07043         const Expr& gterm = instGterms[j];
07044         const std::vector<Expr>& binds = instBindsTerm[j];
07045 
07046         enqueueInst(univ, trig, binds, gterm);
07047 
07048         TRACE("quant inst", "insert full inst", univ.toString(), " | with bind: "+vectorExpr2string(binds));
07049       }
07050     }
07051 
07052       }
07053 
07054       //      if(!d_allout || *d_useLazyInst){
07055       if(!d_allout){
07056   if(trig.hasRW() ){
07057 
07058     if(1 == bVarsTrig.size()){
07059       std::vector<Expr> tp = d_arrayIndic[trig.getHead()];
07060       for(size_t i=0; i<tp.size(); i++){
07061         std::vector<Expr> tp = d_arrayIndic[trig.getHead()];
07062 
07063         Expr index = tp[i];
07064         std::vector<Expr> temp;
07065         temp.clear();
07066         temp.push_back(index);
07067 
07068         enqueueInst(univ, temp, index);
07069         TRACE("quant inst", "read write rule", univ.toString(), " | with bind: "+vectorExpr2string(temp));
07070       }
07071     }
07072     else{
07073     }
07074   }
07075       }
07076     }//end for each trigger
07077   }
07078 }
07079 */
07080 
07081 void TheoryQuant::arrayHeuristic(const Trigger& trig, size_t univ_id){
07082   return;
07083   std::vector<Expr> tp = d_arrayIndic[trig.head];
07084   for(size_t i=0; i<tp.size(); i++){
07085     const Expr& index = tp[i];
07086     std::vector<Expr> temp;
07087     temp.push_back(index);
07088     enqueueInst(univ_id, temp, index);
07089     //    TRACE("quant inst", "read write rule", univ.toString(), " | with bind: "+vectorExpr2string(temp));
07090   }
07091 }
07092 
07093 void inline TheoryQuant::iterFWList(const Expr& sr, const Expr& dt, size_t univ_id, const Expr& gterm){
07094   const CDList<Expr>& dtForw = forwList(dt);
07095   for(size_t k=0; k<dtForw.size(); k++){
07096     vector<Expr> tri_bind;
07097     tri_bind.push_back(sr);
07098     tri_bind.push_back(dt);
07099     tri_bind.push_back(dtForw[k]);
07100     enqueueInst(univ_id, tri_bind, gterm);
07101   }
07102 }
07103 
07104 void inline TheoryQuant::iterBKList(const Expr& sr, const Expr& dt, size_t univ_id, const Expr& gterm){
07105   const CDList<Expr>& srBack = backList(sr);
07106   for(size_t k=0; k<srBack.size(); k++){
07107     vector<Expr> tri_bind;
07108     tri_bind.push_back(srBack[k]);
07109     tri_bind.push_back(sr);
07110     tri_bind.push_back(dt);
07111     enqueueInst(univ_id, tri_bind, gterm);
07112   }
07113 }
07114 
07115 
07116 
07117 Expr TheoryQuant::simpRAWList(const Expr& org){
07118   vector<Expr> result;
07119   if(null_expr == org) return null_expr;
07120   for(int i =0 ; i < org.arity(); i++){
07121     result.push_back(simplifyExpr(org[i]));
07122   }
07123   return Expr(RAW_LIST,result);
07124 }
07125 
07126 
07127 void TheoryQuant::synNewInst(size_t univ_id, const vector<Expr>& bind, const Expr& gterm, const Trigger& trig ){
07128   if(trig.isMulti){
07129     const multTrigsInfo& mtriginfo = d_all_multTrigsInfo[trig.multiId];
07130 
07131     vector<Expr> actual_bind;
07132     for(size_t i=0, iend=bind.size(); i<iend; i++){
07133       if(null_expr != bind[i]){
07134   actual_bind.push_back(bind[i]);
07135       }
07136     }
07137 
07138     Expr actual_bind_expr = Expr(RAW_LIST, actual_bind);
07139 
07140     size_t index = trig.multiIndex;
07141 
07142     // first,  test if we have see this binding before
07143     CDMap<Expr,bool> * oldBindMap = mtriginfo.var_binds_found[index];
07144     CDMap<Expr,bool>::iterator cur_iter = oldBindMap->find(actual_bind_expr);
07145 
07146     if (oldBindMap->end() != cur_iter){
07147       return;
07148     }
07149     else{
07150       (*oldBindMap)[actual_bind_expr] = true;
07151     }
07152 
07153     //for now, we only have one set of commom positions, so it must be 0
07154     //this is not true later.
07155     const vector<size_t>& comm_pos = mtriginfo.common_pos[0];
07156     size_t comm_pos_size = comm_pos.size();
07157 
07158     Expr comm_expr;
07159     vector<Expr> comm_expr_vec;
07160     for(size_t i = 0; i < comm_pos_size; i++){
07161       comm_expr_vec.push_back(bind[comm_pos[i]]);
07162     }
07163 
07164     if(0 == comm_pos_size){
07165       comm_expr = null_expr;
07166     }
07167     else{
07168       comm_expr = Expr(RAW_LIST, comm_expr_vec);
07169     }
07170 
07171     Expr uncomm_expr;
07172     vector<Expr> uncomm_expr_vec;
07173 
07174     const vector<size_t>& uncomm_pos = mtriginfo.var_pos[index];
07175     size_t uncomm_pos_size = uncomm_pos.size();
07176     for(size_t i = 0; i< uncomm_pos_size; i++){
07177       uncomm_expr_vec.push_back(bind[uncomm_pos[i]]);
07178     }
07179     if(0 == uncomm_pos_size){
07180       uncomm_expr = null_expr;
07181     }
07182     else{
07183       uncomm_expr = Expr(RAW_LIST, uncomm_expr_vec);
07184     }
07185 
07186     CDList<Expr>* add_into_list ;
07187     CDList<Expr>* iter_list;
07188     ExprMap<CDList<Expr>* >::iterator add_into_iter;
07189     ExprMap<CDList<Expr>* >::iterator iter_iter;
07190 
07191     size_t other_index = 0;
07192     if(0 == index){
07193       other_index =1;
07194     }
07195     else if (1 == index){
07196       other_index = 0;
07197     }
07198     else{
07199       FatalAssert(false, "Sorry, only two vterms in a multi-trigger.");
07200     }
07201 
07202     add_into_iter = mtriginfo.uncomm_list[index]->find(comm_expr);
07203 
07204     if(mtriginfo.uncomm_list[index]->end() == add_into_iter){
07205       add_into_list = new (true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext());
07206       (*mtriginfo.uncomm_list[index])[comm_expr] = add_into_list;
07207     }
07208     else{
07209       add_into_list = add_into_iter->second;
07210     }
07211 
07212     add_into_list->push_back(uncomm_expr);
07213 
07214 
07215     Expr simpCommExpr = simpRAWList(comm_expr);
07216 //     if(simpCommExpr != comm_expr) {
07217 //       cout<<"common and simplified comm expr" << comm_expr << " I " << simpCommExpr << endl;
07218 //     }
07219 
07220     { //
07221       ExprMap<CDList<Expr>* >* otherMap = mtriginfo.uncomm_list[other_index];
07222 
07223       //      iter_iter = mtriginfo.uncomm_list[other_index]->find(comm_expr);
07224       ExprMap<CDList<Expr>* >::iterator otherMapBegin = otherMap->begin(), otherMapEnd = otherMap->end();
07225       for(ExprMap<CDList<Expr>* >::iterator otherMapIter = otherMapBegin; otherMapIter != otherMapEnd; otherMapIter++){
07226 
07227   Expr otherCommonExpr = simpRAWList(otherMapIter->first);
07228   if(simpCommExpr != otherCommonExpr) continue;
07229   //  iter_iter = otherMap->find(comm_expr);
07230   //  if(mtriginfo.uncomm_list[other_index]->end() == iter_iter){
07231   //    return;
07232   //  }
07233   //  else{
07234   //    iter_list = iter_iter->second;
07235   //  }
07236 
07237   if(comm_expr != otherMapIter->first) {
07238   }
07239 
07240   iter_list = otherMapIter->second;
07241   const vector<size_t>& uncomm_iter_pos = mtriginfo.var_pos[other_index];
07242   size_t uncomm_iter_pos_size = uncomm_iter_pos.size();
07243 
07244   for(size_t i =0, iend = iter_list->size(); i<iend; i++){
07245     const Expr& cur_iter_expr = (*iter_list)[i];
07246     vector<Expr> new_bind(bind);
07247     for(size_t j=0; j<uncomm_iter_pos_size; j++){
07248       new_bind[uncomm_iter_pos[j]] = cur_iter_expr[j];
07249     }
07250     enqueueInst(univ_id, new_bind, gterm);
07251   }
07252       }
07253     }
07254     return;
07255   }
07256 
07257   {//code for trans2
07258     if(trig.hasT2){
07259       vector<Expr> actual_bind;
07260       for(size_t i=0; i<bind.size(); i++){
07261   if(bind[i] != null_expr){
07262     actual_bind.push_back(bind[i]);
07263   }
07264       }
07265       if(actual_bind.size() != 2){
07266   //  cout<<"2 != bind.size()" <<endl;
07267       }
07268 
07269       Expr acb1 = simplifyExpr(actual_bind[0]);
07270       Expr acb2 = simplifyExpr(actual_bind[1]);
07271       actual_bind[0]=acb1;
07272       actual_bind[1]=acb2;
07273       if(acb1 != acb2){
07274   Expr comb = Expr(RAW_LIST,acb1, acb2);
07275   if(!trans2Found(comb)){
07276     setTrans2Found(comb);
07277     Expr comb_rev = Expr(RAW_LIST,acb2, acb1);
07278     if(trans2Found(comb_rev)){
07279       enqueueInst(univ_id, actual_bind, gterm);
07280     }
07281   }
07282       }
07283     return;
07284     }
07285   }
07286 
07287   {//code for trans pred
07288     if(trig.hasTrans){
07289       vector<Expr> actual_bind;
07290       for(size_t i=0; i<bind.size(); i++){
07291   if(bind[i] != null_expr){
07292     actual_bind.push_back(simplifyExpr(bind[i]));
07293   }
07294       }
07295       if(simplifyExpr(actual_bind[0]) != simplifyExpr(actual_bind[1])){
07296   Expr comb = Expr(RAW_LIST,actual_bind[0], actual_bind[1]);
07297 
07298   if(!transFound(comb)){
07299     setTransFound(comb);
07300 
07301     Expr sr(actual_bind[0]);
07302     Expr dt(actual_bind[1]);
07303 
07304     iterFWList(sr, dt, univ_id, gterm);
07305     if(*d_useNewEqu){
07306       Expr cur_next = dt.getEqNext().getRHS();
07307       while (cur_next != dt) {
07308         iterFWList(sr, cur_next, univ_id, gterm);
07309         cur_next = cur_next.getEqNext().getRHS();
07310       }
07311     }
07312 
07313     iterBKList(sr, dt, univ_id, gterm);
07314     if(*d_useNewEqu){
07315       Expr cur_next = sr.getEqNext().getRHS();
07316       while (cur_next != sr) {
07317         iterBKList(cur_next, dt, univ_id, gterm);
07318         cur_next = cur_next.getEqNext().getRHS();
07319       }
07320     }
07321     pushForwList(sr,dt);
07322     pushBackList(dt,sr);
07323   }
07324       }
07325       return;
07326     }
07327   } //end of code for trans
07328 
07329   //  cout<<"before enqueueisnt"<<endl;
07330   enqueueInst(univ_id, bind, gterm);
07331   //      if(!d_allout || *d_useLazyInst){
07332 
07333 }
07334 
07335 
07336 /*
07337 
07338 void TheoryQuant::synNewInst(size_t univ_id, const vector<Expr>& bind, const Expr& gterm, const Trigger& trig ){
07339   //  cout<<"synnewinst "<<univ_id<<endl;
07340   {//code for trans2
07341     if(trig.hasT2){
07342       vector<Expr> actual_bind;
07343       for(size_t i=0; i<bind.size(); i++){
07344   if(bind[i] != null_expr){
07345     actual_bind.push_back(bind[i]);
07346   }
07347       }
07348       if(actual_bind.size() != 2){
07349   cout<<"2 != bind.size()" <<endl;
07350       }
07351       if(simplifyExpr(actual_bind[0]) != simplifyExpr(actual_bind[1])){
07352   Expr comb = Expr(RAW_LIST,actual_bind[0], actual_bind[1]);
07353   if(!trans2Found(comb)){
07354     setTrans2Found(comb);
07355     Expr comb_rev = Expr(RAW_LIST,actual_bind[1], actual_bind[0]);
07356     if(trans2Found(comb_rev)){
07357       enqueueInst(univ_id, actual_bind, gterm);
07358     }
07359   }
07360       }
07361     return;
07362     }
07363   }
07364 
07365   {//code for trans pred
07366     if(trig.hasTrans){
07367       vector<Expr> actual_bind;
07368       for(size_t i=0; i<bind.size(); i++){
07369   if(bind[i] != null_expr){
07370     actual_bind.push_back(bind[i]);
07371   }
07372       }
07373       if(simplifyExpr(actual_bind[0]) != simplifyExpr(actual_bind[1])){
07374   Expr comb = Expr(RAW_LIST,actual_bind[0], actual_bind[1]);
07375 
07376   if(!transFound(comb)){
07377     setTransFound(comb);
07378 
07379     Expr sr(actual_bind[0]);
07380     Expr dt(actual_bind[1]);
07381 
07382     const CDList<Expr>& dtForw = forwList(dt);
07383     const CDList<Expr>& srBack = backList(sr);
07384 
07385     for(size_t k=0; k<dtForw.size(); k++){
07386       vector<Expr> tri_bind;
07387       tri_bind.push_back(sr);
07388       tri_bind.push_back(dt);
07389       tri_bind.push_back(dtForw[k]);
07390 
07391       enqueueInst(univ_id, tri_bind, gterm);
07392     }
07393 
07394     for(size_t k=0; k<srBack.size(); k++){
07395       vector<Expr> tri_bind;
07396       tri_bind.push_back(srBack[k]);
07397       tri_bind.push_back(sr);
07398       tri_bind.push_back(dt);
07399 
07400       enqueueInst(univ_id, tri_bind, gterm);
07401       //      TRACE("quant inst", "trans pred rule ", univ.toString(), " | with bind: "+vectorExpr2string(bind));
07402       //      TRACE("quant trans", "trans res back: ", vectorExpr2string(bind), "");
07403     }
07404 
07405     pushForwList(sr,dt);
07406     pushBackList(dt,sr);
07407   }
07408       }
07409       return;
07410     }
07411   }
07412   //  cout<<"before enqueueisnt"<<endl;
07413   enqueueInst(univ_id, bind, gterm);
07414 
07415   //      if(!d_allout || *d_useLazyInst){
07416   if(!d_allout){
07417     if(trig.hasRWOp ){
07418 
07419       if(1 == trig.bvs.size()){
07420   std::vector<Expr> tp = d_arrayIndic[trig.head];
07421   for(size_t i=0; i<tp.size(); i++){
07422     std::vector<Expr> tp = d_arrayIndic[trig.head];
07423 
07424     Expr index = tp[i];
07425     std::vector<Expr> temp;
07426     temp.clear();
07427     temp.push_back(index);
07428 
07429     enqueueInst(univ_id, temp, index);
07430     //    TRACE("quant inst", "read write rule", univ.toString(), " | with bind: "+vectorExpr2string(temp));
07431   }
07432       }
07433       else{
07434       }
07435     }
07436   }
07437 }
07438 */
07439 
07440 /*
07441 void TheoryQuant::synMultInst(const Theorem & univ, const CDList<Expr>& allterms, size_t tBegin ){
07442 
07443   const Expr& quantExpr = univ.getExpr();
07444 
07445   if(d_multTriggers[quantExpr].size() <= 0) return ;
07446 
07447   TRACE("quant inst", "try muli with:|", quantExpr.toString() , " ");
07448   const std::vector<Expr>& bVarsThm = quantExpr.getVars();
07449 
07450   std::vector<std::vector<Expr> > instSetThm; //set of instantiations for the thm
07451   std::vector<std::vector<Expr> > termInst; //terminst are bindings, in the order of bVarsTrig
07452   std::vector<Expr> bVarsTrig;
07453 
07454 
07455   if(hasGoodSynMultiInst(quantExpr, bVarsTrig, termInst, allterms, tBegin)) {
07456     genInstSetThm(bVarsThm, bVarsTrig, termInst, instSetThm);
07457   }
07458   {
07459     for(std::vector<std::vector<Expr> >::iterator i=instSetThm.begin(), iend=instSetThm.end(); i!=iend; ++i) {
07460       enqueueInst(univ, *i, null_expr);//fix the null_expr here asap
07461       TRACE("quant inst", "insert mult inst", univ.toString(), " | with bind: "+vectorExpr2string(*i));
07462     }
07463   }
07464 
07465 }
07466 */
07467 /*
07468 void TheoryQuant::synPartInst(const Theorem & univ, const CDList<Expr>& allterms,  size_t tBegin ){
07469 
07470   const Expr& quantExpr = univ.getExpr();
07471   TRACE("quant inst", "try part with ", quantExpr.toString() , " ");
07472 
07473   const std::vector<Trigger>& triggers = d_partTrigs[quantExpr];
07474 
07475   std::vector<std::vector<Expr> > instSetThm; //set of instantiations for the thm
07476   std::vector<std::vector<Expr> > termInst; //terminst are bindings, in the order of bVarsTrig
07477   std::vector<Expr> bVarsTrig;
07478   std::vector<Expr> instGterms;
07479 
07480   for( std::vector<Trigger>::const_iterator i= triggers.begin(), iend=triggers.end();i!=iend;++i)  {
07481 
07482     Trigger trig = *i;
07483     TRACE("quant inst","handle part trigger", trig.getEx().toString(),"");
07484     termInst.clear();
07485     bVarsTrig.clear();
07486     instSetThm.clear();
07487     //    if(hasGoodSynInstNewTrig(trig, bVarsTrig, termInst, instGterms,allterms, tBegin)) {
07488     if(hasGoodSynInstNewTrig(trig, trig.getBVs(), termInst, instGterms,allterms, tBegin)) {
07489       TRACE("quant syninst", "has good ", termInst.size(),"");
07490       TRACE("quant syninst", "after good ",instSetThm.size(), "");
07491 
07492       Theorem newUniv = d_rules->adjustVarUniv(univ, trig.getBVs());
07493 
07494       TRACE("quant syninst", " new univ:" ,newUniv.toString(),"");
07495       {
07496   for(size_t i = 0; i< termInst.size(); i++){
07497     const std::vector<Expr>& binds = termInst[i];
07498     const Expr& gterm = instGterms[i];
07499     enqueueInst(newUniv, binds, gterm);
07500     TRACE("quant yeting inst", "instantiating =========", "" , "");
07501     TRACE("quant yeting inst", "instantiating", newUniv.getExpr().toString(), " | with bind: "+vectorExpr2string(binds));
07502     TRACE("quant yeting inst", "instantiating org ", univ.getExpr().toString(), " | with gterm "+gterm.toString());
07503   }
07504       }
07505     }
07506   }
07507 }
07508 
07509 */
07510 /*
07511 void TheoryQuant::semInst(const Theorem & univ, size_t tBegin){
07512 }
07513 */
07514 
07515 
07516 void TheoryQuant::checkSat(bool fullEffort){
07517   if(*d_translate) return;
07518   if(d_rawUnivs.size() <=0 ) return;
07519   if (d_maxILReached) {
07520     //    cout<<"return bc max il "<<endl;
07521     return;
07522   }
07523   else{
07524   }
07525 
07526   DebugAssert(d_univsQueue.size() == 0, "something left in d_univsQueue");
07527   DebugAssert(d_simplifiedThmQueue.size() == 0, "something left in d_univsQueue");
07528 
07529   if( false ) {
07530   //  if( false || true) {
07531 
07532     for(size_t eqs_index = d_lastEqsUpdatePos; eqs_index < d_eqsUpdate.size();  eqs_index++){
07533 
07534       Theorem eqThm = d_eqsUpdate[eqs_index];
07535       //      const Expr& leftTerm = eqThm.getLHS();
07536       const Expr& rightTerm = eqThm.getRHS();
07537 
07538       std::vector<multTrigsInfo> d_all_multTrigsInfo;
07539       //      cout<< " size " << d_all_multTrigsInfo.size() << endl;
07540       int numUsefulMultTriger = 0;
07541       for(size_t i = 0; i < d_all_multTrigsInfo.size(); i++){
07542   multTrigsInfo& curMultiTrigger =  d_all_multTrigsInfo[i];
07543   if(curMultiTrigger.uncomm_list.size() != 2 ){
07544     FatalAssert(false, "error in ");
07545   }
07546   ExprMap<CDList<Expr>* >* uncommonMapOne = curMultiTrigger.uncomm_list[0];
07547   ExprMap<CDList<Expr>* >* uncommonMapTwo = curMultiTrigger.uncomm_list[1];
07548 
07549   if(uncommonMapOne->size() != 0 || uncommonMapTwo->size() != 0 ){
07550     numUsefulMultTriger++;
07551   }
07552 
07553   //  continue;
07554 
07555   if(uncommonMapOne->size() == 0 ) {
07556     continue;
07557   }
07558 
07559   //why uncommonMapOne is empty but uncommonMapTwo is not?, let me figure this out.
07560 
07561 
07562   ExprMap<CDList<Expr>* >::iterator iterOneBegin(uncommonMapOne->begin()), iterOneEnd(uncommonMapOne->end());
07563 
07564   //cout<<"left and right " << leftTerm << " $ " << rightTerm <<endl;
07565   //  cout<<"------------ left and right ---------" << leftTerm << " $ " << rightTerm <<endl;
07566 
07567   vector<pair<Expr, CDList<Expr>* > > oneFoundTerms;
07568   for(ExprMap<CDList<Expr>* >::iterator iterOne=iterOneBegin; iterOne != iterOneEnd; iterOne++){
07569 
07570     if(simplifyExpr((iterOne->first)[0]) == simplifyExpr(rightTerm)){ //for test only for trans
07571       //      cout<<"found one " << iterOne->first << endl;
07572       //      oneFoundTerms.push_back(iterOne->second);
07573       oneFoundTerms.push_back(*iterOne);
07574     }
07575   }
07576 
07577   ExprMap<CDList<Expr>* >::iterator iterTwoBegin(uncommonMapTwo->begin()), iterTwoEnd(uncommonMapTwo->end());
07578   //  vector<CDList<Expr>* > twoFoundTerms;
07579   vector<pair<Expr, CDList<Expr>* > >twoFoundTerms;
07580   for(ExprMap<CDList<Expr>* >::iterator iterTwo = iterTwoBegin; iterTwo != iterTwoEnd; iterTwo++){
07581     if(simplifyExpr((iterTwo->first)[0]) == simplifyExpr(rightTerm)){
07582       //      cout<<"found two " << iterTwo->first << endl;
07583       //      twoFoundTerms.push_back(iterTwo->second);
07584       twoFoundTerms.push_back(*iterTwo);
07585     }
07586   }
07587   {
07588     for(size_t i= 0 ; i< oneFoundTerms.size(); i++){
07589       for(size_t j= 0 ; j< twoFoundTerms.size(); j++){
07590         pair<Expr, CDList<Expr>* > pairOne = oneFoundTerms[i];
07591         pair<Expr, CDList<Expr>* > pairTwo = twoFoundTerms[j];
07592         if(pairOne.first == pairTwo.first) continue;
07593         //        cout<<"pairone.first " << pairOne.first << endl;
07594         //        cout<<"pairTwo.first " << pairTwo.first << endl;
07595         CDList<Expr>* oneExprList = pairOne.second;
07596         CDList<Expr>* twoExprList = pairTwo.second;
07597               //        cout<<"one size" << oneExprList->size() << endl;
07598         for(size_t oneIter = 0; oneIter < oneExprList->size(); oneIter++){
07599     //    cout<<"two size" << twoExprList->size() << endl;
07600     for(size_t twoIter = 0; twoIter < twoExprList->size(); twoIter++){
07601       Expr gterm1 = (*oneExprList)[oneIter][0];
07602       Expr gterm2 = (*twoExprList)[twoIter][0];
07603       //      cout<<"one and two " << oneIter << " # " << twoIter << endl;
07604       //      cout<<"one and two " << gterm1 << " # " << gterm2 << endl;
07605       vector<Expr> bind ;
07606       bind.push_back(gterm1);
07607       bind.push_back(rightTerm);
07608       bind.push_back(gterm2);
07609       size_t univID = curMultiTrigger.univ_id;
07610 
07611       if(d_univs[univID] != curMultiTrigger.univThm) {
07612         //        cout << "errror in debuging:" << endl;
07613                     //        cout << d_univs[univID] << endl;
07614                     //        cout << curMultiTrigger.univThm << endl;
07615         exit(3);
07616       }
07617 
07618       enqueueInst(curMultiTrigger.univ_id, bind, rightTerm);
07619       //      cout << "enqueued 1" <<  vectorExpr2string(bind) <<endl;
07620 
07621       bind.clear();
07622       bind.push_back(gterm2);
07623       bind.push_back(rightTerm);
07624       bind.push_back(gterm1);
07625       enqueueInst(curMultiTrigger.univ_id, bind, rightTerm);
07626       //      cout << "enqueued 3" <<  vectorExpr2string(bind) <<endl;
07627 
07628     }
07629         }
07630       }
07631     }
07632   }//end of add founded new matchings
07633       }
07634       //      cout << "useful multriggers " << numUsefulMultTriger << endl;
07635     }
07636   }
07637 
07638   sendInstNew();
07639   /*
07640   {//to test update eqs list
07641     //    cout<<"# equs in checksat "<<endl;
07642 
07643     cout<<"---------in checksat ----------------" << endl;
07644     for(size_t eqs_index = d_lastEqsUpdatePos; eqs_index < d_eqsUpdate.size();  eqs_index++){
07645 
07646       Theorem t = d_eqsUpdate[eqs_index];
07647       const Expr& leftTerm = t.getLHS();
07648       NotifyList* leftUpList = leftTerm.getNotify();
07649       cout<<"left term is " << leftTerm << " || " << simplifyExpr(leftTerm) << endl;
07650 
07651       if(NULL == leftUpList) continue;
07652 
07653 
07654       cout<<"the left notify list" <<endl;
07655       NotifyList& l = *leftUpList;
07656       for(size_t i=0,iend=l.size(); i<iend; ++i) {
07657   cout << "[" << l.getTheory(i)->getName() << ", " << l.getExpr(i) << "] " << l.getExpr(i).getSig().isNull() << endl;
07658       }
07659 
07660       const Expr& rightTerm = t.getRHS();
07661       cout<<"right term is " << rightTerm << endl;
07662       NotifyList* rightUpList = rightTerm.getNotify();
07663       if(NULL == rightUpList) continue;
07664 
07665       cout<<"the right notify list" << endl;
07666 
07667       NotifyList& ll = *rightUpList;
07668       for(size_t i=0,iend=ll.size(); i<iend; ++i) {
07669   cout << "[" << ll.getTheory(i)->getName() << ", " << ll.getExpr(i) << "] " << ll.getExpr(i).getSig().isNull() << endl;
07670       }
07671 
07672 
07673       cout<<"------------" << leftTerm << " # " << rightTerm <<endl;
07674 
07675     }
07676   }
07677   */
07678 
07679 
07680 #ifdef _CVC3_DEBUG_MODE
07681   if(fullEffort){
07682     if( CVC3::debugger.trace("quant assertfact")  ){
07683       cout<<"===========all cached univs =========="<<endl;
07684       //      for (ExprMap<Theorem>::iterator i=d_simpUnivs.begin(), iend=d_simpUnivs.end(); i!=iend;  i++){
07685       //  cout<<"------------------------------------"<<endl;
07686       //  cout<<(i->first).toString()<<endl;
07687       //  cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
07688       //  cout<<(i->second).getExpr().toString()<<endl;
07689       //}
07690     }
07691     if( CVC3::debugger.trace("quant samehead")  ){
07692       cout<<"===========all cached  =========="<<endl;
07693       for (ExprMap< CDList<Expr>*>::iterator i=d_same_head_expr.begin(), iend=d_same_head_expr.end(); i!=iend;  i++){
07694   cout<<"------------------------------------"<<endl;
07695   cout<<(i->first)<<endl;
07696   cout<<"_______________________"<<endl;
07697   CDList<Expr> * terms= i->second;
07698   for(size_t i =0; i<terms->size(); i++){
07699     cout<<(*terms)[i]<<endl;
07700   }
07701       }
07702     }
07703   }
07704 #endif
07705 
07706 #ifdef _CVC3_DEBUG_MODE
07707   if( CVC3::debugger.trace("quant checksat")  ){
07708     const CDList<Expr>& allpreds = theoryCore()->getPredicates();
07709     cout<<"=========== cur pred & terms =========="<<endl;
07710 
07711     for (size_t i=d_lastPredsPos; i<allpreds.size(); i++){
07712     //    for (size_t i=0; i<allpreds.size(); i++){
07713       cout<<"i="<<allpreds[i].getIndex()<<" :"<<findExpr(allpreds[i])<<"|"<<allpreds[i]<<endl;
07714     }
07715 
07716     const CDList<Expr>&  allterms = theoryCore()->getTerms();
07717 
07718     for (size_t i=d_lastTermsPos; i<allterms.size(); i++){
07719       cout<<"i="<<allterms[i].getIndex()<<" :"<<findExpr(allterms[i])<<"|"<<allterms[i]<<endl;
07720     }
07721     cout<<"=========== cur quant =========="<<endl;
07722     for (size_t i=0; i<d_univs.size(); i++){
07723       cout<<"i="<<d_univs[i].getExpr().getIndex()<<" :"<<findExpr(d_univs[i].getExpr())<<"|"<<d_univs[i]<<endl;
07724     }
07725   }
07726 
07727 
07728   if( CVC3::debugger.trace("quant checksat equ") ){
07729     const CDList<Expr>& allpreds = theoryCore()->getPredicates();
07730     cout<<"=========== cur pred equ =========="<<endl;
07731 
07732     for (size_t i=d_lastPredsPos; i<allpreds.size(); i++){
07733       if(allpreds[i].isEq()){
07734   cout<<"i="<<allpreds[i].getIndex()<<" :"<<findExpr(allpreds[i])<<"|"<<allpreds[i]<<endl;
07735       }
07736     }
07737     cout<<"=========== cur pred equ end  =========="<<endl;
07738   }
07739 
07740 #endif
07741 
07742   if((*d_useLazyInst && !fullEffort) ) return;
07743 
07744   if(false) {//for the same head list
07745    const CDList<Expr>&  allterms = theoryCore()->getTerms();
07746    for(size_t i=d_lastTermsPos; i<allterms.size(); i++){
07747      Expr t = allterms[i];
07748      if(canGetHead(t)){
07749        if(d_same_head_expr.count(getHead(t)) >0){
07750    d_same_head_expr[getHead(t)]->push_back(t);
07751        }
07752        else{
07753    d_same_head_expr[getHead(t)]=
07754      new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
07755    d_same_head_expr[getHead(t)]->push_back(t);
07756        }
07757      }
07758    }
07759 
07760    const CDList<Expr>&  allpreds = theoryCore()->getPredicates();
07761    for(size_t i=d_lastPredsPos; i<allpreds.size(); i++){
07762      Expr t = allpreds[i];
07763      if(canGetHead(t)){
07764        if(d_same_head_expr.count(getHead(t)) >0){
07765    d_same_head_expr[getHead(t)]->push_back(t);
07766        }
07767        else{
07768    d_same_head_expr[getHead(t)]=
07769      new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
07770    d_same_head_expr[getHead(t)]->push_back(t);
07771        }
07772      }
07773    }
07774   }
07775 
07776   if(false){
07777     for(size_t eqs_index = d_lastEqsUpdatePos; eqs_index < d_eqsUpdate.size();  eqs_index++){
07778 
07779       const Expr lTerm = d_eqsUpdate[eqs_index].getLHS();
07780       const Expr rTerm = d_eqsUpdate[eqs_index].getRHS();
07781 
07782       d_eqs.push_back(lTerm);
07783       d_eqs.push_back(rTerm);
07784     }
07785   }
07786 
07787   if(false) {//for the equalities list
07788     const CDList<Expr>&  allpreds = theoryCore()->getPredicates();
07789     for(size_t i=d_lastPredsPos; i<allpreds.size(); i++){
07790       const Expr& t = allpreds[i];
07791       if(t.isEq()){
07792   //  cout<<"EQ: "<<t<<endl;
07793   const Expr lterm = t[0];
07794   const Expr rterm = t[1];
07795   d_eqs.push_back(lterm);
07796   d_eqs.push_back(rterm);
07797 
07798   /*
07799   ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.find(lterm);
07800   if(d_eq_list.end() == iter){
07801     d_eq_list[lterm] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
07802     d_eq_list[lterm]->push_back(rterm);
07803   }
07804   else{
07805     iter->second->push_back(rterm);
07806   }
07807 
07808   //  cout<<"LTERM: " <<rterm<<endl;
07809   iter = d_eq_list.find(rterm);
07810   if(d_eq_list.end() == iter){
07811     d_eq_list[rterm] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
07812     d_eq_list[rterm]->push_back(lterm);
07813   }
07814   else{
07815     iter->second->push_back(lterm);
07816   }
07817   //  cout<<"RTERM: " <<lterm<<endl;
07818   */
07819       }
07820     }
07821   }
07822 
07823 
07824   {//for rw heuristic
07825    const CDList<Expr>&  allterms = theoryCore()->getTerms();
07826    for(size_t i=d_lastTermsPos; i<allterms.size(); i++){
07827      const Expr& cur=allterms[i];
07828      if(READ == cur.getKind() || WRITE == cur.getKind()){
07829        arrayIndexName(cur);
07830      }
07831    }
07832   }
07833 
07834   d_instThisRound = 0;
07835   //  d_useMultTrig=*d_useMult;
07836   //  d_usePartTrig=*d_usePart;
07837   d_useFullTrig=true;
07838 
07839   if(fullEffort) {
07840     d_inEnd=true;
07841   }
07842   else{
07843     d_inEnd=false;
07844   }
07845 
07846 
07847   ExprMap<ExprMap<vector<dynTrig>* >* > new_trigs;
07848   if(fullEffort || theoryCore()->getCM()->scopeLevel() <= 5 || true){
07849     for(size_t i=d_univs.size(); i<d_rawUnivs.size(); i++){
07850       setupTriggers(new_trigs, d_rawUnivs[i], i);
07851     }
07852   }
07853   try {
07854     if (!(*d_useNew)){
07855       naiveCheckSat(fullEffort);
07856     }
07857     else if (*d_useSemMatch){
07858       semCheckSat(fullEffort);
07859     }
07860     else {
07861       synCheckSat(new_trigs, fullEffort);
07862     }
07863   }
07864 
07865   catch (int x){
07866 
07867      while(!d_simplifiedThmQueue.empty()){
07868        d_simplifiedThmQueue.pop();
07869        d_abInstCount++;
07870      }
07871      while(!d_gUnivQueue.empty()){
07872        d_gUnivQueue.pop();
07873      }
07874      while(!d_gBindQueue.empty()){
07875        d_gBindQueue.pop();
07876      }
07877 
07878 
07879 
07880     d_tempBinds.clear();
07881     saveContext();
07882     delNewTrigs(new_trigs);
07883     return;
07884   }
07885 
07886   sendInstNew();
07887 
07888   saveContext();
07889 
07890   try{
07891     if((*d_useNaiveInst) && (*d_useNew) && (0 == d_instThisRound) && fullEffort && theoryCore()->getTerms().size() < (size_t)(*d_maxNaiveCall )) {
07892       //      cout<<"naive called"<<endl;
07893       if (0== theoryCore()->getTerms().size()){
07894   static int counter =0;
07895 
07896   std::set<Expr> types;
07897   for(size_t i = 0; i<d_univs.size(); i++){
07898     const Expr& cur_quant = d_univs[i].getExpr();
07899     const std::vector<Expr> cur_vars = cur_quant.getVars();
07900     for(size_t j =0; j<cur_vars.size(); j++){
07901       types.insert(cur_vars[j].getType().getExpr());
07902     }
07903   }
07904 
07905   std::string base("_naiveInst");
07906   for(std::set<Expr>::iterator i=types.begin(), iend = types.end(); i != iend; i++){
07907     counter++;
07908     std::stringstream tempout;
07909     tempout << counter;
07910     std::string out_str = base + tempout.str();
07911     Expr newExpr = theoryCore()->getEM()->newVarExpr(out_str);
07912 
07913     newExpr.setType(Type(*i));
07914 
07915     Proof pf;
07916 
07917     Expr newExpr2 = theoryCore()->getEM()->newVarExpr(out_str+"extra");
07918     newExpr2.setType(Type(*i));
07919 
07920     Expr newConstThm;
07921 
07922     if(Type(*i) == theoryCore()->getEM()->newRatExpr(0).getType()){
07923       //somehow theory_arith will complain if we use expr2 to form the eq here
07924       newConstThm = newExpr.eqExpr(theoryCore()->getEM()->newRatExpr(0));
07925     }
07926     else{
07927       newConstThm = newExpr.eqExpr(newExpr2);
07928     }
07929     Theorem newThm  = d_rules->addNewConst(newConstThm);
07930 
07931     if(*d_useGFact){
07932       //      addGlobalLemma(newThm, -1);
07933       enqueueFact(newThm);
07934     }
07935     else{
07936       enqueueFact(newThm);
07937     }
07938     //    enqueueSE(newThm);
07939     //
07940     d_tempBinds.clear();
07941     return;
07942   }
07943 
07944       }
07945     naiveCheckSat(fullEffort);
07946     }
07947   }//end of try
07948 
07949   catch (int x){
07950 
07951      while(!d_simplifiedThmQueue.empty()){
07952        d_simplifiedThmQueue.pop();
07953        d_abInstCount++;
07954       }
07955      while(!d_gUnivQueue.empty()){
07956        d_gUnivQueue.pop();
07957      }
07958      while(!d_gBindQueue.empty()){
07959        d_gBindQueue.pop();
07960      }
07961 
07962 
07963     d_tempBinds.clear();
07964     saveContext();
07965     delNewTrigs(new_trigs);
07966     return;
07967   }
07968 
07969   if(fullEffort) {
07970     sendInstNew();
07971   }
07972 
07973   combineOldNewTrigs(new_trigs);
07974   delNewTrigs(new_trigs);
07975 }
07976 
07977 void TheoryQuant::saveContext(){
07978   d_lastArrayPos.set(d_arrayTrigs.size());
07979   d_univsSavedPos.set(d_univs.size());
07980   d_rawUnivsSavedPos.set(d_rawUnivs.size());
07981   d_lastTermsPos.set(theoryCore()->getTerms().size());
07982   d_lastPredsPos.set(theoryCore()->getPredicates().size());
07983   d_lastUsefulGtermsPos.set(d_usefulGterms.size());
07984   d_lastEqsUpdatePos.set(d_eqsUpdate.size());
07985 }
07986 
07987 void TheoryQuant::synCheckSat(ExprMap<ExprMap<vector<dynTrig>* >* >&  new_trigs, bool fullEffort){
07988 
07989   d_allout=false;
07990 
07991   if(fullEffort)   {
07992     setIncomplete("Quantifier instantiation");
07993   }
07994 
07995   size_t uSize = d_univs.size() ;
07996   const CDList<Expr>& allterms = theoryCore()->getTerms();
07997   const CDList<Expr>& allpreds = theoryCore()->getPredicates();
07998   size_t tSize = allterms.size();
07999   size_t pSize = allpreds.size();
08000 
08001   TRACE("quant",uSize, " uSize and univsSavedPOS ", d_univsSavedPos);
08002   TRACE("quant",tSize, " tSize and termsLastPos ", d_lastTermsPos);
08003   TRACE("quant",pSize, " pSize and predsLastPos ", d_lastPredsPos);
08004   TRACE("quant", fullEffort, " fulleffort:scope ",theoryCore()->getCM()->scopeLevel() );
08005 
08006   for(size_t i=d_lastTermsPos; i<tSize; i++){
08007     const Expr& cur(allterms[i]);
08008     //    if(usefulInMatch(cur) && cur.hasFind()){
08009     if(usefulInMatch(cur)){
08010       if(*d_useExprScore){
08011   int score = getExprScore(cur);
08012   if(score <= d_curMaxExprScore && 0 <= score ){
08013     d_usefulGterms.push_back(cur);
08014     add_parent(cur);
08015   }
08016       }
08017       else{
08018   d_usefulGterms.push_back(cur);
08019   add_parent(cur);
08020       }
08021     }
08022     else{
08023     }
08024   }
08025 
08026   for(size_t i=d_lastPredsPos; i<pSize; i++){
08027     const Expr& cur=allpreds[i];
08028     //    if( usefulInMatch(cur) && cur.hasFind()){
08029     if( usefulInMatch(cur)){
08030       if(*d_useExprScore ){
08031   int score = getExprScore(cur);
08032   if(score <= d_curMaxExprScore && 0 <= score){
08033     d_usefulGterms.push_back(cur);
08034     add_parent(cur);
08035   }
08036       }
08037       else{
08038   d_usefulGterms.push_back(cur);
08039   add_parent(cur);
08040       }
08041     }
08042     else{
08043     }
08044   }
08045 
08046 
08047   //  if(d_useFullTrig && d_inEnd && *d_useInstEnd ){
08048   if(d_useFullTrig && d_inEnd ){
08049 
08050     if(*d_useExprScore){
08051 
08052       matchListOld(d_usefulGterms, d_lastUsefulGtermsPos, d_usefulGterms.size() ); //new terms to old list
08053       matchListNew(new_trigs, d_usefulGterms, 0, d_usefulGterms.size()); //new and old terms to new list
08054 
08055       if(sendInstNew() > 0){
08056   TRACE("inend", "debug 1", "" ,"" );
08057   return;
08058       }
08059 
08060       d_allout = true; //let me look at these d_allout later yeting
08061       {
08062   CDList<Expr>* changed_terms = new (false) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
08063   collectChangedTerms(*changed_terms);
08064 
08065   matchListOld(*changed_terms, 0, changed_terms->size());
08066   matchListNew(new_trigs, *changed_terms, 0 , changed_terms->size());
08067   delete changed_terms;
08068       }
08069       d_allout = false;
08070       int n;
08071       if( ( n = sendInstNew()) > 0){
08072   TRACE("inend",  "debug 2", " # ",n );
08073   return;
08074       }
08075 
08076       bool hasMoreGterms(false);
08077 
08078       do {
08079 
08080       hasMoreGterms=false;
08081 
08082       int numNewTerm=0;
08083       int oldNum=d_usefulGterms.size();
08084 
08085       for(size_t i=0; i<tSize; i++){
08086   const Expr& cur(allterms[i]);
08087   //if(!(usefulInMatch(cur)) || !cur.hasFind()) continue;
08088   if(!(usefulInMatch(cur)) ) continue;
08089   int score = getExprScore(cur);
08090   if( score > d_curMaxExprScore){
08091     if((d_curMaxExprScore + 1) == score){
08092       //    if((d_curMaxExprScore + 1) <= score){
08093       d_usefulGterms.push_back(cur);
08094       add_parent(cur);
08095       numNewTerm++;
08096     }
08097     else{
08098       hasMoreGterms = true;
08099       TRACE("inend", "is this good? ", cur.toString()+" #-# " , score);
08100       //      cout<<"should not be here"<<endl;
08101       if(*d_useGFact && false ){
08102         d_usefulGterms.push_back(cur);
08103         add_parent(cur);
08104         numNewTerm++;
08105       }
08106       //      cout<<"extra term e:"<<score<<" # "<<d_curMaxExprScore << " # "<< cur<<endl;
08107       //      cout<<"extra id:"<<cur.getIndex()<<endl;
08108       //      exit(3);
08109     }
08110   }
08111       }
08112 
08113 
08114       for(size_t i=0; i<pSize; i++){
08115   const Expr& cur(allpreds[i]);
08116   //  if(!(usefulInMatch(cur)) ||  !cur.hasFind()) continue;
08117   if(!(usefulInMatch(cur)) ) continue;
08118   int score = getExprScore(cur);
08119   if( score > d_curMaxExprScore){
08120     if((d_curMaxExprScore + 1) == score){
08121       //  if((d_curMaxExprScore + 1) <= score){
08122       d_usefulGterms.push_back(cur);
08123       add_parent(cur);
08124       numNewTerm++;
08125     }
08126     else{
08127       hasMoreGterms = true;
08128       TRACE("inend", "is this good? ", cur.toString()+" #-# " , score);
08129       //      cout<<"should not be here"<<endl;
08130       if(*d_useGFact && false ){
08131         d_usefulGterms.push_back(cur);
08132         add_parent(cur);
08133         numNewTerm++;
08134       }
08135       //      cout<<"extra pred e:"<<score<<" # "<<d_curMaxExprScore << " # "<< cur<<endl;
08136       //      cout<<"extra id:"<<cur.getIndex()<<endl;
08137       //      exit(3);
08138     }
08139   }
08140       }
08141 
08142       /*
08143       IF_DEBUG({
08144   bool hasStrange(false);
08145   for(size_t i=0; i<pSize-1; i++){
08146     if(getExprScore(allpreds[i]) > getExprScore(allpreds[i+1]) ){
08147       cout<<"strange pred"<<allpreds[i]<<endl;
08148       hasStrange=true;
08149     }
08150   }
08151   for(size_t i=0; i<tSize-1; i++){
08152     if(getExprScore(allterms[i]) > getExprScore(allterms[i+1])){
08153       cout<<"strange term"<<allterms[i]<<endl;
08154       hasStrange=true;
08155     }
08156   }
08157   if(hasStrange){
08158     cout<<"strange here"<<endl;
08159     for(size_t i=0; i<pSize; i++){
08160       if (usefulInMatch(allpreds[i]) ) cout<<getExprScore(allpreds[i]) << " t# " <<allpreds[i]<<endl;
08161     }
08162     for(size_t i=0; i<tSize; i++){
08163       if (usefulInMatch(allterms[i]) )  cout<<getExprScore(allterms[i]) << " p# " <<allterms[i]<<endl;
08164     }
08165     cout<<"strange end"<<endl;
08166   }
08167       }
08168          )
08169       */
08170 //       if(d_curMaxExprScore < 15 || true){
08171 //  d_curMaxExprScore = d_curMaxExprScore+1;
08172 //       }
08173 
08174       if(d_curMaxExprScore >= 0 && d_curMaxExprScore <= *d_maxIL ){
08175   d_curMaxExprScore =  d_curMaxExprScore+1;;
08176       }
08177       else {
08178   d_curMaxExprScore =  d_curMaxExprScore+1;
08179   //  d_curMaxExprScore =  d_curMaxExprScore+0; //this is for debugging Yeting
08180   d_maxILReached = true;
08181   //cout<<"il reached: " << endl;
08182       }
08183 
08184       //      cout << " max il " << *d_maxIL << endl;
08185       //      cout <<d_curMaxExprScore << endl;
08186 
08187       if(numNewTerm >0 ){
08188   matchListOld(d_usefulGterms, oldNum, d_usefulGterms.size() );
08189   matchListNew(new_trigs, d_usefulGterms, oldNum, d_usefulGterms.size());
08190 
08191   if(sendInstNew() > 0){
08192     TRACE("inend",  "debug 3 1", "" , "" );
08193     return;
08194   }
08195       }
08196 
08197       if(hasMoreGterms){
08198         ;
08199   //  cout<<"has more " << endl;
08200   //  cout<<d_curMaxExprScore<<endl;
08201   //  cout<<"oldNum" << oldNum << endl;
08202       }
08203       //      } while(hasMoreGterms && d_curMaxExprScore <= 10 );
08204       } while(hasMoreGterms && d_curMaxExprScore <= *d_maxIL);
08205 
08206       d_allout = true;
08207       matchListOld(d_usefulGterms, 0, d_usefulGterms.size() );
08208       matchListNew(new_trigs, d_usefulGterms, 0, d_usefulGterms.size());
08209       if(sendInstNew() > 0){
08210   TRACE("inend",  "debug 3 2", "" , "" );
08211   return;
08212       }
08213       d_allout = false;
08214 
08215       //      for(size_t array_index = 0; array_index < d_arrayTrigs.size(); array_index++){
08216       //  arrayHeuristic(d_arrayTrigs[array_index].trig, d_arrayTrigs[array_index].univ_id);
08217       //      }
08218 
08219 
08220       return ;
08221     }
08222 
08223     TRACE("inend", "debug 3 0", "", "");
08224     TRACE("quant","this round; ",d_callThisRound,"");
08225 
08226     return;
08227   }
08228 
08229 
08230   if ((uSize == d_univsSavedPos) &&
08231       (tSize == d_lastTermsPos) &&
08232       (pSize == d_lastPredsPos) ) return;
08233 
08234   //  cout<<"match old"<<endl;
08235   matchListOld(d_usefulGterms, d_lastUsefulGtermsPos,d_usefulGterms.size() ); //new terms to old list
08236   //  cout<<"match new"<<endl;
08237   matchListNew(new_trigs, d_usefulGterms, 0, d_usefulGterms.size() ); //new and old terms to new list
08238 
08239   for(size_t array_index = d_lastArrayPos; array_index < d_arrayTrigs.size(); array_index++){
08240     arrayHeuristic(d_arrayTrigs[array_index].trig, d_arrayTrigs[array_index].univ_id);
08241   }
08242 
08243   TRACE("quant","this round; ",d_callThisRound,"");
08244 
08245   return;
08246 }
08247 
08248 
08249 void TheoryQuant::semCheckSat(bool fullEffort){
08250 }
08251 
08252 //the following is old code and I did not modify much, Yeting
08253 void TheoryQuant::naiveCheckSat(bool fullEffort){
08254   d_univsSavedPos.set(0);
08255   TRACE("quant", "checkSat ", fullEffort, "{");
08256   IF_DEBUG(int instCount = d_instCount;)
08257   size_t uSize = d_univs.size(), stSize = d_savedTerms.size();
08258   if(true || (fullEffort && uSize > 0)) {
08259     // First of all, this algorithm is incomplete
08260     setIncomplete("Quantifier instantiation");
08261 
08262     if(d_instCount>=*d_maxQuantInst)
08263       return;
08264     //first attempt to instantiate with the saved terms
08265     //only do this if there are new saved terms or new theroems and
08266     // at least some saved terms
08267     bool savedOnly = ((uSize > d_univsSavedPos.get()  && stSize > 0) ||
08268           (stSize > d_savedTermsPos.get()));
08269     int origCount = d_instCount;
08270     if(savedOnly)
08271       {
08272   TRACE("quant", "checkSat [saved insts]: univs size = ", uSize , " ");
08273   for(size_t i=0, pos = d_univsSavedPos.get(); i<uSize; i++) {
08274     if(d_instCount>= *d_maxQuantInst)
08275       break;
08276     else
08277       instantiate(d_univs[i], i>=pos, true,  d_savedTermsPos.get());
08278   }
08279   d_univsSavedPos.set(d_univs.size());
08280   d_savedTermsPos.set(stSize);
08281       }
08282     if(!savedOnly || d_instCount == origCount)
08283       { //instantiate with context dependent assertions terms
08284   TRACE("quant", "checkSat [context insts]: univs size = ", uSize , " ");
08285   const CDList<Expr>& assertions = theoryCore()->getTerms();
08286   int origSize = d_contextTerms.size();
08287   //  for(size_t i=0; i<uSize; i++)
08288   //    assertions.push_back(d_univs[i].getExpr());
08289   //build the map of all terms grouped into vectors by types
08290   TRACE("quant", "checkSat terms size = ", assertions.size() , " ");
08291   mapTermsByType(assertions);
08292   for(size_t i=0, pos = d_univsContextPos.get(); i<uSize; i++) {
08293     if(d_instCount>= *d_maxQuantInst)
08294       break;
08295     else
08296       instantiate(d_univs[i], i>=pos, false, origSize);
08297   }
08298   d_univsContextPos.set(d_univs.size());
08299       }
08300     TRACE("quant terse", "checkSat total insts: ",
08301     d_instCount, ", new "+int2string(d_instCount - instCount));
08302   }
08303   TRACE("quant", "checkSat total insts: ", d_instCount, " ");
08304   TRACE("quant", "checkSat new insts: ", d_instCount - instCount, " ");
08305   TRACE("quant", "checkSat effort:",  fullEffort, " }");
08306 
08307 }
08308 
08309 
08310 /*! \brief Queues up all possible instantiations of bound
08311  * variables.
08312  *
08313  * The savedMap boolean indicates whether to use savedMap or
08314  * d_contextMap the all boolean indicates weather to use all
08315  * instantiation or only new ones and newIndex is the index where
08316  * new instantiations begin.
08317  */
08318 void TheoryQuant::instantiate(Theorem univ, bool all, bool savedMap,
08319             size_t newIndex)
08320 {
08321 
08322   if(!all && ((savedMap &&  newIndex == d_savedTerms.size())
08323           ||(!savedMap && newIndex == d_contextTerms.size())))
08324     return;
08325 
08326   TRACE("quant", "instanitate", all , "{");
08327   std::vector<Expr> varReplacements;
08328   recInstantiate(univ, all, savedMap, newIndex, varReplacements);
08329   TRACE("quant", "instanitate", "", "}");
08330 
08331 }
08332 
08333  //! does most of the work of the instantiate function.
08334 void TheoryQuant::recInstantiate(Theorem& univ, bool all, bool savedMap,
08335          size_t newIndex,
08336          std::vector<Expr>& varReplacements)
08337 {
08338   Expr quantExpr = univ.getExpr();
08339   const vector<Expr>& boundVars = quantExpr.getVars();
08340 
08341   size_t curPos = varReplacements.size();
08342   TRACE("quant", "recInstantiate: ", boundVars.size() - curPos, "");
08343   //base case: a full vector of instantiations exists
08344   if(curPos == boundVars.size()) {
08345     if(!all)
08346       return;
08347     Theorem t = d_rules->universalInst(univ, varReplacements);
08348     d_insts[t.getExpr()] = varReplacements;
08349     TRACE("quant", "recInstantiate => " , t.toString(), "");
08350     if(d_instCount< *d_maxQuantInst) {
08351       d_instCount=d_instCount+1;
08352       enqueueInst(univ, varReplacements, null_expr);
08353       //            enqueueInst(univ, t);
08354       // enqueueFact(t);
08355     }
08356     return;
08357   }
08358   //recursively add all possible instantiations in the next
08359   //available space of the vector
08360   else {
08361     Type t = getBaseType(boundVars[curPos]);
08362     int iendC=0, iendS=0, iend;
08363     std::vector<size_t>* typeVec = NULL; // = d_savedMap[t];
08364     CDList<size_t>* typeList = NULL; // = *d_contextMap[t];
08365     if(d_savedMap.count(t) > 0) {
08366       typeVec = &(d_savedMap[t]);
08367       iendS = typeVec->size();
08368       TRACE("quant", "adding from savedMap: ", iendS, "");
08369     }
08370     if(!savedMap) {
08371       if(d_contextMap.count(t) > 0) {
08372   typeList = d_contextMap[t];
08373   iendC = typeList->size();
08374   TRACE("quant", "adding from contextMap:", iendC , "");
08375       }
08376     }
08377     iend = iendC + iendS;
08378     for(int i =0; i<iend; i++) {
08379       TRACE("quant", "I must have gotten here!", "", "");
08380       size_t index;
08381       if(i<iendS){
08382   index = (*typeVec)[i];
08383   varReplacements.push_back(d_savedTerms[index]);
08384       }
08385       else {
08386   index = (*typeList)[i-iendS];
08387   varReplacements.push_back(d_contextTerms[index]);
08388       }
08389       if((index <  newIndex) || (!savedMap && i<iendS))
08390   recInstantiate(univ, all, savedMap, newIndex,  varReplacements);
08391       else
08392   recInstantiate(univ, true, savedMap, newIndex,  varReplacements);
08393       varReplacements.pop_back();
08394     }
08395 
08396 
08397   }
08398 }
08399 
08400 /*! \brief categorizes all the terms contained in a vector of  expressions by
08401  * type.
08402  *
08403  * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
08404  */
08405 void TheoryQuant::mapTermsByType(const CDList<Expr>& terms)
08406 {
08407   Expr trExpr=trueExpr(), flsExpr = falseExpr();
08408   Type boolT = boolType();
08409   if(d_contextMap.count(boolT) == 0)
08410     {
08411       d_contextMap[boolT] =
08412         new(true) CDList<size_t>(theoryCore()->getCM()->getCurrentContext());
08413       size_t pos = d_contextTerms.size();
08414       d_contextTerms.push_back(trExpr);
08415       d_contextTerms.push_back(flsExpr);
08416       (*d_contextMap[boolT]).push_back(pos);
08417       (*d_contextMap[boolT]).push_back(pos+1);
08418     }
08419   for(size_t i=0; i<terms.size(); i++)
08420     recursiveMap(terms[i]);
08421   // Add all our saved universals to the pool
08422   for(size_t i=0; i<d_univs.size(); i++)
08423     recursiveMap(d_univs[i].getExpr());
08424 }
08425 
08426 /*! \brief categorizes all the terms contained in an expressions by
08427  * type.
08428  *
08429  * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
08430  * returns true if the expression does not contain bound variables, false
08431  * otherwise.
08432  */
08433 bool TheoryQuant::recursiveMap(const Expr& e)
08434 {
08435   if(d_contextCache.count(e)>0) {
08436     return(d_contextCache[e]);
08437   }
08438   if(e.arity()>0)  {
08439     for(Expr::iterator it = e.begin(), iend = e.end(); it!=iend; ++it)
08440       //maps the children and returns a bool
08441       if(recursiveMap(*it) == false) {
08442   d_contextCache[e] = false;
08443       }
08444   }
08445   else if(e.getKind() == EXISTS || e.getKind() == FORALL){
08446     //maps the body
08447     if(recursiveMap(e.getBody())==false) {
08448       d_contextCache[e]=false;
08449     }
08450   }
08451   //found a bound variable in the children
08452   if(d_contextCache.count(e)>0) {
08453     return false;
08454   }
08455 
08456   if(d_savedCache.count(e) > 0) {
08457     return true;
08458   }
08459 
08460   Type type = getBaseType(e);
08461 
08462   if(!type.isBool() && !(e.getKind()==BOUND_VAR)){
08463      TRACE("quant", "recursiveMap: found ",
08464      e.toString() + " of type " + type.toString(), "");
08465     int pos = d_contextTerms.size();
08466     d_contextTerms.push_back(e);
08467     if(d_contextMap.count(type)==0)
08468       d_contextMap[type] =
08469         new(true) CDList<size_t>(theoryCore()->getCM()->getCurrentContext());
08470     (*d_contextMap[type]).push_back(pos);
08471   }
08472 
08473   if(e.getKind() == BOUND_VAR) {
08474     d_contextCache[e] = false;
08475     return false;
08476   }
08477   else {
08478     d_contextCache[e] = true;
08479     return true;
08480   }
08481   //need  to implement:
08482   //insert all instantiations if type is finite and reasonable
08483   //also need to implement instantiations of subtypes
08484 }
08485 
08486 /*!\brief Used to notify the quantifier algorithm of possible
08487  * instantiations that were used in proving a context inconsistent.
08488  */
08489 void TheoryQuant::notifyInconsistent(const Theorem& thm){
08490 #ifdef _CVC3_DEBUG_MODE
08491 
08492   if( CVC3::debugger.trace("quant inscon")  ){
08493 
08494     cout<<"the one caused incsonsistency"<<endl;
08495     cout<<thm.getAssumptionsRef().toString()<<endl;
08496     std::vector<Expr> assump;
08497     thm.getLeafAssumptions(assump);
08498 
08499     cout<<"===========leaf assumptions; =========="<<endl;
08500     for(std::vector<Expr>::iterator i=assump.begin(), iend=assump.end(); i!=iend; i++){
08501       cout<<">>"<<i->toString()<<endl;
08502     }
08503   }
08504 #endif
08505 
08506   if(d_univs.size() == 0)
08507     return;
08508   DebugAssert(thm.getExpr().isFalse(), "notifyInconsistent called with"
08509   " theorem: " + thm.toString() + " which is not a derivation of false");
08510   TRACE("quant", "notifyInconsistent: { " , thm.toString(), "}");
08511   //  thm.clearAllFlags();
08512   //  findInstAssumptions(thm);
08513   TRACE("quant terse", "notifyInconsistent: savedTerms size = ",
08514   d_savedTerms.size(), "");
08515   TRACE("quant terse", "last term: ",
08516   d_savedTerms.size()? d_savedTerms.back() : Expr(), "");
08517 }
08518 /*! \brief A recursive function used to find instantiated universals
08519  * in the hierarchy of assumptions.
08520  */
08521 void TheoryQuant::findInstAssumptions(const Theorem& thm)
08522 {
08523   if(thm.isNull() || thm.isRefl() || thm.isFlagged())
08524     return;
08525   thm.setFlag();
08526   const Expr& e = thm.getExpr();
08527   if(d_insts.count(e) > 0) {
08528     vector<Expr>& insts = d_insts[e];
08529     int pos;
08530     for(vector<Expr>::iterator it = insts.begin(), iend = insts.end(); it!=iend
08531     ; ++it)
08532       {
08533   if(d_savedCache.count(*it) ==  0) {
08534     TRACE("quant", "notifyInconsistent: found:", (*it).toString(), "");
08535     d_savedCache[*it] = true;
08536     pos = d_savedTerms.size();
08537     d_savedTerms.push_back(*it);
08538     d_savedMap[getBaseType(*it)].push_back(pos);
08539   }
08540       }
08541   }
08542   if(thm.isAssump())
08543     return;
08544   const Assumptions& a = thm.getAssumptionsRef();
08545   for(Assumptions::iterator it =a.begin(), iend = a.end(); it!=iend; ++it){
08546     findInstAssumptions(*it);
08547   }
08548 }
08549 
08550 //! computes the type of a quantified term. Always a  boolean.
08551 void TheoryQuant::computeType(const Expr& e)
08552 {
08553   switch (e.getKind()) {
08554   case FORALL:
08555   case EXISTS: {
08556     if(!e.getBody().getType().isBool())
08557       throw TypecheckException("Type mismatch for expression:\n\n   "
08558             + e.getBody().toString()
08559             + "\n\nhas the following type:\n\n  "
08560             + e.getBody().getType().toString()
08561             + "\n\nbut the expected type is Boolean:\n\n  ");
08562     else
08563 
08564       e.setType(e.getBody().getType());
08565     break;
08566   }
08567   default:
08568     DebugAssert(false,"Unexpected kind in Quantifier Theory: "
08569     + e.toString());
08570     break;
08571   }
08572 }
08573 
08574 /*!
08575  * TCC(forall x.phi(x)) = (forall x. TCC(phi(x)))
08576  *                         OR (exists x. TCC(phi(x)) & !phi(x))
08577  * TCC(exists x.phi(x)) = (forall x. TCC(phi(x)))
08578  *                         OR (exists x. TCC(phi(x)) & phi(x))
08579  */
08580 
08581 
08582 Expr TheoryQuant::computeTCC(const Expr& e) {
08583   DebugAssert(e.isQuantifier(), "Unexpected expression in Quantifier Theory: "
08584         + e.toString());
08585 
08586   bool forall(e.getKind() == FORALL);
08587   const Expr& phi = e.getBody();
08588   Expr tcc_phi = getTCC(phi);
08589   Expr forall_tcc = getEM()->newClosureExpr(FORALL, e.getVars(), tcc_phi);
08590   Expr exists_tcc = getEM()->newClosureExpr(EXISTS, e.getVars(),
08591                                             tcc_phi && (forall? !phi : phi));
08592   return (forall_tcc || exists_tcc);
08593 }
08594 
08595 
08596 ExprStream&
08597 TheoryQuant::print(ExprStream& os, const Expr& e) {
08598   switch(os.lang()) {
08599   case SIMPLIFY_LANG:
08600     {
08601       switch(e.getKind()){
08602       case FORALL:
08603       case EXISTS: {
08604   if(!e.isQuantifier()) {
08605     e.print(os);
08606     break;
08607   }
08608   os << "(" << ((e.getKind() == FORALL)? "FORALL" : "EXISTS");
08609   const vector<Expr>& vars = e.getVars();
08610   bool first(true);
08611   os << "(" ;
08612   for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
08613       i!=iend; ++i) {
08614     if(first) first = false;
08615     else os << " " ;
08616     os << *i;
08617     // The quantifier may be in a raw parsed form, in which case
08618     // the type is not assigned yet
08619     //if(i->isVar())  // simplify do not need type
08620     //  os << ":" << space << pushdag << (*i).getType() << popdag;
08621   }
08622   os << ") "  << e.getBody() <<  ")";
08623       }
08624   break;
08625       default:
08626   e.print(os);
08627   break;
08628       }
08629       break;
08630     }
08631   case TPTP_LANG:
08632     {
08633       switch(e.getKind()){
08634       case FORALL:
08635       case EXISTS: {
08636   if(!e.isQuantifier()) {
08637     e.print(os);
08638     break;
08639   }
08640   os << ((e.getKind() == FORALL)? " ! " : " ? ");
08641   const vector<Expr>& vars = e.getVars();
08642   bool first(true);
08643   os << "[" ;
08644   for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
08645       i!=iend; ++i) {
08646     if(first) first = false;
08647     else os << "," ;
08648     os << *i  ;
08649     if(i->isVar())  os <<  ": "<< (*i).getType() ;
08650   }
08651   os << "] : ("  << e.getBody() <<")";
08652       }
08653   break;
08654       default:
08655   e.print(os);
08656   break;
08657       }
08658       break;
08659     }
08660 
08661 
08662   case PRESENTATION_LANG: {
08663     switch(e.getKind()){
08664     case FORALL:
08665     case EXISTS: {
08666       if(!e.isQuantifier()) {
08667   e.print(os);
08668   break;
08669       }
08670       os << "(" << push << ((e.getKind() == FORALL)? "FORALL" : "EXISTS")
08671    << space << push;
08672       const vector<Expr>& vars = e.getVars();
08673       bool first(true);
08674       os << "(" << push;
08675       for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
08676     i!=iend; ++i) {
08677   if(first) first = false;
08678   else os << push << "," << pop << space;
08679   os << *i;
08680   // The quantifier may be in a raw parsed form, in which case
08681   // the type is not assigned yet
08682   // the following lines are changed for a neat output / by yeting
08683   if(*d_translate || true){
08684     if(i->isVar())
08685       os << ":" << space << pushdag << (*i).getType() << popdag;
08686   }
08687       }
08688       os << push << ") " << pushdag << push;
08689 
08690       // print manual triggers
08691       const vector<vector<Expr> >& triggers = e.getTriggers();
08692       for (vector<vector<Expr> >::const_iterator i=triggers.begin(), iend=triggers.end(); i != iend; ++i) {
08693   //        const vector<Expr>& terms = (*i).getKids();
08694         const vector<Expr>& terms = (*i);
08695         if (terms.size() > 0) {
08696           os << push << ": PATTERN (" << pushdag << push;
08697           vector<Expr>::const_iterator j=terms.begin(), jend=terms.end();
08698           os << nodag << pushdag << *j << popdag; ++j;
08699           for(;j!=jend; ++j) {
08700             os << push << ", " << pop << space << pushdag << *j << popdag;
08701           }
08702           os << ") " << push;
08703         }
08704       }
08705 
08706       os << ": " << pushdag << e.getBody() << push << ")";
08707     }
08708       break;
08709     default:
08710       e.print(os);
08711       break;
08712     }
08713     break;
08714   }
08715   case SMTLIB_LANG: {
08716     d_theoryUsed = true;
08717     switch(e.getKind()){
08718       case FORALL:
08719       case EXISTS: {
08720         if(!e.isQuantifier()) {
08721           e.print(os);
08722           break;
08723         }
08724         os << "(" << push << ((e.getKind() == FORALL)? "forall" : "exists")
08725            << space;
08726         const vector<Expr>& vars = e.getVars();
08727         bool first(true);
08728         //      os << "(" << push;
08729         for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
08730             i!=iend; ++i) {
08731           if(first) first = false;
08732           else os << space;
08733           os << "(" << push << *i;
08734           // The quantifier may be in a raw parsed form, in which case
08735           // the type is not assigned yet
08736           if(i->isVar())
08737             os << space << pushdag << (*i).getType() << popdag;
08738           os << push << ")" << pop << pop;
08739         }
08740         os << space << pushdag
08741            << e.getBody() << push;
08742 
08743         // print manual triggers
08744         const vector<vector<Expr> >& triggers = e.getTriggers();
08745         for (vector<vector<Expr> >::const_iterator i=triggers.begin(), iend=triggers.end(); i != iend; ++i) {
08746     //          const vector<Expr>& terms = (*i).getKids();
08747           const vector<Expr>& terms = (*i);
08748           if (terms.size() > 0) {
08749             os << push << space << ":pat {" << space << pushdag << push;
08750             vector<Expr>::const_iterator j=terms.begin(), jend=terms.end();
08751             os << nodag << pushdag << *j << popdag; ++j;
08752             for(;j!=jend; ++j) {
08753               os << space << pushdag << *j << popdag;
08754             }
08755             os << space << "}" << space << push;
08756           }
08757         }
08758         os << push << ")";
08759         break;
08760       }
08761       default:
08762         throw SmtlibException("TheoryQuant::print: SMTLIB_LANG: Unexpected expression: "
08763                               +getEM()->getKindName(e.getKind()));
08764         break;
08765     }
08766     break;
08767   } // End of SMTLIB_LANG
08768   case LISP_LANG: {
08769     switch(e.getKind()){
08770     case FORALL:
08771     case EXISTS: {
08772       if(!e.isQuantifier()) {
08773   e.print(os);
08774   break;
08775       }
08776       os << "(" << push << ((e.getKind() == FORALL)? "FORALL" : "EXISTS")
08777    << space;
08778       const vector<Expr>& vars = e.getVars();
08779       bool first(true);
08780       os << "(" << push;
08781       for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
08782     i!=iend; ++i) {
08783   if(first) first = false;
08784   else os << space;
08785   os << "(" << push << *i;
08786   // The quantifier may be in a raw parsed form, in which case
08787   // the type is not assigned yet
08788   if(i->isVar())
08789     os << space << pushdag << (*i).getType() << popdag;
08790   os << push << ")" << pop << pop;
08791       }
08792       os << push << ")" << pop << pop << pushdag
08793    << e.getBody() << push << ")";
08794     }
08795       break;
08796     default:
08797       e.print(os);
08798       break;
08799     }
08800     break;
08801   }
08802   default:
08803     e.print(os);
08804     break;
08805   }
08806   return os;
08807 }
08808 
08809 ///////////////////////////////////////////////////////////////////////////////
08810 //parseExprOp:
08811 //translating special Exprs to regular EXPR??
08812 ///////////////////////////////////////////////////////////////////////////////
08813 Expr
08814 TheoryQuant::parseExprOp(const Expr& e) {
08815   TRACE("parser", "TheoryQuant::parseExprOp(", e, ")");
08816   // If the expression is not a list, it must have been already
08817   // parsed, so just return it as is.
08818   if(RAW_LIST != e.getKind()) return e;
08819 
08820   DebugAssert(e.arity() > 0,
08821         "TheoryQuant::parseExprOp:\n e = "+e.toString());
08822 
08823   const Expr& c1 = e[0][0];
08824   const string& opName(c1.getString());
08825   int kind = getEM()->getKind(opName);
08826   switch(kind) {
08827   case FORALL:
08828   case EXISTS: { // (OP ((v1 ... vn tp1) ...) body)
08829     if(!( (e.arity() == 3  || 4 == e.arity())  &&
08830     e[1].getKind() == RAW_LIST &&
08831     e[1].arity() > 0))
08832       throw ParserException("Bad "+opName+" expression: "+e.toString());
08833 
08834 
08835     // Iterate through the groups of bound variables
08836     vector<pair<string,Type> > vars; // temporary stack of bound variables
08837     for(Expr::iterator i=e[1].begin(), iend=e[1].end(); i!=iend; ++i) {
08838       if(i->getKind() != RAW_LIST || i->arity() < 2)
08839   throw ParserException("Bad variable declaration block in "+opName
08840           +" expression: "+i->toString()
08841           +"\n e = "+e.toString());
08842       // Iterate through individual bound vars in the group.  The
08843       // last element is the type, which we have to rebuild and
08844       // parse, since it is used in the creation of bound variables.
08845       Type tp(parseExpr((*i)[i->arity()-1]));
08846       if (tp == boolType()) {
08847         throw ParserException("A quantified variable may not be of type BOOLEAN");
08848       }
08849       for(int j=0, jend=i->arity()-1; j<jend; ++j) {
08850   if((*i)[j].getKind() != ID)
08851     throw ParserException("Bad variable declaration in "+opName+""
08852             " expression: "+(*i)[j].toString()+
08853             "\n e = "+e.toString());
08854   vars.push_back(pair<string,Type>((*i)[j][0].getString(), tp));
08855       }
08856     }
08857     // Create all the bound vars and save them in a vector
08858     vector<Expr> boundVars;
08859     for(vector<pair<string,Type> >::iterator i=vars.begin(), iend=vars.end();
08860   i!=iend; ++i)
08861       boundVars.push_back(addBoundVar(i->first, i->second));
08862     // Rebuild the body
08863     Expr body(parseExpr(e[2]));
08864     // Build the resulting Expr as (OP (vars) body)
08865 
08866     std::vector<std::vector<Expr> > patterns;
08867     if(e.arity() == 4){
08868       DebugAssert ((RAW_LIST == e[3].getKind()),"Unknown type for patterns"+e[3].toString());
08869       for(int i = 0; i < e[3].arity(); i++){
08870   const Expr& cur_trig(e[3][i]);
08871   DebugAssert ((RAW_LIST == cur_trig.getKind()),"Unknown type for cur_trig"+cur_trig.toString());
08872   //  cout<<"cur trig"<<cur_trig<<endl;
08873   std::vector<Expr> cur_pattern;
08874   for(int j =0; j < cur_trig.arity(); j++){
08875     try {
08876       cur_pattern.push_back(parseExpr(cur_trig[j]));
08877     }
08878     catch (Exception e){
08879       //      cout <<e << endl;
08880       //      cout <<"exception in pattern" << flush << endl;
08881       cur_pattern.clear();
08882     }
08883   }
08884   if (cur_pattern.size() > 0 ){
08885     //    Expr cur_parsed_trig(RAW_LIST, cur_pattern, getEM());
08886     patterns.push_back(cur_pattern);
08887   }
08888       }
08889     }
08890 
08891 
08892     Expr res;
08893     if(3 == e.arity()) {
08894       res = getEM()->newClosureExpr((kind == FORALL) ? FORALL : EXISTS,boundVars, body);
08895     }
08896     else{// 4 == e.arity()
08897       res = getEM()->newClosureExpr((kind == FORALL) ? FORALL : EXISTS,boundVars, body, patterns );
08898       //      cout<<"patterns vector"<<vectorExpr2string(patterns)<<endl;;
08899       //      cout<<"patterns thm"<<res<<endl;;
08900     }
08901     return res;
08902     break;
08903   }
08904   default:
08905     DebugAssert(false,
08906     "TheoryQuant::parseExprOp: invalid command or expression: " + e.toString());
08907     break;
08908   }
08909   return e;
08910 }
08911 

Generated on Wed Nov 18 16:13:32 2009 for CVC3 by  doxygen 1.5.2