@@ -2300,6 +2300,68 @@ object PredicateTrigger extends PreciseCondFlyweightFactory[(String, Term, Seq[T
23002300
23012301/* Magic wands */
23022302
2303+ abstract class MagicWandSnapshot (val abstractLhs : Term , val rhsSnapshot : Term ) extends Term {
2304+ utils.assertSort(abstractLhs, " abstract lhs" , sorts.Snap )
2305+ utils.assertSort(rhsSnapshot, " rhs snapshot" , sorts.Snap )
2306+ }
2307+
2308+ /**
2309+ * Snapshot for a magic wand. It represents a function which can be used only once
2310+ * by equating a snapshot from consuming the wand's LHS with `abstractLhs`.
2311+ *
2312+ * For a snapshot which can be applied multiple times see [[MagicWandSnapFunction ]].
2313+ *
2314+ * @param abstractLhs The abstract snapshot which acts as a placeholder in the
2315+ * `rhsSnapshot` for the values when applying the magic wand.
2316+ * @param rhsSnapshot Snapshot which can be used when producing the wand's RHS.
2317+ */
2318+ class MagicWandSnapSingleton (override val abstractLhs : Term , override val rhsSnapshot : Term )
2319+ extends MagicWandSnapshot (abstractLhs, rhsSnapshot)
2320+ with ConditionalFlyweightBinaryOp [MagicWandSnapSingleton ] {
2321+
2322+ override lazy val toString : String = s " wandSnap(lhs = $abstractLhs, rhs = $rhsSnapshot) "
2323+
2324+ /* ConditionalFlyweightBinaryOp members */
2325+
2326+ override def sort : Sort = sorts.Snap
2327+
2328+ override def p0 : Term = abstractLhs
2329+
2330+ override def p1 : Term = rhsSnapshot
2331+ }
2332+
2333+ object MagicWandSnapSingleton {
2334+ var pool = new TrieMap [(Term , Term ), MagicWandSnapSingleton ]()
2335+
2336+ /** Craete a new [[MagicWandSnapSingleton ]] from a single snapshot term. */
2337+ def apply (snapshot : Term ): MagicWandSnapshot = {
2338+ assert(snapshot.sort == sorts.Snap , s " MagicWandSnapshot.apply expects sorts Snap but got ${snapshot.sort}" )
2339+
2340+ snapshot match {
2341+ case snap : MagicWandSnapSingleton => snap
2342+ case _ => MagicWandSnapSingleton (First (snapshot), Second (snapshot))
2343+ }
2344+ }
2345+
2346+ /** Create a new [[MagicWandSnapSingleton ]] from two snapshot terms. */
2347+ def apply (abstractLhs : Term , rhsSnapshot : Term ): MagicWandSnapSingleton =
2348+ createIfNonExistent((abstractLhs, rhsSnapshot))
2349+
2350+ /** Destruct a [[MagicWandSnapSingleton ]] instance. Used in [[viper.silicon.state.utils.transform ]] */
2351+ def unapply (mws : MagicWandSnapSingleton ): Some [(Term , Term )] =
2352+ Some ((mws.abstractLhs, mws.rhsSnapshot))
2353+
2354+ private def createIfNonExistent (args : (Term , Term )): MagicWandSnapSingleton = {
2355+ if (Verifier .config.useFlyweight) {
2356+ pool.getOrElseUpdate(args, actualCreate(args))
2357+ } else {
2358+ actualCreate(args)
2359+ }
2360+ }
2361+
2362+ private def actualCreate (tuple : (Term , Term )) = new MagicWandSnapSingleton (tuple._1, tuple._2)
2363+ }
2364+
23032365/**
23042366 * Represents a snapshot of a magic wand, which is a map from Snap to Snap.
23052367 *
@@ -2310,7 +2372,10 @@ object PredicateTrigger extends PreciseCondFlyweightFactory[(String, Term, Seq[T
23102372 * In the symbolic execution this represents a function that when we apply a magic wand
23112373 * it consumes the left-hand side and uses the resulting snapshot to look up which right-hand side should be produced.
23122374 */
2313- class MagicWandSnapshot (val abstractLhs : Var , val rhsSnapshot : Term , val wandMap : Term ) extends Term with ConditionalFlyweight [Term , MagicWandSnapshot ] {
2375+ class MagicWandSnapFunction (override val abstractLhs : Var , override val rhsSnapshot : Term , val wandMap : Term )
2376+ extends MagicWandSnapshot (abstractLhs, rhsSnapshot)
2377+ with ConditionalFlyweight [Term , MagicWandSnapFunction ] {
2378+
23142379 utils.assertSort(abstractLhs, " abstract lhs" , sorts.Snap )
23152380 utils.assertSort(rhsSnapshot, " rhs snapshot" , sorts.Snap )
23162381 utils.assertSort(wandMap, " wand map" , sorts.MagicWandSnapFunction )
@@ -2342,15 +2407,14 @@ class MagicWandSnapshot(val abstractLhs: Var, val rhsSnapshot: Term, val wandMap
23422407 def applyToWandMap (snapLhs : Term ): Term = MWSFLookup (wandMap, snapLhs)
23432408}
23442409
2345- object MagicWandSnapshot {
2346- /**
2347- * Create a new instance of `MagicWandSnapshot`.
2348- *
2349- * @see [[viper.silicon.state.terms.MagicWandSnapshot ]]
2350- */
2351- def apply (abstractLhs : Var , rhsSnapshot : Term , wandMap : Term ): MagicWandSnapshot = new MagicWandSnapshot (abstractLhs, rhsSnapshot, wandMap)
2410+ object MagicWandSnapFunction {
2411+ /** Create a new instance of [[viper.silicon.state.terms.MagicWandSnapFunction ]]. */
2412+ def apply (abstractLhs : Var , rhsSnapshot : Term , wandMap : Term ): MagicWandSnapFunction =
2413+ new MagicWandSnapFunction (abstractLhs, rhsSnapshot, wandMap)
23522414
2353- def unapply (snap : MagicWandSnapshot ): Option [(Var , Term , Term )] = Some (snap.abstractLhs, snap.rhsSnapshot, snap.wandMap)
2415+ /** Destructs an instance of [[viper.silicon.state.terms.MagicWandSnapFunction ]]. */
2416+ def unapply (snap : MagicWandSnapFunction ): Option [(Var , Term , Term )] =
2417+ Some (snap.abstractLhs, snap.rhsSnapshot, snap.wandMap)
23542418}
23552419
23562420class MWSFLookup (val mwsf : Term , val snap : Term ) extends Term with ConditionalFlyweightBinaryOp [MWSFLookup ] {
@@ -2361,7 +2425,7 @@ class MWSFLookup(val mwsf: Term, val snap: Term) extends Term with ConditionalFl
23612425}
23622426
23632427object MWSFLookup extends PreciseCondFlyweightFactory [(Term , Term ), MWSFLookup ] {
2364- override def apply (pair : (Term , Term )) = {
2428+ override def apply (pair : (Term , Term )): MWSFLookup = {
23652429 val (mwsf, snap) = pair
23662430 utils.assertSort(mwsf, " mwsf" , sorts.MagicWandSnapFunction )
23672431 utils.assertSort(snap, " snap" , sorts.Snap )
0 commit comments