FA-67091 / Railway interlocking logic / Open access
Movement authority end computation: blocking section boundary · case 01
The authority extends through the blocking section.
ROOT CAUSE
The end of authority is placed at the far end of the blocking section.
VERIFIED REPAIR
End the authority at the start of the first non-locked section.
Unsuccessful approach: Ending at the start of the previous section withholds a whole free section.
Case contract
Sections have lengths and states locked, occupied or unlocked; the train front is offset_m into section train_sec (which it occupies itself). Scan the following sections; the end of authority is the start of the first section that is not locked (reason = its state) or the end of the last section (end-of-route). If that exceeds max_ma_m ahead of the train front, the authority is cut to front + max_ma_m (reason max-length). The margin is subtracted from the end except for a max-length cut.
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):
secs = x['sections']
bounds = []
acc = 0
for s in secs:
bounds.append(acc)
acc += s['len']
k = x['train_sec']
eoa = acc
reason = 'end-of-route'
for j in range(k + 1, len(secs)):
if secs[j]['state'] != 'locked':
eoa = bounds[j] + secs[j]['len']
reason = secs[j]['state']
break
front = bounds[k] + x['offset_m']
if eoa - front > x['max_ma_m']:
eoa = front + x['max_ma_m']
reason = 'max-length'
if reason != 'max-length':
eoa -= x['margin_m']
return {'eoa_m': eoa, 'reason': reason}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('boundary: own section occupied', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 50, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 675, 'reason': 'end-of-route'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('sampled regression 1', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 69, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 150, 'reason': 'unlocked'}), ('control 4', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 206, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 1325, 'reason': 'end-of-route'}), ('sampled regression 7', {'sections': [{'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 500, 'state': 'unlocked'}, {'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 108, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 550, 'reason': 'unlocked'})], [('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('sampled regression 10', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}], 'train_sec': 5, 'offset_m': 104, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1975, 'reason': 'occupied'}), ('sampled regression 6', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'unlocked'}, {'len': 100, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 2, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 625, 'reason': 'unlocked'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('regression: cap exactly at the obstacle', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 975, 'reason': 'occupied'}), ('control 12', {'sections': [{'len': 200, 'state': 'unlocked'}, {'len': 350, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 34, 'max_ma_m': 300, 'margin_m': 50}, {'eoa_m': 884, 'reason': 'max-length'}), ('control 15', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 4, 'offset_m': 137, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 2100, 'reason': 'end-of-route'}), ('sampled regression 18', {'sections': [{'len': 200, 'state': 'unlocked'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 3, 'offset_m': 181, 'max_ma_m': 1000, 'margin_m': 0}, {'eoa_m': 1250, 'reason': 'occupied'})], [('regression: cap exactly at the obstacle', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 975, 'reason': 'occupied'}), ('sampled regression 22', {'sections': [{'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 500, 'state': 'unlocked'}], 'train_sec': 4, 'offset_m': 91, 'max_ma_m': 1000, 'margin_m': 25}, {'eoa_m': 1325, 'reason': 'unlocked'}), ('sampled regression 11', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 239, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 500, 'reason': 'unlocked'}), ('boundary: end of route with margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 0, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 150, 'reason': 'end-of-route'}), ('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('sampled regression 23', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 1100, 'reason': 'unlocked'}), ('control 26', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}], 'train_sec': 1, 'offset_m': 9, 'max_ma_m': 300, 'margin_m': 25}, {'eoa_m': 409, 'reason': 'max-length'}), ('sampled regression 29', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 288, 'max_ma_m': 600, 'margin_m': 50}, {'eoa_m': 1000, 'reason': 'occupied'})], [('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('sampled regression 35', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}], 'train_sec': 3, 'offset_m': 56, 'max_ma_m': 1000, 'margin_m': 50}, {'eoa_m': 550, 'reason': 'occupied'}), ('sampled regression 19', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 103, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 925, 'reason': 'unlocked'}), ('boundary: own section occupied', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 50, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 675, 'reason': 'end-of-route'}), ('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('sampled regression 34', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 222, 'max_ma_m': 600, 'margin_m': 0}, {'eoa_m': 850, 'reason': 'unlocked'}), ('control 37', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 2, 'max_ma_m': 600, 'margin_m': 50}, {'eoa_m': 602, 'reason': 'max-length'}), ('sampled regression 40', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 500, 'state': 'unlocked'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 25, 'max_ma_m': 1000, 'margin_m': 0}, {'eoa_m': 500, 'reason': 'unlocked'})], [('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('sampled regression 50', {'sections': [{'len': 100, 'state': 'unlocked'}, {'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 3, 'offset_m': 115, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 1150, 'reason': 'unlocked'}), ('sampled regression 28', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}], 'train_sec': 1, 'offset_m': 74, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 1200, 'reason': 'occupied'}), ('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('control 45', {'sections': [{'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 348, 'max_ma_m': 300, 'margin_m': 25}, {'eoa_m': 1198, 'reason': 'max-length'}), ('control 48', {'sections': [{'len': 500, 'state': 'unlocked'}, {'len': 200, 'state': 'unlocked'}, {'len': 350, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 350, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 200, 'max_ma_m': 1000, 'margin_m': 25}, {'eoa_m': 1725, 'reason': 'end-of-route'}), ('sampled regression 51', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}], 'train_sec': 1, 'offset_m': 18, 'max_ma_m': 600, 'margin_m': 0}, {'eoa_m': 1100, 'reason': 'occupied'})]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: occupied section two ahead | {'eoa_m': 675, 'reason': 'occupied'} | {'eoa_m': 375, 'reason': 'occupied'} | Failed |
| regression: unlocked section margin | {'eoa_m': 320, 'reason': 'unlocked'} | {'eoa_m': 220, 'reason': 'unlocked'} | Failed |
| regression: unlocked section next | {'eoa_m': 675, 'reason': 'unlocked'} | {'eoa_m': 375, 'reason': 'unlocked'} | Failed |
| boundary: own section occupied | {'eoa_m': 675, 'reason': 'end-of-route'} | {'eoa_m': 675, 'reason': 'end-of-route'} | Passed |
| boundary: length cap from the front | {'eoa_m': 1000, 'reason': 'max-length'} | {'eoa_m': 1000, 'reason': 'max-length'} | Passed |
| sampled regression 1 | {'eoa_m': 250, 'reason': 'unlocked'} | {'eoa_m': 150, 'reason': 'unlocked'} | Failed |
| control 4 | {'eoa_m': 1325, 'reason': 'end-of-route'} | {'eoa_m': 1325, 'reason': 'end-of-route'} | Passed |
| sampled regression 7 | {'eoa_m': 900, 'reason': 'unlocked'} | {'eoa_m': 550, 'reason': 'unlocked'} | Failed |
SHA-256 / 9a4c819ac4b529a0ad9449d29a7dd0e3d62df7cef6084aaee567f3ccc34dfbf3
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
secs = x['sections']
bounds = []
acc = 0
for s in secs:
bounds.append(acc)
acc += s['len']
k = x['train_sec']
eoa = acc
reason = 'end-of-route'
for j in range(k + 1, len(secs)):
if secs[j]['state'] != 'locked':
eoa = bounds[j - 1]
reason = secs[j]['state']
break
front = bounds[k] + x['offset_m']
if eoa - front > x['max_ma_m']:
eoa = front + x['max_ma_m']
reason = 'max-length'
if reason != 'max-length':
eoa -= x['margin_m']
return {'eoa_m': eoa, 'reason': reason}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('boundary: own section occupied', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 50, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 675, 'reason': 'end-of-route'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('sampled regression 1', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 69, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 150, 'reason': 'unlocked'}), ('control 4', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 206, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 1325, 'reason': 'end-of-route'}), ('sampled regression 7', {'sections': [{'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 500, 'state': 'unlocked'}, {'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 108, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 550, 'reason': 'unlocked'})], [('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('sampled regression 10', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}], 'train_sec': 5, 'offset_m': 104, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1975, 'reason': 'occupied'}), ('sampled regression 6', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'unlocked'}, {'len': 100, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 2, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 625, 'reason': 'unlocked'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('regression: cap exactly at the obstacle', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 975, 'reason': 'occupied'}), ('control 12', {'sections': [{'len': 200, 'state': 'unlocked'}, {'len': 350, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 34, 'max_ma_m': 300, 'margin_m': 50}, {'eoa_m': 884, 'reason': 'max-length'}), ('control 15', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 4, 'offset_m': 137, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 2100, 'reason': 'end-of-route'}), ('sampled regression 18', {'sections': [{'len': 200, 'state': 'unlocked'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 3, 'offset_m': 181, 'max_ma_m': 1000, 'margin_m': 0}, {'eoa_m': 1250, 'reason': 'occupied'})], [('regression: cap exactly at the obstacle', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 975, 'reason': 'occupied'}), ('sampled regression 22', {'sections': [{'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 500, 'state': 'unlocked'}], 'train_sec': 4, 'offset_m': 91, 'max_ma_m': 1000, 'margin_m': 25}, {'eoa_m': 1325, 'reason': 'unlocked'}), ('sampled regression 11', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 239, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 500, 'reason': 'unlocked'}), ('boundary: end of route with margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 0, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 150, 'reason': 'end-of-route'}), ('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('sampled regression 23', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 1100, 'reason': 'unlocked'}), ('control 26', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}], 'train_sec': 1, 'offset_m': 9, 'max_ma_m': 300, 'margin_m': 25}, {'eoa_m': 409, 'reason': 'max-length'}), ('sampled regression 29', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 288, 'max_ma_m': 600, 'margin_m': 50}, {'eoa_m': 1000, 'reason': 'occupied'})], [('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('sampled regression 35', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}], 'train_sec': 3, 'offset_m': 56, 'max_ma_m': 1000, 'margin_m': 50}, {'eoa_m': 550, 'reason': 'occupied'}), ('sampled regression 19', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 103, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 925, 'reason': 'unlocked'}), ('boundary: own section occupied', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 50, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 675, 'reason': 'end-of-route'}), ('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('sampled regression 34', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 222, 'max_ma_m': 600, 'margin_m': 0}, {'eoa_m': 850, 'reason': 'unlocked'}), ('control 37', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 2, 'max_ma_m': 600, 'margin_m': 50}, {'eoa_m': 602, 'reason': 'max-length'}), ('sampled regression 40', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 500, 'state': 'unlocked'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 25, 'max_ma_m': 1000, 'margin_m': 0}, {'eoa_m': 500, 'reason': 'unlocked'})], [('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('sampled regression 50', {'sections': [{'len': 100, 'state': 'unlocked'}, {'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 3, 'offset_m': 115, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 1150, 'reason': 'unlocked'}), ('sampled regression 28', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}], 'train_sec': 1, 'offset_m': 74, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 1200, 'reason': 'occupied'}), ('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('control 45', {'sections': [{'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 348, 'max_ma_m': 300, 'margin_m': 25}, {'eoa_m': 1198, 'reason': 'max-length'}), ('control 48', {'sections': [{'len': 500, 'state': 'unlocked'}, {'len': 200, 'state': 'unlocked'}, {'len': 350, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 350, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 200, 'max_ma_m': 1000, 'margin_m': 25}, {'eoa_m': 1725, 'reason': 'end-of-route'}), ('sampled regression 51', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}], 'train_sec': 1, 'offset_m': 18, 'max_ma_m': 600, 'margin_m': 0}, {'eoa_m': 1100, 'reason': 'occupied'})]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: occupied section two ahead | {'eoa_m': 175, 'reason': 'occupied'} | {'eoa_m': 375, 'reason': 'occupied'} | Failed |
| regression: unlocked section margin | {'eoa_m': 70, 'reason': 'unlocked'} | {'eoa_m': 220, 'reason': 'unlocked'} | Failed |
| regression: unlocked section next | {'eoa_m': 175, 'reason': 'unlocked'} | {'eoa_m': 375, 'reason': 'unlocked'} | Failed |
| boundary: own section occupied | {'eoa_m': 675, 'reason': 'end-of-route'} | {'eoa_m': 675, 'reason': 'end-of-route'} | Passed |
| boundary: length cap from the front | {'eoa_m': 1000, 'reason': 'max-length'} | {'eoa_m': 1000, 'reason': 'max-length'} | Passed |
| sampled regression 1 | {'eoa_m': -50, 'reason': 'unlocked'} | {'eoa_m': 150, 'reason': 'unlocked'} | Failed |
| control 4 | {'eoa_m': 1325, 'reason': 'end-of-route'} | {'eoa_m': 1325, 'reason': 'end-of-route'} | Passed |
| sampled regression 7 | {'eoa_m': 350, 'reason': 'unlocked'} | {'eoa_m': 550, 'reason': 'unlocked'} | Failed |
SHA-256 / bf0dbfd024b499c92f68aed51ae2148081c39ae8a3579a73eb27b471cc17985b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
secs = x['sections']
bounds = []
acc = 0
for s in secs:
bounds.append(acc)
acc += s['len']
k = x['train_sec']
eoa = acc
reason = 'end-of-route'
for j in range(k + 1, len(secs)):
if secs[j]['state'] != 'locked':
eoa = bounds[j]
reason = secs[j]['state']
break
front = bounds[k] + x['offset_m']
if eoa - front > x['max_ma_m']:
eoa = front + x['max_ma_m']
reason = 'max-length'
if reason != 'max-length':
eoa -= x['margin_m']
return {'eoa_m': eoa, 'reason': reason}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('boundary: own section occupied', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 50, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 675, 'reason': 'end-of-route'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('sampled regression 1', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 69, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 150, 'reason': 'unlocked'}), ('control 4', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 206, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 1325, 'reason': 'end-of-route'}), ('sampled regression 7', {'sections': [{'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 500, 'state': 'unlocked'}, {'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 108, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 550, 'reason': 'unlocked'})], [('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('sampled regression 10', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}], 'train_sec': 5, 'offset_m': 104, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1975, 'reason': 'occupied'}), ('sampled regression 6', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'unlocked'}, {'len': 100, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 2, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 625, 'reason': 'unlocked'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('regression: cap exactly at the obstacle', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 975, 'reason': 'occupied'}), ('control 12', {'sections': [{'len': 200, 'state': 'unlocked'}, {'len': 350, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 34, 'max_ma_m': 300, 'margin_m': 50}, {'eoa_m': 884, 'reason': 'max-length'}), ('control 15', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 4, 'offset_m': 137, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 2100, 'reason': 'end-of-route'}), ('sampled regression 18', {'sections': [{'len': 200, 'state': 'unlocked'}, {'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 3, 'offset_m': 181, 'max_ma_m': 1000, 'margin_m': 0}, {'eoa_m': 1250, 'reason': 'occupied'})], [('regression: cap exactly at the obstacle', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 975, 'reason': 'occupied'}), ('sampled regression 22', {'sections': [{'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 500, 'state': 'unlocked'}], 'train_sec': 4, 'offset_m': 91, 'max_ma_m': 1000, 'margin_m': 25}, {'eoa_m': 1325, 'reason': 'unlocked'}), ('sampled regression 11', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 239, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 500, 'reason': 'unlocked'}), ('boundary: end of route with margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 0, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 150, 'reason': 'end-of-route'}), ('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('sampled regression 23', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 1100, 'reason': 'unlocked'}), ('control 26', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}], 'train_sec': 1, 'offset_m': 9, 'max_ma_m': 300, 'margin_m': 25}, {'eoa_m': 409, 'reason': 'max-length'}), ('sampled regression 29', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 288, 'max_ma_m': 600, 'margin_m': 50}, {'eoa_m': 1000, 'reason': 'occupied'})], [('regression: unlocked section margin', {'sections': [{'len': 100, 'state': 'occupied'}, {'len': 150, 'state': 'locked'}, {'len': 100, 'state': 'unlocked'}], 'train_sec': 0, 'offset_m': 20, 'max_ma_m': 5000, 'margin_m': 30}, {'eoa_m': 220, 'reason': 'unlocked'}), ('sampled regression 35', {'sections': [{'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}], 'train_sec': 3, 'offset_m': 56, 'max_ma_m': 1000, 'margin_m': 50}, {'eoa_m': 550, 'reason': 'occupied'}), ('sampled regression 19', {'sections': [{'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}], 'train_sec': 0, 'offset_m': 103, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 925, 'reason': 'unlocked'}), ('boundary: own section occupied', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 50, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 675, 'reason': 'end-of-route'}), ('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('sampled regression 34', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 222, 'max_ma_m': 600, 'margin_m': 0}, {'eoa_m': 850, 'reason': 'unlocked'}), ('control 37', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 2, 'max_ma_m': 600, 'margin_m': 50}, {'eoa_m': 602, 'reason': 'max-length'}), ('sampled regression 40', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 500, 'state': 'unlocked'}, {'len': 100, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 25, 'max_ma_m': 1000, 'margin_m': 0}, {'eoa_m': 500, 'reason': 'unlocked'})], [('regression: occupied section two ahead', {'sections': [{'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 300, 'state': 'occupied'}, {'len': 100, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 100, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'occupied'}), ('sampled regression 50', {'sections': [{'len': 100, 'state': 'unlocked'}, {'len': 350, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 500, 'state': 'occupied'}, {'len': 100, 'state': 'unlocked'}, {'len': 100, 'state': 'locked'}], 'train_sec': 3, 'offset_m': 115, 'max_ma_m': 5000, 'margin_m': 0}, {'eoa_m': 1150, 'reason': 'unlocked'}), ('sampled regression 28', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}, {'len': 100, 'state': 'locked'}, {'len': 350, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}], 'train_sec': 1, 'offset_m': 74, 'max_ma_m': 5000, 'margin_m': 50}, {'eoa_m': 1200, 'reason': 'occupied'}), ('regression: unlocked section next', {'sections': [{'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 300, 'state': 'unlocked'}], 'train_sec': 1, 'offset_m': 10, 'max_ma_m': 5000, 'margin_m': 25}, {'eoa_m': 375, 'reason': 'unlocked'}), ('boundary: length cap from the front', {'sections': [{'len': 500, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 500, 'state': 'locked'}], 'train_sec': 0, 'offset_m': 400, 'max_ma_m': 600, 'margin_m': 25}, {'eoa_m': 1000, 'reason': 'max-length'}), ('control 45', {'sections': [{'len': 350, 'state': 'unlocked'}, {'len': 200, 'state': 'locked'}, {'len': 350, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}, {'len': 200, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 348, 'max_ma_m': 300, 'margin_m': 25}, {'eoa_m': 1198, 'reason': 'max-length'}), ('control 48', {'sections': [{'len': 500, 'state': 'unlocked'}, {'len': 200, 'state': 'unlocked'}, {'len': 350, 'state': 'occupied'}, {'len': 350, 'state': 'locked'}, {'len': 350, 'state': 'locked'}], 'train_sec': 2, 'offset_m': 200, 'max_ma_m': 1000, 'margin_m': 25}, {'eoa_m': 1725, 'reason': 'end-of-route'}), ('sampled regression 51', {'sections': [{'len': 500, 'state': 'locked'}, {'len': 100, 'state': 'occupied'}, {'len': 500, 'state': 'locked'}, {'len': 200, 'state': 'occupied'}, {'len': 200, 'state': 'locked'}], 'train_sec': 1, 'offset_m': 18, 'max_ma_m': 600, 'margin_m': 0}, {'eoa_m': 1100, 'reason': 'occupied'})]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: occupied section two ahead | {'eoa_m': 375, 'reason': 'occupied'} | {'eoa_m': 375, 'reason': 'occupied'} | Passed |
| regression: unlocked section margin | {'eoa_m': 220, 'reason': 'unlocked'} | {'eoa_m': 220, 'reason': 'unlocked'} | Passed |
| regression: unlocked section next | {'eoa_m': 375, 'reason': 'unlocked'} | {'eoa_m': 375, 'reason': 'unlocked'} | Passed |
| boundary: own section occupied | {'eoa_m': 675, 'reason': 'end-of-route'} | {'eoa_m': 675, 'reason': 'end-of-route'} | Passed |
| boundary: length cap from the front | {'eoa_m': 1000, 'reason': 'max-length'} | {'eoa_m': 1000, 'reason': 'max-length'} | Passed |
| sampled regression 1 | {'eoa_m': 150, 'reason': 'unlocked'} | {'eoa_m': 150, 'reason': 'unlocked'} | Passed |
| control 4 | {'eoa_m': 1325, 'reason': 'end-of-route'} | {'eoa_m': 1325, 'reason': 'end-of-route'} | Passed |
| sampled regression 7 | {'eoa_m': 550, 'reason': 'unlocked'} | {'eoa_m': 550, 'reason': 'unlocked'} | Passed |
SHA-256 / 419ba4cbacb3b1656703a9badaeffe4613037138bc5eb01a595957d9328eb049
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:49.704313+00:00.
Case digest / c68674dd37de64ce798499ed33f5192a525164cb833344b3f09a29391e163080