FAILURE MAP
← Case archive

FA-63501 / Actuarial life tables / Open access

Net level annual premium: Maturity benefit is discounted one year short · case 01

Endowment premiums are overstated.

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

ROOT CAUSE

The pure endowment uses v^(n-1).

VERIFIED REPAIR

Use v^n times n-year survival.

Unsuccessful approach: Omitting survival pays the maturity benefit to the dead.

Case contract

Input q (per 100000), n (coverage years), m (premium years, 1<=m<=n and n<=table length else 'invalid'), type term|endowment (else 'invalid type'), i (per mille), benefit. A = sum v^(k+1) kp q_k (+ v^n np for endowment); premium annuity-due over m years; return benefit*A/annuity rounded half-up.

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):
    qs=[Fraction(q,100000) for q in x['q']]; n=x['n']; m=x['m']
    if m>n or m<1 or n>len(qs): return 'invalid'
    if x['type'] not in ('term','endowment'): return 'invalid type'
    v=1/(1+Fraction(x['i'],1000))
    A=Fraction(0); ann=Fraction(0); kp=Fraction(1)
    for k in range(n):
        if k<m: ann+=v**k*kp
        A+=v**(k+1)*kp*qs[k]
        kp*=1-qs[k]
    if x['type']=='endowment': A+=v**(n-1)*kp
    return math.floor(x['benefit']*A/ann+Fraction(1,2))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limited pay term', {'q': [1116, 1354, 1667, 2034, 2465, 2963, 3571, 4298, 5197, 6274, 7556, 9080], 'n': 10, 'm': 6, 'type': 'term', 'i': 50, 'benefit': 32417307}, 1236317], ['limited pay endowment', {'q': [805, 1014, 1237, 1505, 1844, 2262, 2735, 3316, 3991, 4822, 5826, 6998], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 50, 'benefit': 53744860}, 13078746], ['full pay endowment', {'q': [1226, 1472, 1786, 2144, 2583, 3103, 3749, 4533, 5446, 6546, 7888, 9479], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 30, 'benefit': 17182267}, 2700402], ['full pay term', {'q': [636, 786, 984, 1192, 1450, 1750, 2140, 2614, 3160, 3797, 4603, 5551], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77720826}, 1517456], ['single premium', {'q': [586, 718, 878, 1062, 1306, 1614, 1972, 2399, 2899, 3512, 4240, 5126], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 23235362}, 19155246], ['pay period exceeds term', {'q': [704, 861, 1036, 1286, 1567, 1897, 2281, 2786, 3359, 4046, 4868, 5860], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 97510456}, 'invalid'], ['unknown plan type', {'q': [966, 1164, 1413, 1738, 2095, 2527, 3060, 3675, 4454, 5384, 6480, 7790], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 52803794}, 'invalid type'], ['term too long for table', {'q': [1168, 1420, 1752, 2109, 2552, 3075, 3725, 4498, 5446, 6543, 7899, 9488], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 68032420}, 'invalid']], [['limited pay term', {'q': [841, 1053, 1267, 1547, 1901, 2290, 2783, 3379, 4070, 4927, 5917, 7143], 'n': 10, 'm': 5, 'type': 'term', 'i': 40, 'benefit': 10621995}, 390243], ['limited pay endowment', {'q': [1237, 1529, 1837, 2215, 2701, 3286, 3958, 4782, 5775, 6980, 8396, 10091], 'n': 8, 'm': 4, 'type': 'endowment', 'i': 50, 'benefit': 28755476}, 5487845], ['full pay endowment', {'q': [1149, 1421, 1734, 2104, 2524, 3074, 3738, 4524, 5429, 6522, 7842, 9459], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 50, 'benefit': 68984205}, 10136985], ['full pay term', {'q': [1155, 1401, 1706, 2084, 2505, 3052, 3702, 4479, 5396, 6523, 7831, 9442], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77815499}, 2534596], ['single premium', {'q': [1488, 1827, 2210, 2701, 3269, 3941, 4765, 5757, 6948, 8343, 10034, 12042], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 10091605}, 8753895], ['pay period exceeds term', {'q': [1434, 1757, 2137, 2589, 3128, 3764, 4523, 5445, 6554, 7912, 9512, 11438], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 70676453}, 'invalid'], ['unknown plan type', {'q': [1212, 1472, 1779, 2143, 2614, 3137, 3779, 4543, 5470, 6612, 7956, 9572], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 15889609}, 'invalid type'], ['term too long for table', {'q': [663, 804, 993, 1231, 1479, 1787, 2159, 2637, 3213, 3881, 4704, 5656], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 54460124}, 'invalid']], [['limited pay term', {'q': [747, 913, 1131, 1395, 1717, 2081, 2524, 3065, 3693, 4464, 5404, 6511], 'n': 10, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 87228387}, 3048879], ['limited pay endowment', {'q': [829, 1036, 1275, 1538, 1848, 2245, 2727, 3321, 4019, 4840, 5840, 7033], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 74915366}, 12250027], ['full pay endowment', {'q': [1425, 1755, 2109, 2552, 3068, 3709, 4452, 5354, 6453, 7758, 9346, 11251], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 37157222}, 5700405], ['full pay term', {'q': [1109, 1368, 1651, 2017, 2431, 2939, 3572, 4303, 5195, 6284, 7585, 9152], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 11656982}, 367794], ['single premium', {'q': [526, 657, 804, 1002, 1248, 1531, 1861, 2269, 2740, 3321, 4011, 4832], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 36779454}, 30313184], ['pay period exceeds term', {'q': [1308, 1603, 1941, 2359, 2865, 3473, 4180, 5051, 6103, 7351, 8863, 10680], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 33579689}, 'invalid'], ['unknown plan type', {'q': [1363, 1655, 1992, 2437, 2924, 3536, 4286, 5167, 6239, 7489, 9002, 10816], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 98225689}, 'invalid type'], ['term too long for table', {'q': [1070, 1313, 1595, 1918, 2328, 2810, 3419, 4135, 5012, 6063, 7304, 8777], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 38738726}, 'invalid']], [['limited pay term', {'q': [512, 643, 815, 1003, 1212, 1489, 1831, 2210, 2664, 3227, 3916, 4712], 'n': 10, 'm': 3, 'type': 'term', 'i': 50, 'benefit': 45807977}, 1688215], ['limited pay endowment', {'q': [590, 709, 861, 1043, 1276, 1575, 1926, 2361, 2871, 3492, 4201, 5086], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 40, 'benefit': 38192191}, 9833950], ['full pay endowment', {'q': [528, 644, 806, 1014, 1235, 1482, 1819, 2204, 2655, 3234, 3922, 4713], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 71007672}, 10519104], ['full pay term', {'q': [1074, 1331, 1597, 1959, 2390, 2877, 3476, 4185, 5055, 6067, 7296, 8779], 'n': 12, 'm': 12, 'type': 'term', 'i': 30, 'benefit': 83944206}, 2733193], ['single premium', {'q': [678, 813, 994, 1206, 1488, 1828, 2220, 2693, 3274, 3956, 4750, 5720], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 89899331}, 74144103], ['pay period exceeds term', {'q': [983, 1186, 1467, 1792, 2157, 2607, 3155, 3832, 4617, 5558, 6707, 8062], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 49415695}, 'invalid'], ['unknown plan type', {'q': [730, 884, 1091, 1323, 1616, 1984, 2415, 2929, 3548, 4275, 5150, 6215], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 99033643}, 'invalid type'], ['term too long for table', {'q': [1353, 1640, 1996, 2435, 2922, 3548, 4298, 5204, 6275, 7580, 9134, 10967], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 56917171}, 'invalid']], [['limited pay term', {'q': [855, 1042, 1283, 1573, 1895, 2291, 2795, 3365, 4084, 4937, 5928, 7133], 'n': 10, 'm': 4, 'type': 'term', 'i': 30, 'benefit': 26591939}, 1254982], ['limited pay endowment', {'q': [1284, 1558, 1913, 2335, 2838, 3409, 4127, 4953, 5987, 7192, 8649, 10419], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 31636962}, 5267026], ['full pay endowment', {'q': [689, 831, 1026, 1257, 1516, 1826, 2201, 2686, 3249, 3931, 4730, 5695], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 16318284}, 2431737], ['full pay term', {'q': [631, 779, 957, 1167, 1436, 1770, 2163, 2608, 3149, 3826, 4607, 5557], 'n': 12, 'm': 12, 'type': 'term', 'i': 40, 'benefit': 14803880}, 297673], ['single premium', {'q': [1499, 1817, 2219, 2684, 3268, 3964, 4795, 5778, 6979, 8381, 10061, 12080], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 45588105}, 39545285], ['pay period exceeds term', {'q': [1089, 1329, 1604, 1944, 2381, 2862, 3441, 4130, 4970, 5966, 7192, 8664], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 16169173}, 'invalid'], ['unknown plan type', {'q': [627, 776, 934, 1161, 1422, 1733, 2096, 2520, 3024, 3638, 4377, 5280], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 97706465}, 'invalid type'], ['term too long for table', {'q': [697, 840, 1013, 1239, 1511, 1819, 2198, 2660, 3234, 3882, 4708, 5676], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 62443585}, 'invalid']]]
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
limited pay term12363171236317Passed
limited pay endowment1363152813078746Failed
full pay endowment27714052700402Failed
full pay term15174561517456Passed
single premium1988501419155246Failed
pay period exceeds terminvalidinvalidPassed
unknown plan typeinvalid typeinvalid typePassed
term too long for tableinvalidinvalidPassed

SHA-256 / ca4cbc8390543d99903d965e38fee37921c32e4e6efd27e4086ea80b75ce6231

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):
    qs=[Fraction(q,100000) for q in x['q']]; n=x['n']; m=x['m']
    if m>n or m<1 or n>len(qs): return 'invalid'
    if x['type'] not in ('term','endowment'): return 'invalid type'
    v=1/(1+Fraction(x['i'],1000))
    A=Fraction(0); ann=Fraction(0); kp=Fraction(1)
    for k in range(n):
        if k<m: ann+=v**k*kp
        A+=v**(k+1)*kp*qs[k]
        kp*=1-qs[k]
    if x['type']=='endowment': A+=v**n
    return math.floor(x['benefit']*A/ann+Fraction(1,2))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limited pay term', {'q': [1116, 1354, 1667, 2034, 2465, 2963, 3571, 4298, 5197, 6274, 7556, 9080], 'n': 10, 'm': 6, 'type': 'term', 'i': 50, 'benefit': 32417307}, 1236317], ['limited pay endowment', {'q': [805, 1014, 1237, 1505, 1844, 2262, 2735, 3316, 3991, 4822, 5826, 6998], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 50, 'benefit': 53744860}, 13078746], ['full pay endowment', {'q': [1226, 1472, 1786, 2144, 2583, 3103, 3749, 4533, 5446, 6546, 7888, 9479], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 30, 'benefit': 17182267}, 2700402], ['full pay term', {'q': [636, 786, 984, 1192, 1450, 1750, 2140, 2614, 3160, 3797, 4603, 5551], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77720826}, 1517456], ['single premium', {'q': [586, 718, 878, 1062, 1306, 1614, 1972, 2399, 2899, 3512, 4240, 5126], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 23235362}, 19155246], ['pay period exceeds term', {'q': [704, 861, 1036, 1286, 1567, 1897, 2281, 2786, 3359, 4046, 4868, 5860], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 97510456}, 'invalid'], ['unknown plan type', {'q': [966, 1164, 1413, 1738, 2095, 2527, 3060, 3675, 4454, 5384, 6480, 7790], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 52803794}, 'invalid type'], ['term too long for table', {'q': [1168, 1420, 1752, 2109, 2552, 3075, 3725, 4498, 5446, 6543, 7899, 9488], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 68032420}, 'invalid']], [['limited pay term', {'q': [841, 1053, 1267, 1547, 1901, 2290, 2783, 3379, 4070, 4927, 5917, 7143], 'n': 10, 'm': 5, 'type': 'term', 'i': 40, 'benefit': 10621995}, 390243], ['limited pay endowment', {'q': [1237, 1529, 1837, 2215, 2701, 3286, 3958, 4782, 5775, 6980, 8396, 10091], 'n': 8, 'm': 4, 'type': 'endowment', 'i': 50, 'benefit': 28755476}, 5487845], ['full pay endowment', {'q': [1149, 1421, 1734, 2104, 2524, 3074, 3738, 4524, 5429, 6522, 7842, 9459], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 50, 'benefit': 68984205}, 10136985], ['full pay term', {'q': [1155, 1401, 1706, 2084, 2505, 3052, 3702, 4479, 5396, 6523, 7831, 9442], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77815499}, 2534596], ['single premium', {'q': [1488, 1827, 2210, 2701, 3269, 3941, 4765, 5757, 6948, 8343, 10034, 12042], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 10091605}, 8753895], ['pay period exceeds term', {'q': [1434, 1757, 2137, 2589, 3128, 3764, 4523, 5445, 6554, 7912, 9512, 11438], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 70676453}, 'invalid'], ['unknown plan type', {'q': [1212, 1472, 1779, 2143, 2614, 3137, 3779, 4543, 5470, 6612, 7956, 9572], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 15889609}, 'invalid type'], ['term too long for table', {'q': [663, 804, 993, 1231, 1479, 1787, 2159, 2637, 3213, 3881, 4704, 5656], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 54460124}, 'invalid']], [['limited pay term', {'q': [747, 913, 1131, 1395, 1717, 2081, 2524, 3065, 3693, 4464, 5404, 6511], 'n': 10, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 87228387}, 3048879], ['limited pay endowment', {'q': [829, 1036, 1275, 1538, 1848, 2245, 2727, 3321, 4019, 4840, 5840, 7033], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 74915366}, 12250027], ['full pay endowment', {'q': [1425, 1755, 2109, 2552, 3068, 3709, 4452, 5354, 6453, 7758, 9346, 11251], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 37157222}, 5700405], ['full pay term', {'q': [1109, 1368, 1651, 2017, 2431, 2939, 3572, 4303, 5195, 6284, 7585, 9152], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 11656982}, 367794], ['single premium', {'q': [526, 657, 804, 1002, 1248, 1531, 1861, 2269, 2740, 3321, 4011, 4832], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 36779454}, 30313184], ['pay period exceeds term', {'q': [1308, 1603, 1941, 2359, 2865, 3473, 4180, 5051, 6103, 7351, 8863, 10680], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 33579689}, 'invalid'], ['unknown plan type', {'q': [1363, 1655, 1992, 2437, 2924, 3536, 4286, 5167, 6239, 7489, 9002, 10816], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 98225689}, 'invalid type'], ['term too long for table', {'q': [1070, 1313, 1595, 1918, 2328, 2810, 3419, 4135, 5012, 6063, 7304, 8777], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 38738726}, 'invalid']], [['limited pay term', {'q': [512, 643, 815, 1003, 1212, 1489, 1831, 2210, 2664, 3227, 3916, 4712], 'n': 10, 'm': 3, 'type': 'term', 'i': 50, 'benefit': 45807977}, 1688215], ['limited pay endowment', {'q': [590, 709, 861, 1043, 1276, 1575, 1926, 2361, 2871, 3492, 4201, 5086], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 40, 'benefit': 38192191}, 9833950], ['full pay endowment', {'q': [528, 644, 806, 1014, 1235, 1482, 1819, 2204, 2655, 3234, 3922, 4713], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 71007672}, 10519104], ['full pay term', {'q': [1074, 1331, 1597, 1959, 2390, 2877, 3476, 4185, 5055, 6067, 7296, 8779], 'n': 12, 'm': 12, 'type': 'term', 'i': 30, 'benefit': 83944206}, 2733193], ['single premium', {'q': [678, 813, 994, 1206, 1488, 1828, 2220, 2693, 3274, 3956, 4750, 5720], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 89899331}, 74144103], ['pay period exceeds term', {'q': [983, 1186, 1467, 1792, 2157, 2607, 3155, 3832, 4617, 5558, 6707, 8062], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 49415695}, 'invalid'], ['unknown plan type', {'q': [730, 884, 1091, 1323, 1616, 1984, 2415, 2929, 3548, 4275, 5150, 6215], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 99033643}, 'invalid type'], ['term too long for table', {'q': [1353, 1640, 1996, 2435, 2922, 3548, 4298, 5204, 6275, 7580, 9134, 10967], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 56917171}, 'invalid']], [['limited pay term', {'q': [855, 1042, 1283, 1573, 1895, 2291, 2795, 3365, 4084, 4937, 5928, 7133], 'n': 10, 'm': 4, 'type': 'term', 'i': 30, 'benefit': 26591939}, 1254982], ['limited pay endowment', {'q': [1284, 1558, 1913, 2335, 2838, 3409, 4127, 4953, 5987, 7192, 8649, 10419], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 31636962}, 5267026], ['full pay endowment', {'q': [689, 831, 1026, 1257, 1516, 1826, 2201, 2686, 3249, 3931, 4730, 5695], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 16318284}, 2431737], ['full pay term', {'q': [631, 779, 957, 1167, 1436, 1770, 2163, 2608, 3149, 3826, 4607, 5557], 'n': 12, 'm': 12, 'type': 'term', 'i': 40, 'benefit': 14803880}, 297673], ['single premium', {'q': [1499, 1817, 2219, 2684, 3268, 3964, 4795, 5778, 6979, 8381, 10061, 12080], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 45588105}, 39545285], ['pay period exceeds term', {'q': [1089, 1329, 1604, 1944, 2381, 2862, 3441, 4130, 4970, 5966, 7192, 8664], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 16169173}, 'invalid'], ['unknown plan type', {'q': [627, 776, 934, 1161, 1422, 1733, 2096, 2520, 3024, 3638, 4377, 5280], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 97706465}, 'invalid type'], ['term too long for table', {'q': [697, 840, 1013, 1239, 1511, 1819, 2198, 2660, 3234, 3882, 4708, 5676], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 62443585}, 'invalid']]]
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
limited pay term12363171236317Passed
limited pay endowment1485292113078746Failed
full pay endowment30143262700402Failed
full pay term15174561517456Passed
single premium2000882319155246Failed
pay period exceeds terminvalidinvalidPassed
unknown plan typeinvalid typeinvalid typePassed
term too long for tableinvalidinvalidPassed

SHA-256 / 2b442ff8853c6d8ce896545744ab8fb7671c3d9709fc81c17ee0aefd22637d37

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):
    qs=[Fraction(q,100000) for q in x['q']]; n=x['n']; m=x['m']
    if m>n or m<1 or n>len(qs): return 'invalid'
    if x['type'] not in ('term','endowment'): return 'invalid type'
    v=1/(1+Fraction(x['i'],1000))
    A=Fraction(0); ann=Fraction(0); kp=Fraction(1)
    for k in range(n):
        if k<m: ann+=v**k*kp
        A+=v**(k+1)*kp*qs[k]
        kp*=1-qs[k]
    if x['type']=='endowment': A+=v**n*kp
    return math.floor(x['benefit']*A/ann+Fraction(1,2))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limited pay term', {'q': [1116, 1354, 1667, 2034, 2465, 2963, 3571, 4298, 5197, 6274, 7556, 9080], 'n': 10, 'm': 6, 'type': 'term', 'i': 50, 'benefit': 32417307}, 1236317], ['limited pay endowment', {'q': [805, 1014, 1237, 1505, 1844, 2262, 2735, 3316, 3991, 4822, 5826, 6998], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 50, 'benefit': 53744860}, 13078746], ['full pay endowment', {'q': [1226, 1472, 1786, 2144, 2583, 3103, 3749, 4533, 5446, 6546, 7888, 9479], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 30, 'benefit': 17182267}, 2700402], ['full pay term', {'q': [636, 786, 984, 1192, 1450, 1750, 2140, 2614, 3160, 3797, 4603, 5551], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77720826}, 1517456], ['single premium', {'q': [586, 718, 878, 1062, 1306, 1614, 1972, 2399, 2899, 3512, 4240, 5126], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 23235362}, 19155246], ['pay period exceeds term', {'q': [704, 861, 1036, 1286, 1567, 1897, 2281, 2786, 3359, 4046, 4868, 5860], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 97510456}, 'invalid'], ['unknown plan type', {'q': [966, 1164, 1413, 1738, 2095, 2527, 3060, 3675, 4454, 5384, 6480, 7790], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 52803794}, 'invalid type'], ['term too long for table', {'q': [1168, 1420, 1752, 2109, 2552, 3075, 3725, 4498, 5446, 6543, 7899, 9488], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 68032420}, 'invalid']], [['limited pay term', {'q': [841, 1053, 1267, 1547, 1901, 2290, 2783, 3379, 4070, 4927, 5917, 7143], 'n': 10, 'm': 5, 'type': 'term', 'i': 40, 'benefit': 10621995}, 390243], ['limited pay endowment', {'q': [1237, 1529, 1837, 2215, 2701, 3286, 3958, 4782, 5775, 6980, 8396, 10091], 'n': 8, 'm': 4, 'type': 'endowment', 'i': 50, 'benefit': 28755476}, 5487845], ['full pay endowment', {'q': [1149, 1421, 1734, 2104, 2524, 3074, 3738, 4524, 5429, 6522, 7842, 9459], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 50, 'benefit': 68984205}, 10136985], ['full pay term', {'q': [1155, 1401, 1706, 2084, 2505, 3052, 3702, 4479, 5396, 6523, 7831, 9442], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77815499}, 2534596], ['single premium', {'q': [1488, 1827, 2210, 2701, 3269, 3941, 4765, 5757, 6948, 8343, 10034, 12042], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 10091605}, 8753895], ['pay period exceeds term', {'q': [1434, 1757, 2137, 2589, 3128, 3764, 4523, 5445, 6554, 7912, 9512, 11438], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 70676453}, 'invalid'], ['unknown plan type', {'q': [1212, 1472, 1779, 2143, 2614, 3137, 3779, 4543, 5470, 6612, 7956, 9572], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 15889609}, 'invalid type'], ['term too long for table', {'q': [663, 804, 993, 1231, 1479, 1787, 2159, 2637, 3213, 3881, 4704, 5656], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 54460124}, 'invalid']], [['limited pay term', {'q': [747, 913, 1131, 1395, 1717, 2081, 2524, 3065, 3693, 4464, 5404, 6511], 'n': 10, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 87228387}, 3048879], ['limited pay endowment', {'q': [829, 1036, 1275, 1538, 1848, 2245, 2727, 3321, 4019, 4840, 5840, 7033], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 74915366}, 12250027], ['full pay endowment', {'q': [1425, 1755, 2109, 2552, 3068, 3709, 4452, 5354, 6453, 7758, 9346, 11251], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 37157222}, 5700405], ['full pay term', {'q': [1109, 1368, 1651, 2017, 2431, 2939, 3572, 4303, 5195, 6284, 7585, 9152], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 11656982}, 367794], ['single premium', {'q': [526, 657, 804, 1002, 1248, 1531, 1861, 2269, 2740, 3321, 4011, 4832], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 36779454}, 30313184], ['pay period exceeds term', {'q': [1308, 1603, 1941, 2359, 2865, 3473, 4180, 5051, 6103, 7351, 8863, 10680], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 33579689}, 'invalid'], ['unknown plan type', {'q': [1363, 1655, 1992, 2437, 2924, 3536, 4286, 5167, 6239, 7489, 9002, 10816], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 98225689}, 'invalid type'], ['term too long for table', {'q': [1070, 1313, 1595, 1918, 2328, 2810, 3419, 4135, 5012, 6063, 7304, 8777], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 38738726}, 'invalid']], [['limited pay term', {'q': [512, 643, 815, 1003, 1212, 1489, 1831, 2210, 2664, 3227, 3916, 4712], 'n': 10, 'm': 3, 'type': 'term', 'i': 50, 'benefit': 45807977}, 1688215], ['limited pay endowment', {'q': [590, 709, 861, 1043, 1276, 1575, 1926, 2361, 2871, 3492, 4201, 5086], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 40, 'benefit': 38192191}, 9833950], ['full pay endowment', {'q': [528, 644, 806, 1014, 1235, 1482, 1819, 2204, 2655, 3234, 3922, 4713], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 71007672}, 10519104], ['full pay term', {'q': [1074, 1331, 1597, 1959, 2390, 2877, 3476, 4185, 5055, 6067, 7296, 8779], 'n': 12, 'm': 12, 'type': 'term', 'i': 30, 'benefit': 83944206}, 2733193], ['single premium', {'q': [678, 813, 994, 1206, 1488, 1828, 2220, 2693, 3274, 3956, 4750, 5720], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 89899331}, 74144103], ['pay period exceeds term', {'q': [983, 1186, 1467, 1792, 2157, 2607, 3155, 3832, 4617, 5558, 6707, 8062], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 49415695}, 'invalid'], ['unknown plan type', {'q': [730, 884, 1091, 1323, 1616, 1984, 2415, 2929, 3548, 4275, 5150, 6215], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 99033643}, 'invalid type'], ['term too long for table', {'q': [1353, 1640, 1996, 2435, 2922, 3548, 4298, 5204, 6275, 7580, 9134, 10967], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 56917171}, 'invalid']], [['limited pay term', {'q': [855, 1042, 1283, 1573, 1895, 2291, 2795, 3365, 4084, 4937, 5928, 7133], 'n': 10, 'm': 4, 'type': 'term', 'i': 30, 'benefit': 26591939}, 1254982], ['limited pay endowment', {'q': [1284, 1558, 1913, 2335, 2838, 3409, 4127, 4953, 5987, 7192, 8649, 10419], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 31636962}, 5267026], ['full pay endowment', {'q': [689, 831, 1026, 1257, 1516, 1826, 2201, 2686, 3249, 3931, 4730, 5695], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 16318284}, 2431737], ['full pay term', {'q': [631, 779, 957, 1167, 1436, 1770, 2163, 2608, 3149, 3826, 4607, 5557], 'n': 12, 'm': 12, 'type': 'term', 'i': 40, 'benefit': 14803880}, 297673], ['single premium', {'q': [1499, 1817, 2219, 2684, 3268, 3964, 4795, 5778, 6979, 8381, 10061, 12080], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 45588105}, 39545285], ['pay period exceeds term', {'q': [1089, 1329, 1604, 1944, 2381, 2862, 3441, 4130, 4970, 5966, 7192, 8664], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 16169173}, 'invalid'], ['unknown plan type', {'q': [627, 776, 934, 1161, 1422, 1733, 2096, 2520, 3024, 3638, 4377, 5280], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 97706465}, 'invalid type'], ['term too long for table', {'q': [697, 840, 1013, 1239, 1511, 1819, 2198, 2660, 3234, 3882, 4708, 5676], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 62443585}, 'invalid']]]
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
limited pay term12363171236317Passed
limited pay endowment1307874613078746Passed
full pay endowment27004022700402Passed
full pay term15174561517456Passed
single premium1915524619155246Passed
pay period exceeds terminvalidinvalidPassed
unknown plan typeinvalid typeinvalid typePassed
term too long for tableinvalidinvalidPassed

SHA-256 / 0d64f6383f387abbefc1e2298ce7be85ea21fe43c4684d563834fa7bd0cff405

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

Case digest / fc08840fa2c1527e539e4d284c78e94bf20c4d52678989972df0adb8af604a25