FA-88566 / Mesh topology invariants / Open access
Compaction keeps vertices referenced only by dropped faces · case 01
Orphan vertices from discarded degenerate faces remain in the output.
ROOT CAUSE
Referenced vertices are collected from all input faces instead of the kept faces.
VERIFIED REPAIR
Collect references after the degenerate faces are removed.
Unsuccessful approach: Filtering by corner count still keeps vertices of faces like [0,0,5].
Case contract
Input [verts, faces]: drop faces with fewer than 3 distinct vertices, then keep only vertices referenced by remaining faces, renumbered 0-based in increasing old-index order. Faces keep their corner order. Return [kept vertex payloads, remapped faces].
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):
verts,faces=x
keep=[]
for f in faces:
if len(set(f))<3: continue
keep.append(f)
used=sorted({v for f in faces for v in f})
remap={old:new for new,old in enumerate(used)}
return [[verts[o] for o in used],[[remap[v] for v in f] for f in keep]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]]], [['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]]]
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 |
|---|---|---|---|
| gap and degenerate | [['a', 'c', 'd', 'e', 'f'], [[0, 1, 2], [1, 3, 2]]] | [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]] | Failed |
| repeated but valid quad | [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]] | [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]] | Passed |
| first use differs from index order | [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]] | [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]] | Passed |
| only degenerate | [['x', 'y', 'z'], []] | [[], []] | Failed |
| two-corner face | [['x', 'y', 'z', 'w'], [[1, 2, 3]]] | [['y', 'z', 'w'], [[0, 1, 2]]] | Failed |
| no gaps | [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]] | [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]] | Passed |
| high gap | [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]] | [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]] | Passed |
SHA-256 / 7a1b0dc7b712448ce2e34e6ddd0f8f480f03b656d84cda235c745ffe713939e6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
verts,faces=x
keep=[]
for f in faces:
if len(set(f))<3: continue
keep.append(f)
used=sorted({v for f in faces if len(f)>=3 for v in f})
remap={old:new for new,old in enumerate(used)}
return [[verts[o] for o in used],[[remap[v] for v in f] for f in keep]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]]], [['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]]]
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 |
|---|---|---|---|
| gap and degenerate | [['a', 'c', 'd', 'e', 'f'], [[0, 1, 2], [1, 3, 2]]] | [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]] | Failed |
| repeated but valid quad | [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]] | [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]] | Passed |
| first use differs from index order | [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]] | [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]] | Passed |
| only degenerate | [['x', 'y', 'z'], []] | [[], []] | Failed |
| two-corner face | [['y', 'z', 'w'], [[0, 1, 2]]] | [['y', 'z', 'w'], [[0, 1, 2]]] | Passed |
| no gaps | [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]] | [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]] | Passed |
| high gap | [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]] | [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]] | Passed |
SHA-256 / 16084d3831b9307b93c0fe166676feebcacdccf6e6f30b59097e4a8ca7161ebb
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
verts,faces=x
keep=[]
for f in faces:
if len(set(f))<3: continue
keep.append(f)
used=sorted({v for f in keep for v in f})
remap={old:new for new,old in enumerate(used)}
return [[verts[o] for o in used],[[remap[v] for v in f] for f in keep]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]]], [['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['first use differs from index order', [[['v0', 'v1', 'v2', 'v3', 'v4'], [[4, 2, 3], [3, 2, 0]]]], [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['two-corner face', [[['x', 'y', 'z', 'w'], [[0, 1], [1, 2, 3]]]], [['y', 'z', 'w'], [[0, 1, 2]]]], ['no gaps', [[['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]]], [['gap and degenerate', [[['a', 'b', 'c', 'd', 'e', 'f'], [[0, 2, 3], [3, 3, 5], [2, 4, 3]]]], [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]]], ['repeated but valid quad', [[['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]]], ['only degenerate', [[['x', 'y', 'z'], [[0, 0, 1], [1, 2, 2]]]], [[], []]], ['high gap', [[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], [[5, 6, 7], [7, 6, 5, 1]]]], [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]]], ['degenerate references isolated vertex', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 3], [0, 0, 4]]]], [['b', 'c', 'd'], [[0, 1, 2]]]], ['polygon with non-consecutive repeat', [[['a', 'b', 'c', 'd', 'e'], [[1, 2, 1, 3], [4, 3, 2]]]], [['b', 'c', 'd', 'e'], [[0, 1, 0, 2], [3, 2, 1]]]], ['single triangle offset', [[['a', 'b', 'c', 'd', 'e', 'f'], [[3, 4, 5]]]], [['d', 'e', 'f'], [[0, 1, 2]]]]]]
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 |
|---|---|---|---|
| gap and degenerate | [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]] | [['a', 'c', 'd', 'e'], [[0, 1, 2], [1, 3, 2]]] | Passed |
| repeated but valid quad | [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]] | [['p', 'q', 'r', 's'], [[0, 1, 1, 2], [2, 1, 3]]] | Passed |
| first use differs from index order | [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]] | [['v0', 'v2', 'v3', 'v4'], [[3, 1, 2], [2, 1, 0]]] | Passed |
| only degenerate | [[], []] | [[], []] | Passed |
| two-corner face | [['y', 'z', 'w'], [[0, 1, 2]]] | [['y', 'z', 'w'], [[0, 1, 2]]] | Passed |
| no gaps | [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]] | [['a', 'b', 'c', 'd'], [[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]] | Passed |
| high gap | [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]] | [['b', 'f', 'g', 'h'], [[1, 2, 3], [3, 2, 1, 0]]] | Passed |
SHA-256 / d56b285559711f25fc2bcb0ee99d2b37f24eb025fb6136e296ca70c48075818d
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:09.411333+00:00.
Case digest / ae0541565b69b9454cc233db5b984809647a35b7694d7af83d5bd67606bb5643