FA-89666 / Instruction set emulation / Open access
DEC overflow flagged one step late · case 01
PV is set when decrementing 0x81 to 0x80 instead of 0x80 to 0x7F.
ROOT CAUSE
The DEC overflow test checks the result instead of the operand.
VERIFIED REPAIR
PV is set when the operand was 0x80.
Unsuccessful approach: Copying the INC value 0x7F tests the wrong boundary.
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) == 0x00)
pv = int(r == 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, 1, 1, 0], [127, 0, 0, 1, 0, 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 / 6266aac80197b65aba2574534144ef4b642b8c9e237c7eeffac43baa4a10ee0f
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((a & 0x0F) == 0x00)
pv = int(a == 0x7F)
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, 0, 1, 0], [126, 0, 0, 0, 1, 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 / db5b5e4938db2877b968bfdf6fb4789fc6957298234910f1a1b15c421e0b9458
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.421646+00:00.
Case digest / a255700d2905394c706b15cff9ce63e82ab01e429a18937e817b245f4ee66198