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.
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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