@@ -10,6 +10,7 @@ import scala.language.implicitConversions
1010import scala .collection .immutable .Queue
1111import scala .collection .immutable .Queue .{empty => emptyDq }
1212import viper .silver .ast ._
13+ import viper .silver .plugin .standard .termination .DecreasesClause
1314import viper .silver .verifier .DummyNode
1415
1516import scala .annotation .tailrec
@@ -528,13 +529,17 @@ object FastPrettyPrinter extends FastPrettyPrinterBase with BracketPrettyPrinter
528529 case Field (name, typ) =>
529530 text(" field" ) <+> name <> " :" <+> show(typ)
530531 case Method (name, formalArgs, formalReturns, pres, posts, body) =>
532+ // for the time being, the termination plugin transforms decreases clauses into preconditions or postconditions
533+ val (terminationMeasuresInPres, actualPres) = pres.partition(exp => exp.isInstanceOf [DecreasesClause ])
534+ val (terminationMeasuresInPosts, actualPosts) = posts.partition(exp => exp.isInstanceOf [DecreasesClause ])
531535 group(text(" method" ) <+> name <> nest(defaultIndent, parens(showVars(formalArgs))) <> {
532536 if (formalReturns.isEmpty) nil
533537 else nest(defaultIndent, line <> " returns" <+> parens(showVars(formalReturns)))
534538 }) <>
535539 nest(defaultIndent,
536- showContracts(" requires" , pres) <>
537- showContracts(" ensures" , posts)
540+ showContracts(" requires" , actualPres) <>
541+ showContracts(" ensures" , actualPosts) <>
542+ showDecreasesClauses(terminationMeasuresInPres ++ terminationMeasuresInPosts)
538543 ) <>
539544 line <> (
540545 body match {
@@ -549,11 +554,15 @@ object FastPrettyPrinter extends FastPrettyPrinterBase with BracketPrettyPrinter
549554 case Some (exp) => braces(nest(defaultIndent, line <> show(exp)) <> line)
550555 })
551556 case Function (name, formalArgs, typ, pres, posts, optBody) =>
557+ // for the time being, the termination plugin transforms decreases clauses into preconditions or postconditions
558+ val (terminationMeasuresInPres, actualPres) = pres.partition(exp => exp.isInstanceOf [DecreasesClause ])
559+ val (terminationMeasuresInPosts, actualPosts) = posts.partition(exp => exp.isInstanceOf [DecreasesClause ])
552560 text(" function" ) <+> name <> nest(defaultIndent, parens(showVars(formalArgs))) <>
553561 " :" <+> show(typ) <>
554562 nest(defaultIndent,
555- showContracts(" requires" , pres) <>
556- showContracts(" ensures" , posts)
563+ showContracts(" requires" , actualPres) <>
564+ showContracts(" ensures" , actualPosts) <>
565+ showDecreasesClauses(terminationMeasuresInPres ++ terminationMeasuresInPosts)
557566 ) <>
558567 line <>
559568 (optBody match {
@@ -576,6 +585,11 @@ object FastPrettyPrinter extends FastPrettyPrinterBase with BracketPrettyPrinter
576585 lineIfSomeNonEmpty(contracts) <> ssep(contracts.map(c => text(name) <+> nest(defaultIndent, show(c))), line)
577586 }
578587
588+ /** Shows a list of termination measures. */
589+ def showDecreasesClauses (measures : Seq [Exp ]): Cont = {
590+ lineIfSomeNonEmpty(measures) <> ssep(measures.map(c => nest(defaultIndent, show(c))), line)
591+ }
592+
579593 /** Returns `n` lines if at least one element of `s` is non-empty, and an empty document otherwise. */
580594 def lineIfSomeNonEmpty [T ](s : Seq [T ]* )(implicit n : Int = 1 ) = {
581595 if (s.forall(e => e != null && e.isEmpty)) nil
@@ -692,11 +706,11 @@ object FastPrettyPrinter extends FastPrettyPrinterBase with BracketPrettyPrinter
692706 ssep((if (locals == null ) Nil else locals map (text(" var" ) <+> showVar(_))) ++ (stmtsToShow map show), line)
693707 }
694708 case While (cond, invs, body) =>
709+ val (terminationMeasures, actualInvs) = invs.partition(exp => exp.isInstanceOf [DecreasesClause ])
695710 text(" while" ) <+> parens(show(cond)) <>
696- nest(defaultIndent,
697- showContracts(" invariant" , invs)
698- ) <+> lineIfSomeNonEmpty(invs) <>
699- showBlock(body)
711+ nest(defaultIndent, showContracts(" invariant" , actualInvs) <> showDecreasesClauses(terminationMeasures)) <+>
712+ lineIfSomeNonEmpty(invs) <>
713+ showBlock(body)
700714 case If (cond, thn, els) =>
701715 text(" if" ) <+> parens(show(cond)) <+> showBlock(thn) <> showElse(els)
702716 case Label (name, invs) =>
0 commit comments