FAILURE MAP
← Case archive

FA-51551 / Raster clipping / Open access

Cohen sutherland pixel window: stale outcode after clip · case 01

After moving endpoint 0 onto a window edge its outcode is assumed to be zero, so a point pushed into a different outside region is treated as inside.

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

ROOT CAUSE

After moving endpoint 0 onto a window edge its outcode is assumed to be zero, so a point pushed into a different outside region is treated as inside.

VERIFIED REPAIR

Restore the specified clipping decision at stale outcode after clip. Each command is a segment [x0,y0,x1,y1] whose endpoints are integers or exact decimal/rational strings in pixel-center coordinates. The window is the closed square [0,size-1]x[0,size-1] of pixel centers. Outcodes use strict outside tests (left 1, right 2, below 4, above 8). Both codes zero accepts; a shared bit rejects; otherwise the outside endpoint (endpoint 0 first) is moved to the highest set edge in above, below, right, left order and its code is recomputed from the new point; a clip against an edge parallel to the segment is treated as a rejection. At most five iterations are allowed; an unresolved or rejected segment returns None. Accepted endpoints round half-up to integer pixels.

Unsuccessful approach: Recomputing the code but masking out every bit of the previous code hides a corner endpoint that is still outside the other edge.

Case contract

Each command is a segment [x0,y0,x1,y1] whose endpoints are integers or exact decimal/rational strings in pixel-center coordinates. The window is the closed square [0,size-1]x[0,size-1] of pixel centers. Outcodes use strict outside tests (left 1, right 2, below 4, above 8). Both codes zero accepts; a shared bit rejects; otherwise the outside endpoint (endpoint 0 first) is moved to the highest set edge in above, below, right, left order and its code is recomputed from the new point; a clip against an edge parallel to the segment is treated as a rejection. At most five iterations are allowed; an unresolved or rejected segment returns None. Accepted endpoints round half-up to integer pixels.

Why this case matters

Raster clipping decides which pixels a primitive may touch; a single wrong clip decision writes outside the target or scissor, or silently drops visible coverage.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(commands, size):
    lo=0
    hi=size-1
    def code(x,y):
        c=0
        if x<lo: c|=1
        elif x>hi: c|=2
        if y<lo: c|=4
        elif y>hi: c|=8
        return c
    out=[]
    for x0,y0,x1,y1 in commands:
        x0,y0,x1,y1=[Fraction(v) for v in (x0,y0,x1,y1)]
        c0,c1=code(x0,y0),code(x1,y1)
        result=None
        for _ in range(5):
            if not (c0|c1):
                result=[int((v+Fraction(1,2))//1) for v in (x0,y0,x1,y1)]
                break
            if c0&c1: break
            c=c0 if c0 else c1
            if c&12 and y1==y0 or c&3 and x1==x0: break
            if c&8: x,y=x0+(x1-x0)*(hi-y0)/(y1-y0),Fraction(hi)
            elif c&4: x,y=x0+(x1-x0)*(lo-y0)/(y1-y0),Fraction(lo)
            elif c&2: x,y=Fraction(hi),y0+(y1-y0)*(hi-x0)/(x1-x0)
            else: x,y=Fraction(lo),y0+(y1-y0)*(lo-x0)/(x1-x0)
            if c==c0:
                x0,y0=x,y
                c0=0
            else:
                x1,y1=x,y
                c1=code(x1,y1)
        out.append(result)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('explicit case 0', solve([[1, 1, 4, 3]], 6), [[1, 1, 4, 3]])
    check('explicit case 1', solve([[-3, 2, 8, 2]], 6), [[0, 2, 5, 2]])
    check('explicit case 2', solve([[-2, -2, 7, 7]], 6), [[0, 0, 5, 5]])
    check('explicit case 3', solve([[-3, 0, -1, 5]], 6), [None])
    check('explicit case 4', solve([[0, 0, 5, 5]], 6), [[0, 0, 5, 5]])
    check('explicit case 5', solve([[0, 0, '5.8', 0]], 6), [[0, 0, 5, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 6), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 6), [None])
    check('explicit case 8', solve([[-2, 1, 4, 10]], 6), [[0, 4, 1, 5]])
    check('explicit case 9', solve([[0, '2.5', 5, '2.5']], 6), [[0, 3, 5, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 6), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 9, 0]], 6), [[0, 0, 5, 0]])
    check('explicit case 12', solve([['-5', '-7/2', '10', '17/2']], 6), [[0, 1, 5, 5]])
    check('explicit case 13', solve([[2, 1, 4, 11]], 6), [[2, 1, 3, 5]])
    check('explicit case 14', solve([[3, 8, 1, -2]], 6), [[2, 5, 1, 0]])
    check('explicit case 15', solve([[8, 1, 1, 9]], 6), [[5, 4, 5, 5]])
if N == 2:
    check('explicit case 0', solve([[1, 1, 5, 4]], 7), [[1, 1, 5, 4]])
    check('explicit case 1', solve([[-3, 2, 9, 2]], 7), [[0, 2, 6, 2]])
    check('explicit case 2', solve([[-2, -2, 8, 8]], 7), [[0, 0, 6, 6]])
    check('explicit case 3', solve([[-3, 0, -1, 6]], 7), [None])
    check('explicit case 4', solve([[0, 0, 6, 6]], 7), [[0, 0, 6, 6]])
    check('explicit case 5', solve([[0, 0, '6.8', 0]], 7), [[0, 0, 6, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 7), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 7), [None])
    check('explicit case 8', solve([[-2, 1, 4, 11]], 7), [[0, 4, 1, 6]])
    check('explicit case 9', solve([[0, '2.5', 6, '2.5']], 7), [[0, 3, 6, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 7), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 10, 0]], 7), [[0, 0, 6, 0]])
    check('explicit case 12', solve([['-6', '-9/2', '12', '21/2']], 7), [[0, 1, 6, 6]])
    check('explicit case 13', solve([[2, 1, 4, 12]], 7), [[2, 1, 3, 6]])
    check('explicit case 14', solve([[3, 9, 1, -2]], 7), [[2, 6, 1, 0]])
    check('explicit case 15', solve([[9, 1, 1, 10]], 7), [[6, 4, 5, 6]])
if N == 3:
    check('explicit case 0', solve([[1, 1, 6, 5]], 8), [[1, 1, 6, 5]])
    check('explicit case 1', solve([[-3, 2, 10, 2]], 8), [[0, 2, 7, 2]])
    check('explicit case 2', solve([[-2, -2, 9, 9]], 8), [[0, 0, 7, 7]])
    check('explicit case 3', solve([[-3, 0, -1, 7]], 8), [None])
    check('explicit case 4', solve([[0, 0, 7, 7]], 8), [[0, 0, 7, 7]])
    check('explicit case 5', solve([[0, 0, '7.8', 0]], 8), [[0, 0, 7, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 8), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 8), [None])
    check('explicit case 8', solve([[-2, 1, 4, 12]], 8), [[0, 5, 1, 7]])
    check('explicit case 9', solve([[0, '2.5', 7, '2.5']], 8), [[0, 3, 7, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 8), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 11, 0]], 8), [[0, 0, 7, 0]])
    check('explicit case 12', solve([['-7', '-11/2', '14', '25/2']], 8), [[0, 1, 7, 7]])
    check('explicit case 13', solve([[2, 1, 4, 13]], 8), [[2, 1, 3, 7]])
    check('explicit case 14', solve([[3, 10, 1, -2]], 8), [[3, 7, 1, 0]])
    check('explicit case 15', solve([[10, 1, 1, 11]], 8), [[7, 4, 5, 7]])
if N == 4:
    check('explicit case 0', solve([[1, 1, 7, 6]], 9), [[1, 1, 7, 6]])
    check('explicit case 1', solve([[-3, 2, 11, 2]], 9), [[0, 2, 8, 2]])
    check('explicit case 2', solve([[-2, -2, 10, 10]], 9), [[0, 0, 8, 8]])
    check('explicit case 3', solve([[-3, 0, -1, 8]], 9), [None])
    check('explicit case 4', solve([[0, 0, 8, 8]], 9), [[0, 0, 8, 8]])
    check('explicit case 5', solve([[0, 0, '8.8', 0]], 9), [[0, 0, 8, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 9), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 9), [None])
    check('explicit case 8', solve([[-2, 1, 4, 13]], 9), [[0, 5, 2, 8]])
    check('explicit case 9', solve([[0, '2.5', 8, '2.5']], 9), [[0, 3, 8, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 9), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 12, 0]], 9), [[0, 0, 8, 0]])
    check('explicit case 12', solve([['-8', '-13/2', '16', '29/2']], 9), [[0, 1, 8, 8]])
    check('explicit case 13', solve([[2, 1, 4, 14]], 9), [[2, 1, 3, 8]])
    check('explicit case 14', solve([[3, 11, 1, -2]], 9), [[3, 8, 1, 0]])
    check('explicit case 15', solve([[11, 1, 1, 12]], 9), [[8, 4, 5, 8]])
if N == 5:
    check('explicit case 0', solve([[1, 1, 8, 7]], 10), [[1, 1, 8, 7]])
    check('explicit case 1', solve([[-3, 2, 12, 2]], 10), [[0, 2, 9, 2]])
    check('explicit case 2', solve([[-2, -2, 11, 11]], 10), [[0, 0, 9, 9]])
    check('explicit case 3', solve([[-3, 0, -1, 9]], 10), [None])
    check('explicit case 4', solve([[0, 0, 9, 9]], 10), [[0, 0, 9, 9]])
    check('explicit case 5', solve([[0, 0, '9.8', 0]], 10), [[0, 0, 9, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 10), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 10), [None])
    check('explicit case 8', solve([[-2, 1, 4, 14]], 10), [[0, 5, 2, 9]])
    check('explicit case 9', solve([[0, '2.5', 9, '2.5']], 10), [[0, 3, 9, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 10), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 13, 0]], 10), [[0, 0, 9, 0]])
    check('explicit case 12', solve([['-9', '-15/2', '18', '33/2']], 10), [[0, 1, 9, 9]])
    check('explicit case 13', solve([[2, 1, 4, 15]], 10), [[2, 1, 3, 9]])
    check('explicit case 14', solve([[3, 12, 1, -2]], 10), [[3, 9, 1, 0]])
    check('explicit case 15', solve([[12, 1, 1, 13]], 10), [[9, 4, 5, 9]])
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
explicit case 0[[1, 1, 4, 3]][[1, 1, 4, 3]]Passed
explicit case 1[[0, 2, 5, 2]][[0, 2, 5, 2]]Passed
explicit case 2[[0, 0, 5, 5]][[0, 0, 5, 5]]Passed
explicit case 3[None][None]Passed
explicit case 4[[0, 0, 5, 5]][[0, 0, 5, 5]]Passed
explicit case 5[[0, 0, 5, 0]][[0, 0, 5, 0]]Passed
explicit case 6[None][None]Passed
explicit case 7[None][None]Passed
explicit case 8[[0, 4, 1, 5]][[0, 4, 1, 5]]Passed
explicit case 9[[0, 3, 5, 3]][[0, 3, 5, 3]]Passed
explicit case 10[[0, 2, 2, 2]][[0, 2, 2, 2]]Passed
explicit case 11[[0, 0, 5, 0]][[0, 0, 5, 0]]Passed
explicit case 12[[-1, 0, 5, 5]][[0, 1, 5, 5]]Failed
explicit case 13[[2, 1, 3, 5]][[2, 1, 3, 5]]Passed
explicit case 14[[2, 5, 1, 0]][[2, 5, 1, 0]]Passed
explicit case 15[[5, 4, 5, 5]][[5, 4, 5, 5]]Passed

SHA-256 / 81776db43629922a20aa42a40e28a0c49972b6181cad71cce20d53e3182c7613

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(commands, size):
    lo=0
    hi=size-1
    def code(x,y):
        c=0
        if x<lo: c|=1
        elif x>hi: c|=2
        if y<lo: c|=4
        elif y>hi: c|=8
        return c
    out=[]
    for x0,y0,x1,y1 in commands:
        x0,y0,x1,y1=[Fraction(v) for v in (x0,y0,x1,y1)]
        c0,c1=code(x0,y0),code(x1,y1)
        result=None
        for _ in range(5):
            if not (c0|c1):
                result=[int((v+Fraction(1,2))//1) for v in (x0,y0,x1,y1)]
                break
            if c0&c1: break
            c=c0 if c0 else c1
            if c&12 and y1==y0 or c&3 and x1==x0: break
            if c&8: x,y=x0+(x1-x0)*(hi-y0)/(y1-y0),Fraction(hi)
            elif c&4: x,y=x0+(x1-x0)*(lo-y0)/(y1-y0),Fraction(lo)
            elif c&2: x,y=Fraction(hi),y0+(y1-y0)*(hi-x0)/(x1-x0)
            else: x,y=Fraction(lo),y0+(y1-y0)*(lo-x0)/(x1-x0)
            if c==c0:
                x0,y0=x,y
                c0=code(x0,y0)&~c
            else:
                x1,y1=x,y
                c1=code(x1,y1)
        out.append(result)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('explicit case 0', solve([[1, 1, 4, 3]], 6), [[1, 1, 4, 3]])
    check('explicit case 1', solve([[-3, 2, 8, 2]], 6), [[0, 2, 5, 2]])
    check('explicit case 2', solve([[-2, -2, 7, 7]], 6), [[0, 0, 5, 5]])
    check('explicit case 3', solve([[-3, 0, -1, 5]], 6), [None])
    check('explicit case 4', solve([[0, 0, 5, 5]], 6), [[0, 0, 5, 5]])
    check('explicit case 5', solve([[0, 0, '5.8', 0]], 6), [[0, 0, 5, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 6), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 6), [None])
    check('explicit case 8', solve([[-2, 1, 4, 10]], 6), [[0, 4, 1, 5]])
    check('explicit case 9', solve([[0, '2.5', 5, '2.5']], 6), [[0, 3, 5, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 6), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 9, 0]], 6), [[0, 0, 5, 0]])
    check('explicit case 12', solve([['-5', '-7/2', '10', '17/2']], 6), [[0, 1, 5, 5]])
    check('explicit case 13', solve([[2, 1, 4, 11]], 6), [[2, 1, 3, 5]])
    check('explicit case 14', solve([[3, 8, 1, -2]], 6), [[2, 5, 1, 0]])
    check('explicit case 15', solve([[8, 1, 1, 9]], 6), [[5, 4, 5, 5]])
if N == 2:
    check('explicit case 0', solve([[1, 1, 5, 4]], 7), [[1, 1, 5, 4]])
    check('explicit case 1', solve([[-3, 2, 9, 2]], 7), [[0, 2, 6, 2]])
    check('explicit case 2', solve([[-2, -2, 8, 8]], 7), [[0, 0, 6, 6]])
    check('explicit case 3', solve([[-3, 0, -1, 6]], 7), [None])
    check('explicit case 4', solve([[0, 0, 6, 6]], 7), [[0, 0, 6, 6]])
    check('explicit case 5', solve([[0, 0, '6.8', 0]], 7), [[0, 0, 6, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 7), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 7), [None])
    check('explicit case 8', solve([[-2, 1, 4, 11]], 7), [[0, 4, 1, 6]])
    check('explicit case 9', solve([[0, '2.5', 6, '2.5']], 7), [[0, 3, 6, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 7), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 10, 0]], 7), [[0, 0, 6, 0]])
    check('explicit case 12', solve([['-6', '-9/2', '12', '21/2']], 7), [[0, 1, 6, 6]])
    check('explicit case 13', solve([[2, 1, 4, 12]], 7), [[2, 1, 3, 6]])
    check('explicit case 14', solve([[3, 9, 1, -2]], 7), [[2, 6, 1, 0]])
    check('explicit case 15', solve([[9, 1, 1, 10]], 7), [[6, 4, 5, 6]])
if N == 3:
    check('explicit case 0', solve([[1, 1, 6, 5]], 8), [[1, 1, 6, 5]])
    check('explicit case 1', solve([[-3, 2, 10, 2]], 8), [[0, 2, 7, 2]])
    check('explicit case 2', solve([[-2, -2, 9, 9]], 8), [[0, 0, 7, 7]])
    check('explicit case 3', solve([[-3, 0, -1, 7]], 8), [None])
    check('explicit case 4', solve([[0, 0, 7, 7]], 8), [[0, 0, 7, 7]])
    check('explicit case 5', solve([[0, 0, '7.8', 0]], 8), [[0, 0, 7, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 8), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 8), [None])
    check('explicit case 8', solve([[-2, 1, 4, 12]], 8), [[0, 5, 1, 7]])
    check('explicit case 9', solve([[0, '2.5', 7, '2.5']], 8), [[0, 3, 7, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 8), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 11, 0]], 8), [[0, 0, 7, 0]])
    check('explicit case 12', solve([['-7', '-11/2', '14', '25/2']], 8), [[0, 1, 7, 7]])
    check('explicit case 13', solve([[2, 1, 4, 13]], 8), [[2, 1, 3, 7]])
    check('explicit case 14', solve([[3, 10, 1, -2]], 8), [[3, 7, 1, 0]])
    check('explicit case 15', solve([[10, 1, 1, 11]], 8), [[7, 4, 5, 7]])
if N == 4:
    check('explicit case 0', solve([[1, 1, 7, 6]], 9), [[1, 1, 7, 6]])
    check('explicit case 1', solve([[-3, 2, 11, 2]], 9), [[0, 2, 8, 2]])
    check('explicit case 2', solve([[-2, -2, 10, 10]], 9), [[0, 0, 8, 8]])
    check('explicit case 3', solve([[-3, 0, -1, 8]], 9), [None])
    check('explicit case 4', solve([[0, 0, 8, 8]], 9), [[0, 0, 8, 8]])
    check('explicit case 5', solve([[0, 0, '8.8', 0]], 9), [[0, 0, 8, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 9), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 9), [None])
    check('explicit case 8', solve([[-2, 1, 4, 13]], 9), [[0, 5, 2, 8]])
    check('explicit case 9', solve([[0, '2.5', 8, '2.5']], 9), [[0, 3, 8, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 9), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 12, 0]], 9), [[0, 0, 8, 0]])
    check('explicit case 12', solve([['-8', '-13/2', '16', '29/2']], 9), [[0, 1, 8, 8]])
    check('explicit case 13', solve([[2, 1, 4, 14]], 9), [[2, 1, 3, 8]])
    check('explicit case 14', solve([[3, 11, 1, -2]], 9), [[3, 8, 1, 0]])
    check('explicit case 15', solve([[11, 1, 1, 12]], 9), [[8, 4, 5, 8]])
if N == 5:
    check('explicit case 0', solve([[1, 1, 8, 7]], 10), [[1, 1, 8, 7]])
    check('explicit case 1', solve([[-3, 2, 12, 2]], 10), [[0, 2, 9, 2]])
    check('explicit case 2', solve([[-2, -2, 11, 11]], 10), [[0, 0, 9, 9]])
    check('explicit case 3', solve([[-3, 0, -1, 9]], 10), [None])
    check('explicit case 4', solve([[0, 0, 9, 9]], 10), [[0, 0, 9, 9]])
    check('explicit case 5', solve([[0, 0, '9.8', 0]], 10), [[0, 0, 9, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 10), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 10), [None])
    check('explicit case 8', solve([[-2, 1, 4, 14]], 10), [[0, 5, 2, 9]])
    check('explicit case 9', solve([[0, '2.5', 9, '2.5']], 10), [[0, 3, 9, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 10), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 13, 0]], 10), [[0, 0, 9, 0]])
    check('explicit case 12', solve([['-9', '-15/2', '18', '33/2']], 10), [[0, 1, 9, 9]])
    check('explicit case 13', solve([[2, 1, 4, 15]], 10), [[2, 1, 3, 9]])
    check('explicit case 14', solve([[3, 12, 1, -2]], 10), [[3, 9, 1, 0]])
    check('explicit case 15', solve([[12, 1, 1, 13]], 10), [[9, 4, 5, 9]])
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
explicit case 0[[1, 1, 4, 3]][[1, 1, 4, 3]]Passed
explicit case 1[[0, 2, 5, 2]][[0, 2, 5, 2]]Passed
explicit case 2[[0, 0, 5, 5]][[0, 0, 5, 5]]Passed
explicit case 3[None][None]Passed
explicit case 4[[0, 0, 5, 5]][[0, 0, 5, 5]]Passed
explicit case 5[[0, 0, 5, 0]][[0, 0, 5, 0]]Passed
explicit case 6[None][None]Passed
explicit case 7[None][None]Passed
explicit case 8[[0, 4, 1, 5]][[0, 4, 1, 5]]Passed
explicit case 9[[0, 3, 5, 3]][[0, 3, 5, 3]]Passed
explicit case 10[[0, 2, 2, 2]][[0, 2, 2, 2]]Passed
explicit case 11[[0, 0, 5, 0]][[0, 0, 5, 0]]Passed
explicit case 12[[-1, 0, 5, 5]][[0, 1, 5, 5]]Failed
explicit case 13[[2, 1, 3, 5]][[2, 1, 3, 5]]Passed
explicit case 14[[2, 5, 1, 0]][[2, 5, 1, 0]]Passed
explicit case 15[[5, 4, 5, 5]][[5, 4, 5, 5]]Passed

SHA-256 / 7e372cef5e56a8af8fb767e73977308a78f5eb2c0c837f51da99dbd7916b3784

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(commands, size):
    lo=0
    hi=size-1
    def code(x,y):
        c=0
        if x<lo: c|=1
        elif x>hi: c|=2
        if y<lo: c|=4
        elif y>hi: c|=8
        return c
    out=[]
    for x0,y0,x1,y1 in commands:
        x0,y0,x1,y1=[Fraction(v) for v in (x0,y0,x1,y1)]
        c0,c1=code(x0,y0),code(x1,y1)
        result=None
        for _ in range(5):
            if not (c0|c1):
                result=[int((v+Fraction(1,2))//1) for v in (x0,y0,x1,y1)]
                break
            if c0&c1: break
            c=c0 if c0 else c1
            if c&12 and y1==y0 or c&3 and x1==x0: break
            if c&8: x,y=x0+(x1-x0)*(hi-y0)/(y1-y0),Fraction(hi)
            elif c&4: x,y=x0+(x1-x0)*(lo-y0)/(y1-y0),Fraction(lo)
            elif c&2: x,y=Fraction(hi),y0+(y1-y0)*(hi-x0)/(x1-x0)
            else: x,y=Fraction(lo),y0+(y1-y0)*(lo-x0)/(x1-x0)
            if c==c0:
                x0,y0=x,y
                c0=code(x0,y0)
            else:
                x1,y1=x,y
                c1=code(x1,y1)
        out.append(result)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('explicit case 0', solve([[1, 1, 4, 3]], 6), [[1, 1, 4, 3]])
    check('explicit case 1', solve([[-3, 2, 8, 2]], 6), [[0, 2, 5, 2]])
    check('explicit case 2', solve([[-2, -2, 7, 7]], 6), [[0, 0, 5, 5]])
    check('explicit case 3', solve([[-3, 0, -1, 5]], 6), [None])
    check('explicit case 4', solve([[0, 0, 5, 5]], 6), [[0, 0, 5, 5]])
    check('explicit case 5', solve([[0, 0, '5.8', 0]], 6), [[0, 0, 5, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 6), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 6), [None])
    check('explicit case 8', solve([[-2, 1, 4, 10]], 6), [[0, 4, 1, 5]])
    check('explicit case 9', solve([[0, '2.5', 5, '2.5']], 6), [[0, 3, 5, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 6), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 9, 0]], 6), [[0, 0, 5, 0]])
    check('explicit case 12', solve([['-5', '-7/2', '10', '17/2']], 6), [[0, 1, 5, 5]])
    check('explicit case 13', solve([[2, 1, 4, 11]], 6), [[2, 1, 3, 5]])
    check('explicit case 14', solve([[3, 8, 1, -2]], 6), [[2, 5, 1, 0]])
    check('explicit case 15', solve([[8, 1, 1, 9]], 6), [[5, 4, 5, 5]])
if N == 2:
    check('explicit case 0', solve([[1, 1, 5, 4]], 7), [[1, 1, 5, 4]])
    check('explicit case 1', solve([[-3, 2, 9, 2]], 7), [[0, 2, 6, 2]])
    check('explicit case 2', solve([[-2, -2, 8, 8]], 7), [[0, 0, 6, 6]])
    check('explicit case 3', solve([[-3, 0, -1, 6]], 7), [None])
    check('explicit case 4', solve([[0, 0, 6, 6]], 7), [[0, 0, 6, 6]])
    check('explicit case 5', solve([[0, 0, '6.8', 0]], 7), [[0, 0, 6, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 7), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 7), [None])
    check('explicit case 8', solve([[-2, 1, 4, 11]], 7), [[0, 4, 1, 6]])
    check('explicit case 9', solve([[0, '2.5', 6, '2.5']], 7), [[0, 3, 6, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 7), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 10, 0]], 7), [[0, 0, 6, 0]])
    check('explicit case 12', solve([['-6', '-9/2', '12', '21/2']], 7), [[0, 1, 6, 6]])
    check('explicit case 13', solve([[2, 1, 4, 12]], 7), [[2, 1, 3, 6]])
    check('explicit case 14', solve([[3, 9, 1, -2]], 7), [[2, 6, 1, 0]])
    check('explicit case 15', solve([[9, 1, 1, 10]], 7), [[6, 4, 5, 6]])
if N == 3:
    check('explicit case 0', solve([[1, 1, 6, 5]], 8), [[1, 1, 6, 5]])
    check('explicit case 1', solve([[-3, 2, 10, 2]], 8), [[0, 2, 7, 2]])
    check('explicit case 2', solve([[-2, -2, 9, 9]], 8), [[0, 0, 7, 7]])
    check('explicit case 3', solve([[-3, 0, -1, 7]], 8), [None])
    check('explicit case 4', solve([[0, 0, 7, 7]], 8), [[0, 0, 7, 7]])
    check('explicit case 5', solve([[0, 0, '7.8', 0]], 8), [[0, 0, 7, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 8), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 8), [None])
    check('explicit case 8', solve([[-2, 1, 4, 12]], 8), [[0, 5, 1, 7]])
    check('explicit case 9', solve([[0, '2.5', 7, '2.5']], 8), [[0, 3, 7, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 8), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 11, 0]], 8), [[0, 0, 7, 0]])
    check('explicit case 12', solve([['-7', '-11/2', '14', '25/2']], 8), [[0, 1, 7, 7]])
    check('explicit case 13', solve([[2, 1, 4, 13]], 8), [[2, 1, 3, 7]])
    check('explicit case 14', solve([[3, 10, 1, -2]], 8), [[3, 7, 1, 0]])
    check('explicit case 15', solve([[10, 1, 1, 11]], 8), [[7, 4, 5, 7]])
if N == 4:
    check('explicit case 0', solve([[1, 1, 7, 6]], 9), [[1, 1, 7, 6]])
    check('explicit case 1', solve([[-3, 2, 11, 2]], 9), [[0, 2, 8, 2]])
    check('explicit case 2', solve([[-2, -2, 10, 10]], 9), [[0, 0, 8, 8]])
    check('explicit case 3', solve([[-3, 0, -1, 8]], 9), [None])
    check('explicit case 4', solve([[0, 0, 8, 8]], 9), [[0, 0, 8, 8]])
    check('explicit case 5', solve([[0, 0, '8.8', 0]], 9), [[0, 0, 8, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 9), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 9), [None])
    check('explicit case 8', solve([[-2, 1, 4, 13]], 9), [[0, 5, 2, 8]])
    check('explicit case 9', solve([[0, '2.5', 8, '2.5']], 9), [[0, 3, 8, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 9), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 12, 0]], 9), [[0, 0, 8, 0]])
    check('explicit case 12', solve([['-8', '-13/2', '16', '29/2']], 9), [[0, 1, 8, 8]])
    check('explicit case 13', solve([[2, 1, 4, 14]], 9), [[2, 1, 3, 8]])
    check('explicit case 14', solve([[3, 11, 1, -2]], 9), [[3, 8, 1, 0]])
    check('explicit case 15', solve([[11, 1, 1, 12]], 9), [[8, 4, 5, 8]])
if N == 5:
    check('explicit case 0', solve([[1, 1, 8, 7]], 10), [[1, 1, 8, 7]])
    check('explicit case 1', solve([[-3, 2, 12, 2]], 10), [[0, 2, 9, 2]])
    check('explicit case 2', solve([[-2, -2, 11, 11]], 10), [[0, 0, 9, 9]])
    check('explicit case 3', solve([[-3, 0, -1, 9]], 10), [None])
    check('explicit case 4', solve([[0, 0, 9, 9]], 10), [[0, 0, 9, 9]])
    check('explicit case 5', solve([[0, 0, '9.8', 0]], 10), [[0, 0, 9, 0]])
    check('explicit case 6', solve([[1, -4, -2, 2]], 10), [None])
    check('explicit case 7', solve([[-2, 1, 3, -4]], 10), [None])
    check('explicit case 8', solve([[-2, 1, 4, 14]], 10), [[0, 5, 2, 9]])
    check('explicit case 9', solve([[0, '2.5', 9, '2.5']], 10), [[0, 3, 9, 3]])
    check('explicit case 10', solve([[0, '1.5', 2, '1.5']], 10), [[0, 2, 2, 2]])
    check('explicit case 11', solve([[0, 0, 13, 0]], 10), [[0, 0, 9, 0]])
    check('explicit case 12', solve([['-9', '-15/2', '18', '33/2']], 10), [[0, 1, 9, 9]])
    check('explicit case 13', solve([[2, 1, 4, 15]], 10), [[2, 1, 3, 9]])
    check('explicit case 14', solve([[3, 12, 1, -2]], 10), [[3, 9, 1, 0]])
    check('explicit case 15', solve([[12, 1, 1, 13]], 10), [[9, 4, 5, 9]])
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
explicit case 0[[1, 1, 4, 3]][[1, 1, 4, 3]]Passed
explicit case 1[[0, 2, 5, 2]][[0, 2, 5, 2]]Passed
explicit case 2[[0, 0, 5, 5]][[0, 0, 5, 5]]Passed
explicit case 3[None][None]Passed
explicit case 4[[0, 0, 5, 5]][[0, 0, 5, 5]]Passed
explicit case 5[[0, 0, 5, 0]][[0, 0, 5, 0]]Passed
explicit case 6[None][None]Passed
explicit case 7[None][None]Passed
explicit case 8[[0, 4, 1, 5]][[0, 4, 1, 5]]Passed
explicit case 9[[0, 3, 5, 3]][[0, 3, 5, 3]]Passed
explicit case 10[[0, 2, 2, 2]][[0, 2, 2, 2]]Passed
explicit case 11[[0, 0, 5, 0]][[0, 0, 5, 0]]Passed
explicit case 12[[0, 1, 5, 5]][[0, 1, 5, 5]]Passed
explicit case 13[[2, 1, 3, 5]][[2, 1, 3, 5]]Passed
explicit case 14[[2, 5, 1, 0]][[2, 5, 1, 0]]Passed
explicit case 15[[5, 4, 5, 5]][[5, 4, 5, 5]]Passed

SHA-256 / 8885092b602f3d5a6f5769f10ad2a90f91243932b6afd68cbfb3a0c3db9666bb

Verification & scope

Exact integer/rational arithmetic on small stipulated fixtures models the clipping decision only; no memory layout, GPU pipeline, graphics API or standards conformance 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:45:20.056972+00:00.

Case digest / ccda99103d8aa7b1471ec1fafb2bbd4b6b6d989044e3d446ff2a0eafa13d1124