/*! @brief From T|- QUANTIFIER (vars): e we get T|-QUANTIFIER(vars') e * where vars' is obtained from vars by removing all bound variables * not used in e. If vars' is empty the produced theorem is just T|-e */ Theorem QuantTheoremProducer::boundVarElim(const Theorem& t1) { const Expr e=t1.getExpr(); const Expr body = e.getBody(); if(CHECK_PROOFS) { CHECK_SOUND(e.isForall() || e.isExists(), "bound var elimination: " +e.toString()); } ExprMap<bool> boundVars; //a mapping of bound variables in the body to true ExprMap<bool> visited; //to make sure expressions aren't traversed //multiple times recFindBoundVars(body, boundVars, visited); vector<Expr> quantVars; const vector<Expr>& origVars = e.getVars(); for(vector<Expr>::const_iterator it = origVars.begin(), iend=origVars.end(); it!=iend; ++it) { if(boundVars.count(*it) > 0) quantVars.push_back(*it); } // If all variables are used, just return the original theorem if(quantVars.size() == origVars.size()) return t1; Proof pf; if(withProof()) { vector<Expr> es; vector<Proof> pfs; es.push_back(e); es.insert(es.end(), quantVars.begin(), quantVars.end()); pfs.push_back(t1.getProof()); pf= newPf("bound_variable_elimination", es, pfs); } if(quantVars.size() == 0) return(newTheorem(e.getBody(), t1.getAssumptionsRef(), pf)); Expr newQuantExpr; if(e.isForall()) newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, quantVars, body); else newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(EXISTS, quantVars, body); return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); }
//!adjust the order of bound vars, newBvs begin first Theorem QuantTheoremProducer::adjustVarUniv(const Theorem& t1, const std::vector<Expr>& newBvs){ const Expr e=t1.getExpr(); const Expr body = e.getBody(); if(CHECK_PROOFS) { CHECK_SOUND(e.isForall(), "adjustVarUniv: " +e.toString()); } const vector<Expr>& origVars = e.getVars(); ExprMap<bool> oldmap; for(vector<Expr>::const_iterator it = origVars.begin(), iend=origVars.end(); it!=iend; ++it) { oldmap[*it]=true; } vector<Expr> quantVars; for(vector<Expr>::const_iterator it = newBvs.begin(), iend=newBvs.end(); it!=iend; ++it) { if(oldmap.count(*it) > 0) quantVars.push_back(*it); } if(quantVars.size() == origVars.size()) return t1; ExprMap<bool> newmap; for(vector<Expr>::const_iterator it = newBvs.begin(), iend=newBvs.end(); it!=iend; ++it) { newmap[*it]=true; } for(vector<Expr>::const_iterator it = origVars.begin(), iend=origVars.end(); it!=iend; ++it) { if(newmap.count(*it)<=0){ quantVars.push_back(*it); }; } Proof pf; if(withProof()) { vector<Expr> es; vector<Proof> pfs; es.push_back(e); es.insert(es.end(), quantVars.begin(), quantVars.end()); pfs.push_back(t1.getProof()); pf= newPf("adjustVarUniv", es, pfs); } Expr newQuantExpr; newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, quantVars, body); return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); }
//!pack (forall (x) forall (y)) into (forall (x y)) Theorem QuantTheoremProducer::packVar(const Theorem& t1){ Expr out_forall =t1.getExpr(); if(CHECK_PROOFS) { CHECK_SOUND(out_forall.isForall(), "packVar: " +out_forall.toString()); } vector<Expr> bVars = out_forall.getVars(); if(!out_forall.getBody().isForall()){ return t1; } Expr cur_body = out_forall.getBody(); while(cur_body.isForall()){ vector<Expr> bVarsLeft = cur_body.getVars(); for(vector<Expr>::iterator i=bVarsLeft.begin(), iend=bVarsLeft.end(); i!=iend; i++){ bVars.push_back(*i); } cur_body=cur_body.getBody(); } Proof pf; if(withProof()) { vector<Expr> es; vector<Proof> pfs; es.push_back(out_forall); es.insert(es.end(), bVars.begin(), bVars.end()); pfs.push_back(t1.getProof()); pf= newPf("packVar", es, pfs); } Expr newQuantExpr; newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, bVars, cur_body); return (newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); // return (newRWTheorem(t1,newQuantExpr, t1.getAssumptionsRef(), pf)); }
//! convert (forall (x) ... forall (y)) into (forall (x y)...) //! convert (exists (x) ... exists (y)) into (exists (x y)...) Theorem QuantTheoremProducer::pullVarOut(const Theorem& t1){ const Expr thm_expr=t1.getExpr(); if(CHECK_PROOFS) { CHECK_SOUND(thm_expr.isForall() || thm_expr.isExists(), "pullVarOut: " +thm_expr.toString()); } const Expr outBody = thm_expr.getBody(); // if(((outBody.isAnd() && outBody[1].isForall()) || // (outBody.isImpl() && outBody[1].isForall()) || // (outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists()) )){ // return t1; // } if (thm_expr.isForall()){ if((outBody.isNot() && outBody[0].isAnd() && outBody[0][1].isExists())){ vector<Expr> bVarsOut = thm_expr.getVars(); const Expr innerExists =outBody[0][1]; const Expr innerBody = innerExists.getBody(); vector<Expr> bVarsIn = innerExists.getVars(); for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){ bVarsOut.push_back(*i); } Proof pf; if(withProof()) { vector<Expr> es; vector<Proof> pfs; es.push_back(thm_expr); es.insert(es.end(), bVarsIn.begin(), bVarsIn.end()); pfs.push_back(t1.getProof()); pf= newPf("pullVarOut", es, pfs); } Expr newbody; newbody=(outBody[0][0].notExpr()).orExpr(innerBody.notExpr()); Expr newQuantExpr; newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, bVarsOut, newbody); return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); } else if ((outBody.isAnd() && outBody[1].isForall()) || (outBody.isImpl() && outBody[1].isForall())){ vector<Expr> bVarsOut = thm_expr.getVars(); const Expr innerForall=outBody[1]; const Expr innerBody = innerForall.getBody(); vector<Expr> bVarsIn = innerForall.getVars(); for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){ bVarsOut.push_back(*i); } Proof pf; if(withProof()) { vector<Expr> es; vector<Proof> pfs; es.push_back(thm_expr); es.insert(es.end(), bVarsIn.begin(), bVarsIn.end()); pfs.push_back(t1.getProof()); pf= newPf("pullVarOut", es, pfs); } Expr newbody; if(outBody.isAnd()){ newbody=outBody[0].andExpr(innerBody); } else if(outBody.isImpl()){ newbody=outBody[0].impExpr(innerBody); } Expr newQuantExpr; newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, bVarsOut, newbody); return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); } return t1; // case cannot be handled now. } else if (thm_expr.isExists()){ if ((outBody.isAnd() && outBody[1].isExists()) || (outBody.isImpl() && outBody[1].isExists())){ vector<Expr> bVarsOut = thm_expr.getVars(); const Expr innerExists = outBody[1]; const Expr innerBody = innerExists.getBody(); vector<Expr> bVarsIn = innerExists.getVars(); for(vector<Expr>::iterator i=bVarsIn.begin(), iend=bVarsIn.end(); i!=iend; i++){ bVarsOut.push_back(*i); } Proof pf; if(withProof()) { vector<Expr> es; vector<Proof> pfs; es.push_back(thm_expr); es.insert(es.end(), bVarsIn.begin(), bVarsIn.end()); pfs.push_back(t1.getProof()); pf= newPf("pullVarOut", es, pfs); } Expr newbody; if(outBody.isAnd()){ newbody=outBody[0].andExpr(innerBody); } else if(outBody.isImpl()){ newbody=outBody[0].impExpr(innerBody); } Expr newQuantExpr; newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(EXISTS, bVarsOut, newbody); return(newTheorem(newQuantExpr, t1.getAssumptionsRef(), pf)); } } return t1; }
Theorem QuantTheoremProducer::partialUniversalInst(const Theorem& t1, const vector<Expr>& terms, int quantLevel){ cout<<"error in partial inst" << endl; Expr e = t1.getExpr(); const vector<Expr>& boundVars = e.getVars(); if(CHECK_PROOFS) { CHECK_SOUND(boundVars.size() >= terms.size(), "Universal instantiation: size of terms array does " "not match quanitfied variables array size"); CHECK_SOUND(e.isForall(), "universal instantiation: expr must be FORALL:\n" +e.toString()); for(unsigned int i=0; i<terms.size(); i++){ CHECK_SOUND(d_theoryQuant->getBaseType(boundVars[i]) == d_theoryQuant->getBaseType(terms[i]), "partial Universal instantiation: type mismatch"); } } //build up a conjunction of type predicates for expression Expr tr = e.getEM()->trueExpr(); Expr typePred = tr; for(unsigned int i=0; i<terms.size(); i++) { Expr p = d_theoryQuant->getTypePred(boundVars[i].getType(),terms[i]); if(p!=tr) { if(typePred==tr) typePred = p; else typePred = typePred.andExpr(p); } } Proof pf; if(withProof()) { vector<Proof> pfs; vector<Expr> es; pfs.push_back(t1.getProof()); es.push_back(e); es.insert(es.end(), terms.begin(), terms.end()); pf= newPf("partial_universal_instantiation", es, pfs); } if(terms.size() == boundVars.size()){ Expr inst = e.getBody().substExpr(e.getVars(), terms); Expr imp; if(typePred == tr) imp = inst; else imp = typePred.impExpr(inst); return(newTheorem(imp, t1.getAssumptionsRef(), pf)); } else{ vector<Expr> newBoundVars; for(size_t i=0; i<terms.size(); i++) { newBoundVars.push_back(boundVars[i]); } vector<Expr>leftBoundVars; for(size_t i=terms.size(); i<boundVars.size(); i++) { leftBoundVars.push_back(boundVars[i]); } Expr tempinst = e.getBody().substExpr(newBoundVars, terms); Expr inst = d_theoryQuant->getEM()->newClosureExpr(FORALL, leftBoundVars, tempinst); Expr imp; if(typePred == tr) imp = inst; else imp = typePred.impExpr(inst); Theorem res = (newTheorem(imp, t1.getAssumptionsRef(), pf)); int thmLevel = t1.getQuantLevel(); if(quantLevel >= thmLevel) { res.setQuantLevel(quantLevel+1); } else{ //k ret.setQuantLevel(thmLevel+1); res.setQuantLevel(thmLevel); } return res; } }
Theorem QuantTheoremProducer::universalInst(const Theorem& t1, const vector<Expr>& terms){ Expr e = t1.getExpr(); const vector<Expr>& boundVars = e.getVars(); if(CHECK_PROOFS) { CHECK_SOUND(boundVars.size() == terms.size(), "Universal instantiation: size of terms array does " "not match quanitfied variables array size"); CHECK_SOUND(e.isForall(), "universal instantiation: expr must be FORALL:\n" +e.toString()); for(unsigned int i=0; i<terms.size(); i++) CHECK_SOUND(d_theoryQuant->getBaseType(boundVars[i]) == d_theoryQuant->getBaseType(terms[i]), "Universal instantiation: type mismatch"); } //build up a conjunction of type predicates for expression Expr tr = e.getEM()->trueExpr(); Expr typePred = tr; unsigned qlevel=0, qlevelMax = 0; for(unsigned int i=0; i<terms.size(); i++) { Expr p = d_theoryQuant->getTypePred(boundVars[i].getType(),terms[i]); if(p!=tr) { if(typePred==tr) typePred = p; else typePred = typePred.andExpr(p); } qlevel = d_theoryQuant->theoryCore()->getQuantLevelForTerm(terms[i]); if (qlevel > qlevelMax) qlevel = qlevelMax; } Expr inst = e.getBody().substExpr(e.getVars(), terms); // Expr inst = e.getBody().substExprQuant(e.getVars(), terms); // Expr inst = e.getBody().substExpr(e.getVars(), terms); Proof pf; if(withProof()) { vector<Proof> pfs; vector<Expr> es; pfs.push_back(t1.getProof()); es.push_back(e); es.push_back(Expr(RAW_LIST,terms)); // es.insert(es.end(), terms.begin(), terms.end()); es.push_back(inst); pf= newPf("universal_elimination3", es, pfs); } // Expr inst = e.getBody().substExpr(e.getVars(), terms); Expr imp; if( typePred == tr ) //just for easy life, yeting, change this asap imp = inst; else imp = typePred.impExpr(inst); Theorem ret = newTheorem(imp, t1.getAssumptionsRef(), pf); unsigned thmLevel = t1.getQuantLevel(); if(qlevel >= thmLevel) { ret.setQuantLevel(qlevel+1); } else{ // ret.setQuantLevel(thmLevel+1); ret.setQuantLevel(thmLevel+1); } // ret.setQuantLevel(qlevel+1); return ret; }