Skip to content

Conversation

mario-bucev
Copy link
Collaborator

Hopefully fixes the underlying problems of #916, #1099, and #1122 without introducing new bugs...

@vkuncak vkuncak merged commit e91c5d6 into epfl-lara:main Mar 14, 2022
Comment on lines +367 to +370
case Assignment(v, expr) =>
// We explicitly override this case to not have the recursion go through `v` and potentially taking the above case
// (otherwise, we could get something like `env.rewritings(v.toVal) = expr` which may not be well-defined).
Assignment(v, transform(expr, env))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If v belongs to env.rewritings, doesn't that mean that we've added a LetVar to the rewritings map? That would be incorrect in itself, so if this case is cropping up we might have an underlying issue.

Copy link
Collaborator Author

@mario-bucev mario-bucev Mar 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that the only vs for which this case is problematic are those that are of a mutable type and val-defined (such as val x = if (b1) a1 else a2 in invalid/i916a1).
Such rewriting in env is added by:

if (targets.isSuccess) {
// This branch handles all cases when targets can be precisely computed, namely when
// 1. newExpr is a fresh expression
// 2. newExpr is a precise alias to an existing variable
val rewriting = targets.get.foldRight(vd.toVariable : Expr) {
case (Target(r, Some(cond), path), rewriting) =>
val wrapped = path.wrap(r).getOrElse(
throw MalformedStainlessCode(l, "Unsupported `val` in AntiAliasing (conditional target)")
)
IfExpr(cond, wrapped, rewriting)
case (Target(r, None, path), rewriting) =>
path.wrap(r).getOrElse(
throw MalformedStainlessCode(l, "Unsupported `val` in AntiAliasing (unconditional target)")
)
}
val newBody = transform(b, env withRewritings Map(vd -> rewriting) withBinding vd)
LetVar(vd, newExpr, newBody).copiedFrom(l)

and seems to be intended.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But when are we seeing an Assignment(x, ...)? Scala vals can't be assigned, are we applying a transformation twice?

Copy link
Collaborator Author

@mario-bucev mario-bucev Mar 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

val x is transformed into a var x and it is re-assigned each time we modify one of its components.
If we e.g. see x.a = 123, it is transformed into an assignment: x = A(123)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. Thanks for bearing with me :)

I don't like the fact that we're applying transform to assignments produced during the phase since it makes it difficult to distinguish issues in the phase from issues in the input program. I think it would be worth cleaning up these cases to avoid applying transform to the generated Assignment expressions. For example,

https://github.com/mario-bucev/stainless/blob/667ef3da0422c9306a96afc760e7cd6bbaf17c32/core/src/main/scala/stainless/extraction/imperative/AntiAliasing.scala#L501-L502

should probably be something like below instead

val applied = updatedTarget(target, v)
Assignment(target.receiver, transform(applied, env)).copiedFrom(up)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good note, I'll address that in a separate PR

Comment on lines +217 to +224
val combinedCond = Some(cond).zip(effectCond).map {
case (BooleanLiteral(b1), c2) =>
if (b1) c2 else BooleanLiteral(false)
case (c1, BooleanLiteral(b2)) =>
if (b2) c1 else BooleanLiteral(false)
case (c1, c2) =>
And(c1, c2)
}.getOrElse(cond)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can replace this by andJoin(cond +: effectCond.toSeq) for better readability.

@mario-bucev mario-bucev deleted the antialiasing branch March 15, 2022 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants