Skip to content

Commit

Permalink
Merge branch 'master' into meilers_fix_749
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoeilers authored Sep 22, 2023
2 parents 9069f59 + b7bc9ba commit 0bfabda
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/rules/Executor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ object executor extends ExecutionRules {
val (relevantChunks, otherChunks) =
quantifiedChunkSupporter.splitHeap[QuantifiedFieldChunk](s2.h, BasicChunkIdentifier(field.name))
val hints = quantifiedChunkSupporter.extractHints(None, Seq(tRcvr))
val chunkOrderHeuristics = quantifiedChunkSupporter.hintBasedChunkOrderHeuristic(hints)
val chunkOrderHeuristics = quantifiedChunkSupporter.singleReceiverChunkOrderHeuristic(Seq(tRcvr), hints, v2)
val s2p = if (s2.heapDependentTriggers.contains(field)){
val (smDef1, smCache1) =
quantifiedChunkSupporter.summarisingSnapshotMap(
Expand Down
36 changes: 34 additions & 2 deletions src/main/scala/rules/QuantifiedChunkSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1231,8 +1231,8 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
case Some(heuristics) =>
heuristics
case None =>
quantifiedChunkSupporter.hintBasedChunkOrderHeuristic(
quantifiedChunkSupporter.extractHints(None, arguments))
quantifiedChunkSupporter.singleReceiverChunkOrderHeuristic(arguments,
quantifiedChunkSupporter.extractHints(None, arguments), v)
}

if (s.exhaleExt) {
Expand Down Expand Up @@ -1737,6 +1737,38 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
matchingChunks ++ otherChunks
}

def singleReceiverChunkOrderHeuristic(receiver: Seq[Term], hints: Seq[Term], v: Verifier)
: Seq[QuantifiedBasicChunk] => Seq[QuantifiedBasicChunk] = {
// Heuristic that emulates greedy Silicon behavior for consuming single-receiver permissions.
// First: Find singleton chunks that have the same receiver syntactically.
// If so, consider those first, then all others.
// Second: If nothing matches syntactically, try to find a chunk that matches the receiver using the decider.
// If that's the case, consider that chunk first, then all others.
// Third: As a fallback, use the standard hint based heuristics.
val fallback = hintBasedChunkOrderHeuristic(hints)

(chunks: Seq[QuantifiedBasicChunk]) => {
val (syntacticMatches, others) = chunks.partition(c => c.singletonArguments.contains(receiver))
if (syntacticMatches.nonEmpty) {
syntacticMatches ++ others
} else {
val greedyMatch = chunks.find(c => c.singletonArguments match {
case Some(args) if args.length == receiver.length =>
args.zip(receiver).forall(ts => v.decider.check(ts._1 === ts._2, Verifier.config.checkTimeout()))
case _ =>
false
}).toSeq
if (greedyMatch.nonEmpty) {
greedyMatch ++ chunks.diff(greedyMatch)
} else {
// It doesn't seem to be any of the singletons. Use the fallback on the non-singletons.
val (qpChunks, singletons) = chunks.partition(_.singletonArguments.isEmpty)
fallback(qpChunks) ++ singletons
}
}
}
}

def extractHints(cond: Option[Term], arguments: Seq[Term]): Seq[Term] = {
var hints =
arguments.flatMap {
Expand Down

0 comments on commit 0bfabda

Please sign in to comment.