{"abstract":"Tying down one button and pulsing the other still starts the press.","category":"PLC ladder logic scan cycles","checks":8,"contract":"Two-hand press control sampled per scan; samples is a list of [t_ms, left, right]. The press may start only when both buttons become pressed within window ms of the first one being pressed (inclusive), starting from a state where both were released. Releasing either button stops the press, and both buttons must then be released before a new start is allowed (anti-tie-down). Return the run output per scan.","evaluation_group":"w2-plc-ladder-logic-scan-cycles-two-hand-control","failed_approach":"Re-arming on a single release while restarting the window from that scan still defeats anti-tie-down.","family":"w2-plc-ladder-logic-scan-cycles-two-hand-control-rearm-both-released","id":"FA-92276","implementations":{"attempt":{"sha256":"3938ba9714ea2c8db6124fc4796f692e1dad25ee5a4bc76b63e9496cb4a08f3a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(window, samples):\n    first_press = None\n    armed = True\n    run = False\n    out = []\n    for t, left, right in samples:\n        left = bool(left)\n        right = bool(right)\n        if not left and not right:\n            armed = True\n            first_press = None\n            run = False\n        elif left and right:\n            if not run:\n                begin = t if first_press is None else first_press\n                if armed and t - begin <= window:\n                    run = True\n                armed = False\n        else:\n            run = False\n            armed = True\n            first_press = t\n            if first_press is None:\n                first_press = t\n        out.append(run)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['control: scenario 1',\n   [200,\n    [[0, False, False],\n     [100, True, True],\n     [400, True, True],\n     [500, True, True],\n     [650, True, True],\n     [850, True, True],\n     [1050, True, False],\n     [1100, False, False],\n     [1300, True, True],\n     [1600, True, True]]],\n   [False, True, True, True, True, True, False, False, True, True]],\n  ['regression: scenario 2',\n   [200,\n    [[0, True, True],\n     [50, True, False],\n     [200, True, True],\n     [250, False, False],\n     [300, False, True],\n     [400, False, False],\n     [450, False, False],\n     [550, False, True]]],\n   [True, False, False, False, False, False, False, False]],\n  ['control: scenario 3',\n   [200,\n    [[0, True, False],\n     [150, True, True],\n     [200, True, True],\n     [400, False, False],\n     [500, True, True],\n     [700, True, True],\n     [850, True, False],\n     [1000, True, False],\n     [1100, False, False],\n     [1400, True, False],\n     [1450, False, True],\n     [1600, True, True],\n     [1700, True, True]]],\n   [False, True, True, False, True, True, False, False, False, False, False, True, True]]],\n [['regression: scenario 1',\n   [250,\n    [[0, True, True],\n     [50, True, True],\n     [200, False, True],\n     [300, True, True],\n     [600, True, True],\n     [750, False, True],\n     [850, False, False],\n     [1000, False, True],\n     [1100, True, True]]],\n   [True, True, False, False, False, False, False, False, True]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['control: scenario 2',\n   [250,\n    [[0, True, True],\n     [50, False, True],\n     [200, False, False],\n     [250, True, False],\n     [400, True, True],\n     [500, True, True],\n     [650, False, False],\n     [700, True, True],\n     [850, False, False],\n     [1000, False, True],\n     [1150, False, True],\n     [1250, False, True],\n     [1550, False, False]]],\n   [True, False, False, False, True, True, False, True, False, False, False, False, False]],\n  ['control: scenario 3',\n   [500,\n    [[0, True, False],\n     [300, False, False],\n     [400, False, True],\n     [500, False, True],\n     [800, True, True],\n     [950, False, False],\n     [1050, False, False],\n     [1350, False, False],\n     [1450, False, True],\n     [1600, False, True],\n     [1650, True, True],\n     [1800, False, True],\n     [1850, False, True]]],\n   [False, False, False, False, True, False, False, False, False, False, True, False, False]]],\n [['regression: scenario 6',\n   [500,\n    [[0, True, False],\n     [100, True, True],\n     [250, False, True],\n     [400, True, True],\n     [450, False, False],\n     [600, False, False],\n     [900, True, True],\n     [1200, True, True],\n     [1350, False, False],\n     [1550, False, False],\n     [1850, False, True],\n     [1900, True, True],\n     [1950, True, True]]],\n   [False, True, False, False, False, False, True, True, False, False, False, True, True]],\n  ['regression: scenario 3',\n   [250,\n    [[0, False, False],\n     [100, True, False],\n     [400, True, False],\n     [700, True, False],\n     [900, True, True],\n     [1200, True, False],\n     [1400, False, False],\n     [1700, True, False],\n     [1750, True, True],\n     [1950, False, False],\n     [2100, False, False],\n     [2250, False, True]]],\n   [False, False, False, False, False, False, False, False, True, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: scenario 1',\n   [200,\n    [[0, False, True],\n     [100, False, False],\n     [250, False, False],\n     [300, True, False],\n     [400, True, False],\n     [450, False, True],\n     [550, True, False],\n     [700, True, False],\n     [800, False, True]]],\n   [False, False, False, False, False, False, False, False, False]]],\n [['regression: scenario 14',\n   [500,\n    [[0, True, True],\n     [100, False, True],\n     [200, False, True],\n     [400, False, True],\n     [450, True, True],\n     [550, True, False],\n     [700, True, False],\n     [800, False, False]]],\n   [True, False, False, False, False, False, False, False]],\n  ['regression: scenario 5',\n   [500,\n    [[0, True, False],\n     [300, False, False],\n     [350, True, True],\n     [450, True, True],\n     [550, True, True],\n     [750, False, True],\n     [900, True, True],\n     [1000, False, False],\n     [1050, True, True],\n     [1350, False, True],\n     [1650, True, True],\n     [1950, True, False],\n     [2000, False, False]]],\n   [False, False, True, True, True, False, False, False, True, False, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['regression: scenario 1',\n   [250,\n    [[0, False, True],\n     [200, False, False],\n     [250, True, False],\n     [550, True, False],\n     [650, True, True],\n     [700, True, False],\n     [900, True, True],\n     [1100, True, False],\n     [1200, False, True],\n     [1300, True, False],\n     [1450, False, True],\n     [1650, False, False],\n     [1800, True, True]]],\n   [False, False, False, False, False, False, False, False, False, False, False, False, True]]],\n [['regression: scenario 48',\n   [500,\n    [[0, False, False],\n     [50, True, True],\n     [350, True, True],\n     [650, False, False],\n     [800, False, True],\n     [850, True, True],\n     [1150, False, False],\n     [1450, True, True],\n     [1650, True, False],\n     [1700, True, True],\n     [1850, False, False],\n     [2000, False, False],\n     [2150, False, False],\n     [2350, False, True]]],\n   [False, True, True, False, False, True, False, True, False, False, False, False, False, False]],\n  ['regression: scenario 14',\n   [200,\n    [[0, True, True],\n     [150, False, True],\n     [200, False, True],\n     [350, False, True],\n     [550, True, True],\n     [750, False, False],\n     [950, False, False],\n     [1000, True, True],\n     [1100, True, False],\n     [1150, False, True]]],\n   [True, False, False, False, False, False, False, True, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: scenario 1',\n   [500,\n    [[0, True, False],\n     [150, True, False],\n     [250, True, False],\n     [300, False, False],\n     [350, False, True],\n     [650, False, True],\n     [850, False, False],\n     [1150, False, False],\n     [1350, True, False],\n     [1650, True, False],\n     [1800, True, False],\n     [1850, True, False],\n     [1900, False, True]]],\n   [False, False, False, False, False, False, False, False, False, False, False, False, False]]]]\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":"2dd74d5f1c04904ef6c868313b45313bb371b15c5f2fc879da619fbdfc9766fc","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(window, samples):\n    first_press = None\n    armed = True\n    run = False\n    out = []\n    for t, left, right in samples:\n        left = bool(left)\n        right = bool(right)\n        if not left and not right:\n            armed = True\n            first_press = None\n            run = False\n        elif left and right:\n            if not run:\n                begin = t if first_press is None else first_press\n                if armed and t - begin <= window:\n                    run = True\n                armed = False\n        else:\n            run = False\n            armed = True\n            if first_press is None:\n                first_press = t\n        out.append(run)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['control: scenario 1',\n   [200,\n    [[0, False, False],\n     [100, True, True],\n     [400, True, True],\n     [500, True, True],\n     [650, True, True],\n     [850, True, True],\n     [1050, True, False],\n     [1100, False, False],\n     [1300, True, True],\n     [1600, True, True]]],\n   [False, True, True, True, True, True, False, False, True, True]],\n  ['regression: scenario 2',\n   [200,\n    [[0, True, True],\n     [50, True, False],\n     [200, True, True],\n     [250, False, False],\n     [300, False, True],\n     [400, False, False],\n     [450, False, False],\n     [550, False, True]]],\n   [True, False, False, False, False, False, False, False]],\n  ['control: scenario 3',\n   [200,\n    [[0, True, False],\n     [150, True, True],\n     [200, True, True],\n     [400, False, False],\n     [500, True, True],\n     [700, True, True],\n     [850, True, False],\n     [1000, True, False],\n     [1100, False, False],\n     [1400, True, False],\n     [1450, False, True],\n     [1600, True, True],\n     [1700, True, True]]],\n   [False, True, True, False, True, True, False, False, False, False, False, True, True]]],\n [['regression: scenario 1',\n   [250,\n    [[0, True, True],\n     [50, True, True],\n     [200, False, True],\n     [300, True, True],\n     [600, True, True],\n     [750, False, True],\n     [850, False, False],\n     [1000, False, True],\n     [1100, True, True]]],\n   [True, True, False, False, False, False, False, False, True]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['control: scenario 2',\n   [250,\n    [[0, True, True],\n     [50, False, True],\n     [200, False, False],\n     [250, True, False],\n     [400, True, True],\n     [500, True, True],\n     [650, False, False],\n     [700, True, True],\n     [850, False, False],\n     [1000, False, True],\n     [1150, False, True],\n     [1250, False, True],\n     [1550, False, False]]],\n   [True, False, False, False, True, True, False, True, False, False, False, False, False]],\n  ['control: scenario 3',\n   [500,\n    [[0, True, False],\n     [300, False, False],\n     [400, False, True],\n     [500, False, True],\n     [800, True, True],\n     [950, False, False],\n     [1050, False, False],\n     [1350, False, False],\n     [1450, False, True],\n     [1600, False, True],\n     [1650, True, True],\n     [1800, False, True],\n     [1850, False, True]]],\n   [False, False, False, False, True, False, False, False, False, False, True, False, False]]],\n [['regression: scenario 6',\n   [500,\n    [[0, True, False],\n     [100, True, True],\n     [250, False, True],\n     [400, True, True],\n     [450, False, False],\n     [600, False, False],\n     [900, True, True],\n     [1200, True, True],\n     [1350, False, False],\n     [1550, False, False],\n     [1850, False, True],\n     [1900, True, True],\n     [1950, True, True]]],\n   [False, True, False, False, False, False, True, True, False, False, False, True, True]],\n  ['regression: scenario 3',\n   [250,\n    [[0, False, False],\n     [100, True, False],\n     [400, True, False],\n     [700, True, False],\n     [900, True, True],\n     [1200, True, False],\n     [1400, False, False],\n     [1700, True, False],\n     [1750, True, True],\n     [1950, False, False],\n     [2100, False, False],\n     [2250, False, True]]],\n   [False, False, False, False, False, False, False, False, True, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: scenario 1',\n   [200,\n    [[0, False, True],\n     [100, False, False],\n     [250, False, False],\n     [300, True, False],\n     [400, True, False],\n     [450, False, True],\n     [550, True, False],\n     [700, True, False],\n     [800, False, True]]],\n   [False, False, False, False, False, False, False, False, False]]],\n [['regression: scenario 14',\n   [500,\n    [[0, True, True],\n     [100, False, True],\n     [200, False, True],\n     [400, False, True],\n     [450, True, True],\n     [550, True, False],\n     [700, True, False],\n     [800, False, False]]],\n   [True, False, False, False, False, False, False, False]],\n  ['regression: scenario 5',\n   [500,\n    [[0, True, False],\n     [300, False, False],\n     [350, True, True],\n     [450, True, True],\n     [550, True, True],\n     [750, False, True],\n     [900, True, True],\n     [1000, False, False],\n     [1050, True, True],\n     [1350, False, True],\n     [1650, True, True],\n     [1950, True, False],\n     [2000, False, False]]],\n   [False, False, True, True, True, False, False, False, True, False, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['regression: scenario 1',\n   [250,\n    [[0, False, True],\n     [200, False, False],\n     [250, True, False],\n     [550, True, False],\n     [650, True, True],\n     [700, True, False],\n     [900, True, True],\n     [1100, True, False],\n     [1200, False, True],\n     [1300, True, False],\n     [1450, False, True],\n     [1650, False, False],\n     [1800, True, True]]],\n   [False, False, False, False, False, False, False, False, False, False, False, False, True]]],\n [['regression: scenario 48',\n   [500,\n    [[0, False, False],\n     [50, True, True],\n     [350, True, True],\n     [650, False, False],\n     [800, False, True],\n     [850, True, True],\n     [1150, False, False],\n     [1450, True, True],\n     [1650, True, False],\n     [1700, True, True],\n     [1850, False, False],\n     [2000, False, False],\n     [2150, False, False],\n     [2350, False, True]]],\n   [False, True, True, False, False, True, False, True, False, False, False, False, False, False]],\n  ['regression: scenario 14',\n   [200,\n    [[0, True, True],\n     [150, False, True],\n     [200, False, True],\n     [350, False, True],\n     [550, True, True],\n     [750, False, False],\n     [950, False, False],\n     [1000, True, True],\n     [1100, True, False],\n     [1150, False, True]]],\n   [True, False, False, False, False, False, False, True, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: scenario 1',\n   [500,\n    [[0, True, False],\n     [150, True, False],\n     [250, True, False],\n     [300, False, False],\n     [350, False, True],\n     [650, False, True],\n     [850, False, False],\n     [1150, False, False],\n     [1350, True, False],\n     [1650, True, False],\n     [1800, True, False],\n     [1850, True, False],\n     [1900, False, True]]],\n   [False, False, False, False, False, False, False, False, False, False, False, False, False]]]]\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"},"fixed":{"sha256":"61ee98a624f8faa3bc459564b3e68de721b56894f221c70457b685d2f61630a0","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(window, samples):\n    first_press = None\n    armed = True\n    run = False\n    out = []\n    for t, left, right in samples:\n        left = bool(left)\n        right = bool(right)\n        if not left and not right:\n            armed = True\n            first_press = None\n            run = False\n        elif left and right:\n            if not run:\n                begin = t if first_press is None else first_press\n                if armed and t - begin <= window:\n                    run = True\n                armed = False\n        else:\n            run = False\n            if first_press is None:\n                first_press = t\n        out.append(run)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['control: scenario 1',\n   [200,\n    [[0, False, False],\n     [100, True, True],\n     [400, True, True],\n     [500, True, True],\n     [650, True, True],\n     [850, True, True],\n     [1050, True, False],\n     [1100, False, False],\n     [1300, True, True],\n     [1600, True, True]]],\n   [False, True, True, True, True, True, False, False, True, True]],\n  ['regression: scenario 2',\n   [200,\n    [[0, True, True],\n     [50, True, False],\n     [200, True, True],\n     [250, False, False],\n     [300, False, True],\n     [400, False, False],\n     [450, False, False],\n     [550, False, True]]],\n   [True, False, False, False, False, False, False, False]],\n  ['control: scenario 3',\n   [200,\n    [[0, True, False],\n     [150, True, True],\n     [200, True, True],\n     [400, False, False],\n     [500, True, True],\n     [700, True, True],\n     [850, True, False],\n     [1000, True, False],\n     [1100, False, False],\n     [1400, True, False],\n     [1450, False, True],\n     [1600, True, True],\n     [1700, True, True]]],\n   [False, True, True, False, True, True, False, False, False, False, False, True, True]]],\n [['regression: scenario 1',\n   [250,\n    [[0, True, True],\n     [50, True, True],\n     [200, False, True],\n     [300, True, True],\n     [600, True, True],\n     [750, False, True],\n     [850, False, False],\n     [1000, False, True],\n     [1100, True, True]]],\n   [True, True, False, False, False, False, False, False, True]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['control: scenario 2',\n   [250,\n    [[0, True, True],\n     [50, False, True],\n     [200, False, False],\n     [250, True, False],\n     [400, True, True],\n     [500, True, True],\n     [650, False, False],\n     [700, True, True],\n     [850, False, False],\n     [1000, False, True],\n     [1150, False, True],\n     [1250, False, True],\n     [1550, False, False]]],\n   [True, False, False, False, True, True, False, True, False, False, False, False, False]],\n  ['control: scenario 3',\n   [500,\n    [[0, True, False],\n     [300, False, False],\n     [400, False, True],\n     [500, False, True],\n     [800, True, True],\n     [950, False, False],\n     [1050, False, False],\n     [1350, False, False],\n     [1450, False, True],\n     [1600, False, True],\n     [1650, True, True],\n     [1800, False, True],\n     [1850, False, True]]],\n   [False, False, False, False, True, False, False, False, False, False, True, False, False]]],\n [['regression: scenario 6',\n   [500,\n    [[0, True, False],\n     [100, True, True],\n     [250, False, True],\n     [400, True, True],\n     [450, False, False],\n     [600, False, False],\n     [900, True, True],\n     [1200, True, True],\n     [1350, False, False],\n     [1550, False, False],\n     [1850, False, True],\n     [1900, True, True],\n     [1950, True, True]]],\n   [False, True, False, False, False, False, True, True, False, False, False, True, True]],\n  ['regression: scenario 3',\n   [250,\n    [[0, False, False],\n     [100, True, False],\n     [400, True, False],\n     [700, True, False],\n     [900, True, True],\n     [1200, True, False],\n     [1400, False, False],\n     [1700, True, False],\n     [1750, True, True],\n     [1950, False, False],\n     [2100, False, False],\n     [2250, False, True]]],\n   [False, False, False, False, False, False, False, False, True, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: scenario 1',\n   [200,\n    [[0, False, True],\n     [100, False, False],\n     [250, False, False],\n     [300, True, False],\n     [400, True, False],\n     [450, False, True],\n     [550, True, False],\n     [700, True, False],\n     [800, False, True]]],\n   [False, False, False, False, False, False, False, False, False]]],\n [['regression: scenario 14',\n   [500,\n    [[0, True, True],\n     [100, False, True],\n     [200, False, True],\n     [400, False, True],\n     [450, True, True],\n     [550, True, False],\n     [700, True, False],\n     [800, False, False]]],\n   [True, False, False, False, False, False, False, False]],\n  ['regression: scenario 5',\n   [500,\n    [[0, True, False],\n     [300, False, False],\n     [350, True, True],\n     [450, True, True],\n     [550, True, True],\n     [750, False, True],\n     [900, True, True],\n     [1000, False, False],\n     [1050, True, True],\n     [1350, False, True],\n     [1650, True, True],\n     [1950, True, False],\n     [2000, False, False]]],\n   [False, False, True, True, True, False, False, False, True, False, False, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['regression: scenario 1',\n   [250,\n    [[0, False, True],\n     [200, False, False],\n     [250, True, False],\n     [550, True, False],\n     [650, True, True],\n     [700, True, False],\n     [900, True, True],\n     [1100, True, False],\n     [1200, False, True],\n     [1300, True, False],\n     [1450, False, True],\n     [1650, False, False],\n     [1800, True, True]]],\n   [False, False, False, False, False, False, False, False, False, False, False, False, True]]],\n [['regression: scenario 48',\n   [500,\n    [[0, False, False],\n     [50, True, True],\n     [350, True, True],\n     [650, False, False],\n     [800, False, True],\n     [850, True, True],\n     [1150, False, False],\n     [1450, True, True],\n     [1650, True, False],\n     [1700, True, True],\n     [1850, False, False],\n     [2000, False, False],\n     [2150, False, False],\n     [2350, False, True]]],\n   [False, True, True, False, False, True, False, True, False, False, False, False, False, False]],\n  ['regression: scenario 14',\n   [200,\n    [[0, True, True],\n     [150, False, True],\n     [200, False, True],\n     [350, False, True],\n     [550, True, True],\n     [750, False, False],\n     [950, False, False],\n     [1000, True, True],\n     [1100, True, False],\n     [1150, False, True]]],\n   [True, False, False, False, False, False, False, True, False, False]],\n  ['control: normal cycle',\n   [500,\n    [[0, True, False],\n     [300, True, True],\n     [400, True, True],\n     [500, False, True],\n     [600, False, False],\n     [700, True, True]]],\n   [False, True, True, False, False, True]],\n  ['control: late second hand',\n   [200, [[0, True, False], [300, True, True], [400, False, False], [500, True, False], [600, True, True]]],\n   [False, False, False, False, True]],\n  ['control: exact window',\n   [200, [[0, False, True], [200, True, True], [300, False, False]]],\n   [False, True, False]],\n  ['regression: tie down one button',\n   [200,\n    [[0, True, False],\n     [100, True, True],\n     [200, True, False],\n     [300, True, True],\n     [400, True, False],\n     [450, True, True]]],\n   [False, True, False, False, False, False]],\n  ['regression: simultaneous press then release one',\n   [200, [[0, True, True], [100, True, False], [200, True, True]]],\n   [True, False, False]],\n  ['control: scenario 1',\n   [500,\n    [[0, True, False],\n     [150, True, False],\n     [250, True, False],\n     [300, False, False],\n     [350, False, True],\n     [650, False, True],\n     [850, False, False],\n     [1150, False, False],\n     [1350, True, False],\n     [1650, True, False],\n     [1800, True, False],\n     [1850, True, False],\n     [1900, False, True]]],\n   [False, False, False, False, False, False, False, False, False, False, False, False, False]]]]\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":"A deterministic bounded teaching model of one PLC instruction or rung pattern evaluated scan by scan. The stated contract is a stipulated toy convention, not a claim of conformance to any vendor controller or IEC 61131-3 runtime. 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-plc-ladder-logic-scan-cycles-two-hand-control-rearm-both-released","generated_at":"2026-09-29T14:51:44.297614+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Ladder programs are executed as repeated scans; each defect here changes what a rung, timer, counter or data-table instruction reports on a particular scan, which is how commissioning and field faults are actually observed.","repair":"Re-arm only when both buttons are released.","root_cause":"Releasing a single button re-arms the start permission.","sha256":"9bd2c76e87f0ebba262f941596452097538baf5e18d8b5ccece64c7e4c5a78d0","title":"Two-hand control re-arms when only one button is released · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":41.781,"exit_code":1,"observations":[{"actual":[true,false,true],"check":"regression: simultaneous press then release one","expected":[true,false,false],"passed":false},{"actual":[false,true,false,true,false,true],"check":"regression: tie down one button","expected":[false,true,false,false,false,false],"passed":false},{"actual":[false,true,true,false,false,true],"check":"control: normal cycle","expected":[false,true,true,false,false,true],"passed":true},{"actual":[false,false,false,false,true],"check":"control: late second hand","expected":[false,false,false,false,true],"passed":true},{"actual":[false,true,false],"check":"control: exact window","expected":[false,true,false],"passed":true},{"actual":[false,true,true,true,true,true,false,false,true,true],"check":"control: scenario 1","expected":[false,true,true,true,true,true,false,false,true,true],"passed":true},{"actual":[true,false,true,false,false,false,false,false],"check":"regression: scenario 2","expected":[true,false,false,false,false,false,false,false],"passed":false},{"actual":[false,true,true,false,true,true,false,false,false,false,false,true,true],"check":"control: scenario 3","expected":[false,true,true,false,true,true,false,false,false,false,false,true,true],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: simultaneous press then release one\", \"actual\": [true, false, true], \"expected\": [true, false, false], \"passed\": false}, {\"check\": \"regression: tie down one button\", \"actual\": [false, true, false, true, false, true], \"expected\": [false, true, false, false, false, false], \"passed\": false}, {\"check\": \"control: normal cycle\", \"actual\": [false, true, true, false, false, true], \"expected\": [false, true, true, false, false, true], \"passed\": true}, {\"check\": \"control: late second hand\", \"actual\": [false, false, false, false, true], \"expected\": [false, false, false, false, true], \"passed\": true}, {\"check\": \"control: exact window\", \"actual\": [false, true, false], \"expected\": [false, true, false], \"passed\": true}, {\"check\": \"control: scenario 1\", \"actual\": [false, true, true, true, true, true, false, false, true, true], \"expected\": [false, true, true, true, true, true, false, false, true, true], \"passed\": true}, {\"check\": \"regression: scenario 2\", \"actual\": [true, false, true, false, false, false, false, false], \"expected\": [true, false, false, false, false, false, false, false], \"passed\": false}, {\"check\": \"control: scenario 3\", \"actual\": [false, true, true, false, true, true, false, false, false, false, false, true, true], \"expected\": [false, true, true, false, true, true, false, false, false, false, false, true, true], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.928,"exit_code":1,"observations":[{"actual":[true,false,true],"check":"regression: simultaneous press then release one","expected":[true,false,false],"passed":false},{"actual":[false,true,false,false,false,false],"check":"regression: tie down one button","expected":[false,true,false,false,false,false],"passed":true},{"actual":[false,true,true,false,false,true],"check":"control: normal cycle","expected":[false,true,true,false,false,true],"passed":true},{"actual":[false,false,false,false,true],"check":"control: late second hand","expected":[false,false,false,false,true],"passed":true},{"actual":[false,true,false],"check":"control: exact window","expected":[false,true,false],"passed":true},{"actual":[false,true,true,true,true,true,false,false,true,true],"check":"control: scenario 1","expected":[false,true,true,true,true,true,false,false,true,true],"passed":true},{"actual":[true,false,true,false,false,false,false,false],"check":"regression: scenario 2","expected":[true,false,false,false,false,false,false,false],"passed":false},{"actual":[false,true,true,false,true,true,false,false,false,false,false,true,true],"check":"control: scenario 3","expected":[false,true,true,false,true,true,false,false,false,false,false,true,true],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: simultaneous press then release one\", \"actual\": [true, false, true], \"expected\": [true, false, false], \"passed\": false}, {\"check\": \"regression: tie down one button\", \"actual\": [false, true, false, false, false, false], \"expected\": [false, true, false, false, false, false], \"passed\": true}, {\"check\": \"control: normal cycle\", \"actual\": [false, true, true, false, false, true], \"expected\": [false, true, true, false, false, true], \"passed\": true}, {\"check\": \"control: late second hand\", \"actual\": [false, false, false, false, true], \"expected\": [false, false, false, false, true], \"passed\": true}, {\"check\": \"control: exact window\", \"actual\": [false, true, false], \"expected\": [false, true, false], \"passed\": true}, {\"check\": \"control: scenario 1\", \"actual\": [false, true, true, true, true, true, false, false, true, true], \"expected\": [false, true, true, true, true, true, false, false, true, true], \"passed\": true}, {\"check\": \"regression: scenario 2\", \"actual\": [true, false, true, false, false, false, false, false], \"expected\": [true, false, false, false, false, false, false, false], \"passed\": false}, {\"check\": \"control: scenario 3\", \"actual\": [false, true, true, false, true, true, false, false, false, false, false, true, true], \"expected\": [false, true, true, false, true, true, false, false, false, false, false, true, true], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":41.706,"exit_code":0,"observations":[{"actual":[true,false,false],"check":"regression: simultaneous press then release one","expected":[true,false,false],"passed":true},{"actual":[false,true,false,false,false,false],"check":"regression: tie down one button","expected":[false,true,false,false,false,false],"passed":true},{"actual":[false,true,true,false,false,true],"check":"control: normal cycle","expected":[false,true,true,false,false,true],"passed":true},{"actual":[false,false,false,false,true],"check":"control: late second hand","expected":[false,false,false,false,true],"passed":true},{"actual":[false,true,false],"check":"control: exact window","expected":[false,true,false],"passed":true},{"actual":[false,true,true,true,true,true,false,false,true,true],"check":"control: scenario 1","expected":[false,true,true,true,true,true,false,false,true,true],"passed":true},{"actual":[true,false,false,false,false,false,false,false],"check":"regression: scenario 2","expected":[true,false,false,false,false,false,false,false],"passed":true},{"actual":[false,true,true,false,true,true,false,false,false,false,false,true,true],"check":"control: scenario 3","expected":[false,true,true,false,true,true,false,false,false,false,false,true,true],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: simultaneous press then release one\", \"actual\": [true, false, false], \"expected\": [true, false, false], \"passed\": true}, {\"check\": \"regression: tie down one button\", \"actual\": [false, true, false, false, false, false], \"expected\": [false, true, false, false, false, false], \"passed\": true}, {\"check\": \"control: normal cycle\", \"actual\": [false, true, true, false, false, true], \"expected\": [false, true, true, false, false, true], \"passed\": true}, {\"check\": \"control: late second hand\", \"actual\": [false, false, false, false, true], \"expected\": [false, false, false, false, true], \"passed\": true}, {\"check\": \"control: exact window\", \"actual\": [false, true, false], \"expected\": [false, true, false], \"passed\": true}, {\"check\": \"control: scenario 1\", \"actual\": [false, true, true, true, true, true, false, false, true, true], \"expected\": [false, true, true, true, true, true, false, false, true, true], \"passed\": true}, {\"check\": \"regression: scenario 2\", \"actual\": [true, false, false, false, false, false, false, false], \"expected\": [true, false, false, false, false, false, false, false], \"passed\": true}, {\"check\": \"control: scenario 3\", \"actual\": [false, true, true, false, true, true, false, false, false, false, false, true, true], \"expected\": [false, true, true, false, true, true, false, false, false, false, false, true, true], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}