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;

  }
}
Ejemplo n.º 3
0
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;
  }
}