FAILURE MAP
← Case archive

FA-75686 / Text diff and three-way merge / Open access

Intraline change pairing: unmatched lines are paired with empty strings · case 01

Extra removed or added lines produce spurious pairs against an empty line.

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

ROOT CAUSE

Pairs are formed with zip_longest, padding the shorter side.

VERIFIED REPAIR

Pair only up to the shorter of the two runs.

Unsuccessful approach: Filtering pairs with an empty added side still pairs extra added lines with an empty removal.

Case contract

Within each block of consecutive "-" lines immediately followed by consecutive "+" lines, pair the i-th removed line with the i-th added line (extra lines stay unpaired). For each pair report the common prefix length and the common suffix length, where the suffix may not overlap the prefix. Return [old, new, prefix, suffix] rows.

Why this case matters

Word and character highlighting inside changed lines depends on pairing lines and trimming their shared ends.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(ops):
    res = []
    i = 0
    while i < len(ops):
        if ops[i][0] != '-':
            i += 1
            continue
        dels = []
        while i < len(ops) and ops[i][0] == '-':
            dels.append(ops[i][1])
            i += 1
        adds = []
        while i < len(ops) and ops[i][0] == '+':
            adds.append(ops[i][1])
            i += 1
        for d, a in itertools.zip_longest(dels, adds, fillvalue=''):
            p = 0
            while p < min(len(d), len(a)) and d[p] == a[p]:
                p += 1
            s = 0
            while s < min(len(d), len(a)) - p and d[-1 - s] == a[-1 - s]:
                s += 1
            res.append([d, a, p, s])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 21']]], [['value = 1', 'value = 21', 8, 1]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababab']]], [['abab', 'ababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r1']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    2: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 22']]], [['value = 1', 'value = 22', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'abababab']]], [['abab', 'abababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r2']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    3: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 23']]], [['value = 1', 'value = 23', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababababab']]], [['abab', 'ababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r3']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    4: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 24']]], [['value = 1', 'value = 24', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'abababababab']]], [['abab', 'abababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r4']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    5: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 25']]], [['value = 1', 'value = 25', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababababababab']]], [['abab', 'ababababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r5']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
}[N]
for label, args, expected in cases:
    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
simple replacement[['value = 1', 'value = 21', 8, 1]][['value = 1', 'value = 21', 8, 1]]Passed
suffix must not overlap prefix[['aa', 'aaa', 2, 0]][['aa', 'aaa', 2, 0]]Passed
overlap with repeated characters[['abab', 'ababab', 4, 0]][['abab', 'ababab', 4, 0]]Passed
pairs do not cross context[['old', '', 0, 0]][]Failed
more deletions than insertions[['x1', 'y1', 0, 1], ['x2', '', 0, 0]][['x1', 'y1', 0, 1]]Failed
more insertions than deletions[['p', 'q', 0, 0], ['', 'r1', 0, 0]][['p', 'q', 0, 0]]Failed
pure insertion block[['d', 'e', 0, 0]][['d', 'e', 0, 0]]Passed
two blocks[['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]][['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]]Passed

SHA-256 / 3e8b73eb54956f972a855a471352ca3dd4e80507c3405c5d0eb10f9077d2a41a

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(ops):
    res = []
    i = 0
    while i < len(ops):
        if ops[i][0] != '-':
            i += 1
            continue
        dels = []
        while i < len(ops) and ops[i][0] == '-':
            dels.append(ops[i][1])
            i += 1
        adds = []
        while i < len(ops) and ops[i][0] == '+':
            adds.append(ops[i][1])
            i += 1
        for d, a in [x for x in itertools.zip_longest(dels, adds, fillvalue='') if x[1] != '']:
            p = 0
            while p < min(len(d), len(a)) and d[p] == a[p]:
                p += 1
            s = 0
            while s < min(len(d), len(a)) - p and d[-1 - s] == a[-1 - s]:
                s += 1
            res.append([d, a, p, s])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 21']]], [['value = 1', 'value = 21', 8, 1]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababab']]], [['abab', 'ababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r1']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    2: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 22']]], [['value = 1', 'value = 22', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'abababab']]], [['abab', 'abababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r2']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    3: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 23']]], [['value = 1', 'value = 23', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababababab']]], [['abab', 'ababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r3']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    4: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 24']]], [['value = 1', 'value = 24', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'abababababab']]], [['abab', 'abababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r4']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    5: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 25']]], [['value = 1', 'value = 25', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababababababab']]], [['abab', 'ababababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r5']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
}[N]
for label, args, expected in cases:
    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
simple replacement[['value = 1', 'value = 21', 8, 1]][['value = 1', 'value = 21', 8, 1]]Passed
suffix must not overlap prefix[['aa', 'aaa', 2, 0]][['aa', 'aaa', 2, 0]]Passed
overlap with repeated characters[['abab', 'ababab', 4, 0]][['abab', 'ababab', 4, 0]]Passed
pairs do not cross context[][]Passed
more deletions than insertions[['x1', 'y1', 0, 1]][['x1', 'y1', 0, 1]]Passed
more insertions than deletions[['p', 'q', 0, 0], ['', 'r1', 0, 0]][['p', 'q', 0, 0]]Failed
pure insertion block[['d', 'e', 0, 0]][['d', 'e', 0, 0]]Passed
two blocks[['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]][['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]]Passed

SHA-256 / 3560116af58a20e8b2168c97231d1fe6b8b691cdfb7a31ff5bde9b6a21bdc0d2

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(ops):
    res = []
    i = 0
    while i < len(ops):
        if ops[i][0] != '-':
            i += 1
            continue
        dels = []
        while i < len(ops) and ops[i][0] == '-':
            dels.append(ops[i][1])
            i += 1
        adds = []
        while i < len(ops) and ops[i][0] == '+':
            adds.append(ops[i][1])
            i += 1
        for d, a in zip(dels, adds):
            p = 0
            while p < min(len(d), len(a)) and d[p] == a[p]:
                p += 1
            s = 0
            while s < min(len(d), len(a)) - p and d[-1 - s] == a[-1 - s]:
                s += 1
            res.append([d, a, p, s])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 21']]], [['value = 1', 'value = 21', 8, 1]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababab']]], [['abab', 'ababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r1']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    2: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 22']]], [['value = 1', 'value = 22', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'abababab']]], [['abab', 'abababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r2']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    3: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 23']]], [['value = 1', 'value = 23', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababababab']]], [['abab', 'ababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r3']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    4: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 24']]], [['value = 1', 'value = 24', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'abababababab']]], [['abab', 'abababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r4']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
    5: [('simple replacement', [[[' ', 'ctx'], ['-', 'value = 1'], ['+', 'value = 25']]], [['value = 1', 'value = 25', 8, 0]]), ('suffix must not overlap prefix', [[['-', 'aa'], ['+', 'aaa']]], [['aa', 'aaa', 2, 0]]), ('overlap with repeated characters', [[['-', 'abab'], ['+', 'ababababababab']]], [['abab', 'ababababababab', 4, 0]]), ('pairs do not cross context', [[['-', 'old'], [' ', 'keep'], ['+', 'new']]], []), ('more deletions than insertions', [[['-', 'x1'], ['-', 'x2'], ['+', 'y1']]], [['x1', 'y1', 0, 1]]), ('more insertions than deletions', [[['-', 'p'], ['+', 'q'], ['+', 'r5']]], [['p', 'q', 0, 0]]), ('pure insertion block', [[['+', 'only'], [' ', 'c'], ['-', 'd'], ['+', 'e']]], [['d', 'e', 0, 0]]), ('two blocks', [[['-', 'foo(a)'], ['+', 'foo(b)'], [' ', 'x'], [' ', 'y'], ['-', 'bar'], ['+', 'baz']]], [['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]])],
}[N]
for label, args, expected in cases:
    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
simple replacement[['value = 1', 'value = 21', 8, 1]][['value = 1', 'value = 21', 8, 1]]Passed
suffix must not overlap prefix[['aa', 'aaa', 2, 0]][['aa', 'aaa', 2, 0]]Passed
overlap with repeated characters[['abab', 'ababab', 4, 0]][['abab', 'ababab', 4, 0]]Passed
pairs do not cross context[][]Passed
more deletions than insertions[['x1', 'y1', 0, 1]][['x1', 'y1', 0, 1]]Passed
more insertions than deletions[['p', 'q', 0, 0]][['p', 'q', 0, 0]]Passed
pure insertion block[['d', 'e', 0, 0]][['d', 'e', 0, 0]]Passed
two blocks[['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]][['foo(a)', 'foo(b)', 4, 1], ['bar', 'baz', 2, 0]]Passed

SHA-256 / 9ab514a32626ced31b0ec0cafb9e2adab1de9e358c2bd2ef432b1066885a5eb3

Verification & scope

A deterministic, bounded teaching model of one diff, patch or merge rule with stipulated conventions; it is not a production diff or version-control implementation and makes no claim of conformance to any specific tool. 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:09.116071+00:00.

Case digest / 4c0ac9f59d47f380d39e8c6a842d346a4067c88854c6cb9cd0f37ce0af97d82b