FAILURE MAP
← Case archive

FA-70646 / GIS polygon topology / Open access

Area-weighted centroid of a multipolygon with holes: multipart accumulation · case 01

The centroid of a multipolygon equals the centroid of its last part.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The accumulators are reset for every part, discarding earlier parts.

VERIFIED REPAIR

At the multipart accumulation step restore `for rings in polys: for k, r in enumerate(rings):`, leaving the rest of the model unchanged.

Unsuccessful approach: Only the first part is accumulated.

Case contract

Input: a multipolygon as a list of polygons, each a list of closed rings (exterior first). Ring orientation is arbitrary: every ring contributes its absolute area and matching first moments, exteriors positively and holes negatively. Moments use the shoelace terms (xi + xi+1)*cross/6. If the total area is 0 return None, else the centroid [cx, cy] rounded to 6 decimals.

Why this case matters

Label placement, zonal summaries and map joins use polygon centroids; courtyards and multi-part parcels must pull the centroid correctly.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    polys = x
    A = Cx = Cy = 0.0
    for rings in polys:
        A = Cx = Cy = 0.0
        for k, r in enumerate(rings):
            a2 = mx = my = 0.0
            for p, q in zip(r, r[1:]):
                c = p[0] * q[1] - q[0] * p[1]
                a2 += c
                mx += (p[0] + q[0]) * c
                my += (p[1] + q[1]) * c
            sg = 1.0 if a2 >= 0 else -1.0
            w = 1.0 if k == 0 else -1.0
            A += w * sg * a2 / 2
            Cx += w * sg * mx / 6
            Cy += w * sg * my / 6
    if A == 0:
        return None
    return [round(Cx / A, 6), round(Cy / A, 6)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0])], [('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0]), ('regression #8', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]], [[8, 2], [8, 5], [11, 5], [11, 2], [8, 2]]]], [5.737288, 2.991525]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None)], [('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0]), ('regression #8', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]], [[8, 2], [8, 5], [11, 5], [11, 2], [8, 2]]]], [5.737288, 2.991525]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None), ('control #11', [[[[1, 1], [7, 2], [6, 8], [2, 6], [1, 1]]]], [4.121212, 4.10303]), ('regression #12', [[[[-6, -6], [0, -6], [0, 0], [-6, 0], [-6, -6]]], [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[5, -2], [7, -2], [7, 0], [5, 0], [5, -2]]]], [-1.438776, -2.010204]), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])], [('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None), ('control #11', [[[[1, 1], [7, 2], [6, 8], [2, 6], [1, 1]]]], [4.121212, 4.10303]), ('regression #12', [[[[-6, -6], [0, -6], [0, 0], [-6, 0], [-6, -6]]], [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[5, -2], [7, -2], [7, 0], [5, 0], [5, -2]]]], [-1.438776, -2.010204]), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])], [('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])]]
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 fixtureActualExpectedOutcome
control #0[5.0, 5.0][5.0, 5.0]Passed
regression #1[5.833333, 5.833333][5.833333, 5.833333]Passed
regression #2[4.752747, 4.752747][4.752747, 4.752747]Passed
regression #3[5.0, 5.0][5.0, 5.0]Passed
regression #4[15.0, 5.0][14.461538, 4.846154]Failed
regression #5[11.0, 11.0][3.8, 3.8]Failed
boundary #6NoneNonePassed
control #7[3.0, 2.0][3.0, 2.0]Passed

SHA-256 / 35f3a60ac7482bd26bb07b4fc15436cc03031e864810b73af1f7dbc8ff7f3100

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    polys = x
    A = Cx = Cy = 0.0
    for rings in polys[:1]:
        for k, r in enumerate(rings):
            a2 = mx = my = 0.0
            for p, q in zip(r, r[1:]):
                c = p[0] * q[1] - q[0] * p[1]
                a2 += c
                mx += (p[0] + q[0]) * c
                my += (p[1] + q[1]) * c
            sg = 1.0 if a2 >= 0 else -1.0
            w = 1.0 if k == 0 else -1.0
            A += w * sg * a2 / 2
            Cx += w * sg * mx / 6
            Cy += w * sg * my / 6
    if A == 0:
        return None
    return [round(Cx / A, 6), round(Cy / A, 6)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0])], [('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0]), ('regression #8', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]], [[8, 2], [8, 5], [11, 5], [11, 2], [8, 2]]]], [5.737288, 2.991525]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None)], [('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0]), ('regression #8', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]], [[8, 2], [8, 5], [11, 5], [11, 2], [8, 2]]]], [5.737288, 2.991525]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None), ('control #11', [[[[1, 1], [7, 2], [6, 8], [2, 6], [1, 1]]]], [4.121212, 4.10303]), ('regression #12', [[[[-6, -6], [0, -6], [0, 0], [-6, 0], [-6, -6]]], [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[5, -2], [7, -2], [7, 0], [5, 0], [5, -2]]]], [-1.438776, -2.010204]), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])], [('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None), ('control #11', [[[[1, 1], [7, 2], [6, 8], [2, 6], [1, 1]]]], [4.121212, 4.10303]), ('regression #12', [[[[-6, -6], [0, -6], [0, 0], [-6, 0], [-6, -6]]], [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[5, -2], [7, -2], [7, 0], [5, 0], [5, -2]]]], [-1.438776, -2.010204]), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])], [('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])]]
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 fixtureActualExpectedOutcome
control #0[5.0, 5.0][5.0, 5.0]Passed
regression #1[5.833333, 5.833333][5.833333, 5.833333]Passed
regression #2[4.752747, 4.752747][4.752747, 4.752747]Passed
regression #3[5.0, 5.0][5.0, 5.0]Passed
regression #4[1.0, 1.0][14.461538, 4.846154]Failed
regression #5[2.0, 2.0][3.8, 3.8]Failed
boundary #6NoneNonePassed
control #7[3.0, 2.0][3.0, 2.0]Passed

SHA-256 / cad9c0fcc4ce7ec009116fe7c57c2b6435003c0050a7df3ad42721792617979e

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    polys = x
    A = Cx = Cy = 0.0
    for rings in polys:
        for k, r in enumerate(rings):
            a2 = mx = my = 0.0
            for p, q in zip(r, r[1:]):
                c = p[0] * q[1] - q[0] * p[1]
                a2 += c
                mx += (p[0] + q[0]) * c
                my += (p[1] + q[1]) * c
            sg = 1.0 if a2 >= 0 else -1.0
            w = 1.0 if k == 0 else -1.0
            A += w * sg * a2 / 2
            Cx += w * sg * mx / 6
            Cy += w * sg * my / 6
    if A == 0:
        return None
    return [round(Cx / A, 6), round(Cy / A, 6)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0])], [('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0]), ('regression #8', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]], [[8, 2], [8, 5], [11, 5], [11, 2], [8, 2]]]], [5.737288, 2.991525]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None)], [('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('control #7', [[[[0, 0], [9, 0], [0, 6], [0, 0]]]], [3.0, 2.0]), ('regression #8', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]], [[8, 2], [8, 5], [11, 5], [11, 2], [8, 2]]]], [5.737288, 2.991525]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None), ('control #11', [[[[1, 1], [7, 2], [6, 8], [2, 6], [1, 1]]]], [4.121212, 4.10303]), ('regression #12', [[[[-6, -6], [0, -6], [0, 0], [-6, 0], [-6, -6]]], [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[5, -2], [7, -2], [7, 0], [5, 0], [5, -2]]]], [-1.438776, -2.010204]), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])], [('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #9', [[[[0, 0], [12, 0], [12, 6], [0, 6], [0, 0]], [[1, 1], [3, 1], [3, 3], [1, 3], [1, 1]]], [[[20, 0], [20, 2], [22, 2], [22, 0], [20, 0]]]], [7.055556, 2.944444]), ('boundary #10', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]], [[0, 0], [0, 4], [4, 4], [4, 0], [0, 0]]]], None), ('control #11', [[[[1, 1], [7, 2], [6, 8], [2, 6], [1, 1]]]], [4.121212, 4.10303]), ('regression #12', [[[[-6, -6], [0, -6], [0, 0], [-6, 0], [-6, -6]]], [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[5, -2], [7, -2], [7, 0], [5, 0], [5, -2]]]], [-1.438776, -2.010204]), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])], [('control #0', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]], [5.0, 5.0]), ('regression #1', [[[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]], [5.833333, 5.833333]), ('regression #2', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [[6, 6], [9, 6], [9, 9], [6, 9], [6, 6]]]], [4.752747, 4.752747]), ('regression #3', [[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]], [5.0, 5.0]), ('regression #4', [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]], [[[10, 0], [20, 0], [20, 10], [10, 10], [10, 0]]]], [14.461538, 4.846154]), ('regression #5', [[[[0, 0], [4, 0], [4, 4], [0, 4], [0, 0]]], [[[10, 10], [10, 12], [12, 12], [12, 10], [10, 10]]]], [3.8, 3.8]), ('boundary #6', [[[[0, 0], [5, 0], [10, 0], [0, 0]]]], None), ('regression #13', [[[[0, 0], [8, 0], [8, 8], [0, 8], [0, 0]], [[4, 4], [4, 8], [8, 8], [8, 4], [4, 4]]], [[[0, 10], [2, 10], [2, 12], [0, 12], [0, 10]]]], [3.153846, 3.923077])]]
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 fixtureActualExpectedOutcome
control #0[5.0, 5.0][5.0, 5.0]Passed
regression #1[5.833333, 5.833333][5.833333, 5.833333]Passed
regression #2[4.752747, 4.752747][4.752747, 4.752747]Passed
regression #3[5.0, 5.0][5.0, 5.0]Passed
regression #4[14.461538, 4.846154][14.461538, 4.846154]Passed
regression #5[3.8, 3.8][3.8, 3.8]Passed
boundary #6NoneNonePassed
control #7[3.0, 2.0][3.0, 2.0]Passed

SHA-256 / c67bc56ff89772c96918df89d5f0e4eb7e466af4db29cb860a69524018c33bdc

Verification & scope

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.

Observations recorded using Python 3.12.14 at 2026-09-29T14:48:22.570857+00:00.

Case digest / 58bdccc221f42d6a76d409596cb1be8f434008600f8b82a6f1f156f32402158b