FA-88656 / Mesh topology invariants / Open access
Edge flip reads the second apex from the wrong corner · case 01
The second apex is an endpoint of the flipped edge, so valid flips are refused as "edge-exists".
ROOT CAUSE
For the b->a triangle the apex is read at corner j+1 instead of j+2.
VERIFIED REPAIR
The apex is the corner after the half-edge end, (j+2) mod 3.
Unsuccessful approach: Reading corner j returns b itself.
Case contract
Input [faces, a, b] for oriented triangles. The flip needs a triangle holding half-edge a->b (apex c) and one holding b->a (apex d), else "boundary"; exactly two faces may contain both a and b, else "non-manifold"; c==d is "degenerate"; an existing undirected edge c-d is "edge-exists". Otherwise replace the first triangle in place by [c,a,d] and the second by [d,b,c] and return the face list.
Why this case matters
Mesh processing pipelines (remeshing, export, simulation, printing) trust these topological counts and adjacency answers; a wrong invariant silently accepts broken meshes or rejects valid ones.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces,a,b=x
fs=[list(f) for f in faces]
t1=t2=None
for i,f in enumerate(fs):
for j in range(3):
if f[j]==a and f[(j+1)%3]==b: t1=(i,f[(j+2)%3])
if f[j]==b and f[(j+1)%3]==a: t2=(i,f[(j+1)%3])
if t1 is None or t2 is None: return 'boundary'
cnt=sum(1 for f in fs if a in f and b in f)
if cnt!=2: return 'non-manifold'
c,d=t1[1],t2[1]
if c==d: return 'degenerate'
for f in fs:
for j in range(3):
if {f[j],f[(j+1)%3]}=={c,d}: return 'edge-exists'
fs[t1[0]]=[c,a,d]
fs[t2[0]]=[d,b,c]
return fs
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold']], [['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]]], [['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']]]
for label, args, expected in fixtures[N-1]:
check(label, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| square diagonal | edge-exists | [[0, 1, 3], [3, 2, 0]] | Failed |
| square diagonal reversed | edge-exists | [[0, 1, 3], [3, 2, 0]] | Failed |
| rim edge | boundary | boundary | Passed |
| disk spoke | edge-exists | [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]] | Failed |
| tetrahedron edge | edge-exists | edge-exists | Passed |
| octahedron edge | edge-exists | [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]] | Failed |
| book spine | non-manifold | non-manifold | Passed |
SHA-256 / d786de8a152e74d55ae6d4d868547a39e42d13d2e5857706049c43fd3f30ae15
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces,a,b=x
fs=[list(f) for f in faces]
t1=t2=None
for i,f in enumerate(fs):
for j in range(3):
if f[j]==a and f[(j+1)%3]==b: t1=(i,f[(j+2)%3])
if f[j]==b and f[(j+1)%3]==a: t2=(i,f[j])
if t1 is None or t2 is None: return 'boundary'
cnt=sum(1 for f in fs if a in f and b in f)
if cnt!=2: return 'non-manifold'
c,d=t1[1],t2[1]
if c==d: return 'degenerate'
for f in fs:
for j in range(3):
if {f[j],f[(j+1)%3]}=={c,d}: return 'edge-exists'
fs[t1[0]]=[c,a,d]
fs[t2[0]]=[d,b,c]
return fs
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold']], [['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]]], [['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']]]
for label, args, expected in fixtures[N-1]:
check(label, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| square diagonal | edge-exists | [[0, 1, 3], [3, 2, 0]] | Failed |
| square diagonal reversed | edge-exists | [[0, 1, 3], [3, 2, 0]] | Failed |
| rim edge | boundary | boundary | Passed |
| disk spoke | edge-exists | [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]] | Failed |
| tetrahedron edge | edge-exists | edge-exists | Passed |
| octahedron edge | edge-exists | [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]] | Failed |
| book spine | non-manifold | non-manifold | Passed |
SHA-256 / f08076448d4cbeaeac622a158b077b59d5565ef8c7e449b888c509480f43bb55
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces,a,b=x
fs=[list(f) for f in faces]
t1=t2=None
for i,f in enumerate(fs):
for j in range(3):
if f[j]==a and f[(j+1)%3]==b: t1=(i,f[(j+2)%3])
if f[j]==b and f[(j+1)%3]==a: t2=(i,f[(j+2)%3])
if t1 is None or t2 is None: return 'boundary'
cnt=sum(1 for f in fs if a in f and b in f)
if cnt!=2: return 'non-manifold'
c,d=t1[1],t2[1]
if c==d: return 'degenerate'
for f in fs:
for j in range(3):
if {f[j],f[(j+1)%3]}=={c,d}: return 'edge-exists'
fs[t1[0]]=[c,a,d]
fs[t2[0]]=[d,b,c]
return fs
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold']], [['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]]], [['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']]]
for label, args, expected in fixtures[N-1]:
check(label, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| square diagonal | [[0, 1, 3], [3, 2, 0]] | [[0, 1, 3], [3, 2, 0]] | Passed |
| square diagonal reversed | [[0, 1, 3], [3, 2, 0]] | [[0, 1, 3], [3, 2, 0]] | Passed |
| rim edge | boundary | boundary | Passed |
| disk spoke | [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]] | [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]] | Passed |
| tetrahedron edge | edge-exists | edge-exists | Passed |
| octahedron edge | [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]] | [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]] | Passed |
| book spine | non-manifold | non-manifold | Passed |
SHA-256 / aa64a4705028691b10d3cacba688947d83c8ab1f3432a898ac2a9dc09153d970
Verification & scope
Pure combinatorial teaching model over integer face lists with a stipulated contract; no geometry kernel or file format is implied. 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:51:10.122250+00:00.
Case digest / 15f9be81313b3f0e4e02d1c25460c6ce0028fecd16997555f58bc3327403d34a