Skip to content

Conversation

samuelchassot
Copy link
Collaborator

Add a new Cell feature with a swap to support more mutability, notably swapping 2 variables.

This adds a new Cell class in the library, and a swap function exchanging their values:

case class Cell[@mutable T](var v: T) 

def swap[@mutable T](c1: Cell[T], c2: Cell[T]): Unit = {
      val t = c2.v
      c2.v = c1.v
      c1.v = t
  }

These can be used as follows:

import stainless.lang._

object Test {

  def f(c1: Cell[Int], c2: Cell[Int]): Unit = {
    require(c1.v == 1)
    require(c2.v == 2)

    c1.v = 3
    swap(c1, c2)
    assert(c1.v == 2)
    assert(c2.v == 3)
  }
}

samuelchassot and others added 3 commits October 30, 2023 15:03
Add the new feature to support mutable swap operation on Cell
Copy link
Collaborator

@mario-bucev mario-bucev left a comment

Choose a reason for hiding this comment

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

Looks good 👍 ! Just minor details :)
There is also a missing case for CellSwap in AntiAliasing#doNormalize:

case swp @ CellSwap(cell1, cell2) =>
  val (ctxCell1, normCell1) = normalizeForTarget(cell1)
  val (ctxCell2, normCell2) = normalizeForTarget(cell2)
  (ctxCell1 compose ctxCell2, CellSwap(normCell1, normCell2).copiedFrom(swp))

Comment on lines 505 to 521
val cellClassDef = symbols.lookup.get[ClassDef]("stainless.lang.Cell").get
val vFieldId = cellClassDef.fields.head.id

val temp = ValDef.fresh("temp", base).setPos(cellSwap)
val targets1 = getDirectTargetsDealiased(cell1, ClassFieldAccessor(vFieldId), env)
.getOrElse(throw MalformedStainlessCode(cellSwap, "Unsupported cellSwap (first cell)"))
val targets2 = getDirectTargetsDealiased(cell2, ClassFieldAccessor(vFieldId), env)
.getOrElse(throw MalformedStainlessCode(cellSwap, "Unsupported cellSwap (second cell)"))

val updates1 = updatedTargetsAndAliases(targets2, ClassSelector(cell1, vFieldId).setPos(cellSwap), env, cellSwap.getPos)
val updates2 = updatedTargetsAndAliases(targets1, temp.toVariable, env, cellSwap.getPos)
val updates = updates1 ++ updates2
if (updates.isEmpty) UnitLiteral().setPos(cellSwap)
else
Let(temp, transform(ClassSelector(cell2, vFieldId).setPos(cellSwap), env),
Block(updates.init, updates.last).setPos(cellSwap)
).setPos(cellSwap)
Copy link
Collaborator

Choose a reason for hiding this comment

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

recCell1 and recCell2 should be used here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

whoops, fixed! Thanks :)

val tmpId = rec(FreshIdentifier("tmp"))
val tmpVd = CIR.ValDef(tmpId, rec(cellBaseType), false)
val tmp = CIR.Binding(tmpVd)
throw new Exception(f"CellSwap to IR phase: cellBase type = $cellBaseType; vField Id = $vFieldId")
Copy link
Collaborator

Choose a reason for hiding this comment

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

leftover?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

indeed 🙈

@samuelchassot
Copy link
Collaborator Author

Closes #1356

@samuelchassot
Copy link
Collaborator Author

Looks good 👍 ! Just minor details :) There is also a missing case for CellSwap in AntiAliasing#doNormalize:

case swp @ CellSwap(cell1, cell2) =>
  val (ctxCell1, normCell1) = normalizeForTarget(cell1)
  val (ctxCell2, normCell2) = normalizeForTarget(cell2)
  (ctxCell1 compose ctxCell2, CellSwap(normCell1, normCell2).copiedFrom(swp))

Whoops, I added it!

@samuelchassot
Copy link
Collaborator Author

@mario-bucev I applied the fixes according to your comments!

@vkuncak
Copy link
Collaborator

vkuncak commented Oct 30, 2023

Awesome!

@vkuncak vkuncak merged commit c0633c6 into epfl-lara:main Oct 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants