{"abstract":"Boundary vertices with more than one incident triangle are reported interior.","category":"Mesh topology invariants","checks":7,"contract":"Input: triangle faces. For each referenced vertex v, its link is the set of opposite edges of incident triangles. v is \"nonmanifold\" if a link vertex has degree above 2 or the link graph is disconnected, \"interior\" if every link vertex has degree 2, else \"boundary\". Return {vertex string: class}.","contract_signature":"x","evaluation_group":"w2-mesh_topology_invariants-vertex-link","failed_approach":"Counting at least three incident triangles also labels wide boundary fans interior.","family":"w2-mesh_topology_invariants-vertex-link-interior-classification","id":"FA-88426","implementations":{"attempt":{"sha256":"74544a4fae395d59ede27c3edf843f86ec16db041a74434f3b693d0770330bbe","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    faces=x\n    link={}\n    for f in faces:\n        for i in range(3):\n            v=f[i]\n            a=f[(i+1)%3]\n            b=f[(i+2)%3]\n            link.setdefault(v,[]).append((a,b))\n    out={}\n    for v in sorted(link):\n        es=link[v]\n        deg={}\n        for a,b in es:\n            deg[a]=deg.get(a,0)+1\n            deg[b]=deg.get(b,0)+1\n        if any(d>2 for d in deg.values()):\n            out[str(v)]='nonmanifold'\n            continue\n        adj={}\n        for a,b in es:\n            adj.setdefault(a,[]).append(b)\n            adj.setdefault(b,[]).append(a)\n        start=next(iter(adj))\n        stack=[start]\n        seen={start}\n        while stack:\n            u=stack.pop()\n            for w in adj.get(u,[]):\n                if w not in seen:\n                    seen.add(w)\n                    stack.append(w)\n        if len(seen)!=len(adj): out[str(v)]='nonmanifold'\n        elif len(es)>=3: out[str(v)]='interior'\n        else: out[str(v)]='boundary'\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior'}], ['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], {'0': 'interior', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary'}], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['bowtie', [[[0, 1, 2], [0, 3, 4]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['octahedron', [[[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': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}]], [['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['octahedron', [[[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': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}], ['open cylinder', [[[0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary'}], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'interior', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['double disk pinch', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [0, 6, 7], [0, 7, 8], [0, 8, 6]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}]], [['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}], ['open cylinder', [[[0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary'}], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'interior', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['double disk pinch', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [0, 6, 7], [0, 7, 8], [0, 8, 6]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['single triangle', [[[0, 1, 2]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary'}], ['two triangles sharing edge', [[[0, 1, 2], [2, 1, 3]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary'}]], [['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior'}], ['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], {'0': 'interior', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary'}], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['bowtie', [[[0, 1, 2], [0, 3, 4]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'interior', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['two triangles sharing edge', [[[0, 1, 2], [2, 1, 3]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary'}]], [['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['bowtie', [[[0, 1, 2], [0, 3, 4]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['octahedron', [[[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': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}], ['open cylinder', [[[0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary'}], ['double disk pinch', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [0, 6, 7], [0, 7, 8], [0, 8, 6]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"aae0595f907b4c8243f9c60d2c69e5dc8a2164d81348af6ce4a34a9a3b8ff9f3","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    faces=x\n    link={}\n    for f in faces:\n        for i in range(3):\n            v=f[i]\n            a=f[(i+1)%3]\n            b=f[(i+2)%3]\n            link.setdefault(v,[]).append((a,b))\n    out={}\n    for v in sorted(link):\n        es=link[v]\n        deg={}\n        for a,b in es:\n            deg[a]=deg.get(a,0)+1\n            deg[b]=deg.get(b,0)+1\n        if any(d>2 for d in deg.values()):\n            out[str(v)]='nonmanifold'\n            continue\n        adj={}\n        for a,b in es:\n            adj.setdefault(a,[]).append(b)\n            adj.setdefault(b,[]).append(a)\n        start=next(iter(adj))\n        stack=[start]\n        seen={start}\n        while stack:\n            u=stack.pop()\n            for w in adj.get(u,[]):\n                if w not in seen:\n                    seen.add(w)\n                    stack.append(w)\n        if len(seen)!=len(adj): out[str(v)]='nonmanifold'\n        elif any(d==2 for d in deg.values()): out[str(v)]='interior'\n        else: out[str(v)]='boundary'\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior'}], ['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], {'0': 'interior', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary'}], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['bowtie', [[[0, 1, 2], [0, 3, 4]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['octahedron', [[[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': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}]], [['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['octahedron', [[[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': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}], ['open cylinder', [[[0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary'}], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'interior', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['double disk pinch', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [0, 6, 7], [0, 7, 8], [0, 8, 6]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}]], [['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}], ['open cylinder', [[[0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary'}], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'interior', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['double disk pinch', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [0, 6, 7], [0, 7, 8], [0, 8, 6]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['single triangle', [[[0, 1, 2]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary'}], ['two triangles sharing edge', [[[0, 1, 2], [2, 1, 3]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary'}]], [['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior'}], ['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], {'0': 'interior', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary'}], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['bowtie', [[[0, 1, 2], [0, 3, 4]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'interior', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}], ['two triangles sharing edge', [[[0, 1, 2], [2, 1, 3]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary'}]], [['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['bowtie', [[[0, 1, 2], [0, 3, 4]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['book', [[[0, 1, 2], [1, 0, 3], [0, 1, 4]]], {'0': 'nonmanifold', '1': 'nonmanifold', '2': 'boundary', '3': 'boundary', '4': 'boundary'}], ['octahedron', [[[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': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior'}], ['torus', [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]]], {'0': 'interior', '1': 'interior', '2': 'interior', '3': 'interior', '4': 'interior', '5': 'interior', '6': 'interior', '7': 'interior', '8': 'interior'}], ['open cylinder', [[[0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]]], {'0': 'boundary', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary'}], ['double disk pinch', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [0, 6, 7], [0, 7, 8], [0, 8, 6]]], {'0': 'nonmanifold', '1': 'boundary', '2': 'boundary', '3': 'boundary', '4': 'boundary', '5': 'boundary', '6': 'boundary', '7': 'boundary', '8': 'boundary'}]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-mesh_topology_invariants-vertex-link-interior-classification","generated_at":"2026-09-29T14:51:08.128897+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"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.","root_cause":"The interior test uses any(degree==2) instead of all.","sha256":"4b68c6df87019548730ba9584d5e9a88c31545e24af47140a802d4241293786e","title":"Vertex is called interior when any link vertex closes the fan · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":41.783,"exit_code":1,"observations":[{"actual":{"0":"interior","1":"interior","2":"interior","3":"interior"},"check":"tetrahedron","expected":{"0":"interior","1":"interior","2":"interior","3":"interior"},"passed":true},{"actual":{"0":"interior","1":"boundary","2":"boundary","3":"boundary","4":"boundary","5":"boundary"},"check":"disk","expected":{"0":"interior","1":"boundary","2":"boundary","3":"boundary","4":"boundary","5":"boundary"},"passed":true},{"actual":{"0":"interior","1":"boundary","2":"boundary","3":"boundary","4":"boundary"},"check":"fan","expected":{"0":"boundary","1":"boundary","2":"boundary","3":"boundary","4":"boundary"},"passed":false},{"actual":{"0":"nonmanifold","1":"boundary","2":"boundary","3":"boundary","4":"boundary"},"check":"bowtie","expected":{"0":"nonmanifold","1":"boundary","2":"boundary","3":"boundary","4":"boundary"},"passed":true},{"actual":{"0":"nonmanifold","1":"nonmanifold","2":"boundary","3":"boundary","4":"boundary"},"check":"book","expected":{"0":"nonmanifold","1":"nonmanifold","2":"boundary","3":"boundary","4":"boundary"},"passed":true},{"actual":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior"},"check":"octahedron","expected":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior"},"passed":true},{"actual":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior","6":"interior","7":"interior","8":"interior"},"check":"torus","expected":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior","6":"interior","7":"interior","8":"interior"},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"tetrahedron\", \"actual\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\"}, \"expected\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\"}, \"passed\": true}, {\"check\": \"disk\", \"actual\": {\"0\": \"interior\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\", \"5\": \"boundary\"}, \"expected\": {\"0\": \"interior\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\", \"5\": \"boundary\"}, \"passed\": true}, {\"check\": \"fan\", \"actual\": {\"0\": \"interior\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"expected\": {\"0\": \"boundary\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"passed\": false}, {\"check\": \"bowtie\", \"actual\": {\"0\": \"nonmanifold\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"expected\": {\"0\": \"nonmanifold\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"passed\": true}, {\"check\": \"book\", \"actual\": {\"0\": \"nonmanifold\", \"1\": \"nonmanifold\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"expected\": {\"0\": \"nonmanifold\", \"1\": \"nonmanifold\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"passed\": true}, {\"check\": \"octahedron\", \"actual\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\"}, \"expected\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\"}, \"passed\": true}, {\"check\": \"torus\", \"actual\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\", \"6\": \"interior\", \"7\": \"interior\", \"8\": \"interior\"}, \"expected\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\", \"6\": \"interior\", \"7\": \"interior\", \"8\": \"interior\"}, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":42.288,"exit_code":1,"observations":[{"actual":{"0":"interior","1":"interior","2":"interior","3":"interior"},"check":"tetrahedron","expected":{"0":"interior","1":"interior","2":"interior","3":"interior"},"passed":true},{"actual":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior"},"check":"disk","expected":{"0":"interior","1":"boundary","2":"boundary","3":"boundary","4":"boundary","5":"boundary"},"passed":false},{"actual":{"0":"interior","1":"boundary","2":"interior","3":"interior","4":"boundary"},"check":"fan","expected":{"0":"boundary","1":"boundary","2":"boundary","3":"boundary","4":"boundary"},"passed":false},{"actual":{"0":"nonmanifold","1":"boundary","2":"boundary","3":"boundary","4":"boundary"},"check":"bowtie","expected":{"0":"nonmanifold","1":"boundary","2":"boundary","3":"boundary","4":"boundary"},"passed":true},{"actual":{"0":"nonmanifold","1":"nonmanifold","2":"boundary","3":"boundary","4":"boundary"},"check":"book","expected":{"0":"nonmanifold","1":"nonmanifold","2":"boundary","3":"boundary","4":"boundary"},"passed":true},{"actual":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior"},"check":"octahedron","expected":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior"},"passed":true},{"actual":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior","6":"interior","7":"interior","8":"interior"},"check":"torus","expected":{"0":"interior","1":"interior","2":"interior","3":"interior","4":"interior","5":"interior","6":"interior","7":"interior","8":"interior"},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"tetrahedron\", \"actual\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\"}, \"expected\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\"}, \"passed\": true}, {\"check\": \"disk\", \"actual\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\"}, \"expected\": {\"0\": \"interior\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\", \"5\": \"boundary\"}, \"passed\": false}, {\"check\": \"fan\", \"actual\": {\"0\": \"interior\", \"1\": \"boundary\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"boundary\"}, \"expected\": {\"0\": \"boundary\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"passed\": false}, {\"check\": \"bowtie\", \"actual\": {\"0\": \"nonmanifold\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"expected\": {\"0\": \"nonmanifold\", \"1\": \"boundary\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"passed\": true}, {\"check\": \"book\", \"actual\": {\"0\": \"nonmanifold\", \"1\": \"nonmanifold\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"expected\": {\"0\": \"nonmanifold\", \"1\": \"nonmanifold\", \"2\": \"boundary\", \"3\": \"boundary\", \"4\": \"boundary\"}, \"passed\": true}, {\"check\": \"octahedron\", \"actual\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\"}, \"expected\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\"}, \"passed\": true}, {\"check\": \"torus\", \"actual\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\", \"6\": \"interior\", \"7\": \"interior\", \"8\": \"interior\"}, \"expected\": {\"0\": \"interior\", \"1\": \"interior\", \"2\": \"interior\", \"3\": \"interior\", \"4\": \"interior\", \"5\": \"interior\", \"6\": \"interior\", \"7\": \"interior\", \"8\": \"interior\"}, \"passed\": true}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}