FA-12456 / Molecular graph representation / Open access
Ligand reordering silently flips stored orientation · case 01
Ligand reordering silently flips stored orientation.
ROOT CAUSE
Orientation sign is copied when ligand order changes.
VERIFIED REPAIR
Implement the explicit toy representation contract: Four distinct ligand IDs define a local orientation sign +/-1. Return sign multiplied by permutation parity when old ligand order is changed to new order containing the same IDs.
Unsuccessful approach: Flipping for every nonidentity permutation mishandles even permutations.
Case contract
Four distinct ligand IDs define a local orientation sign +/-1. Return sign multiplied by permutation parity when old ligand order is changed to new order containing the same IDs.
Why this case matters
Controlled molecular graph interchange model; tests isolate atom or bond representation errors without claiming chemical validity or production toolkit equivalence.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(old, new, sign):
return sign
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('one swap', solve([N,N+1,N+2,N+3],[N+1,N,N+2,N+3],1), -1)
check('three cycle', solve([N,N+1,N+2,N+3],[N+1,N+2,N,N+3],1), 1)
check('identity', solve([N,N+1,N+2,N+3],[N,N+1,N+2,N+3],-1), -1)
check('double swap', solve([N,N+1,N+2,N+3],[N+1,N,N+3,N+2],-1), -1)
check('four cycle', solve([N,N+1,N+2,N+3],[N+1,N+2,N+3,N],1), -1)
check('reverse order', solve([N,N+1,N+2,N+3],[N+3,N+2,N+1,N],1), 1)
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 |
|---|---|---|---|
| one swap | 1 | -1 | Failed |
| three cycle | 1 | 1 | Passed |
| identity | -1 | -1 | Passed |
| double swap | -1 | -1 | Passed |
| four cycle | 1 | -1 | Failed |
| reverse order | 1 | 1 | Passed |
SHA-256 / 03866289bcddcec18d07db12d13e90291a45cb65da980a4f255bfb97b0584f09
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(old, new, sign):
return -sign if old != new else sign
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('one swap', solve([N,N+1,N+2,N+3],[N+1,N,N+2,N+3],1), -1)
check('three cycle', solve([N,N+1,N+2,N+3],[N+1,N+2,N,N+3],1), 1)
check('identity', solve([N,N+1,N+2,N+3],[N,N+1,N+2,N+3],-1), -1)
check('double swap', solve([N,N+1,N+2,N+3],[N+1,N,N+3,N+2],-1), -1)
check('four cycle', solve([N,N+1,N+2,N+3],[N+1,N+2,N+3,N],1), -1)
check('reverse order', solve([N,N+1,N+2,N+3],[N+3,N+2,N+1,N],1), 1)
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 |
|---|---|---|---|
| one swap | -1 | -1 | Passed |
| three cycle | -1 | 1 | Failed |
| identity | -1 | -1 | Passed |
| double swap | 1 | -1 | Failed |
| four cycle | -1 | -1 | Passed |
| reverse order | -1 | 1 | Failed |
SHA-256 / 8159b568b66edee6fedf9234cd9dc78738f3f21e50867f36f1f1fe76d32e4705
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(old, new, sign):
p = [old.index(x) for x in new]
inv = sum(p[i] > p[j] for i in range(4) for j in range(i+1,4))
return sign * (-1 if inv % 2 else 1)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('one swap', solve([N,N+1,N+2,N+3],[N+1,N,N+2,N+3],1), -1)
check('three cycle', solve([N,N+1,N+2,N+3],[N+1,N+2,N,N+3],1), 1)
check('identity', solve([N,N+1,N+2,N+3],[N,N+1,N+2,N+3],-1), -1)
check('double swap', solve([N,N+1,N+2,N+3],[N+1,N,N+3,N+2],-1), -1)
check('four cycle', solve([N,N+1,N+2,N+3],[N+1,N+2,N+3,N],1), -1)
check('reverse order', solve([N,N+1,N+2,N+3],[N+3,N+2,N+1,N],1), 1)
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 |
|---|---|---|---|
| one swap | -1 | -1 | Passed |
| three cycle | 1 | 1 | Passed |
| identity | -1 | -1 | Passed |
| double swap | -1 | -1 | Passed |
| four cycle | -1 | -1 | Passed |
| reverse order | 1 | 1 | Passed |
SHA-256 / 41eee7731814cd88ad3d7fa5b4345c7438349c69efd127fae2b73189d0d4696b
Verification & scope
Toy representation only; no valence inference, chemical sanitization, synthesis, or real molecular identity determination. 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:38:57.019485+00:00.
Case digest / 000024c3fe2014ab4f9311516f08c5459c5ea1fe3d701e19e3ec446e2aa272a0