FA-65711 / Ecological population dynamics / Open access
Two-patch source-sink dispersal with ceilings: dispersal base · case 01
Dispersal numbers ignore this year's reproduction.
ROOT CAUSE
Emigration is computed from the pre-growth population.
VERIFIED REPAIR
Restore the dispersal base rule: `out = [grown[j] * disperse`.
Unsuccessful approach: Emigration proportional to the ceiling ignores actual abundance.
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[j]) for j in range(2)]
out = [n[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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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 | [[134.0, 30.0], [179.2, 41.8], [172.52, 56.74], [176.844, 62.874], [177.206, 66.8058]] | [[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 | [[183.0, 25.0], [184.2, 35.8], [185.16, 43.48], [185.832, 48.952]] | [[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 |
| regression: full exchange | [[6.0, 60.0], [60.6, -24.0], [-17.94, 72.6]] | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | Failed |
| regression: both sinks | [[80.0, 60.0], [58.0, 42.0], [41.6, 30.0], [29.8, 21.48]] | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | Failed |
| regression: sink ceiling binding | [[40.5, 72.5], [60.65, 79.0], [83.4325, 90.2125], [110.1573, 98.305]] | [[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]] | Failed |
| regression: unequal ceilings | [[117.5, 62.5], [117.25, 62.75], [117.275, 62.725], [117.2725, 62.7275], [117.2728, 62.7272]] | [[117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0], [117.0, 63.0]] | Failed |
SHA-256 / e11d1dfa743e53cf6ca9de9abf7b91711ac7a44172849c63b5a2c1af1e366fb5
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], caps[j]) for j in range(2)]
out = [caps[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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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 | [[150.0, 14.0], [200.0, 9.8], [200.0, 6.86], [200.0, 4.802], [200.0, 3.3614]] | [[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 | [[185.0, 23.0], [185.0, 33.4], [185.0, 41.72], [185.0, 48.376]] | [[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 |
| regression: full exchange | [[66.0, 0.0], [72.6, 0.0], [79.86, 0.0]] | [[0.0, 66.0], [33.0, 0.0], [0.0, 36.3]] | Failed |
| regression: both sinks | [[80.0, 60.0], [64.0, 36.0], [51.2, 21.6], [40.96, 12.96]] | [[74.0, 66.0], [53.32, 45.48], [38.0456, 31.8984], [27.0472, 22.5283]] | Failed |
| regression: sink ceiling binding | [[-37.0, 150.0], [-98.1, 150.0], [-177.53, 150.0], [-280.789, 150.0]] | [[34.75, 78.25], [57.3563, 81.7188], [80.438, 92.1877], [103.427, 101.1423]] | Failed |
| 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 / dafa552bc5937b2062f5c75e25138a252d2ebb8c3676029e2555541eb6b07cc9
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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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]]),
('regression: 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 |
| regression: 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 |
| regression: 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 / 20af016fbef8f8e5bddedad7ba05623f3842a2b921716977f7f68d125d613c3b
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.598542+00:00.
Case digest / 7c1f9dab41a4c8aaa4470f28a7b866fdda43fbb913342efb5210351d7bccfe67