CVC3
theory_quant.cpp
Go to the documentation of this file.
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 
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 
61 bool Trigger::isPos(){
62  return (Pos==polarity||PosNeg==polarity);
63 }
64 
65 bool Trigger::isNeg(){
66  return (Neg==polarity || PosNeg==polarity);
67 }
68 
69 std::vector<Expr> Trigger::getBVs(){
70  return bvs;
71 }
72 
73 Expr Trigger::getEx(){
74  return trig;
75 }
76 
77 void Trigger::setHead(Expr h){
78  head=h;
79 }
80 
81 Expr Trigger::getHead(){
82  return head;
83 }
84 
85 void Trigger::setRWOp(bool b){
86  hasRWOp =b ;
87 }
88 
89 bool Trigger::hasRW(){
90  return hasRWOp;
91 }
92 
93 void Trigger::setTrans(bool b){
94  hasTrans =b ;
95 }
96 
97 bool Trigger::hasTr(){
98  return hasTrans;
99 }
100 
101 void Trigger::setTrans2(bool b){
102  hasT2 =b ;
103 }
104 
105 bool Trigger::hasTr2(){
106  return hasT2;
107 }
108 
109 void Trigger::setSimp(){
110  isSimple =true ;
111 }
112 
113 bool Trigger::isSimp(){
114  return isSimple;
115 }
116 
117 void Trigger::setSuperSimp(){
118  isSuperSimple =true ;
119 }
120 
121 bool Trigger::isSuperSimp(){
122  return isSuperSimple;
123 }
124 
125 void Trigger::setMultiTrig(){
126  isMulti = true ;
127 }
128 
129 bool Trigger::isMultiTrig(){
130  return isMulti;
131 }
132 
133 
135  :trig(t),
136  univ_id(id),
137  binds(b)
138 {}
139 
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;
213  kinds.push_back(EXISTS);
214  kinds.push_back(FORALL);
215  registerTheory(this, kinds);
216  d_partCalled=false;
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);
230 
231 }
232 
233 //! Destructor
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 }
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 
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 
274 int inline TheoryQuant::getExprScore(const Expr& e){
275  return theoryCore()->getQuantLevelForTerm(e);
276 }
277 
278 bool isSysPred(const Expr& e){
279  return ( isLE(e) || isLT(e) || isGE(e) || isGT(e) || e.isEq());
280 }
281 
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 
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 
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 
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 
337 void TheoryQuant::setup(const Expr& e) {}
338 
339 int TheoryQuant::help(int i) {
340  return d_curMaxExprScore;
341 }
342 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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){
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();
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 
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 
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 
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 
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{
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 
1041 
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 
1059 int exprScore(const Expr& e){
1060  return recursiveExprScore(e);
1061 }
1062 
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 
1107  return getHeadExpr(e);
1108 }
1109 
1110 //! get the bound vars in term e,
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,
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 
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 
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 
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 
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 
1345  d_theoryCore(core),
1346  d_quant_rules(quant_rule)
1347 {}
1348 
1349 // collect all uninterpreted pedidates in assert
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 
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 
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 
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 
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 
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
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 
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.
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 
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 
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 
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 
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 
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 
1818  if ( ! isInt(e.getType())) return;
1819  d_allIndex.insert(d_theoryCore->simplifyExpr(e));
1820 }
1821 
1823  Expr one = d_theoryCore->getEM()->newRatExpr(1);
1824  return Expr(PLUS, e, one);
1825 }
1826 
1828  Expr one = d_theoryCore->getEM()->newRatExpr(1);
1829  return Expr(MINUS, e, one);
1830 }
1831 
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 
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 
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 
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 
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 
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;
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 
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 
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 
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 
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 
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){
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 
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 
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 
2457  if(!isSysPred(e)) return false;
2458  if(usefulInMatch(e[0]) || usefulInMatch(e[1])) return true;
2459  return false;
2460 }
2461 
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
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.
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 
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 
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 
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 
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 
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 
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 
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 */
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
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
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 
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 
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
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,
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
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 
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 
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 
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 
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){
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 */
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 
6973 inline bool TheoryQuant::transFound(const Expr& comb){
6974  return (d_trans_found.count(comb) > 0);
6975 }
6976 
6977 inline void TheoryQuant::setTransFound(const Expr& comb){
6978  d_trans_found[comb] = true;
6979 }
6980 
6981 inline bool TheoryQuant::trans2Found(const Expr& comb){
6982  return (d_trans2_found.count(comb) > 0);
6983 }
6984 
6985 inline void TheoryQuant::setTrans2Found(const Expr& comb){
6986  d_trans2_found[comb] = true;
6987 }
6988 
6989 
6991  if(d_trans_back.count(ex)>0){
6992  return *d_trans_back[ex];
6993  }
6994  else{
6995  return null_cdlist;
6996  }
6997 }
6998 
7000  if(d_trans_forw.count(ex)>0){
7001  return *d_trans_forw[ex];
7002  }
7003  else{
7004  return null_cdlist;
7005  }
7006 }
7007 
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 
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 
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 
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 
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 
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 
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 
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{
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{
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 
8113  d_lastTermsPos.set(theoryCore()->getTerms().size());
8114  d_lastPredsPos.set(theoryCore()->getPredicates().size());
8117 }
8118 
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 ){
8146  add_parent(cur);
8147  }
8148  }
8149  else{
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){
8166  add_parent(cur);
8167  }
8168  }
8169  else{
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 
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){
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 ){
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){
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 ){
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 ){
8308  }
8309  else {
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 ){
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;
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;
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 
8381 void TheoryQuant::semCheckSat(bool fullEffort){
8382 }
8383 
8384 //the following is old code and I did not modify much, Yeting
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 
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++) {
8407  break;
8408  else
8409  instantiate(d_univs[i], i>=pos, true, d_savedTermsPos.get());
8410  }
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++) {
8426  break;
8427  else
8428  instantiate(d_univs[i], i>=pos, false, origSize);
8429  }
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  */
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.
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) {
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  */
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  */
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();
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  */
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  */
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.
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 
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&
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
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