FA-70711 / GIS polygon topology / Open access
WKT polygon and multipolygon ring structure: multipolygon nesting · case 01
Multipolygons are read as one polygon whose rings are polygons.
ROOT CAUSE
The extra nesting level of MULTIPOLYGON is not unwrapped.
VERIFIED REPAIR
At the multipolygon nesting step restore `polys = [tree] if words[0] == 'POLYGON' else tree`, leaving the rest of the model unchanged.
Unsuccessful approach: Single-part multipolygons are still wrapped one level too deep.
Case contract
Input: a WKT string. The keyword (case-insensitive) must be POLYGON or MULTIPOLYGON, else None; "<keyword> EMPTY" returns []. Otherwise parse the parenthesised body into polygons -> rings -> positions, keeping only x and y of every position (Z/M ordinates are dropped). Every ring must have at least 4 positions and be closed in x/y, else None. Return a list of polygons (a POLYGON gives a one-element list).
Why this case matters
WKT is the lingua franca between databases and GIS tools; losing a dimension or nesting level corrupts rings.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
s = x.strip()
up = s.upper()
words = up.replace('(', ' ( ').split()
if not words or words[0] not in ('POLYGON', 'MULTIPOLYGON'):
return None
if len(words) == 2 and words[1] == 'EMPTY':
return []
if '(' not in s:
return None
body = s[s.index('('):]
stack = [[]]
cur = ''
for ch in body:
if ch == '(':
stack.append([])
elif ch in '),':
if cur.strip():
nums = [float(t) for t in cur.split()]
stack[-1].append(nums[:2])
cur = ''
if ch == ')':
done = stack.pop()
stack[-1].append(done)
else:
cur += ch
tree = stack[0][0]
polys = [tree]
for poly in polys:
for ring in poly:
if len(ring) < 4 or ring[0] != ring[-1]:
return None
return polys
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control #0', 'POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]]), ('control #1', 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 4, 4 4, 2 2))', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]]), ('regression #2', 'POLYGON Z ((0 0 5, 4 0 5, 4 4 6, 0 0 5))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #3', 'POLYGON ZM ((0 0 5 1, 4 0 5 2, 4 4 6 3, 0 0 5 1))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #4', 'POLYGON M ((0 0 7, 4 0 8, 4 4 9, 0 0 7))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('boundary #5', 'POLYGON EMPTY', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]])], [('regression #3', 'POLYGON ZM ((0 0 5 1, 4 0 5 2, 4 4 6 3, 0 0 5 1))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #4', 'POLYGON M ((0 0 7, 4 0 8, 4 4 9, 0 0 7))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('boundary #5', 'POLYGON EMPTY', []), ('boundary #6', 'polygon empty', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None)], [('boundary #6', 'polygon empty', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None), ('boundary #11', 'POLYGON ((0 0, 4 0, 0 0))', None), ('control #12', 'Polygon((1 1,5 1,5 5,1 1))', [[[[1.0, 1.0], [5.0, 1.0], [5.0, 5.0], [1.0, 1.0]]]]), ('boundary #13', 'LINESTRING (0 0, 1 1)', None)], [('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None), ('boundary #11', 'POLYGON ((0 0, 4 0, 0 0))', None), ('control #12', 'Polygon((1 1,5 1,5 5,1 1))', [[[[1.0, 1.0], [5.0, 1.0], [5.0, 5.0], [1.0, 1.0]]]]), ('boundary #13', 'LINESTRING (0 0, 1 1)', None), ('boundary #14', 'MULTIPOLYGON EMPTY', []), ('control #15', ' POLYGON ((0 0, -3 0, -3 -3, 0 0)) ', [[[[0.0, 0.0], [-3.0, 0.0], [-3.0, -3.0], [0.0, 0.0]]]]), ('regression #16', 'MULTIPOLYGON Z (((0 0 1, 2 0 1, 2 2 1, 0 0 1)), ((9 9 0, 8 9 0, 8 8 0, 9 9 0)))', [[[[0.0, 0.0], [2.0, 0.0], [2.0, 2.0], [0.0, 0.0]]], [[[9.0, 9.0], [8.0, 9.0], [8.0, 8.0], [9.0, 9.0]]]])], [('control #0', 'POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]]), ('control #1', 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 4, 4 4, 2 2))', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]]), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('boundary #14', 'MULTIPOLYGON EMPTY', []), ('control #15', ' POLYGON ((0 0, -3 0, -3 -3, 0 0)) ', [[[[0.0, 0.0], [-3.0, 0.0], [-3.0, -3.0], [0.0, 0.0]]]]), ('regression #16', 'MULTIPOLYGON Z (((0 0 1, 2 0 1, 2 2 1, 0 0 1)), ((9 9 0, 8 9 0, 8 8 0, 9 9 0)))', [[[[0.0, 0.0], [2.0, 0.0], [2.0, 2.0], [0.0, 0.0]]], [[[9.0, 9.0], [8.0, 9.0], [8.0, 8.0], [9.0, 9.0]]]]), ('boundary #17', 'POLYGON ((0 0 1, 4 0 1, 4 4 1, 0 0 2))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]])]]
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 |
|---|---|---|---|
| control #0 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]] | Passed |
| control #1 | [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]] | [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]] | Passed |
| regression #2 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| regression #3 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| regression #4 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| boundary #5 | [] | [] | Passed |
| regression #7 | None | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]] | Failed |
| regression #8 | None | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]] | Failed |
SHA-256 / fb3bfb31770d716a6049fd12e48313b01245574aa4dd2c93ac07510650edc24a
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
s = x.strip()
up = s.upper()
words = up.replace('(', ' ( ').split()
if not words or words[0] not in ('POLYGON', 'MULTIPOLYGON'):
return None
if len(words) == 2 and words[1] == 'EMPTY':
return []
if '(' not in s:
return None
body = s[s.index('('):]
stack = [[]]
cur = ''
for ch in body:
if ch == '(':
stack.append([])
elif ch in '),':
if cur.strip():
nums = [float(t) for t in cur.split()]
stack[-1].append(nums[:2])
cur = ''
if ch == ')':
done = stack.pop()
stack[-1].append(done)
else:
cur += ch
tree = stack[0][0]
polys = tree if words[0] == 'MULTIPOLYGON' and len(tree) > 1 else [tree]
for poly in polys:
for ring in poly:
if len(ring) < 4 or ring[0] != ring[-1]:
return None
return polys
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control #0', 'POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]]), ('control #1', 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 4, 4 4, 2 2))', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]]), ('regression #2', 'POLYGON Z ((0 0 5, 4 0 5, 4 4 6, 0 0 5))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #3', 'POLYGON ZM ((0 0 5 1, 4 0 5 2, 4 4 6 3, 0 0 5 1))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #4', 'POLYGON M ((0 0 7, 4 0 8, 4 4 9, 0 0 7))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('boundary #5', 'POLYGON EMPTY', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]])], [('regression #3', 'POLYGON ZM ((0 0 5 1, 4 0 5 2, 4 4 6 3, 0 0 5 1))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #4', 'POLYGON M ((0 0 7, 4 0 8, 4 4 9, 0 0 7))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('boundary #5', 'POLYGON EMPTY', []), ('boundary #6', 'polygon empty', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None)], [('boundary #6', 'polygon empty', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None), ('boundary #11', 'POLYGON ((0 0, 4 0, 0 0))', None), ('control #12', 'Polygon((1 1,5 1,5 5,1 1))', [[[[1.0, 1.0], [5.0, 1.0], [5.0, 5.0], [1.0, 1.0]]]]), ('boundary #13', 'LINESTRING (0 0, 1 1)', None)], [('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None), ('boundary #11', 'POLYGON ((0 0, 4 0, 0 0))', None), ('control #12', 'Polygon((1 1,5 1,5 5,1 1))', [[[[1.0, 1.0], [5.0, 1.0], [5.0, 5.0], [1.0, 1.0]]]]), ('boundary #13', 'LINESTRING (0 0, 1 1)', None), ('boundary #14', 'MULTIPOLYGON EMPTY', []), ('control #15', ' POLYGON ((0 0, -3 0, -3 -3, 0 0)) ', [[[[0.0, 0.0], [-3.0, 0.0], [-3.0, -3.0], [0.0, 0.0]]]]), ('regression #16', 'MULTIPOLYGON Z (((0 0 1, 2 0 1, 2 2 1, 0 0 1)), ((9 9 0, 8 9 0, 8 8 0, 9 9 0)))', [[[[0.0, 0.0], [2.0, 0.0], [2.0, 2.0], [0.0, 0.0]]], [[[9.0, 9.0], [8.0, 9.0], [8.0, 8.0], [9.0, 9.0]]]])], [('control #0', 'POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]]), ('control #1', 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 4, 4 4, 2 2))', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]]), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('boundary #14', 'MULTIPOLYGON EMPTY', []), ('control #15', ' POLYGON ((0 0, -3 0, -3 -3, 0 0)) ', [[[[0.0, 0.0], [-3.0, 0.0], [-3.0, -3.0], [0.0, 0.0]]]]), ('regression #16', 'MULTIPOLYGON Z (((0 0 1, 2 0 1, 2 2 1, 0 0 1)), ((9 9 0, 8 9 0, 8 8 0, 9 9 0)))', [[[[0.0, 0.0], [2.0, 0.0], [2.0, 2.0], [0.0, 0.0]]], [[[9.0, 9.0], [8.0, 9.0], [8.0, 8.0], [9.0, 9.0]]]]), ('boundary #17', 'POLYGON ((0 0 1, 4 0 1, 4 4 1, 0 0 2))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]])]]
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 |
|---|---|---|---|
| control #0 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]] | Passed |
| control #1 | [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]] | [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]] | Passed |
| regression #2 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| regression #3 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| regression #4 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| boundary #5 | [] | [] | Passed |
| regression #7 | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]] | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]] | Passed |
| regression #8 | None | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]] | Failed |
SHA-256 / 4386b98820caee5a00e5950e401ec4d3bd196b2f6e1afda2dc969d5561067dd2
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
s = x.strip()
up = s.upper()
words = up.replace('(', ' ( ').split()
if not words or words[0] not in ('POLYGON', 'MULTIPOLYGON'):
return None
if len(words) == 2 and words[1] == 'EMPTY':
return []
if '(' not in s:
return None
body = s[s.index('('):]
stack = [[]]
cur = ''
for ch in body:
if ch == '(':
stack.append([])
elif ch in '),':
if cur.strip():
nums = [float(t) for t in cur.split()]
stack[-1].append(nums[:2])
cur = ''
if ch == ')':
done = stack.pop()
stack[-1].append(done)
else:
cur += ch
tree = stack[0][0]
polys = [tree] if words[0] == 'POLYGON' else tree
for poly in polys:
for ring in poly:
if len(ring) < 4 or ring[0] != ring[-1]:
return None
return polys
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('control #0', 'POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]]), ('control #1', 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 4, 4 4, 2 2))', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]]), ('regression #2', 'POLYGON Z ((0 0 5, 4 0 5, 4 4 6, 0 0 5))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #3', 'POLYGON ZM ((0 0 5 1, 4 0 5 2, 4 4 6 3, 0 0 5 1))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #4', 'POLYGON M ((0 0 7, 4 0 8, 4 4 9, 0 0 7))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('boundary #5', 'POLYGON EMPTY', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]])], [('regression #3', 'POLYGON ZM ((0 0 5 1, 4 0 5 2, 4 4 6 3, 0 0 5 1))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('regression #4', 'POLYGON M ((0 0 7, 4 0 8, 4 4 9, 0 0 7))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]]), ('boundary #5', 'POLYGON EMPTY', []), ('boundary #6', 'polygon empty', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None)], [('boundary #6', 'polygon empty', []), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None), ('boundary #11', 'POLYGON ((0 0, 4 0, 0 0))', None), ('control #12', 'Polygon((1 1,5 1,5 5,1 1))', [[[[1.0, 1.0], [5.0, 1.0], [5.0, 5.0], [1.0, 1.0]]]]), ('boundary #13', 'LINESTRING (0 0, 1 1)', None)], [('regression #9', 'multipolygon (((-1.5 -2, 3e2 0, 0 1e1, -1.5 -2)))', [[[[-1.5, -2.0], [300.0, 0.0], [0.0, 10.0], [-1.5, -2.0]]]]), ('boundary #10', 'POLYGON ((0 0, 4 0, 4 4, 0 1))', None), ('boundary #11', 'POLYGON ((0 0, 4 0, 0 0))', None), ('control #12', 'Polygon((1 1,5 1,5 5,1 1))', [[[[1.0, 1.0], [5.0, 1.0], [5.0, 5.0], [1.0, 1.0]]]]), ('boundary #13', 'LINESTRING (0 0, 1 1)', None), ('boundary #14', 'MULTIPOLYGON EMPTY', []), ('control #15', ' POLYGON ((0 0, -3 0, -3 -3, 0 0)) ', [[[[0.0, 0.0], [-3.0, 0.0], [-3.0, -3.0], [0.0, 0.0]]]]), ('regression #16', 'MULTIPOLYGON Z (((0 0 1, 2 0 1, 2 2 1, 0 0 1)), ((9 9 0, 8 9 0, 8 8 0, 9 9 0)))', [[[[0.0, 0.0], [2.0, 0.0], [2.0, 2.0], [0.0, 0.0]]], [[[9.0, 9.0], [8.0, 9.0], [8.0, 8.0], [9.0, 9.0]]]])], [('control #0', 'POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]]), ('control #1', 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 4, 4 4, 2 2))', [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]]), ('regression #7', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)), ((5 5, 6 5, 6 6, 5 5), (5.2 5.1, 5.8 5.8, 5.8 5.1, 5.2 5.1)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]]), ('regression #8', 'MULTIPOLYGON (((0 0, 1 0, 1 1, 0 0)))', [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]]), ('boundary #14', 'MULTIPOLYGON EMPTY', []), ('control #15', ' POLYGON ((0 0, -3 0, -3 -3, 0 0)) ', [[[[0.0, 0.0], [-3.0, 0.0], [-3.0, -3.0], [0.0, 0.0]]]]), ('regression #16', 'MULTIPOLYGON Z (((0 0 1, 2 0 1, 2 2 1, 0 0 1)), ((9 9 0, 8 9 0, 8 8 0, 9 9 0)))', [[[[0.0, 0.0], [2.0, 0.0], [2.0, 2.0], [0.0, 0.0]]], [[[9.0, 9.0], [8.0, 9.0], [8.0, 8.0], [9.0, 9.0]]]]), ('boundary #17', 'POLYGON ((0 0 1, 4 0 1, 4 4 1, 0 0 2))', [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]])]]
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 |
|---|---|---|---|
| control #0 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0], [0.0, 0.0]]]] | Passed |
| control #1 | [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]] | [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[2.0, 2.0], [2.0, 4.0], [4.0, 4.0], [2.0, 2.0]]]] | Passed |
| regression #2 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| regression #3 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| regression #4 | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 0.0]]]] | Passed |
| boundary #5 | [] | [] | Passed |
| regression #7 | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]] | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]], [[[5.0, 5.0], [6.0, 5.0], [6.0, 6.0], [5.0, 5.0]], [[5.2, 5.1], [5.8, 5.8], [5.8, 5.1], [5.2, 5.1]]]] | Passed |
| regression #8 | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]] | [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]] | Passed |
SHA-256 / 80b408525c4a719ae9de62eab88f3e80a1376ec134fc311db6169ecc026f6bf1
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:23.159671+00:00.
Case digest / f8057ff14ac7becdf8b20e353d1b6740771627755ae0fc2af7d1fe6ab8c27cce