From 664507809f3ec763532447d837345e859ce71c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Mayer?= <mikael.mayer@epfl.ch> Date: Thu, 26 May 2016 11:22:07 +0200 Subject: [PATCH] A.holds.because(B) = A.holds(because(B)) = A.holds(B) = A holds because (B) = A.holds because(B) = A holds B --- library/leon/lang/package.scala | 2 +- .../leon/frontends/scalac/ASTExtractors.scala | 29 ++++++++++++++++++- .../frontends/scalac/CodeExtraction.scala | 17 ++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/library/leon/lang/package.scala b/library/leon/lang/package.scala index 8898b5637..f9173b6fe 100644 --- a/library/leon/lang/package.scala +++ b/library/leon/lang/package.scala @@ -13,7 +13,7 @@ package object lang { def holds : Boolean = { underlying } ensuring { - _ == true + (res: Boolean) => res } @inline def holds(becauseOfThat: Boolean) = { diff --git a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala index 5fb96861d..172380794 100644 --- a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala +++ b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala @@ -177,7 +177,7 @@ trait ASTExtractors { } } - /** Matches the `holds` expression at the end of any boolean expression, and return the boolean expression.*/ + /** Matches the `holds` expression at the end of any boolean expression, and returns the boolean expression.*/ object ExHoldsExpression { def unapply(tree: Select) : Option[Tree] = tree match { case Select( @@ -188,6 +188,33 @@ trait ASTExtractors { } } + /** Matches the `holds` expression at the end of any boolean expression with a proof as argument, and returns both of themn.*/ + object ExHoldsWithProofExpression { + def unapply(tree: Apply) : Option[(Tree, Tree)] = tree match { + case Apply(Select(Apply(ExSelected("leon", "lang", "package", "BooleanDecorations"), body :: Nil), ExNamed("holds")), proof :: Nil) => + Some((body, proof)) + case _ => None + } + } + + /** Matches the `because` method at the end of any boolean expression, and return the assertion and the cause. If no "because" method, still returns the expression */ + object ExMaybeBecauseExpressionWrapper { + def unapply(tree: Tree) : Some[Tree] = tree match { + case Apply(ExSelected("leon", "lang", "package", "because"), body :: Nil) => + unapply(body) + case body => Some(body) + } + } + + /** Matches the `because` method at the end of any boolean expression, and return the assertion and the cause.*/ + object ExBecauseExpression { + def unapply(tree: Apply) : Option[(Tree, Tree)] = tree match { + case Apply(Select(Apply(ExSelected("leon", "proof", "package", "boolean2ProofOps"), body :: Nil), ExNamed("because")), proof :: Nil) => + Some((body, proof)) + case _ => None + } + } + /** Matches the `bigLength` expression at the end of any string expression, and returns the expression.*/ object ExBigLengthExpression { def unapply(tree: Apply) : Option[Tree] = tree match { diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala index 99ca8aa07..92829ce8c 100644 --- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala +++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala @@ -1164,6 +1164,13 @@ trait CodeExtraction extends ASTExtractors { Ensuring(b, closure) + case t @ ExHoldsWithProofExpression(body, ExMaybeBecauseExpressionWrapper(proof)) => + val resId = FreshIdentifier("holds", BooleanType).setPos(current.pos) + val p = extractTreeOrNoTree(proof) + val post = Lambda(Seq(LeonValDef(resId)), And(Seq(p, Variable(resId)))).setPos(current.pos) + val b = extractTreeOrNoTree(body) + Ensuring(b, post) + case t @ ExHoldsExpression(body) => val resId = FreshIdentifier("holds", BooleanType).setPos(current.pos) val post = Lambda(Seq(LeonValDef(resId)), Variable(resId)).setPos(current.pos) @@ -1171,7 +1178,15 @@ trait CodeExtraction extends ASTExtractors { val b = extractTreeOrNoTree(body) Ensuring(b, post) - + + // If the because statement encompasses a holds statement + case t @ ExBecauseExpression(ExHoldsExpression(body), proof) => + val resId = FreshIdentifier("holds", BooleanType).setPos(current.pos) + val p = extractTreeOrNoTree(proof) + val post = Lambda(Seq(LeonValDef(resId)), And(Seq(p, Variable(resId)))).setPos(current.pos) + val b = extractTreeOrNoTree(body) + Ensuring(b, post) + case t @ ExComputesExpression(body, expected) => val b = extractTreeOrNoTree(body).setPos(body.pos) val expected_expr = extractTreeOrNoTree(expected).setPos(expected.pos) -- GitLab