//!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));
}
Пример #2
0
Theorem CNF_Manager::replaceITErec(const Expr& e, Var v, bool translateOnly)
{
  // Quick exit for atomic expressions
  if (e.isAtomic()) return d_commonRules->reflexivityRule(e);

  // Check cache
  Theorem thm;
  bool foundInCache = false;
  ExprHashMap<Theorem>::iterator iMap = d_iteMap.find(e);
  if (iMap != d_iteMap.end()) {
    thm = (*iMap).second;
    foundInCache = true;
  }

  if (e.getKind() == ITE) {
    // Replace non-Bool ITE expressions
    DebugAssert(!e.getType().isBool(), "Expected non-Bool ITE");
    // generate e = x for new x
    if (!foundInCache) thm = d_commonRules->varIntroSkolem(e);
    Theorem thm2 = d_commonRules->symmetryRule(thm);
    thm2 = d_commonRules->iffMP(thm2, d_rules->ifLiftRule(thm2.getExpr(), 1));
    d_translateQueueVars.push_back(v);
    d_translateQueueThms.push_back(thm2);
    d_translateQueueFlags.push_back(translateOnly);
  }
  else {
    // Recursively traverse, replacing ITE's
    vector<Theorem> thms;
    vector<unsigned> changed;
    unsigned index = 0;
    Expr::iterator i, iend;
    if (foundInCache) {
      for(i = e.begin(), iend = e.end(); i!=iend; ++i, ++index) {
        replaceITErec(*i, v, translateOnly);
      }
    }
    else {
      for(i = e.begin(), iend = e.end(); i!=iend; ++i, ++index) {
        thm = replaceITErec(*i, v, translateOnly);
        if (!thm.isRefl()) {
          thms.push_back(thm);
          changed.push_back(index);
        }
      }
      if(changed.size() > 0) {
        thm = d_commonRules->substitutivityRule(e, changed, thms);
      }
      else thm = d_commonRules->reflexivityRule(e);
    }
  }

  // Update cache and return
  if (!foundInCache) d_iteMap[e] = thm;
  return thm;
}
/*! @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));
}
//!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));
}
Пример #5
0
Theorem TheoryArith::canonRec(const Expr& e)
{
  if (isLeaf(e)) return reflexivityRule(e);
  int ar = e.arity();
  if (ar > 0) {
    vector<Theorem> newChildrenThm;
    vector<unsigned> changed;
    for(int k = 0; k < ar; ++k) {
      // Recursively canonize the kids
      Theorem thm = canonRec(e[k]);
      if (thm.getLHS() != thm.getRHS()) {
	newChildrenThm.push_back(thm);
	changed.push_back(k);
      }
    }
    if(changed.size() > 0) {
      return canonThm(substitutivityRule(e, changed, newChildrenThm));
    }
  }
  return canon(e);
}
Пример #6
0
Lit CNF_Manager::translateExpr(const Theorem& thmIn, CNF_Formula& cnf)
{
  Lit l;
  Var v;
  Expr e = thmIn.getExpr();
  Theorem thm;
  bool translateOnly;

  Lit ret = translateExprRec(e, cnf, thmIn);

  while (d_translateQueueVars.size()) {
    v = d_translateQueueVars.front();
    d_translateQueueVars.pop_front();
    thm = d_translateQueueThms.front();
    d_translateQueueThms.pop_front();
    translateOnly = d_translateQueueFlags.front();
    d_translateQueueFlags.pop_front();
    l = translateExprRec(thm.getExpr(), cnf, thmIn);
    cnf.newClause();
    cnf.addLiteral(l);
    cnf.registerUnit();

    Theorem newThm = d_rules->CNFAddUnit(thm);
    //    d_theorems.insert(d_clauseIdNext, thm);
    //    cnf.getCurrentClause().setClauseTheorem(thmIn); // by yeting
    cnf.getCurrentClause().setClauseTheorem(newThm); // by yeting

    /*
    cout<<"set clause theorem 1" << thm << endl;
    cout<<"set clause theorem 2 " << thmIn << endl;
    cout<<"set clause print" ;  cnf.getCurrentClause().print() ; cout<<endl;
    cout<<"set clause id " << d_clauseIdNext << endl;
    */
    if (!translateOnly) d_varInfo[v].fanins.push_back(l);
    d_varInfo[l.getVar()].fanouts.push_back(v);
  }
  return ret;
}
Пример #7
0
Theorem TheoryArith::canonSimp(const Expr& e)
{
  DebugAssert(canonRec(e).getRHS() == e, "canonSimp expects input to be canonized");
  int ar = e.arity();
  if (isLeaf(e)) return find(e);
  if (ar > 0) {
    vector<Theorem> newChildrenThm;
    vector<unsigned> changed;
    Theorem thm;
    for (int k = 0; k < ar; ++k) {
      thm = canonSimp(e[k]);
      if (thm.getLHS() != thm.getRHS()) {
        newChildrenThm.push_back(thm);
        changed.push_back(k);
      }
    }
    if(changed.size() > 0) {
      thm = canonThm(substitutivityRule(e, changed, newChildrenThm));
      return transitivityRule(thm, find(thm.getRHS()));
    }
    else return find(e);
  }
  return find(e);
}
//! 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;
}
Пример #11
0
Lit CNF_Manager::translateExprRec(const Expr& e, CNF_Formula& cnf, const Theorem& thmIn)
{
  if (e.isFalse()) return Lit::getFalse();
  if (e.isTrue()) return Lit::getTrue();
  if (e.isNot()) return !translateExprRec(e[0], cnf, thmIn);

  ExprHashMap<Var>::iterator iMap = d_cnfVars.find(e);

  if (e.isTranslated()) {
    DebugAssert(iMap != d_cnfVars.end(), "Translated expr should be in map");
    return Lit((*iMap).second);
  }
  else e.setTranslated(d_bottomScope);

  Var v(int(d_varInfo.size()));
  bool translateOnly = false;

  if (iMap != d_cnfVars.end()) {
    v = (*iMap).second;
    translateOnly = true;
    d_varInfo[v].fanouts.clear();
  }
  else {
    d_varInfo.resize(v+1);
    d_varInfo.back().expr = e;
    d_cnfVars[e] = v;
  }

  Expr::iterator i, iend;
  bool isAnd = false;
  switch (e.getKind()) {
    case AND:
      isAnd = true;
    case OR: {
      vector<Lit> lits;
      unsigned idx;
      for (i = e.begin(), iend = e.end(); i != iend; ++i) {
        lits.push_back(translateExprRec(*i, cnf, thmIn));
      }

      //      DebugAssert(concreteExpr(e,Lit(v)) == e,"why here");

      for (idx = 0; idx < lits.size(); ++idx) {
        cnf.newClause();
        cnf.addLiteral(Lit(v),isAnd);
        cnf.addLiteral(lits[idx], !isAnd);
	
	//	DebugAssert(concreteExpr(e[idx],lits[idx]) == e[idx], "why here");

	std::string reasonStr = (isAnd ? "and_mid" : "or_mid");
	Expr after = e[idx] ;
	cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, after, reasonStr, idx)); // by yeting
      }

      cnf.newClause();
      cnf.addLiteral(Lit(v),!isAnd);
      for (idx = 0; idx < lits.size(); ++idx) {
        cnf.addLiteral(lits[idx], isAnd);
      }

      std::string reasonStr = (isAnd ? "and_final" : "or_final") ;   
      Expr after = e ;

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, after, reasonStr, 0)); // by yeting
      break;
    }
    case IMPLIES: {
      Lit arg0 = translateExprRec(e[0], cnf, thmIn);
      Lit arg1 = translateExprRec(e[1], cnf, thmIn);

      //      DebugAssert(concreteExpr(e, Lit(v)) == e, "why here");
      //      DebugAssert(concreteExpr(e[0], arg0) == e[0], "why here");
      //      DebugAssert(concreteExpr(e[1], arg1) == e[1], "why here");

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg0);

      cnf.getCurrentClause().setClauseTheorem( d_rules->CNFtranslate(e, e, "imp", 0)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg1,true);

      cnf.getCurrentClause().setClauseTheorem( d_rules->CNFtranslate(e, e, "imp", 1)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg0,true);
      cnf.addLiteral(arg1);

      cnf.getCurrentClause().setClauseTheorem( d_rules->CNFtranslate(e, e, "imp", 2)); // by yeting

      break;
    }
    case IFF: {
      Lit arg0 = translateExprRec(e[0], cnf, thmIn);
      Lit arg1 = translateExprRec(e[1], cnf, thmIn);

      //      DebugAssert(concreteExpr(e, Lit(v)) == e, "why here");
      //      DebugAssert(concreteExpr(e[0], arg0) == e[0], "why here");
      //      DebugAssert(concreteExpr(e[1], arg1) == e[1], "why here");

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg0);
      cnf.addLiteral(arg1);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "iff", 0)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg0,true);
      cnf.addLiteral(arg1,true);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "iff", 1)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg0,true);
      cnf.addLiteral(arg1);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "iff", 2)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg0);
      cnf.addLiteral(arg1,true);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "iff", 3)); // by yeting
      break;
    }
    case XOR: {

      Lit arg0 = translateExprRec(e[0], cnf, thmIn);
      Lit arg1 = translateExprRec(e[1], cnf, thmIn);

      //      DebugAssert(concreteExpr(e, Lit(v)) == e, "why here");
      //      DebugAssert(concreteExpr(e[0], arg0) == e[0], "why here");
      //      DebugAssert(concreteExpr(e[1], arg1) == e[1], "why here");


      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg0);
      cnf.addLiteral(arg1);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "xor", 0)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg0,true);
      cnf.addLiteral(arg1,true);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "xor", 1)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg0,true);
      cnf.addLiteral(arg1);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "xor", 2)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg0);
      cnf.addLiteral(arg1,true);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFtranslate(e, e, "xor", 3)); // by yeting
      break;
    }
    case ITE:
    {

      Lit arg0 = translateExprRec(e[0], cnf, thmIn);
      Lit arg1 = translateExprRec(e[1], cnf, thmIn);
      Lit arg2 = translateExprRec(e[2], cnf, thmIn);


      Expr aftere0 = concreteExpr(e[0], arg0);
      Expr aftere1 = concreteExpr(e[1], arg1);
      Expr aftere2 = concreteExpr(e[2], arg2);
      
      vector<Expr> after ;
      after.push_back(aftere0);
      after.push_back(aftere1);
      after.push_back(aftere2);
      
      Theorem e0thm;
      Theorem e1thm;
      Theorem e2thm;

      { e0thm = d_iteMap[e[0]];
	if (e0thm.isNull()) e0thm = d_commonRules->reflexivityRule(e[0]);
	e1thm = d_iteMap[e[1]];
	if (e1thm.isNull()) e1thm = d_commonRules->reflexivityRule(e[1]);
	e2thm = d_iteMap[e[2]];
	if (e2thm.isNull()) e2thm = d_commonRules->reflexivityRule(e[2]);
      }

      vector<Theorem> thms ;
      thms.push_back(e0thm);
      thms.push_back(e1thm);      
      thms.push_back(e2thm);

 

      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg0);
      cnf.addLiteral(arg2);
      
      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFITEtranslate(e, after,thms, 1)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg0);
      cnf.addLiteral(arg2,true);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFITEtranslate(e, after,thms, 2)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg0,true);
      cnf.addLiteral(arg1,true);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFITEtranslate(e, after,thms, 3)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg0,true);
      cnf.addLiteral(arg1);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFITEtranslate(e, after,thms, 4)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v));
      cnf.addLiteral(arg1,true);
      cnf.addLiteral(arg2,true);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFITEtranslate(e, after,thms, 5)); // by yeting

      cnf.newClause();
      cnf.addLiteral(Lit(v),true);
      cnf.addLiteral(arg1);
      cnf.addLiteral(arg2);

      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFITEtranslate(e, after,thms, 6)); // by yeting
      
      break;
    }
    default:
    {
      DebugAssert(!e.isAbsAtomicFormula() || d_varInfo[v].expr == e,
                  "Corrupted Varinfo");
      if (e.isAbsAtomicFormula()) {
        registerAtom(e, thmIn);
        return Lit(v);
      }

      Theorem thm = replaceITErec(e, v, translateOnly);
      const Expr& e2 = thm.getRHS();
      DebugAssert(e2.isAbsAtomicFormula(), "Expected AbsAtomicFormula");
      if (e2.isTranslated()) {
        // Ugly corner case: we happen to create an expression that has been
        // created before.  We remove the current variable and fix up the
        // translation stack.
        if (translateOnly) {
          DebugAssert(v == d_cnfVars[e2], "Expected literal match");
        }
        else {
          d_varInfo.resize(v);
          while (!d_translateQueueVars.empty() &&
                 d_translateQueueVars.back() == v) {
            d_translateQueueVars.pop_back();
          }
          DebugAssert(d_cnfVars.find(e2) != d_cnfVars.end(),
                      "Expected existing literal");
          v = d_cnfVars[e2];
          d_cnfVars[e] = v;
          while (d_translateQueueVars.size() < d_translateQueueThms.size()) {
            d_translateQueueVars.push_back(v);
          }
        }
      }
      else {
        e2.setTranslated(d_bottomScope);
        // Corner case: don't register reflexive equality
        if (!e2.isEq() || e2[0] != e2[1]) registerAtom(e2, thmIn);
        if (!translateOnly) {
          if (d_cnfVars.find(e2) == d_cnfVars.end()) {
            d_varInfo[v].expr = e2;
            d_cnfVars[e2] = v;
          }
          else {
            // Same corner case in an untranslated expr
            d_varInfo.resize(v);
            while (!d_translateQueueVars.empty() &&
                   d_translateQueueVars.back() == v) {
              d_translateQueueVars.pop_back();
            }
            v = d_cnfVars[e2];
            d_cnfVars[e] = v;
            while (d_translateQueueVars.size() < d_translateQueueThms.size()) {
              d_translateQueueVars.push_back(v);
            }
          }
        }
      }
      return Lit(v);
    }
  }

  // Record fanins / fanouts
  Lit l;
  for (i = e.begin(), iend = e.end(); i != iend; ++i) {
    l = getCNFLit(*i);
    DebugAssert(!l.isNull(), "Expected non-null literal");
    if (!translateOnly) d_varInfo[v].fanins.push_back(l);
    if (l.isVar()) d_varInfo[l.getVar()].fanouts.push_back(v);
  }
  return Lit(v);
}
Пример #12
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;
  }
}