Skip to content
Snippets Groups Projects
Commit 69f84164 authored by Manos Koukoutos's avatar Manos Koukoutos
Browse files

EpsilonElimination should create FunDefs with all binders in scope as params

parent 676dea74
No related branches found
No related tags found
No related merge requests found
...@@ -306,8 +306,40 @@ object ExprOps { ...@@ -306,8 +306,40 @@ object ExprOps {
})(expr) })(expr)
} }
def preTransformWithBinders(f: (Expr, Set[Identifier]) => Expr, initBinders: Set[Identifier] = Set())(e: Expr) = {
import xlang.Expressions.LetVar
def rec(binders: Set[Identifier], e: Expr): Expr = (f(e, binders) match {
case LetDef(fd, bd) =>
fd.fullBody = rec(binders ++ fd.paramIds, fd.fullBody)
LetDef(fd, rec(binders, bd))
case Let(i, v, b) =>
Let(i, rec(binders + i, v), rec(binders + i, b))
case LetVar(i, v, b) =>
LetVar(i, rec(binders + i, v), rec(binders + i, b))
case MatchExpr(scrut, cses) =>
MatchExpr(rec(binders, scrut), cses map { case MatchCase(pat, og, rhs) =>
val newBs = binders ++ pat.binders
MatchCase(pat, og map (rec(newBs, _)), rec(newBs, rhs))
})
case Passes(in, out, cses) =>
Passes(rec(binders, in), rec(binders, out), cses map { case MatchCase(pat, og, rhs) =>
val newBs = binders ++ pat.binders
MatchCase(pat, og map (rec(newBs, _)), rec(newBs, rhs))
})
case Lambda(args, bd) =>
Lambda(args, rec(binders ++ args.map(_.id), bd))
case Forall(args, bd) =>
Forall(args, rec(binders ++ args.map(_.id), bd))
case Operator(subs, builder) =>
builder(subs map (rec(binders, _)))
}).copiedFrom(e)
rec(initBinders, e)
}
/** Returns the set of identifiers in an expression */ /** Returns the set of identifiers in an expression */
def variablesOf(expr: Expr): Set[Identifier] = { def variablesOf(expr: Expr): Set[Identifier] = {
import leon.xlang.Expressions.LetVar
fold[Set[Identifier]] { fold[Set[Identifier]] {
case (e, subs) => case (e, subs) =>
val subvs = subs.flatten.toSet val subvs = subs.flatten.toSet
...@@ -315,6 +347,7 @@ object ExprOps { ...@@ -315,6 +347,7 @@ object ExprOps {
case Variable(i) => subvs + i case Variable(i) => subvs + i
case LetDef(fd, _) => subvs -- fd.params.map(_.id) case LetDef(fd, _) => subvs -- fd.params.map(_.id)
case Let(i, _, _) => subvs - i case Let(i, _, _) => subvs - i
case LetVar(i, _, _) => subvs - i
case MatchExpr(_, cses) => subvs -- cses.flatMap(_.pattern.binders) case MatchExpr(_, cses) => subvs -- cses.flatMap(_.pattern.binders)
case Passes(_, _, cses) => subvs -- cses.flatMap(_.pattern.binders) case Passes(_, _, cses) => subvs -- cses.flatMap(_.pattern.binders)
case Lambda(args, _) => subvs -- args.map(_.id) case Lambda(args, _) => subvs -- args.map(_.id)
......
...@@ -16,24 +16,24 @@ object EpsilonElimination extends UnitPhase[Program] { ...@@ -16,24 +16,24 @@ object EpsilonElimination extends UnitPhase[Program] {
def apply(ctx: LeonContext, pgm: Program) = { def apply(ctx: LeonContext, pgm: Program) = {
for { for (fd <- pgm.definedFunctions) {
fd <- pgm.definedFunctions fd.fullBody = preTransformWithBinders({
body <- fd.body case (eps@Epsilon(pred, tpe), binders) =>
} { val freshName = FreshIdentifier("epsilon")
val newBody = postMap{ val bSeq = binders.toSeq
case eps@Epsilon(pred, tpe) => val freshParams = bSeq.map { _.freshen }
val freshName = FreshIdentifier("epsilon") val newFunDef = new FunDef(freshName, Nil, tpe, freshParams map (ValDef(_)))
val newFunDef = new FunDef(freshName, Nil, tpe, Seq()) val epsilonVar = EpsilonVariable(eps.getPos, tpe)
val epsilonVar = EpsilonVariable(eps.getPos, tpe) val resId = FreshIdentifier("res", tpe)
val resId = FreshIdentifier("res", tpe) val eMap: Map[Expr, Expr] = bSeq.zip(freshParams).map {
val postcondition = replace(Map(epsilonVar -> Variable(resId)), pred) case (from, to) => (Variable(from), Variable(to))
}.toMap ++ Seq((epsilonVar, Variable(resId)))
val postcondition = replace(eMap, pred)
newFunDef.postcondition = Some(Lambda(Seq(ValDef(resId)), postcondition)) newFunDef.postcondition = Some(Lambda(Seq(ValDef(resId)), postcondition))
Some(LetDef(newFunDef, FunctionInvocation(newFunDef.typed, Seq()))) LetDef(newFunDef, FunctionInvocation(newFunDef.typed, bSeq map Variable))
case _ => case (other, _) => other
None }, fd.paramIds.toSet)(fd.fullBody)
}(body)
fd.body = Some(newBody)
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment