{"abstract":"Cancelling frees a route that a train is still using.","category":"Railway interlocking logic","checks":8,"contract":"A route can be set only when free. pass_signal moves a set route to in-use; train_clear frees an in-use route. Cancelling a set route frees it at once unless a train is in the approach section, in which case it is approach-locked until cancel time + release_s (released when an event time reaches the deadline). approach_occ/approach_clear track the approach section. query appends set, free, in-use or locked-until:<t>.","contract_signature":"x","evaluation_group":"w2-railway_interlocking_logic-approach-locking","failed_approach":"Accepting cancel in every non-free state also restarts the timer of an already locked route.","family":"w2-railway_interlocking_logic-approach-locking-cancel-while-in-use","id":"FA-66931","implementations":{"attempt":{"sha256":"6acfb12b5981c5c53b0b5f1c453af61d9a4599fc5364263c8d32bd329939769b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    T = x['release_s']\n    state = 'free'\n    until = None\n    approach = False\n    out = []\n    for t, kind in x['events']:\n        if state == 'locked' and t >= until:\n            state = 'free'\n        if kind == 'approach_occ':\n            approach = True\n        elif kind == 'approach_clear':\n            approach = False\n        elif kind == 'set' and state == 'free':\n            state = 'set'\n        elif kind == 'cancel' and state != 'free':\n            if approach:\n                state = 'locked'\n                until = t + T\n            else:\n                state = 'free'\n        elif kind == 'pass_signal':\n            approach = False\n            if state == 'set':\n                state = 'in-use'\n        elif kind == 'train_clear' and state == 'in-use':\n            state = 'free'\n        elif kind == 'query':\n            out.append('locked-until:%d' % until if state == 'locked' else state)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 28', {'release_s': 60, 'events': [[120, 'cancel'], [130, 'approach_clear'], [190, 'approach_clear'], [250, 'approach_clear'], [251, 'train_clear'], [256, 'query'], [286, 'query'], [287, 'approach_clear'], [407, 'set'], [527, 'pass_signal'], [587, 'cancel'], [597, 'approach_occ'], [797, 'query']]}, ['free', 'free', 'in-use']), ('control 8', {'release_s': 120, 'events': [[120, 'approach_occ'], [125, 'approach_occ'], [130, 'set'], [190, 'cancel'], [190, 'query'], [200, 'train_clear'], [260, 'cancel'], [261, 'approach_clear'], [261, 'pass_signal'], [321, 'query']]}, ['locked-until:310', 'free']), ('boundary: query at exactly the release time', {'release_s': 120, 'events': [[0, 'set'], [5, 'approach_occ'], [10, 'cancel'], [130, 'query']]}, ['free']), ('boundary: re-set at exactly the release time', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [62, 'set'], [63, 'query']]}, ['set']), ('control 1', {'release_s': 120, 'events': [[120, 'query'], [125, 'set'], [185, 'set'], [215, 'pass_signal'], [275, 'query'], [475, 'query']]}, ['free', 'in-use', 'in-use']), ('control 4', {'release_s': 60, 'events': [[30, 'query'], [60, 'query'], [120, 'query'], [180, 'cancel'], [240, 'query'], [245, 'approach_occ'], [445, 'query']]}, ['free', 'free', 'free', 'free', 'free']), ('control 7', {'release_s': 120, 'events': [[0, 'cancel'], [0, 'query'], [0, 'approach_occ'], [1, 'set'], [11, 'approach_clear'], [41, 'query'], [42, 'approach_occ'], [242, 'query']]}, ['free', 'set', 'set'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('boundary: train backs out of the approach', {'release_s': 60, 'events': [[0, 'approach_occ'], [1, 'approach_clear'], [2, 'set'], [3, 'cancel'], [4, 'query']]}, ['free']), ('boundary: second lock after an earlier one', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [70, 'set'], [80, 'cancel'], [81, 'query']]}, ['locked-until:140']), ('boundary: set with a train approaching', {'release_s': 60, 'events': [[0, 'approach_occ'], [1, 'set'], [2, 'query']]}, ['set']), ('boundary: cancel with empty approach', {'release_s': 60, 'events': [[0, 'set'], [1, 'cancel'], [2, 'query']]}, ['free']), ('control 12', {'release_s': 120, 'events': [[1, 'query'], [121, 'approach_clear'], [241, 'set'], [271, 'set'], [391, 'approach_occ'], [451, 'query']]}, ['free', 'set']), ('control 15', {'release_s': 60, 'events': [[5, 'set'], [6, 'query'], [6, 'cancel'], [36, 'set'], [46, 'query'], [106, 'approach_clear'], [226, 'query'], [227, 'query'], [237, 'query'], [267, 'set'], [327, 'set'], [327, 'query']]}, ['set', 'set', 'set', 'set', 'set', 'set']), ('control 18', {'release_s': 60, 'events': [[5, 'approach_occ'], [10, 'approach_clear'], [70, 'approach_clear'], [190, 'query'], [195, 'set'], [195, 'cancel'], [195, 'cancel'], [200, 'query'], [260, 'set'], [265, 'set'], [325, 'query']]}, ['free', 'free', 'set'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 16', {'release_s': 60, 'events': [[120, 'approach_occ'], [180, 'query'], [185, 'query'], [305, 'set'], [306, 'pass_signal'], [306, 'cancel'], [307, 'query'], [317, 'cancel'], [318, 'train_clear'], [438, 'query']]}, ['free', 'free', 'in-use', 'free']), ('sampled regression 56', {'release_s': 60, 'events': [[5, 'approach_clear'], [15, 'query'], [75, 'set'], [75, 'query'], [105, 'query'], [106, 'query'], [136, 'pass_signal'], [196, 'approach_clear'], [206, 'cancel'], [216, 'set'], [336, 'query']]}, ['free', 'set', 'set', 'set', 'in-use']), ('boundary: set with a train approaching', {'release_s': 60, 'events': [[0, 'approach_occ'], [1, 'set'], [2, 'query']]}, ['set']), ('boundary: cancel with empty approach', {'release_s': 60, 'events': [[0, 'set'], [1, 'cancel'], [2, 'query']]}, ['free']), ('control 23', {'release_s': 60, 'events': [[10, 'cancel'], [15, 'set'], [25, 'approach_occ'], [26, 'set'], [36, 'cancel'], [156, 'query']]}, ['free']), ('control 26', {'release_s': 60, 'events': [[1, 'approach_occ'], [6, 'set'], [66, 'set'], [66, 'cancel'], [96, 'query'], [106, 'approach_clear'], [136, 'query'], [141, 'approach_clear'], [151, 'approach_occ'], [211, 'train_clear'], [271, 'query']]}, ['locked-until:126', 'free', 'free']), ('control 29', {'release_s': 60, 'events': [[0, 'set'], [0, 'set'], [30, 'train_clear'], [40, 'set'], [40, 'query'], [100, 'cancel'], [110, 'approach_occ'], [170, 'query']]}, ['set', 'free'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 56', {'release_s': 60, 'events': [[5, 'approach_clear'], [15, 'query'], [75, 'set'], [75, 'query'], [105, 'query'], [106, 'query'], [136, 'pass_signal'], [196, 'approach_clear'], [206, 'cancel'], [216, 'set'], [336, 'query']]}, ['free', 'set', 'set', 'set', 'in-use']), ('sampled regression 28', {'release_s': 60, 'events': [[120, 'cancel'], [130, 'approach_clear'], [190, 'approach_clear'], [250, 'approach_clear'], [251, 'train_clear'], [256, 'query'], [286, 'query'], [287, 'approach_clear'], [407, 'set'], [527, 'pass_signal'], [587, 'cancel'], [597, 'approach_occ'], [797, 'query']]}, ['free', 'free', 'in-use']), ('boundary: cancel with empty approach', {'release_s': 60, 'events': [[0, 'set'], [1, 'cancel'], [2, 'query']]}, ['free']), ('boundary: set attempted while locked', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [30, 'set'], [31, 'query']]}, ['locked-until:62']), ('control 34', {'release_s': 120, 'events': [[120, 'set'], [121, 'set'], [121, 'cancel'], [241, 'approach_occ'], [361, 'pass_signal'], [371, 'cancel'], [491, 'approach_occ'], [611, 'query']]}, ['free']), ('control 37', {'release_s': 60, 'events': [[60, 'query'], [61, 'train_clear'], [71, 'set'], [131, 'train_clear'], [131, 'pass_signal'], [136, 'approach_occ'], [196, 'set'], [197, 'cancel'], [202, 'set'], [262, 'train_clear'], [382, 'query'], [382, 'query']]}, ['free', 'free', 'free']), ('control 40', {'release_s': 120, 'events': [[0, 'query'], [30, 'cancel'], [90, 'approach_occ'], [100, 'set'], [130, 'query'], [135, 'approach_clear'], [255, 'train_clear'], [260, 'query'], [265, 'approach_occ'], [270, 'set'], [275, 'train_clear'], [305, 'cancel'], [365, 'query']]}, ['free', 'set', 'set', 'locked-until:425'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 9', {'release_s': 120, 'events': [[10, 'query'], [15, 'set'], [15, 'pass_signal'], [20, 'approach_occ'], [140, 'query'], [260, 'cancel'], [320, 'query'], [321, 'set'], [351, 'approach_clear'], [471, 'cancel'], [471, 'query']]}, ['free', 'in-use', 'in-use', 'in-use']), ('sampled regression 16', {'release_s': 60, 'events': [[120, 'approach_occ'], [180, 'query'], [185, 'query'], [305, 'set'], [306, 'pass_signal'], [306, 'cancel'], [307, 'query'], [317, 'cancel'], [318, 'train_clear'], [438, 'query']]}, ['free', 'free', 'in-use', 'free']), ('boundary: query at exactly the release time', {'release_s': 120, 'events': [[0, 'set'], [5, 'approach_occ'], [10, 'cancel'], [130, 'query']]}, ['free']), ('boundary: re-set at exactly the release time', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [62, 'set'], [63, 'query']]}, ['set']), ('control 45', {'release_s': 120, 'events': [[0, 'set'], [0, 'cancel'], [0, 'train_clear'], [0, 'approach_occ'], [1, 'approach_clear'], [6, 'approach_clear'], [126, 'query'], [136, 'set'], [141, 'train_clear'], [151, 'cancel'], [152, 'approach_clear'], [152, 'pass_signal'], [212, 'query']]}, ['free', 'free']), ('control 48', {'release_s': 60, 'events': [[120, 'set'], [121, 'train_clear'], [122, 'set'], [242, 'query'], [242, 'query'], [252, 'pass_signal'], [257, 'approach_occ'], [257, 'query']]}, ['set', 'set', 'in-use']), ('control 51', {'release_s': 60, 'events': [[120, 'pass_signal'], [120, 'cancel'], [125, 'approach_clear'], [126, 'cancel'], [136, 'cancel'], [256, 'approach_clear'], [316, 'pass_signal'], [376, 'query'], [377, 'query'], [387, 'cancel'], [387, 'query']]}, ['free', 'free', 'free'])]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"e261a62d884dd235b87616063a19b48ef8b3b6bdd5e7bab901c7821fed16923f","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    T = x['release_s']\n    state = 'free'\n    until = None\n    approach = False\n    out = []\n    for t, kind in x['events']:\n        if state == 'locked' and t >= until:\n            state = 'free'\n        if kind == 'approach_occ':\n            approach = True\n        elif kind == 'approach_clear':\n            approach = False\n        elif kind == 'set' and state == 'free':\n            state = 'set'\n        elif kind == 'cancel' and state in ('set', 'in-use'):\n            if approach:\n                state = 'locked'\n                until = t + T\n            else:\n                state = 'free'\n        elif kind == 'pass_signal':\n            approach = False\n            if state == 'set':\n                state = 'in-use'\n        elif kind == 'train_clear' and state == 'in-use':\n            state = 'free'\n        elif kind == 'query':\n            out.append('locked-until:%d' % until if state == 'locked' else state)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 28', {'release_s': 60, 'events': [[120, 'cancel'], [130, 'approach_clear'], [190, 'approach_clear'], [250, 'approach_clear'], [251, 'train_clear'], [256, 'query'], [286, 'query'], [287, 'approach_clear'], [407, 'set'], [527, 'pass_signal'], [587, 'cancel'], [597, 'approach_occ'], [797, 'query']]}, ['free', 'free', 'in-use']), ('control 8', {'release_s': 120, 'events': [[120, 'approach_occ'], [125, 'approach_occ'], [130, 'set'], [190, 'cancel'], [190, 'query'], [200, 'train_clear'], [260, 'cancel'], [261, 'approach_clear'], [261, 'pass_signal'], [321, 'query']]}, ['locked-until:310', 'free']), ('boundary: query at exactly the release time', {'release_s': 120, 'events': [[0, 'set'], [5, 'approach_occ'], [10, 'cancel'], [130, 'query']]}, ['free']), ('boundary: re-set at exactly the release time', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [62, 'set'], [63, 'query']]}, ['set']), ('control 1', {'release_s': 120, 'events': [[120, 'query'], [125, 'set'], [185, 'set'], [215, 'pass_signal'], [275, 'query'], [475, 'query']]}, ['free', 'in-use', 'in-use']), ('control 4', {'release_s': 60, 'events': [[30, 'query'], [60, 'query'], [120, 'query'], [180, 'cancel'], [240, 'query'], [245, 'approach_occ'], [445, 'query']]}, ['free', 'free', 'free', 'free', 'free']), ('control 7', {'release_s': 120, 'events': [[0, 'cancel'], [0, 'query'], [0, 'approach_occ'], [1, 'set'], [11, 'approach_clear'], [41, 'query'], [42, 'approach_occ'], [242, 'query']]}, ['free', 'set', 'set'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('boundary: train backs out of the approach', {'release_s': 60, 'events': [[0, 'approach_occ'], [1, 'approach_clear'], [2, 'set'], [3, 'cancel'], [4, 'query']]}, ['free']), ('boundary: second lock after an earlier one', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [70, 'set'], [80, 'cancel'], [81, 'query']]}, ['locked-until:140']), ('boundary: set with a train approaching', {'release_s': 60, 'events': [[0, 'approach_occ'], [1, 'set'], [2, 'query']]}, ['set']), ('boundary: cancel with empty approach', {'release_s': 60, 'events': [[0, 'set'], [1, 'cancel'], [2, 'query']]}, ['free']), ('control 12', {'release_s': 120, 'events': [[1, 'query'], [121, 'approach_clear'], [241, 'set'], [271, 'set'], [391, 'approach_occ'], [451, 'query']]}, ['free', 'set']), ('control 15', {'release_s': 60, 'events': [[5, 'set'], [6, 'query'], [6, 'cancel'], [36, 'set'], [46, 'query'], [106, 'approach_clear'], [226, 'query'], [227, 'query'], [237, 'query'], [267, 'set'], [327, 'set'], [327, 'query']]}, ['set', 'set', 'set', 'set', 'set', 'set']), ('control 18', {'release_s': 60, 'events': [[5, 'approach_occ'], [10, 'approach_clear'], [70, 'approach_clear'], [190, 'query'], [195, 'set'], [195, 'cancel'], [195, 'cancel'], [200, 'query'], [260, 'set'], [265, 'set'], [325, 'query']]}, ['free', 'free', 'set'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 16', {'release_s': 60, 'events': [[120, 'approach_occ'], [180, 'query'], [185, 'query'], [305, 'set'], [306, 'pass_signal'], [306, 'cancel'], [307, 'query'], [317, 'cancel'], [318, 'train_clear'], [438, 'query']]}, ['free', 'free', 'in-use', 'free']), ('sampled regression 56', {'release_s': 60, 'events': [[5, 'approach_clear'], [15, 'query'], [75, 'set'], [75, 'query'], [105, 'query'], [106, 'query'], [136, 'pass_signal'], [196, 'approach_clear'], [206, 'cancel'], [216, 'set'], [336, 'query']]}, ['free', 'set', 'set', 'set', 'in-use']), ('boundary: set with a train approaching', {'release_s': 60, 'events': [[0, 'approach_occ'], [1, 'set'], [2, 'query']]}, ['set']), ('boundary: cancel with empty approach', {'release_s': 60, 'events': [[0, 'set'], [1, 'cancel'], [2, 'query']]}, ['free']), ('control 23', {'release_s': 60, 'events': [[10, 'cancel'], [15, 'set'], [25, 'approach_occ'], [26, 'set'], [36, 'cancel'], [156, 'query']]}, ['free']), ('control 26', {'release_s': 60, 'events': [[1, 'approach_occ'], [6, 'set'], [66, 'set'], [66, 'cancel'], [96, 'query'], [106, 'approach_clear'], [136, 'query'], [141, 'approach_clear'], [151, 'approach_occ'], [211, 'train_clear'], [271, 'query']]}, ['locked-until:126', 'free', 'free']), ('control 29', {'release_s': 60, 'events': [[0, 'set'], [0, 'set'], [30, 'train_clear'], [40, 'set'], [40, 'query'], [100, 'cancel'], [110, 'approach_occ'], [170, 'query']]}, ['set', 'free'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 56', {'release_s': 60, 'events': [[5, 'approach_clear'], [15, 'query'], [75, 'set'], [75, 'query'], [105, 'query'], [106, 'query'], [136, 'pass_signal'], [196, 'approach_clear'], [206, 'cancel'], [216, 'set'], [336, 'query']]}, ['free', 'set', 'set', 'set', 'in-use']), ('sampled regression 28', {'release_s': 60, 'events': [[120, 'cancel'], [130, 'approach_clear'], [190, 'approach_clear'], [250, 'approach_clear'], [251, 'train_clear'], [256, 'query'], [286, 'query'], [287, 'approach_clear'], [407, 'set'], [527, 'pass_signal'], [587, 'cancel'], [597, 'approach_occ'], [797, 'query']]}, ['free', 'free', 'in-use']), ('boundary: cancel with empty approach', {'release_s': 60, 'events': [[0, 'set'], [1, 'cancel'], [2, 'query']]}, ['free']), ('boundary: set attempted while locked', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [30, 'set'], [31, 'query']]}, ['locked-until:62']), ('control 34', {'release_s': 120, 'events': [[120, 'set'], [121, 'set'], [121, 'cancel'], [241, 'approach_occ'], [361, 'pass_signal'], [371, 'cancel'], [491, 'approach_occ'], [611, 'query']]}, ['free']), ('control 37', {'release_s': 60, 'events': [[60, 'query'], [61, 'train_clear'], [71, 'set'], [131, 'train_clear'], [131, 'pass_signal'], [136, 'approach_occ'], [196, 'set'], [197, 'cancel'], [202, 'set'], [262, 'train_clear'], [382, 'query'], [382, 'query']]}, ['free', 'free', 'free']), ('control 40', {'release_s': 120, 'events': [[0, 'query'], [30, 'cancel'], [90, 'approach_occ'], [100, 'set'], [130, 'query'], [135, 'approach_clear'], [255, 'train_clear'], [260, 'query'], [265, 'approach_occ'], [270, 'set'], [275, 'train_clear'], [305, 'cancel'], [365, 'query']]}, ['free', 'set', 'set', 'locked-until:425'])], [('regression: cancel under a train', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'pass_signal'], [3, 'cancel'], [4, 'query'], [5, 'train_clear'], [6, 'query']]}, ['in-use', 'free']), ('sampled regression 9', {'release_s': 120, 'events': [[10, 'query'], [15, 'set'], [15, 'pass_signal'], [20, 'approach_occ'], [140, 'query'], [260, 'cancel'], [320, 'query'], [321, 'set'], [351, 'approach_clear'], [471, 'cancel'], [471, 'query']]}, ['free', 'in-use', 'in-use', 'in-use']), ('sampled regression 16', {'release_s': 60, 'events': [[120, 'approach_occ'], [180, 'query'], [185, 'query'], [305, 'set'], [306, 'pass_signal'], [306, 'cancel'], [307, 'query'], [317, 'cancel'], [318, 'train_clear'], [438, 'query']]}, ['free', 'free', 'in-use', 'free']), ('boundary: query at exactly the release time', {'release_s': 120, 'events': [[0, 'set'], [5, 'approach_occ'], [10, 'cancel'], [130, 'query']]}, ['free']), ('boundary: re-set at exactly the release time', {'release_s': 60, 'events': [[0, 'set'], [1, 'approach_occ'], [2, 'cancel'], [62, 'set'], [63, 'query']]}, ['set']), ('control 45', {'release_s': 120, 'events': [[0, 'set'], [0, 'cancel'], [0, 'train_clear'], [0, 'approach_occ'], [1, 'approach_clear'], [6, 'approach_clear'], [126, 'query'], [136, 'set'], [141, 'train_clear'], [151, 'cancel'], [152, 'approach_clear'], [152, 'pass_signal'], [212, 'query']]}, ['free', 'free']), ('control 48', {'release_s': 60, 'events': [[120, 'set'], [121, 'train_clear'], [122, 'set'], [242, 'query'], [242, 'query'], [252, 'pass_signal'], [257, 'approach_occ'], [257, 'query']]}, ['set', 'set', 'in-use']), ('control 51', {'release_s': 60, 'events': [[120, 'pass_signal'], [120, 'cancel'], [125, 'approach_clear'], [126, 'cancel'], [136, 'cancel'], [256, 'approach_clear'], [316, 'pass_signal'], [376, 'query'], [377, 'query'], [387, 'cancel'], [387, 'query']]}, ['free', 'free', 'free'])]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-railway_interlocking_logic-approach-locking-cancel-while-in-use","generated_at":"2026-09-29T14:47:48.185528+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Interlocking logic decides whether trains may be given authority; a wrong decision at this point either grants unsafe movements or strands traffic.","root_cause":"Cancellation is accepted in the in-use state, dropping the route lock under the train.","sha256":"1c0bac527aaee8ba8e1e406b4bc8afc8a50e96fb31a6afa81dd34b43078a158e","title":"Approach locking time release: cancel while in use · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":40.361,"exit_code":1,"observations":[{"actual":["free","free"],"check":"regression: cancel under a train","expected":["in-use","free"],"passed":false},{"actual":["free","free","free"],"check":"sampled regression 28","expected":["free","free","in-use"],"passed":false},{"actual":["locked-until:310","locked-until:380"],"check":"control 8","expected":["locked-until:310","free"],"passed":false},{"actual":["free"],"check":"boundary: query at exactly the release time","expected":["free"],"passed":true},{"actual":["set"],"check":"boundary: re-set at exactly the release time","expected":["set"],"passed":true},{"actual":["free","in-use","in-use"],"check":"control 1","expected":["free","in-use","in-use"],"passed":true},{"actual":["free","free","free","free","free"],"check":"control 4","expected":["free","free","free","free","free"],"passed":true},{"actual":["free","set","set"],"check":"control 7","expected":["free","set","set"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: cancel under a train\", \"actual\": [\"free\", \"free\"], \"expected\": [\"in-use\", \"free\"], \"passed\": false}, {\"check\": \"sampled regression 28\", \"actual\": [\"free\", \"free\", \"free\"], \"expected\": [\"free\", \"free\", \"in-use\"], \"passed\": false}, {\"check\": \"control 8\", \"actual\": [\"locked-until:310\", \"locked-until:380\"], \"expected\": [\"locked-until:310\", \"free\"], \"passed\": false}, {\"check\": \"boundary: query at exactly the release time\", \"actual\": [\"free\"], \"expected\": [\"free\"], \"passed\": true}, {\"check\": \"boundary: re-set at exactly the release time\", \"actual\": [\"set\"], \"expected\": [\"set\"], \"passed\": true}, {\"check\": \"control 1\", \"actual\": [\"free\", \"in-use\", \"in-use\"], \"expected\": [\"free\", \"in-use\", \"in-use\"], \"passed\": true}, {\"check\": \"control 4\", \"actual\": [\"free\", \"free\", \"free\", \"free\", \"free\"], \"expected\": [\"free\", \"free\", \"free\", \"free\", \"free\"], \"passed\": true}, {\"check\": \"control 7\", \"actual\": [\"free\", \"set\", \"set\"], \"expected\": [\"free\", \"set\", \"set\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.029,"exit_code":1,"observations":[{"actual":["free","free"],"check":"regression: cancel under a train","expected":["in-use","free"],"passed":false},{"actual":["free","free","free"],"check":"sampled regression 28","expected":["free","free","in-use"],"passed":false},{"actual":["locked-until:310","free"],"check":"control 8","expected":["locked-until:310","free"],"passed":true},{"actual":["free"],"check":"boundary: query at exactly the release time","expected":["free"],"passed":true},{"actual":["set"],"check":"boundary: re-set at exactly the release time","expected":["set"],"passed":true},{"actual":["free","in-use","in-use"],"check":"control 1","expected":["free","in-use","in-use"],"passed":true},{"actual":["free","free","free","free","free"],"check":"control 4","expected":["free","free","free","free","free"],"passed":true},{"actual":["free","set","set"],"check":"control 7","expected":["free","set","set"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: cancel under a train\", \"actual\": [\"free\", \"free\"], \"expected\": [\"in-use\", \"free\"], \"passed\": false}, {\"check\": \"sampled regression 28\", \"actual\": [\"free\", \"free\", \"free\"], \"expected\": [\"free\", \"free\", \"in-use\"], \"passed\": false}, {\"check\": \"control 8\", \"actual\": [\"locked-until:310\", \"free\"], \"expected\": [\"locked-until:310\", \"free\"], \"passed\": true}, {\"check\": \"boundary: query at exactly the release time\", \"actual\": [\"free\"], \"expected\": [\"free\"], \"passed\": true}, {\"check\": \"boundary: re-set at exactly the release time\", \"actual\": [\"set\"], \"expected\": [\"set\"], \"passed\": true}, {\"check\": \"control 1\", \"actual\": [\"free\", \"in-use\", \"in-use\"], \"expected\": [\"free\", \"in-use\", \"in-use\"], \"passed\": true}, {\"check\": \"control 4\", \"actual\": [\"free\", \"free\", \"free\", \"free\", \"free\"], \"expected\": [\"free\", \"free\", \"free\", \"free\", \"free\"], \"passed\": true}, {\"check\": \"control 7\", \"actual\": [\"free\", \"set\", \"set\"], \"expected\": [\"free\", \"set\", \"set\"], \"passed\": true}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}