FA-63391 / Actuarial life tables / Open access
Fractional age survival assumptions: UDD force of mortality ignores the elapsed fraction · case 01
The UDD hazard is flat within the year.
ROOT CAUSE
mu is taken as q instead of q/(1-tq).
VERIFIED REPAIR
Use q/(1-t*q).
Unsuccessful approach: Using the full-year survivor denominator is only right at t=1.
Case contract
Input q (per 100000), t as [num, den] in [0,1], assumption udd|cfm|balducci. UDD: tp=1-tq, mu=q/(1-tq); constant force: tp=p^t, mu=-ln p; Balducci: tp=p/(1-(1-t)q), mu=q/(1-(1-t)q). Out-of-range -> 'invalid'; infinite force -> 'infinite force'; other -> 'unknown assumption'. Return [tp, mu] rounded to 8 places.
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):
q=Fraction(x['q'],100000); t=Fraction(*x['t']); a=x['assumption']
if t<0 or t>1 or q<0 or q>1: return 'invalid'
p=1-q
if a=='udd':
tp=1-t*q; mu=q if 1-t*q else None
elif a=='cfm':
if p==0: return 'infinite force'
tp=Fraction(float(p)**float(t)); mu=-math.log(p)
elif a=='balducci':
tp=p/(1-(1-t)*q)
mu=q/(1-(1-t)*q)
else:
return 'unknown assumption'
if mu is None: return 'infinite force'
return [round(float(tp),8),round(float(mu),8)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['udd mid-year', {'q': 3964, 't': [1, 4], 'assumption': 'udd'}, [0.99009, 0.04003676]], ['udd third of year', {'q': 57411, 't': [1, 3], 'assumption': 'udd'}, [0.80863, 0.70997861]], ['cfm mid-year', {'q': 31716, 't': [3, 4], 'assumption': 'cfm'}, [0.7511717, 0.38149471]], ['cfm third of year', {'q': 35719, 't': [1, 3], 'assumption': 'cfm'}, [0.86303328, 0.44190609]], ['balducci mid-year', {'q': 2891, 't': [2, 4], 'assumption': 'balducci'}, [0.98533299, 0.02933402]], ['balducci third of year', {'q': 37692, 't': [1, 3], 'assumption': 'balducci'}, [0.83219361, 0.50341917]], ['udd full year', {'q': 34482, 't': [1, 1], 'assumption': 'udd'}, [0.65518, 0.52629812]], ['cfm at start', {'q': 29787, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.35363671]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 38019, 't': [2, 4], 'assumption': 'udd'}, [0.809905, 0.46942543]], ['udd third of year', {'q': 44263, 't': [1, 3], 'assumption': 'udd'}, [0.85245667, 0.51924047]], ['cfm mid-year', {'q': 36269, 't': [2, 4], 'assumption': 'cfm'}, [0.79831698, 0.45049909]], ['cfm third of year', {'q': 41961, 't': [1, 3], 'assumption': 'cfm'}, [0.83414197, 0.54405499]], ['balducci mid-year', {'q': 22422, 't': [2, 4], 'assumption': 'balducci'}, [0.87373436, 0.25253128]], ['balducci third of year', {'q': 25020, 't': [1, 3], 'assumption': 'balducci'}, [0.89990398, 0.30028805]], ['udd full year', {'q': 37371, 't': [1, 1], 'assumption': 'udd'}, [0.62629, 0.5967044]], ['cfm at start', {'q': 12769, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.13661041]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 7646, 't': [2, 4], 'assumption': 'udd'}, [0.96177, 0.07949926]], ['udd third of year', {'q': 30081, 't': [1, 3], 'assumption': 'udd'}, [0.89973, 0.33433363]], ['cfm mid-year', {'q': 8794, 't': [2, 4], 'assumption': 'cfm'}, [0.95501832, 0.0920495]], ['cfm third of year', {'q': 26692, 't': [1, 3], 'assumption': 'cfm'}, [0.90167589, 0.31050044]], ['balducci mid-year', {'q': 6887, 't': [1, 4], 'assumption': 'balducci'}, [0.98184474, 0.07262106]], ['balducci third of year', {'q': 38785, 't': [1, 3], 'assumption': 'balducci'}, [0.82563054, 0.52310839]], ['udd full year', {'q': 23553, 't': [1, 1], 'assumption': 'udd'}, [0.76447, 0.3080958]], ['cfm at start', {'q': 30697, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.36668199]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 31223, 't': [3, 4], 'assumption': 'udd'}, [0.7658275, 0.40770278]], ['udd third of year', {'q': 27799, 't': [1, 3], 'assumption': 'udd'}, [0.90733667, 0.30638021]], ['cfm mid-year', {'q': 5158, 't': [3, 4], 'assumption': 'cfm'}, [0.96106006, 0.05295784]], ['cfm third of year', {'q': 20081, 't': [1, 3], 'assumption': 'cfm'}, [0.92800435, 0.22415656]], ['balducci mid-year', {'q': 2076, 't': [2, 4], 'assumption': 'balducci'}, [0.98951113, 0.02097775]], ['balducci third of year', {'q': 51959, 't': [1, 3], 'assumption': 'balducci'}, [0.73501392, 0.79495823]], ['udd full year', {'q': 28689, 't': [1, 1], 'assumption': 'udd'}, [0.71311, 0.4023082]], ['cfm at start', {'q': 30130, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.35853381]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 3152, 't': [2, 4], 'assumption': 'udd'}, [0.98424, 0.03202471]], ['udd third of year', {'q': 29489, 't': [1, 3], 'assumption': 'udd'}, [0.90170333, 0.32703661]], ['cfm mid-year', {'q': 34830, 't': [1, 4], 'assumption': 'cfm'}, [0.89848727, 0.42817095]], ['cfm third of year', {'q': 57603, 't': [1, 3], 'assumption': 'cfm'}, [0.75123943, 0.85809258]], ['balducci mid-year', {'q': 37115, 't': [3, 4], 'assumption': 'balducci'}, [0.69316726, 0.40911032]], ['balducci third of year', {'q': 20896, 't': [1, 3], 'assumption': 'balducci'}, [0.919073, 0.24278101]], ['udd full year', {'q': 24445, 't': [1, 1], 'assumption': 'udd'}, [0.75555, 0.32353914]], ['cfm at start', {'q': 24358, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.2791585]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']]]
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 |
|---|---|---|---|
| udd mid-year | [0.99009, 0.03964] | [0.99009, 0.04003676] | Failed |
| udd third of year | [0.80863, 0.57411] | [0.80863, 0.70997861] | Failed |
| cfm mid-year | [0.7511717, 0.38149471] | [0.7511717, 0.38149471] | Passed |
| cfm third of year | [0.86303328, 0.44190609] | [0.86303328, 0.44190609] | Passed |
| balducci mid-year | [0.98533299, 0.02933402] | [0.98533299, 0.02933402] | Passed |
| balducci third of year | [0.83219361, 0.50341917] | [0.83219361, 0.50341917] | Passed |
| udd full year | [0.65518, 0.34482] | [0.65518, 0.52629812] | Failed |
| cfm at start | [1.0, 0.35363671] | [1.0, 0.35363671] | Passed |
| udd terminal year | [0.5, 1.0] | [0.5, 2.0] | Failed |
| cfm terminal year | infinite force | infinite force | Passed |
| beyond one year rejected | invalid | invalid | Passed |
| unknown assumption | unknown assumption | unknown assumption | Passed |
SHA-256 / cd962abc016381b58ab77ed8f946125320e8a78512ad08e79a753067e4217823
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):
q=Fraction(x['q'],100000); t=Fraction(*x['t']); a=x['assumption']
if t<0 or t>1 or q<0 or q>1: return 'invalid'
p=1-q
if a=='udd':
tp=1-t*q; mu=q/(1-q) if 1-q else None
elif a=='cfm':
if p==0: return 'infinite force'
tp=Fraction(float(p)**float(t)); mu=-math.log(p)
elif a=='balducci':
tp=p/(1-(1-t)*q)
mu=q/(1-(1-t)*q)
else:
return 'unknown assumption'
if mu is None: return 'infinite force'
return [round(float(tp),8),round(float(mu),8)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['udd mid-year', {'q': 3964, 't': [1, 4], 'assumption': 'udd'}, [0.99009, 0.04003676]], ['udd third of year', {'q': 57411, 't': [1, 3], 'assumption': 'udd'}, [0.80863, 0.70997861]], ['cfm mid-year', {'q': 31716, 't': [3, 4], 'assumption': 'cfm'}, [0.7511717, 0.38149471]], ['cfm third of year', {'q': 35719, 't': [1, 3], 'assumption': 'cfm'}, [0.86303328, 0.44190609]], ['balducci mid-year', {'q': 2891, 't': [2, 4], 'assumption': 'balducci'}, [0.98533299, 0.02933402]], ['balducci third of year', {'q': 37692, 't': [1, 3], 'assumption': 'balducci'}, [0.83219361, 0.50341917]], ['udd full year', {'q': 34482, 't': [1, 1], 'assumption': 'udd'}, [0.65518, 0.52629812]], ['cfm at start', {'q': 29787, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.35363671]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 38019, 't': [2, 4], 'assumption': 'udd'}, [0.809905, 0.46942543]], ['udd third of year', {'q': 44263, 't': [1, 3], 'assumption': 'udd'}, [0.85245667, 0.51924047]], ['cfm mid-year', {'q': 36269, 't': [2, 4], 'assumption': 'cfm'}, [0.79831698, 0.45049909]], ['cfm third of year', {'q': 41961, 't': [1, 3], 'assumption': 'cfm'}, [0.83414197, 0.54405499]], ['balducci mid-year', {'q': 22422, 't': [2, 4], 'assumption': 'balducci'}, [0.87373436, 0.25253128]], ['balducci third of year', {'q': 25020, 't': [1, 3], 'assumption': 'balducci'}, [0.89990398, 0.30028805]], ['udd full year', {'q': 37371, 't': [1, 1], 'assumption': 'udd'}, [0.62629, 0.5967044]], ['cfm at start', {'q': 12769, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.13661041]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 7646, 't': [2, 4], 'assumption': 'udd'}, [0.96177, 0.07949926]], ['udd third of year', {'q': 30081, 't': [1, 3], 'assumption': 'udd'}, [0.89973, 0.33433363]], ['cfm mid-year', {'q': 8794, 't': [2, 4], 'assumption': 'cfm'}, [0.95501832, 0.0920495]], ['cfm third of year', {'q': 26692, 't': [1, 3], 'assumption': 'cfm'}, [0.90167589, 0.31050044]], ['balducci mid-year', {'q': 6887, 't': [1, 4], 'assumption': 'balducci'}, [0.98184474, 0.07262106]], ['balducci third of year', {'q': 38785, 't': [1, 3], 'assumption': 'balducci'}, [0.82563054, 0.52310839]], ['udd full year', {'q': 23553, 't': [1, 1], 'assumption': 'udd'}, [0.76447, 0.3080958]], ['cfm at start', {'q': 30697, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.36668199]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 31223, 't': [3, 4], 'assumption': 'udd'}, [0.7658275, 0.40770278]], ['udd third of year', {'q': 27799, 't': [1, 3], 'assumption': 'udd'}, [0.90733667, 0.30638021]], ['cfm mid-year', {'q': 5158, 't': [3, 4], 'assumption': 'cfm'}, [0.96106006, 0.05295784]], ['cfm third of year', {'q': 20081, 't': [1, 3], 'assumption': 'cfm'}, [0.92800435, 0.22415656]], ['balducci mid-year', {'q': 2076, 't': [2, 4], 'assumption': 'balducci'}, [0.98951113, 0.02097775]], ['balducci third of year', {'q': 51959, 't': [1, 3], 'assumption': 'balducci'}, [0.73501392, 0.79495823]], ['udd full year', {'q': 28689, 't': [1, 1], 'assumption': 'udd'}, [0.71311, 0.4023082]], ['cfm at start', {'q': 30130, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.35853381]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 3152, 't': [2, 4], 'assumption': 'udd'}, [0.98424, 0.03202471]], ['udd third of year', {'q': 29489, 't': [1, 3], 'assumption': 'udd'}, [0.90170333, 0.32703661]], ['cfm mid-year', {'q': 34830, 't': [1, 4], 'assumption': 'cfm'}, [0.89848727, 0.42817095]], ['cfm third of year', {'q': 57603, 't': [1, 3], 'assumption': 'cfm'}, [0.75123943, 0.85809258]], ['balducci mid-year', {'q': 37115, 't': [3, 4], 'assumption': 'balducci'}, [0.69316726, 0.40911032]], ['balducci third of year', {'q': 20896, 't': [1, 3], 'assumption': 'balducci'}, [0.919073, 0.24278101]], ['udd full year', {'q': 24445, 't': [1, 1], 'assumption': 'udd'}, [0.75555, 0.32353914]], ['cfm at start', {'q': 24358, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.2791585]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']]]
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 |
|---|---|---|---|
| udd mid-year | [0.99009, 0.04127619] | [0.99009, 0.04003676] | Failed |
| udd third of year | [0.80863, 1.34802414] | [0.80863, 0.70997861] | Failed |
| cfm mid-year | [0.7511717, 0.38149471] | [0.7511717, 0.38149471] | Passed |
| cfm third of year | [0.86303328, 0.44190609] | [0.86303328, 0.44190609] | Passed |
| balducci mid-year | [0.98533299, 0.02933402] | [0.98533299, 0.02933402] | Passed |
| balducci third of year | [0.83219361, 0.50341917] | [0.83219361, 0.50341917] | Passed |
| udd full year | [0.65518, 0.52629812] | [0.65518, 0.52629812] | Passed |
| cfm at start | [1.0, 0.35363671] | [1.0, 0.35363671] | Passed |
| udd terminal year | infinite force | [0.5, 2.0] | Failed |
| cfm terminal year | infinite force | infinite force | Passed |
| beyond one year rejected | invalid | invalid | Passed |
| unknown assumption | unknown assumption | unknown assumption | Passed |
SHA-256 / c095937cbb6758f3a9ff438dc7e2c2c7962f29083d2e84f86a842635082ab7ea
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):
q=Fraction(x['q'],100000); t=Fraction(*x['t']); a=x['assumption']
if t<0 or t>1 or q<0 or q>1: return 'invalid'
p=1-q
if a=='udd':
tp=1-t*q; mu=q/(1-t*q) if 1-t*q else None
elif a=='cfm':
if p==0: return 'infinite force'
tp=Fraction(float(p)**float(t)); mu=-math.log(p)
elif a=='balducci':
tp=p/(1-(1-t)*q)
mu=q/(1-(1-t)*q)
else:
return 'unknown assumption'
if mu is None: return 'infinite force'
return [round(float(tp),8),round(float(mu),8)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['udd mid-year', {'q': 3964, 't': [1, 4], 'assumption': 'udd'}, [0.99009, 0.04003676]], ['udd third of year', {'q': 57411, 't': [1, 3], 'assumption': 'udd'}, [0.80863, 0.70997861]], ['cfm mid-year', {'q': 31716, 't': [3, 4], 'assumption': 'cfm'}, [0.7511717, 0.38149471]], ['cfm third of year', {'q': 35719, 't': [1, 3], 'assumption': 'cfm'}, [0.86303328, 0.44190609]], ['balducci mid-year', {'q': 2891, 't': [2, 4], 'assumption': 'balducci'}, [0.98533299, 0.02933402]], ['balducci third of year', {'q': 37692, 't': [1, 3], 'assumption': 'balducci'}, [0.83219361, 0.50341917]], ['udd full year', {'q': 34482, 't': [1, 1], 'assumption': 'udd'}, [0.65518, 0.52629812]], ['cfm at start', {'q': 29787, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.35363671]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 38019, 't': [2, 4], 'assumption': 'udd'}, [0.809905, 0.46942543]], ['udd third of year', {'q': 44263, 't': [1, 3], 'assumption': 'udd'}, [0.85245667, 0.51924047]], ['cfm mid-year', {'q': 36269, 't': [2, 4], 'assumption': 'cfm'}, [0.79831698, 0.45049909]], ['cfm third of year', {'q': 41961, 't': [1, 3], 'assumption': 'cfm'}, [0.83414197, 0.54405499]], ['balducci mid-year', {'q': 22422, 't': [2, 4], 'assumption': 'balducci'}, [0.87373436, 0.25253128]], ['balducci third of year', {'q': 25020, 't': [1, 3], 'assumption': 'balducci'}, [0.89990398, 0.30028805]], ['udd full year', {'q': 37371, 't': [1, 1], 'assumption': 'udd'}, [0.62629, 0.5967044]], ['cfm at start', {'q': 12769, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.13661041]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 7646, 't': [2, 4], 'assumption': 'udd'}, [0.96177, 0.07949926]], ['udd third of year', {'q': 30081, 't': [1, 3], 'assumption': 'udd'}, [0.89973, 0.33433363]], ['cfm mid-year', {'q': 8794, 't': [2, 4], 'assumption': 'cfm'}, [0.95501832, 0.0920495]], ['cfm third of year', {'q': 26692, 't': [1, 3], 'assumption': 'cfm'}, [0.90167589, 0.31050044]], ['balducci mid-year', {'q': 6887, 't': [1, 4], 'assumption': 'balducci'}, [0.98184474, 0.07262106]], ['balducci third of year', {'q': 38785, 't': [1, 3], 'assumption': 'balducci'}, [0.82563054, 0.52310839]], ['udd full year', {'q': 23553, 't': [1, 1], 'assumption': 'udd'}, [0.76447, 0.3080958]], ['cfm at start', {'q': 30697, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.36668199]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 31223, 't': [3, 4], 'assumption': 'udd'}, [0.7658275, 0.40770278]], ['udd third of year', {'q': 27799, 't': [1, 3], 'assumption': 'udd'}, [0.90733667, 0.30638021]], ['cfm mid-year', {'q': 5158, 't': [3, 4], 'assumption': 'cfm'}, [0.96106006, 0.05295784]], ['cfm third of year', {'q': 20081, 't': [1, 3], 'assumption': 'cfm'}, [0.92800435, 0.22415656]], ['balducci mid-year', {'q': 2076, 't': [2, 4], 'assumption': 'balducci'}, [0.98951113, 0.02097775]], ['balducci third of year', {'q': 51959, 't': [1, 3], 'assumption': 'balducci'}, [0.73501392, 0.79495823]], ['udd full year', {'q': 28689, 't': [1, 1], 'assumption': 'udd'}, [0.71311, 0.4023082]], ['cfm at start', {'q': 30130, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.35853381]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']], [['udd mid-year', {'q': 3152, 't': [2, 4], 'assumption': 'udd'}, [0.98424, 0.03202471]], ['udd third of year', {'q': 29489, 't': [1, 3], 'assumption': 'udd'}, [0.90170333, 0.32703661]], ['cfm mid-year', {'q': 34830, 't': [1, 4], 'assumption': 'cfm'}, [0.89848727, 0.42817095]], ['cfm third of year', {'q': 57603, 't': [1, 3], 'assumption': 'cfm'}, [0.75123943, 0.85809258]], ['balducci mid-year', {'q': 37115, 't': [3, 4], 'assumption': 'balducci'}, [0.69316726, 0.40911032]], ['balducci third of year', {'q': 20896, 't': [1, 3], 'assumption': 'balducci'}, [0.919073, 0.24278101]], ['udd full year', {'q': 24445, 't': [1, 1], 'assumption': 'udd'}, [0.75555, 0.32353914]], ['cfm at start', {'q': 24358, 't': [0, 1], 'assumption': 'cfm'}, [1.0, 0.2791585]], ['udd terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'udd'}, [0.5, 2.0]], ['cfm terminal year', {'q': 100000, 't': [1, 2], 'assumption': 'cfm'}, 'infinite force'], ['beyond one year rejected', {'q': 1000, 't': [5, 4], 'assumption': 'udd'}, 'invalid'], ['unknown assumption', {'q': 1000, 't': [1, 2], 'assumption': 'gompertz'}, 'unknown assumption']]]
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 |
|---|---|---|---|
| udd mid-year | [0.99009, 0.04003676] | [0.99009, 0.04003676] | Passed |
| udd third of year | [0.80863, 0.70997861] | [0.80863, 0.70997861] | Passed |
| cfm mid-year | [0.7511717, 0.38149471] | [0.7511717, 0.38149471] | Passed |
| cfm third of year | [0.86303328, 0.44190609] | [0.86303328, 0.44190609] | Passed |
| balducci mid-year | [0.98533299, 0.02933402] | [0.98533299, 0.02933402] | Passed |
| balducci third of year | [0.83219361, 0.50341917] | [0.83219361, 0.50341917] | Passed |
| udd full year | [0.65518, 0.52629812] | [0.65518, 0.52629812] | Passed |
| cfm at start | [1.0, 0.35363671] | [1.0, 0.35363671] | Passed |
| udd terminal year | [0.5, 2.0] | [0.5, 2.0] | Passed |
| cfm terminal year | infinite force | infinite force | Passed |
| beyond one year rejected | invalid | invalid | Passed |
| unknown assumption | unknown assumption | unknown assumption | Passed |
SHA-256 / 3aa6b71ce13e9c739fe19f7944e519251863753c3626bbd8c982dafb8886e46f
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:13.914674+00:00.
Case digest / e1457c2117d8cf42db319ec77abf65cf1a641f9e400ff3c3f8eec9a255cdadc6