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