FA-89656 / Instruction set emulation / Open access
DEC half borrow uses the increment rule · case 01
Decrementing 0x10 leaves H clear.
ROOT CAUSE
The DEC half-flag test is copied from INC.
VERIFIED REPAIR
H is set when the operand low nibble is 0 (borrow from bit 4).
Unsuccessful approach: Testing the result nibble for 0 flags 0x11->0x10 instead of 0x10->0x0F.
Case contract
Input [a, ops]; ops are 'inc', 'dec', ['add', v], ['sub', v] on 8-bit A; carry starts 0. After each op report [A, S, Z, H, PV, N, C]. inc: H = carry out of bit 3, PV = (A was 0x7F), N = 0, C unchanged. dec: H = borrow from bit 4 (low nibble was 0), PV = (A was 0x80), N = 1, C unchanged. add: H = carry out of bit 3, PV = signed overflow, N = 0, C = carry out. sub: H = borrow into bit 4 (low nibble of A < low nibble of v), PV = signed overflow, N = 1, C = borrow.
Why this case matters
Half-carry and parity/overflow flags are observable through DAA and conditional branches; emulators often get the INC/DEC special cases wrong.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
a, ops = args
c = 0
out = []
for op in ops:
if op == 'inc':
r = (a + 1) & 0xFF
h = int((a & 0x0F) == 0x0F)
pv = int(a == 0x7F)
nflag = 0
elif op == 'dec':
r = (a - 1) & 0xFF
h = int((a & 0x0F) == 0x0F)
pv = int(a == 0x80)
nflag = 1
else:
kind, v = op
if kind == 'add':
full = a + v
h = int((a & 0x0F) + (v & 0x0F) > 0x0F)
pv = int(((a ^ ~v) & (a ^ full) & 0x80) != 0)
nflag = 0
else:
full = a - v
h = int((a & 0x0F) < (v & 0x0F))
pv = int(((a ^ v) & (a ^ full) & 0x80) != 0)
nflag = 1
c = int(full > 0xFF or full < 0)
r = full & 0xFF
a = r
out.append([a, r >> 7, int(r == 0), h, pv, nflag, c])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('inc across nibble', [31, ['inc', 'inc']], [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [17, ['dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 4], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 113], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 7], ['add', 64]]], [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [47, ['inc', 'inc']], [[48, 0, 0, 1, 0, 0, 0], [49, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [18, ['dec', 'dec', 'dec']], [[17, 0, 0, 0, 0, 1, 0], [16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 5], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [27, 0, 0, 1, 0, 1, 0], [12, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 114], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [241, 1, 0, 1, 1, 0, 0], [97, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 8], ['add', 64]]], [[66, 0, 0, 1, 0, 0, 0], [130, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [63, ['inc', 'inc']], [[64, 0, 0, 1, 0, 0, 0], [65, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [19, ['dec', 'dec', 'dec']], [[18, 0, 0, 0, 0, 1, 0], [17, 0, 0, 0, 0, 1, 0], [16, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 6], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [26, 0, 0, 1, 0, 1, 0], [11, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 115], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [242, 1, 0, 1, 1, 0, 0], [98, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 9], ['add', 64]]], [[67, 0, 0, 1, 0, 0, 0], [131, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [79, ['inc', 'inc']], [[80, 0, 0, 1, 0, 0, 0], [81, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1], [13, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [20, ['dec', 'dec', 'dec']], [[19, 0, 0, 0, 0, 1, 0], [18, 0, 0, 0, 0, 1, 0], [17, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 7], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [25, 0, 0, 1, 0, 1, 0], [10, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 116], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [243, 1, 0, 1, 1, 0, 0], [99, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 10], ['add', 64]]], [[68, 0, 0, 1, 0, 0, 0], [132, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [95, ['inc', 'inc']], [[96, 0, 0, 1, 0, 0, 0], [97, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1], [13, 0, 0, 0, 0, 1, 1], [12, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [21, ['dec', 'dec', 'dec']], [[20, 0, 0, 0, 0, 1, 0], [19, 0, 0, 0, 0, 1, 0], [18, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 8], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [24, 0, 0, 1, 0, 1, 0], [9, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 117], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [244, 1, 0, 1, 1, 0, 0], [100, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 11], ['add', 64]]], [[69, 0, 0, 1, 0, 0, 0], [133, 1, 0, 0, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| inc across nibble | [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]] | [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]] | Passed |
| inc into sign overflow | [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]] | [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]] | Passed |
| inc wraps to zero keeps carry | [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]] | [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]] | Passed |
| inc from ff | [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]] | [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]] | Passed |
| dec across nibble | [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 0, 0, 1, 0], [14, 0, 0, 1, 0, 1, 0]] | [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]] | Failed |
| dec out of sign overflow | [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 0, 1, 1, 0], [126, 0, 0, 1, 0, 1, 0]] | [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]] | Failed |
| sub half borrow | [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]] | [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]] | Passed |
| sub overflow | [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]] | [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]] | Passed |
| add half carry and overflow | [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]] | [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]] | Passed |
SHA-256 / 40a07f0ad23b2bf784573448949fcfe7a799c8670b9e6b2230fa7114428abc42
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
a, ops = args
c = 0
out = []
for op in ops:
if op == 'inc':
r = (a + 1) & 0xFF
h = int((a & 0x0F) == 0x0F)
pv = int(a == 0x7F)
nflag = 0
elif op == 'dec':
r = (a - 1) & 0xFF
h = int((r & 0x0F) == 0x00)
pv = int(a == 0x80)
nflag = 1
else:
kind, v = op
if kind == 'add':
full = a + v
h = int((a & 0x0F) + (v & 0x0F) > 0x0F)
pv = int(((a ^ ~v) & (a ^ full) & 0x80) != 0)
nflag = 0
else:
full = a - v
h = int((a & 0x0F) < (v & 0x0F))
pv = int(((a ^ v) & (a ^ full) & 0x80) != 0)
nflag = 1
c = int(full > 0xFF or full < 0)
r = full & 0xFF
a = r
out.append([a, r >> 7, int(r == 0), h, pv, nflag, c])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('inc across nibble', [31, ['inc', 'inc']], [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [17, ['dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 4], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 113], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 7], ['add', 64]]], [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [47, ['inc', 'inc']], [[48, 0, 0, 1, 0, 0, 0], [49, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [18, ['dec', 'dec', 'dec']], [[17, 0, 0, 0, 0, 1, 0], [16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 5], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [27, 0, 0, 1, 0, 1, 0], [12, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 114], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [241, 1, 0, 1, 1, 0, 0], [97, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 8], ['add', 64]]], [[66, 0, 0, 1, 0, 0, 0], [130, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [63, ['inc', 'inc']], [[64, 0, 0, 1, 0, 0, 0], [65, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [19, ['dec', 'dec', 'dec']], [[18, 0, 0, 0, 0, 1, 0], [17, 0, 0, 0, 0, 1, 0], [16, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 6], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [26, 0, 0, 1, 0, 1, 0], [11, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 115], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [242, 1, 0, 1, 1, 0, 0], [98, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 9], ['add', 64]]], [[67, 0, 0, 1, 0, 0, 0], [131, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [79, ['inc', 'inc']], [[80, 0, 0, 1, 0, 0, 0], [81, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1], [13, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [20, ['dec', 'dec', 'dec']], [[19, 0, 0, 0, 0, 1, 0], [18, 0, 0, 0, 0, 1, 0], [17, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 7], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [25, 0, 0, 1, 0, 1, 0], [10, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 116], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [243, 1, 0, 1, 1, 0, 0], [99, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 10], ['add', 64]]], [[68, 0, 0, 1, 0, 0, 0], [132, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [95, ['inc', 'inc']], [[96, 0, 0, 1, 0, 0, 0], [97, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1], [13, 0, 0, 0, 0, 1, 1], [12, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [21, ['dec', 'dec', 'dec']], [[20, 0, 0, 0, 0, 1, 0], [19, 0, 0, 0, 0, 1, 0], [18, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 8], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [24, 0, 0, 1, 0, 1, 0], [9, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 117], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [244, 1, 0, 1, 1, 0, 0], [100, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 11], ['add', 64]]], [[69, 0, 0, 1, 0, 0, 0], [133, 1, 0, 0, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| inc across nibble | [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]] | [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]] | Passed |
| inc into sign overflow | [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]] | [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]] | Passed |
| inc wraps to zero keeps carry | [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 1, 0, 1, 1]] | [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]] | Failed |
| inc from ff | [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]] | [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]] | Passed |
| dec across nibble | [[16, 0, 0, 1, 0, 1, 0], [15, 0, 0, 0, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]] | [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]] | Failed |
| dec out of sign overflow | [[128, 1, 0, 1, 0, 1, 0], [127, 0, 0, 0, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]] | [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]] | Failed |
| sub half borrow | [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]] | [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]] | Passed |
| sub overflow | [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]] | [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]] | Passed |
| add half carry and overflow | [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]] | [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]] | Passed |
SHA-256 / 0a4df6b8ddd3c6caba52b26c26d1da175fa8c7cfe3c9f1d6c20dfe6a1b80118c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
a, ops = args
c = 0
out = []
for op in ops:
if op == 'inc':
r = (a + 1) & 0xFF
h = int((a & 0x0F) == 0x0F)
pv = int(a == 0x7F)
nflag = 0
elif op == 'dec':
r = (a - 1) & 0xFF
h = int((a & 0x0F) == 0x00)
pv = int(a == 0x80)
nflag = 1
else:
kind, v = op
if kind == 'add':
full = a + v
h = int((a & 0x0F) + (v & 0x0F) > 0x0F)
pv = int(((a ^ ~v) & (a ^ full) & 0x80) != 0)
nflag = 0
else:
full = a - v
h = int((a & 0x0F) < (v & 0x0F))
pv = int(((a ^ v) & (a ^ full) & 0x80) != 0)
nflag = 1
c = int(full > 0xFF or full < 0)
r = full & 0xFF
a = r
out.append([a, r >> 7, int(r == 0), h, pv, nflag, c])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('inc across nibble', [31, ['inc', 'inc']], [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [17, ['dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 4], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 113], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 7], ['add', 64]]], [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [47, ['inc', 'inc']], [[48, 0, 0, 1, 0, 0, 0], [49, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [18, ['dec', 'dec', 'dec']], [[17, 0, 0, 0, 0, 1, 0], [16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 5], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [27, 0, 0, 1, 0, 1, 0], [12, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 114], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [241, 1, 0, 1, 1, 0, 0], [97, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 8], ['add', 64]]], [[66, 0, 0, 1, 0, 0, 0], [130, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [63, ['inc', 'inc']], [[64, 0, 0, 1, 0, 0, 0], [65, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [19, ['dec', 'dec', 'dec']], [[18, 0, 0, 0, 0, 1, 0], [17, 0, 0, 0, 0, 1, 0], [16, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 6], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [26, 0, 0, 1, 0, 1, 0], [11, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 115], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [242, 1, 0, 1, 1, 0, 0], [98, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 9], ['add', 64]]], [[67, 0, 0, 1, 0, 0, 0], [131, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [79, ['inc', 'inc']], [[80, 0, 0, 1, 0, 0, 0], [81, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1], [13, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [20, ['dec', 'dec', 'dec']], [[19, 0, 0, 0, 0, 1, 0], [18, 0, 0, 0, 0, 1, 0], [17, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 7], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [25, 0, 0, 1, 0, 1, 0], [10, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 116], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [243, 1, 0, 1, 1, 0, 0], [99, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 10], ['add', 64]]], [[68, 0, 0, 1, 0, 0, 0], [132, 1, 0, 0, 1, 0, 0]])], [('inc across nibble', [95, ['inc', 'inc']], [[96, 0, 0, 1, 0, 0, 0], [97, 0, 0, 0, 0, 0, 0]]), ('inc into sign overflow', [126, ['inc', 'inc', 'inc']], [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]]), ('inc wraps to zero keeps carry', [240, [['add', 32], 'inc', 'dec', 'dec', 'dec', 'dec', 'dec']], [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1], [15, 0, 0, 1, 0, 1, 1], [14, 0, 0, 0, 0, 1, 1], [13, 0, 0, 0, 0, 1, 1], [12, 0, 0, 0, 0, 1, 1]]), ('inc from ff', [255, ['inc', ['sub', 1], 'inc']], [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]]), ('dec across nibble', [21, ['dec', 'dec', 'dec']], [[20, 0, 0, 0, 0, 1, 0], [19, 0, 0, 0, 0, 1, 0], [18, 0, 0, 0, 0, 1, 0]]), ('dec out of sign overflow', [129, ['dec', 'dec', 'dec']], [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]]), ('sub half borrow', [50, [['sub', 18], ['sub', 8], ['sub', 15]]], [[32, 0, 0, 0, 0, 1, 0], [24, 0, 0, 1, 0, 1, 0], [9, 0, 0, 1, 0, 1, 0]]), ('sub overflow', [128, [['sub', 1], ['add', 117], ['sub', 144]]], [[127, 0, 0, 1, 1, 1, 0], [244, 1, 0, 1, 1, 0, 0], [100, 0, 0, 0, 0, 1, 0]]), ('add half carry and overflow', [58, [['add', 11], ['add', 64]]], [[69, 0, 0, 1, 0, 0, 0], [133, 1, 0, 0, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| inc across nibble | [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]] | [[32, 0, 0, 1, 0, 0, 0], [33, 0, 0, 0, 0, 0, 0]] | Passed |
| inc into sign overflow | [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]] | [[127, 0, 0, 0, 0, 0, 0], [128, 1, 0, 1, 1, 0, 0], [129, 1, 0, 0, 0, 0, 0]] | Passed |
| inc wraps to zero keeps carry | [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]] | [[16, 0, 0, 0, 0, 0, 1], [17, 0, 0, 0, 0, 0, 1], [16, 0, 0, 0, 0, 1, 1]] | Passed |
| inc from ff | [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]] | [[0, 0, 1, 1, 0, 0, 0], [255, 1, 0, 1, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1]] | Passed |
| dec across nibble | [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]] | [[16, 0, 0, 0, 0, 1, 0], [15, 0, 0, 1, 0, 1, 0], [14, 0, 0, 0, 0, 1, 0]] | Passed |
| dec out of sign overflow | [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]] | [[128, 1, 0, 0, 0, 1, 0], [127, 0, 0, 1, 1, 1, 0], [126, 0, 0, 0, 0, 1, 0]] | Passed |
| sub half borrow | [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]] | [[32, 0, 0, 0, 0, 1, 0], [28, 0, 0, 1, 0, 1, 0], [13, 0, 0, 1, 0, 1, 0]] | Passed |
| sub overflow | [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]] | [[127, 0, 0, 1, 1, 1, 0], [240, 1, 0, 1, 1, 0, 0], [96, 0, 0, 0, 0, 1, 0]] | Passed |
| add half carry and overflow | [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]] | [[65, 0, 0, 1, 0, 0, 0], [129, 1, 0, 0, 1, 0, 0]] | Passed |
SHA-256 / 2e1f0f8ed98dcaf75321998c3a9a050941fbdd602e5f683b75dfad3fc1131bf9
Verification & scope
A deterministic bounded teaching model of one emulator rule; the instruction semantics are a stipulated contract inspired by common ISAs and are not a claim of cycle-exact or architectural conformance. 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:51:19.384608+00:00.
Case digest / 5119ee15de969590964ddb6e3d813b890c3510b2ff130317501a7558358f8f80