FAILURE MAP
← Case archive

FA-95206 / Warehouse slotting and bin packing / Open access

Temperature putaway: matching range limits rejected · case 01

A zone whose limits exactly equal the product limits is refused.

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

ROOT CAUSE

Both containment bounds are treated as exclusive.

VERIFIED REPAIR

Allow zone limits equal to the product limits on both ends.

Unsuccessful approach: Relaxing only the lower bound still refuses zones that share the upper limit.

Case contract

zones [[zone, min_c, max_c, free_positions]], product [min_c, max_c]. A zone is eligible when its whole range lies inside the product range (inclusive) and it has free positions. Prefer the narrowest zone range, then most free positions, then zone id. None -> "REJECT".

Why this case matters

Cold chain putaway must keep product within its storage temperature range.

1 / The failure

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

N = 1
observations = []
def solve(zones, product):
    pmin, pmax = product
    best = None
    for zid, zmin, zmax, free in zones:
        if zmin <= pmin or zmax >= pmax:
            continue
        if free <= 0:
            continue
        key = (zmax - zmin, -free, zid)
        if best is None or key < best:
            best = key
    return best[2] if best else 'REJECT'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['full zone', [[['A', 2, 8, 0], ['B', 0, 8, 1]], [0, 8]], 'B'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['generated mix 7', [[['Z0', 0, 4, 1], ['Z1', 10, 30, 12], ['Z2', -25, -18, 5], ['Z3', 15, 25, 5], ['Z4', 15, 25, 1]], [0, 4]], 'Z0'], ['generated mix 15', [[['Z0', -25, -18, 1]], [15, 25]], 'REJECT'], ['generated mix 23', [[['Z0', 0, 4, 1], ['Z1', -25, -18, 12]], [-5, 10]], 'Z0']], [['generated mix 26', [[['Z0', -30, -15, 0], ['Z1', 10, 30, 1], ['Z2', 15, 25, 5], ['Z3', 2, 8, 1]], [15, 25]], 'Z2'], ['full zone', [[['A', 2, 8, 0], ['B', 0, 8, 1]], [0, 8]], 'B'], ['frozen', [[['F', -25, -18, 2], ['C', 0, 4, 9]], [-30, -15]], 'F'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['generated mix 9', [[['Z0', 15, 25, 1], ['Z1', 10, 30, 0], ['Z2', 10, 30, 5]], [15, 25]], 'Z0'], ['generated mix 17', [[['Z0', 15, 25, 1], ['Z1', 15, 25, 0], ['Z2', 15, 25, 0]], [2, 8]], 'REJECT'], ['generated mix 25', [[['Z0', 0, 4, 0]], [10, 30]], 'REJECT'], ['generated mix 34', [[['Z0', 0, 8, 0], ['Z1', 0, 4, 5], ['Z2', 2, 8, 5], ['Z3', 0, 4, 1], ['Z4', 0, 8, 1]], [-30, -18]], 'REJECT']], [['generated mix 53', [[['Z0', 15, 25, 1], ['Z1', -30, -15, 12], ['Z2', 10, 30, 12], ['Z3', -30, -15, 1], ['Z4', 0, 4, 0]], [15, 25]], 'Z0'], ['generated mix 55', [[['Z0', -25, -18, 1], ['Z1', 0, 4, 1], ['Z2', 0, 4, 0], ['Z3', 10, 30, 12]], [0, 4]], 'Z1'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['generated mix 20', [[['Z0', 15, 25, 5], ['Z1', 10, 30, 1], ['Z2', 0, 4, 12], ['Z3', 15, 25, 0], ['Z4', 0, 4, 12]], [-30, -18]], 'REJECT'], ['generated mix 28', [[['Z0', 2, 8, 0]], [15, 25]], 'REJECT'], ['generated mix 36', [[['Z0', -30, -15, 0], ['Z1', 0, 4, 1], ['Z2', -25, -18, 12], ['Z3', 15, 25, 0]], [-5, 10]], 'Z1']], [['generated mix 76', [[['Z0', 15, 25, 12], ['Z1', -25, -18, 12]], [-25, -15]], 'Z1'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['frozen', [[['F', -25, -18, 2], ['C', 0, 4, 9]], [-30, -15]], 'F'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['generated mix 33', [[['Z0', 0, 4, 1], ['Z1', 2, 8, 1], ['Z2', 2, 8, 0]], [0, 8]], 'Z0'], ['generated mix 41', [[['Z0', 0, 8, 12], ['Z1', 0, 4, 0], ['Z2', 0, 8, 5], ['Z3', -30, -15, 1], ['Z4', 10, 30, 5]], [10, 30]], 'Z4']], [['generated mix 22', [[['Z0', -25, -18, 5], ['Z1', 2, 8, 0], ['Z2', 0, 4, 12], ['Z3', 0, 8, 12]], [-25, -15]], 'Z0'], ['generated mix 9', [[['Z0', 15, 25, 1], ['Z1', 10, 30, 0], ['Z2', 10, 30, 5]], [15, 25]], 'Z0'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['generated mix 44', [[['Z0', 0, 8, 12], ['Z1', 0, 4, 12]], [-25, -15]], 'REJECT'], ['generated mix 52', [[['Z0', 10, 30, 0], ['Z1', 0, 4, 0]], [-25, -15]], 'REJECT'], ['generated mix 60', [[['Z0', 15, 25, 0], ['Z1', -25, -18, 12]], [2, 8]], 'REJECT']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
exact matchREJECTCFailed
full zoneREJECTBFailed
zone too wideREJECTREJECTPassed
tie most freeBBPassed
narrowestBBPassed
generated mix 7REJECTZ0Failed
generated mix 15REJECTREJECTPassed
generated mix 23Z0Z0Passed

SHA-256 / f6aced75862e205ef52a5c0619888b45efa4ff1f619713847e59897136e3cd41

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(zones, product):
    pmin, pmax = product
    best = None
    for zid, zmin, zmax, free in zones:
        if zmin < pmin or zmax >= pmax:
            continue
        if free <= 0:
            continue
        key = (zmax - zmin, -free, zid)
        if best is None or key < best:
            best = key
    return best[2] if best else 'REJECT'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['full zone', [[['A', 2, 8, 0], ['B', 0, 8, 1]], [0, 8]], 'B'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['generated mix 7', [[['Z0', 0, 4, 1], ['Z1', 10, 30, 12], ['Z2', -25, -18, 5], ['Z3', 15, 25, 5], ['Z4', 15, 25, 1]], [0, 4]], 'Z0'], ['generated mix 15', [[['Z0', -25, -18, 1]], [15, 25]], 'REJECT'], ['generated mix 23', [[['Z0', 0, 4, 1], ['Z1', -25, -18, 12]], [-5, 10]], 'Z0']], [['generated mix 26', [[['Z0', -30, -15, 0], ['Z1', 10, 30, 1], ['Z2', 15, 25, 5], ['Z3', 2, 8, 1]], [15, 25]], 'Z2'], ['full zone', [[['A', 2, 8, 0], ['B', 0, 8, 1]], [0, 8]], 'B'], ['frozen', [[['F', -25, -18, 2], ['C', 0, 4, 9]], [-30, -15]], 'F'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['generated mix 9', [[['Z0', 15, 25, 1], ['Z1', 10, 30, 0], ['Z2', 10, 30, 5]], [15, 25]], 'Z0'], ['generated mix 17', [[['Z0', 15, 25, 1], ['Z1', 15, 25, 0], ['Z2', 15, 25, 0]], [2, 8]], 'REJECT'], ['generated mix 25', [[['Z0', 0, 4, 0]], [10, 30]], 'REJECT'], ['generated mix 34', [[['Z0', 0, 8, 0], ['Z1', 0, 4, 5], ['Z2', 2, 8, 5], ['Z3', 0, 4, 1], ['Z4', 0, 8, 1]], [-30, -18]], 'REJECT']], [['generated mix 53', [[['Z0', 15, 25, 1], ['Z1', -30, -15, 12], ['Z2', 10, 30, 12], ['Z3', -30, -15, 1], ['Z4', 0, 4, 0]], [15, 25]], 'Z0'], ['generated mix 55', [[['Z0', -25, -18, 1], ['Z1', 0, 4, 1], ['Z2', 0, 4, 0], ['Z3', 10, 30, 12]], [0, 4]], 'Z1'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['generated mix 20', [[['Z0', 15, 25, 5], ['Z1', 10, 30, 1], ['Z2', 0, 4, 12], ['Z3', 15, 25, 0], ['Z4', 0, 4, 12]], [-30, -18]], 'REJECT'], ['generated mix 28', [[['Z0', 2, 8, 0]], [15, 25]], 'REJECT'], ['generated mix 36', [[['Z0', -30, -15, 0], ['Z1', 0, 4, 1], ['Z2', -25, -18, 12], ['Z3', 15, 25, 0]], [-5, 10]], 'Z1']], [['generated mix 76', [[['Z0', 15, 25, 12], ['Z1', -25, -18, 12]], [-25, -15]], 'Z1'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['frozen', [[['F', -25, -18, 2], ['C', 0, 4, 9]], [-30, -15]], 'F'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['generated mix 33', [[['Z0', 0, 4, 1], ['Z1', 2, 8, 1], ['Z2', 2, 8, 0]], [0, 8]], 'Z0'], ['generated mix 41', [[['Z0', 0, 8, 12], ['Z1', 0, 4, 0], ['Z2', 0, 8, 5], ['Z3', -30, -15, 1], ['Z4', 10, 30, 5]], [10, 30]], 'Z4']], [['generated mix 22', [[['Z0', -25, -18, 5], ['Z1', 2, 8, 0], ['Z2', 0, 4, 12], ['Z3', 0, 8, 12]], [-25, -15]], 'Z0'], ['generated mix 9', [[['Z0', 15, 25, 1], ['Z1', 10, 30, 0], ['Z2', 10, 30, 5]], [15, 25]], 'Z0'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['generated mix 44', [[['Z0', 0, 8, 12], ['Z1', 0, 4, 12]], [-25, -15]], 'REJECT'], ['generated mix 52', [[['Z0', 10, 30, 0], ['Z1', 0, 4, 0]], [-25, -15]], 'REJECT'], ['generated mix 60', [[['Z0', 15, 25, 0], ['Z1', -25, -18, 12]], [2, 8]], 'REJECT']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
exact matchREJECTCFailed
full zoneREJECTBFailed
zone too wideREJECTREJECTPassed
tie most freeBBPassed
narrowestBBPassed
generated mix 7REJECTZ0Failed
generated mix 15REJECTREJECTPassed
generated mix 23Z0Z0Passed

SHA-256 / 38c3b4a08ff610aaab376b5e301122878eaaf304720ae8b50d206372b0c91f7a

3 / The verified repair

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

N = 1
observations = []
def solve(zones, product):
    pmin, pmax = product
    best = None
    for zid, zmin, zmax, free in zones:
        if zmin < pmin or zmax > pmax:
            continue
        if free <= 0:
            continue
        key = (zmax - zmin, -free, zid)
        if best is None or key < best:
            best = key
    return best[2] if best else 'REJECT'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['full zone', [[['A', 2, 8, 0], ['B', 0, 8, 1]], [0, 8]], 'B'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['generated mix 7', [[['Z0', 0, 4, 1], ['Z1', 10, 30, 12], ['Z2', -25, -18, 5], ['Z3', 15, 25, 5], ['Z4', 15, 25, 1]], [0, 4]], 'Z0'], ['generated mix 15', [[['Z0', -25, -18, 1]], [15, 25]], 'REJECT'], ['generated mix 23', [[['Z0', 0, 4, 1], ['Z1', -25, -18, 12]], [-5, 10]], 'Z0']], [['generated mix 26', [[['Z0', -30, -15, 0], ['Z1', 10, 30, 1], ['Z2', 15, 25, 5], ['Z3', 2, 8, 1]], [15, 25]], 'Z2'], ['full zone', [[['A', 2, 8, 0], ['B', 0, 8, 1]], [0, 8]], 'B'], ['frozen', [[['F', -25, -18, 2], ['C', 0, 4, 9]], [-30, -15]], 'F'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['generated mix 9', [[['Z0', 15, 25, 1], ['Z1', 10, 30, 0], ['Z2', 10, 30, 5]], [15, 25]], 'Z0'], ['generated mix 17', [[['Z0', 15, 25, 1], ['Z1', 15, 25, 0], ['Z2', 15, 25, 0]], [2, 8]], 'REJECT'], ['generated mix 25', [[['Z0', 0, 4, 0]], [10, 30]], 'REJECT'], ['generated mix 34', [[['Z0', 0, 8, 0], ['Z1', 0, 4, 5], ['Z2', 2, 8, 5], ['Z3', 0, 4, 1], ['Z4', 0, 8, 1]], [-30, -18]], 'REJECT']], [['generated mix 53', [[['Z0', 15, 25, 1], ['Z1', -30, -15, 12], ['Z2', 10, 30, 12], ['Z3', -30, -15, 1], ['Z4', 0, 4, 0]], [15, 25]], 'Z0'], ['generated mix 55', [[['Z0', -25, -18, 1], ['Z1', 0, 4, 1], ['Z2', 0, 4, 0], ['Z3', 10, 30, 12]], [0, 4]], 'Z1'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['generated mix 20', [[['Z0', 15, 25, 5], ['Z1', 10, 30, 1], ['Z2', 0, 4, 12], ['Z3', 15, 25, 0], ['Z4', 0, 4, 12]], [-30, -18]], 'REJECT'], ['generated mix 28', [[['Z0', 2, 8, 0]], [15, 25]], 'REJECT'], ['generated mix 36', [[['Z0', -30, -15, 0], ['Z1', 0, 4, 1], ['Z2', -25, -18, 12], ['Z3', 15, 25, 0]], [-5, 10]], 'Z1']], [['generated mix 76', [[['Z0', 15, 25, 12], ['Z1', -25, -18, 12]], [-25, -15]], 'Z1'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['frozen', [[['F', -25, -18, 2], ['C', 0, 4, 9]], [-30, -15]], 'F'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['zone too wide', [[['C', 0, 8, 3]], [2, 8]], 'REJECT'], ['generated mix 33', [[['Z0', 0, 4, 1], ['Z1', 2, 8, 1], ['Z2', 2, 8, 0]], [0, 8]], 'Z0'], ['generated mix 41', [[['Z0', 0, 8, 12], ['Z1', 0, 4, 0], ['Z2', 0, 8, 5], ['Z3', -30, -15, 1], ['Z4', 10, 30, 5]], [10, 30]], 'Z4']], [['generated mix 22', [[['Z0', -25, -18, 5], ['Z1', 2, 8, 0], ['Z2', 0, 4, 12], ['Z3', 0, 8, 12]], [-25, -15]], 'Z0'], ['generated mix 9', [[['Z0', 15, 25, 1], ['Z1', 10, 30, 0], ['Z2', 10, 30, 5]], [15, 25]], 'Z0'], ['exact match', [[['C', 2, 8, 3]], [2, 8]], 'C'], ['narrowest', [[['A', 0, 8, 5], ['B', 2, 6, 1]], [0, 8]], 'B'], ['tie most free', [[['A', 2, 8, 1], ['B', 2, 8, 4]], [0, 10]], 'B'], ['generated mix 44', [[['Z0', 0, 8, 12], ['Z1', 0, 4, 12]], [-25, -15]], 'REJECT'], ['generated mix 52', [[['Z0', 10, 30, 0], ['Z1', 0, 4, 0]], [-25, -15]], 'REJECT'], ['generated mix 60', [[['Z0', 15, 25, 0], ['Z1', -25, -18, 12]], [2, 8]], 'REJECT']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
exact matchCCPassed
full zoneBBPassed
zone too wideREJECTREJECTPassed
tie most freeBBPassed
narrowestBBPassed
generated mix 7Z0Z0Passed
generated mix 15REJECTREJECTPassed
generated mix 23Z0Z0Passed

SHA-256 / 6a0b525c7210a3ffdc934c85725ec77b9431d0cdaf0d4dfb40e25244be7cce5c

Verification & scope

Stipulated integer temperature ranges; no excursion or dwell time logic. 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:52:11.555929+00:00.

Case digest / 8d51f3fee686e027598daf8f667e0525945a1483f45df5e29bdad354bab1cb7f