FAILURE MAP
← Case archive

FA-67156 / Railway interlocking logic / Open access

Signal lamp proving and aspect degradation: degradation direction · case 01

A signal with a failed lamp shows a less restrictive aspect than requested.

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

ROOT CAUSE

The fallback search walks towards less restrictive aspects.

VERIFIED REPAIR

Fall back through progressively more restrictive aspects.

Unsuccessful approach: Jumping straight to R discards an intermediate aspect that could still be shown.

Case contract

Aspects need lamps: G needs G; YY needs Y1 and Y2; Y needs Y1; R needs R. A lamp is lit if its main or auxiliary filament works. If the requested aspect cannot be lit, show the next more restrictive aspect that can (G, YY, Y, R); if even R cannot be lit the signal is DARK. alarm is raised if the signal is DARK or any lamp used by the shown aspect runs on its auxiliary filament. degraded means shown != requested.

Why this case matters

Interlocking logic decides whether trains may be given authority; a wrong decision at this point either grants unsafe movements or strands traffic.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    lamps = x['lamps']
    need = {'G': ['G'], 'YY': ['Y1', 'Y2'], 'Y': ['Y1'], 'R': ['R']}
    order = ['G', 'YY', 'Y', 'R']
    def lit(l):
        return lamps[l]['main'] or lamps[l]['aux']
    shown = 'DARK'
    for asp in order[:order.index(x['requested']) + 1][::-1]:
        if all(lit(l) for l in need[asp]):
            shown = asp
            break
    alarm = shown == 'DARK' or any(not lamps[l]['main'] for l in need[shown])
    return {'shown': shown, 'alarm': alarm, 'degraded': shown != x['requested']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('boundary: green on auxiliary filament', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'G', 'alarm': True, 'degraded': False}), ('boundary: red on auxiliary filament', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': True, 'degraded': False}), ('control 1', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 4', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 7', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False})], [('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('sampled regression 70', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': False}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('sampled regression 14', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': True, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('control 12', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': False, 'aux': True}}}, {'shown': 'YY', 'alarm': False, 'degraded': False}), ('control 15', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'YY', 'alarm': True, 'degraded': False}), ('control 18', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'Y', 'alarm': True, 'degraded': False})], [('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('sampled regression 14', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': True, 'degraded': True}), ('sampled regression 58', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('control 23', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 26', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 29', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False})], [('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('boundary: unused lamp on auxiliary', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 34', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': True, 'degraded': False}), ('control 37', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False}), ('control 40', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': False})], [('regression: all yellows dead', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('sampled regression 62', {'requested': 'Y', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': False}}}, {'shown': 'R', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('boundary: green on auxiliary filament', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'G', 'alarm': True, 'degraded': False}), ('control 45', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': False}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 48', {'requested': 'G', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 51', {'requested': 'YY', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'YY', 'alarm': False, 'degraded': False})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: green lamp dead{'alarm': True, 'degraded': True, 'shown': 'DARK'}{'alarm': False, 'degraded': True, 'shown': 'YY'}Failed
regression: red lamp dead{'alarm': False, 'degraded': True, 'shown': 'Y'}{'alarm': True, 'degraded': True, 'shown': 'DARK'}Failed
regression: lower yellow dead under double yellow{'alarm': False, 'degraded': True, 'shown': 'G'}{'alarm': False, 'degraded': True, 'shown': 'Y'}Failed
boundary: green on auxiliary filament{'alarm': True, 'degraded': False, 'shown': 'G'}{'alarm': True, 'degraded': False, 'shown': 'G'}Passed
boundary: red on auxiliary filament{'alarm': True, 'degraded': False, 'shown': 'R'}{'alarm': True, 'degraded': False, 'shown': 'R'}Passed
control 1{'alarm': False, 'degraded': False, 'shown': 'G'}{'alarm': False, 'degraded': False, 'shown': 'G'}Passed
control 4{'alarm': False, 'degraded': False, 'shown': 'G'}{'alarm': False, 'degraded': False, 'shown': 'G'}Passed
control 7{'alarm': False, 'degraded': False, 'shown': 'R'}{'alarm': False, 'degraded': False, 'shown': 'R'}Passed

SHA-256 / 573f41d36c08be3e1a14fba6bdf63dbb907adc6d493b11c0fd4bedc81d59a471

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    lamps = x['lamps']
    need = {'G': ['G'], 'YY': ['Y1', 'Y2'], 'Y': ['Y1'], 'R': ['R']}
    order = ['G', 'YY', 'Y', 'R']
    def lit(l):
        return lamps[l]['main'] or lamps[l]['aux']
    shown = 'DARK'
    for asp in [x['requested'], 'R']:
        if all(lit(l) for l in need[asp]):
            shown = asp
            break
    alarm = shown == 'DARK' or any(not lamps[l]['main'] for l in need[shown])
    return {'shown': shown, 'alarm': alarm, 'degraded': shown != x['requested']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('boundary: green on auxiliary filament', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'G', 'alarm': True, 'degraded': False}), ('boundary: red on auxiliary filament', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': True, 'degraded': False}), ('control 1', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 4', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 7', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False})], [('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('sampled regression 70', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': False}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('sampled regression 14', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': True, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('control 12', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': False, 'aux': True}}}, {'shown': 'YY', 'alarm': False, 'degraded': False}), ('control 15', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'YY', 'alarm': True, 'degraded': False}), ('control 18', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'Y', 'alarm': True, 'degraded': False})], [('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('sampled regression 14', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': True, 'degraded': True}), ('sampled regression 58', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('control 23', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 26', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 29', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False})], [('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('boundary: unused lamp on auxiliary', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 34', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': True, 'degraded': False}), ('control 37', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False}), ('control 40', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': False})], [('regression: all yellows dead', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('sampled regression 62', {'requested': 'Y', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': False}}}, {'shown': 'R', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('boundary: green on auxiliary filament', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'G', 'alarm': True, 'degraded': False}), ('control 45', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': False}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 48', {'requested': 'G', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 51', {'requested': 'YY', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'YY', 'alarm': False, 'degraded': False})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: green lamp dead{'alarm': False, 'degraded': True, 'shown': 'R'}{'alarm': False, 'degraded': True, 'shown': 'YY'}Failed
regression: red lamp dead{'alarm': True, 'degraded': True, 'shown': 'DARK'}{'alarm': True, 'degraded': True, 'shown': 'DARK'}Passed
regression: lower yellow dead under double yellow{'alarm': False, 'degraded': True, 'shown': 'R'}{'alarm': False, 'degraded': True, 'shown': 'Y'}Failed
boundary: green on auxiliary filament{'alarm': True, 'degraded': False, 'shown': 'G'}{'alarm': True, 'degraded': False, 'shown': 'G'}Passed
boundary: red on auxiliary filament{'alarm': True, 'degraded': False, 'shown': 'R'}{'alarm': True, 'degraded': False, 'shown': 'R'}Passed
control 1{'alarm': False, 'degraded': False, 'shown': 'G'}{'alarm': False, 'degraded': False, 'shown': 'G'}Passed
control 4{'alarm': False, 'degraded': False, 'shown': 'G'}{'alarm': False, 'degraded': False, 'shown': 'G'}Passed
control 7{'alarm': False, 'degraded': False, 'shown': 'R'}{'alarm': False, 'degraded': False, 'shown': 'R'}Passed

SHA-256 / bcff981aec7f4908ded46e12eb351035f80f623de82a53527fd031191306138c

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    lamps = x['lamps']
    need = {'G': ['G'], 'YY': ['Y1', 'Y2'], 'Y': ['Y1'], 'R': ['R']}
    order = ['G', 'YY', 'Y', 'R']
    def lit(l):
        return lamps[l]['main'] or lamps[l]['aux']
    shown = 'DARK'
    for asp in order[order.index(x['requested']):]:
        if all(lit(l) for l in need[asp]):
            shown = asp
            break
    alarm = shown == 'DARK' or any(not lamps[l]['main'] for l in need[shown])
    return {'shown': shown, 'alarm': alarm, 'degraded': shown != x['requested']}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('boundary: green on auxiliary filament', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'G', 'alarm': True, 'degraded': False}), ('boundary: red on auxiliary filament', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': True, 'degraded': False}), ('control 1', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 4', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 7', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False})], [('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('sampled regression 70', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': False}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('sampled regression 14', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': True, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('control 12', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': False, 'aux': True}}}, {'shown': 'YY', 'alarm': False, 'degraded': False}), ('control 15', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'YY', 'alarm': True, 'degraded': False}), ('control 18', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'Y', 'alarm': True, 'degraded': False})], [('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('sampled regression 14', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': True, 'degraded': True}), ('sampled regression 58', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('control 23', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 26', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': False}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 29', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False})], [('regression: red lamp dead', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'DARK', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('regression: upper yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('boundary: unused lamp on auxiliary', {'requested': 'Y', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': False}), ('control 34', {'requested': 'R', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': True, 'degraded': False}), ('control 37', {'requested': 'R', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': False}), ('control 40', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': False})], [('regression: all yellows dead', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'R', 'alarm': False, 'degraded': True}), ('regression: green lamp dead', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': False}}}, {'shown': 'YY', 'alarm': False, 'degraded': True}), ('sampled regression 62', {'requested': 'Y', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': False, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': False}}}, {'shown': 'R', 'alarm': True, 'degraded': True}), ('regression: lower yellow dead under double yellow', {'requested': 'YY', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': False}, 'G': {'main': True, 'aux': True}}}, {'shown': 'Y', 'alarm': False, 'degraded': True}), ('boundary: green on auxiliary filament', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': False, 'aux': True}}}, {'shown': 'G', 'alarm': True, 'degraded': False}), ('control 45', {'requested': 'G', 'lamps': {'R': {'main': True, 'aux': True}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': True, 'aux': False}, 'G': {'main': True, 'aux': False}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 48', {'requested': 'G', 'lamps': {'R': {'main': False, 'aux': False}, 'Y1': {'main': True, 'aux': True}, 'Y2': {'main': False, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'G', 'alarm': False, 'degraded': False}), ('control 51', {'requested': 'YY', 'lamps': {'R': {'main': False, 'aux': True}, 'Y1': {'main': True, 'aux': False}, 'Y2': {'main': True, 'aux': True}, 'G': {'main': True, 'aux': True}}}, {'shown': 'YY', 'alarm': False, 'degraded': False})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: green lamp dead{'alarm': False, 'degraded': True, 'shown': 'YY'}{'alarm': False, 'degraded': True, 'shown': 'YY'}Passed
regression: red lamp dead{'alarm': True, 'degraded': True, 'shown': 'DARK'}{'alarm': True, 'degraded': True, 'shown': 'DARK'}Passed
regression: lower yellow dead under double yellow{'alarm': False, 'degraded': True, 'shown': 'Y'}{'alarm': False, 'degraded': True, 'shown': 'Y'}Passed
boundary: green on auxiliary filament{'alarm': True, 'degraded': False, 'shown': 'G'}{'alarm': True, 'degraded': False, 'shown': 'G'}Passed
boundary: red on auxiliary filament{'alarm': True, 'degraded': False, 'shown': 'R'}{'alarm': True, 'degraded': False, 'shown': 'R'}Passed
control 1{'alarm': False, 'degraded': False, 'shown': 'G'}{'alarm': False, 'degraded': False, 'shown': 'G'}Passed
control 4{'alarm': False, 'degraded': False, 'shown': 'G'}{'alarm': False, 'degraded': False, 'shown': 'G'}Passed
control 7{'alarm': False, 'degraded': False, 'shown': 'R'}{'alarm': False, 'degraded': False, 'shown': 'R'}Passed

SHA-256 / 7a50a1151cf1c4e1abca2f980660973c84259a4a5887c4b3fca321ca638e0c2f

Verification & scope

Stipulated toy interlocking contract for a bounded teaching model; it makes no claim of conformance to any railway signalling standard and omits real safety cases. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:47:50.249660+00:00.

Case digest / 9417248ac40f4cbbdc289cc0719cec44b2972ce0245bf9cd62540970a0c23024