Skip to content

Commit 832140d

Browse files
authored
Merge pull request #9 from Chessing234/research/rational-band-obstruction
Formalize rational band obstruction and integer return comparison
2 parents 9f337b3 + 84f87ec commit 832140d

7 files changed

Lines changed: 376 additions & 0 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ jobs:
4040
python3 scripts/audit_interval_capacity.py
4141
python3 scripts/audit_floor_excursion.py
4242
python3 scripts/audit_five_band_clock.py
43+
python3 scripts/audit_rational_band_obstruction.py
4344
4445
- name: Check exact first-descent intervals
4546
run: |

‎Collatz.lean‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,3 +2110,4 @@ import Collatz.Exploration.IntervalCapacity
21102110
import Collatz.Exploration.TwoStepCapacity
21112111
import Collatz.Exploration.FloorExcursion
21122112
import Collatz.Exploration.FiveBandClock
2113+
import Collatz.Exploration.RationalBandObstruction
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import Collatz.Exploration.FloorExcursion
2+
3+
/-! Odd-denominator rational Collatz dynamics encoded by natural numerators.
4+
With a fixed odd denominator d, the odd update on numerators is 3n+d;
5+
the even update halves an even numerator. All comparisons below are exact
6+
cross-multiplied rational comparisons. This map is distinct from step. -/
7+
namespace Collatz.Exploration.RationalBandObstruction
8+
9+
def denominatorStep (d n : Nat) : Nat :=
10+
if n % 2 = 0 then n / 2 else 3*n+d
11+
12+
def denominatorOrbit (d : Nat) : Nat → Nat → Nat
13+
| 0, n => n
14+
| k+1, n => denominatorStep d (denominatorOrbit d k n)
15+
16+
/-- Denominator one recovers the original integer map, including zero. -/
17+
theorem denominator_one_step (n : Nat) : denominatorStep 1 n = step n := by
18+
by_cases hz : n = 0
19+
· subst n; decide
20+
· simp [denominatorStep, step, hz]
21+
22+
theorem denominator_one_orbit (k n : Nat) : denominatorOrbit 1 k n = orbit k n := by
23+
induction k with
24+
| zero => rfl
25+
| succ k ih =>
26+
simp only [denominatorOrbit, ih, denominator_one_step, orbit_succ_steps]
27+
exact (orbit_step_commute k n).symm
28+
29+
/-- The branch word OEOEEOEE has this affine identity for every fixed offset. -/
30+
theorem word_identity (d x0 x1 x2 x3 x4 x5 x6 x7 x8 : Nat)
31+
(h0 : x1 = 3*x0+d) (h1 : 2*x2 = x1)
32+
(h2 : x3 = 3*x2+d) (h3 : 2*x4 = x3) (h4 : 2*x5 = x4)
33+
(h5 : x6 = 3*x5+d) (h6 : 2*x7 = x6) (h7 : 2*x8 = x7) :
34+
32*x8 = 27*x0+23*d := by omega
35+
36+
/-- Closure in this word forces the encoding denominator to be divisible by five. -/
37+
theorem closure_denominator (d n : Nat) (h : 32*n = 27*n+23*d) : d%5 = 0 := by
38+
omega
39+
40+
/-- This word's closed encodings are exactly multiples of the primitive pair (5,23). -/
41+
theorem closure_classification (d n : Nat) (h : 32*n = 27*n+23*d) :
42+
∃ t, d = 5*t ∧ n = 23*t := by
43+
have hd := closure_denominator d n h
44+
refine ⟨d/5, ?_, ?_⟩ <;> omega
45+
46+
/-- The rational 23/5 cycle, uniformly encoded at every odd scale. -/
47+
theorem scaled_transitions (t : Nat) (ht : t%2 = 1) :
48+
denominatorStep (5*t) (23*t) = 74*t ∧
49+
denominatorStep (5*t) (74*t) = 37*t ∧
50+
denominatorStep (5*t) (37*t) = 116*t ∧
51+
denominatorStep (5*t) (116*t) = 58*t ∧
52+
denominatorStep (5*t) (58*t) = 29*t ∧
53+
denominatorStep (5*t) (29*t) = 92*t ∧
54+
denominatorStep (5*t) (92*t) = 46*t ∧
55+
denominatorStep (5*t) (46*t) = 23*t := by
56+
simp [denominatorStep, Nat.mul_mod, ht]
57+
omega
58+
59+
/-- These eight numerator values form a closed invariant set. -/
60+
def Member (t n : Nat) : Prop :=
61+
n = 23*t ∨ n = 74*t ∨ n = 37*t ∨ n = 116*t ∨
62+
n = 58*t ∨ n = 29*t ∨ n = 92*t ∨ n = 46*t
63+
64+
theorem member_forward {t n : Nat} (ht : t%2 = 1) (h : Member t n) :
65+
Member t (denominatorStep (5*t) n) := by
66+
obtain ⟨h0,h1,h2,h3,h4,h5,h6,h7⟩ := scaled_transitions t ht
67+
rcases h with h | h | h | h | h | h | h | h <;>
68+
simp_all [Member]
69+
70+
theorem orbit_member (t : Nat) (ht : t%2 = 1) (k : Nat) :
71+
Member t (denominatorOrbit (5*t) k (23*t)) := by
72+
induction k with
73+
| zero => exact Or.inl rfl
74+
| succ k ih => exact member_forward ht ih
75+
76+
theorem cycle_eight (t : Nat) (ht : t%2 = 1) :
77+
denominatorOrbit (5*t) 8 (23*t) = 23*t := by
78+
obtain ⟨h0,h1,h2,h3,h4,h5,h6,h7⟩ := scaled_transitions t ht
79+
simp only [denominatorOrbit, h0,h1,h2,h3,h4,h5,h6,h7]
80+
81+
/-- The primitive normalized cycle has least positive period eight. -/
82+
theorem primitive_period : denominatorOrbit 5 8 23 = 23 ∧
83+
∀ k : Fin 7, denominatorOrbit 5 (k.val+1) 23 ≠ 23 := by decide
84+
85+
/-- The numerator cycle stays in the interval [23t,116t] for all time. -/
86+
theorem bounds_all (t : Nat) (ht : t%2 = 1) (k : Nat) :
87+
23*t ≤ denominatorOrbit (5*t) k (23*t) ∧
88+
denominatorOrbit (5*t) k (23*t) ≤ 116*t := by
89+
have h := orbit_member t ht k
90+
rcases h with h | h | h | h | h | h | h | h <;> omega
91+
92+
/-- Its rational minimum is greater than one, and the maximum ratio is 116/23. -/
93+
theorem rational_floor_certificate :
94+
5 < 23 ∧ (∀ k, 23 ≤ denominatorOrbit 5 k 23 ∧
95+
denominatorOrbit 5 k 23 ≤ 116) ∧ denominatorOrbit 5 3 23 = 116 := by
96+
refine ⟨by decide, ?_, by decide⟩
97+
intro k
98+
simpa using bounds_all 1 (by decide) k
99+
100+
/-- The cycle defeats every rational-interval clock at ratio 51/10. -/
101+
theorem band_fifty_one_tenths (k : Nat) :
102+
23 ≤ denominatorOrbit 5 k 23 ∧ 10*denominatorOrbit 5 k 23 ≤ 51*23 := by
103+
have h := bounds_all 1 (by decide) k
104+
simp only [Nat.mul_one] at h
105+
omega
106+
107+
/-- It still exits the narrower ratio-five band, at its largest point. -/
108+
theorem exits_five_band : 5*23 < denominatorOrbit 5 3 23 := by decide
109+
110+
/-- Even the multiplicative part 81/16 of the integer-floor bound fails here. -/
111+
theorem fails_integer_floor_excursion (k : Nat) :
112+
16*denominatorOrbit 5 k 23 < 81*23 := by
113+
have h := bounds_all 1 (by decide) k
114+
simp only [Nat.mul_one] at h
115+
omega
116+
117+
/-- A uniform result for arbitrary odd offsets would wrongly exclude this cycle. -/
118+
theorem no_offset_band_exit :
119+
¬ (∀ d b n : Nat, d%2 = 1 → 1 < b →
120+
∃ k, denominatorOrbit d k n < b ∨
121+
116*b < 23*denominatorOrbit d k n) := by
122+
intro h
123+
obtain ⟨k,hl | hu⟩ := h 5 23 23 (by decide) (by decide)
124+
· have hb := bounds_all 1 (by decide) k
125+
simp only [Nat.mul_one] at hb
126+
omega
127+
· have hb := bounds_all 1 (by decide) k
128+
simp only [Nat.mul_one] at hb
129+
omega
130+
131+
/-- Changing the denominator changes the odd update; this is no integer cycle. -/
132+
theorem ordinary_map_control : step 23 = 70 ∧ denominatorStep 5 23 = 74 := by decide
133+
134+
/-- The corresponding ordinary integer congruence class has an exact descending trace.
135+
This class was already closed in Strategy/ExcursionMap; this records the fixed clock. -/
136+
theorem integer_trace (q : Nat) :
137+
step (32*q+11) = 96*q+34 ∧ step (96*q+34) = 48*q+17 ∧
138+
step (48*q+17) = 144*q+52 ∧ step (144*q+52) = 72*q+26 ∧
139+
step (72*q+26) = 36*q+13 ∧ step (36*q+13) = 108*q+40 ∧
140+
step (108*q+40) = 54*q+20 ∧ step (54*q+20) = 27*q+10 := by
141+
have h0 : (32*q+11)%2 = 1 := by omega
142+
have h1 : (96*q+34)%2 = 0 := by omega
143+
have h2 : (48*q+17)%2 = 1 := by omega
144+
have h3 : (144*q+52)%2 = 0 := by omega
145+
have h4 : (72*q+26)%2 = 0 := by omega
146+
have h5 : (36*q+13)%2 = 1 := by omega
147+
have h6 : (108*q+40)%2 = 0 := by omega
148+
have h7 : (54*q+20)%2 = 0 := by omega
149+
simp [step, h0,h1,h2,h3,h4,h5,h6,h7]
150+
omega
151+
152+
theorem integer_eighth_value (q : Nat) : orbit 8 (32*q+11) = 27*q+10 := by
153+
obtain ⟨h0,h1,h2,h3,h4,h5,h6,h7⟩ := integer_trace q
154+
simp only [orbit, h0,h1,h2,h3,h4,h5,h6,h7]
155+
156+
theorem integer_strict_descent (q : Nat) : orbit 8 (32*q+11) < 32*q+11 := by
157+
rw [integer_eighth_value]
158+
omega
159+
160+
/-- The formal affine return identity, exposing the rational fixed point 23/5. -/
161+
theorem integer_return_identity (q : Nat) :
162+
32*orbit 8 (32*q+11) = 27*(32*q+11)+23 := by
163+
rw [integer_eighth_value]
164+
omega
165+
166+
/-- The word's affine identity enforces the exact integer source residue. -/
167+
theorem integer_source_residue (n r : Nat) (h : 32*r = 27*n+23) : n%32 = 11 := by
168+
omega
169+
170+
theorem integer_descent_of_residue {n : Nat} (h : n%32 = 11) : orbit 8 n < n := by
171+
have hn : n = 32*(n/32)+11 := by omega
172+
rw [hn]
173+
exact integer_strict_descent (n/32)
174+
175+
theorem no_integer_fixed_point (n : Nat) : ¬ (32*n = 27*n+23) := by omega
176+
177+
end Collatz.Exploration.RationalBandObstruction

‎README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ own verification instructions.
3535
a hypothetical orbit floor to exceed five times its starting value. Every
3636
arbitrary-start orbit exits `[b,5b]` within twelve steps for `b>1`; the
3737
clock is sharp and yields conditional high-visit witnesses.
38+
- [Rational band obstruction](Research/RationalBandObstruction.md) — a
39+
denominator-aware cycle certificate, exact closure classification, and
40+
why the integer floor bound does not extend to rational floors.
3841

3942
- [First passage through 2,592 steps](Research/PassageAtlas/README.md) —
4043
a stronger conditional descent theorem, an exact residual condition
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Rational band obstruction and integer return clock
2+
3+
The investigation of wider bands exposed a limit of the real affine
4+
relaxation used to guide the ratio-five certificate. It is not sufficient
5+
to strengthen an integer theorem by treating its orbit values and anchor
6+
as unconstrained rational numbers. This note records a counterexample to
7+
that transfer, not a counterexample to the integer Collatz conjecture.
8+
9+
## Exact denominator encoding
10+
11+
For an odd fixed denominator `d`, a rational state `n/d` has an even or
12+
odd numerator. Its numerator update is
13+
14+
`denominatorStep(d,n) = n/2` if `n` is even, and `3n+d` otherwise.
15+
16+
An even numerator is halved exactly; the odd denominator remains fixed.
17+
Reducing such a fraction cancels an odd common factor and preserves the
18+
numerator parity. At denominator one, Lean proves both the step and the
19+
whole orbit equal the original integer definitions, including zero.
20+
The Lean file works with natural numerators and exact cross-multiplied
21+
comparisons; it does not silently identify the offset map with `3n+1`.
22+
23+
At denominator five the numerator cycle is
24+
25+
`23→74→37→116→58→29→92→46→23`.
26+
27+
Lean proves its least positive period is eight and every future value lies
28+
in `[23,116]`. Every odd scale `t` gives the encoding with denominator `5t`
29+
and numerators multiplied by `t`; the normalized rational cycle is the
30+
same. Even scales are deliberately excluded from the numerator parity
31+
statement and rejected by a test control.
32+
33+
The underlying affine cycle method is standard. [Halbeisen and
34+
Hungerbühler, *Optimal Bounds for the Length of Rational Collatz Cycles*](https://people.math.ethz.ch/~halorenz/publications/pdf/collatz.pdf)
35+
define the odd-denominator rational parity rule and present the affine
36+
parity-word fixed-point formula (Lemma 2, attributed there to Lagarias).
37+
Their accelerated map includes an odd update followed immediately by a
38+
halving. The ordinary eight-step word here corresponds to the five-step
39+
accelerated word `11010`. No priority claim is made for this rational cycle
40+
or the standard affine identity.
41+
42+
## Why integrality matters
43+
44+
The rational minimum is `23/5>1`. The maximum/minimum ratio is
45+
`116/23≈5.04348`, so every state remains in the ratio-`51/10` band anchored
46+
at that minimum. Yet every value is strictly less than `(81/16)*(23/5)`.
47+
The exact gap between that threshold and the maximum is `7/80`.
48+
Consequently, even the multiplicative part of the repository's integer
49+
floor excursion theorem fails for this rational floor. The cycle does
50+
exceed five times its minimum, by `1/5`, and therefore does not refute the
51+
ratio-five excursion result.
52+
53+
Lean proves the generalized return equation for the branch word `OEOEEOEE`:
54+
55+
`32*x8 = 27*x0 + 23*d`.
56+
57+
Closure forces `5*x0=23*d`, and the full natural-number classification is
58+
`d=5t`, `x0=23t`. In particular, denominator one has no closed encoding in
59+
this word. The actual integer class `n=32q+11` instead satisfies
60+
61+
`C^8(n)=27q+10<n`.
62+
63+
The code gives its exact eight-step trace, return identity, and the converse
64+
source-residue constraint. This integer class was already closed in
65+
`Strategy/ExcursionMap.lean`; the new file records the fixed clock and its
66+
relationship to the rational closure obstruction. It is not a newly
67+
resolved residue class or an established frontier discovery.
68+
69+
The exploratory real-affine guide exhausted ratio five at depth twelve,
70+
but retained feasible prefixes at depth 48 for several larger ratios.
71+
Those surviving prefixes are evidence about a relaxation, not integer
72+
orbits. In particular, the rational anchor `23/5` is not an allowed natural
73+
anchor in the current band-clock theorem. No wider-band integer exit
74+
clock is refuted or proved by this exploration. A subsequent search can
75+
use the anchor's integrality and state congruences before declaring a
76+
prefix viable.
77+
78+
## Verification
79+
80+
Run `python3 scripts/audit_rational_band_obstruction.py`. It builds the
81+
module, checks all 24 named theorem axiom footprints, scans the source for
82+
proof escapes, and requires Lean to reject four false transfers. Independent
83+
Fraction tests check 10,000 rational states, 4,100 odd scales including large
84+
integers, 56 exact affine branch words (16 parity-valid), 10,004 integer
85+
traces, and denominator-one/even-scale controls. These finite tests
86+
corroborate the universal Lean proofs; no computation is imported as an
87+
axiom. The library export and CI include the new audit.
88+
89+
The conjecture and the requested frontier-novel proportion remain open.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env python3
2+
"""Build, independently test, audit axioms, and reject false denominator transfers."""
3+
import subprocess
4+
from audit_barrier_kernel import ROOT, check_axioms, check_false_certificates
5+
from check_proof_escapes import violations
6+
7+
MODULE = 'Collatz.Exploration.RationalBandObstruction'
8+
SOURCE = ROOT / 'Collatz/Exploration/RationalBandObstruction.lean'
9+
10+
11+
def main():
12+
assert not violations(SOURCE.read_text())
13+
subprocess.run(['lake', 'build', MODULE], cwd=ROOT, check=True)
14+
subprocess.run(['python3', str(ROOT / 'scripts/test_rational_band_obstruction.py')],
15+
cwd=ROOT, check=True)
16+
count = check_axioms(SOURCE, MODULE)
17+
prefix = 'Collatz.Exploration.RationalBandObstruction.'
18+
claims = [
19+
f'example : {prefix}denominatorOrbit 5 8 23 = 24 := by decide\n',
20+
f'example : {prefix}denominatorStep 1 23 = 74 := by decide\n',
21+
f'example : {prefix}denominatorOrbit 10 8 46 = 46 := by decide\n',
22+
'example : Collatz.orbit 8 11 = 11 := by decide\n',
23+
]
24+
rejected = check_false_certificates(MODULE, claims)
25+
print(f'{count} theorem axiom footprints checked; {rejected} false transfers rejected')
26+
27+
28+
if __name__ == '__main__':
29+
main()
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env python3
2+
"""Exact Fraction dynamics, odd-scale encodings, and integer comparison controls."""
3+
from fractions import Fraction as F
4+
from itertools import combinations
5+
from test_barrier_kernel import trajectory
6+
7+
8+
def rational_step(x):
9+
assert x.denominator % 2 == 1
10+
return x/2 if x.numerator % 2 == 0 else 3*x+1
11+
12+
13+
def numerator_step(d, n):
14+
return n//2 if n % 2 == 0 else 3*n+d
15+
16+
17+
def main():
18+
expected = [23, 74, 37, 116, 58, 29, 92, 46]
19+
x = F(23, 5)
20+
for k in range(10000):
21+
assert x == F(expected[k % 8], 5)
22+
assert F(23, 5) <= x <= F(116, 5)
23+
assert x < F(81, 16)*F(23, 5)
24+
x = rational_step(x)
25+
assert x == F(23, 5)
26+
assert F(81, 16)*F(23, 5)-F(116, 5) == F(7, 80)
27+
assert F(116, 23) < F(51, 10)
28+
scales = list(range(1, 8192, 2)) + [2**p-1 for p in (90, 180, 512, 1024)]
29+
for t in scales:
30+
n = 23*t
31+
for k in range(64):
32+
assert n == expected[k % 8]*t
33+
assert F(n, 5*t) == F(expected[k % 8], 5)
34+
n = numerator_step(5*t, n)
35+
assert n == 23*t
36+
# Systematic enumeration of the 56 branch words with three odd updates.
37+
words = genuine = 0
38+
ratios = []
39+
for positions in combinations(range(8), 3):
40+
word = ''.join('1' if i in positions else '0' for i in range(8))
41+
a, c = F(1), F(0)
42+
for bit in word:
43+
a, c = (a/2, c/2) if bit == '0' else (3*a, 3*c+1)
44+
assert a == F(27, 32)
45+
start = c/(1-a)
46+
states = []
47+
x = start
48+
valid = True
49+
for bit in word:
50+
states.append(x)
51+
valid &= (x.numerator % 2 == int(bit)) and x.denominator % 2 == 1
52+
x = x/2 if bit == '0' else 3*x+1
53+
assert x == start
54+
words += 1
55+
if valid:
56+
genuine += 1
57+
ratios.append(max(states)/min(states))
58+
assert words == 56 and genuine == 16 and min(ratios) == F(116, 23)
59+
qs = list(range(10000)) + [2**p-1 for p in (90, 180, 512, 1024)]
60+
for q in qs:
61+
values = trajectory(32*q+11, 8)
62+
assert values == [32*q+11, 96*q+34, 48*q+17, 144*q+52,
63+
72*q+26, 36*q+13, 108*q+40, 54*q+20, 27*q+10]
64+
assert values[-1] < values[0]
65+
assert 32*values[-1] == 27*values[0]+23
66+
# Actual integer dynamics and a changed/even denominator must not be conflated.
67+
assert numerator_step(5, 23) == 74 and trajectory(23, 1)[1] == 70
68+
assert numerator_step(10, 46) != 74*2
69+
for n in range(10000):
70+
assert numerator_step(1, n) == trajectory(n, 1)[1]
71+
print(f'10000 rational states; {len(scales)} odd scales; {words} exact affine words '
72+
f'({genuine} parity-valid); {len(qs)} integer traces; bridge and denominator controls passed')
73+
74+
75+
if __name__ == '__main__':
76+
main()

0 commit comments

Comments
 (0)