FA-89171 / Digital logic simulation / Open access
Hazard pair reported twice · case 01
Each hazard appears as both [a, b] and [b, a].
ROOT CAUSE
The neighbour loop does not restrict itself to the higher minterm of each pair.
VERIFIED REPAIR
Report each adjacent pair once, from its lower minterm.
Unsuccessful approach: Keeping only the lower neighbour reports every pair reversed.
Case contract
Input [nv, terms]: product terms are strings over '0','1','-' with character 0 the most significant variable. Minterm m is covered by a term when every non-'-' position matches bit (m >> (nv-1-k)) & 1. A static-1 hazard is a pair of adjacent minterms (differing in one bit), both in the on-set, that no single term covers together. Return sorted [low, high] pairs.
Why this case matters
Glitch analysis in logic simulators flags transitions that may pulse when two product terms hand off.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
nv, terms = args
def covers(t, m):
for k, ch in enumerate(t):
bit = (m >> (nv - 1 - k)) & 1
if ch != '-' and int(ch) != bit:
return False
return True
ones = [m for m in range(2 ** nv) if any(covers(t, m) for t in terms)]
out = []
for m in ones:
for k in range(nv):
p = m ^ (1 << k)
if p != m and p in ones and not any(covers(t, m) and covers(t, p) for t in terms):
out.append([m, p])
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cover 0', [3, ['1-0', '-11', '11-']], []), ('cover 1', [2, ['1-', '-1']], []), ('cover 2', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 3', [3, ['0-0', '1-1']], []), ('cover 4', [4, ['11--', '--11']], []), ('cover 5', [3, ['00-', '-01', '1-1']], []), ('cover 6', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [2, ['1-', '-1']], []), ('cover 1', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 2', [3, ['0-0', '1-1']], []), ('cover 3', [4, ['11--', '--11']], []), ('cover 4', [3, ['00-', '-01', '1-1']], []), ('cover 5', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 6', [3, ['1--', '-1-']], []), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 1', [3, ['0-0', '1-1']], []), ('cover 2', [4, ['11--', '--11']], []), ('cover 3', [3, ['00-', '-01', '1-1']], []), ('cover 4', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 5', [3, ['1--', '-1-']], []), ('cover 6', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [3, ['0-0', '1-1']], []), ('cover 1', [4, ['11--', '--11']], []), ('cover 2', [3, ['00-', '-01', '1-1']], []), ('cover 3', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 4', [3, ['1--', '-1-']], []), ('cover 5', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('cover 6', [3, ['10-', '-11']], [[5, 7]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [4, ['11--', '--11']], []), ('cover 1', [3, ['00-', '-01', '1-1']], []), ('cover 2', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 3', [3, ['1--', '-1-']], []), ('cover 4', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('cover 5', [3, ['10-', '-11']], [[5, 7]]), ('cover 6', [3, ['1-0', '-11', '11-']], []), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])]]
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 |
|---|---|---|---|
| cover 0 | [] | [] | Passed |
| cover 1 | [] | [] | Passed |
| cover 2 | [[2, 10], [6, 14], [10, 2], [12, 13], [13, 12], [14, 6], [14, 15], [15, 14]] | [[2, 10], [6, 14], [12, 13], [14, 15]] | Failed |
| cover 3 | [] | [] | Passed |
| cover 4 | [] | [] | Passed |
| cover 5 | [] | [] | Passed |
| cover 6 | [[3, 11], [7, 15], [11, 3], [12, 14], [13, 15], [14, 12], [15, 7], [15, 13]] | [[3, 11], [7, 15], [12, 14], [13, 15]] | Failed |
| msb only term | [[1, 5], [3, 7], [5, 1], [7, 3]] | [[1, 5], [3, 7]] | Failed |
SHA-256 / 6547d3e7738f80a6212fe05a4a63c4674bdfa17cd6f63bb2c3c54dda6ba089d9
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
nv, terms = args
def covers(t, m):
for k, ch in enumerate(t):
bit = (m >> (nv - 1 - k)) & 1
if ch != '-' and int(ch) != bit:
return False
return True
ones = [m for m in range(2 ** nv) if any(covers(t, m) for t in terms)]
out = []
for m in ones:
for k in range(nv):
p = m ^ (1 << k)
if p < m and p in ones and not any(covers(t, m) and covers(t, p) for t in terms):
out.append([m, p])
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cover 0', [3, ['1-0', '-11', '11-']], []), ('cover 1', [2, ['1-', '-1']], []), ('cover 2', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 3', [3, ['0-0', '1-1']], []), ('cover 4', [4, ['11--', '--11']], []), ('cover 5', [3, ['00-', '-01', '1-1']], []), ('cover 6', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [2, ['1-', '-1']], []), ('cover 1', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 2', [3, ['0-0', '1-1']], []), ('cover 3', [4, ['11--', '--11']], []), ('cover 4', [3, ['00-', '-01', '1-1']], []), ('cover 5', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 6', [3, ['1--', '-1-']], []), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 1', [3, ['0-0', '1-1']], []), ('cover 2', [4, ['11--', '--11']], []), ('cover 3', [3, ['00-', '-01', '1-1']], []), ('cover 4', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 5', [3, ['1--', '-1-']], []), ('cover 6', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [3, ['0-0', '1-1']], []), ('cover 1', [4, ['11--', '--11']], []), ('cover 2', [3, ['00-', '-01', '1-1']], []), ('cover 3', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 4', [3, ['1--', '-1-']], []), ('cover 5', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('cover 6', [3, ['10-', '-11']], [[5, 7]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [4, ['11--', '--11']], []), ('cover 1', [3, ['00-', '-01', '1-1']], []), ('cover 2', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 3', [3, ['1--', '-1-']], []), ('cover 4', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('cover 5', [3, ['10-', '-11']], [[5, 7]]), ('cover 6', [3, ['1-0', '-11', '11-']], []), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])]]
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 |
|---|---|---|---|
| cover 0 | [] | [] | Passed |
| cover 1 | [] | [] | Passed |
| cover 2 | [[10, 2], [13, 12], [14, 6], [15, 14]] | [[2, 10], [6, 14], [12, 13], [14, 15]] | Failed |
| cover 3 | [] | [] | Passed |
| cover 4 | [] | [] | Passed |
| cover 5 | [] | [] | Passed |
| cover 6 | [[11, 3], [14, 12], [15, 7], [15, 13]] | [[3, 11], [7, 15], [12, 14], [13, 15]] | Failed |
| msb only term | [[5, 1], [7, 3]] | [[1, 5], [3, 7]] | Failed |
SHA-256 / dfc28bd6f277863209d78049b7190b22f2f4c2e311703e7c374165a916fc1d2a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
nv, terms = args
def covers(t, m):
for k, ch in enumerate(t):
bit = (m >> (nv - 1 - k)) & 1
if ch != '-' and int(ch) != bit:
return False
return True
ones = [m for m in range(2 ** nv) if any(covers(t, m) for t in terms)]
out = []
for m in ones:
for k in range(nv):
p = m ^ (1 << k)
if p > m and p in ones and not any(covers(t, m) and covers(t, p) for t in terms):
out.append([m, p])
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cover 0', [3, ['1-0', '-11', '11-']], []), ('cover 1', [2, ['1-', '-1']], []), ('cover 2', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 3', [3, ['0-0', '1-1']], []), ('cover 4', [4, ['11--', '--11']], []), ('cover 5', [3, ['00-', '-01', '1-1']], []), ('cover 6', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [2, ['1-', '-1']], []), ('cover 1', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 2', [3, ['0-0', '1-1']], []), ('cover 3', [4, ['11--', '--11']], []), ('cover 4', [3, ['00-', '-01', '1-1']], []), ('cover 5', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 6', [3, ['1--', '-1-']], []), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [4, ['1--0', '-1-1', '0-1-']], [[2, 10], [6, 14], [12, 13], [14, 15]]), ('cover 1', [3, ['0-0', '1-1']], []), ('cover 2', [4, ['11--', '--11']], []), ('cover 3', [3, ['00-', '-01', '1-1']], []), ('cover 4', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 5', [3, ['1--', '-1-']], []), ('cover 6', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [3, ['0-0', '1-1']], []), ('cover 1', [4, ['11--', '--11']], []), ('cover 2', [3, ['00-', '-01', '1-1']], []), ('cover 3', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 4', [3, ['1--', '-1-']], []), ('cover 5', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('cover 6', [3, ['10-', '-11']], [[5, 7]]), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])], [('cover 0', [4, ['11--', '--11']], []), ('cover 1', [3, ['00-', '-01', '1-1']], []), ('cover 2', [4, ['0--1', '-10-', '1-1-']], [[3, 11], [7, 15], [12, 14], [13, 15]]), ('cover 3', [3, ['1--', '-1-']], []), ('cover 4', [4, ['1-00', '0-11', '-1-1', '10--']], [[3, 11], [9, 13], [11, 15], [12, 13]]), ('cover 5', [3, ['10-', '-11']], [[5, 7]]), ('cover 6', [3, ['1-0', '-11', '11-']], []), ('msb only term', [3, ['1--', '0-1']], [[1, 5], [3, 7]])]]
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 |
|---|---|---|---|
| cover 0 | [] | [] | Passed |
| cover 1 | [] | [] | Passed |
| cover 2 | [[2, 10], [6, 14], [12, 13], [14, 15]] | [[2, 10], [6, 14], [12, 13], [14, 15]] | Passed |
| cover 3 | [] | [] | Passed |
| cover 4 | [] | [] | Passed |
| cover 5 | [] | [] | Passed |
| cover 6 | [[3, 11], [7, 15], [12, 14], [13, 15]] | [[3, 11], [7, 15], [12, 14], [13, 15]] | Passed |
| msb only term | [[1, 5], [3, 7]] | [[1, 5], [3, 7]] | Passed |
SHA-256 / d19ab8ba60a0de1be74a6425b09582dd5ff6c04608ba891f8bd5b189e80f915c
Verification & scope
A deterministic bounded teaching model of one simulator rule set; the contract is stipulated and is not a claim of conformance to any HDL standard or commercial simulator. 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:14.901647+00:00.
Case digest / 81b3807fde976808bd22fa3e32108af4933bde0b075b5b08cc4f3a2c2ec1a29f