Skip to content
Snippets Groups Projects
Commit 82c4e093 authored by Régis Blanc's avatar Régis Blanc
Browse files

change all function invocation to new fundef when parameters contain arrays

parent 48d91e36
No related branches found
No related tags found
No related merge requests found
...@@ -11,42 +11,45 @@ object ArrayTransformation extends Pass { ...@@ -11,42 +11,45 @@ object ArrayTransformation extends Pass {
def apply(pgm: Program): Program = { def apply(pgm: Program): Program = {
fd2fd = Map()
id2id = Map()
val allFuns = pgm.definedFunctions val allFuns = pgm.definedFunctions
val newFuns: Seq[Definition] = allFuns.map(fd => {
val newFuns: Seq[FunDef] = allFuns.map(fd => {
if(fd.hasImplementation) { if(fd.hasImplementation) {
val body = fd.body.get
id2id = Map()
val args = fd.args val args = fd.args
val newFd = if(args.exists(vd => containsArrayType(vd.tpe))) {
if(args.exists(vd => containsArrayType(vd.tpe))) { val newArgs = args.map(vd => {
println("args has array") val freshId = FreshIdentifier(vd.id.name).setType(TupleType(Seq(vd.tpe, Int32Type)))
val newArgs = args.map(vd => { id2id += (vd.id -> freshId)
val freshId = FreshIdentifier(vd.id.name).setType(TupleType(Seq(vd.tpe, Int32Type))) val newTpe = transform(vd.tpe)
id2id += (vd.id -> freshId) VarDecl(freshId, newTpe)
val newTpe = transform(vd.tpe) })
VarDecl(freshId, newTpe) val freshFunName = FreshIdentifier(fd.id.name)
}) val freshFunDef = new FunDef(freshFunName, fd.returnType, newArgs)
val freshFunName = FreshIdentifier(fd.id.name) freshFunDef.fromLoop = fd.fromLoop
val freshFunDef = new FunDef(freshFunName, fd.returnType, newArgs) freshFunDef.parent = fd.parent
freshFunDef.fromLoop = fd.fromLoop freshFunDef.precondition = fd.precondition
freshFunDef.parent = fd.parent freshFunDef.postcondition = fd.postcondition
freshFunDef.precondition = fd.precondition freshFunDef.addAnnotation(fd.annotations.toSeq:_*)
freshFunDef.postcondition = fd.postcondition fd2fd += (fd -> freshFunDef)
freshFunDef.addAnnotation(fd.annotations.toSeq:_*) freshFunDef
freshFunDef } else fd
} else fd
val newBody = transform(body)
newFd.body = Some(newBody)
newFd
} else fd } else fd
}) })
println(newFuns)
allFuns.zip(newFuns).foreach{ case (ofd, nfd) => ofd.body.map(body => {
val newBody = transform(body)
nfd.body = Some(newBody)
})}
val Program(id, ObjectDef(objId, _, invariants)) = pgm val Program(id, ObjectDef(objId, _, invariants)) = pgm
val allClasses: Seq[Definition] = pgm.definedClasses val allClasses: Seq[Definition] = pgm.definedClasses
Program(id, ObjectDef(objId, allClasses ++ newFuns, invariants)) Program(id, ObjectDef(objId, allClasses ++ newFuns, invariants))
} }
private var id2id: Map[Identifier, Identifier] = Map()
private def transform(tpe: TypeTree): TypeTree = tpe match { private def transform(tpe: TypeTree): TypeTree = tpe match {
case ArrayType(base) => TupleType(Seq(ArrayType(transform(base)), Int32Type)) case ArrayType(base) => TupleType(Seq(ArrayType(transform(base)), Int32Type))
...@@ -59,6 +62,8 @@ object ArrayTransformation extends Pass { ...@@ -59,6 +62,8 @@ object ArrayTransformation extends Pass {
case t => false case t => false
} }
private var id2id: Map[Identifier, Identifier] = Map()
private var fd2fd: Map[FunDef, FunDef] = Map()
private def transform(expr: Expr): Expr = expr match { private def transform(expr: Expr): Expr = expr match {
case fill@ArrayFill(length, default) => { case fill@ArrayFill(length, default) => {
...@@ -139,8 +144,40 @@ object ArrayTransformation extends Pass { ...@@ -139,8 +144,40 @@ object ArrayTransformation extends Pass {
val tpe = csesRec.head.rhs.getType val tpe = csesRec.head.rhs.getType
MatchExpr(scrutRec, csesRec).setType(tpe).setPosInfo(m) MatchExpr(scrutRec, csesRec).setType(tpe).setPosInfo(m)
} }
case LetDef(fd, b) => {
//case LetDef(fd, b) => val newFd = if(fd.hasImplementation) {
val body = fd.body.get
val args = fd.args
val newFd =
if(args.exists(vd => containsArrayType(vd.tpe))) {
val newArgs = args.map(vd => {
val freshId = FreshIdentifier(vd.id.name).setType(TupleType(Seq(vd.tpe, Int32Type)))
id2id += (vd.id -> freshId)
val newTpe = transform(vd.tpe)
VarDecl(freshId, newTpe)
})
val freshFunName = FreshIdentifier(fd.id.name)
val freshFunDef = new FunDef(freshFunName, fd.returnType, newArgs)
freshFunDef.fromLoop = fd.fromLoop
freshFunDef.parent = fd.parent
freshFunDef.precondition = fd.precondition
freshFunDef.postcondition = fd.postcondition
freshFunDef.addAnnotation(fd.annotations.toSeq:_*)
fd2fd += (fd -> freshFunDef)
freshFunDef
} else fd
val newBody = transform(body)
newFd.body = Some(newBody)
newFd
} else fd
val rb = transform(b)
LetDef(newFd, rb)
}
case FunctionInvocation(fd, args) => {
val rargs = args.map(transform)
val rfd = fd2fd.get(fd).getOrElse(fd)
FunctionInvocation(rfd, rargs)
}
case n @ NAryOperator(args, recons) => recons(args.map(transform)).setType(n.getType) case n @ NAryOperator(args, recons) => recons(args.map(transform)).setType(n.getType)
case b @ BinaryOperator(a1, a2, recons) => recons(transform(a1), transform(a2)).setType(b.getType) case b @ BinaryOperator(a1, a2, recons) => recons(transform(a1), transform(a2)).setType(b.getType)
......
import leon.Utils._
object Array4 {
def foo(a: Array[Int]): Int = {
var i = 0
var sum = 0
(while(i < a.length) {
sum = sum + a(i)
i = i + 1
}) invariant(i >= 0)
sum
}
def bar(): Int = {
val a = Array.fill(5)(5)
foo(a)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment