FA-88646 / Mesh topology invariants / Open access
Edge flip accepts two triangles with the same apex · case 01
A folded pair is flipped into triangles that repeat a vertex.
ROOT CAUSE
The c == d degeneracy check is missing.
VERIFIED REPAIR
Return "degenerate" when both apices coincide.
Unsuccessful approach: Checking whether an apex equals an edge endpoint tests the wrong condition.
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+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]
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]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate']], [['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'], ['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]]]], [['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]]], ['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]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['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 |
| folded pair | [[2, 0, 2], [2, 1, 2]] | degenerate | Failed |
SHA-256 / 7e77966a036d12e4d027da6e0a58db22b312ac3ec2fc0c2c5e507c538949c400
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+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==a or d==b: 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]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate']], [['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'], ['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]]]], [['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]]], ['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]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['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 |
| folded pair | [[2, 0, 2], [2, 1, 2]] | degenerate | Failed |
SHA-256 / 50ba511ee434843048755ff7cc3feda75402623e9793fefeb5bf1f3b4e6490d9
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]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate']], [['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'], ['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]]]], [['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]]], ['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]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['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 |
| folded pair | degenerate | degenerate | Passed |
SHA-256 / 7f06cdfec3cf8ea69560da0ae85b94b0c02f7219032c9052744f1c7e181108a3
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.075947+00:00.
Case digest / 2b839e637a616dc66ddda110bb226cebeae7fc8062cf124e7ddf389abbe28d9f