CVC3
|
00001 /*****************************************************************************/ 00002 /*! 00003 * \file quant_theorem_producer.cpp 00004 * 00005 * Author: Daniel Wichs, Yeting Ge 00006 * 00007 * Created: Jul 07 22:22:38 GMT 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 * CLASS: QuantProofRules 00019 * 00020 * 00021 * Description: TRUSTED implementation of arithmetic proof rules. 00022 * 00023 */ 00024 /*****************************************************************************/ 00025 00026 // This code is trusted 00027 #define _CVC3_TRUSTED_ 00028 00029 00030 #include "quant_theorem_producer.h" 00031 #include "theory_quant.h" 00032 #include "theory_core.h" 00033 00034 00035 using namespace std; 00036 using namespace CVC3; 00037 00038 00039 QuantProofRules* TheoryQuant::createProofRules() { 00040 return new QuantTheoremProducer(theoryCore()->getTM(), this); 00041 } 00042 00043 00044 #define CLASS_NAME "CVC3::QuantTheoremProducer" 00045 00046 00047 //! ==> NOT FORALL (vars): e IFF EXISTS (vars) NOT e 00048 Theorem 00049 QuantTheoremProducer::rewriteNotForall(const Expr& e) { 00050 if(CHECK_PROOFS) { 00051 CHECK_SOUND(e.isNot() && e[0].isForall(), 00052 "rewriteNotForall: expr must be NOT FORALL:\n" 00053 +e.toString()); 00054 } 00055 Proof pf; 00056 if(withProof()) 00057 pf = newPf("rewrite_not_forall", e); 00058 return newRWTheorem(e, e.getEM()->newClosureExpr(EXISTS, e[0].getVars(), 00059 !e[0].getBody()), 00060 Assumptions::emptyAssump(), pf); 00061 } 00062 00063 Theorem 00064 QuantTheoremProducer::addNewConst(const Expr& e) { 00065 Proof pf; 00066 if(withProof()) 00067 pf = newPf("add_new_const", e); 00068 return newTheorem(e, Assumptions::emptyAssump(), pf); 00069 } 00070 00071 ///do not use this rule, this is for debug only 00072 Theorem 00073 QuantTheoremProducer::newRWThm(const Expr& e, const Expr& newE) { 00074 Proof pf; 00075 if(withProof()) 00076 pf = newPf("from cache", e); 00077 return newRWTheorem(e, newE,Assumptions::emptyAssump(), pf); 00078 } 00079 00080 00081 Theorem 00082 QuantTheoremProducer::normalizeQuant(const Expr& quant) { 00083 if(CHECK_PROOFS) { 00084 CHECK_SOUND(quant.isForall()||quant.isExists(), 00085 "normalizeQuant: expr must be FORALL or EXISTS\n" 00086 +quant.toString()); 00087 } 00088 00089 00090 std::map<Expr,int>::iterator typeIter; 00091 std::string base("_BD"); 00092 int counter(0); 00093 00094 vector<Expr> newVars; 00095 const std::vector<Expr>& cur_vars = quant.getVars(); 00096 for(size_t j =0; j<cur_vars.size(); j++){ 00097 Type t = cur_vars[j].getType(); 00098 int typeIndex ; 00099 00100 typeIter = d_typeFound.find(t.getExpr()); 00101 00102 if(d_typeFound.end() == typeIter){ 00103 typeIndex = d_typeFound.size(); 00104 d_typeFound[t.getExpr()] = typeIndex; 00105 } 00106 else{ 00107 typeIndex = typeIter->second; 00108 } 00109 00110 counter++; 00111 std::stringstream stringType; 00112 stringType << counter << "TY" << typeIndex ; 00113 std::string out_str = base + stringType.str(); 00114 Expr newExpr = d_theoryQuant->getEM()->newBoundVarExpr(out_str, int2string(counter)); 00115 newExpr.setType(t); 00116 newVars.push_back(newExpr); 00117 } 00118 00119 vector<vector<Expr> > trigs = quant.getTriggers(); 00120 for(size_t i = 0 ; i < trigs.size(); i++){ 00121 for(size_t j = 0 ; j < trigs[i].size(); j++){ 00122 trigs[i][j] = trigs[i][j].substExpr(cur_vars,newVars); 00123 } 00124 } 00125 00126 Expr normBody = quant.getBody().substExpr(cur_vars,newVars); 00127 Expr normQuant = d_theoryQuant->getEM()->newClosureExpr(quant.isForall()?FORALL:EXISTS, newVars, normBody, trigs); 00128 00129 Proof pf; 00130 if(withProof()) 00131 pf = newPf("normalizeQuant", quant, normQuant); 00132 00133 return newRWTheorem(quant, normQuant, Assumptions::emptyAssump(), pf); 00134 00135 } 00136 00137 00138 //! ==> NOT EXISTS (vars): e IFF FORALL (vars) NOT e 00139 Theorem QuantTheoremProducer::rewriteNotExists(const Expr& e) { 00140 if(CHECK_PROOFS) { 00141 CHECK_SOUND(e.isNot() && e[0].isExists(), 00142 "rewriteNotExists: expr must be NOT FORALL:\n" 00143 +e.toString()); 00144 } 00145 Proof pf; 00146 if(withProof()) 00147 pf = newPf("rewrite_not_exists", e); 00148 return newRWTheorem(e, e.getEM()->newClosureExpr(FORALL, e[0].getVars(), 00149 !e[0].getBody()), 00150 Assumptions::emptyAssump(), pf); 00151 } 00152 00153 00154 Theorem QuantTheoremProducer::universalInst(const Theorem& t1, const vector<Expr>& terms, int quantLevel, Expr gterm){ 00155 Expr e = t1.getExpr(); 00156 const vector<Expr>& boundVars = e.getVars(); 00157 00158 for(unsigned int i=0; i<terms.size(); i++){ 00159 if (d_theoryQuant->getBaseType(boundVars[i]) != 00160 d_theoryQuant->getBaseType(terms[i])){ 00161 Proof pf; 00162 return newRWTheorem(terms[i],terms[i], 00163 Assumptions::emptyAssump(), pf); 00164 } 00165 //this is the same as return a TRUE theorem, which will be ignored immeridatele. So, this is just return doing nothing. 00166 } 00167 00168 00169 if(CHECK_PROOFS) { 00170 CHECK_SOUND(boundVars.size() == terms.size(), 00171 "Universal instantiation: size of terms array does " 00172 "not match quanitfied variables array size"); 00173 CHECK_SOUND(e.isForall(), 00174 "universal instantiation: expr must be FORALL:\n" 00175 +e.toString()); 00176 00177 for(unsigned int i=0; i<terms.size(); i++) 00178 CHECK_SOUND(d_theoryQuant->getBaseType(boundVars[i]) == 00179 d_theoryQuant->getBaseType(terms[i]), 00180 "Universal instantiation: type mismatch"); 00181 } 00182 00183 //build up a conjunction of type predicates for expression 00184 Expr tr = e.getEM()->trueExpr(); 00185 Expr typePred = tr; 00186 // unsigned qlevel, qlevelMax = 0; 00187 for(unsigned int i=0; i<terms.size(); i++) { 00188 Expr p = d_theoryQuant->getTypePred(boundVars[i].getType(),terms[i]); 00189 if(p!=tr) { 00190 if(typePred==tr) 00191 typePred = p; 00192 else 00193 typePred = typePred.andExpr(p); 00194 } 00195 // qlevel = d_theoryQuant->theoryCore()->getQuantLevelForTerm(terms[i]); 00196 // if (qlevel > qlevelMax) qlevel = qlevelMax; 00197 } 00198 00199 00200 // Expr inst = e.getBody().substExprQuant(e.getVars(), terms); 00201 Expr inst = e.getBody().substExpr(e.getVars(), terms); 00202 00203 // Expr inst = e.getBody().substExpr(e.getVars(), terms); 00204 00205 00206 Proof pf; 00207 if(withProof()) { 00208 vector<Proof> pfs; 00209 vector<Expr> es; 00210 pfs.push_back(t1.getProof()); 00211 es.push_back(e); 00212 es.push_back(Expr(RAW_LIST,terms)); 00213 // es.insert(es.end(), terms.begin(), terms.end()); 00214 es.push_back(inst); 00215 if (gterm.isNull()) { 00216 es.push_back( d_theoryQuant->getEM()->newRatExpr(0)); 00217 } 00218 else {es.push_back(gterm); 00219 } 00220 pf= newPf("universal_elimination1", es, pfs); 00221 } 00222 00223 00224 // Expr inst = e.getBody().substExpr(e.getVars(), terms); 00225 00226 00227 Expr imp; 00228 if(typePred == tr ) //just for a easy life, yeting, change this assp 00229 imp = inst; 00230 else 00231 imp = typePred.impExpr(inst); 00232 Theorem ret = newTheorem(imp, t1.getAssumptionsRef(), pf); 00233 00234 int thmLevel = t1.getQuantLevel(); 00235 if(quantLevel >= thmLevel) { 00236 ret.setQuantLevel(quantLevel+1); 00237 } 00238 else{ 00239 ret.setQuantLevel(thmLevel+1); 00240 } 00241 00242 // ret.setQuantLevel(quantLevel+1); 00243 return ret; 00244 } 00245 00246 00247 //! Instantiate a universally quantified formula 00248 /*! From T|-FORALL(var): e generate T|-psi => e' where e' is obtained 00249 * from e by instantiating bound variables with terms in 00250 * vector<Expr>& terms. The vector of terms should be the same 00251 * size as the vector of bound variables in e. Also elements in 00252 * each position i need to have matching base types. psi is the conjunction of 00253 * subtype predicates for the bound variables of the quanitfied expression. 00254 * \param t1 the quantifier (a Theorem) 00255 * \param terms the terms to instantiate. 00256 * \param quantLevel the quantification level for the formula 00257 */ 00258 Theorem QuantTheoremProducer::universalInst(const Theorem& t1, const vector<Expr>& terms, int quantLevel){ 00259 00260 Expr e = t1.getExpr(); 00261 const vector<Expr>& boundVars = e.getVars(); 00262 if(CHECK_PROOFS) { 00263 CHECK_SOUND(boundVars.size() == terms.size(), 00264 "Universal instantiation: size of terms array does " 00265 "not match quanitfied variables array size"); 00266 CHECK_SOUND(e.isForall(), 00267 "universal instantiation: expr must be FORALL:\n" 00268 +e.toString()); 00269 for(unsigned int i=0; i<terms.size(); i++) 00270 CHECK_SOUND(d_theoryQuant->getBaseType(boundVars[i]) == 00271 d_theoryQuant->getBaseType(terms[i]), 00272 "Universal instantiation: type mismatch"); 00273 } 00274 00275 //build up a conjunction of type predicates for expression 00276 Expr tr = e.getEM()->trueExpr(); 00277 Expr typePred = tr; 00278 // unsigned qlevel, qlevelMax = 0; 00279 for(unsigned int i=0; i<terms.size(); i++) { 00280 Expr p = d_theoryQuant->getTypePred(boundVars[i].getType(),terms[i]); 00281 if(p!=tr) { 00282 if(typePred==tr) 00283 typePred = p; 00284 else 00285 typePred = typePred.andExpr(p); 00286 } 00287 // qlevel = d_theoryQuant->theoryCore()->getQuantLevelForTerm(terms[i]); 00288 // if (qlevel > qlevelMax) qlevel = qlevelMax; 00289 } 00290 00291 //Expr inst = e.getBody().substExprQuant(e.getVars(), terms); 00292 Expr inst = e.getBody().substExpr(e.getVars(), terms); 00293 00294 00295 // Expr inst = e.getBody().substExpr(e.getVars(), terms); 00296 00297 00298 Proof pf; 00299 if(withProof()) { 00300 vector<Proof> pfs; 00301 vector<Expr> es; 00302 pfs.push_back(t1.getProof()); 00303 es.push_back(e); 00304 es.push_back(Expr(RAW_LIST,terms)); 00305 // es.insert(es.end(), terms.begin(), terms.end()); 00306 es.push_back(inst); 00307 pf= newPf("universal_elimination2", es, pfs); 00308 } 00309 00310 // Expr inst = e.getBody().substExpr(e.getVars(), terms); 00311 00312 00313 Expr imp; 00314 if(typePred == tr) //just for a easy life, yeting, change this assp 00315 imp = inst; 00316 else 00317 imp = typePred.impExpr(inst); 00318 Theorem ret = newTheorem(imp, t1.getAssumptionsRef(), pf); 00319 00320 int thmLevel = t1.getQuantLevel(); 00321 if(quantLevel >= thmLevel) { 00322 ret.setQuantLevel(quantLevel+1); 00323 } 00324 else{ 00325 ret.setQuantLevel(thmLevel+1); 00326 } 00327 00328 // ret.setQuantLevel(quantLevel+1); 00329 return ret; 00330 } 00331 00332 Theorem QuantTheoremProducer::universalInst(const Theorem& t1, const vector<Expr>& terms){ 00333 00334 Expr e = t1.getExpr(); 00335 const vector<Expr>& boundVars = e.getVars(); 00336 if(CHECK_PROOFS) { 00337 CHECK_SOUND(boundVars.size() == terms.size(), 00338 "Universal instantiation: size of terms array does " 00339 "not match quanitfied variables array size"); 00340 CHECK_SOUND(e.isForall(), 00341 "universal instantiation: expr must be FORALL:\n" 00342 +e.toString()); 00343 for(unsigned int i=0; i<terms.size(); i++) 00344 CHECK_SOUND(d_theoryQuant->getBaseType(boundVars[i]) == 00345 d_theoryQuant->getBaseType(terms[i]), 00346 "Universal instantiation: type mismatch"); 00347 } 00348 00349 //build up a conjunction of type predicates for expression 00350 Expr tr = e.getEM()->trueExpr(); 00351 Expr typePred = tr; 00352 unsigned qlevel=0, qlevelMax = 0; 00353 for(unsigned int i=0; i<terms.size(); i++) { 00354 Expr p = d_theoryQuant->getTypePred(boundVars[i].getType(),terms[i]); 00355 if(p!=tr) { 00356 if(typePred==tr) 00357 typePred = p; 00358 else 00359 typePred = typePred.andExpr(p); 00360 } 00361 qlevel = d_theoryQuant->theoryCore()->getQuantLevelForTerm(terms[i]); 00362 if (qlevel > qlevelMax) qlevel = qlevelMax; 00363 } 00364 00365 Expr inst = e.getBody().substExpr(e.getVars(), terms); 00366 // Expr inst = e.getBody().substExprQuant(e.getVars(), terms); 00367 00368 00369 // Expr inst = e.getBody().substExpr(e.getVars(), terms); 00370 00371 Proof pf; 00372 if(withProof()) { 00373 vector<Proof> pfs; 00374 vector<Expr> es; 00375 pfs.push_back(t1.getProof()); 00376 es.push_back(e); 00377 es.push_back(Expr(RAW_LIST,terms)); 00378 // es.insert(es.end(), terms.begin(), terms.end()); 00379 es.push_back(inst); 00380 pf= newPf("universal_elimination3", es, pfs); 00381 } 00382 00383 // Expr inst = e.getBody().substExpr(e.getVars(), terms); 00384 00385 Expr imp; 00386 if( typePred == tr ) //just for easy life, yeting, change this asap 00387 imp = inst; 00388 else 00389 imp = typePred.impExpr(inst); 00390 Theorem ret = newTheorem(imp, t1.getAssumptionsRef(), pf); 00391 00392 00393 unsigned thmLevel = t1.getQuantLevel(); 00394 if(qlevel >= thmLevel) { 00395 ret.setQuantLevel(qlevel+1); 00396 } 00397 else{ 00398 // ret.setQuantLevel(thmLevel+1); 00399 ret.setQuantLevel(thmLevel+1); 00400 } 00401 00402 00403 // ret.setQuantLevel(qlevel+1); 00404 return ret; 00405 } 00406 00407 00408 Theorem QuantTheoremProducer::partialUniversalInst(const Theorem& t1, const vector<Expr>& terms, int quantLevel){ 00409 cout<<"error in partial inst" << endl; 00410 Expr e = t1.getExpr(); 00411 const vector<Expr>& boundVars = e.getVars(); 00412 if(CHECK_PROOFS) { 00413 CHECK_SOUND(boundVars.size() >= terms.size(), 00414 "Universal instantiation: size of terms array does " 00415 "not match quanitfied variables array size"); 00416 CHECK_SOUND(e.isForall(), 00417 "universal instantiation: expr must be FORALL:\n" 00418 +e.toString()); 00419 for(unsigned int i=0; i<terms.size(); i++){ 00420 CHECK_SOUND(d_theoryQuant->getBaseType(boundVars[i]) == 00421 d_theoryQuant->getBaseType(terms[i]), 00422 "partial Universal instantiation: type mismatch"); 00423 } 00424 } 00425 00426 //build up a conjunction of type predicates for expression 00427 Expr tr = e.getEM()->trueExpr(); 00428 Expr typePred = tr; 00429 for(unsigned int i=0; i<terms.size(); i++) { 00430 Expr p = d_theoryQuant->getTypePred(boundVars[i].getType(),terms[i]); 00431 if(p!=tr) { 00432 if(typePred==tr) 00433 typePred = p; 00434 else 00435 typePred = typePred.andExpr(p); 00436 } 00437 } 00438 Proof pf; 00439 if(withProof()) { 00440 vector<Proof> pfs; 00441 vector<Expr> es; 00442 pfs.push_back(t1.getProof()); 00443 es.push_back(e); 00444 es.insert(es.end(), terms.begin(), terms.end()); 00445 pf= newPf("partial_universal_instantiation", es, pfs); 00446 } 00447 00448 00449 if(terms.size() == boundVars.size()){ 00450 Expr inst = e.getBody().substExpr(e.getVars(), terms); 00451 Expr imp; 00452 if(typePred == tr) 00453 imp = inst; 00454 else 00455 imp = typePred.impExpr(inst); 00456 return(newTheorem(imp, t1.getAssumptionsRef(), pf)); 00457 } 00458 else{ 00459 vector<Expr> newBoundVars; 00460 for(size_t i=0; i<terms.size(); i++) { 00461 newBoundVars.push_back(boundVars[i]); 00462 } 00463 00464 vector<Expr>leftBoundVars; 00465 for(size_t i=terms.size(); i<boundVars.size(); i++) { 00466 leftBoundVars.push_back(boundVars[i]); 00467 } 00468 00469 Expr tempinst = e.getBody().substExpr(newBoundVars, terms); 00470 Expr inst = d_theoryQuant->getEM()->newClosureExpr(FORALL, leftBoundVars, tempinst); 00471 00472 Expr imp; 00473 if(typePred == tr) 00474 imp = inst; 00475 else 00476 imp = typePred.impExpr(inst); 00477 00478 Theorem res = (newTheorem(imp, t1.getAssumptionsRef(), pf)); 00479 int thmLevel = t1.getQuantLevel(); 00480 if(quantLevel >= thmLevel) { 00481 res.setQuantLevel(quantLevel+1); 00482 } 00483 else{ 00484 //k ret.setQuantLevel(thmLevel+1); 00485 res.setQuantLevel(thmLevel); 00486 } 00487 return res; 00488 00489 } 00490 } 00491 00492 //! find all bound variables in e and maps them to true in boundVars 00493 void QuantTheoremProducer::recFindBoundVars(const Expr& e, 00494 ExprMap<bool> & boundVars, ExprMap<bool> &visited) 00495 { 00496 if(visited.count(e)>0) 00497 return; 00498 else 00499 visited[e] = true; 00500 if(e.getKind() == BOUND_VAR) 00501 boundVars[e] = true; 00502 if(e.getKind() == EXISTS || e.getKind() == FORALL) 00503 recFindBoundVars(e.getBody(), boundVars, visited); 00504 for(Expr::iterator it = e.begin(); it!=e.end(); ++it) 00505 recFindBoundVars(*it, boundVars, visited); 00506 00507 } 00508 00509 //!adjust the order of bound vars, newBvs begin first 00510 Theorem QuantTheoremProducer::adjustVarUniv(const Theorem& t1, const std::vector<Expr>& newBvs){ 00511 const Expr e=t1.getExpr(); 00512 const Expr body = e.getBody(); 00513 if(CHECK_PROOFS) { 00514 CHECK_SOUND(e.isForall(), 00515 "adjustVarUniv: " 00516 +e.toString()); 00517 } 00518 00519 const vector<Expr>& origVars = e.getVars(); 00520 00521 00522 ExprMap<bool> oldmap; 00523 for(vector<Expr>::const_iterator it = origVars.begin(), 00524 iend=origVars.end(); it!=iend; ++it) { 00525 oldmap[*it]=true; 00526 } 00527 00528 vector<Expr> quantVars; 00529 for(vector<Expr>::const_iterator it = newBvs.begin(), 00530 iend=newBvs.end(); it!=iend; ++it) { 00531 if(oldmap.count(*it) > 0) 00532 quantVars.push_back(*it); 00533 } 00534 00535 if(quantVars.size() == origVars.size()) 00536 return t1; 00537 00538 ExprMap<bool> newmap; 00539 for(vector<Expr>::const_iterator it = newBvs.begin(), 00540 iend=newBvs.end(); it!=iend; ++it) { 00541 newmap[*it]=true; 00542 } 00543 00544 for(vector<Expr>::const_iterator it = origVars.begin(), 00545 iend=origVars.end(); it!=iend; ++it) { 00546 if(newmap.count(*it)<=0){ 00547 quantVars.push_back(*it); 00548 }; 00549 } 00550 00551 Proof pf; 00552 if(withProof()) { 00553 vector<Expr> es; 00554 vector<Proof> pfs; 00555 es.push_back(e); 00556 es.insert(es.end(), quantVars.begin(), quantVars.end()); 00557 pfs.push_back(t1.getProof()); 00558 pf= newPf("adjustVarUniv", es, pfs); 00559 } 00560 00561 Expr newQuantExpr; 00562 newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, quantVars, body); 00563 00564 return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); 00565 } 00566 00567 //!pack (forall (x) forall (y)) into (forall (x y)) 00568 Theorem QuantTheoremProducer::packVar(const Theorem& t1){ 00569 Expr out_forall =t1.getExpr(); 00570 00571 if(CHECK_PROOFS) { 00572 CHECK_SOUND(out_forall.isForall(), 00573 "packVar: " 00574 +out_forall.toString()); 00575 } 00576 00577 vector<Expr> bVars = out_forall.getVars(); 00578 00579 if(!out_forall.getBody().isForall()){ 00580 return t1; 00581 } 00582 00583 Expr cur_body = out_forall.getBody(); 00584 00585 while(cur_body.isForall()){ 00586 vector<Expr> bVarsLeft = cur_body.getVars(); 00587 for(vector<Expr>::iterator i=bVarsLeft.begin(), iend=bVarsLeft.end(); i!=iend; i++){ 00588 bVars.push_back(*i); 00589 } 00590 cur_body=cur_body.getBody(); 00591 } 00592 00593 Proof pf; 00594 if(withProof()) { 00595 vector<Expr> es; 00596 vector<Proof> pfs; 00597 es.push_back(out_forall); 00598 es.insert(es.end(), bVars.begin(), bVars.end()); 00599 pfs.push_back(t1.getProof()); 00600 pf= newPf("packVar", es, pfs); 00601 } 00602 00603 Expr newQuantExpr; 00604 newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, bVars, cur_body); 00605 00606 return (newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); 00607 // return (newRWTheorem(t1,newQuantExpr, t1.getAssumptionsRef(), pf)); 00608 } 00609 00610 //! convert (forall (x) ... forall (y)) into (forall (x y)...) 00611 //! convert (exists (x) ... exists (y)) into (exists (x y)...) 00612 Theorem QuantTheoremProducer::pullVarOut(const Theorem& t1){ 00613 const Expr thm_expr=t1.getExpr(); 00614 00615 if(CHECK_PROOFS) { 00616 CHECK_SOUND(thm_expr.isForall() || thm_expr.isExists(), 00617 "pullVarOut: " 00618 +thm_expr.toString()); 00619 } 00620 00621 const Expr outBody = thm_expr.getBody(); 00622 00623 // if(((outBody.isAnd() && outBody[1].isForall()) || 00624 // (outBody.isImpl() && outBody[1].isForall()) || 00625 // (outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists()) )){ 00626 // return t1; 00627 // } 00628 00629 if (thm_expr.isForall()){ 00630 if((outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists())){ 00631 00632 vector<Expr> bVarsOut = thm_expr.getVars(); 00633 00634 const Expr innerExists =outBody[0][1]; 00635 const Expr innerBody = innerExists.getBody(); 00636 vector<Expr> bVarsIn = innerExists.getVars(); 00637 00638 for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){ 00639 bVarsOut.push_back(*i); 00640 } 00641 00642 Proof pf; 00643 if(withProof()) { 00644 vector<Expr> es; 00645 vector<Proof> pfs; 00646 es.push_back(thm_expr); 00647 es.insert(es.end(), bVarsIn.begin(), bVarsIn.end()); 00648 pfs.push_back(t1.getProof()); 00649 pf= newPf("pullVarOut", es, pfs); 00650 } 00651 00652 Expr newbody; 00653 00654 newbody=(outBody[0][0].notExpr()).orExpr(innerBody.notExpr()); 00655 00656 Expr newQuantExpr; 00657 newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, bVarsOut, newbody); 00658 00659 return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); 00660 } 00661 00662 else if ((outBody.isAnd() && outBody[1].isForall()) || 00663 (outBody.isImpl() && outBody[1].isForall())){ 00664 00665 vector<Expr> bVarsOut = thm_expr.getVars(); 00666 00667 const Expr innerForall=outBody[1]; 00668 const Expr innerBody = innerForall.getBody(); 00669 vector<Expr> bVarsIn = innerForall.getVars(); 00670 00671 for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){ 00672 bVarsOut.push_back(*i); 00673 } 00674 00675 Proof pf; 00676 if(withProof()) { 00677 vector<Expr> es; 00678 vector<Proof> pfs; 00679 es.push_back(thm_expr); 00680 es.insert(es.end(), bVarsIn.begin(), bVarsIn.end()); 00681 pfs.push_back(t1.getProof()); 00682 pf= newPf("pullVarOut", es, pfs); 00683 } 00684 00685 Expr newbody; 00686 if(outBody.isAnd()){ 00687 newbody=outBody[0].andExpr(innerBody); 00688 } 00689 else if(outBody.isImpl()){ 00690 newbody=outBody[0].impExpr(innerBody); 00691 } 00692 00693 Expr newQuantExpr; 00694 newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, bVarsOut, newbody); 00695 00696 return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); 00697 } 00698 return t1; // case cannot be handled now. 00699 } 00700 00701 else if (thm_expr.isExists()){ 00702 if ((outBody.isAnd() && outBody[1].isExists()) || 00703 (outBody.isImpl() && outBody[1].isExists())){ 00704 00705 vector<Expr> bVarsOut = thm_expr.getVars(); 00706 00707 const Expr innerExists = outBody[1]; 00708 const Expr innerBody = innerExists.getBody(); 00709 vector<Expr> bVarsIn = innerExists.getVars(); 00710 00711 for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){ 00712 bVarsOut.push_back(*i); 00713 } 00714 00715 Proof pf; 00716 if(withProof()) { 00717 vector<Expr> es; 00718 vector<Proof> pfs; 00719 es.push_back(thm_expr); 00720 es.insert(es.end(), bVarsIn.begin(), bVarsIn.end()); 00721 pfs.push_back(t1.getProof()); 00722 pf= newPf("pullVarOut", es, pfs); 00723 } 00724 00725 Expr newbody; 00726 if(outBody.isAnd()){ 00727 newbody=outBody[0].andExpr(innerBody); 00728 } 00729 else if(outBody.isImpl()){ 00730 newbody=outBody[0].impExpr(innerBody); 00731 } 00732 00733 Expr newQuantExpr; 00734 newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(EXISTS, bVarsOut, newbody); 00735 00736 return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); 00737 } 00738 } 00739 return t1; 00740 } 00741 00742 00743 00744 /*! @brief From T|- QUANTIFIER (vars): e we get T|-QUANTIFIER(vars') e 00745 * where vars' is obtained from vars by removing all bound variables 00746 * not used in e. If vars' is empty the produced theorem is just T|-e 00747 */ 00748 Theorem QuantTheoremProducer::boundVarElim(const Theorem& t1) 00749 { 00750 const Expr e=t1.getExpr(); 00751 const Expr body = e.getBody(); 00752 if(CHECK_PROOFS) { 00753 CHECK_SOUND(e.isForall() || e.isExists(), 00754 "bound var elimination: " 00755 +e.toString()); 00756 } 00757 ExprMap<bool> boundVars; //a mapping of bound variables in the body to true 00758 ExprMap<bool> visited; //to make sure expressions aren't traversed 00759 //multiple times 00760 recFindBoundVars(body, boundVars, visited); 00761 vector<Expr> quantVars; 00762 const vector<Expr>& origVars = e.getVars(); 00763 for(vector<Expr>::const_iterator it = origVars.begin(), 00764 iend=origVars.end(); it!=iend; ++it) 00765 { 00766 if(boundVars.count(*it) > 0) 00767 quantVars.push_back(*it); 00768 } 00769 00770 // If all variables are used, just return the original theorem 00771 if(quantVars.size() == origVars.size()) 00772 return t1; 00773 00774 Proof pf; 00775 if(withProof()) { 00776 vector<Expr> es; 00777 vector<Proof> pfs; 00778 es.push_back(e); 00779 es.insert(es.end(), quantVars.begin(), quantVars.end()); 00780 pfs.push_back(t1.getProof()); 00781 pf= newPf("bound_variable_elimination", es, pfs); 00782 } 00783 if(quantVars.size() == 0) 00784 return(newTheorem(e.getBody(), t1.getAssumptionsRef(), pf)); 00785 00786 Expr newQuantExpr; 00787 if(e.isForall()) 00788 newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, quantVars, body); 00789 else 00790 newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(EXISTS, quantVars, body); 00791 00792 return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); 00793 }