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; }
bool TheoryArith::leavesAreNumConst(const Expr& e) { DebugAssert(e.isTerm() || (e.isPropAtom() && theoryOf(e) == this), "Expected term or arith prop atom"); if (e.validTerminalsConstFlag()) { return e.getTerminalsConstFlag(); } if (e.isRational()) { e.setTerminalsConstFlag(true); return true; } if (e.isAtomic() && isLeaf(e)) { e.setTerminalsConstFlag(false); return false; } DebugAssert(e.arity() > 0, "Expected non-zero arity"); int k = 0; if (e.isITE()) { k = 1; } for (; k < e.arity(); ++k) { if (!leavesAreNumConst(e[k])) { e.setTerminalsConstFlag(false); return false; } } e.setTerminalsConstFlag(true); return true; }