Skip to content
Snippets Groups Projects
Commit 4ab5205a authored by Nicolas Voirol's avatar Nicolas Voirol
Browse files

More fixes in lambda normalization

parent 5212f885
No related branches found
No related tags found
No related merge requests found
...@@ -116,7 +116,7 @@ trait SymbolOps { self: TypeOps => ...@@ -116,7 +116,7 @@ trait SymbolOps { self: TypeOps =>
val remainingIds: MutableMap[Type, List[Identifier]] = MutableMap.empty ++ typedIds.toMap val remainingIds: MutableMap[Type, List[Identifier]] = MutableMap.empty ++ typedIds.toMap
def getId(e: Expr): Identifier = { def getId(e: Expr): Identifier = {
val tpe = bestRealType(e.getType) val tpe = e.getType
val newId = remainingIds.get(tpe) match { val newId = remainingIds.get(tpe) match {
case Some(x :: xs) => case Some(x :: xs) =>
remainingIds += tpe -> xs remainingIds += tpe -> xs
......
...@@ -55,7 +55,6 @@ trait LambdaTemplates { self: Templates => ...@@ -55,7 +55,6 @@ trait LambdaTemplates { self: Templates =>
ids: (Variable, Encoded), ids: (Variable, Encoded),
pathVar: (Variable, Encoded), pathVar: (Variable, Encoded),
arguments: Seq[(Variable, Encoded)], arguments: Seq[(Variable, Encoded)],
closures: Seq[(Variable, Encoded)],
condVars: Map[Variable, Encoded], condVars: Map[Variable, Encoded],
exprVars: Map[Variable, Encoded], exprVars: Map[Variable, Encoded],
condTree: Map[Variable, Set[Variable]], condTree: Map[Variable, Set[Variable]],
...@@ -72,14 +71,14 @@ trait LambdaTemplates { self: Templates => ...@@ -72,14 +71,14 @@ trait LambdaTemplates { self: Templates =>
val tpe = ids._1.getType.asInstanceOf[FunctionType] val tpe = ids._1.getType.asInstanceOf[FunctionType]
val (clauses, blockers, applications, matchers, templateString) = val (clauses, blockers, applications, matchers, templateString) =
Template.encode(pathVar, arguments, condVars, exprVars, guardedExprs, equations, Template.encode(pathVar, arguments, condVars, exprVars, guardedExprs, equations,
lambdas, quantifications, substMap = baseSubstMap + ids ++ closures, optApp = Some(id -> tpe)) lambdas, quantifications, substMap = baseSubstMap + ids, optApp = Some(id -> tpe))
val lambdaString : () => String = () => { val lambdaString : () => String = () => {
"Template for lambda " + ids._1 + ": " + lambda + " is :\n" + templateString() "Template for lambda " + ids._1 + ": " + lambda + " is :\n" + templateString()
} }
new LambdaTemplate( new LambdaTemplate(
ids, pathVar, arguments, closures, ids, pathVar, arguments,
condVars, exprVars, condTree, condVars, exprVars, condTree,
clauses, blockers, applications, matchers, clauses, blockers, applications, matchers,
lambdas, quantifications, lambdas, quantifications,
...@@ -201,7 +200,6 @@ trait LambdaTemplates { self: Templates => ...@@ -201,7 +200,6 @@ trait LambdaTemplates { self: Templates =>
val ids: (Variable, Encoded), val ids: (Variable, Encoded),
val pathVar: (Variable, Encoded), val pathVar: (Variable, Encoded),
val arguments: Seq[(Variable, Encoded)], val arguments: Seq[(Variable, Encoded)],
val closures: Seq[(Variable, Encoded)],
val condVars: Map[Variable, Encoded], val condVars: Map[Variable, Encoded],
val exprVars: Map[Variable, Encoded], val exprVars: Map[Variable, Encoded],
val condTree: Map[Variable, Set[Variable]], val condTree: Map[Variable, Set[Variable]],
...@@ -222,7 +220,7 @@ trait LambdaTemplates { self: Templates => ...@@ -222,7 +220,7 @@ trait LambdaTemplates { self: Templates =>
def substitute(substituter: Encoded => Encoded, msubst: Map[Encoded, Matcher]): LambdaTemplate = new LambdaTemplate( def substitute(substituter: Encoded => Encoded, msubst: Map[Encoded, Matcher]): LambdaTemplate = new LambdaTemplate(
ids._1 -> substituter(ids._2), ids._1 -> substituter(ids._2),
pathVar._1 -> substituter(pathVar._2), pathVar._1 -> substituter(pathVar._2),
arguments, closures, condVars, exprVars, condTree, arguments, condVars, exprVars, condTree,
clauses.map(substituter), clauses.map(substituter),
blockers.map { case (b, fis) => substituter(b) -> fis.map(_.substitute(substituter, msubst)) }, blockers.map { case (b, fis) => substituter(b) -> fis.map(_.substitute(substituter, msubst)) },
applications.map { case (b, apps) => substituter(b) -> apps.map(_.substitute(substituter, msubst)) }, applications.map { case (b, apps) => substituter(b) -> apps.map(_.substitute(substituter, msubst)) },
...@@ -235,10 +233,10 @@ trait LambdaTemplates { self: Templates => ...@@ -235,10 +233,10 @@ trait LambdaTemplates { self: Templates =>
/** This must be called right before returning the clauses in [[structure.instantiation]]! */ /** This must be called right before returning the clauses in [[structure.instantiation]]! */
def concretize(idT: Encoded): LambdaTemplate = { def concretize(idT: Encoded): LambdaTemplate = {
assert(!isConcrete, "Can't concretize concrete lambda template") assert(!isConcrete, "Can't concretize concrete lambda template")
val substituter = mkSubstituter(Map(ids._2 -> idT) ++ (closures.map(_._2) zip structure.locals.map(_._2))) val substituter = mkSubstituter(Map(ids._2 -> idT))
new LambdaTemplate( new LambdaTemplate(
ids._1 -> idT, ids._1 -> idT,
pathVar, arguments, closures, condVars, exprVars, condTree, pathVar, arguments, condVars, exprVars, condTree,
clauses map substituter, clauses map substituter,
blockers.map { case (b, fis) => b -> fis.map(_.substitute(substituter, Map.empty)) }, blockers.map { case (b, fis) => b -> fis.map(_.substitute(substituter, Map.empty)) },
applications.map { case (b, apps) => b -> apps.map(_.substitute(substituter, Map.empty)) }, applications.map { case (b, apps) => b -> apps.map(_.substitute(substituter, Map.empty)) },
......
...@@ -278,21 +278,16 @@ trait TemplateGenerator { self: Templates => ...@@ -278,21 +278,16 @@ trait TemplateGenerator { self: Templates =>
val (struct, deps) = normalizeStructure(l) val (struct, deps) = normalizeStructure(l)
val sortedDeps = deps.toSeq.sortBy(_._1.id.uniqueName) val sortedDeps = deps.toSeq.sortBy(_._1.id.uniqueName)
val idDeps = sortedDeps.map(_._1)
val trDeps = idDeps.map(id => encodeSymbol(id))
val lid = Variable(FreshIdentifier("lambda", true), bestRealType(l.getType)) val depsByScope: Seq[(Variable, Expr)] = {
val clauses = liftedEquals(lid, struct, idArgs, inlineFirst = true) def rec(v: Variable): Seq[Variable] =
(exprOps.variablesOf(deps(v)) & deps.keySet).toSeq.flatMap(rec) :+ v
deps.keys.toSeq.flatMap(rec).distinct.map(v => v -> deps(v))
}
val localSubst: Map[Variable, Encoded] = substMap ++ condVars ++ exprVars ++ lambdaVars val localSubst: Map[Variable, Encoded] = substMap ++ condVars ++ exprVars ++ lambdaVars
val clauseSubst: Map[Variable, Encoded] = localSubst ++ (idArgs zip trArgs) ++ (idDeps zip trDeps)
val (lambdaConds, lambdaExprs, lambdaTree, lambdaGuarded, lambdaEqs, lambdaTemplates, lambdaQuants) =
clauses.foldLeft(emptyClauses)((clsSet, cls) => clsSet ++ mkClauses(pathVar, cls, clauseSubst))
val ids: (Variable, Encoded) = lid -> storeLambda(lid)
val (depSubst, (depConds, depExprs, depTree, depGuarded, depEqs, depLambdas, depQuants)) = val (depSubst, (depConds, depExprs, depTree, depGuarded, depEqs, depLambdas, depQuants)) =
sortedDeps.foldLeft[(Map[Variable, Encoded], TemplateClauses)](localSubst -> emptyClauses) { depsByScope.foldLeft[(Map[Variable, Encoded], TemplateClauses)](localSubst -> emptyClauses) {
case ((depSubst, clsSet), (v, expr)) => case ((depSubst, clsSet), (v, expr)) =>
if (!exprOps.isSimple(expr)) { if (!exprOps.isSimple(expr)) {
val (e, cls @ (_, _, _, _, _, lmbds, quants)) = mkExprClauses(pathVar, expr, depSubst) val (e, cls @ (_, _, _, _, _, lmbds, quants)) = mkExprClauses(pathVar, expr, depSubst)
...@@ -322,8 +317,36 @@ trait TemplateGenerator { self: Templates => ...@@ -322,8 +317,36 @@ trait TemplateGenerator { self: Templates =>
struct, dependencies, pathVar -> encodedCond(pathVar), depClosures, struct, dependencies, pathVar -> encodedCond(pathVar), depClosures,
depConds, depExprs, depTree, depClauses, depCalls, depApps, depMatchers, depLambdas, depQuants) depConds, depExprs, depTree, depClauses, depCalls, depApps, depMatchers, depLambdas, depQuants)
val isNormalForm: Boolean = {
def extractBody(e: Expr): (Seq[ValDef], Expr) = e match {
case Lambda(args, body) =>
val (nextArgs, nextBody) = extractBody(body)
(args ++ nextArgs, nextBody)
case _ => (Seq.empty, e)
}
extractBody(struct) match {
case (params, ApplicationExtractor(caller: Variable, args)) =>
(params.map(_.toVariable) == args) && (deps.get(caller) match {
case Some(_: Application | _: FunctionInvocation) => true
case _ => false
})
case _ => false
}
}
val realLambda = if (isNormalForm) l else struct
val lid = Variable(FreshIdentifier("lambda", true), bestRealType(l.getType))
val clauses = liftedEquals(lid, realLambda, idArgs, inlineFirst = true)
val clauseSubst: Map[Variable, Encoded] = depSubst ++ (idArgs zip trArgs)
val (lambdaConds, lambdaExprs, lambdaTree, lambdaGuarded, lambdaEqs, lambdaTemplates, lambdaQuants) =
clauses.foldLeft(emptyClauses)((clsSet, cls) => clsSet ++ mkClauses(pathVar, cls, clauseSubst))
val ids: (Variable, Encoded) = lid -> storeLambda(lid)
val template = LambdaTemplate(ids, pathVar -> encodedCond(pathVar), val template = LambdaTemplate(ids, pathVar -> encodedCond(pathVar),
idArgs zip trArgs, idDeps zip trDeps, lambdaConds, lambdaExprs, lambdaTree, idArgs zip trArgs, lambdaConds, lambdaExprs, lambdaTree,
lambdaGuarded, lambdaEqs, lambdaTemplates, lambdaQuants, structure, depSubst, l) lambdaGuarded, lambdaEqs, lambdaTemplates, lambdaQuants, structure, depSubst, l)
registerLambda(template) registerLambda(template)
lid lid
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment