FAILURE MAP
← Case archive

FA-63541 / Actuarial life tables / Open access

Joint-life and last-survivor status: Last-survivor probability double counts both alive · case 01

Last-survivor probabilities exceed one.

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

ROOT CAUSE

The joint-survival term is not subtracted.

VERIFIED REPAIR

Use tp_x+tp_y-tp_xy.

Unsuccessful approach: The larger single-life probability ignores the second life.

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
        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 fixtureActualExpectedOutcome
joint life[0.995206, 5.85864][0.995206, 5.85864]Passed
last survivor unequal tables[1.99372, 12.77263][0.999991, 8.847686]Failed
last survivor beyond shorter table[0.95876, 10.779][0.95876, 7.831146]Failed
last survivor open tables[1.96918, 11.75948][0.999784, 5.997024]Failed
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 statusunknown statusunknown statusPassed

SHA-256 / 6204fd9526667f9aed4b509b59366fb8aa12ec9180b45cf54bb14178fde3b816

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 max(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 fixtureActualExpectedOutcome
joint life[0.995206, 5.85864][0.995206, 5.85864]Passed
last survivor unequal tables[0.99746, 8.81908][0.999991, 8.847686]Failed
last survivor beyond shorter table[0.95876, 7.80775][0.95876, 7.831146]Failed
last survivor open tables[0.98921, 5.91558][0.999784, 5.997024]Failed
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 statusunknown statusunknown statusPassed

SHA-256 / 84b9518ca34fe2a0d82bf33b9299766a518b4cbe190df7b4def0cf50cc883aa6

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 fixtureActualExpectedOutcome
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 statusunknown statusunknown statusPassed

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

Case digest / d5bcffbf21b0d6b843e7c60a2c9eec8f8ac3c05925a851a2de65496f5ab6f735