{"abstract":"Points on axis-parallel edges and on vertices are not reported as boundary.","category":"GIS polygon topology","checks":8,"contract":"Input [point, rings]: exterior ring then hole rings, closed, integer coordinates. A point on any ring edge (exact cross product 0 and inside the closed segment bounding box) is \"boundary\". Otherwise a crossing-number test with the half-open rule (a.y > py) != (b.y > py) and ray toward +x decides containment: outside the exterior or inside any hole is \"exterior\", else \"interior\".","contract_signature":"x","evaluation_group":"w2-gis-polygon-topology-point-in-polygon-with-holes","failed_approach":"Checking only the x extent accepts points on the supporting line beyond the end of a vertical edge.","family":"w2-gis-polygon-topology-point-in-polygon-with-holes-segment-extent-test","id":"FA-70406","implementations":{"attempt":{"sha256":"d3ec9ac01d50f27c3052c1af44a5247780ddbee8db31eb4d73e1c3fdafa78d3d","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    pt, rings = x\n    px, py = pt\n    def on_seg(a, b):\n        cross = (b[0] - a[0]) * (py - a[1]) - (b[1] - a[1]) * (px - a[0])\n        if cross != 0:\n            return False\n        return min(a[0], b[0]) <= px <= max(a[0], b[0])\n    def inside(ring):\n        c = False\n        for a, b in zip(ring, ring[1:]):\n            if (a[1] > py) != (b[1] > py):\n                xi = a[0] + (py - a[1]) * (b[0] - a[0]) / (b[1] - a[1])\n                if px < xi:\n                    c = not c\n        return c\n    for ring in rings:\n        for a, b in zip(ring, ring[1:]):\n            if on_seg(a, b):\n                return 'boundary'\n    if not inside(rings[0]):\n        return 'exterior'\n    for hole in rings[1:]:\n        if inside(hole):\n            return 'exterior'\n    return 'interior'\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('control #0', [[1, 1], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #1', [[3, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #2', [[8, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #3', [[6, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #4', [[12, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #5', [[0, 0], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #6', [[2, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #3', [[6, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #4', [[12, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #5', [[0, 0], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #6', [[2, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #7', [[7, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #9', [[11, 11], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #10', [[13, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #6', [[2, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #7', [[7, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #8', [[8, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #9', [[11, 11], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #10', [[13, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #11', [[-1, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #12', [[6, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #7', [[7, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #10', [[13, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #11', [[-1, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #12', [[6, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #13', [[5, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #14', [[4, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #15', [[6, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #8', [[8, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #13', [[5, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #14', [[4, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #15', [[6, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #16', [[9, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #21', [[8, 1], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #24', [[9, 3], [[[0, 0], [8, 0], [4, 6], [0, 0]]]], 'exterior'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')]]\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":"0d08cb791efb99008ff22971bcebec0220e31574a16285fc07bd1be251d88f37","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    pt, rings = x\n    px, py = pt\n    def on_seg(a, b):\n        cross = (b[0] - a[0]) * (py - a[1]) - (b[1] - a[1]) * (px - a[0])\n        if cross != 0:\n            return False\n        return min(a[0], b[0]) < px < max(a[0], b[0]) and min(a[1], b[1]) < py < max(a[1], b[1])\n    def inside(ring):\n        c = False\n        for a, b in zip(ring, ring[1:]):\n            if (a[1] > py) != (b[1] > py):\n                xi = a[0] + (py - a[1]) * (b[0] - a[0]) / (b[1] - a[1])\n                if px < xi:\n                    c = not c\n        return c\n    for ring in rings:\n        for a, b in zip(ring, ring[1:]):\n            if on_seg(a, b):\n                return 'boundary'\n    if not inside(rings[0]):\n        return 'exterior'\n    for hole in rings[1:]:\n        if inside(hole):\n            return 'exterior'\n    return 'interior'\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('control #0', [[1, 1], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #1', [[3, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #2', [[8, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #3', [[6, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #4', [[12, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #5', [[0, 0], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #6', [[2, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #3', [[6, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #4', [[12, 6], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #5', [[0, 0], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #6', [[2, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #7', [[7, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #9', [[11, 11], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #10', [[13, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #6', [[2, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #7', [[7, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #8', [[8, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #9', [[11, 11], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #10', [[13, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #11', [[-1, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #12', [[6, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #7', [[7, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #10', [[13, 5], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #11', [[-1, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'exterior'), ('control #12', [[6, 12], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #13', [[5, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #14', [[4, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #15', [[6, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')], [('control #8', [[8, 9], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #13', [[5, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #14', [[4, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #15', [[6, 2], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #16', [[9, 3], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'boundary'), ('control #21', [[8, 1], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]]]], 'interior'), ('control #24', [[9, 3], [[[0, 0], [8, 0], [4, 6], [0, 0]]]], 'exterior'), ('regression #35', [[2, 8], [[[0, 0], [12, 0], [12, 12], [0, 12], [0, 0]], [[2, 2], [2, 5], [5, 5], [5, 2], [2, 2]], [[7, 3], [7, 9], [10, 9], [10, 3], [7, 3]], [[1, 7], [1, 10], [3, 10], [3, 7], [1, 7]]]], 'exterior')]]\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":"Stipulated deterministic toy contract on a bounded input domain; results are rounded as stated and no conformance with any published standard or library is claimed. 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-gis-polygon-topology-point-in-polygon-with-holes-segment-extent-test","generated_at":"2026-09-29T14:48:20.420763+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Parcel lookup, geofencing and spatial joins classify points against polygons with holes; lakes and courtyards must not count as inside.","root_cause":"The on-segment extent test uses strict inequalities, which reject every point on a horizontal or vertical edge.","sha256":"135c0f4c67de04d196e191041dde1103aafbb6774984b3769171522d006f01b7","title":"Point classification against a polygon with holes: segment extent test · 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.715,"exit_code":1,"observations":[{"actual":"interior","check":"control #0","expected":"interior","passed":true},{"actual":"exterior","check":"control #1","expected":"exterior","passed":true},{"actual":"exterior","check":"control #2","expected":"exterior","passed":true},{"actual":"interior","check":"control #3","expected":"interior","passed":true},{"actual":"boundary","check":"control #4","expected":"boundary","passed":true},{"actual":"boundary","check":"control #5","expected":"boundary","passed":true},{"actual":"boundary","check":"control #6","expected":"boundary","passed":true},{"actual":"boundary","check":"regression #35","expected":"exterior","passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"control #0\", \"actual\": \"interior\", \"expected\": \"interior\", \"passed\": true}, {\"check\": \"control #1\", \"actual\": \"exterior\", \"expected\": \"exterior\", \"passed\": true}, {\"check\": \"control #2\", \"actual\": \"exterior\", \"expected\": \"exterior\", \"passed\": true}, {\"check\": \"control #3\", \"actual\": \"interior\", \"expected\": \"interior\", \"passed\": true}, {\"check\": \"control #4\", \"actual\": \"boundary\", \"expected\": \"boundary\", \"passed\": true}, {\"check\": \"control #5\", \"actual\": \"boundary\", \"expected\": \"boundary\", \"passed\": true}, {\"check\": \"control #6\", \"actual\": \"boundary\", \"expected\": \"boundary\", \"passed\": true}, {\"check\": \"regression #35\", \"actual\": \"boundary\", \"expected\": \"exterior\", \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.37,"exit_code":1,"observations":[{"actual":"interior","check":"control #0","expected":"interior","passed":true},{"actual":"exterior","check":"control #1","expected":"exterior","passed":true},{"actual":"exterior","check":"control #2","expected":"exterior","passed":true},{"actual":"interior","check":"control #3","expected":"interior","passed":true},{"actual":"exterior","check":"control #4","expected":"boundary","passed":false},{"actual":"interior","check":"control #5","expected":"boundary","passed":false},{"actual":"exterior","check":"control #6","expected":"boundary","passed":false},{"actual":"exterior","check":"regression #35","expected":"exterior","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"control #0\", \"actual\": \"interior\", \"expected\": \"interior\", \"passed\": true}, {\"check\": \"control #1\", \"actual\": \"exterior\", \"expected\": \"exterior\", \"passed\": true}, {\"check\": \"control #2\", \"actual\": \"exterior\", \"expected\": \"exterior\", \"passed\": true}, {\"check\": \"control #3\", \"actual\": \"interior\", \"expected\": \"interior\", \"passed\": true}, {\"check\": \"control #4\", \"actual\": \"exterior\", \"expected\": \"boundary\", \"passed\": false}, {\"check\": \"control #5\", \"actual\": \"interior\", \"expected\": \"boundary\", \"passed\": false}, {\"check\": \"control #6\", \"actual\": \"exterior\", \"expected\": \"boundary\", \"passed\": false}, {\"check\": \"regression #35\", \"actual\": \"exterior\", \"expected\": \"exterior\", \"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."}}