import Mathlib import Definitions.Def_TateCurve_XMultDistinctRouteB set_option autoImplicit false set_option linter.unusedSectionVars false open scoped NNReal namespace TateCurve variable {K : Type*} [NontriviallyNormedField K] [IsUltrametricDist K] [CompleteSpace K] [CharZero K] [DecidableEq K] variable {q u v : K} section Helpers private lemma lt_of_mul_self_lt_mul_self {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (h : a * a < b * b) : a < b := by nlinarith private lemma lt_mul_inv_of_mul_lt {a b c : ℝ} (hb : 0 < b) (h : c * b < a) : c < a * b⁻¹ := by have h2 := mul_lt_mul_of_pos_right h (inv_pos.mpr hb) rwa [mul_assoc, mul_inv_cancel₀ (ne_of_gt hb), mul_one] at h2 private lemma mul_inv_le_one_of_le {a b : ℝ} (hb : 0 < b) (h : a ≤ b) : a * b⁻¹ ≤ 1 := by have h2 := mul_le_mul_of_nonneg_right h (inv_nonneg.mpr hb.le) rwa [mul_inv_cancel₀ (ne_of_gt hb)] at h2 private lemma mul_inv_lt_one_of_lt {a b : ℝ} (hb : 0 < b) (h : a < b) : a * b⁻¹ < 1 := by have h2 := mul_lt_mul_of_pos_right h (inv_pos.mpr hb) rwa [mul_inv_cancel₀ (ne_of_gt hb)] at h2 private lemma norm_zpow_le_or_one_le (hq0 : q ≠ 0) (hqR : ‖q‖ < 1) (n : ℤ) : ‖(q ^ n : K)‖ ≤ ‖q‖ ∨ (1 : ℝ) ≤ ‖(q ^ n : K)‖ := by have hqpos : (0 : ℝ) < ‖q‖ := norm_pos_iff.mpr hq0 by_cases hn : 1 ≤ n · left obtain ⟨a, ha⟩ : ∃ a : ℕ, n = (a : ℤ) + 1 := ⟨(n - 1).toNat, by omega⟩ have hsplit : (q : K) ^ n = q ^ (a : ℕ) * q := by rw [ha, zpow_add₀ hq0, zpow_one, zpow_natCast] rw [hsplit, norm_mul, norm_pow] calc ‖q‖ ^ a * ‖q‖ ≤ 1 * ‖q‖ := mul_le_mul_of_nonneg_right (pow_le_one₀ hqpos.le hqR.le) hqpos.le _ = ‖q‖ := one_mul _ · right obtain ⟨a, ha⟩ : ∃ a : ℕ, n = -(a : ℤ) := ⟨(-n).toNat, by omega⟩ have hpow : (q : K) ^ n = (q ^ (a : ℕ))⁻¹ := by rw [ha, zpow_neg, zpow_natCast] have hpos : (0 : ℝ) < ‖q‖ ^ a := pow_pos hqpos a have hle : ‖q‖ ^ a ≤ 1 := pow_le_one₀ hqpos.le hqR.le rw [hpow, norm_inv, norm_pow] calc (1 : ℝ) = ‖q‖ ^ a * (‖q‖ ^ a)⁻¹ := (mul_inv_cancel₀ (ne_of_gt hpos)).symm _ ≤ 1 * (‖q‖ ^ a)⁻¹ := mul_le_mul_of_nonneg_right hle (inv_nonneg.mpr hpos.le) _ = (‖q‖ ^ a)⁻¹ := one_mul _ lemma offLattice_of_norm_Ioo (hq0 : q ≠ 0) (hqR : ‖q‖ < 1) {x : K} (h1 : ‖q‖ < ‖x‖) (h2 : ‖x‖ < 1) : OffLattice q x := by intro n hn have hx : x = (q ^ n)⁻¹ := eq_inv_of_mul_eq_one_right hn have hxnorm : ‖x‖ = ‖(q ^ (-n) : K)‖ := by rw [hx, ← zpow_neg] rcases norm_zpow_le_or_one_le hq0 hqR (-n) with hle | hge · rw [hxnorm] at h1; linarith · rw [hxnorm] at h2; linarith private lemma AddParams.contra_div (h : AddParams q u v) {a b : ℤ} (heq : q ^ a * u = q ^ b * v) : False := by have hq0 := h.q_ne_zero apply h.offLattice_div (a - b) have hu : u = q ^ (-a) * (q ^ b * v) := by rw [← heq, ← mul_assoc, ← zpow_add₀ hq0, neg_add_cancel, zpow_zero, one_mul] rw [hu] calc q ^ (a - b) * (q ^ (-a) * (q ^ b * v) * v⁻¹) = (q ^ (a - b) * q ^ (-a) * q ^ b) * (v * v⁻¹) := by ring _ = q ^ (a - b + -a + b) * 1 := by rw [← zpow_add₀ hq0, ← zpow_add₀ hq0, mul_inv_cancel₀ h.v_ne_zero] _ = 1 := by rw [show a - b + -a + b = 0 by omega, zpow_zero, one_mul] private lemma AddParams.contra_mul (h : AddParams q u v) {a b : ℤ} (heq : (q ^ a * u) * (q ^ b * v) = 1) : False := by have hq0 := h.q_ne_zero apply h.offLattice_mul (a + b) calc q ^ (a + b) * (u * v) = (q ^ a * u) * (q ^ b * v) := by rw [zpow_add₀ hq0]; ring _ = 1 := heq end Helpers section Windowed private lemma contra_of_window (hq : ‖q‖₊ < 1) (h : AddParams q u v) {k m : ℤ} (hk2 : ‖q ^ k * u‖ ≤ 1) (hm2 : ‖q ^ m * v‖ ≤ 1) (hX : pointX q u = pointX q v) (hA : ‖q‖ < ‖q ^ k * u‖ * ‖q ^ m * v‖) : False := by have hq0 := h.q_ne_zero have hu'0 : q ^ k * u ≠ 0 := mul_ne_zero (zpow_ne_zero k hq0) h.u_ne_zero have hv'0 : q ^ m * v ≠ 0 := mul_ne_zero (zpow_ne_zero m hq0) h.v_ne_zero have hu'lat : OffLattice q (q ^ k * u) := h.offLattice_u.zpow_mul hq0 k have hv'lat : OffLattice q (q ^ m * v) := h.offLattice_v.zpow_mul hq0 m have hX' : pointX q (q ^ k * u) = pointX q (q ^ m * v) := by rw [pointX_zpow_mul hq0 k, pointX_zpow_mul hq0 m, hX] have hwin : ‖q‖ < ‖(q ^ k * u) * (q ^ m * v)‖ := by rwa [norm_mul] rcases eq_or_mul_eq_one_of_pointX_eq hq0 hq hu'0 hv'0 hu'lat hv'lat hk2 hm2 hwin hX' with hcase | hcase · exact h.contra_div hcase · exact h.contra_mul hcase private lemma contra_of_mul_lt (hq : ‖q‖₊ < 1) (h : AddParams q u v) {k m : ℤ} (hk1 : ‖q‖ < ‖q ^ k * u‖) (hm1 : ‖q‖ < ‖q ^ m * v‖) (hX : pointX q u = pointX q v) (hC : ‖q ^ k * u‖ * ‖q ^ m * v‖ < ‖q‖) : False := by have hq0 := h.q_ne_zero have hqpos : (0 : ℝ) < ‖q‖ := norm_pos_iff.mpr hq0 have hu'0 : q ^ k * u ≠ 0 := mul_ne_zero (zpow_ne_zero k hq0) h.u_ne_zero have hv'0 : q ^ m * v ≠ 0 := mul_ne_zero (zpow_ne_zero m hq0) h.v_ne_zero have hu'pos : (0 : ℝ) < ‖q ^ k * u‖ := norm_pos_iff.mpr hu'0 have hv'pos : (0 : ℝ) < ‖q ^ m * v‖ := norm_pos_iff.mpr hv'0 have hu'lat : OffLattice q (q ^ k * u) := h.offLattice_u.zpow_mul hq0 k have hv'lat : OffLattice q (q ^ m * v) := h.offLattice_v.zpow_mul hq0 m have hα0 : q * (q ^ k * u)⁻¹ ≠ 0 := mul_ne_zero hq0 (inv_ne_zero hu'0) have hβ0 : q * (q ^ m * v)⁻¹ ≠ 0 := mul_ne_zero hq0 (inv_ne_zero hv'0) have hαlat : OffLattice q (q * (q ^ k * u)⁻¹) := (hu'lat.inv hq0).q_mul hq0 have hβlat : OffLattice q (q * (q ^ m * v)⁻¹) := (hv'lat.inv hq0).q_mul hq0 have hα1 : ‖q * (q ^ k * u)⁻¹‖ ≤ 1 := by rw [norm_mul, norm_inv] exact mul_inv_le_one_of_le hu'pos hk1.le have hβ1 : ‖q * (q ^ m * v)⁻¹‖ ≤ 1 := by rw [norm_mul, norm_inv] exact mul_inv_le_one_of_le hv'pos hm1.le have hXα : pointX q (q * (q ^ k * u)⁻¹) = pointX q u := by rw [pointX_q_mul hq0, pointX_inv hq0 hu'0 hu'lat, pointX_zpow_mul hq0 k] have hXβ : pointX q (q * (q ^ m * v)⁻¹) = pointX q v := by rw [pointX_q_mul hq0, pointX_inv hq0 hv'0 hv'lat, pointX_zpow_mul hq0 m] have hX' : pointX q (q * (q ^ k * u)⁻¹) = pointX q (q * (q ^ m * v)⁻¹) := by rw [hXα, hXβ, hX] have hwin : ‖q‖ < ‖(q * (q ^ k * u)⁻¹) * (q * (q ^ m * v)⁻¹)‖ := by have hkey : ‖q‖ * (‖q ^ k * u‖ * ‖q ^ m * v‖) < ‖q‖ * ‖q‖ := mul_lt_mul_of_pos_left hC hqpos have hprod_pos : (0 : ℝ) < ‖q ^ k * u‖ * ‖q ^ m * v‖ := mul_pos hu'pos hv'pos calc ‖q‖ < (‖q‖ * ‖q‖) * (‖q ^ k * u‖ * ‖q ^ m * v‖)⁻¹ := lt_mul_inv_of_mul_lt hprod_pos hkey _ = (‖q‖ * ‖q ^ k * u‖⁻¹) * (‖q‖ * ‖q ^ m * v‖⁻¹) := by rw [mul_inv]; ring _ = ‖(q * (q ^ k * u)⁻¹) * (q * (q ^ m * v)⁻¹)‖ := by rw [norm_mul (q * (q ^ k * u)⁻¹) (q * (q ^ m * v)⁻¹), norm_mul q (q ^ k * u)⁻¹, norm_mul q (q ^ m * v)⁻¹, norm_inv (q ^ k * u), norm_inv (q ^ m * v)] have hαeq : q * (q ^ k * u)⁻¹ = q ^ (1 + -k) * u⁻¹ := by rw [mul_inv, ← zpow_neg, zpow_add₀ hq0, zpow_one]; ring have hβeq : q * (q ^ m * v)⁻¹ = q ^ (1 + -m) * v⁻¹ := by rw [mul_inv, ← zpow_neg, zpow_add₀ hq0, zpow_one]; ring rcases eq_or_mul_eq_one_of_pointX_eq hq0 hq hα0 hβ0 hαlat hβlat hα1 hβ1 hwin hX' with hcase | hcase · rw [hαeq, hβeq] at hcase exact (h.inv_left.inv_right).contra_div hcase · rw [hαeq, hβeq] at hcase exact (h.inv_left.inv_right).contra_mul hcase private lemma contra_of_norm_lt (hq : ‖q‖₊ < 1) (h : AddParams q u v) {k m : ℤ} (hk2 : ‖q ^ k * u‖ ≤ 1) (hm1 : ‖q‖ < ‖q ^ m * v‖) (hX : pointX q u = pointX q v) (hD : ‖q ^ m * v‖ < ‖q ^ k * u‖) : False := by have hq0 := h.q_ne_zero have hqpos : (0 : ℝ) < ‖q‖ := norm_pos_iff.mpr hq0 have hu'0 : q ^ k * u ≠ 0 := mul_ne_zero (zpow_ne_zero k hq0) h.u_ne_zero have hv'0 : q ^ m * v ≠ 0 := mul_ne_zero (zpow_ne_zero m hq0) h.v_ne_zero have hv'pos : (0 : ℝ) < ‖q ^ m * v‖ := norm_pos_iff.mpr hv'0 have hu'lat : OffLattice q (q ^ k * u) := h.offLattice_u.zpow_mul hq0 k have hv'lat : OffLattice q (q ^ m * v) := h.offLattice_v.zpow_mul hq0 m have hβ0 : q * (q ^ m * v)⁻¹ ≠ 0 := mul_ne_zero hq0 (inv_ne_zero hv'0) have hβlat : OffLattice q (q * (q ^ m * v)⁻¹) := (hv'lat.inv hq0).q_mul hq0 have hβ1 : ‖q * (q ^ m * v)⁻¹‖ ≤ 1 := by rw [norm_mul, norm_inv] exact mul_inv_le_one_of_le hv'pos hm1.le have hXβ : pointX q (q * (q ^ m * v)⁻¹) = pointX q v := by rw [pointX_q_mul hq0, pointX_inv hq0 hv'0 hv'lat, pointX_zpow_mul hq0 m] have hX' : pointX q (q ^ k * u) = pointX q (q * (q ^ m * v)⁻¹) := by rw [pointX_zpow_mul hq0 k, hXβ, hX] have hwin : ‖q‖ < ‖(q ^ k * u) * (q * (q ^ m * v)⁻¹)‖ := by have hkey : ‖q‖ * ‖q ^ m * v‖ < ‖q ^ k * u‖ * ‖q‖ := by calc ‖q‖ * ‖q ^ m * v‖ < ‖q‖ * ‖q ^ k * u‖ := mul_lt_mul_of_pos_left hD hqpos _ = ‖q ^ k * u‖ * ‖q‖ := mul_comm _ _ calc ‖q‖ < (‖q ^ k * u‖ * ‖q‖) * ‖q ^ m * v‖⁻¹ := lt_mul_inv_of_mul_lt hv'pos hkey _ = ‖q ^ k * u‖ * (‖q‖ * ‖q ^ m * v‖⁻¹) := by ring _ = ‖(q ^ k * u) * (q * (q ^ m * v)⁻¹)‖ := by rw [norm_mul (q ^ k * u) (q * (q ^ m * v)⁻¹), norm_mul q (q ^ m * v)⁻¹, norm_inv (q ^ m * v)] have hβeq : q * (q ^ m * v)⁻¹ = q ^ (1 + -m) * v⁻¹ := by rw [mul_inv, ← zpow_neg, zpow_add₀ hq0, zpow_one]; ring rcases eq_or_mul_eq_one_of_pointX_eq hq0 hq hu'0 hβ0 hu'lat hβlat hk2 hβ1 hwin hX' with hcase | hcase · rw [hβeq] at hcase exact (h.inv_right).contra_div hcase · rw [hβeq] at hcase exact (h.inv_right).contra_mul hcase end Windowed theorem pointX_ne_of_addParams_of_psiTwo (hq0 : q ≠ 0) (hq : ‖q‖₊ < 1) (hex : ∃ w : K, ‖q‖ < ‖w‖ * ‖w‖ ∧ ‖w‖ < 1) (hsum : ∀ u v : K, AddParams q u v → (pointX q (u * v) + pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = symSumNum q (pointX q u) (pointX q v)) (hdiff : ∀ u v : K, AddParams q u v → (pointX q (u * v) - pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = -((2 * pointY q u + pointX q u) * (2 * pointY q v + pointX q v))) (h : AddParams q u v) (hpsiu : 2 * pointY q u + pointX q u = 0) (hpsiv : 2 * pointY q v + pointX q v = 0) : pointX q u ≠ pointX q v := by intro hX have hqR : ‖q‖ < 1 := by exact_mod_cast hq have hqpos : (0 : ℝ) < ‖q‖ := norm_pos_iff.mpr hq0 obtain ⟨k, hk1, hk2⟩ := exists_zpow_mul_norm_Ioc hq0 hqR h.u_ne_zero obtain ⟨m, hm1, hm2⟩ := exists_zpow_mul_norm_Ioc hq0 hqR h.v_ne_zero rcases lt_trichotomy (‖q ^ k * u‖ * ‖q ^ m * v‖) ‖q‖ with hC | hAB | hA · exact contra_of_mul_lt hq h hk1 hm1 hX hC · rcases lt_trichotomy ‖q ^ k * u‖ ‖q ^ m * v‖ with hD | hEq | hD · exact contra_of_norm_lt hq h.swap hm2 hk1 hX.symm hD · have hu'sq : ‖q ^ k * u‖ * ‖q ^ k * u‖ = ‖q‖ := by rw [hEq] at hAB ⊢; exact hAB have hv'sq : ‖q ^ m * v‖ * ‖q ^ m * v‖ = ‖q‖ := by rw [← hEq]; exact hu'sq have huv_eq : ‖q ^ k * u‖ * ‖q ^ m * v‖ = ‖q‖ := hAB have hu'0 : q ^ k * u ≠ 0 := mul_ne_zero (zpow_ne_zero k hq0) h.u_ne_zero have hv'0 : q ^ m * v ≠ 0 := mul_ne_zero (zpow_ne_zero m hq0) h.v_ne_zero have hu'pos : (0 : ℝ) < ‖q ^ k * u‖ := norm_pos_iff.mpr hu'0 have hv'pos : (0 : ℝ) < ‖q ^ m * v‖ := norm_pos_iff.mpr hv'0 have hu'lat : OffLattice q (q ^ k * u) := h.offLattice_u.zpow_mul hq0 k have hv'lat : OffLattice q (q ^ m * v) := h.offLattice_v.zpow_mul hq0 m have hXu' : pointX q (q ^ k * u) = pointX q u := pointX_zpow_mul hq0 k have hXv' : pointX q (q ^ m * v) = pointX q v := pointX_zpow_mul hq0 m have hX' : pointX q (q ^ k * u) = pointX q (q ^ m * v) := by rw [hXu', hXv', hX] have hpsiu' : 2 * pointY q (q ^ k * u) + pointX q (q ^ k * u) = 0 := by rw [pointX_zpow_mul hq0 k, pointY_zpow_mul hq0 k]; exact hpsiu have hpsiv' : 2 * pointY q (q ^ m * v) + pointX q (q ^ m * v) = 0 := by rw [pointX_zpow_mul hq0 m, pointY_zpow_mul hq0 m]; exact hpsiv set u' := q ^ k * u with hu'def set v' := q ^ m * v with hv'def obtain ⟨ω, hω1, hω2⟩ := hex have hωpos : (0 : ℝ) < ‖ω‖ := by nlinarith [norm_nonneg ω] have hω0 : ω ≠ 0 := norm_pos_iff.mp hωpos have hωgt : ‖q‖ < ‖ω‖ := by nlinarith have hωlat : OffLattice q ω := offLattice_of_norm_Ioo hq0 hqR hωgt hω2 have hu'ω_lt : ‖u' * ω‖ < 1 := by rw [norm_mul] calc ‖u'‖ * ‖ω‖ ≤ 1 * ‖ω‖ := mul_le_mul_of_nonneg_right hk2 (norm_nonneg ω) _ = ‖ω‖ := one_mul _ _ < 1 := hω2 have hu'ω_gt : ‖q‖ < ‖u' * ω‖ := by rw [norm_mul] apply lt_of_mul_self_lt_mul_self hqpos.le (by positivity) calc ‖q‖ * ‖q‖ < ‖q‖ * (‖ω‖ * ‖ω‖) := mul_lt_mul_of_pos_left hω1 hqpos _ = (‖u'‖ * ‖u'‖) * (‖ω‖ * ‖ω‖) := by rw [hu'sq] _ = (‖u'‖ * ‖ω‖) * (‖u'‖ * ‖ω‖) := by ring have hv'ω_lt : ‖v' * ω‖ < 1 := by rw [norm_mul] calc ‖v'‖ * ‖ω‖ ≤ 1 * ‖ω‖ := mul_le_mul_of_nonneg_right hm2 (norm_nonneg ω) _ = ‖ω‖ := one_mul _ _ < 1 := hω2 have hv'ω_gt : ‖q‖ < ‖v' * ω‖ := by rw [norm_mul] apply lt_of_mul_self_lt_mul_self hqpos.le (by positivity) calc ‖q‖ * ‖q‖ < ‖q‖ * (‖ω‖ * ‖ω‖) := mul_lt_mul_of_pos_left hω1 hqpos _ = (‖v'‖ * ‖v'‖) * (‖ω‖ * ‖ω‖) := by rw [hv'sq] _ = (‖v'‖ * ‖ω‖) * (‖v'‖ * ‖ω‖) := by ring have hu'ωinv_lt : ‖u' * ω⁻¹‖ < 1 := by rw [norm_mul, norm_inv] apply mul_inv_lt_one_of_lt hωpos apply lt_of_mul_self_lt_mul_self (norm_nonneg _) (norm_nonneg _) rw [hu'sq]; exact hω1 have hu'ωinv_gt : ‖q‖ < ‖u' * ω⁻¹‖ := by rw [norm_mul, norm_inv] apply lt_mul_inv_of_mul_lt hωpos calc ‖q‖ * ‖ω‖ < ‖q‖ * 1 := mul_lt_mul_of_pos_left hω2 hqpos _ = ‖q‖ := mul_one _ _ < ‖u'‖ := hk1 have hv'ωinv_lt : ‖v' * ω⁻¹‖ < 1 := by rw [norm_mul, norm_inv] apply mul_inv_lt_one_of_lt hωpos apply lt_of_mul_self_lt_mul_self (norm_nonneg _) (norm_nonneg _) rw [hv'sq]; exact hω1 have hv'ωinv_gt : ‖q‖ < ‖v' * ω⁻¹‖ := by rw [norm_mul, norm_inv] apply lt_mul_inv_of_mul_lt hωpos calc ‖q‖ * ‖ω‖ < ‖q‖ * 1 := mul_lt_mul_of_pos_left hω2 hqpos _ = ‖q‖ := mul_one _ _ < ‖v'‖ := hm1 have hPu : AddParams q u' ω := { q_ne_zero := hq0 u_ne_zero := hu'0 v_ne_zero := hω0 offLattice_u := hu'lat offLattice_v := hωlat offLattice_mul := offLattice_of_norm_Ioo hq0 hqR hu'ω_gt hu'ω_lt offLattice_div := offLattice_of_norm_Ioo hq0 hqR hu'ωinv_gt hu'ωinv_lt } have hPv : AddParams q v' ω := { q_ne_zero := hq0 u_ne_zero := hv'0 v_ne_zero := hω0 offLattice_u := hv'lat offLattice_v := hωlat offLattice_mul := offLattice_of_norm_Ioo hq0 hqR hv'ω_gt hv'ω_lt offLattice_div := offLattice_of_norm_Ioo hq0 hqR hv'ωinv_gt hv'ωinv_lt } have hXuω : pointX q u' ≠ pointX q ω := by intro hXeq rcases eq_or_mul_eq_one_of_pointX_eq hq0 hq hu'0 hω0 hu'lat hωlat hk2 hω2.le hu'ω_gt hXeq with hcase | hcase · have hcontra : ‖u'‖ * ‖u'‖ = ‖ω‖ * ‖ω‖ := by rw [hcase] rw [hu'sq] at hcontra exact absurd hcontra (ne_of_lt hω1) · have hcontra : ‖u' * ω‖ = 1 := by rw [hcase, norm_one] exact absurd hcontra (ne_of_lt hu'ω_lt) have hXvω : pointX q v' ≠ pointX q ω := by intro hXeq rcases eq_or_mul_eq_one_of_pointX_eq hq0 hq hv'0 hω0 hv'lat hωlat hm2 hω2.le hv'ω_gt hXeq with hcase | hcase · have hcontra : ‖v'‖ * ‖v'‖ = ‖ω‖ * ‖ω‖ := by rw [hcase] rw [hv'sq] at hcontra exact absurd hcontra (ne_of_lt hω1) · have hcontra : ‖v' * ω‖ = 1 := by rw [hcase, norm_one] exact absurd hcontra (ne_of_lt hv'ω_lt) have hΔu : (pointX q u' - pointX q ω) ^ 2 ≠ 0 := pow_ne_zero 2 (sub_ne_zero.mpr hXuω) have hΔv : (pointX q v' - pointX q ω) ^ 2 ≠ 0 := pow_ne_zero 2 (sub_ne_zero.mpr hXvω) have hDu : pointX q (u' * ω) = pointX q (u' * ω⁻¹) := by have h0 : (pointX q (u' * ω) - pointX q (u' * ω⁻¹)) * (pointX q u' - pointX q ω) ^ 2 = 0 := by rw [hdiff u' ω hPu, hpsiu']; ring rcases mul_eq_zero.mp h0 with h1 | h1 · exact sub_eq_zero.mp h1 · exact absurd h1 hΔu have hDv : pointX q (v' * ω) = pointX q (v' * ω⁻¹) := by have h0 : (pointX q (v' * ω) - pointX q (v' * ω⁻¹)) * (pointX q v' - pointX q ω) ^ 2 = 0 := by rw [hdiff v' ω hPv, hpsiv']; ring rcases mul_eq_zero.mp h0 with h1 | h1 · exact sub_eq_zero.mp h1 · exact absurd h1 hΔv have hSsum : (pointX q (u' * ω) + pointX q (u' * ω⁻¹)) * (pointX q u' - pointX q ω) ^ 2 = (pointX q (v' * ω) + pointX q (v' * ω⁻¹)) * (pointX q v' - pointX q ω) ^ 2 := by rw [hsum u' ω hPu, hsum v' ω hPv, hX'] have hΔeq : (pointX q u' - pointX q ω) ^ 2 = (pointX q v' - pointX q ω) ^ 2 := by rw [hX'] have hXsum : pointX q (u' * ω) + pointX q (u' * ω⁻¹) = pointX q (v' * ω) + pointX q (v' * ω⁻¹) := by rw [hΔeq] at hSsum exact mul_right_cancel₀ hΔv hSsum have hfinal : pointX q (u' * ω⁻¹) = pointX q (v' * ω⁻¹) := by rw [hDu, hDv, ← two_mul, ← two_mul] at hXsum exact mul_left_cancel₀ (by norm_num : (2 : K) ≠ 0) hXsum have hα0 : u' * ω⁻¹ ≠ 0 := mul_ne_zero hu'0 (inv_ne_zero hω0) have hβ0 : v' * ω⁻¹ ≠ 0 := mul_ne_zero hv'0 (inv_ne_zero hω0) have hαlat : OffLattice q (u' * ω⁻¹) := offLattice_of_norm_Ioo hq0 hqR hu'ωinv_gt hu'ωinv_lt have hβlat : OffLattice q (v' * ω⁻¹) := offLattice_of_norm_Ioo hq0 hqR hv'ωinv_gt hv'ωinv_lt have hwin : ‖q‖ < ‖(u' * ω⁻¹) * (v' * ω⁻¹)‖ := by have hωω_lt : ‖ω‖ * ‖ω‖ < 1 := by nlinarith [norm_nonneg ω] have hωω_pos : (0 : ℝ) < ‖ω‖ * ‖ω‖ := mul_pos hωpos hωpos have hkey : ‖q‖ * (‖ω‖ * ‖ω‖) < ‖u'‖ * ‖v'‖ := by calc ‖q‖ * (‖ω‖ * ‖ω‖) < ‖q‖ * 1 := mul_lt_mul_of_pos_left hωω_lt hqpos _ = ‖q‖ := mul_one _ _ = ‖u'‖ * ‖v'‖ := huv_eq.symm calc ‖q‖ < (‖u'‖ * ‖v'‖) * (‖ω‖ * ‖ω‖)⁻¹ := lt_mul_inv_of_mul_lt hωω_pos hkey _ = (‖u'‖ * ‖ω‖⁻¹) * (‖v'‖ * ‖ω‖⁻¹) := by rw [mul_inv]; ring _ = ‖(u' * ω⁻¹) * (v' * ω⁻¹)‖ := by rw [norm_mul (u' * ω⁻¹) (v' * ω⁻¹), norm_mul u' ω⁻¹, norm_mul v' ω⁻¹, norm_inv ω] rcases eq_or_mul_eq_one_of_pointX_eq hq0 hq hα0 hβ0 hαlat hβlat hu'ωinv_lt.le hv'ωinv_lt.le hwin hfinal with hcase | hcase · have huv' : u' = v' := mul_right_cancel₀ (inv_ne_zero hω0) hcase rw [hu'def, hv'def] at huv' exact h.contra_div huv' · have hval : u' * v' = ω * ω := by have hexp : ((u' * ω⁻¹) * (v' * ω⁻¹)) * (ω * ω) = u' * v' := by calc ((u' * ω⁻¹) * (v' * ω⁻¹)) * (ω * ω) = (u' * v') * ((ω⁻¹ * ω) * (ω⁻¹ * ω)) := by ring _ = (u' * v') * (1 * 1) := by rw [inv_mul_cancel₀ hω0] _ = u' * v' := by ring calc u' * v' = ((u' * ω⁻¹) * (v' * ω⁻¹)) * (ω * ω) := hexp.symm _ = 1 * (ω * ω) := by rw [hcase] _ = ω * ω := one_mul _ have hnorm : ‖q‖ = ‖ω‖ * ‖ω‖ := by calc ‖q‖ = ‖u'‖ * ‖v'‖ := huv_eq.symm _ = ‖u' * v'‖ := (norm_mul u' v').symm _ = ‖ω * ω‖ := by rw [hval] _ = ‖ω‖ * ‖ω‖ := norm_mul ω ω exact absurd hnorm (ne_of_lt hω1) · exact contra_of_norm_lt hq h hk2 hm1 hX hD · exact contra_of_window hq h hk2 hm2 hX hA theorem symAdd_prod_of_sum_diff_forall_of_exists (hq0 : q ≠ 0) (hq : ‖q‖₊ < 1) (hex : ∃ w : K, ‖q‖ < ‖w‖ * ‖w‖ ∧ ‖w‖ < 1) (hsum : ∀ u v : K, AddParams q u v → (pointX q (u * v) + pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = symSumNum q (pointX q u) (pointX q v)) (hdiff : ∀ u v : K, AddParams q u v → (pointX q (u * v) - pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = -((2 * pointY q u + pointX q u) * (2 * pointY q v + pointX q v))) : ∀ u v : K, AddParams q u v → pointX q (u * v) * pointX q (u * v⁻¹) * (pointX q u - pointX q v) ^ 2 = symProdNum q (pointX q u) (pointX q v) := by intro u v h by_cases hne : pointX q u = pointX q v · exfalso have hS1 := hsum u v h have hQ1 := two_mul_pointY_add_pointX_sq hq0 hq h.u_ne_zero h.offLattice_u have hQ2 := two_mul_pointY_add_pointX_sq hq0 hq h.v_ne_zero h.offLattice_v have hzero : symSumNum q (pointX q u) (pointX q u) = 0 := by have h2 : (pointX q u - pointX q v) ^ 2 = 0 := by rw [hne]; ring calc symSumNum q (pointX q u) (pointX q u) = symSumNum q (pointX q u) (pointX q v) := by rw [hne] _ = (pointX q (u * v) + pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 := hS1.symm _ = 0 := by rw [h2, mul_zero] have hpsiu : 2 * pointY q u + pointX q u = 0 := by have hsq : (2 * pointY q u + pointX q u) ^ 2 = 0 := by rw [hQ1] simp only [symSumNum] at hzero linear_combination hzero exact pow_eq_zero_iff (n := 2) (by norm_num) |>.mp hsq have hpsiv : 2 * pointY q v + pointX q v = 0 := by have hsq : (2 * pointY q v + pointX q v) ^ 2 = 0 := by rw [hQ2, ← hne] simp only [symSumNum] at hzero linear_combination hzero exact pow_eq_zero_iff (n := 2) (by norm_num) |>.mp hsq exact pointX_ne_of_addParams_of_psiTwo hq0 hq hex hsum hdiff h hpsiu hpsiv hne · exact symAdd_prod_of_sum_of_diff hq0 hq h.u_ne_zero h.offLattice_u h.v_ne_zero h.offLattice_v hne (hsum u v h) (hdiff u v h) theorem symAddHyps_of_sum_diff_of_exists (hq0 : q ≠ 0) (hq : ‖q‖₊ < 1) (hex : ∃ w : K, ‖q‖ < ‖w‖ * ‖w‖ ∧ ‖w‖ < 1) (hsum : ∀ u v : K, AddParams q u v → (pointX q (u * v) + pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = symSumNum q (pointX q u) (pointX q v)) (hdiff : ∀ u v : K, AddParams q u v → (pointX q (u * v) - pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = -((2 * pointY q u + pointX q u) * (2 * pointY q v + pointX q v))) : SymAddHyps q := symAddHyps_of_sum_prod hq0 hq hsum (symAdd_prod_of_sum_diff_forall_of_exists hq0 hq hex hsum hdiff) theorem symAddHyps_of_sum_diff_of_isAlgClosed [IsAlgClosed K] (hq0 : q ≠ 0) (hq : ‖q‖₊ < 1) (hsum : ∀ u v : K, AddParams q u v → (pointX q (u * v) + pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = symSumNum q (pointX q u) (pointX q v)) (hdiff : ∀ u v : K, AddParams q u v → (pointX q (u * v) - pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = -((2 * pointY q u + pointX q u) * (2 * pointY q v + pointX q v))) : SymAddHyps q := by refine symAddHyps_of_sum_diff_of_exists hq0 hq ?_ hsum hdiff obtain ⟨z, hz⟩ := IsAlgClosed.exists_pow_nat_eq q (n := 4) (by norm_num) have hqR : ‖q‖ < 1 := by exact_mod_cast hq have hz0 : z ≠ 0 := by intro h0 apply hq0 rw [← hz, h0] norm_num have hzpos : (0 : ℝ) < ‖z‖ := norm_pos_iff.mpr hz0 have h4 : ‖z‖ ^ 4 = ‖q‖ := by rw [← norm_pow, hz] have hzlt : ‖z‖ < 1 := by by_contra hcon rw [not_lt] at hcon have h1 : (1 : ℝ) ≤ ‖z‖ ^ 4 := by calc (1 : ℝ) = 1 ^ 4 := by norm_num _ ≤ ‖z‖ ^ 4 := by gcongr rw [h4] at h1 linarith have hzz_lt : ‖z‖ * ‖z‖ < 1 := by nlinarith [norm_nonneg z] have hzz_pos : (0 : ℝ) < ‖z‖ * ‖z‖ := mul_pos hzpos hzpos refine ⟨z, ?_, hzlt⟩ have hq_eq : ‖q‖ = (‖z‖ * ‖z‖) * (‖z‖ * ‖z‖) := by rw [← h4]; ring rw [hq_eq] calc (‖z‖ * ‖z‖) * (‖z‖ * ‖z‖) < (‖z‖ * ‖z‖) * 1 := mul_lt_mul_of_pos_left hzz_lt hzz_pos _ = ‖z‖ * ‖z‖ := mul_one _ end TateCurve