FAILURE MAP
← Case archive

FA-12036 / Optimization solver contracts / Open access

Iteration exhaustion is reported as convergence · case 01

Iteration exhaustion is reported as convergence.

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

ROOT CAUSE

A small latest objective change is enough even if residual is large.

VERIFIED REPAIR

Converged requires residual tolerance; otherwise distinguish exhausted budget from ongoing iteration.

Unsuccessful approach: Always labeling a large residual as exhausted ignores remaining iterations.

Case contract

Nonnegative residual, tolerance, iteration and budget: converged if residual<=tol; otherwise exhausted if iteration>=budget; else continue. Objective delta alone never certifies convergence.

Why this case matters

This deterministic solver-step model isolates an algorithmic invariant used by iterative optimization implementations.

1 / The failure

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

N = 1
observations = []
def solve(residual, tol, delta, iteration, budget):
    return "converged" if abs(delta)<=tol else ("exhausted" if iteration>=budget else "continue")
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('stagnation with budget', solve(N,0,0,1,10), 'continue')
check('stagnation exhausted', solve(N,0,0,10,10), 'exhausted')
check('residual wins', solve(0,0,N,1,10), 'converged')
check('tolerance boundary', solve(N,N,10*N,10,10), 'converged')
check('unfinished', solve(N,0,N,1,10), 'continue')
check('zero budget', solve(N,0,N,0,0), 'exhausted')
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
stagnation with budgetconvergedcontinueFailed
stagnation exhaustedconvergedexhaustedFailed
residual winscontinueconvergedFailed
tolerance boundaryexhaustedconvergedFailed
unfinishedcontinuecontinuePassed
zero budgetexhaustedexhaustedPassed

SHA-256 / c167beb04ec4d2daecd09260a5353a91ea18841da2d4fed99763d925f69891fb

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(residual, tol, delta, iteration, budget):
    return "converged" if residual<=tol else "exhausted"
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('stagnation with budget', solve(N,0,0,1,10), 'continue')
check('stagnation exhausted', solve(N,0,0,10,10), 'exhausted')
check('residual wins', solve(0,0,N,1,10), 'converged')
check('tolerance boundary', solve(N,N,10*N,10,10), 'converged')
check('unfinished', solve(N,0,N,1,10), 'continue')
check('zero budget', solve(N,0,N,0,0), 'exhausted')
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
stagnation with budgetexhaustedcontinueFailed
stagnation exhaustedexhaustedexhaustedPassed
residual winsconvergedconvergedPassed
tolerance boundaryconvergedconvergedPassed
unfinishedexhaustedcontinueFailed
zero budgetexhaustedexhaustedPassed

SHA-256 / 63c6c65c29f072626dc4b82f800f619517aad16d625e21e80e3813632dadf588

3 / The verified repair

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

N = 1
observations = []
def solve(residual, tol, delta, iteration, budget):
    return "converged" if residual<=tol else ("exhausted" if iteration>=budget else "continue")
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('stagnation with budget', solve(N,0,0,1,10), 'continue')
check('stagnation exhausted', solve(N,0,0,10,10), 'exhausted')
check('residual wins', solve(0,0,N,1,10), 'converged')
check('tolerance boundary', solve(N,N,10*N,10,10), 'converged')
check('unfinished', solve(N,0,N,1,10), 'continue')
check('zero budget', solve(N,0,N,0,0), 'exhausted')
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
stagnation with budgetcontinuecontinuePassed
stagnation exhaustedexhaustedexhaustedPassed
residual winsconvergedconvergedPassed
tolerance boundaryconvergedconvergedPassed
unfinishedcontinuecontinuePassed
zero budgetexhaustedexhaustedPassed

SHA-256 / 7afc6dcbb458ded261a945a618d89829ee1ad788a92abcf3f3f52569c6af24a9

Verification & scope

Controlled finite inputs and explicit one-step contracts; this is not a production solver or a numerical stability benchmark. 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:38:53.249119+00:00.

Case digest / 38350c114403b4fc29ead0b3afe51930204c12ce0f8c845d5f7d3ca64be8c894