FAILURE MAP
← Case archive

FA-11991 / Optimization solver contracts / Open access

Line search accepts decrease without sufficient decrease · case 01

Line search accepts decrease without sufficient decrease.

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

ROOT CAUSE

Any reduction is accepted without the directional derivative term.

VERIFIED REPAIR

Require a descent direction and the Armijo inequality.

Unsuccessful approach: Adding the inequality alone accepts an uphill direction when its allowance is positive.

Case contract

For positive alpha and 0<c<1, accept exactly when slope<0 and trial<=old+c*alpha*slope.

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(old, trial, slope, alpha, c):
    return trial < old
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('weak decrease', solve(10*N, 9*N, -10*N, 1, 0.5), False)
check('exact sufficient decrease', solve(10*N, 5*N, -10*N, 1, 0.5), True)
check('strong decrease', solve(10, 1, -2, 1, 0.5), True)
check('uphill direction', solve(10, 11, 4, 1, 0.5), False)
check('zero direction', solve(10, 10, 0, 1, 0.5), False)
check('short step', solve(10, 9, -4, 0.5, 0.5), True)
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
weak decreaseTrueFalseFailed
exact sufficient decreaseTrueTruePassed
strong decreaseTrueTruePassed
uphill directionFalseFalsePassed
zero directionFalseFalsePassed
short stepTrueTruePassed

SHA-256 / 8536e42a97e08c3cc3e571901fd4e1cc2d2d1d3082f2b272ab23e5509becc14b

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(old, trial, slope, alpha, c):
    return trial <= old+c*alpha*slope
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('weak decrease', solve(10*N, 9*N, -10*N, 1, 0.5), False)
check('exact sufficient decrease', solve(10*N, 5*N, -10*N, 1, 0.5), True)
check('strong decrease', solve(10, 1, -2, 1, 0.5), True)
check('uphill direction', solve(10, 11, 4, 1, 0.5), False)
check('zero direction', solve(10, 10, 0, 1, 0.5), False)
check('short step', solve(10, 9, -4, 0.5, 0.5), True)
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
weak decreaseFalseFalsePassed
exact sufficient decreaseTrueTruePassed
strong decreaseTrueTruePassed
uphill directionTrueFalseFailed
zero directionTrueFalseFailed
short stepTrueTruePassed

SHA-256 / 6d82bd393a30982f6a1ffa0a4440db0d4b3fbb9d3646312ca6c65235325e025a

3 / The verified repair

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

N = 1
observations = []
def solve(old, trial, slope, alpha, c):
    return slope < 0 and trial <= old+c*alpha*slope
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('weak decrease', solve(10*N, 9*N, -10*N, 1, 0.5), False)
check('exact sufficient decrease', solve(10*N, 5*N, -10*N, 1, 0.5), True)
check('strong decrease', solve(10, 1, -2, 1, 0.5), True)
check('uphill direction', solve(10, 11, 4, 1, 0.5), False)
check('zero direction', solve(10, 10, 0, 1, 0.5), False)
check('short step', solve(10, 9, -4, 0.5, 0.5), True)
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
weak decreaseFalseFalsePassed
exact sufficient decreaseTrueTruePassed
strong decreaseTrueTruePassed
uphill directionFalseFalsePassed
zero directionFalseFalsePassed
short stepTrueTruePassed

SHA-256 / 8f249223d9873973dd2d53162f5a2baa6ea9b2750fc4825d42d54a3360061aa4

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:52.864476+00:00.

Case digest / d5d63441e1ee3d95e0a3f6cc8cb978da4e9fce14639574ed269bff2bb2f2baf1