1 /*****************************************************************************/
2 /*!
3  * \File theory_quant.cpp
4  *
5  * Author: Daniel Wichs, Yeting Ge
6  *
7  * Created: Wednesday July 2, 2003
8  *
9  * <hr>
10  *
11  * License to use, copy, modify, sell and/or distribute this software
12  * and its documentation for any purpose is hereby granted without
13  * royalty, subject to the terms and conditions defined in the \ref
14  * LICENSE file provided with this distribution.
15  *
16  * <hr>
17  *
18  */
19 /*****************************************************************************/
20 #include "theory_quant.h"
21 #include "theory_arith.h"
22 #include "theory_array.h"
23 #include "typecheck_exception.h"
24 #include "parser_exception.h"
25 #include "smtlib_exception.h"
26 #include "quant_proof_rules.h"
27 #include "theory_core.h"
28 #include "command_line_flags.h"
29 #include "vcl.h"
30 #include<string>
31 #include<string.h>
32 #include <algorithm>
33 #include "assumptions.h"
34 
35 using namespace std;
36 using namespace CVC3;
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // TheoryQuant Public Methods                                                 //
40 ///////////////////////////////////////////////////////////////////////////////
41 
42 static const Expr null_expr;
43 const int FOUND_FALSE = 1;
44 
Trigger(TheoryCore * core,Expr e,Polarity pol,std::set<Expr> boundVars)45 Trigger::Trigger(TheoryCore* core, Expr e, Polarity pol, std::set<Expr> boundVars){
46   trig=e ;
47   polarity=pol;
48   head=null_expr;
49   hasRWOp=false;
50   hasTrans=false;
51   hasT2=false;
52   isSimple=false;
53   isSuperSimple=false;
54   isMulti=false;
55   multiIndex = 99999;
56   multiId = 99999;
57   for(std::set<Expr>::const_iterator i=boundVars.begin(),iend=boundVars.end(); i!=iend; ++i)
58     bvs.push_back(*i);
59 }
60 
isPos()61 bool Trigger::isPos(){
62   return (Pos==polarity||PosNeg==polarity);
63 }
64 
isNeg()65 bool Trigger::isNeg(){
66   return (Neg==polarity || PosNeg==polarity);
67 }
68 
getBVs()69 std::vector<Expr> Trigger::getBVs(){
70   return bvs;
71 }
72 
getEx()73 Expr Trigger::getEx(){
74   return trig;
75 }
76 
setHead(Expr h)77 void Trigger::setHead(Expr h){
78   head=h;
79 }
80 
getHead()81 Expr Trigger::getHead(){
82   return head;
83 }
84 
setRWOp(bool b)85 void Trigger::setRWOp(bool b){
86   hasRWOp =b ;
87 }
88 
hasRW()89 bool Trigger::hasRW(){
90   return hasRWOp;
91 }
92 
setTrans(bool b)93 void Trigger::setTrans(bool b){
94   hasTrans =b ;
95 }
96 
hasTr()97 bool Trigger::hasTr(){
98   return hasTrans;
99 }
100 
setTrans2(bool b)101 void Trigger::setTrans2(bool b){
102   hasT2 =b ;
103 }
104 
hasTr2()105 bool Trigger::hasTr2(){
106   return hasT2;
107 }
108 
setSimp()109 void Trigger::setSimp(){
110   isSimple =true ;
111 }
112 
isSimp()113 bool Trigger::isSimp(){
114   return isSimple;
115 }
116 
setSuperSimp()117 void Trigger::setSuperSimp(){
118   isSuperSimple =true ;
119 }
120 
isSuperSimp()121 bool Trigger::isSuperSimp(){
122   return isSuperSimple;
123 }
124 
setMultiTrig()125 void Trigger::setMultiTrig(){
126   isMulti = true ;
127 }
128 
isMultiTrig()129 bool Trigger::isMultiTrig(){
130   return isMulti;
131 }
132 
133 
dynTrig(Trigger t,ExprMap<Expr> b,size_t id)134 dynTrig::dynTrig(Trigger t, ExprMap<Expr> b, size_t id)
135   :trig(t),
136    univ_id(id),
137    binds(b)
138 {}
139 
TheoryQuant(TheoryCore * core)140 TheoryQuant::TheoryQuant(TheoryCore* core) //!< Constructor
141   : Theory(core, "Quantified Expressions"),
142     d_univs(core->getCM()->getCurrentContext()),
143     d_rawUnivs(core->getCM()->getCurrentContext()),
144     d_arrayTrigs(core->getCM()->getCurrentContext()),
145     d_lastArrayPos(core->getCM()->getCurrentContext(), 0 , 0),
146     d_lastPredsPos(core->getCM()->getCurrentContext(), 0, 0),
147     d_lastTermsPos(core->getCM()->getCurrentContext(), 0, 0),
148     d_lastPartPredsPos(core->getCM()->getCurrentContext(), 0, 0),
149     d_lastPartTermsPos(core->getCM()->getCurrentContext(), 0, 0),
150     d_univsPartSavedPos(core->getCM()->getCurrentContext(), 0, 0),
151     d_lastPartLevel(core->getCM()->getCurrentContext(), 0, 0),
152     d_partCalled(core->getCM()->getCurrentContext(),false,0),
153     d_maxILReached(core->getCM()->getCurrentContext(),false,0),
154     d_usefulGterms(core->getCM()->getCurrentContext()),
155     d_lastUsefulGtermsPos(core->getCM()->getCurrentContext(), 0, 0),
156     d_savedTermsPos(core->getCM()->getCurrentContext(), 0, 0),
157     d_univsSavedPos(core->getCM()->getCurrentContext(), 0, 0),
158     d_rawUnivsSavedPos(core->getCM()->getCurrentContext(), 0, 0),
159     d_univsPosFull(core->getCM()->getCurrentContext(), 0, 0),
160     d_univsContextPos(core->getCM()->getCurrentContext(), 0, 0),
161     d_instCount(core->getCM()->getCurrentContext(), 0,0),
162     d_contextTerms(core->getCM()->getCurrentContext()),
163     d_contextCache(core->getCM()->getCurrentContext()),
164     d_maxQuantInst(&(core->getFlags()["max-quant-inst"].getInt())),
165     d_useNew(&(core->getFlags()["quant-new"].getBool())),
166     d_useLazyInst(&(core->getFlags()["quant-lazy"].getBool())),
167     d_useSemMatch(&(core->getFlags()["quant-sem-match"].getBool())),
168     d_useCompleteInst(&(core->getFlags()["quant-complete-inst"].getBool())),
169     d_translate(&(core->getFlags()["translate"].getBool())),
170     //    d_usePart(&(core->getFlags()["quant-inst-part"].getBool())),
171     //    d_useMult(&(core->getFlags()["quant-inst-mult"].getBool())),
172     d_useInstLCache(&(core->getFlags()["quant-inst-lcache"].getBool())),
173     d_useInstGCache(&(core->getFlags()["quant-inst-gcache"].getBool())),
174     d_useInstThmCache(&(core->getFlags()["quant-inst-tcache"].getBool())),
175     d_useInstTrue(&(core->getFlags()["quant-inst-true"].getBool())),
176     d_usePullVar(&(core->getFlags()["quant-pullvar"].getBool())),
177     d_useExprScore(&(core->getFlags()["quant-score"].getBool())),
178     d_maxIL(&(core->getFlags()["quant-max-IL"].getInt())),
179     d_useTrans(&(core->getFlags()["quant-trans3"].getBool())),
180     d_useTrans2(&(core->getFlags()["quant-trans2"].getBool())),
181     d_useManTrig(&(core->getFlags()["quant-man-trig"].getBool())),
182     d_useGFact(&(core->getFlags()["quant-gfact"].getBool())),
183     d_gfactLimit(&(core->getFlags()["quant-glimit"].getInt())),
184     d_usePolarity(&(core->getFlags()["quant-polarity"].getBool())),
185     d_useNewEqu(&(core->getFlags()["quant-eqnew"].getBool())),
186     d_maxNaiveCall(&(core->getFlags()["quant-naive-num"].getInt())),
187     d_useNaiveInst(&(core->getFlags()["quant-naive-inst"].getBool())),
188     d_curMaxExprScore(core->getCM()->getCurrentContext(), (core->getFlags()["quant-max-score"].getInt()),0),
189     d_arrayIndic(core->getCM()->getCurrentContext()),
190     d_exprLastUpdatedPos(core->getCM()->getCurrentContext(),0 ,0),
191     d_trans_found(core->getCM()->getCurrentContext()),
192     d_trans2_found(core->getCM()->getCurrentContext()),
193     null_cdlist(core->getCM()->getCurrentContext()),
194     d_eqsUpdate(core->getCM()->getCurrentContext()),
195     d_lastEqsUpdatePos(core->getCM()->getCurrentContext(), 0, 0),
196     d_eqs(core->getCM()->getCurrentContext()),
197     d_eqs_pos(core->getCM()->getCurrentContext(), 0, 0),
198     d_allInstCount(core->getStatistics().counter("quantifier instantiations")),
199     d_allInstCount2(core->getStatistics().counter("quantifier instantiations2")),
200     d_totalInstCount(core->getStatistics().counter("quant total instantiations")),
201     d_trueInstCount(core->getStatistics().counter("quant true instantiations")),
202     d_abInstCount(core->getStatistics().counter("quant abandoned instantiations")),
203     d_instHistory(core->getCM()->getCurrentContext()),
204     d_alltrig_list(core->getCM()->getCurrentContext())
205 {
206   IF_DEBUG(d_univs.setName("CDList[TheoryQuant::d_univs]");)
207   vector<int> kinds;
208   d_instCount = 0;
209   d_cacheThmPos=0;
210   d_trans_num=0;
211   d_trans2_num=0;
212   d_rules=createProofRules();
213   kinds.push_back(EXISTS);
214   kinds.push_back(FORALL);
215   registerTheory(this, kinds);
216   d_partCalled=false;
217   d_offset_multi_trig=2;
218   d_initMaxScore=(theoryCore()->getFlags()["quant-max-score"].getInt());
219   for(size_t i=0; i<MAX_TRIG_BVS; i++){
220     d_mybvs[i] = getEM()->newBoundVarExpr("_genbv", int2string(i), Type::anyType(getEM()));
221   }
222   core->addNotifyEq(this, null_expr);
223   defaultReadExpr = theoryCore()->getEM()->newStringExpr("read");
224   defaultWriteExpr = theoryCore()->getEM()->newStringExpr("write");
225   defaultPlusExpr= theoryCore()->getEM()->newStringExpr("+");
226   defaultMinusExpr= theoryCore()->getEM()->newStringExpr("-");
227   defaultMultExpr= theoryCore()->getEM()->newStringExpr("*");
228   defaultDivideExpr= theoryCore()->getEM()->newStringExpr("/");
229   defaultPowExpr= theoryCore()->getEM()->newStringExpr("pow");
230 
231 }
232 
233 //! Destructor
~TheoryQuant()234 TheoryQuant::~TheoryQuant() {
235   if(d_rules != NULL) delete d_rules;
236   for(std::map<Type, CDList<size_t>* ,TypeComp>::iterator
237 	it = d_contextMap.begin(), iend = d_contextMap.end();
238       it!= iend; ++it) {
239     delete it->second;
240      free(it->second);
241   }
242 
243 }
vectorExpr2string(const std::vector<Expr> & vec)244 std::string vectorExpr2string(const std::vector<Expr> & vec){
245   std::string buf;
246   for(size_t i=0; i<vec.size(); i++){
247     buf.append(vec[i].toString());
248     buf.append(" # ");
249   }
250   return buf;
251 }
252 
253 
rewrite(const Expr & e)254 Theorem TheoryQuant::rewrite(const Expr& e){
255   //  return reflexivityRule(e);
256   // should combined with packvar, rewriet_not_all, etc,
257   if(e.isForall() || e.isExists() ){
258     Theorem resThm =  d_rules->normalizeQuant(e);
259     //    Expr newE = resThm.getRHS();
260     return resThm;
261   }
262   else{
263     if (e.isNot() && e[0].isForall()){
264       //      cout<<vectorExpr2string(e[0].getVars()) << endl;
265     }
266     else {
267       //      cout<<e<<endl;
268     }
269     return reflexivityRule(e);
270   }
271 }
272 
273 
getExprScore(const Expr & e)274 int inline TheoryQuant::getExprScore(const Expr& e){
275   return theoryCore()->getQuantLevelForTerm(e);
276 }
277 
isSysPred(const Expr & e)278 bool isSysPred(const Expr& e){
279   return ( isLE(e) || isLT(e) || isGE(e) || isGT(e) || e.isEq());
280 }
281 
canGetHead(const Expr & e)282 bool canGetHead(const Expr& e){
283   //  return (e.getKind() == APPLY || e.getKind() == READ || e.getKind() == WRITE);
284   return (e.getKind() == APPLY
285 	  || e.getKind() == READ
286 	  || e.getKind() == WRITE
287 	  || isPlus(e)
288 	  || isMinus(e)
289 	  || isMult(e)
290 	  || isDivide(e)
291 	  || isPow(e)
292 	  );
293 }
294 
isSimpleTrig(const Expr & t)295 bool isSimpleTrig(const Expr& t){
296   if(!canGetHead(t)) return false;
297   for(int i = 0; i < t.arity(); i++){
298     if (t[i].arity()>0 && t[i].containsBoundVar()) return false;
299     if (BOUND_VAR == t[i].getKind()){
300       for(int j = 0; j < i; j++){
301 	if(t[i] == t[j]) return false;
302       }
303     }
304   }
305   return true;
306 }
307 
isSuperSimpleTrig(const Expr & t)308 bool isSuperSimpleTrig(const Expr& t){
309   if(!isSimpleTrig(t)) return false;
310   if(t.getKind() == READ || t.getKind() == WRITE){
311     return false; //in case var1[var2]
312   }
313   for(int i = 0; i < t.arity(); i++){
314     if (t[i].arity()>0 ) return false;
315     if (BOUND_VAR != t[i].getKind()){
316       return false;
317     }
318   }
319   return true;
320 }
321 
322 
usefulInMatch(const Expr & e)323 bool usefulInMatch(const Expr& e){
324   if(e.arity() == 0){
325     TRACE("usefulInMatch", e.toString()+": ",e.arity(), "");
326     TRACE("usefulInMatch", e.isRational(), "", "");
327   }
328   //  cout << "is useful in match" << (canGetHead(e) || (isSysPred(e) && (!e.isEq()) )) << "#" <<  e<< endl;
329   //  if (e.getKind() == APPLY){
330   //    cout << (e.getKind() == APPLY) << endl;
331   //    cout << e.getOp().getExpr() << endl;
332   //    cout << e.getOp() << endl;
333   //  }
334   return ( canGetHead(e) || (isSysPred(e) && (!e.isEq()) ) );
335 }
336 
setup(const Expr & e)337 void TheoryQuant::setup(const Expr& e) {}
338 
help(int i)339 int TheoryQuant::help(int i) {
340   return d_curMaxExprScore;
341 }
342 
debug(int i)343 void TheoryQuant::debug(int i){
344 
345   cout<<"in debug " << endl;
346   cout << "max expr score " << d_curMaxExprScore << endl;
347   cout << "all gterms " << endl;
348   for(size_t gtermIndex =0; gtermIndex <  d_usefulGterms.size() ; gtermIndex++){
349     cout << gtermIndex << " :: " << getExprScore(d_usefulGterms[gtermIndex]) << " | " << d_usefulGterms[gtermIndex] << endl;
350   }
351 
352   cout << " =============  all terms ========================== " << endl;
353   const CDList<Expr>&  allterms = theoryCore()->getTerms();
354   for(size_t gtermIndex =0; gtermIndex <  allterms.size() ; gtermIndex++){
355     const Expr& curGterm = allterms[gtermIndex];
356     cout << gtermIndex << " :: " << getExprScore(curGterm) << " | " << curGterm << endl;
357     cout << "--- ";
358     if (curGterm.isApply() && curGterm.hasRep()){
359       Expr curRep = curGterm.getRep().getRHS() ;
360       if(curRep != curGterm){
361 	cout<<"DIFF " <<curRep << endl;
362       }
363     }
364     else {
365       cout << "No Rep" ;
366     }
367     cout << endl ;
368 
369     cout << "=== ";
370     if (curGterm.isApply() && curGterm.hasSig()){
371       Expr curSig = curGterm.getSig().getRHS() ;
372       if(curSig != curGterm){
373 	cout<<"DIFF " <<curSig << endl;
374       }
375     }
376     else {
377       cout << "No Sig" ;
378     }
379     cout << endl ;
380 
381 
382   }
383   cout << " =============  all preds  ========================== " << endl;
384   const CDList<Expr>&  allpreds = theoryCore()->getPredicates();
385   for(size_t gtermIndex =0; gtermIndex <  allpreds.size() ; gtermIndex++){
386     const Expr& curGterm = allpreds[gtermIndex];
387     cout << gtermIndex << " :: " << getExprScore(curGterm) << " | " << curGterm << endl;
388     cout << "--- ";
389     if (curGterm.isApply() && curGterm.hasRep()){
390       Expr curRep = curGterm.getRep().getRHS() ;
391       if(curRep != curGterm){
392 	cout<<"DIFF " <<curRep << endl;
393       }
394     }
395     else {
396       cout << "No Rep" ;
397     }
398     cout << endl ;
399 
400     cout << "=== ";
401     if (curGterm.isApply() && curGterm.hasSig()){
402       Expr curSig = curGterm.getSig().getRHS() ;
403       if(curSig != curGterm){
404 	cout<<"DIFF " <<curSig << endl;
405       }
406     }
407     else {
408       cout << "No Sig" ;
409     }
410     cout << endl ;
411   }
412 
413   cout<<"let us try more"<<endl;
414 
415   //  checkSat(true);
416 
417 }
418 
update(const Theorem & t,const Expr & e)419 void TheoryQuant::update(const Theorem& t, const Expr& e) {
420 
421   TRACE("quant update", "eqs updated: ",  t.getExpr(), "");
422 
423   //  if(! (*d_useNewEqu)) return;
424   //  cout<<" ===== eqs in update =================== " <<endl;
425 
426   d_eqsUpdate.push_back(t);
427 
428   return;
429 
430   const Expr& leftTerm = t.getLHS();
431   const Expr& rightTerm = t.getRHS();
432   /*
433   NotifyList* leftUpList = leftTerm.getNotify();
434 
435   cout<<"left term is " << leftTerm << endl;
436 
437   if(NULL == leftUpList) return;
438 
439 
440   cout<<"the left notify list" <<endl;
441   NotifyList& l = *leftUpList;
442   for(size_t i=0,iend=l.size(); i<iend; ++i) {
443     if(l.getTheory(i)->getName() == "Uninterpreted Functions"){
444     cout << "[" << l.getTheory(i)->getName() << ", " << l.getExpr(i) << "] " << l.getExpr(i).getSig().isNull() << endl;
445     }
446   }
447 
448   const Expr& rightTerm = t.getRHS();
449   cout<<"right term is " << rightTerm << endl;
450   NotifyList* rightUpList = rightTerm.getNotify();
451   if(NULL == rightUpList) return;
452 
453   cout<<"the right notify list" << endl;
454 
455   NotifyList& ll = *rightUpList;
456   for(size_t i=0,iend=ll.size(); i<iend; ++i) {
457     if(ll.getTheory(i)->getName() == "Uninterpreted Functions"){
458     cout << "[" << ll.getTheory(i)->getName() << ", " << ll.getExpr(i) << "] " << ll.getExpr(i).getSig().isNull() << endl;
459     }
460   }
461 
462 
463 //   cout<<"------------" << leftTerm << " # " << rightTerm <<endl;
464 //   cout<<"$$$$$$$$$$$$" << leftTerm.hasFind() << " # " << rightTerm.hasFind() <<endl;
465 //   if(theoryOf(leftTerm)->getName() == "Uninterpreted Functions"){
466 //     cout<<"%%%%%%%%%%%%" << (leftTerm.getSig()).isNull() << " # " << (rightTerm.getSig()).isNull() <<endl;
467 //   }
468 //   else{
469 //     cout<<"tttt" <<theoryOf(leftTerm)->getName()<<endl;
470 //   }
471 */
472   if(false)
473   {
474     CDList<Expr>& backL = backList(leftTerm);
475     CDList<Expr>& forwL = forwList(rightTerm);
476 
477     size_t backLen = backL.size();
478     size_t forwLen = forwL.size();
479     for(size_t i =0; i < backLen; i++){
480       for(size_t j =0; j < forwLen; j++){
481 	//	cout<<backL[i] << " # " << leftTerm << " # " << forwL[j] << endl;
482       }
483     }
484   }
485   {
486     CDList<Expr>& backL = backList(rightTerm);
487     CDList<Expr>& forwL = forwList(leftTerm);
488     size_t backLen = backL.size();
489     size_t forwLen = forwL.size();
490     for(size_t i = 0; i < backLen; i++){
491       for(size_t j = 0; j < forwLen; j++){
492 	//	cout<<backL[i] << " # " << rightTerm << " # " << forwL[j] << endl;
493       }
494     }
495   }
496 
497 }
498 
499 
exprMap2string(const ExprMap<Expr> & vec)500 std::string TheoryQuant::exprMap2string(const ExprMap<Expr>& vec){
501   string result;
502 //   for( ExprMap<Expr>::iterator i = vec.begin(), iend = vec.end(); i != iend; i++){
503 //     result.append((i->first).toString());
504 //     result.append(" # ");
505 //     result.append((i->second).toString());
506 //     result.append("\n");
507 //   }
508 //   result.append("------ end map ------\n");
509   return result;
510 }
511 
512 
513 
exprMap2stringSimplify(const ExprMap<Expr> & vec)514 std::string TheoryQuant::exprMap2stringSimplify(const ExprMap<Expr>& vec){
515   string result;
516 //   for( ExprMap<Expr>::iterator i = vec.begin(), iend = vec.end(); i != iend; i++){
517 //     result.append((i->first).toString());
518 //     result.append(" # ");
519 //     result.append((simplifyExpr(i->second)).toString());
520 //     result.append("\n");
521 //   }
522   result.append("------ end map ------\n");
523   return result;
524 }
525 
exprMap2stringSig(const ExprMap<Expr> & vec)526 std::string TheoryQuant::exprMap2stringSig(const ExprMap<Expr>& vec){
527   string result;
528 //     for( ExprMap<Expr>::iterator i = vec.begin(), iend = vec.end(); i != iend; i++){
529 //     result.append((i->first).toString());
530 //     result.append(" # ");
531 //     Expr isecond = i->second;
532 //     if(simplifyExpr(isecond) == isecond && isecond.isApply() && isecond.hasSig()){
533 //       result.append((isecond.getSig().getRHS()).toString());
534 //     }
535 //     else{
536 //       //      result.append(isecond.toString());
537 //     }
538 //     result.append("\n");
539 //   }
540   result.append("------ end map ------\n");
541   return result;
542 }
543 
544 
simplifyExprMap(ExprMap<Expr> & orgExprMap)545 void TheoryQuant::simplifyExprMap(ExprMap<Expr>& orgExprMap){
546   ExprMap<Expr> newExprMap;
547   for( ExprMap<Expr>::iterator i = orgExprMap.begin(), iend = orgExprMap.end(); i != iend; i++){
548     newExprMap[(*i).first] = simplifyExpr((*i).second);
549   }
550   orgExprMap = newExprMap;
551 }
552 
simplifyVectorExprMap(vector<ExprMap<Expr>> & orgVectorExprMap)553 void TheoryQuant::simplifyVectorExprMap(vector<ExprMap<Expr> >& orgVectorExprMap){
554   std::vector<ExprMap<Expr> > newVectorExprMap;
555   for( size_t orgVectorIndex = 0; orgVectorIndex < orgVectorExprMap.size(); orgVectorIndex++){
556     ExprMap<Expr> curExprMap = orgVectorExprMap[orgVectorIndex];
557     simplifyExprMap(curExprMap);
558     newVectorExprMap.push_back(curExprMap);
559   }
560   orgVectorExprMap = newVectorExprMap;
561 }
562 
recursiveGetSubTrig(const Expr & e,std::vector<Expr> & res)563 static void recursiveGetSubTrig(const Expr& e, std::vector<Expr> & res) {
564   if(e.getFlag())
565    return;
566 
567   if(e.isClosure())
568     return recursiveGetSubTrig(e.getBody(),res);
569 
570   if (e.isApply()|| isSysPred(e)){
571     res.push_back(e);
572   }
573   else
574     if ( e.isTerm() && (!e.isVar()) && (e.getKind()!=RATIONAL_EXPR) ) {
575 	res.push_back(e);
576       }
577 
578   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)    {
579       recursiveGetSubTrig(*i,res);
580     }
581 
582   e.setFlag();
583   return ;
584 }
585 
getSubTrig(const Expr & e)586 std::vector<Expr> getSubTrig(const Expr& e){
587   e.clearFlags();
588   std::vector<Expr> res;
589   recursiveGetSubTrig(e,res);
590   e.clearFlags();
591   TRACE("getsub","e is ", e.toString(),"");
592   TRACE("getsub","have ", res.size()," subterms");
593   return res;
594 }
595 
recGetSubTerms(const Expr & e,std::vector<Expr> & res)596 static void recGetSubTerms(const Expr& e, std::vector<Expr> & res) {
597   if(e.getFlag())
598    return;
599 
600   if(e.isClosure())
601     return recGetSubTerms(e.getBody(),res);
602 
603   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)  {
604     recGetSubTerms(*i,res);
605   }
606 
607   res.push_back(e);
608 
609   e.setFlag();
610   return ;
611 }
612 
getSubTerms(const Expr & e)613 const std::vector<Expr>& TheoryQuant::getSubTerms(const Expr& e){
614   //the last item in res is e itself
615   ExprMap<std::vector<Expr> >::iterator iter= d_subTermsMap.find(e);
616   if( d_subTermsMap.end() == iter){
617     e.clearFlags();
618     std::vector<Expr> res;
619     recGetSubTerms(e,res);
620     e.clearFlags();
621 
622     TRACE("getsubs", "getsubs, e is: ", e, "");
623     TRACE("getsubs", "e has ", res.size(), " subterms");
624 
625     d_subTermsMap[e] = res;
626     return d_subTermsMap[e];
627   }
628   else{
629     return (*iter).second;
630   }
631 }
632 
enqueueInst(const Theorem & univ,const vector<Expr> & bind,const Expr & gterm)633 void TheoryQuant::enqueueInst(const Theorem& univ, const vector<Expr>& bind, const Expr& gterm){
634   static int max_score =-1;
635 
636   bool partInst=false;
637   if(bind.size() < univ.getExpr().getVars().size()){
638     partInst=false;
639     TRACE("sendinst","partinst",partInst,"");
640   }
641 
642   Expr bind_expr(RAW_LIST, bind, getEM());
643 
644   if (*d_useInstLCache){
645     const Expr& e = univ.getExpr();
646     ExprMap<CDMap<Expr,bool>*>::iterator iterCache = d_bindHistory.find(e);
647     if (iterCache != d_bindHistory.end()){
648       CDMap<Expr,bool>* cache = (*iterCache).second;
649       if(cache->find(bind_expr) !=cache->end()){
650 	return ;
651       }
652       else{
653 	(*cache)[bind_expr] = true;
654       }
655     }
656     else{
657       CDMap<Expr,bool>* new_cache = new(true) CDMap<Expr,bool> (theoryCore()->getCM()->getCurrentContext());
658       (*new_cache)[bind_expr] = true;
659       d_bindHistory[e] = new_cache;
660     }
661 
662   }
663 
664   Theorem thm ;
665   if(null_expr == gterm ){//it is from naive instantiation or multi-inst
666     TRACE("sendinst","gterm",gterm,"");
667     if(partInst) {
668       thm = d_rules->partialUniversalInst(univ, bind, 0);
669     }
670     else{
671       //      thm = d_rules->universalInst(univ, bind, 0);
672       thm = d_rules->universalInst(univ, bind, 0, gterm);
673     }
674   }
675   else{
676     int gscore = theoryCore()->getQuantLevelForTerm(gterm);
677     if(gscore > max_score){
678       max_score = gscore;
679       //      cout<<"max score "<<max_score<<endl;
680     }
681     if(partInst) {
682       thm = d_rules->partialUniversalInst(univ, bind, gscore);
683     }
684     else{
685       //      thm = d_rules->universalInst(univ, bind, gscore);
686       thm = d_rules->universalInst(univ, bind, gscore, gterm);
687     }
688   }
689 
690   d_totalInstCount++;
691   d_totalThmCount[thm.getExpr()]++;
692   Theorem simpThm = simplify(thm.getExpr());
693 
694   if(*d_useInstTrue){
695     Expr res = simpThm.getRHS();
696     if(res.isTrue()){
697       d_trueInstCount++;
698       return;
699     }
700     if(res.isFalse() ){
701       d_thmCount[thm.getExpr()]++;
702       //      enqueueSE(thm);
703       //      if(*d_useGFact || d_totalThmCount[thm.getExpr()] > *d_gfactLimit){
704       if(*d_useGFact || d_thmCount[thm.getExpr()] > *d_gfactLimit){
705 	//      if(*d_useGFact || ){
706 	//	addGlobalLemma(thm, -1);
707 	enqueueFact(thm);
708       }
709       else{
710 	enqueueFact(thm);
711       }
712       //
713       //      cout<<"false found "<<endl;
714       //      setInconsistent(simpThm);
715       d_allInstCount++;
716       d_instThisRound++;
717 
718       throw FOUND_FALSE;
719     }
720   }
721 
722   d_simplifiedThmQueue.push(thm);
723 
724   TRACE("quant sendinst", "= gterm:",gterm, "");
725   //  TRACE("quant sendinst", "= IL: ", theoryCore()->getQuantLevelForTerm(gterm), "");
726   TRACE("quant sendinst", "= add fact simp: ", simplifyExpr(thm.getExpr()), "");
727   TRACE("quant sendinst", "= add fact org: ", thm.getExpr(), "");
728   TRACE("quant sendinst", "= add fact from: ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
729 }
730 
731 
732 //void TheoryQuant::enqueueInst(size_t univ_id , const std::vector<Expr>& bind, const Expr& gterm){
enqueueInst(size_t univ_id,const std::vector<Expr> & orgBind,const Expr & gterm)733 void TheoryQuant::enqueueInst(size_t univ_id , const std::vector<Expr>& orgBind, const Expr& gterm){
734   //  static int max_score =-1;
735   TRACE("quant sendinst", "= begin univ id: ", univ_id, "");
736   TRACE("quant sendinst", "= begin bind: ", vectorExpr2string(orgBind), "");
737   TRACE("quant sendinst", "= begin gterm: ", gterm, "");
738   const Theorem& univ = d_univs[univ_id];
739 
740   //  static vector<Theorem> storage ;
741   //  storage.push_back(univ);
742 
743   bool partInst=false;
744   if(orgBind.size() < univ.getExpr().getVars().size()){
745     partInst=false;
746     TRACE("sendinst","partinst",partInst,"");
747   }
748 
749   vector<Expr> simpBind(orgBind);
750   for(size_t orgBindIndex = 0; orgBindIndex < orgBind.size(); orgBindIndex++){
751     simpBind [orgBindIndex] = simplifyExpr(orgBind[orgBindIndex]);
752   }
753 
754   Expr orgBindList(RAW_LIST, orgBind, getEM());
755   Expr simpBindList(RAW_LIST, simpBind, getEM());
756 
757 //   if(orgBindList != simpBindList){
758 //     cout<<"debugerror" << endl;
759 //     cout<< "-orgBind " << vectorExpr2string(orgBind) << endl;
760 //     cout<< "-simpBind " << vectorExpr2string(simpBind) << endl;
761 //   }
762 
763   vector<Expr> bind(simpBind);
764   Expr bind_expr(simpBindList);
765 
766 //   vector<Expr> bind(orgBind);
767 //   Expr bind_expr(orgBindList);
768 
769   TRACE("quant sendinst", "==add fact from= ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
770 
771   if (*d_useInstLCache){
772     const Expr& e = univ.getExpr();
773     ExprMap<CDMap<Expr,bool>*>::iterator iterCache = d_bindHistory.find(e);
774     if (iterCache != d_bindHistory.end()){
775       CDMap<Expr,bool>* cache = (*iterCache).second;
776       if(cache->find(bind_expr) != cache->end()){
777 	//	cout<<"return inst 1"<<endl;
778 	return ;
779       }
780       else{
781 	(*cache)[bind_expr] = true;
782       }
783     }
784     else{
785       CDMap<Expr,bool>* new_cache = new(true) CDMap<Expr,bool> (theoryCore()->getCM()->getCurrentContext());
786       (*new_cache)[bind_expr] = true;
787       d_bindHistory[e] = new_cache;
788     }
789   }
790 
791   if (*d_useInstGCache){
792     const Expr& e = univ.getExpr();
793     ExprMap<std::hash_map<Expr,bool>*>::iterator iterCache = d_bindGlobalHistory.find(e);
794     if (iterCache != d_bindGlobalHistory.end()){
795       std::hash_map<Expr,bool>* cache = (*iterCache).second;
796       if(cache->find(bind_expr) != cache->end()){
797 	//	cout<<"return inst 1"<<endl;
798 
799 	//	int gscore = theoryCore()->getQuantLevelForTerm(gterm);
800 	//	Theorem local_thm = d_rules->universalInst(univ, bind, gscore);
801 	/*
802 	if(!(simplifyExpr(local_thm.getExpr())).isTrue()){
803 	  cout<<"en?" <<endl;
804 	  TRACE("quant sendinst", "==add fact simp =", simplifyExpr(local_thm.getExpr()), "");
805 	  TRACE("quant sendinst", "==add fact org =", local_thm.getExpr(), "");
806 	  TRACE("quant sendinst", "==add fact from= ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
807 	  TRACE("quant sendinst", "== end === ", "=========", "============");
808 	  }
809 	*/
810 	d_allInstCount2++;
811 	return ;
812       }
813       /*
814       else{
815 	(*cache)[bind_expr] = true;
816 
817 	d_allInstCount2++;
818       }
819     }
820     else{
821       std::hash_map<Expr,bool>* new_cache = new std::hash_map<Expr,bool> ;
822       (*new_cache)[bind_expr] = true;
823       d_bindGlobalHistory[e] = new_cache;
824       d_allInstCount2++;
825       */
826     }
827   }
828 
829   Theorem thm ;
830 
831   if (*d_useInstThmCache){
832     const Expr& e = univ.getExpr();
833     ExprMap<std::hash_map<Expr,Theorem>* >::iterator iterCache = d_bindGlobalThmHistory.find(e);
834     if (iterCache != d_bindGlobalThmHistory.end()){
835       std::hash_map<Expr,Theorem>* cache = (*iterCache).second;
836       std::hash_map<Expr,Theorem>::iterator thm_iter = cache->find(bind_expr);
837 
838       if(thm_iter != cache->end()){
839 	thm = thm_iter->second;
840       }
841       else{
842 	{
843 	  if(null_expr == gterm ){//it is from naive instantiation or multi-inst
844 	    TRACE("sendinst","gterm",gterm,"");
845 	    if(partInst) {
846 	      thm = d_rules->partialUniversalInst(univ, bind, 0);
847 	    }
848 	    else{
849 	      //	      thm = d_rules->universalInst(univ, bind, 0);
850 	      thm = d_rules->universalInst(univ, bind, 0, gterm);
851 	    }
852 	  }
853 	  else{
854 	    int gscore = theoryCore()->getQuantLevelForTerm(gterm);
855 	    if(partInst) {
856 	      thm = d_rules->partialUniversalInst(univ, bind, gscore);
857 	    }
858 	    else{
859 	      //	      thm = d_rules->universalInst(univ, bind, gscore);
860 	      thm = d_rules->universalInst(univ, bind, gscore, gterm);
861 	    }
862 	  }
863 	}
864 
865 	(*cache)[bind_expr] = thm;
866 	d_allInstCount2++;
867       }
868     }
869     else{
870       {
871 	if(null_expr == gterm ){//it is from naive instantiation or multi-inst
872 	  TRACE("sendinst","gterm",gterm,"");
873 	  if(partInst) {
874 	    thm = d_rules->partialUniversalInst(univ, bind, 0);
875 	  }
876 	  else{
877 	    //	    thm = d_rules->universalInst(univ, bind, 0);
878 	    thm = d_rules->universalInst(univ, bind, 0, gterm);
879 	  }
880 	}
881 	else{
882 	  int gscore = theoryCore()->getQuantLevelForTerm(gterm);
883 	  if(partInst) {
884 	    thm = d_rules->partialUniversalInst(univ, bind, gscore);
885 	  }
886 	  else{
887 	    //	    thm = d_rules->universalInst(univ, bind, gscore);
888 	    thm = d_rules->universalInst(univ, bind, gscore, gterm);
889 	  }
890 	}
891       }
892 
893       std::hash_map<Expr,Theorem>* new_cache = new std::hash_map<Expr,Theorem> ;
894       (*new_cache)[bind_expr] = thm;
895       d_bindGlobalThmHistory[e] = new_cache;
896       d_allInstCount2++;
897     }
898   }
899   else{
900     if(null_expr == gterm ){//it is from naive instantiation or multi-inst
901       TRACE("sendinst","gterm",gterm,"");
902       if(partInst) {
903 	thm = d_rules->partialUniversalInst(univ, bind, 0);
904       }
905       else{
906 	//thm = d_rules->universalInst(univ, bind, 0);
907 	thm = d_rules->universalInst(univ, bind, 0, gterm);
908       }
909     }
910     else{
911       int gscore = theoryCore()->getQuantLevelForTerm(gterm);
912             /*
913 	if(gscore > max_score){
914 	max_score = gscore;
915 	cout<<"max score "<<max_score<<endl;
916 	}
917       */
918       if(partInst) {
919 	thm = d_rules->partialUniversalInst(univ, bind, gscore);
920       }
921       else{
922 	//	thm = d_rules->universalInst(univ, bind, gscore);
923 	thm = d_rules->universalInst(univ, bind, gscore, gterm);
924       }
925     }
926   }
927 
928   d_totalInstCount++;
929   d_totalThmCount[thm.getExpr()]++;
930   Theorem simpThm = simplify(thm.getExpr());
931 
932   if(*d_useInstTrue){
933     Expr res = simpThm.getRHS();
934     if(res.isTrue()){
935       d_trueInstCount++;
936 
937 //        cout<<"return because true"<<endl;
938 //        cout<<"true thm expr: " <<thm.getExpr()<<endl;
939 //        cout<<"true thm: " <<thm<<endl;
940 
941 //        cout<<"return inst 2"<<endl;
942       return;
943     }
944     if(res.isFalse() ){
945       d_thmCount[thm.getExpr()]++;
946       //      if(*d_useGFact || d_totalThmCount[thm.getExpr()] > *d_gfactLimit ){
947 
948       if(*d_useGFact || d_thmCount[thm.getExpr()] > *d_gfactLimit ){
949 
950 	//      if(*d_useGFact){
951 	//	addGlobalLemma(thm, -1);
952 	enqueueFact(thm);
953       }
954       else{
955 	enqueueFact(thm);
956       }
957       //      enqueueSE(thm);
958       //
959       //      setInconsistent(simpThm);
960       d_allInstCount++;
961       d_instThisRound++;
962       //      cout<<"false found 2"<<endl;
963       /*
964       if (*d_useInstGCache){
965 	sendInstNew();
966       }
967       */
968       //      cout<<"return inst 3"<<endl;
969       throw FOUND_FALSE;
970     }
971   }
972 
973   d_simplifiedThmQueue.push(thm);
974   d_gUnivQueue.push(univ);
975   d_gBindQueue.push(bind_expr);
976 
977   //  cout<<"enqueue inst"<<thm << endl;
978   TRACE("quant sendinst", "=gterm: ",gterm, "");
979   /*
980   if(true || 0 == theoryCore()->getQuantLevelForTerm(gterm)){
981     cout<<"gterm" << gterm <<endl;;
982     cout<<"IL=== "<<theoryCore()->getQuantLevelForTerm(gterm)<<endl;;
983   }
984   */
985 
986   //  cout << "gterm: " <<  gterm << endl;
987   TRACE("quant sendinst", "= add fact simp: ", simplifyExpr(thm.getExpr()), "");
988   TRACE("quant sendinst", "= add fact org: ", thm.getExpr(), "");
989   TRACE("quant sendinst", "= add fact from:  ", univ.getExpr(), "\n===: "+vectorExpr2string(bind));
990   TRACE("quant sendinst", "= end === ", "=========", "============");
991 }
992 
993 
enqueueInst(const Theorem & univ,Trigger & trig,const std::vector<Expr> & binds,const Expr & gterm)994 void TheoryQuant::enqueueInst(const Theorem& univ, Trigger& trig,  const std::vector<Expr>& binds,  const Expr& gterm) {
995   return enqueueInst(univ,binds,gterm);
996 }
997 
sendInstNew()998 int TheoryQuant::sendInstNew(){
999   int resNum = 0 ;
1000 
1001   while(!d_simplifiedThmQueue.empty()){
1002     const Theorem thm = d_simplifiedThmQueue.front();
1003     d_simplifiedThmQueue.pop();
1004 
1005     d_allInstCount++;
1006     d_instThisRound++;
1007     resNum++;
1008     if (*d_useInstGCache){
1009       const Theorem & univ = d_gUnivQueue.front();
1010       const Expr & bind = d_gBindQueue.front();
1011 
1012       const Expr& e = univ.getExpr();
1013       ExprMap<std::hash_map<Expr,bool>*>::iterator iterCache = d_bindGlobalHistory.find(e);
1014       if (iterCache != d_bindGlobalHistory.end()){
1015 	std::hash_map<Expr,bool>* cache = (*iterCache).second;
1016 	(*cache)[bind] = true;
1017       }
1018       else{
1019 	std::hash_map<Expr,bool>* new_cache = new std::hash_map<Expr,bool> ;
1020 	(*new_cache)[bind] = true;
1021 	d_bindGlobalHistory[e] = new_cache;
1022       }
1023     }
1024     d_thmCount[thm.getExpr()]++;
1025     //    if(*d_useGFact || d_totalThmCount[thm.getExpr()] > *d_gfactLimit ){
1026     if(*d_useGFact || d_thmCount[thm.getExpr()] > *d_gfactLimit ){
1027       //      addGlobalLemma(thm, -1);
1028       enqueueFact(thm);
1029     }
1030     else{
1031       enqueueFact(thm);
1032     }
1033     //    enqueueSE(thm);
1034     //
1035   }
1036 
1037   return resNum;
1038 }
1039 
addNotify(const Expr & e)1040 void TheoryQuant::addNotify(const Expr& e){}
1041 
recursiveExprScore(const Expr & e)1042 int recursiveExprScore(const Expr& e) {
1043   int res=0;
1044   DebugAssert(!(e.isClosure()), "exprScore called on closure");
1045 
1046   if(e.arity()== 0){
1047     res = 0;
1048   }
1049   else{
1050     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)  {
1051       res += recursiveExprScore(*i);
1052     }
1053   }
1054   res++;
1055   return res;
1056 }
1057 
1058 
exprScore(const Expr & e)1059 int exprScore(const Expr& e){
1060   return recursiveExprScore(e);
1061 }
1062 
getHeadExpr(const Expr & e)1063 Expr TheoryQuant::getHeadExpr(const Expr& e){
1064   if (e.getKind() == APPLY){
1065     return e.getOp().getExpr();
1066   }
1067 
1068   if ( READ == e.getKind() ){
1069     return defaultReadExpr;
1070   }
1071   if ( WRITE == e.getKind() ){
1072     return defaultWriteExpr;
1073   }
1074   if (isPlus(e)){
1075     return defaultPlusExpr;
1076   }
1077   if (isMinus(e)){
1078     return defaultMinusExpr;
1079   }
1080   if (isMult(e)){
1081     return defaultMultExpr;
1082   }
1083   if (isDivide(e)){
1084     return defaultDivideExpr;
1085   }
1086   if (isPow(e)){
1087     return defaultPowExpr;
1088   }
1089 
1090 //   if ( READ == e.getKind() || WRITE == e.getKind() )  {
1091 //     int kind = e[0].getKind();
1092 //     if (UCONST==kind) {
1093 //       return e[0];
1094 //     }
1095 //     else if (APPLY==kind || UFUNC == kind || READ == kind || WRITE == kind){
1096 //       return getHeadExpr(e[0]);
1097 //     }
1098 //     else if(e[0].isSkolem()){
1099 //       return e[0];
1100 //     }
1101 //   }
1102 
1103   return null_expr;
1104 }
1105 
getHead(const Expr & e)1106 Expr  TheoryQuant::getHead(const Expr& e) {
1107   return getHeadExpr(e);
1108 }
1109 
1110 //! get the bound vars in term e,
recursiveGetBoundVars(const Expr & e,std::set<Expr> & result)1111 static bool recursiveGetBoundVars(const Expr& e, std::set<Expr>& result) {
1112   bool res(false);
1113   if(e.getFlag()){
1114     return e.containsBoundVar();
1115   }
1116   else if(e.isClosure()){
1117     res = recursiveGetBoundVars(e.getBody(),result);
1118   }
1119   else if (BOUND_VAR == e.getKind() ){
1120     result.insert(e);
1121     e.setContainsBoundVar();
1122     res = true;
1123   }
1124   else {
1125     res = false;
1126     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i){
1127       if(recursiveGetBoundVars(*i,result)){
1128 	res = true;
1129       }
1130     }
1131   }
1132 
1133   e.setFlag();
1134 
1135   if(res) {
1136     e.setContainsBoundVar();
1137   }
1138 
1139   return res;
1140 }
1141 
1142 
1143 //! get bound vars in term e,
getBoundVars(const Expr & e)1144 std::set<Expr>  getBoundVars(const Expr& e){
1145 
1146   //  static ExprMap<std::set<Expr> > bvsCache;
1147 
1148   //  static std::map<Expr, std::set<Expr> > bvsCache;
1149   //  std::map<Expr, std::set<Expr> >::iterator iterCache = bvsCache.find(e);
1150 
1151   //ExprMap<std::set<Expr> >::iterator iterCache = bvsCache.find(e);
1152 
1153   //  if (iterCache != bvsCache.end()){
1154   //    //    return iterCache->second;
1155   //    return (*iterCache).second;
1156   //  }
1157 
1158   e.clearFlags();
1159   std::set<Expr> result ;
1160   recursiveGetBoundVars(e,result);
1161   e.clearFlags();
1162   //  bvsCache[e]=result;
1163   return  result;
1164 }
1165 
findPolarity(const Expr & e,ExprMap<Polarity> & res,Polarity pol)1166 void findPolarity(const Expr& e, ExprMap<Polarity>& res, Polarity  pol){
1167   if(!e.getType().isBool()) return;
1168   //now a AND b will be given a polarity too, this is not necessary.
1169   if(res.count(e)>0){
1170     if ((Neg == res[e] && Pos == pol) || (Neg == res[e] && Pos == pol) ){
1171       res[e]=PosNeg;
1172     }
1173   }
1174   else{
1175     res[e]=pol;
1176   }
1177 
1178   TRACE("find-polarity", e, "has ", (int)pol);
1179 
1180   if(PosNeg==pol){
1181     for(int i=0; i<e.arity(); i++){
1182       findPolarity(e[i], res, pol);
1183     }
1184   }
1185   else{
1186     Polarity neg_pol=Ukn;
1187     if(Pos == pol) {
1188       neg_pol = Neg;
1189     }
1190     else if(Neg == pol){
1191       neg_pol = Pos;
1192     }
1193 
1194     if(e.isImpl()){
1195       findPolarity(e[0], res, neg_pol);
1196       findPolarity(e[1], res, pol);
1197     }
1198     else if(e.isAnd() || e.isOr()){
1199       for(int i=0; i<e.arity(); i++){
1200 	findPolarity(e[i], res, pol);
1201       }
1202     }
1203     else if(e.isNot()){
1204       findPolarity(e[0], res, neg_pol);
1205     }
1206     else if(e.isITE()){
1207       findPolarity(e[0], res, PosNeg);
1208       findPolarity(e[1], res, pol);
1209       findPolarity(e[2], res, pol);
1210     }
1211     else if(e.isClosure()){
1212       findPolarity(e.getBody(), res, pol);
1213     }
1214     else if(e.isIff()){
1215       findPolarity(e[0], res, PosNeg);
1216       findPolarity(e[1], res, PosNeg);
1217     }
1218     else if(e.isXor()){
1219       findPolarity(e[0], res, neg_pol);
1220       findPolarity(e[1], res, neg_pol);
1221     }
1222     else if(e.isAtomicFormula()){
1223       return;
1224     }
1225     else{
1226       //      DebugAssert(false, "Error in find polarity in "+e.toString());
1227     }
1228   }
1229 }
1230 
isUniterpFunc(const Expr & e)1231 bool isUniterpFunc(const Expr & e){
1232   if ( e.isApply() && e.getOpKind() == UFUNC){
1233     return true;
1234   }
1235   return false;
1236 }
1237 //   if (e.getKind() == READ || e.getKind() == WRITE){
1238 //     return true;
1239 //   }
1240 //   return false;
1241 // }
1242 
isGround(const Expr & e)1243 bool isGround(const Expr& e){
1244   //be careful, this function must be called after some calls to getBoundVar() because containsBoundVar() will be set only in getBoundVar() method.
1245   //if e contains a closed quantifier, e is not ground.
1246   return ! e.containsBoundVar();
1247 }
1248 
pullVarOut(const Expr & thm_expr)1249 Expr CompleteInstPreProcessor::pullVarOut(const Expr& thm_expr){
1250 
1251   const Expr outBody = thm_expr.getBody();
1252 
1253 //   if(((outBody.isAnd() && outBody[1].isForall()) ||
1254 //        (outBody.isImpl() && outBody[1].isForall()) ||
1255 //        (outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists()) )){
1256 //     return t1;
1257 //   }
1258 
1259   if (thm_expr.isForall()){
1260     if((outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists())){
1261 
1262       vector<Expr> bVarsOut = thm_expr.getVars();
1263 
1264       const Expr innerExists =outBody[0][1];
1265       const Expr innerBody = innerExists.getBody();
1266       vector<Expr> bVarsIn = innerExists.getVars();
1267 
1268       for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){
1269 	bVarsOut.push_back(*i);
1270       }
1271 
1272       Expr newbody;
1273 
1274       newbody=(outBody[0][0].notExpr()).orExpr(innerBody.notExpr());
1275 
1276       Expr newQuantExpr;
1277       newQuantExpr = d_theoryCore->getEM()->newClosureExpr(FORALL, bVarsOut, newbody);
1278 
1279       return newQuantExpr ;
1280     }
1281 
1282     else if ((outBody.isAnd() && outBody[1].isForall()) ||
1283 	     (outBody.isImpl() && outBody[1].isForall())){
1284 
1285       vector<Expr> bVarsOut = thm_expr.getVars();
1286 
1287       const Expr innerForall=outBody[1];
1288       const Expr innerBody = innerForall.getBody();
1289       vector<Expr> bVarsIn = innerForall.getVars();
1290 
1291       for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){
1292 	bVarsOut.push_back(*i);
1293       }
1294 
1295 
1296       Expr newbody;
1297       if(outBody.isAnd()){
1298 	newbody=outBody[0].andExpr(innerBody);
1299       }
1300       else if(outBody.isImpl()){
1301 	newbody=outBody[0].impExpr(innerBody);
1302       }
1303 
1304       Expr newQuantExpr;
1305       newQuantExpr = d_theoryCore->getEM()->newClosureExpr(FORALL, bVarsOut, newbody);
1306 
1307       return(newQuantExpr);
1308     }
1309     return thm_expr; // case cannot be handled now.
1310   }
1311 
1312   else if (thm_expr.isExists()){
1313     if ((outBody.isAnd() && outBody[1].isExists()) ||
1314 	(outBody.isImpl() && outBody[1].isExists())){
1315 
1316       vector<Expr> bVarsOut = thm_expr.getVars();
1317 
1318       const Expr innerExists = outBody[1];
1319       const Expr innerBody = innerExists.getBody();
1320       vector<Expr> bVarsIn = innerExists.getVars();
1321 
1322       for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){
1323 	bVarsOut.push_back(*i);
1324       }
1325 
1326       Expr newbody;
1327       if(outBody.isAnd()){
1328 	newbody=outBody[0].andExpr(innerBody);
1329       }
1330       else if(outBody.isImpl()){
1331 	newbody=outBody[0].impExpr(innerBody);
1332       }
1333 
1334       Expr newQuantExpr;
1335       newQuantExpr = d_theoryCore->getEM()->newClosureExpr(EXISTS, bVarsOut, newbody);
1336 
1337       return newQuantExpr;
1338     }
1339   }
1340   return thm_expr;
1341 }
1342 
1343 
CompleteInstPreProcessor(TheoryCore * core,QuantProofRules * quant_rule)1344 CompleteInstPreProcessor::CompleteInstPreProcessor(TheoryCore * core, QuantProofRules* quant_rule):
1345   d_theoryCore(core),
1346   d_quant_rules(quant_rule)
1347 {}
1348 
1349 // collect all uninterpreted pedidates in assert
collectHeads(const Expr & assert,set<Expr> & heads)1350 void CompleteInstPreProcessor::collectHeads(const Expr& assert, set<Expr>& heads){
1351   if ( ! assert.getType().isBool()){
1352     return;
1353   }
1354   else if ( ! assert.isAbsAtomicFormula()){
1355     for (int i = 0 ; i < assert.arity(); i++){
1356       collectHeads(assert[i], heads);
1357     }
1358     return;
1359   }
1360   else if (assert.isClosure()){
1361     collectHeads(assert.getBody(), heads);
1362   }
1363   else if (assert.isAtomicFormula()){
1364     if (isUniterpFunc(assert)){
1365       heads.insert(assert.getOp().getExpr());
1366     }
1367   }
1368   else{
1369     //    cout << " error in collect heads" << endl;
1370   }
1371 }
1372 
isMacro(const Expr & assert)1373 bool CompleteInstPreProcessor::isMacro(const Expr& assert){
1374   if (d_is_macro_def.count(assert) > 0 ) {
1375     return true;
1376   }
1377 
1378   if (assert.isForall()){
1379     Expr body = assert.getBody();
1380     if (body.isIff()){
1381       Expr right = body[0];
1382       Expr left = body[1];
1383       if ((isUniterpFunc(right) && left.isForall())
1384 	  || (right.isForall() && isUniterpFunc(left) )){
1385 	    Expr macro_lhs ;
1386 	    Expr macro_def;
1387 	    if (isUniterpFunc(right)){
1388 	      macro_lhs = right;
1389 	      macro_def = left;
1390 	    }
1391 	    else{
1392 	      macro_lhs = left;
1393 	      macro_def = right;
1394 	    }
1395 
1396 	    Expr test_def_exists = d_theoryCore->getEM()->newClosureExpr(EXISTS, assert.getVars(), macro_def);
1397 
1398 	    Expr test_def_sko = d_theoryCore->getCommonRules()->skolemize(test_def_exists);
1399 
1400 	    if (isGoodQuant(test_def_sko)){
1401 	      Expr macro_head = macro_lhs.getOp().getExpr();
1402 	      set<Expr> heads_set;
1403 	      collectHeads(macro_def, heads_set);
1404 	      if (heads_set.count(macro_head) <= 0 ){
1405 		d_is_macro_def[assert] = true;
1406 		d_macro_quant[macro_head] = assert;
1407 		d_macro_def[macro_head] = macro_def;
1408 		d_macro_lhs[macro_head] = macro_lhs;
1409 		return true;
1410 	      }
1411 	    }
1412 	    else {
1413 	      //     cout << "NOT good DEF" << def<< endl;
1414 	    }
1415       }
1416     }
1417   }
1418   return false;
1419 }
1420 
hasMacros(const vector<Expr> & asserts)1421 bool CompleteInstPreProcessor::hasMacros(const vector<Expr>& asserts){
1422   bool has_macros = false;
1423   for (size_t i = 0 ; i < asserts.size(); i++){
1424     if (isMacro(asserts[i])){
1425       has_macros = true;
1426     }
1427   }
1428   return has_macros;
1429 }
1430 
1431 
substMacro(const Expr & old)1432 Expr CompleteInstPreProcessor::substMacro(const Expr& old){
1433   Expr head = old.getOp().getExpr();
1434 
1435   DebugAssert(d_macro_lhs.count(head)>0, "macro lhs not found");
1436   DebugAssert(d_macro_def.count(head)>0, "macro def not found");
1437   DebugAssert(d_macro_quant.count(head)>0, "macro quant not found");
1438 
1439   Expr macro_lhs = d_macro_lhs[head];
1440   Expr macro_def = d_macro_def[head];
1441   Expr macro_quant = d_macro_quant[head];
1442 
1443   DebugAssert(head == macro_lhs.getOp().getExpr(), "impossible in substMacro");
1444 
1445   ExprMap<Expr> binding;
1446   for (int i = 0; i < macro_lhs.arity(); i++){
1447     if (macro_lhs[i].isBoundVar()){
1448       binding[macro_lhs[i]] = old[i];
1449     }
1450   }
1451 
1452   vector<Expr> quant_vars = macro_quant.getVars();
1453 
1454   vector<Expr> gterms;
1455   for (size_t i = 0 ; i < binding.size(); i++){
1456     gterms.push_back(binding[quant_vars[i]]);
1457   }
1458 
1459   return macro_def.substExpr(quant_vars,gterms);
1460 }
1461 
simplifyEq(const Expr & assert)1462 Expr CompleteInstPreProcessor::simplifyEq(const Expr& assert){
1463   if ( ! assert.getType().isBool()){
1464     return assert;
1465   }
1466   else if ( ! assert.isAbsAtomicFormula()){
1467     vector<Expr> children ;
1468     for (int i = 0 ; i < assert.arity(); i++){
1469       children.push_back(simplifyEq(assert[i]));
1470     }
1471     return Expr(assert.getOp(),children);
1472   }
1473   else if (assert.isClosure()){
1474     Expr new_body = simplifyEq(assert.getBody());
1475     if (assert.isForall()){
1476       d_theoryCore->getEM()->newClosureExpr(FORALL, assert.getVars(), new_body);
1477     }
1478     else if (assert.isExists()){
1479       d_theoryCore->getEM()->newClosureExpr(EXISTS, assert.getVars(), new_body);
1480     }
1481     else{
1482       DebugAssert(false, "impossible case in recInstMacros");
1483     }
1484   }
1485   else if (assert.isAtomicFormula()){
1486     if (assert.isEq() && assert[0] == assert[1]){
1487       return d_theoryCore->trueExpr();
1488     }
1489     else {
1490       return assert;
1491     }
1492   }
1493   cout <<assert<<endl;
1494   DebugAssert(false, "impossible case in simplifyEq");
1495   return assert;
1496 }
1497 
1498 
recInstMacros(const Expr & assert)1499 Expr CompleteInstPreProcessor::recInstMacros(const Expr& assert){
1500   if ( ! assert.getType().isBool()){
1501     return assert;
1502   }
1503   else if ( ! assert.isAbsAtomicFormula()){
1504     vector<Expr> children ;
1505     for (int i = 0 ; i < assert.arity(); i++){
1506       children.push_back(recInstMacros(assert[i]));
1507     }
1508     return Expr(assert.getOp(),children);
1509   }
1510   else if (assert.isClosure()){
1511     Expr new_body = recInstMacros(assert.getBody());
1512     if (assert.isForall()){
1513       d_theoryCore->getEM()->newClosureExpr(FORALL, assert.getVars(), new_body);
1514     }
1515     else if (assert.isExists()){
1516       d_theoryCore->getEM()->newClosureExpr(EXISTS, assert.getVars(), new_body);
1517     }
1518     else{
1519       DebugAssert(false, "impossible case in recInstMacros");
1520     }
1521   }
1522   else if (assert.isAtomicFormula()){
1523 
1524     if (isUniterpFunc(assert)){
1525       Expr assert_op = assert.getOp().getExpr();
1526       if ( d_macro_def.count(assert_op) > 0 ){
1527 	return substMacro(assert);
1528       }
1529       else{
1530 	return assert;
1531       }
1532     }
1533     else {
1534       return assert;
1535     }
1536   }
1537 
1538   DebugAssert(false, "impossible case in recInstMacors");
1539   return assert;
1540 
1541 }
1542 
1543 // if assert is a macro quant, then replace it with macro_quant_sub
instMacros(const Expr & assert,const Expr macro_quant_sub)1544 Expr CompleteInstPreProcessor::instMacros(const Expr& assert, const Expr macro_quant_sub ){
1545 
1546   if (isMacro(assert)){
1547     return macro_quant_sub;
1548   }
1549 
1550   return recInstMacros(assert);
1551 }
1552 
1553 
hasShieldVar(const Expr & e)1554 bool CompleteInstPreProcessor::hasShieldVar(const Expr& e){
1555   if (isUniterpFunc(e) && e.arity() > 0 ){
1556     for (int i = 0; i<e.arity(); i++){
1557       if (e[i].isBoundVar() ){
1558 	return true;
1559       }
1560     }
1561   }
1562   else if (e.getKind() == READ || e.getKind() == WRITE){
1563     return (hasShieldVar(e[0]) || e[1].isBoundVar());
1564   }
1565   else if (e.arity() > 0 ){
1566     for (int i = 0; i<e.arity(); i++){
1567       if (hasShieldVar(e[i])){
1568 	return true;
1569       }
1570     }
1571   }
1572   return false;
1573 }
1574 
1575 
1576 //if bound vars only appear as argument of uninterpreted function/predidate and array reads/writes.
isShield(const Expr & e)1577 bool CompleteInstPreProcessor::isShield(const Expr& e){
1578   if (isGround(e)){
1579     return true;
1580   }
1581   else if (isUniterpFunc(e) && e.arity() > 0 ){
1582     for (int i = 0; i<e.arity(); i++){
1583       //      if ( ! ( isShield(e[i]) || e[i].isBoundVar())){
1584       if ( e[i].containsBoundVar() &&  ( ! e[i].isBoundVar() )){ //no nested
1585 	return false;
1586       }
1587     }
1588     return true;
1589   }
1590   else if (e.getKind() == READ){
1591     if ( isShield(e[0])
1592 	 //	 && (e[1].isBoundVar()  || isShield(e[1])){
1593 	 && (e[1].isBoundVar() || isGround(e[1]))){
1594       return true;
1595     }
1596     else {
1597       return false;
1598     }
1599   }
1600   else if (e.getKind() == WRITE){
1601     if ( isShield( e[0] )
1602       //	 && (e[1].isBoundVar() || isShield(e[1]))
1603 	 && (e[1].isBoundVar() || isGround( e[1] ))
1604 	 && ( isGround( e[2] ))){
1605       return true;
1606     }
1607     else {
1608       return false;
1609     }
1610   }
1611   else if (e.arity() > 0 ){
1612     for (int i = 0; i<e.arity(); i++){
1613       if (!isShield(e[i])){
1614 	return false;
1615       }
1616     }
1617     return true;
1618   }
1619   else if (e.arity () == 0){
1620     return true;
1621   }
1622   DebugAssert(false, "impossible case in isShield");
1623   return false;
1624 }
1625 
findPolarityAtomic(const Expr & e,ExprMap<Polarity> & res,Polarity pol)1626 void findPolarityAtomic(const Expr& e, ExprMap<Polarity>& res, Polarity  pol){
1627   if(!e.getType().isBool()) return;
1628   //now a AND b will be given a polarity too, this is not necessary.
1629   if(res.count(e)>0){
1630     if ((Neg == res[e] && Pos == pol) || (Neg == res[e] && Pos == pol) ){
1631       res[e]=PosNeg;
1632     }
1633   }
1634   else{
1635     res[e]=pol;
1636   }
1637 
1638   //  cout <<"finding " << e << endl;
1639 
1640   if(PosNeg == pol){
1641     for(int i=0; i<e.arity(); i++){
1642       findPolarityAtomic(e[i], res, pol);
1643     }
1644   }
1645   else{
1646     Polarity neg_pol=Ukn;
1647     if(Pos == pol) {
1648       neg_pol = Neg;
1649     }
1650     else if(Neg == pol){
1651       neg_pol = Pos;
1652     }
1653 
1654     if(e.isImpl()){
1655       findPolarityAtomic(e[0], res, neg_pol);
1656       findPolarityAtomic(e[1], res, pol);
1657     }
1658     else if(e.isAnd() || e.isOr()){
1659       for(int i=0; i<e.arity(); i++){
1660 	findPolarityAtomic(e[i], res, pol);
1661       }
1662     }
1663     else if(e.isNot()){
1664       findPolarityAtomic(e[0], res, neg_pol);
1665     }
1666     else if(e.isITE()){
1667       findPolarityAtomic(e[0], res, PosNeg);
1668       findPolarityAtomic(e[1], res, pol);
1669       findPolarityAtomic(e[2], res, pol);
1670     }
1671     else if(e.isClosure()){
1672       //      cout << " found closure " << endl;
1673       //      cout << e << endl;
1674       //findPolarityAtomic(e.getBody(), res, pol);
1675     }
1676     else if(e.isIff()){
1677       findPolarityAtomic(e[0], res, PosNeg);
1678       findPolarityAtomic(e[1], res, PosNeg);
1679     }
1680     else if(e.isXor()){
1681       findPolarityAtomic(e[0], res, neg_pol);
1682       findPolarityAtomic(e[1], res, neg_pol);
1683     }
1684     else if(e.isAtomicFormula()){
1685       return;
1686     }
1687     else{
1688       DebugAssert(false, "Error in find polarity in "+e.toString());
1689     }
1690   }
1691 }
1692 
recSkolemize(const Expr & e,ExprMap<Polarity> & pol_map)1693 Expr CompleteInstPreProcessor::recSkolemize(const Expr& e, ExprMap<Polarity>& pol_map){
1694 
1695   if ( ! e.getType().isBool()){
1696     return e;
1697   }
1698   else if (e.isClosure()){
1699     if (e.isForall()) {
1700       return e;
1701     }
1702     else if (e.isExists() && Pos == pol_map[e]){
1703       Expr new_body = recSkolemize(e.getBody(), pol_map);
1704       Expr new_quant = d_theoryCore->getEM()->newClosureExpr(EXISTS, e.getVars(), new_body);
1705       return d_theoryCore->getCommonRules()->skolemize(new_quant);
1706     }
1707   }
1708   else if (e.arity() > 0 ) {
1709     vector<Expr> children;
1710     for (int i = 0 ; i < e.arity(); i++){
1711       Expr new_child = recSkolemize(e[i], pol_map);
1712       if (new_child.isNot() && new_child[0].isNot()){
1713 	children.push_back(new_child[0][0]); //(not not expr) --> expr
1714       }
1715       else{
1716 	children.push_back(new_child);
1717       }
1718     }
1719     Expr new_expr = Expr(e.getOp(), children);
1720     if (new_expr.isNot() && new_expr[0].isNot()){
1721       return new_expr[0][0];
1722     }
1723     else {
1724       return new_expr;
1725     }
1726   }
1727 
1728   return e;
1729 }
1730 
simplifyQuant(const Expr & e)1731 Expr CompleteInstPreProcessor::simplifyQuant(const Expr& e){
1732   //put all quant into postive form
1733   Expr pos_expr = rewriteNot(e);
1734   TRACE("simp-quant", e , "\n ---rewriteNot---> \n", pos_expr);
1735 
1736   Expr next_expr;
1737   if(e.isForall()){
1738     Theorem atoa = d_theoryCore->getCommonRules()->assumpRule(pos_expr);
1739     Theorem packVarThm = d_quant_rules->packVar(atoa);
1740     next_expr = packVarThm.getExpr();
1741   }
1742   else{
1743     next_expr = pos_expr;
1744   }
1745   //skolemize all postive exists, because we only care for satisfiablility now.
1746   ExprMap<Polarity> pol_map;
1747   //  findPolarity(pos_expr, pol_map, Pos);
1748   findPolarity(next_expr, pol_map, Pos);
1749   //  Expr ret = recSkolemize(pos_expr, pol_map);
1750   Expr ret = recSkolemize(next_expr, pol_map);
1751   TRACE("simp-quant", e , "\n ---skolemize---> \n", ret);
1752   return ret;
1753 }
1754 
1755 
rewriteNot(const Expr & e)1756 Expr CompleteInstPreProcessor::rewriteNot(const Expr& e){
1757   ExprMap<Polarity> pol_map;
1758   findPolarity(e, pol_map, Pos);
1759   set<Expr> t = getBoundVars(e); //set containsBoundVar flag
1760   return recRewriteNot(e, pol_map);
1761 }
1762 
recRewriteNot(const Expr & e,ExprMap<Polarity> & pol_map)1763 Expr CompleteInstPreProcessor::recRewriteNot(const Expr & e,  ExprMap<Polarity>& pol_map){
1764   if ( ! e.getType().isBool()){
1765     return e;
1766   }
1767 
1768   if (isGround(e)){
1769     return e;
1770   }
1771 
1772   if (e.isClosure()){
1773     DebugAssert(pol_map.find(e) != pol_map.end(), "cannot find polarity" );
1774     if ( Neg == pol_map[e]){
1775       Expr body = recRewriteNot(e.getBody(), pol_map);
1776       Expr new_body = body.notExpr();
1777       Kind new_kind = e.isForall() ? EXISTS : FORALL;
1778       Expr new_quant = d_theoryCore->getEM()->newClosureExpr(new_kind,e.getVars(),new_body);
1779       Expr new_expr = new_quant.notExpr();
1780       return new_expr;
1781     }
1782     else {
1783       //it is too much to deal with the case PosNeg == pol_map[e]
1784       //becasue PosNeg will be introduced for IFF and IF,
1785       return e;
1786     }
1787   }
1788   else if (e.arity() > 0 ) {
1789     vector<Expr> children;
1790 
1791     for (int i = 0 ; i < e.arity(); i++){
1792       Expr new_child = recRewriteNot(e[i], pol_map);
1793       if (new_child.isNot() && new_child[0].isNot()){
1794 	children.push_back(new_child[0][0]); //(not not expr) --> expr
1795       }
1796       else{
1797 	children.push_back(new_child);
1798       }
1799     }
1800 
1801     Expr new_expr = Expr(e.getOp(), children);
1802     if (new_expr.isNot() && new_expr[0].isNot()){
1803       return new_expr[0][0];
1804     }
1805     else {
1806       return new_expr;
1807     }
1808   }
1809   else if (0 == e.arity() ){
1810     return e;
1811   }
1812 
1813   DebugAssert(false, "impossible in rewriteNot");
1814   return e;
1815 }
1816 
addIndex(const Expr & e)1817 void CompleteInstPreProcessor::addIndex(const Expr& e){
1818   if ( ! isInt(e.getType())) return;
1819   d_allIndex.insert(d_theoryCore->simplifyExpr(e));
1820 }
1821 
plusOne(const Expr & e)1822 Expr CompleteInstPreProcessor::plusOne(const Expr& e){
1823   Expr one = d_theoryCore->getEM()->newRatExpr(1);
1824   return Expr(PLUS, e, one);
1825 }
1826 
minusOne(const Expr & e)1827 Expr CompleteInstPreProcessor::minusOne(const Expr& e){
1828   Expr one = d_theoryCore->getEM()->newRatExpr(1);
1829   return Expr(MINUS, e, one);
1830 }
1831 
collect_shield_index(const Expr & e)1832 void CompleteInstPreProcessor::collect_shield_index(const Expr& e){
1833   if (isUniterpFunc(e) && e.arity() > 0 ){
1834     for (int i = 0; i<e.arity(); i++){
1835       if ( isGround(e[i])){
1836 	addIndex(e[i]);
1837       }
1838     }
1839   }
1840   else if (e.getKind() == READ){
1841     collect_shield_index(e[0]);
1842     if (isGround(e[1])){
1843       addIndex(e[1]);
1844     }
1845   }
1846   else if (e.getKind() == WRITE){
1847     collect_shield_index(e[0]);
1848     if ( isGround( e[1] )){
1849       addIndex(e[1]);
1850       addIndex(plusOne(e[1]));
1851       addIndex(minusOne(e[1]));
1852     }
1853   }
1854   else if (e.arity() > 0 ){
1855     for (int i = 0; i<e.arity(); i++){
1856       collect_shield_index(e[i]);
1857     }
1858   }
1859 }
1860 
collect_forall_index(const Expr & forall_quant)1861 void CompleteInstPreProcessor::collect_forall_index(const Expr& forall_quant){
1862   ExprMap<Polarity> cur_expr_pol;
1863   findPolarity(forall_quant, cur_expr_pol, Pos);
1864 
1865   for (ExprMap<Polarity>::iterator i = cur_expr_pol.begin(), iend = cur_expr_pol.end(); i != iend ; i++){
1866     Expr cur_expr = i->first;
1867     Polarity pol = i->second;
1868 
1869     if (isLE(cur_expr)){
1870       const Expr& left = cur_expr[0];
1871       const Expr& right = cur_expr[1];
1872       if (left.isBoundVar() && isGround(right)){
1873 	if (Pos == pol || PosNeg == pol){
1874 	  addIndex(plusOne(right));
1875 	}
1876 	if (Neg == pol || PosNeg == pol){
1877 	  addIndex(right);
1878 	}
1879       }
1880       else if (right.isBoundVar() && isGround(left)){
1881 	if (Pos == pol || PosNeg == pol){
1882 	  addIndex(plusOne(left));
1883 	}
1884 	if (Neg == pol || PosNeg == pol){
1885 	  addIndex(left);
1886 	}
1887       }
1888       else if (left.isBoundVar() && right.isBoundVar()){
1889 	//do nothing
1890       }
1891       //well, neither left nor right is a bound var.
1892       else if (isShield(left) && isShield(right)){
1893 	collect_shield_index(left);
1894 	collect_shield_index(right);
1895       }
1896       else{
1897 	cout << " foall is " << forall_quant << endl;
1898 	DebugAssert(false, "impossible case in collect index ");
1899       }
1900     }
1901     else if (cur_expr.isEq()){
1902       const Expr& left = cur_expr[0];
1903       const Expr& right = cur_expr[1];
1904       if (left.isBoundVar() && isGround(right)){
1905 	if (Pos == pol || PosNeg == pol){
1906 	  addIndex(minusOne(right));
1907 	  addIndex(plusOne(right));
1908 	}
1909 	if (Neg == pol || PosNeg == pol){
1910 	  addIndex(minusOne(right));
1911 	}
1912       }
1913       else if (right.isBoundVar() && isGround(left)){
1914 	if (Pos == pol || PosNeg == pol){
1915 	  addIndex(minusOne(left));
1916 	  addIndex(plusOne(left));
1917 	}
1918 	if (Neg == pol || PosNeg == pol){
1919 	  addIndex(left);
1920 	}
1921       }
1922       else if (left.isBoundVar() && right.isBoundVar()){
1923 	DebugAssert(false, "impossible case collect index");
1924       }
1925       //well, neither left nor right is a bound var.
1926       else if (isShield(left) && isShield(right)){
1927 	collect_shield_index(left);
1928 	collect_shield_index(right);
1929       }
1930       else{
1931 	DebugAssert(false, "impossible case in collect index");
1932       }
1933     }
1934     else if (isLT(cur_expr)){
1935       const Expr& left = cur_expr[0];
1936       const Expr& right = cur_expr[1];
1937       if (left.isBoundVar() && isGround(right)){
1938 	if (Pos == pol || PosNeg == pol){
1939 	  addIndex(plusOne(right));
1940 	}
1941 	if (Neg == pol || PosNeg == pol){
1942 	  addIndex(right);
1943 	}
1944       }
1945       else if (right.isBoundVar() && isGround(left)){
1946 	if (Pos == pol || PosNeg == pol){
1947 	  addIndex(plusOne(left));
1948 	}
1949 	if (Neg == pol || PosNeg == pol){
1950 	  addIndex(left);
1951 	}
1952       }
1953       else if (left.isBoundVar() && right.isBoundVar()){
1954 	//do nothing
1955       }
1956       //well, neither left nor right is a bound var.
1957       else if (isShield(left) && isShield(right)){
1958 	collect_shield_index(left);
1959 	collect_shield_index(right);
1960       }
1961       else{
1962 	DebugAssert(false,  "impossible case in collect index");
1963       }
1964     }
1965     else{
1966       collect_shield_index(cur_expr);
1967     }
1968   }
1969 }
1970 
1971 
collectIndex(const Expr & assert)1972 void CompleteInstPreProcessor::collectIndex(const Expr& assert){
1973   //  cout <<"BEGIN COLLECTING " << assert << endl;
1974   //must be called after isGoodForCompleteInst;
1975   if(isGround(assert)){
1976     collect_shield_index(assert);
1977     return;
1978   }
1979 
1980 
1981   ExprMap<Polarity> cur_expr_pol;
1982   findPolarityAtomic(assert, cur_expr_pol, Pos);
1983 
1984   for(ExprMap<Polarity>::iterator i = cur_expr_pol.begin(), iend = cur_expr_pol.end(); i != iend; i++) {
1985 
1986     const Expr& cur_expr = i->first;
1987     Polarity pol = i->second;
1988     //    cout <<"NOW COLLECTING " << cur_expr << endl;
1989     if (cur_expr.isAtomicFormula()){
1990       if (cur_expr.containsBoundVar()){
1991 	DebugAssert(false, "error in collecting ");
1992 	return;
1993       }
1994       collect_shield_index(cur_expr);
1995     }
1996     else if (cur_expr.isForall()){
1997       if (Pos != pol){
1998 	DebugAssert(false, "error in polarity ");
1999 	return;
2000       }
2001       Expr newQuant = pullVarOut(cur_expr);
2002       collect_forall_index(newQuant);
2003       //      cout <<"PUSH FORALL" << cur_expr << endl;
2004       d_quant_equiv_map[cur_expr] = newQuant;
2005     }
2006     else if (cur_expr.isExists()){
2007       if (Pos != pol){
2008 	DebugAssert(false, "error in polarity " );
2009 	return;
2010       }
2011       Expr newQuant = pullVarOut(cur_expr);
2012       Expr sko_expr = d_theoryCore->getCommonRules()->skolemize(newQuant);
2013       collect_forall_index(sko_expr);
2014       //      cout <<"PUSH EXISTS" << cur_expr << endl;
2015       d_quant_equiv_map[cur_expr] = sko_expr;
2016     }
2017   }
2018   return;
2019 }
2020 
2021 
isGood(const Expr & assert)2022 bool CompleteInstPreProcessor::isGood(const Expr& assert){
2023   //  cout << " in isgood " << assert << endl;
2024   const std::set<Expr>& bvs = getBoundVars(assert);
2025   if (bvs.size() <= 0 ) {
2026     //    d_gnd_cache.push_back(e);
2027     //    cout << " return in isgood because no bound vars" << assert << endl;
2028     return true; //this is a ground formula,
2029   }
2030 
2031   ExprMap<Polarity> cur_expr_pol;
2032   findPolarityAtomic(assert, cur_expr_pol, Pos);
2033 
2034   for(ExprMap<Polarity>::iterator i = cur_expr_pol.begin(),
2035 	iend = cur_expr_pol.end();
2036       i != iend; i++) {
2037 
2038     const Expr& cur_expr = i->first;
2039     Polarity pol = i->second;
2040 
2041     //    cout <<"isgood cur expr " << cur_expr << endl;
2042 
2043     if(cur_expr.isForall()) {
2044       if (Pos == pol){
2045 	if( isGoodQuant(cur_expr)){
2046 	  if ( ! hasShieldVar(cur_expr)) {
2047 	    return false;
2048 	  }
2049 	}
2050 	else{
2051 	  d_all_good = false;
2052 	  return false;
2053 	}
2054       }
2055       else {
2056 	DebugAssert(false, "error, Neg polarity in isGood ");
2057 	return false;
2058       }
2059     }
2060     else if (cur_expr.isExists()){
2061       DebugAssert(false, "error, found exists in is good");
2062       if (Neg == pol || PosNeg == pol){
2063 	DebugAssert(false, "error, neg polarity in isGood ");
2064 	return false;
2065       }
2066     }
2067   }
2068   return true;
2069 }
2070 
2071     //    if (cur_expr.isClosure()){
2072 
2073 //       if( Pos == pol){
2074 // 	Theorem newQuant;
2075 // 	newQuant = (d_rules->pullVarOut(d_rules->addNewConst(cur_expr))).getExpr();
2076 // 	if (cur_expr.isExists()){
2077 // 	  Expr t = getCommonRules()->skolemize(newQuant);
2078 // 	  d_quant_equiv_map[cur_expr] = t;
2079 // 	  d_gnd_cache.push_Back(t); //used later by isGoodQuant and collectIndex
2080 // 	}
2081 // 	else if (cur_expr.isForall()){
2082 
2083 // 	  if( isGoodQuantCompleteInst()){
2084 // 	    d_quant_equiv_map[cur_expr] = newQuant;
2085 // 	  }
2086 // 	  else{
2087 // 	    d_all_good = false;
2088 // 	    return false;
2089 // 	  }
2090 // 	}
2091 //       }
2092 //       else{
2093 // 	cout << "cannot deal with neg polarity now " << endl;
2094 //       }
2095 //     }
2096 //     else if (cur_expr.isAtomicFormula()){
2097 //       findPolarity(cur_expr, d_expr_pol, Pos); //used later by isGoodQuant and collectIndex
2098 //     }
2099 //   }
2100 //  return true;
2101 //}
2102 
isGoodQuant(const Expr & e)2103 bool CompleteInstPreProcessor::isGoodQuant(const Expr& e){
2104   //  cout << " test is good quant" << endl;
2105   //  const std::set<Expr>& bvs = getBoundVars(e);
2106 
2107   //  if (bvs.size() <= 0 ) {
2108   //    return true; //this is a ground formula,
2109   //  }
2110 
2111   //  if (e.getVars().size() != bvs.size()){
2112   //    return false; // we can do more on this case later.
2113   //  }
2114 
2115   vector<Expr> bvs = e.getVars();
2116 
2117   for (vector<Expr>::iterator i = bvs.begin(), iend = bvs.end(); i != iend; i++){
2118     if ( ! isInt(i->getType() ) ){
2119       return false; //now only inteter can be handled
2120     }
2121   }
2122 
2123 //   if (e.isExists()){
2124 //     return true;
2125 //   }
2126 
2127 //  findPolarity(newQuant, d_expr_pol, Pos); //used later by isGoodQuant and collectIndex
2128   ExprMap<Polarity> body_pol ;
2129   findPolarity(e, body_pol, Pos);
2130 
2131   for(ExprMap<Polarity>::iterator i = body_pol.begin(), iend = body_pol.end(); i != iend; i++) {
2132     if ((i->first).isAtomicFormula()){
2133       const Expr& cur_expr = i->first;
2134       Polarity pol = i->second;
2135 
2136       //      cout <<" good " << cur_expr << endl;
2137       if (!cur_expr.containsBoundVar()){
2138 	continue; // this is a ground term, no need to do anything
2139       }
2140       else if (isShield(cur_expr)){
2141 	continue; // this is good
2142       }
2143       else if (isLE(cur_expr) || isLT(cur_expr) || cur_expr.isEq()){
2144 	const Expr& left = cur_expr[0];
2145 	const Expr& right = cur_expr[1];
2146 	if (left.isBoundVar() && !right.containsBoundVar()){
2147 	  continue; //good case
2148 	}
2149 	else if (right.isBoundVar() && !left.containsBoundVar()){
2150 	  continue;
2151 	}
2152 	else if (left.isBoundVar() && right.isBoundVar()){
2153 	  if (Neg == pol && isLE(cur_expr)){
2154 	    continue;
2155 	  }
2156 	}
2157 	//well, neither left nor right is a bound var.
2158 	else if (isShield(left) && isShield(right)){
2159 	  continue;
2160 	}
2161 	//	cout << "RETURN 1 " << cur_expr << endl;
2162 	return false;
2163       }
2164       else{
2165 	//	cout << "RETURN 2 " << cur_expr << endl;
2166 	return false;
2167       }
2168     }
2169   }
2170   return true;
2171 }
2172 
2173 class recCompleteInster{
2174   const Expr& d_body;
2175   const std::vector<Expr>& d_bvs;
2176   std::vector<Expr> d_buff;
2177   const std::set<Expr>& d_all_index;
2178   std::vector<Expr> d_exprs;
2179   Expr d_result;
2180   void inst_helper(int num_vars);
2181   Expr& build_tree();
2182 public:
2183   recCompleteInster(const Expr&, const std::vector<Expr>&, std::set<Expr>& , Expr);
2184   Expr inst();
2185 };
2186 
recCompleteInster(const Expr & body,const std::vector<Expr> & bvs,std::set<Expr> & all_index,Expr res)2187 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){}
2188 
inst()2189 Expr recCompleteInster::inst(){
2190   d_buff.resize(d_bvs.size());
2191   //  cout << "there are " << d_all_index.size() << " gterms" << endl;
2192   inst_helper(d_bvs.size());
2193   return build_tree();
2194 }
2195 
inst_helper(int num_vars)2196 void recCompleteInster::inst_helper(int num_vars){
2197   if (1 == num_vars){
2198     for (set<Expr>::const_iterator i = d_all_index.begin(), iend = d_all_index.end();  i != iend; i++ ){
2199       d_buff[num_vars-1] = *i;
2200       d_exprs.push_back(d_body.substExpr(d_bvs,d_buff));
2201     }
2202   }
2203   else{
2204     for (set<Expr>::const_iterator i = d_all_index.begin(), iend = d_all_index.end();  i != iend; i++ ){
2205       d_buff[num_vars-1] = *i;
2206       inst_helper(num_vars-1);
2207     }
2208   }
2209 }
2210 
build_tree()2211 Expr& recCompleteInster::build_tree() {
2212     std::vector<Expr>& d_old = d_exprs, d_new;
2213     while (d_old.size() > 1) {
2214         int old_size = d_old.size();
2215         for (int i = 0; i < old_size - 1; i += 2) {
2216             d_new.push_back(d_old[i].andExpr(d_old[i + 1]));
2217         }
2218         if (old_size % 2 == 1) {
2219             d_new.push_back(d_old[old_size - 1]);
2220         }
2221         d_old.clear();
2222         d_old.swap(d_new);
2223     }
2224     if (d_old.size() > 0) d_result = d_result.andExpr(d_old[0]);
2225     d_old.clear();
2226     return d_result;
2227 }
2228 
inst(const Expr & assert)2229 Expr CompleteInstPreProcessor::inst(const Expr& assert){
2230   if(isGround(assert)){
2231     return assert;
2232   }
2233   else  if (assert.isExists()){
2234     DebugAssert(d_quant_equiv_map.count(assert) > 0,"assert not found" ) ;
2235     return d_quant_equiv_map[assert];
2236   }
2237   else if( ! assert.isForall()){
2238     if (assert.arity() > 0){
2239       vector<Expr> children;
2240       for (int i = 0 ; i < assert.arity(); i++){
2241 	Expr rep_child;
2242 	rep_child = inst(assert[i]);
2243 	children.push_back(rep_child);
2244       }
2245       return Expr(assert.getOp(), children);
2246     }
2247     else{
2248       DebugAssert(false, "error in inst");
2249       return assert;
2250     }
2251   }
2252 
2253   DebugAssert(assert.isForall(), "not a forall");
2254   DebugAssert(d_quant_equiv_map.count(assert) > 0, "assert not found" ) ;
2255   Expr forall = d_quant_equiv_map[assert];
2256 
2257   const vector<Expr>& bvs = forall.getVars();
2258   const Expr body = forall.getBody();
2259   vector<Expr> and_list;
2260 
2261   if(d_allIndex.size() == 0){
2262     addIndex(d_theoryCore->getEM()->newRatExpr(0));
2263   }
2264 
2265   if(bvs.size() == 1 ) {
2266     //    getBoundVars(body);
2267     for (set<Expr>::const_iterator i = d_allIndex.begin(), iend = d_allIndex.end();
2268 	 i != iend; i++ ){
2269       vector<Expr> inst_st;
2270 
2271       inst_st.push_back(*i);
2272 
2273 //       if(body.substExprQuant(bvs,inst_st) != body.substExpr(bvs,inst_st)){
2274 // 	cout << "old " << body.substExpr(bvs,inst_st) << endl ;
2275 // 	cout << "new " << body.substExprQuant(bvs,inst_st) << endl;
2276 //       }
2277 
2278       //and_list.push_back(body.substExprQuant(bvs,inst_st));
2279       and_list.push_back(body.substExpr(bvs,inst_st));
2280     }
2281     return Expr(AND,and_list);
2282   }
2283   else if (bvs.size() == 2 ){
2284     //    getBoundVars(body);
2285     for (set<Expr>::const_iterator i = d_allIndex.begin(), iend = d_allIndex.end();
2286 	 i != iend; i++ ){
2287       for (set<Expr>::const_iterator j = d_allIndex.begin(), jend = d_allIndex.end();
2288 	   j != jend; j++ ){
2289 	vector<Expr> inst_st;
2290 	inst_st.push_back(*i);
2291 	inst_st.push_back(*j);
2292 
2293 	//	cout << "== " << inst_st[0] << " " << inst_st[1] << endl;
2294 
2295 // 	if(body.substExprQuant(bvs,inst_st) != body.substExpr(bvs,inst_st)){
2296 // 	  cout << "old " << body.substExpr(bvs,inst_st) << endl ;
2297 // 	  cout << "new " << body.substExprQuant(bvs,inst_st) << endl;
2298 // 	}
2299 
2300 	//and_list.push_back(body.substExprQuant(bvs,inst_st));
2301 	and_list.push_back(body.substExpr(bvs,inst_st));
2302 	//	cout << "INST: " <<  body.substExpr(bvs,inst_st) << endl;
2303       }
2304     }
2305     //    cout << "we have " << and_list.size() << " ands " << endl;
2306     return Expr(AND,and_list);
2307   }
2308   //  else if ( 0 < bvs.size()  && bvs.size() <= 5 ){
2309   else{
2310     Expr init_expr = d_theoryCore->trueExpr();
2311     //    cout <<"we have " << bvs.size() << endl;
2312     recCompleteInster inster(body, bvs, d_allIndex, init_expr);
2313     //    cout<<inster.inst();
2314     return inster.inst();
2315   }
2316 //   else{
2317 //     DebugAssert(false, "More than five vars, too many.");
2318 //   }
2319   return assert;
2320 }
2321 
flatAnds(const Expr & ands,vector<Expr> & results)2322 void flatAnds(const Expr& ands, vector<Expr>& results){
2323   if (ands.isAnd()){
2324     for(Expr::iterator i=ands.begin(), iend=ands.end(); i!=iend; ++i)    {
2325       flatAnds(*i,results);
2326     }
2327   }
2328   else if (ands.isNot() && ands[0].isOr()){
2329     for(Expr::iterator i=ands[0].begin(), iend=ands[0].end(); i!=iend; ++i)    {
2330       if(i->isNot()){
2331 	flatAnds((*i)[0], results);
2332       }
2333       else{
2334 	flatAnds(i->notExpr(), results);
2335       }
2336     }
2337   }
2338   else{
2339     results.push_back(ands);
2340   }
2341 }
2342 
theoryPreprocess(const Expr & e)2343 Theorem TheoryQuant::theoryPreprocess(const Expr& e){
2344   //  cout<<"theory process " << e << endl;
2345   // COMMENT for LFSC on 4-2-2010, Yeting
2346   //  return reflexivityRule(e);
2347   if ( ! theoryCore()->getFlags()["quant-complete-inst"].getBool()){
2348     return reflexivityRule(e);
2349   }
2350 
2351   const std::set<Expr>& bvs = getBoundVars(e);
2352   if (bvs.size() <= 0){
2353     return reflexivityRule(e);
2354   }
2355 
2356   std::vector<Expr> assertList;
2357   flatAnds(e, assertList);
2358 
2359   CompleteInstPreProcessor comp_inst_proc(theoryCore(), d_rules);
2360 
2361   if (comp_inst_proc.hasMacros(assertList)){
2362     for(size_t i = 0; i < assertList.size();i++){
2363       //    cout << "== assert: " << i << " : " << assertList[i] << endl;
2364       assertList[i] = comp_inst_proc.instMacros(assertList[i], trueExpr().notExpr().notExpr());
2365     }
2366   }
2367 
2368   for(size_t i = 0; i < assertList.size() ; i++){
2369     //    cout << "BEFORE: " << assertList[i] << endl;
2370     assertList[i] = comp_inst_proc.simplifyQuant(assertList[i]);
2371     //    cout << "AFTER: " << assertList[i] << endl;
2372   }
2373 
2374   for(size_t i = 0; i < assertList.size() ; i++){
2375     if ( ! comp_inst_proc.isGood(assertList[i])){
2376       //      cout << " no good " << endl;
2377       //      cout << " because of " <<  assertList[i] << endl;
2378       return reflexivityRule(e);
2379     }
2380   }
2381 
2382   for(size_t i = 0; i < assertList.size() ; i++){
2383     //    cout << "collecting " << assertList[i] << endl;
2384     comp_inst_proc.collectIndex(assertList[i]);
2385   }
2386 
2387   vector<Expr> new_asserts;
2388   for(size_t i = 0; i < assertList.size() ; i++){
2389     Expr new_asser = comp_inst_proc.inst(assertList[i]);
2390     getBoundVars(new_asser);
2391     if (new_asser.containsBoundVar()){
2392       return reflexivityRule(e);
2393     }
2394     else{
2395       new_asserts.push_back(new_asser);
2396     }
2397   }
2398 
2399 
2400   //  vector<Expr> all_index;
2401   //  for(size_t i = 0; i < assertList.size() ; i++){
2402   //    collectIndex(assertList[i], all_index);
2403   //  }
2404 
2405 
2406 //   set<Expr> inst_index;
2407 //   for(size_t i = 0; i < all_index.size() ; i++){
2408 //     if (isInt(all_index[i].getType())){
2409 //       inst_index.insert(all_index[i]);
2410 //     }
2411 //     else{
2412 //       cout <<"strange" << all_index[i] << endl;
2413 //     }
2414 //   }
2415 
2416 //   int j(0);
2417 //   for(set<Expr>::iterator i = inst_index.begin(), iend = inst_index.end();
2418 //       i != iend; i++){
2419 //     cout << "i=" << j++ << " " << *i << endl;
2420 //   }
2421 
2422 
2423 //   for(size_t i = 0; i < assertList.size() ; i++){
2424 //     Expr& cur_expr = assertList[i];
2425 //     if(cur_expr.isForall()){
2426 //       Expr new_inst = instIndex(cur_expr, inst_index);
2427 //       assertList[i] = new_inst;
2428 //       //      cout << "new inst " << new_inst << endl;
2429 //     }
2430 //   }
2431 
2432 //   for(size_t i = 0; i < assertList.size() ; i++){
2433 //     //    cout << "AFTER i=" << i << " " << assertList[i] << endl;
2434 //   }
2435 
2436   for(size_t i = 0; i < new_asserts.size() ; i++){
2437     new_asserts[i] = comp_inst_proc.simplifyEq(new_asserts[i]);
2438   }
2439 
2440   for(size_t i = 0; i < new_asserts.size() ; i++){
2441     //cout << ":assumption "  << new_asserts[i] << endl;
2442     //    cout << "NEW" << comp_inst_proc.inst(assertList[i]) << endl;
2443   }
2444 
2445 
2446   //this is really a bad way, add a new proof rule here
2447   Expr res = Expr(AND, new_asserts);
2448   Theorem ret_thm = d_rules->addNewConst(e.iffExpr(res));
2449   //  cout << "NEW THM " << ret_thm << endl;
2450   return ret_thm;
2451 }
2452 
2453 
2454 
2455 
isGoodSysPredTrigger(const Expr & e)2456 bool isGoodSysPredTrigger(const Expr& e){
2457   if(!isSysPred(e)) return false;
2458   if(usefulInMatch(e[0]) || usefulInMatch(e[1])) return true;
2459   return false;
2460 }
2461 
isGoodFullTrigger(const Expr & e,const std::vector<Expr> & bVarsThm)2462 bool isGoodFullTrigger(const Expr& e, const std::vector<Expr>& bVarsThm){
2463   if( !usefulInMatch(e))
2464     return false;
2465 
2466   const std::set<Expr>& bvs = getBoundVars(e);
2467 
2468   if (bvs.size() >= bVarsThm.size()){
2469      for(size_t i=0; i<bVarsThm.size(); i++)	{
2470        if (bvs.find(bVarsThm[i]) == bvs.end()){
2471 	 return false;
2472        }
2473      }
2474      return true;
2475   }
2476   else {
2477     return false;
2478   }
2479 }
2480 
isGoodMultiTrigger(const Expr & e,const std::vector<Expr> & bVarsThm,int offset)2481 bool isGoodMultiTrigger(const Expr& e, const std::vector<Expr>& bVarsThm, int offset){
2482   if( !usefulInMatch(e) )
2483     return false;
2484 
2485   int bvar_missing = 0;
2486   const std::set<Expr>& bvs = getBoundVars(e);
2487 
2488   if(bvs.size() <= 0) return false;
2489 
2490   for(size_t i=0; i<bVarsThm.size(); i++)	{
2491     if (bvs.find(bVarsThm[i]) == bvs.end()){
2492       bvar_missing++; // found one bound var missing in the e.
2493     }
2494   }
2495 
2496   if (0 == bvar_missing){ //it is a full triggers
2497     return false;
2498   }
2499 
2500   if(bvar_missing <= offset){
2501     if(isSysPred(e)){
2502       if (isGoodSysPredTrigger(e)) {
2503 	return true;
2504       }
2505       else {
2506 	return false;
2507       }
2508     }
2509     else {
2510       return true;
2511     }
2512   }
2513   return false;
2514 }
2515 
isGoodPartTrigger(const Expr & e,const std::vector<Expr> & bVarsThm)2516 bool isGoodPartTrigger(const Expr& e, const std::vector<Expr>& bVarsThm){
2517   if( !usefulInMatch(e) )
2518     return false;
2519 
2520   size_t bvar_missing = 0;
2521   const std::set<Expr>& bvs = getBoundVars(e);
2522 
2523   for(size_t i=0; i<bVarsThm.size(); i++)	{
2524     if (bvs.find(bVarsThm[i]) == bvs.end()){
2525       bvar_missing++; // found one bound var missing in the e.
2526     }
2527   }
2528 
2529   if (0 == bvar_missing){ //it is a full triggers
2530     return false;
2531   }
2532 
2533   if(0 == bvs.size()){
2534     return false;
2535   }
2536 
2537   if(bvar_missing < bVarsThm.size()){
2538     if(isSysPred(e)){
2539       if (isGoodSysPredTrigger(e)) {
2540 	return true;
2541       }
2542       else {
2543 	return false;
2544       }
2545     }
2546     else {
2547       return true;
2548     }
2549   }
2550   return false;
2551 }
2552 
2553 
recursiveGetPartTriggers(const Expr & e,std::vector<Expr> & res)2554 static bool recursiveGetPartTriggers(const Expr& e, std::vector<Expr>& res) {
2555   if(e.getFlag())
2556    return false;
2557 
2558   if(e.isClosure())
2559     return recursiveGetPartTriggers(e.getBody(), res);
2560 
2561   if(0 == e.arity()){
2562     if(BOUND_VAR == e.getKind()){
2563       return false;
2564     }
2565     else{
2566       return true;
2567     }
2568   }
2569 
2570   bool good=true;
2571   bool no_bound =true;
2572 
2573   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
2574     if(BOUND_VAR == i->getKind()){
2575       no_bound=false;
2576       continue;
2577     }
2578     bool temp = recursiveGetPartTriggers(*i,res);
2579     if(false == temp) {
2580       good=false;
2581     }
2582   }
2583 
2584   e.setFlag();
2585 
2586   if(good && no_bound) {
2587     return true;
2588   }
2589   else if(good && !no_bound){
2590     res.push_back(e);
2591     return false;
2592   }
2593   else{
2594     return false;
2595   }
2596 }
2597 
2598 
getPartTriggers(const Expr & e)2599 std::vector<Expr> getPartTriggers(const Expr& e){
2600   e.clearFlags();
2601   std::vector<Expr> res;
2602   recursiveGetPartTriggers(e,res);
2603   e.clearFlags();
2604   return res;
2605 }
2606 
trigInitScore(const Expr & e)2607 int trigInitScore(const Expr& e){
2608   if( isSysPred(e) && !isGoodSysPredTrigger(e)){
2609     return 1;
2610   }
2611   else {
2612     return 0;
2613   }
2614 }
2615 
2616 
arrayIndexName(const Expr & e)2617 void TheoryQuant::arrayIndexName(const Expr& e){
2618   std::vector<Expr> res;
2619 
2620   const std::vector<Expr>& subs=getSubTerms(e);
2621 
2622   for(size_t i=0; i<subs.size(); i++){
2623     int kind = subs[i].getKind();
2624     if (READ == kind || WRITE == kind){
2625       const Expr& name = subs[i][0];
2626       const Expr& index = subs[i][1];
2627       if(getBoundVars(name).size() <= 0 && (getBoundVars(index).size() <=0)){
2628 	std::vector<Expr> tp = d_arrayIndic[name];
2629 	tp.push_back(index);
2630 	d_arrayIndic[name]=tp;
2631       }
2632       else {
2633       }
2634     }
2635   }
2636 }
2637 
registerTrig(ExprMap<ExprMap<std::vector<dynTrig> * > * > & cur_trig_map,Trigger trig,const std::vector<Expr> thmBVs,size_t univ_id)2638 void TheoryQuant::registerTrig(ExprMap<ExprMap<std::vector<dynTrig>* >* >& cur_trig_map,
2639 			       Trigger trig,
2640 			       const std::vector<Expr> thmBVs,
2641 			       size_t univ_id){
2642   {
2643     if(trig.hasRWOp){
2644       ExprMap<Expr> bv_map;
2645       dynTrig newDynTrig(trig, bv_map,univ_id);
2646       d_arrayTrigs.push_back(newDynTrig);
2647     }
2648   }
2649 
2650   ExprMap<Expr> bv_map;
2651   /*
2652   for(size_t i = 0; i<thmBVs.size(); i++){
2653     bv_map[thmBVs[i]] = null_expr;
2654   }
2655   */
2656 
2657 //temp fix,
2658    for(size_t i = 0; i<thmBVs.size(); i++){
2659      bv_map[thmBVs[i]] = thmBVs[i];
2660    }
2661 
2662 
2663 
2664   const Expr& trig_ex = trig.getEx();
2665 
2666   Expr genTrig = trig_ex;
2667   //  Expr genTrig = generalTrig(trig_ex, bv_map);
2668 
2669   dynTrig newDynTrig(trig,bv_map,univ_id);
2670 
2671   Expr head = trig.getHead();
2672 
2673   ExprMap<ExprMap<vector<dynTrig>* >* >::iterator iter = cur_trig_map.find(head);
2674   if(cur_trig_map.end() == iter){
2675     ExprMap<vector<dynTrig>* >* new_cd_map= new  ExprMap<vector<dynTrig>* > ;
2676     cur_trig_map[head] = new_cd_map;
2677     vector<dynTrig>* new_dyntrig_list = new vector<dynTrig>;
2678     (*new_cd_map)[genTrig] = new_dyntrig_list;
2679     (*new_dyntrig_list).push_back(newDynTrig);
2680   }
2681   else{
2682     ExprMap<vector<dynTrig>* >* cd_map = iter->second;
2683     ExprMap<vector<dynTrig>* >::iterator iter_map = cd_map->find(genTrig);
2684     if(cd_map->end() == iter_map){
2685       vector<dynTrig>* new_dyntrig_list = new vector<dynTrig>;
2686       (*cd_map)[genTrig] = new_dyntrig_list;
2687       (*new_dyntrig_list).push_back(newDynTrig);
2688     }
2689     else{
2690       //      cout<<"never happen here" << endl;
2691       //      (*((*cd_map)[generalTrig])).push_back(newDynTrig);
2692       (*(iter_map->second)).push_back(newDynTrig);
2693     }
2694   }
2695 }
2696 
2697 /*
2698 void TheoryQuant::registerTrigReal(Trigger trig, const std::vector<Expr> thmBVs, size_t univ_id){
2699   cout<<"register: "<<trig.getEx()<<endl;
2700   ExprMap<Expr> bv_map;
2701   for(size_t i = 0; i<thmBVs.size(); i++){
2702     bv_map[thmBVs[i]] = null_expr;
2703   }
2704   const Expr& trig_ex = trig.getEx();
2705 
2706   Expr genTrig = generalTrig(trig_ex, bv_map);
2707 
2708   dynTrig newDynTrig(trig,bv_map,univ_id);
2709 
2710   Expr head = trig.getHead();
2711 
2712   ExprMap<CDMap<Expr, CDList<dynTrig>* >* >::iterator iter = d_allmap_trigs.find(head);
2713   if(d_allmap_trigs.end() == iter){
2714     CDMap<Expr, CDList<dynTrig>* >* new_cd_map=
2715       new(true) CDMap<Expr, CDList<dynTrig>* > (theoryCore()->getCM()->getCurrentContext());
2716     d_allmap_trigs[head] = new_cd_map;
2717     CDList<dynTrig>* new_dyntrig_list = new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
2718     (*new_cd_map)[genTrig] = new_dyntrig_list;
2719     (*new_dyntrig_list).push_back(newDynTrig);
2720   }
2721   else{
2722     CDMap<Expr, CDList<dynTrig>* >* cd_map = iter->second;
2723     CDMap<Expr, CDList<dynTrig>* >::iterator iter_map = cd_map->find(genTrig);
2724     if(cd_map->end() == iter_map){
2725       CDList<dynTrig>* new_dyntrig_list = new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
2726       (*cd_map)[genTrig] = new_dyntrig_list;
2727       (*new_dyntrig_list).push_back(newDynTrig);
2728     }
2729     else{
2730       //      (*((*cd_map)[generalTrig])).push_back(newDynTrig);
2731       (*((*iter_map).second)).push_back(newDynTrig);
2732       cout<<"once more"<<endl;
2733     }
2734   }
2735 
2736 }
2737 */
2738 
2739 /*
2740 Expr TheoryQuant::generalTrig(const Expr& trig, ExprMap<Expr>& bvs){
2741   //temp fix
2742   return trig;
2743 
2744   Expr newtrig = trig;
2745   getBoundVars(newtrig);
2746 
2747 
2748   size_t count =0 ;
2749   Expr res = recGeneralTrig(trig, bvs, count);
2750   getBoundVars(res);
2751   return res;
2752 
2753 }
2754 
2755 
2756 Expr TheoryQuant::recGeneralTrig(const Expr& trig, ExprMap<Expr>& bvs, size_t& mybvs_count){
2757 
2758   if (!trig.containsBoundVar()) return trig;
2759   if (BOUND_VAR == trig.getKind()){
2760     if (bvs.find(trig) != bvs.end()){
2761       const Expr& ubv = bvs[trig];
2762       if(null_expr ==ubv){
2763 	Expr new_bv = d_mybvs[mybvs_count++];
2764 	bvs[trig] = new_bv ;
2765 	if((mybvs_count) >= MAX_TRIG_BVS ){
2766 	  //	  cout<< "general trig error" <<endl;
2767 	}
2768 	else{
2769 	  return new_bv;
2770 	}
2771       }
2772       else{
2773 	return bvs[trig];
2774       }
2775     }
2776     else{
2777       return d_mybvs[0];
2778     }
2779   }
2780   else{
2781     vector<Expr> children;
2782       for(Expr::iterator i=trig.begin(), iend=trig.end(); i!=iend; ++i){
2783 	Expr repChild;
2784 	if(i->containsBoundVar()){
2785 	  repChild = recGeneralTrig(*i, bvs, mybvs_count);
2786 	}
2787 	else{
2788 	  repChild = *i;
2789 	}
2790 	children.push_back(repChild);
2791       }
2792       return Expr(trig.getOp(), children);
2793   }
2794 }
2795 
2796 */
2797 //this function is used to check if two triggers can match with eath other
canMatch(const Expr & t1,const Expr & t2,ExprMap<Expr> & env)2798 bool TheoryQuant::canMatch(const Expr& t1, const Expr& t2, ExprMap<Expr>& env){
2799   if(getBaseType(t1) != getBaseType(t2)) return false;
2800 
2801   if (BOUND_VAR == t1.getKind() || BOUND_VAR == t2.getKind()) {
2802     return true;
2803   }
2804 
2805   if ( (t1.arity() != t2.arity()) || (t1.getKind() != t2.getKind() )) {
2806     return false;
2807   }
2808   if (canGetHead(t1) && canGetHead(t2)) {
2809     if ( getHead(t1) != getHead(t2) ){
2810       return false;
2811     }
2812     for(int i=0; i<t1.arity(); i++){
2813       if (false == canMatch(t1[i], t2[i] , env))
2814 	return false;
2815     }
2816     return true;
2817   }
2818   else{
2819     return false;
2820   }
2821 }
2822 
isTransLike(const vector<Expr> & cur_trig)2823 bool TheoryQuant::isTransLike (const vector<Expr>& cur_trig){
2824   if(!(*d_useTrans)){
2825     return false;
2826   }
2827   if(3==cur_trig.size()){
2828     const Expr& t1=cur_trig[0];
2829     const Expr& t2=cur_trig[1];
2830     const Expr& t3=cur_trig[2];
2831     if ( canGetHead(t1) && canGetHead(t2) && canGetHead(t3) &&
2832 	 (getHead(t1) == getHead(t2)) &&  (getHead(t2) == getHead(t3))){
2833       const std::set<Expr>& ts1 = getBoundVars(t1);
2834       const std::set<Expr>& ts2 = getBoundVars(t2);
2835       const std::set<Expr>& ts3 = getBoundVars(t3);
2836       if ( 2==ts1.size() && 2==ts2.size() && 2==ts2.size() &&
2837 	   (ts1 != ts2) && (ts2 != ts3) && (ts3 != ts1)){
2838 	std::set<Expr> all;
2839 	for(set<Expr>::const_iterator i=ts1.begin(), iend = ts1.end(); i != iend; i++){
2840 	  all.insert(*i);
2841 	}
2842 	for(set<Expr>::const_iterator i=ts2.begin(), iend = ts2.end(); i != iend; i++){
2843 	  all.insert(*i);
2844 	}
2845 	for(set<Expr>::const_iterator i=ts3.begin(), iend = ts3.end(); i != iend; i++){
2846 	  all.insert(*i);
2847 	}
2848 	bool res = true;
2849 	if(3==all.size()){
2850 	  for(set<Expr>::const_iterator i=all.begin(), iend = all.end(); i != iend; i++){
2851 	    if(!i->isVar()) {
2852 	      res = false;
2853 	      break;
2854 	    }
2855 	  }
2856 	  if(res) {
2857 	  }
2858 	  return res;
2859 	}
2860       }
2861     }
2862   }
2863   return false;
2864 }
2865 
isTrans2Like(const std::vector<Expr> & all_terms,const Expr & tr2)2866 bool TheoryQuant::isTrans2Like (const std::vector<Expr>& all_terms, const Expr& tr2){
2867   if(!(*d_useTrans2)){
2868     return false;
2869   }
2870   for(size_t i = 0; i < all_terms.size(); i++){
2871     if(all_terms[i].isEq()){
2872       const Expr& cur = all_terms[i];
2873       if(cur[0] != cur[1] && ( (cur[0]==tr2[0] && cur[1]==tr2[1]) || (cur[0]==tr2[1] && cur[1]==tr2[0]))){
2874 	return true;
2875       }
2876     }
2877   }
2878   return false;
2879 }
2880 
2881 
goodMultiTriggers(const std::vector<Expr> & exprs,const std::vector<Expr> bVars)2882 bool goodMultiTriggers(const std::vector<Expr>& exprs, const std::vector<Expr> bVars){
2883   ExprMap<bool> bvar_found;
2884 
2885   for( std::vector<Expr>::const_iterator i = bVars.begin(),  iend= bVars.end();  i!=iend; i++) {
2886     bvar_found[*i]=false;
2887   }
2888 
2889   for (size_t  i=0; i< exprs.size();i++){
2890     const std::set<Expr> & bv_in_trig = getBoundVars(exprs[i]);
2891     for(std::set<Expr>::const_iterator j=bv_in_trig.begin(), jend = bv_in_trig.end();  j != jend; j++){
2892       if(bvar_found.find(*j) != bvar_found.end()){
2893 	bvar_found[*j]=true;
2894       }
2895     }
2896   }
2897 
2898   for( std::vector<Expr>::const_iterator i = bVars.begin(), iend= bVars.end();  i!=iend;  i++) {
2899     if(false == bvar_found[*i]){
2900       return false ;
2901     }
2902   }
2903   return true;
2904 }
2905 
2906 
locVar(const vector<Expr> & bvsThm,const Expr & bv)2907 inline size_t locVar(const vector<Expr>& bvsThm, const Expr& bv){
2908   for(size_t i=0, iend = bvsThm.size(); i < iend; i++){
2909     if (bvsThm[i] == bv){
2910       return i;
2911     }
2912   }
2913   return 999; //this number should be big enough
2914 }
2915 
2916 
setupTriggers(ExprMap<ExprMap<vector<dynTrig> * > * > & trig_maps,const Theorem & thm,size_t univs_id)2917 void TheoryQuant::setupTriggers(ExprMap<ExprMap<vector<dynTrig>* >*>& trig_maps, const Theorem& thm, size_t univs_id){
2918 
2919   //  static std::vector<Expr> libQuant;
2920   const Expr& e = thm.getExpr();
2921 
2922   TRACE("triggers", "setup : "+int2string(e.getIndex()),  " | " , e.toString());
2923 
2924   d_univs.push_back(thm);
2925   const std::vector<Expr>& bVarsThm = e.getVars();
2926   if  (d_hasTriggers.count(e) > 0 ) {
2927 
2928     if(d_fullTrigs.count(e)>0){
2929       std::vector<Trigger>& new_trigs = d_fullTrigs[e];
2930       for(size_t i=0; i<new_trigs.size(); i++){
2931 	registerTrig(trig_maps, new_trigs[i], bVarsThm, univs_id);
2932       }
2933     }
2934     //    if(0 == new_trigs.size() && d_multTrigs.count(e) > 0){
2935     if( d_multTrigs.count(e) > 0){
2936       std::vector<Trigger>& new_mult_trigs = d_multTrigs[e];
2937       for(size_t j=0; j<new_mult_trigs.size(); j++){
2938 	registerTrig(trig_maps, new_mult_trigs[j], bVarsThm, univs_id);
2939       }
2940     }
2941     return;
2942   }
2943 
2944   if  (*d_useManTrig  ) {
2945     if(e.getTriggers().size() > 0) {
2946       //      cout<<"manual trig found"<<endl;
2947       //      cout<<vectorExpr2string(e.getTriggers())<<endl;
2948     }
2949   }
2950 
2951   d_hasTriggers[e]=true;
2952 
2953   TRACE("triggers-new", "setup : "+int2string(e.getIndex()),  " | " , e.toString());
2954   //  libQuant.push_back(e);
2955 
2956   //  const std::vector<Expr>& subterms = getSubTrig(e);
2957   const std::vector<Expr> subterms = getSubTrig(e);
2958 
2959 
2960 // #ifdef _CVC3_DEBUG_MODE
2961 //   if( CVC3::debugger.trace("triggers")  ){
2962 //     cout<<"===========all sub terms =========="<<endl;
2963 //     for (size_t i=0; i<subterms.size(); i++){
2964 //       const Expr& sub = subterms[i];
2965 //       cout<<"i="<< i << " : " << findExpr(sub) << " | " << sub << " and type is " << sub.getType()
2966 // 	  << " and kind is " << sub.getEM()->getKindName(sub.getKind()) << endl;
2967 //     }
2968 //   }
2969 // #endif
2970 
2971   ExprMap<Polarity> exprPol;
2972   findPolarity(e, exprPol, Pos);
2973 
2974   {// for full triggers
2975     std::vector<Expr> trig_list;
2976     std::vector<Expr> trig_cadt;
2977     for(std::vector<Expr>::const_iterator i = subterms.begin(),iend=subterms.end(); i!=iend; i++){
2978       if(isGoodFullTrigger(*i, bVarsThm)) {
2979 	trig_cadt.push_back(*i);
2980       }
2981     }
2982 
2983 
2984     if(*d_useManTrig && e.getTriggers().size() > 0  ){
2985       std::vector<std::vector<Expr> > man_trigs = e.getTriggers();
2986       for(std::vector<std::vector<Expr> >::const_iterator i=man_trigs.begin(), iend=man_trigs.end(); i != iend; i++){
2987 	if(1 == i->size()){
2988 	  if (isGoodFullTrigger((*i)[0],bVarsThm)){
2989 	    trig_list.push_back((*i)[0]);
2990 	    //	    cout<<"full manual pushed "<<(*i)[0] << endl;
2991 	  }
2992 	  else{
2993 	    //	    cout<<"full manual discarded "<<(*i)[0] << endl;
2994 	  }
2995 
2996 	}
2997 	//	else if(2 == i->arity()){
2998 	else if(2 == i->size()){
2999 	  if (isGoodFullTrigger((*i)[0], bVarsThm) && isGoodFullTrigger((*i)[1], bVarsThm)){
3000 	    trig_list.push_back((*i)[0]);
3001 	    trig_list.push_back((*i)[1]);
3002 	    break; // it must be trans2like
3003 	  }
3004 	}
3005       }
3006     }
3007     else{
3008       for(size_t iter =0; iter < trig_cadt.size(); iter++) {
3009 	Expr* i = &(trig_cadt[iter]);
3010 	bool notfound = true;
3011 
3012 	for(size_t index=0; index< trig_list.size(); index++){
3013 	  if (i->subExprOf(trig_list[index])) {
3014 	    trig_list[index]=*i;
3015 	    notfound=false;
3016 	    break;
3017 	  }
3018 	  if (trig_list[index].subExprOf(*i)) {
3019 	    notfound=false;
3020 	    break;
3021 	  }
3022 	}
3023 	if (notfound) {
3024 	  trig_list.push_back(*i);
3025 	}
3026       }
3027     }
3028 
3029     std::vector<Trigger> trig_ex;
3030 
3031     for (size_t  i=0; i< trig_list.size();i++){
3032       const Expr& cur = trig_list[i];
3033       const std::set<Expr> cur_bvs = getBoundVars(cur);
3034       int score = trigInitScore(cur);
3035       if(score > 0) continue;
3036 
3037       //1. test trans2
3038       //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.
3039 
3040       for(size_t j=0; j< trig_cadt.size(); j++){
3041 	if (trig_list[i] == trig_cadt[j]) continue;
3042 	ExprMap<Expr> null;
3043 	if (canMatch(trig_list[i], trig_cadt[j], null)){
3044 	  if(exprScore(trig_list[i]) < exprScore(trig_cadt[j])){
3045 	  }
3046 	  else if(*d_useTrans2 &&
3047 		  trig_list.size() == 2 &&
3048 		  trig_list[i].arity() == 2 &&
3049 		  BOUND_VAR == trig_list[i][0].getKind() &&
3050 		  BOUND_VAR == trig_list[i][1].getKind() &&
3051 		  BOUND_VAR == trig_cadt[j][0].getKind() &&
3052 		  BOUND_VAR == trig_cadt[j][1].getKind() &&
3053 		  isTrans2Like(subterms, trig_list[i])
3054 		  ){
3055 
3056 	    score =0; //useless, to delete;
3057 	    d_trans2_num++;
3058 
3059 	    DebugAssert(d_trans2_num<=1, "more than 2 trans2 found");
3060 	    TRACE("triggers",  "trans2 found ", trig_list[i], "");
3061 
3062 	    Trigger t(theoryCore(), cur, Neg, cur_bvs);
3063 	    t.setTrans2(true);
3064 	    t.setHead(getHeadExpr(cur));
3065 	    if(isSimpleTrig(cur)){
3066 	      t.setSimp();
3067 	    }
3068 	    if(isSuperSimpleTrig(cur)){
3069 	      t.setSuperSimp();
3070 	    }
3071 	    d_fullTrigs[e].push_back(t);
3072 	    registerTrig(trig_maps,t, bVarsThm, univs_id);
3073 	    return;
3074 	  }
3075 	  else{
3076 	    score =0;
3077 	  }
3078 	}
3079       }
3080 
3081       Polarity pol= Ukn;
3082 
3083       if(cur.getType().isBool()){
3084 	DebugAssert(exprPol.count(e)>0,"unknown polarity:"+cur.toString());
3085 	pol = exprPol[cur];
3086       }
3087 
3088       Trigger* t;
3089       Trigger* t_ex; //so, if a pred is PosNeg, we actually put two triggers into the list, one pos and the other neg
3090 
3091       if(PosNeg == pol && *d_usePolarity){
3092 	t = new Trigger(theoryCore(), cur, Pos, cur_bvs);
3093 	t_ex = new Trigger(theoryCore(), cur, Neg, cur_bvs);
3094 	if(isSimpleTrig(cur)){
3095 	  t->setSimp();
3096 	  t_ex->setSimp();
3097 	}
3098 	if(isSuperSimpleTrig(cur)){
3099 	  t->setSuperSimp();
3100 	  t_ex->setSuperSimp();
3101 	}
3102 
3103       }
3104       else{
3105 	t = new Trigger(theoryCore(), cur, pol, cur_bvs);
3106 	if(isSimpleTrig(cur)){
3107 	  t->setSimp();
3108 	}
3109 	if(isSuperSimpleTrig(cur)){
3110 	  t->setSuperSimp();
3111 	}
3112 	t_ex = NULL;
3113       }
3114 
3115       if(canGetHead(cur)) {
3116 	t->setHead(getHeadExpr(cur));
3117 	if(NULL != t_ex){
3118 	  t_ex->setHead(getHeadExpr(cur));
3119 	}
3120       }
3121       else{
3122 	if(!isSysPred(cur)){
3123 	  //	  cout<<"cur " << cur <<endl;
3124 	  //	  DebugAssert(false, "why this is a trigger");
3125 	}
3126       }
3127 
3128       t->setRWOp(false);
3129 
3130       if(READ == cur.getKind() || WRITE == cur.getKind()){
3131 	arrayIndexName(cur);
3132       }
3133 
3134       if(READ == cur.getKind() && WRITE== cur[0].getKind() && 1 == bVarsThm.size() ){
3135 	//	cout<<t->trig<<endl;
3136 	t->setRWOp(true);
3137 	if(t_ex != NULL) t_ex->setRWOp(true);
3138       }
3139 
3140       if(t_ex != NULL)  {
3141 	trig_ex.push_back(*t_ex);
3142       }
3143 
3144       d_fullTrigs[e].push_back(*t);
3145       registerTrig(trig_maps,*t, bVarsThm, univs_id);
3146 
3147       TRACE("triggers", "new:full triggers:", cur.toString(),"");
3148       TRACE("triggers", "new:full trigger score:", score,"");
3149       TRACE("triggers", "new:full trigger pol:", pol,"");
3150     }
3151 
3152     if(e.getTriggers().size() > 0) {
3153       //      cout<<"#### manual_trig: ";
3154       //      cout<<vectorExpr2string(e.getTriggers())<<endl;
3155     }
3156 
3157 
3158     for(size_t i=0; i<trig_ex.size(); i++){
3159       d_fullTrigs[e].push_back(trig_ex[i]);
3160       registerTrig(trig_maps,trig_ex[i], bVarsThm, univs_id);
3161       TRACE("triggers", "new extra :full triggers:", trig_ex[i].getEx().toString(),"");
3162     }
3163 
3164     if(d_fullTrigs[e].size() == 0){
3165       TRACE("triggers warning", "no full trig: ", e , "");
3166     }
3167   }
3168 
3169   //  if(0 == d_fullTrigs[e].size() && *d_useMult )
3170   if(0 == d_fullTrigs[e].size())
3171     {  //setup multriggers
3172       std::vector<Expr>& cur_trig = d_multTriggers[e];
3173       if(*d_useManTrig && e.getTriggers().size() > 0 ){
3174 	std::vector<std::vector<Expr> > man_trig = e.getTriggers();
3175 	int count(0);
3176 	for(std::vector<std::vector<Expr> >::const_iterator i = man_trig.begin(), iend = man_trig.end(); i != iend; i++){
3177 	  //	  if (i->arity() > 1) count++;
3178 	  if (i->size() > 1) count++;
3179 	  //	  cout << "count" << count << " " <<  *i << endl;
3180 	}
3181 	/*
3182 	if(count > 1){
3183 
3184 	  //cout<<"en, cannot handle this now"<<endl;
3185 
3186 	}
3187 	//	if(man_trig[count-1].arity() != 2){
3188 	if(man_trig[count-1].size() != 2){
3189 	  //	  cout<<man_trig[count-1]<<endl;
3190 	  //	  cout<<"sorry, only two exprs are handled now"<<endl;
3191 	  //cout<<man_trig[count-1]<<endl;
3192 	  //cout<<"sorry, only two exprs are handled now"<<endl;
3193 
3194 	  }*/
3195 	if (1 == count && 2 == man_trig[count-1].size()){
3196 	  for(std::vector<Expr>::const_iterator j = man_trig[count-1].begin(), jend = man_trig[count-1].end(); j != jend; ++j){
3197 	    cur_trig.push_back(*j);
3198 	  }
3199 	  if (! goodMultiTriggers(cur_trig, bVarsThm)){
3200 	    cur_trig.clear();
3201 	    return;
3202 	  }
3203 	}
3204       }
3205       else{
3206 	for( std::vector<Expr>::const_iterator i = subterms.begin(),  iend=subterms.end();  i!=iend;  i++) {
3207 	  if(isGoodMultiTrigger(*i, bVarsThm, d_offset_multi_trig))  {
3208 	    bool notfound = true;
3209 	    for(size_t index=0; index<d_multTriggers[e].size(); index++){
3210 	      if (i->subExprOf(d_multTriggers[e][index]))    {
3211 		(d_multTriggers[e][index])=*i;
3212 		notfound=false;
3213 	      }
3214 	    }
3215 	    if (notfound){
3216 	      d_multTriggers[e].push_back(*i);
3217 	    }
3218 	  }
3219 	}
3220 
3221 	if (goodMultiTriggers(cur_trig, bVarsThm)){
3222 	  //	cout<<"good multi triggers"<<endl;
3223 	  TRACE("multi-triggers", "good set of multi triggers","","");
3224 	  for (size_t  i=0; i< d_multTriggers[e].size();i++){
3225 	    //	  cout<<"multi-triggers" <<d_multTriggers[e][i]<<endl;
3226 	    TRACE("multi-triggers", "multi-triggers:", d_multTriggers[e][i].toString(),"");
3227 	  }
3228 	}
3229 	else{
3230 	  cur_trig.clear();
3231 	  //	  cout<<"bad multi triggers"<<endl;
3232 	  TRACE("multi-triggers", "bad set of multi triggers","","");
3233 	  return;
3234 	}
3235 
3236       }
3237 
3238       //special code for transitive pred,
3239       {
3240 	if(isTransLike(cur_trig)){
3241 	  d_trans_num++;
3242 	  DebugAssert(d_trans_num <= 1, "more than one trans found");
3243 
3244 	  Expr ex = cur_trig[0];
3245 
3246 	  Trigger* trans_trig = new Trigger(theoryCore(), ex, Neg, getBoundVars(ex));
3247 	  trans_trig->setHead(getHeadExpr(ex));
3248 	  if(isSimpleTrig(ex)){
3249 	    trans_trig->setSimp();
3250 	  }
3251 	  if(isSuperSimpleTrig(ex)){
3252 	    trans_trig->setSuperSimp();
3253 	  }
3254 
3255 	  trans_trig->setTrans(true);
3256 
3257 	  d_fullTrigs[e].push_back(*trans_trig);
3258 	  registerTrig(trig_maps,*trans_trig, bVarsThm, univs_id);
3259 	  cur_trig.clear();
3260 	  TRACE("triggers", " trans like found ", ex, "");
3261 	  d_transThm = thm;
3262 	}
3263       }
3264 
3265       //enhanced multi-triggers
3266       //      if(cur_trig.size() >0 && !(*d_useManTrig)){
3267       if(cur_trig.size() >0 ){
3268 	//  if(cur_trig.size() >0 ){
3269 	std::vector<Expr> posList, negList;
3270 	for(size_t k=0; k<cur_trig.size(); k++){
3271 	  const Expr& cur_item = cur_trig[k];
3272 	  if (cur_item.getType().isBool()){
3273 	    Polarity pol = exprPol[cur_item];
3274 	    if(PosNeg == pol || Pos == pol){
3275 	      posList.push_back(cur_item);
3276 	    }
3277 	    if(PosNeg == pol || Neg == pol){
3278 	      negList.push_back(cur_item);
3279 	    }
3280 	  }
3281 	}
3282 	if (goodMultiTriggers(posList, bVarsThm)){
3283 	  TRACE("multi-triggers", "good set of multi triggers pos","","");
3284 	  for (size_t  i=0; i< posList.size();i++){
3285 	    TRACE("multi-triggers", "multi-triggers:", posList[i].toString(),"");
3286 	  }
3287 	  cur_trig.clear();
3288 	  for(size_t m=0; m<posList.size(); m++){
3289 	    cur_trig.push_back(posList[m]);
3290 	  }
3291 	}
3292 	if (goodMultiTriggers(negList, bVarsThm) && negList.size() < cur_trig.size()){
3293 	  TRACE("multi-triggers", "good set of multi triggers neg","","");
3294 	  for (size_t  i=0; i< negList.size();i++){
3295 	    TRACE("multi-triggers", "multi-triggers:", negList[i].toString(),"");
3296 	  }
3297 	  cur_trig.clear();
3298 	  for(size_t m=0; m<negList.size(); m++){
3299 	    cur_trig.push_back(negList[m]);
3300 	  }
3301 	}
3302       }
3303 
3304       {//new way of multi trigger
3305 
3306 	if(!(*d_useManTrig) || e.getTriggers().size() <= 0){
3307 	//	if(!(*d_useManTrig)){
3308 	  if( 3 == cur_trig.size() ||  4 == cur_trig.size() || 5 == cur_trig.size() || 6 == cur_trig.size()  ){
3309 	    for(size_t i = 0; i < cur_trig.size(); i++){
3310 	      for(size_t j = 0; j < i; j++){
3311 		vector<Expr> tempList;
3312 		tempList.clear();
3313 		tempList.push_back(cur_trig[i]);
3314 		tempList.push_back(cur_trig[j]);
3315 		//	      cout<<i<<" | "<<j<<endl;
3316 		//	      cout<<vectorExpr2string(tempList)<<endl;
3317 		if (goodMultiTriggers(tempList, bVarsThm)){
3318 		  cur_trig.clear();
3319 		  cur_trig.push_back(tempList[0]);
3320 		  cur_trig.push_back(tempList[1]);
3321 		  //		  cout << "good multi triggers" << endl;
3322 		  //		  cout << (tempList[0]) << endl;
3323 		  //		  cout << (tempList[1]) << endl;
3324 		  break;
3325 	      }
3326 	      }
3327 	    }
3328 	  }
3329 	}
3330 
3331 	if(cur_trig.size() != 2){
3332 	  if( 0 == cur_trig.size()){
3333 	    return;
3334 	  }
3335 	  //	  FatalAssert(false, "unsupported multi-triggers");
3336 	  //	  cout<<"e: "<<e<<endl;
3337 	  //	  cout<<cur_trig.size()<<endl;
3338 	  //	  cout<<bVarsThm.size()<<endl;
3339 
3340 	  //	  cout<<vectorExpr2string(bVarsThm)<<endl;
3341 	  //	  for(size_t i =0; i<cur_trig.size(); i++){
3342 	  //	    cout<<cur_trig[i]<<endl;
3343 	  //	  }
3344 	  return;
3345 	}
3346 
3347 	//	cout<<"== new multi-trig ==" << endl;
3348 	for(size_t i = 0 ; i<cur_trig.size(); i++){
3349 	  set<Expr> bvs = getBoundVars(cur_trig[i]);
3350 	  Trigger trig(theoryCore(), cur_trig[i], Ukn, bvs); //
3351 	  //	  cout<<"new way of multi-trig"<<cur_trig[i]<<endl;
3352 	  trig.setHead(getHead(cur_trig[i]));
3353 	  trig.setMultiTrig();
3354 	  trig.multiIndex = i;
3355 	  trig.multiId=d_all_multTrigsInfo.size();
3356 	  d_multTrigs[e].push_back(trig);
3357 	  registerTrig(trig_maps, trig, bVarsThm, univs_id);
3358 	}
3359 
3360 	{
3361 	  multTrigsInfo multTrigs;
3362 	  for(size_t i =0, iend = d_multTrigs[e].size(); i<iend; i++){
3363 	    const std::vector<Expr>& one_set_bvs = d_multTrigs[e][i].bvs;
3364 	    std::vector<size_t> one_set_pos;
3365 
3366 	    for(size_t v = 0, vend = one_set_bvs.size(); v<vend; v++){
3367 	      size_t loc = locVar(bVarsThm, one_set_bvs[v]);
3368 	      if( 999 != loc ){
3369 		one_set_pos.push_back(loc);
3370 	      }
3371 	    }
3372 
3373 	    sort(one_set_pos.begin(), one_set_pos.end());
3374 
3375 	    for(size_t v = 0, vend = one_set_pos.size(); v<vend; v++){
3376 	    }
3377 
3378 	    multTrigs.var_pos.push_back(one_set_pos);
3379 	  }//setup pos of all multi tirggers
3380 
3381 	  //now we only consider two multi triggers
3382 	  vector<size_t> common;
3383 	  std::vector<size_t>& tar1 = multTrigs.var_pos[0];
3384 	  std::vector<size_t>& tar2 = multTrigs.var_pos[1];
3385 	  vector<size_t>::iterator t1(tar1.begin()), t2(tar2.begin());
3386 	  while(t1 != tar1.end() && t2!= tar2.end()){
3387 	    size_t pos1 = *t1;
3388 	    size_t pos2 = *t2;
3389 	    if( pos1  == pos2 ) {
3390 	      common.push_back(pos1);
3391 	      t1=tar1.erase(t1);
3392 	      t2=tar2.erase(t2);
3393 	    }
3394 	    else if( pos1 > pos2 ){
3395 	      t2++;
3396 	    }
3397 	    else {
3398 	      t1++;
3399 	    }
3400 	  }
3401 	  multTrigs.common_pos.push_back(common);
3402 
3403 	  size_t multi_size = d_multTrigs[e].size(); //should be 2
3404 	  for(size_t i =0; i< multi_size; i++){
3405 	    multTrigs.var_binds_found.push_back(new (true) CDMap<Expr, bool> (theoryCore()->getCM()->getCurrentContext()));
3406 	  }
3407 	  multTrigs.uncomm_list.push_back(new ExprMap<CDList<Expr>* >);
3408 	  multTrigs.uncomm_list.push_back(new ExprMap<CDList<Expr>* >);
3409 	  multTrigs.univThm = thm;
3410 	  multTrigs.univ_id = univs_id;
3411 	  d_multitrigs_maps[e] = multTrigs;
3412 	  d_all_multTrigsInfo.push_back(multTrigs);
3413 	}
3414       }
3415     }
3416 
3417   /*
3418   //setup partial triggers
3419   if(*d_usePart)    {
3420     std::vector<Trigger> trig_ex;
3421 
3422     trig_ex.clear();
3423     for( std::vector<Expr>::const_iterator i = subterms.begin(),  iend=subterms.end();  i!=iend;  i++) {
3424       if(isGoodPartTrigger(*i, bVarsThm))  {
3425 	bool notfound = true;
3426 	for(size_t index=0; index<d_partTriggers[e].size(); index++){
3427 	  if (i->subExprOf(d_partTriggers[e][index]))    {
3428 	    (d_partTriggers[e][index])=*i;
3429 	    notfound=false;
3430 	  }
3431 	}
3432 	if (notfound)
3433 	  d_partTriggers[e].push_back(*i);
3434       }
3435     }
3436 
3437     for (size_t  i=0; i< d_partTriggers[e].size();i++){
3438       TRACE("triggers", "partial triggers:", d_partTriggers[e][i].toString(),"");
3439     }
3440 
3441     for (size_t  i=0; i< d_partTriggers[e].size();i++){
3442       Polarity pol= Ukn;
3443       const Expr& cur = d_partTriggers[e][i];
3444       const std::set<Expr> cur_bvs = getBoundVars(cur);
3445       if(cur.getType().isBool()){
3446 	DebugAssert(exprPol.count(e)>0,"unknown polarity:"+cur.toString());
3447 	pol = exprPol[cur];
3448       }
3449 
3450       Trigger* t;
3451       Trigger* t_ex; //so, if a pred is PosNeg, we actually put two triggers into the list, one pos and the other neg
3452 
3453       if(PosNeg == pol && *d_usePolarity){
3454 	t = new Trigger(theoryCore(), cur, Pos, cur_bvs);
3455 	t_ex = new Trigger(theoryCore(), cur, Neg, cur_bvs);
3456       }
3457       else{
3458 	t = new Trigger(theoryCore(), cur, pol, cur_bvs);
3459 	t_ex = NULL;
3460       }
3461 
3462       if(canGetHead(cur)) {
3463 	t->setHead(getHeadExpr(cur));
3464       }
3465 
3466       if(t_ex != NULL)  trig_ex.push_back(*t_ex);
3467 
3468       d_partTrigs[e].push_back(*t);
3469 
3470       TRACE("triggers", "new:part trigger pol:", pol,cur.toString());
3471     }
3472 
3473     for(size_t i=0; i<trig_ex.size(); i++){
3474       d_partTrigs[e].push_back(trig_ex[i]);
3475       TRACE("triggers", "new extra :part triggers:", trig_ex[i].getEx().toString(),"");
3476     }
3477   }
3478   */
3479 }
3480 
3481 
3482 //! test if a sub-term contains more bounded vars than quantified by out-most quantifier.
hasMoreBVs(const Expr & thm)3483 int hasMoreBVs(const Expr& thm){
3484   DebugAssert(thm.isForall(), "hasMoreBVS called by non-forall exprs");
3485 
3486   const std::vector<Expr>& bvsOutmost = thm.getVars();
3487   const std::set<Expr>& bvs = getBoundVars(thm);
3488 
3489   return int(bvs.size()-bvsOutmost.size());
3490 
3491 }
3492 
3493 /*! \brief Theory interface function to assert quantified formulas
3494  *
3495  * pushes in negations and converts to either universally or existentially
3496  * quantified theorems. Universals are stored in a database while
3497  * existentials are enqueued to be handled by the search engine.
3498  */
3499 
3500 //static ExprMap<bool> found_exist;
3501 
assertFact(const Theorem & thm)3502 void TheoryQuant::assertFact(const Theorem& thm){
3503 
3504   if(d_maxILReached){
3505     return;
3506   }
3507   if(*d_translate) return;
3508 
3509   TRACE("quant assertfact", "assertFact => ", thm.toString(), "{");
3510   Theorem rule, result;
3511   const Expr& expr = thm.getExpr();
3512 
3513   // Ignore existentials
3514   if(expr.isExists()) {
3515     TRACE("quant assertfact", "assertFact => (ignoring existential) }", expr.toString(), "");
3516     return;
3517   }
3518 
3519   DebugAssert(expr.isForall() || (expr.isNot() && (expr[0].isExists() || expr[0].isForall())),
3520 	      "Theory of quantifiers cannot handle expression "
3521 	     + expr.toString());
3522 
3523  if(expr.isNot()) {//find the right rule to eliminate negation
3524    if(expr[0].isForall()) {
3525      rule = d_rules->rewriteNotForall(expr);
3526    }
3527    else if(expr[0].isExists()) {
3528      rule = d_rules->rewriteNotExists(expr);
3529    }
3530    result = iffMP(thm, rule);
3531  }
3532  else{
3533    result = thm;
3534  }
3535 
3536  result = d_rules->boundVarElim(result); //eliminate useless bound variables
3537 
3538 
3539  if(result.getExpr().isForall()){
3540 
3541    // Added by Clark:
3542    // If domain of quantified variable is finite and not too big, just do complete instantiation
3543    const vector<Expr>& vars = result.getExpr().getVars();
3544    Unsigned u, count = 1;
3545    Cardinality card;
3546    vector<Expr>::const_iterator it = vars.begin(), iend = vars.end();
3547    for (; it != iend; ++it) {
3548      card = (*it).getType().card();
3549      if (card != CARD_FINITE) {
3550        count = 0;
3551        break;
3552      }
3553      u = (*it).getType().sizeFinite();
3554      if (u > 100) u = 0;
3555      count = count * u;
3556      if (count == 0 || count > 100) {
3557        count = 0;
3558        break;
3559      }
3560    }
3561    bool incomplete = false;
3562    if (count > 0 && count <= 100) {
3563      vector<Expr> terms(vars.size());
3564      vector<Unsigned> indices(vars.size());
3565      for (unsigned i = 0; i < vars.size(); ++i) {
3566        indices[i] = 0;
3567        terms[i] = vars[i].getType().enumerateFinite(0);
3568        if (terms[i].isNull()) {
3569          incomplete = true;
3570          break;
3571        }
3572      }
3573      Theorem thm;
3574      unsigned i = 0;
3575      for (;;) {
3576        thm = d_rules->universalInst(result, terms, 0);
3577        enqueueFact(thm);
3578        while (i < indices.size()) {
3579          indices[i] = indices[i] + 1;
3580          if (indices[i] < vars[i].getType().sizeFinite()) {
3581            terms[i] = vars[i].getType().enumerateFinite(indices[i]);
3582            if (terms[i].isNull()) {
3583              incomplete = true;
3584              i = indices.size();
3585            }
3586            break;
3587          }
3588          ++i;
3589        }
3590        if (i > 0) {
3591          if (i == indices.size()) break;
3592          for (unsigned j = 0; j < i; ++j) {
3593            indices[j] = 0;
3594            terms[j] = vars[j].getType().enumerateFinite(0);
3595          }
3596          i = 0;
3597        }
3598      }
3599      if (!incomplete) return;
3600    }
3601 
3602    if(*d_useNew){
3603 
3604      if(result.getExpr().getBody().isForall()){ // if it is of the form forall x. forall. y
3605        // COMMENT for LFSC on 4-3-2010, Yeting
3606        result=d_rules->packVar(result);
3607 
3608      }
3609      result = d_rules->boundVarElim(result); //eliminate useless bound variables
3610 
3611      //      int nBVs = hasMoreBVs(result.getExpr());
3612      //      if( nBVs >= 1){
3613      //	d_hasMoreBVs[result.getExpr()]=true;
3614      //      }
3615 
3616      if(result.getExpr().isForall()){
3617        d_rawUnivs.push_back(result);
3618      }
3619      else{
3620        enqueueFact(result);
3621      }
3622      return;
3623      /* -------------------------------------- */
3624      //      int nBVs = hasMoreBVs(result.getExpr());
3625 
3626      /*
3627 
3628      if(0 == nBVs){//good
3629      TRACE("quant assertfact", "assertFact => forall enqueueing: ", result.toString(), "}");
3630       	d_univs.push_back(result);
3631 	setupTriggers(result, d_univs.size()-1);
3632       }
3633       else if(1== nBVs){
3634 	d_hasMoreBVs[result.getExpr()]=true;
3635 	const Expr& body = result.getExpr().getBody();
3636 
3637 	if(*d_usePullVar){
3638 	  if((body.isAnd() && body[1].isForall()) || (body.isImpl() && body[1].isForall()) ){
3639 	    result=d_rules->pullVarOut(result);
3640 
3641 	    TRACE("quant assertfact", "assertFact => pull-var enqueueing: ", result.toString(), "}");
3642 
3643 	    d_univs.push_back(result);
3644 	    setupTriggers(result,  d_univs.size()-1);
3645 	  }
3646 	}
3647 	else{
3648 	  TRACE("quant assertfact", "debug:not recognized case", result.toString(), thm.toString());
3649 
3650 	  d_univs.push_back(result);
3651 	  setupTriggers(result,  d_univs.size()-1);
3652 	  return;
3653 	}
3654       }
3655       else{
3656 	d_hasMoreBVs[result.getExpr()]=true;
3657 	d_univs.push_back(result);
3658 	setupTriggers(result,  d_univs.size()-1);
3659 	return;
3660       }
3661       */
3662    }
3663    else{
3664 
3665      TRACE("quant assertfact", "assertFact => old-fashoin enqueueing: ", result.toString(), "}");
3666      //      cout<<"error"<<endl;
3667      d_univs.push_back(result);
3668    }
3669  }
3670  else { //quantifier got eliminated or is an existantial formula
3671    TRACE("quant assertfact", "assertFact => non-forall enqueueing: ", result.toString(), "}");
3672    if(*d_useGFact || true ){
3673      //      addGlobalLemma(result, -1);
3674      enqueueFact(result);
3675    }
3676    else{
3677      enqueueFact(result);
3678      //    enqueueSE(result);
3679    }
3680    /*
3681      {
3682      Expr expr = result.getExpr();
3683      if(expr.isNot()) {
3684      expr = expr[0];
3685      }  ;
3686      if (expr.isExists()){
3687      if(found_exist.find(expr) != found_exist.end()) {
3688      //	  cout<<"again " << expr<<endl;
3689      return;
3690      }
3691      else  found_exist[expr]=true;
3692      }
3693      }
3694    */
3695 
3696    //
3697  }
3698 }
3699 
recGoodSemMatch(const Expr & e,const std::vector<Expr> & bVars,std::vector<Expr> & newInst,std::set<std::vector<Expr>> & instSet)3700 void TheoryQuant::recGoodSemMatch(const Expr& e,
3701 				  const std::vector<Expr>& bVars,
3702 				  std::vector<Expr>& newInst,
3703 				  std::set<std::vector<Expr> >& instSet)
3704 {
3705   size_t curPos = newInst.size();
3706   if (bVars.size() == curPos)    {
3707     Expr simpleExpr = simplifyExpr(e.substExpr(bVars,newInst));
3708     if (simpleExpr.hasFind()){
3709       std::vector<Expr> temp = newInst;
3710       instSet.insert(temp);
3711       TRACE("quant yeting", "new inst found for ", e.toString()+" ==> ", simpleExpr.toString());
3712     };
3713   }
3714   else {
3715     Type t = getBaseType(bVars[curPos]);
3716     std::vector<Expr> tyExprs= d_typeExprMap[t];
3717     if (0 == tyExprs.size())  {
3718       return;//has some problem
3719     }
3720     else{
3721       for (size_t i=0;i<tyExprs.size();i++){
3722 	newInst.push_back(tyExprs[i]);
3723 	recGoodSemMatch(e,bVars,newInst,instSet);
3724 	newInst.pop_back();
3725       }
3726     }
3727   }
3728 }
3729 
3730 
isIntx(const Expr & e,const Rational & x)3731 bool isIntx(const Expr& e, const Rational& x){
3732   if(e.isRational() && e.getRational()==x)
3733     return true;
3734   else return false;
3735 }
3736 
3737 
getLeft(const Expr & e)3738 Expr getLeft(const Expr& e){
3739   if(e.getKind()!= PLUS) return null_expr;
3740   if(e.arity() != 3) return null_expr;
3741   Expr const_expr, minus ,pos;
3742   int numMinus=0, numPos=0, numConst=0;;
3743   for(int i=0; i<e.arity(); i++){
3744     if((e[i]).getKind() == MULT){
3745       if(isIntx(e[i][0], -1)){
3746 	numMinus++;
3747 	minus=e[i][1];
3748       }
3749       else{
3750 	numPos++;
3751 	pos=e[i];
3752       }
3753     }
3754     else if(e[i].isRational())      {
3755       const_expr = e[i];
3756       numConst++;
3757     }
3758     else{
3759       numPos++;
3760       pos=e[i];
3761     }
3762   }
3763   if(1==numPos && 1==numConst && 1==numMinus){
3764     return minus;
3765   }
3766   else{
3767     return null_expr;
3768   }
3769 }
3770 
getRight(const Expr & e)3771 Expr getRight(const Expr& e){
3772   if(e.getKind()!= PLUS) return null_expr;
3773   if(e.arity() != 3) return null_expr;
3774   Expr const_expr, minus ,pos;
3775   int numMinus=0, numPos=0, numConst=0;;
3776 
3777   for(int i=0; i<e.arity(); i++){
3778     if((e[i]).getKind() == MULT){
3779       if(isIntx(e[i][0], -1)){
3780 	numMinus++;
3781 	minus=e[i][1];
3782       }
3783       else{
3784 	numPos++;
3785 	pos=e[i];
3786       }
3787     }
3788     else if(e[i].isRational())      {
3789       const_expr = e[i];
3790       numConst++;
3791     }
3792     else{
3793       numPos++;
3794       pos=e[i];
3795     }
3796   }
3797 
3798   if(1==numPos && 1==numConst && 1==numMinus){
3799     if(isIntx(const_expr,0)){
3800       return pos;
3801     }
3802     else{
3803       //      return null_expr;
3804       return Expr(PLUS, const_expr, pos);
3805     }
3806   }
3807   else{
3808     return null_expr;
3809   }
3810   return null_expr;
3811 }
3812 
add_parent(const Expr & parent)3813 inline void TheoryQuant::add_parent(const Expr& parent){
3814   ExprMap<CDList<Expr>* >::iterator iter;
3815   for(int i=0; i< parent.arity(); i++){
3816     const Expr& child = parent[i];
3817     iter = d_parent_list.find(child);
3818     if(d_parent_list.end() == iter){
3819       d_parent_list[child] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
3820       d_parent_list[child]->push_back(parent);
3821     }
3822     else{
3823       iter->second->push_back(parent);
3824     }
3825   }
3826 }
3827 
collectChangedTerms(CDList<Expr> & changed)3828 void TheoryQuant::collectChangedTerms(CDList<Expr>& changed){
3829   ExprMap<bool> eqs_hash;
3830   ExprMap<bool> changed_hash;
3831   /*
3832   {
3833     for(ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.begin(), iter_end=d_eq_list.end();
3834 	iter != iter_end; iter++){
3835       CDList<Expr>* cur_eqs = iter->second;
3836       int begin_pos;
3837       Expr head = iter->first;
3838       if(d_eq_pos.find(head) == d_eq_pos.end()){
3839 	begin_pos=0;
3840 	d_eq_pos[head]= new(true) CDO<size_t>(theoryCore()->getCM()->getCurrentContext(), 0, 0);
3841 
3842       }
3843       else{
3844 	begin_pos = *(d_eq_pos[head]);
3845       }
3846       for(size_t i=begin_pos; i<cur_eqs->size(); i++){
3847 	eqs_hash[(*cur_eqs)[i]]=true;
3848       }
3849       (d_eq_pos[head])->set(cur_eqs->size());
3850     }
3851     }*/
3852   for(size_t i=d_eqs_pos; i<d_eqs.size(); i++){
3853     eqs_hash[d_eqs[i]]=true;
3854   }
3855   d_eqs_pos.set(d_eqs.size());
3856   {
3857     for(ExprMap<bool>::iterator iter = eqs_hash.begin(), iter_end = eqs_hash.end(); iter != iter_end; iter++){
3858       const Expr& cur_ex = iter->first;
3859       ExprMap<CDList<Expr>* >::iterator iter_parent = d_parent_list.find(cur_ex);
3860       if(d_parent_list.end() != iter_parent){
3861 	CDList<Expr>* cur_parents = iter_parent->second;
3862 	for(size_t i=0; i<cur_parents->size(); i++){
3863 	  changed_hash[(*cur_parents)[i]]=true;
3864 	}
3865       }
3866     }
3867   }
3868   {
3869     for(ExprMap<bool>::iterator iter = changed_hash.begin(), iter_end = changed_hash.end(); iter != iter_end; iter++){
3870       changed.push_back(iter->first);
3871     }
3872   }
3873 }
3874 
3875 /*
3876 inline bool TheoryQuant::matchChild(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
3877   cout<<"error, should not be called, matchChild" << endl;
3878   if(gterm.arity() != vterm.arity()) {
3879     return false;
3880   }
3881   for(int i = 0 ; i< gterm.arity(); i++){ //we should make the matching "flat"
3882     const Expr& cur_v = vterm[i];
3883     const Expr& cur_g = gterm[i];
3884     if(BOUND_VAR == cur_v.getKind()){
3885       ExprMap<Expr>::iterator p = env.find(cur_v);
3886       if ( p != env.end()){
3887 	if (simplifyExpr(cur_g) != simplifyExpr(p->second)){
3888 	  return false;
3889 	}
3890       }
3891       else {
3892 	env[cur_v] = simplifyExpr(cur_g);
3893       }
3894     }
3895     else if (!cur_v.containsBoundVar()){
3896       if(simplifyExpr(cur_v) != simplifyExpr(cur_g)){
3897 	return false;
3898       }
3899     }
3900     else{
3901       if (false == recSynMatch(cur_g, cur_v, env)){
3902 	return false;
3903       }
3904     }
3905   }
3906   return true;
3907 }
3908 
3909 inline void TheoryQuant::matchChild(const Expr& gterm, const Expr& vterm, vector<ExprMap<Expr> >& binds){
3910   cout<<"-error, should not be called more, matchChild" << endl;
3911   ExprMap<Expr> env;
3912   if(gterm.arity() != vterm.arity()) {
3913     return;
3914   }
3915 
3916   for(int i = 0 ; i< gterm.arity(); i++){
3917     const Expr& cur_v = vterm[i];
3918     const Expr& cur_g = gterm[i];
3919     if(BOUND_VAR == cur_v.getKind()){
3920       ExprMap<Expr>::iterator p = env.find(cur_v);
3921       if ( p != env.end()){
3922 	if (simplifyExpr(cur_g) != simplifyExpr(p->second)){
3923 	  return;
3924 	}
3925       }
3926       else {
3927 	env[cur_v] = simplifyExpr(cur_g);
3928       }
3929     }
3930     else if (!cur_v.containsBoundVar()){
3931       if(simplifyExpr(cur_v) != simplifyExpr(cur_g)){
3932 	return ;
3933       }
3934     }
3935     else{
3936       if (false == recSynMatch(cur_g, cur_v, env)){
3937 	return;
3938       }
3939     }
3940   }
3941   binds.push_back(env);
3942   return;
3943 }
3944 */
3945 
3946 /* multMatchChild
3947   input : partial bindings in binds
3948   output: successful bindings in binds
3949 */
multMatchChild(const Expr & gterm,const Expr & vterm,vector<ExprMap<Expr>> & binds,bool top)3950 inline bool TheoryQuant::multMatchChild(const Expr& gterm, const Expr& vterm, vector<ExprMap<Expr> >& binds, bool top){
3951   if(gterm.arity() != vterm.arity()) {
3952     TRACE("multmatch", "not same kind", gterm , vterm);
3953     return false;
3954   }
3955 
3956   //  if (binds.size()>1) {cout<<"match child >1 " <<endl;};
3957 
3958   vector<Expr> allGterms;
3959   allGterms.push_back(gterm);
3960 
3961 
3962  if(!gterm.getSig().isNull() ){
3963     Expr gtermSig = gterm.getSig().getRHS();
3964     if(!top && gterm.hasFind() && !gterm.isAtomicFormula() ) {
3965       Expr curCandidateGterm = gterm.getEqNext().getRHS();
3966       while (curCandidateGterm != gterm){
3967 	if(getHead(curCandidateGterm) == getHead(gterm)
3968 	   &&	!curCandidateGterm.getSig().isNull()
3969 	   &&   curCandidateGterm.getSig().getRHS() != gtermSig
3970 	   &&	getExprScore(curCandidateGterm) <= d_curMaxExprScore
3971 	   ){
3972 	  allGterms.push_back(curCandidateGterm);
3973 	}
3974 	curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
3975       }
3976     }
3977   }
3978 
3979 
3980   vector<ExprMap<Expr> > returnBinds;
3981   for(size_t curGtermIndex =0; curGtermIndex < allGterms.size(); curGtermIndex++)
3982   {
3983     vector<ExprMap<Expr> > currentBinds(binds);
3984 
3985     if(0 == currentBinds.size()){//we need something to work on, even it is empty
3986       ExprMap<Expr> emptyEnv;
3987       currentBinds.push_back(emptyEnv);
3988     }
3989 
3990     Expr gterm = allGterms[curGtermIndex]; //be careful, this gterm hides the gterm in the beginning. fix this soon
3991 
3992     vector<ExprMap<Expr> > nextBinds;
3993 
3994     for(int i = 0 ; i< gterm.arity(); i++){
3995       const Expr& curVterm = vterm[i];
3996       const Expr& curGterm = gterm[i];
3997 
3998       for(size_t curEnvIndex =0; curEnvIndex < currentBinds.size(); curEnvIndex++){
3999 	//maybe we should exchange the iteration of ith child and curentBinds.
4000 	ExprMap<Expr>& curEnv(currentBinds[curEnvIndex]);
4001 	if(BOUND_VAR == curVterm.getKind()){
4002 	  ExprMap<Expr>::iterator iterVterm = curEnv.find(curVterm);
4003 	  if ( iterVterm != curEnv.end()){
4004 	    if (simplifyExpr(curGterm) == simplifyExpr(iterVterm->second)){
4005 	      nextBinds.push_back(curEnv); //success, record the good binding
4006 	    } //else do nothing
4007 	  }
4008 	  else {
4009 	    curEnv[curVterm] = simplifyExpr(curGterm);
4010 	    nextBinds.push_back(curEnv); // success, record the good binding
4011 	  }
4012 	}
4013 	else if (!curVterm.containsBoundVar()){
4014 	  if(simplifyExpr(curVterm) == simplifyExpr(curGterm)){
4015 	    nextBinds.push_back(curEnv); // sueecess, record the good
4016 	  } //else do nothing
4017 	}
4018 	else{
4019 	  vector<ExprMap<Expr> > newBinds;
4020 	  newBinds.push_back(curEnv);
4021 	  bool goodChild = recMultMatch(curGterm, curVterm, newBinds);
4022 	  if(goodChild){
4023 	    for(vector<ExprMap<Expr> >::iterator i = newBinds.begin(), iend = newBinds.end(); i != iend; i++){
4024 	      nextBinds.push_back(*i);
4025 	    }
4026 	  }
4027 	}
4028       }
4029       currentBinds = nextBinds; //nextBinds are good bindings
4030       nextBinds.clear();
4031     }
4032     for(size_t curBindsIndex=0; curBindsIndex < currentBinds.size(); curBindsIndex++){
4033       returnBinds.push_back(currentBinds[curBindsIndex]);
4034     }
4035 
4036   }
4037 
4038   //  binds = currentBinds;
4039   binds = returnBinds;
4040   return (binds.size() > 0) ? true : false;
4041 }
4042 
4043 
4044 //multMatchTop can be called anywhere
multMatchTop(const Expr & gterm,const Expr & vterm,vector<ExprMap<Expr>> & binds)4045 inline bool TheoryQuant::multMatchTop(const Expr& gterm, const Expr& vterm, vector<ExprMap<Expr> >& binds){
4046   vector<ExprMap<Expr> > currentBinds(binds);
4047 
4048   if(0 == currentBinds.size()){//we need something to work on, even it is empty
4049     ExprMap<Expr> emptyEnv;
4050     currentBinds.push_back(emptyEnv);
4051   }
4052 
4053   vector<ExprMap<Expr> > nextBinds;
4054 
4055   const Expr& curVterm = vterm;
4056   const Expr& curGterm = gterm;
4057 
4058   for(size_t curEnvIndex =0; curEnvIndex < currentBinds.size(); curEnvIndex++){
4059     ExprMap<Expr>& curEnv(currentBinds[curEnvIndex]);
4060     vector<ExprMap<Expr> > newBinds;
4061     newBinds.push_back(curEnv);
4062     bool goodChild = recMultMatch(curGterm, curVterm, newBinds);
4063     if(goodChild){
4064       for(vector<ExprMap<Expr> >::iterator i = newBinds.begin(), iend = newBinds.end(); i != iend; i++){
4065 	nextBinds.push_back(*i);
4066       }
4067     }
4068   }
4069   binds = nextBinds; //nextBinds stores the good bindings
4070   return (binds.size() > 0) ? true : false;
4071 }
4072 
4073 
4074 //match a gterm against all the trigs in d_allmap_trigs
matchListOld(const CDList<Expr> & glist,size_t gbegin,size_t gend)4075 void TheoryQuant::matchListOld(const CDList<Expr>& glist, size_t gbegin, size_t gend){
4076   for(size_t g_index = gbegin; g_index < gend; g_index++){
4077 
4078     const Expr& gterm = glist[g_index];
4079     //    cout<<"matching old "<<gterm<<endl;
4080     if(gterm.isEq()){
4081       continue; // we do not match with equality
4082     }
4083 
4084      if(gterm.getSig().isNull() ){
4085        if ( ! ( (gterm.hasFind() && !canGetHead(gterm.getFind().getRHS())) || gterm.getType().isBool() )  ){
4086 // 	 cout<<"gterm skipped " << gterm << endl;
4087 // 	 cout<<"Find? " << (gterm.hasFind() ? gterm.getFind().getExpr().toString() : "NO " ) << endl;
4088 // 	 cout<<"Rep?  " << (gterm.hasRep() ? gterm.getRep().getExpr().toString() : "NO " ) << endl;
4089 	 continue;
4090        }
4091      }
4092 
4093     Expr head = getHead(gterm);
4094 
4095     ExprMap<CDMap<Expr, CDList<dynTrig>* > *>::iterator iter = d_allmap_trigs.find(head);
4096     if(d_allmap_trigs.end() == iter) continue;
4097     CDMap<Expr, CDList<dynTrig>*>* cd_map = iter->second;
4098 
4099 //     if(cd_map->size()>10){
4100 //       cout<<"map size1:"<<cd_map->size()<<endl;
4101 //       cout<<head<<endl;
4102 //     }
4103 
4104     CDMap<Expr, CDList<dynTrig>*>::iterator iter_trig = (*cd_map).begin();
4105     CDMap<Expr, CDList<dynTrig>*>::iterator iter_trig_end = (*cd_map).end();
4106 
4107     for(;iter_trig != iter_trig_end; iter_trig++){
4108       CDList<dynTrig>* cur_list = (*iter_trig).second;
4109       if(1 == cur_list->size() || null_expr == head || gterm.getType().isBool() ){
4110 	for(size_t cur_index =0; cur_index < cur_list->size(); cur_index++){
4111 
4112 	  const Trigger& cur_trig = (*cur_list)[cur_index].trig;
4113 	  size_t univ_id = (*cur_list)[cur_index].univ_id;
4114 	  vector<ExprMap<Expr> > binds;
4115 	  const Expr& vterm = cur_trig.trig;
4116 	  if(vterm.getKind() != gterm.getKind()) continue;
4117 
4118 
4119 // 	  if(*d_useNewEqu){
4120 // 	    if  ( d_allout && cur_trig.isSuperSimple ) continue; //delete this after test yeting
4121 // 	  }
4122 
4123 	  if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans && !cur_trig.isMulti) continue;
4124 	    //      if  ( d_allout && cur_trig.isSimple ) continue;
4125 
4126 	  newTopMatch(gterm, vterm, binds, cur_trig);
4127 
4128 	  for(size_t i=0; i<binds.size(); i++){
4129 	    ExprMap<Expr>& cur_map = binds[i];
4130 	    vector<Expr> bind_vec;
4131 	    const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
4132 	    for(size_t j=0; j< bVarsThm.size(); j++){
4133 	      bind_vec.push_back(cur_map[bVarsThm[j]]);
4134 	    }
4135 	    synNewInst(univ_id, bind_vec, gterm, cur_trig);
4136 	  }
4137 	}
4138       }
4139       else if ( cur_list->size() > 1){
4140 
4141 	const Trigger& cur_trig = (*cur_list)[0].trig;//here we have a polarity problem
4142 
4143 	const Expr& general_vterm = (*iter_trig).first;
4144 
4145 	//	cout<<"matching new trig case 2:"<<general_vterm<<endl;
4146 
4147 	if(general_vterm.getKind() != gterm.getKind()) continue;
4148 	vector<ExprMap<Expr> > binds;
4149 
4150 // 	if(*d_useNewEqu){
4151 // 	  if  ( d_allout && cur_trig.isSuperSimple ) continue; //delete this after test yeting
4152 // 	}
4153 	if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans && !cur_trig.isMulti) continue;
4154 	//if  ( d_allout && cur_trig.isSimple ) continue;
4155 
4156 	newTopMatch(gterm, general_vterm, binds, cur_trig);
4157 
4158  	for(size_t bindsIndex = 0 ; bindsIndex < binds.size() ; bindsIndex++){
4159 	  // 	  cout<<"i = " << bindsIndex << " : " << exprMap2string(binds[bindsIndex]) << endl ;
4160  	}
4161 
4162 	if(binds.size() <= 0) continue;
4163 
4164 	for(size_t trig_index = 0; trig_index< cur_list->size(); trig_index++){
4165 	  size_t univ_id = (*cur_list)[trig_index].univ_id;
4166 	  const ExprMap<Expr>& trig_map = (*cur_list)[trig_index].binds;
4167 	  const Trigger& ind_cur_trig = (*cur_list)[trig_index].trig;
4168 	  for(size_t i=0; i<binds.size(); i++){
4169 	    ExprMap<Expr>& cur_map = binds[i];
4170 	    vector<Expr> bind_vec;
4171 	    const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
4172 	    for(size_t j=0; j< bVarsThm.size(); j++){
4173 	      const Expr& inter=(*(trig_map.find(bVarsThm[j]))).second;
4174 	      const Expr& inter2 = cur_map[inter];
4175 	      bind_vec.push_back(inter2);
4176 	    }
4177 	    //	    cout<<"==++ for instantiation " << d_univs[univ_id] <<endl;
4178 	    //	    cout<<"==--  bings " << vectorExpr2string(bind_vec) <<endl;
4179 	    synNewInst(univ_id, bind_vec, gterm, ind_cur_trig);
4180 	  }
4181 	  //	  cout<<"==** end \n";
4182 	}
4183       }
4184       else{
4185 	FatalAssert(false, "error in matchlistold");
4186       }
4187     }//end of for each trig begins with head
4188   }//end of each gterm
4189 }
4190 
delNewTrigs(ExprMap<ExprMap<std::vector<dynTrig> * > * > & new_trigs)4191 void TheoryQuant::delNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs){
4192   //return;
4193   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator i = new_trigs.begin();
4194   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator iend = new_trigs.end();
4195   for(; i!=iend; i++){
4196     ExprMap<std::vector<dynTrig>*>* cur_new_cd_map = i->second;
4197     ExprMap<vector<dynTrig>* >::iterator j = cur_new_cd_map->begin();
4198     ExprMap<vector<dynTrig>* >::iterator jend = cur_new_cd_map->end();
4199       for(; j!=jend; j++){
4200 	Expr general_trig = j->first;
4201 	vector<dynTrig>* trigs = j->second;
4202 	delete trigs;
4203       }
4204       delete cur_new_cd_map;
4205     }
4206   new_trigs.clear();
4207 }
4208 
4209 
combineOldNewTrigs(ExprMap<ExprMap<std::vector<dynTrig> * > * > & new_trigs)4210 void TheoryQuant::combineOldNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs){
4211   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator i = new_trigs.begin();
4212   ExprMap<ExprMap<std::vector<dynTrig>*>*>::iterator iend = new_trigs.end();
4213   for(; i!=iend; i++){
4214     ExprMap<std::vector<dynTrig>*>* cur_new_cd_map = i->second;
4215     Expr head = i->first;
4216     ExprMap<CDMap<Expr, CDList<dynTrig>* >* >::iterator old_iter = d_allmap_trigs.find(head);
4217     if(d_allmap_trigs.end() == old_iter){
4218       CDMap<Expr, CDList<dynTrig>* >* old_cd_map =
4219 	//	new(true) CDMap<Expr, CDList<dynTrig>* > (theoryCore()->getCM()->getCurrentContext());
4220 	new(false) CDMap<Expr, CDList<dynTrig>* > (theoryCore()->getCM()->getCurrentContext());
4221       d_allmap_trigs[head] = old_cd_map;
4222       ExprMap<vector<dynTrig>* >::iterator j = cur_new_cd_map->begin();
4223       ExprMap<vector<dynTrig>* >::iterator jend = cur_new_cd_map->end();
4224       for(; j!=jend; j++){
4225 	Expr general_trig = j->first;
4226 	vector<dynTrig>* trigs = j->second;
4227 	CDList<dynTrig>* old_cd_list =
4228 	  //new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
4229 	  new(false) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
4230 	(*old_cd_map)[general_trig] = old_cd_list;
4231 	for(size_t k=0; k<trigs->size(); k++){
4232 	  (*old_cd_list).push_back((*trigs)[k]);
4233 	  //	  cout<<"combined 1 "<<(*trigs)[k].trig.getEx()<<endl;
4234 	}
4235 	//	delete trigs;
4236       }
4237       //      delete cur_new_cd_map;
4238     }
4239     else{
4240       CDMap<Expr, CDList<dynTrig>* >* old_cd_map = old_iter->second;
4241       ExprMap<std::vector<dynTrig>*>::iterator j = cur_new_cd_map->begin();
4242       ExprMap<std::vector<dynTrig>*>::iterator jend = cur_new_cd_map->end();
4243       for(; j!=jend; j++){
4244 	Expr general_trig = j->first;
4245 	vector<dynTrig>* trigs = j->second;
4246 	CDMap<Expr, CDList<dynTrig>* >::iterator old_trigs_iter = old_cd_map->find(general_trig);
4247 	CDList<dynTrig>* old_cd_list;
4248 	if(old_cd_map->end() == old_trigs_iter){
4249 	 old_cd_list =
4250 	   //new(true) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
4251 	   new(false) CDList<dynTrig> (theoryCore()->getCM()->getCurrentContext());
4252 	 (*old_cd_map)[general_trig] = old_cd_list;
4253 	}
4254 	else{
4255 	  old_cd_list = (*old_trigs_iter).second;
4256 	}
4257 	for(size_t k=0; k<trigs->size(); k++){
4258 	  (*old_cd_list).push_back((*trigs)[k]);
4259 	  //	  cout<<"combined 2 "<<(*trigs)[k].trig.getEx()<<endl;
4260 	}
4261 	//	delete trigs;
4262       }
4263       //      delete cur_new_cd_map;
4264     }
4265   }
4266   delNewTrigs(new_trigs);
4267   new_trigs.clear();
4268 }
4269 
4270 //match a gterm against all the trigs in d_allmap_trigs
matchListNew(ExprMap<ExprMap<vector<dynTrig> * > * > & new_trigs,const CDList<Expr> & glist,size_t gbegin,size_t gend)4271 void TheoryQuant::matchListNew(ExprMap<ExprMap<vector<dynTrig>*>*>& new_trigs,
4272 			       const CDList<Expr>& glist,
4273 			       size_t gbegin,
4274 			       size_t gend){
4275   //return;
4276   //  if(!d_allout) return;
4277   for(size_t g_index = gbegin; g_index<gend; g_index++){
4278 
4279     const Expr& gterm = glist[g_index];
4280     //    cout<<"matching new "<<gterm<<endl;
4281     if(gterm.isEq()){
4282       continue; // we do not match with equality
4283     }
4284 
4285     if(gterm.getSig().isNull()){
4286       //add the code as in matchlistold
4287 
4288 //      continue;
4289     }
4290 
4291     Expr head = getHead(gterm);
4292 
4293     ExprMap<ExprMap<vector<dynTrig>* > *>::iterator iter = new_trigs.find(head);
4294     if(new_trigs.end() == iter) continue;
4295     ExprMap<vector<dynTrig>*>* cd_map = iter->second;
4296 //     if(cd_map->size()>10){
4297 //       cout<<"map size2:"<<cd_map->size()<<endl;
4298 //       cout<<head<<endl;
4299 //     }
4300 
4301     ExprMap<vector<dynTrig>*>::iterator iter_trig = (*cd_map).begin();
4302     ExprMap<vector<dynTrig>*>::iterator iter_trig_end = (*cd_map).end();
4303 
4304     for(;iter_trig != iter_trig_end; iter_trig++){
4305 
4306       vector<dynTrig>* cur_list = (*iter_trig).second;
4307       if(1 == cur_list->size() || null_expr == head ||  gterm.getType().isBool() ){
4308 	for(size_t cur_index =0; cur_index < cur_list->size(); cur_index++){
4309 	  const Trigger& cur_trig = (*cur_list)[cur_index].trig;
4310 
4311 // 	  if(*d_useNewEqu){
4312 //	  if  ( d_allout &&  cur_trig.isSuperSimple ) continue; //delete this after test yeting
4313 // 	  }
4314 
4315 	  if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans) continue;
4316 
4317 	  size_t univ_id = (*cur_list)[cur_index].univ_id;
4318 	  vector<ExprMap<Expr> > binds;
4319 	  const Expr& vterm = cur_trig.trig;
4320 	  if(vterm.getKind() != gterm.getKind()) continue;
4321 	  newTopMatch(gterm, vterm, binds, cur_trig);
4322 	  for(size_t i=0; i<binds.size(); i++){
4323 	    ExprMap<Expr>& cur_map = binds[i];
4324 	    vector<Expr> bind_vec;
4325 	    const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
4326 	    for(size_t j=0; j< bVarsThm.size(); j++){
4327 	      bind_vec.push_back(cur_map[bVarsThm[j]]);
4328 	    }
4329 	    synNewInst(univ_id, bind_vec, gterm, cur_trig);
4330 	  }
4331 	}
4332       }
4333       else if ( cur_list->size() > 1){
4334 
4335 	const Trigger& cur_trig = (*cur_list)[0].trig;//here we have a polarity problem
4336 
4337 // 	if(*d_useNewEqu){
4338 // 	  if  ( d_allout &&  cur_trig.isSuperSimple ) continue; //delete this after test yeting
4339 // 	}
4340 
4341 //	if  ( d_allout && cur_trig.isSuperSimple && !cur_trig.hasTrans) continue;
4342 
4343 	const Expr& general_vterm = (*iter_trig).first;
4344 	if(general_vterm.getKind() != gterm.getKind()) continue;
4345 	vector<ExprMap<Expr> > binds;
4346 	newTopMatch(gterm, general_vterm, binds, cur_trig);
4347 
4348 	if(binds.size() <= 0) continue;
4349 	for(size_t trig_index = 0; trig_index< cur_list->size(); trig_index++){
4350 	  size_t univ_id = (*cur_list)[trig_index].univ_id;
4351 	  const Trigger& ind_cur_trig = (*cur_list)[trig_index].trig;
4352 	  const ExprMap<Expr>& trig_map = (*cur_list)[trig_index].binds;
4353 
4354 	  for(size_t i=0; i<binds.size(); i++){
4355 	    ExprMap<Expr>& cur_map = binds[i];
4356 	    vector<Expr> bind_vec;
4357 	    const vector<Expr>& bVarsThm = d_univs[univ_id].getExpr().getVars();
4358 	    for(size_t j=0; j< bVarsThm.size(); j++){
4359 	      const Expr& inter=(*(trig_map.find(bVarsThm[j]))).second;
4360 	      const Expr& inter2 = cur_map[inter];
4361 	      bind_vec.push_back(inter2);
4362 	    }
4363 	    synNewInst(univ_id, bind_vec, gterm, ind_cur_trig);
4364 	  }
4365 	}
4366       }
4367       else{
4368 	FatalAssert(false, "error in matchlistnew");
4369       }
4370     }//end of for each trig begins with head
4371   }// end of each gterm
4372 }
4373 
4374 
4375 
4376 //void TheoryQuant::newTopMatchNoSig(const Expr& gtermOrg,
newTopMatchNoSig(const Expr & gterm,const Expr & vterm,vector<ExprMap<Expr>> & binds,const Trigger & trig)4377 void TheoryQuant::newTopMatchNoSig(const Expr& gterm,
4378 				   const Expr& vterm,
4379 				   vector<ExprMap<Expr> >& binds,
4380 				   const Trigger& trig){
4381 
4382   //  cout<<"matching " << gterm << endl << "----" << endl << vterm << endl;
4383 
4384   if(trig.isSuperSimple){
4385     ExprMap<Expr>  cur_bind;
4386     for(int i = vterm.arity()-1; i>=0 ; i--){
4387       cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
4388     }
4389     binds.push_back(cur_bind);
4390     return;
4391   }
4392 
4393   if(trig.isSimple){
4394     ExprMap<Expr>  cur_bind;
4395     for(int i = vterm.arity()-1; i>=0 ; i--){
4396       if(BOUND_VAR != vterm[i].getKind()){
4397 	if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
4398 	  return ;
4399 	}
4400       }
4401       else{
4402 	if(getBaseType(vterm[i]) == (getBaseType(gterm[i]))){
4403 	  cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
4404 	}
4405 	else return;
4406       }
4407     }
4408     binds.push_back(cur_bind);
4409     return;
4410   }
4411 
4412   if(!isSysPred(vterm)){ //then gterm cannot be a syspred
4413     if(!gterm.getType().isBool()){
4414       //      res2= recSynMatch(gterm, vterm, env);
4415       multMatchChild(gterm, vterm, binds, true);
4416       return;
4417     }
4418 
4419     //    DebugAssert(falseExpr()==findExpr(gterm) || trueExpr()==findExpr(gterm), " why ");
4420 
4421     multMatchChild(gterm, vterm, binds, true);
4422     return;
4423 
4424     if(!*d_usePolarity){
4425       //      return recSynMatch(gterm, vterm, env);
4426       multMatchChild(gterm, vterm, binds);
4427       return;
4428     }
4429 
4430     const bool gtrue = (trueExpr()==findExpr(gterm));
4431     //    const bool gtrue = (trueExpr()==simplifyExpr(gterm));
4432     if(gtrue ){
4433       if((Neg==trig.polarity || PosNeg==trig.polarity)) {
4434 	//	return recSynMatch(gterm, vterm, env);
4435 	multMatchChild(gterm, vterm, binds);
4436 	return;
4437       }
4438       else{
4439 	//	cout<<"returned 1"<<endl;
4440 	return;
4441       }
4442     }
4443     const bool gfalse = (falseExpr()==findExpr(gterm));
4444     //const bool gfalse = (falseExpr()==simplifyExpr(gterm));
4445     if(gfalse){
4446       if((Pos==trig.polarity || PosNeg==trig.polarity)) {
4447 	//	return recSynMatch(gterm, vterm, env);
4448 	multMatchChild(gterm, vterm, binds); //it is possible that we need binds here, not a single bind
4449 	return;
4450       }
4451       else{
4452 	//	cout<<"returned 2"<<endl;
4453 	return;
4454       }
4455     }
4456 
4457 //     cout<<"impossible here in new top match"<<endl;
4458 //     cout<<"vterm "<<vterm<<endl;
4459 //     cout<<"gterm " <<gterm<<endl;
4460 //     cout<<trig.polarity<<endl;
4461 //     cout<<"gtrue and gfalse: " << gtrue<<" |and| " <<gfalse<<endl;
4462 //     return;
4463     multMatchChild(gterm, vterm, binds);
4464 
4465     return;
4466   }
4467   else{ // must be syspreds
4468     //we can move the work to split vterm into left and right into setuptriggers
4469     Expr gl = getLeft(gterm[1]);
4470     Expr gr = getRight(gterm[1]);
4471 
4472     if(null_expr == gr || null_expr == gl){
4473       gl = gterm[0];
4474       gr = gterm[1];
4475     }
4476 
4477     Expr vr, vl;
4478     Expr tvr, tvl;
4479 
4480     tvr=null_expr;
4481     tvl=null_expr;
4482 
4483     if(isGE(vterm) || isGT(vterm)){
4484       vr = vterm[0];
4485       vl = vterm[1];
4486     }
4487     else if(isLE(vterm) || isLT(vterm)){
4488       vr = vterm[1];
4489       vl = vterm[0];
4490     }
4491     else{
4492       FatalAssert(false, "impossilbe in toppred");
4493     }
4494 
4495     if(isIntx(vl,0)){
4496       tvl = getLeft(vr);
4497       tvr = getRight(vr);
4498     }
4499     else if(isIntx(vr,0)) {
4500       tvl = getLeft(vl);
4501       tvr = getRight(vl);
4502     }
4503 
4504     if( (null_expr != tvl) && (null_expr != tvr)){
4505       vl = tvl;
4506       vr = tvr;
4507     }
4508 
4509 
4510     const bool gtrue = (trueExpr()==findExpr(gterm));
4511     const bool gfalse = (falseExpr()==findExpr(gterm));
4512 
4513     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
4514 
4515     //    DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
4516 
4517     if(!*d_usePolarity){
4518       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
4519 	return;
4520       }
4521       else{
4522 	return;
4523       }
4524     }
4525     if((Neg==trig.polarity || PosNeg==trig.polarity)) {
4526       if (( gtrue ) )  {
4527 	if (multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
4528 	  return;
4529 	}
4530 	else{
4531 	  return;
4532 	}
4533       }
4534       else {
4535 	if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
4536 	  return;
4537 	}
4538 	else{
4539 	  return;
4540 	}
4541       }
4542     }
4543     else if((Pos==trig.polarity || PosNeg==trig.polarity)) {
4544       if (( gfalse )) {
4545 	if(multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
4546 	  return;
4547 	}
4548 	else{
4549 	  return;
4550 	}
4551       }
4552       else {
4553 	if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
4554 	  return;
4555 	}
4556 	else{
4557 	  return;
4558 	}
4559       }
4560     }
4561     else {
4562       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
4563 	// it is possible that cur_bind will be binds
4564 	return;
4565       }
4566       else{
4567 	return;
4568       }
4569       return;
4570     }
4571   }
4572 }
4573 
4574 
4575 
4576 // std::string exprChild2string(const Expr& expr){
4577 //   std::string result;
4578 //   result.append("head is: ");
4579 //   result.append(getHead(expr).toString());
4580 //   result.append("\n");
4581 //   for(int i = 0; i < expr.arity(); i++){
4582 //     result.append(int2string(i));
4583 //     result.append(": ");
4584 //     result.append(expr[i].toString());
4585 //     result.append("\n");
4586 //   }
4587 //   result.append("---- end ---- \n");
4588 //   return result;
4589 // }
4590 
4591 //wrap function for newTopMatch, for test only
newTopMatch(const Expr & gtermOrg,const Expr & vterm,vector<ExprMap<Expr>> & binds,const Trigger & trig)4592 void TheoryQuant::newTopMatch(const Expr& gtermOrg,
4593 			      const Expr& vterm,
4594 			      vector<ExprMap<Expr> >& binds,
4595 			      const Trigger& trig){
4596 
4597   //return   newTopMatchSig(gtermOrg,vterm, binds, trig);
4598 
4599   return   newTopMatchNoSig(gtermOrg,vterm, binds, trig);
4600 
4601 //   cout<<"gterm org: " << gtermOrg << endl;
4602 //   cout<<"vterm org: " << vterm << endl;
4603 
4604 //   if(isPow(gtermOrg)){
4605 //     if(isIntx(gtermOrg[0],2)){
4606 //       vector<Expr> mults;
4607 //       mults.push_back(gtermOrg[1]);
4608 //       mults.push_back(gtermOrg[1]);
4609 //       cout<<"new expr" << multExpr(mults) << endl;;
4610 //     }
4611 //     else{
4612 //       cout <<"cannot do this"<<endl;
4613 //     }
4614 
4615 //   }
4616 
4617   vector<ExprMap<Expr> > oldBinds;
4618   newTopMatchNoSig(gtermOrg,vterm, oldBinds, trig);
4619   vector<ExprMap<Expr> > newBinds;
4620   newTopMatchSig(gtermOrg,vterm, newBinds, trig);
4621 
4622   vector<ExprMap<Expr> > oldBindsBack(oldBinds);
4623   vector<ExprMap<Expr> > newBindsBack(newBinds);
4624 
4625   simplifyVectorExprMap(oldBinds);
4626   simplifyVectorExprMap(newBinds);
4627 
4628   if (false && oldBinds != newBinds){
4629 
4630     cout<<"let us see" << endl;
4631     cout<< "===gterm is    : " << gtermOrg << endl ;;
4632 //     cout<< exprChild2string(gtermOrg) << endl;
4633 //     cout<< exprChild2string(gtermOrg[0]) << endl;
4634 //     cout<< exprChild2string(gtermOrg[1]) << endl;
4635     if(gtermOrg.isApply() && gtermOrg.hasSig()){
4636       Expr sig = gtermOrg.getSig().getRHS();
4637       cout << "\n---gterm sig is: " << sig << endl;
4638 //       cout << exprChild2string(sig) << endl;
4639 //       cout << exprChild2string(sig[0]) << endl;
4640 //       cout << exprChild2string(sig[1]) << endl;
4641     }
4642     //    cout << "vterm is " << vterm << endl << exprChild2string(vterm) << endl;
4643 //     cout << exprChild2string(vterm[0]) << endl;
4644 //     cout << exprChild2string(vterm[1]) << endl;
4645 
4646     for(size_t oldBindsIndex = 0; oldBindsIndex < oldBinds.size(); oldBindsIndex++){
4647       cout << "--O- " << oldBindsIndex << endl;
4648       cout << exprMap2string(oldBindsBack[oldBindsIndex]) << endl;
4649       cout << exprMap2string(oldBinds[oldBindsIndex]) << endl;
4650       cout << exprMap2stringSimplify(oldBinds[oldBindsIndex]) << endl;
4651       cout << exprMap2stringSig(oldBinds[oldBindsIndex]) << endl;
4652     }
4653 
4654     for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
4655       cout << "--N- " << newBindsIndex << endl;
4656       cout << exprMap2string(newBindsBack[newBindsIndex]) << endl;
4657       cout << exprMap2string(newBinds[newBindsIndex]) << endl;
4658       cout << exprMap2stringSimplify(newBinds[newBindsIndex]) << endl;
4659       cout << exprMap2stringSig(newBinds[newBindsIndex]) << endl;
4660     }
4661 
4662   }
4663 
4664 
4665     //binds = newBinds;
4666   //  cout<<"newbinds size" << newBinds.size() << endl;
4667   binds = oldBinds;
4668   return;
4669 }
4670 
newTopMatchSig(const Expr & gtermOrg,const Expr & vterm,vector<ExprMap<Expr>> & binds,const Trigger & trig)4671 void TheoryQuant::newTopMatchSig(const Expr& gtermOrg,
4672 				 const Expr& vterm,
4673 				 vector<ExprMap<Expr> >& binds,
4674 				 const Trigger& trig){
4675 
4676   //  cout<<"matching " << gterm << endl << "----" << endl << vterm << endl;
4677   Expr gterm;
4678   if(gtermOrg.isApply() && gtermOrg.hasSig()){
4679     gterm = gtermOrg.getSig().getRHS();
4680   }
4681   else{
4682     gterm = gtermOrg;
4683   }
4684 
4685 
4686   if(trig.isSuperSimple){
4687     ExprMap<Expr>  cur_bind;
4688     for(int i = vterm.arity()-1; i>=0 ; i--){
4689       cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
4690     }
4691     binds.push_back(cur_bind);
4692     return;
4693   }
4694 
4695   if(trig.isSimple){
4696     ExprMap<Expr>  cur_bind;
4697     for(int i = vterm.arity()-1; i>=0 ; i--){
4698       if(BOUND_VAR != vterm[i].getKind()){
4699 	if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
4700 	  return ;
4701 	}
4702       }
4703       else{
4704 	if (getBaseType(vterm[i])==getBaseType(gterm[i])){
4705 	  cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
4706 	}
4707 	else return;
4708       }
4709     }
4710     binds.push_back(cur_bind);
4711     return;
4712   }
4713 
4714   if(!isSysPred(vterm)){ //then gterm cannot be a syspred
4715     if(!gterm.getType().isBool()){
4716       //      res2= recSynMatch(gterm, vterm, env);
4717       multMatchChild(gterm, vterm, binds);
4718       return;
4719     }
4720 
4721 
4722     //    DebugAssert(falseExpr()==findExpr(gterm) || trueExpr()==findExpr(gterm), " why ");
4723 
4724     //    multMatchChild(gterm, vterm, binds);
4725     //    return;
4726 
4727     // when man trig is enabled, we should not use polarity because the manual triggers do not have polairities.
4728     // should I fix this?
4729     if(!*d_usePolarity || d_useManTrig){
4730       //      return recSynMatch(gterm, vterm, env);
4731       multMatchChild(gterm, vterm, binds);
4732       return;
4733     }
4734 
4735     const bool gtrue = (trueExpr()==findExpr(gterm));
4736     //    const bool gtrue = (trueExpr()==simplifyExpr(gterm));
4737     if(gtrue ){
4738       if((Neg==trig.polarity || PosNeg==trig.polarity)) {
4739 	//	return recSynMatch(gterm, vterm, env);
4740 	multMatchChild(gterm, vterm, binds);
4741 	return;
4742       }
4743       else{
4744 	//	cout<<"returned 1"<<endl;
4745 	return;
4746       }
4747     }
4748     const bool gfalse = (falseExpr()==findExpr(gterm));
4749     //const bool gfalse = (falseExpr()==simplifyExpr(gterm));
4750     if(gfalse){
4751       if((Pos==trig.polarity || PosNeg==trig.polarity)) {
4752 	//	return recSynMatch(gterm, vterm, env);
4753 	multMatchChild(gterm, vterm, binds); //it is possible that we need binds here, not a single bind
4754 	return;
4755       }
4756       else{
4757 	//	cout<<"returned 2"<<endl;
4758 	return;
4759       }
4760     }
4761 
4762 
4763     FatalAssert(false, "impossible");
4764     cout<<"impossible here in new top match"<<endl;
4765     cout<<"vterm "<<vterm<<endl;
4766     cout<<"gterm " <<gterm<<endl;
4767     cout<<trig.polarity<<endl;
4768     cout<<"gtrue and gfalse: " << gtrue<<" |and| " <<gfalse<<endl;
4769     return;
4770     multMatchChild(gterm, vterm, binds);
4771 
4772     return;
4773   }
4774   else{ // must be syspreds
4775     //we can move the work to split vterm into left and right into setuptriggers
4776     Expr gl = getLeft(gterm[1]);
4777     Expr gr = getRight(gterm[1]);
4778 
4779     if(null_expr == gr || null_expr == gl){
4780       gl = gterm[0];
4781       gr = gterm[1];
4782     }
4783 
4784     Expr vr, vl;
4785     Expr tvr, tvl;
4786 
4787     tvr=null_expr;
4788     tvl=null_expr;
4789 
4790     if(isGE(vterm) || isGT(vterm)){
4791       vr = vterm[0];
4792       vl = vterm[1];
4793     }
4794     else if(isLE(vterm) || isLT(vterm)){
4795       vr = vterm[1];
4796       vl = vterm[0];
4797     }
4798     else{
4799       FatalAssert(false, "impossilbe in toppred");
4800     }
4801 
4802     if(isIntx(vl,0)){
4803       tvl = getLeft(vr);
4804       tvr = getRight(vr);
4805     }
4806     else if(isIntx(vr,0)) {
4807       tvl = getLeft(vl);
4808       tvr = getRight(vl);
4809     }
4810 
4811     if( (null_expr != tvl) && (null_expr != tvr)){
4812       vl = tvl;
4813       vr = tvr;
4814     }
4815 
4816 
4817     const bool gtrue = (trueExpr()==findExpr(gterm));
4818     const bool gfalse = (falseExpr()==findExpr(gterm));
4819 
4820     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
4821 
4822     //    DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
4823 
4824     if(!*d_usePolarity){
4825       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
4826 	return;
4827       }
4828       else{
4829 	return;
4830       }
4831     }
4832     if((Neg==trig.polarity || PosNeg==trig.polarity)) {
4833       if (( gtrue ) )  {
4834 	if (multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
4835 	  return;
4836 	}
4837 	else{
4838 	  return;
4839 	}
4840       }
4841       else {
4842 	if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
4843 	  return;
4844 	}
4845 	else{
4846 	  return;
4847 	}
4848       }
4849     }
4850     else if((Pos==trig.polarity || PosNeg==trig.polarity)) {
4851       if (( gfalse )) {
4852 	if(multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds)){
4853 	  return;
4854 	}
4855 	else{
4856 	  return;
4857 	}
4858       }
4859       else {
4860 	if(multMatchTop(gl, vr, binds) && multMatchTop(gr, vl, binds)){
4861 	  return;
4862 	}
4863 	else{
4864 	  return;
4865 	}
4866       }
4867     }
4868     else {
4869       if((multMatchTop(gl, vl, binds) && multMatchTop(gr, vr, binds))){
4870 	// it is possible that cur_bind will be binds
4871 	return;
4872       }
4873       else{
4874 	return;
4875       }
4876       return;
4877     }
4878   }
4879 }
4880 
4881 
4882 /*
4883 void TheoryQuant::newTopMatchBackupOnly(const Expr& gterm,
4884 					const Expr& vterm,
4885 					vector<ExprMap<Expr> >& binds,
4886 					const Trigger& trig){
4887   cout<<"-error should not be called more,  newTopMatchBackupOnly" << endl;
4888   ExprMap<Expr>  cur_bind;
4889   //  cout<<"matching " << gterm << " +++ " <<vterm<<endl;
4890   if(trig.isSuperSimple){
4891     for(int i = vterm.arity()-1; i>=0 ; i--){
4892       cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
4893     }
4894     binds.push_back(cur_bind);
4895     return;
4896   }
4897 
4898   if(trig.isSimple){
4899     for(int i = vterm.arity()-1; i>=0 ; i--){
4900       if(BOUND_VAR != vterm[i].getKind()){
4901 	if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
4902 	  return ;
4903 	}
4904       }
4905       else{
4906 	cur_bind[vterm[i]] = simplifyExpr(gterm[i]);
4907       }
4908     }
4909     binds.push_back(cur_bind);
4910     return;
4911   }
4912 
4913 
4914   if(!isSysPred(vterm)){ //then gterm cannot be a syspred
4915     if(!gterm.getType().isBool()){
4916       //      res2= recSynMatch(gterm, vterm, env);
4917       matchChild(gterm, vterm, binds);
4918       return;
4919     }
4920 
4921     matchChild(gterm, vterm, binds);
4922     return;
4923 
4924 
4925     if(!*d_usePolarity){
4926       //      return recSynMatch(gterm, vterm, env);
4927       matchChild(gterm, vterm, binds);
4928       return;
4929     }
4930 
4931     const bool gtrue = (trueExpr()==findExpr(gterm));
4932     //    const bool gtrue = (trueExpr()==simplifyExpr(gterm));
4933     if(gtrue ){
4934       if((Neg==trig.polarity || PosNeg==trig.polarity)) {
4935 	//	return recSynMatch(gterm, vterm, env);
4936 	matchChild(gterm, vterm, binds);
4937 	return;
4938       }
4939       else{
4940 	//	cout<<"returned 1"<<endl;
4941 	return;
4942       }
4943     }
4944     const bool gfalse = (falseExpr()==findExpr(gterm));
4945     //const bool gfalse = (falseExpr()==simplifyExpr(gterm));
4946     if(gfalse){
4947       if((Pos==trig.polarity || PosNeg==trig.polarity)) {
4948 	//	return recSynMatch(gterm, vterm, env);
4949 	matchChild(gterm, vterm, binds); //it is possible that we need binds here, not a single bind
4950 	return;
4951       }
4952       else{
4953 	//	cout<<"returned 2"<<endl;
4954 	return;
4955       }
4956     }
4957 
4958 
4959 //     cout<<"immpossible here in new top match"<<endl;
4960 //     cout<<"vterm "<<vterm<<endl;
4961 //     cout<<trig.polarity<<endl;
4962 //     cout<<gtrue<<" | " <<gfalse<<endl;
4963 //     cout<<"gterm " <<gterm<<endl;
4964 //     cout<<"gterm " <<simplifyExpr(gterm)<<endl;
4965 
4966     matchChild(gterm, vterm, binds);
4967     return;
4968 
4969     return;
4970   }
4971   else{ // must be syspreds
4972     //we can move the work to split vterm into left and right into setuptriggers
4973     Expr gl = getLeft(gterm[1]);
4974     Expr gr = getRight(gterm[1]);
4975 
4976     if(null_expr == gr || null_expr == gl){
4977       gl = gterm[0];
4978       gr = gterm[1];
4979     }
4980 
4981     Expr vr, vl;
4982     Expr tvr, tvl;
4983 
4984     tvr=null_expr;
4985     tvl=null_expr;
4986 
4987     if(isGE(vterm) || isGT(vterm)){
4988       vr = vterm[0];
4989       vl = vterm[1];
4990     }
4991     else if(isLE(vterm) || isLT(vterm)){
4992       vr = vterm[1];
4993       vl = vterm[0];
4994     }
4995     else{
4996       FatalAssert(false, "impossilbe in toppred");
4997     }
4998 
4999     if(isIntx(vl,0)){
5000       tvl = getLeft(vr);
5001       tvr = getRight(vr);
5002     }
5003     else if(isIntx(vr,0)) {
5004       tvl = getLeft(vl);
5005       tvr = getRight(vl);
5006     }
5007 
5008     if( (null_expr != tvl) && (null_expr != tvr)){
5009       vl = tvl;
5010       vr = tvr;
5011     }
5012 
5013 
5014     const bool gtrue = (trueExpr()==findExpr(gterm));
5015     const bool gfalse = (falseExpr()==findExpr(gterm));
5016 
5017     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
5018 
5019     //    DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
5020 
5021     if(!*d_usePolarity){
5022       if((recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind))){
5023 	binds.push_back(cur_bind); // it is possible that cur_bind will be binds
5024 	return;
5025       }
5026       else{
5027 	return;
5028       }
5029     }
5030     if((Neg==trig.polarity || PosNeg==trig.polarity)) {
5031       if (( gtrue ) )  {
5032 	if (recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind)){
5033 	  binds.push_back(cur_bind);
5034 	  return;
5035 	}
5036 	else{
5037 	  return;
5038 	}
5039       }
5040       else {
5041 	if(recSynMatch(gl, vr, cur_bind) && recSynMatch(gr, vl, cur_bind)){
5042 	  binds.push_back(cur_bind);
5043 	  return;
5044 	}
5045 	else{
5046 	  return;
5047 	}
5048       }
5049     }
5050     else if((Pos==trig.polarity || PosNeg==trig.polarity)) {
5051       if (( gfalse )) {
5052 	if(recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind)){
5053 	  binds.push_back(cur_bind);
5054 	  return;
5055 	}
5056 	else{
5057 	  return;
5058 	}
5059       }
5060       else {
5061 	if(recSynMatch(gl, vr, cur_bind) && recSynMatch(gr, vl, cur_bind)){
5062 	  binds.push_back(cur_bind);
5063 	  return;
5064 	}
5065 	else{
5066 	  return;
5067 	}
5068       }
5069     }
5070     else {
5071       //      FatalAssert(false, "impossible polarity for trig");
5072 	//DebugAssert(false, "impossible polarity for trig");
5073 //      res = false;
5074       if((recSynMatch(gl, vl, cur_bind) && recSynMatch(gr, vr, cur_bind))){
5075 	binds.push_back(cur_bind); // it is possible that cur_bind will be binds
5076 	return;
5077       }
5078       else{
5079 	return;
5080       }
5081 
5082       return;
5083     }
5084   }
5085 }
5086 */
5087 
5088 /*
5089 bool TheoryQuant::synMatchTopPred(const Expr& gterm, Trigger trig, ExprMap<Expr>& env){
5090 
5091 
5092   Expr vterm = trig.getEx();
5093 
5094   TRACE("quant toppred", "top pred: gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
5095 
5096   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
5097   DebugAssert ((BOUND_VAR != vterm.getKind()),"top pred match "+gterm.toString()+" has bound var");
5098 
5099   if(gterm.isEq() || vterm.isEq()){
5100     return false; // we do not match with equality
5101   }
5102 
5103   bool res2=false;
5104 
5105   if(vterm.arity() != gterm.arity()) return false;
5106 
5107   if(trig.isSuperSimp()){
5108     if(trig.getHead() == getHead(gterm) ){
5109       for(int i = vterm.arity()-1; i>=0 ; i--){
5110 	env[vterm[i]] = simplifyExpr(gterm[i]);
5111       }
5112       return true;
5113     }
5114     return false;
5115   }
5116 
5117 
5118 
5119   if(trig.isSimp()){
5120     if(trig.getHead() == getHead(gterm) ){
5121        for(int i = vterm.arity()-1; i>=0 ; i--){
5122  	if(BOUND_VAR != vterm[i].getKind()){
5123  	  if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
5124  	    return false;
5125  	  }
5126  	}
5127        }
5128       for(int i = vterm.arity()-1; i>=0 ; i--){
5129 	if(BOUND_VAR == vterm[i].getKind()){
5130 	  if(d_allout){
5131 	    env[vterm[i]] = simplifyExpr(gterm[i]);
5132 	  }
5133 	  else {
5134 	    env[vterm[i]] = simplifyExpr(gterm[i]);
5135 	  }
5136 	}
5137       }
5138       return true;
5139     }
5140     else{
5141       return false;
5142     }
5143   }
5144 
5145   if(!(isSysPred(vterm) && isSysPred(gterm))){
5146     if(isSysPred(vterm) || isSysPred(gterm)) {
5147       return false;
5148     }
5149     if(!usefulInMatch(gterm)){
5150       return false;
5151     }
5152     if(trig.getHead() != getHead(gterm)){
5153       return false;
5154     }
5155 
5156     if(!gterm.getType().isBool()){
5157       //      res2= recSynMatch(gterm, vterm, env);
5158       res2= matchChild(gterm, vterm, env);
5159       return res2;
5160     }
5161 
5162     if(!*d_usePolarity){
5163       //      return recSynMatch(gterm, vterm, env);
5164       return matchChild(gterm, vterm, env);
5165     }
5166 
5167     const bool gtrue = (trueExpr()==findExpr(gterm));
5168     if(gtrue ){
5169       if(trig.isNeg()) {
5170 	//	return recSynMatch(gterm, vterm, env);
5171 	return matchChild(gterm, vterm, env);
5172       }
5173       else{
5174 	return false;
5175       }
5176     }
5177     const bool gfalse = (falseExpr()==findExpr(gterm));
5178     if(gfalse){
5179       if (trig.isPos()){
5180 	//	return recSynMatch(gterm, vterm, env);
5181 	return matchChild(gterm, vterm, env);
5182       }
5183       else{
5184 	return false;
5185       }
5186     }
5187     else {
5188       return false;
5189     }
5190   }
5191   else{
5192     DebugAssert((2==gterm.arity() && 2==vterm.arity()), "impossible situation in top pred");
5193     DebugAssert(!((isLE(gterm) || isLT(gterm)) && !isIntx(gterm[0],0)), "canonical form changed");
5194 
5195 #ifdef _CVC3_DEBUG_MODE
5196     if( CVC3::debugger.trace("quant toppred")  ){
5197       cout << "toppred gterm, vterm" << gterm << "::" << vterm << endl;
5198       cout << findExpr(gterm) << "::" << trig.isPos() << "|" << trig.isNeg() << endl;
5199     }
5200 #endif
5201 
5202 
5203     Expr gl = getLeft(gterm[1]);
5204     Expr gr = getRight(gterm[1]);
5205 
5206     if(null_expr == gr || null_expr == gl){
5207       gl = gterm[0];
5208       gr = gterm[1];
5209     }
5210 
5211     Expr vr, vl;
5212     Expr tvr, tvl;
5213 
5214     tvr=null_expr;
5215     tvl=null_expr;
5216 
5217     if(isGE(vterm) || isGT(vterm)){
5218       vr = vterm[0];
5219       vl = vterm[1];
5220     }
5221     else if(isLE(vterm) || isLT(vterm)){
5222       vr = vterm[1];
5223       vl = vterm[0];
5224     }
5225     else{
5226       DebugAssert(false, "impossilbe in toppred");
5227     }
5228 
5229     if(isIntx(vl,0)){
5230       tvl = getLeft(vr);
5231       tvr = getRight(vr);
5232     }
5233     else if(isIntx(vr,0)) {
5234       tvl = getLeft(vl);
5235       tvr = getRight(vl);
5236     }
5237 
5238     if( (null_expr != tvl) && (null_expr != tvr)){
5239       vl = tvl;
5240       vr = tvr;
5241     }
5242 
5243 
5244     const bool gtrue = (trueExpr()==findExpr(gterm));
5245     const bool gfalse = (falseExpr()==findExpr(gterm));
5246 
5247     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
5248 
5249     bool res;
5250 
5251     DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
5252 
5253     if(!*d_usePolarity){
5254       return (recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
5255     }
5256 
5257     if(trig.isNeg()){
5258       if (( gtrue ) )  {
5259 	res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
5260       }
5261       else {
5262 	res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
5263       }
5264     }
5265     else if(trig.isPos()){
5266       if (( gfalse )) {
5267 	res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
5268       }
5269       else {
5270 	res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
5271       }
5272     }
5273     else {
5274       DebugAssert(false, "impossible polarity for trig");
5275       res = false;
5276     }
5277 
5278 #ifdef _CVC3_DEBUG_MODE
5279     if( CVC3::debugger.trace("quant toppred")  ){
5280       cout<<"res| "<< res << " | " << gtrue << " | " << gfalse << endl;
5281     }
5282 #endif
5283     return res;
5284   }
5285 }
5286 */
5287 
5288 /*
5289   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
5290   This is not true for set1.smt
5291 */
5292 
cmpExpr(Expr e1,Expr e2)5293 bool cmpExpr( Expr e1, Expr e2){
5294 
5295   if(e1.isNull()) return true;
5296   if(e2.isNull()) return false;
5297   return (e1.getIndex() < e2.getIndex());
5298 }
5299 
5300 /*
5301   recMultMatch:
5302       syntax match, will return multiple bindings if possible
5303       must be called by multMatchChild or multMatchTop
5304       requires binds.size() == 1;
5305 
5306   input: one partial (empty) bindings in binds.
5307   output: successful bindings in binds
5308 */
5309 
recMultMatchDebug(const Expr & gterm,const Expr & vterm,vector<ExprMap<Expr>> & binds)5310 bool TheoryQuant::recMultMatchDebug(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
5311   //bool TheoryQuant::recMultMatch(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
5312   TRACE("quant match", gterm , " VS ", vterm);
5313   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
5314   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found in recMultMatch");
5315   DebugAssert (binds.size() == 1, "binds.size() > 1");
5316 
5317 
5318   if (BOUND_VAR == vterm.getKind() )  {
5319     ExprMap<Expr>& curEnv = binds[0]; //curEnv is both input and output
5320     ExprMap<Expr>::iterator iterVterm = curEnv.find(vterm);
5321     if ( iterVterm != curEnv.end()){
5322       return (simplifyExpr(gterm) == simplifyExpr(iterVterm->second)) ? true : false ;
5323     }
5324     else {
5325       curEnv[vterm] = simplifyExpr(gterm);
5326       return true;
5327     }
5328   }
5329   else if (!vterm.containsBoundVar()){
5330     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
5331   }
5332   else{ //let's do matching
5333     if(canGetHead(vterm)){
5334       Expr vhead = getHead(vterm);
5335       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.
5336 
5337 	// anoher problem is the interaction between matching and term's signature, I need to figure this out.
5338 
5339 	if (canGetHead(gterm)) {
5340 	  if ( vhead != getHead(gterm) ){
5341 	    return false;
5342 	  }
5343 	  return multMatchChild(gterm, vterm, binds);
5344 	}
5345 	else{
5346 	  return false;
5347 	}
5348       }
5349       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
5350 	return multMatchChild(gterm, vterm, binds);
5351       }
5352 
5353       //      cout<<"-- begin multi equality matching -- " << endl;
5354       //      cout<<"vterm: " << vterm << endl;
5355       //      cout<<"gterm: " << gterm << endl;
5356 
5357       ExprMap<Expr> orginalEnv = binds[0];
5358       vector<ExprMap<Expr> > candidateNewEnvs;
5359       bool newwayResult(false);
5360 
5361       if(*d_useNewEqu){
5362 	vector<Expr> candidateGterms;
5363 	{
5364 	  Expr curCandidateGterm = gterm.getEqNext().getRHS();
5365 	  while (curCandidateGterm != gterm){
5366 	    DebugAssert(simplifyExpr(curCandidateGterm) == simplifyExpr(gterm), "curCandidateGterm != gterm");
5367             //	    cout<<"pushed candidate gterm " << getExprScore(curCandidateGterm) << " # " << curCandidateGterm << endl;
5368 	    if(getExprScore(curCandidateGterm) <= d_curMaxExprScore || true){
5369 	      candidateGterms.push_back(curCandidateGterm);
5370 	    }
5371 	    curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
5372 	  }
5373 	}
5374 	//	std::sort(candidateGterms.begin(), candidateGterms.end());
5375 	//	for(int curGtermIndex = candidateGterms.size()-1; curGtermIndex >=0 ; curGtermIndex--){
5376 	for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
5377 	  const Expr& curGterm = candidateGterms[curGtermIndex];
5378 	  if(getHead(curGterm) == vhead){
5379 	    vector<ExprMap<Expr> > newBinds;
5380 	    newBinds.push_back(orginalEnv);
5381 	    bool res =  multMatchChild(curGterm, vterm, newBinds);
5382 	    if (res) 	{
5383               //	      cout << "found new match: " << endl;
5384               //	      cout << "curGterm: " <<  curGterm << endl;
5385               //	      cout << "simplified Gterm: " << simplifyExpr(gterm) << endl;
5386               //	      cout << "simplified curGterm: " << simplifyExpr(curGterm) << endl;
5387 	      for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
5388 		candidateNewEnvs.push_back(newBinds[newBindsIndex]);
5389 	      }
5390               //	      cout << "pushed newEnvs " << newBinds.size() << endl;
5391 	    }
5392 	  }
5393 	}
5394 
5395 	if (candidateNewEnvs.size() >= 1){
5396           //	  cout<<"found more matcings: " << candidateNewEnvs.size() << endl;
5397 	  newwayResult = true;
5398 	}
5399 	else{
5400 	  newwayResult = false;
5401 	}
5402       } //end of new way of matching
5403       // let's do matching in the old way
5404 
5405       vector<ExprMap<Expr> > candidateOldEnvs;
5406 
5407       if( d_same_head_expr.count(vhead) > 0 ) {
5408 	const Expr& findGterm = simplifyExpr(gterm);
5409 	//if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
5410 	CDList<Expr>* gls = d_same_head_expr[vhead];
5411 	for(size_t i = 0; i < gls->size(); i++){
5412 	  const Expr& curGterm = (*gls)[i];
5413 	  if(getExprScore(curGterm)> d_curMaxExprScore){
5414 	    continue;
5415 	  }
5416           //	  cout<<"same head term " << curGterm << endl;
5417 	  if (simplifyExpr(curGterm) == findGterm){
5418 	    DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
5419 
5420 	    vector<ExprMap<Expr> > newBinds ;
5421 	    newBinds.push_back(orginalEnv);
5422 	    bool goodMatching(false);
5423 	    goodMatching = multMatchChild(curGterm, vterm, newBinds);
5424 
5425 	    if(goodMatching){
5426               //	      cout << "old curGterm: " << curGterm << endl;
5427               //	      cout << "old simplifed  curGterm: " << simplifyExpr(curGterm) << endl;
5428 	      for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
5429 		candidateOldEnvs.push_back(newBinds[newBindsIndex]);
5430 	      }
5431               //	      cout << "pushed oldEnvs " << newBinds.size() << endl;
5432 	    }
5433 	  }
5434 	}//end of same head list
5435       }
5436 
5437       bool oldwayResult(false);
5438 
5439       if(candidateOldEnvs.size() >= 1){
5440 	oldwayResult = true;
5441       }
5442       else{
5443 	oldwayResult = false;
5444       }
5445 
5446       //      cout<<"new env size" << candidateNewEnvs.size() << endl;
5447       //      cout<<"old env size" << candidateOldEnvs.size() << endl;
5448       if( candidateNewEnvs.size() != candidateOldEnvs.size()){
5449         ;
5450         //	cout<<"found error?" << endl;
5451       }
5452 
5453       if(oldwayResult != newwayResult){
5454         ;
5455         //	cout << "-found bug in multMatch " << endl;
5456       }
5457 
5458       // binds = candidateNewEnvs;
5459       binds = candidateOldEnvs;
5460 
5461       return oldwayResult;
5462     }
5463     else{
5464       if( (gterm.getKind() == vterm.getKind()) &&
5465 	  (gterm.arity() == vterm.arity()) &&
5466 	  gterm.arity()>0 ){
5467         //	cout<<"why"<<endl;
5468 	return multMatchChild(gterm, vterm, binds);
5469       }
5470       else {
5471 	return false;
5472       }
5473     }
5474   }
5475   return false;
5476 }
5477 
recMultMatchOldWay(const Expr & gterm,const Expr & vterm,vector<ExprMap<Expr>> & binds)5478 bool TheoryQuant::recMultMatchOldWay(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
5479   //bool TheoryQuant::recMultMatch(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
5480   TRACE("quant match",  "==recMultMatch\n", "---"+gterm.toString(), "\n+++"+vterm.toString());
5481   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
5482   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found in recMultMatch");
5483   DebugAssert (binds.size() == 1, "binds.size() > 1");
5484 
5485 
5486   if (BOUND_VAR == vterm.getKind() )  {
5487     ExprMap<Expr>& curEnv = binds[0]; //curEnv is both input and output
5488     ExprMap<Expr>::iterator iterVterm = curEnv.find(vterm);
5489     if ( iterVterm != curEnv.end()){
5490       return (simplifyExpr(gterm) == simplifyExpr(iterVterm->second)) ? true : false ;
5491     }
5492     else {
5493       curEnv[vterm] = simplifyExpr(gterm);
5494       return true;
5495     }
5496   }
5497   else if (!vterm.containsBoundVar()){
5498     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
5499   }
5500   else{ //let's do matching
5501     if(canGetHead(vterm)){
5502       Expr vhead = getHead(vterm);
5503       if(vterm.isAtomicFormula()){ //we do not want to match predicate up to equality here.  why?
5504 	if (canGetHead(gterm)) {
5505 	  if ( vhead != getHead(gterm) ){
5506 	    return false;
5507 	  }
5508 	  return multMatchChild(gterm, vterm, binds);
5509 	}
5510 	else{
5511 	  return false;
5512 	}
5513       }
5514       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
5515 	return multMatchChild(gterm, vterm, binds);
5516       }
5517 
5518       TRACE("quant multmatch", "-- begin multi equality matching -- ", "" ,"");
5519       TRACE("quant multmatch", "vterm: " ,  vterm, "");
5520       TRACE("quant multmatch", "gterm: " ,  gterm, "");
5521 
5522       ExprMap<Expr> orginalEnv = binds[0];
5523 
5524       vector<ExprMap<Expr> > candidateOldEnvs;
5525 
5526       if( d_same_head_expr.count(vhead) > 0 ) {
5527 	const Expr& findGterm = simplifyExpr(gterm);
5528 	TRACE("quant multmatch", "simp gterm: " ,  simplifyExpr(gterm), "");
5529 	//if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
5530 	CDList<Expr>* gls = d_same_head_expr[vhead];
5531 	for(size_t i = 0; i < gls->size(); i++){
5532 	  const Expr& curGterm = (*gls)[i];
5533    	  if(getExprScore(curGterm)> d_curMaxExprScore){
5534    	    continue;
5535    	  }
5536 	  TRACE("quant multmatch", "same head term ", curGterm, "");
5537 	  TRACE("quant multmatch", "simp same head term ", simplifyExpr(curGterm), "");
5538 	  if (simplifyExpr(curGterm) == findGterm){
5539 	    DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
5540 	    vector<ExprMap<Expr> > newBinds ;
5541 	    newBinds.push_back(orginalEnv);
5542 	    bool goodMatching(false);
5543 	    goodMatching = multMatchChild(curGterm, vterm, newBinds);
5544 
5545 	    if(goodMatching){
5546 	      TRACE("quant multmatch", "old curGterm: ", curGterm, "");
5547 	      TRACE("quant multmatch", "old simplifed  curGterm: ", simplifyExpr(curGterm), "");
5548 	      for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
5549 		candidateOldEnvs.push_back(newBinds[newBindsIndex]);
5550 	      }
5551 	      TRACE("quant multmatch", "pushed oldEnvs " , newBinds.size(), "");
5552 	    }
5553 	  }
5554 	}//end of same head list
5555       }
5556 
5557       bool oldwayResult(false);
5558 
5559       if(candidateOldEnvs.size() >= 1){
5560 	oldwayResult = true;
5561       }
5562       else{
5563 	oldwayResult = false;
5564       }
5565 
5566       TRACE("quant multmatch", "old env size" ,candidateOldEnvs.size(), "");
5567       binds = candidateOldEnvs;
5568       return oldwayResult;
5569     }
5570     else{
5571       if( (gterm.getKind() == vterm.getKind()) &&
5572 	  (gterm.arity() == vterm.arity()) &&
5573 	  gterm.arity()>0 ){
5574 	return multMatchChild(gterm, vterm, binds);
5575       }
5576       else {
5577 	return false;
5578       }
5579     }
5580   }
5581   return false;
5582 }
5583 
5584 
5585 
5586 //bool TheoryQuant::recMultMatchNewWay(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
recMultMatch(const Expr & gterm,const Expr & vterm,vector<ExprMap<Expr>> & binds)5587 bool TheoryQuant::recMultMatch(const Expr& gterm,const Expr& vterm, vector<ExprMap<Expr> >& binds){
5588   TRACE("quant match", gterm , " VS ", vterm);
5589   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
5590   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found in recMultMatch");
5591   DebugAssert (binds.size() == 1, "binds.size() > 1");
5592 
5593   if (BOUND_VAR == vterm.getKind() )  {
5594     ExprMap<Expr>& curEnv = binds[0]; //curEnv is both input and output
5595     ExprMap<Expr>::iterator iterVterm = curEnv.find(vterm);
5596     if ( iterVterm != curEnv.end()){
5597       return (simplifyExpr(gterm) == simplifyExpr(iterVterm->second)) ? true : false ;
5598     }
5599     else {
5600       curEnv[vterm] = simplifyExpr(gterm);
5601       return true;
5602     }
5603   }
5604   else if (!vterm.containsBoundVar()){
5605     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
5606   }
5607   else{ //let's do matching
5608     if(canGetHead(vterm)){
5609       Expr vhead = getHead(vterm);
5610       if(vterm.isAtomicFormula()){ //we do not want to match predicate up to equality here.  why?
5611 	if (canGetHead(gterm)) {
5612 	  if ( vhead != getHead(gterm) ){
5613 	    return false;
5614 	  }
5615 	  return multMatchChild(gterm, vterm, binds);
5616 	}
5617 	else{
5618 	  return false;
5619 	}
5620       }
5621       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
5622 	//well, what if gterm and vterm cannot match later, but vterm can match some guys in the equivalent class of gterm?
5623 	return multMatchChild(gterm, vterm, binds);
5624       }
5625 
5626       TRACE("quant multmatch", "-- begin multi equality matching -- ", "" ,"");
5627       TRACE("qunat multmatch", "vterm: " ,  vterm, "");
5628       TRACE("qunat multmatch", "gterm: " ,  gterm, "");
5629 
5630       ExprMap<Expr> orginalEnv = binds[0];
5631       vector<ExprMap<Expr> > candidateNewEnvs;
5632       bool newwayResult(false);
5633 
5634       if(*d_useNewEqu){
5635 	vector<Expr> candidateGterms;
5636 	{
5637 	  if(!gterm.hasFind()) {
5638 	    return false;
5639 	  }
5640 	  Expr curCandidateGterm = gterm.getEqNext().getRHS();
5641 	  while (curCandidateGterm != gterm){
5642 	    DebugAssert(simplifyExpr(curCandidateGterm) == simplifyExpr(gterm), "curCandidateGterm != gterm");
5643 	    TRACE("quant multmatch", "pushed candidate gterm ", getExprScore(curCandidateGterm),  " # " + curCandidateGterm.toString());
5644 	    //maybe we should not check the score here, but we need check sig .
5645 	    if(getExprScore(curCandidateGterm) <= d_curMaxExprScore || true ){
5646  	      candidateGterms.push_back(curCandidateGterm);
5647 	    }
5648 	    curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
5649 	  }
5650 	}
5651 	for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
5652 	  const Expr& curGterm = candidateGterms[curGtermIndex];
5653 	  if(getHead(curGterm) == vhead){
5654 	    vector<ExprMap<Expr> > newBinds;
5655 	    newBinds.push_back(orginalEnv);
5656 	    bool res =  multMatchChild(curGterm, vterm, newBinds, true);
5657 	    if (res) 	{
5658 	      TRACE("quant multmatch", "found new match: ", "" ,"");
5659 	      TRACE("quant multmatch", "curGterm: ",  curGterm , "");
5660 	      TRACE("quant multmatch", "simplified Gterm: ", simplifyExpr(gterm), "" );
5661 	      TRACE("quant multmatch", "simplified curGterm: ",  simplifyExpr(curGterm), "");
5662 	      for(size_t newBindsIndex = 0; newBindsIndex < newBinds.size(); newBindsIndex++){
5663 		candidateNewEnvs.push_back(newBinds[newBindsIndex]);
5664 	      }
5665 	      TRACE("quant multmathc", "pushed newEnvs ", newBinds.size(), "");
5666 	    }
5667 	  }
5668 	}
5669 
5670 	if (candidateNewEnvs.size() >= 1){
5671 	  TRACE("quant multmacht", "found more matcings: " , candidateNewEnvs.size(), "");
5672 	  newwayResult = true;
5673 	}
5674 	else{
5675 	  newwayResult = false;
5676 	}
5677       } //end of new way of matching
5678 
5679       TRACE("quant multmatch", "new env size " , candidateNewEnvs.size(), "");
5680       binds = candidateNewEnvs;
5681       return newwayResult;
5682     }
5683     else{
5684       if  ( (gterm.getKind() == vterm.getKind()) &&
5685 	    (gterm.arity() == vterm.arity()) &&
5686 	    gterm.arity()>0 )
5687 	{
5688 	  return multMatchChild(gterm, vterm, binds);
5689 	}
5690       else {
5691 	return false;
5692       }
5693     }
5694   }
5695   return false;
5696 }
5697 
5698 
5699 /*
5700 bool TheoryQuant::recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
5701   cout << "-error: should not be called, recSynMatch" << endl;
5702   TRACE("quant match", gterm , " VS ", vterm);
5703   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
5704   DebugAssert (!isSysPred(vterm) && !isSysPred(gterm), "pred found");
5705 
5706   if (BOUND_VAR == vterm.getKind() )  {
5707     ExprMap<Expr>::iterator p = env.find(vterm);
5708     if ( p != env.end()){
5709       return (simplifyExpr(gterm) == simplifyExpr(p->second)) ? true : false ;
5710     }
5711     else {
5712       env[vterm] = simplifyExpr(gterm);
5713       return true;
5714     }
5715   }
5716   else if (!vterm.containsBoundVar()){
5717     return (simplifyExpr(vterm) == simplifyExpr(gterm)) ? true : false ;
5718   }
5719   else{ //let's do matching
5720     if(canGetHead(vterm)){
5721       Expr vhead = getHead(vterm);
5722       if(vterm.isAtomicFormula()){ //we do not want to match predicate up to equality here.  why?
5723 	if (canGetHead(gterm)) {
5724 	  if ( vhead != getHead(gterm) ){
5725 	    return false;
5726 	  }
5727 	  return matchChild(gterm, vterm, env);
5728 	}
5729 	else{
5730 	  return false;
5731 	}
5732       }
5733       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
5734 	return matchChild(gterm, vterm, env);
5735       }
5736 
5737       if(!*d_useEqu){
5738 	return false;
5739       }
5740 
5741       cout<<"-- begin equality matching -- " << endl;
5742       cout<<"vterm: " << vterm << endl;
5743       cout<<"gterm: " << gterm << endl;
5744 
5745       ExprMap<Expr> orginalEnv = env;
5746 
5747       vector<ExprMap<Expr> > candidateNewEnvs;
5748 
5749       //      if(*d_useNewEqu){
5750 
5751 	vector<Expr> candidateGterms;
5752 	{
5753 	  Expr curCandidateGterm = gterm.getEqNext().getRHS();
5754 	  while (curCandidateGterm != gterm){
5755 	    DebugAssert(simplifyExpr(curCandidateGterm) == simplifyExpr(gterm), "curCandidateGterm != gterm");
5756 	    cout<<"pushed candidate gterm " << curCandidateGterm << endl;
5757 	    candidateGterms.push_back(curCandidateGterm);
5758 	    curCandidateGterm = curCandidateGterm.getEqNext().getRHS();
5759 	  }
5760 	}
5761 	std::sort(candidateGterms.begin(), candidateGterms.end());
5762 	//	for(int curGtermIndex = candidateGterms.size()-1; curGtermIndex >=0 ; curGtermIndex--){
5763 	for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
5764 	  const Expr& curGterm = candidateGterms[curGtermIndex];
5765 	  if(getHead(curGterm) == vhead){
5766 	    ExprMap<Expr> newEnv = orginalEnv;
5767 	    bool res =  matchChild(curGterm, vterm, newEnv);
5768 	    if (res) 	{
5769 	      cout << "found new match: " << endl;
5770 	      cout << "curGterm: " <<  curGterm << endl;
5771 	      cout << "simplified Gterm: " << simplifyExpr(gterm) << endl;
5772 	      cout << "simplified curGterm: " << simplifyExpr(curGterm) << endl;
5773 	      candidateNewEnvs.push_back(newEnv);
5774 	    }
5775 	  }
5776 	}
5777 
5778 	ExprMap<Expr> newwayEnv;
5779 	bool newwayResult(false);
5780 
5781 	if (candidateNewEnvs.size() >= 1){
5782 	  cout<<"found more matcings: " << candidateNewEnvs.size() << endl;
5783 	  newwayEnv = candidateNewEnvs[0]; // we have a choice here
5784 	  //	  newwayEnv = candidateNewEnvs.back(); // we have a choice here
5785 	  newwayResult = true;
5786 	}
5787 	else{
5788 	  newwayResult = false;
5789 	}
5790 	//      } //end of new way of matching
5791       // let's do matching in the old way
5792 
5793       vector<ExprMap<Expr> > candidateOldEnvs;
5794 
5795       if( d_same_head_expr.count(vhead) > 0 ) {
5796 	const Expr& findGterm = simplifyExpr(gterm);
5797 	//if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
5798 	CDList<Expr>* gls = d_same_head_expr[vhead];
5799 	for(size_t i = 0; i < gls->size(); i++){
5800 	  cout<<"same head term " << (*gls)[i] << endl;
5801 	  if (simplifyExpr((*gls)[i]) == findGterm){
5802 	    DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
5803 
5804 	    ExprMap<Expr> curEnv = orginalEnv;
5805 	    const Expr& curGterm = (*gls)[i];
5806 
5807 	    bool goodMatching(false);
5808 	    goodMatching = matchChild(curGterm, vterm, curEnv);
5809 
5810 	    if(goodMatching){
5811 	      cout << "old curGterm: " << curGterm << endl;
5812 	      cout << "old simplifed  curGterm: " << simplifyExpr(curGterm) << endl;
5813 	      candidateOldEnvs.push_back(curEnv);
5814 ;
5815 	    }
5816 	  }
5817 	}//end of same head list
5818       }
5819 
5820       ExprMap<Expr> oldwayEnv;
5821       bool oldwayResult(false);
5822 
5823       if(candidateOldEnvs.size() >= 1){
5824 	oldwayResult = true;
5825 	oldwayEnv = candidateOldEnvs[0];
5826       }
5827       else{
5828 	oldwayResult = false;
5829       }
5830 
5831       cout<<"new env size" << candidateNewEnvs.size() << endl;
5832       cout<<"old env size" << candidateOldEnvs.size() << endl;
5833       if( candidateNewEnvs.size() != candidateOldEnvs.size()){
5834 	cout<<"found error?" << endl;
5835       }
5836 
5837       if(oldwayResult != newwayResult){
5838 	cout<<"found bug" << endl;
5839 	cout<<"oldway result: " << oldwayResult << endl;
5840 	cout<<"newway result: " << newwayResult << endl;
5841       }
5842 
5843       if(false == oldwayResult ) return false;
5844 
5845       if(newwayEnv != oldwayEnv){
5846 	bool notFound(true);
5847 	int foundIndex(-1);
5848 	for(size_t i = 0; i <candidateNewEnvs.size(); i++){
5849 	  if (candidateNewEnvs[i] == oldwayEnv){
5850 	    foundIndex = i;
5851 	    cout<<"found env " << i << endl;
5852 	    notFound = false;
5853 	  }
5854 	}
5855 	if (notFound){
5856 	  cout<<"found strange env" << endl;;
5857 	  cout<<gterm << " " << gterm.getIndex()<<endl;
5858 	  cout<<vterm << " " << vterm.getIndex()<<endl;
5859 	  cout<<exprMap2string(newwayEnv)<<endl;
5860 	  cout<<exprMap2string(oldwayEnv)<<endl;
5861 	}
5862       }
5863       //env = oldwayEnv;
5864       env = newwayEnv;
5865       return true;
5866     }
5867     else{
5868       if( (gterm.getKind() == vterm.getKind()) &&
5869 	  (gterm.arity() == vterm.arity()) &&
5870 	  gterm.arity()>0 ){
5871 	return matchChild(gterm, vterm, env);
5872       }
5873       else {
5874 	return false;
5875       }
5876     }
5877   }
5878   return false;
5879 }
5880 
5881 */
5882 
5883 /*
5884 //the following is not used anymore, the code is here for refreence.
5885 bool TheoryQuant::recSynMatchBackupOnly(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
5886   cout<<"-error: should not be called: recSynMatchBackupOnly " << endl;
5887   TRACE("quant match", "gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
5888   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
5889 
5890   if (BOUND_VAR == vterm.getKind() )  {
5891     TRACE("quant match", "bound var found;", vterm.toString(),"");
5892     ExprMap<Expr>::iterator p = env.find(vterm);
5893     if ( p != env.end()){
5894       if (simplifyExpr(gterm) != simplifyExpr(p->second)){
5895 	return false;
5896       }
5897       else
5898 	return true;
5899     }
5900     else {
5901       env[vterm] = simplifyExpr(gterm);
5902       return true;
5903     }
5904   }
5905   else if (!vterm.containsBoundVar()){
5906     //    return true;
5907     //    cout<<"vterm and gterm"<<vterm << " # " <<gterm<<endl;
5908     if(simplifyExpr(vterm) == simplifyExpr(gterm)) {
5909       return true;
5910     }
5911     else{
5912       return false;
5913     }
5914   }
5915 
5916   else if(false && isSysPred(vterm) && isSysPred(gterm)){
5917 
5918     TRACE("quant syspred"," vterm, gterm ", vterm.toString()+" :|: ", gterm.toString());
5919     TRACE("quant syspred"," simplified vterm, gterm ", simplifyExpr(vterm).toString()+" :|: ", simplifyExpr(gterm).toString());
5920     FatalAssert(false, "should not be here in synmatch");
5921     exit(3);
5922   }
5923   else{ //let's do matching
5924     if(canGetHead(vterm)){
5925       Expr vhead = getHead(vterm);
5926       TRACE("quant match", "head vterm:", getHead(vterm), "");
5927       if(vterm.isAtomicFormula()){
5928 	if (canGetHead(gterm)) {
5929 	  if ( vhead != getHead(gterm) ){
5930 	    return false;
5931 	  }
5932 	  return matchChild(gterm, vterm, env);
5933 	  // 	    for(int i=vterm.arity()-1; i >= 0; i--){
5934 	  // 	      if (false == recSynMatch(gterm[i], vterm[i] , env))
5935 	  // 		return false;
5936 	  // 	    }
5937 	  // 	    return true;
5938 	}
5939 	else{
5940 	  return false;
5941 	}
5942       }
5943       if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
5944 	//	  if(gterm.arity() != vterm.arity()){
5945 	//	    return false;
5946 	//	  }
5947 	// 	  for(int i=vterm.arity()-1; i >= 0; i--){
5948 	// 	    if (false == recSynMatch(gterm[i], vterm[i] , env)) {
5949 	// 	      return false;
5950 	// 	    }
5951 // 	  }
5952 // 	  return true;
5953 	return matchChild(gterm, vterm, env);
5954       }
5955 
5956       if(!*d_useEqu){
5957 	return false;
5958       }
5959 
5960       cout<<"-- begin equality matching -- " << endl;
5961       cout<<"vterm: " << vterm << endl;
5962       cout<<"gterm: " << gterm << endl;
5963       bool newwayResult(false);
5964       bool oldwayResult(false);
5965       ExprMap<Expr> orgEnv = env;
5966       ExprMap<Expr> newwayEnv;
5967       ExprMap<Expr> oldwayEnv;
5968 
5969       vector<ExprMap<Expr> > candidateEnv; // here just for test
5970       if(*d_useNewEqu){
5971 // 	int debug1= vterm.getIndex();
5972 // 	int debug2= gterm.getIndex();
5973 // 	if(debug1 == 311 && debug2 == 361){
5974 // 	  cout<<"begin here" << endl;
5975 // 	}
5976 
5977 
5978 	Expr cur_next = gterm.getEqNext().getRHS();
5979 	Expr vhead = getHead(vterm);
5980 	TRACE("quant newequ", "gterm: " ,gterm, "");
5981 	TRACE("quant newequ", "v: " , vterm, "" );
5982 	//
5983 	  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
5984 	  //	  This is not true for set1.smt
5985 	//	vector<ExprMap<Expr> > candidateEnv;
5986 	vector<Expr> candidateGterms;
5987 
5988 	while (cur_next != gterm){
5989 	  if(simplifyExpr(cur_next) != simplifyExpr(gterm)){
5990 	    cout<<" impossible"<<endl;
5991 	  }
5992 	  cout<<"pushed candidate gterm " << cur_next << endl;
5993 	  candidateGterms.push_back(cur_next);
5994 	  cur_next = cur_next.getEqNext().getRHS();
5995 	}
5996 
5997 	//	for(int curGtermIndex = candidateGterms.size()-1; curGtermIndex >=0 ; curGtermIndex--){
5998 	for(size_t curGtermIndex = 0 ; curGtermIndex < candidateGterms.size(); curGtermIndex++){
5999 	  Expr curGterm = candidateGterms[curGtermIndex];
6000 	  if(getHead(curGterm) == vhead){
6001 	    TRACE("quant newequ", " matched good", "", "");
6002 	    ExprMap<Expr> newEnv = orgEnv;
6003 	    bool res =  matchChild(curGterm, vterm, newEnv);
6004 	    TRACE("quant newequ", "final result: ",res ,"");
6005 	    if (res) 	{
6006 	      env=newEnv;
6007 	      //	return res;
6008 	      cout << "found new match: " << endl;
6009 	      cout << "curGterm: " <<  curGterm << endl;
6010 	      cout << "simplified Gterm: " << simplifyExpr(gterm) << endl;
6011 	      cout << "simplified curGterm: " << simplifyExpr(curGterm) << endl;
6012 	      newwayEnv = newEnv;
6013 	      newwayResult = res; //break;;
6014 	      candidateEnv.push_back(newEnv);
6015 	    }
6016 	  }
6017 	}
6018 
6019 
6020 
6021 	while (cur_next != gterm) {
6022 	  TRACE("quant newequ", "g: " ,cur_next, "");
6023 	  TRACE("quant newequ", "vhead: ", vhead, "");
6024 	  TRACE("quant newequ", "g head: ", getHead(cur_next), "");
6025 	  TRACE("quant newequ", "g score: ", getExprScore(cur_next), "");
6026 	  //	    if(getExprScore(cur_next)>15) continue;
6027 
6028 	  if(getHead(cur_next) == vhead){
6029 
6030 	    TRACE("quant newequ", " matched good", "", "");
6031 	    ExprMap<Expr> newEnv = env;
6032 	    bool res =  matchChild(cur_next, vterm, newEnv);
6033 	    TRACE("quant newequ", "final result: ",res ,"");
6034 	    if (res) 	{
6035 	      env=newEnv;
6036 	      //	return res;
6037 	      newwayEnv = newEnv;
6038 	      newwayResult = res; //break;;
6039 	      candidateEnv.push_back(newEnv);
6040 	    }
6041 	  }
6042 	  cur_next = cur_next.getEqNext().getRHS();
6043 	}
6044 
6045 
6046 // 	if(candidateEnv.size() == 1){
6047 // 	  env = candidateEnv[0];
6048 // 	  return true;
6049 // 	}
6050 // 	else if (candidateEnv.size() > 1){
6051 // 	  env = candidateEnv[0];
6052 // 	  return true;
6053 // 	  cout<<"found more matcings" << endl;
6054 // 	}
6055 
6056 
6057 	if (candidateEnv.size() > 1){
6058 	  cout<<"found more matcings" << endl;
6059 	  //	  newwayEnv = candidateEnv[0];
6060 	}
6061 
6062 	TRACE("quant newequ", " not matched ", vterm, gterm);
6063 	  //	  return false;
6064 	if(newwayResult) {
6065 	}
6066 	else{
6067 	newwayResult = false ;
6068 	}
6069       }
6070 
6071       vector<ExprMap<Expr> > candidateOldEnv; //for test only
6072       //      else { //else we use old equ algorithm
6073 	env = orgEnv;
6074 	//	cout<<"==============================="<<endl;
6075 	//	cout<<gterm<<" # " <<vterm<<endl;
6076 
6077 	if(false)
6078 	  { //
6079 	  //	  std::set<Expr> eq_set;
6080 	  std::map<Expr,bool> eq_set;
6081 	  eq_set.clear();
6082 	  eq_set[gterm]=true;
6083 
6084 	  std::queue<Expr> eq_queue;
6085 
6086 	  ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.find(gterm);
6087 
6088 	  if(iter != d_eq_list.end()){
6089 	    for(size_t len =0; len< iter->second->size(); len++){
6090 	      eq_queue.push((*(iter->second))[len]);
6091 	    }
6092 	    int count =0;
6093 	    while(eq_queue.size()>0){
6094 	      count++;
6095 	      const Expr& cur = eq_queue.front();
6096 	      eq_queue.pop();
6097 	      if(eq_set.find(cur) == eq_set.end()){
6098 		if(canGetHead(cur) && getHead(cur) == vhead){
6099 // 		  	      cout<<"VTERM: "<<vterm<<endl;
6100 // 		  	      cout<<"FOUND: "<<cur<<endl;
6101 // 		  	      cout<<"GTERM:  "<<gterm<<endl;
6102 		  //		  cout<<"--good match: " << count << "  // " << gterm << " # " << cur << endl;
6103 		  //		  cout<<"===good simple: " << count << "  // " << simplifyExpr(gterm) << " # " << simplifyExpr(cur) << endl;
6104 
6105 		  if(simplifyExpr(cur) != simplifyExpr(gterm)){
6106 		    // return false;
6107 		    //		    return matchChild(cur, vterm, env);
6108 		    //		    cout<<"en? "<<gterm<<" # " <<cur <<" # " <<vterm<<endl;
6109 		  }
6110 		  else{
6111 		    //		    cout<<"--good match: " << count << "  // " << gterm << " # " << cur << endl;
6112 		    //		    cout<<"===good simple: " << count << "  // " << simplifyExpr(gterm) << " # " << simplifyExpr(cur) << endl;
6113 		    //		    return matchChild(cur, vterm, env);
6114 		  }
6115 		}
6116 
6117 		eq_set[cur]=true;
6118 		ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.find(cur);
6119 
6120 		if(iter != d_eq_list.end()){
6121 		  for(size_t len =0; len< iter->second->size(); len++){
6122 		    eq_queue.push((*(iter->second))[len]);
6123 		  }
6124 		}
6125 	      }
6126 	    }
6127 	  }
6128 	  //	  return false;
6129 	}
6130 
6131 	if( d_same_head_expr.count(vhead) > 0 ) {
6132 	  const Expr& findGterm = simplifyExpr(gterm);
6133 	  //if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
6134 	  TRACE("quant match", "find gterm:", findGterm.toString(),"");
6135 	  CDList<Expr>* gls = d_same_head_expr[vhead];
6136 	  if (false)
6137 	    { int count =0;
6138 	      for(size_t i = 0; i<gls->size(); i++){
6139 	      if (simplifyExpr((*gls)[i]) == findGterm){
6140 	      count++;
6141 	      }
6142 	      }
6143 	      if(count>1){
6144 	      cout<<"count " << count << " # " << gls->size() << " | "<<gterm<<endl;
6145 	      for(size_t i = 0; i<gls->size(); i++){
6146 	      if (simplifyExpr((*gls)[i]) == findGterm){
6147 	      cout<<"eq "<<(*gls)[i]<<endl;
6148 	      }
6149 	      }
6150 	      }
6151 	      }
6152 
6153 	  for(size_t i = 0; i<gls->size(); i++){
6154 	    cout<<"same head term " << (*gls)[i] << endl;
6155 	    if (simplifyExpr((*gls)[i]) == findGterm){
6156 	      env = orgEnv;
6157 	      oldwayResult = true;
6158 	      TRACE("quant match", "find matched gterm:", (*gls)[i].toString(),"");
6159 	      DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
6160 
6161 	      const Expr& newgterm = (*gls)[i];
6162 	      for(int child=vterm.arity()-1; child >= 0 ; child--){
6163 		if (false == recSynMatch(newgterm[child], vterm[child] , env)){
6164 		  TRACE("quant match", "match false", (*gls)[i][child].toString(), vterm[child].toString());
6165 		  //		    return false;
6166 		  oldwayEnv = env; oldwayResult = false; break;
6167 		}
6168 	      }
6169 	      TRACE("quant match", "good match, return true:", gterm, vterm.toString());
6170 	      //	      cout<<"quant good match: " <<i<<" // "<<gterm << " # "<<vterm<<endl;
6171 	      //	      cout<<"quant simple: " <<i<<" // "<<simplifyExpr(gterm) << " # "<<vterm<<endl;
6172 		//		return true;
6173 	      //problem
6174 	      if(oldwayResult){
6175 		cout << "old curGterm: " << newgterm << endl;
6176 		cout << "old simplifed  curGterm: " << simplifyExpr(newgterm) << endl;
6177 		oldwayResult = true; oldwayEnv = env; //break;
6178 		candidateOldEnv.push_back(oldwayEnv);
6179 	      }
6180 	      else{
6181 		oldwayResult = false;
6182 	      }
6183 	    }
6184 	  }//end of for
6185 	  //	do not forget this    return false;
6186 
6187 	}
6188 	else  {
6189 	  oldwayResult = false;
6190 	  //	    return false;//end of if
6191 	}
6192 	//      }
6193 
6194 	cout<<"new env size" << candidateEnv.size() << endl;
6195 	cout<<"old env size" << candidateOldEnv.size() << endl;
6196 	if( candidateEnv.size() != candidateOldEnv.size()){
6197 	  cout<<"error?" << endl;
6198 	}
6199 	if(newwayEnv != oldwayEnv && oldwayResult == newwayResult){
6200 	bool notFound(true);
6201 	int foundIndex(-1);
6202 	for(size_t i = 0; i <candidateEnv.size(); i++){
6203 	  if (candidateEnv[i] == oldwayEnv){
6204 	    foundIndex = i;
6205 	    cout<<"found env " << i << endl;
6206 	    notFound = false;
6207 	  }
6208 	}
6209 	if (notFound){
6210 	  cout<<"found strange env" << endl;;
6211 	  cout<<"new way find " << candidateEnv.size()<<endl;
6212 	  cout<<gterm << " " << gterm.getIndex()<<endl;
6213 	  cout<<vterm << " " << vterm.getIndex()<<endl;
6214 	  cout << "oldEnv" << candidateOldEnv.size() << endl;
6215 	  cout<<exprMap2string(newwayEnv)<<endl;
6216 	  cout<<exprMap2string(oldwayEnv)<<endl;
6217 
6218 	}
6219       }
6220       if(oldwayResult != newwayResult){
6221 	cout<<"found strange" << endl;
6222 	cout<<gterm << " " << gterm.getIndex()<<endl;
6223 	cout<<vterm << " " << vterm.getIndex()<<endl;
6224       }
6225       else{
6226 	//	env = newwayEnv;
6227 	return oldwayResult;
6228       }
6229 
6230     }
6231     else{
6232       TRACE("quant match more", "match more", gterm.toString()+" # ", vterm.toString());
6233       if( (gterm.getKind() == vterm.getKind()) &&
6234 	  (gterm.arity() == vterm.arity()) &&
6235 	  gterm.arity()>0 ){
6236 	//   	  for(int child=0; child < vterm.arity() ; child++){
6237 	//   	    if (false == recSynMatch(gterm[child], vterm[child] , env)){
6238 	//   	      TRACE("quant match", "match false", gterm[child].toString(), vterm[child].toString());
6239 //   	      return false;
6240 //   	    }
6241 //   	  }
6242 //   	  return true;
6243 //   	  if( gterm.getKind() == PLUS || gterm.getKind() == MINUS){
6244 //   	    cout<<"g v"<<gterm<< " # " <<vterm<<endl;
6245 //   	  }
6246 
6247 	return matchChild(gterm, vterm, env);
6248       }
6249       else {
6250 //   	  if( gterm.getKind() == PLUS || gterm.getKind() == MINUS){
6251 // 	    static bool gvfound = false;
6252 //   	    if(!gvfound){
6253 // 	      cout<<"g v 1"<<endl;
6254 // 	      gvfound =true;
6255 // 	    }
6256 	    //gterm<< " # " <<vterm<<endl;
6257 	  //  }
6258 	return false;
6259       }
6260     }
6261   }
6262 }
6263 */
6264 
6265 /*
6266 
6267 bool TheoryQuant::synMatchTopPred(const Expr& gterm, Trigger trig, ExprMap<Expr>& env){
6268 
6269   const Expr vterm = trig.getEx();
6270 
6271   TRACE("quant toppred", "top pred: gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
6272 
6273   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
6274   DebugAssert ((BOUND_VAR != vterm.getKind()),"top pred match "+gterm.toString()+" has bound var");
6275 
6276   if(gterm.isEq() || vterm.isEq()){
6277     return false; // we do not match with equality
6278   }
6279 
6280   bool res2=false;
6281 
6282   //  if(vterm.arity() != gterm.arity()) return false;
6283 
6284   if(trig.isSimp()){
6285     if(trig.getHead() == getHead(gterm) ){
6286       for(int i = vterm.arity()-1; i>=0 ; i--){
6287 	if(BOUND_VAR != vterm[i].getKind()){
6288 	  if(simplifyExpr(gterm[i]) != simplifyExpr(vterm[i])) {
6289 	    return false;
6290 	  }
6291 	}
6292       }
6293       for(int i = vterm.arity()-1; i>=0 ; i--){
6294 	if(BOUND_VAR == vterm[i].getKind()){
6295 	  if(d_allout){
6296 	    env[vterm[i]] = simplifyExpr(gterm[i]);
6297 	  }
6298 	  else {
6299 	    env[vterm[i]] = simplifyExpr(gterm[i]);
6300 	  }
6301 	}
6302       }
6303       return true;
6304     }
6305     else{
6306       return false;
6307     }
6308   }
6309 
6310   if(!(isSysPred(vterm) && isSysPred(gterm))){
6311     if(isSysPred(vterm) || isSysPred(gterm)) {
6312       return false;
6313     }
6314     if(!usefulInMatch(gterm)){
6315       return false;
6316     }
6317     if(trig.getHead() != getHead(gterm)){
6318       return false;
6319     }
6320 
6321     if(!gterm.getType().isBool()){
6322       res2= recSynMatch(gterm, vterm, env);
6323       return res2;
6324     }
6325 
6326     if(!*d_usePolarity){
6327       return recSynMatch(gterm, vterm, env);
6328     }
6329 
6330     const bool gtrue = (trueExpr()==findExpr(gterm));
6331     if(gtrue ){
6332       if(trig.isNeg()) {
6333 	return recSynMatch(gterm, vterm, env);
6334       }
6335       else{
6336 	return false;
6337       }
6338     }
6339     const bool gfalse = (falseExpr()==findExpr(gterm));
6340     if(gfalse){
6341       if (trig.isPos()){
6342 	return recSynMatch(gterm, vterm, env);
6343       }
6344       else{
6345 	return false;
6346       }
6347     }
6348     else {
6349       return false;
6350     }
6351   }
6352   else{
6353     DebugAssert((2==gterm.arity() && 2==vterm.arity()), "impossible situation in top pred");
6354     DebugAssert(!((isLE(gterm) || isLT(gterm)) && !isIntx(gterm[0],0)), "canonical form changed");
6355 
6356 #ifdef _CVC3_DEBUG_MODE
6357     if( CVC3::debugger.trace("quant toppred")  ){
6358       cout << "toppred gterm, vterm" << gterm << "::" << vterm << endl;
6359       cout << findExpr(gterm) << "::" << trig.isPos() << "|" << trig.isNeg() << endl;
6360     }
6361 #endif
6362 
6363 
6364     Expr gl = getLeft(gterm[1]);
6365     Expr gr = getRight(gterm[1]);
6366 
6367     if(null_expr == gr || null_expr == gl){
6368       gl = gterm[0];
6369       gr = gterm[1];
6370     }
6371 
6372     Expr vr, vl;
6373     Expr tvr, tvl;
6374 
6375     tvr=null_expr;
6376     tvl=null_expr;
6377 
6378     if(isGE(vterm) || isGT(vterm)){
6379       vr = vterm[0];
6380       vl = vterm[1];
6381     }
6382     else if(isLE(vterm) || isLT(vterm)){
6383       vr = vterm[1];
6384       vl = vterm[0];
6385     }
6386     else{
6387       DebugAssert(false, "impossilbe in toppred");
6388     }
6389 
6390     if(isIntx(vl,0)){
6391       tvl = getLeft(vr);
6392       tvr = getRight(vr);
6393     }
6394     else if(isIntx(vr,0)) {
6395       tvl = getLeft(vl);
6396       tvr = getRight(vl);
6397     }
6398 
6399     if( (null_expr != tvl) && (null_expr != tvr)){
6400       vl = tvl;
6401       vr = tvr;
6402     }
6403 
6404 
6405     const bool gtrue = (trueExpr()==findExpr(gterm));
6406     const bool gfalse = (falseExpr()==findExpr(gterm));
6407 
6408     TRACE("quant toppred"," vl, gl, vr, gr:", vl.toString()+"::"+gl.toString()+"||", vr.toString()+"::"+gr.toString());
6409 
6410     bool res;
6411 
6412     DebugAssert(!(trig.isNeg() && trig.isPos()), "expr in both pos and neg");
6413 
6414     if(!*d_usePolarity){
6415       return (recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
6416     }
6417 
6418     if(trig.isNeg()){
6419       if (( gtrue ) )  {
6420 	res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
6421       }
6422       else {
6423 	res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
6424       }
6425     }
6426     else if(trig.isPos()){
6427       if (( gfalse )) {
6428 	res=(recSynMatch(gl, vl, env) && recSynMatch(gr, vr, env));
6429       }
6430       else {
6431 	res=(recSynMatch(gl, vr, env) && recSynMatch(gr, vl, env));
6432       }
6433     }
6434     else {
6435       DebugAssert(false, "impossible polarity for trig");
6436       res = false;
6437     }
6438 
6439 #ifdef _CVC3_DEBUG_MODE
6440     if( CVC3::debugger.trace("quant toppred")  ){
6441       cout<<"res| "<< res << " | " << gtrue << " | " << gfalse << endl;
6442     }
6443 #endif
6444     return res;
6445   }
6446 }
6447 
6448 bool TheoryQuant::recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env){
6449   TRACE("quant match", "gterm:| "+gterm.toString()," vterm:| "+vterm.toString(),"");
6450   DebugAssert ((BOUND_VAR != gterm.getKind()),"gound term "+gterm.toString()+" has bound var");
6451 
6452   if (BOUND_VAR == vterm.getKind())  {
6453     TRACE("quant match", "bound var found;", vterm.toString(),"");
6454     ExprMap<Expr>::iterator p = env.find(vterm);
6455     if ( p != env.end()){
6456       if (simplifyExpr(gterm) != simplifyExpr(p->second)){
6457 	return false;
6458       }
6459       else
6460 	return true;
6461     }
6462     else {
6463       env[vterm] = simplifyExpr(gterm);
6464       return true;
6465     }
6466   }
6467   else if (!vterm.containsBoundVar()){
6468     if(simplifyExpr(vterm) == simplifyExpr(gterm)) {
6469       return true;
6470     }
6471     else{
6472       return false;
6473     }
6474   }
6475 
6476   else if(false && isSysPred(vterm) && isSysPred(gterm)){
6477 
6478     TRACE("quant syspred"," vterm, gterm ", vterm.toString()+" :|: ", gterm.toString());
6479     TRACE("quant syspred"," simplified vterm, gterm ", simplifyExpr(vterm).toString()+" :|: ", simplifyExpr(gterm).toString());
6480     FatalAssert(false, "should not be here in synmatch");
6481     exit(3);
6482   }
6483   else{
6484       if(canGetHead(vterm)){
6485 	Expr vhead = getHead(vterm);
6486 	TRACE("quant match", "head vterm:", getHead(vterm), "");
6487 	if(vterm.isAtomicFormula()){
6488 	  if (canGetHead(gterm)) {
6489 	    if ( vhead != getHead(gterm) ){
6490 	      return false;
6491 	    }
6492 	    for(int i=vterm.arity()-1; i >= 0; i--){
6493 	      if (false == recSynMatch(gterm[i], vterm[i] , env))
6494 		return false;
6495 	    }
6496 	    return true;
6497 	  }
6498 	  else{
6499 	    return false;
6500 	  }
6501 	}
6502 	if ( (canGetHead(gterm)) && vhead == getHead(gterm)){
6503 	  if(gterm.arity() != vterm.arity()){
6504 	    return false;
6505 	  }
6506 	  for(int i=vterm.arity()-1; i >= 0; i--){
6507 	    if (false == recSynMatch(gterm[i], vterm[i] , env)) {
6508 	      return false;
6509 	    }
6510 	  }
6511 	  return true;
6512 	}
6513 
6514 	if(false && !*d_useEqu){
6515 	  return false;
6516 	}
6517 
6518 	if( d_same_head_expr.count(vhead) > 0 ) {
6519 	  const Expr& findGterm = simplifyExpr(gterm);
6520 	  //if(isIntx(findGterm,0) || isIntx(findGterm,1)) return false;//special for simplify benchmark
6521 	  TRACE("quant match", "find gterm:", findGterm.toString(),"");
6522 	  CDList<Expr>* gls = d_same_head_expr[vhead];
6523 	  for(size_t i = 0; i<gls->size(); i++){
6524 	    if (simplifyExpr((*gls)[i]) == findGterm){
6525 	      TRACE("quant match", "find matched gterm:", (*gls)[i].toString(),"");
6526 	      DebugAssert((*gls)[i].arity() == vterm.arity(), "gls has different arity");
6527 
6528 	      for(int child=vterm.arity()-1; child >= 0 ; child--){
6529 		const Expr& newgterm = (*gls)[i];
6530 		if (false == recSynMatch(newgterm[child], vterm[child] , env)){
6531 		  TRACE("quant match", "match false", (*gls)[i][child].toString(), vterm[child].toString());
6532 		  return false;
6533 		}
6534 	      }
6535 	      TRACE("quant match", "good match, return true:", gterm, vterm.toString());
6536 	      return true;
6537 	    }
6538 	  }//end of for
6539 	  return false;
6540 	}
6541 	else  {
6542 	  return false;//end of if
6543 	}
6544       }
6545       else{
6546  	TRACE("quant match more", "match more", gterm.toString()+" # ", vterm.toString());
6547  	if( (gterm.getKind() == vterm.getKind()) &&
6548 	    (gterm.arity() == vterm.arity()) &&
6549 	    gterm.arity()>0 ){
6550  	  for(int child=0; child < vterm.arity() ; child++){
6551  	    if (false == recSynMatch(gterm[child], vterm[child] , env)){
6552  	      TRACE("quant match", "match false", gterm[child].toString(), vterm[child].toString());
6553  	      return false;
6554  	    }
6555  	  }
6556  	  return true;
6557  	}
6558 	else  return false;
6559       }
6560   }
6561 }
6562 
6563 */
6564 
6565 /*
6566 void TheoryQuant::goodSynMatch(const Expr& e,
6567 			       const std::vector<Expr> & boundVars,
6568 			       std::vector<std::vector<Expr> >& instBinds,
6569 			       std::vector<Expr>& instGterms,
6570 			       const CDList<Expr>& allterms,
6571 			       size_t tBegin){
6572   for (size_t i=tBegin; i<allterms.size(); i++)    {
6573     Expr gterm = allterms[i];
6574     if (0 == gterm.arity() )
6575       continue;
6576     TRACE("quant matching", gterm.toString(), "||", e.toString()) ;
6577     //    if( usefulInMatch(gterm) && possibleMatch(gterm,e))   {
6578     if(usefulInMatch(gterm))   {
6579       ExprMap<Expr> env;
6580       env.clear();
6581       bool found = recSynMatch(gterm,e,env);
6582       if(found){
6583 
6584 	TRACE("quant matching found", " good:",gterm.toString()+" to " , e.toString());
6585 	TRACE("quant matching found", " simplified good:",simplifyExpr(gterm).toString()+" to " , simplifyExpr(e).toString());
6586 	std::vector<Expr> inst;
6587 
6588 	DebugAssert((boundVars.size() == env.size()),"bound var size != env.size()");
6589 
6590 	for(size_t i=0; i<boundVars.size(); i++) {
6591 	  ExprMap<Expr>::iterator p = env.find(boundVars[i]);
6592 	  DebugAssert((p!=env.end()),"bound var cannot be found");
6593 	  inst.push_back(p->second);
6594 	}
6595 	instBinds.push_back(inst);
6596 	instGterms.push_back(gterm);
6597       }
6598       else{
6599 	TRACE("quant matching", "bad one",gterm.toString()+" to " , e.toString());
6600       }
6601     }
6602   }
6603 }
6604 
6605 */
6606 /*
6607 void TheoryQuant::goodSynMatchNewTrig(const Trigger& trig,
6608 				      const std::vector<Expr> & boundVars,
6609 				      std::vector<std::vector<Expr> >& instBinds,
6610 				      std::vector<Expr>& instGterms,
6611 				      const CDList<Expr>& allterms,
6612 				      size_t tBegin){
6613   for (size_t i=tBegin; i<allterms.size(); i++)    {
6614     Expr gterm (allterms[i]);
6615     //    TRACE("quant matching", gterm.toString(), "||", trig.getEx().toString()) ;
6616     if(usefulInMatch(gterm)) {
6617       ExprMap<Expr> env;
6618       env.clear();
6619       bool found = synMatchTopPred(gterm,trig,env);
6620       if(found){
6621 	//TRACE("quant matching found", " top good:",gterm.toString()+" to " , trig.getEx().toString());
6622 	std::vector<Expr> inst;
6623 	inst.clear();
6624 	DebugAssert((boundVars.size() <= env.size()),"bound var size != env.size()");
6625 
6626 	for(size_t i=0; i<boundVars.size(); i++) {
6627 	  ExprMap<Expr>::iterator p = env.find(boundVars[i]);
6628 	  DebugAssert((p!=env.end()),"bound var cannot be found");
6629 	  inst.push_back(p->second);
6630 	}
6631 
6632 	instBinds.push_back(inst);
6633 	instGterms.push_back(gterm);
6634       }
6635       else{
6636 	//	TRACE("quant matching", "bad one",gterm.toString()+" to ", trig.getEx().toString());
6637       }
6638     }
6639   }
6640 }
6641 */
6642 
6643 /*
6644 bool TheoryQuant::hasGoodSynInstNewTrigOld(Trigger& trig,
6645 					   std::vector<Expr> & boundVars,
6646 					   std::vector<std::vector<Expr> >& instBinds,
6647 					   std::vector<Expr>& instGterms,
6648 					   const CDList<Expr>& allterms,
6649 					   size_t tBegin){
6650 
6651   const std::set<Expr>& bvs = getBoundVars(trig.getEx());
6652 
6653   boundVars.clear();
6654   for(std::set<Expr>::const_iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
6655     boundVars.push_back(*i);
6656 
6657   instBinds.clear();
6658   goodSynMatchNewTrig(trig, boundVars, instBinds, instGterms, allterms, tBegin);
6659 
6660   if (instBinds.size() > 0)
6661     return true;
6662   else
6663     return false;
6664 }
6665 
6666 
6667 bool TheoryQuant::hasGoodSynInstNewTrig(Trigger& trig,
6668 					const std::vector<Expr>& boundVars,
6669 					std::vector<std::vector<Expr> >& instBinds,
6670 					std::vector<Expr>& instGterms,
6671 					const CDList<Expr>& allterms,
6672 					size_t tBegin){
6673 //   boundVars=trig.getBVs();
6674 //   const std::set<Expr>& bvs = getBoundVars(trig.getEx());
6675 
6676 //   boundVars.clear();
6677 //   for(std::set<Expr>::const_iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
6678 //     boundVars.push_back(*i);
6679 
6680   instBinds.clear();
6681   goodSynMatchNewTrig(trig, boundVars, instBinds, instGterms, allterms, tBegin);
6682 
6683   if (instBinds.size() > 0)
6684     return true;
6685   else
6686     return false;
6687 }
6688 */
loc_gterm(const std::vector<Expr> & border,const Expr & vterm,int pos)6689 int TheoryQuant::loc_gterm(const std::vector<Expr>& border,
6690 			   const Expr& vterm,
6691 			   int pos){
6692   const std::vector<Expr>& order = d_mtrigs_bvorder[vterm];
6693   const Expr& var = order[pos];
6694   for(size_t i=0; i<border.size(); i++){
6695     if (border[i] == var) return i;
6696   }
6697 
6698   DebugAssert(false, "internal error in loc_germ");
6699   return -1;
6700 }
6701 
6702 /*
6703 void  TheoryQuant::recSearchCover(const std::vector<Expr>& border,
6704 				  const std::vector<Expr>& mtrigs,
6705 				  int cur_depth,
6706 				  std::vector<std::vector<Expr> >& instSet,
6707 				  std::vector<Expr>& cur_inst
6708 				  ){
6709   int max_dep = mtrigs.size();
6710 
6711   if(cur_depth >= max_dep) return;
6712 
6713   Expr cur_vterm = mtrigs[cur_depth]; //get the current vterm
6714   if(d_mtrigs_inst.count(cur_vterm) <=0) return;
6715   CDList<std::vector<Expr> >* gterm_list = d_mtrigs_inst[cur_vterm]; // get the list of ground term found for cur_vterm
6716   for(size_t i=0; i< gterm_list->size(); i++){
6717     const std::vector<Expr>& cur_gterm = (*gterm_list)[i];
6718     std::vector<Expr> new_inst(border.size()); //get a new inst array
6719 
6720     for(size_t j=0; j< border.size(); j++){
6721       new_inst[j]=cur_inst[j]; //copy to cur_int to new_inst
6722     }
6723 
6724     bool has_problem = false;//next, try to put the cur gterm into new_inst
6725     for(size_t j=0; j< cur_gterm.size(); j++){
6726       int cur_loc_gterm = loc_gterm(border, cur_vterm, j);
6727 
6728       if( null_expr == new_inst[cur_loc_gterm]){
6729 	new_inst[cur_loc_gterm] = cur_gterm[j];
6730       }
6731       else if (new_inst[cur_loc_gterm] != cur_gterm[j]){
6732 	has_problem = true;
6733 	break;
6734       }
6735 
6736     }
6737 
6738     if (has_problem){
6739       continue;
6740     }
6741 
6742     bool finished = true;
6743     for(size_t j=0; j< border.size() ;j++){
6744       if(null_expr == new_inst[j]){
6745 	finished = false;
6746 	break;
6747       }
6748     }
6749 
6750     if(finished){
6751       std::vector<Expr> good_inst;
6752       for(size_t j=0; j<border.size(); j++){
6753 	good_inst.push_back(new_inst[j]);
6754       }
6755       instSet.push_back(good_inst);
6756     }
6757     else{
6758       recSearchCover(border,
6759 		     mtrigs,
6760 		     cur_depth+1,
6761 		     instSet,
6762 		     new_inst);
6763     }
6764   }//end of for
6765 }
6766 */
6767 /*
6768 void  TheoryQuant::searchCover(const Expr& thm,
6769 			       const std::vector<Expr>& border,
6770 			       std::vector<std::vector<Expr> >& instSet
6771 			       ){
6772   std::vector<Expr> dumy(border.size()) ; //use dynamic array here
6773   for(size_t j=0; j< border.size() ;j++){
6774     dumy[j]=null_expr;
6775   }
6776   const std::vector<Expr>& mtrigs = d_multTriggers[thm];
6777   recSearchCover(border, mtrigs, 0, instSet, dumy);
6778 }
6779 
6780 */
6781 /*
6782 bool TheoryQuant::hasGoodSynMultiInst(const Expr& thm,
6783 				      std::vector<Expr> & boundVars,
6784 				      std::vector<std::vector<Expr> >& instSet,
6785 				      const CDList<Expr>& allterms,
6786 				      size_t tBegin){
6787 
6788   const std::set<Expr>& bvs = getBoundVars(thm);
6789 
6790   boundVars.clear();
6791   for(std::set<Expr>::const_iterator i=bvs.begin(),iend=bvs.end(); i!=iend; ++i)
6792     boundVars.push_back(*i);
6793 
6794   instSet.clear();
6795 
6796   bool new_match = false;
6797   //assumption: every trig is different
6798   //this is not true later, fix this asap
6799   const std::vector<Expr>& mtrigs = d_multTriggers[thm];
6800 
6801   for(std::vector<Expr>::const_iterator i= mtrigs.begin(), iend = mtrigs.end(); i != iend; i++){
6802 
6803     if(d_mtrigs_bvorder[*i].empty()){ //setup an order
6804       const std::set<Expr>& trig_bvs = getBoundVars(*i);
6805       for(std::set<Expr>::const_iterator j= trig_bvs.begin(), jend = trig_bvs.end();
6806 	  j != jend;
6807 	  j++){
6808 	d_mtrigs_bvorder[*i].push_back(*j);
6809       }
6810     }
6811 
6812     const std::vector<Expr>& trig_bvorder = d_mtrigs_bvorder[*i];
6813     //    std::set<std::vector<Expr> > trig_insts;
6814     std::vector<std::vector<Expr> > trig_insts;
6815     trig_insts.clear();
6816 
6817     std::vector<Expr> gtms;
6818     goodSynMatch(*i, trig_bvorder, trig_insts, gtms, allterms, tBegin);
6819 
6820     if (trig_insts.size() > 0){
6821       new_match=true;
6822       if(d_mtrigs_inst.count(*i) <= 0){
6823 	d_mtrigs_inst[*i] = new(true) CDList<std::vector<Expr> > (theoryCore()->getCM()->getCurrentContext());
6824       }
6825       for(std::vector<std::vector<Expr> >::const_iterator j = trig_insts.begin(), jend = trig_insts.end();
6826 	  j != jend;
6827 	  j++){
6828 
6829 	d_mtrigs_inst[*i]->push_back(*j);
6830 	for(std::vector<Expr>::const_iterator k = j->begin(), kend = j->end();
6831 	    k != kend;
6832 	    k++){
6833 	}
6834       }
6835     }
6836   } // end of for
6837 
6838   for(std::vector<Expr>::const_iterator i= mtrigs.begin(), iend = mtrigs.end(); i != iend; i++){
6839     if (d_mtrigs_inst.count(*i) <=0 ) continue;
6840     for(CDList<std::vector<Expr> >::const_iterator j = d_mtrigs_inst[*i]->begin(),
6841 	  jend = d_mtrigs_inst[*i]->end();
6842 	  j != jend;
6843 	  j++){
6844 
6845       for(std::vector<Expr>::const_iterator k = j->begin(), kend = j->end();
6846 	  k != kend;
6847 	  k++){
6848       }
6849     }
6850   }
6851   {//code for search a cover
6852     if(new_match){
6853       searchCover(thm, boundVars, instSet);
6854     }
6855   }
6856 
6857   if(instSet.size() > 0 ) {
6858     return true;
6859   }
6860   else {
6861     return false;
6862   }
6863 
6864 }
6865 
6866 */
6867 /*
6868 
6869 bool inStrCache(std::set<std::string> cache, std::string str){
6870   return (cache.find(str) != cache.end());
6871 }
6872 */
6873 /*
6874 bool TheoryQuant::hasGoodSemInst(const Expr& e,
6875 				 std::vector<Expr> & boundVars,
6876 				 std::set<std::vector<Expr> >& instSet,
6877 				 size_t tBegin){
6878   return false;
6879 }
6880 
6881 */
6882 /*
6883 void genPartInstSetThm(const std::vector<Expr>&  bVarsThm,
6884 		       std::vector<Expr>& bVarsTerm,
6885 		       const std::vector<std::vector<Expr> >& termInst,
6886 		       std::vector<std::vector<Expr> >& instSetThm){
6887   ExprMap<bool> bVmap;
6888 
6889   for(size_t i=0; i< bVarsThm.size(); ++i)    {
6890     bVmap[bVarsThm[i]]=true;
6891   }
6892 
6893   std::vector<Expr> tempBVterm;
6894   std::vector<int> locTerm;
6895 
6896   for (size_t j=0; j<bVarsTerm.size(); j++){
6897     if (bVmap.count(bVarsTerm[j]) > 0){
6898       locTerm.push_back(1);
6899       tempBVterm.push_back(bVarsTerm[j]);
6900     }
6901     else{
6902       locTerm.push_back(0);
6903     }
6904   }
6905 
6906   DebugAssert(locTerm.size() == bVarsTerm.size(), "locTerm.size !- bVarsTerm.size()");
6907 
6908   for(std::vector<std::vector<Expr> >::const_iterator i=termInst.begin(),
6909 	iend=termInst.end();i!=iend; i++)  {
6910     std::vector<Expr> buf;
6911     buf.clear();
6912     for(size_t j=0; j< bVarsTerm.size(); ++j){
6913       if(locTerm[j])
6914 	buf.push_back((*i)[j]);
6915     }
6916     instSetThm.push_back(buf);
6917   }
6918   bVarsTerm=tempBVterm;
6919 }
6920 */
6921 
6922 /*
6923 void genInstSetThm(const std::vector<Expr>& bVarsThm,
6924 		   const std::vector<Expr>& bVarsTerm,
6925 		   const std::vector<std::vector<Expr> >& termInst,
6926 		   std::vector<std::vector<Expr> >& instSetThm){
6927 
6928   std::vector<int> bVmap;
6929 
6930   for(size_t i=0; i< bVarsThm.size(); ++i)    {
6931     bVmap.push_back(-1);
6932     for (size_t j=0; j<bVarsTerm.size(); j++){
6933       if (bVarsThm[i] == bVarsTerm[j]){
6934 	DebugAssert(bVmap[i] == -1, "bVmap[1] != -1");
6935 	bVmap[i]=j;
6936       }
6937     }
6938   }
6939 
6940   for(size_t i=0; i< bVarsThm.size(); ++i)
6941     if( -1 == bVmap[i])  {
6942       return;
6943     }
6944 
6945   for(std::vector<std::vector<Expr> >::const_iterator i=termInst.begin(),
6946 	iend=termInst.end();i!=iend; i++)  {
6947     std::vector<Expr> buf;
6948     buf.clear();
6949     for(size_t j=0; j< bVarsThm.size(); ++j){
6950       buf.push_back((*i)[bVmap[j]]);
6951     }
6952     instSetThm.push_back(buf);
6953   }
6954 }
6955 */
6956 
6957 /*
6958 void TheoryQuant::synInst(const Theorem & univ, const CDList<Expr>& allterms, size_t tBegin ){
6959   if(d_useFullTrig){
6960     synFullInst(univ, allterms, tBegin);
6961   }
6962 
6963   if(d_useMultTrig){
6964     synMultInst(univ, allterms, tBegin);
6965   }
6966 
6967   if(d_usePartTrig){
6968     synPartInst(univ, allterms, tBegin);
6969   }
6970 }
6971 */
6972 
transFound(const Expr & comb)6973 inline bool TheoryQuant::transFound(const Expr& comb){
6974   return (d_trans_found.count(comb) > 0);
6975 }
6976 
setTransFound(const Expr & comb)6977 inline void TheoryQuant::setTransFound(const Expr& comb){
6978   d_trans_found[comb] = true;
6979 }
6980 
trans2Found(const Expr & comb)6981 inline bool TheoryQuant::trans2Found(const Expr& comb){
6982   return (d_trans2_found.count(comb) > 0);
6983 }
6984 
setTrans2Found(const Expr & comb)6985 inline void TheoryQuant::setTrans2Found(const Expr& comb){
6986   d_trans2_found[comb] = true;
6987 }
6988 
6989 
backList(const Expr & ex)6990 inline CDList<Expr> & TheoryQuant::backList(const Expr& ex){
6991   if(d_trans_back.count(ex)>0){
6992     return *d_trans_back[ex];
6993   }
6994   else{
6995     return null_cdlist;
6996   }
6997 }
6998 
forwList(const Expr & ex)6999 inline CDList<Expr> & TheoryQuant::forwList(const Expr& ex){
7000   if(d_trans_forw.count(ex)>0){
7001     return *d_trans_forw[ex];
7002   }
7003   else{
7004     return null_cdlist;
7005   }
7006 }
7007 
pushBackList(const Expr & node,Expr ex)7008 inline void  TheoryQuant::pushBackList(const Expr& node, Expr ex){
7009   if(d_trans_back.count(node)>0){
7010     d_trans_back[node]->push_back(ex);
7011   }
7012   else{
7013     d_trans_back[node] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext());
7014     d_trans_back[node]->push_back(ex);
7015   }
7016 }
7017 
pushForwList(const Expr & node,Expr ex)7018 inline void  TheoryQuant::pushForwList(const Expr& node, Expr ex){
7019   if(d_trans_forw.count(node)>0){
7020     d_trans_forw[node]->push_back(ex);
7021   }
7022   else{
7023     d_trans_forw[node] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext());
7024     d_trans_forw[node]->push_back(ex);
7025   }
7026 }
7027 
7028 /*
7029 void TheoryQuant::synFullInst(const Theorem & univ, const CDList<Expr>& allterms, size_t tBegin ){
7030 
7031   const Expr& quantExpr = univ.getExpr();
7032   //  const std::vector<Expr>& bVarsThm = quantExpr.getVars();
7033   std::vector<Expr> bVarsThm = quantExpr.getVars();
7034 
7035   TRACE("quant inst", "try full inst with:|", quantExpr.toString() , " ");
7036 
7037   std::vector<std::vector<Expr> > instBindsThm; //set of instantiations for the thm,
7038   std::vector<std::vector<Expr> > instBindsTerm; //bindings, in the order of bVarsTrig
7039   std::vector<Expr > instGterms; //instGterms are gterms matched, instBindsTerm and instGterms must have the same length
7040   std::vector<Expr> bVarsTrig;
7041 
7042   if(*d_useTrigNew){
7043     std::vector<Trigger>& new_trigs=d_fullTrigs[quantExpr];
7044     for( size_t i= 0; i<new_trigs.size(); i++)  {
7045       Trigger& trig = new_trigs[i];
7046       //      if( 0 != trig.getPri()) continue;
7047       TRACE("quant inst","try new full trigger:|", trig.getEx().toString(),"");
7048 
7049       instBindsTerm.clear();
7050       bVarsTrig.clear();
7051       instBindsThm.clear();
7052       instGterms.clear();
7053 
7054       {//code for trans2
7055 	if(trig.hasTr2()){
7056 	  //if(hasGoodSynInstNewTrig(trig, bVarsTrig, instBindsTerm, instGterms, allterms, tBegin)) {
7057 	  if(hasGoodSynInstNewTrig(trig, trig.getBVs(), instBindsTerm, instGterms, allterms, tBegin)) {
7058 	    for(size_t j=0; j<instBindsTerm.size(); j++){
7059 	      DebugAssert(2 == instBindsTerm[j].size(), "internal error in trans2");
7060 
7061 	      Expr& gterm = instGterms[j];
7062 
7063 	      if(simplifyExpr(instBindsTerm[j][0]) != simplifyExpr(instBindsTerm[j][1])){
7064 		Expr comb = Expr(RAW_LIST,instBindsTerm[j][0],instBindsTerm[j][1]);
7065 		if(!trans2Found(comb)){
7066 		  setTrans2Found(comb);
7067 
7068 		  TRACE("quant trans","new trans2: ", vectorExpr2string(instBindsTerm[j]), "");
7069 
7070 		  Expr comb_rev = Expr(RAW_LIST,instBindsTerm[j][1],instBindsTerm[j][0]);
7071 		  if(trans2Found(comb_rev)){
7072 		    Expr sr(instBindsTerm[j][0]);
7073 		    Expr dt(instBindsTerm[j][1]);
7074 
7075 		    vector<Expr> bind;
7076 		    bind.clear();
7077 		    bind.push_back(sr);
7078 		    bind.push_back(dt);
7079 
7080 		    enqueueInst(univ, bind, gterm);
7081 		    TRACE("quant inst", "trans pred rule2 ", univ.toString(), " | with bind: "+vectorExpr2string(bind));  		    TRACE("quant trans", "trans2 ", vectorExpr2string(bind), "");
7082 		  }
7083 		}
7084 	      }
7085 	    }
7086 	  }
7087 	  return;
7088 	}
7089       }
7090 
7091       {//code for trans pred
7092 	if(trig.hasTr()){
7093 	  //	  if(hasGoodSynInstNewTrig(trig, bVarsTrig, instBindsTerm, instGterms, allterms, tBegin)) {
7094 	  if(hasGoodSynInstNewTrig(trig, trig.getBVs(), instBindsTerm, instGterms, allterms, tBegin)) {
7095 	    for(size_t j=0; j<instBindsTerm.size(); j++){
7096 	      DebugAssert(2 == instBindsTerm[j].size(), "internal error in trans");
7097 
7098 	      Expr& gterm = instGterms[j];
7099 
7100 	      if(simplifyExpr(instBindsTerm[j][0]) != simplifyExpr(instBindsTerm[j][1])){
7101 
7102 		Expr comb = Expr(RAW_LIST,instBindsTerm[j][0],instBindsTerm[j][1]);
7103 
7104 		if(!transFound(comb)){
7105 		  setTransFound(comb);
7106 
7107 		  TRACE("quant trans","new: ", vectorExpr2string(instBindsTerm[j]), "");
7108 
7109 		  Expr sr(instBindsTerm[j][0]);
7110 		  Expr dt(instBindsTerm[j][1]);
7111 
7112 		  const CDList<Expr>& dtForw = forwList(dt);
7113 		  const CDList<Expr>& srBack = backList(sr);
7114 
7115 		  for(size_t k=0; k<dtForw.size(); k++){
7116 		    vector<Expr> bind;
7117 		    bind.clear();
7118 		    bind.push_back(sr);
7119 		    bind.push_back(dt);
7120 		    bind.push_back(dtForw[k]);
7121 
7122 		    enqueueInst(univ, bind, gterm);
7123 
7124 		    TRACE("quant inst", "trans pred rule", univ.toString(), " | with bind: "+vectorExpr2string(bind));
7125 		    TRACE("quant trans", "trans res forw: ", vectorExpr2string(bind), "");
7126 		  }
7127 
7128 		  for(size_t k=0; k<srBack.size(); k++){
7129 		    vector<Expr> bind;
7130 		    bind.clear();
7131 		    bind.push_back(srBack[k]);
7132 		    bind.push_back(sr);
7133 		    bind.push_back(dt);
7134 
7135 		    enqueueInst(univ, bind, gterm);
7136 		    TRACE("quant inst", "trans pred rule ", univ.toString(), " | with bind: "+vectorExpr2string(bind));
7137   		    TRACE("quant trans", "trans res back: ", vectorExpr2string(bind), "");
7138 		  }
7139 
7140 		  pushForwList(sr,dt);
7141 		  pushBackList(dt,sr);
7142 		}
7143 	      }
7144 	    }
7145 	  }
7146 	  return;
7147 	}
7148       }
7149 
7150       bool univsHasMoreBVs ;
7151 
7152       univsHasMoreBVs = (d_hasMoreBVs.count(quantExpr) > 0);
7153 
7154       //      if ( !d_allout || !trig.isSimp() || univsHasMoreBVs || *d_useLazyInst){
7155       //      if ( !d_allout || !trig.isSimp() || univsHasMoreBVs || true){
7156       if  ( !d_allout || !trig.isSuperSimp() || univsHasMoreBVs ){
7157       //      if ( !d_allout || !trig.isSimp() || univsHasMoreBVs ){
7158       */
7159 	/*
7160 	if(hasGoodSynInstNewTrigOld(trig, bVarsTrig, instBindsTerm, instGterms, allterms, tBegin)) {
7161 	  genInstSetThm(bVarsThm, bVarsTrig, instBindsTerm, instBindsThm);
7162 	  for (size_t j = 0; j<instBindsTerm.size(); j++){
7163  	    const Expr& gterm = instGterms[j];
7164  	    const std::vector<Expr>& binds = instBindsThm[j];
7165  	    enqueueInst(univ, trig, binds, gterm);
7166  	    TRACE("quant inst", "insert full inst", univ.toString(), " | with bind: "+vectorExpr2string(binds));
7167  	  }
7168  	}
7169 	*/
7170 /*
7171 	bVarsTrig=trig.getBVs();//vVarsTrig is used later, do not forget this.
7172  	if(hasGoodSynInstNewTrig(trig, bVarsThm, instBindsTerm, instGterms, allterms, tBegin)) {
7173   	  for (size_t j = 0; j<instBindsTerm.size(); j++){
7174   	    const Expr& gterm = instGterms[j];
7175   	    const std::vector<Expr>& binds = instBindsTerm[j];
7176 
7177   	    enqueueInst(univ, trig, binds, gterm);
7178 
7179   	    TRACE("quant inst", "insert full inst", univ.toString(), " | with bind: "+vectorExpr2string(binds));
7180   	  }
7181   	}
7182 
7183       }
7184 
7185       //      if(!d_allout || *d_useLazyInst){
7186       if(!d_allout){
7187 	if(trig.hasRW() ){
7188 
7189 	  if(1 == bVarsTrig.size()){
7190 	    std::vector<Expr> tp = d_arrayIndic[trig.getHead()];
7191 	    for(size_t i=0; i<tp.size(); i++){
7192 	      std::vector<Expr> tp = d_arrayIndic[trig.getHead()];
7193 
7194 	      Expr index = tp[i];
7195 	      std::vector<Expr> temp;
7196 	      temp.clear();
7197 	      temp.push_back(index);
7198 
7199 	      enqueueInst(univ, temp, index);
7200 	      TRACE("quant inst", "read write rule", univ.toString(), " | with bind: "+vectorExpr2string(temp));
7201 	    }
7202 	  }
7203 	  else{
7204 	  }
7205 	}
7206       }
7207     }//end for each trigger
7208   }
7209 }
7210 */
7211 
arrayHeuristic(const Trigger & trig,size_t univ_id)7212 void TheoryQuant::arrayHeuristic(const Trigger& trig, size_t univ_id){
7213   return;
7214   std::vector<Expr> tp = d_arrayIndic[trig.head];
7215   for(size_t i=0; i<tp.size(); i++){
7216     const Expr& index = tp[i];
7217     std::vector<Expr> temp;
7218     temp.push_back(index);
7219     enqueueInst(univ_id, temp, index);
7220     //	  TRACE("quant inst", "read write rule", univ.toString(), " | with bind: "+vectorExpr2string(temp));
7221   }
7222 }
7223 
iterFWList(const Expr & sr,const Expr & dt,size_t univ_id,const Expr & gterm)7224 void inline TheoryQuant::iterFWList(const Expr& sr, const Expr& dt, size_t univ_id, const Expr& gterm){
7225   const CDList<Expr>& dtForw = forwList(dt);
7226   for(size_t k=0; k<dtForw.size(); k++){
7227     vector<Expr> tri_bind;
7228     tri_bind.push_back(sr);
7229     tri_bind.push_back(dt);
7230     tri_bind.push_back(dtForw[k]);
7231     enqueueInst(univ_id, tri_bind, gterm);
7232   }
7233 }
7234 
iterBKList(const Expr & sr,const Expr & dt,size_t univ_id,const Expr & gterm)7235 void inline TheoryQuant::iterBKList(const Expr& sr, const Expr& dt, size_t univ_id, const Expr& gterm){
7236   const CDList<Expr>& srBack = backList(sr);
7237   for(size_t k=0; k<srBack.size(); k++){
7238     vector<Expr> tri_bind;
7239     tri_bind.push_back(srBack[k]);
7240     tri_bind.push_back(sr);
7241     tri_bind.push_back(dt);
7242     enqueueInst(univ_id, tri_bind, gterm);
7243   }
7244 }
7245 
7246 
7247 
simpRAWList(const Expr & org)7248 Expr TheoryQuant::simpRAWList(const Expr& org){
7249   vector<Expr> result;
7250   if(null_expr == org) return null_expr;
7251   for(int i =0 ; i < org.arity(); i++){
7252     result.push_back(simplifyExpr(org[i]));
7253   }
7254   return Expr(RAW_LIST,result);
7255 }
7256 
7257 
synNewInst(size_t univ_id,const vector<Expr> & bind,const Expr & gterm,const Trigger & trig)7258 void TheoryQuant::synNewInst(size_t univ_id, const vector<Expr>& bind, const Expr& gterm, const Trigger& trig ){
7259   if(trig.isMulti){
7260     const multTrigsInfo& mtriginfo = d_all_multTrigsInfo[trig.multiId];
7261 
7262     vector<Expr> actual_bind;
7263     for(size_t i=0, iend=bind.size(); i<iend; i++){
7264       if(null_expr != bind[i]){
7265 	actual_bind.push_back(bind[i]);
7266       }
7267     }
7268 
7269     Expr actual_bind_expr = Expr(RAW_LIST, actual_bind);
7270 
7271     size_t index = trig.multiIndex;
7272 
7273     // first,  test if we have see this binding before
7274     CDMap<Expr,bool> * oldBindMap = mtriginfo.var_binds_found[index];
7275     CDMap<Expr,bool>::iterator cur_iter = oldBindMap->find(actual_bind_expr);
7276 
7277     if (oldBindMap->end() != cur_iter){
7278       return;
7279     }
7280     else{
7281       (*oldBindMap)[actual_bind_expr] = true;
7282     }
7283 
7284     //for now, we only have one set of commom positions, so it must be 0
7285     //this is not true later.
7286     const vector<size_t>& comm_pos = mtriginfo.common_pos[0];
7287     size_t comm_pos_size = comm_pos.size();
7288 
7289     Expr comm_expr;
7290     vector<Expr> comm_expr_vec;
7291     for(size_t i = 0; i < comm_pos_size; i++){
7292       comm_expr_vec.push_back(bind[comm_pos[i]]);
7293     }
7294 
7295     if(0 == comm_pos_size){
7296       comm_expr = null_expr;
7297     }
7298     else{
7299       comm_expr = Expr(RAW_LIST, comm_expr_vec);
7300     }
7301 
7302     Expr uncomm_expr;
7303     vector<Expr> uncomm_expr_vec;
7304 
7305     const vector<size_t>& uncomm_pos = mtriginfo.var_pos[index];
7306     size_t uncomm_pos_size = uncomm_pos.size();
7307     for(size_t i = 0; i< uncomm_pos_size; i++){
7308       uncomm_expr_vec.push_back(bind[uncomm_pos[i]]);
7309     }
7310     if(0 == uncomm_pos_size){
7311       uncomm_expr = null_expr;
7312     }
7313     else{
7314       uncomm_expr = Expr(RAW_LIST, uncomm_expr_vec);
7315     }
7316 
7317     CDList<Expr>* add_into_list ;
7318     CDList<Expr>* iter_list;
7319     ExprMap<CDList<Expr>* >::iterator add_into_iter;
7320     ExprMap<CDList<Expr>* >::iterator iter_iter;
7321 
7322     size_t other_index = 0;
7323     if(0 == index){
7324       other_index =1;
7325     }
7326     else if (1 == index){
7327       other_index = 0;
7328     }
7329     else{
7330       FatalAssert(false, "Sorry, only two vterms in a multi-trigger.");
7331     }
7332 
7333     add_into_iter = mtriginfo.uncomm_list[index]->find(comm_expr);
7334 
7335     if(mtriginfo.uncomm_list[index]->end() == add_into_iter){
7336       add_into_list = new (true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext());
7337       (*mtriginfo.uncomm_list[index])[comm_expr] = add_into_list;
7338     }
7339     else{
7340       add_into_list = add_into_iter->second;
7341     }
7342 
7343     add_into_list->push_back(uncomm_expr);
7344 
7345 
7346     Expr simpCommExpr = simpRAWList(comm_expr);
7347 //     if(simpCommExpr != comm_expr) {
7348 //       cout<<"common and simplified comm expr" << comm_expr << " I " << simpCommExpr << endl;
7349 //     }
7350 
7351     { //
7352       ExprMap<CDList<Expr>* >* otherMap = mtriginfo.uncomm_list[other_index];
7353 
7354       //      iter_iter = mtriginfo.uncomm_list[other_index]->find(comm_expr);
7355       ExprMap<CDList<Expr>* >::iterator otherMapBegin = otherMap->begin(), otherMapEnd = otherMap->end();
7356       for(ExprMap<CDList<Expr>* >::iterator otherMapIter = otherMapBegin; otherMapIter != otherMapEnd; otherMapIter++){
7357 
7358 	Expr otherCommonExpr = simpRAWList(otherMapIter->first);
7359 	if(simpCommExpr != otherCommonExpr) continue;
7360 	//	iter_iter = otherMap->find(comm_expr);
7361 	//	if(mtriginfo.uncomm_list[other_index]->end() == iter_iter){
7362 	//	  return;
7363 	//	}
7364 	//	else{
7365 	//	  iter_list = iter_iter->second;
7366 	//	}
7367 
7368 	if(comm_expr != otherMapIter->first) {
7369 	}
7370 
7371 	iter_list = otherMapIter->second;
7372 	const vector<size_t>& uncomm_iter_pos = mtriginfo.var_pos[other_index];
7373 	size_t uncomm_iter_pos_size = uncomm_iter_pos.size();
7374 
7375 	for(size_t i =0, iend = iter_list->size(); i<iend; i++){
7376 	  const Expr& cur_iter_expr = (*iter_list)[i];
7377 	  vector<Expr> new_bind(bind);
7378 	  for(size_t j=0; j<uncomm_iter_pos_size; j++){
7379 	    new_bind[uncomm_iter_pos[j]] = cur_iter_expr[j];
7380 	  }
7381 	  enqueueInst(univ_id, new_bind, gterm);
7382 	}
7383       }
7384     }
7385     return;
7386   }
7387 
7388   {//code for trans2
7389     if(trig.hasT2){
7390       vector<Expr> actual_bind;
7391       for(size_t i=0; i<bind.size(); i++){
7392 	if(bind[i] != null_expr){
7393 	  actual_bind.push_back(bind[i]);
7394 	}
7395       }
7396       if(actual_bind.size() != 2){
7397 	//	cout<<"2 != bind.size()" <<endl;
7398       }
7399 
7400       Expr acb1 = simplifyExpr(actual_bind[0]);
7401       Expr acb2 = simplifyExpr(actual_bind[1]);
7402       actual_bind[0]=acb1;
7403       actual_bind[1]=acb2;
7404       if(acb1 != acb2){
7405 	Expr comb = Expr(RAW_LIST,acb1, acb2);
7406 	if(!trans2Found(comb)){
7407 	  setTrans2Found(comb);
7408 	  Expr comb_rev = Expr(RAW_LIST,acb2, acb1);
7409 	  if(trans2Found(comb_rev)){
7410 	    enqueueInst(univ_id, actual_bind, gterm);
7411 	  }
7412 	}
7413       }
7414     return;
7415     }
7416   }
7417 
7418   {//code for trans pred
7419     if(trig.hasTrans){
7420       vector<Expr> actual_bind;
7421       for(size_t i=0; i<bind.size(); i++){
7422 	if(bind[i] != null_expr){
7423 	  actual_bind.push_back(simplifyExpr(bind[i]));
7424 	}
7425       }
7426       if(simplifyExpr(actual_bind[0]) != simplifyExpr(actual_bind[1])){
7427 	Expr comb = Expr(RAW_LIST,actual_bind[0], actual_bind[1]);
7428 
7429 	if(!transFound(comb)){
7430 	  setTransFound(comb);
7431 
7432 	  Expr sr(actual_bind[0]);
7433 	  Expr dt(actual_bind[1]);
7434 
7435 	  iterFWList(sr, dt, univ_id, gterm);
7436 	  if(*d_useNewEqu){
7437 	    Expr cur_next = dt.getEqNext().getRHS();
7438 	    while (cur_next != dt) {
7439 	      iterFWList(sr, cur_next, univ_id, gterm);
7440 	      cur_next = cur_next.getEqNext().getRHS();
7441 	    }
7442 	  }
7443 
7444 	  iterBKList(sr, dt, univ_id, gterm);
7445 	  if(*d_useNewEqu){
7446 	    Expr cur_next = sr.getEqNext().getRHS();
7447 	    while (cur_next != sr) {
7448 	      iterBKList(cur_next, dt, univ_id, gterm);
7449 	      cur_next = cur_next.getEqNext().getRHS();
7450 	    }
7451 	  }
7452 	  pushForwList(sr,dt);
7453 	  pushBackList(dt,sr);
7454 	}
7455       }
7456       return;
7457     }
7458   } //end of code for trans
7459 
7460   //  cout<<"before enqueueisnt"<<endl;
7461   enqueueInst(univ_id, bind, gterm);
7462   //      if(!d_allout || *d_useLazyInst){
7463 
7464 }
7465 
7466 
7467 /*
7468 
7469 void TheoryQuant::synNewInst(size_t univ_id, const vector<Expr>& bind, const Expr& gterm, const Trigger& trig ){
7470   //  cout<<"synnewinst "<<univ_id<<endl;
7471   {//code for trans2
7472     if(trig.hasT2){
7473       vector<Expr> actual_bind;
7474       for(size_t i=0; i<bind.size(); i++){
7475 	if(bind[i] != null_expr){
7476 	  actual_bind.push_back(bind[i]);
7477 	}
7478       }
7479       if(actual_bind.size() != 2){
7480 	cout<<"2 != bind.size()" <<endl;
7481       }
7482       if(simplifyExpr(actual_bind[0]) != simplifyExpr(actual_bind[1])){
7483 	Expr comb = Expr(RAW_LIST,actual_bind[0], actual_bind[1]);
7484 	if(!trans2Found(comb)){
7485 	  setTrans2Found(comb);
7486 	  Expr comb_rev = Expr(RAW_LIST,actual_bind[1], actual_bind[0]);
7487 	  if(trans2Found(comb_rev)){
7488 	    enqueueInst(univ_id, actual_bind, gterm);
7489 	  }
7490 	}
7491       }
7492     return;
7493     }
7494   }
7495 
7496   {//code for trans pred
7497     if(trig.hasTrans){
7498       vector<Expr> actual_bind;
7499       for(size_t i=0; i<bind.size(); i++){
7500 	if(bind[i] != null_expr){
7501 	  actual_bind.push_back(bind[i]);
7502 	}
7503       }
7504       if(simplifyExpr(actual_bind[0]) != simplifyExpr(actual_bind[1])){
7505 	Expr comb = Expr(RAW_LIST,actual_bind[0], actual_bind[1]);
7506 
7507 	if(!transFound(comb)){
7508 	  setTransFound(comb);
7509 
7510 	  Expr sr(actual_bind[0]);
7511 	  Expr dt(actual_bind[1]);
7512 
7513 	  const CDList<Expr>& dtForw = forwList(dt);
7514 	  const CDList<Expr>& srBack = backList(sr);
7515 
7516 	  for(size_t k=0; k<dtForw.size(); k++){
7517 	    vector<Expr> tri_bind;
7518 	    tri_bind.push_back(sr);
7519 	    tri_bind.push_back(dt);
7520 	    tri_bind.push_back(dtForw[k]);
7521 
7522 	    enqueueInst(univ_id, tri_bind, gterm);
7523 	  }
7524 
7525 	  for(size_t k=0; k<srBack.size(); k++){
7526 	    vector<Expr> tri_bind;
7527 	    tri_bind.push_back(srBack[k]);
7528 	    tri_bind.push_back(sr);
7529 	    tri_bind.push_back(dt);
7530 
7531 	    enqueueInst(univ_id, tri_bind, gterm);
7532 	    //	    TRACE("quant inst", "trans pred rule ", univ.toString(), " | with bind: "+vectorExpr2string(bind));
7533 	    //	    TRACE("quant trans", "trans res back: ", vectorExpr2string(bind), "");
7534 	  }
7535 
7536 	  pushForwList(sr,dt);
7537 	  pushBackList(dt,sr);
7538 	}
7539       }
7540       return;
7541     }
7542   }
7543   //  cout<<"before enqueueisnt"<<endl;
7544   enqueueInst(univ_id, bind, gterm);
7545 
7546   //      if(!d_allout || *d_useLazyInst){
7547   if(!d_allout){
7548     if(trig.hasRWOp ){
7549 
7550       if(1 == trig.bvs.size()){
7551 	std::vector<Expr> tp = d_arrayIndic[trig.head];
7552 	for(size_t i=0; i<tp.size(); i++){
7553 	  std::vector<Expr> tp = d_arrayIndic[trig.head];
7554 
7555 	  Expr index = tp[i];
7556 	  std::vector<Expr> temp;
7557 	  temp.clear();
7558 	  temp.push_back(index);
7559 
7560 	  enqueueInst(univ_id, temp, index);
7561 	  //	  TRACE("quant inst", "read write rule", univ.toString(), " | with bind: "+vectorExpr2string(temp));
7562 	}
7563       }
7564       else{
7565       }
7566     }
7567   }
7568 }
7569 */
7570 
7571 /*
7572 void TheoryQuant::synMultInst(const Theorem & univ, const CDList<Expr>& allterms, size_t tBegin ){
7573 
7574   const Expr& quantExpr = univ.getExpr();
7575 
7576   if(d_multTriggers[quantExpr].size() <= 0) return ;
7577 
7578   TRACE("quant inst", "try muli with:|", quantExpr.toString() , " ");
7579   const std::vector<Expr>& bVarsThm = quantExpr.getVars();
7580 
7581   std::vector<std::vector<Expr> > instSetThm; //set of instantiations for the thm
7582   std::vector<std::vector<Expr> > termInst; //terminst are bindings, in the order of bVarsTrig
7583   std::vector<Expr> bVarsTrig;
7584 
7585 
7586   if(hasGoodSynMultiInst(quantExpr, bVarsTrig, termInst, allterms, tBegin)) {
7587     genInstSetThm(bVarsThm, bVarsTrig, termInst, instSetThm);
7588   }
7589   {
7590     for(std::vector<std::vector<Expr> >::iterator i=instSetThm.begin(), iend=instSetThm.end(); i!=iend; ++i) {
7591       enqueueInst(univ, *i, null_expr);//fix the null_expr here asap
7592       TRACE("quant inst", "insert mult inst", univ.toString(), " | with bind: "+vectorExpr2string(*i));
7593     }
7594   }
7595 
7596 }
7597 */
7598 /*
7599 void TheoryQuant::synPartInst(const Theorem & univ, const CDList<Expr>& allterms,  size_t tBegin ){
7600 
7601   const Expr& quantExpr = univ.getExpr();
7602   TRACE("quant inst", "try part with ", quantExpr.toString() , " ");
7603 
7604   const std::vector<Trigger>& triggers = d_partTrigs[quantExpr];
7605 
7606   std::vector<std::vector<Expr> > instSetThm; //set of instantiations for the thm
7607   std::vector<std::vector<Expr> > termInst; //terminst are bindings, in the order of bVarsTrig
7608   std::vector<Expr> bVarsTrig;
7609   std::vector<Expr> instGterms;
7610 
7611   for( std::vector<Trigger>::const_iterator i= triggers.begin(), iend=triggers.end();i!=iend;++i)  {
7612 
7613     Trigger trig = *i;
7614     TRACE("quant inst","handle part trigger", trig.getEx().toString(),"");
7615     termInst.clear();
7616     bVarsTrig.clear();
7617     instSetThm.clear();
7618     //    if(hasGoodSynInstNewTrig(trig, bVarsTrig, termInst, instGterms,allterms, tBegin)) {
7619     if(hasGoodSynInstNewTrig(trig, trig.getBVs(), termInst, instGterms,allterms, tBegin)) {
7620       TRACE("quant syninst", "has good ", termInst.size(),"");
7621       TRACE("quant syninst", "after good ",instSetThm.size(), "");
7622 
7623       Theorem newUniv = d_rules->adjustVarUniv(univ, trig.getBVs());
7624 
7625       TRACE("quant syninst", " new univ:" ,newUniv.toString(),"");
7626       {
7627 	for(size_t i = 0; i< termInst.size(); i++){
7628 	  const std::vector<Expr>& binds = termInst[i];
7629 	  const Expr& gterm = instGterms[i];
7630 	  enqueueInst(newUniv, binds, gterm);
7631 	  TRACE("quant yeting inst", "instantiating =========", "" , "");
7632 	  TRACE("quant yeting inst", "instantiating", newUniv.getExpr().toString(), " | with bind: "+vectorExpr2string(binds));
7633 	  TRACE("quant yeting inst", "instantiating org ", univ.getExpr().toString(), " | with gterm "+gterm.toString());
7634 	}
7635       }
7636     }
7637   }
7638 }
7639 
7640 */
7641 /*
7642 void TheoryQuant::semInst(const Theorem & univ, size_t tBegin){
7643 }
7644 */
7645 
7646 
checkSat(bool fullEffort)7647 void TheoryQuant::checkSat(bool fullEffort){
7648 
7649   if(*d_translate) return;
7650   if(d_rawUnivs.size() <=0 ) return;
7651   if (d_maxILReached) {
7652     //    cout<<"return bc max il "<<endl;
7653     return;
7654   }
7655   else{
7656   }
7657 
7658   DebugAssert(d_univsQueue.size() == 0, "something left in d_univsQueue");
7659   DebugAssert(d_simplifiedThmQueue.size() == 0, "something left in d_univsQueue");
7660 
7661   if( false ) {
7662   //  if( false || true) {
7663 
7664     for(size_t eqs_index = d_lastEqsUpdatePos; eqs_index < d_eqsUpdate.size();  eqs_index++){
7665 
7666       Theorem eqThm = d_eqsUpdate[eqs_index];
7667       //      const Expr& leftTerm = eqThm.getLHS();
7668       const Expr& rightTerm = eqThm.getRHS();
7669 
7670       std::vector<multTrigsInfo> d_all_multTrigsInfo;
7671       //      cout<< " size " << d_all_multTrigsInfo.size() << endl;
7672       int numUsefulMultTriger = 0;
7673       for(size_t i = 0; i < d_all_multTrigsInfo.size(); i++){
7674 	multTrigsInfo& curMultiTrigger =  d_all_multTrigsInfo[i];
7675 	if(curMultiTrigger.uncomm_list.size() != 2 ){
7676 	  FatalAssert(false, "error in ");
7677 	}
7678 	ExprMap<CDList<Expr>* >* uncommonMapOne = curMultiTrigger.uncomm_list[0];
7679 	ExprMap<CDList<Expr>* >* uncommonMapTwo = curMultiTrigger.uncomm_list[1];
7680 
7681 	if(uncommonMapOne->size() != 0 || uncommonMapTwo->size() != 0 ){
7682 	  numUsefulMultTriger++;
7683 	}
7684 
7685 	//	continue;
7686 
7687 	if(uncommonMapOne->size() == 0 ) {
7688 	  continue;
7689 	}
7690 
7691 	//why uncommonMapOne is empty but uncommonMapTwo is not?, let me figure this out.
7692 
7693 
7694 	ExprMap<CDList<Expr>* >::iterator iterOneBegin(uncommonMapOne->begin()), iterOneEnd(uncommonMapOne->end());
7695 
7696 	//cout<<"left and right " << leftTerm << " $ " << rightTerm <<endl;
7697 	//	cout<<"------------ left and right ---------" << leftTerm << " $ " << rightTerm <<endl;
7698 
7699 	vector<pair<Expr, CDList<Expr>* > > oneFoundTerms;
7700 	for(ExprMap<CDList<Expr>* >::iterator iterOne=iterOneBegin; iterOne != iterOneEnd; iterOne++){
7701 
7702 	  if(simplifyExpr((iterOne->first)[0]) == simplifyExpr(rightTerm)){ //for test only for trans
7703 	    //	    cout<<"found one " << iterOne->first << endl;
7704 	    //	    oneFoundTerms.push_back(iterOne->second);
7705 	    oneFoundTerms.push_back(*iterOne);
7706 	  }
7707 	}
7708 
7709 	ExprMap<CDList<Expr>* >::iterator iterTwoBegin(uncommonMapTwo->begin()), iterTwoEnd(uncommonMapTwo->end());
7710 	//	vector<CDList<Expr>* > twoFoundTerms;
7711 	vector<pair<Expr, CDList<Expr>* > >twoFoundTerms;
7712 	for(ExprMap<CDList<Expr>* >::iterator iterTwo = iterTwoBegin; iterTwo != iterTwoEnd; iterTwo++){
7713 	  if(simplifyExpr((iterTwo->first)[0]) == simplifyExpr(rightTerm)){
7714 	    //	    cout<<"found two " << iterTwo->first << endl;
7715 	    //	    twoFoundTerms.push_back(iterTwo->second);
7716 	    twoFoundTerms.push_back(*iterTwo);
7717 	  }
7718 	}
7719 	{
7720 	  for(size_t i= 0 ; i< oneFoundTerms.size(); i++){
7721 	    for(size_t j= 0 ; j< twoFoundTerms.size(); j++){
7722 	      pair<Expr, CDList<Expr>* > pairOne = oneFoundTerms[i];
7723 	      pair<Expr, CDList<Expr>* > pairTwo = twoFoundTerms[j];
7724 	      if(pairOne.first == pairTwo.first) continue;
7725 	      //	      cout<<"pairone.first " << pairOne.first << endl;
7726 	      //	      cout<<"pairTwo.first " << pairTwo.first << endl;
7727 	      CDList<Expr>* oneExprList = pairOne.second;
7728 	      CDList<Expr>* twoExprList = pairTwo.second;
7729               //	      cout<<"one size" << oneExprList->size() << endl;
7730 	      for(size_t oneIter = 0; oneIter < oneExprList->size(); oneIter++){
7731 		//		cout<<"two size" << twoExprList->size() << endl;
7732 		for(size_t twoIter = 0; twoIter < twoExprList->size(); twoIter++){
7733 		  Expr gterm1 = (*oneExprList)[oneIter][0];
7734 		  Expr gterm2 = (*twoExprList)[twoIter][0];
7735 		  //		  cout<<"one and two " << oneIter << " # " << twoIter << endl;
7736 		  //		  cout<<"one and two " << gterm1 << " # " << gterm2 << endl;
7737 		  vector<Expr> bind ;
7738 		  bind.push_back(gterm1);
7739 		  bind.push_back(rightTerm);
7740 		  bind.push_back(gterm2);
7741 		  size_t univID = curMultiTrigger.univ_id;
7742 
7743 		  if(d_univs[univID] != curMultiTrigger.univThm) {
7744 		    //		    cout << "errror in debuging:" << endl;
7745                     //		    cout << d_univs[univID] << endl;
7746                     //		    cout << curMultiTrigger.univThm << endl;
7747 		    exit(3);
7748 		  }
7749 
7750 		  enqueueInst(curMultiTrigger.univ_id, bind, rightTerm);
7751 		  //		  cout << "enqueued 1" <<  vectorExpr2string(bind) <<endl;
7752 
7753  		  bind.clear();
7754  		  bind.push_back(gterm2);
7755  		  bind.push_back(rightTerm);
7756  		  bind.push_back(gterm1);
7757  		  enqueueInst(curMultiTrigger.univ_id, bind, rightTerm);
7758 		  //		  cout << "enqueued 3" <<  vectorExpr2string(bind) <<endl;
7759 
7760 		}
7761 	      }
7762 	    }
7763 	  }
7764 	}//end of add founded new matchings
7765       }
7766       //      cout << "useful multriggers " << numUsefulMultTriger << endl;
7767     }
7768   }
7769 
7770   sendInstNew();
7771   /*
7772   {//to test update eqs list
7773     //    cout<<"# equs in checksat "<<endl;
7774 
7775     cout<<"---------in checksat ----------------" << endl;
7776     for(size_t eqs_index = d_lastEqsUpdatePos; eqs_index < d_eqsUpdate.size();  eqs_index++){
7777 
7778       Theorem t = d_eqsUpdate[eqs_index];
7779       const Expr& leftTerm = t.getLHS();
7780       NotifyList* leftUpList = leftTerm.getNotify();
7781       cout<<"left term is " << leftTerm << " || " << simplifyExpr(leftTerm) << endl;
7782 
7783       if(NULL == leftUpList) continue;
7784 
7785 
7786       cout<<"the left notify list" <<endl;
7787       NotifyList& l = *leftUpList;
7788       for(size_t i=0,iend=l.size(); i<iend; ++i) {
7789 	cout << "[" << l.getTheory(i)->getName() << ", " << l.getExpr(i) << "] " << l.getExpr(i).getSig().isNull() << endl;
7790       }
7791 
7792       const Expr& rightTerm = t.getRHS();
7793       cout<<"right term is " << rightTerm << endl;
7794       NotifyList* rightUpList = rightTerm.getNotify();
7795       if(NULL == rightUpList) continue;
7796 
7797       cout<<"the right notify list" << endl;
7798 
7799       NotifyList& ll = *rightUpList;
7800       for(size_t i=0,iend=ll.size(); i<iend; ++i) {
7801 	cout << "[" << ll.getTheory(i)->getName() << ", " << ll.getExpr(i) << "] " << ll.getExpr(i).getSig().isNull() << endl;
7802       }
7803 
7804 
7805       cout<<"------------" << leftTerm << " # " << rightTerm <<endl;
7806 
7807     }
7808   }
7809   */
7810 
7811 
7812 #ifdef _CVC3_DEBUG_MODE
7813   if(fullEffort){
7814     if( CVC3::debugger.trace("quant assertfact")  ){
7815       cout<<"===========all cached univs =========="<<endl;
7816       //      for (ExprMap<Theorem>::iterator i=d_simpUnivs.begin(), iend=d_simpUnivs.end(); i!=iend;  i++){
7817       //	cout<<"------------------------------------"<<endl;
7818       //	cout<<(i->first).toString()<<endl;
7819       //	cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
7820       //	cout<<(i->second).getExpr().toString()<<endl;
7821       //}
7822     }
7823     if( CVC3::debugger.trace("quant samehead")  ){
7824       cout<<"===========all cached  =========="<<endl;
7825       for (ExprMap< CDList<Expr>*>::iterator i=d_same_head_expr.begin(), iend=d_same_head_expr.end(); i!=iend;  i++){
7826 	cout<<"------------------------------------"<<endl;
7827 	cout<<(i->first)<<endl;
7828 	cout<<"_______________________"<<endl;
7829 	CDList<Expr> * terms= i->second;
7830 	for(size_t i =0; i<terms->size(); i++){
7831 	  cout<<(*terms)[i]<<endl;
7832 	}
7833       }
7834     }
7835   }
7836 #endif
7837 
7838 #ifdef _CVC3_DEBUG_MODE
7839   if( CVC3::debugger.trace("quant checksat")  ){
7840     const CDList<Expr>& allpreds = theoryCore()->getPredicates();
7841     cout<<"=========== cur pred & terms =========="<<endl;
7842 
7843     for (size_t i=d_lastPredsPos; i<allpreds.size(); i++){
7844     //    for (size_t i=0; i<allpreds.size(); i++){
7845       cout<<"i="<<allpreds[i].getIndex()<<" :"<<findExpr(allpreds[i])<<"|"<<allpreds[i]<<endl;
7846     }
7847 
7848     const CDList<Expr>&  allterms = theoryCore()->getTerms();
7849 
7850     for (size_t i=d_lastTermsPos; i<allterms.size(); i++){
7851       cout<<"i="<<allterms[i].getIndex()<<" :"<<findExpr(allterms[i])<<"|"<<allterms[i]<<endl;
7852     }
7853     cout<<"=========== cur quant =========="<<endl;
7854     for (size_t i=0; i<d_univs.size(); i++){
7855       cout<<"i="<<d_univs[i].getExpr().getIndex()<<" :"<<findExpr(d_univs[i].getExpr())<<"|"<<d_univs[i]<<endl;
7856     }
7857   }
7858 
7859 
7860   if( CVC3::debugger.trace("quant checksat equ") ){
7861     const CDList<Expr>& allpreds = theoryCore()->getPredicates();
7862     cout<<"=========== cur pred equ =========="<<endl;
7863 
7864     for (size_t i=d_lastPredsPos; i<allpreds.size(); i++){
7865       if(allpreds[i].isEq()){
7866 	cout<<"i="<<allpreds[i].getIndex()<<" :"<<findExpr(allpreds[i])<<"|"<<allpreds[i]<<endl;
7867       }
7868     }
7869     cout<<"=========== cur pred equ end  =========="<<endl;
7870   }
7871 
7872 #endif
7873 
7874   if((*d_useLazyInst && !fullEffort) ) return;
7875 
7876   if(false) {//for the same head list
7877    const CDList<Expr>&  allterms = theoryCore()->getTerms();
7878    for(size_t i=d_lastTermsPos; i<allterms.size(); i++){
7879      Expr t = allterms[i];
7880      if(canGetHead(t)){
7881        if(d_same_head_expr.count(getHead(t)) >0){
7882 	 d_same_head_expr[getHead(t)]->push_back(t);
7883        }
7884        else{
7885 	 d_same_head_expr[getHead(t)]=
7886 	   new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
7887 	 d_same_head_expr[getHead(t)]->push_back(t);
7888        }
7889      }
7890    }
7891 
7892    const CDList<Expr>&  allpreds = theoryCore()->getPredicates();
7893    for(size_t i=d_lastPredsPos; i<allpreds.size(); i++){
7894      Expr t = allpreds[i];
7895      if(canGetHead(t)){
7896        if(d_same_head_expr.count(getHead(t)) >0){
7897 	 d_same_head_expr[getHead(t)]->push_back(t);
7898        }
7899        else{
7900 	 d_same_head_expr[getHead(t)]=
7901 	   new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
7902 	 d_same_head_expr[getHead(t)]->push_back(t);
7903        }
7904      }
7905    }
7906   }
7907 
7908   if(false){
7909     for(size_t eqs_index = d_lastEqsUpdatePos; eqs_index < d_eqsUpdate.size();  eqs_index++){
7910 
7911       const Expr lTerm = d_eqsUpdate[eqs_index].getLHS();
7912       const Expr rTerm = d_eqsUpdate[eqs_index].getRHS();
7913 
7914       d_eqs.push_back(lTerm);
7915       d_eqs.push_back(rTerm);
7916     }
7917   }
7918 
7919   if(false) {//for the equalities list
7920     const CDList<Expr>&  allpreds = theoryCore()->getPredicates();
7921     for(size_t i=d_lastPredsPos; i<allpreds.size(); i++){
7922       const Expr& t = allpreds[i];
7923       if(t.isEq()){
7924 	//	cout<<"EQ: "<<t<<endl;
7925 	const Expr lterm = t[0];
7926 	const Expr rterm = t[1];
7927 	d_eqs.push_back(lterm);
7928 	d_eqs.push_back(rterm);
7929 
7930 	/*
7931 	ExprMap<CDList<Expr>* >::iterator iter = d_eq_list.find(lterm);
7932 	if(d_eq_list.end() == iter){
7933 	  d_eq_list[lterm] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
7934 	  d_eq_list[lterm]->push_back(rterm);
7935 	}
7936 	else{
7937 	  iter->second->push_back(rterm);
7938 	}
7939 
7940 	//	cout<<"LTERM: " <<rterm<<endl;
7941 	iter = d_eq_list.find(rterm);
7942 	if(d_eq_list.end() == iter){
7943 	  d_eq_list[rterm] = new(true) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
7944 	  d_eq_list[rterm]->push_back(lterm);
7945 	}
7946 	else{
7947 	  iter->second->push_back(lterm);
7948 	}
7949 	//	cout<<"RTERM: " <<lterm<<endl;
7950 	*/
7951       }
7952     }
7953   }
7954 
7955 
7956   {//for rw heuristic
7957    const CDList<Expr>&  allterms = theoryCore()->getTerms();
7958    for(size_t i=d_lastTermsPos; i<allterms.size(); i++){
7959      const Expr& cur=allterms[i];
7960      if(READ == cur.getKind() || WRITE == cur.getKind()){
7961        arrayIndexName(cur);
7962      }
7963    }
7964   }
7965 
7966   d_instThisRound = 0;
7967   //  d_useMultTrig=*d_useMult;
7968   //  d_usePartTrig=*d_usePart;
7969   d_useFullTrig=true;
7970 
7971   if(fullEffort) {
7972     d_inEnd=true;
7973   }
7974   else{
7975     d_inEnd=false;
7976   }
7977 
7978 
7979   ExprMap<ExprMap<vector<dynTrig>* >* > new_trigs;
7980   if(fullEffort || theoryCore()->getCM()->scopeLevel() <= 5 || true){
7981     for(size_t i=d_univs.size(); i<d_rawUnivs.size(); i++){
7982       setupTriggers(new_trigs, d_rawUnivs[i], i);
7983     }
7984   }
7985   try {
7986     if (!(*d_useNew)){
7987       naiveCheckSat(fullEffort);
7988     }
7989     else if (*d_useSemMatch){
7990       semCheckSat(fullEffort);
7991     }
7992     else {
7993       synCheckSat(new_trigs, fullEffort);
7994     }
7995   }
7996 
7997   catch (int x){
7998 
7999      while(!d_simplifiedThmQueue.empty()){
8000        d_simplifiedThmQueue.pop();
8001        d_abInstCount++;
8002      }
8003      while(!d_gUnivQueue.empty()){
8004        d_gUnivQueue.pop();
8005      }
8006      while(!d_gBindQueue.empty()){
8007        d_gBindQueue.pop();
8008      }
8009 
8010 
8011 
8012     d_tempBinds.clear();
8013     saveContext();
8014     delNewTrigs(new_trigs);
8015     return;
8016   }
8017 
8018   sendInstNew();
8019 
8020   saveContext();
8021 
8022   try{
8023     if((*d_useNaiveInst) && (*d_useNew) && (0 == d_instThisRound) && fullEffort && theoryCore()->getTerms().size() < (size_t)(*d_maxNaiveCall )) {
8024       //      cout<<"naive called"<<endl;
8025       if (0== theoryCore()->getTerms().size()){
8026 	static int counter =0;
8027 
8028 	std::set<Expr> types;
8029 	for(size_t i = 0; i<d_univs.size(); i++){
8030 	  const Expr& cur_quant = d_univs[i].getExpr();
8031 	  const std::vector<Expr> cur_vars = cur_quant.getVars();
8032 	  for(size_t j =0; j<cur_vars.size(); j++){
8033 	    types.insert(cur_vars[j].getType().getExpr());
8034 	  }
8035 	}
8036 
8037 	std::string base("_naiveInst");
8038 	for(std::set<Expr>::iterator i=types.begin(), iend = types.end(); i != iend; i++){
8039 	  counter++;
8040 	  std::stringstream tempout;
8041 	  tempout << counter;
8042 	  std::string out_str = base + tempout.str();
8043 	  Expr newExpr = theoryCore()->getEM()->newVarExpr(out_str);
8044 
8045 	  newExpr.setType(Type(*i));
8046 
8047 	  Proof pf;
8048 
8049 	  Expr newExpr2 = theoryCore()->getEM()->newVarExpr(out_str+"extra");
8050 	  newExpr2.setType(Type(*i));
8051 
8052 	  Expr newConstThm;
8053 
8054 	  if(Type(*i) == theoryCore()->getEM()->newRatExpr(0).getType()){
8055 	    //somehow theory_arith will complain if we use expr2 to form the eq here
8056 	    newConstThm = newExpr.eqExpr(theoryCore()->getEM()->newRatExpr(0));
8057 	  }
8058 	  else{
8059 	    newConstThm = newExpr.eqExpr(newExpr2);
8060 	  }
8061 	  Theorem newThm  = d_rules->addNewConst(newConstThm);
8062 
8063 	  if(*d_useGFact){
8064 	    //	    addGlobalLemma(newThm, -1);
8065 	    enqueueFact(newThm);
8066 	  }
8067 	  else{
8068 	    enqueueFact(newThm);
8069 	  }
8070 	  //	  enqueueSE(newThm);
8071 	  //
8072 	  d_tempBinds.clear();
8073 	  return;
8074 	}
8075 
8076       }
8077     naiveCheckSat(fullEffort);
8078     }
8079   }//end of try
8080 
8081   catch (int x){
8082 
8083      while(!d_simplifiedThmQueue.empty()){
8084        d_simplifiedThmQueue.pop();
8085        d_abInstCount++;
8086       }
8087      while(!d_gUnivQueue.empty()){
8088        d_gUnivQueue.pop();
8089      }
8090      while(!d_gBindQueue.empty()){
8091        d_gBindQueue.pop();
8092      }
8093 
8094 
8095     d_tempBinds.clear();
8096     saveContext();
8097     delNewTrigs(new_trigs);
8098     return;
8099   }
8100 
8101   if(fullEffort) {
8102     sendInstNew();
8103   }
8104 
8105   combineOldNewTrigs(new_trigs);
8106   delNewTrigs(new_trigs);
8107 }
8108 
saveContext()8109 void TheoryQuant::saveContext(){
8110   d_lastArrayPos.set(d_arrayTrigs.size());
8111   d_univsSavedPos.set(d_univs.size());
8112   d_rawUnivsSavedPos.set(d_rawUnivs.size());
8113   d_lastTermsPos.set(theoryCore()->getTerms().size());
8114   d_lastPredsPos.set(theoryCore()->getPredicates().size());
8115   d_lastUsefulGtermsPos.set(d_usefulGterms.size());
8116   d_lastEqsUpdatePos.set(d_eqsUpdate.size());
8117 }
8118 
synCheckSat(ExprMap<ExprMap<vector<dynTrig> * > * > & new_trigs,bool fullEffort)8119 void TheoryQuant::synCheckSat(ExprMap<ExprMap<vector<dynTrig>* >* >&  new_trigs, bool fullEffort){
8120 
8121   d_allout=false;
8122 
8123   if(fullEffort)   {
8124     setIncomplete("Quantifier instantiation");
8125   }
8126 
8127   size_t uSize = d_univs.size() ;
8128   const CDList<Expr>& allterms = theoryCore()->getTerms();
8129   const CDList<Expr>& allpreds = theoryCore()->getPredicates();
8130   size_t tSize = allterms.size();
8131   size_t pSize = allpreds.size();
8132 
8133   TRACE("quant",uSize, " uSize and univsSavedPOS ", d_univsSavedPos);
8134   TRACE("quant",tSize, " tSize and termsLastPos ", d_lastTermsPos);
8135   TRACE("quant",pSize, " pSize and predsLastPos ", d_lastPredsPos);
8136   TRACE("quant", fullEffort, " fulleffort:scope ",theoryCore()->getCM()->scopeLevel() );
8137 
8138   for(size_t i=d_lastTermsPos; i<tSize; i++){
8139     const Expr& cur(allterms[i]);
8140     //    if(usefulInMatch(cur) && cur.hasFind()){
8141     if(usefulInMatch(cur)){
8142       if(*d_useExprScore){
8143 	int score = getExprScore(cur);
8144 	if(score <= d_curMaxExprScore && 0 <= score ){
8145 	  d_usefulGterms.push_back(cur);
8146 	  add_parent(cur);
8147 	}
8148       }
8149       else{
8150 	d_usefulGterms.push_back(cur);
8151 	add_parent(cur);
8152       }
8153     }
8154     else{
8155     }
8156   }
8157 
8158   for(size_t i=d_lastPredsPos; i<pSize; i++){
8159     const Expr& cur=allpreds[i];
8160     //    if( usefulInMatch(cur) && cur.hasFind()){
8161     if( usefulInMatch(cur)){
8162       if(*d_useExprScore ){
8163 	int score = getExprScore(cur);
8164 	if(score <= d_curMaxExprScore && 0 <= score){
8165 	  d_usefulGterms.push_back(cur);
8166 	  add_parent(cur);
8167 	}
8168       }
8169       else{
8170 	d_usefulGterms.push_back(cur);
8171 	add_parent(cur);
8172       }
8173     }
8174     else{
8175     }
8176   }
8177 
8178 
8179   //  if(d_useFullTrig && d_inEnd && *d_useInstEnd ){
8180   if(d_useFullTrig && d_inEnd ){
8181 
8182     if(*d_useExprScore){
8183 
8184       matchListOld(d_usefulGterms, d_lastUsefulGtermsPos, d_usefulGterms.size() ); //new terms to old list
8185       matchListNew(new_trigs, d_usefulGterms, 0, d_usefulGterms.size()); //new and old terms to new list
8186 
8187       if(sendInstNew() > 0){
8188 	TRACE("inend", "debug 1", "" ,"" );
8189 	return;
8190       }
8191 
8192       d_allout = true; //let me look at these d_allout later yeting
8193       {
8194 	CDList<Expr>* changed_terms = new (false) CDList<Expr> (theoryCore()->getCM()->getCurrentContext()) ;
8195 	collectChangedTerms(*changed_terms);
8196 
8197 	matchListOld(*changed_terms, 0, changed_terms->size());
8198 	matchListNew(new_trigs, *changed_terms, 0 , changed_terms->size());
8199 	delete changed_terms;
8200       }
8201       d_allout = false;
8202       int n;
8203       if( ( n = sendInstNew()) > 0){
8204 	TRACE("inend",  "debug 2", " # ",n );
8205 	return;
8206       }
8207 
8208       bool hasMoreGterms(false);
8209 
8210       do {
8211 
8212       hasMoreGterms=false;
8213 
8214       int numNewTerm=0;
8215       int oldNum=d_usefulGterms.size();
8216 
8217       for(size_t i=0; i<tSize; i++){
8218 	const Expr& cur(allterms[i]);
8219 	//if(!(usefulInMatch(cur)) || !cur.hasFind()) continue;
8220 	if(!(usefulInMatch(cur)) ) continue;
8221 	int score = getExprScore(cur);
8222 	if( score > d_curMaxExprScore){
8223 	  if((d_curMaxExprScore + 1) == score){
8224 	    //	  if((d_curMaxExprScore + 1) <= score){
8225 	    d_usefulGterms.push_back(cur);
8226 	    add_parent(cur);
8227 	    numNewTerm++;
8228 	  }
8229 	  else{
8230 	    hasMoreGterms = true;
8231 	    TRACE("inend", "is this good? ", cur.toString()+" #-# " , score);
8232 	    //	    cout<<"should not be here"<<endl;
8233 	    if(*d_useGFact && false ){
8234 	      d_usefulGterms.push_back(cur);
8235 	      add_parent(cur);
8236 	      numNewTerm++;
8237 	    }
8238 	    //	    cout<<"extra term e:"<<score<<" # "<<d_curMaxExprScore << " # "<< cur<<endl;
8239 	    //	    cout<<"extra id:"<<cur.getIndex()<<endl;
8240 	    //	    exit(3);
8241 	  }
8242 	}
8243       }
8244 
8245 
8246       for(size_t i=0; i<pSize; i++){
8247 	const Expr& cur(allpreds[i]);
8248 	//	if(!(usefulInMatch(cur)) ||  !cur.hasFind()) continue;
8249 	if(!(usefulInMatch(cur)) ) continue;
8250 	int score = getExprScore(cur);
8251 	if( score > d_curMaxExprScore){
8252 	  if((d_curMaxExprScore + 1) == score){
8253 	    //  if((d_curMaxExprScore + 1) <= score){
8254 	    d_usefulGterms.push_back(cur);
8255 	    add_parent(cur);
8256 	    numNewTerm++;
8257 	  }
8258 	  else{
8259 	    hasMoreGterms = true;
8260 	    TRACE("inend", "is this good? ", cur.toString()+" #-# " , score);
8261 	    //	    cout<<"should not be here"<<endl;
8262 	    if(*d_useGFact && false ){
8263 	      d_usefulGterms.push_back(cur);
8264 	      add_parent(cur);
8265 	      numNewTerm++;
8266 	    }
8267 	    //	    cout<<"extra pred e:"<<score<<" # "<<d_curMaxExprScore << " # "<< cur<<endl;
8268 	    //	    cout<<"extra id:"<<cur.getIndex()<<endl;
8269 	    //	    exit(3);
8270 	  }
8271 	}
8272       }
8273 
8274       /*
8275       IF_DEBUG({
8276 	bool hasStrange(false);
8277 	for(size_t i=0; i<pSize-1; i++){
8278 	  if(getExprScore(allpreds[i]) > getExprScore(allpreds[i+1]) ){
8279 	    cout<<"strange pred"<<allpreds[i]<<endl;
8280 	    hasStrange=true;
8281 	  }
8282 	}
8283 	for(size_t i=0; i<tSize-1; i++){
8284 	  if(getExprScore(allterms[i]) > getExprScore(allterms[i+1])){
8285 	    cout<<"strange term"<<allterms[i]<<endl;
8286 	    hasStrange=true;
8287 	  }
8288 	}
8289 	if(hasStrange){
8290 	  cout<<"strange here"<<endl;
8291 	  for(size_t i=0; i<pSize; i++){
8292 	    if (usefulInMatch(allpreds[i]) ) cout<<getExprScore(allpreds[i]) << " t# " <<allpreds[i]<<endl;
8293 	  }
8294 	  for(size_t i=0; i<tSize; i++){
8295 	    if (usefulInMatch(allterms[i]) )  cout<<getExprScore(allterms[i]) << " p# " <<allterms[i]<<endl;
8296 	  }
8297 	  cout<<"strange end"<<endl;
8298 	}
8299       }
8300 	       )
8301       */
8302 //       if(d_curMaxExprScore < 15 || true){
8303 // 	d_curMaxExprScore = d_curMaxExprScore+1;
8304 //       }
8305 
8306       if(d_curMaxExprScore >= 0 && d_curMaxExprScore <= *d_maxIL ){
8307 	d_curMaxExprScore =  d_curMaxExprScore+1;;
8308       }
8309       else {
8310 	d_curMaxExprScore =  d_curMaxExprScore+1;
8311 	//	d_curMaxExprScore =  d_curMaxExprScore+0; //this is for debugging Yeting
8312 	d_maxILReached = true;
8313 	//cout<<"il reached: " << endl;
8314       }
8315 
8316       //      cout << " max il " << *d_maxIL << endl;
8317       //      cout <<d_curMaxExprScore << endl;
8318 
8319       if(numNewTerm >0 ){
8320 	matchListOld(d_usefulGterms, oldNum, d_usefulGterms.size() );
8321 	matchListNew(new_trigs, d_usefulGterms, oldNum, d_usefulGterms.size());
8322 
8323 	if(sendInstNew() > 0){
8324 	  TRACE("inend",  "debug 3 1", "" , "" );
8325 	  return;
8326 	}
8327       }
8328 
8329       if(hasMoreGterms){
8330         ;
8331 	//	cout<<"has more " << endl;
8332 	//	cout<<d_curMaxExprScore<<endl;
8333 	//	cout<<"oldNum" << oldNum << endl;
8334       }
8335       //      } while(hasMoreGterms && d_curMaxExprScore <= 10 );
8336       } while(hasMoreGterms && d_curMaxExprScore <= *d_maxIL);
8337 
8338       d_allout = true;
8339       matchListOld(d_usefulGterms, 0, d_usefulGterms.size() );
8340       matchListNew(new_trigs, d_usefulGterms, 0, d_usefulGterms.size());
8341       if(sendInstNew() > 0){
8342 	TRACE("inend",  "debug 3 2", "" , "" );
8343 	return;
8344       }
8345       d_allout = false;
8346 
8347       //      for(size_t array_index = 0; array_index < d_arrayTrigs.size(); array_index++){
8348       //	arrayHeuristic(d_arrayTrigs[array_index].trig, d_arrayTrigs[array_index].univ_id);
8349       //      }
8350 
8351 
8352       return ;
8353     }
8354 
8355     TRACE("inend", "debug 3 0", "", "");
8356     TRACE("quant","this round; ",d_callThisRound,"");
8357 
8358     return;
8359   }
8360 
8361 
8362   if ((uSize == d_univsSavedPos) &&
8363       (tSize == d_lastTermsPos) &&
8364       (pSize == d_lastPredsPos) ) return;
8365 
8366   //  cout<<"match old"<<endl;
8367   matchListOld(d_usefulGterms, d_lastUsefulGtermsPos,d_usefulGterms.size() ); //new terms to old list
8368   //  cout<<"match new"<<endl;
8369   matchListNew(new_trigs, d_usefulGterms, 0, d_usefulGterms.size() ); //new and old terms to new list
8370 
8371   for(size_t array_index = d_lastArrayPos; array_index < d_arrayTrigs.size(); array_index++){
8372     arrayHeuristic(d_arrayTrigs[array_index].trig, d_arrayTrigs[array_index].univ_id);
8373   }
8374 
8375   TRACE("quant","this round; ",d_callThisRound,"");
8376 
8377   return;
8378 }
8379 
8380 
semCheckSat(bool fullEffort)8381 void TheoryQuant::semCheckSat(bool fullEffort){
8382 }
8383 
8384 //the following is old code and I did not modify much, Yeting
naiveCheckSat(bool fullEffort)8385 void TheoryQuant::naiveCheckSat(bool fullEffort){
8386   d_univsSavedPos.set(0);
8387   TRACE("quant", "checkSat ", fullEffort, "{");
8388   IF_DEBUG(int instCount = d_instCount;)
8389   size_t uSize = d_univs.size(), stSize = d_savedTerms.size();
8390   if(true || (fullEffort && uSize > 0)) {
8391     // First of all, this algorithm is incomplete
8392     setIncomplete("Quantifier instantiation");
8393 
8394     if(d_instCount>=*d_maxQuantInst)
8395       return;
8396     //first attempt to instantiate with the saved terms
8397     //only do this if there are new saved terms or new theroems and
8398     // at least some saved terms
8399     bool savedOnly = ((uSize > d_univsSavedPos.get()  && stSize > 0) ||
8400 		      (stSize > d_savedTermsPos.get()));
8401     int origCount = d_instCount;
8402     if(savedOnly)
8403       {
8404 	TRACE("quant", "checkSat [saved insts]: univs size = ", uSize , " ");
8405 	for(size_t i=0, pos = d_univsSavedPos.get(); i<uSize; i++) {
8406 	  if(d_instCount>= *d_maxQuantInst)
8407 	    break;
8408 	  else
8409 	    instantiate(d_univs[i], i>=pos, true,  d_savedTermsPos.get());
8410 	}
8411 	d_univsSavedPos.set(d_univs.size());
8412 	d_savedTermsPos.set(stSize);
8413       }
8414     if(!savedOnly || d_instCount == origCount)
8415       { //instantiate with context dependent assertions terms
8416 	TRACE("quant", "checkSat [context insts]: univs size = ", uSize , " ");
8417 	const CDList<Expr>& assertions = theoryCore()->getTerms();
8418 	int origSize = d_contextTerms.size();
8419 	//	for(size_t i=0; i<uSize; i++)
8420 	//	  assertions.push_back(d_univs[i].getExpr());
8421 	//build the map of all terms grouped into vectors by types
8422 	TRACE("quant", "checkSat terms size = ", assertions.size() , " ");
8423 	mapTermsByType(assertions);
8424 	for(size_t i=0, pos = d_univsContextPos.get(); i<uSize; i++) {
8425 	  if(d_instCount>= *d_maxQuantInst)
8426 	    break;
8427 	  else
8428 	    instantiate(d_univs[i], i>=pos, false, origSize);
8429 	}
8430 	d_univsContextPos.set(d_univs.size());
8431       }
8432     TRACE("quant terse", "checkSat total insts: ",
8433 	  d_instCount, ", new "+int2string(d_instCount - instCount));
8434   }
8435   TRACE("quant", "checkSat total insts: ", d_instCount, " ");
8436   TRACE("quant", "checkSat new insts: ", d_instCount - instCount, " ");
8437   TRACE("quant", "checkSat effort:",  fullEffort, " }");
8438 
8439 }
8440 
8441 
8442 /*! \brief Queues up all possible instantiations of bound
8443  * variables.
8444  *
8445  * The savedMap boolean indicates whether to use savedMap or
8446  * d_contextMap the all boolean indicates weather to use all
8447  * instantiation or only new ones and newIndex is the index where
8448  * new instantiations begin.
8449  */
instantiate(Theorem univ,bool all,bool savedMap,size_t newIndex)8450 void TheoryQuant::instantiate(Theorem univ, bool all, bool savedMap,
8451 			      size_t newIndex)
8452 {
8453 
8454   if(!all && ((savedMap &&  newIndex == d_savedTerms.size())
8455   	      ||(!savedMap && newIndex == d_contextTerms.size())))
8456     return;
8457 
8458   TRACE("quant", "instanitate", all , "{");
8459   std::vector<Expr> varReplacements;
8460   recInstantiate(univ, all, savedMap, newIndex, varReplacements);
8461   TRACE("quant", "instanitate", "", "}");
8462 
8463 }
8464 
8465  //! does most of the work of the instantiate function.
recInstantiate(Theorem & univ,bool all,bool savedMap,size_t newIndex,std::vector<Expr> & varReplacements)8466 void TheoryQuant::recInstantiate(Theorem& univ, bool all, bool savedMap,
8467 				 size_t newIndex,
8468 				 std::vector<Expr>& varReplacements)
8469 {
8470   Expr quantExpr = univ.getExpr();
8471   const vector<Expr>& boundVars = quantExpr.getVars();
8472 
8473   size_t curPos = varReplacements.size();
8474   TRACE("quant", "recInstantiate: ", boundVars.size() - curPos, "");
8475   //base case: a full vector of instantiations exists
8476   if(curPos == boundVars.size()) {
8477     if(!all)
8478       return;
8479     Theorem t = d_rules->universalInst(univ, varReplacements);
8480     d_insts[t.getExpr()] = varReplacements;
8481     TRACE("quant", "recInstantiate => " , t.toString(), "");
8482     if(d_instCount< *d_maxQuantInst) {
8483       d_instCount=d_instCount+1;
8484       enqueueInst(univ, varReplacements, null_expr);
8485       //            enqueueInst(univ, t);
8486 	    // enqueueFact(t);
8487     }
8488     return;
8489   }
8490   //recursively add all possible instantiations in the next
8491   //available space of the vector
8492   else {
8493     Type t = getBaseType(boundVars[curPos]);
8494     int iendC=0, iendS=0, iend;
8495     std::vector<size_t>* typeVec = NULL; // = d_savedMap[t];
8496     CDList<size_t>* typeList = NULL; // = *d_contextMap[t];
8497     if(d_savedMap.count(t) > 0) {
8498       typeVec = &(d_savedMap[t]);
8499       iendS = typeVec->size();
8500       TRACE("quant", "adding from savedMap: ", iendS, "");
8501     }
8502     if(!savedMap) {
8503       if(d_contextMap.count(t) > 0) {
8504 	typeList = d_contextMap[t];
8505 	iendC = typeList->size();
8506 	TRACE("quant", "adding from contextMap:", iendC , "");
8507       }
8508     }
8509     iend = iendC + iendS;
8510     for(int i =0; i<iend; i++) {
8511       TRACE("quant", "I must have gotten here!", "", "");
8512       size_t index;
8513       if(i<iendS){
8514 	index = (*typeVec)[i];
8515 	varReplacements.push_back(d_savedTerms[index]);
8516       }
8517       else {
8518 	index = (*typeList)[i-iendS];
8519 	varReplacements.push_back(d_contextTerms[index]);
8520       }
8521       if((index <  newIndex) || (!savedMap && i<iendS))
8522 	recInstantiate(univ, all, savedMap, newIndex,  varReplacements);
8523       else
8524 	recInstantiate(univ, true, savedMap, newIndex,  varReplacements);
8525       varReplacements.pop_back();
8526     }
8527 
8528 
8529   }
8530 }
8531 
8532 /*! \brief categorizes all the terms contained in a vector of  expressions by
8533  * type.
8534  *
8535  * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
8536  */
mapTermsByType(const CDList<Expr> & terms)8537 void TheoryQuant::mapTermsByType(const CDList<Expr>& terms)
8538 {
8539   Expr trExpr=trueExpr(), flsExpr = falseExpr();
8540   Type boolT = boolType();
8541   if(d_contextMap.count(boolT) == 0)
8542     {
8543       d_contextMap[boolT] =
8544         new(true) CDList<size_t>(theoryCore()->getCM()->getCurrentContext());
8545       size_t pos = d_contextTerms.size();
8546       d_contextTerms.push_back(trExpr);
8547       d_contextTerms.push_back(flsExpr);
8548       (*d_contextMap[boolT]).push_back(pos);
8549       (*d_contextMap[boolT]).push_back(pos+1);
8550     }
8551   for(size_t i=0; i<terms.size(); i++)
8552     recursiveMap(terms[i]);
8553   // Add all our saved universals to the pool
8554   for(size_t i=0; i<d_univs.size(); i++)
8555     recursiveMap(d_univs[i].getExpr());
8556 }
8557 
8558 /*! \brief categorizes all the terms contained in an expressions by
8559  * type.
8560  *
8561  * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
8562  * returns true if the expression does not contain bound variables, false
8563  * otherwise.
8564  */
recursiveMap(const Expr & e)8565 bool TheoryQuant::recursiveMap(const Expr& e)
8566 {
8567   if(d_contextCache.count(e)>0) {
8568     return(d_contextCache[e]);
8569   }
8570   if(e.arity()>0)  {
8571     for(Expr::iterator it = e.begin(), iend = e.end(); it!=iend; ++it)
8572       //maps the children and returns a bool
8573       if(recursiveMap(*it) == false) {
8574 	d_contextCache[e] = false;
8575       }
8576   }
8577   else if(e.getKind() == EXISTS || e.getKind() == FORALL){
8578     //maps the body
8579     if(recursiveMap(e.getBody())==false) {
8580       d_contextCache[e]=false;
8581     }
8582   }
8583   //found a bound variable in the children
8584   if(d_contextCache.count(e)>0) {
8585     return false;
8586   }
8587 
8588   if(d_savedCache.count(e) > 0) {
8589     return true;
8590   }
8591 
8592   Type type = getBaseType(e);
8593 
8594   if(!type.isBool() && !(e.getKind()==BOUND_VAR)){
8595      TRACE("quant", "recursiveMap: found ",
8596 	   e.toString() + " of type " + type.toString(), "");
8597     int pos = d_contextTerms.size();
8598     d_contextTerms.push_back(e);
8599     if(d_contextMap.count(type)==0)
8600       d_contextMap[type] =
8601         new(true) CDList<size_t>(theoryCore()->getCM()->getCurrentContext());
8602     (*d_contextMap[type]).push_back(pos);
8603   }
8604 
8605   if(e.getKind() == BOUND_VAR) {
8606     d_contextCache[e] = false;
8607     return false;
8608   }
8609   else {
8610     d_contextCache[e] = true;
8611     return true;
8612   }
8613   //need  to implement:
8614   //insert all instantiations if type is finite and reasonable
8615   //also need to implement instantiations of subtypes
8616 }
8617 
8618 /*!\brief Used to notify the quantifier algorithm of possible
8619  * instantiations that were used in proving a context inconsistent.
8620  */
notifyInconsistent(const Theorem & thm)8621 void TheoryQuant::notifyInconsistent(const Theorem& thm){
8622 #ifdef _CVC3_DEBUG_MODE
8623 
8624   if( CVC3::debugger.trace("quant inscon")  ){
8625 
8626     cout<<"the one caused incsonsistency"<<endl;
8627     cout<<thm.getAssumptionsRef().toString()<<endl;
8628     std::vector<Expr> assump;
8629     thm.getLeafAssumptions(assump);
8630 
8631     cout<<"===========leaf assumptions; =========="<<endl;
8632     for(std::vector<Expr>::iterator i=assump.begin(), iend=assump.end(); i!=iend; i++){
8633       cout<<">>"<<i->toString()<<endl;
8634     }
8635   }
8636 #endif
8637 
8638   if(d_univs.size() == 0)
8639     return;
8640   DebugAssert(thm.getExpr().isFalse(), "notifyInconsistent called with"
8641 	" theorem: " + thm.toString() + " which is not a derivation of false");
8642   TRACE("quant", "notifyInconsistent: { " , thm.toString(), "}");
8643   //  thm.clearAllFlags();
8644   //  findInstAssumptions(thm);
8645   TRACE("quant terse", "notifyInconsistent: savedTerms size = ",
8646 	d_savedTerms.size(), "");
8647   TRACE("quant terse", "last term: ",
8648 	d_savedTerms.size()? d_savedTerms.back() : Expr(), "");
8649 }
8650 /*! \brief A recursive function used to find instantiated universals
8651  * in the hierarchy of assumptions.
8652  */
findInstAssumptions(const Theorem & thm)8653 void TheoryQuant::findInstAssumptions(const Theorem& thm)
8654 {
8655   if(thm.isNull() || thm.isRefl() || thm.isFlagged())
8656     return;
8657   thm.setFlag();
8658   const Expr& e = thm.getExpr();
8659   if(d_insts.count(e) > 0) {
8660     vector<Expr>& insts = d_insts[e];
8661     int pos;
8662     for(vector<Expr>::iterator it = insts.begin(), iend = insts.end(); it!=iend
8663 	  ; ++it)
8664       {
8665 	if(d_savedCache.count(*it) ==  0) {
8666 	  TRACE("quant", "notifyInconsistent: found:", (*it).toString(), "");
8667 	  d_savedCache[*it] = true;
8668 	  pos = d_savedTerms.size();
8669 	  d_savedTerms.push_back(*it);
8670 	  d_savedMap[getBaseType(*it)].push_back(pos);
8671 	}
8672       }
8673   }
8674   if(thm.isAssump())
8675     return;
8676   const Assumptions& a = thm.getAssumptionsRef();
8677   for(Assumptions::iterator it =a.begin(), iend = a.end(); it!=iend; ++it){
8678     findInstAssumptions(*it);
8679   }
8680 }
8681 
8682 //! computes the type of a quantified term. Always a  boolean.
computeType(const Expr & e)8683 void TheoryQuant::computeType(const Expr& e)
8684 {
8685   switch (e.getKind()) {
8686   case FORALL:
8687   case EXISTS: {
8688     if(!e.getBody().getType().isBool())
8689       throw TypecheckException("Type mismatch for expression:\n\n   "
8690 			      + e.getBody().toString()
8691 			      + "\n\nhas the following type:\n\n  "
8692 			      + e.getBody().getType().toString()
8693 			      + "\n\nbut the expected type is Boolean:\n\n  ");
8694     else
8695 
8696       e.setType(e.getBody().getType());
8697     break;
8698   }
8699   default:
8700     DebugAssert(false,"Unexpected kind in Quantifier Theory: "
8701 		+ e.toString());
8702     break;
8703   }
8704 }
8705 
8706 /*!
8707  * TCC(forall x.phi(x)) = (forall x. TCC(phi(x)))
8708  *                         OR (exists x. TCC(phi(x)) & !phi(x))
8709  * TCC(exists x.phi(x)) = (forall x. TCC(phi(x)))
8710  *                         OR (exists x. TCC(phi(x)) & phi(x))
8711  */
8712 
8713 
computeTCC(const Expr & e)8714 Expr TheoryQuant::computeTCC(const Expr& e) {
8715   DebugAssert(e.isQuantifier(), "Unexpected expression in Quantifier Theory: "
8716 	      + e.toString());
8717 
8718   bool forall(e.getKind() == FORALL);
8719   const Expr& phi = e.getBody();
8720   Expr tcc_phi = getTCC(phi);
8721   Expr forall_tcc = getEM()->newClosureExpr(FORALL, e.getVars(), tcc_phi);
8722   Expr exists_tcc = getEM()->newClosureExpr(EXISTS, e.getVars(),
8723                                             tcc_phi && (forall? !phi : phi));
8724   return (forall_tcc || exists_tcc);
8725 }
8726 
8727 
8728 ExprStream&
print(ExprStream & os,const Expr & e)8729 TheoryQuant::print(ExprStream& os, const Expr& e) {
8730   switch(os.lang()) {
8731   case SIMPLIFY_LANG:
8732     {
8733       switch(e.getKind()){
8734       case FORALL:
8735       case EXISTS: {
8736 	if(!e.isQuantifier()) {
8737 	  e.print(os);
8738 	  break;
8739 	}
8740 	os << "(" << ((e.getKind() == FORALL)? "FORALL" : "EXISTS");
8741 	const vector<Expr>& vars = e.getVars();
8742 	bool first(true);
8743 	os << "(" ;
8744 	for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
8745 	    i!=iend; ++i) {
8746 	  if(first) first = false;
8747 	  else os << " " ;
8748 	  os << *i;
8749 	  // The quantifier may be in a raw parsed form, in which case
8750 	  // the type is not assigned yet
8751 	  //if(i->isVar())  // simplify do not need type
8752 	  //  os << ":" << space << pushdag << (*i).getType() << popdag;
8753 	}
8754 	os << ") "  << e.getBody() <<  ")";
8755       }
8756 	break;
8757       default:
8758 	e.print(os);
8759 	break;
8760       }
8761       break;
8762     }
8763   case TPTP_LANG:
8764     {
8765       switch(e.getKind()){
8766       case FORALL:
8767       case EXISTS: {
8768 	if(!e.isQuantifier()) {
8769 	  e.print(os);
8770 	  break;
8771 	}
8772 	os << ((e.getKind() == FORALL)? " ! " : " ? ");
8773 	const vector<Expr>& vars = e.getVars();
8774 	bool first(true);
8775 	os << "[" ;
8776 	for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
8777 	    i!=iend; ++i) {
8778 	  if(first) first = false;
8779 	  else os << "," ;
8780 	  os << *i  ;
8781 	  if(i->isVar())  os <<  ": "<< (*i).getType() ;
8782 	}
8783 	os << "] : ("  << e.getBody() <<")";
8784       }
8785 	break;
8786       default:
8787 	e.print(os);
8788 	break;
8789       }
8790       break;
8791     }
8792 
8793 
8794   case PRESENTATION_LANG: {
8795     switch(e.getKind()){
8796     case FORALL:
8797     case EXISTS: {
8798       if(!e.isQuantifier()) {
8799 	e.print(os);
8800 	break;
8801       }
8802       os << "(" << push << ((e.getKind() == FORALL)? "FORALL" : "EXISTS")
8803 	 << space << push;
8804       const vector<Expr>& vars = e.getVars();
8805       bool first(true);
8806       os << "(" << push;
8807       for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
8808 	  i!=iend; ++i) {
8809 	if(first) first = false;
8810 	else os << push << "," << pop << space;
8811 	os << *i;
8812 	// The quantifier may be in a raw parsed form, in which case
8813 	// the type is not assigned yet
8814 	// the following lines are changed for a neat output / by yeting
8815 	if(*d_translate || true){
8816 	  if(i->isVar())
8817 	    os << ":" << space << pushdag << (*i).getType() << popdag;
8818 	}
8819       }
8820       os << push << ") " << pushdag << push;
8821 
8822       // print manual triggers
8823       const vector<vector<Expr> >& triggers = e.getTriggers();
8824       for (vector<vector<Expr> >::const_iterator i=triggers.begin(), iend=triggers.end(); i != iend; ++i) {
8825 	//        const vector<Expr>& terms = (*i).getKids();
8826         const vector<Expr>& terms = (*i);
8827         if (terms.size() > 0) {
8828           os << push << ": PATTERN (" << pushdag << push;
8829           vector<Expr>::const_iterator j=terms.begin(), jend=terms.end();
8830           os << nodag << pushdag << *j << popdag; ++j;
8831           for(;j!=jend; ++j) {
8832             os << push << ", " << pop << space << pushdag << *j << popdag;
8833           }
8834           os << ") " << push;
8835         }
8836       }
8837 
8838       os << ": " << pushdag << e.getBody() << push << ")";
8839     }
8840       break;
8841     default:
8842       e.print(os);
8843       break;
8844     }
8845     break;
8846   }
8847   case SMTLIB_LANG: {
8848     d_theoryUsed = true;
8849     switch(e.getKind()){
8850       case FORALL:
8851       case EXISTS: {
8852         if(!e.isQuantifier()) {
8853           e.print(os);
8854           break;
8855         }
8856         os << "(" << push << ((e.getKind() == FORALL)? "forall" : "exists")
8857            << space;
8858         const vector<Expr>& vars = e.getVars();
8859         bool first(true);
8860         //      os << "(" << push;
8861         for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
8862             i!=iend; ++i) {
8863           if(first) first = false;
8864           else os << space;
8865           os << "(" << push << *i;
8866           // The quantifier may be in a raw parsed form, in which case
8867           // the type is not assigned yet
8868           if(i->isVar())
8869             os << space << pushdag << (*i).getType() << popdag;
8870           os << push << ")" << pop << pop;
8871         }
8872 
8873         os << space << pushdag
8874            << e.getBody() << push;
8875 
8876         // print manual triggers
8877         const vector<vector<Expr> >& triggers = e.getTriggers();
8878         for (vector<vector<Expr> >::const_iterator i=triggers.begin(), iend=triggers.end(); i != iend; ++i) {
8879 	  //          const vector<Expr>& terms = (*i).getKids();
8880           const vector<Expr>& terms = (*i);
8881           /* TODO: How does SMT-LIB v2 handle patterns? */
8882           if (terms.size() > 0) {
8883             os << push << space << ":pat {" << space << pushdag << push;
8884             vector<Expr>::const_iterator j=terms.begin(), jend=terms.end();
8885             os << nodag << pushdag << *j << popdag; ++j;
8886             for(;j!=jend; ++j) {
8887               os << space << pushdag << *j << popdag;
8888             }
8889             os << space << "}" << space << push;
8890           }
8891         }
8892         os << push << ")";
8893         break;
8894       }
8895       default:
8896         throw SmtlibException("TheoryQuant::print: SMTLIB_LANG: Unexpected expression: "
8897                               +getEM()->getKindName(e.getKind()));
8898         break;
8899     }
8900     break;
8901   } // End of SMTLIB_LANG
8902   case SMTLIB_V2_LANG: {
8903     d_theoryUsed = true;
8904     switch(e.getKind()){
8905       case FORALL:
8906       case EXISTS: {
8907         if(!e.isQuantifier()) {
8908           e.print(os);
8909           break;
8910         }
8911         os << "(" << push << ((e.getKind() == FORALL)? "forall" : "exists")
8912            << space;
8913         const vector<Expr>& vars = e.getVars();
8914         bool first(true);
8915         os << "(" << push;
8916         for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
8917             i!=iend; ++i) {
8918           if(first) first = false;
8919           else os << space;
8920           os << "(" << push << *i;
8921           // The quantifier may be in a raw parsed form, in which case
8922           // the type is not assigned yet
8923           if(i->isVar())
8924             os << space << pushdag << (*i).getType() << popdag;
8925           os << push << ")" << pop << pop;
8926         }
8927         os << ")" << pop;
8928 
8929         const vector<vector<Expr> >& triggers = e.getTriggers();
8930         if( !triggers.empty() ) {
8931           os << space << push << "(!";
8932         }
8933         os << space << pushdag << e.getBody() << popdag;
8934 
8935         // print manual triggers
8936         for (vector<vector<Expr> >::const_iterator i=triggers.begin(), iend=triggers.end(); i != iend; ++i) {
8937           //          const vector<Expr>& terms = (*i).getKids();
8938           const vector<Expr>& terms = (*i);
8939           if (terms.size() > 0) {
8940             os << push << space << ":pattern" << space << push << "(" ;
8941             vector<Expr>::const_iterator j=terms.begin(), jend=terms.end();
8942             os << nodag << pushdag << *j << popdag; ++j;
8943             for(;j!=jend; ++j) {
8944               os << space << pushdag << *j << popdag;
8945             }
8946             os << ")" << pop << space ;
8947           }
8948         }
8949         if( !triggers.empty() ) {
8950           os << ")" << pop;
8951         }
8952         os << ")" << pop;
8953         break;
8954       }
8955       default:
8956         throw SmtlibException("TheoryQuant::print: SMTLIB_LANG: Unexpected expression: "
8957                               +getEM()->getKindName(e.getKind()));
8958         break;
8959     }
8960     break;
8961   } // End of SMTLIB_LANG
8962 
8963   case LISP_LANG: {
8964     switch(e.getKind()){
8965     case FORALL:
8966     case EXISTS: {
8967       if(!e.isQuantifier()) {
8968 	e.print(os);
8969 	break;
8970       }
8971       os << "(" << push << ((e.getKind() == FORALL)? "FORALL" : "EXISTS")
8972 	 << space;
8973       const vector<Expr>& vars = e.getVars();
8974       bool first(true);
8975       os << "(" << push;
8976       for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end();
8977 	  i!=iend; ++i) {
8978 	if(first) first = false;
8979 	else os << space;
8980 	os << "(" << push << *i;
8981 	// The quantifier may be in a raw parsed form, in which case
8982 	// the type is not assigned yet
8983 	if(i->isVar())
8984 	  os << space << pushdag << (*i).getType() << popdag;
8985 	os << push << ")" << pop << pop;
8986       }
8987       os << push << ")" << pop << pop << pushdag
8988 	 << e.getBody() << push << ")";
8989     }
8990       break;
8991     default:
8992       e.print(os);
8993       break;
8994     }
8995     break;
8996   }
8997   default:
8998     e.print(os);
8999     break;
9000   }
9001   return os;
9002 }
9003 
9004 ///////////////////////////////////////////////////////////////////////////////
9005 //parseExprOp:
9006 //translating special Exprs to regular EXPR??
9007 ///////////////////////////////////////////////////////////////////////////////
9008 Expr
parseExprOp(const Expr & e)9009 TheoryQuant::parseExprOp(const Expr& e) {
9010   if(theoryCore()->getFlags()["unknown-check-model"].getBool()) {
9011     throw ParserException("ERROR: +unknown-check-model unsafe with quantifiers");
9012   }
9013 
9014   TRACE("parser", "TheoryQuant::parseExprOp(", e, ")");
9015   // If the expression is not a list, it must have been already
9016   // parsed, so just return it as is.
9017   if(RAW_LIST != e.getKind()) return e;
9018 
9019   DebugAssert(e.arity() > 0,
9020 	      "TheoryQuant::parseExprOp:\n e = "+e.toString());
9021 
9022   const Expr& c1 = e[0][0];
9023   const string& opName(c1.getString());
9024   int kind = getEM()->getKind(opName);
9025   switch(kind) {
9026   case FORALL:
9027   case EXISTS: { // (OP ((v1 ... vn tp1) ...) body)
9028     if(!( (e.arity() == 3  || 4 == e.arity())  &&
9029 	  e[1].getKind() == RAW_LIST &&
9030 	  e[1].arity() > 0))
9031       throw ParserException("Bad "+opName+" expression: "+e.toString());
9032 
9033 
9034     // Iterate through the groups of bound variables
9035     vector<pair<string,Type> > vars; // temporary stack of bound variables
9036     for(Expr::iterator i=e[1].begin(), iend=e[1].end(); i!=iend; ++i) {
9037       if(i->getKind() != RAW_LIST || i->arity() < 2)
9038 	throw ParserException("Bad variable declaration block in "+opName
9039 			    +" expression: "+i->toString()
9040 			    +"\n e = "+e.toString());
9041       // Iterate through individual bound vars in the group.  The
9042       // last element is the type, which we have to rebuild and
9043       // parse, since it is used in the creation of bound variables.
9044       Type tp(parseExpr((*i)[i->arity()-1]));
9045       if (tp == boolType()) {
9046         throw ParserException("A quantified variable may not be of type BOOLEAN");
9047       }
9048       for(int j=0, jend=i->arity()-1; j<jend; ++j) {
9049 	if((*i)[j].getKind() != ID)
9050 	  throw ParserException("Bad variable declaration in "+opName+""
9051 			      " expression: "+(*i)[j].toString()+
9052 			      "\n e = "+e.toString());
9053 	vars.push_back(pair<string,Type>((*i)[j][0].getString(), tp));
9054       }
9055     }
9056     // Create all the bound vars and save them in a vector
9057     vector<Expr> boundVars;
9058     for(vector<pair<string,Type> >::iterator i=vars.begin(), iend=vars.end();
9059 	i!=iend; ++i)
9060       boundVars.push_back(addBoundVar(i->first, i->second));
9061     // Rebuild the body
9062     Expr body(parseExpr(e[2]));
9063     // Build the resulting Expr as (OP (vars) body)
9064 
9065     std::vector<std::vector<Expr> > patterns;
9066     if(e.arity() == 4){
9067       DebugAssert ((RAW_LIST == e[3].getKind()),"Unknown type for patterns"+e[3].toString());
9068       for(int i = 0; i < e[3].arity(); i++){
9069 	const Expr& cur_trig(e[3][i]);
9070 	DebugAssert ((RAW_LIST == cur_trig.getKind()),"Unknown type for cur_trig"+cur_trig.toString());
9071 	//	cout<<"cur trig"<<cur_trig<<endl;
9072 	std::vector<Expr> cur_pattern;
9073 	for(int j =0; j < cur_trig.arity(); j++){
9074 	  try {
9075 	    cur_pattern.push_back(parseExpr(cur_trig[j]));
9076 	  }
9077 	  catch (Exception e){
9078 	    //	    cout <<e << endl;
9079 	    //	    cout <<"exception in pattern" << flush << endl;
9080             if(theoryCore()->getFlags()["translate"].getBool()) {
9081               // don't tolerate bad patterns when translating
9082               throw;
9083             }
9084 	    cur_pattern.clear();
9085 	  }
9086 	}
9087 	if (cur_pattern.size() > 0 ){
9088 	  //	  Expr cur_parsed_trig(RAW_LIST, cur_pattern, getEM());
9089 	  patterns.push_back(cur_pattern);
9090 	}
9091       }
9092     }
9093 
9094 
9095     Expr res;
9096     if(3 == e.arity()) {
9097       res = getEM()->newClosureExpr((kind == FORALL) ? FORALL : EXISTS,boundVars, body);
9098     }
9099     else{// 4 == e.arity()
9100       res = getEM()->newClosureExpr((kind == FORALL) ? FORALL : EXISTS,boundVars, body, patterns );
9101       //      cout<<"patterns vector"<<vectorExpr2string(patterns)<<endl;;
9102       //      cout<<"patterns thm"<<res<<endl;;
9103     }
9104     return res;
9105     break;
9106   }
9107   default:
9108     DebugAssert(false,
9109 		"TheoryQuant::parseExprOp: invalid command or expression: " + e.toString());
9110     break;
9111   }
9112   return e;
9113 }
9114 
9115