Theorem QuantTheoremProducer::normalizeQuant(const Expr& quant) { if(CHECK_PROOFS) { CHECK_SOUND(quant.isForall()||quant.isExists(), "normalizeQuant: expr must be FORALL or EXISTS\n" +quant.toString()); } std::map<Expr,int>::iterator typeIter; std::string base("_BD"); int counter(0); vector<Expr> newVars; const std::vector<Expr>& cur_vars = quant.getVars(); for(size_t j =0; j<cur_vars.size(); j++){ Type t = cur_vars[j].getType(); int typeIndex ; typeIter = d_typeFound.find(t.getExpr()); if(d_typeFound.end() == typeIter){ typeIndex = d_typeFound.size(); d_typeFound[t.getExpr()] = typeIndex; } else{ typeIndex = typeIter->second; } counter++; std::stringstream stringType; stringType << counter << "TY" << typeIndex ; std::string out_str = base + stringType.str(); Expr newExpr = d_theoryQuant->getEM()->newBoundVarExpr(out_str, int2string(counter)); newExpr.setType(t); newVars.push_back(newExpr); } vector<vector<Expr> > trigs = quant.getTriggers(); for(size_t i = 0 ; i < trigs.size(); i++){ for(size_t j = 0 ; j < trigs[i].size(); j++){ trigs[i][j] = trigs[i][j].substExpr(cur_vars,newVars); } } Expr normBody = quant.getBody().substExpr(cur_vars,newVars); Expr normQuant = d_theoryQuant->getEM()->newClosureExpr(quant.isForall()?FORALL:EXISTS, newVars, normBody, trigs); Proof pf; if(withProof()) pf = newPf("normalizeQuant", quant, normQuant); return newRWTheorem(quant, normQuant, Assumptions::emptyAssump(), pf); }
/*! @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)); }
//! 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; }