CVC3

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