Esempio n. 1
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;
}
// For debugging: there are missing cases: user-defined types, symbols inside of quantifiers, etc.
void VCCmd::printSymbols(Expr e, ExprMap<bool>& cache)
{
  if (cache.find(e) != cache.end()) return;
  switch (e.getKind()) {
    case SKOLEM_VAR:
    case UCONST: {
      cout << e << " : ";
      ExprStream os(d_vc->getEM());
      os.dagFlag(false);
      os << e.getType().getExpr();
      cout << ";" << endl;
      break;
    }
    case APPLY: {
      Expr op = e.getOpExpr();
      if ((op.getKind() == UFUNC) && (cache.find(op) == cache.end())) {
        cout << op << " : ";
        ExprStream os(d_vc->getEM());
        os.dagFlag(false);
        os << op.getType().getExpr();
        cout << ";" << endl;
        cache[op] = true;
      }
      // fall through
    }
    default: {
      Expr::iterator i = e.begin(), iend = e.end();
      for (; i != iend; ++i) {
        printSymbols(*i, cache);
      }
      break;
    }
  }
  cache[e] = true;
}
Esempio n. 3
0
void Tptp::checkLetBinding(const std::vector<Expr>& bvlist, Expr lhs, Expr rhs,
                           bool formula) {
  if (lhs.getKind() != CVC4::kind::APPLY_UF) {
    parseError("malformed let: LHS must be a flat function application");
  }
  const std::multiset<CVC4::Expr> vars{lhs.begin(), lhs.end()};
  if(formula && !lhs.getType().isBoolean()) {
    parseError("malformed let: LHS must be formula");
  }
  for (const CVC4::Expr& var : vars) {
    if (var.hasOperator()) {
      parseError("malformed let: LHS must be flat, illegal child: " +
                 var.toString());
    }
  }

  // ensure all let-bound variables appear on the LHS, and appear only once
  for (const Expr& bound_var : bvlist) {
    const size_t count = vars.count(bound_var);
    if (count == 0) {
      parseError(
          "malformed let: LHS must make use of all quantified variables, "
          "missing `" +
          bound_var.toString() + "'");
    } else if (count >= 2) {
      parseError("malformed let: LHS cannot use same bound variable twice: " +
                 bound_var.toString());
    }
  }
}
Esempio n. 4
0
void CNF_Manager::convertLemma(const Theorem& thm, CNF_Formula& cnf)
{
  DebugAssert(cnf.empty(), "Expected empty cnf");
  vector<Theorem> clauses;

  d_rules->learnedClauses(thm, clauses, false);
  
  vector<Theorem>::iterator i = clauses.begin(), iend = clauses.end();
  for (; i < iend; ++i) {
    // for dumping lemmas:
    //    cerr << "QUERY " << (*i).getExpr() << ";" << endl;
    cnf.newClause();
    Expr e = (*i).getExpr();
    if (!e.isOr()) {
      DebugAssert(!getCNFLit(e).isNull(), "Unknown literal");
      cnf.addLiteral(getCNFLit(e));
      cnf.registerUnit();
      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFAddUnit(*i));
    }
    else {
      Expr::iterator jend = e.end();
      for (Expr::iterator j = e.begin(); j != jend; ++j) {
        DebugAssert(!getCNFLit(*j).isNull(), "Unknown literal");
        cnf.addLiteral(getCNFLit(*j));
      }
      cnf.getCurrentClause().setClauseTheorem(d_rules->CNFConvert(e, *i));
    }
  }
}
Esempio n. 5
0
bool TheoryArith::recursiveCanonSimpCheck(const Expr& e)
{
  if (e.hasFind()) return true;
  if (e != canonSimp(e).getRHS()) return false;
  Expr::iterator i = e.begin(), iend = e.end();
  for (; i != iend; ++i)
    if (!recursiveCanonSimpCheck(*i)) return false;
  return true;
}
//! find all bound variables in e and maps them to true in boundVars
void QuantTheoremProducer::recFindBoundVars(const Expr& e,
		           ExprMap<bool> & boundVars, ExprMap<bool> &visited)
{
  if(visited.count(e)>0)
    return;
  else
    visited[e] = true;
  if(e.getKind() == BOUND_VAR)
    boundVars[e] = true;
  if(e.getKind() == EXISTS || e.getKind() == FORALL)
    recFindBoundVars(e.getBody(), boundVars, visited);
  for(Expr::iterator it = e.begin(); it!=e.end(); ++it)
    recFindBoundVars(*it, boundVars, visited);

}
Esempio n. 7
0
void prefixPrintGetValue(SmtEngine& smt, Expr e, int level = 0){
  for(int i = 0; i < level; ++i){ cout << '-'; }
  cout << "smt.getValue(" << e << ") -> " << smt.getValue(e) << endl;

  if(e.hasOperator()){
    prefixPrintGetValue(smt, e.getOperator(), level + 1);
  }

  for(Expr::const_iterator term_i = e.begin(), term_end = e.end();
      term_i != term_end; ++term_i)
  {
    Expr curr = *term_i;
    prefixPrintGetValue(smt, curr, level + 1);
  }
}
void VCCmd::findAxioms(const Expr& e,  ExprMap<bool>& skolemAxioms,
		       ExprMap<bool>& visited) {
  if(visited.count(e)>0)
    return;
  else visited[e] = true;
  if(e.isSkolem()) {
    skolemAxioms.insert(e.getExistential(), true);
    return;
  }
  if(e.isClosure()) {
    findAxioms(e.getBody(), skolemAxioms, visited);
  }
  if(e.arity()>0) {
    Expr::iterator end = e.end();
    for(Expr::iterator i = e.begin(); i!=end; ++i)
      findAxioms(*i, skolemAxioms, visited);
  }

}
Esempio n. 9
0
void BCPattern::matchAnchored(const Expr& pattern,
                              PC start, PC end, Result& result) {
  auto pos = pattern.begin();

  for (auto inst = start; inst != end; ) {
    // Detect a match.
    if (pos == pattern.end()) {
      result.m_start = start;
      result.m_end = inst;
      return;
    }

    auto const op = peek_op(inst);

    // Skip pattern-globally ignored opcodes.
    if (m_ignores.count(op)) {
      inst = next(inst);
      continue;
    }

    // Check for alternations whenever we fail to match.
    auto nomatch = [&] {
      if (!pos->hasAlt()) return result.erase();

      // Pop the capture if we made one.
      if (pos->shouldCapture()) {
        result.m_captures.pop_back();
      }

      for (auto const& atom : pos->getAlt()) {
        // Construct the full alternate pattern.
        auto alt = Expr { atom };
        alt.insert(alt.end(), std::next(pos), pattern.end());
        auto res = result;

        // Match on the alternate.
        matchAnchored(alt, inst, end, res);

        if (res.found()) {
          result = res;
          result.m_start = start;
          return;
        }
      }
      return result.erase();
    };

    // Capture the atom if desired.
    if (pos->shouldCapture()) {
      result.m_captures.push_back(inst);
    }

    // Check for shallow match.
    if (pos->op() != op) {
      return nomatch();
    }

    auto filter = pos->getFilter();

    // Check for deep match if desired.
    if (filter && !filter(inst, result.m_captures)) {
      return nomatch();
    }

    if ((pos->op() == Op::JmpZ || pos->op() == Op::JmpNZ)) {
      // Match the taken block, if there is one.
      auto off = instrJumpOffset(inst);
      assert(off);

      auto res = result;
      matchAnchored(pos->getTaken(), inst + *off, end, res);

      if (!res.found()) {
        return nomatch();
      }

      // Grab the captures.
      result.m_captures = res.m_captures;
    }

    if (pos->hasSeq()) {
      // Match the subsequence if we have one.
      auto res = result;
      matchAnchored(pos->getSeq(), next(inst), end, res);

      if (!res.found()) {
        return nomatch();
      }

      // Set the PC.
      result.m_captures = res.m_captures;
      inst = res.m_end;
    } else {
      // Step the PC.
      inst = next(inst);
    }

    // Step the pattern.
    ++pos;
  }

  // Detect a terminal match.
  if (pos == pattern.end()) {
    result.m_start = start;
    result.m_end = end;
  }
}
Esempio n. 10
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);
}