FAILURE MAP
← Case archive

FA-65531 / Ecological population dynamics / Open access

Lotka-Volterra competition outcome: interior classification · case 01

Stable coexistence and founder control are swapped.

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

ROOT CAUSE

The sign test for the interior equilibrium is reversed.

VERIFIED REPAIR

Restore the interior classification rule: `kind = 'coexist' if c1 < 0 else 'founder'`.

Unsuccessful approach: Requiring both coefficients below one misclassifies coexistence with unequal capacities.

Case contract

c1=K1*a21-K2, c2=K2*a12-K1; any zero -> neutral; c1>0,c2<0 species1 wins at [K1,0]; c1<0,c2>0 species2 at [0,K2]; otherwise interior N1=(K1-a12K2)/(1-a12a21), N2=(K2-a21K1)/(1-a12a21), coexist if both negative, founder if both positive; None for non-positive K or negative coefficients (zero allowed).

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(k1, k2, a12, a21):
    if min(k1, k2) <= 0 or min(a12, a21) < 0:
        return None
    c1 = k1 * a21 - k2
    c2 = k2 * a12 - k1
    if c1 == 0 or c2 == 0:
        return ['neutral', None]
    if c1 > 0 and c2 < 0:
        return ['species1', [float(k1), 0.0]]
    if c1 < 0 and c2 > 0:
        return ['species2', [0.0, float(k2)]]
    den = 1 - a12 * a21
    n1 = (k1 - a12 * k2) / den
    n2 = (k2 - a21 * k1) / den
    kind = 'coexist' if c1 > 0 else 'founder'
    return [kind, [round(n1, 4), round(n2, 4)]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]])],
 [('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None),
  ('control: invalid capacity', (0, 100, 0.5, 0.5), None),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]])],
 [('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None),
  ('control: invalid capacity', (0, 100, 0.5, 0.5), None),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]]),
  ('regression: founder asymmetric', (90, 150, 2.0, 2.5), ['founder', [52.5, 18.75]])],
 [('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]]),
  ('regression: founder asymmetric', (90, 150, 2.0, 2.5), ['founder', [52.5, 18.75]])],
 [('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None)]]
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: weak competition coexist['founder', [75.0, 50.0]]['coexist', [75.0, 50.0]]Failed
control: strong asymmetric species1['species1', [100.0, 0.0]]['species1', [100.0, 0.0]]Passed
control: species2 wins['species2', [0.0, 120.0]]['species2', [0.0, 120.0]]Passed
regression: founder control['coexist', [35.7143, 42.8571]]['founder', [35.7143, 42.8571]]Failed
control: neutral tie['neutral', None]['neutral', None]Passed
regression: no competition['founder', [70.0, 40.0]]['coexist', [70.0, 40.0]]Failed
regression: coexist with one strong coefficient['founder', [157.1429, 28.5714]]['coexist', [157.1429, 28.5714]]Failed

SHA-256 / 31e438c77c0c454aa2a9e4d07cbcee5d94772d0d4c9571b92f4b984561aa7299

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(k1, k2, a12, a21):
    if min(k1, k2) <= 0 or min(a12, a21) < 0:
        return None
    c1 = k1 * a21 - k2
    c2 = k2 * a12 - k1
    if c1 == 0 or c2 == 0:
        return ['neutral', None]
    if c1 > 0 and c2 < 0:
        return ['species1', [float(k1), 0.0]]
    if c1 < 0 and c2 > 0:
        return ['species2', [0.0, float(k2)]]
    den = 1 - a12 * a21
    n1 = (k1 - a12 * k2) / den
    n2 = (k2 - a21 * k1) / den
    kind = 'coexist' if a12 < 1 and a21 < 1 else 'founder'
    return [kind, [round(n1, 4), round(n2, 4)]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]])],
 [('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None),
  ('control: invalid capacity', (0, 100, 0.5, 0.5), None),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]])],
 [('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None),
  ('control: invalid capacity', (0, 100, 0.5, 0.5), None),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]]),
  ('regression: founder asymmetric', (90, 150, 2.0, 2.5), ['founder', [52.5, 18.75]])],
 [('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]]),
  ('regression: founder asymmetric', (90, 150, 2.0, 2.5), ['founder', [52.5, 18.75]])],
 [('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None)]]
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: weak competition coexist['coexist', [75.0, 50.0]]['coexist', [75.0, 50.0]]Passed
control: strong asymmetric species1['species1', [100.0, 0.0]]['species1', [100.0, 0.0]]Passed
control: species2 wins['species2', [0.0, 120.0]]['species2', [0.0, 120.0]]Passed
regression: founder control['founder', [35.7143, 42.8571]]['founder', [35.7143, 42.8571]]Passed
control: neutral tie['neutral', None]['neutral', None]Passed
regression: no competition['coexist', [70.0, 40.0]]['coexist', [70.0, 40.0]]Passed
regression: coexist with one strong coefficient['founder', [157.1429, 28.5714]]['coexist', [157.1429, 28.5714]]Failed

SHA-256 / d32988d85cdbc9be2bcbe85ac643bbd3a8141663c0bce591ddd715f4b6aedc5a

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(k1, k2, a12, a21):
    if min(k1, k2) <= 0 or min(a12, a21) < 0:
        return None
    c1 = k1 * a21 - k2
    c2 = k2 * a12 - k1
    if c1 == 0 or c2 == 0:
        return ['neutral', None]
    if c1 > 0 and c2 < 0:
        return ['species1', [float(k1), 0.0]]
    if c1 < 0 and c2 > 0:
        return ['species2', [0.0, float(k2)]]
    den = 1 - a12 * a21
    n1 = (k1 - a12 * k2) / den
    n2 = (k2 - a21 * k1) / den
    kind = 'coexist' if c1 < 0 else 'founder'
    return [kind, [round(n1, 4), round(n2, 4)]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]])],
 [('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None),
  ('control: invalid capacity', (0, 100, 0.5, 0.5), None),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]])],
 [('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None),
  ('control: invalid capacity', (0, 100, 0.5, 0.5), None),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]]),
  ('regression: founder asymmetric', (90, 150, 2.0, 2.5), ['founder', [52.5, 18.75]])],
 [('regression: weak competition coexist', (100, 80, 0.5, 0.4), ['coexist', [75.0, 50.0]]),
  ('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: near tie', (100, 99.5, 1.0, 1.0), ['species1', [100.0, 0.0]]),
  ('regression: founder asymmetric', (90, 150, 2.0, 2.5), ['founder', [52.5, 18.75]])],
 [('control: strong asymmetric species1', (100, 60, 0.5, 1.2), ['species1', [100.0, 0.0]]),
  ('control: species2 wins', (50, 120, 1.5, 0.3), ['species2', [0.0, 120.0]]),
  ('regression: founder control', (100, 100, 1.5, 1.6), ['founder', [35.7143, 42.8571]]),
  ('control: neutral tie', (100, 50, 1.0, 0.5), ['neutral', None]),
  ('regression: no competition', (70, 40, 0.0, 0.0), ['coexist', [70.0, 40.0]]),
  ('regression: coexist with one strong coefficient', (200, 60, 1.5, 0.2), ['coexist', [157.1429, 28.5714]]),
  ('control: invalid negative coefficient', (100, 100, -0.1, 0.5), None)]]
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: weak competition coexist['coexist', [75.0, 50.0]]['coexist', [75.0, 50.0]]Passed
control: strong asymmetric species1['species1', [100.0, 0.0]]['species1', [100.0, 0.0]]Passed
control: species2 wins['species2', [0.0, 120.0]]['species2', [0.0, 120.0]]Passed
regression: founder control['founder', [35.7143, 42.8571]]['founder', [35.7143, 42.8571]]Passed
control: neutral tie['neutral', None]['neutral', None]Passed
regression: no competition['coexist', [70.0, 40.0]]['coexist', [70.0, 40.0]]Passed
regression: coexist with one strong coefficient['coexist', [157.1429, 28.5714]]['coexist', [157.1429, 28.5714]]Passed

SHA-256 / 692aa99aa2a146610940215dc42f36f1f6ee610ee18f89df87e564ac9ae14f4e

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.709834+00:00.

Case digest / acd4397a994050af78cb24fbe6136f6a598cefd3a6fbaf53c436fb2524c71926