FAILURE MAP
← Case archive

FA-65476 / Ecological population dynamics / Open access

Cohort life table statistics: survivorship accumulation · case 01

Survivorship rises again after a bad year.

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

ROOT CAUSE

Annual survival probabilities are used directly as cumulative survivorship.

VERIFIED REPAIR

Restore the survivorship accumulation rule: `l.append(l[-1] * px[x - 1])`.

Unsuccessful approach: Clamping to the previous survivorship keeps the curve monotone but still is not the cumulative product.

Case contract

l0=1 and l[x+1]=l[x]*px[x]; R0=sum l[x]*mx[x]; generation time T=sum x*l[x]*mx[x]/R0; r=ln(R0)/T (None if T=0); e0 = sum over x of (l[x]+l[x+1])/2; return [R0, T, r, e0] rounded 6 with [0.0, None, None, e0] when R0=0; None for empty or mismatched schedules.

Why this case matters

Population projections set harvest quotas, conservation status and pest-control timing; a wrong update order, boundary or rate conversion silently changes management advice.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(px, mx):
    n = len(px)
    if n == 0 or len(mx) != n:
        return None
    l = [1.0]
    for x in range(1, n + 1):
        l.append(px[x - 1])
    e0 = round(sum((l[x] + l[x + 1]) / 2 for x in range(n)), 6)
    r0 = sum(l[x] * mx[x] for x in range(n))
    if r0 <= 0:
        return [0.0, None, None, e0]
    gen = sum(x * l[x] * mx[x] for x in range(n)) / r0
    rate = math.log(r0) / gen if gen > 0 else None
    return [round(r0, 6), round(gen, 6), None if rate is None else round(rate, 6), e0]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])]]
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
regression: songbird[2.85, 2.263158, 0.462769, 2.25][1.026, 1.77193, 0.014486, 1.115]Failed
regression: perennial plant[18.4, 3.173913, 0.91759, 3.2][1.4944, 3.079229, 0.130463, 0.8168]Failed
regression: replacement cohort[2.0, 1.0, 0.693147, 1.25][2.0, 1.0, 0.693147, 1.125]Failed
regression: age zero breeding only[1.5, 0.0, None, 1.1][1.5, 0.0, None, 1.05]Failed
regression: sterile cohort[0.0, None, None, 1.85][0.0, None, None, 1.805]Failed
control: mismatched schedulesNoneNonePassed
control: annual insect[1.5, 1.0, 0.405465, 0.55][1.5, 1.0, 0.405465, 0.55]Passed

SHA-256 / a80ef983f52165ce1c4eb637f6a3e60d87f8d0ebe30f2f9b07b39da8de84a3e3

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(px, mx):
    n = len(px)
    if n == 0 or len(mx) != n:
        return None
    l = [1.0]
    for x in range(1, n + 1):
        l.append(min(l[-1], px[x - 1]))
    e0 = round(sum((l[x] + l[x + 1]) / 2 for x in range(n)), 6)
    r0 = sum(l[x] * mx[x] for x in range(n))
    if r0 <= 0:
        return [0.0, None, None, e0]
    gen = sum(x * l[x] * mx[x] for x in range(n)) / r0
    rate = math.log(r0) / gen if gen > 0 else None
    return [round(r0, 6), round(gen, 6), None if rate is None else round(rate, 6), e0]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])]]
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
regression: songbird[1.65, 2.090909, 0.239501, 1.55][1.026, 1.77193, 0.014486, 1.115]Failed
regression: perennial plant[2.1, 3.142857, 0.236071, 0.9][1.4944, 3.079229, 0.130463, 0.8168]Failed
regression: replacement cohort[2.0, 1.0, 0.693147, 1.25][2.0, 1.0, 0.693147, 1.125]Failed
regression: age zero breeding only[1.5, 0.0, None, 1.1][1.5, 0.0, None, 1.05]Failed
regression: sterile cohort[0.0, None, None, 1.85][0.0, None, None, 1.805]Failed
control: mismatched schedulesNoneNonePassed
control: annual insect[1.5, 1.0, 0.405465, 0.55][1.5, 1.0, 0.405465, 0.55]Passed

SHA-256 / b9505d8f9b0a33bc28c49f4caf9a51df2b4a7d7a7a2c01886b170219d8afcf92

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(px, mx):
    n = len(px)
    if n == 0 or len(mx) != n:
        return None
    l = [1.0]
    for x in range(1, n + 1):
        l.append(l[-1] * px[x - 1])
    e0 = round(sum((l[x] + l[x + 1]) / 2 for x in range(n)), 6)
    r0 = sum(l[x] * mx[x] for x in range(n))
    if r0 <= 0:
        return [0.0, None, None, e0]
    gen = sum(x * l[x] * mx[x] for x in range(n)) / r0
    rate = math.log(r0) / gen if gen > 0 else None
    return [round(r0, 6), round(gen, 6), None if rate is None else round(rate, 6), e0]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: age zero breeding only', ([0.5, 0.2], [1.5, 0.0]), [1.5, 0.0, None, 1.05]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])],
 [('regression: songbird', ([0.3, 0.6, 0.6, 0.5], [0.0, 1.5, 2.0, 2.0]), [1.026, 1.77193, 0.014486, 1.115]),
  ('regression: perennial plant',
   ([0.1, 0.8, 0.9, 0.9, 0.0], [0.0, 0.0, 5.0, 8.0, 8.0]),
   [1.4944, 3.079229, 0.130463, 0.8168]),
  ('regression: replacement cohort', ([0.5, 0.5], [0.0, 4.0]), [2.0, 1.0, 0.693147, 1.125]),
  ('regression: sterile cohort', ([0.9, 0.9], [0.0, 0.0]), [0.0, None, None, 1.805]),
  ('control: mismatched schedules', ([0.5], [0.0, 1.0]), None),
  ('control: annual insect', ([0.05, 0.0], [0.0, 30.0]), [1.5, 1.0, 0.405465, 0.55]),
  ('regression: long-lived',
   ([0.95, 0.95, 0.95, 0.95, 0.95, 0.9], [0.0, 0.0, 0.2, 0.4, 0.4, 0.4]),
   [1.158765, 3.659605, 0.040265, 5.146364])]]
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
regression: songbird[1.026, 1.77193, 0.014486, 1.115][1.026, 1.77193, 0.014486, 1.115]Passed
regression: perennial plant[1.4944, 3.079229, 0.130463, 0.8168][1.4944, 3.079229, 0.130463, 0.8168]Passed
regression: replacement cohort[2.0, 1.0, 0.693147, 1.125][2.0, 1.0, 0.693147, 1.125]Passed
regression: age zero breeding only[1.5, 0.0, None, 1.05][1.5, 0.0, None, 1.05]Passed
regression: sterile cohort[0.0, None, None, 1.805][0.0, None, None, 1.805]Passed
control: mismatched schedulesNoneNonePassed
control: annual insect[1.5, 1.0, 0.405465, 0.55][1.5, 1.0, 0.405465, 0.55]Passed

SHA-256 / 5e19de3f8be7aacfaf2ed8579c45191c94403727b825f5272b609f79c7357ffd

Verification & scope

Deterministic bounded teaching model with a stipulated contract; not a validated scientific or public-health modelling library. 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:34.407125+00:00.

Case digest / 210d71543d560e5783a4e61de7cf59af93f26e25922d7bcef04eeef5f2d146ee