FA-63561 / Actuarial life tables / Open access
Joint-life and last-survivor status: Expectation includes time zero · case 01
Curtate expectations are one year too high.
ROOT CAUSE
The sum starts at k=0.
VERIFIED REPAIR
Start the curtate sum at k=1.
Unsuccessful approach: Starting at 2 drops the first year.
Case contract
Input lx, ly (independent lives, survival zero beyond each table), status joint|last (else 'unknown status'), t. Joint: tp_x*tp_y; last survivor: tp_x+tp_y-tp_x*tp_y. Return [status survival at t, curtate expectation = sum over k from 1 to the longer table length - 1], rounded to 6.
Why this case matters
Life-table arithmetic compounds across ages, so one misplaced index or assumption shifts every downstream value.
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):
lx=x['lx']; ly=x['ly']
def p(l,t): return Fraction(l[t],l[0]) if t<len(l) else Fraction(0)
def status(t):
a=p(lx,t); b=p(ly,t)
if x['status']=='joint': return a*b
if x['status']=='last': return a+b-a*b
return None
if status(0) is None: return 'unknown status'
T=x['t']
e=sum(status(k) for k in range(0,max(len(lx),len(ly))))
return [round(float(status(T)),6), round(float(e),6)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['joint life', {'lx': [100000, 99760, 99486, 99134, 98731, 98239, 97663, 0], 'ly': [100000, 99760, 99459, 99109, 98669, 98170, 97567, 96868, 96074, 95178], 'status': 'joint', 't': 1}, [0.995206, 5.85864]], ['last survivor unequal tables', {'lx': [100000, 99626, 99174, 98609, 97946, 0], 'ly': [100000, 99746, 99485, 99140, 98725, 98253, 97716, 97067, 96305, 95471], 'status': 'last', 't': 1}, [0.999991, 8.847686]], ['last survivor beyond shorter table', {'lx': [100000, 99547, 99068, 98510, 0], 'ly': [100000, 99650, 99240, 98743, 98172, 97496, 96738, 95876, 94860], 'status': 'last', 't': 7}, [0.95876, 7.831146]], ['last survivor open tables', {'lx': [100000, 99439, 98772, 97997, 97122, 96107, 94953], 'ly': [100000, 99716, 99346, 98921, 98456, 97885, 97234], 'status': 'last', 't': 3}, [0.999784, 5.997024]], ['joint life open tables', {'lx': [100000, 99684, 99310, 98868, 98342, 97727, 97000, 96166, 95225], 'ly': [100000, 99674, 99301, 98855, 98291, 97654], 'status': 'joint', 't': 2}, [0.986158, 4.878065]], ['joint beyond table', {'lx': [100000, 99570, 99088, 98538, 0], 'ly': [100000, 99747, 99450, 99136, 98733, 98245, 97704, 97074], 'status': 'joint', 't': 9}, [0.0, 2.955477]], ['unknown status', {'lx': [100000, 99617, 99173, 98642, 0], 'ly': [100000, 99511, 98916, 98270, 97551], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99448, 98811, 98046, 97202, 96224, 95108, 0], 'ly': [100000, 99673, 99302, 98874, 98346, 97733, 97042, 96243, 95322, 94293], 'status': 'joint', 't': 4}, [0.955943, 5.761177]], ['last survivor unequal tables', {'lx': [100000, 99718, 99414, 99081, 98674, 0], 'ly': [100000, 99715, 99364, 98938, 98447, 97838, 97148, 96371, 95513, 94519], 'status': 'last', 't': 1}, [0.999992, 8.813541]], ['last survivor beyond shorter table', {'lx': [100000, 99428, 98762, 98025, 0], 'ly': [100000, 99693, 99289, 98823, 98276, 97648, 96919, 96073, 95105], 'status': 'last', 't': 7}, [0.96073, 7.839872]], ['last survivor open tables', {'lx': [100000, 99783, 99509, 99191, 98791, 98327, 97812], 'ly': [100000, 99761, 99460, 99128, 98713, 98242, 97687], 'status': 'last', 't': 3}, [0.999929, 5.998942]], ['joint life open tables', {'lx': [100000, 99667, 99266, 98772, 98175, 97495, 96689, 95778, 94734], 'ly': [100000, 99563, 99077, 98505, 97818, 97009], 'status': 'joint', 't': 2}, [0.983498, 4.854883]], ['joint beyond table', {'lx': [100000, 99653, 99229, 98732, 0], 'ly': [100000, 99509, 98964, 98317, 97578, 96754, 95832, 94804], 'status': 'joint', 't': 9}, [0.0, 2.94435]], ['unknown status', {'lx': [100000, 99557, 99059, 98473, 0], 'ly': [100000, 99384, 98656, 97854, 96902], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99420, 98745, 98004, 97134, 96149, 95028, 0], 'ly': [100000, 99781, 99500, 99136, 98731, 98273, 97761, 97153, 96455, 95674], 'status': 'joint', 't': 1}, [0.992023, 5.77901]], ['last survivor unequal tables', {'lx': [100000, 99469, 98862, 98156, 97349, 0], 'ly': [100000, 99528, 98974, 98327, 97564, 96691, 95712, 94591, 93350, 91946], 'status': 'last', 't': 1}, [0.999975, 8.721804]], ['last survivor beyond shorter table', {'lx': [100000, 99476, 98855, 98104, 0], 'ly': [100000, 99661, 99248, 98756, 98176, 97498, 96731, 95865, 94884], 'status': 'last', 't': 7}, [0.95865, 7.8312]], ['last survivor open tables', {'lx': [100000, 99450, 98799, 98048, 97168, 96153, 95008], 'ly': [100000, 99755, 99464, 99076, 98648, 98129, 97541], 'status': 'last', 't': 3}, [0.99982, 5.997412]], ['joint life open tables', {'lx': [100000, 99685, 99309, 98892, 98407, 97822, 97160, 96399, 95545], 'ly': [100000, 99396, 98724, 97967, 97081, 96062], 'status': 'joint', 't': 2}, [0.980418, 4.835105]], ['joint beyond table', {'lx': [100000, 99548, 99025, 98421, 0], 'ly': [100000, 99505, 98968, 98338, 97593, 96743, 95786, 94672], 'status': 'joint', 't': 9}, [0.0, 2.938435]], ['unknown status', {'lx': [100000, 99455, 98849, 98120, 0], 'ly': [100000, 99494, 98921, 98296, 97615], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99524, 98933, 98258, 97497, 96646, 95677, 0], 'ly': [100000, 99594, 99118, 98553, 97900, 97141, 96258, 95231, 94074, 92762], 'status': 'joint', 't': 3}, [0.968362, 5.754458]], ['last survivor unequal tables', {'lx': [100000, 99732, 99425, 99030, 98600, 0], 'ly': [100000, 99770, 99497, 99164, 98735, 98241, 97675, 97023, 96270, 95436], 'status': 'last', 't': 3}, [0.999919, 8.846157]], ['last survivor beyond shorter table', {'lx': [100000, 99698, 99335, 98894, 0], 'ly': [100000, 99669, 99278, 98818, 98308, 97710, 97016, 96215, 95327], 'status': 'last', 't': 7}, [0.96215, 7.845571]], ['last survivor open tables', {'lx': [100000, 99784, 99547, 99245, 98874, 98425, 97879], 'ly': [100000, 99504, 98929, 98302, 97565, 96734, 95811], 'status': 'last', 't': 3}, [0.999872, 5.998136]], ['joint life open tables', {'lx': [100000, 99606, 99145, 98568, 97907, 97123, 96202, 95190, 94059], 'ly': [100000, 99527, 98969, 98322, 97575, 96743], 'status': 'joint', 't': 2}, [0.981228, 4.836642]], ['joint beyond table', {'lx': [100000, 99565, 99039, 98435, 0], 'ly': [100000, 99674, 99279, 98817, 98295, 97694, 96998, 96233], 'status': 'joint', 't': 9}, [0.0, 2.948359]], ['unknown status', {'lx': [100000, 99508, 98911, 98195, 0], 'ly': [100000, 99742, 99447, 99070, 98653], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99789, 99523, 99217, 98831, 98388, 97851, 0], 'ly': [100000, 99688, 99282, 98825, 98282, 97645, 96945, 96125, 95188, 94126], 'status': 'joint', 't': 3}, [0.980512, 5.84403]], ['last survivor unequal tables', {'lx': [100000, 99741, 99448, 99116, 98714, 0], 'ly': [100000, 99521, 98971, 98345, 97624, 96787, 95853, 94770, 93551, 92159], 'status': 'last', 't': 1}, [0.999988, 8.730679]], ['last survivor beyond shorter table', {'lx': [100000, 99668, 99245, 98758, 0], 'ly': [100000, 99563, 99025, 98427, 97706, 96930, 96030, 94987, 93814], 'status': 'last', 't': 7}, [0.94987, 7.794387]], ['last survivor open tables', {'lx': [100000, 99694, 99322, 98864, 98352, 97783, 97128], 'ly': [100000, 99535, 98960, 98318, 97580, 96708, 95703], 'status': 'last', 't': 3}, [0.999809, 5.997361]], ['joint life open tables', {'lx': [100000, 99664, 99263, 98780, 98192, 97509, 96759, 95881, 94872], 'ly': [100000, 99636, 99196, 98689, 98098, 97408], 'status': 'joint', 't': 2}, [0.984649, 4.865571]], ['joint beyond table', {'lx': [100000, 99667, 99263, 98779, 0], 'ly': [100000, 99685, 99331, 98920, 98454, 97919, 97309, 96596], 'status': 'joint', 't': 9}, [0.0, 2.956642]], ['unknown status', {'lx': [100000, 99732, 99419, 99061, 0], 'ly': [100000, 99758, 99459, 99121, 98740], 'status': 'reversionary', 't': 1}, 'unknown status']]]
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 |
|---|---|---|---|
| joint life | [0.995206, 6.85864] | [0.995206, 5.85864] | Failed |
| last survivor unequal tables | [0.999991, 9.847686] | [0.999991, 8.847686] | Failed |
| last survivor beyond shorter table | [0.95876, 8.831146] | [0.95876, 7.831146] | Failed |
| last survivor open tables | [0.999784, 6.997024] | [0.999784, 5.997024] | Failed |
| joint life open tables | [0.986158, 5.878065] | [0.986158, 4.878065] | Failed |
| joint beyond table | [0.0, 3.955477] | [0.0, 2.955477] | Failed |
| unknown status | unknown status | unknown status | Passed |
SHA-256 / ba72710a2e7e6050132e31447bffc10f0e8bf87e2f02566fc9b984bff4ba5d88
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):
lx=x['lx']; ly=x['ly']
def p(l,t): return Fraction(l[t],l[0]) if t<len(l) else Fraction(0)
def status(t):
a=p(lx,t); b=p(ly,t)
if x['status']=='joint': return a*b
if x['status']=='last': return a+b-a*b
return None
if status(0) is None: return 'unknown status'
T=x['t']
e=sum(status(k) for k in range(2,max(len(lx),len(ly))))
return [round(float(status(T)),6), round(float(e),6)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['joint life', {'lx': [100000, 99760, 99486, 99134, 98731, 98239, 97663, 0], 'ly': [100000, 99760, 99459, 99109, 98669, 98170, 97567, 96868, 96074, 95178], 'status': 'joint', 't': 1}, [0.995206, 5.85864]], ['last survivor unequal tables', {'lx': [100000, 99626, 99174, 98609, 97946, 0], 'ly': [100000, 99746, 99485, 99140, 98725, 98253, 97716, 97067, 96305, 95471], 'status': 'last', 't': 1}, [0.999991, 8.847686]], ['last survivor beyond shorter table', {'lx': [100000, 99547, 99068, 98510, 0], 'ly': [100000, 99650, 99240, 98743, 98172, 97496, 96738, 95876, 94860], 'status': 'last', 't': 7}, [0.95876, 7.831146]], ['last survivor open tables', {'lx': [100000, 99439, 98772, 97997, 97122, 96107, 94953], 'ly': [100000, 99716, 99346, 98921, 98456, 97885, 97234], 'status': 'last', 't': 3}, [0.999784, 5.997024]], ['joint life open tables', {'lx': [100000, 99684, 99310, 98868, 98342, 97727, 97000, 96166, 95225], 'ly': [100000, 99674, 99301, 98855, 98291, 97654], 'status': 'joint', 't': 2}, [0.986158, 4.878065]], ['joint beyond table', {'lx': [100000, 99570, 99088, 98538, 0], 'ly': [100000, 99747, 99450, 99136, 98733, 98245, 97704, 97074], 'status': 'joint', 't': 9}, [0.0, 2.955477]], ['unknown status', {'lx': [100000, 99617, 99173, 98642, 0], 'ly': [100000, 99511, 98916, 98270, 97551], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99448, 98811, 98046, 97202, 96224, 95108, 0], 'ly': [100000, 99673, 99302, 98874, 98346, 97733, 97042, 96243, 95322, 94293], 'status': 'joint', 't': 4}, [0.955943, 5.761177]], ['last survivor unequal tables', {'lx': [100000, 99718, 99414, 99081, 98674, 0], 'ly': [100000, 99715, 99364, 98938, 98447, 97838, 97148, 96371, 95513, 94519], 'status': 'last', 't': 1}, [0.999992, 8.813541]], ['last survivor beyond shorter table', {'lx': [100000, 99428, 98762, 98025, 0], 'ly': [100000, 99693, 99289, 98823, 98276, 97648, 96919, 96073, 95105], 'status': 'last', 't': 7}, [0.96073, 7.839872]], ['last survivor open tables', {'lx': [100000, 99783, 99509, 99191, 98791, 98327, 97812], 'ly': [100000, 99761, 99460, 99128, 98713, 98242, 97687], 'status': 'last', 't': 3}, [0.999929, 5.998942]], ['joint life open tables', {'lx': [100000, 99667, 99266, 98772, 98175, 97495, 96689, 95778, 94734], 'ly': [100000, 99563, 99077, 98505, 97818, 97009], 'status': 'joint', 't': 2}, [0.983498, 4.854883]], ['joint beyond table', {'lx': [100000, 99653, 99229, 98732, 0], 'ly': [100000, 99509, 98964, 98317, 97578, 96754, 95832, 94804], 'status': 'joint', 't': 9}, [0.0, 2.94435]], ['unknown status', {'lx': [100000, 99557, 99059, 98473, 0], 'ly': [100000, 99384, 98656, 97854, 96902], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99420, 98745, 98004, 97134, 96149, 95028, 0], 'ly': [100000, 99781, 99500, 99136, 98731, 98273, 97761, 97153, 96455, 95674], 'status': 'joint', 't': 1}, [0.992023, 5.77901]], ['last survivor unequal tables', {'lx': [100000, 99469, 98862, 98156, 97349, 0], 'ly': [100000, 99528, 98974, 98327, 97564, 96691, 95712, 94591, 93350, 91946], 'status': 'last', 't': 1}, [0.999975, 8.721804]], ['last survivor beyond shorter table', {'lx': [100000, 99476, 98855, 98104, 0], 'ly': [100000, 99661, 99248, 98756, 98176, 97498, 96731, 95865, 94884], 'status': 'last', 't': 7}, [0.95865, 7.8312]], ['last survivor open tables', {'lx': [100000, 99450, 98799, 98048, 97168, 96153, 95008], 'ly': [100000, 99755, 99464, 99076, 98648, 98129, 97541], 'status': 'last', 't': 3}, [0.99982, 5.997412]], ['joint life open tables', {'lx': [100000, 99685, 99309, 98892, 98407, 97822, 97160, 96399, 95545], 'ly': [100000, 99396, 98724, 97967, 97081, 96062], 'status': 'joint', 't': 2}, [0.980418, 4.835105]], ['joint beyond table', {'lx': [100000, 99548, 99025, 98421, 0], 'ly': [100000, 99505, 98968, 98338, 97593, 96743, 95786, 94672], 'status': 'joint', 't': 9}, [0.0, 2.938435]], ['unknown status', {'lx': [100000, 99455, 98849, 98120, 0], 'ly': [100000, 99494, 98921, 98296, 97615], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99524, 98933, 98258, 97497, 96646, 95677, 0], 'ly': [100000, 99594, 99118, 98553, 97900, 97141, 96258, 95231, 94074, 92762], 'status': 'joint', 't': 3}, [0.968362, 5.754458]], ['last survivor unequal tables', {'lx': [100000, 99732, 99425, 99030, 98600, 0], 'ly': [100000, 99770, 99497, 99164, 98735, 98241, 97675, 97023, 96270, 95436], 'status': 'last', 't': 3}, [0.999919, 8.846157]], ['last survivor beyond shorter table', {'lx': [100000, 99698, 99335, 98894, 0], 'ly': [100000, 99669, 99278, 98818, 98308, 97710, 97016, 96215, 95327], 'status': 'last', 't': 7}, [0.96215, 7.845571]], ['last survivor open tables', {'lx': [100000, 99784, 99547, 99245, 98874, 98425, 97879], 'ly': [100000, 99504, 98929, 98302, 97565, 96734, 95811], 'status': 'last', 't': 3}, [0.999872, 5.998136]], ['joint life open tables', {'lx': [100000, 99606, 99145, 98568, 97907, 97123, 96202, 95190, 94059], 'ly': [100000, 99527, 98969, 98322, 97575, 96743], 'status': 'joint', 't': 2}, [0.981228, 4.836642]], ['joint beyond table', {'lx': [100000, 99565, 99039, 98435, 0], 'ly': [100000, 99674, 99279, 98817, 98295, 97694, 96998, 96233], 'status': 'joint', 't': 9}, [0.0, 2.948359]], ['unknown status', {'lx': [100000, 99508, 98911, 98195, 0], 'ly': [100000, 99742, 99447, 99070, 98653], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99789, 99523, 99217, 98831, 98388, 97851, 0], 'ly': [100000, 99688, 99282, 98825, 98282, 97645, 96945, 96125, 95188, 94126], 'status': 'joint', 't': 3}, [0.980512, 5.84403]], ['last survivor unequal tables', {'lx': [100000, 99741, 99448, 99116, 98714, 0], 'ly': [100000, 99521, 98971, 98345, 97624, 96787, 95853, 94770, 93551, 92159], 'status': 'last', 't': 1}, [0.999988, 8.730679]], ['last survivor beyond shorter table', {'lx': [100000, 99668, 99245, 98758, 0], 'ly': [100000, 99563, 99025, 98427, 97706, 96930, 96030, 94987, 93814], 'status': 'last', 't': 7}, [0.94987, 7.794387]], ['last survivor open tables', {'lx': [100000, 99694, 99322, 98864, 98352, 97783, 97128], 'ly': [100000, 99535, 98960, 98318, 97580, 96708, 95703], 'status': 'last', 't': 3}, [0.999809, 5.997361]], ['joint life open tables', {'lx': [100000, 99664, 99263, 98780, 98192, 97509, 96759, 95881, 94872], 'ly': [100000, 99636, 99196, 98689, 98098, 97408], 'status': 'joint', 't': 2}, [0.984649, 4.865571]], ['joint beyond table', {'lx': [100000, 99667, 99263, 98779, 0], 'ly': [100000, 99685, 99331, 98920, 98454, 97919, 97309, 96596], 'status': 'joint', 't': 9}, [0.0, 2.956642]], ['unknown status', {'lx': [100000, 99732, 99419, 99061, 0], 'ly': [100000, 99758, 99459, 99121, 98740], 'status': 'reversionary', 't': 1}, 'unknown status']]]
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 |
|---|---|---|---|
| joint life | [0.995206, 4.863435] | [0.995206, 5.85864] | Failed |
| last survivor unequal tables | [0.999991, 7.847696] | [0.999991, 8.847686] | Failed |
| last survivor beyond shorter table | [0.95876, 6.831162] | [0.95876, 7.831146] | Failed |
| last survivor open tables | [0.999784, 4.99704] | [0.999784, 5.997024] | Failed |
| joint life open tables | [0.986158, 3.884474] | [0.986158, 4.878065] | Failed |
| joint beyond table | [0.0, 1.962296] | [0.0, 2.955477] | Failed |
| unknown status | unknown status | unknown status | Passed |
SHA-256 / 95c529d7bb710398e0e0e8ba620de17f799bc201fc9d292d45f9c16ae78b03fe
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):
lx=x['lx']; ly=x['ly']
def p(l,t): return Fraction(l[t],l[0]) if t<len(l) else Fraction(0)
def status(t):
a=p(lx,t); b=p(ly,t)
if x['status']=='joint': return a*b
if x['status']=='last': return a+b-a*b
return None
if status(0) is None: return 'unknown status'
T=x['t']
e=sum(status(k) for k in range(1,max(len(lx),len(ly))))
return [round(float(status(T)),6), round(float(e),6)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['joint life', {'lx': [100000, 99760, 99486, 99134, 98731, 98239, 97663, 0], 'ly': [100000, 99760, 99459, 99109, 98669, 98170, 97567, 96868, 96074, 95178], 'status': 'joint', 't': 1}, [0.995206, 5.85864]], ['last survivor unequal tables', {'lx': [100000, 99626, 99174, 98609, 97946, 0], 'ly': [100000, 99746, 99485, 99140, 98725, 98253, 97716, 97067, 96305, 95471], 'status': 'last', 't': 1}, [0.999991, 8.847686]], ['last survivor beyond shorter table', {'lx': [100000, 99547, 99068, 98510, 0], 'ly': [100000, 99650, 99240, 98743, 98172, 97496, 96738, 95876, 94860], 'status': 'last', 't': 7}, [0.95876, 7.831146]], ['last survivor open tables', {'lx': [100000, 99439, 98772, 97997, 97122, 96107, 94953], 'ly': [100000, 99716, 99346, 98921, 98456, 97885, 97234], 'status': 'last', 't': 3}, [0.999784, 5.997024]], ['joint life open tables', {'lx': [100000, 99684, 99310, 98868, 98342, 97727, 97000, 96166, 95225], 'ly': [100000, 99674, 99301, 98855, 98291, 97654], 'status': 'joint', 't': 2}, [0.986158, 4.878065]], ['joint beyond table', {'lx': [100000, 99570, 99088, 98538, 0], 'ly': [100000, 99747, 99450, 99136, 98733, 98245, 97704, 97074], 'status': 'joint', 't': 9}, [0.0, 2.955477]], ['unknown status', {'lx': [100000, 99617, 99173, 98642, 0], 'ly': [100000, 99511, 98916, 98270, 97551], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99448, 98811, 98046, 97202, 96224, 95108, 0], 'ly': [100000, 99673, 99302, 98874, 98346, 97733, 97042, 96243, 95322, 94293], 'status': 'joint', 't': 4}, [0.955943, 5.761177]], ['last survivor unequal tables', {'lx': [100000, 99718, 99414, 99081, 98674, 0], 'ly': [100000, 99715, 99364, 98938, 98447, 97838, 97148, 96371, 95513, 94519], 'status': 'last', 't': 1}, [0.999992, 8.813541]], ['last survivor beyond shorter table', {'lx': [100000, 99428, 98762, 98025, 0], 'ly': [100000, 99693, 99289, 98823, 98276, 97648, 96919, 96073, 95105], 'status': 'last', 't': 7}, [0.96073, 7.839872]], ['last survivor open tables', {'lx': [100000, 99783, 99509, 99191, 98791, 98327, 97812], 'ly': [100000, 99761, 99460, 99128, 98713, 98242, 97687], 'status': 'last', 't': 3}, [0.999929, 5.998942]], ['joint life open tables', {'lx': [100000, 99667, 99266, 98772, 98175, 97495, 96689, 95778, 94734], 'ly': [100000, 99563, 99077, 98505, 97818, 97009], 'status': 'joint', 't': 2}, [0.983498, 4.854883]], ['joint beyond table', {'lx': [100000, 99653, 99229, 98732, 0], 'ly': [100000, 99509, 98964, 98317, 97578, 96754, 95832, 94804], 'status': 'joint', 't': 9}, [0.0, 2.94435]], ['unknown status', {'lx': [100000, 99557, 99059, 98473, 0], 'ly': [100000, 99384, 98656, 97854, 96902], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99420, 98745, 98004, 97134, 96149, 95028, 0], 'ly': [100000, 99781, 99500, 99136, 98731, 98273, 97761, 97153, 96455, 95674], 'status': 'joint', 't': 1}, [0.992023, 5.77901]], ['last survivor unequal tables', {'lx': [100000, 99469, 98862, 98156, 97349, 0], 'ly': [100000, 99528, 98974, 98327, 97564, 96691, 95712, 94591, 93350, 91946], 'status': 'last', 't': 1}, [0.999975, 8.721804]], ['last survivor beyond shorter table', {'lx': [100000, 99476, 98855, 98104, 0], 'ly': [100000, 99661, 99248, 98756, 98176, 97498, 96731, 95865, 94884], 'status': 'last', 't': 7}, [0.95865, 7.8312]], ['last survivor open tables', {'lx': [100000, 99450, 98799, 98048, 97168, 96153, 95008], 'ly': [100000, 99755, 99464, 99076, 98648, 98129, 97541], 'status': 'last', 't': 3}, [0.99982, 5.997412]], ['joint life open tables', {'lx': [100000, 99685, 99309, 98892, 98407, 97822, 97160, 96399, 95545], 'ly': [100000, 99396, 98724, 97967, 97081, 96062], 'status': 'joint', 't': 2}, [0.980418, 4.835105]], ['joint beyond table', {'lx': [100000, 99548, 99025, 98421, 0], 'ly': [100000, 99505, 98968, 98338, 97593, 96743, 95786, 94672], 'status': 'joint', 't': 9}, [0.0, 2.938435]], ['unknown status', {'lx': [100000, 99455, 98849, 98120, 0], 'ly': [100000, 99494, 98921, 98296, 97615], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99524, 98933, 98258, 97497, 96646, 95677, 0], 'ly': [100000, 99594, 99118, 98553, 97900, 97141, 96258, 95231, 94074, 92762], 'status': 'joint', 't': 3}, [0.968362, 5.754458]], ['last survivor unequal tables', {'lx': [100000, 99732, 99425, 99030, 98600, 0], 'ly': [100000, 99770, 99497, 99164, 98735, 98241, 97675, 97023, 96270, 95436], 'status': 'last', 't': 3}, [0.999919, 8.846157]], ['last survivor beyond shorter table', {'lx': [100000, 99698, 99335, 98894, 0], 'ly': [100000, 99669, 99278, 98818, 98308, 97710, 97016, 96215, 95327], 'status': 'last', 't': 7}, [0.96215, 7.845571]], ['last survivor open tables', {'lx': [100000, 99784, 99547, 99245, 98874, 98425, 97879], 'ly': [100000, 99504, 98929, 98302, 97565, 96734, 95811], 'status': 'last', 't': 3}, [0.999872, 5.998136]], ['joint life open tables', {'lx': [100000, 99606, 99145, 98568, 97907, 97123, 96202, 95190, 94059], 'ly': [100000, 99527, 98969, 98322, 97575, 96743], 'status': 'joint', 't': 2}, [0.981228, 4.836642]], ['joint beyond table', {'lx': [100000, 99565, 99039, 98435, 0], 'ly': [100000, 99674, 99279, 98817, 98295, 97694, 96998, 96233], 'status': 'joint', 't': 9}, [0.0, 2.948359]], ['unknown status', {'lx': [100000, 99508, 98911, 98195, 0], 'ly': [100000, 99742, 99447, 99070, 98653], 'status': 'reversionary', 't': 1}, 'unknown status']], [['joint life', {'lx': [100000, 99789, 99523, 99217, 98831, 98388, 97851, 0], 'ly': [100000, 99688, 99282, 98825, 98282, 97645, 96945, 96125, 95188, 94126], 'status': 'joint', 't': 3}, [0.980512, 5.84403]], ['last survivor unequal tables', {'lx': [100000, 99741, 99448, 99116, 98714, 0], 'ly': [100000, 99521, 98971, 98345, 97624, 96787, 95853, 94770, 93551, 92159], 'status': 'last', 't': 1}, [0.999988, 8.730679]], ['last survivor beyond shorter table', {'lx': [100000, 99668, 99245, 98758, 0], 'ly': [100000, 99563, 99025, 98427, 97706, 96930, 96030, 94987, 93814], 'status': 'last', 't': 7}, [0.94987, 7.794387]], ['last survivor open tables', {'lx': [100000, 99694, 99322, 98864, 98352, 97783, 97128], 'ly': [100000, 99535, 98960, 98318, 97580, 96708, 95703], 'status': 'last', 't': 3}, [0.999809, 5.997361]], ['joint life open tables', {'lx': [100000, 99664, 99263, 98780, 98192, 97509, 96759, 95881, 94872], 'ly': [100000, 99636, 99196, 98689, 98098, 97408], 'status': 'joint', 't': 2}, [0.984649, 4.865571]], ['joint beyond table', {'lx': [100000, 99667, 99263, 98779, 0], 'ly': [100000, 99685, 99331, 98920, 98454, 97919, 97309, 96596], 'status': 'joint', 't': 9}, [0.0, 2.956642]], ['unknown status', {'lx': [100000, 99732, 99419, 99061, 0], 'ly': [100000, 99758, 99459, 99121, 98740], 'status': 'reversionary', 't': 1}, 'unknown status']]]
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 |
|---|---|---|---|
| joint life | [0.995206, 5.85864] | [0.995206, 5.85864] | Passed |
| last survivor unequal tables | [0.999991, 8.847686] | [0.999991, 8.847686] | Passed |
| last survivor beyond shorter table | [0.95876, 7.831146] | [0.95876, 7.831146] | Passed |
| last survivor open tables | [0.999784, 5.997024] | [0.999784, 5.997024] | Passed |
| joint life open tables | [0.986158, 4.878065] | [0.986158, 4.878065] | Passed |
| joint beyond table | [0.0, 2.955477] | [0.0, 2.955477] | Passed |
| unknown status | unknown status | unknown status | Passed |
SHA-256 / e537130d6af98544d6b178390987f7ae3276684956b3f554394067ae6876cf53
Verification & scope
A deterministic bounded teaching model of a stipulated toy actuarial contract. Rates are small synthetic tables, exact rationals are used where practical and floats are rounded at the output; it makes no claim of conformance with any published table, standard of practice or regulation. 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:47:15.676432+00:00.
Case digest / 2f3993a77bf4e1836f4aae21fcc039e57df9f8fe399c851c270d3f2ae882fdd1