FA-79866 / Typography line breaking / Open access
Glue-set badness rating: rigid line with slack · case 01
A line with slack but no stretchable glue is accepted as perfect.
ROOT CAUSE
The zero-stretch guard returns an ok decent rating instead of an infinitely bad underfull one.
VERIFIED REPAIR
Treat positive shortfall with zero stretch as underfull with badness 10000.
Unsuccessful approach: Returning 10000 but classifying it loose still misreports the fitness class.
Case contract
Input [natural, stretch, shrink, width, tolerance] (ints). shortfall=width-natural. Positive shortfall with zero stretch is underfull 10000 very_loose; shrinking past total shrink is overfull 1000000 tight. r=shortfall/stretch (or /shrink when negative); badness=min(10000, floor(100*|r|^3+1/2)); fitness tight r<-1/2, decent r<=1/2, loose r<=1, else very_loose; status ok iff badness<=tolerance. Return [status, badness, fitness].
Why this case matters
Line breaking decides where paragraphs wrap on screen and in print; a wrong decision point shifts every following line.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
natural, stretch, shrink, width, tolerance = x
shortfall = width - natural
if shortfall > 0:
if stretch == 0:
return ['ok', 0, 'decent']
r = Fraction(shortfall, stretch)
elif shortfall < 0:
if -shortfall > shrink:
return ['overfull', 1000000, 'tight']
r = Fraction(shortfall, shrink)
else:
r = Fraction(0)
badness = min(10000, math.floor(100 * abs(r) ** 3 + Fraction(1, 2)))
if r < Fraction(-1, 2):
fitness = 'tight'
elif r <= Fraction(1, 2):
fitness = 'decent'
elif r <= 1:
fitness = 'loose'
else:
fitness = 'very_loose'
status = 'ok' if badness <= tolerance else 'underfull'
return [status, badness, fitness]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [62, 0, 4, 76, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [91, 0, 10, 106, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [80, 0, 11, 90, 100], ['underfull', 10000, 'very_loose']), ('half stretch ratio rounds 12.5 up', [100, 10, 5, 105, 200], ['ok', 13, 'decent']), ('exact natural width', [100, 10, 5, 100, 200], ['ok', 0, 'decent']), ('control layout', [69, 10, 7, 69, 100], ['ok', 0, 'decent']), ('control layout', [74, 6, 6, 67, 100], ['overfull', 1000000, 'tight'])], [('regression: rigid line with slack', [94, 0, 10, 118, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [72, 0, 3, 87, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [114, 0, 6, 129, 200], ['underfull', 10000, 'very_loose']), ('exact natural width', [100, 10, 5, 100, 200], ['ok', 0, 'decent']), ('very loose over tolerance', [100, 4, 0, 110, 200], ['underfull', 1563, 'very_loose']), ('control layout', [69, 2, 11, 55, 150], ['overfull', 1000000, 'tight']), ('control layout', [62, 4, 4, 58, 200], ['ok', 100, 'tight'])], [('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [90, 0, 6, 102, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [62, 0, 4, 76, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [79, 0, 11, 96, 1000], ['underfull', 10000, 'very_loose']), ('full shrink is still acceptable', [100, 10, 5, 95, 200], ['ok', 100, 'tight']), ('half stretch ratio rounds 12.5 up', [100, 10, 5, 105, 200], ['ok', 13, 'decent']), ('control layout', [118, 6, 5, 121, 100], ['ok', 13, 'decent']), ('control layout', [105, 4, 1, 111, 100], ['underfull', 338, 'very_loose'])], [('regression: rigid line with slack', [114, 0, 6, 129, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [83, 0, 3, 97, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [116, 0, 11, 126, 100], ['underfull', 10000, 'very_loose']), ('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('one unit past total shrink', [100, 10, 5, 94, 200], ['overfull', 1000000, 'tight']), ('control layout', [85, 4, 0, 98, 150], ['underfull', 3433, 'very_loose']), ('control layout', [62, 6, 1, 51, 100], ['overfull', 1000000, 'tight'])], [('regression: rigid line with slack', [90, 0, 6, 102, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [91, 0, 10, 106, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [75, 0, 11, 88, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('very loose over tolerance', [100, 4, 0, 110, 200], ['underfull', 1563, 'very_loose']), ('negative half ratio is decent', [100, 10, 6, 97, 200], ['ok', 13, 'decent']), ('control layout', [79, 6, 10, 67, 1000], ['overfull', 1000000, 'tight']), ('control layout', [74, 16, 0, 61, 200], ['overfull', 1000000, 'tight'])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| rigid line with slack | ['ok', 0, 'decent'] | ['underfull', 10000, 'very_loose'] | Failed |
| regression: rigid line with slack | ['ok', 0, 'decent'] | ['underfull', 10000, 'very_loose'] | Failed |
| regression: rigid line with slack | ['ok', 0, 'decent'] | ['underfull', 10000, 'very_loose'] | Failed |
| regression: rigid line with slack | ['ok', 0, 'decent'] | ['underfull', 10000, 'very_loose'] | Failed |
| half stretch ratio rounds 12.5 up | ['ok', 13, 'decent'] | ['ok', 13, 'decent'] | Passed |
| exact natural width | ['ok', 0, 'decent'] | ['ok', 0, 'decent'] | Passed |
| control layout | ['ok', 0, 'decent'] | ['ok', 0, 'decent'] | Passed |
| control layout | ['overfull', 1000000, 'tight'] | ['overfull', 1000000, 'tight'] | Passed |
SHA-256 / dd5753763dae7c9e1681a964f4b76c084a6cd33f38d30891cbcb7b9f0065ce39
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
natural, stretch, shrink, width, tolerance = x
shortfall = width - natural
if shortfall > 0:
if stretch == 0:
return ['underfull', 10000, 'loose']
r = Fraction(shortfall, stretch)
elif shortfall < 0:
if -shortfall > shrink:
return ['overfull', 1000000, 'tight']
r = Fraction(shortfall, shrink)
else:
r = Fraction(0)
badness = min(10000, math.floor(100 * abs(r) ** 3 + Fraction(1, 2)))
if r < Fraction(-1, 2):
fitness = 'tight'
elif r <= Fraction(1, 2):
fitness = 'decent'
elif r <= 1:
fitness = 'loose'
else:
fitness = 'very_loose'
status = 'ok' if badness <= tolerance else 'underfull'
return [status, badness, fitness]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [62, 0, 4, 76, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [91, 0, 10, 106, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [80, 0, 11, 90, 100], ['underfull', 10000, 'very_loose']), ('half stretch ratio rounds 12.5 up', [100, 10, 5, 105, 200], ['ok', 13, 'decent']), ('exact natural width', [100, 10, 5, 100, 200], ['ok', 0, 'decent']), ('control layout', [69, 10, 7, 69, 100], ['ok', 0, 'decent']), ('control layout', [74, 6, 6, 67, 100], ['overfull', 1000000, 'tight'])], [('regression: rigid line with slack', [94, 0, 10, 118, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [72, 0, 3, 87, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [114, 0, 6, 129, 200], ['underfull', 10000, 'very_loose']), ('exact natural width', [100, 10, 5, 100, 200], ['ok', 0, 'decent']), ('very loose over tolerance', [100, 4, 0, 110, 200], ['underfull', 1563, 'very_loose']), ('control layout', [69, 2, 11, 55, 150], ['overfull', 1000000, 'tight']), ('control layout', [62, 4, 4, 58, 200], ['ok', 100, 'tight'])], [('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [90, 0, 6, 102, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [62, 0, 4, 76, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [79, 0, 11, 96, 1000], ['underfull', 10000, 'very_loose']), ('full shrink is still acceptable', [100, 10, 5, 95, 200], ['ok', 100, 'tight']), ('half stretch ratio rounds 12.5 up', [100, 10, 5, 105, 200], ['ok', 13, 'decent']), ('control layout', [118, 6, 5, 121, 100], ['ok', 13, 'decent']), ('control layout', [105, 4, 1, 111, 100], ['underfull', 338, 'very_loose'])], [('regression: rigid line with slack', [114, 0, 6, 129, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [83, 0, 3, 97, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [116, 0, 11, 126, 100], ['underfull', 10000, 'very_loose']), ('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('one unit past total shrink', [100, 10, 5, 94, 200], ['overfull', 1000000, 'tight']), ('control layout', [85, 4, 0, 98, 150], ['underfull', 3433, 'very_loose']), ('control layout', [62, 6, 1, 51, 100], ['overfull', 1000000, 'tight'])], [('regression: rigid line with slack', [90, 0, 6, 102, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [91, 0, 10, 106, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [75, 0, 11, 88, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('very loose over tolerance', [100, 4, 0, 110, 200], ['underfull', 1563, 'very_loose']), ('negative half ratio is decent', [100, 10, 6, 97, 200], ['ok', 13, 'decent']), ('control layout', [79, 6, 10, 67, 1000], ['overfull', 1000000, 'tight']), ('control layout', [74, 16, 0, 61, 200], ['overfull', 1000000, 'tight'])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| rigid line with slack | ['underfull', 10000, 'loose'] | ['underfull', 10000, 'very_loose'] | Failed |
| regression: rigid line with slack | ['underfull', 10000, 'loose'] | ['underfull', 10000, 'very_loose'] | Failed |
| regression: rigid line with slack | ['underfull', 10000, 'loose'] | ['underfull', 10000, 'very_loose'] | Failed |
| regression: rigid line with slack | ['underfull', 10000, 'loose'] | ['underfull', 10000, 'very_loose'] | Failed |
| half stretch ratio rounds 12.5 up | ['ok', 13, 'decent'] | ['ok', 13, 'decent'] | Passed |
| exact natural width | ['ok', 0, 'decent'] | ['ok', 0, 'decent'] | Passed |
| control layout | ['ok', 0, 'decent'] | ['ok', 0, 'decent'] | Passed |
| control layout | ['overfull', 1000000, 'tight'] | ['overfull', 1000000, 'tight'] | Passed |
SHA-256 / d7d6004e4ea8202b7d4d723e88d4c11dddc57f91c44187f97c6f31c7f3ce07bf
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
natural, stretch, shrink, width, tolerance = x
shortfall = width - natural
if shortfall > 0:
if stretch == 0:
return ['underfull', 10000, 'very_loose']
r = Fraction(shortfall, stretch)
elif shortfall < 0:
if -shortfall > shrink:
return ['overfull', 1000000, 'tight']
r = Fraction(shortfall, shrink)
else:
r = Fraction(0)
badness = min(10000, math.floor(100 * abs(r) ** 3 + Fraction(1, 2)))
if r < Fraction(-1, 2):
fitness = 'tight'
elif r <= Fraction(1, 2):
fitness = 'decent'
elif r <= 1:
fitness = 'loose'
else:
fitness = 'very_loose'
status = 'ok' if badness <= tolerance else 'underfull'
return [status, badness, fitness]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [62, 0, 4, 76, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [91, 0, 10, 106, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [80, 0, 11, 90, 100], ['underfull', 10000, 'very_loose']), ('half stretch ratio rounds 12.5 up', [100, 10, 5, 105, 200], ['ok', 13, 'decent']), ('exact natural width', [100, 10, 5, 100, 200], ['ok', 0, 'decent']), ('control layout', [69, 10, 7, 69, 100], ['ok', 0, 'decent']), ('control layout', [74, 6, 6, 67, 100], ['overfull', 1000000, 'tight'])], [('regression: rigid line with slack', [94, 0, 10, 118, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [72, 0, 3, 87, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [114, 0, 6, 129, 200], ['underfull', 10000, 'very_loose']), ('exact natural width', [100, 10, 5, 100, 200], ['ok', 0, 'decent']), ('very loose over tolerance', [100, 4, 0, 110, 200], ['underfull', 1563, 'very_loose']), ('control layout', [69, 2, 11, 55, 150], ['overfull', 1000000, 'tight']), ('control layout', [62, 4, 4, 58, 200], ['ok', 100, 'tight'])], [('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [90, 0, 6, 102, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [62, 0, 4, 76, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [79, 0, 11, 96, 1000], ['underfull', 10000, 'very_loose']), ('full shrink is still acceptable', [100, 10, 5, 95, 200], ['ok', 100, 'tight']), ('half stretch ratio rounds 12.5 up', [100, 10, 5, 105, 200], ['ok', 13, 'decent']), ('control layout', [118, 6, 5, 121, 100], ['ok', 13, 'decent']), ('control layout', [105, 4, 1, 111, 100], ['underfull', 338, 'very_loose'])], [('regression: rigid line with slack', [114, 0, 6, 129, 200], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [83, 0, 3, 97, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [116, 0, 11, 126, 100], ['underfull', 10000, 'very_loose']), ('rigid line with slack', [100, 0, 5, 110, 200], ['underfull', 10000, 'very_loose']), ('one unit past total shrink', [100, 10, 5, 94, 200], ['overfull', 1000000, 'tight']), ('control layout', [85, 4, 0, 98, 150], ['underfull', 3433, 'very_loose']), ('control layout', [62, 6, 1, 51, 100], ['overfull', 1000000, 'tight'])], [('regression: rigid line with slack', [90, 0, 6, 102, 1000], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [91, 0, 10, 106, 500], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [75, 0, 11, 88, 100], ['underfull', 10000, 'very_loose']), ('regression: rigid line with slack', [100, 0, 9, 105, 100], ['underfull', 10000, 'very_loose']), ('very loose over tolerance', [100, 4, 0, 110, 200], ['underfull', 1563, 'very_loose']), ('negative half ratio is decent', [100, 10, 6, 97, 200], ['ok', 13, 'decent']), ('control layout', [79, 6, 10, 67, 1000], ['overfull', 1000000, 'tight']), ('control layout', [74, 16, 0, 61, 200], ['overfull', 1000000, 'tight'])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| rigid line with slack | ['underfull', 10000, 'very_loose'] | ['underfull', 10000, 'very_loose'] | Passed |
| regression: rigid line with slack | ['underfull', 10000, 'very_loose'] | ['underfull', 10000, 'very_loose'] | Passed |
| regression: rigid line with slack | ['underfull', 10000, 'very_loose'] | ['underfull', 10000, 'very_loose'] | Passed |
| regression: rigid line with slack | ['underfull', 10000, 'very_loose'] | ['underfull', 10000, 'very_loose'] | Passed |
| half stretch ratio rounds 12.5 up | ['ok', 13, 'decent'] | ['ok', 13, 'decent'] | Passed |
| exact natural width | ['ok', 0, 'decent'] | ['ok', 0, 'decent'] | Passed |
| control layout | ['ok', 0, 'decent'] | ['ok', 0, 'decent'] | Passed |
| control layout | ['overfull', 1000000, 'tight'] | ['overfull', 1000000, 'tight'] | Passed |
SHA-256 / a336926be9041142777b200695c81a0ea052f540d6a2858e335e2965d6672f0e
Verification & scope
A deterministic toy typesetting model with integer widths and a stipulated rule set; it does not claim conformance to any engine. 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:49:48.298745+00:00.
Case digest / 090fdf39d986abca1c465fb8fcc797c20d9a1ef9287714da4265f36fb6ec6cca