FA-65716 / Ecological population dynamics / Open access
Two-pass removal abundance estimate: estimator numerator · case 01
Abundance is underestimated and becomes zero when the second pass is empty.
ROOT CAUSE
The numerator uses c1*c2 instead of c1^2.
VERIFIED REPAIR
Restore the estimator numerator rule: `n_hat = c1 * c1 / (c1 - c2)`.
Unsuccessful approach: Dividing by the total catch confuses removal with pooled counts.
Case contract
N = c1^2/(c1-c2), p = (c1-c2)/c1, var = c1^2*c2^2*(c1+c2)/(c1-c2)^4 rounded [2, 4, 2]; [None, None, None] when c1<=c2; None for negative catches.
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(c1, c2):
if c1 < 0 or c2 < 0:
return None
if c1 <= c2:
return [None, None, None]
n_hat = c1 * c2 / (c1 - c2)
p_hat = (c1 - c2) / c1
var = c1 ** 2 * c2 ** 2 * (c1 + c2) / (c1 - c2) ** 4
return [round(n_hat, 2), round(p_hat, 4), round(var, 2)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('regression: weak depletion', (40, 32), [200.0, 0.2, 28800.0]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('control: no depletion', (30, 30), [None, None, None]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('regression: weak depletion', (40, 32), [200.0, 0.2, 28800.0]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])]]
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 |
|---|---|---|---|
| regression: stream electrofishing | [42.86, 0.5833, 127.45] | [102.86, 0.5833, 127.45] | Failed |
| regression: efficient first pass | [11.25, 0.8889, 1.98] | [101.25, 0.8889, 1.98] | Failed |
| regression: weak depletion | [160.0, 0.2, 28800.0] | [200.0, 0.2, 28800.0] | Failed |
| control: no depletion | [None, None, None] | [None, None, None] | Passed |
| regression: second pass empty | [0.0, 1.0, 0.0] | [45.0, 1.0, 0.0] | Failed |
| control: negative catch | None | None | Passed |
| control: increasing catch | [None, None, None] | [None, None, None] | Passed |
SHA-256 / a3e2e6b2de381b40fcf593a8225b43dc1624d798cf8b82b11d59e5a1eba8e557
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(c1, c2):
if c1 < 0 or c2 < 0:
return None
if c1 <= c2:
return [None, None, None]
n_hat = c1 * c1 / (c1 + c2)
p_hat = (c1 - c2) / c1
var = c1 ** 2 * c2 ** 2 * (c1 + c2) / (c1 - c2) ** 4
return [round(n_hat, 2), round(p_hat, 4), round(var, 2)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('regression: weak depletion', (40, 32), [200.0, 0.2, 28800.0]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('control: no depletion', (30, 30), [None, None, None]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('regression: weak depletion', (40, 32), [200.0, 0.2, 28800.0]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])]]
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 |
|---|---|---|---|
| regression: stream electrofishing | [42.35, 0.5833, 127.45] | [102.86, 0.5833, 127.45] | Failed |
| regression: efficient first pass | [81.0, 0.8889, 1.98] | [101.25, 0.8889, 1.98] | Failed |
| regression: weak depletion | [22.22, 0.2, 28800.0] | [200.0, 0.2, 28800.0] | Failed |
| control: no depletion | [None, None, None] | [None, None, None] | Passed |
| regression: second pass empty | [45.0, 1.0, 0.0] | [45.0, 1.0, 0.0] | Passed |
| control: negative catch | None | None | Passed |
| control: increasing catch | [None, None, None] | [None, None, None] | Passed |
SHA-256 / a1d3aeff9482965088f9323d75cddd982ef64b41c9a814fd8ebbd9e382cfa038
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(c1, c2):
if c1 < 0 or c2 < 0:
return None
if c1 <= c2:
return [None, None, None]
n_hat = c1 * c1 / (c1 - c2)
p_hat = (c1 - c2) / c1
var = c1 ** 2 * c2 ** 2 * (c1 + c2) / (c1 - c2) ** 4
return [round(n_hat, 2), round(p_hat, 4), round(var, 2)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('regression: weak depletion', (40, 32), [200.0, 0.2, 28800.0]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('control: no depletion', (30, 30), [None, None, None]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('regression: efficient first pass', (90, 10), [101.25, 0.8889, 1.98]),
('regression: weak depletion', (40, 32), [200.0, 0.2, 28800.0]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None])],
[('regression: stream electrofishing', (60, 25), [102.86, 0.5833, 127.45]),
('control: no depletion', (30, 30), [None, None, None]),
('regression: second pass empty', (45, 0), [45.0, 1.0, 0.0]),
('control: negative catch', (-1, 3), None),
('control: increasing catch', (20, 25), [None, None, None]),
('regression: small stream', (12, 5), [20.57, 0.5833, 25.49]),
('regression: large lake', (300, 140), [562.5, 0.5333, 1184.33])]]
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 |
|---|---|---|---|
| regression: stream electrofishing | [102.86, 0.5833, 127.45] | [102.86, 0.5833, 127.45] | Passed |
| regression: efficient first pass | [101.25, 0.8889, 1.98] | [101.25, 0.8889, 1.98] | Passed |
| regression: weak depletion | [200.0, 0.2, 28800.0] | [200.0, 0.2, 28800.0] | Passed |
| control: no depletion | [None, None, None] | [None, None, None] | Passed |
| regression: second pass empty | [45.0, 1.0, 0.0] | [45.0, 1.0, 0.0] | Passed |
| control: negative catch | None | None | Passed |
| control: increasing catch | [None, None, None] | [None, None, None] | Passed |
SHA-256 / 8718f700c7658999930b884ee484febf3cd7abb453718809b4eb3faf4e7f6fbe
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:36.597124+00:00.
Case digest / e8f7696a30d5dc76c5ba0379275114ccf85690995dfa552fed9693ca62ac99ab