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; }
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; } }
void TheoryUF::assertFact(const Theorem& e) { const Expr& expr = e.getExpr(); switch (expr.getKind()) { case NOT: break; case APPLY: if (expr.getOpExpr().computeTransClosure()) { enqueueFact(d_rules->relToClosure(e)); } else if (expr.getOpKind() == TRANS_CLOSURE) { // const Expr& rel = expr.getFun(); DebugAssert(expr.isApply(), "Should be apply"); Expr rel = resolveID(expr.getOpExpr().getName()); DebugAssert(!rel.isNull(), "Expected known identifier"); DebugAssert(rel.isSymbol() && rel.getKind()==UFUNC && expr.arity()==2, "Unexpected use of transitive closure: "+expr.toString()); // Insert into transitive closure table ExprMap<TCMapPair*>::iterator i = d_transClosureMap.find(rel); TCMapPair* pTable; if (i == d_transClosureMap.end()) { pTable = new TCMapPair(); d_transClosureMap[rel] = pTable; } else { pTable = (*i).second; } ExprMap<CDList<Theorem>*>::iterator i2 = pTable->appearsFirstMap.find(expr[0]); CDList<Theorem>* pList; if (i2 == pTable->appearsFirstMap.end()) { pList = new(true) CDList<Theorem>(theoryCore()->getCM()->getCurrentContext()); pTable->appearsFirstMap[expr[0]] = pList; } else { pList = (*i2).second; } pList->push_back(e); i2 = pTable->appearsSecondMap.find(expr[1]); if (i2 == pTable->appearsSecondMap.end()) { pList = new(true) CDList<Theorem>(theoryCore()->getCM()->getCurrentContext()); pTable->appearsSecondMap[expr[1]] = pList; } else { pList = (*i2).second; } pList->push_back(e); // Compute transitive closure with existing relations size_t s,l; i2 = pTable->appearsFirstMap.find(expr[1]); if (i2 != pTable->appearsFirstMap.end()) { pList = (*i2).second; s = pList->size(); for (l = 0; l < s; ++l) { enqueueFact(d_rules->relTrans(e,(*pList)[l])); } } i2 = pTable->appearsSecondMap.find(expr[0]); if (i2 != pTable->appearsSecondMap.end()) { pList = (*i2).second; s = pList->size(); for (l = 0; l < s; ++l) { enqueueFact(d_rules->relTrans((*pList)[l],e)); } } } break; default: break; } }