broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, ins = args
    def inv(v):
        return {'0': '1', '1': '0'}.get(v, 'x')
    ins = [('x' if v == 'z' else v) for v in ins]
    if gate == 'bufif1':
        d, e = ins
        return 'z' if e != '1' else d
    if gate in ('and', 'nand'):
        r = '0' if '0' in ins else ('1' if all(v == '1' for v in ins) else 'x')
    elif gate in ('or', 'nor'):
        r = '1' if '1' in ins else ('0' if all(v == '0' for v in ins) else 'x')
    elif gate in ('xor', 'xnor'):
        r = 'x' if 'x' in ins else str(ins.count('1') % 2)
    else:
        r = ins[0]
    return inv(r) if gate in ('nand', 'nor', 'xnor', 'not') else r
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('and gate: controlling zero after unknowns', ['and', ['x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '0']], '0'), ('inverter control', ['not', ['1']], '0'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['1', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '0']], '1'), ('inverter control', ['not', ['0']], '1'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['0', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '1', '0']], '0'), ('inverter control', ['not', ['1']], '0'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['1', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', 'z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', 'x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', '1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0', '0', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '1', '1', '0']], '1'), ('inverter control', ['not', ['0']], '1'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['0', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', 'z', 'z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', 'x', 'x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1', '1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', '1', '1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0', '0', '0', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '1', '1', '1', '0']], '0'), ('inverter control', ['not', ['1']], '0'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['1', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', 'z', 'z', 'z', '1']], '1')]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, ins = args
    def inv(v):
        return {'0': '1', '1': '0'}.get(v, 'x')
    ins = [('x' if v == 'z' else v) for v in ins]
    if gate == 'bufif1':
        d, e = ins
        return 'z' if e == '0' else ('x' if e == 'x' and d != '0' else d)
    if gate in ('and', 'nand'):
        r = '0' if '0' in ins else ('1' if all(v == '1' for v in ins) else 'x')
    elif gate in ('or', 'nor'):
        r = '1' if '1' in ins else ('0' if all(v == '0' for v in ins) else 'x')
    elif gate in ('xor', 'xnor'):
        r = 'x' if 'x' in ins else str(ins.count('1') % 2)
    else:
        r = ins[0]
    return inv(r) if gate in ('nand', 'nor', 'xnor', 'not') else r
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('and gate: controlling zero after unknowns', ['and', ['x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '0']], '0'), ('inverter control', ['not', ['1']], '0'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['1', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '0']], '1'), ('inverter control', ['not', ['0']], '1'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['0', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '1', '0']], '0'), ('inverter control', ['not', ['1']], '0'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['1', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', 'z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', 'x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', '1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0', '0', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '1', '1', '0']], '1'), ('inverter control', ['not', ['0']], '1'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['0', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', 'z', 'z', '1']], '1')], [('and gate: controlling zero after unknowns', ['and', ['x', 'x', 'x', 'x', 'x', '0']], '0'), ('nand gate: all ones', ['nand', ['1', '1', '1', '1', '1', '1']], '0'), ('xor gate: floating input', ['xor', ['1', '1', '1', '1', '1', 'z']], 'x'), ('buffer of a floating net', ['buf', ['z']], 'x'), ('xor gate: two unknowns', ['xor', ['x', 'x', '0', '0', '0', '0']], 'x'), ('xnor gate: parity inversion', ['xnor', ['1', '1', '1', '1', '1', '0']], '0'), ('inverter control', ['not', ['1']], '0'), ('bufif1 unknown enable with low data', ['bufif1', ['0', 'x']], 'x'), ('bufif1 unknown enable with high data', ['bufif1', ['1', 'z']], 'x'), ('bufif1 disabled drives z', ['bufif1', ['1', '0']], 'z'), ('or gate: controlling one beside z', ['or', ['z', 'z', 'z', 'z', 'z', '1']], '1')]]
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)

prompt:
A bufif1 with an unknown enable drives 'z' instead of an unknown value.

Values are '0','1','x','z'. A 'z' on any gate input is read as 'x'. and/nand: any 0 -> 0, all 1 -> 1, else x; or/nor: any 1 -> 1, all 0 -> 0, else x; xor/xnor: any x -> x, else parity of ones; buf/not use the single input; nand/nor/xnor/not invert (x stays x). bufif1(data, enable): enable 0 -> 'z', enable x/z -> 'x', enable 1 -> data (z data becomes x).

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        pass
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q = q[-1:]
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

prompt:
A pulse narrower than the gate delay appears on the output instead of being swallowed.

Input [gate, rise_delay, fall_delay, v0, events]; gate is 'buf' or 'not', events are time-sorted [t, v] input changes. Output starts at f(v0) (not reported). Each input change schedules f(v) at t + rise_delay when f(v)==1 else t + fall_delay, and cancels every pending output event (inertial delay). Pending events maturing at or before the next input time are committed first. Report [time, value] only when the output value changes; all pending events are committed after the last input.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if v == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if (v == 1) != (gate == 'buf') else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

prompt:
An inverter output falls after the rise delay and rises after the fall delay.

Input [gate, rise_delay, fall_delay, v0, events]; gate is 'buf' or 'not', events are time-sorted [t, v] input changes. Output starts at f(v0) (not reported). Each input change schedules f(v) at t + rise_delay when f(v)==1 else t + fall_delay, and cancels every pending output event (inertial delay). Pending events maturing at or before the next input time are committed first. Report [time, value] only when the output value changes; all pending events are committed after the last input.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if True:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if not res or res[-1][1] != nv:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

prompt:
The waveform lists a transition to the value the output already holds.

Input [gate, rise_delay, fall_delay, v0, events]; gate is 'buf' or 'not', events are time-sorted [t, v] input changes. Output starts at f(v0) (not reported). Each input change schedules f(v) at t + rise_delay when f(v)==1 else t + fall_delay, and cancels every pending output event (inertial delay). Pending events maturing at or before the next input time are committed first. Report [time, value] only when the output value changes; all pending events are committed after the last input.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = v0
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = 0
    q = []
    res = []
    for t, v in events + [[10 ** 9, None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

prompt:
An inverter whose input starts low is assumed to start low, so its first falling edge disappears.

Input [gate, rise_delay, fall_delay, v0, events]; gate is 'buf' or 'not', events are time-sorted [t, v] input changes. Output starts at f(v0) (not reported). Each input change schedules f(v) at t + rise_delay when f(v)==1 else t + fall_delay, and cancels every pending output event (inertial delay). Pending events maturing at or before the next input time are committed first. Report [time, value] only when the output value changes; all pending events are committed after the last input.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    gate, dr, df, v0, events = args
    f = (lambda v: 1 - v) if gate == 'not' else (lambda v: v)
    out = f(v0)
    q = []
    res = []
    for t, v in events + [[events[-1][0], None]]:
        while q and q[0][0] <= t:
            at, nv = q.pop(0)
            if nv != out:
                out = nv
                res.append([at, nv])
        if v is None:
            break
        q.clear()
        nv = f(v)
        q.append([t + (dr if nv == 1 else df), nv])
    return res
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pulse shorter than inertial delay is filtered', ['buf', 4, 4, 0, [[10, 1], [12, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [21, 0]]], [[12, 1], [25, 0]]), ('inverter uses output polarity for delay', ['not', 2, 6, 0, [[10, 1], [30, 0]]], [[16, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [10, 0]]], [[12, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[1, 1]]], [[5, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [21, 0]]], [[25, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [41, 1]]], [[15, 1], [20, 0], [46, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 5, 5, 0, [[10, 1], [13, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [22, 0]]], [[12, 1], [26, 0]]), ('inverter uses output polarity for delay', ['not', 2, 7, 0, [[10, 1], [30, 0]]], [[17, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [11, 0]]], [[13, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[2, 1]]], [[6, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [22, 0]]], [[26, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [42, 1]]], [[15, 1], [20, 0], [47, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 6, 6, 0, [[10, 1], [14, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [23, 0]]], [[12, 1], [27, 0]]), ('inverter uses output polarity for delay', ['not', 2, 8, 0, [[10, 1], [30, 0]]], [[18, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [12, 0]]], [[14, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[3, 1]]], [[7, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [23, 0]]], [[27, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [43, 1]]], [[15, 1], [20, 0], [48, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 7, 7, 0, [[10, 1], [15, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [24, 0]]], [[12, 1], [28, 0]]), ('inverter uses output polarity for delay', ['not', 2, 9, 0, [[10, 1], [30, 0]]], [[19, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [13, 0]]], [[15, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[4, 1]]], [[8, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [24, 0]]], [[28, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [44, 1]]], [[15, 1], [20, 0], [49, 1]])], [('pulse shorter than inertial delay is filtered', ['buf', 8, 8, 0, [[10, 1], [16, 0]]], []), ('wide pulse passes with rise and fall delays', ['buf', 2, 4, 0, [[10, 1], [25, 0]]], [[12, 1], [29, 0]]), ('inverter uses output polarity for delay', ['not', 2, 10, 0, [[10, 1], [30, 0]]], [[20, 0], [32, 1]]), ('redundant input event produces no output edge', ['buf', 1, 2, 1, [[5, 1], [14, 0]]], [[16, 0]]), ('final pending event is committed', ['buf', 4, 4, 0, [[5, 1]]], [[9, 1]]), ('inverter glitch cancelled', ['not', 4, 4, 1, [[10, 0], [12, 1], [25, 0]]], [[29, 1]]), ('output matures exactly at next input change', ['buf', 5, 5, 0, [[10, 1], [15, 0], [45, 1]]], [[15, 1], [20, 0], [50, 1]])]]
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)

prompt:
The final output transition is missing whenever it matures after the last input change.

Input [gate, rise_delay, fall_delay, v0, events]; gate is 'buf' or 'not', events are time-sorted [t, v] input changes. Output starts at f(v0) (not reported). Each input change schedules f(v) at t + rise_delay when f(v)==1 else t + fall_delay, and cancels every pending output event (inertial delay). Pending events maturing at or before the next input time are committed first. Report [time, value] only when the output value changes; all pending events are committed after the last input.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    pis, gates = args
    seen = set(pis)
    for out, op, ins in gates:
        if out in seen:
            return 'multiply driven ' + out
        seen.add(out)
    for out, op, ins in gates:
        for i in ins:
            if i not in seen:
                return 'undriven ' + i
    level = {p: 0 for p in pis}
    val = dict(pis)
    pending = list(gates)
    while pending:
        ready = [g for g in pending if all(i in level for i in g[2])]
        if not ready:
            return 'loop'
        for out, op, ins in ready:
            level[out] = 1 + min([level[i] for i in ins], default=-1)
            bits = [val[i] for i in ins]
            if op == 'and': v = int(all(bits))
            elif op == 'or': v = int(any(bits))
            elif op == 'xor': v = sum(bits) % 2
            elif op == 'nand': v = 1 - int(all(bits))
            elif op in ('tie0', 'tie1'): v = int(op == 'tie1')
            else: v = 1 - bits[0]
            val[out] = v
        pending = [g for g in pending if g not in ready]
    return {'depth': max(level.values()), 'values': [[k, val[k]] for k in sorted(val)]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch1']]]], 'undriven nosuch1'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 1], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch2']]]], 'undriven nosuch2'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 1], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 1], ['g1', 0], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch3']]]], 'undriven nosuch3'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 1], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 0], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch4']]]], 'undriven nosuch4'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 0], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 0]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch5']]]], 'undriven nosuch5'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    pis, gates = args
    seen = set(pis)
    for out, op, ins in gates:
        if out in seen:
            return 'multiply driven ' + out
        seen.add(out)
    for out, op, ins in gates:
        for i in ins:
            if i not in seen:
                return 'undriven ' + i
    level = {p: 0 for p in pis}
    val = dict(pis)
    pending = list(gates)
    while pending:
        ready = [g for g in pending if all(i in level for i in g[2])]
        if not ready:
            return 'loop'
        for out, op, ins in ready:
            level[out] = 1 + max([level[i] for i in ins[:1]], default=-1)
            bits = [val[i] for i in ins]
            if op == 'and': v = int(all(bits))
            elif op == 'or': v = int(any(bits))
            elif op == 'xor': v = sum(bits) % 2
            elif op == 'nand': v = 1 - int(all(bits))
            elif op in ('tie0', 'tie1'): v = int(op == 'tie1')
            else: v = 1 - bits[0]
            val[out] = v
        pending = [g for g in pending if g not in ready]
    return {'depth': max(level.values()), 'values': [[k, val[k]] for k in sorted(val)]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch1']]]], 'undriven nosuch1'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 1], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch2']]]], 'undriven nosuch2'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 1], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 1], ['g1', 0], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch3']]]], 'undriven nosuch3'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 1], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 0], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch4']]]], 'undriven nosuch4'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 0], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 0]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch5']]]], 'undriven nosuch5'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})]]
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)

prompt:
Reconvergent logic reports a smaller depth than its longest path.

Input [pis, gates]: pis maps primary input net -> 0/1; gates are [out, op, ins] in any order with ops and/or/xor/nand/not/tie0/tie1. Reject with 'undriven <net>' (first gate in list order, first pin) if a gate reads a net driven by nobody, or 'multiply driven <net>' if a net has two drivers (a gate driving a primary input counts). Otherwise evaluate in dependency waves; return 'loop' if no gate becomes ready. Level: primary inputs 0, gate = 1 + max input level, tie cells 0. Return {'depth': max level, 'values': sorted [net, value]}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    pis, gates = args
    seen = set(pis)
    for out, op, ins in gates:
        if out in seen:
            return 'multiply driven ' + out
        seen.add(out)
    for out, op, ins in gates:
        for i in ins:
            if i not in seen:
                return 'undriven ' + i
    level = {p: 0 for p in pis}
    val = dict(pis)
    pending = list(gates)
    while pending:
        ready = [g for g in pending if all(i in level for i in g[2])]
        if not ready:
            return 'loop'
        for out, op, ins in ready:
            level[out] = 1 + max([level[i] for i in ins], default=0)
            bits = [val[i] for i in ins]
            if op == 'and': v = int(all(bits))
            elif op == 'or': v = int(any(bits))
            elif op == 'xor': v = sum(bits) % 2
            elif op == 'nand': v = 1 - int(all(bits))
            elif op in ('tie0', 'tie1'): v = int(op == 'tie1')
            else: v = 1 - bits[0]
            val[out] = v
        pending = [g for g in pending if g not in ready]
    return {'depth': max(level.values()), 'values': [[k, val[k]] for k in sorted(val)]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch1']]]], 'undriven nosuch1'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 1], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch2']]]], 'undriven nosuch2'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 1], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 1], ['g1', 0], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch3']]]], 'undriven nosuch3'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 1], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 0], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch4']]]], 'undriven nosuch4'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 0], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 0]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch5']]]], 'undriven nosuch5'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    pis, gates = args
    seen = set(pis)
    for out, op, ins in gates:
        if out in seen:
            return 'multiply driven ' + out
        seen.add(out)
    for out, op, ins in gates:
        for i in ins:
            if i not in seen:
                return 'undriven ' + i
    level = {p: 0 for p in pis}
    val = dict(pis)
    pending = list(gates)
    while pending:
        ready = [g for g in pending if all(i in level for i in g[2])]
        if not ready:
            return 'loop'
        for out, op, ins in ready:
            level[out] = 1 + max([level[i] for i in ins], default=-1) if ins else 1
            bits = [val[i] for i in ins]
            if op == 'and': v = int(all(bits))
            elif op == 'or': v = int(any(bits))
            elif op == 'xor': v = sum(bits) % 2
            elif op == 'nand': v = 1 - int(all(bits))
            elif op in ('tie0', 'tie1'): v = int(op == 'tie1')
            else: v = 1 - bits[0]
            val[out] = v
        pending = [g for g in pending if g not in ready]
    return {'depth': max(level.values()), 'values': [[k, val[k]] for k in sorted(val)]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch1']]]], 'undriven nosuch1'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 1], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch2']]]], 'undriven nosuch2'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 1], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 1}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 1], ['g1', 0], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 1}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 1], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 1}, [['g1', 'and', ['a', 'nosuch3']]]], 'undriven nosuch3'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 1}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 1}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 1}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 1}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 1], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})], [('reconvergent netlist listed out of order', [{'a': 0, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 0], ['b', 1], ['c', 0], ['g1', 1], ['g2', 1], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 0, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 0], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 0, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch4']]]], 'undriven nosuch4'), ('real combinational loop', [{'a': 0, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 0, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 0, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 0}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 0], ['y', 1]]}), ('unbalanced depth', [{'a': 0, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 0], ['b', 1], ['c', 0], ['d1', 1], ['d2', 0], ['d3', 0], ['d4', 0]]})], [('reconvergent netlist listed out of order', [{'a': 1, 'b': 1, 'c': 0}, [['g3', 'or', ['g1', 'g2', 'c']], ['g1', 'nand', ['a', 'b', 'c']], ['g2', 'not', ['a']], ['g4', 'and', ['g3', 'b']]]], {'depth': 3, 'values': [['a', 1], ['b', 1], ['c', 0], ['g1', 1], ['g2', 0], ['g3', 1], ['g4', 1]]}), ('tie cell chain depth', [{'a': 1, 'b': 1, 'c': 0}, [['t', 'tie1', []], ['u', 'not', ['t']], ['w', 'not', ['u']]]], {'depth': 2, 'values': [['a', 1], ['b', 1], ['c', 0], ['t', 1], ['u', 0], ['w', 1]]}), ('undriven input on a later pin', [{'a': 1, 'b': 1, 'c': 0}, [['g1', 'and', ['a', 'nosuch5']]]], 'undriven nosuch5'), ('real combinational loop', [{'a': 1, 'b': 1, 'c': 0}, [['p', 'and', ['a', 'q']], ['q', 'or', ['p', 'b']]]], 'loop'), ('two gates drive one net', [{'a': 1, 'b': 1, 'c': 0}, [['m', 'and', ['a', 'b']], ['m', 'or', ['a', 'c']], ['o', 'not', ['m']]]], 'multiply driven m'), ('gate drives a primary input', [{'a': 1, 'b': 1, 'c': 0}, [['a', 'not', ['b']]]], 'multiply driven a'), ('three-input nand', [{'a': 1, 'b': 1, 'c': 0, 'e': 1}, [['y', 'nand', ['a', 'b', 'c']]]], {'depth': 1, 'values': [['a', 1], ['b', 1], ['c', 0], ['e', 1], ['y', 1]]}), ('unbalanced depth', [{'a': 1, 'b': 1, 'c': 0}, [['d1', 'not', ['a']], ['d2', 'not', ['d1']], ['d3', 'and', ['b', 'd2']], ['d4', 'or', ['c', 'c', 'c', 'c', 'c', 'd3']]]], {'depth': 4, 'values': [['a', 1], ['b', 1], ['c', 0], ['d1', 0], ['d2', 1], ['d3', 1], ['d4', 1]]})]]
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)

prompt:
A chain fed by a tie cell reports one extra level of depth.

Input [pis, gates]: pis maps primary input net -> 0/1; gates are [out, op, ins] in any order with ops and/or/xor/nand/not/tie0/tie1. Reject with 'undriven <net>' (first gate in list order, first pin) if a gate reads a net driven by nobody, or 'multiply driven <net>' if a net has two drivers (a gate driving a primary input counts). Otherwise evaluate in dependency waves; return 'loop' if no gate becomes ready. Level: primary inputs 0, gate = 1 + max input level, tie cells 0. Return {'depth': max level, 'values': sorted [net, value]}.

split: open-access