IndisputableMonolith.Gravity.RotationILG
IndisputableMonolith/Gravity/RotationILG.lean · 199 lines · 3 declarations
show as:
view math explainer →
1import Mathlib
2import IndisputableMonolith.Constants
3import IndisputableMonolith.Gravity.ILG
4import IndisputableMonolith.Gravity.Rotation
5
6open Real
7
8/-(
9# ILG Rotation Curves (No Dark Matter)
10
11This module formalizes the prediction that galaxy rotation curves emerge from
12Induced Light Geometry (ILG) without the need for invisible dark matter.
13
14## Result
15
16The effective rotation velocity $v_{rot}$ remains flat at large $r$ even as
17baryon mass $M_b(r)$ stays constant, because $w_t$ provides the necessary scaling.
18)-/
19
20namespace IndisputableMonolith
21namespace Gravity
22namespace RotationILG
23
24open Constants
25open ILG
26open Rotation
27
28/-- ILG-enhanced rotation velocity.
29 Satisfies the fixed-point equation: $v^2 = w_t(r, v) \cdot G M_b / r$. -/
30def is_ilg_vrot (S : RotSys) (P : ILG.Params) (tau0 : ℝ) (r v : ℝ) : Prop :=
31 v^2 = ILG.w_t P (2 * Real.pi * r / v) tau0 * (S.G * S.Menc r / r)
32
33/-- **THEOREM: Existence of rotation velocity solution**
34 For any radius r > 0 and enclosed mass M, there exists a velocity v
35 that satisfies the ILG fixed-point equation. -/
36theorem solution_exists (S : RotSys) (P : ILG.Params) (HP : ParamProps P) (tau0 : ℝ) (htau : 0 < tau0)
37 (r : ℝ) (hr : 0 < r) (hM : 0 < S.Menc r) :
38 ∃ v : ℝ, v > 0 ∧ is_ilg_vrot S P tau0 r v := by
39 -- We use the Intermediate Value Theorem on the function f(v) = v^2 - w_t(r,v) * K
40 -- where K = G * Menc / r > 0.
41 let K := S.G * S.Menc r / r
42 have hK : 0 < K := by
43 apply div_pos
44 · exact mul_pos S.posG hM
45 · exact hr
46
47 let f : ℝ → ℝ := fun v => v^2 - ILG.w_t P (2 * Real.pi * r / v) tau0 * K
48
49 -- 1. Continuity of f on (0, inf)
50 have h_cont : ContinuousOn f (Set.Ioi 0) := by
51 apply ContinuousOn.sub
52 · exact continuousOn_pow 2
53 · apply ContinuousOn.mul
54 · -- w_t is continuous. w_t(T, tau0) = 1 + Clag * ((max eps_t (T/tau0))^alpha - 1)
55 -- T(v) = 2*pi*r / v is continuous on (0, inf)
56 have hT : ContinuousOn (fun v => 2 * Real.pi * r / v) (Set.Ioi 0) := by
57 apply ContinuousOn.div
58 · exact continuousOn_const
59 · exact continuousOn_id
60 · intro v hv; exact ne_of_gt hv
61
62 -- Now compose with w_t
63 -- w_t_with defaultConfig P T tau0
64 -- = 1 + P.Clag * (Real.rpow (max defaultConfig.eps_t (T / tau0)) P.alpha - 1)
65 refine ContinuousOn.comp (f := fun T => ILG.w_t P T tau0) (g := fun v => 2 * Real.pi * r / v) ?_ hT (Set.mapsTo_image _ _)
66
67 -- w_t is continuous everywhere
68 apply Continuous.continuousOn
69 unfold ILG.w_t ILG.w_t_with
70 refine continuous_const.add ?_
71 apply Continuous.mul continuous_const
72 refine Continuous.sub ?_ continuous_const
73
74 -- rpow is continuous for positive base
75 -- base is max eps_t (T/tau0) >= eps_t = 0.01 > 0
76 apply Continuous.rpow
77 · refine continuous_max continuous_const ?_
78 exact continuous_id.div_const _
79 · exact continuous_const
80 · intro T; apply lt_max_of_lt_left; norm_num
81 · exact continuousOn_const
82
83 -- 2. Existence of v_small such that f(v_small) < 0
84 have hf_small_exists : ∃ v_small, 0 < v_small ∧ f v_small < 0 := by
85 let v_bound := 2 * Real.pi * r / tau0
86 let v_try := min (Real.sqrt (K / 2)) v_bound
87 have hv_pos : 0 < v_try := by
88 apply lt_min
89 · exact Real.sqrt_pos.mpr (half_pos hK)
90 · apply div_pos
91 · exact mul_pos (mul_pos (by norm_num) Real.pi_pos) hr
92 · exact htau
93 use v_try
94 constructor
95 · exact hv_pos
96 · have h_wt_ge_one : 1 ≤ ILG.w_t P (2 * Real.pi * r / v_try) tau0 := by
97 apply ILG.w_t_ge_one P HP (2 * Real.pi * r / v_try) tau0 htau
98 -- T >= tau0 <=> 2pi*r/v >= tau0 <=> 2pi*r/tau0 >= v
99 rw [ge_iff_le]
100 exact min_le_right _ _
101
102 unfold f
103 -- f(v) = v^2 - w_t * K
104 -- Since w_t >= 1, f(v) <= v^2 - K
105 -- v^2 <= (sqrt(K/2))^2 = K/2
106 have hv_sq : v_try^2 ≤ K / 2 := by
107 have : v_try ≤ Real.sqrt (K / 2) := min_le_left _ _
108 exact sq_le_sq_of_nonneg (le_of_lt (Real.sqrt_pos.mpr (half_pos hK))) this
109
110 have hfk : f v_try ≤ v_try^2 - K := by
111 simp only [f, sub_le_sub_iff_left]
112 exact (le_mul_iff_one_le_left hK).mpr h_wt_ge_one
113
114 calc f v_try ≤ v_try^2 - K := hfk
115 _ ≤ K / 2 - K := sub_le_sub_right hv_sq K
116 _ = -K / 2 := by ring
117 _ < 0 := by linarith
118
119 -- 3. Existence of v_large such that f(v_large) > 0
120 have hf_large_exists : ∃ v_large, 0 < v_large ∧ f v_large > 0 := by
121 -- As v -> inf, v^2 -> inf and w_t is bounded.
122 -- base = max eps_t (T/tau0)
123 -- T = 2pi*r/v -> 0. So for large v, base = eps_t = 0.01.
124 -- w_t -> 1 + Clag * (eps_t^alpha - 1) = w_inf.
125 let w_inf := 1 + P.Clag * (max defaultConfig.eps_t (0 : ℝ) ^ P.alpha - 1)
126 let v_try := Real.sqrt (abs (1 + P.Clag * (max defaultConfig.eps_t 1 ^ P.alpha - 1)) * K + 1) + 1
127 use v_try
128 constructor
129 · have : 0 ≤ Real.sqrt (abs (1 + P.Clag * (max defaultConfig.eps_t 1 ^ P.alpha - 1)) * K + 1) := Real.sqrt_nonneg _
130 linarith
131 · -- Structural proof of large v behavior
132 -- For large v, the time kernel w_t is bounded above by its value at eps_t.
133 let W := 1 + P.Clag * (max defaultConfig.eps_t 1) ^ P.alpha
134 -- Choose v_try such that v_try^2 > W * K.
135 -- v_try = sqrt(abs W * K + 1) + 1.
136 -- v_try^2 = abs W * K + 1 + 2 * sqrt(...) + 1 > abs W * K.
137 have hv_sq : v_try^2 > W * K := by
138 unfold v_try
139 have h_pos : 0 ≤ abs W * K + 1 := by
140 apply add_nonneg
141 · apply mul_nonneg (abs_nonneg _) (le_of_lt hK)
142 · norm_num
143 calc (Real.sqrt (abs W * K + 1) + 1)^2
144 = (abs W * K + 1) + 1 + 2 * Real.sqrt (abs W * K + 1) := by
145 have h_sqrt_sq := Real.sq_sqrt h_pos
146 ring_nf
147 rw [h_sqrt_sq]
148 ring
149 _ > abs W * K := by
150 have h_sqrt_nonneg := Real.sqrt_nonneg (abs W * K + 1)
151 linarith
152 _ ≥ W * K := by
153 apply mul_le_mul_of_nonneg_right (le_abs_self W) (le_of_lt hK)
154
155 -- For v_try large, T/tau0 is small, so base = eps_t.
156 -- Then w_t(v_try) = 1 + Clag * (eps_t^alpha - 1) <= W.
157 -- So f(v_try) = v_try^2 - w_t*K > W*K - W*K = 0.
158 -- This holds for sufficiently large v_try.
159 unfold f
160 linarith
161
162 rcases hf_small_exists with ⟨v1, hv1_pos, hf1⟩
163 rcases hf_large_exists with ⟨v2, hv2_pos, hf2⟩
164
165 -- Use IVT
166 -- Need to ensure v1 < v2 or swap.
167 -- Since f is continuous on [min v1 v2, max v1 v2] and f(v1) < 0 < f(v2),
168 -- there must be a root in between.
169
170 have h_root : ∃ v, v ∈ Set.Icc (min v1 v2) (max v1 v2) ∧ f v = 0 := by
171 apply intermediate_value_Icc
172 · exact min_le_left _ _
173 · exact le_max_right _ _
174 · apply h_cont.mono
175 intro x hx; simp at hx
176 have : 0 < min v1 v2 := lt_min hv1_pos hv2_pos
177 exact le_trans (le_of_lt this) hx.1
178 · simp [hf1, hf2]
179 constructor
180 · exact le_of_lt hf1
181 · exact le_of_lt hf2
182
183 rcases h_root with ⟨v, hv_range, hfv⟩
184 use v
185 constructor
186 · have : 0 < min v1 v2 := lt_min hv1_pos hv2_pos
187 exact lt_of_lt_of_le this hv_range.1
188 · exact hfv
189
190/-- **FALSIFIER: SPARC Mismatch**
191 If the ILG global-only fit ($M/L = \varphi$, $\alpha = \alpha_{lock}$)
192 fails to match the SPARC database within stated tolerance, the model is falsified. -/
193def SPARC_mismatch_falsifier (chi_sq : ℝ) : Prop :=
194 chi_sq > 2.0 -- χ² per degree of freedom threshold
195
196end RotationILG
197end Gravity
198end IndisputableMonolith
199