From 63dedf7113008454f30439b40348e5fb6b8e92ef Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Mon, 22 Jun 2015 18:09:23 +0200 Subject: [PATCH] Termination works with a fresh duplicated program The termination checker updates the functions it checks in place (it removes and adds post-conditions). We duplicate the program here to ensure that side-effects do not propagate to other parts (such as synthesis in the web-interface) --- .../scala/leon/termination/ComplexTerminationChecker.scala | 2 +- src/main/scala/leon/termination/ProcessingPipeline.scala | 2 +- src/main/scala/leon/termination/TerminationChecker.scala | 7 ++++++- src/main/scala/leon/termination/TerminationPhase.scala | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/scala/leon/termination/ComplexTerminationChecker.scala b/src/main/scala/leon/termination/ComplexTerminationChecker.scala index 024792e23..eef8ddaac 100644 --- a/src/main/scala/leon/termination/ComplexTerminationChecker.scala +++ b/src/main/scala/leon/termination/ComplexTerminationChecker.scala @@ -8,7 +8,7 @@ import purescala.Expressions._ import scala.collection.mutable.{Map => MutableMap} -class ComplexTerminationChecker(context: LeonContext, program: Program) extends ProcessingPipeline(context, program) { +class ComplexTerminationChecker(context: LeonContext, initProgram: Program) extends ProcessingPipeline(context, initProgram) { val name = "Complex Termination Checker" val description = "A modular termination checker with a few basic modulesâ„¢" diff --git a/src/main/scala/leon/termination/ProcessingPipeline.scala b/src/main/scala/leon/termination/ProcessingPipeline.scala index 3b7a36c0a..0dbdb9bd0 100644 --- a/src/main/scala/leon/termination/ProcessingPipeline.scala +++ b/src/main/scala/leon/termination/ProcessingPipeline.scala @@ -32,7 +32,7 @@ case class Cleared(funDef: FunDef) extends Result(funDef) case class Broken(funDef: FunDef, args: Seq[Expr]) extends Result(funDef) case class MaybeBroken(funDef: FunDef, args: Seq[Expr]) extends Result(funDef) -abstract class ProcessingPipeline(context: LeonContext, program: Program) extends TerminationChecker(context, program) { +abstract class ProcessingPipeline(context: LeonContext, initProgram: Program) extends TerminationChecker(context, initProgram) { implicit val debugSection = utils.DebugSectionTermination import scala.collection.mutable.{PriorityQueue, Map => MutableMap, Set => MutableSet} diff --git a/src/main/scala/leon/termination/TerminationChecker.scala b/src/main/scala/leon/termination/TerminationChecker.scala index 9b12460d2..fb8818922 100644 --- a/src/main/scala/leon/termination/TerminationChecker.scala +++ b/src/main/scala/leon/termination/TerminationChecker.scala @@ -7,7 +7,12 @@ import purescala.Definitions._ import purescala.Expressions._ import purescala.DefOps._ -abstract class TerminationChecker(val context: LeonContext, val program: Program) extends LeonComponent { +abstract class TerminationChecker(val context: LeonContext, initProgram: Program) extends LeonComponent { + val program = { + val (pgm, _) = replaceFunDefs(initProgram){ fd => Some(fd.duplicate) } + + pgm + } val functions = visibleFunDefsFromMain(program) diff --git a/src/main/scala/leon/termination/TerminationPhase.scala b/src/main/scala/leon/termination/TerminationPhase.scala index 12af96737..a2bd46d90 100644 --- a/src/main/scala/leon/termination/TerminationPhase.scala +++ b/src/main/scala/leon/termination/TerminationPhase.scala @@ -24,7 +24,7 @@ object TerminationPhase extends LeonPhase[Program,TerminationReport] { filterInclusive(ctx.findOption(SharedOptions.optFunctions).map(fdMatcher), Some(excludeByDefault _)) } - val toVerify = program.definedFunctions.filter(fdFilter).sortWith((fd1, fd2) => fd1.getPos < fd2.getPos) + val toVerify = tc.program.definedFunctions.filter(fdFilter).sortWith((fd1, fd2) => fd1.getPos < fd2.getPos) val results = toVerify.map { funDef => funDef -> tc.terminates(funDef) -- GitLab