import HeytingLean.Bridge.Veselov.HybridZeckendorf.Addition import Mathlib.Data.Real.GoldenRatio import Mathlib.Algebra.BigOperators.Group.Finset.Defs /-! # Bridge.Veselov.HybridZeckendorf.Multiplication Stretch operations: parity/halving/doubling, multiplication, and density. -/ namespace HeytingLean.Bridge.Veselov.HybridZeckendorf /-- Double operation at semantic level. -/ noncomputable def doubleHybrid (X : HybridNumber) : HybridNumber := add X X /-- Positive hybrid levels carry even weights. -/ theorem weight_even_of_pos : ∀ {i : Nat}, 0 < i → 2 ∣ weight i | 0, h => (Nat.lt_irrefl 0 h).elim | 1, _ => ⟨500, by norm_num [weight]⟩ | i + 2, _ => by have hprev : 2 ∣ weight (i + 1) := weight_even_of_pos (Nat.succ_pos _) have hmul : 2 ∣ weight (i + 1) * weight (i + 1) := dvd_mul_of_dvd_left hprev _ simpa [weight, Nat.pow_two] using hmul /-- Structural half of all positive-level contributions. -/ noncomputable def halfTailNat (X : HybridNumber) : Nat := (X.erase 0).sum (fun i z => levelEval z * (weight i / 2)) theorem eval_erase_zero_even (X : HybridNumber) : 2 ∣ eval (X.erase 0) := by classical unfold eval Finsupp.sum refine Finset.dvd_sum ?_ intro i hi have hi0 : i ≠ 0 := by intro h0 subst h0 simp [Finsupp.mem_support_iff] at hi exact dvd_mul_of_dvd_right (weight_even_of_pos (Nat.pos_of_ne_zero hi0)) _ theorem eval_erase_zero_eq_two_mul_halfTailNat (X : HybridNumber) : eval (X.erase 0) = 2 * halfTailNat X := by classical unfold eval halfTailNat Finsupp.sum calc ∑ i ∈ (X.erase 0).support, levelEval ((X.erase 0) i) * weight i = ∑ i ∈ (X.erase 0).support, 2 * (levelEval ((X.erase 0) i) * (weight i / 2)) := by refine Finset.sum_congr rfl ?_ intro i hi have hi0 : i ≠ 0 := by intro h0 subst h0 simp [Finsupp.mem_support_iff] at hi have hdiv : 2 ∣ weight i := weight_even_of_pos (Nat.pos_of_ne_zero hi0) have hmul : 2 * (weight i / 2) = weight i := Nat.mul_div_cancel' hdiv calc levelEval ((X.erase 0) i) * weight i = levelEval ((X.erase 0) i) * (2 * (weight i / 2)) := by rw [hmul] _ = 2 * (levelEval ((X.erase 0) i) * (weight i / 2)) := by simp [Nat.mul_assoc, Nat.mul_comm] _ = ∑ i ∈ (X.erase 0).support, (levelEval ((X.erase 0) i) * (weight i / 2) + levelEval ((X.erase 0) i) * (weight i / 2)) := by simp [two_mul] _ = (∑ i ∈ (X.erase 0).support, levelEval ((X.erase 0) i) * (weight i / 2)) + (∑ i ∈ (X.erase 0).support, levelEval ((X.erase 0) i) * (weight i / 2)) := by rw [Finset.sum_add_distrib] _ = 2 * (∑ i ∈ (X.erase 0).support, levelEval ((X.erase 0) i) * (weight i / 2)) := by simp [two_mul] theorem eval_eq_level_zero_add_eval_erase_zero (X : HybridNumber) : eval X = levelEval (X 0) + eval (X.erase 0) := by calc eval X = eval (X.erase 0 + Finsupp.single 0 (X 0)) := by simpa using congrArg eval (Finsupp.erase_add_single 0 X).symm _ = eval (X.erase 0) + eval (Finsupp.single 0 (X 0)) := eval_add _ _ _ = eval (X.erase 0) + levelEval (X 0) * weight 0 := by simp [eval_single] _ = levelEval (X 0) + eval (X.erase 0) := by simp [weight, Nat.add_comm] /-- Halve operation by structural decomposition: level `0` handles odd remainder; positive levels contribute an even tail. -/ noncomputable def halveHybrid (X : HybridNumber) : HybridNumber := let level0Half := levelEval (X 0) / 2 let tailHalf := halfTailNat X add (fromNat level0Half) (fromNat tailHalf) /-- Parity query. -/ def isOddHybrid (X : HybridNumber) : Bool := decide (eval X % 2 = 1) theorem doubleHybrid_correct (X : HybridNumber) : eval (doubleHybrid X) = 2 * eval X := by calc eval (doubleHybrid X) = eval X + eval X := by simp [doubleHybrid, add_correct] _ = 2 * eval X := by rw [two_mul] theorem halveHybrid_correct (X : HybridNumber) : eval (halveHybrid X) = eval X / 2 := by let a := levelEval (X 0) let b := halfTailNat X have htail : eval (X.erase 0) = 2 * b := by simpa [b] using eval_erase_zero_eq_two_mul_halfTailNat X have hsplit : eval X = a + eval (X.erase 0) := by simpa [a] using eval_eq_level_zero_add_eval_erase_zero X rcases eval_erase_zero_even X with ⟨k, hk⟩ have hb : b = k := by have h2 : 2 * b = 2 * k := by rw [← htail, hk] exact Nat.eq_of_mul_eq_mul_left (by decide : 0 < (2 : Nat)) h2 calc eval (halveHybrid X) = a / 2 + b := by simp [halveHybrid, a, b, add_correct] _ = a / 2 + k := by rw [hb] _ = (a + 2 * k) / 2 := by have hdiv : (a + 2 * k) / 2 = a / 2 + k := by simpa [Nat.mul_comm] using (Nat.add_mul_div_right a k (by decide : 0 < (2 : Nat))) exact hdiv.symm _ = (a + eval (X.erase 0)) / 2 := by rw [hk] _ = eval X / 2 := by rw [hsplit] /-- Repeated structural addition. -/ noncomputable def repeatAdd (A : HybridNumber) : Nat → HybridNumber | 0 => 0 | n + 1 => add (repeatAdd A n) A theorem repeatAdd_correct (A : HybridNumber) : ∀ n : Nat, eval (repeatAdd A n) = eval A * n | 0 => by simp [repeatAdd, eval] | n + 1 => by calc eval (repeatAdd A (n + 1)) = eval (add (repeatAdd A n) A) := by simp [repeatAdd] _ = eval (repeatAdd A n) + eval A := add_correct _ _ _ = eval A * n + eval A := by simp [repeatAdd_correct A n, Nat.mul_comm] _ = eval A * (n + 1) := by rw [Nat.mul_add, Nat.mul_one] /-- Structural bounded multiplication fold over levels `0..n-1`. The outer loop is support-bounded; the per-level multiplicity remains semantic via `levelEval (B n) * weight n`. -/ noncomputable def multiplyUpTo (A B : HybridNumber) : Nat → HybridNumber | 0 => fromNat 0 | n + 1 => add (multiplyUpTo A B n) (repeatAdd A (levelEval (B n) * weight n)) theorem multiplyUpTo_correct (A B : HybridNumber) : ∀ n : Nat, eval (multiplyUpTo A B n) = eval A * (∑ i ∈ Finset.range n, levelEval (B i) * weight i) | 0 => by simp [multiplyUpTo] | n + 1 => by calc eval (multiplyUpTo A B (n + 1)) = eval (add (multiplyUpTo A B n) (repeatAdd A (levelEval (B n) * weight n))) := by simp [multiplyUpTo] _ = eval (multiplyUpTo A B n) + eval (repeatAdd A (levelEval (B n) * weight n)) := by simpa using add_correct (multiplyUpTo A B n) (repeatAdd A (levelEval (B n) * weight n)) _ = eval A * (∑ i ∈ Finset.range n, levelEval (B i) * weight i) + eval A * (levelEval (B n) * weight n) := by simp [multiplyUpTo_correct A B n, repeatAdd_correct] _ = eval A * ((∑ i ∈ Finset.range n, levelEval (B i) * weight i) + (levelEval (B n) * weight n)) := by rw [Nat.mul_add] _ = eval A * (∑ i ∈ Finset.range (n + 1), levelEval (B i) * weight i) := by simp [Finset.sum_range_succ] /-- Sum over bounded levels up to support depth matches semantic evaluation. -/ theorem sum_range_supportDepth_eq_eval (B : HybridNumber) : (∑ i ∈ Finset.range (B.support.sup id + 1), levelEval (B i) * weight i) = eval B := by have hsub : B.support ⊆ Finset.range (B.support.sup id + 1) := by intro i hi exact Finset.mem_range.mpr (Nat.lt_succ_of_le (Finset.le_sup (f := id) hi)) have hsum : (∑ i ∈ B.support, levelEval (B i) * weight i) = (∑ i ∈ Finset.range (B.support.sup id + 1), levelEval (B i) * weight i) := by refine Finset.sum_subset hsub ?_ intro i hiRange hiNotMem have hiZero : B i = 0 := Finsupp.notMem_support_iff.mp hiNotMem have hlevel0 : levelEval (B i) = 0 := by rw [hiZero] change (List.map Nat.fib ([] : List Nat)).sum = 0 simp simp [hlevel0] calc (∑ i ∈ Finset.range (B.support.sup id + 1), levelEval (B i) * weight i) = (∑ i ∈ B.support, levelEval (B i) * weight i) := hsum.symm _ = eval B := by simp [eval, Finsupp.sum] /-- Binary multiplication via structural bounded fold over support depth, with per-level semantic multiplicities delegated to `repeatAdd`. -/ noncomputable def multiplyBinary (A B : HybridNumber) : HybridNumber := multiplyUpTo A B (B.support.sup id + 1) theorem multiplyBinary_correct (A B : HybridNumber) : eval (multiplyBinary A B) = eval A * eval B := by calc eval (multiplyBinary A B) = eval A * (∑ i ∈ Finset.range (B.support.sup id + 1), levelEval (B i) * weight i) := by simpa [multiplyBinary] using multiplyUpTo_correct A B (B.support.sup id + 1) _ = eval A * eval B := by rw [sum_range_supportDepth_eq_eval] /-- Number of active indices across levels. -/ def supportCard (X : HybridNumber) : Nat := X.sum (fun _ z => z.length) /-- Density-like statistic from the paper's section 4 expression. -/ noncomputable def density (X : HybridNumber) : Real := if eval X = 0 then 0 else (supportCard X : Real) / Real.logb Real.goldenRatio (eval X) end HeytingLean.Bridge.Veselov.HybridZeckendorf