Skip to content

Commit 0bfabda

Browse files
authored
Merge branch 'master' into meilers_fix_749
2 parents 9069f59 + b7bc9ba commit 0bfabda

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

src/main/scala/rules/Executor.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ object executor extends ExecutionRules {
313313
val (relevantChunks, otherChunks) =
314314
quantifiedChunkSupporter.splitHeap[QuantifiedFieldChunk](s2.h, BasicChunkIdentifier(field.name))
315315
val hints = quantifiedChunkSupporter.extractHints(None, Seq(tRcvr))
316-
val chunkOrderHeuristics = quantifiedChunkSupporter.hintBasedChunkOrderHeuristic(hints)
316+
val chunkOrderHeuristics = quantifiedChunkSupporter.singleReceiverChunkOrderHeuristic(Seq(tRcvr), hints, v2)
317317
val s2p = if (s2.heapDependentTriggers.contains(field)){
318318
val (smDef1, smCache1) =
319319
quantifiedChunkSupporter.summarisingSnapshotMap(

src/main/scala/rules/QuantifiedChunkSupport.scala

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,8 +1231,8 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
12311231
case Some(heuristics) =>
12321232
heuristics
12331233
case None =>
1234-
quantifiedChunkSupporter.hintBasedChunkOrderHeuristic(
1235-
quantifiedChunkSupporter.extractHints(None, arguments))
1234+
quantifiedChunkSupporter.singleReceiverChunkOrderHeuristic(arguments,
1235+
quantifiedChunkSupporter.extractHints(None, arguments), v)
12361236
}
12371237

12381238
if (s.exhaleExt) {
@@ -1737,6 +1737,38 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
17371737
matchingChunks ++ otherChunks
17381738
}
17391739

1740+
def singleReceiverChunkOrderHeuristic(receiver: Seq[Term], hints: Seq[Term], v: Verifier)
1741+
: Seq[QuantifiedBasicChunk] => Seq[QuantifiedBasicChunk] = {
1742+
// Heuristic that emulates greedy Silicon behavior for consuming single-receiver permissions.
1743+
// First: Find singleton chunks that have the same receiver syntactically.
1744+
// If so, consider those first, then all others.
1745+
// Second: If nothing matches syntactically, try to find a chunk that matches the receiver using the decider.
1746+
// If that's the case, consider that chunk first, then all others.
1747+
// Third: As a fallback, use the standard hint based heuristics.
1748+
val fallback = hintBasedChunkOrderHeuristic(hints)
1749+
1750+
(chunks: Seq[QuantifiedBasicChunk]) => {
1751+
val (syntacticMatches, others) = chunks.partition(c => c.singletonArguments.contains(receiver))
1752+
if (syntacticMatches.nonEmpty) {
1753+
syntacticMatches ++ others
1754+
} else {
1755+
val greedyMatch = chunks.find(c => c.singletonArguments match {
1756+
case Some(args) if args.length == receiver.length =>
1757+
args.zip(receiver).forall(ts => v.decider.check(ts._1 === ts._2, Verifier.config.checkTimeout()))
1758+
case _ =>
1759+
false
1760+
}).toSeq
1761+
if (greedyMatch.nonEmpty) {
1762+
greedyMatch ++ chunks.diff(greedyMatch)
1763+
} else {
1764+
// It doesn't seem to be any of the singletons. Use the fallback on the non-singletons.
1765+
val (qpChunks, singletons) = chunks.partition(_.singletonArguments.isEmpty)
1766+
fallback(qpChunks) ++ singletons
1767+
}
1768+
}
1769+
}
1770+
}
1771+
17401772
def extractHints(cond: Option[Term], arguments: Seq[Term]): Seq[Term] = {
17411773
var hints =
17421774
arguments.flatMap {

0 commit comments

Comments
 (0)