FAILURE MAP
← Case archive

FA-80676 / Bidirectional text layout / Open access

Bidi selection highlight: backward selection normalisation · case 01

Selections dragged right-to-left highlight nothing.

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

ROOT CAUSE

Anchor and focus are not ordered before building the range.

VERIFIED REPAIR

Normalise to the smaller and larger offset.

Unsuccessful approach: Unconditionally swapping breaks forward selections.

Case contract

Input [levels, anchor, focus]. The logical selection covers characters min..max-1. Each selected character occupies its unit visual slot (level reversal); merge adjacent slots into [x0, x1) rectangles sorted by x. Return the rectangles.

Why this case matters

Mixed right-to-left and left-to-right text must resolve levels and visual order exactly, or words, numbers and carets land in the wrong place.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    def reorder(lv):
        vis = list(range(len(lv)))
        odd = [l for l in lv if l % 2 == 1]
        if not odd:
            return vis
        for lev in range(max(lv), min(odd) - 1, -1):
            i = 0
            while i < len(vis):
                if lv[vis[i]] >= lev:
                    j = i
                    while j < len(vis) and lv[vis[j]] >= lev:
                        j += 1
                    vis[i:j] = vis[i:j][::-1]
                    i = j
                else:
                    i += 1
        return vis
    
    levels, a, b = x
    a, b = a, b
    vis = reorder(levels)
    pos = [0] * len(levels)
    for v, i in enumerate(vis):
        pos[i] = v
    sel = sorted(pos[i] for i in range(a, b))
    rects = []
    for p in sel:
        if rects and rects[-1][1] == p:
            rects[-1][1] = p + 1
        else:
            rects.append([p, p + 1])
    return rects
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('regression: backward selection normalisation', [[2, 4, 4, 3, 3], 4, 1], [[2, 5]]), ('partial-repair probe', [[0, 0, 0, 1, 1, 1, 1], 1, 4], [[1, 3], [6, 7]]), ('partial-repair probe', [[1, 1, 1, 1, 1, 1, 4, 2, 2, 2, 2, 1], 4, 9], [[1, 4], [6, 8]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[1, 1], 1, 1], []), ('control layout', [[1, 1, 1], 0, 0], []), ('control layout', [[3], 1, 1], [])], [('regression: backward selection normalisation', [[1, 3, 3], 1, 0], [[2, 3]]), ('regression: backward selection normalisation', [[1, 1, 2, 1, 2, 2, 2, 2, 4, 4], 5, 1], [[0, 1], [6, 9]]), ('partial-repair probe', [[1, 1, 1, 1, 1, 1, 1, 0, 0, 0], 2, 8], [[0, 5], [7, 8]]), ('partial-repair probe', [[0, 2, 2, 0, 0, 0, 0, 2, 2], 0, 4], [[0, 4]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('control layout', [[1, 1, 1, 2], 3, 3], []), ('control layout', [[4, 4, 2, 3, 3, 3, 4, 2, 2, 2, 2], 6, 6], [])], [('regression: backward selection normalisation', [[4, 4, 3, 4], 4, 2], [[0, 2]]), ('regression: backward selection normalisation', [[2, 2, 2, 2, 2, 4, 4], 7, 0], [[0, 7]]), ('partial-repair probe', [[1, 1, 1, 4, 4, 3, 3, 3, 2], 3, 7], [[1, 5]]), ('partial-repair probe', [[2, 2, 2, 2, 2, 4, 4, 4, 3, 3, 3], 10, 11], [[5, 6]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('control layout', [[4, 1, 3, 3, 3, 3], 0, 0], []), ('control layout', [[2, 2], 1, 1], [])], [('regression: backward selection normalisation', [[1], 1, 0], [[0, 1]]), ('regression: backward selection normalisation', [[3, 3, 3, 0], 4, 3], [[3, 4]]), ('partial-repair probe', [[2, 4, 4, 4, 4, 2, 2, 1, 1, 1, 4], 5, 11], [[0, 4], [9, 11]]), ('partial-repair probe', [[1, 1, 1, 1, 0, 0, 0], 3, 7], [[0, 1], [4, 7]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[0], 1, 1], []), ('control layout', [[1], 0, 0], [])], [('regression: backward selection normalisation', [[3, 3, 1, 1, 1, 4, 1, 1, 1, 1], 8, 6], [[2, 4]]), ('regression: backward selection normalisation', [[0, 0, 3, 3, 3, 2, 3, 0, 0], 8, 4], [[2, 3], [5, 8]]), ('partial-repair probe', [[0, 0, 0, 0], 0, 4], [[0, 4]]), ('partial-repair probe', [[0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1], 4, 7], [[7, 10]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[3, 3], 2, 2], []), ('control layout', [[1], 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 fixtureActualExpectedOutcome
backward selection[][[0, 2]]Failed
regression: backward selection normalisation[][[2, 5]]Failed
partial-repair probe[[1, 3], [6, 7]][[1, 3], [6, 7]]Passed
partial-repair probe[[1, 4], [6, 8]][[1, 4], [6, 8]]Passed
selection crossing direction change[[1, 4]][[1, 4]]Passed
control layout[][]Passed
control layout[][]Passed
control layout[][]Passed

SHA-256 / 5698fa7906a794730f28cce1f1b3145f7b77ad9237570e0ecf923d54b97978c8

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    def reorder(lv):
        vis = list(range(len(lv)))
        odd = [l for l in lv if l % 2 == 1]
        if not odd:
            return vis
        for lev in range(max(lv), min(odd) - 1, -1):
            i = 0
            while i < len(vis):
                if lv[vis[i]] >= lev:
                    j = i
                    while j < len(vis) and lv[vis[j]] >= lev:
                        j += 1
                    vis[i:j] = vis[i:j][::-1]
                    i = j
                else:
                    i += 1
        return vis
    
    levels, a, b = x
    a, b = b, a
    vis = reorder(levels)
    pos = [0] * len(levels)
    for v, i in enumerate(vis):
        pos[i] = v
    sel = sorted(pos[i] for i in range(a, b))
    rects = []
    for p in sel:
        if rects and rects[-1][1] == p:
            rects[-1][1] = p + 1
        else:
            rects.append([p, p + 1])
    return rects
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('regression: backward selection normalisation', [[2, 4, 4, 3, 3], 4, 1], [[2, 5]]), ('partial-repair probe', [[0, 0, 0, 1, 1, 1, 1], 1, 4], [[1, 3], [6, 7]]), ('partial-repair probe', [[1, 1, 1, 1, 1, 1, 4, 2, 2, 2, 2, 1], 4, 9], [[1, 4], [6, 8]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[1, 1], 1, 1], []), ('control layout', [[1, 1, 1], 0, 0], []), ('control layout', [[3], 1, 1], [])], [('regression: backward selection normalisation', [[1, 3, 3], 1, 0], [[2, 3]]), ('regression: backward selection normalisation', [[1, 1, 2, 1, 2, 2, 2, 2, 4, 4], 5, 1], [[0, 1], [6, 9]]), ('partial-repair probe', [[1, 1, 1, 1, 1, 1, 1, 0, 0, 0], 2, 8], [[0, 5], [7, 8]]), ('partial-repair probe', [[0, 2, 2, 0, 0, 0, 0, 2, 2], 0, 4], [[0, 4]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('control layout', [[1, 1, 1, 2], 3, 3], []), ('control layout', [[4, 4, 2, 3, 3, 3, 4, 2, 2, 2, 2], 6, 6], [])], [('regression: backward selection normalisation', [[4, 4, 3, 4], 4, 2], [[0, 2]]), ('regression: backward selection normalisation', [[2, 2, 2, 2, 2, 4, 4], 7, 0], [[0, 7]]), ('partial-repair probe', [[1, 1, 1, 4, 4, 3, 3, 3, 2], 3, 7], [[1, 5]]), ('partial-repair probe', [[2, 2, 2, 2, 2, 4, 4, 4, 3, 3, 3], 10, 11], [[5, 6]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('control layout', [[4, 1, 3, 3, 3, 3], 0, 0], []), ('control layout', [[2, 2], 1, 1], [])], [('regression: backward selection normalisation', [[1], 1, 0], [[0, 1]]), ('regression: backward selection normalisation', [[3, 3, 3, 0], 4, 3], [[3, 4]]), ('partial-repair probe', [[2, 4, 4, 4, 4, 2, 2, 1, 1, 1, 4], 5, 11], [[0, 4], [9, 11]]), ('partial-repair probe', [[1, 1, 1, 1, 0, 0, 0], 3, 7], [[0, 1], [4, 7]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[0], 1, 1], []), ('control layout', [[1], 0, 0], [])], [('regression: backward selection normalisation', [[3, 3, 1, 1, 1, 4, 1, 1, 1, 1], 8, 6], [[2, 4]]), ('regression: backward selection normalisation', [[0, 0, 3, 3, 3, 2, 3, 0, 0], 8, 4], [[2, 3], [5, 8]]), ('partial-repair probe', [[0, 0, 0, 0], 0, 4], [[0, 4]]), ('partial-repair probe', [[0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1], 4, 7], [[7, 10]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[3, 3], 2, 2], []), ('control layout', [[1], 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 fixtureActualExpectedOutcome
backward selection[[0, 2]][[0, 2]]Passed
regression: backward selection normalisation[[2, 5]][[2, 5]]Passed
partial-repair probe[][[1, 3], [6, 7]]Failed
partial-repair probe[][[1, 4], [6, 8]]Failed
selection crossing direction change[][[1, 4]]Failed
control layout[][]Passed
control layout[][]Passed
control layout[][]Passed

SHA-256 / 8560b50259d9b444c94db437fcf21d23a9e75f17037a9feeddea185e8b9b6527

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    def reorder(lv):
        vis = list(range(len(lv)))
        odd = [l for l in lv if l % 2 == 1]
        if not odd:
            return vis
        for lev in range(max(lv), min(odd) - 1, -1):
            i = 0
            while i < len(vis):
                if lv[vis[i]] >= lev:
                    j = i
                    while j < len(vis) and lv[vis[j]] >= lev:
                        j += 1
                    vis[i:j] = vis[i:j][::-1]
                    i = j
                else:
                    i += 1
        return vis
    
    levels, a, b = x
    a, b = min(a, b), max(a, b)
    vis = reorder(levels)
    pos = [0] * len(levels)
    for v, i in enumerate(vis):
        pos[i] = v
    sel = sorted(pos[i] for i in range(a, b))
    rects = []
    for p in sel:
        if rects and rects[-1][1] == p:
            rects[-1][1] = p + 1
        else:
            rects.append([p, p + 1])
    return rects
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('regression: backward selection normalisation', [[2, 4, 4, 3, 3], 4, 1], [[2, 5]]), ('partial-repair probe', [[0, 0, 0, 1, 1, 1, 1], 1, 4], [[1, 3], [6, 7]]), ('partial-repair probe', [[1, 1, 1, 1, 1, 1, 4, 2, 2, 2, 2, 1], 4, 9], [[1, 4], [6, 8]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[1, 1], 1, 1], []), ('control layout', [[1, 1, 1], 0, 0], []), ('control layout', [[3], 1, 1], [])], [('regression: backward selection normalisation', [[1, 3, 3], 1, 0], [[2, 3]]), ('regression: backward selection normalisation', [[1, 1, 2, 1, 2, 2, 2, 2, 4, 4], 5, 1], [[0, 1], [6, 9]]), ('partial-repair probe', [[1, 1, 1, 1, 1, 1, 1, 0, 0, 0], 2, 8], [[0, 5], [7, 8]]), ('partial-repair probe', [[0, 2, 2, 0, 0, 0, 0, 2, 2], 0, 4], [[0, 4]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('control layout', [[1, 1, 1, 2], 3, 3], []), ('control layout', [[4, 4, 2, 3, 3, 3, 4, 2, 2, 2, 2], 6, 6], [])], [('regression: backward selection normalisation', [[4, 4, 3, 4], 4, 2], [[0, 2]]), ('regression: backward selection normalisation', [[2, 2, 2, 2, 2, 4, 4], 7, 0], [[0, 7]]), ('partial-repair probe', [[1, 1, 1, 4, 4, 3, 3, 3, 2], 3, 7], [[1, 5]]), ('partial-repair probe', [[2, 2, 2, 2, 2, 4, 4, 4, 3, 3, 3], 10, 11], [[5, 6]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('control layout', [[4, 1, 3, 3, 3, 3], 0, 0], []), ('control layout', [[2, 2], 1, 1], [])], [('regression: backward selection normalisation', [[1], 1, 0], [[0, 1]]), ('regression: backward selection normalisation', [[3, 3, 3, 0], 4, 3], [[3, 4]]), ('partial-repair probe', [[2, 4, 4, 4, 4, 2, 2, 1, 1, 1, 4], 5, 11], [[0, 4], [9, 11]]), ('partial-repair probe', [[1, 1, 1, 1, 0, 0, 0], 3, 7], [[0, 1], [4, 7]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[0], 1, 1], []), ('control layout', [[1], 0, 0], [])], [('regression: backward selection normalisation', [[3, 3, 1, 1, 1, 4, 1, 1, 1, 1], 8, 6], [[2, 4]]), ('regression: backward selection normalisation', [[0, 0, 3, 3, 3, 2, 3, 0, 0], 8, 4], [[2, 3], [5, 8]]), ('partial-repair probe', [[0, 0, 0, 0], 0, 4], [[0, 4]]), ('partial-repair probe', [[0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1], 4, 7], [[7, 10]]), ('backward selection', [[1, 1, 1], 3, 1], [[0, 2]]), ('selection crossing direction change', [[0, 0, 1, 1, 0], 1, 4], [[1, 4]]), ('control layout', [[3, 3], 2, 2], []), ('control layout', [[1], 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 fixtureActualExpectedOutcome
backward selection[[0, 2]][[0, 2]]Passed
regression: backward selection normalisation[[2, 5]][[2, 5]]Passed
partial-repair probe[[1, 3], [6, 7]][[1, 3], [6, 7]]Passed
partial-repair probe[[1, 4], [6, 8]][[1, 4], [6, 8]]Passed
selection crossing direction change[[1, 4]][[1, 4]]Passed
control layout[][]Passed
control layout[][]Passed
control layout[][]Passed

SHA-256 / e71f1346431705ac362fb7df5bddfb86c771ba88b2cfd99718001622dbb6b6ee

Verification & scope

A deterministic toy bidi model over stipulated class labels and integer levels; it is inspired by, but does not claim conformance to, any published algorithm. 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:49:56.106552+00:00.

Case digest / 309d48dd8a34047a4c327e175ef30cd0654686dcd51edd4759617c4ab5993771