FA-67336 / Railway interlocking logic / Open access
Temporary speed restriction over train length: sighting distance reference · case 01
A restriction exactly at the sighting distance is not announced, or sighting is measured from the wrong end.
ROOT CAUSE
The sighting comparison is exclusive.
VERIFIED REPAIR
Announce restrictions starting within sight_m of the front, inclusive.
Unsuccessful approach: Measuring from the rear shortens the effective sighting distance.
Case contract
A restriction [from_m, to_m) applies while any part of the train (rear = front - length) is inside it: from <= front and to > rear. The limit is the minimum of the line speed and applicable restrictions. next_m is the start of the nearest restriction ahead of the front (from > front) within sight_m of the front whose speed is below the current limit, else None.
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):
front = x['front_m']
rear = front - x['length_m']
limit = x['line_kmh']
for s in x['tsr']:
if s['from_m'] <= front and s['to_m'] > rear:
limit = min(limit, s['kmh'])
ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front < x['sight_m'] and s['kmh'] < limit]
nxt = min(ahead, key=lambda s: s['from_m'])['from_m'] if ahead else None
return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('control 57', {'front_m': 250, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 120, 'next_m': 500}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('control 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 32', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 62', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}]}, {'limit': 100, 'next_m': 1000}), ('control 57', {'front_m': 250, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 120, 'next_m': 500}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('sampled regression 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('control 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None})]]
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: restriction exactly at sighting distance | {'limit': 100, 'next_m': None} | {'limit': 100, 'next_m': 600} | Failed |
| sampled regression 34 | {'limit': 100, 'next_m': None} | {'limit': 100, 'next_m': 1000} | Failed |
| sampled regression 5 | {'limit': 120, 'next_m': None} | {'limit': 120, 'next_m': 800} | Failed |
| boundary: rear still inside the restriction | {'limit': 40, 'next_m': None} | {'limit': 40, 'next_m': None} | Passed |
| boundary: rear exactly at the restriction end | {'limit': 100, 'next_m': None} | {'limit': 100, 'next_m': None} | Passed |
| control 1 | {'limit': 40, 'next_m': None} | {'limit': 40, 'next_m': None} | Passed |
| control 4 | {'limit': 20, 'next_m': None} | {'limit': 20, 'next_m': None} | Passed |
| control 7 | {'limit': 60, 'next_m': None} | {'limit': 60, 'next_m': None} | Passed |
SHA-256 / c2d8842555a1b8b99cdaf8abe30bf85d25d476bb5486f03d0578f34b756053c4
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
front = x['front_m']
rear = front - x['length_m']
limit = x['line_kmh']
for s in x['tsr']:
if s['from_m'] <= front and s['to_m'] > rear:
limit = min(limit, s['kmh'])
ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - rear <= x['sight_m'] and s['kmh'] < limit]
nxt = min(ahead, key=lambda s: s['from_m'])['from_m'] if ahead else None
return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('control 57', {'front_m': 250, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 120, 'next_m': 500}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('control 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 32', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 62', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}]}, {'limit': 100, 'next_m': 1000}), ('control 57', {'front_m': 250, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 120, 'next_m': 500}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('sampled regression 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('control 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None})]]
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: restriction exactly at sighting distance | {'limit': 100, 'next_m': None} | {'limit': 100, 'next_m': 600} | Failed |
| sampled regression 34 | {'limit': 100, 'next_m': None} | {'limit': 100, 'next_m': 1000} | Failed |
| sampled regression 5 | {'limit': 120, 'next_m': None} | {'limit': 120, 'next_m': 800} | Failed |
| boundary: rear still inside the restriction | {'limit': 40, 'next_m': None} | {'limit': 40, 'next_m': None} | Passed |
| boundary: rear exactly at the restriction end | {'limit': 100, 'next_m': None} | {'limit': 100, 'next_m': None} | Passed |
| control 1 | {'limit': 40, 'next_m': None} | {'limit': 40, 'next_m': None} | Passed |
| control 4 | {'limit': 20, 'next_m': None} | {'limit': 20, 'next_m': None} | Passed |
| control 7 | {'limit': 60, 'next_m': None} | {'limit': 60, 'next_m': None} | Passed |
SHA-256 / 1a589044bbad198e3a9977a6c061cc9b5ba1a7a0b1890be44b5b299d958ec407
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
front = x['front_m']
rear = front - x['length_m']
limit = x['line_kmh']
for s in x['tsr']:
if s['from_m'] <= front and s['to_m'] > rear:
limit = min(limit, s['kmh'])
ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front <= x['sight_m'] and s['kmh'] < limit]
nxt = min(ahead, key=lambda s: s['from_m'])['from_m'] if ahead else None
return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('control 57', {'front_m': 250, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 120, 'next_m': 500}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('control 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 32', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 62', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}]}, {'limit': 100, 'next_m': 1000}), ('control 57', {'front_m': 250, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 120, 'next_m': 500}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('sampled regression 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('sampled regression 5', {'front_m': 500, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}]}, {'limit': 120, 'next_m': 800}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('control 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None})]]
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: restriction exactly at sighting distance | {'limit': 100, 'next_m': 600} | {'limit': 100, 'next_m': 600} | Passed |
| sampled regression 34 | {'limit': 100, 'next_m': 1000} | {'limit': 100, 'next_m': 1000} | Passed |
| sampled regression 5 | {'limit': 120, 'next_m': 800} | {'limit': 120, 'next_m': 800} | Passed |
| boundary: rear still inside the restriction | {'limit': 40, 'next_m': None} | {'limit': 40, 'next_m': None} | Passed |
| boundary: rear exactly at the restriction end | {'limit': 100, 'next_m': None} | {'limit': 100, 'next_m': None} | Passed |
| control 1 | {'limit': 40, 'next_m': None} | {'limit': 40, 'next_m': None} | Passed |
| control 4 | {'limit': 20, 'next_m': None} | {'limit': 20, 'next_m': None} | Passed |
| control 7 | {'limit': 60, 'next_m': None} | {'limit': 60, 'next_m': None} | Passed |
SHA-256 / a167d7445c56ef53c7b7cbbd4a6aed3285ebdb6b76db3c065826788d2df3ab73
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:51.982542+00:00.
Case digest / 8fb19a7c3a62d9754065788bd47950293904e4105c9b7af252731028428447f3