@@ -45,24 +45,32 @@ trait ExpTransformer extends ProgramManager with ErrorReporter {
4545 val fstBlock = Seqn (Seq (fstIf), Seq (nonDetVarDecl))()
4646 val sndStmt = transformExp(snd, c, inhaleExp)
4747 Seqn (Seq (fstBlock, sndStmt), Nil )()
48+
4849 case CondExp (cond, thn, els) =>
4950 val condStmt = transformExp(cond, c, false )
5051 val thnStmt = transformExp(thn, c, inhaleExp)
5152 val elsStmt = transformExp(els, c, inhaleExp)
52-
53- val ifStmt = If (cond, Seqn (Seq (thnStmt), Nil )(), Seqn (Seq (elsStmt), Nil )())()
54-
53+ val ifStmt = if (isEmptyStatement(thnStmt) && isEmptyStatement(elsStmt))
54+ EmptyStmt
55+ else
56+ If (cond, Seqn (Seq (thnStmt), Nil )(), Seqn (Seq (elsStmt), Nil )())()
5557 val stmts = Seq (condStmt, ifStmt)
5658 Seqn (stmts, Nil )()
59+
5760 case Unfolding (acc, unfBody) =>
5861 val permCheck = transformExp(acc.perm, c, false )
5962 val unfoldBody = transformExp(unfBody, c, inhaleExp)
6063 val unfold = Unfold (acc)()
6164 val nonDetVarDecl = LocalVarDecl (uniqueName(" b" ), Bool )(e.pos, e.info, e.errT)
6265 val assumeFalse = Inhale (FalseLit ()())()
63- val thenBranch = Seqn (Seq (permCheck, unfold, unfoldBody, assumeFalse), Nil )()
66+ val unfoldPart = if (! isEmptyStatement(unfoldBody)) Seqn (Seq (unfold, unfoldBody), Nil )() else EmptyStmt
67+ val thenBranch = Seqn (Seq (permCheck, unfoldPart, assumeFalse), Nil )()
6468 val elseBranch = if (inhaleExp) Seqn (Seq (Inhale (e)(e.pos, e.info)), Nil )() else EmptyStmt
65- Seqn (Seq (If (nonDetVarDecl.localVar, thenBranch, elseBranch)()), Seq (nonDetVarDecl))()
69+ if (isEmptyStatement(permCheck) && isEmptyStatement(unfoldPart))
70+ elseBranch
71+ else
72+ Seqn (Seq (If (nonDetVarDecl.localVar, thenBranch, elseBranch)()), Seq (nonDetVarDecl))()
73+
6674 case Applying (wand, body) =>
6775 // note that this case is untested -- it's not possible to write a function with an `applying` expression
6876 val nonDetVarDecl = LocalVarDecl (uniqueName(" b" ), Bool )(e.pos, e.info, e.errT)
@@ -71,6 +79,7 @@ trait ExpTransformer extends ProgramManager with ErrorReporter {
7179 val thnStmt = Seqn (Seq (Apply (wand)(e.pos, e.info, e.errT), bodyStmt, killBranchStmt), Nil )()
7280 val ifStmt = If (nonDetVarDecl.localVar, thnStmt, EmptyStmt )(e.pos, e.info, e.errT)
7381 Seqn (Seq (ifStmt), Seq (nonDetVarDecl))(e.pos, e.info, e.errT)
82+
7483 case inex : InhaleExhaleExp =>
7584 val inhaleStmt = transformExp(inex.in, c, inhaleExp)
7685 val exhaleStmt = transformExp(inex.ex, c, inhaleExp)
@@ -79,6 +88,7 @@ trait ExpTransformer extends ProgramManager with ErrorReporter {
7988 case Some (conditionVar) => If (conditionVar.localVar, Seqn (Seq (inhaleStmt), Nil )(), Seqn (Seq (exhaleStmt), Nil )())()
8089 case None => Seqn (Seq (inhaleStmt, exhaleStmt), Nil )()
8190 }
91+
8292 case letExp : Let =>
8393 val expressionStmt = transformExp(letExp.exp, c, false )
8494 val localVarDecl = letExp.variable
@@ -87,15 +97,20 @@ trait ExpTransformer extends ProgramManager with ErrorReporter {
8797
8898 val bodyStmt = transformExp(letExp.body, c, inhaleExp)
8999
90- Seqn (Seq (expressionStmt, inhaleEq, bodyStmt), Seq (localVarDecl))()
100+ val bodyCheck = if (isEmptyStatement(bodyStmt))
101+ EmptyStmt
102+ else
103+ Seqn (Seq (inhaleEq, bodyStmt), Seq (localVarDecl))()
104+
105+ Seqn (Seq (expressionStmt, bodyCheck), Nil )()
91106
92107 case b : BinExp =>
93108 val left = transformExp(b.left, c, inhaleExp)
94109 val right = transformExp(b.right, c, inhaleExp)
95110
96111 // Short circuit evaluation
97112 val pureLeft : Exp = toPureBooleanExp(c).execute(b.left)
98- val rightSCE = b match {
113+ val rightSCE = if (isEmptyStatement(right)) EmptyStmt else b match {
99114 case _ : Or =>
100115 If (Not (pureLeft)(), Seqn (Seq (right), Nil )(), EmptyStmt )()
101116 case _ : And =>
@@ -119,12 +134,14 @@ trait ExpTransformer extends ProgramManager with ErrorReporter {
119134 val check = transformExp(ap.perm, c, false )
120135 val inhale = Inhale (ap)(ap.pos)
121136 Seqn (Seq (check, inhale), Nil )()
137+
122138 case fa : Forall =>
123139 // we turn the quantified variables into local variables with arbitrary value and show that the expression holds
124140 // for arbitrary values, which is similar to a forall introduction
125141 val (localDeclMapping, transformedExp) = substituteWithFreshVars(fa.variables, fa.exp)
126142 val expressionStmt = transformExp(transformedExp, c, inhaleExp)
127143 Seqn (Seq (expressionStmt), localDeclMapping.map(_._2))(fa.pos, fa.info, fa.errT)
144+
128145 case fp : ForPerm =>
129146 // let's pick arbitrary values for the quantified variables and check the body given that the current heap has
130147 // sufficient permissions
@@ -136,6 +153,7 @@ trait ExpTransformer extends ProgramManager with ErrorReporter {
136153 val ifCond = GtCmp (CurrentPerm (transformedRes)(e.pos, e.info, e.errT), NoPerm ()(e.pos, e.info, e.errT))(e.pos, e.info, e.errT)
137154 val ifStmt = If (ifCond, thnStmt, EmptyStmt )(e.pos, e.info, e.errT)
138155 Seqn (Seq (ifStmt), localDeclMapping.map(_._2))(e.pos, e.info, e.errT)
156+
139157 case ex : Exists =>
140158 // we perform existential elimination by retrieving witnesses for the quantified variables
141159 val (localDeclMapping, transformedExp) = substituteWithFreshVars(ex.variables, ex.exp)
@@ -144,16 +162,23 @@ trait ExpTransformer extends ProgramManager with ErrorReporter {
144162 val inhaleWitnesses = Inhale (transformedExp)(ex.pos, ex.info, ex.errT)
145163 val expressionStmt = transformExp(transformedExp, c, inhaleExp)
146164 Seqn (Seq (inhaleWitnesses, expressionStmt), localDeclMapping.map(_._2))(ex.pos, ex.info, ex.errT)
165+
147166 case fa : FuncLikeApp =>
148167 val argStmts = fa.args.map(transformExp(_, c, false ))
149168 Seqn (argStmts, Nil )()
169+
150170 case e : ExtensionExp => reportUnsupportedExp(e)
151171
152172 case _ =>
153173 val sub = e.subExps.map(transformExp(_, c, false ))
154174 Seqn (sub, Nil )()
155175 }
156176
177+ def isEmptyStatement (stmt : Stmt ): Boolean = stmt match {
178+ case Seqn (stmts, _) => stmts.forall(isEmptyStatement)
179+ case _ => false
180+ }
181+
157182 /**
158183 * Issues a consistency error for unsupported expressions.
159184 *
0 commit comments