FAILURE MAP
← Case archive

FA-87556 / Collision detection broadphase / Open access

Ended pairs are computed from the symmetric difference · case 01

New contacts are reported as ending on their first frame.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

end = P ^ C.

VERIFIED REPAIR

end = P - C.

Unsuccessful approach: Using C - P makes end a copy of begin.

Case contract

solve(prev, curr, asleep): contact pair cache update. Pairs are unordered; self pairs in curr are ignored. Previous pairs whose two bodies are both asleep persist even if not re-reported. Return [begin, end, persist] as sorted [min,max] lists.

Why this case matters

Broadphase stages decide which object pairs ever reach narrowphase; a wrong boundary, ordering or bookkeeping rule silently drops real contacts or floods the solver with false candidates.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(prev, curr, asleep):
    def norm(p):
        return (min(p), max(p))
    P = {norm(p) for p in prev}
    C = {norm(p) for p in curr if p[0] != p[1]}
    sl = set(asleep)
    for p in P:
        if p[0] in sl and p[1] in sl:
            C.add(p)
    begin = sorted(C - P)
    end = sorted(P ^ C)
    keep = sorted(P & C)
    return [[list(p) for p in begin], [list(p) for p in end], [list(p) for p in keep]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[[7, 6]], [[5, 3], [5, 6]], [1, 4]], [[[3, 5], [5, 6]], [[6, 7]], []]], [[[[1, 7], [7, 1], [1, 3], [2, 6]], [[3, 4], [3, 4], [4, 7], [4, 1], [7, 3], [4, 3]], []], [[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 7], [2, 6]], []]], [[[[2, 5], [3, 6], [1, 4], [6, 7], [1, 3], [6, 7]], [[4, 5], [1, 1]], [1, 2]], [[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [6, 7]], []]], [[[[1, 3], [1, 2], [3, 4]], [[4, 3], [3, 6], [1, 4], [4, 5], [6, 4], [7, 7]], [4, 1]], [[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3]], [[3, 4]]]], [[[[5, 7]], [[2, 7]], []], [[[2, 7]], [[5, 7]], []]], [[[[6, 2], [7, 5]], [[5, 7]], []], [[], [[2, 6]], [[5, 7]]]], [[[[4, 3], [7, 1], [6, 1], [3, 6], [7, 4]], [[3, 2], [2, 2]], [4, 1, 5]], [[[2, 3]], [[1, 6], [1, 7], [3, 4], [3, 6], [4, 7]], []]], [[[[3, 6], [3, 7]], [[5, 2], [4, 3], [5, 5]], []], [[[2, 5], [3, 4]], [[3, 6], [3, 7]], []]]], [[[[[2, 1], [3, 2]], [[1, 7], [7, 4], [1, 3], [6, 2], [2, 2]], [7, 2, 1, 6]], [[[1, 3], [1, 7], [2, 6], [4, 7]], [[2, 3]], [[1, 2]]]], [[[[3, 4], [3, 7]], [[7, 6], [2, 1], [1, 6]], []], [[[1, 2], [1, 6], [6, 7]], [[3, 4], [3, 7]], []]], [[[[7, 3], [6, 1], [5, 3], [2, 7]], [[5, 6], [5, 2], [1, 3], [2, 3]], []], [[[1, 3], [2, 3], [2, 5], [5, 6]], [[1, 6], [2, 7], [3, 5], [3, 7]], []]], [[[[3, 4], [4, 2], [1, 5], [5, 6], [3, 4], [3, 5]], [[1, 4]], [3, 6, 4]], [[[1, 4]], [[1, 5], [2, 4], [3, 5], [5, 6]], [[3, 4]]]], [[[[7, 1], [5, 7], [5, 3]], [[4, 2], [5, 2], [2, 4], [7, 6], [5, 2], [6, 7], [5, 5]], [7]], [[[2, 4], [2, 5], [6, 7]], [[1, 7], [3, 5], [5, 7]], []]], [[[[1, 5], [1, 7], [5, 1], [4, 2], [3, 5], [6, 7]], [[6, 4], [1, 3], [1, 2], [4, 6], [7, 5], [5, 5]], [1, 3]], [[[1, 2], [1, 3], [4, 6], [5, 7]], [[1, 5], [1, 7], [2, 4], [3, 5], [6, 7]], []]], [[[[2, 4], [5, 4], [1, 7], [6, 7]], [[5, 7], [7, 7]], [3]], [[[5, 7]], [[1, 7], [2, 4], [4, 5], [6, 7]], []]], [[[[7, 5], [1, 6], [3, 2]], [[5, 7]], [4, 1, 3, 6]], [[], [[2, 3]], [[1, 6], [5, 7]]]]], [[[[[3, 2]], [[2, 1]], [6]], [[[1, 2]], [[2, 3]], []]], [[[[1, 3], [4, 7], [6, 5]], [[3, 1]], [5, 6, 3]], [[], [[4, 7]], [[1, 3], [5, 6]]]], [[[[4, 3], [1, 3]], [[1, 6], [1, 7], [2, 6], [2, 2]], [4, 1, 2, 5]], [[[1, 6], [1, 7], [2, 6]], [[1, 3], [3, 4]], []]], [[[[5, 6], [5, 1], [2, 3]], [[5, 2], [7, 1], [7, 1], [4, 6]], [7]], [[[1, 7], [2, 5], [4, 6]], [[1, 5], [2, 3], [5, 6]], []]], [[[[3, 5], [2, 1], [2, 6], [2, 4], [1, 7], [5, 7]], [[6, 1], [2, 1]], []], [[[1, 6]], [[1, 7], [2, 4], [2, 6], [3, 5], [5, 7]], [[1, 2]]]], [[[[3, 5], [4, 5], [4, 5], [6, 1], [6, 5]], [[4, 3], [6, 7], [4, 1], [7, 3], [2, 4]], [2, 7, 5]], [[[1, 4], [2, 4], [3, 4], [3, 7], [6, 7]], [[1, 6], [3, 5], [4, 5], [5, 6]], []]], [[[[7, 3], [4, 3], [5, 1], [5, 4], [6, 7], [5, 4]], [[4, 5], [5, 4], [6, 7], [6, 6]], [4]], [[], [[1, 5], [3, 4], [3, 7]], [[4, 5], [6, 7]]]], [[[[7, 5], [3, 1], [4, 2], [4, 2]], [[3, 7]], [6, 2, 7, 4]], [[[3, 7]], [[1, 3], [5, 7]], [[2, 4]]]]], [[[[[2, 4], [4, 5], [1, 4], [5, 3], [7, 1]], [[7, 4], [3, 5], [6, 2], [1, 1]], [1]], [[[2, 6], [4, 7]], [[1, 4], [1, 7], [2, 4], [4, 5]], [[3, 5]]]], [[[[5, 6], [1, 3], [4, 7], [3, 6], [7, 2], [5, 3]], [[5, 1], [4, 2], [4, 7], [1, 7]], [1, 5]], [[[1, 5], [1, 7], [2, 4]], [[1, 3], [2, 7], [3, 5], [3, 6], [5, 6]], [[4, 7]]]], [[[[1, 6], [4, 3], [7, 5], [5, 4], [6, 1]], [[2, 1], [3, 1], [4, 7], [1, 5], [6, 4]], [2, 7]], [[[1, 2], [1, 3], [1, 5], [4, 6], [4, 7]], [[1, 6], [3, 4], [4, 5], [5, 7]], []]], [[[[1, 2], [4, 3], [5, 2], [1, 7]], [[2, 1], [4, 2], [4, 3], [1, 2], [3, 5]], [3]], [[[2, 4], [3, 5]], [[1, 7], [2, 5]], [[1, 2], [3, 4]]]], [[[[4, 7], [4, 6], [3, 7], [3, 1], [7, 3], [1, 5]], [[4, 6], [3, 7]], [2, 7, 4, 1]], [[], [[1, 3], [1, 5]], [[3, 7], [4, 6], [4, 7]]]], [[[[7, 6], [2, 6], [2, 5]], [[4, 7], [7, 1], [4, 3], [2, 6], [3, 1]], [5, 3, 1, 2]], [[[1, 3], [1, 7], [3, 4], [4, 7]], [[6, 7]], [[2, 5], [2, 6]]]], [[[[6, 2], [7, 6]], [[7, 6]], []], [[], [[2, 6]], [[6, 7]]]], [[[[2, 5], [7, 1], [1, 7], [7, 5], [5, 3], [4, 6]], [[1, 7]], [5, 4]], [[], [[2, 5], [3, 5], [4, 6], [5, 7]], [[1, 7]]]]], [[[[[5, 3]], [[2, 6], [1, 3], [4, 6], [3, 7]], [1, 6, 2, 7]], [[[1, 3], [2, 6], [3, 7], [4, 6]], [[3, 5]], []]], [[[[3, 1], [3, 2], [4, 6], [5, 1], [2, 5], [2, 7]], [[6, 4], [6, 2], [1, 6], [3, 2], [1, 7], [2, 7]], [7, 3]], [[[1, 6], [1, 7], [2, 6]], [[1, 3], [1, 5], [2, 5]], [[2, 3], [2, 7], [4, 6]]]], [[[[1, 5], [3, 5], [1, 4], [3, 2], [5, 4]], [[4, 3], [4, 5], [2, 5], [2, 3], [1, 5], [6, 4], [5, 5]], [1, 4]], [[[2, 5], [3, 4], [4, 6]], [[3, 5]], [[1, 4], [1, 5], [2, 3], [4, 5]]]], [[[[2, 7], [1, 7], [4, 3], [2, 5], [7, 2], [6, 5]], [[3, 5], [3, 7], [1, 4], [3, 7], [3, 6], [5, 3]], []], [[[1, 4], [3, 5], [3, 6], [3, 7]], [[1, 7], [2, 5], [2, 7], [3, 4], [5, 6]], []]], [[[[2, 1], [6, 5], [2, 3], [6, 2], [4, 5]], [[3, 6]], [6]], [[[3, 6]], [[1, 2], [2, 3], [2, 6], [4, 5], [5, 6]], []]], [[[[7, 3], [4, 6], [3, 7], [7, 5], [4, 2]], [[2, 3], [1, 5], [6, 1], [7, 5], [4, 4]], [2, 6]], [[[1, 5], [1, 6], [2, 3]], [[2, 4], [3, 7], [4, 6]], [[5, 7]]]], [[[[4, 1]], [[4, 1], [4, 1]], [5, 4, 6]], [[], [], [[1, 4]]]], [[[[5, 1], [7, 1], [5, 3], [6, 2], [7, 5]], [[3, 7], [4, 1], [5, 6], [4, 7]], [1, 6, 4, 5]], [[[1, 4], [3, 7], [4, 7], [5, 6]], [[1, 7], [2, 6], [3, 5], [5, 7]], [[1, 5]]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("case %d" % i, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
case 0[[[3, 5], [5, 6]], [[3, 5], [5, 6], [6, 7]], []][[[3, 5], [5, 6]], [[6, 7]], []]Failed
case 1[[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 4], [1, 7], [2, 6], [3, 4], [3, 7], [4, 7]], []][[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 7], [2, 6]], []]Failed
case 2[[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [4, 5], [6, 7]], []][[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [6, 7]], []]Failed
case 3[[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3], [1, 4], [3, 6], [4, 5], [4, 6]], [[3, 4]]][[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3]], [[3, 4]]]Failed
case 4[[[2, 7]], [[2, 7], [5, 7]], []][[[2, 7]], [[5, 7]], []]Failed
case 5[[], [[2, 6]], [[5, 7]]][[], [[2, 6]], [[5, 7]]]Passed
case 6[[[2, 3]], [[1, 6], [1, 7], [2, 3], [3, 4], [3, 6], [4, 7]], []][[[2, 3]], [[1, 6], [1, 7], [3, 4], [3, 6], [4, 7]], []]Failed
case 7[[[2, 5], [3, 4]], [[2, 5], [3, 4], [3, 6], [3, 7]], []][[[2, 5], [3, 4]], [[3, 6], [3, 7]], []]Failed

SHA-256 / 7848f8ba252b4c5b5ad876eace8ea1486bb3877c133d9b936b9b317618b5bf73

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(prev, curr, asleep):
    def norm(p):
        return (min(p), max(p))
    P = {norm(p) for p in prev}
    C = {norm(p) for p in curr if p[0] != p[1]}
    sl = set(asleep)
    for p in P:
        if p[0] in sl and p[1] in sl:
            C.add(p)
    begin = sorted(C - P)
    end = sorted(C - P)
    keep = sorted(P & C)
    return [[list(p) for p in begin], [list(p) for p in end], [list(p) for p in keep]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[[7, 6]], [[5, 3], [5, 6]], [1, 4]], [[[3, 5], [5, 6]], [[6, 7]], []]], [[[[1, 7], [7, 1], [1, 3], [2, 6]], [[3, 4], [3, 4], [4, 7], [4, 1], [7, 3], [4, 3]], []], [[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 7], [2, 6]], []]], [[[[2, 5], [3, 6], [1, 4], [6, 7], [1, 3], [6, 7]], [[4, 5], [1, 1]], [1, 2]], [[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [6, 7]], []]], [[[[1, 3], [1, 2], [3, 4]], [[4, 3], [3, 6], [1, 4], [4, 5], [6, 4], [7, 7]], [4, 1]], [[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3]], [[3, 4]]]], [[[[5, 7]], [[2, 7]], []], [[[2, 7]], [[5, 7]], []]], [[[[6, 2], [7, 5]], [[5, 7]], []], [[], [[2, 6]], [[5, 7]]]], [[[[4, 3], [7, 1], [6, 1], [3, 6], [7, 4]], [[3, 2], [2, 2]], [4, 1, 5]], [[[2, 3]], [[1, 6], [1, 7], [3, 4], [3, 6], [4, 7]], []]], [[[[3, 6], [3, 7]], [[5, 2], [4, 3], [5, 5]], []], [[[2, 5], [3, 4]], [[3, 6], [3, 7]], []]]], [[[[[2, 1], [3, 2]], [[1, 7], [7, 4], [1, 3], [6, 2], [2, 2]], [7, 2, 1, 6]], [[[1, 3], [1, 7], [2, 6], [4, 7]], [[2, 3]], [[1, 2]]]], [[[[3, 4], [3, 7]], [[7, 6], [2, 1], [1, 6]], []], [[[1, 2], [1, 6], [6, 7]], [[3, 4], [3, 7]], []]], [[[[7, 3], [6, 1], [5, 3], [2, 7]], [[5, 6], [5, 2], [1, 3], [2, 3]], []], [[[1, 3], [2, 3], [2, 5], [5, 6]], [[1, 6], [2, 7], [3, 5], [3, 7]], []]], [[[[3, 4], [4, 2], [1, 5], [5, 6], [3, 4], [3, 5]], [[1, 4]], [3, 6, 4]], [[[1, 4]], [[1, 5], [2, 4], [3, 5], [5, 6]], [[3, 4]]]], [[[[7, 1], [5, 7], [5, 3]], [[4, 2], [5, 2], [2, 4], [7, 6], [5, 2], [6, 7], [5, 5]], [7]], [[[2, 4], [2, 5], [6, 7]], [[1, 7], [3, 5], [5, 7]], []]], [[[[1, 5], [1, 7], [5, 1], [4, 2], [3, 5], [6, 7]], [[6, 4], [1, 3], [1, 2], [4, 6], [7, 5], [5, 5]], [1, 3]], [[[1, 2], [1, 3], [4, 6], [5, 7]], [[1, 5], [1, 7], [2, 4], [3, 5], [6, 7]], []]], [[[[2, 4], [5, 4], [1, 7], [6, 7]], [[5, 7], [7, 7]], [3]], [[[5, 7]], [[1, 7], [2, 4], [4, 5], [6, 7]], []]], [[[[7, 5], [1, 6], [3, 2]], [[5, 7]], [4, 1, 3, 6]], [[], [[2, 3]], [[1, 6], [5, 7]]]]], [[[[[3, 2]], [[2, 1]], [6]], [[[1, 2]], [[2, 3]], []]], [[[[1, 3], [4, 7], [6, 5]], [[3, 1]], [5, 6, 3]], [[], [[4, 7]], [[1, 3], [5, 6]]]], [[[[4, 3], [1, 3]], [[1, 6], [1, 7], [2, 6], [2, 2]], [4, 1, 2, 5]], [[[1, 6], [1, 7], [2, 6]], [[1, 3], [3, 4]], []]], [[[[5, 6], [5, 1], [2, 3]], [[5, 2], [7, 1], [7, 1], [4, 6]], [7]], [[[1, 7], [2, 5], [4, 6]], [[1, 5], [2, 3], [5, 6]], []]], [[[[3, 5], [2, 1], [2, 6], [2, 4], [1, 7], [5, 7]], [[6, 1], [2, 1]], []], [[[1, 6]], [[1, 7], [2, 4], [2, 6], [3, 5], [5, 7]], [[1, 2]]]], [[[[3, 5], [4, 5], [4, 5], [6, 1], [6, 5]], [[4, 3], [6, 7], [4, 1], [7, 3], [2, 4]], [2, 7, 5]], [[[1, 4], [2, 4], [3, 4], [3, 7], [6, 7]], [[1, 6], [3, 5], [4, 5], [5, 6]], []]], [[[[7, 3], [4, 3], [5, 1], [5, 4], [6, 7], [5, 4]], [[4, 5], [5, 4], [6, 7], [6, 6]], [4]], [[], [[1, 5], [3, 4], [3, 7]], [[4, 5], [6, 7]]]], [[[[7, 5], [3, 1], [4, 2], [4, 2]], [[3, 7]], [6, 2, 7, 4]], [[[3, 7]], [[1, 3], [5, 7]], [[2, 4]]]]], [[[[[2, 4], [4, 5], [1, 4], [5, 3], [7, 1]], [[7, 4], [3, 5], [6, 2], [1, 1]], [1]], [[[2, 6], [4, 7]], [[1, 4], [1, 7], [2, 4], [4, 5]], [[3, 5]]]], [[[[5, 6], [1, 3], [4, 7], [3, 6], [7, 2], [5, 3]], [[5, 1], [4, 2], [4, 7], [1, 7]], [1, 5]], [[[1, 5], [1, 7], [2, 4]], [[1, 3], [2, 7], [3, 5], [3, 6], [5, 6]], [[4, 7]]]], [[[[1, 6], [4, 3], [7, 5], [5, 4], [6, 1]], [[2, 1], [3, 1], [4, 7], [1, 5], [6, 4]], [2, 7]], [[[1, 2], [1, 3], [1, 5], [4, 6], [4, 7]], [[1, 6], [3, 4], [4, 5], [5, 7]], []]], [[[[1, 2], [4, 3], [5, 2], [1, 7]], [[2, 1], [4, 2], [4, 3], [1, 2], [3, 5]], [3]], [[[2, 4], [3, 5]], [[1, 7], [2, 5]], [[1, 2], [3, 4]]]], [[[[4, 7], [4, 6], [3, 7], [3, 1], [7, 3], [1, 5]], [[4, 6], [3, 7]], [2, 7, 4, 1]], [[], [[1, 3], [1, 5]], [[3, 7], [4, 6], [4, 7]]]], [[[[7, 6], [2, 6], [2, 5]], [[4, 7], [7, 1], [4, 3], [2, 6], [3, 1]], [5, 3, 1, 2]], [[[1, 3], [1, 7], [3, 4], [4, 7]], [[6, 7]], [[2, 5], [2, 6]]]], [[[[6, 2], [7, 6]], [[7, 6]], []], [[], [[2, 6]], [[6, 7]]]], [[[[2, 5], [7, 1], [1, 7], [7, 5], [5, 3], [4, 6]], [[1, 7]], [5, 4]], [[], [[2, 5], [3, 5], [4, 6], [5, 7]], [[1, 7]]]]], [[[[[5, 3]], [[2, 6], [1, 3], [4, 6], [3, 7]], [1, 6, 2, 7]], [[[1, 3], [2, 6], [3, 7], [4, 6]], [[3, 5]], []]], [[[[3, 1], [3, 2], [4, 6], [5, 1], [2, 5], [2, 7]], [[6, 4], [6, 2], [1, 6], [3, 2], [1, 7], [2, 7]], [7, 3]], [[[1, 6], [1, 7], [2, 6]], [[1, 3], [1, 5], [2, 5]], [[2, 3], [2, 7], [4, 6]]]], [[[[1, 5], [3, 5], [1, 4], [3, 2], [5, 4]], [[4, 3], [4, 5], [2, 5], [2, 3], [1, 5], [6, 4], [5, 5]], [1, 4]], [[[2, 5], [3, 4], [4, 6]], [[3, 5]], [[1, 4], [1, 5], [2, 3], [4, 5]]]], [[[[2, 7], [1, 7], [4, 3], [2, 5], [7, 2], [6, 5]], [[3, 5], [3, 7], [1, 4], [3, 7], [3, 6], [5, 3]], []], [[[1, 4], [3, 5], [3, 6], [3, 7]], [[1, 7], [2, 5], [2, 7], [3, 4], [5, 6]], []]], [[[[2, 1], [6, 5], [2, 3], [6, 2], [4, 5]], [[3, 6]], [6]], [[[3, 6]], [[1, 2], [2, 3], [2, 6], [4, 5], [5, 6]], []]], [[[[7, 3], [4, 6], [3, 7], [7, 5], [4, 2]], [[2, 3], [1, 5], [6, 1], [7, 5], [4, 4]], [2, 6]], [[[1, 5], [1, 6], [2, 3]], [[2, 4], [3, 7], [4, 6]], [[5, 7]]]], [[[[4, 1]], [[4, 1], [4, 1]], [5, 4, 6]], [[], [], [[1, 4]]]], [[[[5, 1], [7, 1], [5, 3], [6, 2], [7, 5]], [[3, 7], [4, 1], [5, 6], [4, 7]], [1, 6, 4, 5]], [[[1, 4], [3, 7], [4, 7], [5, 6]], [[1, 7], [2, 6], [3, 5], [5, 7]], [[1, 5]]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("case %d" % i, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
case 0[[[3, 5], [5, 6]], [[3, 5], [5, 6]], []][[[3, 5], [5, 6]], [[6, 7]], []]Failed
case 1[[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 4], [3, 4], [3, 7], [4, 7]], []][[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 7], [2, 6]], []]Failed
case 2[[[4, 5]], [[4, 5]], []][[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [6, 7]], []]Failed
case 3[[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 4], [3, 6], [4, 5], [4, 6]], [[3, 4]]][[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3]], [[3, 4]]]Failed
case 4[[[2, 7]], [[2, 7]], []][[[2, 7]], [[5, 7]], []]Failed
case 5[[], [], [[5, 7]]][[], [[2, 6]], [[5, 7]]]Failed
case 6[[[2, 3]], [[2, 3]], []][[[2, 3]], [[1, 6], [1, 7], [3, 4], [3, 6], [4, 7]], []]Failed
case 7[[[2, 5], [3, 4]], [[2, 5], [3, 4]], []][[[2, 5], [3, 4]], [[3, 6], [3, 7]], []]Failed

SHA-256 / 72c5dd16e66e18cdc7453970fe729da06e835b2a40cc4e6024095a74fd05c2a8

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(prev, curr, asleep):
    def norm(p):
        return (min(p), max(p))
    P = {norm(p) for p in prev}
    C = {norm(p) for p in curr if p[0] != p[1]}
    sl = set(asleep)
    for p in P:
        if p[0] in sl and p[1] in sl:
            C.add(p)
    begin = sorted(C - P)
    end = sorted(P - C)
    keep = sorted(P & C)
    return [[list(p) for p in begin], [list(p) for p in end], [list(p) for p in keep]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[[7, 6]], [[5, 3], [5, 6]], [1, 4]], [[[3, 5], [5, 6]], [[6, 7]], []]], [[[[1, 7], [7, 1], [1, 3], [2, 6]], [[3, 4], [3, 4], [4, 7], [4, 1], [7, 3], [4, 3]], []], [[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 7], [2, 6]], []]], [[[[2, 5], [3, 6], [1, 4], [6, 7], [1, 3], [6, 7]], [[4, 5], [1, 1]], [1, 2]], [[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [6, 7]], []]], [[[[1, 3], [1, 2], [3, 4]], [[4, 3], [3, 6], [1, 4], [4, 5], [6, 4], [7, 7]], [4, 1]], [[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3]], [[3, 4]]]], [[[[5, 7]], [[2, 7]], []], [[[2, 7]], [[5, 7]], []]], [[[[6, 2], [7, 5]], [[5, 7]], []], [[], [[2, 6]], [[5, 7]]]], [[[[4, 3], [7, 1], [6, 1], [3, 6], [7, 4]], [[3, 2], [2, 2]], [4, 1, 5]], [[[2, 3]], [[1, 6], [1, 7], [3, 4], [3, 6], [4, 7]], []]], [[[[3, 6], [3, 7]], [[5, 2], [4, 3], [5, 5]], []], [[[2, 5], [3, 4]], [[3, 6], [3, 7]], []]]], [[[[[2, 1], [3, 2]], [[1, 7], [7, 4], [1, 3], [6, 2], [2, 2]], [7, 2, 1, 6]], [[[1, 3], [1, 7], [2, 6], [4, 7]], [[2, 3]], [[1, 2]]]], [[[[3, 4], [3, 7]], [[7, 6], [2, 1], [1, 6]], []], [[[1, 2], [1, 6], [6, 7]], [[3, 4], [3, 7]], []]], [[[[7, 3], [6, 1], [5, 3], [2, 7]], [[5, 6], [5, 2], [1, 3], [2, 3]], []], [[[1, 3], [2, 3], [2, 5], [5, 6]], [[1, 6], [2, 7], [3, 5], [3, 7]], []]], [[[[3, 4], [4, 2], [1, 5], [5, 6], [3, 4], [3, 5]], [[1, 4]], [3, 6, 4]], [[[1, 4]], [[1, 5], [2, 4], [3, 5], [5, 6]], [[3, 4]]]], [[[[7, 1], [5, 7], [5, 3]], [[4, 2], [5, 2], [2, 4], [7, 6], [5, 2], [6, 7], [5, 5]], [7]], [[[2, 4], [2, 5], [6, 7]], [[1, 7], [3, 5], [5, 7]], []]], [[[[1, 5], [1, 7], [5, 1], [4, 2], [3, 5], [6, 7]], [[6, 4], [1, 3], [1, 2], [4, 6], [7, 5], [5, 5]], [1, 3]], [[[1, 2], [1, 3], [4, 6], [5, 7]], [[1, 5], [1, 7], [2, 4], [3, 5], [6, 7]], []]], [[[[2, 4], [5, 4], [1, 7], [6, 7]], [[5, 7], [7, 7]], [3]], [[[5, 7]], [[1, 7], [2, 4], [4, 5], [6, 7]], []]], [[[[7, 5], [1, 6], [3, 2]], [[5, 7]], [4, 1, 3, 6]], [[], [[2, 3]], [[1, 6], [5, 7]]]]], [[[[[3, 2]], [[2, 1]], [6]], [[[1, 2]], [[2, 3]], []]], [[[[1, 3], [4, 7], [6, 5]], [[3, 1]], [5, 6, 3]], [[], [[4, 7]], [[1, 3], [5, 6]]]], [[[[4, 3], [1, 3]], [[1, 6], [1, 7], [2, 6], [2, 2]], [4, 1, 2, 5]], [[[1, 6], [1, 7], [2, 6]], [[1, 3], [3, 4]], []]], [[[[5, 6], [5, 1], [2, 3]], [[5, 2], [7, 1], [7, 1], [4, 6]], [7]], [[[1, 7], [2, 5], [4, 6]], [[1, 5], [2, 3], [5, 6]], []]], [[[[3, 5], [2, 1], [2, 6], [2, 4], [1, 7], [5, 7]], [[6, 1], [2, 1]], []], [[[1, 6]], [[1, 7], [2, 4], [2, 6], [3, 5], [5, 7]], [[1, 2]]]], [[[[3, 5], [4, 5], [4, 5], [6, 1], [6, 5]], [[4, 3], [6, 7], [4, 1], [7, 3], [2, 4]], [2, 7, 5]], [[[1, 4], [2, 4], [3, 4], [3, 7], [6, 7]], [[1, 6], [3, 5], [4, 5], [5, 6]], []]], [[[[7, 3], [4, 3], [5, 1], [5, 4], [6, 7], [5, 4]], [[4, 5], [5, 4], [6, 7], [6, 6]], [4]], [[], [[1, 5], [3, 4], [3, 7]], [[4, 5], [6, 7]]]], [[[[7, 5], [3, 1], [4, 2], [4, 2]], [[3, 7]], [6, 2, 7, 4]], [[[3, 7]], [[1, 3], [5, 7]], [[2, 4]]]]], [[[[[2, 4], [4, 5], [1, 4], [5, 3], [7, 1]], [[7, 4], [3, 5], [6, 2], [1, 1]], [1]], [[[2, 6], [4, 7]], [[1, 4], [1, 7], [2, 4], [4, 5]], [[3, 5]]]], [[[[5, 6], [1, 3], [4, 7], [3, 6], [7, 2], [5, 3]], [[5, 1], [4, 2], [4, 7], [1, 7]], [1, 5]], [[[1, 5], [1, 7], [2, 4]], [[1, 3], [2, 7], [3, 5], [3, 6], [5, 6]], [[4, 7]]]], [[[[1, 6], [4, 3], [7, 5], [5, 4], [6, 1]], [[2, 1], [3, 1], [4, 7], [1, 5], [6, 4]], [2, 7]], [[[1, 2], [1, 3], [1, 5], [4, 6], [4, 7]], [[1, 6], [3, 4], [4, 5], [5, 7]], []]], [[[[1, 2], [4, 3], [5, 2], [1, 7]], [[2, 1], [4, 2], [4, 3], [1, 2], [3, 5]], [3]], [[[2, 4], [3, 5]], [[1, 7], [2, 5]], [[1, 2], [3, 4]]]], [[[[4, 7], [4, 6], [3, 7], [3, 1], [7, 3], [1, 5]], [[4, 6], [3, 7]], [2, 7, 4, 1]], [[], [[1, 3], [1, 5]], [[3, 7], [4, 6], [4, 7]]]], [[[[7, 6], [2, 6], [2, 5]], [[4, 7], [7, 1], [4, 3], [2, 6], [3, 1]], [5, 3, 1, 2]], [[[1, 3], [1, 7], [3, 4], [4, 7]], [[6, 7]], [[2, 5], [2, 6]]]], [[[[6, 2], [7, 6]], [[7, 6]], []], [[], [[2, 6]], [[6, 7]]]], [[[[2, 5], [7, 1], [1, 7], [7, 5], [5, 3], [4, 6]], [[1, 7]], [5, 4]], [[], [[2, 5], [3, 5], [4, 6], [5, 7]], [[1, 7]]]]], [[[[[5, 3]], [[2, 6], [1, 3], [4, 6], [3, 7]], [1, 6, 2, 7]], [[[1, 3], [2, 6], [3, 7], [4, 6]], [[3, 5]], []]], [[[[3, 1], [3, 2], [4, 6], [5, 1], [2, 5], [2, 7]], [[6, 4], [6, 2], [1, 6], [3, 2], [1, 7], [2, 7]], [7, 3]], [[[1, 6], [1, 7], [2, 6]], [[1, 3], [1, 5], [2, 5]], [[2, 3], [2, 7], [4, 6]]]], [[[[1, 5], [3, 5], [1, 4], [3, 2], [5, 4]], [[4, 3], [4, 5], [2, 5], [2, 3], [1, 5], [6, 4], [5, 5]], [1, 4]], [[[2, 5], [3, 4], [4, 6]], [[3, 5]], [[1, 4], [1, 5], [2, 3], [4, 5]]]], [[[[2, 7], [1, 7], [4, 3], [2, 5], [7, 2], [6, 5]], [[3, 5], [3, 7], [1, 4], [3, 7], [3, 6], [5, 3]], []], [[[1, 4], [3, 5], [3, 6], [3, 7]], [[1, 7], [2, 5], [2, 7], [3, 4], [5, 6]], []]], [[[[2, 1], [6, 5], [2, 3], [6, 2], [4, 5]], [[3, 6]], [6]], [[[3, 6]], [[1, 2], [2, 3], [2, 6], [4, 5], [5, 6]], []]], [[[[7, 3], [4, 6], [3, 7], [7, 5], [4, 2]], [[2, 3], [1, 5], [6, 1], [7, 5], [4, 4]], [2, 6]], [[[1, 5], [1, 6], [2, 3]], [[2, 4], [3, 7], [4, 6]], [[5, 7]]]], [[[[4, 1]], [[4, 1], [4, 1]], [5, 4, 6]], [[], [], [[1, 4]]]], [[[[5, 1], [7, 1], [5, 3], [6, 2], [7, 5]], [[3, 7], [4, 1], [5, 6], [4, 7]], [1, 6, 4, 5]], [[[1, 4], [3, 7], [4, 7], [5, 6]], [[1, 7], [2, 6], [3, 5], [5, 7]], [[1, 5]]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("case %d" % i, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
case 0[[[3, 5], [5, 6]], [[6, 7]], []][[[3, 5], [5, 6]], [[6, 7]], []]Passed
case 1[[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 7], [2, 6]], []][[[1, 4], [3, 4], [3, 7], [4, 7]], [[1, 3], [1, 7], [2, 6]], []]Passed
case 2[[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [6, 7]], []][[[4, 5]], [[1, 3], [1, 4], [2, 5], [3, 6], [6, 7]], []]Passed
case 3[[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3]], [[3, 4]]][[[1, 4], [3, 6], [4, 5], [4, 6]], [[1, 2], [1, 3]], [[3, 4]]]Passed
case 4[[[2, 7]], [[5, 7]], []][[[2, 7]], [[5, 7]], []]Passed
case 5[[], [[2, 6]], [[5, 7]]][[], [[2, 6]], [[5, 7]]]Passed
case 6[[[2, 3]], [[1, 6], [1, 7], [3, 4], [3, 6], [4, 7]], []][[[2, 3]], [[1, 6], [1, 7], [3, 4], [3, 6], [4, 7]], []]Passed
case 7[[[2, 5], [3, 4]], [[3, 6], [3, 7]], []][[[2, 5], [3, 4]], [[3, 6], [3, 7]], []]Passed

SHA-256 / 21e329f6fbfd9e04b5bbcf50c4ec68ac5929bb93da9681fd0c39c659dd74cd24

Verification & scope

A deterministic bounded teaching model with stipulated toy conventions; not a production physics engine or spatial index. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:59.925391+00:00.

Case digest / 5ee2e546f3fe44d80d7cbe62cf6f6b22ec3bf4723437214ee6de758afa8170e2