Skip to content

Commit 46d91a5

Browse files
jp-fizzbeejayaprabhakarclaude
authored
fix(modelchecker): preserve action return values across symmetric clones (#354)
CloneWithRefs was initializing the clone's Returns field to an empty StringDict. Since the symmetric-permutation hashing path (findVisitedSymmetric -> getSymmetryTranslations -> symmetricHashWithoutClone -> p2.HashCode()) operates on a clone, per-action return values were silently stripped from the dedup key. Two yield-points that differ only in what an action returned collapsed into one node. Copy p.Returns into the clone so the symmetric hash matches the original HashCode (which includes Returns at line 604). This restores the pre-#297 behavior where actions returning values produce distinct nodes — needed for visualization, MBT, and explorer consumers that depend on the return value being visible in the graph. Regression introduced by #297 ("Consistently use min hash value") when the dedup lookup switched from `visited[node.HashCode()]` to `visited[minHash]` — the new path always goes through CloneWithRefs. Co-authored-by: jayaprabhakar <jayaprabhakar@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 14760e2 commit 46d91a5

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

modelchecker/processor.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,15 @@ func (p *Process) CloneForAssert(permutations map[*lib.SymmetricValue][]*lib.Sym
396396
}
397397

398398
func (p *Process) CloneWithRefs(permutations map[*lib.SymmetricValue][]*lib.SymmetricValue, alt int, refs map[starlark.Value]starlark.Value) *Process {
399+
// Copy p.Returns so the clone's HashCode (used by symmetric-permutation
400+
// hashing) sees the same action-return data as the original. A fresh
401+
// empty map here would silently strip per-action returns from the
402+
// dedup key and collapse states that differ only in what an action
403+
// returned.
404+
returnsCopy := make(starlark.StringDict, len(p.Returns))
405+
for k, v := range p.Returns {
406+
returnsCopy[k] = v
407+
}
399408
p2 := &Process{
400409
Name: p.Name,
401410
Heap: p.Heap.Clone(refs, permutations, alt),
@@ -408,7 +417,7 @@ func (p *Process) CloneWithRefs(permutations map[*lib.SymmetricValue][]*lib.Symm
408417

409418
Children: []*Process{},
410419
Files: p.Files,
411-
Returns: make(starlark.StringDict),
420+
Returns: returnsCopy,
412421
SymbolTable: p.SymbolTable,
413422
Modules: p.Modules,
414423
Labels: make([]string, 0),

0 commit comments

Comments
 (0)