PreprocessingPassResult HoElim::applyInternal(
AssertionPipeline* assertionsToPreprocess)
{
+ // this preprocessing pass is only applicable if we are eliminating
+ // higher-order, or are adding the store axiom
+ if (!options().quantifiers.hoElim && !options().quantifiers.hoElimStoreAx)
+ {
+ return PreprocessingPassResult::NO_CONFLICT;
+ }
// step [1]: apply lambda lifting to eliminate all lambdas
NodeManager* nm = NodeManager::currentNM();
std::vector<Node> axioms;
- std::map<Node, Node> newLambda;
- for (unsigned i = 0, size = assertionsToPreprocess->size(); i < size; ++i)
+ if (options().quantifiers.hoElim)
{
- Node prev = (*assertionsToPreprocess)[i];
- Node res = eliminateLambdaComplete(prev, newLambda);
- if (res != prev)
+ std::map<Node, Node> newLambda;
+ for (size_t i = 0, size = assertionsToPreprocess->size(); i < size; ++i)
{
- res = rewrite(res);
- Assert(!expr::hasFreeVar(res));
- assertionsToPreprocess->replace(i, res);
+ Node prev = (*assertionsToPreprocess)[i];
+ Node res = eliminateLambdaComplete(prev, newLambda);
+ if (res != prev)
+ {
+ res = rewrite(res);
+ Assert(!expr::hasFreeVar(res));
+ assertionsToPreprocess->replace(i, res);
+ }
}
- }
- // do lambda lifting on new lambda definitions
- // this will do fixed point to eliminate lambdas within lambda lifting axioms.
- while (!newLambda.empty())
- {
- std::map<Node, Node> lproc = newLambda;
- newLambda.clear();
- for (const std::pair<const Node, Node>& l : lproc)
+ // do lambda lifting on new lambda definitions
+ // this will do fixed point to eliminate lambdas within lambda lifting axioms.
+ while (!newLambda.empty())
{
- Node lambda = l.second;
- std::vector<Node> vars;
- std::vector<Node> nvars;
- for (const Node& v : lambda[0])
+ std::map<Node, Node> lproc = newLambda;
+ newLambda.clear();
+ for (const std::pair<const Node, Node>& l : lproc)
{
- Node bv = nm->mkBoundVar(v.getType());
- vars.push_back(v);
- nvars.push_back(bv);
- }
+ Node lambda = l.second;
+ std::vector<Node> vars;
+ std::vector<Node> nvars;
+ for (const Node& v : lambda[0])
+ {
+ Node bv = nm->mkBoundVar(v.getType());
+ vars.push_back(v);
+ nvars.push_back(bv);
+ }
- Node bd = lambda[1].substitute(
- vars.begin(), vars.end(), nvars.begin(), nvars.end());
- Node bvl = nm->mkNode(BOUND_VAR_LIST, nvars);
+ Node bd = lambda[1].substitute(
+ vars.begin(), vars.end(), nvars.begin(), nvars.end());
+ Node bvl = nm->mkNode(BOUND_VAR_LIST, nvars);
- nvars.insert(nvars.begin(), l.first);
- Node curr = nm->mkNode(APPLY_UF, nvars);
+ nvars.insert(nvars.begin(), l.first);
+ Node curr = nm->mkNode(APPLY_UF, nvars);
- Node llfax = nm->mkNode(FORALL, bvl, curr.eqNode(bd));
- Trace("ho-elim-ax") << "Lambda lifting axiom (pre-elim) " << llfax
- << " for " << lambda << std::endl;
- Assert(!expr::hasFreeVar(llfax));
- Node llfaxe = eliminateLambdaComplete(llfax, newLambda);
- Trace("ho-elim-ax") << "Lambda lifting axiom " << llfaxe << " for "
- << lambda << std::endl;
- axioms.push_back(llfaxe);
+ Node llfax = nm->mkNode(FORALL, bvl, curr.eqNode(bd));
+ Trace("ho-elim-ax") << "Lambda lifting axiom (pre-elim) " << llfax
+ << " for " << lambda << std::endl;
+ Assert(!expr::hasFreeVar(llfax));
+ Node llfaxe = eliminateLambdaComplete(llfax, newLambda);
+ Trace("ho-elim-ax") << "Lambda lifting axiom " << llfaxe << " for "
+ << lambda << std::endl;
+ axioms.push_back(llfaxe);
+ }
}
- }
- d_visited.clear();
- // add lambda lifting axioms as a conjunction to the first assertion
- if (!axioms.empty())
- {
- Node conj = nm->mkAnd(axioms);
- conj = rewrite(conj);
- Assert(!expr::hasFreeVar(conj));
- assertionsToPreprocess->conjoin(0, conj);
+ d_visited.clear();
+ // add lambda lifting axioms as a conjunction to the first assertion
+ if (!axioms.empty())
+ {
+ Node conj = nm->mkAnd(axioms);
+ conj = rewrite(conj);
+ Assert(!expr::hasFreeVar(conj));
+ assertionsToPreprocess->conjoin(0, conj);
+ }
+ axioms.clear();
}
- axioms.clear();
// step [2]: eliminate all higher-order constraints
for (unsigned i = 0, size = assertionsToPreprocess->size(); i < size; ++i)