FA-68841 / Tide and marine navigation tables / Open access
Rule of twelfths: Per-hour twelfths are used as cumulative fractions · case 01
Mid-flood heights stay far too low and the tide never reaches high water.
ROOT CAUSE
The table [1,2,3,3,2,1] of per-hour increments is indexed as though it were the cumulative curve.
VERIFIED REPAIR
Use the cumulative table 0,1,3,6,9,11,12.
Unsuccessful approach: Replacing it with a linear 0,2,4,...,12 table reaches high water but ignores the fast mid-tide rise.
Case contract
Input [t1,h1,t2,h2,t] in hours/metres for consecutive turning points t1<t2 (rise or fall). The interval is split into six equal tide hours with cumulative twelfths 0,1,3,6,9,11,12 and linear interpolation inside a tide hour. Return height rounded to 4 decimals, or None when t2<=t1 or t lies outside [t1,t2].
Why this case matters
Tide tables and passage plans turn published predictions into go/no-go decisions about depth, clearance and timing.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
t1,h1,t2,h2,t=x
if t2<=t1: return None
if t<t1 or t>t2: return None
u=(t-t1)*6/(t2-t1)
k=min(int(u),5)
cum=[0,1,2,3,3,2,1]
c=cum[k]+(cum[k+1]-cum[k])*(u-k)
return round(h1+(h2-h1)*c/12,4)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('rule of twelfths [0, 0.5, 6, 4.1, 1.5]', [0, 0.5, 6, 4.1, 1.5], 1.1), ('rule of twelfths [0, 0.5, 6, 4.1, 1]', [0, 0.5, 6, 4.1, 1], 0.8), ('rule of twelfths [0, 0.5, 6, 4.1, 0]', [0, 0.5, 6, 4.1, 0], 0.5), ('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8)], [('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 1.5]', [0, 0.5, 6, 4.1, 1.5], 1.1), ('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [0, 0.5, 6, 4.1, 6]', [0, 0.5, 6, 4.1, 6], 4.1), ('rule of twelfths [0, 0.5, 6, 4.1, 6.5]', [0, 0.5, 6, 4.1, 6.5], None)], [('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [0, 0.5, 6, 4.1, 6]', [0, 0.5, 6, 4.1, 6], 4.1), ('rule of twelfths [0, 0.5, 6, 4.1, 6.5]', [0, 0.5, 6, 4.1, 6.5], None), ('rule of twelfths [0, 0.5, 6, 4.1, 7.25]', [0, 0.5, 6, 4.1, 7.25], None), ('rule of twelfths [2, 5.2, 8.5, 0.8, 2]', [2, 5.2, 8.5, 0.8, 2], 5.2)], [('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 7.25]', [0, 0.5, 6, 4.1, 7.25], None), ('rule of twelfths [2, 5.2, 8.5, 0.8, 2]', [2, 5.2, 8.5, 0.8, 2], 5.2), ('rule of twelfths [2, 5.2, 8.5, 0.8, 3.1]', [2, 5.2, 8.5, 0.8, 3.1], 4.8221), ('rule of twelfths [2, 5.2, 8.5, 0.8, 4]', [2, 5.2, 8.5, 0.8, 4], 4.2128), ('rule of twelfths [2, 5.2, 8.5, 0.8, 5.25]', [2, 5.2, 8.5, 0.8, 5.25], 3.0), ('rule of twelfths [2, 5.2, 8.5, 0.8, 7]', [2, 5.2, 8.5, 0.8, 7], 1.4487)], [('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [2, 5.2, 8.5, 0.8, 4]', [2, 5.2, 8.5, 0.8, 4], 4.2128), ('rule of twelfths [2, 5.2, 8.5, 0.8, 5.25]', [2, 5.2, 8.5, 0.8, 5.25], 3.0), ('rule of twelfths [2, 5.2, 8.5, 0.8, 7]', [2, 5.2, 8.5, 0.8, 7], 1.4487), ('rule of twelfths [2, 5.2, 8.5, 0.8, 8.5]', [2, 5.2, 8.5, 0.8, 8.5], 0.8), ('rule of twelfths [2, 5.2, 8.5, 0.8, 9]', [2, 5.2, 8.5, 0.8, 9], None), ('rule of twelfths [1, 1.0, 7, 1.0, 3]', [1, 1.0, 7, 1.0, 3], 1.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 |
|---|---|---|---|
| rule of twelfths [0, 0.5, 6, 4.1, 1.5] | 0.95 | 1.1 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 1] | 0.8 | 0.8 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 0] | 0.5 | 0.5 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 2] | 1.1 | 1.4 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 3] | 1.4 | 2.3 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 4.5] | 1.25 | 3.5 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 5] | 1.1 | 3.8 | Failed |
SHA-256 / 224ff9fba57c50682cdf130fdb2ac597e57b41dc9ce10daa43009d676909673a
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
t1,h1,t2,h2,t=x
if t2<=t1: return None
if t<t1 or t>t2: return None
u=(t-t1)*6/(t2-t1)
k=min(int(u),5)
cum=[0,2,4,6,8,10,12]
c=cum[k]+(cum[k+1]-cum[k])*(u-k)
return round(h1+(h2-h1)*c/12,4)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('rule of twelfths [0, 0.5, 6, 4.1, 1.5]', [0, 0.5, 6, 4.1, 1.5], 1.1), ('rule of twelfths [0, 0.5, 6, 4.1, 1]', [0, 0.5, 6, 4.1, 1], 0.8), ('rule of twelfths [0, 0.5, 6, 4.1, 0]', [0, 0.5, 6, 4.1, 0], 0.5), ('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8)], [('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 1.5]', [0, 0.5, 6, 4.1, 1.5], 1.1), ('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [0, 0.5, 6, 4.1, 6]', [0, 0.5, 6, 4.1, 6], 4.1), ('rule of twelfths [0, 0.5, 6, 4.1, 6.5]', [0, 0.5, 6, 4.1, 6.5], None)], [('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [0, 0.5, 6, 4.1, 6]', [0, 0.5, 6, 4.1, 6], 4.1), ('rule of twelfths [0, 0.5, 6, 4.1, 6.5]', [0, 0.5, 6, 4.1, 6.5], None), ('rule of twelfths [0, 0.5, 6, 4.1, 7.25]', [0, 0.5, 6, 4.1, 7.25], None), ('rule of twelfths [2, 5.2, 8.5, 0.8, 2]', [2, 5.2, 8.5, 0.8, 2], 5.2)], [('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 7.25]', [0, 0.5, 6, 4.1, 7.25], None), ('rule of twelfths [2, 5.2, 8.5, 0.8, 2]', [2, 5.2, 8.5, 0.8, 2], 5.2), ('rule of twelfths [2, 5.2, 8.5, 0.8, 3.1]', [2, 5.2, 8.5, 0.8, 3.1], 4.8221), ('rule of twelfths [2, 5.2, 8.5, 0.8, 4]', [2, 5.2, 8.5, 0.8, 4], 4.2128), ('rule of twelfths [2, 5.2, 8.5, 0.8, 5.25]', [2, 5.2, 8.5, 0.8, 5.25], 3.0), ('rule of twelfths [2, 5.2, 8.5, 0.8, 7]', [2, 5.2, 8.5, 0.8, 7], 1.4487)], [('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [2, 5.2, 8.5, 0.8, 4]', [2, 5.2, 8.5, 0.8, 4], 4.2128), ('rule of twelfths [2, 5.2, 8.5, 0.8, 5.25]', [2, 5.2, 8.5, 0.8, 5.25], 3.0), ('rule of twelfths [2, 5.2, 8.5, 0.8, 7]', [2, 5.2, 8.5, 0.8, 7], 1.4487), ('rule of twelfths [2, 5.2, 8.5, 0.8, 8.5]', [2, 5.2, 8.5, 0.8, 8.5], 0.8), ('rule of twelfths [2, 5.2, 8.5, 0.8, 9]', [2, 5.2, 8.5, 0.8, 9], None), ('rule of twelfths [1, 1.0, 7, 1.0, 3]', [1, 1.0, 7, 1.0, 3], 1.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 |
|---|---|---|---|
| rule of twelfths [0, 0.5, 6, 4.1, 1.5] | 1.4 | 1.1 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 1] | 1.1 | 0.8 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 0] | 0.5 | 0.5 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 2] | 1.7 | 1.4 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 3] | 2.3 | 2.3 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 4.5] | 3.2 | 3.5 | Failed |
| rule of twelfths [0, 0.5, 6, 4.1, 5] | 3.5 | 3.8 | Failed |
SHA-256 / e170a7e8990e3785f6d0cbd1e09d6a65a64e8162fa3ded6662a9ef9c805df707
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
t1,h1,t2,h2,t=x
if t2<=t1: return None
if t<t1 or t>t2: return None
u=(t-t1)*6/(t2-t1)
k=min(int(u),5)
cum=[0,1,3,6,9,11,12]
c=cum[k]+(cum[k+1]-cum[k])*(u-k)
return round(h1+(h2-h1)*c/12,4)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('rule of twelfths [0, 0.5, 6, 4.1, 1.5]', [0, 0.5, 6, 4.1, 1.5], 1.1), ('rule of twelfths [0, 0.5, 6, 4.1, 1]', [0, 0.5, 6, 4.1, 1], 0.8), ('rule of twelfths [0, 0.5, 6, 4.1, 0]', [0, 0.5, 6, 4.1, 0], 0.5), ('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8)], [('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 1.5]', [0, 0.5, 6, 4.1, 1.5], 1.1), ('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [0, 0.5, 6, 4.1, 6]', [0, 0.5, 6, 4.1, 6], 4.1), ('rule of twelfths [0, 0.5, 6, 4.1, 6.5]', [0, 0.5, 6, 4.1, 6.5], None)], [('rule of twelfths [0, 0.5, 6, 4.1, 3]', [0, 0.5, 6, 4.1, 3], 2.3), ('rule of twelfths [0, 0.5, 6, 4.1, 2]', [0, 0.5, 6, 4.1, 2], 1.4), ('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [0, 0.5, 6, 4.1, 6]', [0, 0.5, 6, 4.1, 6], 4.1), ('rule of twelfths [0, 0.5, 6, 4.1, 6.5]', [0, 0.5, 6, 4.1, 6.5], None), ('rule of twelfths [0, 0.5, 6, 4.1, 7.25]', [0, 0.5, 6, 4.1, 7.25], None), ('rule of twelfths [2, 5.2, 8.5, 0.8, 2]', [2, 5.2, 8.5, 0.8, 2], 5.2)], [('rule of twelfths [0, 0.5, 6, 4.1, 4.5]', [0, 0.5, 6, 4.1, 4.5], 3.5), ('rule of twelfths [0, 0.5, 6, 4.1, 7.25]', [0, 0.5, 6, 4.1, 7.25], None), ('rule of twelfths [2, 5.2, 8.5, 0.8, 2]', [2, 5.2, 8.5, 0.8, 2], 5.2), ('rule of twelfths [2, 5.2, 8.5, 0.8, 3.1]', [2, 5.2, 8.5, 0.8, 3.1], 4.8221), ('rule of twelfths [2, 5.2, 8.5, 0.8, 4]', [2, 5.2, 8.5, 0.8, 4], 4.2128), ('rule of twelfths [2, 5.2, 8.5, 0.8, 5.25]', [2, 5.2, 8.5, 0.8, 5.25], 3.0), ('rule of twelfths [2, 5.2, 8.5, 0.8, 7]', [2, 5.2, 8.5, 0.8, 7], 1.4487)], [('rule of twelfths [0, 0.5, 6, 4.1, 5]', [0, 0.5, 6, 4.1, 5], 3.8), ('rule of twelfths [2, 5.2, 8.5, 0.8, 4]', [2, 5.2, 8.5, 0.8, 4], 4.2128), ('rule of twelfths [2, 5.2, 8.5, 0.8, 5.25]', [2, 5.2, 8.5, 0.8, 5.25], 3.0), ('rule of twelfths [2, 5.2, 8.5, 0.8, 7]', [2, 5.2, 8.5, 0.8, 7], 1.4487), ('rule of twelfths [2, 5.2, 8.5, 0.8, 8.5]', [2, 5.2, 8.5, 0.8, 8.5], 0.8), ('rule of twelfths [2, 5.2, 8.5, 0.8, 9]', [2, 5.2, 8.5, 0.8, 9], None), ('rule of twelfths [1, 1.0, 7, 1.0, 3]', [1, 1.0, 7, 1.0, 3], 1.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 |
|---|---|---|---|
| rule of twelfths [0, 0.5, 6, 4.1, 1.5] | 1.1 | 1.1 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 1] | 0.8 | 0.8 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 0] | 0.5 | 0.5 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 2] | 1.4 | 1.4 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 3] | 2.3 | 2.3 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 4.5] | 3.5 | 3.5 | Passed |
| rule of twelfths [0, 0.5, 6, 4.1, 5] | 3.8 | 3.8 | Passed |
SHA-256 / 384b31987c4c12a6c28399a0aa29ba9fdeb553d9306c6ba7477b049f32c4553a
Verification & scope
A deterministic toy model with stipulated rules and constants; not certified hydrographic software or a substitute for official tide tables. 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:48:06.070179+00:00.
Case digest / 49d4fefcb131973f11226e919aefad9f89880878b59bd105136fbb5cf0da84b3