FAILURE MAP
← Case archive

FA-89176 / Digital logic simulation / Open access

Hazard judged by first covering term only · case 01

Adjacent minterms sharing a consensus term are still reported as hazards.

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

ROOT CAUSE

The check compares the first covering term of each minterm instead of asking whether any single term covers both.

VERIFIED REPAIR

A pair is hazard-free if some term covers both minterms.

Unsuccessful approach: Requiring identical covering sets flags pairs that share a term but are also covered by others.

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 [t for t in terms if covers(t, m)][0] != [t for t in terms if covers(t, p)][0]:
                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 fixtureActualExpectedOutcome
cover 0[[6, 7]][]Failed
cover 1[[1, 3]][]Failed
cover 2[[2, 10], [3, 7], [6, 7], [6, 14], [12, 13], [14, 15]][[2, 10], [6, 14], [12, 13], [14, 15]]Failed
cover 3[][]Passed
cover 4[[7, 15], [11, 15]][]Failed
cover 5[[1, 5], [5, 7]][]Failed
cover 6[[3, 11], [4, 5], [5, 13], [7, 15], [12, 14], [13, 15]][[3, 11], [7, 15], [12, 14], [13, 15]]Failed
msb only term[[1, 5], [3, 7]][[1, 5], [3, 7]]Passed

SHA-256 / fd261da87919cad4943bc1e11a0dce5fd4a614a4351310068efe41da2d187ded

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 {t for t in terms if covers(t, m)} != {t for t in terms if covers(t, p)}:
                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 fixtureActualExpectedOutcome
cover 0[[3, 7], [4, 6], [6, 7]][]Failed
cover 1[[1, 3], [2, 3]][]Failed
cover 2[[2, 10], [3, 7], [5, 7], [6, 7], [6, 14], [7, 15], [12, 13], [14, 15]][[2, 10], [6, 14], [12, 13], [14, 15]]Failed
cover 3[][]Passed
cover 4[[7, 15], [11, 15], [13, 15], [14, 15]][]Failed
cover 5[[0, 1], [1, 5], [5, 7]][]Failed
cover 6[[1, 5], [3, 11], [4, 5], [5, 7], [5, 13], [7, 15], [12, 14], [13, 15]][[3, 11], [7, 15], [12, 14], [13, 15]]Failed
msb only term[[1, 5], [3, 7]][[1, 5], [3, 7]]Passed

SHA-256 / 6c74424921ac14b21719289e87a18ccbc44d1b11863033f22bd20472d0c6cde5

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 fixtureActualExpectedOutcome
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.901741+00:00.

Case digest / b9dacefb2b27c692f86a0aa63363afbb77617190608bb803b71edaf7a1ed1115