FA-65696 / Ecological population dynamics / Open access
Two-patch source-sink dispersal with ceilings: patch-specific ceiling · case 01
The sink patch is allowed to fill to the source ceiling.
ROOT CAUSE
Every patch uses the first patch's ceiling.
VERIFIED REPAIR
Restore the patch-specific ceiling rule: `min(n[j] * lambdas[j], caps[j])`.
Unsuccessful approach: Capping at the combined ceiling never binds a single patch.
Case contract
Each year each patch grows by its lambda and is capped at its own ceiling, then fraction disperse of each post-growth patch moves to the other simultaneously; return yearly [N1, N2] rounded 4.
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(n0s, lambdas, caps, disperse, years):
n = [float(x) for x in n0s]
traj = []
for _ in range(years):
grown = [min(n[j] * lambdas[j], caps[0]) for j in range(2)]
out = [grown[j] * disperse for j in range(2)]
n = [grown[0] - out[0] + out[1], grown[1] - out[1] + out[0]]
traj.append([round(x, 4) for x in n])
return traj
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])]]
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: meadow source woodland sink | [[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]] | [[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]] | Passed |
| regression: ceiling binding in source | [[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]] | [[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]] | Passed |
| control: no dispersal | [[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]] | [[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]] | Passed |
| control: full exchange | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | Passed |
| control: both sinks | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | Passed |
| regression: sink ceiling binding | [[45.75, 111.25], [77.9813, 114.9938], [110.5298, 128.8383], [146.4181, 151.8767]] | [[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]] | Failed |
| regression: unequal ceilings | [[117.0, 63.0], [118.725, 95.775], [120.0, 120.0], [120.0, 120.0], [120.0, 120.0]] | [[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]] | Failed |
SHA-256 / 5f0ab2dde2e8132d424af39e229b8c4b6eadad640f4e14da428d2740a63d12c1
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(n0s, lambdas, caps, disperse, years):
n = [float(x) for x in n0s]
traj = []
for _ in range(years):
grown = [min(n[j] * lambdas[j], sum(caps)) for j in range(2)]
out = [grown[j] * disperse for j in range(2)]
n = [grown[0] - out[0] + out[1], grown[1] - out[1] + out[0]]
traj.append([round(x, 4) for x in n])
return traj
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])]]
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: meadow source woodland sink | [[122.8, 41.2], [153.128, 59.912], [192.1413, 79.4891], [241.698, 102.1563], [304.3395, 129.7169]] | [[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]] | Failed |
| regression: ceiling binding in source | [[225.8, 32.2], [227.576, 48.184], [228.8547, 59.6925], [229.7754, 67.9786]] | [[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]] | Failed |
| control: no dispersal | [[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]] | [[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]] | Passed |
| control: full exchange | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | Passed |
| control: both sinks | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | Passed |
| regression: sink ceiling binding | [[45.75, 111.25], [77.9813, 114.9938], [110.5298, 128.8383], [146.4181, 151.8767]] | [[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]] | Failed |
| regression: unequal ceilings | [[174.0, 66.0], [175.95, 103.05], [178.7287, 155.8462], [180.0, 180.0], [180.0, 180.0]] | [[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]] | Failed |
SHA-256 / a53ccf4b16778275117fde2873a7ee8ea8d43e01e5d8d58839f6ce3c0d5e174c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(n0s, lambdas, caps, disperse, years):
n = [float(x) for x in n0s]
traj = []
for _ in range(years):
grown = [min(n[j] * lambdas[j], caps[j]) for j in range(2)]
out = [grown[j] * disperse for j in range(2)]
n = [grown[0] - out[0] + out[1], grown[1] - out[1] + out[0]]
traj.append([round(x, 4) for x in n])
return traj
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])],
[('regression: meadow source woodland sink',
([100, 20], [1.5, 0.7], [200, 200], 0.2, 5),
[[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]]),
('regression: ceiling binding in source',
([180, 10], [1.4, 0.8], [200, 50], 0.1, 4),
[[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]]),
('control: no dispersal',
([50, 50], [1.2, 0.9], [100, 100], 0.0, 3),
[[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]]),
('control: full exchange',
([60, 0], [1.1, 0.5], [100, 100], 1.0, 3),
[[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]]),
('control: both sinks',
([100, 100], [0.8, 0.6], [150, 150], 0.3, 4),
[[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]]),
('regression: sink ceiling binding',
([10, 120], [1.3, 1.2], [300, 100], 0.25, 4),
[[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]]),
('regression: unequal ceilings',
([90, 40], [2.0, 1.5], [120, 60], 0.05, 5),
[[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]])]]
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: meadow source woodland sink | [[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]] | [[122.8, 41.2], [153.128, 59.912], [168.3877, 73.5507], [170.2971, 81.1884], [171.3664, 85.4655]] | Passed |
| regression: ceiling binding in source | [[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]] | [[180.8, 27.2], [182.176, 39.584], [183.1667, 48.5005], [183.88, 54.9203]] | Passed |
| control: no dispersal | [[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]] | [[60.0, 45.0], [72.0, 40.5], [86.4, 36.45]] | Passed |
| control: full exchange | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | Passed |
| control: both sinks | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | Passed |
| regression: sink ceiling binding | [[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]] | [[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]] | Passed |
| regression: unequal ceilings | [[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]] | [[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]] | Passed |
SHA-256 / 4163838221b080713a4d61cd6e0290b37763a26b8d93731342954e2552564adc
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.489647+00:00.
Case digest / af178c0f78d503b47dd1dbe0d879d793c12dd2c2c7eee9e0218040652bb794ff