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