import ContractExact /-! # Exact runtime, season 2: starting champion for the new families The season-1 families are the contract's pinned kernels (`Pinned.kernels`); this entry replaces `conv2d` and supplies the `attn` and `rnn` families: - `conv2d` (`convFast`) has fast paths for depthwise layers (one exact dot over the window taps per output) and pointwise 1×1 layers (`dotSel` over the input channels); other shapes use the generic `conv2dWith dotFn` (`convFast_eq`, `pointwiseConv_eq`). - `sigmoid`, `tanh` and `exp` (for `x ≤ 0`) have fast paths (`FastAct`). `e^(−|x|)` is enclosed in 64-bit fixed point (tables of `e^(−n)` and `e^(−j/64)`, a degree-6 Taylor sum, every product rounded in the safe direction); quotients start from a `Float` guess that is then checked exactly; a result is returned only when both ends of its enclosure round to the same finite nonzero word (`FastRound.roundW`, `FastRound.bracket_spec`). Otherwise the spec decides. - `scores`, `mix` and softmax's sum use `dotSel`: sums of more than two terms go to `dotWin`, which sums the products truncated on a window below the largest exponent in 64-bit words and accepts when both ends of the `±n`-unit enclosure round alike (`dotWin_spec`); the rest use `dotFn`. - LSTM and GRU use the fast activations with the pinned `dotFn`: their operands are computed per read, and the window path, which reads them twice, measured slower there. `correct` proves the entry equals the specs; `sigmoidF_eq`, `tanhF_eq`, `expF_eq`, `dotWin_spec` and `convFast_eq` carry the new parts. -/ namespace FastAct /-! ## 128-bit products of 64-bit words -/ /-- The middle column of `a · b` from four 32-bit products (carries into the high half). -/ @[inline] def midW (a b : UInt64) : UInt64 := (((a &&& (0xffffffff : UInt64)) * (b &&& (0xffffffff : UInt64))) >>> (32 : UInt64)) + (((a &&& (0xffffffff : UInt64)) * (b >>> (32 : UInt64))) &&& (0xffffffff : UInt64)) + (((a >>> (32 : UInt64)) * (b &&& (0xffffffff : UInt64))) &&& (0xffffffff : UInt64)) /-- The high 64 bits of `a · b`. -/ @[inline] def mulHiW (a b : UInt64) : UInt64 := (a >>> (32 : UInt64)) * (b >>> (32 : UInt64)) + (((a &&& (0xffffffff : UInt64)) * (b >>> (32 : UInt64))) >>> (32 : UInt64)) + (((a >>> (32 : UInt64)) * (b &&& (0xffffffff : UInt64))) >>> (32 : UInt64)) + (midW a b >>> (32 : UInt64)) /-- The low 64 bits of `a · b`. -/ @[inline] def mulLoW (a b : UInt64) : UInt64 := (midW a b <<< (32 : UInt64)) + ((a &&& (0xffffffff : UInt64)) * (b &&& (0xffffffff : UInt64)) &&& (0xffffffff : UInt64)) /-- `a · b` as `(high, low)` 64-bit halves (for proofs; the code reads the halves directly). -/ def mul128 (a b : UInt64) : UInt64 × UInt64 := (mulHiW a b, mulLoW a b) theorem toNat_and_mask (x : UInt64) : (x &&& 0xffffffff).toNat = x.toNat % 2 ^ 32 := by rw [UInt64.toNat_and] exact Nat.and_two_pow_sub_one_eq_mod x.toNat 32 theorem toNat_shr32 (x : UInt64) : (x >>> 32).toNat = x.toNat / 2 ^ 32 := by rw [UInt64.toNat_shiftRight] simp [Nat.shiftRight_eq_div_pow] theorem mul128_spec (a b : UInt64) : (mul128 a b).1.toNat * 2 ^ 64 + (mul128 a b).2.toNat = a.toNat * b.toNat := by have ha := a.toNat_lt have hb := b.toNat_lt have hk : a.toNat * b.toNat < 2 ^ 128 := calc a.toNat * b.toNat < 2 ^ 64 * 2 ^ 64 := Nat.mul_lt_mul'' ha hb _ = 2 ^ 128 := by norm_num simp only [mul128, mulHiW, mulLoW, midW, UInt64.toNat_add, UInt64.toNat_mul, UInt64.toNat_shiftLeft, toNat_and_mask, toNat_shr32] have h32 : (32 : UInt64).toNat % 64 = 32 := by decide rw [h32, Nat.shiftLeft_eq] have hA := (Nat.div_add_mod' a.toNat (2 ^ 32)).symm have hB := (Nat.div_add_mod' b.toNat (2 ^ 32)).symm have hA0 : a.toNat % 2 ^ 32 < 2 ^ 32 := Nat.mod_lt _ (by norm_num) have hB0 : b.toNat % 2 ^ 32 < 2 ^ 32 := Nat.mod_lt _ (by norm_num) have hA1 : a.toNat / 2 ^ 32 < 2 ^ 32 := by omega have hB1 : b.toNat / 2 ^ 32 < 2 ^ 32 := by omega generalize a.toNat / 2 ^ 32 = A1 at * generalize a.toNat % 2 ^ 32 = A0 at * generalize b.toNat / 2 ^ 32 = B1 at * generalize b.toNat % 2 ^ 32 = B0 at * have prod_lt : ∀ x y : Nat, x < 2 ^ 32 → y < 2 ^ 32 → x * y < 2 ^ 64 := fun x y hx hy => calc x * y < 2 ^ 32 * 2 ^ 32 := Nat.mul_lt_mul'' hx hy _ = 2 ^ 64 := by norm_num have m00 := prod_lt A0 B0 hA0 hB0 have m01 := prod_lt A0 B1 hA0 hB1 have m10 := prod_lt A1 B0 hA1 hB0 have m11 := prod_lt A1 B1 hA1 hB1 have hab : a.toNat * b.toNat = A1 * B1 * 2 ^ 64 + (A0 * B1 + A1 * B0) * 2 ^ 32 + A0 * B0 := by rw [hA, hB]; ring simp only [Nat.mod_eq_of_lt m00, Nat.mod_eq_of_lt m01, Nat.mod_eq_of_lt m10, Nat.mod_eq_of_lt m11] rw [hab] generalize A0 * B0 = p00 at * generalize A0 * B1 = p01 at * generalize A1 * B0 = p10 at * generalize A1 * B1 = p11 at * omega /-! ## Fixed point on the grid `2^(−62)` A natural number `a` stands for `a / 2^62` (`V a`). Every quantity below is at most about `1`, so values stay below `2^63` and remain unboxed. -/ /-- `1` on the grid. -/ def one : Nat := 2 ^ 62 /-- The real value of a grid number. -/ noncomputable def V (a : Nat) : ℝ := (a : ℝ) / 2 ^ 62 theorem V_nonneg (a : Nat) : 0 ≤ V a := by unfold V; positivity theorem V_one : V one = 1 := by norm_num [V, one] theorem V_mono {a b : Nat} (h : a ≤ b) : V a ≤ V b := by unfold V; gcongr theorem V_add (a b : Nat) : V (a + b) = V a + V b := by unfold V; push_cast; ring theorem V_sub_ge (a b : Nat) : V a - V b ≤ V (a - b) := by unfold V rcases le_total b a with h | h · rw [Nat.cast_sub h]; ring_nf; rfl · rw [Nat.sub_eq_zero_of_le h] have : (a : ℝ) ≤ b := by exact_mod_cast h simp only [Nat.cast_zero, zero_div] rw [div_sub_div_same] exact div_nonpos_of_nonpos_of_nonneg (by linarith) (by positivity) theorem V_sub_le_of_le {a b : Nat} (h : b ≤ a) : V (a - b) = V a - V b := by unfold V; rw [Nat.cast_sub h]; ring /-- `⌊a · b / 2^62⌋` as a word (wrapping past `2^64`). -/ @[inline] def mulDnW (a b : UInt64) : UInt64 := (mulHiW a b <<< 2) + (mulLoW a b >>> 62) /-- `⌈a · b / 2^62⌉` as a word. -/ @[inline] def mulUpW (a b : UInt64) : UInt64 := if mulLoW a b &&& 0x3fffffffffffffff = 0 then mulDnW a b else mulDnW a b + 1 /-- `⌊a · b / 2^62⌋`; a lower bound for any `a, b`. -/ @[inline] def mulDn (a b : Nat) : Nat := (mulDnW a.toUInt64 b.toUInt64).toNat /-- `⌈a · b / 2^62⌉` for `a, b ≤ one`. -/ @[inline] def mulUp (a b : Nat) : Nat := (mulUpW a.toUInt64 b.toUInt64).toNat theorem toNat_toUInt64_le (a : Nat) : a.toUInt64.toNat ≤ a := by rw [UInt64.toNat_ofNat']; exact Nat.mod_le _ _ theorem toNat_toUInt64_of_lt {a : Nat} (h : a < 2 ^ 64) : a.toUInt64.toNat = a := by rw [UInt64.toNat_ofNat']; exact Nat.mod_eq_of_lt h theorem toNat_mulDnW (a b : UInt64) : (mulDnW a b).toNat = ((mulHiW a b).toNat * 4 % 2 ^ 64 + (mulLoW a b).toNat / 2 ^ 62) % 2 ^ 64 := by unfold mulDnW rw [UInt64.toNat_add, UInt64.toNat_shiftLeft, UInt64.toNat_shiftRight] have h2 : (2 : UInt64).toNat % 64 = 2 := by decide have h62 : (62 : UInt64).toNat % 64 = 62 := by decide rw [h2, h62, Nat.shiftLeft_eq, Nat.shiftRight_eq_div_pow] theorem low62_zero_iff (x : UInt64) : (x &&& 0x3fffffffffffffff = 0) ↔ x.toNat % 2 ^ 62 = 0 := by rw [← UInt64.toNat_inj, UInt64.toNat_and] have : (0x3fffffffffffffff : UInt64).toNat = 2 ^ 62 - 1 := by decide rw [this, Nat.and_two_pow_sub_one_eq_mod]; simp /-- The halves of a product of two numbers below `2^64`. -/ theorem halves {a b : Nat} (ha : a < 2 ^ 64) (hb : b < 2 ^ 64) : (mulHiW a.toUInt64 b.toUInt64).toNat * 2 ^ 64 + (mulLoW a.toUInt64 b.toUInt64).toNat = a * b := by have hs := mul128_spec a.toUInt64 b.toUInt64 rwa [toNat_toUInt64_of_lt ha, toNat_toUInt64_of_lt hb] at hs theorem mulDn_mul_le (a b : Nat) : mulDn a b * 2 ^ 62 ≤ a * b := by have hs := mul128_spec a.toUInt64 b.toUInt64 have hle : a.toUInt64.toNat * b.toUInt64.toNat ≤ a * b := Nat.mul_le_mul (toNat_toUInt64_le a) (toNat_toUInt64_le b) simp only [mul128] at hs unfold mulDn rw [toNat_mulDnW] generalize (mulHiW a.toUInt64 b.toUInt64).toNat = h at * generalize (mulLoW a.toUInt64 b.toUInt64).toNat = l at * omega /-- For operands at most `one`, `mulUp` is the exact ceiling: within `2^62` above `a · b`. -/ theorem mulUp_bounds {a b : Nat} (ha : a ≤ one) (hb : b ≤ one) : a * b ≤ mulUp a b * 2 ^ 62 ∧ mulUp a b * 2 ^ 62 < a * b + 2 ^ 62 := by have hs := halves (a := a) (b := b) (by unfold one at ha; omega) (by unfold one at hb; omega) have hab : a * b ≤ 2 ^ 62 * 2 ^ 62 := Nat.mul_le_mul ha hb have hl := (mulLoW a.toUInt64 b.toUInt64).toNat_lt unfold mulUp mulUpW split · rename_i h rw [low62_zero_iff] at h rw [toNat_mulDnW] generalize a * b = p at * generalize (mulHiW a.toUInt64 b.toUInt64).toNat = hi at * generalize (mulLoW a.toUInt64 b.toUInt64).toNat = l at * omega · rename_i h rw [low62_zero_iff] at h rw [UInt64.toNat_add, toNat_mulDnW, show (1 : UInt64).toNat = 1 from rfl] generalize a * b = p at * generalize (mulHiW a.toUInt64 b.toUInt64).toNat = hi at * generalize (mulLoW a.toUInt64 b.toUInt64).toNat = l at * omega theorem mulUp_mul_ge {a b : Nat} (ha : a ≤ one) (hb : b ≤ one) : a * b ≤ mulUp a b * 2 ^ 62 := (mulUp_bounds ha hb).1 theorem mulUp_le {a b : Nat} (ha : a ≤ one) (hb : b ≤ one) : mulUp a b ≤ one := by have h := (mulUp_bounds ha hb).2 have hab : a * b ≤ 2 ^ 62 * 2 ^ 62 := Nat.mul_le_mul ha hb unfold one at * generalize a * b = p at * omega theorem V_mulDn (a b : Nat) : V (mulDn a b) ≤ V a * V b := by have h := mulDn_mul_le a b unfold V rw [div_mul_div_comm, le_div_iff₀ (by positivity), div_mul_eq_mul_div, div_le_iff₀ (by positivity)] have : ((mulDn a b * 2 ^ 62 : Nat) : ℝ) ≤ ((a * b : Nat) : ℝ) := by exact_mod_cast h push_cast at this nlinarith [this] theorem V_mulUp {a b : Nat} (ha : a ≤ one) (hb : b ≤ one) : V a * V b ≤ V (mulUp a b) := by have h := mulUp_mul_ge ha hb unfold V rw [div_mul_div_comm, div_le_iff₀ (by positivity), div_mul_eq_mul_div, le_div_iff₀ (by positivity)] have : ((a * b : Nat) : ℝ) ≤ ((mulUp a b * 2 ^ 62 : Nat) : ℝ) := by exact_mod_cast h push_cast at this nlinarith [this] /-- Lower bounds multiply. -/ theorem V_mulDn_le {a b : Nat} {x y : ℝ} (ha : V a ≤ x) (hb : V b ≤ y) : V (mulDn a b) ≤ x * y := (V_mulDn a b).trans (mul_le_mul ha hb (V_nonneg b) ((V_nonneg a).trans ha)) /-- Upper bounds multiply (operands at most `1`). -/ theorem le_V_mulUp {a b : Nat} {x y : ℝ} (ha : x ≤ V a) (hb : y ≤ V b) (hy : 0 ≤ y) (ha1 : a ≤ one) (hb1 : b ≤ one) : x * y ≤ V (mulUp a b) := (mul_le_mul ha hb hy (V_nonneg a)).trans (V_mulUp ha1 hb1) theorem V_div_le (k : Nat) : V (one / k) ≤ 1 / k := by rcases Nat.eq_zero_or_pos k with rfl | hk · simp [V] have h : one / k * k ≤ one := Nat.div_mul_le_self one k have hc : ((one / k : Nat) : ℝ) * k ≤ (one : ℝ) := by exact_mod_cast h unfold V rw [div_le_div_iff₀ (by positivity) (by exact_mod_cast hk)] have : (one : ℝ) = 2 ^ 62 := by norm_num [one] linarith theorem le_V_divUp (k : Nat) (hk : 0 < k) : 1 / (k : ℝ) ≤ V ((one + k - 1) / k) := by have h : one ≤ (one + k - 1) / k * k := by have h2 := Nat.div_add_mod (one + k - 1) k have h3 := Nat.mod_lt (one + k - 1) hk have : (one + k - 1) / k * k = k * ((one + k - 1) / k) := Nat.mul_comm _ _ omega have hc : (one : ℝ) ≤ (((one + k - 1) / k : Nat) : ℝ) * k := by exact_mod_cast h unfold V rw [div_le_div_iff₀ (by exact_mod_cast hk) (by positivity)] have : (one : ℝ) = 2 ^ 62 := by norm_num [one] linarith /-! ## `e^(−r)` for `0 ≤ r ≤ 1/64`: Taylor sum of degree 6 with directed rounding -/ def f2l : Nat := one / 2 def f3l : Nat := one / 6 def f4l : Nat := one / 24 def f5l : Nat := one / 120 def f6l : Nat := one / 720 def f2h : Nat := (one + 2 - 1) / 2 def f3h : Nat := (one + 6 - 1) / 6 def f4h : Nat := (one + 24 - 1) / 24 def f5h : Nat := (one + 120 - 1) / 120 def f6h : Nat := (one + 720 - 1) / 720 /-- `8 / (7! · 7)` rounded up: the Taylor remainder factor (`Real.exp_bound`, `n = 7`). -/ def remF : Nat := (one + 35280 - 1) / 35280 * 8 /-- Enclosure of `e^(−r)` from `V rl ≤ r ≤ V rh`. -/ @[inline] def expSmall (rl rh : Nat) : Nat × Nat := let p2l := mulDn rl rl let p3l := mulDn p2l rl let p4l := mulDn p3l rl let p5l := mulDn p4l rl let p6l := mulDn p5l rl let p2h := mulUp rh rh let p3h := mulUp p2h rh let p4h := mulUp p3h rh let p5h := mulUp p4h rh let p6h := mulUp p5h rh let p7h := mulUp p6h rh let lo := (one + mulDn p2l f2l + mulDn p4l f4l + mulDn p6l f6l) - (rh + mulUp p3h f3h + mulUp p5h f5h + mulUp p7h remF) let hi := (one + mulUp p2h f2h + mulUp p4h f4h + mulUp p6h f6h + mulUp p7h remF) - (rl + mulDn p3l f3l + mulDn p5l f5l) (lo, min one hi) theorem exp_neg_taylor {r : ℝ} (h0 : 0 ≤ r) (h1 : r ≤ 1) : |Real.exp (-r) - (1 - r + r ^ 2 / 2 - r ^ 3 / 6 + r ^ 4 / 24 - r ^ 5 / 120 + r ^ 6 / 720)| ≤ r ^ 7 * (8 / 35280) := by have h := Real.exp_bound (x := -r) (by rw [abs_neg, abs_of_nonneg h0]; exact h1) (n := 7) (by norm_num) simp only [Finset.sum_range_succ, Finset.sum_range_zero, Nat.factorial] at h rw [abs_neg, abs_of_nonneg h0] at h convert h using 2 · norm_num; ring · norm_num theorem f_le_one {x : Nat} (k : Nat) (hk : 0 < k) (h : x = (one + k - 1) / k) : x ≤ one := by subst h; unfold one; apply Nat.div_le_of_le_mul; omega theorem expSmall_spec {rl rh : Nat} {r : ℝ} (hl : V rl ≤ r) (hh : r ≤ V rh) (hrh : rh ≤ one) : V (expSmall rl rh).1 ≤ Real.exp (-r) ∧ Real.exp (-r) ≤ V (expSmall rl rh).2 ∧ (expSmall rl rh).2 ≤ one := by have h0 : 0 ≤ r := (V_nonneg rl).trans hl have h1 : r ≤ 1 := hh.trans (V_one ▸ V_mono hrh) have hT := exp_neg_taylor h0 h1 have hp : ∀ n, 0 ≤ r ^ n := fun n => pow_nonneg h0 n -- lower powers have l2 : V (mulDn rl rl) ≤ r ^ 2 := by rw [sq]; exact V_mulDn_le hl hl have l3 : V (mulDn (mulDn rl rl) rl) ≤ r ^ 3 := by rw [pow_succ]; exact V_mulDn_le l2 hl have l4 : V (mulDn (mulDn (mulDn rl rl) rl) rl) ≤ r ^ 4 := by rw [pow_succ]; exact V_mulDn_le l3 hl have l5 : V (mulDn (mulDn (mulDn (mulDn rl rl) rl) rl) rl) ≤ r ^ 5 := by rw [pow_succ]; exact V_mulDn_le l4 hl have l6 : V (mulDn (mulDn (mulDn (mulDn (mulDn rl rl) rl) rl) rl) rl) ≤ r ^ 6 := by rw [pow_succ]; exact V_mulDn_le l5 hl -- upper powers, each at most `one` have u2 : r ^ 2 ≤ V (mulUp rh rh) := by rw [sq]; exact le_V_mulUp hh hh h0 hrh hrh have b2 : mulUp rh rh ≤ one := mulUp_le hrh hrh have u3 : r ^ 3 ≤ V (mulUp (mulUp rh rh) rh) := by rw [pow_succ]; exact le_V_mulUp u2 hh h0 b2 hrh have b3 := mulUp_le b2 hrh have u4 : r ^ 4 ≤ V (mulUp (mulUp (mulUp rh rh) rh) rh) := by rw [pow_succ]; exact le_V_mulUp u3 hh h0 b3 hrh have b4 := mulUp_le b3 hrh have u5 : r ^ 5 ≤ V (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) := by rw [pow_succ]; exact le_V_mulUp u4 hh h0 b4 hrh have b5 := mulUp_le b4 hrh have u6 : r ^ 6 ≤ V (mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) rh) := by rw [pow_succ]; exact le_V_mulUp u5 hh h0 b5 hrh have b6 := mulUp_le b5 hrh have u7 : r ^ 7 ≤ V (mulUp (mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) rh) rh) := by rw [pow_succ]; exact le_V_mulUp u6 hh h0 b6 hrh have b7 := mulUp_le b6 hrh -- factorial factors have fl : ∀ (k : Nat) (x : Nat), x = one / k → V x ≤ 1 / k := fun k x h => h ▸ V_div_le k have fh : ∀ (k : Nat) (x : Nat), 0 < k → x = (one + k - 1) / k → 1 / (k : ℝ) ≤ V x := fun k x hk h => h ▸ le_V_divUp k hk have hf2l := fl 2 f2l rfl have hf3l := fl 6 f3l rfl have hf4l := fl 24 f4l rfl have hf5l := fl 120 f5l rfl have hf6l := fl 720 f6l rfl have hf2h := fh 2 f2h (by norm_num) rfl have hf3h := fh 6 f3h (by norm_num) rfl have hf4h := fh 24 f4h (by norm_num) rfl have hf5h := fh 120 f5h (by norm_num) rfl have hf6h := fh 720 f6h (by norm_num) rfl have hremF : 8 / (35280 : ℝ) ≤ V remF := by have h := fh 35280 ((one + 35280 - 1) / 35280) (by norm_num) rfl unfold remF V at * push_cast at * rw [mul_div_right_comm] nlinarith have bf2 := f_le_one 2 (by norm_num) (rfl : f2h = _) have bf3 := f_le_one 6 (by norm_num) (rfl : f3h = _) have bf4 := f_le_one 24 (by norm_num) (rfl : f4h = _) have bf5 := f_le_one 120 (by norm_num) (rfl : f5h = _) have bf6 := f_le_one 720 (by norm_num) (rfl : f6h = _) have brem : remF ≤ one := by unfold remF one; norm_num have c2 := V_mulDn_le l2 hf2l have c3 := V_mulDn_le l3 hf3l have c4 := V_mulDn_le l4 hf4l have c5 := V_mulDn_le l5 hf5l have c6 := V_mulDn_le l6 hf6l have d2 := le_V_mulUp u2 hf2h (by norm_num) b2 bf2 have d3 := le_V_mulUp u3 hf3h (by norm_num) b3 bf3 have d4 := le_V_mulUp u4 hf4h (by norm_num) b4 bf4 have d5 := le_V_mulUp u5 hf5h (by norm_num) b5 bf5 have d6 := le_V_mulUp u6 hf6h (by norm_num) b6 bf6 have d7 := le_V_mulUp u7 hremF (by norm_num) b7 brem have hexp1 : Real.exp (-r) ≤ 1 := Real.exp_le_one_iff.mpr (by linarith) have hab := abs_le.mp hT refine ⟨?_, ?_, min_le_left _ _⟩ · simp only [expSmall] refine le_trans (b := max 0 (V (one + mulDn (mulDn rl rl) f2l + mulDn (mulDn (mulDn (mulDn rl rl) rl) rl) f4l + mulDn (mulDn (mulDn (mulDn (mulDn (mulDn rl rl) rl) rl) rl) rl) f6l) - V (rh + mulUp (mulUp (mulUp rh rh) rh) f3h + mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) f5h + mulUp (mulUp (mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) rh) rh) remF))) ?_ ?_ · unfold V rw [le_max_iff] rcases le_total (rh + mulUp (mulUp (mulUp rh rh) rh) f3h + mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) f5h + mulUp (mulUp (mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) rh) rh) remF) (one + mulDn (mulDn rl rl) f2l + mulDn (mulDn (mulDn (mulDn rl rl) rl) rl) f4l + mulDn (mulDn (mulDn (mulDn (mulDn (mulDn rl rl) rl) rl) rl) rl) f6l) with h | h · right; rw [Nat.cast_sub h]; ring_nf; rfl · left; rw [Nat.sub_eq_zero_of_le h]; simp · apply max_le (Real.exp_pos _).le simp only [V_add, V_one] at * nlinarith · simp only [expSmall] rcases le_total one (one + mulUp (mulUp rh rh) f2h + mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) f4h + mulUp (mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) rh) f6h + mulUp (mulUp (mulUp (mulUp (mulUp (mulUp (mulUp rh rh) rh) rh) rh) rh) rh) remF - (rl + mulDn (mulDn (mulDn rl rl) rl) f3l + mulDn (mulDn (mulDn (mulDn (mulDn rl rl) rl) rl) rl) f5l)) with h | h · rw [min_eq_left h, V_one]; exact hexp1 · rw [min_eq_right h] refine le_trans ?_ (V_sub_ge _ _) simp only [V_add, V_one] linarith [hab.2] /-! ## Tables: powers of an enclosure -/ /-- An enclosure `(lo, hi)` of `e^(−b)` with `hi ≤ one`. -/ def Encl (iv : Nat × Nat) (b : ℝ) : Prop := V iv.1 ≤ Real.exp (-b) ∧ Real.exp (-b) ≤ V iv.2 ∧ iv.2 ≤ one /-- `j`-th power of an enclosure of `e^(−b)`: an enclosure of `e^(−j b)`. -/ def powOf (base : Nat × Nat) : Nat → Nat × Nat | 0 => (one, one) | j + 1 => let p := powOf base j; (mulDn p.1 base.1, min one (mulUp p.2 base.2)) /-- The product of enclosures of `e^(−a)` and `e^(−b)` encloses `e^(−(a + b))`. -/ theorem Encl.mul {x y : Nat × Nat} {a b : ℝ} (hx : Encl x a) (hy : Encl y b) : Encl (mulDn x.1 y.1, min one (mulUp x.2 y.2)) (a + b) := by have he : Real.exp (-(a + b)) = Real.exp (-a) * Real.exp (-b) := by rw [← Real.exp_add]; ring_nf refine ⟨?_, ?_, min_le_left _ _⟩ · rw [he]; exact V_mulDn_le hx.1 hy.1 · rw [he] rcases le_total one (mulUp x.2 y.2) with h | h · rw [min_eq_left h, V_one, ← he] exact Real.exp_le_one_iff.mpr (by have := Real.exp_le_one_iff.mp (le_trans hx.2.1 (V_one ▸ V_mono hx.2.2)) have := Real.exp_le_one_iff.mp (le_trans hy.2.1 (V_one ▸ V_mono hy.2.2)) linarith) · rw [min_eq_right h] exact le_V_mulUp hx.2.1 hy.2.1 (Real.exp_pos _).le hx.2.2 hy.2.2 theorem powOf_spec {base : Nat × Nat} {b : ℝ} (hb : Encl base b) : ∀ j : Nat, Encl (powOf base j) (j * b) | 0 => by refine ⟨?_, ?_, le_rfl⟩ <;> simp [powOf, V_one] | j + 1 => by have := (powOf_spec hb j).mul hb simp only [powOf] convert this using 2; push_cast; ring /-- `2^56`, that is `1/64` on the grid. -/ def sixtyFourth : Nat := 2 ^ 56 theorem V_sixtyFourth : V sixtyFourth = 1 / 64 := by norm_num [V, sixtyFourth] /-- An enclosure of `e^(−1/64)`. -/ def base64 : Nat × Nat := expSmall sixtyFourth sixtyFourth theorem base64_spec : Encl base64 (1 / 64) := by exact expSmall_spec (rl := sixtyFourth) (rh := sixtyFourth) (r := 1 / 64) V_sixtyFourth.le V_sixtyFourth.ge (by norm_num [sixtyFourth, one]) /-- `e^(−j/64)` for `j < 64`. -/ def fracTab : Array (Nat × Nat) := Array.ofFn (n := 64) fun j => powOf base64 j.val /-- An enclosure of `e^(−1)`. -/ def baseOne : Nat × Nat := powOf base64 64 /-- `e^(−n)` for `n ≤ 16`. -/ def intTab : Array (Nat × Nat) := Array.ofFn (n := 17) fun n => powOf baseOne n.val theorem getElem!_ofFn' {α : Type} [Inhabited α] {n : Nat} (f : Fin n → α) {i : Nat} (h : i < n) : (Array.ofFn f)[i]! = f ⟨i, h⟩ := by rw [getElem!_pos (Array.ofFn f) i (by simpa using h)] simp theorem fracTab_spec {j : Nat} (h : j < 64) : Encl fracTab[j]! (j * (1 / 64)) := by rw [fracTab, getElem!_ofFn' _ h] exact powOf_spec base64_spec j theorem intTab_spec {n : Nat} (h : n < 17) : Encl intTab[n]! n := by rw [intTab, getElem!_ofFn' _ h] have h1 : Encl baseOne 1 := by have := powOf_spec base64_spec 64 simp only [baseOne]; convert this using 1; norm_num have := powOf_spec h1 n simpa using this /-! ## `e^(−c)` for `0 ≤ c < 17`: `c = n + j/64 + r` -/ /-- `c · 2^56` rounded down and up, for `c = m · 2^e`. -/ @[inline] def scaled (m : Nat) (e : Int) : Nat × Nat := if 0 ≤ e + 56 then let v := m <<< (e + 56).toNat; (v, v) else let v := m >>> (-(e + 56)).toNat; (v, v + 1) theorem scaled_spec (m : Nat) (e : Int) : ((scaled m e).1 : ℝ) ≤ m * (2 : ℝ) ^ e * 2 ^ 56 ∧ (m : ℝ) * (2 : ℝ) ^ e * 2 ^ 56 ≤ (scaled m e).2 ∧ (scaled m e).1 ≤ (scaled m e).2 := by unfold scaled have hz : (m : ℝ) * (2 : ℝ) ^ e * 2 ^ 56 = m * (2 : ℝ) ^ (e + 56) := by rw [zpow_add₀ two_ne_zero]; norm_num; ring split · rename_i h have hk : ((2 : ℝ) ^ (e + 56)) = 2 ^ (e + 56).toNat := by rw [← zpow_natCast, Int.toNat_of_nonneg h] simp only [Nat.shiftLeft_eq, hz, hk]; push_cast; simp · rename_i h set k := (-(e + 56)).toNat have hk : ((2 : ℝ) ^ (e + 56)) = 1 / 2 ^ k := by rw [show e + 56 = -(k : Int) by omega, zpow_neg, zpow_natCast, one_div] simp only [Nat.shiftRight_eq_div_pow, hz, hk] have hp : (0 : ℝ) < 2 ^ k := by positivity have h1 := Nat.div_mul_le_self m (2 ^ k) have h2 := Nat.lt_succ_iff.mpr (le_refl (m / 2 ^ k)) have h3 : m < (m / 2 ^ k + 1) * 2 ^ k := by have := Nat.lt_mul_div_succ m (Nat.two_pow_pos k); linarith refine ⟨?_, ?_, Nat.le_succ _⟩ · rw [mul_one_div, le_div_iff₀ hp]; exact_mod_cast h1 · rw [mul_one_div, div_le_iff₀ hp]; push_cast; exact_mod_cast h3.le def lim17 : Nat := 17 * 2 ^ 56 /-- An enclosure of `e^(−c)` for `c = m · 2^e`, when `c < 17`. -/ @[inline] def expNeg (m : Nat) (e : Int) : Option (Nat × Nat) := let c := scaled m e if lim17 ≤ c.2 then none else let q := c.1 >>> 50 let rl := (c.1 - (q <<< 50)) <<< 6 let rh := (c.2 - (q <<< 50)) <<< 6 if one < rh then none else let P := expSmall rl rh let F := fracTab[q % 64]! let I := intTab[q >>> 6]! let IF := (mulDn I.1 F.1, min one (mulUp I.2 F.2)) some (mulDn IF.1 P.1, min one (mulUp IF.2 P.2)) theorem expNeg_spec {m : Nat} {e : Int} {iv : Nat × Nat} (h : expNeg m e = some iv) : Encl iv (m * (2 : ℝ) ^ e) := by unfold expNeg at h simp only [Nat.shiftRight_eq_div_pow, Nat.shiftLeft_eq] at h obtain ⟨hlo, hhi, hle⟩ := scaled_spec m e generalize (scaled m e).1 = cl at * generalize (scaled m e).2 = ch at * split at h · exact absurd h (by simp) rename_i hlim split at h · exact absurd h (by simp) rename_i hrh simp only [Option.some.injEq] at h subst h set q := cl / 2 ^ 50 have hq : q * 2 ^ 50 ≤ cl := Nat.div_mul_le_self cl _ have hqd : q = q / 2 ^ 6 * 64 + q % 64 := by have := Nat.div_add_mod q 64; omega have hn : q / 2 ^ 6 < 17 := by unfold lim17 at hlim; omega have hj : q % 64 < 64 := Nat.mod_lt _ (by norm_num) set C := (m : ℝ) * (2 : ℝ) ^ e set r := C - (q / 2 ^ 6 : Nat) - (q % 64 : Nat) * (1 / 64 : ℝ) have hr : C = (q / 2 ^ 6 : Nat) + (q % 64 : Nat) * (1 / 64 : ℝ) + r := by ring have hqr : ((q : Nat) : ℝ) * 2 ^ 50 = ((q / 2 ^ 6 : Nat) : ℝ) * 2 ^ 56 + ((q % 64 : Nat) : ℝ) * 2 ^ 50 := by have : ((q : Nat) : ℝ) = ((q / 2 ^ 6 * 64 + q % 64 : Nat) : ℝ) := by rw [← hqd] rw [this]; push_cast; ring have hrl : V ((cl - q * 2 ^ 50) * 2 ^ 6) ≤ r := by unfold V; rw [Nat.cast_mul, Nat.cast_sub hq]; push_cast rw [div_le_iff₀ (by positivity)] simp only [r]; nlinarith [hqr] have hrh' : r ≤ V ((ch - q * 2 ^ 50) * 2 ^ 6) := by unfold V; rw [Nat.cast_mul, Nat.cast_sub (hq.trans hle)]; push_cast rw [le_div_iff₀ (by positivity)] simp only [r]; nlinarith [hqr] have hP := expSmall_spec hrl hrh' (by omega) have hI := intTab_spec hn have hF := fracTab_spec hj rw [hr] exact (hI.mul hF).mul hP /-! ## Quotients: a guess, checked exactly -/ def two62f : Float := 4611686018427387904.0 /-- `q · d ≤ num · 2^62` by 128-bit comparison (for `q, d < 2^64`). -/ @[inline] def mulLe (q d num : Nat) : Bool := let h := (mulHiW q.toUInt64 d.toUInt64).toNat let nh := num >>> 2 h < nh || (h == nh && mulLoW q.toUInt64 d.toUInt64 ≤ (num % 4).toUInt64 <<< 62) /-- `num · 2^62 ≤ q · d`. -/ @[inline] def mulGe (q d num : Nat) : Bool := let h := (mulHiW q.toUInt64 d.toUInt64).toNat let nh := num >>> 2 nh < h || (h == nh && (num % 4).toUInt64 <<< 62 ≤ mulLoW q.toUInt64 d.toUInt64) theorem num_split (num : Nat) : ((num % 4).toUInt64 <<< 62).toNat = num % 4 * 2 ^ 62 := by have h4 : num % 4 < 4 := Nat.mod_lt _ (by norm_num) rw [UInt64.toNat_shiftLeft, toNat_toUInt64_of_lt (by omega)] have : (62 : UInt64).toNat % 64 = 62 := by decide rw [this, Nat.shiftLeft_eq, Nat.mod_eq_of_lt (by omega)] theorem mulLe_spec {q d num : Nat} (hq : q < 2 ^ 64) (hd : d < 2 ^ 64) (h : mulLe q d num = true) : q * d ≤ num * 2 ^ 62 := by have hs := halves hq hd unfold mulLe at h simp only [Nat.shiftRight_eq_div_pow, Bool.or_eq_true, decide_eq_true_eq, Bool.and_eq_true, beq_iff_eq, UInt64.le_iff_toNat_le, num_split] at h have hl := (mulLoW q.toUInt64 d.toUInt64).toNat_lt generalize (mulHiW q.toUInt64 d.toUInt64).toNat = a at * generalize (mulLoW q.toUInt64 d.toUInt64).toNat = b at * omega theorem mulGe_spec {q d num : Nat} (hq : q < 2 ^ 64) (hd : d < 2 ^ 64) (h : mulGe q d num = true) : num * 2 ^ 62 ≤ q * d := by have hs := halves hq hd unfold mulGe at h simp only [Nat.shiftRight_eq_div_pow, Bool.or_eq_true, decide_eq_true_eq, Bool.and_eq_true, beq_iff_eq, UInt64.le_iff_toNat_le, num_split] at h have hl := (mulLoW q.toUInt64 d.toUInt64).toNat_lt generalize (mulHiW q.toUInt64 d.toUInt64).toNat = a at * generalize (mulLoW q.toUInt64 d.toUInt64).toNat = b at * omega /-- A guess for `num · 2^62 / den` (untrusted; only the checks below matter). -/ @[inline] def guess (num den : Nat) : Nat := ((num.toUInt64.toFloat * two62f) / den.toUInt64.toFloat).toUInt64.toNat /-- `2^64`, computed once. -/ def lim64 : Nat := 2 ^ 64 /-- `q` with `V q · V den ≤ V num`. -/ @[inline] def divLo (num den : Nat) : Option Nat := let g := guess num den let q := g - ((g >>> 50) + 2) if q < lim64 && den < lim64 && mulLe q den num then some q else none /-- `q` with `V num ≤ V q · V den`. -/ @[inline] def divHi (num den : Nat) : Option Nat := let g := guess num den let q := g + ((g >>> 50) + 2) if q < lim64 && den < lim64 && mulGe q den num then some q else none theorem V_mul_iff (a b c : Nat) : V a * V b ≤ V c ↔ a * b ≤ c * 2 ^ 62 := by unfold V rw [div_mul_div_comm, div_le_div_iff₀ (by positivity) (by positivity)] constructor · intro h have : ((a * b : Nat) : ℝ) * 2 ^ 62 ≤ ((c * 2 ^ 62 : Nat) : ℝ) * 2 ^ 62 := by push_cast; nlinarith exact_mod_cast le_of_mul_le_mul_right this (by positivity) · intro h have : ((a * b : Nat) : ℝ) ≤ ((c * 2 ^ 62 : Nat) : ℝ) := by exact_mod_cast h push_cast at this; nlinarith theorem divLo_spec {num den q : Nat} (h : divLo num den = some q) : V q * V den ≤ V num := by unfold divLo at h dsimp only at h generalize guess num den = g at h split at h · rename_i hc simp only [Bool.and_eq_true, decide_eq_true_eq] at hc simp only [Option.some.injEq] at h; subst h exact (V_mul_iff _ _ _).mpr (mulLe_spec hc.1.1 hc.1.2 hc.2) · simp at h theorem divHi_spec {num den q : Nat} (h : divHi num den = some q) : V num ≤ V q * V den := by unfold divHi at h dsimp only at h generalize guess num den = g at h split at h · rename_i hc simp only [Bool.and_eq_true, decide_eq_true_eq] at hc simp only [Option.some.injEq] at h; subst h have h2 := mulGe_spec hc.1.1 hc.1.2 hc.2 unfold V rw [div_mul_div_comm, div_le_div_iff₀ (by positivity) (by positivity)] have : ((num * 2 ^ 62 : Nat) : ℝ) ≤ (((g + (g >>> 50 + 2)) * den : Nat) : ℝ) := by exact_mod_cast h2 push_cast at this ⊢; nlinarith · simp at h /-! ## Rounding both ends, and the bridge to the specs -/ open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Numerics open ExactRuntime.FastRound /-- The word both ends of `[lo, hi] · 2^(−62)` round to, when they agree on a finite nonzero word, through FloatLib's rounding (the reference for `settle`). -/ def settleInt (lo hi : Int) : Option UInt32 := let a := finishWord lo (-62) false if lo ≠ 0 && hi ≠ 0 && a == finishWord hi (-62) false && expOf a != 255 && (decodeD a).significand != 0 then some a else none @[inline] def settle (neg : Bool) (a b : Nat) : Option UInt32 := let w := roundW neg a (-62) if a ≠ 0 && b ≠ 0 && w == roundW neg b (-62) && expOf w != 255 && (decodeD w).significand != 0 then some w else none theorem settle_eq (neg : Bool) (a b : Nat) : settle neg a b = settleInt (if neg then -(b : Int) else a) (if neg then -(a : Int) else b) := by unfold settle settleInt by_cases ha : a = 0 · subst ha; cases neg <;> simp by_cases hb : b = 0 · subst hb; cases neg <;> simp rw [roundW_signed neg a _ ha, roundW_signed neg b _ hb] cases neg · simp · simp only [ite_true] by_cases he : finishWord (-(a : Int)) (-62) false = finishWord (-(b : Int)) (-62) false · simp [ha, hb, he] · have he' : ¬ finishWord (-(b : Int)) (-62) false = finishWord (-(a : Int)) (-62) false := fun h => he h.symm simp [ha, hb, he, he'] /-- A finite word rounding `S · 2^e` has that rounding as its value. -/ theorem settleInt_spec {lo hi : Int} {a : UInt32} (h : settleInt lo hi = some a) {v : ℝ} (hl : (lo : ℝ) * 2 ^ (-62 : Int) ≤ v) (hh : v ≤ (hi : ℝ) * 2 ^ (-62 : Int)) {z : Model Fmt} (hz : Model.toReal z = Model.roundAt Fmt v) : toWord z = a := by unfold settleInt at h dsimp only at h split at h · rename_i hc simp only [Option.some.injEq] at h subst h simp only [Bool.and_eq_true, bne_iff_ne, ne_eq, decide_eq_true_eq, beq_iff_eq] at hc obtain ⟨⟨⟨⟨hlo, hhi⟩, heq⟩, hfin⟩, hsig⟩ := hc exact bracket_spec hlo hhi rfl heq.symm hfin hsig hl hh hz · simp at h theorem int_scale (n : Nat) : ((n : Int) : ℝ) * 2 ^ (-62 : Int) = V n := by unfold V; push_cast; rw [zpow_neg, zpow_ofNat]; ring /-- The value of a finite word: `±m · 2^e` from `decodeD`. -/ theorem toReal_ofW_decode {w : UInt32} (hfin : expOf w ≠ 255) : Model.toReal (ofW w) = (if (decodeD w).negative then -1 else 1) * ((decodeD w).significand * (2 : ℝ) ^ (decodeD w).exponent) := by rw [Model.toReal_eq, ofW, toDyadic_ofUInt32 _ hfin] simp only [FloatLib.Numerics.Dyadic.toReal, FloatLib.Numerics.Dyadic.cast_signedSignificand] ring /-! ### Sigmoid -/ theorem realSigmoid_neg_eq (C : ℝ) : realSigmoid (-C) = Real.exp (-C) / (1 + Real.exp (-C)) := by unfold realSigmoid rw [neg_neg] have hp := Real.exp_pos (-C) have h : Real.exp C = 1 / Real.exp (-C) := by rw [Real.exp_neg, one_div, inv_inv] rw [h]; field_simp; ring /-- Fast path for the correctly rounded sigmoid; `none` when it doesn't settle. -/ def sigmoidFast (w : UInt32) : Option UInt32 := if expOf w = 255 then none else let d := decodeD w match expNeg d.significand d.exponent with | none => none | some t => if d.negative then -- σ(−c) = t / (1 + t), increasing in t match divLo t.1 (one + t.1), divHi t.2 (one + t.2) with | some ql, some qh => settle false ql qh | _, _ => none else -- σ(c) = 1 / (1 + t), decreasing in t match divLo one (one + t.2), divHi one (one + t.1) with | some ql, some qh => settle false ql qh | _, _ => none theorem sigmoidFast_spec {w a : UInt32} (h : sigmoidFast w = some a) : sigmoidCR w = a := by unfold sigmoidFast at h split at h · simp at h rename_i hfin dsimp only at h have hx := toReal_ofW_decode hfin generalize decodeD w = d at h hx have hspec := (toReal_sigmoidModel (fmt := Fmt) (by decide) (input := Model.ofUInt32 w) (by simp [isFinite_ofUInt32, hfin])).2 change Model.toReal (sigmoidModel (ofW w)) = Model.roundAt Fmt (realSigmoid (Model.toReal (ofW w))) at hspec rw [hx] at hspec change toWord (sigmoidModel (ofW w)) = a split at h · simp at h rename_i t ht have hE := expNeg_spec ht set C := (d.significand : ℝ) * (2 : ℝ) ^ d.exponent set T := Real.exp (-C) have hT : 0 < T := Real.exp_pos _ obtain ⟨h1, h2, h3⟩ := hE have v1 := V_nonneg t.1 have v2 := V_nonneg t.2 split at h · rename_i hneg split at h · rename_i ql qh hql hqh have bl := divLo_spec hql have bh := divHi_spec hqh rw [V_add, V_one] at bl bh rw [settle_eq] at h simp only [Bool.false_eq_true, ite_false] at h refine settleInt_spec h (v := realSigmoid (-C)) ?_ ?_ (by rw [hspec, hneg]; simp) · rw [int_scale] have : realSigmoid (-C) = T / (1 + T) := realSigmoid_neg_eq C rw [this, le_div_iff₀ (by linarith)] nlinarith · rw [int_scale] have : realSigmoid (-C) = T / (1 + T) := realSigmoid_neg_eq C rw [this, div_le_iff₀ (by linarith)] nlinarith · simp at h · rename_i hneg split at h · rename_i ql qh hql hqh have bl := divLo_spec hql have bh := divHi_spec hqh rw [V_add, V_one] at bl bh have hs : realSigmoid C = 1 / (1 + T) := rfl rw [settle_eq] at h simp only [Bool.false_eq_true, ite_false] at h refine settleInt_spec h (v := realSigmoid C) ?_ ?_ (by rw [hspec]; simp [hneg]) · rw [int_scale, hs, le_div_iff₀ (by linarith)] nlinarith · rw [int_scale, hs, div_le_iff₀ (by linarith)] nlinarith · simp at h /-- `sigmoid`, fast where it settles and the spec elsewhere. -/ def sigmoidF (w : UInt32) : UInt32 := (sigmoidFast w).getD (sigmoidCR w) theorem sigmoidF_eq : sigmoidF = sigmoidCR := by funext w unfold sigmoidF cases h : sigmoidFast w with | none => rfl | some a => exact (sigmoidFast_spec h).symm /-! ### Tanh -/ /-- Fast path for the correctly rounded `tanh`: `tanh |x| = (1 − t)/(1 + t)`, `t = e^(−2|x|)`. -/ def tanhFast (w : UInt32) : Option UInt32 := if expOf w = 255 then none else let d := decodeD w match expNeg d.significand (d.exponent + 1) with | none => none | some t => if one < t.1 then none else match divLo (one - t.2) (one + t.2), divHi (one - t.1) (one + t.1) with | some ql, some qh => settle d.negative ql qh | _, _ => none theorem neg_int_scale (n : Nat) : ((-(n : Int) : Int) : ℝ) * 2 ^ (-62 : Int) = -V n := by rw [Int.cast_neg, neg_mul, int_scale] theorem tanhFast_spec {w a : UInt32} (h : tanhFast w = some a) : tanhCR w = a := by unfold tanhFast at h split at h · simp at h rename_i hfin dsimp only at h have hx := toReal_ofW_decode hfin generalize decodeD w = d at h hx have hspec := (toReal_tanhModel (fmt := Fmt) (by decide) (input := Model.ofUInt32 w) (by simp [isFinite_ofUInt32, hfin])).2 change Model.toReal (tanhModel (ofW w)) = Model.roundAt Fmt (Real.tanh (Model.toReal (ofW w))) at hspec rw [hx] at hspec change toWord (tanhModel (ofW w)) = a split at h · simp at h rename_i t ht have hE := expNeg_spec ht set C := (d.significand : ℝ) * (2 : ℝ) ^ d.exponent have h2C : (d.significand : ℝ) * (2 : ℝ) ^ (d.exponent + 1) = 2 * C := by rw [zpow_add₀ two_ne_zero]; simp only [C]; ring rw [h2C] at hE set T := Real.exp (-(2 * C)) have hT : 0 < T := Real.exp_pos _ have htanh : Real.tanh C = (1 - T) / (1 + T) := by rw [tanh_eq_exp_neg_two]; simp only [T]; ring_nf obtain ⟨h1, h2, h3⟩ := hE have v1 := V_nonneg t.1 have v2 := V_nonneg t.2 split at h · simp at h rename_i ht1 replace ht1 := not_lt.mp ht1 split at h · rename_i ql qh hql hqh have bl := divLo_spec hql have bh := divHi_spec hqh rw [V_add, V_one, V_sub_le_of_le h3, V_one] at bl rw [V_add, V_one, V_sub_le_of_le ht1, V_one] at bh have lo : V ql ≤ Real.tanh C := by rw [htanh, le_div_iff₀ (by linarith)]; nlinarith have hi : Real.tanh C ≤ V qh := by rw [htanh, div_le_iff₀ (by linarith)]; nlinarith rw [settle_eq] at h cases hneg : d.negative <;> simp only [hneg, ite_true, Bool.false_eq_true, ite_false] at h · refine settleInt_spec h (v := Real.tanh C) ?_ ?_ (by rw [hspec]; simp [hneg]) · rw [int_scale]; exact lo · rw [int_scale]; exact hi · refine settleInt_spec h (v := Real.tanh (-C)) ?_ ?_ (by rw [hspec, hneg]; simp) · rw [neg_int_scale, Real.tanh_neg]; linarith · rw [neg_int_scale, Real.tanh_neg]; linarith · simp at h /-- `tanh`, fast where it settles and the spec elsewhere. -/ def tanhF (w : UInt32) : UInt32 := (tanhFast w).getD (tanhCR w) theorem tanhF_eq : tanhF = tanhCR := by funext w unfold tanhF cases h : tanhFast w with | none => rfl | some a => exact (tanhFast_spec h).symm /-! ### Exp, for softmax's arguments (`x ≤ 0`) -/ /-- Fast path for the correctly rounded `exp` at `x ≤ 0`: `e^x = e^(−|x|)`, enclosed by `expNeg`. -/ def expFast (w : UInt32) : Option UInt32 := if expOf w = 255 then none else let d := decodeD w if !d.negative && d.significand != 0 then none else match expNeg d.significand d.exponent with | none => none | some t => settle false t.1 t.2 theorem expFast_spec {w a : UInt32} (h : expFast w = some a) : expW w = a := by unfold expFast at h split at h · simp at h rename_i hfin dsimp only at h have hx := toReal_ofW_decode hfin generalize hd : decodeD w = d at h hx split at h · simp at h rename_i hsign simp only [Bool.and_eq_true, Bool.not_eq_true', bne_iff_ne, ne_eq, not_and, not_not] at hsign split at h · simp at h rename_i t ht obtain ⟨h1, h2, -⟩ := expNeg_spec ht set C := (d.significand : ℝ) * (2 : ℝ) ^ d.exponent -- the input is `−C` have hxC : Model.toReal (ofW w) = -C := by rw [hx] by_cases hneg : d.negative = true · simp [hneg] · have hz : d.significand = 0 := hsign (by simpa using hneg) simp [C, hz] have hfinw : Model.isFinite (ofW w) = true := by simp [ofW, isFinite_ofUInt32, hfin] have hrange : Real.exp (Model.toReal (ofW w)) < (Model.Transcendentals.Certified.overflowThreshold Fmt : ℝ) := by have hC : 0 ≤ C := by simp only [C]; positivity have : Real.exp (-C) ≤ 1 := Real.exp_le_one_iff.mpr (by linarith) rw [hxC] exact lt_of_le_of_lt this (Model.Transcendentals.CorrectlyRounded.one_lt_overflowThreshold (by decide)) have hspec := Model.Transcendentals.CorrectlyRounded.toReal_exp_eq_roundAt (fmt := Fmt) (by decide) hfinw hrange (budget := {}) rw [hxC] at hspec rw [settle_eq] at h simp only [Bool.false_eq_true, ite_false] at h exact settleInt_spec h (v := Real.exp (-C)) (by rw [int_scale]; exact h1) (by rw [int_scale]; exact h2) hspec /-- `exp`, fast at `x ≤ 0` where it settles and the spec elsewhere. -/ def expF (w : UInt32) : UInt32 := (expFast w).getD (expW w) theorem expF_eq : expF = expW := by funext w unfold expF cases h : expFast w with | none => rfl | some a => exact (expFast_spec h).symm end FastAct namespace Submission open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Floats.ExecFloat.Binary open _root_ renaming mul_le_mul_of_nonneg_right → ἀ, mul_le_mul_of_nonneg_left → ἁ, abs_of_nonneg → ἅ, abs_nonneg → Ἀ, dite_eq_left → Ἄ, mul_nonneg → Ἆ, ite_eq_right → ἐ, mul_le_mul → ἑ, zpow_le_zpow_right₀ → ἒ, two_ne_zero → ἓ, dite_eq_right → ἔ, abs_add_le → Ἐ, zpow_add₀ → Ἓ, getElem!_pos → Ἕ, abs_of_pos → ἡ, abs_mul → ἢ, abs_sub_comm → ἣ, zpow_natCast → Ἡ, lt_of_lt_of_le → Ἥ, mul_lt_mul_of_pos_right → Ἦ, ite_eq_left → ἱ, zpow_pos → ἵ, lt_of_le_of_lt → ἷ, pow_le_pow_left₀ → Ἳ, le_trans → ὂ, sq_nonneg → ὅ, getElem!_neg → ὑ, abs_sub → Ὕ, le_refl → Ὗ, FloatArray → ὤ, UInt32 → ὥ, USize → ὦ, Float → ὧ, UInt64 → Ὠ, Bool → Ὡ, Nat → Ὣ, abs_sub_abs_le_abs_sub → Ὥ, if_pos → Ὦ, if_neg → Ὧ, abs_le → ὸ, zpow_sub₀ → ᾂ open ExactRuntime renaming rationalWord → ἂ, toDyadic_ofUInt32 → ἶ, Word → Ὢ open UInt32 renaming le_iff_toNat_le → ἃ, toNat_inj → ἠ, toNat_and → Ἧ, lt_iff_toNat_lt → ἳ, toNat_toUSize → ὃ, toNat_sub_of_le → ὓ, le_refl → Ὓ, toNat_ofNat' → ὡ, ofNat → ὺ open List renaming range → ἄ, mem_range → Ἅ, nodup_range → Ὂ, foldl_cons → ὔ, mem_cons_of_mem → ὖ, range_eq_range' → ὗ, map_congr_left → ὠ, mem_cons_self → ὣ open FloatArray renaming emptyWithCapacity → ἆ open Array renaming replicate → ἇ open Nat renaming mod_eq_of_lt → Ἁ, and_two_pow_sub_one_eq_mod → Ἂ, zero_add → Ἇ, mul_le_mul_right → Ἒ, cast_nonneg → Ἔ, mul_comm → ἥ, div_lt_of_lt_mul → Ἰ, shiftRight_eq_div_pow → Ἱ, not_lt_zero → Ἲ, add_zero → Ἵ, mod_lt → ὀ, shiftLeft_eq → ὁ, div_eq_of_lt → Ὃ, le_mul_of_pos_right → Ὄ, zero_mul → ὒ, one_mul → Ὑ, add_assoc → ὢ, add_mul → ὰ, pos_of_ne_zero → ὼ, succ_mul → ᾀ open Float renaming ofBits → Ἃ, sqrt → Ἤ open FloatLib.Floats.Formats.BinaryInterchange.Model renaming roundDyadic → ἕ, isFinite → Ἑ, toReal_eq_unpackedToReal_toModel → ἦ, toReal → Ἢ, modelSignBit → Ἴ, toModel_ofFloatModel → Ὀ, modelSign → ὶ, roundAt → ᾁ open UInt64 renaming toNat_add → ἤ, toNat_shiftRight → ἰ, lt_iff_toNat_lt → ἴ, toNat_and → Ὅ, le_iff_toNat_le → Ὤ, toNat_sub → ὲ open Real renaming sqrt → ἧ open FloatLib.Numerics.Dyadic renaming cast_toRat → Ἠ, toRat_eq_zero_iff → ὐ open Finset renaming range → Ἣ, sum_congr → Ἷ, mem_range → Ὁ open FloatLib.Numerics renaming binaryRadix → ἲ open Float.Model.UnpackedFloat renaming unpack → Ἶ open USize renaming toNat_one → ὄ, ofNat → ὴ open Bool renaming and_eq_true_iff → ὕ local notation"А"=>USize.lt_iff_toNat_lt local notation"В"=>0x7FFFFFFF local notation"Е"=>0xFFFFFFFF local notation"У"=>0x7F800000 local notation"ь"=>0x3CE0000000000000 local notation"س"=>0x80000000 local notation"ظ"=>0x3370000000000000 local notation"א"=>by omega local notation"ב"=>by norm_num local notation"ג"=>by simp local notation"ѐ"=>Array UInt32 local notation"ё"=>Array Word local notation"ї"=>Array Nat local notation"љ"=>List Nat open USize (toNat) open UInt32 (toNat) open UInt64 (toNat) local notation:max"Ѡ"x:max=>toNat x open Array (size) open FloatArray (size) local notation:max"ѡ"x:max=>size x open Nat (toUSize) open UInt32 (toUSize) local notation:max"Ѣ"x:max=>toUSize x local notation:max"Ѥ"x:max=>USize.toNat x local notation:max"ѥ"x:max=>UInt32.toNat x local notation:max"Ѧ"x:max=>UInt64.toNat x local notation:max"ѧ"x:max=>Array.size x local notation:max"Ѩ"x:max=>FloatArray.size x local notation:max"ѩ"x:max=>Nat.toUSize x local notation:max"Ѫ"x:max=>UInt32.toUSize x local notation:max"ѣ"x:max=>List.length x open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Floats.ExecFloat.Binary open FloatLib.Numerics.Dyadic (signedSignificand toRat_eq_zero_iff add_toRat mul_toRat mulFields) open UInt64 (toNat_sub_of_le) open Bool (false_eq_true and_eq_true or_eq_true) open USize (toNat) open UInt32 (toNat) open UInt64 (toNat) open Array (size) open FloatArray (size) open Nat (toUSize) open UInt32 (toUSize) local notation"Մ"=>Array.ext local notation"ה"=>(by decide) local notation"ו"=>(by positivity) local notation"ז"=>(by simp;omega) local notation"ט"=>(by rw[А];omega) local notation:max x:max "ᶠ"=>Float.isFinite x=true local notation "⟡"=>FloatFormat.binary64 local notation "⟠"=>Float.Model.Format.binary64 theorem omS3 {x0 x1 : ℕ} (h0 : x0 / 32 + 1 < 18) (h1 : x1 = 18) : x0 / 32 + 1 < x1 := by subst_vars; omega theorem omS4 {x0 x1 x2 : ℕ} (h0 : x0 + (x2 + 1) ≤ x1) : x0 < x1 := by omega theorem omS5 {x0 x1 x2 : ℕ} (h0 : x0 + (x1 + 1) ≤ x2) : x0 + 1 + x1 ≤ x2 := by subst_vars; simp only [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm, Nat.zero_add, Nat.add_zero] at *; assumption theorem omS6 {x0 x1 : ℕ} (h0 : x1 ≤ x0) (h1 : x0 < x1 + 1) : x0 = x1 := by omega theorem omS7 {x0 x1 x2 : ℕ} (h0 : x0 < x1 + (x2 + 1)) : x0 < x1 + 1 + x2 := by subst_vars; simp only [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm, Nat.zero_add, Nat.add_zero] at *; assumption theorem omS8 {x0 x1 : ℕ} (h0 : x0 < x1 + 1) (h1 : x0 ≥ x1) : x0 = x1 := by omega theorem omS9 {x0 : ℕ} : 0 < x0 + 1 := by subst_vars; simp theorem omS10 {x0 : ℕ} : 0 + x0 ≤ x0 := by subst_vars; simp theorem omS11 {x0 x1 x2 : ℕ} (h0 : x1 = x2) (h1 : x0 = x2) : x0 = x1 := by subst_vars; rfl theorem omS12 {x0 x1 x2 : ℕ} (h0 : x2 = x1) (h1 : x0 < x2) : x0 < 0 + x1 := by subst_vars; simp only [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm, Nat.zero_add, Nat.add_zero] at *; assumption theorem omS13 {x0 : ℕ} (h0 : x0 < 4294967296) : x0 / 8388608 < 512 := by omega theorem omS14 {x0 x1 x2 x3 : ℕ} (h0 : x0 + x2 ≤ x3) (h1 : x3 < 2 ^ 32) (h2 : x1 < x2) : x0 + x1 < 2 ^ 32 := by omega theorem omS15 {x0 x1 x2 x3 : ℕ} (h0 : x0 + x3 ≤ x2) (h1 : x1 < x3) : x0 + x1 < x2 := by omega theorem omS16 {x0 x1 x2 x3 : ℕ} (h0 : x1 + 8 * x2 ≤ x3) (h1 : x3 < 2 ^ 32) (h2 : x0 < x2) : 8 * x0 < 2 ^ 32 := by omega theorem omS17 {x0 x1 x2 x3 : ℕ} (h0 : x0 + 8 * x2 ≤ x3) (h1 : x3 < 2 ^ 32) (h2 : x1 < x2) : x0 + 8 * x1 < 2 ^ 32 := by omega theorem omS18 {x0 x1 x2 x3 x4 : ℕ} (h0 : x2 < 8) (h1 : x0 + 8 * x3 ≤ x4) (h2 : x4 < 2 ^ 32) (h3 : x1 < x3) : x0 + 8 * x1 + x2 < 2 ^ 32 := by omega theorem omS19 {x0 x1 x2 : ℕ} (h0 : x0 + 5 + 8 * x1 ≤ x2) (h1 : x2 ≤ 4294967295) : x0 + 5 < 2 ^ 32 := by omega theorem omS23 {x0 x1 x2 x3 x4 : ℕ} (h0 : x1 < 8) (h1 : x2 < x3) (h2 : x0 = 8 * x2 + 1) (h3 : 8 * x3 + 1 ≤ x4) (h4 : x4 < 2 ^ 32) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS24 {x0 x1 x2 x3 x4 : ℕ} (h0 : x1 < 8) (h1 : x3 < x4) (h2 : x0 = 8 * x3 + 1) (h3 : 8 * x4 + 1 ≤ x2) : x0 + x1 < x2 := by subst_vars; omega theorem omS27 {x0 : ℕ} {x1 : ℤ} (h0 : ↑(0 : ℕ) - ((1023 : ℤ) + ↑(52 : ℕ)) + (1 : ℤ) = x1) : (2 : ℕ) ^ (52 : ℕ) ≤ x0 ∨ x1 = (-1074 : ℤ) := by simp_all theorem omS28 {x0 : ℕ} : ↑(x0 % (256 : ℕ)) - (150 : ℤ) ≤ (128 : ℤ) ∧ (-150 : ℤ) ≤ ↑(x0 % (256 : ℕ)) - (150 : ℤ) := by omega theorem omS29 {x0 : ℤ} (h0 : x0 ≤ (128 : ℤ) ∧ (-150 : ℤ) ≤ x0) : x0 ≤ (300 : ℤ) := by omega theorem omS30 {x0 : ℤ} {x1 : ℤ} (h0 : (-900 : ℤ) ≤ x0) (h1 : x1 ≤ (128 : ℤ) ∧ (-150 : ℤ) ≤ x1) : (-1074 : ℤ) ≤ x0 + x1 := by omega theorem omS31 {x0 : ℕ} : x0 / 2 ^ 31 % 2 = 0 ∨ x0 / 2 ^ 31 % 2 = 1 := by omega theorem omS32 {x0 : ℕ} (h0 : x0 < 2 ^ 32) : ¬x0 / 2 ^ 31 % 2 * 2 ^ 31 = 0 ↔ 2 ^ 31 ≤ x0 := by omega theorem omS33 {x0 x1 : ℕ} (h0 : x0 = x1 % 2 ^ 31) (h1 : (4286578688 + x0) % 4294967296 ≤ 2130706431) : 2 ^ 23 ≤ x0 ∧ x0 < 2139095040 := by subst_vars; omega theorem omS34 {x0 : ℕ} (h0 : 255 = x0 / 2 ^ 23 % 2 ^ 8) (h1 : x0 % 2 ^ 31 = 0 ∨ 2 ^ 23 ≤ x0 % 2 ^ 31 ∧ x0 % 2 ^ 31 < 2139095040) : False := by omega theorem omS35 {x0 : ℕ} (h0 : x0 % 2 ^ 31 = 0) : x0 / 2 ^ 23 % 2 ^ 8 = 0 := by omega theorem omS36 {x0 : ℕ} (h0 : x0 % 2 ^ 31 = 0) : x0 % 2 ^ 23 = 0 := by omega theorem omS37 {x0 : ℕ} (h0 : x0 % 2 ^ 31 = 0 ∨ 2 ^ 23 ≤ x0 % 2 ^ 31 ∧ x0 % 2 ^ 31 < 2139095040) (h1 : ¬x0 % 2 ^ 31 = 0) (h2 : 0 = x0 / 2 ^ 23 % 2 ^ 8) : False := by omega theorem omS38 {x0 : ℕ} : x0 % 2 ^ 31 % 2 ^ 23 = x0 % 2 ^ 23 := by omega theorem omS39 {x0 : ℕ} : x0 % 2 ^ 31 / 2 ^ 23 = x0 / 2 ^ 23 % 2 ^ 8 := by omega theorem omS40 {x0 : ℕ} : 2 ^ 23 + x0 % 2 ^ 23 ≤ 2 ^ 24 := by omega theorem omS41 {x0 : ℕ} (h0 : x0 < (2139095040 : ℕ)) : ↑(x0 / (2 : ℕ) ^ (23 : ℕ)) - (150 : ℤ) ≤ (104 : ℤ) := by omega theorem omS42 {x0 : ℕ} (h0 : 2 ^ 23 ≤ x0) : ¬x0 = 0 := by omega theorem omS43 {x0 x1 : ℕ} (h0 : x1 ≤ x0) (h1 : 2 ^ 23 ≤ x1) : ¬x0 = 0 := by omega theorem omS44 {x0 x1 : ℕ} (h0 : x0 ≤ x1) (h1 : x0 / 2 ^ 23 = x1 / 2 ^ 23) : 2 ^ 23 + x0 % 2 ^ 23 ≤ 2 ^ 23 + x1 % 2 ^ 23 := by omega theorem omS45 {x0 : ℕ} {x1 : ℕ} (h0 : x0 / (2 : ℕ) ^ (23 : ℕ) < x1 / (2 : ℕ) ^ (23 : ℕ)) : ↑(x0 / (2 : ℕ) ^ (23 : ℕ)) - (150 : ℤ) + (1 : ℤ) ≤ ↑(x1 / (2 : ℕ) ^ (23 : ℕ)) - (150 : ℤ) := by omega theorem omS46 {x0 : ℕ} : 2 ^ 23 ≤ 2 ^ 23 + x0 % 2 ^ 23 := by omega theorem omS47 {x0 : ℕ} : 2 ^ 23 + x0 % 2 ^ 23 ≤ 2 ^ 23 * 2 := by omega theorem omS48 {x0 : ℕ} : 2 ^ 23 + x0 % 2 ^ 23 < 2 ^ 53 := by omega theorem omS49 {x0 : ℕ} (h0 : x0 < 2 ^ 32) : x0 / 2 ^ 23 < 512 := by omega theorem omS51 {x0 : ℕ} : 2 ^ 23 + x0 % 2 ^ 23 ≤ 2 ^ 128 := by omega theorem omS52 {x0 : ℕ} (h0 : x0 % 2 ^ 31 = 0) : x0 / 2 ^ 23 % 256 = 0 := by omega theorem omS53 {x0 : ℕ} : 256 ≤ x0 / 2 ^ 23 ↔ 2 ^ 31 ≤ x0 := by omega theorem omS54 {x0 : ℕ} : x0 % 2 ^ 31 / 2 ^ 23 = x0 / 2 ^ 23 % 256 := by omega theorem omS55 {x0 : ℕ} (h0 : 2 ^ 23 ≤ x0 % 2 ^ 31) : ¬x0 / 2 ^ 23 % 256 = 0 := by omega theorem omS56 {x0 : ℕ} (h0 : 2 ^ 23 ≤ x0 % 2 ^ 31) : ¬x0 % 2 ^ 31 = 0 := by omega theorem omS57 {x0 : ℕ} (h0 : x0 < 2 ^ 20) : x0 + 8 < 18446744073709551616 := by omega theorem omS58 {x0 : ℕ} (h0 : x0 < 2 ^ 20) : x0 + 8 < 2 ^ 53 := by omega theorem omS60 {x0 : ℕ} (h0 : x0 < 2 ^ 20) : x0 + 8 ≤ 2 ^ 128 := by omega theorem omS61 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 20) (h1 : x0 ≤ x1) : x0 ≤ 2 ^ 20 := by omega theorem omS62 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 20) (h1 : x0 ≤ x1) : x0 ≤ 2097152 := by omega theorem omS63 {x0 : ℕ} : (-900 : ℤ) ≤ ↑(x0 / (2 : ℕ) ^ (23 : ℕ) % (256 : ℕ)) - (150 : ℤ) := by omega theorem omS64 {x0 : ℤ} {x1 : ℤ} {x2 : ℕ} (h0 : x1 = x0 + ↑(x2 + (1 : ℕ))) : x0 ≤ x1 := by subst_vars; omega theorem omS65 {x0 : ℤ} {x1 : ℤ} {x2 : ℕ} (h0 : x0 = x1 + ↑(x2 + (1 : ℕ))) : (x0 - x1).toNat = x2 + (1 : ℕ) := by simp_all theorem omS66 {x0 x1 x2 : ℕ} (h0 : x0 < 2 * x1 + x2) (h1 : 2 * x1 ≤ x0) : x0 - 2 * x1 < x2 := by omega theorem omS67 {x0 x1 x2 : ℕ} (h0 : 2 * x0 < x1 + x2) (h1 : x1 ≤ 2 * x0) : 2 * x0 - x1 < x2 := by omega theorem omS68 {x0 : ℤ} (h0 : (-149 : ℤ) ≤ x0) : (-126 : ℤ) ≤ x0 + (23 : ℤ) := by omega theorem omS69 {x0 : ℤ} (h0 : x0 + (150 : ℤ) ≤ (254 : ℤ)) : ¬(2 : ℕ) ^ (8 : ℕ) ≤ (x0 + (150 : ℤ)).toNat + (1 : ℕ) := by subst_vars; simp at *; omega theorem omS70 {x0 : ℤ} (h0 : x0 + (150 : ℤ) ≤ (254 : ℤ)) : (x0 + (150 : ℤ)).toNat < (2 : ℕ) ^ (8 : ℕ) := by subst_vars; simp at *; omega theorem omS71 {x0 : ℕ} (h0 : 2 ^ 23 ≤ x0) : 0 < x0 := by omega theorem omS72 {x0 : ℤ} {x1 : ℤ} : x0 - x1 + (2 : ℤ) ≤ ↑(x0 - x1 + (2 : ℤ)).toNat := by subst_vars; simp theorem omS73 {x0 : ℤ} {x1 : ℕ} {x2 : ℤ} (h0 : x0 - x2 + (2 : ℤ) ≤ ↑x1) : x0 - ↑x1 + ↑((x2 - (x0 - ↑x1) - (2 : ℤ)).toNat + (2 : ℕ)) = x2 := by omega theorem omS74 {x0 : ℤ} {x1 : ℕ} : x0 = ↑x1 + (x0 - ↑x1) := by subst_vars; simp theorem omS75 {x0 : ℤ} {x1 : ℕ} {x2 : ℤ} {x3 : ℕ} (h0 : x2 - ↑x3 + ↑(x1 + (2 : ℕ)) = x0) : x0 = ↑(x1 + (2 : ℕ)) + (x2 - ↑x3) := by subst_vars; ring theorem omS76 {x0 x1 x2 : ℕ} (h0 : x0 < 4 * x2 + 2 * x1) (h1 : x2 ≤ (2 ^ 24 - 1) * x1) : x0 < 2 ^ 25 * x1 * 2 := by omega theorem omS77 {x0 : ℕ} {x1 : ℤ} {x2 : ℤ} (h0 : (-149 : ℤ) ≤ x2) (h1 : x1 + ↑(x0 + (2 : ℕ)) = x2) : Max.max (↑((25 : ℕ) + x0) + (1 : ℤ) + x1 - (24 : ℤ)) (-149 : ℤ) = x2 := by subst_vars; omega theorem omS78 {x0 x1 : ℕ} (h0 : 2 ^ 25 * x0 ≤ x1) (h1 : x1 < 4 * (2 ^ 23 * x0) + 2 * x0) : 4 * (2 ^ 23 * x0) < x1 + 2 * x0 := by omega theorem omS79 {x0 : ℕ} (h0 : 2 ^ 23 ≤ x0) (h1 : ¬x0 = 2 ^ 23) : 2 ^ 23 + 1 ≤ x0 := by omega theorem omS80 {x0 x1 : ℕ} (h0 : 33554431 * x0 < x1) : 2 ^ 24 * x0 ≤ x1 := by omega theorem omS81 {x0 x1 : ℕ} (h0 : ¬2 ^ 25 * x1 ≤ x0) : x0 < 2 ^ 24 * x1 * 2 := by omega theorem omS82 {x0 : ℕ} {x1 : ℤ} {x2 : ℤ} (h0 : x1 + ↑(x0 + (2 : ℕ)) = x2) (h1 : (-148 : ℤ) ≤ x2) : Max.max (↑((24 : ℕ) + x0) + (1 : ℤ) + x1 - (24 : ℤ)) (-149 : ℤ) = x2 - (1 : ℤ) := by subst_vars; omega theorem omS83 {x0 : ℤ} {x1 : ℤ} {x2 : ℕ} (h0 : x1 + ↑(x2 + (2 : ℕ)) = x0) : x0 - (1 : ℤ) = x1 + ↑(x2 + (1 : ℕ)) := by subst_vars; push_cast; ring theorem omS84 {x0 x1 : ℕ} (h0 : 33554431 * x0 < x1) : 2 * (2 ^ 24 * x0) < x1 + x0 := by omega theorem omS85 {x0 x1 : ℕ} (h0 : ¬2 ^ 25 * x1 ≤ x0) : x0 < 2 * (2 ^ 24 * x1) + x1 := by omega theorem omS86 {x0 : ℤ} (h0 : (-148 : ℤ) ≤ x0) : (-126 : ℤ) ≤ x0 - (1 : ℤ) + (23 : ℤ) := by omega theorem omS87 {x0 : ℤ} : x0 - (1 : ℤ) + (23 : ℤ) - (23 : ℤ) = x0 - (1 : ℤ) := by subst_vars; simp theorem omS88 {x0 : ℤ} : x0 - (1 : ℤ) + (23 : ℤ) + (1 : ℤ) - (23 : ℤ) = x0 := by ring theorem omS89 {x0 : ℕ} {x1 : ℤ} {x2 : ℤ} (h0 : (-149 : ℤ) ≤ x2) (h1 : x1 + ↑(x0 + (2 : ℕ)) = x2) (h2 : ¬(-148 : ℤ) ≤ x2) : Max.max (↑((24 : ℕ) + x0) + (1 : ℤ) + x1 - (24 : ℤ)) (-149 : ℤ) = x2 := by subst_vars; omega theorem omS90 {x0 x1 : ℕ} (h0 : 33554431 * x0 < x1) : 2 * (2 ^ 23 * (2 * x0)) < x1 + 2 * x0 := by omega theorem omS91 {x0 x1 : ℕ} (h0 : x0 < 4 * (2 ^ 23 * x1) + 2 * x1) : x0 < 2 * (2 ^ 23 * (2 * x1)) + 2 * x1 := by omega theorem omS92 {x0 : ℤ} (h0 : (-149 : ℤ) ≤ x0) : (1 : ℤ) ≤ x0 + (150 : ℤ) := by omega theorem omS93 {x0 : ℤ} (h0 : x0 + (150 : ℤ) ≤ (254 : ℤ)) : x0 + (150 : ℤ) ≤ (254 : ℤ) := by omega theorem omS94 {x0 : ℕ} (h0 : x0 < 2047) : ¬x0 = 2047 := by omega theorem omS95 {x0 : ℕ} (h0 : 1 ≤ x0) : ¬x0 = 0 := by omega theorem omS96 {x0 : ℕ} : ↑x0 - (1023 : ℤ) - (52 : ℤ) = ↑x0 - (1075 : ℤ) := by ring theorem omS97 {x0 x1 : ℕ} (h0 : x0 = (x1 + 268435455) % 2 ^ 64 / 2 ^ 29) : x0 < 2 ^ 35 := by subst_vars; omega theorem omS98 {x0 x1 : ℕ} (h0 : 897 ≤ x1 / 2 ^ 23 % 2 ^ 11) (h1 : x1 = (x0 + 268435455) % 2 ^ 64 / 2 ^ 29) (h2 : 2 ^ 34 ≤ x1) : x0 = 2 ^ 63 + (x0 - 2 ^ 63) := by subst_vars; omega theorem omS99 {x0 x1 : ℕ} (h0 : x0 = (x1 + 268435455) % 2 ^ 64 / 2 ^ 29) (h1 : 2 ^ 34 ≤ x0) : (x0 / 2 ^ 23 % 2 ^ 11 * 2 ^ 23 + x0 % 2 ^ 23) * 2 ^ 29 < x1 - 2 ^ 63 + 2 ^ 28 := by subst_vars; omega theorem omS100 {x0 x1 : ℕ} (h0 : x0 < 2 ^ 64) (h1 : x1 = (x0 + 268435455) % 2 ^ 64 / 2 ^ 29) (h2 : 2 ^ 34 ≤ x1) : x0 - 2 ^ 63 ≤ (x1 / 2 ^ 23 % 2 ^ 11 * 2 ^ 23 + x1 % 2 ^ 23) * 2 ^ 29 + 2 ^ 28 := by subst_vars; omega theorem omS101 {x0 : ℕ} : x0 = 0 + x0 := by subst_vars; simp theorem omS102 {x0 x1 : ℕ} (h0 : x0 = (x1 + 268435455) % 2 ^ 64 / 2 ^ 29) : (x0 / 2 ^ 23 % 2 ^ 11 * 2 ^ 23 + x0 % 2 ^ 23) * 2 ^ 29 < x1 + 2 ^ 28 := by subst_vars; omega theorem omS103 {x0 x1 : ℕ} (h0 : 897 ≤ x1 / 2 ^ 23 % 2 ^ 11) (h1 : x0 < 2 ^ 64) (h2 : x1 = (x0 + 268435455) % 2 ^ 64 / 2 ^ 29) (h3 : ¬2 ^ 34 ≤ x1) : x0 ≤ (x1 / 2 ^ 23 % 2 ^ 11 * 2 ^ 23 + x1 % 2 ^ 23) * 2 ^ 29 + 2 ^ 28 := by omega theorem omS107 {x0 x1 : ℕ} (h0 : x1 = x0 / 2 ^ 23 % 2 ^ 11) (h1 : (18446744073709550719 + x1) % 18446744073709551616 < 254) : 897 ≤ x0 / 2 ^ 23 % 2 ^ 11 := by subst_vars; omega theorem omS108 {x0 x1 : ℕ} (h0 : x1 = x0 / 2 ^ 23 % 2 ^ 11) (h1 : (18446744073709550719 + x1) % 18446744073709551616 < 254) : x0 / 2 ^ 23 % 2 ^ 11 < 1151 := by subst_vars; omega theorem omS109 {x0 : ℕ} : x0 % 2 ^ 23 < 2 ^ 23 := by omega theorem omS110 {x0 : ℕ} (h0 : x0 < 2 ^ 32) (h1 : 2 ^ 31 ≤ x0) : x0 / 2 ^ 31 = 1 := by omega theorem omS111 {x0 : ℕ} (h0 : x0 < 2 ^ 32) (h1 : 2 ^ 31 ≤ x0) : x0 / 2147483648 % 2 = 1 := by omega theorem omS112 {x0 : ℕ} (h0 : ¬2 ^ 31 ≤ x0) : x0 / 2 ^ 31 = 0 := by omega theorem omS113 {x0 : ℕ} (h0 : ¬2 ^ 31 ≤ x0) : x0 / 2147483648 % 2 = 0 := by omega theorem omS114 {x0 : ℕ} : x0 = x0 / 2 ^ 52 * 2 ^ 52 + x0 % 2 ^ 52 := by omega theorem omS115 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 2 ^ 23) (h1 : x3 < 2 ^ 52) (h2 : (x1 * 2 ^ 23 + x2) * 2 ^ 29 < x0 * 2 ^ 52 + x3 + 2 ^ 28) (h3 : x0 * 2 ^ 52 + x3 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 = x1 ∨ x0 + 1 = x1 ∧ x2 = 0 := by omega theorem omS116 {x0 x1 x2 x3 : ℕ} (h0 : 897 ≤ x1) (h1 : x2 < 2 ^ 52) (h2 : (x1 * 2 ^ 23 + x3) * 2 ^ 29 < x0 * 2 ^ 52 + x2 + 2 ^ 28) : 1 ≤ x0 := by omega theorem omS117 {x0 x1 x2 x3 : ℕ} (h0 : x1 < 1151) (h1 : x2 < 2 ^ 23) (h2 : x0 * 2 ^ 52 + x3 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 < 2047 := by omega theorem omS118 {x0 x1 x2 : ℕ} (h0 : x2 * 2 ^ 52 + x0 ≤ (x2 * 2 ^ 23 + x1) * 2 ^ 29 + 2 ^ 28) : 2 * (2 ^ 52 + x0) ≤ 2 ^ 53 + x1 * 2 ^ 30 + 2 ^ 29 := by omega theorem omS119 {x0 x1 x2 : ℕ} (h0 : (x2 * 2 ^ 23 + x0) * 2 ^ 29 < x2 * 2 ^ 52 + x1 + 2 ^ 28) : x0 ≠ 0 → 2 ^ 53 + x0 * 2 ^ 30 < 2 * (2 ^ 52 + x1) + 2 ^ 29 := by omega theorem omS120 {x0 : ℕ} : 2 ^ 53 < 2 * (2 ^ 52 + x0) + 2 ^ 28 := by omega theorem omS121 {x0 : ℕ} (h0 : x0 < 2 ^ 52) : 2 ^ 52 + x0 ≤ 2 ^ 53 + 0 * 2 ^ 30 + 2 ^ 29 := by omega theorem omS122 {x0 : ℕ} : 0 ≠ 0 → 2 ^ 53 + 0 * 2 ^ 30 < 2 ^ 52 + x0 + 2 ^ 29 := by omega theorem omS123 {x0 x1 : ℕ} (h0 : ((x1 + 1) * 2 ^ 23 + 0) * 2 ^ 29 < x1 * 2 ^ 52 + x0 + 2 ^ 28) : 2 ^ 53 < 2 ^ 52 + x0 + 2 ^ 28 := by omega theorem omS124 {x0 : ℕ} (h0 : (897 : ℕ) ≤ x0) : (-179 : ℤ) ≤ ↑x0 - (1076 : ℤ) := by omega theorem omS125 {x0 : ℕ} : 2 ^ 23 ≤ 2 ^ 23 + x0 := by omega theorem omS126 {x0 : ℕ} (h0 : x0 < 2 ^ 23) : 2 ^ 23 + x0 < 2 ^ 24 := by omega theorem omS127 {x0 : ℕ} (h0 : (897 : ℕ) ≤ x0) : (-149 : ℤ) ≤ ↑x0 - (1046 : ℤ) := by omega theorem omS128 {x0 : ℕ} (h0 : x0 < (1151 : ℕ)) : ↑x0 - (1046 : ℤ) + (150 : ℤ) ≤ (254 : ℤ) := by omega theorem omS129 {x0 : ℕ} (h0 : x0 = 0) : 2 ^ 23 + x0 = 2 ^ 23 := by subst_vars; omega theorem omS130 {x0 : ℕ} : (↑x0 - (1046 : ℤ) + (150 : ℤ)).toNat = x0 - (896 : ℕ) := by omega theorem omS131 {x0 : ℕ} (h0 : x0 < 2 ^ 23) : (2 ^ 23 + x0) % 2 ^ 23 = x0 := by omega theorem omS132 {x0 x1 x2 : ℕ} (h0 : x1 < x2) (h1 : ¬x0 < x2) : ¬x0 = x1 := by omega theorem omS133 {x0 : ℕ} (h0 : ѥ(8388607 : UInt32) ≤ x0 - ѥ(1 : UInt32)) (h1 : ѥ(8388607 : UInt32) = 8388607) (h2 : ѥ(8388608 : UInt32) = 8388608) (h3 : ѥ(1 : UInt32) = 1) : ѥ(8388608 : UInt32) ≤ x0 := by omega theorem omS134 {x0 : ℕ} (h0 : x0 < ѥ(2139095040 : UInt32)) (h1 : ѥ(2139095040 : UInt32) = 2139095040) (h2 : ѥ(8388608 : UInt32) = 8388608) (h3 : ѥ(2130706431 : UInt32) = 2130706431) : x0 - ѥ(8388608 : UInt32) ≤ ѥ(2130706431 : UInt32) := by omega theorem omS135 {x0 : Prop} {x1 : Prop} {x2 : ℕ} {x3 : ℕ} {x4 : ℕ} (h0 : x2 + (0 : ℕ) = x3) (h1 : x2 ≤ x4) (h2 : x4 < x3) : x0 ∧ x1 := by subst_vars; simp at *; omega theorem omS136 {x0 x1 x2 : ℕ} (h0 : x0 + (x2 + 1) = x1) : x0 < x1 := by subst_vars; simp theorem omS137 {x0 x1 x2 : ℕ} (h0 : x0 + (x1 + 1) = x2) : x0 + 1 + x1 = x2 := by subst_vars; simp +arith at * theorem omS138 {x0 x1 : ℕ} (h0 : x0 ≤ x1) (h1 : ¬x1 = x0) : x0 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS139 {x0 : ℕ} : 0 + x0 = x0 := by subst_vars; simp theorem omS140 {x0 x1 x2 : ℕ} (h0 : x1 = x2) (h1 : x0 < x2) : x0 < x1 := by subst_vars; omega theorem omS141 {x0 : ℕ} (h0 : x0 ≠ 0) (h1 : 8388607 ≤ (2 ^ 32 - 1 + x0) % 2 ^ 32) : 8388608 ≤ x0 := by omega theorem omS142 {x0 : ℕ} (h0 : x0 ≤ 2 ^ 31 - 1) : x0 % 2 ^ 31 = x0 := by omega theorem omS143 {x0 x1 x2 : ℕ} (h0 : x0 + x1 ≤ x2) (h1 : x2 < 2 ^ 32) : x0 < 2 ^ 32 := by exact Nat.lt_of_le_of_lt (Nat.le_trans (Nat.le_add_right _ _) ‹_›) ‹_› theorem omS144 {x0 x1 x2 x3 : ℕ} (h0 : x2 ≤ x1) (h1 : x0 + (x3 + 1) = x2) : x0 < x1 := by subst_vars; omega theorem omS145 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x0 + x3 ≤ x2) (h2 : x1 < x3) : x0 + x1 < 2 ^ 32 := by omega theorem omS146 {x0 x1 : ℕ} : x0 + 1 + x1 = x0 + (x1 + 1) := by simp +arith at * theorem omS147 {x0 x1 : ℕ} (h0 : x1 < x0) : 0 < x0 := by omega theorem omS148 {x0 x1 : ℕ} (h0 : x0 < x1 + 1) : x0 = x1 ∨ x0 < x1 := by omega theorem omS149 {x0 x1 x2 : ℕ} (h0 : x0 = x2) (h1 : x2 + x1 < 2 ^ 32) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS150 {x0 : ℕ} (h0 : x0 + 3 < 2 ^ 32) : x0 + 1 < 2 ^ 32 := by omega theorem omS151 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + 4 ≤ x1) : x0 + 3 < 2 ^ 32 := by omega theorem omS152 {x0 x1 : ℕ} (h0 : x0 + 4 ≤ x1) : x0 < x1 := by omega theorem omS153 {x0 x1 : ℕ} (h0 : x0 + 4 ≤ x1) : x0 + 1 < x1 := by omega theorem omS154 {x0 x1 x2 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + x2 ≤ x1) : x0 < 2 ^ 32 := by exact Nat.lt_of_le_of_lt (Nat.le_trans (Nat.le_add_right _ _) ‹_›) ‹_› theorem omS155 {x0 x1 : ℕ} (h0 : x0 + 0 = x1) : x0 = x1 := by omega theorem omS156 {x0 x1 x2 x3 x4 x5 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x3 + x4 ≤ x2) (h2 : x0 = x3) (h3 : x1 + (x5 + 1) = x4) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS157 {x0 x1 x2 x3 : ℕ} (h0 : x3 + (x1 + 1) = x2) (h1 : x0 = x3 + 1) : x0 + x1 = x2 := by subst_vars; simp +arith at * theorem omS158 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 := by omega theorem omS159 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 + 1 := by omega theorem omS160 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 + 1 + 1 := by omega theorem omS161 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 + 1 + 1 + 1 := by subst_vars; simp +arith at * <;> omega theorem omS162 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 + 1 + 1 + 1 + 1 := by subst_vars; simp +arith at * <;> omega theorem omS163 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 + 1 + 1 + 1 + 1 + 1 := by subst_vars; simp +arith at * <;> omega theorem omS164 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 + 1 + 1 + 1 + 1 + 1 + 1 := by subst_vars; simp +arith at * <;> omega theorem omS165 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 ≠ x1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 := by subst_vars; simp +arith at * <;> omega theorem omS166 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 < x1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 := by subst_vars; simp +arith at * <;> omega theorem omS167 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 8) (h1 : x0 = x1 + 8 * (x3 - x3) + x2) : x0 < x1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 := by simp_all +arith theorem omS168 {x0 x1 x2 x3 : ℕ} (h0 : x0 = x1 + 8 * (x3 - x3) + x2) : x0 = x1 + x2 := by simp_all +arith theorem omS169 {x0 x1 x2 x3 x4 : ℕ} (h0 : x3 ≤ x2) (h1 : x0 = x1 + 8 * (x2 - x3) + x4) (h2 : ¬x2 = x3) : x0 = x1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 8 * (x2 - (x3 + 1)) + x4 := by subst_vars; simp +arith at * <;> omega theorem omS170 {x0 x1 x2 : ℕ} (h0 : x2 < x0) (h1 : x1 ≤ x2) : x0 - (x1 + 1) < x0 - x1 := by omega theorem omS171 {x0 x1 x2 : ℕ} (h0 : x0 < x1) : x0 < x1 + 8 * (x2 - 0) := by omega theorem omS172 {x0 x1 x2 x3 x4 : ℕ} (h0 : x3 < x2) (h1 : x4 < 8) (h2 : x0 = x1 + 0 + 8 * x3 + x4) : x0 < x1 + 8 * (x2 - 0) := by subst_vars; simp at *; omega theorem omS173 {x0 x1 x2 x3 : ℕ} (h0 : x0 = x1 + 0 + 8 * x2 + x3) : x0 = x1 + 8 * (x2 - 0) + x3 := by omega theorem omS174 {x0 x1 : ℕ} (h0 : x1 ≤ x0) (h1 : ¬x0 = x1) : x0 - x1 = x0 - (x1 + 1) + 1 := by omega theorem omS175 {x0 x1 : ℕ} (h0 : x1 - x0 = x1 - (x0 + 1) + 1) : x0 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS176 {x0 x1 x2 x3 x4 x5 : ℕ} (h0 : x0 = x1 + (x3 + 8 * x2) + 8 * x4 + x5) : x0 = x1 + 8 * (x2 - 0) + x3 + 8 * x4 + x5 := by subst_vars; simp +arith at * theorem omS177 {x0 x1 : ℕ} (h0 : x1 < x0) : x0 - x1 = x0 - (x1 + 1) + 1 := by omega theorem omS178 {x0 x1 : ℕ} (h0 : ¬x1 < x0) : x0 - x1 = 0 := by simp_all +arith theorem omS179 {x0 : ℕ} (h0 : x0 % 8 = 0) : 8 * (x0 / 8) = x0 := by omega theorem omS180 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 / 8 < x1 / 8 := by omega theorem omS181 {x0 x1 x2 : ℕ} : x0 + 5 + 8 * x1 + x2 = 5 + x0 + 8 * x1 + x2 := by simp +arith at * theorem omS182 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 / 8 + 1 ≤ x1 / 8 := by omega theorem omS183 {x0 x1 x2 x3 : ℕ} (h0 : x1 < x3) (h1 : x2 < 8) : x0 + 8 * x1 + x2 < x0 + 8 * x3 := by omega theorem omS184 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x1 < x3) (h2 : x0 + x3 ≤ x2) : x0 + x1 < 2 ^ 32 := by omega theorem omS185 {x0 : ℕ} (h0 : x0 < 2 ^ 32) : x0 ≤ 4294967295 := by omega theorem omS186 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + 4 ≤ x1) : x0 < 2 ^ 32 := by exact Nat.lt_of_le_of_lt (Nat.le_trans (Nat.le_add_right _ _) ‹_›) ‹_› theorem omS187 {x0 x1 : ℕ} (h0 : x0 + 4 ≤ x1) : x0 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS188 {x0 x1 : ℕ} (h0 : x0 + 4 ≤ x1) : x0 + 1 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS189 {x0 x1 : ℕ} (h0 : x0 + 4 ≤ x1) : x0 + 2 + 1 ≤ x1 := by subst_vars; exact le_of_lt ‹_› theorem omS190 {x0 x1 : ℕ} (h0 : x0 + 4 ≤ x1) : x0 + 3 + 1 ≤ x1 := by omega theorem omS191 {x0 x1 : ℕ} (h0 : x1 ≤ x0) : x0 = x1 + (x0 - x1) := by simp_all +arith theorem omS192 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x1) (h1 : x1 + 4 ≤ x2) : x0 + (x1 - x0) < x2 := by omega theorem omS193 {x0 x1 : ℕ} (h0 : x1 ≤ x0) : x0 + 1 = x1 + (x0 + 1 - x1) := by subst_vars; exact (Nat.add_sub_of_le (Nat.le_trans ‹_› (Nat.le_add_right _ _))).symm theorem omS194 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x1) (h1 : x1 + 4 ≤ x2) : x0 + (x1 + 1 - x0) < x2 := by omega theorem omS195 {x0 x1 : ℕ} (h0 : x1 ≤ x0) : x0 + 2 = x1 + (x0 + 2 - x1) := by subst_vars; exact (Nat.add_sub_of_le (Nat.le_trans ‹_› (Nat.le_add_right _ _))).symm theorem omS196 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x1) (h1 : x1 + 4 ≤ x2) : x0 + (x1 + 2 - x0) < x2 := by omega theorem omS197 {x0 x1 : ℕ} (h0 : x1 ≤ x0) : x0 + 3 = x1 + (x0 + 3 - x1) := by subst_vars; exact (Nat.add_sub_of_le (Nat.le_trans ‹_› (Nat.le_add_right _ _))).symm theorem omS198 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x1) (h1 : x1 + 4 ≤ x2) : x0 + (x1 + 3 - x0) < x2 := by omega theorem omS199 {x0 x1 x2 : ℕ} (h0 : x0 - x1 = x2) (h1 : x1 + 4 ≤ x0) : x0 - (x1 + 4) < x2 := by subst_vars; omega theorem omS200 {x0 x1 : ℕ} (h0 : x0 ≤ x1) : x0 ≤ x1 + 4 := by omega theorem omS201 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 < x1) : x0 < 2 ^ 32 := by omega theorem omS202 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 + 1 ≤ x1 := by subst_vars; assumption theorem omS203 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x1) (h1 : x1 < x2) : x0 + (x1 - x0) < x2 := by simp_all +arith theorem omS204 {x0 x1 x2 : ℕ} (h0 : x0 - x1 = x2) (h1 : x1 < x0) : x0 - (x1 + 1) < x2 := by subst_vars; exact Nat.sub_lt_sub_left ‹_› (Nat.lt_succ_self _) theorem omS205 {x0 x1 : ℕ} (h0 : x0 ≤ x1) : x0 ≤ x1 + 1 := by omega theorem omS206 {x0 x1 x2 : ℕ} (h0 : x1 = 8 * (x2 / 8)) (h1 : x1 + x0 < x2) : x0 < 8 := by subst_vars; omega theorem omS207 {x0 x1 : ℕ} (h0 : x0 = 8 * (x1 / 8)) (h1 : x1 < 2 ^ 32) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS208 {x0 x1 : ℕ} (h0 : x0 = 8 * (x1 / 8)) : x0 ≤ x1 := by subst_vars; omega theorem omS209 {x0 x1 x2 x3 : ℕ} (h0 : x0 + x3 < x2) : Min.min (x0 + x1) (x2 - 1) + 1 ≤ x2 := by subst_vars; simp at *; omega theorem omS210 {x0 x1 x2 : ℕ} (h0 : x0 + x1 < x2) : x0 + x1 = Min.min (x0 + x1) (x2 - 1) := by subst_vars; simp at *; omega theorem omS211 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + 8 ≤ x1) : x0 < 2 ^ 32 := by exact Nat.lt_of_le_of_lt (Nat.le_trans (Nat.le_add_right _ _) ‹_›) ‹_› theorem omS212 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + 8 ≤ x1) : x0 + 4 < 2 ^ 32 := by omega theorem omS213 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + 8 ≤ x1) : x0 + 3 < 2 ^ 32 := by omega theorem omS214 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + 8 ≤ x1) : x0 + 4 + 3 < 2 ^ 32 := by omega theorem omS215 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS216 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 + 1 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS217 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 + 2 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS218 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 + 3 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS219 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 + 4 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS220 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 + 4 + 1 + 1 ≤ x1 := by subst_vars; simp at *; omega theorem omS221 {x0 : ℕ} : x0 + 5 = x0 + 4 + 1 := by subst_vars; rfl theorem omS222 {x0 : ℕ} : x0 + 6 = x0 + 4 + 2 := by subst_vars; rfl theorem omS223 {x0 : ℕ} : x0 + 7 = x0 + 4 + 3 := by subst_vars; rfl theorem omS224 {x0 x1 : ℕ} (h0 : x0 + 8 ≤ x1) : x0 + 4 ≤ x1 := by omega theorem omS226 {x0 x1 x2 : ℕ} (h0 : x0 - x1 = x2) (h1 : x1 + 8 ≤ x0) : x0 - (x1 + 8) < x2 := by subst_vars; omega theorem omS227 {x0 : ℕ} (h0 : x0 % 8 = 0) : (x0 + 8) % 8 = 0 := by omega theorem omS228 {x0 x1 : ℕ} (h0 : x0 % 8 = 0) (h1 : ¬x0 + 8 ≤ x1) (h2 : x0 < x1) : x0 = 8 * (x1 / 8) := by omega theorem omS229 {x0 x1 : ℕ} (h0 : x1 < x0) (h1 : x1 = 8 * (x0 / 8)) : x0 % 8 ≠ 0 := by subst_vars; omega theorem omS230 {x0 x1 x2 x3 x4 : ℕ} (h0 : x0 < 2 ^ 64) (h1 : (x0 + 2097152) % 2 ^ 64 = x1 + x4) (h2 : (2 ^ 64 - 2097152 + x0) % 2 ^ 64 = x1 + x2) (h3 : x3 < x4 + 2 ^ 28) (h4 : x4 ≤ x3 + 2 ^ 28) (h5 : x3 < x2 + 2 ^ 28) (h6 : x2 ≤ x3 + 2 ^ 28) : x0 = x1 + (x2 + 2097152) ∧ x3 + 2097152 < x2 + 2097152 + 2 ^ 28 ∧ x2 + 2097152 + 2097152 ≤ x3 + 2 ^ 28 := by omega theorem omS231 {x0 x1 x2 : ℕ} (h0 : x2 + x1 + 2097152 < x2 + x0 + 2 ^ 28) (h1 : x2 + x0 + 2097152 ≤ x2 + x1 + 2 ^ 28) : x0 + 2097152 ≤ x1 + 2 ^ 28 ∧ x1 + 2097152 < x0 + 2 ^ 28 := by omega theorem omS232 {x0 x1 : ℕ} (h0 : 897 ≤ x0) : 2 ^ 61 ≤ (x0 * 2 ^ 23 + x1) * 2 ^ 29 := by omega theorem omS233 {x0 x1 : ℕ} (h0 : x0 < 1151) (h1 : x1 < 2 ^ 23) : (x0 * 2 ^ 23 + x1) * 2 ^ 29 < 2 ^ 63 - 2 ^ 60 := by omega theorem omS234 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 2 ^ 23) (h1 : x3 < 2 ^ 52) (h2 : (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2097152 < x0 * 2 ^ 52 + x3 + 2 ^ 28) (h3 : x0 * 2 ^ 52 + x3 + 2097152 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 = x1 ∨ x0 + 1 = x1 ∧ x2 = 0 := by omega theorem omS235 {x0 : ℕ} {x1 : ℕ} {x2 : ℕ} {x3 : ℕ} (h0 : (897 : ℕ) ≤ x1) (h1 : x2 < (2 : ℕ) ^ (52 : ℕ)) (h2 : (x1 * (2 : ℕ) ^ (23 : ℕ) + x3) * (2 : ℕ) ^ (29 : ℕ) + (2097152 : ℕ) < x0 * (2 : ℕ) ^ (52 : ℕ) + x2 + (2 : ℕ) ^ (28 : ℕ)) : (-1021 : ℤ) ≤ ↑x0 - (1075 : ℤ) := by omega theorem omS236 {x0 : ℕ} (h0 : x0 < 2 ^ 52) : 2 ^ 52 + x0 ≤ 2 ^ 53 := by omega theorem omS237 {x0 x1 : ℕ} (h0 : ((x1 + 1) * 2 ^ 23 + 0) * 2 ^ 29 + 2097152 < x1 * 2 ^ 52 + x0 + 2 ^ 28) : 2 ^ 52 + 2097152 < x0 + 2 ^ 28 := by omega theorem omS238 {x0 x1 x2 x3 : ℕ} (h0 : 897 ≤ x1) (h1 : x2 < 2 ^ 52) (h2 : (x1 * 2 ^ 23 + x3) * 2 ^ 29 + 2097152 < x0 * 2 ^ 52 + x2 + 2 ^ 28) : 1 ≤ x0 := by omega theorem omS239 {x0 x1 x2 x3 : ℕ} (h0 : x1 < 1151) (h1 : x2 < 2 ^ 23) (h2 : x0 * 2 ^ 52 + x3 + 2097152 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 < 2047 := by omega theorem omS240 {x0 x1 x2 x3 : ℕ} (h0 : (x0 * 2 ^ 23 + x1) * 2 ^ 29 + 2097152 < x2 * 2 ^ 52 + x3 + 2 ^ 28) : (x0 * 2 ^ 23 + x1) * 2 ^ 29 + 2097152 < x2 * 2 ^ 52 + x3 + 2 ^ 28 := by omega theorem omS241 {x0 x1 x2 x3 : ℕ} (h0 : x0 * 2 ^ 52 + x1 + 2097152 ≤ (x2 * 2 ^ 23 + x3) * 2 ^ 29 + 2 ^ 28) : x0 * 2 ^ 52 + x1 + 2097152 ≤ (x2 * 2 ^ 23 + x3) * 2 ^ 29 + 2 ^ 28 := by omega theorem omS242 {x0 x1 : ℕ} (h0 : x0 = x1 / 2 ^ 52 % 2 ^ 11) (h1 : (18446744073709551615 + x0) % 18446744073709551616 < 1900) : 1 ≤ x0 ∧ x0 ≤ 1900 := by subst_vars; omega theorem omS243 {x0 x1 x2 : ℕ} (h0 : 1 ≤ x0 ∧ x0 ≤ 1900) (h1 : x2 < 2 ^ 52) (h2 : (x0 + 35) * 9007199254740992 % 18446744073709551616 ≤ 2 * (x1 * 2 ^ 52 + x2)) : x0 + 35 ≤ x1 := by omega theorem omS244 {x0 : ℕ} (h0 : 1 ≤ x0 ∧ x0 ≤ 1900) : x0 < 2047 := by omega theorem omS245 {x0 x1 x2 : ℕ} (h0 : (18446744073709551615 + x1) % 18446744073709551616 < 1900) (h1 : x2 < 2 ^ 52) (h2 : (x1 + 35) * 9007199254740992 % 18446744073709551616 ≤ 2 * (x0 * 2 ^ 52 + x2)) : 1 ≤ x0 := by omega theorem omS246 {x0 x1 : ℕ} (h0 : x0 * 2 ^ 52 + x1 < 2047 * 2 ^ 52) : x0 < 2047 := by omega theorem omS247 {x0 : ℕ} {x1 : ℕ} (h0 : x0 + (35 : ℕ) ≤ x1) : ↑x0 + (35 : ℤ) - (1075 : ℤ) ≤ ↑x1 - (1075 : ℤ) := by subst_vars; simp at *; omega theorem omS248 {x0 : ℕ} : 2 ^ 52 ≤ 2 ^ 52 + x0 := by omega theorem omS249 {x0 : ℕ} (h0 : x0 < 2047 * 2 ^ 52) (h1 : 18446744073709551615 ≤ 2 * x0) : False := by omega theorem omS250 {x0 x1 : ℕ} (h0 : x0 + 2097152 < x1 + 2 ^ 28) (h1 : x1 + 2097152 ≤ x0 + 2 ^ 28) : x0 < x1 + 2 ^ 28 ∧ x1 ≤ x0 + 2 ^ 28 := by omega theorem omS251 {x0 x1 x2 : ℕ} (h0 : x1 < 1151) (h1 : x2 < 2 ^ 23) (h2 : x0 + 2097152 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 < 2047 * 2 ^ 52 := by omega theorem omS252 {x0 : ℕ} (h0 : x0 < (1151 : ℕ)) : ↑x0 - (1076 : ℤ) ≤ (74 : ℤ) := by omega theorem omS253 {x0 x1 : ℕ} (h0 : x0 < 10349271943697399808) (h1 : (18446744073709551616 - x0 + x1) % 18446744073709551616 < (18446744073709551616 - x0 + 10349271943697399808) % 18446744073709551616) : x0 ≤ x1 := by omega theorem omS254 {x0 x1 : ℕ} (h0 : x1 < 10349271943697399808) (h1 : (18446744073709551616 - x1 + x0) % 18446744073709551616 < (18446744073709551616 - x1 + 10349271943697399808) % 18446744073709551616) (h2 : x0 < 18446744073709551616) : x0 < 10349271943697399808 := by omega theorem omS255 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) : x0 + 266338303 < 18446744073709551616 := by omega theorem omS256 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) (h2 : (x0 + 266338303) % 536870912 < 532676608) : (x0 + 2097152 + 268435455) % 18446744073709551616 / 536870912 = (x0 + 266338303) / 536870912 := by omega theorem omS257 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) : (18446744073707454464 + x0 + 268435455) % 18446744073709551616 / 536870912 = (x0 + 266338303) / 536870912 := by omega theorem omS258 {x0 : ℕ} (h0 : 8088464930757410816 ≤ x0 * 2 % 18446744073709551616) (h1 : x0 * 2 % 18446744073709551616 < 10349271943697399808) : 898 ≤ (x0 + 266338303) / 536870912 / 8388608 % 2048 := by omega theorem omS259 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) : (x0 + 266338303) / 536870912 / 8388608 % 2048 < 1151 := by omega theorem omS260 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) : (x0 + 266338303) / 536870912 < 34359738368 := by omega theorem omS261 {x0 : ℕ} (h0 : 898 ≤ x0 / 8388608 % 2048) (h1 : x0 / 8388608 % 2048 < 1151) : (18446744073709550719 + x0 / 8388608 % 2048) % 18446744073709551616 < 254 := by omega theorem omS262 {x0 x1 : ℕ} (h0 : x0 < Ѧ(8088464930757410816 : UInt64)) (h1 : Ѧ(8088464930757410816 : UInt64) ≤ x1) : x0 ≤ x1 := by omega theorem omS263 {x0 x1 : ℕ} (h0 : ¬x1 < Ѧ(8088464930757410816 : UInt64)) (h1 : x1 ≤ x0) : Ѧ(8088464930757410816 : UInt64) ≤ x0 := by omega theorem omS264 {x0 x1 x2 : ℕ} (h0 : x1 < 1151) (h1 : x2 < 2 ^ 23) (h2 : x0 + 2097152 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 < 2 ^ 63 := by omega theorem omS265 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 52) (h1 : 8088464930757410816 ≤ 2 * (x0 * 2 ^ 52 + x1)) : 898 ≤ x0 := by omega theorem omS266 {x0 : ℕ} (h0 : 898 ≤ x0) : 1 ≤ x0 := by omega theorem omS267 {x0 : ℕ} (h0 : (898 : ℕ) ≤ x0) : (-125 : ℤ) ≤ (52 : ℤ) + (↑x0 - (1075 : ℤ)) := by omega theorem omS268 {x0 x1 : ℕ} (h0 : x0 ≤ x1) (h1 : x1 < 2 ^ 20) : x0 ≤ 2 ^ 20 := by omega theorem omS269 {x0 x1 x2 x3 : ℕ} (h0 : x0 + x1 ≤ x2) (h1 : x2 = x3) (h2 : x3 < 2 ^ 32) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS270 {x0 x1 x2 x3 : ℕ} (h0 : x0 + x1 ≤ x3) (h1 : x3 = x2) : x0 + x1 ≤ x2 := by subst_vars; omega theorem omS271 {x0 x1 x2 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x2 + (x0 + 3) < x1) : x0 < 2 ^ 32 := by omega theorem omS272 {x0 x1 x2 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x2 + (x0 + 3) < x1) : x0 + 3 < 2 ^ 32 := by omega theorem omS273 {x0 x1 x2 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x0 + (x1 + 3) < x2) : x0 + x1 < 2 ^ 32 := by omega theorem omS274 {x0 x1 x2 : ℕ} (h0 : x1 + x0 = x2) (h1 : x1 + 4 ≤ x2) : x0 - 4 < x0 := by subst_vars; simp at *; omega theorem omS275 {x0 x1 x2 : ℕ} (h0 : x0 + x1 = x2) (h1 : x0 + 4 ≤ x2) : x0 + 4 + (x1 - 4) = x2 := by subst_vars; simp_all +arith theorem omS276 {x0 x1 : ℕ} : x0 + (x1 + 4) = x0 + x1 + 4 := by subst_vars; rfl theorem omS277 {x0 x1 : ℕ} (h0 : x0 + 4 ≤ x1) : x0 + 0 < x1 := by subst_vars; simp at *; omega theorem omS278 {x0 x1 x2 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x2 + x0 < x1) : x0 < 2 ^ 32 := by omega theorem omS279 {x0 x1 x2 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x0 + x1 < x2) : x0 + x1 < 2 ^ 32 := by omega theorem omS280 {x0 x1 x2 : ℕ} (h0 : x1 + x0 = x2) (h1 : x1 < x2) : x0 - 1 < x0 := by subst_vars; simp at *; omega theorem omS281 {x0 x1 x2 : ℕ} (h0 : x0 + x1 = x2) (h1 : x0 < x2) : x0 + 1 + (x1 - 1) = x2 := by subst_vars; simp_all +arith theorem omS282 {x0 x1 x2 : ℕ} (h0 : x0 + x2 = x1) (h1 : ¬x0 < x1) : x0 = x1 := by subst_vars; simp at *; omega theorem omS283 {x0 x1 : ℕ} (h0 : x0 + x1 < 2 ^ 32) : x0 < 2 ^ 32 := by omega theorem omS284 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : 8 * x0 + 9 ≤ x1) : 8 * x0 < 2 ^ 32 := by exact Nat.lt_of_le_of_lt (Nat.le_trans (Nat.le_add_right _ _) ‹_›) ‹_› theorem omS285 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 < 2 ^ 32 := by omega theorem omS286 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 7 < x1 := by subst_vars; assumption theorem omS287 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 6 < x1 := by omega theorem omS288 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 5 < x1 := by omega theorem omS289 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 4 < x1 := by omega theorem omS290 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 3 < x1 := by omega theorem omS291 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 2 < x1 := by omega theorem omS292 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 1 < x1 := by omega theorem omS293 {x0 x1 : ℕ} (h0 : 8 * x0 + 9 ≤ x1) : 8 * x0 + 1 + 0 < x1 := by subst_vars; simp at *; omega theorem omS294 {x0 x1 x2 x3 x4 : ℕ} (h0 : x0 = 8 * x2 + 1) (h1 : x2 < x3) (h2 : x4 < 2 ^ 32) (h3 : 8 * x3 + 1 ≤ x4) (h4 : x1 < 8) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS295 {x0 x1 : ℕ} (h0 : x1 ≤ 128) (h1 : x0 + 1 = x1 * 2 ^ 23) : x0 < 1073741824 := by omega theorem omS296 {x0 x1 : ℕ} (h0 : 2 ≤ x1) (h1 : x1 ≤ 128) (h2 : x0 + 1 = x1 * 2 ^ 23) : 8388608 ≤ x0 % 2 ^ 31 := by omega theorem omS297 {x0 x1 : ℕ} (h0 : x1 ≤ 128) (h1 : x0 + 1 = x1 * 2 ^ 23) : x0 % 2 ^ 31 < 1073741824 := by omega theorem omS298 {x0 x1 : ℕ} (h0 : x1 ≤ 128) (h1 : x0 + 1 = x1 * 2 ^ 23) : x0 ≤ 2147483647 := by omega theorem omS299 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x1 / 2 ^ 23 % 256 ∧ x1 / 2 ^ 23 % 256 < x2) : x0 * 8388608 ≤ x1 % 2 ^ 31 := by omega theorem omS300 {x0 x1 x2 x3 : ℕ} (h0 : x1 + 1 = x2 * 2 ^ 23) (h1 : x3 ≤ x0 / 2 ^ 23 % 256 ∧ x0 / 2 ^ 23 % 256 < x2) : x0 % 2 ^ 31 ≤ x1 := by omega theorem omS309 {x0 x1 : ℕ} (h0 : x0 < x1 + 1) (h1 : ¬x0 < x1) : x0 = x1 := by omega theorem omS312 {x0 x1 : ℕ} (h0 : x1 < 1073741824) (h1 : x0 ≤ x1) : x0 < 2139095040 := by omega theorem omS313 {x0 x1 x2 x3 x4 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x0 + x3 ≤ x2) (h2 : x1 + (x4 + 1) = x3) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS314 {x0 x1 x2 x3 x4 : ℕ} (h0 : 8 * x1 + 1 ≤ x2) (h1 : x2 < 2 ^ 32) (h2 : x0 = 8 * x3 + 1) (h3 : x3 + (x4 + 1) = x1) : x0 + 8 < 2 ^ 32 := by subst_vars; omega theorem omS315 {x0 x1 : ℕ} (h0 : x0 = 8 * x1 + 1) : x0 + 8 = 8 * (x1 + 1) + 1 := by subst_vars; rfl theorem omS316 {x0 x1 x2 x3 : ℕ} (h0 : x2 + x1 < 2 ^ 32) (h1 : x2 = x3 + x0) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS317 {x0 x1 x2 x3 : ℕ} (h0 : x3 + x2 < 2 ^ 32) (h1 : x3 = x0 + x1) : x0 + (x1 + x2) < 2 ^ 32 := by subst_vars; omega theorem omS318 {x0 x1 : ℕ} (h0 : x1 < 8) : x0 + x1 + 1 ≤ x0 + 8 := by subst_vars; simp +arith at * <;> omega theorem omS319 {x0 x1 x2 : ℕ} (h0 : x1 < x2 + 8) (h1 : x1 = x2 + x0) : x0 < 8 := by subst_vars; simp at *; omega theorem omS320 {x0 x1 x2 x3 x4 : ℕ} (h0 : x3 < 2 ^ 32) (h1 : x4 + x2 < x3) (h2 : x4 = x0 + x1) : x0 + (x1 + x2) < 2 ^ 32 := by subst_vars; omega theorem omS321 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x3 + x1 < x2) (h2 : x3 = x0) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS322 {x0 x1 : ℕ} (h0 : 1 * x0 + x1 < 2 ^ 32) : x0 + x1 < 2 ^ 32 := by omega theorem omS323 {x0 x1 x2 : ℕ} (h0 : x1 = x2) (h1 : x2 < 2 ^ 32) (h2 : x0 ≤ x1) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS324 {x0 x1 x2 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 + (x2 + 1) = x1) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS325 {x0 x1 : ℕ} (h0 : x1 + 8 ≤ x0) : 1 ≤ x0 := by omega theorem omS326 {x0 x1 x2 : ℕ} (h0 : x0 + 8 ≤ x2) (h1 : x1 < 8) : x0 + x1 < x2 := by omega theorem omS329 {x0 x1 : ℕ} : x0 + (x1 + 1) = x0 + x1 + 1 := by subst_vars; rfl theorem omS330 {x0 x1 : ℕ} : x0 + 1 + x1 = x0 + x1 + 1 := by simp +arith at * theorem omS332 {x0 x1 : ℕ} (h0 : 1 * x0 = x1) : 0 * x0 + x0 ≤ x1 := by subst_vars; simp theorem omS333 {x0 : ℕ} : 0 * x0 < 2 ^ 32 := by omega theorem omS334 {x0 x1 : ℕ} (h0 : x0 < 1 * x1) : x0 < 0 * x1 + x1 := by subst_vars; simp at *; omega theorem omS335 {x0 : ℕ} : ↑x0 - (1046 : ℤ) = ↑(30 : ℕ) + (↑x0 - (1076 : ℤ)) := by ring theorem omS336 {x0 : ℕ} (h0 : x0 % 2 ^ 31 = 0 ∨ 2 ^ 23 ≤ x0 % 2 ^ 31 ∧ x0 % 2 ^ 31 < 2139095040) : x0 % 2 ^ 31 = 0 ∨ 2 ^ 23 ≤ x0 % 2 ^ 31 := by omega theorem omS337 {x0 : ℕ} : x0 % 2 ^ 52 < 2 ^ 52 := by omega theorem omS338 {x0 x1 : ℕ} (h0 : x0 / 2 ^ 52 = x1) : x0 = x1 * 2 ^ 52 + x0 % 2 ^ 52 := by omega theorem omS339 {x0 : ℕ} : ↑x0 - (1023 : ℤ) = ↑(52 : ℕ) + (↑x0 - (1075 : ℤ)) := by ring theorem omS340 {x0 : ℕ} : ↑x0 - (1022 : ℤ) = ↑(53 : ℕ) + (↑x0 - (1075 : ℤ)) := by ring theorem omS341 {x0 x1 : ℕ} (h0 : x0 + x1 = 1023) : x0 < 2047 := by omega theorem omS342 {x0 : ℕ} {x1 : ℕ} (h0 : x0 + x1 = (1023 : ℕ)) : ↑x0 - (1075 : ℤ) = -((52 : ℤ) + ↑x1) := by omega theorem omS343 {x0 x1 : ℕ} (h0 : x0 / 2 ^ 52 = x1) (h1 : x1 < 2047) : x0 < 2 ^ 63 := by subst_vars; omega theorem omS344 {x0 : ℕ} (h0 : x0 < 1151) (h1 : ¬x0 ≤ 1149) : x0 = 1150 := by omega theorem omS345 {x0 : ℕ} (h0 : x0 ≤ (1149 : ℕ)) : ↑x0 - (1076 : ℤ) ≤ (73 : ℤ) := by subst_vars; simp at *; omega theorem omS346 {x0 x1 x2 x3 x4 x5 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x0 = x3) (h2 : x3 + x4 ≤ x2) (h3 : x1 + (x5 + 1) = x4) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS347 {x0 x1 x2 x3 x4 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x2 + x3 ≤ x1) (h2 : x0 + (x4 + 1) = x3) : x0 + 1 < 2 ^ 32 := by subst_vars; omega theorem omS348 {x0 x1 x2 x3 x4 : ℕ} (h0 : x0 + x3 ≤ x2) (h1 : x1 + (x4 + 1) = x3) : x0 + x1 < x2 := by subst_vars; omega theorem omS349 {x0 : ℕ} (h0 : x0 ≤ 1895825407) : ¬2 ^ 31 ≤ x0 := by omega theorem omS350 {x0 : ℕ} (h0 : 528482304 ≤ x0) (h1 : x0 ≤ 1895825407) : 528482304 ≤ x0 % 2 ^ 31 := by omega theorem omS351 {x0 : ℕ} (h0 : x0 < 2 ^ 20) : x0 + 8 ≤ 2 ^ 21 := by omega theorem omS352 {x0 : ℕ} (h0 : x0 < (2 : ℕ) ^ (20 : ℕ)) : (↑x0 + (8 : ℤ)).natAbs < (2 : ℕ) ^ (53 : ℕ) := by subst_vars; simp at *; omega theorem omS353 {x0 : ℕ} (h0 : x0 < (1 : ℕ) + (1222 : ℕ)) : ↑x0 - (1022 : ℤ) ≤ (200 : ℤ) := by subst_vars; simp at *; omega theorem omS354 {x0 : ℕ} (h0 : (972 : ℕ) ≤ x0) : (-51 : ℤ) ≤ ↑x0 - (1023 : ℤ) := by omega theorem omS355 {x0 : ℕ} (h0 : x0 < (972 : ℕ) + (2 : ℕ)) : ↑x0 - (1022 : ℤ) ≤ (-49 : ℤ) := by subst_vars; simp at *; omega theorem omS356 {x0 : ℕ} (h0 : x0 ≤ (1222 : ℕ)) : ↑x0 - (1022 : ℤ) ≤ (200 : ℤ) := by subst_vars; simp at *; omega theorem omS357 {x0 x1 : ℕ} (h0 : 2 * (x0 * 2 ^ 52 + x1) < 10349271943697399808) : x0 ≤ 1148 := by omega theorem omS358 {x0 : ℕ} (h0 : x0 ≤ 1148) : x0 < 2047 := by omega theorem omS359 {x0 : ℕ} (h0 : x0 ≤ (1148 : ℕ)) : (53 : ℤ) + (↑x0 - (1075 : ℤ)) ≤ (126 : ℤ) := by omega theorem omS360 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x0 = x1) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS361 {x0 x1 : ℕ} (h0 : x1 < 2 ^ 20) (h1 : x0 = x1) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS362 {x0 x1 : ℕ} (h0 : x0 = x1) (h1 : x1 < 2 ^ 20) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS363 {x0 : ℕ} (h0 : x0 < 2 ^ 20) : x0 < 2 ^ 32 := by omega theorem omS364 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) : x0 + 268435453 < 18446744073709551616 := by omega theorem omS365 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) (h2 : (x0 + 268435453) % 536870912 < 536870908) : (x0 + 2 + 268435455) % 18446744073709551616 / 536870912 = (x0 + 268435453) / 536870912 := by omega theorem omS366 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) : (18446744073709551614 + x0 + 268435455) % 18446744073709551616 / 536870912 = (x0 + 268435453) / 536870912 := by omega theorem omS367 {x0 : ℕ} (h0 : 8088464930757410816 ≤ x0 * 2 % 18446744073709551616) (h1 : x0 * 2 % 18446744073709551616 < 10349271943697399808) : 898 ≤ (x0 + 268435453) / 536870912 / 8388608 % 2048 := by omega theorem omS368 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) : (x0 + 268435453) / 536870912 / 8388608 % 2048 < 1151 := by omega theorem omS369 {x0 : ℕ} (h0 : x0 * 2 % 18446744073709551616 < 10349271943697399808) (h1 : x0 < 18446744073709551616) : (x0 + 268435453) / 536870912 < 34359738368 := by omega theorem omS370 {x0 x1 : ℕ} (h0 : x0 < x1) : ¬x0 = x1 := by omega theorem omS371 {x0 x1 : ℕ} (h0 : ¬x1 < x0) (h1 : ¬x1 = x0) : x0 < x1 := by omega theorem omS372 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 2 ^ 32) (h1 : x0 + x1 + x3 < x2) : x0 + x1 < 2 ^ 32 := by omega theorem omS373 {x0 x1 x2 : ℕ} (h0 : x0 < 2 ^ 32) : x0 - (x1 + x2) < 2 ^ 32 := by omega theorem omS374 {x0 x1 : ℕ} (h0 : x0 < x1 + 1) (h1 : ¬x0 = x1) : x0 < x1 := by omega theorem omS375 {x0 x1 : ℕ} : x0 + (x1 + 1) = x0 + 1 + x1 := by simp +arith at * theorem omS376 {x0 x1 : ℕ} (h0 : x1 < x0) : x0 > 0 := by omega theorem omS377 {x0 x1 x2 : ℕ} (h0 : x2 + x0 < x2 + x1) : x0 < x1 := by subst_vars; simp at *; omega theorem omS378 {x0 x1 x2 : ℕ} : x0 + (x1 + 2 * x2) = x0 + x2 + x1 + x2 := by simp +arith at * theorem omS379 {x0 x1 : ℕ} (h0 : x1 + 2 * x0 < 2 ^ 32) : x0 < 2 ^ 32 := by omega theorem omS380 {x0 x1 : ℕ} (h0 : x0 + 2 * x1 < 2 ^ 32) : x0 < 2 ^ 32 := by omega theorem omS381 {x0 x1 x2 : ℕ} (h0 : x0 < x2) : x0 < x1 + 2 * x2 := by omega theorem omS382 {x0 x1 x2 x3 x4 : ℕ} (h0 : x2 < x1) : x0 < x1 ∨ x2 < x1 ∨ x0 - x1 ≥ x3 ∨ x2 - x1 ≥ x4 := by simp_all +arith theorem omS383 {x0 x1 x2 : ℕ} (h0 : x1 < x2) : x0 + x1 < x2 + 2 * x0 := by subst_vars; simp +arith at * <;> omega theorem omS384 {x0 x1 x2 x3 x4 : ℕ} (h0 : x1 ≤ x0) (h1 : x0 - x1 < x3) (h2 : x2 < x4) : ¬(x0 < x1 ∨ x1 + x2 < x1 ∨ x0 - x1 ≥ x3 ∨ x1 + x2 - x1 ≥ x4) := by simp_all +arith theorem omS385 {x0 x1 x2 x3 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x1 = x2) (h2 : x0 + x3 ≤ x2) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS386 {x0 x1 x2 : ℕ} (h0 : x2 < x0) : x0 + (x1 + x2) < x1 + 2 * x0 := by subst_vars; simp +arith at * <;> omega theorem omS387 {x0 x1 x2 x3 x4 : ℕ} : x0 < x1 ∨ x1 + (x2 + x3) < x1 ∨ x0 - x1 ≥ x4 ∨ x1 + (x2 + x3) - x1 ≥ x2 := by subst_vars; simp theorem omS388 {x0 x1 x2 x3 x4 : ℕ} (h0 : ¬(x0 < x1 ∨ x3 < x1 ∨ x0 - x1 ≥ x2 ∨ x3 - x1 ≥ x4)) : x0 - x1 < x2 := by simp_all +arith theorem omS389 {x0 x1 x2 x3 x4 : ℕ} (h0 : ¬(x1 < x0 ∨ x2 < x0 ∨ x1 - x0 ≥ x3 ∨ x2 - x0 ≥ x4)) : x0 ≤ x1 := by simp_all +arith theorem omS390 {x0 x1 x2 x3 : ℕ} (h0 : x0 = x2) (h1 : x1 = x3) (h2 : x2 + x3 < 2 ^ 32) : x0 + x1 < 2 ^ 32 := by subst_vars; omega theorem omS391 {x0 x1 x2 : ℕ} : x0 + (x1 + x2) = x0 + x1 + x2 := by simp +arith at * theorem omS392 {x0 x1 x2 x3 x4 : ℕ} (h0 : x1 + x2 ≤ x3) (h1 : x3 < 2 ^ 32) (h2 : x4 + x0 < x2) : x0 < 2 ^ 32 := by omega theorem omS393 {x0 x1 x2 x3 x4 : ℕ} (h0 : x1 + x2 ≤ x3) (h1 : x3 < 2 ^ 32) (h2 : x4 + x0 ≤ x2) : x0 < 2 ^ 32 := by omega theorem omS394 {x0 x1 x2 x3 x4 : ℕ} (h0 : x0 + x3 ≤ x4) (h1 : x4 < 2 ^ 32) (h2 : x1 + x2 ≤ x3) : x0 + x1 + x2 < 2 ^ 32 := by omega theorem omS395 {x0 x1 : ℕ} (h0 : x0 < 2 ^ 32) : x0 - x1 < 2 ^ 32 := by omega theorem omS396 {x0 x1 x2 : ℕ} : x0 < x1 - x2 ↔ x2 + x0 < x1 := by omega theorem omS397 {x0 x1 x2 x3 x4 : ℕ} (h0 : x0 + x4 ≤ x3) (h1 : x1 + x2 < x4) : x0 + (x1 + x2) < x3 := by omega theorem omS398 {x0 x1 x2 : ℕ} (h0 : ¬x1 + x2 < x0) : x0 ≤ x1 + x2 + 1 := by omega theorem omS399 {x0 x1 x2 : ℕ} (h0 : x0 - x1 = x2) (h1 : x1 < x0) : x0 - (x1 + 8) < x2 := by subst_vars; omega theorem omS400 {x0 x1 : ℕ} (h0 : ¬x1 < x0) : x0 ≤ x1 := by subst_vars; simp at *; omega theorem omS401 {x0 x1 x2 x3 : ℕ} (h0 : x1 + (x3 + 1) = x2) : x0 + x1 < x0 + x2 := by subst_vars; simp theorem omS402 {x0 x1 x2 x3 : ℕ} (h0 : x1 ≤ x2) (h1 : x2 < 2 ^ 32) (h2 : x3 + x0 ≤ x1) : x0 < 2 ^ 32 := by omega theorem omS403 {x0 x1 x2 x3 : ℕ} (h0 : x2 ≤ x3) (h1 : x3 < 2 ^ 32) (h2 : x0 + x1 ≤ x2) : x0 + x1 < 2 ^ 32 := by omega theorem omS404 {x0 x1 : ℕ} (h0 : x0 + 0 = x1) : ¬x0 < x1 := by subst_vars; simp theorem omS405 {x0 x1 x2 : ℕ} (h0 : x0 = x2) (h1 : x2 ≤ x1) : x0 < x1 + 1 := by subst_vars; simp at *; omega theorem omS406 {x0 x1 x2 x3 : ℕ} (h0 : x2 = x1) (h1 : x0 + (x3 + 1) = x2) : x0 < x1 := by subst_vars; simp theorem omS407 {x0 x1 : ℕ} (h0 : ¬x0 = x1) (h1 : ¬x0 < x1) : x0 - x1 = x0 - x1 - 1 + 1 := by omega theorem omS408 {x0 x1 x2 : ℕ} (h0 : x1 < 2 ^ 32) (h1 : x2 + x0 ≤ x1) : x0 < 2 ^ 32 := by omega theorem omS409 {x0 x1 x2 : ℕ} (h0 : x0 = x1 + x2) : x0 + 1 = x1 + (x2 + 1) := by subst_vars; rfl theorem omS410 {x0 : ℕ} {x1 : ℕ} {x2 : ℕ} {x3 : Prop} {x4 : Prop} (h0 : x0 - x1 = x2) (h1 : x1 < x0 ∧ x3 ∧ x4) : x0 - (x1 + (8 : ℕ)) < x2 := by subst_vars; omega theorem omS411 {x0 x1 : ℕ} (h0 : x1 - x0 = 0) : ¬x0 < x1 := by omega theorem omS412 {x0 x1 x2 : ℕ} (h0 : x1 - x0 = x2 + 1) : x0 < x1 := by omega theorem omS413 {x0 x1 x2 : ℕ} (h0 : x0 - x1 = x2 + 1) : x0 - (x1 + 1) = x2 := by omega theorem omS414 {x0 x1 x2 x3 : ℕ} (h0 : x1 = x3) (h1 : x2 = x3) (h2 : x0 ≤ x3) : x0 ≤ x1 ∧ x0 ≤ x2 := by subst_vars; simp at *; omega theorem omS415 {x0 x1 x2 x3 : ℕ} (h0 : x2 + x3 ≤ x1) (h1 : x0 = x2 + x3) : x0 ≤ x1 := by subst_vars; omega theorem omS416 {x0 x1 x2 : ℕ} (h0 : ¬x0 < x1) (h1 : x0 < x1 + x2) : x0 - x1 < x2 := by omega theorem omS417 {x0 x1 : ℕ} (h0 : x0 = x1) : x0 < x1 + 1 := by subst_vars; simp theorem omS418 {x0 x1 : ℕ} (h0 : x0 < x1) : x0 < x1 + 1 := by omega theorem omS419 {x0 x1 : ℕ} (h0 : ¬x0 = x1) (h1 : ¬x0 < x1) : ¬x0 < x1 + 1 := by omega theorem omS420 {x0 x1 x2 x3 x4 : ℕ} (h0 : x2 ≤ x3) (h1 : x3 < 2 ^ 32) (h2 : x0 + x1 + x4 + x1 ≤ x2) : x0 + x1 < 2 ^ 32 := by omega theorem omS421 {x0 x1 x2 x3 x4 : ℕ} (h0 : x4 ≤ x3) (h1 : x0 + x1 + x2 + x1 ≤ x4) : x0 + x1 + x2 ≤ x3 := by omega theorem omS422 {x0 x1 : ℕ} (h0 : x0 + 7 ≤ x1) : x0 ≤ x1 := by omega theorem omS423 {x0 x1 x2 : ℕ} (h0 : x2 + 7 ≤ x1) (h1 : x0 < x2) : x0 < x1 := by omega theorem omS424 {x0 : ℕ} (h0 : 0 < x0) : x0 ≠ 0 := by omega theorem omS425 {x0 : ℕ} : x0 - x0 / 2 ^ 39 * 2 ^ 39 = x0 % 2 ^ 39 := by omega theorem omS426 {x0 : ℤ} (h0 : (-148 : ℤ) ≤ x0 + (39 : ℤ)) : Max.max (↑(62 : ℕ) + (1 : ℤ) + x0 - (24 : ℤ)) (-149 : ℤ) = x0 + (39 : ℤ) := by subst_vars; simp at *; omega theorem omS427 {x0 : ℤ} (h0 : x0 ≤ (104 : ℤ)) : x0 + (150 : ℤ) ≤ (254 : ℤ) := by omega theorem omS429 {x0 : ℤ} : x0 ≤ x0 + (39 : ℤ) := by subst_vars; simp theorem omS430 {x0 : ℤ} : (x0 + (39 : ℤ) - x0).toNat = (39 : ℕ) := by subst_vars; simp theorem omS431 {x0 : ℤ} (h0 : (-148 : ℤ) ≤ x0 + (39 : ℤ)) : (-126 : ℤ) ≤ x0 + (39 : ℤ) + (23 : ℤ) := by omega theorem omS432 {x0 : ℤ} : x0 + (39 : ℤ) + (23 : ℤ) - (23 : ℤ) = x0 + (39 : ℤ) := by subst_vars; simp theorem omS433 {x0 : ℤ} : x0 + (39 : ℤ) + (23 : ℤ) + (1 : ℤ) - (23 : ℤ) = x0 + (40 : ℤ) := by ring theorem omS434 {x0 : ℤ} (h0 : (-148 : ℤ) ≤ x0 + (39 : ℤ)) : (-149 : ℤ) ≤ x0 + (40 : ℤ) := by omega theorem omS435 {x0 : ℤ} (h0 : x0 + (39 : ℤ) + (150 : ℤ) ≤ (253 : ℤ)) : x0 + (40 : ℤ) ≤ (104 : ℤ) := by omega theorem omS436 {x0 : ℤ} (h0 : (-148 : ℤ) ≤ x0 + (39 : ℤ)) : (x0 + (40 : ℤ) + (150 : ℤ)).toNat = (x0 + (39 : ℤ) + (149 : ℤ)).toNat + (2 : ℕ) := by omega theorem omS437 {x0 : ℤ} : ((x0 + (39 : ℤ) + (149 : ℤ)).toNat + (2 : ℕ)) * (2 : ℕ) ^ (23 : ℕ) + (2 : ℕ) ^ (23 : ℕ) % (2 : ℕ) ^ (23 : ℕ) = (x0 + (39 : ℤ) + (149 : ℤ)).toNat * (2 : ℕ) ^ (23 : ℕ) + (2 : ℕ) ^ (24 : ℕ) := by omega theorem omS438 {x0 : ℕ} (h0 : x0 ≤ 2 ^ 24) (h1 : ¬x0 = 2 ^ 24) : x0 < 2 ^ 24 := by omega theorem omS439 {x0 : ℤ} (h0 : (-148 : ℤ) ≤ x0 + (39 : ℤ)) : (-149 : ℤ) ≤ x0 + (39 : ℤ) := by subst_vars; exact le_of_lt ‹_› theorem omS440 {x0 : ℤ} (h0 : x0 + (39 : ℤ) + (150 : ℤ) ≤ (253 : ℤ)) : x0 + (39 : ℤ) ≤ (104 : ℤ) := by omega theorem omS441 {x0 : ℤ} (h0 : (-148 : ℤ) ≤ x0 + (39 : ℤ)) : (x0 + (39 : ℤ) + (150 : ℤ)).toNat = (x0 + (39 : ℤ) + (149 : ℤ)).toNat + (1 : ℕ) := by omega theorem omS442 {x0 : ℤ} {x1 : ℕ} (h0 : (2 : ℕ) ^ (23 : ℕ) ≤ x1) (h1 : x1 ≤ (2 : ℕ) ^ (24 : ℕ)) (h2 : ¬x1 = (2 : ℕ) ^ (24 : ℕ)) : ((x0 + (39 : ℤ) + (149 : ℤ)).toNat + (1 : ℕ)) * (2 : ℕ) ^ (23 : ℕ) + x1 % (2 : ℕ) ^ (23 : ℕ) = (x0 + (39 : ℤ) + (149 : ℤ)).toNat * (2 : ℕ) ^ (23 : ℕ) + x1 := by omega theorem omS452 {x0 : ℕ} (h0 : x0 < 2 ^ 32) (h1 : 0 = x0 % 2147483648) : x0 = 0 ∨ x0 = 2147483648 := by omega theorem omS453 {x0 x1 : ℕ} (h0 : x1 % 2 ^ 31 = 0 ∨ 2 ^ 23 ≤ x1 % 2 ^ 31 ∧ x1 % 2 ^ 31 < 2139095040) (h1 : x1 % 2 ^ 31 ≠ 0) (h2 : x0 = x1 / 2 ^ 23 % 2 ^ 8) : 1 ≤ x0 := by subst_vars; omega theorem omS454 {x0 x1 : ℕ} (h0 : x1 % 2 ^ 31 = 0 ∨ 2 ^ 23 ≤ x1 % 2 ^ 31 ∧ x1 % 2 ^ 31 < 2139095040) (h1 : x0 = x1 / 2 ^ 23 % 2 ^ 8) : x0 ≤ 254 := by subst_vars; omega theorem omS455 {x0 x1 : ℕ} (h0 : x0 = x1 % 2 ^ 23) : x0 < 2 ^ 23 := by subst_vars; omega theorem omS456 {x0 x1 : ℕ} (h0 : x0 = x1 % 2 ^ 23) : x0 + 8388608 < 2 ^ 32 := by subst_vars; omega theorem omS457 {x0 : ℕ} : x0 + 8388608 = 2 ^ 23 + x0 := by omega theorem omS458 {x0 x1 : ℕ} (h0 : x0 = x1 % 2 ^ 23) : 2 ^ 23 + x0 ≤ 2 ^ 24 := by subst_vars; omega theorem omS459 {x0 x1 : ℕ} (h0 : x0 = x1 % 2 ^ 23) : 2 ^ 23 + x0 ≤ 2 ^ 24 - 1 := by subst_vars; omega theorem omS460 {x0 : ℕ} {x1 : ℕ} (h0 : x1 ≤ x0) : ↑x0 - (150 : ℤ) = ↑(x0 - x1) + (↑x1 - (150 : ℤ)) := by simp_all theorem omS461 {x0 x1 : ℕ} (h0 : x1 = 2 ^ 61 - 1) (h1 : x0 < 2 ^ 61) : x0 ≤ x1 := by subst_vars; omega theorem omS462 {x0 x1 x2 x3 : ℕ} (h0 : x2 + x3 < 2 ^ 63) (h1 : x0 ≤ x2) (h2 : x1 < 2 ^ 61) : x0 + x1 < 2 ^ 64 := by omega theorem omS463 {x0 x1 x2 x3 : ℕ} (h0 : x3 = 2 ^ 61 - 1) (h1 : x0 ≤ x2) (h2 : x1 < 2 ^ 61) : x0 + x1 ≤ x2 + x3 := by subst_vars; omega theorem omS464 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x1) : x0 ≤ x1 + x2 := by omega theorem omS465 {x0 x1 x2 : ℕ} (h0 : x1 < x2) (h1 : x0 = x2 - x1) : x0 ≠ 0 := by subst_vars; omega theorem omS466 {x0 x1 x2 : ℕ} (h0 : x1 < 2 ^ 63) (h1 : x0 = x1 - x2) : x0 < 2 ^ 63 := by subst_vars; omega theorem omS467 {x0 x1 x2 : ℕ} (h0 : x1 ≠ x2) (h1 : x2 ≤ x1) (h2 : x0 = x1 - x2) : x0 ≠ 0 := by subst_vars; omega theorem omS468 {x0 x1 : ℕ} (h0 : x0 ≤ 255) (h1 : x1 ≤ 62) : x0 + x1 < 2 ^ 64 := by omega theorem omS469 {x0 x1 : ℕ} (h0 : ¬x0 + x1 ≤ Ѧ(24 : UInt64)) (h1 : Ѧ(24 : UInt64) = 24) : 24 < x0 + x1 := by subst_vars; simp at *; omega theorem omS470 {x0 x1 : ℕ} (h0 : ¬Ѧ(277 : UInt64) ≤ x0 + x1) (h1 : Ѧ(277 : UInt64) = 277) : x0 + x1 < 277 := by subst_vars; simp at *; omega theorem omS471 {x0 x1 x2 x3 x4 : ℕ} (h0 : x0 < 2 ^ 64) (h1 : (x0 + 2) % 2 ^ 64 = x1 + x4) (h2 : (2 ^ 64 - 2 + x0) % 2 ^ 64 = x1 + x2) (h3 : x3 < x4 + 2 ^ 28) (h4 : x4 ≤ x3 + 2 ^ 28) (h5 : x3 < x2 + 2 ^ 28) (h6 : x2 ≤ x3 + 2 ^ 28) : x0 = x1 + (x2 + 2) ∧ x3 + 2 < x2 + 2 + 2 ^ 28 ∧ x2 + 2 + 2 ≤ x3 + 2 ^ 28 := by omega theorem omS472 {x0 x1 x2 : ℕ} (h0 : x2 + x1 + 2 < x2 + x0 + 2 ^ 28) (h1 : x2 + x0 + 2 ≤ x2 + x1 + 2 ^ 28) : x0 + 2 ≤ x1 + 2 ^ 28 ∧ x1 + 2 < x0 + 2 ^ 28 := by omega theorem omS473 {x0 x1 x2 x3 : ℕ} (h0 : x2 < 2 ^ 23) (h1 : x3 < 2 ^ 52) (h2 : (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 < x0 * 2 ^ 52 + x3 + 2 ^ 28) (h3 : x0 * 2 ^ 52 + x3 + 2 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 = x1 ∨ x0 + 1 = x1 ∧ x2 = 0 := by omega theorem omS474 {x0 : ℕ} {x1 : ℕ} {x2 : ℕ} {x3 : ℕ} (h0 : (897 : ℕ) ≤ x1) (h1 : x2 < (2 : ℕ) ^ (52 : ℕ)) (h2 : (x1 * (2 : ℕ) ^ (23 : ℕ) + x3) * (2 : ℕ) ^ (29 : ℕ) + (2 : ℕ) < x0 * (2 : ℕ) ^ (52 : ℕ) + x2 + (2 : ℕ) ^ (28 : ℕ)) : (-1021 : ℤ) ≤ ↑x0 - (1075 : ℤ) := by omega theorem omS475 {x0 x1 : ℕ} (h0 : ((x1 + 1) * 2 ^ 23 + 0) * 2 ^ 29 + 2 < x1 * 2 ^ 52 + x0 + 2 ^ 28) : 2 ^ 52 + 2 < x0 + 2 ^ 28 := by omega theorem omS476 {x0 x1 x2 x3 : ℕ} (h0 : 897 ≤ x1) (h1 : x2 < 2 ^ 52) (h2 : (x1 * 2 ^ 23 + x3) * 2 ^ 29 + 2 < x0 * 2 ^ 52 + x2 + 2 ^ 28) : 1 ≤ x0 := by omega theorem omS477 {x0 x1 x2 x3 : ℕ} (h0 : x1 < 1151) (h1 : x2 < 2 ^ 23) (h2 : x0 * 2 ^ 52 + x3 + 2 ≤ (x1 * 2 ^ 23 + x2) * 2 ^ 29 + 2 ^ 28) : x0 < 2047 := by omega theorem omS478 {x0 x1 x2 x3 : ℕ} (h0 : (x0 * 2 ^ 23 + x1) * 2 ^ 29 + 2 < x2 * 2 ^ 52 + x3 + 2 ^ 28) : (x0 * 2 ^ 23 + x1) * 2 ^ 29 + 2 < x2 * 2 ^ 52 + x3 + 2 ^ 28 := by omega theorem omS479 {x0 x1 x2 x3 : ℕ} (h0 : x0 * 2 ^ 52 + x1 + 2 ≤ (x2 * 2 ^ 23 + x3) * 2 ^ 29 + 2 ^ 28) : x0 * 2 ^ 52 + x1 + 2 ≤ (x2 * 2 ^ 23 + x3) * 2 ^ 29 + 2 ^ 28 := by omega theorem omS480 {x0 : ℕ} : (-160 : ℤ) ≤ ↑(x0 % (2 : ℕ) ^ (31 : ℕ) / (2 : ℕ) ^ (23 : ℕ)) - (150 : ℤ) := by omega theorem omS481 {x0 : ℕ} : 2 ^ 23 + x0 % 2 ^ 31 % 2 ^ 23 < 2 ^ 25 := by omega theorem omS482 {x0 : ℤ} {x1 : ℤ} (h0 : (-160 : ℤ) ≤ x0) (h1 : (-160 : ℤ) ≤ x1) : (-1074 : ℤ) ≤ x0 + x1 := by omega theorem omS483 {x0 x1 x2 : ℕ} (h0 : x0 + 0 = x2) : ¬(x0 ≤ x1 ∧ x1 < x2) := by subst_vars; simp theorem omS484 {x0 x1 x2 : ℕ} (h0 : x0 ≤ x2) (h1 : x1 = x2) : x0 ≤ x1 := by subst_vars; omega theorem omS485 {x0 x1 : ℕ} : ¬(x0 + 1 ≤ x0 ∧ x0 < x1) := by subst_vars; simp theorem omS486 {x0 x1 x2 : ℕ} (h0 : x0 + (x2 + 1) = x1) : x0 ≤ x0 ∧ x0 < x1 := by subst_vars; simp theorem omS487 {x0 x1 x2 : ℕ} (h0 : ¬x1 = x0) : x0 + 1 ≤ x1 ∧ x1 < x2 ↔ x0 ≤ x1 ∧ x1 < x2 := by subst_vars; simp at *; omega theorem omS488 {x0 : ℕ} (h0 : ¬x0 / 2 ^ 23 % 256 = 0 ∧ ¬x0 / 2 ^ 23 % 256 = 255) : 8388608 ≤ x0 % 2 ^ 31 := by omega theorem omS489 {x0 : ℕ} (h0 : ¬x0 / 2 ^ 23 % 256 = 0 ∧ ¬x0 / 2 ^ 23 % 256 = 255) : x0 % 2 ^ 31 < 2139095040 := by omega theorem omS490 {x0 x1 : ℕ} (h0 : x0 + 2 < x1 + 2 ^ 28) (h1 : x1 + 2 ≤ x0 + 2 ^ 28) : x0 < x1 + 2 ^ 28 ∧ x1 ≤ x0 + 2 ^ 28 := by omega theorem omS491 {x0 : ℕ} : ¬x0 < x0 + 0 := by subst_vars; simp theorem omS492 {x0 x1 x2 : ℕ} (h0 : x0 + (x2 + 1) = x1) : x0 + 1 ≤ x1 := by subst_vars; simp theorem omS493 {x0 x1 x2 : ℕ} (h0 : x1 = x2) (h1 : x1 < 2 ^ 32) (h2 : x0 ≤ x2) : x0 < 2 ^ 32 := by subst_vars; omega theorem omS494 {x0 x1 x2 x3 x4 : ℕ} (h0 : x1 = x2) (h1 : x1 < 2 ^ 32) (h2 : x3 ≤ x2) (h3 : x3 = x0 + x4) : x0 < 2 ^ 32 := by subst_vars; omega structure OS where (cin h w cout kh kw stride pad:Nat) def OS.ho (s:OS):Nat:=(s.h+2*s.pad-s.kh)/s.stride+1 def OS.wo (s:OS):Nat:=(s.w+2*s.pad-s.kw)/s.stride+1 @[inline] def windowAtO (s:OS) (inp:Array Word) (y x t:Nat):Word := let c:=t/(s.kh*s.kw) let dy:=t/s.kw%s.kh let dx:=t%s.kw let yy:=y*s.stride+dy let xx:=x*s.stride+dx if yy< s.pad∨xx< s.pad∨yy-s.pad≥s.h∨xx-s.pad≥s.w then 0 else inp[(c*s.h+(yy-s.pad))*s.w+(xx-s.pad)]! @[specialize] def conv2dWithO (dot:DotFn) (s:OS) (relu:Bool) (inp wts b:Array Word):Array Word := let k:=s.cin*s.kh*s.kw Array.ofFn (n:=s.cout*(s.ho*s.wo)) fun q => let o:=q.val/(s.ho*s.wo) let y:=q.val/s.wo%s.ho let x:=q.val%s.wo act relu <| dot (k+1) (fun t=>if t< k then windowAtO s inp y x t else oneW) (fun t=>if t< k then wts[o*k+t]! else b[o]!) def conv2dSpecO:=conv2dWithO dotOf @[specialize] def depthwiseWithO (dot:DotFn) (s:OS) (relu:Bool) (inp wts b:Array Word):Array Word := let k:=s.kh*s.kw Array.ofFn (n:=s.cin*(s.ho*s.wo)) fun q => let c:=q.val/(s.ho*s.wo) let y:=q.val/s.wo%s.ho let x:=q.val%s.wo act relu <| dot (k+1) (fun t=>if t< k then windowAtO s inp y x (c*k+t) else oneW) (fun t=>if t< k then wts[c*k+t]! else b[c]!) def depthwiseSpecO:=depthwiseWithO dotOf @[inline] def poolAtO (h w k:Nat) (inp:Array Word) (ch y x t:Nat):Word := inp[(ch*h+y*k+t/k)*w+x*k+t%k]! @[specialize] def avgpoolWithO (dot:DotFn) (c h w k:Nat) (inp:Array Word):Array Word := Array.ofFn (n:=c*(h/k*(w/k))) fun q => let ch:=q.val/(h/k*(w/k)) let y:=q.val/(w/k)%(h/k) let x:=q.val%(w/k) let s:=dot (k*k) (poolAtO h w k inp ch y x) (fun _=>oneW) toWord (Model.div (ofW s) (ofW (natW (k*k)))) def avgpoolSpecO:=avgpoolWithO dotOf def maxpoolSpecO (c h w k:Nat) (inp:Array Word):Array Word := Array.ofFn (n:=c*(h/k*(w/k))) fun q => let ch:=q.val/(h/k*(w/k)) let y:=q.val/(w/k)%(h/k) let x:=q.val%(w/k) toWord <| (List.range (k*k)).foldl (fun acc t=> Model.maximum acc (ofW (poolAtO h w k inp ch y x t))) (ofW (poolAtO h w k inp ch y x 0)) namespace C theorem zw_mant {w:UInt32} (h:w &&& 0x7FFFFFFF = 0) : mantOf w = 0 := by have h1 : (w &&& 0x7FFFFFFF).toNat = 0 := by rw [h]; rfl rw [UInt32.toNat_and] at h1 have h3 : (0x7FFFFFFF:UInt32).toNat = 2^31-1 := rfl rw [h3, Nat.and_two_pow_sub_one_eq_mod] at h1 have hl := w.toNat_lt unfold mantOf expOf fracOf have he : (w >>> 23) &&& 0xFF = 0 := by apply UInt32.toNat_inj.mp rw [UInt32.toNat_and, UInt32.toNat_shiftRight] have h3 : (0xFF:UInt32).toNat = 2^8-1 := rfl have h4 : (23:UInt32).toNat % 32 = 23 := rfl rw [h3, h4, Nat.and_two_pow_sub_one_eq_mod, Nat.shiftRight_eq_div_pow] show _ = 0 omega rw [ite_eq_left he] rw [UInt32.toNat_and] have h5 : (0x7FFFFF:UInt32).toNat = 2^23-1 := rfl rw [h5, Nat.and_two_pow_sub_one_eq_mod] omega /-- first column `≥ i` (within `n` more) holding a nonzero word, or `i+n` -/ def xLo (X:Array UInt32) (base i:Nat) : Nat → Nat | 0 => i | n+1 => if X[base+i]! &&& 0x7FFFFFFF == 0 then xLo X base (i+1) n else i /-- one past the last column `< n` holding a nonzero word, or `0` -/ def xHi (X:Array UInt32) (base:Nat) : Nat → Nat | 0 => 0 | n+1 => if X[base+n]! &&& 0x7FFFFFFF == 0 then xHi X base n else n+1 theorem xLo_spec (X:Array UInt32) (base:Nat) : ∀ n i xx, i ≤ xx → xx < xLo X base i n → mantOf X[base+xx]! = 0 := by intro n induction n with | zero => intro i xx h1 h2; simp only [xLo] at h2; omega | succ n ih => intro i xx h1 h2 simp only [xLo] at h2 split at h2 · rename_i hz by_cases hx : xx = i · subst hx; exact zw_mant (by simpa using hz) · exact ih (i+1) xx (by omega) h2 · omega theorem xLo_le (X:Array UInt32) (base:Nat) : ∀ n i, xLo X base i n ≤ i+n := by intro n induction n with | zero => intro i; simp [xLo] | succ n ih => intro i; simp only [xLo]; split · have := ih (i+1); omega · omega theorem xHi_spec (X:Array UInt32) (base:Nat) : ∀ n xx, xHi X base n ≤ xx → xx < n → mantOf X[base+xx]! = 0 := by intro n induction n with | zero => intro xx _ h2; omega | succ n ih => intro xx h1 h2 simp only [xHi] at h1 split at h1 · rename_i hz by_cases hx : xx = n · subst hx; exact zw_mant (by simpa using hz) · exact ih xx h1 (by omega) · omega theorem xHi_le (X:Array UInt32) (base:Nat) : ∀ n, xHi X base n ≤ n := by intro n induction n with | zero => simp [xHi] | succ n ih => simp only [xHi]; split <;> omega theorem push2_getD (a:Array Nat) (u v j:Nat) : ((a.push u).push v).getD j 0 = if j < a.size then a.getD j 0 else if j = a.size then u else if j = a.size+1 then v else 0 := by simp only [Array.getD, Array.size_push] by_cases h1 : j < a.size · rw [dite_eq_left (by omega), ite_eq_left h1, dite_eq_left h1]; simp [Array.getElem_push, h1, show j < a.size + 1 by omega] · rw [ite_eq_right h1] by_cases h2 : j = a.size · subst h2; rw [dite_eq_left (by omega), ite_eq_left rfl]; simp [Array.getElem_push] · rw [ite_eq_right h2] by_cases h3 : j = a.size+1 · subst h3; rw [dite_eq_left (by omega), ite_eq_left rfl]; simp [Array.getElem_push] · rw [ite_eq_right h3, dite_eq_right (by omega)] /-- Pixel `(c, yy, xx)` of the zero-padded input is a zero word (or padding). -/ @[inline] def pixZ (s:OS) (X:Array UInt32) (c yy xx:Nat) : Bool := decide (yy < s.pad) || decide (xx < s.pad) || decide (s.h ≤ yy - s.pad) || decide (s.w ≤ xx - s.pad) || mantOf X[(c*s.h+(yy-s.pad))*s.w+(xx-s.pad)]! == 0 /-- padded-column bounds `(L, G)` of the nonzero words of input row `r` (width `w`): columns `< L` and `≥ w+2pad-G` are zero words or padding; an all-zero row gives `(w+2pad, w+2pad)` -/ @[inline] def rowE (X:Array UInt32) (w pad r:Nat) : Nat × Nat := let lo:=xLo X (r*w) 0 w if lo = w then (w+2*pad, w+2*pad) else (pad+lo, w+pad-xHi X (r*w) w) def rowsE (X:Array UInt32) (w pad:Nat) (r:Nat) : Nat → Array Nat → Array Nat | 0, a => a | n+1, a => let p:=rowE X w pad r; rowsE X w pad (r+1) n ((a.push p.1).push p.2) /-- hull of the row bounds over the padded rows `y0+i ..` of channel `c` -/ def hullE (s:OS) (RE:Array Nat) (c y0:Nat) (i:Nat) (L G:Nat) : Nat → Nat × Nat | 0 => (L, G) | n+1 => if y0+i < s.pad ∨ s.h ≤ y0+i-s.pad then hullE s RE c y0 (i+1) L G n else hullE s RE c y0 (i+1) (min L (RE.getD (2*(c*s.h+(y0+i-s.pad))) 0)) (min G (RE.getD (2*(c*s.h+(y0+i-s.pad))+1) 0)) n /-- per output row `y` (per channel if `dw`, merged otherwise): entries `2j, 2j+1` with `j = c*ho+y` -/ def Sound3 (s:OS) (X:Array UInt32) (dw:Bool) (ho:Nat) (e:Array Nat) : Prop := ∀ c y xx i, c < s.cin → y < ho → i < s.kh → (xx < e.getD (2*((if dw then c else 0)*ho+y)) 0 ∨ s.w+2*s.pad-e.getD (2*((if dw then c else 0)*ho+y)+1) 0 ≤ xx) → pixZ s X c (y*s.stride+i) xx = true def ex3G (s:OS) (RE:Array Nat) (ho:Nat) (c y:Nat) : Nat → Array Nat → Array Nat | 0, a => a | n+1, a => let p:=hullE s RE c (y*s.stride) 0 (s.w+2*s.pad) (s.w+2*s.pad) s.kh ex3G s RE ho c (y+1) n ((a.push p.1).push p.2) def ex3D (s:OS) (RE:Array Nat) (ho:Nat) (c:Nat) : Nat → Array Nat → Array Nat | 0, a => a | n+1, a => ex3D s RE ho (c+1) n (ex3G s RE ho c 0 ho a) theorem pixZ_pad (s:OS) (X:Array UInt32) (c yy xx:Nat) (h:s.w+2*s.pad ≤ xx) : pixZ s X c yy xx = true := by unfold pixZ; simp only [Bool.or_eq_true, decide_eq_true_eq]; exact Or.inl (Or.inr (by omega)) /-- row bounds soundness for rows `< R` -/ def RowOk (X:Array UInt32) (w pad R:Nat) (e:Array Nat) : Prop := ∀ r xx, r < R → (xx < e.getD (2*r) 0 ∨ w+2*pad-e.getD (2*r+1) 0 ≤ xx) → xx < pad ∨ w ≤ xx-pad ∨ mantOf X[r*w+(xx-pad)]! = 0 theorem rowE_ok (X:Array UInt32) (w pad r xx:Nat) (h:xx < (rowE X w pad r).1 ∨ w+2*pad-(rowE X w pad r).2 ≤ xx) : xx < pad ∨ w ≤ xx-pad ∨ mantOf X[r*w+(xx-pad)]! = 0 := by by_cases q1 : xx < pad · exact Or.inl q1 by_cases q2 : w ≤ xx-pad · exact Or.inr (Or.inl q2) refine Or.inr (Or.inr ?_) by_cases hl : xLo X (r*w) 0 w = w · simp only [rowE, hl, ↓reduceIte] at h exact xLo_spec X _ w 0 (xx-pad) (Nat.zero_le _) (by omega) · simp only [rowE, hl, ↓reduceIte] at h have hhl := xHi_le X (r*w) w rcases h with h | h · exact xLo_spec X _ w 0 (xx-pad) (Nat.zero_le _) (by omega) · exact xHi_spec X _ w (xx-pad) (by omega) (by omega) theorem rowsE_spec (X:Array UInt32) (w pad:Nat) : ∀ n r (a:Array Nat), a.size = 2*r → (rowsE X w pad r n a).size = 2*(r+n) ∧ (∀ j, j < a.size → (rowsE X w pad r n a).getD j 0 = a.getD j 0) ∧ ∀ r' xx, r ≤ r' → r' < r+n → (xx < (rowsE X w pad r n a).getD (2*r') 0 ∨ w+2*pad-(rowsE X w pad r n a).getD (2*r'+1) 0 ≤ xx) → xx < pad ∨ w ≤ xx-pad ∨ mantOf X[r'*w+(xx-pad)]! = 0 := by intro n induction n with | zero => intro r a hs; simp only [rowsE]; exact ⟨by omega, fun _ _ => by simp, fun r' _ h1 h2 => by omega⟩ | succ n ih => intro r a hs simp only [rowsE] have hs2 : ((a.push (rowE X w pad r).1).push (rowE X w pad r).2).size = 2*(r+1) := by simp; omega obtain ⟨a1, a2, a3⟩ := ih (r+1) _ hs2 refine ⟨by rw [a1]; omega, fun j hj => ?_, fun r' xx h1 h2 h3 => ?_⟩ · rw [a2 j (by simp; omega), push2_getD, ite_eq_left (by omega)] · by_cases hr : r' = r · subst hr rw [a2 _ (by simp; omega), a2 _ (by simp; omega), push2_getD, push2_getD] at h3 rw [ite_eq_right (by omega), ite_eq_left (by omega)] at h3 rw [ite_eq_right (by omega), ite_eq_right (by omega), ite_eq_left (by omega)] at h3 exact rowE_ok X w pad r' xx h3 · exact a3 r' xx (by omega) (by omega) h3 theorem hullE_spec (s:OS) (X:Array UInt32) (RE:Array Nat) (hR:RowOk X s.w s.pad (s.cin*s.h) RE) (c y0:Nat) (hc:c< s.cin) : ∀ n i L G, (hullE s RE c y0 i L G n).1 ≤ L ∧ (hullE s RE c y0 i L G n).2 ≤ G ∧ ∀ i' xx, i ≤ i' → i' < i+n → (xx < (hullE s RE c y0 i L G n).1 ∨ s.w+2*s.pad-(hullE s RE c y0 i L G n).2 ≤ xx) → pixZ s X c (y0+i') xx = true := by intro n induction n with | zero => intro i L G; simp only [hullE]; exact ⟨Nat.le_refl _, Nat.le_refl _, fun i' xx h1 h2 _ => by omega⟩ | succ n ih => intro i L G simp only [hullE] split · rename_i hp obtain ⟨a1, a2, a3⟩ := ih (i+1) L G refine ⟨a1, a2, fun i' xx h1 h2 h3 => ?_⟩ by_cases hi : i' = i · subst hi; unfold pixZ; simp only [Bool.or_eq_true, decide_eq_true_eq] rcases hp with hp | hp · exact Or.inl (Or.inl (Or.inl (Or.inl hp))) · exact Or.inl (Or.inl (Or.inr hp)) · exact a3 i' xx (by omega) (by omega) h3 · rename_i hp obtain ⟨a1, a2, a3⟩ := ih (i+1) (min L (RE.getD (2*(c*s.h+(y0+i-s.pad))) 0)) (min G (RE.getD (2*(c*s.h+(y0+i-s.pad))+1) 0)) refine ⟨Nat.le_trans a1 (Nat.min_le_left _ _), Nat.le_trans a2 (Nat.min_le_left _ _), fun i' xx h1 h2 h3 => ?_⟩ by_cases hi : i' = i · subst hi have hm1 := Nat.min_le_right L (RE.getD (2*(c*s.h+(y0+i'-s.pad))) 0) have hm2 := Nat.min_le_right G (RE.getD (2*(c*s.h+(y0+i'-s.pad))+1) 0) have hrow : c*s.h+(y0+i'-s.pad) < s.cin*s.h := by have : (c+1)*s.h ≤ s.cin*s.h := Nat.mul_le_mul_right _ (by omega) rw [Nat.add_mul, Nat.one_mul] at this; omega have r := hR _ xx hrow (h3.imp (fun h => by omega) (fun h => by omega)) unfold pixZ; simp only [Bool.or_eq_true, decide_eq_true_eq, beq_iff_eq] rcases r with r | r | r · exact Or.inl (Or.inl (Or.inl (Or.inr r))) · exact Or.inl (Or.inr r) · exact Or.inr r · exact a3 i' xx (by omega) (by omega) h3 theorem ex3G_spec (s:OS) (X:Array UInt32) (RE:Array Nat) (hR:RowOk X s.w s.pad (s.cin*s.h) RE) (ho c:Nat) (hc:c< s.cin) : ∀ n y (a:Array Nat), a.size = 2*(c*ho+y) → y+n ≤ ho → (ex3G s RE ho c y n a).size = 2*(c*ho+y+n) ∧ (∀ j, j < a.size → (ex3G s RE ho c y n a).getD j 0 = a.getD j 0) ∧ ∀ y' xx i, y ≤ y' → y' < y+n → i < s.kh → (xx < (ex3G s RE ho c y n a).getD (2*(c*ho+y')) 0 ∨ s.w+2*s.pad-(ex3G s RE ho c y n a).getD (2*(c*ho+y')+1) 0 ≤ xx) → pixZ s X c (y'*s.stride+i) xx = true := by intro n induction n with | zero => intro y a hs _; simp only [ex3G]; exact ⟨by omega, fun _ _ => by simp, fun y' _ _ h1 h2 => by omega⟩ | succ n ih => intro y a hs hy simp only [ex3G] have hs2 : ((a.push (hullE s RE c (y*s.stride) 0 (s.w+2*s.pad) (s.w+2*s.pad) s.kh).1).push (hullE s RE c (y*s.stride) 0 (s.w+2*s.pad) (s.w+2*s.pad) s.kh).2).size = 2*(c*ho+(y+1)) := by simp; omega obtain ⟨a1, a2, a3⟩ := ih (y+1) _ hs2 (by omega) obtain ⟨b1, b2, b3⟩ := hullE_spec s X RE hR c (y*s.stride) hc s.kh 0 (s.w+2*s.pad) (s.w+2*s.pad) refine ⟨by rw [a1]; omega, fun j hj => ?_, fun y' xx i h1 h2 h4 h3 => ?_⟩ · rw [a2 j (by simp; omega), push2_getD, ite_eq_left (by omega)] · by_cases hy' : y' = y · subst hy' rw [a2 _ (by simp; omega), a2 _ (by simp; omega), push2_getD, push2_getD] at h3 rw [ite_eq_right (by omega), ite_eq_left (by omega)] at h3 rw [ite_eq_right (by omega), ite_eq_right (by omega), ite_eq_left (by omega)] at h3 exact b3 i xx (Nat.zero_le _) (by omega) h3 · exact a3 y' xx i (by omega) (by omega) h4 h3 theorem ex3D_spec (s:OS) (X:Array UInt32) (RE:Array Nat) (hR:RowOk X s.w s.pad (s.cin*s.h) RE) (ho:Nat) : ∀ n c (a:Array Nat), a.size = 2*(c*ho) → c+n ≤ s.cin → (ex3D s RE ho c n a).size = 2*((c+n)*ho) ∧ (∀ j, j < a.size → (ex3D s RE ho c n a).getD j 0 = a.getD j 0) ∧ ∀ c' y xx i, c ≤ c' → c' < c+n → y < ho → i < s.kh → (xx < (ex3D s RE ho c n a).getD (2*(c'*ho+y)) 0 ∨ s.w+2*s.pad-(ex3D s RE ho c n a).getD (2*(c'*ho+y)+1) 0 ≤ xx) → pixZ s X c' (y*s.stride+i) xx = true := by intro n induction n with | zero => intro c a hs _; simp only [ex3D]; exact ⟨by omega, fun _ _ => by simp, fun c' _ _ _ h1 h2 => by omega⟩ | succ n ih => intro c a hs hn simp only [ex3D] obtain ⟨b1, b2, b3⟩ := ex3G_spec s X RE hR ho c (by omega) ho 0 a (by omega) (by omega) obtain ⟨a1, a2, a3⟩ := ih (c+1) (ex3G s RE ho c 0 ho a) (by rw [b1, Nat.add_mul, Nat.one_mul]; omega) (by omega) refine ⟨by rw [a1]; congr 1; rw [show c+(n+1) = c+1+n by omega], fun j hj => ?_, fun c' y xx i h1 h2 hy hi h3 => ?_⟩ · rw [a2 j (by rw [b1]; omega), b2 j hj] · by_cases hc : c' = c · subst hc have hlt : 2*(c'*ho+y)+1 < (ex3G s RE ho c' 0 ho a).size := by rw [b1]; omega rw [a2 _ (by omega), a2 _ hlt] at h3 exact b3 y xx i (Nat.zero_le _) (by omega) hi h3 · exact a3 c' y xx i (by omega) (by omega) hy hi h3 theorem sound3_empty (s:OS) (X:Array UInt32) (dw:Bool) (ho:Nat) : Sound3 s X dw ho #[] := by intro c y xx i _ _ _ h have e : ∀ j, (#[]:Array Nat).getD j 0 = 0 := fun j => rfl rw [e, e, Nat.sub_zero] at h rcases h with h | h · omega · exact pixZ_pad s X c _ xx h theorem rowsE_ok (s:OS) (X:Array UInt32) : RowOk X s.w s.pad (s.cin*s.h) (rowsE X s.w s.pad 0 (s.cin*s.h) (Array.emptyWithCapacity (2*(s.cin*s.h)))) := by intro r xx hr h exact (rowsE_spec X s.w s.pad (s.cin*s.h) 0 _ (by simp)).2.2 r xx (Nat.zero_le _) (by omega) h @[noinline] def mkExS (s:OS) (X b:Array UInt32) (dw:Bool) (ho:Nat) : {e:Array Nat // Sound3 s X dw ho e} := if hg:(b.all (· == 0) && decide (1 < s.kh*s.kw) && (dw || s.cin == 1)) = true then ⟨ex3D s (rowsE X s.w s.pad 0 (s.cin*s.h) (Array.emptyWithCapacity (2*(s.cin*s.h)))) ho 0 s.cin (Array.emptyWithCapacity (2*(s.cin*ho))), fun c y xx i hc hy hi h => by have e : (if dw then c else 0) = c := by cases hd : dw · simp only [hd, Bool.false_or, Bool.and_eq_true, beq_iff_eq] at hg simp only [Bool.false_eq_true, ite_false]; omega · rfl rw [e] at h exact (ex3D_spec s X _ (rowsE_ok s X) ho s.cin 0 _ (by simp) (by omega)).2.2 c y xx i (Nat.zero_le _) (by omega) hy hi h⟩ else ⟨#[], sound3_empty s X dw ho⟩ structure D_Sc where (lo hi:ὥ) structure D_C where (dw relu f4:Ὡ) (s:OS) (X W b:ѐ) (k C ho wo wp:Ὣ) (step:ὦ) (hi:ὥ) (xd:ὤ) (nf:ὧ) (tab:ѐ) (ex:{e:Array Nat // Sound3 s X dw ho e}) structure D_P where (g:D_C) (wd:ὤ) (off:ѐ) (e l1 l8:ὦ) (e0 bv ze:ὧ) (he:Ѥe<=ѧoff) (hw:Ѥe<=Ѩwd) (hs:g.xd.size<2^32) (h1:∀ b:ὦ,b< l1->∀ j (h:j< ѧoff),Ѥb+off[j].toNat+0< g.xd.size) (h8:∀ b:ὦ,b< l8->∀ j (h:j< ѧoff),Ѥb+off[j].toNat+7< g.xd.size) (hz:ze=0) structure D_R where (t:UInt8) (A B C D E F G I:ὧ) structure R2 where (off:ѐ) (buf:ὤ) (c:ὦ) (l:ὧ) (m:ὥ) (hm:∀ j (h:j< ѧoff),off[j].toNat<=ѥm) structure CV where (hW hb:ὥ) (tab:ѐ) (rs:Array R2) end C namespace D open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Floats.ExecFloat.Binary open USize (toNat) open UInt32 (toNat) open UInt64 (toNat) open Array (size) open FloatArray (size) open Nat (toUSize) open UInt32 (toUSize) section open FloatLib.Numerics end structure LnS where fast:Ὡ m:ὧ ir:ὧ em:ὧ den:ὥ deriving Inhabited structure Acc where (pos neg:ї) (special negZero:Ὡ) structure F1 where (s t:ὧ) structure F4 where (a b c d:ὧ) structure G8 where (a b c d e f g k:ὧ) structure G24 where (a b c d e f g k a' b' c' d' e' f' g' k' a'' b'' c'' d'' e'' f'' g'' k'':ὧ) structure G16 where (a b c d e f g k a' b' c' d' e' f' g' k':ὧ) structure CN where (out:ѐ) (ok:Ὡ) structure F8 where (u:UInt8) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (p q:ὥ) structure H8 where (xs:ὤ) (h0 h1 h2 h3 h4 h5 h6 h7:ὧ) structure L8 where (l0 l1 l2 l3 l4 l5 l6 l7:Ὠ) lemma qAb (n:Ὣ) (f:Ὣ->ὥ) (k:Ὣ) (hk:k< n) : (Array.ofFn (n:=n) λi=>f i.val)[k]! = f k:=by rw[Ἕ _ k (by simpa using hk),Array.getElem_ofFn] lemma qEb (z:Model Fmt):ofW (toWord z)=z:=by have h:z.toNatBits<2^32:=Model.toNatBits_lt_two_pow z;simp only[ofW,toWord,Model.ofUInt32,UInt32.toNat_ofNat',Nat.mod_eq_of_lt h];exact Model.ofNatBits_toNatBits z lemma qGw {w:ὥ} (h:expOf w≠255):Ἑ (ofW w)=true:=by simp[ofW,isFinite_ofUInt32,h] lemma qEg (A B:Array UInt32) (hB:B.size=A.size) (hall:∀ k,k< A.size->expOf A[k]!≠255∧expOf B[k]!≠255) : finishWord (dsum A B 0 A.size) (-298) (decide (A.size≠0) && dallNZ A B 0 A.size)=dotSpec A B:=by set L := A.map (Model.ofUInt32 (fmt := Fmt)) with hL set R := B.map (Model.ofUInt32 (fmt := Fmt)) with hR have hLR : L.size = R.size := by simp [hL, hR, hB] have hLsize : L.size = A.size := by simp [hL] have hLfin : ∀ k (hk : k < L.size), Model.isFinite L[k] = true := by intro k hk have hk' : k < A.size := by simpa [hL] using hk have := (hall k hk').1 rw [getElem!_pos A k hk'] at this simp [hL, isFinite_ofUInt32, this] have hRfin : ∀ k (hk : k < R.size), Model.isFinite R[k] = true := by intro k hk have hk' : k < B.size := by simpa [hR] using hk have := (hall k (by omega)).2 rw [getElem!_pos B k hk'] at this simp [hR, isFinite_ofUInt32, this] have hslice : Model.Reduction.Semantics.finiteDotSlice L R 0 L.size (by simp) (by simp [hLR]) = (dsum A B 0 A.size : ℚ) * 2 ^ (-298 : ℤ) := by have := finiteDotSlice_eq A B 0 L.size (by simp [hL]) (by simp [hL, hB]) (by intro k k1 k2; exact hall k (by omega)) exact this.trans (by rw [hLsize]) have hexact := Model.Reduction.Internal.dotState_exact_toRat (destination := Fmt) L R hLR unfold dotSpec rw [← Model.Reduction.map_value_dot] by_cases hS0 : dsum A B 0 A.size = 0 · have hz0 : (Model.Reduction.Internal.dotState L R hLR : Model.Reduction.Internal.State Fmt).exact.significand = 0 := by rw [← FloatLib.Numerics.Dyadic.toRat_eq_zero_iff, hexact, hslice, hS0]; simp rw [Model.Reduction.dot_status_eq_zero_of_finite Fmt L R .nearest hLR hLfin hRfin hz0, hS0, finishWord_zero] unfold Model.Reduction.Internal.dotState obtain ⟨h1, h2⟩ := dotStateLoop_flags A B {} 0 L.size (by simp [hL]) (by simp [hL, hB]) (by intro k k1 k2; exact hall k (by omega)) have h1' : (Model.Reduction.Internal.dotStateLoop L R ({} : Model.Reduction.Internal.State Fmt) 0 L.size (by simp) (by simp [hLR])).sawFiniteTerm = decide (L.size ≠ 0) := by rw [show decide (L.size ≠ 0) = (false || decide (L.size ≠ 0)) by simp]; exact h1 have h2' : (Model.Reduction.Internal.dotStateLoop L R ({} : Model.Reduction.Internal.State Fmt) 0 L.size (by simp) (by simp [hLR])).allTermsNegativeZero = dallNZ A B 0 L.size := by rw [show dallNZ A B 0 L.size = (true && dallNZ A B 0 L.size) by simp]; exact h2 simp only [Except.map, h1', h2'] simp [hLsize] · have hnz : Model.Reduction.Semantics.finiteDot L.toList R.toList ≠ .ok 0 := by rw [Model.Reduction.Semantics.finiteDot_toList_eq_slice L R hLR] intro h injection h with h rw [hslice] at h simp at h; exact hS0 h rw [Model.Reduction.dot_status_eq_round_of_finite_nonzero Fmt L R .nearest hLR hLfin hRfin hnz] simp only [Except.map] exact finishWord_of_ne _ _ _ _ hS0 (by rw [hexact, hslice]) def Acc.total (acc:Acc):Int:=(limbVal acc.pos.toList:Int)-limbVal acc.neg.toList @[inline] def Acc.add (acc:Acc) (m idx:Ὣ) (neg:Ὡ):Acc := match acc with | ⟨pos,ng,sp,nz⟩ => if m=0 then ⟨pos,ng,sp,nz && neg⟩ else if neg then ⟨pos,addLimbs64 ng m.toUInt64 idx,sp,false⟩ else ⟨addLimbs64 pos m.toUInt64 idx,ng,sp,false⟩ lemma Acc.add_spec (acc:Acc) (m idx:Ὣ) (neg:Ὡ) (hp:acc.pos.size=18) (hn:acc.neg.size=18) (hm:m<2^64) (hi:idx/32+1<18) : (acc.add m idx neg).pos.size=18∧(acc.add m idx neg).neg.size=18 ∧ (acc.add m idx neg).special=acc.special ∧ (acc.add m idx neg).negZero=(acc.negZero && (decide (m=0) && neg)) ∧ (acc.add m idx neg).total=acc.total+(if neg then -(m:Int) else m)*2^idx:=by obtain ⟨pos,ng,sp,nz⟩:=acc;simp only at hp hn;by_cases hm0:m=0;. simp[Acc.add,Acc.total,hm0,hp,hn] . cases neg;. refine ⟨by simp[Acc.add,hm0,addLimbs64_size,hp],by simp[Acc.add,hm0,hn],by simp[Acc.add,hm0],by simp[Acc.add,hm0],?_⟩;simp only[Acc.add,hm0,ite_false,Bool.false_eq_true,addLimbs64_eq _ _ _ hm,Acc.total];rw[addLimbs_val _ _ _ (by clear hm hn hm0; exact omS3 hi hp)];push_cast;ring . refine ⟨by simp[Acc.add,hm0,hp],by simp[Acc.add,hm0,addLimbs64_size,hn],by simp[Acc.add,hm0],by simp[Acc.add,hm0],?_⟩;simp only[Acc.add,hm0,ite_false,ite_true,addLimbs64_eq _ _ _ hm,Acc.total];rw[addLimbs_val _ _ _ (by clear hm hp hm0; exact omS3 hi hn)];push_cast;ring @[inline] def dotStep (acc:Acc) (wa wb:ὥ):Acc := if expOf wa=255∨expOf wb=255 then ⟨acc.pos,acc.neg,true,acc.negZero⟩ else acc.add (mantOf wa*mantOf wb) (idxOf wa+idxOf wb) (Bool.xor (signOf wa) (signOf wb)) @[specialize] def dotLoop (fa fb:Ὣ->ὥ) (pos neg:ї) (sp nz:Ὡ) (index:Ὣ):Ὣ->Acc | 0=>⟨pos,neg,sp,nz⟩ | count+1 => match dotStep ⟨pos,neg,sp,nz⟩ (fa index) (fb index) with | ⟨p,n,s,z⟩=>dotLoop fa fb p n s z (index+1) count lemma qCb (fa fb:Ὣ->ὥ) (pos neg:ї) (nz:Ὡ) (index count:Ὣ):(dotLoop fa fb pos neg true nz index count).special=true:=by induction count generalizing pos neg nz index with | zero=>rfl | succ count ih => rw[dotLoop];have hs:(dotStep ⟨pos,neg,true,nz⟩ (fa index) (fb index)).special=true:=by unfold dotStep Acc.add;split_ifs<;>rfl generalize dotStep ⟨pos,neg,true,nz⟩ (fa index) (fb index)=r at hs ⊢;obtain ⟨p,q,s,z⟩:=r;simp only at hs;subst hs;exact ih .. lemma qC6 (fa fb:Ὣ->ὥ) (A B:ѐ) (n:Ὣ) (hA:∀ k,k< n->A[k]! = fa k) (hB:∀ k,k< n->B[k]! = fb k) (acc:Acc) (index remaining:Ὣ) (h:index+remaining<=n) (hp:acc.pos.size=18) (hn:acc.neg.size=18) (hfin:(dotLoop fa fb acc.pos acc.neg acc.special acc.negZero index remaining).special =false) : (dotLoop fa fb acc.pos acc.neg acc.special acc.negZero index remaining).pos.size=18 ∧ (dotLoop fa fb acc.pos acc.neg acc.special acc.negZero index remaining).neg.size=18 ∧ acc.special=false ∧ (∀ k,index<=k->k< index+remaining->expOf A[k]!≠255∧expOf B[k]!≠255) ∧ (dotLoop fa fb acc.pos acc.neg acc.special acc.negZero index remaining).total =acc.total+dsum A B index remaining ∧ (dotLoop fa fb acc.pos acc.neg acc.special acc.negZero index remaining).negZero =(acc.negZero && dallNZ A B index remaining):=by induction remaining generalizing acc index with | zero=>obtain ⟨p,n,s,z⟩:=acc;simp_all [dotLoop,dsum,dallNZ] | succ count ih => obtain ⟨p,q,s,z⟩:=acc simp only at hp hn have ha:=hA index (by clear hp hn; exact omS4 h) have hb:=hB index (by clear hp hn ha; exact omS4 h) by_cases he:expOf (fa index)=255∨expOf (fb index)=255 . exfalso;rw[dotLoop] at hfin;have hs:(dotStep ⟨p,q,s,z⟩ (fa index) (fb index)).special=true:=by simp[dotStep,he] generalize dotStep ⟨p,q,s,z⟩ (fa index) (fb index)=r at hs hfin;obtain ⟨p',q',s',z'⟩:=r;simp only at hs;subst hs;rw[qCb] at hfin;exact Bool.noConfusion hfin . have he':=not_or.mp he obtain ⟨h1,h2,h3,h4,h5⟩ := Acc.add_spec ⟨p,q,s,z⟩ (mantOf (fa index)*mantOf (fb index)) (idxOf (fa index)+idxOf (fb index)) (Bool.xor (signOf (fa index)) (signOf (fb index))) hp hn (mul_mant_lt _ _) (by have:=idxOf_le _ he'.1;have:=idxOf_le _ he'.2;(clear h hp hn ha hb he he'; omega)) have hstep:dotStep ⟨p,q,s,z⟩ (fa index) (fb index) = Acc.add ⟨p,q,s,z⟩ (mantOf (fa index)*mantOf (fb index)) (idxOf (fa index)+idxOf (fb index)) (Bool.xor (signOf (fa index)) (signOf (fb index))):=by simp[dotStep,he] rw[dotLoop,hstep] at hfin ⊢;obtain ⟨hP,hN,hs,hall,hD,hz⟩:=ih _ (index+1) (by clear hp hn ha hb he he' h1 h2 h5; exact omS5 h) h1 h2 hfin;refine ⟨hP,hN,by rw[<-h3,hs],?_,?_,?_⟩ . intro k k1 k2;rcases Nat.lt_or_ge k (index+1) with hk | hk;. have:k=index :=(by clear h hp hn ha hb he he' h1 h2 h5 hP hN hD k2; exact omS6 k1 hk);subst this;rw[ha,hb];exact he' . exact hall k hk (by clear h hp hn ha hb he he' h1 h2 h5 hP hN hD k1 hk; exact omS7 k2) . have sv2:(if Bool.xor (signOf (fa index)) (signOf (fb index)) then -((mantOf (fa index)*mantOf (fb index):Ὣ):Int) else ((mantOf (fa index)*mantOf (fb index):Ὣ):Int)) =sv (fa index)*sv (fb index):=by unfold sv;cases signOf (fa index)<;>cases signOf (fb index)<;>simp rw[hD,h5,dsum,ha,hb,sv2];ring . rw[hz,h4,dallNZ,ha,hb];simp[Bool.and_assoc] def Y_low (p q:ї) (k:Ὣ):Ὣ->Ὣ | 0=>k | f+1=>if p[k]! = 0 && q[k]! = 0 then Y_low p q (k+1) f else k lemma qD3 (p q:ї):∀ f k,(∀ j,j< k->p[j]! = 0∧q[j]! = 0) → ∀ j,j< Y_low p q k f->p[j]! = 0∧q[j]! = 0:=by intro f;induction f with | zero=>exact λk h j hj=>h j hj | succ f ih => intro k h j hj;unfold Y_low at hj;split at hj . rename_i hk;simp only[Bool.and_eq_true,decide_eq_true_eq] at hk;refine ih (k+1) (λi hi=>?_) j hj;rcases Nat.lt_or_ge i k with h1 | h1;. exact h i h1 . have:i=k :=(by clear hj hk; exact omS8 hi h1);subst this;exact hk . exact h j hj lemma qHd (L:љ):∀ l,(∀ j,j< l->L[j]! = 0) → limbVal L=2^(32*l)*limbVal (L.drop l):=by induction L with | nil=>simp[limbVal] | cons x xs ih => intro l h;cases l with | zero=>simp | succ l => have h0:x=0:=by simpa using h 0 (by exact omS9) have:=ih l (λj hj=>by simpa using h (j+1) (by exact Nat.lt_succ_of_le ‹_›));simp only[limbVal,List.drop_succ_cons,h0,this];rw[Nat.mul_add 32 l 1,pow_add];ring lemma qFr (A:ї) (l:Ὣ) (h:∀ j,j< l->A[j]! = 0) : limbVal A.toList=2^(32*l)*limbValA (A.extract l ѧA):=by rw[limbValA_eq,Array.toList_extract,List.extract_eq_drop_take,<-Array.length_toList];rw[List.take_of_length_le ג];refine qHd _ l λj hj=>?_;have:=h j hj;rw[getElem!_def] at this;simp only[getElem!_def] at *;cases e:A[j]?<;>simp_all lemma qIo (S:Int) (l:Ὣ) (e:Int) (z:Ὡ) : finishWord S (e+32*l) z=finishWord (2^(32*l)*S) e z:=by by_cases hS:S=0;. simp[hS,finishWord] have h2:(2:Int)^(32*l)*S≠0:=mul_ne_zero (by positivity) hS rw[finishWord_of_ne (ofIntDyadic (2^(32*l)*S) e) S (e+32*l) z hS (by rw[toRat_ofIntDyadic,Ἓ (by positivity),show (32:ℤ)*l=((32*l:ℕ):ℤ) by push_cast;ring,Ἡ];push_cast;ring)] simp[finishWord,h2] @[inline] def dotFn (n:Ὣ) (fa fb:Ὣ->ὥ):ὥ := let acc:=dotLoop fa fb (ἇ 18 0) (ἇ 18 0) false true 0 n if acc.special then dotSpec (Array.ofFn (n:=n) λi=>fa i) (Array.ofFn (n:=n) λi=>fb i) else let l:=Y_low acc.pos acc.neg 0 18 finishWord ((limbValA (acc.pos.extract l 18):Int)-limbValA (acc.neg.extract l 18)) (-298+32*l) (n≠0 && acc.negZero) lemma qAi:dotFn=dotOf:=by funext n fa fb;unfold dotFn dotOf;set A:=Array.ofFn (n:=n) λi=>fa i with hA;set B:=Array.ofFn (n:=n) λi=>fb i with hB;set acc:=dotLoop fa fb (ἇ 18 0) (ἇ 18 0) false true 0 n with hacc;by_cases hsp:acc.special=true;. simp[hsp] have hsp':acc.special=false:=by simpa using hsp have hF:=qC6 fa fb A B n (qAb n fa) (qAb n fb) ⟨ἇ 18 0,ἇ 18 0,false,true⟩ 0 n (by exact omS10) ג ג hsp';obtain ⟨hP,hN,-,hall,hD,hz⟩:=hF;have hAs:ѧA=n:=by simp[hA] have hBs:ѧB=n:=by simp[hB] have hL:=qD3 acc.pos acc.neg 18 0 (λj hj=>absurd hj (Ἲ _));simp only[hsp',Bool.false_eq_true,ite_false];have e0:(⟨ἇ 18 0,ἇ 18 0,false,true⟩:Acc).total=0:=by decide rw[e0,Int.zero_add] at hD;rw[Bool.true_and] at hz;generalize Y_low acc.pos acc.neg 0 18=l at hL ⊢;have h1:=qFr acc.pos l (λj hj=>(hL j hj).1);have h2:=qFr acc.neg l (λj hj=>(hL j hj).2);rw[hP] at h1;rw[hN] at h2;rw[qIo,<-qEg A B (by clear hP hN hD e0 h1 h2; exact omS11 hAs hBs) (λk hk=>hall k (by exact Nat.zero_le _) (by clear hP hN hD e0 h1 h2; exact omS12 hAs hk)),hAs,<-hD,<-hz];congr 1;have:acc.total=(limbVal acc.pos.toList:Int)-limbVal acc.neg.toList:=rfl;rw[this,h1,h2];push_cast;ring lemma usz (t n:ὦ) (h:t< n):(t+1).toNat=Ѥt+1:=by have h1:Ѥt< Ѥn:=А.mp h;have h2:Ѥn< USize.size:=n.toNat_lt_size;have h3:USize.size=2^System.Platform.numBits:=rfl;rw[USize.toNat_add,ὄ];exact Ἁ (by exact Nat.lt_of_le_of_lt ‹_› ‹_›) lemma qAf (a b:ὦ) (h:Ѥa+Ѥb<2^32):(a+b).toNat=Ѥa+Ѥb:=by have h1:2^32<=USize.size:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl;rw[USize.toNat_add];exact Ἁ (by exact Nat.lt_of_lt_of_le ‹_› ‹_›) lemma uk (k:Ὣ) (h:k<2^32):(USize.ofNat k).toNat=k:=by have h1:2^32<=USize.size:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl;rw[USize.toNat_ofNat'];exact Ἁ (by exact Nat.lt_of_lt_of_le ‹_› ‹_›) lemma qDo (a:ὤ) (i:ὦ) (h:i< a.usize):Ѥi< Ѩa:=by have h1:=А.mp h;have h2:a.usize.toNat<=Ѩa:=by simp only[FloatArray.usize,Nat.toUSize_eq,USize.toNat_ofNat'];exact Nat.mod_le _ _ (exact Nat.lt_of_lt_of_le ‹_› ‹_›) lemma qBd (a:ѐ) (i:ὦ) (h:i< a.usize):Ѥi< ѧa:=by have h1:=А.mp h;have h2:a.usize.toNat<=ѧa:=by simp only[Array.usize,Nat.toUSize_eq,USize.toNat_ofNat'];exact Nat.mod_le _ _ (exact Nat.lt_of_lt_of_le ‹_› ‹_›) @[inline] def rdW (a:ѐ) (i:ὦ):ὥ := if h:i< a.usize then a.uget i (qBd a i h) else 0 @[inline] def wrF (a:ὤ) (i:ὦ) (v:ὧ):ὤ := if h:i< a.usize then a.uset i v (qDo a i h) else a @[inline] def wrW (a:ѐ) (i:ὦ) (v:ὥ):ѐ := if h:i< a.usize then a.uset i v (qBd a i h) else a def pwEntry (i:Ὣ):ὧ := let e:=(i%256).toUInt64 let s:Ὠ:=if i ≥ 256 then 0x8000000000000000 else 0 if e == 0 then Ἃ s else Ἃ (s ||| ((e+873) <<< (52:Ὠ))) def pw:ὤ := (ἄ 512).foldl (λa i=>a.push (pwEntry i)) (ἆ 512) lemma qDx:pw.data=(ἄ 512).toArray.map pwEntry:=by have key:∀ (l:љ) (a:ὤ),(l.foldl (λa i=>a.push (pwEntry i)) a).data=a.data ++ (l.toArray.map pwEntry):=by intro l;induction l with | nil=>intro a;simp | cons x l ih => intro a;simp only[List.foldl_cons,ih];simp[FloatArray.push] simp only[pw,key];simp[FloatArray.emptyWithCapacity] lemma qGe:Ѩpw=512:=by simp[FloatArray.size,qDx] lemma qCh (w:ὥ):(w >>> (23:ὥ)).toUSize.toNat< Ѩpw:=by rw[qGe];have h:=w.toNat_lt_size;simp only[UInt32.toNat_toUSize,UInt32.toNat_shiftRight];norm_num [Nat.shiftRight_eq_div_pow] at h ⊢;exact omS13 h def pwEntryN (z k i:Ὣ):ὧ := if i%256a.push (pwEntryN z k i)) (ἆ 512) lemma qDj (z k:Ὣ):(pwTb z k).data=(ἄ 512).toArray.map (pwEntryN z k):=by have key:∀ (l:љ) (a:ὤ),(l.foldl (λa i=>a.push (pwEntryN z k i)) a).data=a.data ++ (l.toArray.map (pwEntryN z k)):=by intro l;induction l with | nil=>intro a;simp | cons x l ih => intro a;simp only[List.foldl_cons,ih];simp[FloatArray.push] simp only[pwTb,key];simp[FloatArray.emptyWithCapacity] lemma qTd (z k:Ὣ):(pwTb z k).size=512:=by simp only[FloatArray.size,qDj,Array.size_map,List.size_toArray,List.length_range] lemma qBx {T:ὤ} (hT:ѨT=512) (w:ὥ):(w >>> (23:ὥ)).toUSize.toNat< ѨT:=by rw[hT];have h:=w.toNat_lt_size;simp only[UInt32.toNat_toUSize,UInt32.toNat_shiftRight];norm_num [Nat.shiftRight_eq_div_pow,UInt32.size] at h ⊢;(clear hT; exact omS13 h) def tZa:ὤ:=pwTb 0 125 def tZb:ὤ:=pwTb 0 126 def tZc:ὤ:=pwTb 0 127 def tZd:ὤ:=pwTb 0 128 @[inline] def tZ (n:Ὣ):ὤ:=if 256<=n then tZa else if 64<=n then tZb else if 16<=n then tZc else tZd @[inline] def hvI (n:Ὣ):ὥ:=if 256<=n then 0x3E7FFFFF else if 64<=n then 0x3EFFFFFF else if 16<=n then 0x3F7FFFFF else 0x3FFFFFFF lemma qFz (z k:Ὣ) (i:ὦ) (h:Ѥi< (pwTb z k).size):(pwTb z k).uget i h=pwEntryN z k Ѥi:=by simp[FloatArray.uget,qDj] def TOK (z:Ὣ) (T:ὤ) (h:ὥ):Prop:=∃ k,ѨT=512∧(∀ (i:ὦ) (p:Ѥi< ѨT),T.uget i p=pwEntryN z k Ѥi)∧2<=k∧k<=128∧ѥh+1=k*2^23 lemma qTs {z:Ὣ} {T:ὤ} {h:ὥ} (o:TOK z T h):ѨT=512:=by obtain ⟨k,e,-⟩:=o;exact e lemma qTZ (n:Ὣ):TOK 0 (tZ n) (hvI n):=by unfold tZ hvI;split . exact ⟨125,qTd _ _,qFz _ _,by (norm_num1),by (norm_num1),rfl⟩ . split . exact ⟨126,qTd _ _,qFz _ _,by (norm_num1),by (norm_num1),rfl⟩ . split . exact ⟨127,qTd _ _,qFz _ _,by (norm_num1),by (norm_num1),rfl⟩ . exact ⟨128,qTd _ _,qFz _ _,by (norm_num1),by (norm_num1),rfl⟩ @[inline] def dv (w:ὥ):ὧ := ((w &&& 0x7FFFFF) ||| 0x800000).toFloat*pw.uget (w >>> (23:ὥ)).toUSize (qCh w) @[inline] def dvB (v:ὧ) (w:ὥ):ὧ := (v*pw.uget (w >>> (23:ὥ)).toUSize (qCh w))*((w &&& 0x7FFFFF) ||| 0x800000).toFloat @[inline] def good (w:ὥ):Ὡ := let v:=w &&& В v == 0 || v-(0x00800000:ὥ)<=(0x7EFFFFFF:ὥ) def scan (A:ѐ) (n i:ὦ) (hn:Ѥn<=ѧA) (lo hi:ὥ):ὥ := if h:i< n then have ht:=А.mp h let v:=A.uget i א &&& В let u:=v-1 scan A n (i+1) hn (if u< lo then u else lo) (if hi< v then v else hi) else if 0x007FFFFF<=lo∧hi<У then hi else Е partial_fixpoint def scanF (A:ѐ) (n i:ὦ) (hn:Ѥn<=ѧA) (o s:ὥ):ὥ := if h:i< n then have ht:=А.mp h let v:=A.uget i א &&& В scanF A n (i+1) hn (o ||| v) (s &&& (v-1)) else if 0x7FFFFF<=s∧o<У then o else Е partial_fixpoint structure C_Row (I:Ὣ) (X:ё) (i:Ὣ) (ix:ѐ) (x:ὤ) (c:ὦ) (L:љ) (l:ὧ):Prop where len:Ѥc=ѣL cle:ѣL<=I six:I<=ѧix sx:I<=Ѩx∧Ѩx<2^32 nd:L.Nodup lt:∀ t∈L,t< I hz:∀ t,t< I->t∉L->X[i*I+t]! &&& В=0 rd:∀ k p:Ὣ,L[k]?=some p → (ix[k]! : ὥ).toNat=p∧x.data[k]! = dv X[i*I+p]! ok:l=L.foldl (λ(a:ὧ) t=>a+(dv X[i*I+t]!).abs) 0 lemma qAc (a:ѐ):a.usize.toNat<=ѧa:=by simp only[Array.usize,Nat.toUSize_eq,USize.toNat_ofNat'];exact Nat.mod_le _ _ @[inline] def scanH (r:Ὣ) (A:ѐ):ὥ := let h:=if r == 1 then scanF A A.usize 0 (qAc A) 0 Е else Е if h == Е then scan A A.usize 0 (qAc A) Е 0 else h @[inline] def scanW (r:Ὣ) (A:ѐ):ὥ := if r == 8 || r == 1 || r == 4 then 0 else scanH r A def pushZ (n k:ὦ) (a:ὤ):ὤ := if h:k< n then pushZ n (k+1) (a.push 0) else a partial_fixpoint @[inline] def zivW (A B:Ὠ):ὥ := let x:Ὠ:=(A+(0x0FFFFFFF:Ὠ)) >>> (29:Ὠ) let y:Ὠ:=(B+(0x0FFFFFFF:Ὠ)) >>> (29:Ὠ) let ex:Ὠ:=(x >>> (23:Ὠ)) &&& (0x7FF:Ὠ) if x == y && ex-(897:Ὠ)<(254:Ὠ) then (((x >>> (34:Ὠ)) <<< (31:Ὠ)) ||| ((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< (23:Ὠ)))).toUInt32 else Е @[inline] def ziv (s e:ὧ):ὥ := zivW (s+e).toBits (s-e).toBits @[noinline] def slowOut (inW:Ὣ) (relu:Ὡ) (X W b:@& ё) (i j:Ὣ):Ὢ := act relu (dotFn (inW+1) (λt=>if t< inW then X[i*inW+t]! else oneW) (λt=>if t< inW then W[j*inW+t]! else b[j]!)) @[inline] def fin (inW:Ὣ) (relu:Ὡ) (X W b:ё) (i j:Ὣ) (s nf t:ὧ) (bw:ὥ):ὥ := let bv:=dv bw let r:=ziv (s+bv) (nf*(t+bv.abs)) if r == Е then slowOut inW relu X W b i j else act relu r local instance ecNe0:Nonempty F1:=⟨by constructor <;> exact default⟩ def tightGo (X W:ѐ) (xo wo n t:ὦ) (s a:ὧ):F1 := if h:t< n then let q:=dv (rdW X (xo+t))*dv (rdW W (wo+t)) tightGo X W xo wo n (t+1) (s+q) (a+q.abs) else ⟨s,a⟩ termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];exact Nat.sub_lt_sub_left (А.mp h) (Nat.lt_succ_self _) @[noinline] def fin8s (inW:Ὣ) (relu:Ὡ) (X W b:@& ё) (i j:Ὣ) (nf:ὧ) (bw:ὥ) (n:ὦ):ὥ := let q:=tightGo X W (i*inW).toUSize (j*inW).toUSize n 0 0 0 fin inW relu X W b i j q.s nf q.t bw @[inline] def fin8 (inW:Ὣ) (relu:Ὡ) (X W b:ё) (i j:Ὣ) (s nf a:ὧ) (hx bw:ὥ) (n:ὦ):ὥ := let bv:=dv bw let r:=ziv (s+bv) (nf*(dv hx*a+bv.abs)) if r == Е then fin8s inW relu X W b i j nf bw n else r &&& ((if relu then (0:ὥ) else Е) ||| ((r >>> (31:ὥ))-1)) def thOf (e:ὧ):Ὠ := let E:=(e.toBits >>> (52:Ὠ)) &&& 0x7FF if E-1<1900 then (E+35) <<< (53:Ὠ) else 0xFFFFFFFFFFFFFFFF @[inline] def zivC (x:Ὠ):ὥ := (((x >>> (34:Ὠ)) <<< (31:Ὠ)) ||| ((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< (23:Ὠ)))).toUInt32 def loOf (e:ὧ):Ὠ := let th:=thOf e if th<0x7040000000000000 then 0x7040000000000000 else th def spOf (lo:Ὠ):Ὠ := if lo<0x8FA0000000000000 then 0x8FA0000000000000-lo else 0 def spR (relu:Ὡ) (lo:Ὠ):Ὠ:=if relu then 0 else spOf lo @[inline] def fin1 (lo sp:Ὠ) (s:ὧ):ὥ := let w:=s.toBits let u:=w+0x0FDFFFFF if (w <<< (1:Ὠ))-lo< sp && (u &&& 0x1FFFFFFF)<0x1FC00000 then zivC (u >>> (29:Ὠ)) else Е @[inline] def fz (relu:Ὡ) (r:ὥ):ὥ := r &&& ((if relu then (0:ὥ) else Е) ||| ((r >>> (31:ὥ))-1)) @[noinline] def fin8n (inW:Ὣ) (relu:Ὡ) (X W b:@& ё) (i j:Ὣ) (s nf a:ὧ) (hx bw:ὥ) (n:ὦ):ὥ :=fin8 inW relu X W b i j s nf a hx bw n @[inline] def fin8L (inW:Ὣ) (relu:Ὡ) (X W b:ё) (i j:Ὣ) (s nf a:ὧ) (hx:ὥ) (lo:Ὠ) (bw:ὥ) (n:ὦ):ὥ := let t:=fin1 lo (spOf lo) (s+dv bw) if t == Е then fin8n inW relu X W b i j s nf a hx bw n else fz relu t structure R2 where (buf:ὤ) (l:ὧ) (ok:Ὡ) local instance ecNe1:Nonempty R2:=⟨by constructor <;> exact default⟩ def decD (X:ѐ) (o n t:ὦ) (buf:ὤ) (l:ὧ):R2 := if h:t< n then let v:=dv (rdW X (o+t)) decD X o n (t+1) (wrF buf t v) (l+v.abs) else ⟨buf,l,true⟩ partial_fixpoint def idA:ѐ:=Array.ofFn (n:=8192) (λk=>k.val.toUInt32) lemma wi (w i m:ὦ) (W:ѐ) (hw:Ѥw+Ѥm<=ѧW) (hs:ѧW<2^32) (hi:Ѥi< Ѥm):(w+i).toNat< ѧW:=by rw[qAf _ _ (by exact omS14 hw hs hi)];(clear hs; exact omS15 hw hi) def armT:Ὡ:=System.Platform.target.startsWith "aarch64" local instance ecNe2:Nonempty F4:=⟨by constructor <;> exact default⟩ def go4B (x:ὤ) (ix W:ѐ) (w0 w1 w2 w3 m n t:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hs:ѧW<2^32) (h0:Ѥw0+Ѥm<=ѧW) (h1:Ѥw1+Ѥm<=ѧW) (h2:Ѥw2+Ѥm<=ѧW) (h3:Ѥw3+Ѥm<=ѧW) (a b c d:ὧ):F4 := if h:t< n then have ht:=А.mp h let v:=x.uget t א let i:=(ix.uget t א).toUSize if hm:i< m then have him:=А.mp hm let q0:=v*dv (W.uget (w0+i) (wi w0 i m W h0 hs him)) let q1:=dvB v (W.uget (w1+i) (wi w1 i m W h1 hs him)) let q2:=v*dv (W.uget (w2+i) (wi w2 i m W h2 hs him)) let q3:=dvB v (W.uget (w3+i) (wi w3 i m W h3 hs him)) go4B x ix W w0 w1 w2 w3 m n (t+1) hx hi hs h0 h1 h2 h3 (a+q0) (b+q1) (c+q2) (d+q3) else go4B x ix W w0 w1 w2 w3 m n (t+1) hx hi hs h0 h1 h2 h3 a b c d else ⟨a,b,c,d⟩ termination_by Ѥn-Ѥt decreasing_by all_goals (rw[usz t n h];omega) def go1 (x:ὤ) (ix W:ѐ) (w0 m n t:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hs:ѧW<2^32) (h0:Ѥw0+Ѥm<=ѧW) (a:ὧ):ὧ := if h:t< n then have ht:=А.mp h let i:=(ix.uget t א).toUSize if hm:i< m then have him:=А.mp hm let q:=x.uget t א*dv (W.uget (w0+i) (wi w0 i m W h0 hs him)) go1 x ix W w0 m n (t+1) hx hi hs h0 (a+q) else go1 x ix W w0 m n (t+1) hx hi hs h0 a else a partial_fixpoint lemma qA9 {n:Ὣ} (h:n<=4294967295):n<2^32 :=(by exact Nat.lt_succ_of_le ‹_›) def cols1 (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ):ѐ := if h4:j+4<=outW then let ju:=ѩj let w0:=ju*m let w1:=(ju+1)*m let w2:=(ju+2)*m let w3:=(ju+3)*m if hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѥw0+Ѥm<=ѧW ∧ Ѥw1+Ѥm<=ѧW∧Ѥw2+Ѥm<=ѧW∧Ѥw3+Ѥm<=ѧW then let r:=go4B x ix W w0 w1 w2 w3 m n 0 hg.1 hg.2.1 (qA9 hg.2.2.1) hg.2.2.2.1 hg.2.2.2.2.1 hg.2.2.2.2.2.1 hg.2.2.2.2.2.2 0 0 0 0 let o0:=fin8L inW relu X W b i j r.a nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i (j+1) r.b nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i (j+2) r.c nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i (j+3) r.d nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 cols1 inW outW relu X W b i ix x wd nf a hx lo m n (j+4) base out else out else if h1:j< outW then let ju:=ѩj let w0:=ju*m if hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѥw0+Ѥm<=ѧW then let r:=go1 x ix W w0 m n 0 hg.1 hg.2.1 (qA9 hg.2.2.1) hg.2.2.2 0 let o:=fin8L inW relu X W b i j r nf a hx lo (rdW b ju) m cols1 inW outW relu X W b i ix x wd nf a hx lo m n (j+1) base (wrW out (base+ju) o) else out else out partial_fixpoint lemma qWm (a b:ὦ) (h:Ѥa*Ѥb<2^32) : (a*b).toNat=Ѥa*Ѥb:=by have h1:2^32<=USize.size:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl;rw[USize.toNat_mul];exact Ἁ (by exact Nat.lt_of_lt_of_le ‹_› ‹_›) lemma wq (p i m:ὦ) (wb:ὤ) (k:Ὣ) (hk:k<8) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat k).toNat< Ѩwb:=by have e8:(USize.ofNat 8*i).toNat=8*Ѥi:=by rw[qWm _ _ (by rw[uk 8 (by decide)];(clear hk; exact omS16 hb hs him)),uk 8 (by decide)] rw[qAf _ _ (by rw[qAf _ _ (by rw[e8];(clear hk e8; exact omS17 hb hs him)),e8,uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];(clear e8; exact omS18 hk hb hs him)),qAf _ _ (by rw[e8];(clear hk e8; exact omS17 hb hs him)),e8,uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];(clear hs e8; omega) lemma wq0 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 0).toNat< Ѩwb:=wq p i m wb 0 (by decide) hb hs him lemma wq1 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 1).toNat< Ѩwb:=wq p i m wb 1 (by decide) hb hs him lemma wq2 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 2).toNat< Ѩwb:=wq p i m wb 2 (by decide) hb hs him lemma wq3 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 3).toNat< Ѩwb:=wq p i m wb 3 (by decide) hb hs him lemma wq4 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 4).toNat< Ѩwb:=wq p i m wb 4 (by decide) hb hs him lemma wq5 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 5).toNat< Ѩwb:=wq p i m wb 5 (by decide) hb hs him lemma wq6 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 6).toNat< Ѩwb:=wq p i m wb 6 (by decide) hb hs him lemma wq7 (p i m:ὦ) (wb:ὤ) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (him:Ѥi< Ѥm):(p+USize.ofNat 8*i+USize.ofNat 7).toNat< Ѩwb:=wq p i m wb 7 (by decide) hb hs him lemma pk (w m:ὦ) (wb:ὤ) (h:Ѥw+5+8*Ѥm<=Ѩwb) (hs:Ѩwb<=4294967295):Ѥ(w+USize.ofNat 5)+8*Ѥm<=Ѩwb∧Ѥ(w+USize.ofNat 5)=Ѥw+5:=by have e:Ѥ(w+USize.ofNat 5)=Ѥw+5:=by rw[qAf _ _ (by rw[uk 5 (by decide)];exact omS19 h hs),uk 5 (by decide)] exact ⟨by rw[e];exact h,e⟩ def go8W (x wb:ὤ) (ix:ѐ) (p m n t:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (a b c d e f g k:ὧ):F4×F4 := if h:t< n then have ht:=А.mp h let v:=x.uget t (Nat.lt_of_lt_of_le ht hx) let i:=(ix.uget t (Nat.lt_of_lt_of_le ht hi)).toUSize if hm:i< m then have him:=А.mp hm let q:=p+USize.ofNat 8*i go8W x wb ix p m n (t+1) hx hi hb hs (a+v*wb.uget (q+USize.ofNat 0) (wq0 p i m wb hb hs him)) (b+v*wb.uget (q+USize.ofNat 1) (wq1 p i m wb hb hs him)) (c+v*wb.uget (q+USize.ofNat 2) (wq2 p i m wb hb hs him)) (d+v*wb.uget (q+USize.ofNat 3) (wq3 p i m wb hb hs him)) (e+v*wb.uget (q+USize.ofNat 4) (wq4 p i m wb hb hs him)) (f+v*wb.uget (q+USize.ofNat 5) (wq5 p i m wb hb hs him)) (g+v*wb.uget (q+USize.ofNat 6) (wq6 p i m wb hb hs him)) (k+v*wb.uget (q+USize.ofNat 7) (wq7 p i m wb hb hs him)) else go8W x wb ix p m n (t+1) hx hi hb hs a b c d e f g k else (⟨a,b,c,d⟩,⟨e,f,g,k⟩) termination_by Ѥn-Ѥt decreasing_by all_goals (rw[usz t n h];omega) local instance ecNe3:Nonempty G8:=⟨by constructor <;> exact default⟩ def go8V (x wb:ὤ) (p m n t:ὦ) (hx:Ѥn<=Ѩx) (hn:Ѥn<=Ѥm) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (a b c d e f g k:ὧ):G8 := if h:t< n then have ht:=А.mp h have him:Ѥt< Ѥm:=Nat.lt_of_lt_of_le ht hn let v:=x.uget t (Nat.lt_of_lt_of_le ht hx) let q:=p+USize.ofNat 8*t go8V x wb p m n (t+1) hx hn hb hs (a+v*wb.uget (q+USize.ofNat 0) (wq0 p t m wb hb hs him)) (b+v*wb.uget (q+USize.ofNat 1) (wq1 p t m wb hb hs him)) (c+v*wb.uget (q+USize.ofNat 2) (wq2 p t m wb hb hs him)) (d+v*wb.uget (q+USize.ofNat 3) (wq3 p t m wb hb hs him)) (e+v*wb.uget (q+USize.ofNat 4) (wq4 p t m wb hb hs him)) (f+v*wb.uget (q+USize.ofNat 5) (wq5 p t m wb hb hs him)) (g+v*wb.uget (q+USize.ofNat 6) (wq6 p t m wb hb hs him)) (k+v*wb.uget (q+USize.ofNat 7) (wq7 p t m wb hb hs him)) else ⟨a,b,c,d,e,f,g,k⟩ termination_by Ѥn-Ѥt decreasing_by all_goals (rw[usz t n h];omega) def g8of (r:F4×F4):G8:=⟨r.1.a,r.1.b,r.1.c,r.1.d,r.2.a,r.2.b,r.2.c,r.2.d⟩ local instance ecNe4:Nonempty G24:=⟨by constructor <;> exact default⟩ def go24V (x wb:ὤ) (p p' p'' m n t:ὦ) (hx:Ѥn<=Ѩx) (hn:Ѥn<=Ѥm) (hb:Ѥp+8*Ѥm<=Ѩwb) (hb':Ѥp'+8*Ѥm<=Ѩwb) (hb'':Ѥp''+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (a b c d e f g k a' b' c' d' e' f' g' k' a'' b'' c'' d'' e'' f'' g'' k'':ὧ):G24 := if h:t< n then have ht:=А.mp h have him:Ѥt< Ѥm:=Nat.lt_of_lt_of_le ht hn let v:=x.uget t (Nat.lt_of_lt_of_le ht hx) let q:=p+USize.ofNat 8*t let q':=p'+USize.ofNat 8*t let q'':=p''+USize.ofNat 8*t go24V x wb p p' p'' m n (t+1) hx hn hb hb' hb'' hs (a+v*wb.uget (q+USize.ofNat 0) (wq0 p t m wb hb hs him)) (b+v*wb.uget (q+USize.ofNat 1) (wq1 p t m wb hb hs him)) (c+v*wb.uget (q+USize.ofNat 2) (wq2 p t m wb hb hs him)) (d+v*wb.uget (q+USize.ofNat 3) (wq3 p t m wb hb hs him)) (e+v*wb.uget (q+USize.ofNat 4) (wq4 p t m wb hb hs him)) (f+v*wb.uget (q+USize.ofNat 5) (wq5 p t m wb hb hs him)) (g+v*wb.uget (q+USize.ofNat 6) (wq6 p t m wb hb hs him)) (k+v*wb.uget (q+USize.ofNat 7) (wq7 p t m wb hb hs him)) (a'+v*wb.uget (q'+USize.ofNat 0) (wq0 p' t m wb hb' hs him)) (b'+v*wb.uget (q'+USize.ofNat 1) (wq1 p' t m wb hb' hs him)) (c'+v*wb.uget (q'+USize.ofNat 2) (wq2 p' t m wb hb' hs him)) (d'+v*wb.uget (q'+USize.ofNat 3) (wq3 p' t m wb hb' hs him)) (e'+v*wb.uget (q'+USize.ofNat 4) (wq4 p' t m wb hb' hs him)) (f'+v*wb.uget (q'+USize.ofNat 5) (wq5 p' t m wb hb' hs him)) (g'+v*wb.uget (q'+USize.ofNat 6) (wq6 p' t m wb hb' hs him)) (k'+v*wb.uget (q'+USize.ofNat 7) (wq7 p' t m wb hb' hs him)) (a''+v*wb.uget (q''+USize.ofNat 0) (wq0 p'' t m wb hb'' hs him)) (b''+v*wb.uget (q''+USize.ofNat 1) (wq1 p'' t m wb hb'' hs him)) (c''+v*wb.uget (q''+USize.ofNat 2) (wq2 p'' t m wb hb'' hs him)) (d''+v*wb.uget (q''+USize.ofNat 3) (wq3 p'' t m wb hb'' hs him)) (e''+v*wb.uget (q''+USize.ofNat 4) (wq4 p'' t m wb hb'' hs him)) (f''+v*wb.uget (q''+USize.ofNat 5) (wq5 p'' t m wb hb'' hs him)) (g''+v*wb.uget (q''+USize.ofNat 6) (wq6 p'' t m wb hb'' hs him)) (k''+v*wb.uget (q''+USize.ofNat 7) (wq7 p'' t m wb hb'' hs him)) else ⟨a,b,c,d,e,f,g,k,a',b',c',d',e',f',g',k',a'',b'',c'',d'',e'',f'',g'',k''⟩ termination_by Ѥn-Ѥt decreasing_by all_goals (rw[usz t n h];omega) local instance ecNe5:Nonempty G16:=⟨by constructor <;> exact default⟩ def go16V (x wb:ὤ) (p p' m n t:ὦ) (hx:Ѥn<=Ѩx) (hn:Ѥn<=Ѥm) (hb:Ѥp+8*Ѥm<=Ѩwb) (hb':Ѥp'+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (a b c d e f g k a' b' c' d' e' f' g' k':ὧ):G16 := if h:t< n then have ht:=А.mp h have him:Ѥt< Ѥm:=Nat.lt_of_lt_of_le ht hn let v:=x.uget t (Nat.lt_of_lt_of_le ht hx) let q:=p+USize.ofNat 8*t let q':=p'+USize.ofNat 8*t go16V x wb p p' m n (t+1) hx hn hb hb' hs (a+v*wb.uget (q+USize.ofNat 0) (wq0 p t m wb hb hs him)) (b+v*wb.uget (q+USize.ofNat 1) (wq1 p t m wb hb hs him)) (c+v*wb.uget (q+USize.ofNat 2) (wq2 p t m wb hb hs him)) (d+v*wb.uget (q+USize.ofNat 3) (wq3 p t m wb hb hs him)) (e+v*wb.uget (q+USize.ofNat 4) (wq4 p t m wb hb hs him)) (f+v*wb.uget (q+USize.ofNat 5) (wq5 p t m wb hb hs him)) (g+v*wb.uget (q+USize.ofNat 6) (wq6 p t m wb hb hs him)) (k+v*wb.uget (q+USize.ofNat 7) (wq7 p t m wb hb hs him)) (a'+v*wb.uget (q'+USize.ofNat 0) (wq0 p' t m wb hb' hs him)) (b'+v*wb.uget (q'+USize.ofNat 1) (wq1 p' t m wb hb' hs him)) (c'+v*wb.uget (q'+USize.ofNat 2) (wq2 p' t m wb hb' hs him)) (d'+v*wb.uget (q'+USize.ofNat 3) (wq3 p' t m wb hb' hs him)) (e'+v*wb.uget (q'+USize.ofNat 4) (wq4 p' t m wb hb' hs him)) (f'+v*wb.uget (q'+USize.ofNat 5) (wq5 p' t m wb hb' hs him)) (g'+v*wb.uget (q'+USize.ofNat 6) (wq6 p' t m wb hb' hs him)) (k'+v*wb.uget (q'+USize.ofNat 7) (wq7 p' t m wb hb' hs him)) else ⟨a,b,c,d,e,f,g,k,a',b',c',d',e',f',g',k'⟩ termination_by Ѥn-Ѥt decreasing_by all_goals (rw[usz t n h];omega) def g16of (r s:G8):G16:=⟨r.a,r.b,r.c,r.d,r.e,r.f,r.g,r.k,s.a,s.b,s.c,s.d,s.e,s.f,s.g,s.k⟩ theorem g16V (x wb:ὤ) (p p' m n t:ὦ) (hx:Ѥn<=Ѩx) (hn:Ѥn<=Ѥm) (hb:Ѥp+8*Ѥm<=Ѩwb) (hb':Ѥp'+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (a b c d e f g k a' b' c' d' e' f' g' k':ὧ): go16V x wb p p' m n t hx hn hb hb' hs a b c d e f g k a' b' c' d' e' f' g' k'=g16of (go8V x wb p m n t hx hn hb hs a b c d e f g k) (go8V x wb p' m n t hx hn hb' hs a' b' c' d' e' f' g' k'):=by obtain ⟨N,hN⟩:∃N,Ѥn-Ѥt=N:=⟨_,rfl⟩ induction N generalizing t a b c d e f g k a' b' c' d' e' f' g' k' with | zero=> have h:¬t< n:=fun h=>by have:=А.mp h;omega rw[go16V,go8V,go8V,ἔ h,ἔ h,ἔ h];rfl | succ N ih=> have h:t< n:=А.mpr (by omega) rw[go16V,go8V,go8V,Ἄ h,Ἄ h,Ἄ h];dsimp only exact ih (t+1) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ (by rw[usz t n h];omega) def g24of (r s u:G8):G24:=⟨r.a,r.b,r.c,r.d,r.e,r.f,r.g,r.k,s.a,s.b,s.c,s.d,s.e,s.f,s.g,s.k,u.a,u.b,u.c,u.d,u.e,u.f,u.g,u.k⟩ theorem g24V (x wb:ὤ) (p p' p'' m n t:ὦ) (hx:Ѥn<=Ѩx) (hn:Ѥn<=Ѥm) (hb:Ѥp+8*Ѥm<=Ѩwb) (hb':Ѥp'+8*Ѥm<=Ѩwb) (hb'':Ѥp''+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (a b c d e f g k a' b' c' d' e' f' g' k' a'' b'' c'' d'' e'' f'' g'' k'':ὧ): go24V x wb p p' p'' m n t hx hn hb hb' hb'' hs a b c d e f g k a' b' c' d' e' f' g' k' a'' b'' c'' d'' e'' f'' g'' k''=g24of (go8V x wb p m n t hx hn hb hs a b c d e f g k) (go8V x wb p' m n t hx hn hb' hs a' b' c' d' e' f' g' k') (go8V x wb p'' m n t hx hn hb'' hs a'' b'' c'' d'' e'' f'' g'' k''):=by obtain ⟨N,hN⟩:∃N,Ѥn-Ѥt=N:=⟨_,rfl⟩ induction N generalizing t a b c d e f g k a' b' c' d' e' f' g' k' a'' b'' c'' d'' e'' f'' g'' k'' with | zero=> have h:¬t< n:=fun h=>by have:=А.mp h;omega rw[go24V,go8V,go8V,go8V,ἔ h,ἔ h,ἔ h,ἔ h];rfl | succ N ih=> have h:t< n:=А.mpr (by omega) rw[go24V,go8V,go8V,go8V,Ἄ h,Ἄ h,Ἄ h,Ἄ h];dsimp only exact ih (t+1) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ (by rw[usz t n h];omega) def C_g8 (r:G8):Ὣ->ὧ | 0=>r.a | 1=>r.b | 2=>r.c | 3=>r.d | 4=>r.e | 5=>r.f | 6=>r.g | _=>r.k def cols1T (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m:ὦ) (rr:G8) (j0 j:Ὣ) (base:ὦ) (out:ѐ):ѐ := if h4:j+4<=outW then let ju:=ѩj let o0:=fin8L inW relu X W b i j (C_g8 rr (j-j0)) nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i (j+1) (C_g8 rr (j+1-j0)) nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i (j+2) (C_g8 rr (j+2-j0)) nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i (j+3) (C_g8 rr (j+3-j0)) nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 cols1T inW outW relu X W b i nf a hx lo m rr j0 (j+4) base out else if h1:j< outW then let ju:=ѩj let o:=fin8L inW relu X W b i j (C_g8 rr (j-j0)) nf a hx lo (rdW b ju) m cols1T inW outW relu X W b i nf a hx lo m rr j0 (j+1) base (wrW out (base+ju) o) else out partial_fixpoint def cols1W (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ):ѐ := if h8:j+8<=outW then let ju:=ѩj let jv:=(j+4).toUSize let w0:=ju*m let w1:=(ju+1)*m let w2:=(ju+2)*m let w3:=(ju+3)*m let v0:=jv*m let v1:=(jv+1)*m let v2:=(jv+2)*m let v3:=(jv+3)*m if hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѥw0+Ѥm<=ѧW∧Ѥw1+Ѥm<=ѧW∧Ѥw2+Ѥm<=ѧW∧Ѥw3+Ѥm<=ѧW∧ Ѥv0+Ѥm<=ѧW∧Ѥv1+Ѥm<=ѧW∧Ѥv2+Ѥm<=ѧW∧Ѥv3+Ѥm<=ѧW∧Ѩwb<=4294967295∧Ѥw0+5+8*Ѥm<=Ѩwb then let rr:=go8W x wb ix (w0+USize.ofNat 5) m n 0 hg.1 hg.2.1 (pk w0 m wb hg.2.2.2.2.2.2.2.2.2.2.2.2 hg.2.2.2.2.2.2.2.2.2.2.2.1).1 (qA9 hg.2.2.2.2.2.2.2.2.2.2.2.1) 0 0 0 0 0 0 0 0 let o0:=fin8L inW relu X W b i j rr.1.a nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i (j+1) rr.1.b nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i (j+2) rr.1.c nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i (j+3) rr.1.d nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 let ju:=jv let o0:=fin8L inW relu X W b i (j+4) rr.2.a nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i ((j+4)+1) rr.2.b nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i ((j+4)+2) rr.2.c nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i ((j+4)+3) rr.2.d nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 cols1W inW outW relu X W b i ix x wd wb nf a hx lo m n (j+8) base out else cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out else if ht:j< outW then if hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb then cols1T inW outW relu X W b i nf a hx lo m (g8of (go8W x wb ix (ѩj*m+USize.ofNat 5) m n 0 hg.1 hg.2.1 (pk (ѩj*m) m wb hg.2.2.2.2.2 hg.2.2.2.1).1 (qA9 hg.2.2.2.1) 0 0 0 0 0 0 0 0)) j j base out else cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out else cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out partial_fixpoint def cols1V (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ):ѐ := if h8:j+8<=outW then let ju:=ѩj let jv:=(j+4).toUSize let w0:=ju*m let w1:=(ju+1)*m let w2:=(ju+2)*m let w3:=(ju+3)*m let v0:=jv*m let v1:=(jv+1)*m let v2:=(jv+2)*m let v3:=(jv+3)*m if hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѥw0+Ѥm<=ѧW∧Ѥw1+Ѥm<=ѧW∧Ѥw2+Ѥm<=ѧW∧Ѥw3+Ѥm<=ѧW∧ Ѥv0+Ѥm<=ѧW∧Ѥv1+Ѥm<=ѧW∧Ѥv2+Ѥm<=ѧW∧Ѥv3+Ѥm<=ѧW∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥw0+5+8*Ѥm<=Ѩwb then let rr:=go8V x wb (w0+USize.ofNat 5) m n 0 hg.1 hg.2.2.2.2.2.2.2.2.2.2.2.2.1 (pk w0 m wb hg.2.2.2.2.2.2.2.2.2.2.2.2.2 hg.2.2.2.2.2.2.2.2.2.2.2.1).1 (qA9 hg.2.2.2.2.2.2.2.2.2.2.2.1) 0 0 0 0 0 0 0 0 let o0:=fin8L inW relu X W b i j rr.a nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i (j+1) rr.b nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i (j+2) rr.c nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i (j+3) rr.d nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 let ju:=jv let o0:=fin8L inW relu X W b i (j+4) rr.e nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i ((j+4)+1) rr.f nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i ((j+4)+2) rr.g nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i ((j+4)+3) rr.k nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n (j+8) base out else cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out else if ht:j< outW then if hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb then cols1T inW outW relu X W b i nf a hx lo m (go8V x wb (ѩj*m+USize.ofNat 5) m n 0 hg.1 hg.2.2.2.2.1 (pk (ѩj*m) m wb hg.2.2.2.2.2 hg.2.2.2.1).1 (qA9 hg.2.2.2.1) 0 0 0 0 0 0 0 0) j j base out else cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out else cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out partial_fixpoint @[noinline] def fw8 (inW:Ὣ) (relu:Ὡ) (X W b:@& ѐ) (i:Ὣ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ):ѐ := let ju:=ѩj let jv:=(j+4).toUSize let o0:=fin8L inW relu X W b i j s0 nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i (j+1) s1 nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i (j+2) s2 nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i (j+3) s3 nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 let ju:=jv let o0:=fin8L inW relu X W b i (j+4) s4 nf a hx lo (rdW b ju) m let o1:=fin8L inW relu X W b i ((j+4)+1) s5 nf a hx lo (rdW b (ju+1)) m let o2:=fin8L inW relu X W b i ((j+4)+2) s6 nf a hx lo (rdW b (ju+2)) m let o3:=fin8L inW relu X W b i ((j+4)+3) s7 nf a hx lo (rdW b (ju+3)) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 out def cols1VS (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ):ѐ := cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n j base out theorem c1VS' (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ) : cols1VS inW outW relu X W b i ix x wd wb nf a hx lo m n j base out=cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n j base out:=rfl @[inline] def dvN (T:ὤ) (hT:ѨT=512) (w:ὥ):ὧ := ((w &&& 0x7FFFFF) ||| 0x800000).toFloat*T.uget (w >>> (23:ὥ)).toUSize (qBx hT w) lemma xi (xs:ὤ) (i t n:ὦ) (k:Ὣ) (hk:k<8) (ht:Ѥt< Ѥn) (hi:Ѥi=8*Ѥt+1) (hx:8*Ѥn+1<=Ѩxs) (hs:Ѩxs<2^32) : (i+USize.ofNat k).toNat< Ѩxs:=by rw[qAf _ _ (by rw[uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];exact omS23 hk ht hi hx hs),uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];(clear hs; exact omS24 hk ht hi hx) local instance ecNe6:Nonempty F8:=⟨by constructor <;> exact default⟩ def go8Z (T:ὤ) (hT:ѨT=512) (xs:ὤ) (W:ѐ) (wo n t i:ὦ) (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw:Ѥwo+Ѥn<=ѧW) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (q:ὥ) (r:F8):F8 := if h:t< n then have ht:=А.mp h let w:=W.uget (wo+t) (wi wo t n W hw hs ht) let v:=dvN T hT w go8Z T hT xs W wo n (t+1) (i+USize.ofNat 8) hx hsx hs hw (by rw[usz t n h,qAf _ _ (by rw[uk 8 (by decide)];omega),uk 8 (by decide)];omega) (s0+xs.uget (i+USize.ofNat 0) (xi xs i t n 0 (by decide) ht hi hx hsx)*v) (s1+xs.uget (i+USize.ofNat 1) (xi xs i t n 1 (by decide) ht hi hx hsx)*v) (s2+xs.uget (i+USize.ofNat 2) (xi xs i t n 2 (by decide) ht hi hx hsx)*v) (s3+xs.uget (i+USize.ofNat 3) (xi xs i t n 3 (by decide) ht hi hx hsx)*v) (s4+xs.uget (i+USize.ofNat 4) (xi xs i t n 4 (by decide) ht hi hx hsx)*v) (s5+xs.uget (i+USize.ofNat 5) (xi xs i t n 5 (by decide) ht hi hx hsx)*v) (s6+xs.uget (i+USize.ofNat 6) (xi xs i t n 6 (by decide) ht hi hx hsx)*v) (s7+xs.uget (i+USize.ofNat 7) (xi xs i t n 7 (by decide) ht hi hx hsx)*v) (q &&& ((w &&& В)-1)) r else match r with | ⟨u,_,_,_,_,_,_,_,_,_,_⟩=>⟨u,s0,s1,s2,s3,s4,s5,s6,s7,0,q⟩ partial_fixpoint def zA:ὤ:=pushZ 32 0 (ἆ 32) def z0:ὤ:=pushZ 128 0 (ἆ 128) def zB:ὤ:=pushZ 256 0 (ἆ 256) def zC:ὤ:=pushZ 512 0 (ἆ 512) def z1:ὤ:=pushZ 1024 0 (ἆ 1024) def z4:ὤ:=pushZ 4096 0 (ἆ 4096) def z8:ὤ:=pushZ 8192 0 (ἆ 8192) @[inline] def zFor (m:Ὣ):ὤ:= if m<=32 then zA else if m<=128 then z0 else if m<=256 then zB else if m<=512 then zC else if m<=1024 then z1 else if m<=4096 then z4 else if m<=8192 then z8 else pushZ ѩm 0 (ἆ m) @[inline] def wr8 (xs:ὤ) (i:ὦ) (a0 a1 a2 a3 a4 a5 a6 a7:ὧ):ὤ := wrF (wrF (wrF (wrF (wrF (wrF (wrF (wrF xs (i+USize.ofNat 0) a0) (i+USize.ofNat 1) a1) (i+USize.ofNat 2) a2) (i+USize.ofNat 3) a3) (i+USize.ofNat 4) a4) (i+USize.ofNat 5) a5) (i+USize.ofNat 6) a6) (i+USize.ofNat 7) a7 def go8ZD (D:ὤ) (xs:ὤ) (W:ѐ) (hd:ѨD=ѧW) (wo n t i:ὦ) (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw:Ѥwo+Ѥn<=ѧW) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (q:ὥ) (r:F8):F8 := if h:t< n then have ht:=А.mp h let v:=D.uget (wo+t) (hd ▸ wi wo t n W hw hs ht) go8ZD D xs W hd wo n (t+1) (i+USize.ofNat 8) hx hsx hs hw (by rw[usz t n h,qAf _ _ (by rw[uk 8 (by decide)];omega),uk 8 (by decide)];omega) (s0+xs.uget (i+USize.ofNat 0) (xi xs i t n 0 (by decide) ht hi hx hsx)*v) (s1+xs.uget (i+USize.ofNat 1) (xi xs i t n 1 (by decide) ht hi hx hsx)*v) (s2+xs.uget (i+USize.ofNat 2) (xi xs i t n 2 (by decide) ht hi hx hsx)*v) (s3+xs.uget (i+USize.ofNat 3) (xi xs i t n 3 (by decide) ht hi hx hsx)*v) (s4+xs.uget (i+USize.ofNat 4) (xi xs i t n 4 (by decide) ht hi hx hsx)*v) (s5+xs.uget (i+USize.ofNat 5) (xi xs i t n 5 (by decide) ht hi hx hsx)*v) (s6+xs.uget (i+USize.ofNat 6) (xi xs i t n 6 (by decide) ht hi hx hsx)*v) (s7+xs.uget (i+USize.ofNat 7) (xi xs i t n 7 (by decide) ht hi hx hsx)*v) q r else match r with | ⟨u,_,_,_,_,_,_,_,_,_,_⟩=>⟨u,s0,s1,s2,s3,s4,s5,s6,s7,0,q⟩ partial_fixpoint def go8ZS (D:ὤ) (xs:ὤ) (W:ѐ) (hd:ѨD=ѧW) (wo n t i:ὦ) (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw:Ѥwo+Ѥn<=ѧW) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (q:ὥ) (r:F8):F8 := if h:armT∧t< n∧t+1< n then have ht:=А.mp h.2.1 have hu:=А.mp h.2.2 have hj:(i+USize.ofNat 8).toNat=8*(t+1).toNat+1:=by rw[usz t n h.2.1,qAf _ _ (by rw[uk 8 (by decide)];omega),uk 8 (by decide)];omega let v:=D.uget (wo+t) (hd ▸ wi wo t n W hw hs ht) let u:=D.uget (wo+(t+1)) (hd ▸ wi wo (t+1) n W hw hs hu) go8ZS D xs W hd wo n (t+1+1) (i+USize.ofNat 8+USize.ofNat 8) hx hsx hs hw (by rw[usz (t+1) n h.2.2,qAf _ _ (by rw[uk 8 (by decide)];omega),uk 8 (by decide)];omega) (s0+xs.uget (i+USize.ofNat 0) (xi xs i t n 0 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 0) (xi xs (i+USize.ofNat 8) (t+1) n 0 (by decide) hu hj hx hsx)*u) (s1+xs.uget (i+USize.ofNat 1) (xi xs i t n 1 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 1) (xi xs (i+USize.ofNat 8) (t+1) n 1 (by decide) hu hj hx hsx)*u) (s2+xs.uget (i+USize.ofNat 2) (xi xs i t n 2 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 2) (xi xs (i+USize.ofNat 8) (t+1) n 2 (by decide) hu hj hx hsx)*u) (s3+xs.uget (i+USize.ofNat 3) (xi xs i t n 3 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 3) (xi xs (i+USize.ofNat 8) (t+1) n 3 (by decide) hu hj hx hsx)*u) (s4+xs.uget (i+USize.ofNat 4) (xi xs i t n 4 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 4) (xi xs (i+USize.ofNat 8) (t+1) n 4 (by decide) hu hj hx hsx)*u) (s5+xs.uget (i+USize.ofNat 5) (xi xs i t n 5 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 5) (xi xs (i+USize.ofNat 8) (t+1) n 5 (by decide) hu hj hx hsx)*u) (s6+xs.uget (i+USize.ofNat 6) (xi xs i t n 6 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 6) (xi xs (i+USize.ofNat 8) (t+1) n 6 (by decide) hu hj hx hsx)*u) (s7+xs.uget (i+USize.ofNat 7) (xi xs i t n 7 (by decide) ht hi hx hsx)*v+xs.uget (i+USize.ofNat 8+USize.ofNat 7) (xi xs (i+USize.ofNat 8) (t+1) n 7 (by decide) hu hj hx hsx)*u) q r else go8ZD D xs W hd wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q r partial_fixpoint theorem g8ZS (D:ὤ) (xs:ὤ) (W:ѐ) (hd:ѨD=ѧW) (wo n:ὦ) (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw:Ѥwo+Ѥn<=ѧW) (r:F8) (t i:ὦ) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (q:ὥ): go8ZS D xs W hd wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q r=go8ZD D xs W hd wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q r:=by generalize hm:Ѥn-Ѥt=m induction m using Nat.strong_induction_on generalizing t i hi s0 s1 s2 s3 s4 s5 s6 s7 q with | _ m ih=> rw[go8ZS];split . rename_i h;have:=usz t n h.2.1;have:=usz (t+1) n h.2.2;have:=А.mp h.2.2 rw[ih _ (by clear hi h; omega) (t+1+1) _ _ _ _ _ _ _ _ _ _ _ rfl];simp only[go8ZD.eq_1 D xs W hd wo n t,go8ZD.eq_1 D xs W hd wo n (t+1),Ἄ h.2.1,Ἄ h.2.2] . rfl def dnOf (T:ὤ) (hT:ѨT=512) (W:ѐ):ὤ:=⟨W.map (dvN T hT)⟩ theorem dnFoldL (f:ὥ→ὧ):∀ (l:List ὥ) (a:ὤ),l.foldl (fun a w=>a.push (f w)) a=⟨a.data++(l.map f).toArray⟩:=by intro l;induction l with | nil=>intro a;cases a;simp | cons x xs ih=>intro a;rw[List.foldl_cons,ih];cases a;simp[FloatArray.push] theorem dnFold (f:ὥ→ὧ) (W:ѐ):W.foldl (fun a w=>a.push (f w)) (ἆ W.size)=⟨W.map f⟩:=by rw[←Array.foldl_toList,dnFoldL];simp[FloatArray.emptyWithCapacity];apply Array.ext';simp @[inline] def nE (n:Ὣ) (W:ѐ):Ὣ:=let h:=scanH 2 W;if h<=hvI n then n else if h<=0x3EFFFFFF then 64 else if h<=0x3F7FFFFF then 16 else 0 def qScan (W:ѐ) (e i:ὦ) (q:ὥ):ὥ := if h:i< e then qScan W e (i+1) (q &&& ((rdW W i &&& В)-1)) else q partial_fixpoint def F8q (R:F8) (u:UInt8) (q:ὥ):F8:=⟨u,R.s0,R.s1,R.s2,R.s3,R.s4,R.s5,R.s6,R.s7,R.p,q⟩ abbrev WV8 (n:Ὣ) (W:ѐ):=({p:ὤ×ὥ×Ὣ//p=(dnOf (tZ (nE n W)) (qTs (qTZ (nE n W))) W,qScan W W.usize 0 Е,nE n W)}) local instance wv8Sub (n:Ὣ) (W:ѐ):Subsingleton (WV8 n W):=⟨λa b=>Subtype.ext (a.2.trans b.2.symm)⟩ structure WE8 where (w:ѐ) (n:Ὣ) (p:ὤ×ὥ×Ὣ) (g:USize) (ok:p=(dnOf (tZ (nE n w)) (qTs (qTZ (nE n w))) w,qScan w w.usize 0 Е,nE n w)) def wd8F (n:Ὣ) (W:ѐ) (g:USize) (s:Array WE8) (i:Ὣ):Option (WV8 n W):= if h:i< s.size then if s[i].g==g then if hn:s[i].n=n then if hk:withPtrEq s[i].w W (λ_=>s[i].w==W) (λe=>by rw[e];exact beq_self_eq_true W) then some ⟨s[i].p,by rw[←hn,←eq_of_beq hk];exact s[i].ok⟩ else wd8F n W g s (i+1) else wd8F n W g s (i+1) else wd8F n W g s (i+1) else none partial_fixpoint @[noinline] def wd8S:ST.Ref Unit (Array WE8):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def wd8Get (n:Ὣ) (W:ѐ):WV8 n W:= withPtrAddr W (λg=> let s:=(ST.Prim.Ref.get wd8S (Void.mk ())).val match wd8F n W g s 0 with | some v=>v | none=> let p:=(dnOf (tZ (nE n W)) (qTs (qTZ (nE n W))) W,qScan W W.usize 0 Е,nE n W) let old:=(ST.Prim.Ref.swap wd8S (#[⟨W,n,p,g,rfl⟩]++(if s.size<256 then s else s.pop)) (Void.mk ())).val match wd8F n W g old 0 with | some v=>v | none=>⟨p,rfl⟩) (λ_ _=>Subsingleton.elim _ _) lemma dnU (T:ὤ) (hT:ѨT=512) (W:ѐ) (j:ὦ) (h1:Ѥj<(dnOf T hT W).size) (h2:Ѥj<ѧW):(dnOf T hT W).uget j h1=dvN T hT (W.uget j h2):=by simp [dnOf, FloatArray.uget, Array.uget] theorem g8ZE (T:ὤ) (hT:ѨT=512) (xs:ὤ) (W:ѐ) (hd:(dnOf T hT W).size=ѧW) (wo n t i:ὦ) (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw:Ѥwo+Ѥn<=ѧW) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (q q':ὥ) (r r':F8): go8ZD (dnOf T hT W) xs W hd wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q' r'=F8q (go8Z T hT xs W wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q r) r'.u q':=by rw[go8ZD,go8Z];by_cases h:t< n . rw[Ἄ h,Ἄ h];dsimp only;rw[dnU T hT W (wo+t) _ (wi wo t n W hw hs (А.mp h))];exact g8ZE T hT xs W hd wo n (t+1) _ hx hsx hs hw _ _ _ _ _ _ _ _ _ _ _ r r' . rw[ἔ h,ἔ h];cases r;cases r';rfl termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];have:=А.mp h;(clear h; omega) /-! Weight setup cache: inside one process a layer's weights stay fixed, so their decoded form and bound are built once per weight array and reused by later calls; outputs are unchanged. -/ def wbI (W:ѐ) (m r i:Ὣ) (a:ὤ):ὤ:= if i< m then wbI W m r (i+1) (((((((((a.push (dv W[r*m+i]!)).push (dv W[(r+1)*m+i]!)).push (dv W[(r+2)*m+i]!)).push (dv W[(r+3)*m+i]!)).push (dv W[(r+4)*m+i]!)).push (dv W[(r+5)*m+i]!)).push (dv W[(r+6)*m+i]!)).push (dv W[(r+7)*m+i]!))) else a partial_fixpoint def wbO (W:ѐ) (m nb c:Ὣ) (a:ὤ):ὤ:= if c< nb then wbO W m nb (c+1) (wbI W m (8*c) 0 a) else a partial_fixpoint def wbIT (W:ѐ) (m r o i:Ὣ) (a:ὤ):ὤ:= if i< m then wbIT W m r o (i+1) ((((((((a.push (dv W[(min (r+0) (o-1))*m+i]!)).push (dv W[(min (r+1) (o-1))*m+i]!)).push (dv W[(min (r+2) (o-1))*m+i]!)).push (dv W[(min (r+3) (o-1))*m+i]!)).push (dv W[(min (r+4) (o-1))*m+i]!)).push (dv W[(min (r+5) (o-1))*m+i]!)).push (dv W[(min (r+6) (o-1))*m+i]!)).push (dv W[(min (r+7) (o-1))*m+i]!)) else a partial_fixpoint def wbZ (n:Ὣ):ὤ:=(((((ἆ (n+8)).push 0).push 0).push 0).push 0).push 0 def wbOf (m o:Ὣ) (W:ѐ):ὤ:=let a:=wbO W m (o/8) 0 (wbZ ѧW);if o%8=0 then a else wbIT W m (8*(o/8)) o 0 a abbrev WVB (m o:Ὣ) (W:ѐ):=({p:ὤ×ὥ//p=(wbOf m o W,scanH 2 W)}) local instance wvbSub (m o:Ὣ) (W:ѐ):Subsingleton (WVB m o W):=⟨λa b=>Subtype.ext (a.2.trans b.2.symm)⟩ structure WEB where (w:ѐ) (m o:Ὣ) (p:ὤ×ὥ) (g:ὦ) (ok:p=(wbOf m o w,scanH 2 w)) def wbF (m o:Ὣ) (W:ѐ) (g:ὦ) (s:Array WEB) (i:Ὣ):Option (WVB m o W):= if h:i< s.size then if s[i].g==g then if ho:s[i].m=m∧s[i].o=o then if hk:withPtrEq s[i].w W (λ_=>s[i].w==W) (λe=>by rw[e];exact beq_self_eq_true W) then some ⟨s[i].p,by rw[←ho.1,←ho.2,←eq_of_beq hk];exact s[i].ok⟩ else wbF m o W g s (i+1) else wbF m o W g s (i+1) else wbF m o W g s (i+1) else none partial_fixpoint @[noinline] def wbS:ST.Ref Unit (Array WEB):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def wbGet (m o:Ὣ) (W:ѐ):WVB m o W:= withPtrAddr W (λg=> let s:=(ST.Prim.Ref.get wbS (Void.mk ())).val match wbF m o W g s 0 with | some v=>v | none=> let p:=(wbOf m o W,scanH 2 W) let old:=(ST.Prim.Ref.swap wbS (#[⟨W,m,o,p,g,rfl⟩]++(if s.size<256 then s else s.pop)) (Void.mk ())).val match wbF m o W g old 0 with | some v=>v | none=>⟨p,rfl⟩) (λ_ _=>Subsingleton.elim _ _) lemma qUs (a:ὤ) (i:ὦ) (v:ὧ) (h:Ѥi< Ѩa):(a.uset i v h).size=Ѩa:=by obtain ⟨ds⟩:=a;exact Array.size_uset _ def decE (X:ѐ) (o n t:ὦ) (buf:ὤ) (l:ὧ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (hb:Ѥn<=Ѩbuf):R2 := if h:t< n then have ht:=А.mp h let v:=dv (X.uget (o+t) (wi o t n X hX hs ht)) decE X o n (t+1) (buf.uset t v (by omega)) (l+v.abs) hX hs (by rw[qUs];exact hb) else ⟨buf,l,true⟩ partial_fixpoint @[inline] def decF (X:ѐ) (o n:ὦ) (buf:ὤ) (l:ὧ):R2 := if hh:Ѥo+Ѥn<=ѧX∧ѧX<=4294967295∧Ѥn<=Ѩbuf∧Ѩbuf<=4294967295 then decE X o n 0 buf l hh.1 (by have:=hh.2.1;omega) hh.2.2.1 else decD X o n 0 buf l structure R3 where (buf:ὤ) (l:ὧ) (lo hi:ὥ) local instance ecNe7:Nonempty R3:=⟨by constructor <;> exact default⟩ def decV (X:ѐ) (o n t:ὦ) (buf:ὤ) (l:ὧ) (lo hi:ὥ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (hb:Ѥn<=Ѩbuf):R3 := if h:t< n then have ht:=А.mp h let w:=X.uget (o+t) (wi o t n X hX hs ht) let v:=w &&& В let u:=v-1 let d:=dv w decV X o n (t+1) (buf.uset t d (by omega)) (l+d.abs) (if u< lo then u else lo) (if hi< v then v else hi) hX hs (by rw[qUs];exact hb) else ⟨buf,l,lo,hi⟩ termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];exact Nat.sub_lt_sub_left (А.mp h) (Nat.lt_succ_self _) def bOf (b:ѐ):ὤ:=⟨b.map dv⟩ def bOfF (b:ѐ):ὤ:=b.foldl (λa w=>a.push (dv w)) (ἆ b.size) theorem bOfF_eq (b:ѐ):bOfF b=bOf b:=dnFold _ b abbrev WVN (m o:Ὣ) (W b:ѐ):=({p:(ὤ×ὥ)×(ὤ×ὥ)//p=((wbOf m o W,scanH 2 W),(bOf b,scanH 1 b))}) structure WEN where (w b:ѐ) (m o:Ὣ) (p:(ὤ×ὥ)×(ὤ×ὥ)) (g:ὦ) (ok:p=((wbOf m o w,scanH 2 w),(bOf b,scanH 1 b))) def wnF (m o:Ὣ) (W b:ѐ) (g:ὦ) (s:Array WEN) (i:Ὣ):Option (WVN m o W b):= if h:i< s.size then if s[i].g==g then if ho:s[i].m=m∧s[i].o=o then if hk:withPtrEq s[i].w W (λ_=>s[i].w==W) (λe=>by rw[e];exact beq_self_eq_true W) then if hk2:withPtrEq s[i].b b (λ_=>s[i].b==b) (λe=>by rw[e];exact beq_self_eq_true b) then some ⟨s[i].p,by rw[←ho.1,←ho.2,←eq_of_beq hk,←eq_of_beq hk2];exact s[i].ok⟩ else wnF m o W b g s (i+1) else wnF m o W b g s (i+1) else wnF m o W b g s (i+1) else wnF m o W b g s (i+1) else none partial_fixpoint @[noinline] def wnS:ST.Ref Unit (Array WEN):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def wnGet (m o:Ὣ) (W b:ѐ):WVN m o W b:= withPtrAddr W (λg=> let s:=(ST.Prim.Ref.get wnS (Void.mk ())).val match wnF m o W b g s 0 with | some v=>v | none=> let p:=((wbOf m o W,scanH 2 W),(bOfF b,scanH 1 b)) let old:=(ST.Prim.Ref.swap wnS (#[⟨W,b,m,o,p,g,(congrArg (((wbOf m o W,scanH 2 W),·)) (congrArg (·,scanH 1 b) (bOfF_eq b)))⟩]++(if s.size<256 then s else s.pop)) (Void.mk ())).val match wnF m o W b g old 0 with | some v=>v | none=>⟨p,(congrArg (((wbOf m o W,scanH 2 W),·)) (congrArg (·,scanH 1 b) (bOfF_eq b)))⟩) (λ_ _=>Subsingleton.elim _ _) @[inline] def rdB (a:ὤ) (i:ὦ):ὧ:= if h:i< a.usize then a.uget i (qDo a i h) else 0 @[inline] def fin8LB (inW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i j:Ὣ) (s nf a:ὧ) (hx:ὥ) (lo sp:Ὠ) (B:ὤ) (u:ὦ) (n:ὦ):ὥ := let t:=fin1 lo sp (s+rdB B u) if t == Е then fin8n inW relu X W b i j s nf a hx (rdW b u) n else fz relu t @[noinline] def fin8u (inW:Ὣ) (relu:Ὡ) (X W b:@& ѐ) (i:Ὣ) (u:ὦ) (s nf a:ὧ) (hx:ὥ) (n:ὦ):ὥ := fin8 inW relu X W b i Ѥu s nf a hx (rdW b u) n @[inline] def fin8LU (inW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (s nf a:ὧ) (hx:ὥ) (lo sp:Ὠ) (B:ὤ) (u:ὦ) (n:ὦ):ὥ := let t:=fin1 lo sp (s+rdB B u) if t == Е then fin8u inW relu X W b i u s nf a hx n else fz relu t @[noinline] def fN8 (inW:Ὣ) (relu:Ὡ) (X W b:@& ѐ) (i:Ὣ) (B:ὤ) (nf a:ὧ) (hx:ὥ) (lo sp:Ὠ) (m:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ):ѐ := let ju:=ѩj let jv:=(j+4).toUSize let o0:=fin8LU inW relu X W b i s0 nf a hx lo sp B ju m let o1:=fin8LU inW relu X W b i s1 nf a hx lo sp B (ju+1) m let o2:=fin8LU inW relu X W b i s2 nf a hx lo sp B (ju+2) m let o3:=fin8LU inW relu X W b i s3 nf a hx lo sp B (ju+3) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 let ju:=jv let o0:=fin8LU inW relu X W b i s4 nf a hx lo sp B ju m let o1:=fin8LU inW relu X W b i s5 nf a hx lo sp B (ju+1) m let o2:=fin8LU inW relu X W b i s6 nf a hx lo sp B (ju+2) m let o3:=fin8LU inW relu X W b i s7 nf a hx lo sp B (ju+3) m let out:=wrW out (base+ju) o0 let out:=wrW out (base+ju+1) o1 let out:=wrW out (base+ju+2) o2 let out:=wrW out (base+ju+3) o3 out def colsN2 (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb B:ὤ) (nf a:ὧ) (hx:ὥ) (lo sp:Ὠ) (m n:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ):ѐ := if h16:j+16<=outW then let w0:=ѩj*m let yw0:=(j+8).toUSize*m if hg:Ѥn<=Ѩx∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥw0+5+8*Ѥm<=Ѩwb∧Ѥyw0+5+8*Ѥm<=Ѩwb then let rr:=go16V x wb (w0+USize.ofNat 5) (yw0+USize.ofNat 5) m n 0 hg.1 hg.2.2.1 (pk w0 m wb hg.2.2.2.1 hg.2.1).1 (pk yw0 m wb hg.2.2.2.2 hg.2.1).1 (qA9 hg.2.1) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 let out:=fN8 inW relu X W b i B nf a hx lo sp m j base out rr.a rr.b rr.c rr.d rr.e rr.f rr.g rr.k let out:=fN8 inW relu X W b i B nf a hx lo sp m (j+8) base out rr.a' rr.b' rr.c' rr.d' rr.e' rr.f' rr.g' rr.k' colsN2 inW outW relu X W b i ix x wd wb B nf a hx lo sp m n (j+8+8) base out else cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n j base out else cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n j base out partial_fixpoint def colsN3 (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb B:ὤ) (nf a:ὧ) (hx:ὥ) (lo sp:Ὠ) (m n:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ):ѐ := if h24:j+24<=outW then let w0:=ѩj*m let yw0:=(j+8).toUSize*m let zw0:=(j+8+8).toUSize*m if hg:Ѥn<=Ѩx∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥw0+5+8*Ѥm<=Ѩwb∧Ѥyw0+5+8*Ѥm<=Ѩwb∧Ѥzw0+5+8*Ѥm<=Ѩwb then let rr:=go24V x wb (w0+USize.ofNat 5) (yw0+USize.ofNat 5) (zw0+USize.ofNat 5) m n 0 hg.1 hg.2.2.1 (pk w0 m wb hg.2.2.2.1 hg.2.1).1 (pk yw0 m wb hg.2.2.2.2.1 hg.2.1).1 (pk zw0 m wb hg.2.2.2.2.2 hg.2.1).1 (qA9 hg.2.1) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 let out:=fN8 inW relu X W b i B nf a hx lo sp m j base out rr.a rr.b rr.c rr.d rr.e rr.f rr.g rr.k let out:=fN8 inW relu X W b i B nf a hx lo sp m (j+8) base out rr.a' rr.b' rr.c' rr.d' rr.e' rr.f' rr.g' rr.k' let out:=fN8 inW relu X W b i B nf a hx lo sp m (j+8+8) base out rr.a'' rr.b'' rr.c'' rr.d'' rr.e'' rr.f'' rr.g'' rr.k'' colsN3 inW outW relu X W b i ix x wd wb B nf a hx lo sp m n (j+8+8+8) base out else colsN2 inW outW relu X W b i ix x wd wb B nf a hx lo sp m n j base out else colsN2 inW outW relu X W b i ix x wd wb B nf a hx lo sp m n j base out partial_fixpoint def linF0 (rows inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ):ѐ := let hw:=scanW rows W if rows*inW=ѧX∧outW*inW=ѧW∧outW=ѧb∧0< inW∧0< outW∧inW<2^20 ∧ ѧX<=4294967295∧ѧW<=4294967295∧ѧb<=4294967295∧rows*outW<=4294967295 ∧ scanH 0 X≠Е∧hw≠Е∧scanH 1 b≠Е then let n:=ѩinW let nf:ὧ:=(inW.toUInt64+8).toFloat*Ἃ 0x3CA0000000000000 let out:ѐ:=ἇ (rows*outW) 0 if rows == 1 then let p:=(wbGet inW outW W).1 if p.2≠Е then let v:=decF X (0*inW).toUSize n (zFor inW) 0 if v.ok && inW<=8192 then cols1VS inW outW relu X W b 0 idA v.buf (ἆ 0) p.1 nf v.l p.2 (loOf (nf*(dv p.2*v.l+dv (scanH 1 b)))) n n 0 (0*outW).toUSize (ἇ (1*outW) 0) else linearWith dotFn rows inW outW relu X W b else linearWith dotFn rows inW outW relu X W b else linearWith dotFn rows inW outW relu X W b else linearWith dotFn rows inW outW relu X W b def fz0:ὧ:=0 @[noinline] def linNc (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (c:@& ((ὤ×ὥ)×(ὤ×ὥ))):ѐ := if 1*inW=ѧX∧outW*inW=ѧW∧outW=ѧb∧0< inW∧0< outW∧inW<2^20∧ѧX<=4294967295∧ѧW<=4294967295∧ѧb<=4294967295∧1*outW<=4294967295∧scanW 1 W≠Е∧c.2.2≠Е∧c.1.2≠Е∧inW<=8192 then let n:=ѩinW let nf:ὧ:=(inW.toUInt64+8).toFloat*Ἃ 0x3CA0000000000000 let o:=(0*inW).toUSize let z:=zFor inW if hz:Ѥo+Ѥn<=ѧX∧Ѥn<=Ѩz∧Ѩz<=4294967295∧ѧX<=4294967295 then let v:=decV X o n 0 z fz0 Е 0 hz.1 (by have:=hz.2.2.2;omega) hz.2.1 if 0x007FFFFF<=v.lo∧v.hi<У then let lo:=loOf (nf*(dv c.1.2*v.l+dv c.2.2)) if 128<=inW then colsN3 inW outW relu X W b 0 idA v.buf (ἆ 0) c.1.1 c.2.1 nf v.l c.1.2 lo (spOf lo) n n 0 (0*outW).toUSize (ἇ (1*outW) 0) else colsN2 inW outW relu X W b 0 idA v.buf (ἆ 0) c.1.1 c.2.1 nf v.l c.1.2 lo (spOf lo) n n 0 (0*outW).toUSize (ἇ (1*outW) 0) else linF0 1 inW outW relu X W b else linF0 1 inW outW relu X W b else linF0 1 inW outW relu X W b def linN (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ):ѐ :=linNc inW outW relu X W b (wnGet inW outW W b).1 def linF (rows inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ):ѐ := if rows == 1 then linN inW outW relu X W b else linF0 rows inW outW relu X W b section noncomputable def R (f:ὧ):ℝ:=Ἢ (toModel (ofFloat f : Binary64)) noncomputable def wv (w:ὥ):ℝ:=Ἢ (ofW w) noncomputable def exactS (n:Ὣ) (xw ww:Ὣ->ὥ) (bw:ὥ):ℝ := (Ἣ n).sum (λt=>wv (xw t)*wv (ww t))+wv bw def nfOf (n:Ὣ):ὧ:=(n.toUInt64+8).toFloat*Ἃ 0x3CA0000000000000 structure C_G (R I O:Ὣ) (X W b:ё):Prop where hX:R*I=ѧX hW:O*I=ѧW hb:O=ѧb pi:0< I po:0< O ni:I<2^20 sX:ѧX<2^32 sW:ѧW<2^32 sb:ѧb<2^32 sO:R*O<2^32 gX:∀ q,q< ѧX->good X[q]! = true gW:∀ q,q< ѧW->good W[q]! = true gb:∀ q,q< ѧb->good b[q]! = true lemma qAj:⟡.isIEEE=true:=by decide lemma qAy (a:Model ⟡) : Ἑ a=(Model.toModel a).isFinite:=by rw[<-Model.toDyadic?_isSome_eq_isFinite,Model.toDyadic?_ieee_eq_model _ qAj];cases Model.toModel a<;>rfl abbrev A_M (x:ὧ):Model ⟡:=Model.ofFloatModel x.toModel lemma A_R (x:ὧ):R x=Ἢ (A_M x):=rfl lemma qAh (x:ὧ):Ἑ (A_M x)=x.isFinite:=by rw[qAy,Ὀ];rfl lemma qA3 {x:ὧ} (h:xᶠ):Ἑ (A_M x)=true :=(qAh x).trans h lemma qA0 (e:ℤ):Formats.Flocq.bpow ἲ e=(2:ℝ)^e:=by simp[Formats.Flocq.bpow,FloatLib.Numerics.binaryRadix,FloatLib.Numerics.Radix.toReal] lemma qCd:(2:ℝ)^(1000:ℤ)<=Ἢ (Model.posMaxFinite ⟡):=by rw[Model.toReal_posMaxFinite,show Model.pow2 ⟡.fracWidth + ⟡.maxFiniteFracField=2^53-1 by decide +kernel, show ⟡.maxNormalExponent-Int.ofNat ⟡.fracWidth=971 by decide +kernel,Model.bpow,qA0,show (1000:ℤ)=29+971 from rfl,Ἓ ἓ] exact ἀ (by norm_num1) (by positivity) open Float.Model.UnpackedFloat in lemma qDv {b:BitVec 64} {s m e h} (a:unpack ⟠ b=.finite s m e h) : 2^52<=m∨e=-1074:=by unfold Float.Model.UnpackedFloat.unpack at a;simp only at a;rw[show (⟠.exponentBias:ℤ)=1023 by decide] at a;split_ifs at a with h1 h2 h3;. injection a with _ _ he;rw[show (unpackExponent (spec:=⟠) b).toNat=0 by simp[h3]] at he;exact omS27 he . injection a with _ hm;rw[<-hm,BitVec.toNat_append];exact .inl (ὂ (by simp[Nat.shiftLeft_eq]) Nat.left_le_or) open Float.Model.UnpackedFloat in lemma qH1 {s₁ s₂ m₁ m₂ e₁ e₂ h₁ h₂} {f g:BitVec 64} (e:unpack ⟠ f=.finite s₁ m₁ e₁ h₁) (b:unpack ⟠ g=.finite s₂ m₂ e₂ h₂) : e₁+e₂<=⟠.targetExponent (Float.Model.totalExponent (m₁*m₂) (e₁+e₂)):=by have a:2^52<=m₁*m₂->52<=(m₁*m₂).log2:=(Nat.le_log2 (Nat.mul_ne_zero h₁.ne' h₂.ne')).2 simp only[Float.Model.Format.targetExponent,Float.Model.totalExponent,Float.Model.Format.mantissaBits,Float.Model.Format.minExponent] (norm_num1) rcases qDv e with c | c . have:=a (c.trans (Ὄ _ h₂));(clear c; omega) rcases qDv b with d | d . have:=a (d.trans (Nat.le_mul_of_pos_left _ h₁));(clear d; omega) omega lemma qB0 (x y:ὧ) (a:xᶠ) (b:yᶠ) : A_M (x*y)=Model.mul (A_M x) (A_M y):=by change Model.ofFloatModel (Float.Model.mul x.toModel y.toModel)=_;rw[Float.Model.mul,Model.ofFloatModel_pack,Model.Proof.mul_eq_spec,Model.Spec.mul];simp only[Model.toDyadic?_ieee_eq_model _ qAj,Model.toModel_ofFloatModel];change x.toModel.unpack.isFinite=true at a;change y.toModel.unpack.isFinite=true at b;have c:∀ s t:Float.Model.UnpackedFloat.Sign,Model.ofModel ⟡ (.zero (s*t)) =Model.zero _ (Ἴ s ^^ Ἴ t):=λs t=>by cases s<;>cases t<;>simp[Model.modelSignBit] <;>first | exact (Model.negZero_eq_ofModel_zero _).symm | exact (Model.posZero_eq_ofModel_zero _).symm cases hxm:x.toModel.unpack<;>cases hym:y.toModel.unpack <;>simp only[hxm,hym,Float.Model.UnpackedFloat.isFinite,Bool.false_eq_true] at a b case finite.finite s₁ m₁ e₁ h₁ s₂ m₂ e₂ h₂ => have d:(m₁ == 0 || m₂ == 0)=false:=by simp[h₁.ne',h₂.ne'] have e:Model.modelSign (Ἴ s₁ ^^ Ἴ s₂)=s₁*s₂:=by cases s₁<;>cases s₂<;>rfl simp only[Model.unpackedToDyadic?,Float.Model.UnpackedFloat.mul];rw[Model.roundWithAccuracy_exact_eq_round_of_le_targetExponent _ _ _ _ (qH1 hxm hym),d];simp only[Bool.false_eq_true,ite_false,Model.roundDyadic,qAj,ite_true,Model.ieeeRoundDyadic,e];rfl all_goals simp[Model.unpackedToDyadic?,Float.Model.UnpackedFloat.mul,c] lemma A_E (z:ὧ) {a:Model ⟡} {c:ℝ} (h:A_M z=a) (b:Ἑ a=true) (d:Ἢ a=Model.roundAt ⟡ c) : zᶠ∧R z=Model.roundAt ⟡ c:=by subst h;exact ⟨(qAh z).symm.trans b,d⟩ lemma qEd (x y:ὧ) (hx:xᶠ) (hy:yᶠ) (hb : |R x| * |R y| ≤ 2^(1000:ℤ)) : (x*y)ᶠ ∧ R (x*y)=Model.roundAt ⟡ (R x*R y) := A_E _ (qB0 x y hx hy) (Model.isFinite_mul_of_abs_mul_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (hb.trans qCd)) (Model.toReal_mul_eq_roundAt_of_abs_mul_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (hb.trans qCd)) noncomputable def A_z:ℝ:=2^(-1021:ℤ) noncomputable def A_B:ℝ:=2^(300:ℤ) lemma qAr:0< A_z:=by unfold A_z;positivity lemma A_p (a b c d:ℤ) (h:a+b<=c+d):(2:ℝ)^a*2^b<=2^c*2^d:=by rw[<-Ἓ ἓ,<-Ἓ ἓ];exact ἒ one_le_two h lemma qAw:A_z<=1/2^200*(1/2^200):=by simpa [A_z] using A_p (-1021) 0 (-200) (-200) (by norm_num1) lemma qI1:0< A_B:=by unfold A_B;positivity lemma qCc:(2:ℝ)^256*2^42<=A_B:=by simpa [A_B] using A_p 256 42 300 0 (by norm_num1) lemma qAn:(2:ℝ)^128<=A_B :=(by (norm_num1):(2:ℝ)^128<=2^256*2^42).trans qCc lemma qE7 {k:ℕ} (h:k<=2^128):(k:ℝ)<=A_B :=(show (k:ℝ)<=2^128 by exact_mod_cast h).trans qAn lemma qE3:A_B*2<=2^(1000:ℤ):=by simpa [A_B] using A_p 300 1 1000 0 (by norm_num1) lemma qDe:A_B*A_B<=2^(1000:ℤ):=by simpa [A_B] using A_p 300 300 1000 0 (by norm_num1) lemma qFp (x:ℝ) : |Model.roundAt ⟡ x-x| ≤ 1/2^53*(|x| + A_z):=by rw[show (1/2^53*(|x| + A_z):ℝ)=2^(-53:ℤ) * |x| + 2^(-1074:ℤ) by rw[show (1/2^53:ℝ)=2^(-53:ℤ) by (norm_num1),show (-1074:ℤ)=-53+-1021 from rfl,Ἓ ἓ (-53),mul_add] rfl] by_cases a:x=0 . rw[a,Model.roundAt_zero,sub_self,abs_zero];positivity refine (Model.abs_roundAt_sub_le _ x).trans ?_ change Formats.Flocq.ulp _ (Model.fexpOf ⟡) x/2<=_ rw[Formats.Flocq.ulp.of_ne_zero _ _ x a] simp only[Formats.Flocq.cexp,Model.fexpOf,Formats.Flocq.fltExp] have b:=Formats.Flocq.bpow_magnitude_sub_one_le ἲ x a rw[qA0] at b rw[qA0,show ((⟡.fracWidth:ℤ)+1)=53 from rfl,show ⟡.minSubnormalExponent=-1074 from rfl] generalize Formats.Flocq.magnitude ἲ x=M at b ⊢ have d:(0:ℝ)<=2^(-53:ℤ) * |x|:=by positivity have c:(0:ℝ)<2^(-1074:ℤ):=by positivity rcases le_total (-1074) (M-53) with h | h . rw[max_eq_left h,show (2:ℝ)^(M-53)/2=2^(-53:ℤ)*2^(M-1) by rw[<-Ἓ ἓ,show (-53:ℤ)+(M-1)=M-53-1 by ring,zpow_sub₀ ἓ _ 1,zpow_one]] linarith [ἁ b (show (0:ℝ)<=2^(-53:ℤ) by positivity)] . rw[max_eq_right h];exact (half_le_self c.le).trans (le_add_of_nonneg_left d) lemma qFc {z:ὧ} {c:ℝ} (h:zᶠ∧R z=Model.roundAt ⟡ c) : zᶠ∧|R z-c| ≤ 1/2^53*(|c| + A_z) :=⟨h.1,h.2 ▸ qFp c⟩ lemma qEe {a b:ℝ} (d : |a| ≤ A_B) (c : |b| ≤ A_B) : |a| + |b| ≤ Ἢ (Model.posMaxFinite ⟡):=by have:=qE3 have:=qCd linarith section variable (x y:ὧ) (hx:xᶠ) (hy:yᶠ) (h1 : |R x| ≤ A_B) (h2 : |R y| ≤ A_B) include x y hx hy h1 h2 lemma qBf : (x+y)ᶠ∧|R (x+y)-(R x+R y)| ≤ 1/2^53*(|R x+R y| + A_z) := qFc (A_E _ (toModel_ofFloat_add_of_isFinite x y hx hy) (Model.isFinite_add_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2)) (Model.toReal_add_eq_roundAt_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2))) lemma qDf : (x-y)ᶠ∧|R (x-y)-(R x-R y)| ≤ 1/2^53*(|R x-R y| + A_z) := qFc (A_E _ (toModel_ofFloat_sub_of_isFinite x y hx hy) (Model.isFinite_sub_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2)) (Model.toReal_sub_eq_roundAt_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2))) lemma qCf : (x*y)ᶠ∧|R (x*y)-R x*R y| ≤ 1/2^53*(|R x*R y| + A_z) :=qFc (qEd x y hx hy ((ἑ h1 h2 (Ἀ _) qI1.le).trans qDe)) end lemma qA2 (m k:ℤ) (hm:m.natAbs<2^53) (hk:-1074<=k) : Model.roundAt ⟡ ((m:ℝ)*2^k)=(m:ℝ)*2^k:=by apply Formats.Flocq.round_preserves_generic;exact (Formats.Flocq.generic_format_FLT_iff (⟡.minSubnormalExponent) (⟡.fracWidth+1) (by decide) _).2 ⟨by decide,⟨m,k⟩,by simp[Formats.Flocq.toReal,qA0],hm,hk⟩ lemma qBk (x:ὧ):R x=Model.unpackedToReal x.toModel.unpack:=by rw[A_R,ἦ qAj,Ὀ] lemma qE0 {f:ὧ} {s m e h} (c:f.toModel.unpack=.finite s m e h) : (Model.ofModel ⟡ (.finite .positive m e h)).toModel=.finite .positive m e h:=by have a:Model.toModel (A_M f)=.finite s m e h:=(Ὀ _).trans c;cases s;. have b:=Model.toModel_neg qAj (A_M f);rw[a] at b;change _=Float.Model.UnpackedFloat.finite .positive m e h at b;rw[<-b];exact Model.toModel_canonicalizeModel _ . rw[<-a];exact Model.toModel_canonicalizeModel _ set_option maxRecDepth 8192 in lemma qBl (f:ὧ) (hf:fᶠ):f.absᶠ∧R f.abs = |R f|:=by have a:A_M f.abs=Model.ofModel ⟡ f.toModel.unpack.abs :=Model.ofFloatModel_pack _;change f.toModel.unpack.isFinite=true at hf;cases hu:f.toModel.unpack with | notANumber | infinity _=>simp[hu,Float.Model.UnpackedFloat.isFinite] at hf | zero s => rw[hu] at a;refine ⟨by rw[<-qAh,a];exact Model.isFinite_ofModel_zero _ qAj _,?_⟩;rw[A_R f.abs,a,qBk f,hu];simp[Float.Model.UnpackedFloat.abs,Model.toReal_ofModel_zero _ (FloatFormat.supportsSignedZero_eq_true_of_isIEEE _ qAj)] | finite s m e h => have b:=qE0 hu;rw[hu] at a;have c:A_M f.abs=Model.ofModel ⟡ (.finite .positive m e h):=a;refine ⟨by rw[<-qAh,c,qAy,b];rfl,?_⟩;rw[A_R f.abs,c,qBk f,hu,ἦ qAj,b];simp only[Model.unpackedToReal_finite,qA0];cases s<;>simp[Model.modelSignBit,abs_of_nonneg (by positivity:(0:ℝ)<=(m:ℝ)*2^e)] lemma qCl (f:ὧ) (k:ℕ) (g:k<2^53) (e:f.toModel=Float.Model.pack (Float.Model.UnpackedFloat.ofNat ⟠ k)) : fᶠ∧R f=k:=by obtain ⟨d,b,c⟩:∃ d,A_M f=ἕ ⟡ d∧d.toReal=k:=by refine ⟨.ofScaledInt k 0,?_,?_⟩;. change Model.ofFloatModel f.toModel=_;rw[e,Model.ofFloatModel_pack];exact Model.ofModel_ofInt_eq_roundDyadic _ qAj (k:ℤ) . rw[<-Ἠ,FloatLib.Numerics.Dyadic.ofScaledInt_toRat];simp have a:Ἑ (A_M f)=true:=by rw[b];apply Model.isFinite_roundDyadic_of_isIEEE_of_abs_toReal_le_posMaxFinite _ qAj;rw[c,ἅ (Ἔ _)];exact ((qE7 ((by exact Nat.le_of_lt (Nat.lt_of_lt_of_le ‹_› (by decide))):k<=2^128)).trans ((le_mul_of_one_le_right qI1.le one_le_two).trans qE3)).trans qCd refine ⟨(qAh f).symm.trans a,?_⟩;rw[A_R,b,Model.toReal_roundDyadic_eq_roundAt _ qAj _ (b ▸ a),c];simpa using qA2 k 0 (by simpa using g) (by norm_num1) lemma qCk (m:Ὠ) (h:Ѧm<2^53):m.toFloatᶠ∧R m.toFloat=Ѧm :=qCl _ _ h rfl lemma qHg:(0:ὧ)ᶠ∧R 0=0:=by simpa using qCl 0 0 (by positivity) rfl def A_bits (i:ℕ):Ὠ := let e:=(i%256).toUInt64 let s:Ὠ:=if i ≥ 256 then 0x8000000000000000 else 0 if e == 0 then s else s ||| ((e+873) <<< (52:Ὠ)) lemma qCu (i:ℕ):pwEntry i=Ἃ (A_bits i):=by unfold pwEntry A_bits;dsimp only;split<;>rfl def A_chk (i:ℕ):Ὡ := match Ἶ ⟠ (A_bits i).toBitVec with | .finite s m e _=>(Ἴ s == decide (256<=i)) && m == 2^52 && e == ((i%256:ℕ):ℤ)-202 && (i%256 != 0) | .zero _=>i%256 == 0 | _=>false lemma qEm:∀ i,i<512->A_chk i=true:=by decide +kernel lemma qDa (i:ℕ) (b:i<512) : (pwEntry i)ᶠ∧R (pwEntry i) =if i%256=0 then 0 else (if 256<=i then -1 else 1)*2^(((i%256:ℕ):ℤ)-150):=by have a:=qEm i b unfold A_chk at a rw[qCu,qBk] change (Ἃ (A_bits i)).toModel.unpack.isFinite=true∧_ rw[show (Ἃ (A_bits i)).toModel.unpack =Ἶ ⟠ (A_bits i).toBitVec from Model.unpack_pack_unpack _ _] generalize Ἶ ⟠ (A_bits i).toBitVec=u at a cases u with | notANumber | infinity _=>simp at a | zero s => simp only[beq_iff_eq] at a exact ⟨rfl,by simp[a]⟩ | finite s m e h => simp only[Bool.and_eq_true,beq_iff_eq,bne_iff_ne] at a obtain ⟨⟨⟨g,d⟩,f⟩,c⟩:=a refine ⟨rfl,?_⟩ rw[Model.unpackedToReal_finite,qA0,f,g,d,mul_assoc, show ((2^52:ℕ):ℝ)*2^(((i%256:ℕ):ℤ)-202) =2^(((i%256:ℕ):ℤ)-150) by rw[Nat.cast_pow,Nat.cast_ofNat,<-Ἡ,<-Ἓ ἓ] congr 1 push_cast ring] simp only[decide_eq_true_eq,c,↓reduceIte] lemma qCw (i:ℕ) (a:i<512):∃ σ:ℤ,σ.natAbs<=1 ∧ R (pwEntry i)=σ*2^(((i%256:ℕ):ℤ)-150):=by rw[(qDa i a).2];split_ifs;exacts [⟨0,by (positivity),by simp⟩,⟨-1,by (norm_num1),by simp⟩,⟨1,by (norm_num1),by simp⟩] lemma qCm (f:ὧ) (i:ℕ) (g:i<512) (q:fᶠ) (c k:ℤ) (r:c.natAbs<2^53) (s:-900<=k) (m : |R f| ≤ A_B) (l:R f=c*2^k) : (f*pwEntry i)ᶠ∧R (f*pwEntry i)=R f*R (pwEntry i):=by obtain ⟨b,a,d⟩:=qCw i g;have o:((i%256:ℕ):ℤ)-150<=128∧-150<=((i%256:ℕ):ℤ)-150 :=(by clear g r s a; exact omS28);generalize ((i%256:ℕ):ℤ)-150=E at o d;have p : |(b:ℝ)| ≤ 1:=by rw[<-Int.cast_abs,<-Nat.cast_natAbs];exact_mod_cast a have e:=ἵ (two_pos (α:=ℝ)) E;have h : |R (pwEntry i)| ≤ A_B:=by rw[d,ἢ,ἡ e,<-one_mul A_B];exact ἑ p (ἒ one_le_two (by clear g r s a; exact omS29 o)) e.le zero_le_one obtain ⟨j,n⟩:=qEd f _ q (qDa i g).1 ((ἑ m h (Ἀ _) qI1.le).trans qDe);refine ⟨j,?_⟩ have:=qA2 (c*b) (k+E) (by rw[Int.natAbs_mul];have:=Nat.mul_le_mul_left c.natAbs a (clear g s a o; omega)) (by clear g r a; exact omS30 s o) rw[Ἓ ἓ] at this;push_cast at this;rw[n,d,l,show (c:ℝ)*2^k*(b*2^E)=c*b*(2^k*2^E) by ring];exact this lemma qDc (i:ὦ) (h:Ѥi< Ѩpw):pw.uget i h=pwEntry Ѥi:=by simp[FloatArray.uget,qDx] section variable (w:ὥ) include w lemma qAq:(w &&& В).toNat=ѥw%2^31:=by rw[Ἧ];exact Ἂ ѥw 31 lemma qCo:(w &&& 0x7FFFFF).toNat=ѥw%2^23:=by rw[Ἧ];exact Ἂ ѥw 23 lemma qD8:(w >>> 23).toNat=ѥw/2^23:=by rw[UInt32.toNat_shiftRight,Ἱ];rfl lemma qCa:(expOf w).toNat=ѥw/2^23%2^8:=by unfold expOf;rw[Ἧ,qD8];exact Ἂ _ 8 lemma qGl:signOf w=decide (2^31<=ѥw):=by have b:=w.toNat_lt;unfold signOf;have h:((w &&& س).toNat)=(ѥw/2^31%2)*2^31:=by rw[Ἧ];show ѥw &&& 2^31=_;rw[Nat.and_two_pow,Nat.testBit_eq_decide_div_mod_eq];have a:ѥw/2^31%2=0∨ѥw/2^31%2=1 :=(by clear b; exact omS31);rcases a with a | a<;>rw[a]<;>rfl rw[Bool.eq_iff_iff];simp only[bne_iff_ne,ne_eq,decide_eq_true_eq];rw[<-ἠ,h];simp only[UInt32.toNat_zero];exact omS32 b lemma qHa : ((w &&& 0x7FFFFF) ||| 0x800000).toNat=2^23+ѥw%2^23:=by rw[UInt32.toNat_or,qCo,Nat.or_comm];simpa using (Nat.two_pow_add_eq_or_of_lt (Nat.mod_lt ѥw (by positivity:2^23 > 0)) 1).symm lemma qAz (h:good w=true) : ѥw%2^31=0∨(2^23<=ѥw%2^31∧ѥw%2^31<У):=by have a:=qAq w;have b:=(w &&& В).toNat_lt;unfold good at h;simp only[Bool.or_eq_true,beq_iff_eq,decide_eq_true_eq] at h;rcases h with h | h;. left;rw[<-a,h];rfl . right;rw[ἃ,UInt32.toNat_sub] at h;rw[<-a];generalize (w &&& В).toNat=v at *;simp at h;(clear b; exact omS33 a h) lemma qAe (h:good w=true):expOf w≠255:=by intro he;have a:=qCa w;rw[he] at a;change 255=_ at a;have:=qAz w h;have:=w.toNat_lt;(clear he this; exact omS34 a this) end noncomputable def A_mag (v:ℕ):ℝ := if v=0 then 0 else ((2^23+v%2^23:ℕ):ℝ)*2^(((v/2^23:ℕ):ℤ)-150) lemma qAs (v:ℕ):0<=A_mag v:=by unfold A_mag;split_ifs<;>positivity lemma qA7 (w:ὥ) (hg:good w=true) : wv w=(if 2^31<=ѥw then -1 else 1)*A_mag (ѥw%2^31):=by have g:=w.toNat_lt;have:=qAz w hg;have a:=qCa w;have d:(fracOf w).toNat=ѥw%2^23:=qCo w;have f:wv w=(decodeD w).toReal:=by unfold wv ofW;rw[Model.toReal_eq,ἶ w (qAe w hg)] rw[f];unfold decodeD A_mag;by_cases c:ѥw%2^31=0;. have b:expOf w=0:=ἠ.mp (by rw[a];show _=0;(clear g this; exact omS35 c));have e:fracOf w=0:=ἠ.mp (by rw[d];show _=0;(clear g this a b; exact omS36 c));simp only[b,e,c,↓reduceIte];simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand] . have b:expOf w≠0:=λh=>by rw[h] at a;change 0=_ at a;(clear g h; exact omS37 this c a) simp only[b,c,↓reduceIte];rw[show ѥw%2^31%2^23=(fracOf w).toNat by rw[d];(clear g this a c b; exact omS38),show ѥw%2^31/2^23=(expOf w).toNat by rw[a];(clear g this c b; exact omS39)];simp only[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,qGl];simp;split_ifs<;>ring lemma qFb (v:ℕ) (h:v<У):A_mag v<=2^128:=by unfold A_mag;split_ifs with h0;. positivity . exact (ἑ (show ((2^23+v%2^23:ℕ):ℝ)<=((2^24:ℕ):ℝ) from Nat.cast_le.2 (by clear h h0; exact omS40)) (ἒ one_le_two (by (clear h0; exact omS41 h):_<=(104:ℤ))) (by positivity) (by positivity)).trans_eq (by norm_num1) lemma qA6 (a b:ℕ) (hab:a<=b) (ha:a=0∨2^23<=a):A_mag a<=A_mag b:=by rcases ha with rfl | ha;. simpa [A_mag] using qAs b unfold A_mag;simp only[show ¬ a=0 by (clear hab; exact omS42 ha),show ¬ b=0 by exact omS43 hab ha,↓reduceIte];have c:a/2^23<=b/2^23:=Nat.div_le_div_right hab;rcases c.eq_or_lt with d | g;. rw[d];exact ἀ (Nat.cast_le.2 (by clear ha c; exact omS44 hab d)) (by positivity) . have e:(2:ℝ)^(((a/2^23:ℕ):ℤ)-150)*2<=2^(((b/2^23:ℕ):ℤ)-150):=by rw[<-zpow_add_one₀ ἓ];exact ἒ one_le_two (by clear hab ha c; exact omS45 g) have f:((2^23:ℕ):ℝ)<=((2^23+b%2^23:ℕ):ℝ):=Nat.cast_le.2 (by clear hab ha c g; exact omS46) calc _<=((2^23*2:ℕ):ℝ)*2^(((a/2^23:ℕ):ℤ)-150) := ἀ (Nat.cast_le.2 (by clear hab ha c g; exact omS47)) (by positivity) _=((2^23:ℕ):ℝ)*(2^(((a/2^23:ℕ):ℤ)-150)*2):=by push_cast;ring _<=_:=ἑ f e (by positivity) (by positivity) abbrev A_mf (w:ὥ):ὧ:=((w &&& 0x7FFFFF) ||| 0x800000).toFloat lemma qD1 (w:ὥ):pw.uget (w >>> 23).toUSize (qCh w) =pwEntry (ѥw/2^23)∧ѥw/2^23<512∧(A_mf w)ᶠ ∧ (A_mf w*pwEntry (ѥw/2^23))ᶠ ∧ R (A_mf w*pwEntry (ѥw/2^23))=R (A_mf w)*R (pwEntry (ѥw/2^23)) ∧ R (A_mf w)=((2^23+ѥw%2^23:ℕ):ℝ):=by have g:=w.toNat_lt;have c:=qHa w;obtain ⟨d,a⟩:=qCl (A_mf w) _ (by rw[c];(clear g; (clear c; exact omS48))) rfl;rw[c] at a;have b:ѥw/2^23<512 :=(by exact omS49 g) obtain ⟨f,e⟩:=qCm _ _ b d ((2^23+ѥw%2^23:ℕ):ℤ) 0 (by clear g b; (clear c; omega)) (by norm_num1) (by rw[a,ἅ (Ἔ _)] exact qE7 (by clear g b; (clear c; exact omS51))) (by rw[a,zpow_zero,mul_one,Int.cast_natCast]) refine ⟨?_,b,d,f,e,a⟩;rw[qDc,ὃ,qD8] lemma qDvF (w:ὥ):(dv w)ᶠ:=by obtain ⟨g,-,-,e,-,-⟩:=qD1 w;unfold dv;rw[g];exact e lemma qAm (w:ὥ) (hg:good w=true):(dv w)ᶠ∧R (dv w)=wv w:=by obtain ⟨g,a,-,e,d,c⟩:=qD1 w;have j:=w.toNat_lt;unfold dv;rw[g];refine ⟨e,?_⟩;rw[d,c,(qDa _ a).2,qA7 w hg];have b:=qAz w hg;generalize ѥw=v at *;rcases b with h | ⟨l,k⟩;. rw[h];simp only[show v/2^23%256=0 by (clear a j; exact omS52 h),↓reduceIte,mul_zero,show A_mag 0=0 by simp[A_mag]] . have f:(256<=v/2^23) ↔ 2^31<=v :=(by exact omS53);unfold A_mag;rw[((by clear a j f; exact omS54):v%2^31/2^23=v/2^23%256),((by clear a j l k f; exact omS38):v%2^31%2^23=v%2^23),ἐ ((by clear a j f; exact omS55 l):¬ v/2^23%256=0),ἐ ((by clear a j f; exact omS56 l):¬ v%2^31=0)];by_cases i:2^31<=v<;>simp only[f,i,↓reduceIte]<;>ring def A_fsum (l:List ὧ):ὧ:=l.foldl (.+·) 0 noncomputable def A_sa (l:List ὧ):ℝ:=(l.map λq=>|R q|).sum noncomputable def A_sr (l:List ὧ):ℝ:=(l.map R).sum lemma qC4 {a:Type} (l:List a) (f:a->ℝ):0<=(l.map λq=>|f q|).sum :=List.sum_nonneg (by simp only[List.mem_map];rintro _ ⟨q,_,rfl⟩;exact Ἀ _) lemma qCe (l:List ὧ):0<=A_sa l:=qC4 l R lemma qGr (l:List ὧ) (q:ὧ):A_sa (l ++ [q])=A_sa l + |R q| ∧ A_sr (l ++ [q])=A_sr l+R q∧A_fsum (l ++ [q])=A_fsum l+q:=by simp[A_sa,A_sr,A_fsum] lemma qC7 (l:List ὧ) : |A_sr l| ≤ A_sa l:=by induction l with | nil=>simp[A_sa,A_sr] | cons q l ih => simp only[A_sa,A_sr,List.map_cons,List.sum_cons] at ih ⊢;exact (Ἐ _ _).trans (by linarith only [ih]) lemma qBo:A_z<=1:=qAw.trans (by norm_num1) section variable (l:List ὧ) (hf:∀ q∈l,qᶠ) (hlen:ѣl<=2^21) (hb:A_sa l<=A_B/4) include l hf hlen hb lemma qDd : (A_fsum l)ᶠ ∧ |R (A_fsum l)-A_sr l| ≤ (1+1/2^22)*ѣl*(1/2^53*(A_sa l+A_z)):=by have e2AB6:A_B/4<=A_B:=div_le_self qI1.le (by norm_num) induction l using List.reverseRecOn with | nil=>exact ⟨qHg.1,by simp[A_fsum,qHg.2,A_sr]⟩ | append_singleton l q ih => obtain ⟨e,f,n⟩:=qGr l q rw[e] at hb rw[List.length_append,List.length_singleton] at hlen have t:=qCe l have j:=Ἀ (R q) obtain ⟨h,v⟩:=ih (λx i=>hf x (by simp[i])) (by exact Nat.le_of_lt ‹_›) ((le_add_of_nonneg_right j).trans hb) have u:(ѣl:ℝ)+1<=2^21:=by exact_mod_cast hlen have d:(0:ℝ)<=ѣl:=Ἔ _ have y:=qC7 l have o:=qAr have m:=qBo have p:=qAn have s:=abs_sub_abs_le_abs_sub (R (A_fsum l)) (A_sr l) have w:=ἀ ((le_add_of_nonneg_right zero_le_one).trans u:(ѣl:ℝ)<=2^21) (add_nonneg t o.le) obtain ⟨b,z⟩:=qBf _ q h (hf q ג) (by linarith only [hb, j, v, y, m, p, s, w]) ((le_add_of_nonneg_left t).trans (hb.trans e2AB6)) rw[n,e,f,List.length_append,List.length_singleton] refine ⟨b,?_⟩ push_cast generalize R (A_fsum l)=r at * generalize R q=a at * generalize A_sa l=P at * generalize A_sr l=S at * generalize (ѣl:ℝ)=k at * obtain ⟨W,g⟩:∃ W:ℝ,W=1/2^53*(P + |a| + A_z):=⟨_,rfl⟩ have c:0<=W :=(mul_nonneg (one_div_nonneg.mpr (pow_nonneg zero_le_two 53)) (add_nonneg (add_nonneg t j) o.le)).trans_eq g.symm rw[<-g] refine (abs_sub_le _ (r+a) (S+a)).trans ?_ rw[add_sub_add_right_eq_sub] linarith only [z, v, y, s, g, c, Ἐ r a,ἁ (show 1/2^53*(P+A_z)<=W from (mul_le_mul_of_nonneg_left (add_le_add (le_add_of_nonneg_right j) le_rfl) (one_div_nonneg.mpr (pow_nonneg zero_le_two 53))).trans_eq g.symm) d,ἀ ((le_add_of_nonneg_right zero_le_one).trans u:k<=2^21) c] lemma qBz : (A_fsum l)ᶠ ∧ |R (A_fsum l)-A_sr l| ≤ 2*ѣl*(1/2^53*(A_sa l+A_z)):=by obtain ⟨a,b⟩:=qDd l hf hlen hb have c:=Ἆ (Nat.cast_nonneg (α:=ℝ) ѣl) (add_nonneg (qCe l) qAr.le) exact ⟨a,b.trans (by linarith only [c])⟩ end lemma qB7 (l:List ὧ) (c:∀ q∈l,qᶠ) (d:ѣl<=2^21) (f:A_sa l<=A_B/4) : (A_fsum (l.map Float.abs))ᶠ ∧ |R (A_fsum (l.map Float.abs))-A_sa l| ≤ 2*ѣl*(1/2^53*(A_sa l+A_z)):=by have a:A_sa (l.map Float.abs)=A_sa l∧A_sr (l.map Float.abs)=A_sa l:=by constructor<;>simp only[A_sa,A_sr,List.map_map]<;>congr 1 <;>exact ὠ λq b=>by simp[(qBl q (c q b)).2] have:=qBz (l.map Float.abs) (λq b=>by obtain ⟨x,e,rfl⟩:=List.mem_map.mp b exact (qBl x (c x e)).1) (by simpa) (a.1.symm ▸ f) rwa [a.1,a.2,List.length_map] at this lemma qIn (n:ℕ) (g:n<2^20) : (nfOf n)ᶠ∧R (nfOf n)=((n:ℝ)+8)/2^53:=by have b:(n.toUInt64+8).toNat=n+8:=by have c:(8:Ὠ).toNat=8:=rfl;simp[UInt64.toNat_add,c];(clear c; exact omS57 g) obtain ⟨f,a⟩:=qCk (n.toUInt64+8) (by rw[b];exact omS58 g);rw[b] at a obtain ⟨e,d⟩:=qCm _ 97 ב f ((n+8:ℕ):ℤ) 0 (by omega) ב (by rw[a,ἅ (Ἔ _)] exact qE7 (by exact omS60 g)) (by rw[a];simp) push_cast at a;rw[show nfOf n=(n.toUInt64+8).toFloat*pwEntry 97 by rw[nfOf,qCu];rfl];refine ⟨e,?_⟩;rw[d,a,(qDa 97 ב).2];norm_num;ring lemma qGb {n:ℕ} (l:n<2^20) {s t:ὧ} (k:sᶠ) (m:tᶠ) {X Y:ℝ} (e:0<=Y) (v:Y<=A_B/8) (y : |R s-X| ≤ ((n:ℝ)+4)*(1/2^53*Y)+1/2^250) (u : |R t-Y| ≤ Y/2^30+1/2^250) (I : |R s| ≤ 2*Y) (c:(2:ℝ)^(-127:ℤ) ≤ |R (s+nfOf n*t)|) : R (s-nfOf n*t)< X∧X< R (s+nfOf n*t):=by have sck:∀ {k a b:ℝ},0(le_div_iff₀' hk).mp (h.trans_eq (one_div_mul_eq_div _ _)) have e2d:∀ {x:ℝ} (n:ℕ),0<=x->1/2^n*x<=x:=fun n h0=>mul_le_of_le_one_left h0 (div_le_one_of_le₀ (one_le_pow₀ one_le_two) (pow_nonneg zero_le_two n)) have e2aa:∀ (x y:ℝ),|x| ≤ |y| + |x-y|:=fun x y=>sub_le_iff_le_add'.mp (abs_sub_abs_le_abs_sub x y) have A:(n:ℝ)+1<=2^20:=by exact_mod_cast l have o:(0:ℝ)<=n:=Ἔ n;obtain ⟨h,b⟩:=qIn n l;have E:=qAr;have B:=qAw have B':(2:ℝ)^200*(2^200*A_z) ≤ 1:=(le_div_iff₀' (by norm_num1)).mp ((le_div_iff₀' (by norm_num1)).mp (B.trans_eq (one_div_mul_eq_div _ _))) have b':(n:ℝ)+8=R (nfOf n)*2^53:=(div_eq_iff (by norm_num1)).mp b.symm have nf0:0<=R (nfOf n):=b ▸ div_nonneg (add_nonneg o (by norm_num1)) (by norm_num1) have c30:2^30*R (nfOf n)<=1:=by linarith only [b', A] have nf1:R (nfOf n)<=1:=by linarith only [c30, nf0] generalize hε:(1:ℝ)/2^250=ε at y u;have hε1:(2:ℝ)^250*ε=1:=by rw[<-hε];exact mul_one_div_cancel (by norm_num1) have hε0:0<=ε:=by linarith only [hε1] have hε2:ε<=1:=by linarith only [hε1] have y':2^53*|R s-X| ≤ ((n:ℝ)+4)*Y+2^53*ε:=sck (by norm_num1) (y.trans_eq (by ring)) have u':2^30*|R t-Y| ≤ Y+2^30*ε:=(le_div_iff₀' (by norm_num1)).mp (u.trans_eq (by rw[add_div,mul_div_cancel_left₀ _ (by norm_num1)])) have i : |R t| ≤ 2*Y+ε:=by linarith only [e2aa (R t) Y, ἅ e, u', e, hε0] have x' : 2^30*|R (nfOf n)*R t| ≤ 2*Y+ε:=by rw[ἢ,ἅ nf0,<-mul_assoc];exact (ἑ c30 i (Ἀ _) zero_le_one).trans_eq (one_mul _) have h8:(2:ℝ)^3<=A_B:=(pow_le_pow_right₀ one_le_two (Nat.le_of_ble_eq_true rfl:3<=128)).trans qAn have kAB:∀ {x:ℝ},x<=(2*Y+1)+((2*Y+1)+1)->x<=A_B:=fun h=>h.trans (by linarith only [v, h8]) have nn':(0:ℝ)<=2*Y+1:=add_nonneg (mul_nonneg zero_le_two e) zero_le_one have nn:(0:ℝ)<=(2*Y+1)+1:=add_nonneg nn' zero_le_one obtain ⟨d,f⟩:=qCf _ _ h m ((ἅ nf0).le.trans (nf1.trans ((one_le_pow₀ one_le_two).trans qAn))) (kAB (i.trans (add_le_add (le_add_of_nonneg_right zero_le_one) (hε2.trans (le_add_of_nonneg_left nn'))))) have Xa : |R (nfOf n)*R t| ≤ 2*Y+1:=by linarith only [x', hε2, e, hε0] have G6:=kAB ((e2aa _ (R (nfOf n)*R t)).trans (add_le_add Xa ((f.trans (e2d 53 (add_nonneg (Ἀ _) E.le))).trans (add_le_add Xa qBo)))) have D:=e2aa (R (nfOf n*t)) (R (nfOf n)*R t) obtain ⟨z,j⟩:=qBf s _ k d (kAB (I.trans (le_add_of_le_of_nonneg (le_add_of_nonneg_right zero_le_one) nn))) G6 obtain ⟨r,g⟩:=qDf s _ k d (kAB (I.trans (le_add_of_le_of_nonneg (le_add_of_nonneg_right zero_le_one) nn))) G6 have H:=e2aa (R (s+nfOf n*t)) (R s+R (nfOf n*t));have q:=Ἐ (R s) (R (nfOf n*t));have p:=Ὕ (R s) (R (nfOf n*t)) rw[zpow_neg,zpow_ofNat,<-one_div] at c;have c':=(div_le_iff₀' (by norm_num1:(0:ℝ)<2^127)).mp c have f':=sck (by norm_num1) f;have j':=sck (by norm_num1) j;have g':=sck (by norm_num1) g have M:=ἀ ((le_add_of_nonneg_right zero_le_one).trans A:(n:ℝ)<=2^20) e have bT:((n:ℝ)+8)*R t=R (nfOf n)*2^53*R t:=by rw[b'] have bY:((n:ℝ)+8)*Y=R (nfOf n)*2^53*Y:=by rw[b'] have nT:=ἁ (neg_abs_le (R t-Y)) nf0;have nU:=ἁ u' nf0;have nE:=ἀ c30 hε0 have pg:=le_abs_self (R (s-nfOf n*t)-(R s-R (nfOf n*t)));have nj:=neg_abs_le (R (s+nfOf n*t)-(R s+R (nfOf n*t))) have pf:=le_abs_self (R (nfOf n*t)-R (nfOf n)*R t);have nf':=neg_abs_le (R (nfOf n*t)-R (nfOf n)*R t) have py:=le_abs_self (R s-X);have ny:=neg_abs_le (R s-X);have nS:=Ἀ (R s);have nP:=Ἀ (R (nfOf n*t)) constructor . linarith only [y', py, g', pg, p, I, f', nf', x', D, bT, bY, nT, nU, nE, M, A, o, e, B', E, hε1, hε0, nf0, c30, c', H, j', q, nS, nP] . linarith only [y', ny, j', nj, q, I, f', nf', x', D, bT, bY, nT, nU, nE, M, A, o, e, B', E, hε1, hε0, nf0, c30, c', H, p, nS, nP] lemma qEv (g h:ℕ->ὧ) (l:List ℕ) (a b:ὧ) : l.foldl (λ(d:F1) t=>F1.mk (d.s+g t) (d.t+h t)) ⟨a,b⟩ =⟨l.foldl (λ(c:ὧ) t=>c+g t) a,l.foldl (λ(c:ὧ) t=>c+h t) b⟩:=by induction l generalizing a b with | nil=>rfl | cons x l ih=>simp only[List.foldl_cons,ih] lemma qC9 (a:List ℕ) (f:ℕ->ℝ) (M:ℝ) (h:∀ t∈a,f t<=M) : (a.map f).sum<=ѣa*M:=by simpa using List.sum_le_sum h section variable (w:ὥ) (hg:good w=true) include w hg lemma qB5 : |wv w| = A_mag (ѥw%2^31):=by rw[qA7 w hg,ἢ,ἅ (qAs _)];split_ifs<;>simp lemma qAo : |wv w| ≤ 2^128:=by rw[qB5 w hg];apply qFb;rcases qAz w hg with h | h<;>omega lemma qBr (h:w &&& В=0):wv w=0:=by rw[qA7 w hg,<-qAq w,h];simp[A_mag] end lemma qHc (a b:ὥ) (ha:good a=true) (hb:good b=true) : (dv a*dv b)ᶠ ∧ |R (dv a*dv b)-wv a*wv b| ≤ 1/2^53*(|wv a*wv b| + A_z) ∧ |wv a*wv b| ≤ 2^256:=by obtain ⟨j,g⟩:=qAm a ha obtain ⟨i,d⟩:=qAm b hb have c:=qAo a ha have e:=qAo b hb obtain ⟨h,f⟩:=qCf _ _ j i (g ▸ c.trans qAn) (d ▸ e.trans qAn) rw[g,d] at f exact ⟨h,f,by rw[ἢ] exact (ἑ c e (Ἀ _) (by positivity)).trans_eq (by norm_num1)⟩ lemma qBs {n:ℕ} {a b:ℕ->ὥ} {f:ὥ} (g:∀ t,t< n->good (a t)=true) (j:∀ t,t< n->good (b t)=true) {l:List ℕ} (k:l.Nodup) (d:∀ t∈l,t< n) (i:∀ t,t< n->t∉l->a t &&& В=0∨b t &&& В=0) : exactS n a b f=(l.map λt=>wv (a t)*wv (b t)).sum+wv f:=by unfold exactS;congr 1;rw[<-List.sum_toFinset _ k];refine (Finset.sum_subset (λt c=>by simpa using d t (by simpa using c)) λt c h=>?_).symm;have e:=Ὁ.mp c;rcases i t e (by simpa using h) with h | h;. simp[qBr (a t) (g t e) h] . simp[qBr (b t) (j t e) h] lemma qFu {n:ℕ} {l:List ℕ} (b:l.Nodup) (a:∀ t∈l,t< n):ѣl<=n:=by simpa using (b.subperm λt h=>List.mem_range.2 (a t h)).length_le abbrev A_G (ts:List ℕ) (g:ℕ->ὧ) (p:ℕ->ℝ):Prop := ∀ t∈ts,(g t)ᶠ∧|R (g t)-p t| ≤ 1/2^53*(|p t| + A_z)∧|p t| ≤ 2^256 lemma qFj {b c:ℕ->ὥ} {l:List ℕ} {n:ℕ} (a:∀ t∈l,t< n) (e:∀ t,t< n->good (b t)=true) (f:∀ t,t< n->good (c t)=true) : A_G l (λt=>dv (b t)*dv (c t)) λt=>wv (b t)*wv (c t) :=λt d=>qHc _ _ (e t (a t d)) (f t (a t d)) lemma qCr {a:List ℕ} {g:ℕ->ὧ} {p:ℕ->ℝ} (b:ὧ) (c:A_G a g p) : let A:=(a.map λt=>|p t|).sum let L:=a.map g ++ [b] |A_sr L-((a.map p).sum+R b)| ≤ 1/2^53*(A+ѣa*A_z) ∧ A_sa L<=A + |R b| + 1/2^53*(A+ѣa*A_z)∧A<=2*A_sa L+ѣa*A_z:=by induction a with | nil=>simp[A_sa,A_sr] | cons x a ih => obtain ⟨d,i,j⟩:=ih (λt e=>c t (by simp[e])) have f:=(c x ג).2.1 simp only[A_sa,A_sr,List.map_cons,List.sum_cons,List.length_cons,List.cons_append] at d i j ⊢ have sck:∀ {k a b:ℝ},0(le_div_iff₀' hk).mp (h.trans_eq (one_div_mul_eq_div _ _)) have m:=qAr have f':=sck (by norm_num1) f have d':=sck (by norm_num1) d have i':=sck (by norm_num1) (sub_le_iff_le_add'.mpr i) have nf:=neg_abs_le (R (g x)-p x);have pf:=le_abs_self (R (g x)-p x) have nd:=neg_abs_le ((List.map R (List.map g a ++ [b])).sum-((List.map p a).sum+R b));have pd:=le_abs_self ((List.map R (List.map g a ++ [b])).sum-((List.map p a).sum+R b)) have k:=Ἀ (p x) have h:=abs_sub_abs_le_abs_sub (p x) (R (g x)) have l:=abs_sub_abs_le_abs_sub (R (g x)) (p x) rw[ἣ] at h refine ⟨abs_le.mpr ⟨?_,?_⟩,?_,?_⟩<;>push_cast . rw[one_div_mul_eq_div,<-neg_div,div_le_iff₀' (by norm_num1)];linarith only [nf, nd, f', d', m, k] . rw[one_div_mul_eq_div,le_div_iff₀' (by norm_num1)];linarith only [pf, pd, f', d', m, k] . rw[<-sub_le_iff_le_add',one_div_mul_eq_div,le_div_iff₀' (by norm_num1)];linarith only [i', l, f', m, k] . linarith only [j, h, f', m, k] lemma qHh (l:List ℕ) (g:ℕ->ὧ) (b:ὧ) : ((l.map g ++ [b]).length:ℝ)=ѣl+1:=by simp lemma qHf {a:List ℕ} {g:ℕ->ὧ} {p:ℕ->ℝ} {b:ὧ} (d:A_G a g p) (c:bᶠ):∀ q∈a.map g ++ [b],qᶠ:=by simp only[List.mem_append,List.mem_map,List.mem_singleton];rintro q (⟨t,e,rfl⟩ | rfl);. exact (d t e).1 . exact c lemma qCs {a:ὥ} (d:good a=true) (h:a<=В) : 0<=wv a∧wv a<=2^128 ∧ ∀ w,good w=true->w &&& В<=a->|wv w| ≤ wv a:=by have g:ѥa<=2147483647:=ἃ.mp h have b:wv a=A_mag ѥa:=by rw[qA7 a d,Ἁ (by exact Nat.lt_succ_of_le ‹_›)] simp only[show ¬ 2^31<=ѥa by (exact Nat.not_lt.mpr ‹_›),↓reduceIte,one_mul] refine ⟨b ▸ qAs _,(le_abs_self _).trans (qAo a d),λw c f=>?_⟩ have e:=ἃ.mp f rw[qAq] at e rw[qB5 _ c,b] exact qA6 _ _ e ((qAz _ c).imp_right (·.1)) section variable {n:ℕ} {ts:List ℕ} {g:ℕ->ὧ} {p:ℕ->ℝ} {bw hh:ὥ} {X Y J:ℝ} {s t a e:ὧ} (A:n<2^20) (B:ѣts<=n) (C:A_G ts g p) (D:good bw=true) (E:X=(ts.map p).sum+wv bw) (F:s=ts.foldl (λ(c:ὧ) t=>c+g t) 0+dv bw) (G:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) include A B C D E F G lemma qEz (k:tᶠ) (b:Y<=A_B/8) (o:A_sa (ts.map g ++ [dv bw])+A_z<=(1+1/2^22)*Y) (u:(1+1/2^22)*((ѣts:ℝ)+1)*(A_sa (ts.map g ++ [dv bw])+A_z) + ((ts.map λt=>|p t|).sum+ѣts*A_z)<=((ѣts:ℝ)+4)*Y+1/2^240) (m : |R t-Y| ≤ Y/2^30+1/2^250) (h:e=nfOf n*t) : R (s-e)< X∧X< R (s+e):=by have e2AB7:∀ {Y:ℝ},0<=Y->Y<=A_B/8->(1+1/2^22)*Y<=A_B/4:=fun hY0 hY=>by linarith only [hY0, hY] subst h obtain rfl:s=A_fsum (ts.map g ++ [dv bw]):=by simp[F,A_fsum,List.foldl_map] obtain ⟨c,d⟩:=qAm bw D obtain ⟨j,-,-⟩:=qCr (dv bw) C rw[d,<-E] at j have i:=qCe (ts.map g ++ [dv bw]) have r:=qAr have l:(ѣts:ℝ)<=n:=by exact_mod_cast B have q:(n:ℝ)+1<=2^20:=by exact_mod_cast A have a:0<=Y :=nonneg_of_mul_nonneg_right ((add_nonneg i r.le).trans o) (by positivity) obtain ⟨f,h⟩:=qDd _ (qHf C c) (by rw[List.length_append,List.length_map,List.length_singleton];exact (Nat.succ_le_of_lt (Nat.lt_of_le_of_lt B A)).trans (Nat.le_of_ble_eq_true rfl)) ((le_add_of_nonneg_right r.le).trans (o.trans (e2AB7 a b))) rw[qHh] at h generalize ts.map g ++ [dv bw]=L at * have x:=qC7 L have y:=ἀ l a have v:=ἑ ((add_le_add l le_rfl).trans q:(ѣts:ℝ)+1<=2^20) o (add_nonneg i r.le) (by positivity) have w:=abs_sub_le (R (A_fsum L)) (A_sr L) X have z:=abs_sub_abs_le_abs_sub (R (A_fsum L)) (A_sr L) exact qGb A f k a b (by linarith only [u, j, h, y, w]) m (by linarith only [r, o, i, h, x, v, z]) G lemma qDi (P:good hh=true) (hp:hh<=В) (U:(ts.map λt=>|p t|).sum<=wv hh*J) (m:aᶠ) (d:0<=J) (z:J<=2^149) (v : |R a-J| ≤ (J+A_z)/2^32) (he:e=nfOf n*(dv hh*a+(dv bw).abs)) : R (s-e)< X∧X< R (s+e):=by have e2pa:∀ {x y:ℝ} {a b j:ℕ},x<=2^a->y<=2^b->a<=j->b<=j->x+y<=2^(j+1):=fun {x y a b j} hx hy ha hb=>(add_le_add (hx.trans (pow_le_pow_right₀ one_le_two ha)) (hy.trans (pow_le_pow_right₀ one_le_two hb))).trans_eq ((two_mul _).symm.trans (pow_succ' 2 j).symm) have e2z0:A_z<=2^0:=qBo.trans_eq (pow_zero 2).symm have e2d:∀ {x:ℝ} (n:ℕ),0<=x->1/2^n*x<=x:=fun n h0=>mul_le_of_le_one_left h0 (div_le_one_of_le₀ (one_le_pow₀ one_le_two) (pow_nonneg zero_le_two n)) have e2AB:∀ {x:ℝ} {k:ℕ},x<=2^k->k+3<=256+42->x<=A_B/8:=fun {x k} h hk=>(le_div_iff₀ (by norm_num:(0:ℝ)<8)).mpr ((mul_le_mul_of_nonneg_right h (by norm_num:(0:ℝ)<=8)).trans ((((congrArg ((2:ℝ)^k*·) (by norm_num:(8:ℝ)=2^3)).trans (pow_add 2 k 3).symm).trans_le ((pow_le_pow_right₀ one_le_two hk).trans_eq (pow_add 2 256 42))).trans qCc)) have e2AB1:∀ {x:ℝ} {k:ℕ},x<=2^k->k<=256+42->x<=A_B:=fun h hk=>h.trans (((pow_le_pow_right₀ one_le_two hk).trans_eq (pow_add 2 256 42)).trans qCc) have e2aa:∀ (x y:ℝ),|x| ≤ |y| + |x-y|:=fun x y=>sub_le_iff_le_add'.mp (abs_sub_abs_le_abs_sub x y) obtain ⟨b,h,-⟩:=qCs P hp;obtain ⟨Q,N⟩:=qAm hh P;obtain ⟨q,j⟩:=qAm bw D;obtain ⟨-,K,-⟩:=qCr (dv bw) C;rw[j] at K;have S:=qAo bw D;generalize wv hh=H at *;have hk:(ѣts:ℝ)+1<=2^20:=by exact_mod_cast (by (exact Nat.lt_of_le_of_lt ‹_› ‹_›):ѣts+1<=2^20) have L:(0:ℝ)<=ѣts:=Ἔ _;have hkN:(ѣts:ℝ)<=2^20:=(le_add_of_nonneg_right zero_le_one).trans hk;have M:=qAr;have x:=qAw;have r:=qC4 ts p;have u:=abs_sub_abs_le_abs_sub (R a) J;rw[ἅ d] at u;obtain ⟨e1,W⟩:=abs_le.mp v;have e3:=ἁ e1 b;have e4:=ἁ W b;have e5:=ἑ h x M.le (by positivity) have e6':=(e2aa (R a) J).trans (add_le_add (ἅ d).le v);have e6 : |H*R a| ≤ H*(J+(J+A_z)/2^32):=by rw[ἢ,ἅ b];exact ἁ e6' b have bRa : |R a| ≤ 2^151:=e6'.trans (e2pa (j:=150) z ((div_le_self (add_nonneg d M.le) (one_le_pow₀ one_le_two)).trans (e2pa (j:=149) z e2z0 le_rfl (Nat.le_of_ble_eq_true rfl))) (Nat.le_of_ble_eq_true rfl) le_rfl) have hRa : |H*R a| ≤ 2^279:=by rw[ἢ,ἅ b];exact (ἑ h bRa (Ἀ _) (by positivity)).trans_eq (pow_add 2 128 151).symm have hW:=Ἆ b d;have hHJ:H*J<=2^128*2^149:=ἑ h z d (by positivity);obtain ⟨o,i⟩:=qCf _ a Q m (by rw[N,ἅ b];exact h.trans qAn) (e2AB1 bRa (Nat.le_of_ble_eq_true rfl));rw[N] at i;have e7:=abs_sub_abs_le_abs_sub (R (dv hh*a)) (H*R a);obtain ⟨w,f⟩:=qBl (dv bw) q;rw[j] at f have bRha : |R (dv hh*a)| ≤ 2^281:=(e2aa _ (H*R a)).trans (e2pa (j:=280) hRa (i.trans ((e2d 53 (add_nonneg (Ἀ _) M.le)).trans (e2pa (j:=279) hRa e2z0 le_rfl (Nat.le_of_ble_eq_true rfl)))) (Nat.le_of_ble_eq_true rfl) le_rfl) obtain ⟨y,k⟩:=qBf _ _ o w (e2AB1 bRha (Nat.le_of_ble_eq_true rfl)) (by rw[f,abs_abs];exact S.trans qAn);rw[f] at k;have e8:=Ἐ (R (dv hh*a)) |wv bw|;rw[abs_abs] at e8;obtain ⟨e9,Z⟩:=abs_le.mp i;obtain ⟨e11,V⟩:=abs_le.mp k;have hkz:=ἀ hkN M.le;have O:=Ἀ (wv bw);obtain ⟨Y,hY⟩:∃ Y,Y=H*J + |wv bw| + A_z:=⟨_,rfl⟩;have c:A_sa (ts.map g ++ [dv bw])+A_z<=(1+1/2^22)*Y :=(by linarith only [hY, O, hkz, r, M, U, K]);have d2 : |H*R a-H*J| ≤ H*((J+A_z)/2^32):=by rw[<-mul_sub,ἢ,ἅ b];exact ἁ v b have d3 : |R (dv hh*a+(dv bw).abs)-Y| ≤ |R (dv hh*a+(dv bw).abs)-(R (dv hh*a)+|wv bw|)|+(|R (dv hh*a)-H*R a|+(|H*R a-H*J|+A_z)):=by rw[hY,show R (dv hh*a+(dv bw).abs)-(H*J+|wv bw|+A_z)=(R (dv hh*a+(dv bw).abs)-(R (dv hh*a)+|wv bw|))+((R (dv hh*a)-H*R a)+((H*R a-H*J)-A_z)) by ring] exact (Ἐ _ _).trans (add_le_add le_rfl ((Ἐ _ _).trans (add_le_add le_rfl ((Ὕ _ _).trans (add_le_add le_rfl (ἅ M.le).le))))) have l : |R (dv hh*a+(dv bw).abs)-Y| ≤ Y/2^30+1/2^250 :=d3.trans (by linarith only [k, i, d2, e8, e7, e6, e5, hY, O, x, M, hW]) have Y0:0<=Y:=(add_nonneg (add_nonneg hW O) M.le).trans_eq hY.symm refine qEz A B C D E F G y (e2AB (k:=279) (hY.trans_le (e2pa (j:=278) (e2pa (j:=277) (hHJ.trans_eq (pow_add 2 128 149).symm) S (Nat.le_of_ble_eq_true rfl) (Nat.le_of_ble_eq_true rfl)) e2z0 (Nat.le_of_ble_eq_true rfl) (Nat.le_of_ble_eq_true rfl))) (Nat.le_of_ble_eq_true rfl)) c ?_ l he have h3:=ἁ c (add_nonneg L zero_le_one);have h4:=ἀ hkN Y0 linarith only [h4, h3, hY, O, hkz, r, x, M, U] lemma qBm {a:ℕ->ὥ} (u:good hh=true) (w:hh<=В) (i:∀ t∈ts,good (a t)=true) (o:∀ t∈ts,|p t| ≤ wv hh * |wv (a t)|) (r:e=nfOf n*(dv hh*ts.foldl (λ(c:ὧ) t=>c+(dv (a t)).abs) 0+(dv bw).abs)) : R (s-e)< X∧X< R (s+e):=by have f:(ѣts:ℝ)<=2^20:=by exact_mod_cast (by (clear w; exact omS61 A B):ѣts<=2^20) have k:A_sa (ts.map λt=>dv (a t))=(ts.map λt=>|wv (a t)|).sum:=by simp only[A_sa,List.map_map];congr 1;exact ὠ λt d=>by simp[(qAm _ (i t d)).2] have h:=(qC9 ts _ _ λt d=>qAo _ (i t d)).trans (ἀ f (by positivity));rw[<-k] at h;have m:=qCc obtain ⟨j,b⟩:=qB7 _ (λq v=>by obtain ⟨t,d,rfl⟩:=List.mem_map.mp v exact (qAm _ (i t d)).1) (by simp;(clear w; exact omS62 A B)) (by linarith only [m, h, D]) rw[List.length_map] at b;have g:=qCe (ts.map λt=>dv (a t));have l:=qAr;refine qDi A B C D E F G u w ?_ j g (h.trans (by norm_num1)) ?_ (r.trans (by simp[A_fsum,List.foldl_map]));. rw[k,<-List.sum_map_mul_left];exact List.sum_le_sum o . refine b.trans ?_;have:=ἀ f (add_nonneg g l.le);linarith only [this, D] end section variable (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) include n hn xw ww lemma qDm (bw:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (l:љ) (hl:l.Nodup) (hl2:∀ t∈l,t< n) (hz:∀ t,t< n->t∉l->xw t &&& В=0∨ww t &&& В=0) (s e:ὧ) (hs:let r:=l.foldl (λ(acc:F1) t=>let q:=dv (xw t)*dv (ww t) F1.mk (acc.s+q) (acc.t+q.abs)) ⟨0,0⟩;s=r.s+dv bw∧e=nfOf n*(r.t+(dv bw).abs)) (hbig:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) : R (s-e)< exactS n xw ww bw∧exactS n xw ww bw< R (s+e):=by have e2pa:∀ {x y:ℝ} {a b j:ℕ},x<=2^a->y<=2^b->a<=j->b<=j->x+y<=2^(j+1):=fun {x y a b j} hx hy ha hb=>(add_le_add (hx.trans (pow_le_pow_right₀ one_le_two ha)) (hy.trans (pow_le_pow_right₀ one_le_two hb))).trans_eq ((two_mul _).symm.trans (pow_succ' 2 j).symm) have e2z0:A_z<=2^0:=qBo.trans_eq (pow_zero 2).symm have e2d:∀ {x:ℝ} (n:ℕ),0<=x->1/2^n*x<=x:=fun n h0=>mul_le_of_le_one_left h0 (div_le_one_of_le₀ (one_le_pow₀ one_le_two) (pow_nonneg zero_le_two n)) have e2AB:∀ {x:ℝ} {k:ℕ},x<=2^k->k+3<=256+42->x<=A_B/8:=fun {x k} h hk=>(le_div_iff₀ (by norm_num:(0:ℝ)<8)).mpr ((mul_le_mul_of_nonneg_right h (by norm_num:(0:ℝ)<=8)).trans ((((congrArg ((2:ℝ)^k*·) (by norm_num:(8:ℝ)=2^3)).trans (pow_add 2 k 3).symm).trans_le ((pow_le_pow_right₀ one_le_two hk).trans_eq (pow_add 2 256 42))).trans qCc)) have e2AB4:A_B/8<=A_B/4:=div_le_div_of_nonneg_left qI1.le (by norm_num) (by norm_num) have e2z250:A_z<=1/2^250:=qAw.trans (by norm_num) simp only[qEv] at hs obtain ⟨hs,E⟩:=hs have a:=qFj hl2 hx hw have f:=qFu hl hl2 obtain ⟨h,i⟩:=qAm bw hb obtain ⟨-,m,y⟩:=qCr (dv bw) a rw[i] at m have b:=qCe (l.map (λt=>dv (xw t)*dv (ww t)) ++ [dv bw]) have k:=qC9 l _ _ λt u=>(a t u).2.2 have v:(ѣl:ℝ)+1<=2^20:=by exact_mod_cast (by (exact Nat.lt_of_le_of_lt ‹_› ‹_›):ѣl+1<=2^20) have o:(0:ℝ)<=ѣl:=Ἔ _ have d:=qAr have D:=qAw have D':(2:ℝ)^200*(2^200*A_z) ≤ 1:=(le_div_iff₀' (by norm_num1)).mp ((le_div_iff₀' (by norm_num1)).mp (qAw.trans_eq (one_div_mul_eq_div _ _))) have w:=qAo bw hb have z:=qCc have A:=qC4 l λt=>wv (xw t)*wv (ww t) have v':(ѣl:ℝ)<=2^20:=(le_add_of_nonneg_right zero_le_one).trans v have p:=(k.trans (ἀ v' (by positivity))).trans_eq (pow_add 2 20 256).symm have C:=ἀ v' d.le have nz:=(C.trans (mul_le_of_le_one_right (pow_nonneg zero_le_two 20) qBo)) have pa:=e2pa (j:=276) p nz (Nat.le_of_ble_eq_true rfl) (Nat.le_of_ble_eq_true rfl) have g:A_sa (l.map (λt=>dv (xw t)*dv (ww t)) ++ [dv bw])+A_z<=A_B/8 :=e2AB (k:=279) (e2pa (j:=278) (m.trans (e2pa (j:=277) (e2pa (j:=276) p w (Nat.le_of_ble_eq_true rfl) (Nat.le_of_ble_eq_true rfl)) ((e2d 53 (add_nonneg A (Ἆ o d.le))).trans pa) (Nat.le_of_ble_eq_true rfl) (Nat.le_of_ble_eq_true rfl))) e2z0 (Nat.le_of_ble_eq_true rfl) (Nat.le_of_ble_eq_true rfl)) (Nat.le_of_ble_eq_true rfl) obtain ⟨j,c⟩:=qB7 _ (qHf a h) (by rw[List.length_append,List.length_map,List.length_singleton];exact (Nat.succ_le_of_lt (Nat.lt_of_le_of_lt f hn)).trans (Nat.le_of_ble_eq_true rfl)) (((le_add_of_nonneg_right d.le).trans g).trans e2AB4) rw[qHh] at c have B:=Ἆ o b have x:=ἀ v (add_nonneg b d.le) have Y0:=add_nonneg b d.le exact qEz hn f a hb (qBs hx hw hl hl2 hz) hs hbig j g (le_mul_of_one_le_left Y0 (le_add_of_nonneg_right (one_div_nonneg.mpr (pow_nonneg zero_le_two 22)))) (by have G:=(abs_le.mp c).1;have F:=(abs_le.mp c).2;linarith only [y, D', C, x, G, F]) ((congrArg (fun r:ℝ=>|r|) (sub_sub _ _ _).symm).trans_le ((Ὕ _ _).trans (add_le_add (c.trans (by linarith only [x, Y0]:_<=(A_sa (l.map (λt=>dv (xw t)*dv (ww t)) ++ [dv bw])+A_z)/2^30)) ((abs_of_pos d).trans_le e2z250)))) (E.trans (by simp[A_fsum,List.foldl_map])) lemma qC8 (bw hv:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (hgv:good hv=true) (hpv:hv<=В) (l:љ) (hl:l.Nodup) (hl2:∀ t∈l,t< n) (hmv:∀ t∈l,ww t &&& В<=hv) (hz:∀ t,t< n->t∉l->xw t &&& В=0) (s e:ὧ) (hs:s=l.foldl (λ(acc:ὧ) t=>acc+dv (xw t)*dv (ww t)) 0+dv bw ∧ e=nfOf n*(dv hv*(l.foldl (λ(acc:ὧ) t=>acc+(dv (xw t)).abs) 0)+(dv bw).abs)) (hbig:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) : R (s-e)< exactS n xw ww bw∧exactS n xw ww bw< R (s+e):=by obtain ⟨hs,b⟩:=hs obtain ⟨-,-,c⟩:=qCs hgv hpv exact qBm hn (qFu hl hl2) (qFj hl2 hx hw) hb (qBs hx hw hl hl2 λt i z=>.inl (hz t i z)) hs hbig hgv hpv (λt a=>hx t (hl2 t a)) (λt a=>by rw[ἢ,mul_comm] exact ἀ (c _ (hw t (hl2 t a)) (hmv t a)) (Ἀ _)) b end end section noncomputable def A_r (b:Ὡ):ℝ:=if b then -1 else 1 lemma qF9 (s t:Ὡ):A_r (s ^^ t)=A_r s*A_r t:=by cases s<;>cases t<;>simp[A_r] lemma qF8 (S T:Ὡ) (X Y:ℝ) (a:0< X) (b:0< Y) (h:A_r S*X=A_r T*Y) : S=T:=by cases S<;>cases T<;>simp[A_r] at h ⊢<;>linarith only [h, b, a] section variable (d:FloatLib.Numerics.Dyadic) include d lemma qD4 : d.toReal=A_r d.negative*((d.significand:ℝ)*2^d.exponent):=by obtain ⟨n,m,e⟩:=d;cases n<;>simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,A_r] lemma A_s:d.toReal=0 ↔ d.significand=0:=by have h:(2:ℝ)^d.exponent≠0:=zpow_ne_zero _ ἓ;rw[qD4];cases d.negative<;>simp[A_r,h] lemma qE9 (h:d.significand≠0) : 0<(d.significand:ℝ)*2^d.exponent :=mul_pos (Nat.cast_pos.mpr (Nat.pos_of_ne_zero h)) (ἵ two_pos _) end lemma qIe (a b:ὧ) (h:A_M a=A_M b):a=b:=by have:=Model.ofFloatModel_injective h;cases a;cases b;simp_all lemma qDk (f:ὧ) (h:fᶠ) : ∃ d,Model.toDyadic? (A_M f)=some d∧d.toReal=R f:=by obtain ⟨d,a⟩:=Model.exists_toDyadic?_of_isFinite ((qAh f).trans h);exact ⟨d,a,by rw[A_R,Model.toReal_eq,a]⟩ lemma qCq {a b:ὧ} {x y:FloatLib.Numerics.Dyadic} (f:Model.toDyadic? (A_M a)=some x) (d:Model.toDyadic? (A_M b)=some y) (e:aᶠ) (c:bᶠ) : A_M (a*b)=if x.significand*y.significand=0 then Model.zero _ (x.negative ^^ y.negative) else ἕ _ ⟨x.negative ^^ y.negative,x.significand*y.significand,x.exponent+y.exponent⟩:=by rw[qB0 a b e c,Model.Proof.mul_eq_spec,Model.Spec.mul,f,d] simp lemma qHe {a b:ὧ} {x y z:FloatLib.Numerics.Dyadic} (m:Model.toDyadic? (A_M a)=some x) (n:Model.toDyadic? (A_M b)=some y) (e:Model.toDyadic? (A_M (a*b))=some z) (k:aᶠ) (l:bᶠ) (c:z.toReal=x.toReal*y.toReal):z.negative=(x.negative ^^ y.negative):=by by_cases g:x.significand*y.significand=0;. have d:=qCq m n k l;simp only[g,↓reduceIte] at d;rw[d,Model.toDyadic?_zero] at e;cases e;show Model.signBit _=_;cases x.negative<;>cases y.negative<;>simp[Model.zero] . obtain ⟨f,i⟩:=Nat.mul_ne_zero_iff.mp g;have j:z.significand≠0:=λh=>by rw[(A_s z).2 h] at c;exact mul_ne_zero (mt (A_s x).1 f) (mt (A_s y).1 i) c.symm rw[qD4 z,qD4 x,qD4 y,mul_mul_mul_comm,<-qF9] at c;exact qF8 _ _ _ _ (qE9 z j) (mul_pos (qE9 x f) (qE9 y i)) c lemma qGg (v m p:ὧ) (f:vᶠ) (i:mᶠ) (h:pᶠ) (u:(v*p)ᶠ) (s:(m*p)ᶠ) (q:R (v*p)=R v*R p) (r:R (m*p)=R m*R p):v*p*m=v*(m*p):=by obtain ⟨a,o,n⟩:=qDk v f;obtain ⟨b,y,k⟩:=qDk p h;obtain ⟨c,w,A⟩:=qDk m i;obtain ⟨d,t,B⟩:=qDk _ u;obtain ⟨e,l,x⟩:=qDk _ s;have D:=qHe o y t f h (by rw[B,n,k,q]);have E:=qHe w y l i h (by rw[x,A,k,r]);have C:(d.negative ^^ c.negative)=(a.negative ^^ e.negative):=by rw[D,E];cases a.negative<;>cases b.negative<;>cases c.negative<;>rfl have j:d.toReal*c.toReal=a.toReal*e.toReal:=by rw[B,A,n,x,q,r];ring have g:d.significand*c.significand=0 ↔ a.significand*e.significand=0:=by simp only[Nat.mul_eq_zero,<-A_s,<-mul_eq_zero,j] apply qIe;rw[qCq t w u i,qCq o l f s];by_cases z:d.significand*c.significand=0;. simp only[z,g.1 z,↓reduceIte,C] . simp only[z,mt g.2 z,↓reduceIte];refine ExactRuntime.roundDyadic_congr _ qAj _ _ z (mt g.2 z) (Rat.cast_injective (α:=ℝ) ?_);rw[Ἠ,Ἠ,Model.Dyadic.toReal_mul,Model.Dyadic.toReal_mul,j] lemma qFw (x w:ὥ) (hx:good x=true) : dvB (dv x) w=dv x*dv w:=by obtain ⟨e,o⟩:=qAm x hx;obtain ⟨p,f,j,q,g,-⟩:=qD1 w;obtain ⟨d,a,-,-,l,b⟩:=qD1 x;obtain ⟨m,c,k⟩:=qCw _ a;have r:=x.toNat_lt;have h:R (dv x)=(((2^23+ѥx%2^23:ℕ)*m:ℤ):ℝ) * 2^(((ѥx/2^23%256:ℕ):ℤ)-150):=by unfold dv;rw[d,l,b,k,Int.cast_mul,Int.cast_natCast,mul_assoc] obtain ⟨n,i⟩:=qCm (dv x) _ f e _ _ (by rw[Int.natAbs_mul,Int.natAbs_natCast];have:=Nat.mul_le_mul_left (2^23+ѥx%2^23) c (clear f a c r; omega)) (by clear f a c r; exact omS63) (by rw[o];exact (qAo x hx).trans qAn) h show dv x*pw.uget _ _*_=dv x*(_*pw.uget _ _);rw[p];exact qGg _ _ _ e j (qDa _ f).1 n q i g end section section open Float.Model Float.Model.UnpackedFloat lemma qFq (t:Int):Format.binary32.targetExponent t=max (t-24) (-149):=by simp[Format.targetExponent,Format.mantissaBits,Format.minExponent] lemma B_z (a b:ℤ) (n:ℕ) (h:a=n+b):(2:ℝ)^a=2^n*2^b:=by rw[h,Ἓ ἓ,Ἡ] lemma qDg (m L:Ὣ) (h1:2^L<=m) (h2:m<2^(L+1)):m.log2=L :=(Nat.log2_eq_iff (by have:=Nat.two_pow_pos L;(clear h2; omega))).2 ⟨h1,h2⟩ lemma qEa (M:Ὣ) (e T:Int) (K r:Ὣ) (d:T=e+(K+1:Ὣ)) (c:0< r) (f:2*(r*2^K)< M+2^K) (g:M<2*(r*2^K)+2^K) : Model.roundMantissaAtExponentEven M e T=r:=by have b:r <<< (K+1)=2*(r*2^K):=by rw[ὁ,Nat.pow_succ];ring have a:Model.pow2 (K+1-1)=2^K:=Model.pow2_eq_two_pow K;rw[Model.roundMantissaAtExponentEven,ἱ (by clear c f g b a; exact omS64 d),show (T-e).toNat=K+1 by (clear c f g b a; exact omS65 d)];rcases le_total (2*(r*2^K)) M with h | h;. have:=Model.roundShiftRightEven_shiftLeft_add_of_lt_half r (M-2*(r*2^K)) (K+1) (by rw[a];(clear d c f b; exact omS66 g h));rwa [b,Nat.add_sub_cancel' h] at this . have:=Model.roundShiftRightEven_shiftLeft_sub_of_lt_half r (2*(r*2^K)-M) (K+1) (by rw[a];(clear d c g b; exact omS67 f h));rwa [b,Nat.sub_sub_self h] at this lemma qEf (s:Sign) (P:Ὣ) (E:Int) (h1:2^23<=P) (h2:P<2^24) (hE:-149<=E) (hp:0< P):Model.finishRoundedMantissa Format.binary32 s (P,E)=.finite s P E hp:=by have:=Model.finishRoundedMantissa_normalized FloatFormat.binary32 s P (E+23) h1 h2 (by show -126<=E+23;(clear h1 h2 hp; exact omS68 hE)) rwa [show E+23-(FloatFormat.binary32.fracWidth:ℤ)=E from Int.add_sub_cancel E 23] at this lemma qBb (neg:Ὡ) (m:Ὣ) (e:Int) : ἕ Fmt ⟨neg,m,e⟩ =Model.ofModel Fmt (UnpackedFloat.round Format.binary32 (Model.modelSign neg) m e):=by simp[Model.roundDyadic,Model.ieeeRoundDyadic] rfl lemma qBn (s:Sign) (M:Ὣ) (E:Int) (h:0< M) (hM1:2^23<=M) (hM2:M<2^24) (hb1:1<=E+150) (hb2:E+150<=254) : (UnpackedFloat.pack Format.binary32 (.finite s M E h)).toNat =(if s=.negative then 2^31 else 0)+(E+150).toNat*2^23+M%2^23:=by simp only[UnpackedFloat.pack,qDg M 23 hM1 hM2] rw[show (E+↑Format.binary32.exponentBias + ↑Format.binary32.mantissaBitsWithoutImplicit).toNat=(E+150).toNat by simp only[Format.exponentBias];(norm_num1);ring_nf] have c:¬ (2^Format.binary32.exponentBits<=(E+150).toNat+1):=by show ¬ (2^8<=(E+150).toNat+1);(clear h hM1 hM2; exact omS69 hb2) have a:(23+1=Format.binary32.mantissaBits):=rfl have b:s.toBitVec.toNat=if s=.negative then 1 else 0:=by cases s<;>rfl simp only[c,ite_false,a,ite_true,packComponents,BitVec.toNat_append,b,BitVec.toNat_ofNat] rw[Ἁ (by (clear h hM1 hM2 c a b; exact omS70 hb2):(E+150).toNat<2^8), <-Nat.shiftLeft_add_eq_or_of_lt (by (clear h hM1 hM2 c a b; exact omS70 hb2):(E+150).toNat<2^8), <-Nat.shiftLeft_add_eq_or_of_lt (ὀ _ (by positivity):M%2^23<2^23)] split_ifs<;>simp[Nat.shiftLeft_eq] (clear h hM1 hM2 hb1 hb2 c a b; omega) lemma qE4 (neg:Ὡ) (m:Ὣ) (e:Int) (P:Ὣ) (E:Int) (hm:m≠0) (hP1:2^23<=P) (hP2:P<2^24) (hE:-149<=E) (hE2:E+150<=254) (hhi:2*((m:ℝ)*2^e)<(2*P+1)*2^E) (hlo1:P≠2^23->(2*P-1)*2^E<2*((m:ℝ)*2^e)) (hlo2:P=2^23->33554431*2^E<4*((m:ℝ)*2^e)) : toWord (ἕ Fmt ⟨neg,m,e⟩) =UInt32.ofNat ((if neg then 2^31 else 0)+(E+150).toNat*2^23+P%2^23):=by have l:0< P :=(by clear hm hE hE2; exact omS71 hP1) obtain ⟨k,F⟩:∃ k:Ὣ,e-E+2<=k:=⟨(e-E+2).toNat,by (clear hm hP1 hP2 hE hE2 l; exact omS72)⟩ obtain ⟨g,z⟩:∃ g:Ὣ,(e-k)+(g+2:Ὣ)=E:=⟨(E-(e-k)-2).toNat,by (clear hm hP1 hP2 hE hE2 l; exact omS73 F)⟩ have u:(0:ℝ)<2^(e-k):=ἵ two_pos _ have s:(m:ℝ)*2^e=((m*2^k:Ὣ):ℝ)*2^(e-k):=by push_cast rw[mul_assoc,<-B_z e _ k (by clear hm hP1 hP2 hE hE2 l F z; exact omS74)] have i:(2:ℝ)^E=4*((2^g:Ὣ):ℝ)*2^(e-k):=by rw[B_z E (e-k) (g+2) (by clear hm hP1 hP2 hE hE2 l F; exact omS75 z)] push_cast ring rw[qBb,<-ExactRuntime.round_scale _ _ m e k hm] have p:m*2^k≠0:=Nat.mul_ne_zero hm (by positivity) rw[s,i] at hhi rw[s,i] at hlo1 hlo2 have H:0<2^g:=by positivity generalize m*2^k=M at * generalize e-k=q at * generalize (2:ℝ)^q=b at * have f:∀ A B:ℕ,(A:ℝ)*b< B*b->A< B :=λA B h=>by exact_mod_cast lt_of_mul_lt_mul_right h u.le push_cast at hhi hlo1 hlo2 have G:M<4*(P*2^g)+2*2^g:=f _ _ (by push_cast;linarith only [hhi]) have t:P≠2^23->4*(P*2^g)< M+2*2^g :=λh=>f _ _ (by push_cast;linarith only [hlo1 h]) have y:P=2^23->33554431*2^g< M :=λh=>f _ _ (by push_cast;linarith only [hlo2 h]) have C:P*2^g<=(2^24-1)*2^g:=Ἒ _ (by exact Nat.le_of_lt_succ ‹_›) have r:2*(P*2^(g+1))=4*(P*2^g):=by rw[Nat.pow_succ];ring have n:2^(g+1)=2*2^g:=by rw[Nat.pow_succ];ring have w:UnpackedFloat.round Format.binary32 (Model.modelSign neg) M q =.finite (Model.modelSign neg) P E l:=by rw[Model.round_exact_eq_finishRoundedMantissa _ _ _ _] have o:∀ (L:ℕ) (T:ℤ),2^L*2^g<=M->M<2^L*2^g*2 → max (((L+g:ℕ):ℤ)+1+q-24) (-149)=T → Format.binary32.targetExponent (totalExponent M q)=T:=λL T a c d=>by rw[<-Nat.pow_add] at a c simp only[totalExponent,qDg M _ a c,qFq];exact d by_cases v:2^25*2^g<=M . rw[o 25 E v (by clear hm hP1 hP2 hE hE2 l F H p z r n v; exact omS76 G C) (by clear hm hP1 hP2 l F H p G C r n v; exact omS77 hE z),qEa M q E (g+1) P (by clear hm hP1 hP2 hE hE2 l F H p G C r n v; (exact Eq.symm ‹_›)) l ?_ (by rw[r,n];(exact Nat.succ_le_of_lt ‹_›))];. exact qEf _ P E hP1 hP2 hE l . rw[r,n];by_cases j:P=2^23;. subst j;(clear hm hE hE2 F H p z n hP1 hP2 l C r; exact omS78 v G) . have:=t j;(exact Nat.succ_le_of_lt ‹_›) have j:P=2^23:=by by_contra hne have:=t hne have:(2^23+1)*2^g<=P*2^g:=Ἒ _ (by clear hm hE hE2 l F H p z G C r n v this; exact omS79 hP1 hne) (clear hm hP1 hP2 hE hE2 l F H p z C r n hne; (clear G; omega)) have D:=y j subst j by_cases x:-148<=E . rw[o 24 (E-1) (by clear hm hE hE2 F H p z n v hP1 hP2 l G C r x; exact omS80 D) (by clear hm hE hE2 F H p z n D hP1 hP2 l G C r x; exact omS81 v) (by clear hm F H p n v D hP1 hP2 l G C r; exact omS82 z x),qEa M q (E-1) g (2^24) (by clear hm hE hE2 F H p n v D hP1 hP2 l G C r x; exact omS83 z) (by positivity) (by clear hm hE hE2 F H p z n v hP1 hP2 l G C r x; exact omS84 D) (by clear hm hE hE2 F H p z n hP1 hP2 l G C r x; (clear D; exact omS85 v))];have:=Model.finishRoundedMantissa_normalized_carry FloatFormat.binary32 (Model.modelSign neg) (E-1+23) (by show -126<=E-1+23;(clear hm F H p n v D hP1 hP2 l G C r; exact omS86 x));rw[show (FloatFormat.binary32.fracWidth:ℤ)=23 from rfl] at this;rwa [((by clear hm hE hE2 F H p z n v D hP1 hP2 l G C r x; exact omS87):E-1+23-23=E-1),((by clear hm hE hE2 F H p z n v D hP1 hP2 l G C r x; exact omS88):E-1+23+1-23=E)] at this . rw[o 24 E (by clear hm hE hE2 F H p z n hP1 hP2 l G C r x; (clear v; exact omS80 D)) (by clear hm hE hE2 F H p z n D hP1 hP2 l G C r x; exact omS81 v) (by clear hm F H p n v D hP1 hP2 l G C r; exact omS89 hE z x),qEa M q E (g+1) (2^23) (by clear hm hE hE2 F H p n v D hP1 hP2 l G C r x; (exact Eq.symm ‹_›)) (by positivity) (by rw[n];(clear hm hE hE2 F H p z n hP1 hP2 l G C r x; exact omS90 D)) (by rw[n];(clear hm hE hE2 F H p z n v D hP1 hP2 l C r x; exact omS91 G))];exact qEf _ _ E (by norm_num1) (by norm_num1) hE l rw[w] simp only[toWord,Model.toNatBits,Model.ofModel,Model.ofModelBits] congr 1 show (UnpackedFloat.pack Format.binary32 _).toNat=_ rw[qBn _ _ _ _ hP1 hP2 (by clear hm hP1 hP2 F H p G C r n; exact omS92 hE) (by exact omS93 hE2)] cases neg<;>simp[Model.modelSign] end abbrev B_D:=ExecFloat.Binary.descriptor (exponentBits:=11) (fractionBits:=52) lemma qFs (f:ὧ):Model.signBit (toModel (ofFloat f : Binary64))=decide (2^63<=f.toBits.toNat):=by rw[Model.signBit_eq_msb];show f.toBits.toBitVec.msb=_;rw[BitVec.msb_eq_decide];rfl lemma B_R (f:ὧ) (s:Ὡ) (E F:Ὣ) (hE1:1<=E) (hE:E<2047) (hF:F<2^52) (h:f.toBits.toNat=(if s then 2^63 else 0)+E*2^52+F) : f.isFinite=true ∧ R f=(if s then -1 else 1)*((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075):=by have g:Model.expField (toModel (ofFloat f : Binary64))=f.toBits.toNat/2^52%2^11:=by show ((f.toBits.toBitVec >>> 52) &&& BitVec.ofNat 64 2047).toNat=_ rw[BitVec.toNat_and,BitVec.toNat_ushiftRight,BitVec.toNat_ofNat,Ἱ] exact Ἂ _ 11 have e:Model.fracField (toModel (ofFloat f : Binary64))=f.toBits.toNat%2^52:=by show (f.toBits.toBitVec &&& BitVec.ofNat 64 (2^52-1)).toNat=_ rw[BitVec.toNat_and,BitVec.toNat_ofNat] exact Ἂ _ 52 have i:Model.signBit (toModel (ofFloat f : Binary64))=s :=(qFs f).trans (by cases s<;>simp at h ⊢<;>(clear g; omega)) have b:E<2^11 :=(by exact Nat.lt_of_lt_of_le ‹_› (by decide)) have hE':f.toBits.toNat/2^52%2^11=E:=by rw[h];cases s . rw[ἐ Bool.false_ne_true,Nat.zero_add,Nat.mul_comm E,Nat.mul_add_div (by decide),Nat.div_eq_of_lt hF,Nat.add_zero,Nat.mod_eq_of_lt b] . rw[ἱ rfl,show (2:ℕ)^63=2^11*2^52 by decide,<-Nat.add_mul,Nat.mul_comm (2^11+E),Nat.mul_add_div (by decide),Nat.div_eq_of_lt hF,Nat.add_zero,Nat.add_mod_left,Nat.mod_eq_of_lt b] have hF':f.toBits.toNat%2^52=F:=by rw[h];cases s . rw[ἐ Bool.false_ne_true,Nat.zero_add,Nat.mul_comm E,Nat.mul_add_mod,Nat.mod_eq_of_lt hF] . rw[ἱ rfl,show (2:ℕ)^63=2^11*2^52 by decide,<-Nat.add_mul,Nat.mul_comm (2^11+E),Nat.mul_add_mod,Nat.mod_eq_of_lt hF] have c:=Model.ofFields_signBit_expField_fracField (toModel (ofFloat f : Binary64)) rw[g,e,i,hE',hF'] at c have a:Ἑ (Model.ofFields B_D s E F)=true:=by rw[Model.isFinite_ofFields B_D _ _ _ b hF] show (E != 2047)=true simp;(clear hF h g e b; exact omS94 hE) have d:=Model.toDyadic?_ofFields_of_isFinite B_D _ _ _ b hF a rw[c,ἐ ((by clear hF h g e b; exact omS95 hE1):¬ E=0)] at d rw[c] at a refine ⟨(qAh f).symm.trans a,?_⟩ rw[R,Model.toReal_eq,d] simp only[show Model.pow2 B_D.fracWidth=2^52 from rfl, show Int.ofNat E-Int.ofNat B_D.exponentBias-Int.ofNat B_D.fracWidth=(E:ℤ)-1075 by show (E:ℤ)-1023-52=_;(clear hE1 hE hF h g e b; exact omS96)] cases s<;>simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand] def B_near (A:Ὣ) (S:Ὡ) (ex fr:Ὣ):Prop := ∃ M,A=(if S then 2^63 else 0)+M∧(ex*2^23+fr)*2^29< M+2^28 ∧ M<=(ex*2^23+fr)*2^29+2^28 lemma B_x (A:Ὠ) (x:Ὠ) (hx:(A+0x0FFFFFFF) >>> 29=x) (h1:897<=Ѧx/2^23%2^11) (h2:Ѧx/2^23%2^11<1151) : Ѧx<2^35∧B_near ѦA (decide (2^34<=Ѧx)) (Ѧx/2^23%2^11) (Ѧx%2^23):=by have a:=A.toNat_lt have e:Ѧx=(ѦA+268435455)%2^64/2^29:=by rw[<-hx,ἰ,ἤ] norm_num [Nat.shiftRight_eq_div_pow] refine ⟨by (clear hx h1 h2 a; exact omS97 e),?_⟩ unfold B_near by_cases h:2^34<=Ѧx . simp only[h,decide_true,ite_true];exact ⟨ѦA-2^63,by (clear hx; exact omS98 h1 e h),by (clear hx; exact omS99 e h),by (clear hx h1 h2; exact omS100 a e h)⟩ . simp only[h,decide_false,Bool.false_eq_true,ite_false];exact ⟨ѦA,by (clear hx h1 h2 a e h; exact omS101),by (clear hx h; exact omS102 e),by (clear hx; exact omS103 h1 a e h)⟩ lemma qHw (x:Ὠ) (hx:Ѧx<2^35) (h1:897<=Ѧx/2^23%2^11) (h2:Ѧx/2^23%2^11<1151) : (((x >>> 34) <<< 31) ||| ((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< 23))).toUInt32 = UInt32.ofNat ((if decide (2^34<=Ѧx) then 2^31 else 0) + (Ѧx/2^23%2^11-896)*2^23+Ѧx%2^23):=by have G1:Ѧx%2^34/2^23=Ѧx/2^23%2^11:=by rw[show (2:ℕ)^34=2^23*2^11 by decide];exact Nat.mod_mul_right_div_self _ _ _ have F1:Ѧx%2^34%2^23=Ѧx%2^23:=Nat.mod_mod_of_dvd _ (Nat.pow_dvd_pow 2 (by decide)) have h1':897<=Ѧx%2^34/2^23:=by rw[G1];exact h1 have h2':Ѧx%2^34/2^23<1151:=by rw[G1];exact h2 have L896:896*2^23<=Ѧx%2^34:=Nat.le_trans (by decide) ((Nat.le_div_iff_mul_le (by decide)).mp h1') have b:((x >>> 34) <<< 31).toNat=(Ѧx/2^34)*2^31:=by rw[UInt64.toNat_shiftLeft,ἰ] norm_num [Nat.shiftRight_eq_div_pow,Nat.shiftLeft_eq] exact Nat.lt_of_lt_of_le (Nat.mul_lt_mul_of_pos_right (Nat.div_lt_of_lt_mul (hx:Ѧx<17179869184*2)) (by decide)) (by decide) have a:(x &&& (0x3FFFFFFFF:Ὠ)).toNat=Ѧx%2^34:=by rw[Ὅ] exact Ἂ _ 34 have d:((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< 23)).toNat =Ѧx%2^34-896*2^23:=by rw[show ((896:Ὠ) <<< 23)=7516192768 by decide,UInt64.toNat_sub_of_le,a] . rfl . rw[UInt64.le_iff_toNat_le,a];exact L896 have c:(Ѧx/2^34)*2^31 ||| (Ѧx%2^34-896*2^23) =(Ѧx/2^34)*2^31+(Ѧx%2^34-896*2^23):=by rw[ἥ (Ѧx/2^34)] exact (Nat.two_pow_add_eq_or_of_lt (Nat.lt_of_lt_of_le (Nat.sub_lt_sub_right L896 ((Nat.div_lt_iff_lt_mul (by decide)).mp h2')) (by decide)) _).symm have GEF:Ѧx%2^34-896*2^23=(Ѧx/2^23%2^11-896)*2^23+Ѧx%2^23:=by rw[<-Nat.div_add_mod' (Ѧx%2^34) (2^23),G1,F1,Nat.sub_add_comm (Nat.mul_le_mul_right _ (Nat.le_of_lt h1)),<-Nat.sub_mul] apply ἠ.mp rw[UInt64.toNat_toUInt32,UInt64.toNat_or,b,d,c,ὡ] simp only[decide_eq_true_eq] split_ifs with hh . rw[Nat.div_eq_of_lt_le (k:=1) (by rw[Nat.one_mul];exact hh) hx,GEF,Nat.one_mul,Nat.add_assoc] . rw[Nat.div_eq_of_lt (Nat.not_le.mp hh),GEF,Nat.zero_mul,Nat.zero_add,Nat.zero_add] lemma qEs (A B:Ὠ) (h:zivW A B≠Е) : ∃ (S:Ὡ) (ex fr:Ὣ),897<=ex∧ex<1151∧fr<2^23 ∧ zivW A B=UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr) ∧ B_near ѦA S ex fr∧B_near ѦB S ex fr:=by unfold zivW at h ⊢ dsimp only at h ⊢ generalize hx:(A+(0x0FFFFFFF:Ὠ)) >>> (29:Ὠ)=x at h ⊢ generalize hy:(B+(0x0FFFFFFF:Ὠ)) >>> (29:Ὠ)=y at h ⊢ have hex:((x >>> (23:Ὠ)) &&& (0x7FF:Ὠ)).toNat=Ѧx/2^23%2^11:=by rw[Ὅ,ἰ] have:=Ἂ (Ѧx >>> 23) 11 norm_num [Nat.shiftRight_eq_div_pow] at this ⊢ exact this generalize (x >>> (23:Ὠ)) &&& (0x7FF:Ὠ)=ex at h hex ⊢ split at h . rename_i hc;have hc0:=hc;obtain ⟨hxy,hc⟩:=ὕ.mp hc;have hxy:x=y:=by simpa using hxy subst hxy;have hc:ex-(897:Ὠ)<(254:Ὠ):=by simpa using hc rw[ἴ,UInt64.toNat_sub] at hc;have hv:=ex.toNat_lt;norm_num at hc hv;have h1:897<=Ѧx/2^23%2^11 :=(by clear hx h hy hv; exact omS107 hex hc);have h2:Ѧx/2^23%2^11<1151 :=(by clear hx h hy hv; exact omS108 hex hc);simp only[hc0,ite_true];obtain ⟨hx35,ha⟩:=B_x A x hx h1 h2;exact ⟨_,_,_,h1,h2,by (clear hx hex h hy hc hv h1 h2 hx35; exact omS109),qHw x hx35 h1 h2,ha,(B_x B x hy h1 h2).2⟩ . exact absurd rfl h lemma qR0 (Y:Ὡ) (r:ὥ) (he:expOf r≠255) : r &&& ((if Y then (0:ὥ) else Е) ||| ((r >>> (31:ὥ))-1))=act Y r:=by have b:=r.toNat_lt have f:∀ u:ὥ,u&&&Е=u:=λu=>UInt32.toNat_inj.mp (by rw[UInt32.toNat_and];show ѥu&&&(2^32-1)=_;rw[Nat.and_two_pow_sub_one_eq_mod];exact Nat.mod_eq_of_lt u.toNat_lt) by_cases h:2^31<=ѥr . have e:r>>>(31:ὥ)=1:=UInt32.toNat_inj.mp (by rw[UInt32.toNat_shiftRight];show ѥr>>>31=1;rw[Nat.shiftRight_eq_div_pow];(clear he; exact omS110 b h)) have g:(r&&&0x80000000!=0)=true:=by have:(r&&&0x80000000).toNat≠0:=by rw[UInt32.toNat_and];show ѥr&&&2^31≠0;rw[Nat.and_two_pow];simp [Nat.testBit_eq_decide_div_mod_eq];(clear he e; exact omS111 b h) simp only[bne_iff_ne];intro c;rw[c] at this;exact this rfl cases Y<;>simp[act,reluW,e,g,he,f] . have e:r>>>(31:ὥ)=0:=UInt32.toNat_inj.mp (by rw[UInt32.toNat_shiftRight];show ѥr>>>31=0;rw[Nat.shiftRight_eq_div_pow];(clear he; exact omS112 h)) have g:(r&&&0x80000000)=0:=UInt32.toNat_inj.mp (by rw[UInt32.toNat_and];show ѥr&&&2^31=0;rw[Nat.and_two_pow];simp [Nat.testBit_eq_decide_div_mod_eq];(clear he e; exact omS113 h)) cases Y<;>simp[act,reluW,e,g] lemma qRe (w:ὥ):(expOf w).toNat=ѥw/2^23%2^8:=by unfold expOf rw[UInt32.toNat_and,UInt32.toNat_shiftRight] show (ѥw>>>23)&&&(2^8-1)=_ rw[Nat.and_two_pow_sub_one_eq_mod,Nat.shiftRight_eq_div_pow] lemma qR1 (r:ὥ) (S:Ὡ) (ex fr:Ὣ) (h1:897<=ex) (h2:ex<1151) (h3:fr<2^23) (hz:r=UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr)):expOf r≠255:=by intro e;have a:=qRe r;rw[e] at a;change 255=_ at a;rw[hz,UInt32.toNat_ofNat'] at a;cases S<;>simp only[Bool.false_eq_true,ite_false,ite_true] at a<;>(clear e hz; omega) lemma qB6 (s e:ὧ) (h:ziv s e≠Е) : ∃ (S:Ὡ) (ex fr:Ὣ),897<=ex∧ex<1151∧fr<2^23 ∧ ziv s e=UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr) ∧ B_near (s+e).toBits.toNat S ex fr∧B_near (s-e).toBits.toNat S ex fr := qEs (s+e).toBits (s-e).toBits h set_option maxRecDepth 8192 in lemma qA4 (f:ὧ) (S:Ὡ) (ex fr:Ὣ) (h1:897<=ex) (h2:ex<1151) (hfr:fr<2^23) (hn:B_near f.toBits.toNat S ex fr) : f.isFinite=true∧∃ v:ℝ,R f=(if S then -v else v) ∧ v<=(2^53+fr*2^30+2^29)*2^((ex:Int)-1076) ∧ (fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)< v) ∧ (2^53-2^28)*2^((ex:Int)-1076)< v:=by obtain ⟨M,k,o,n⟩:=hn have d:M%2^52<2^52:=ὀ _ (by positivity) have b:M=(M/2^52)*2^52+M%2^52 :=(by clear h1 h2 hfr k o n d; exact omS114) generalize M/2^52=E at b generalize M%2^52=F at b d subst b have c:(0:ℝ)<2^((ex:Int)-1076):=ἵ (by positivity) _ have m:E=ex∨(E+1=ex∧fr=0) :=(by clear h1 h2; exact omS115 hfr d o n) obtain ⟨a,l⟩:=B_R f S E F (by clear m; exact omS116 h1 d o) (by clear m; exact omS117 h2 hfr n) d (by rw[k,ὢ]) obtain ⟨w,j,i,e,g⟩:∃ w:ℕ,((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075) =w*2^((ex:Int)-1076)∧w<=2^53+fr*2^30+2^29 ∧ (fr≠0->2^53+fr*2^30< w+2^29)∧2^53< w+2^28:=by rcases m with rfl | ⟨rfl,rfl⟩ . refine ⟨2*(2^52+F),?_,by (clear hfr d h1 h2; (clear k; exact omS118 n)),by (clear hfr d h1 h2; (clear k; exact omS119 o)),by (clear hfr h1 h2 o n; exact omS120)⟩;rw[show (E:Int)-1075=1+((E:Int)-1076) by ring,Ἓ ἓ,zpow_one];push_cast;ring . exact ⟨2^52+F,by congr 2;push_cast;ring,by (clear h1 h2 hfr n; exact omS121 d),by (clear h1 h2 hfr n; exact omS122),by (clear h1 h2 hfr n; exact omS123 o)⟩ refine ⟨a,(w:ℝ)*2^((ex:Int)-1076),?_,ἀ ?_ c.le,λh=>Ἦ ?_ c,Ἦ ?_ c⟩ . rw[l,mul_assoc,j];cases S<;>simp . exact_mod_cast i . rw[sub_lt_iff_lt_add];exact_mod_cast e h . rw[sub_lt_iff_lt_add];exact_mod_cast g lemma qBw (s e:ὧ) (h:ziv s e≠Е) : (s+e).isFinite=true∧(s-e).isFinite=true∧(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|:=by obtain ⟨S,f,c,b,d,a,-,j,k⟩:=qB6 s e h;obtain ⟨g,v,i,-,-,l⟩:=qA4 _ S f c b d a j;refine ⟨g,(qA4 _ S f c b d a k).1,?_⟩ exact (show (2:ℝ)^(-127:ℤ)<=(2^53-2^28)*2^(-179:ℤ) by (norm_num1)).trans ((ἁ (ἒ one_le_two (by clear h a; exact omS124 b)) (by positivity)).trans (l.le.trans (by rw[i];cases S<;>simp[le_abs_self]))) lemma qAx (w:ὥ) (h:expOf w≠255):wv w=(ἂ w:ℝ):=by rw[wv,Model.toReal_eq,ofW,ἶ w h];simp only[rationalWord,FloatLib.Numerics.Dyadic.cast_toRat] lemma qEl (a b:ѐ) (start n:Ὣ) : (dsum a b start n:ℚ)*2^(-298:Int) =∑ j∈Ἣ n,ἂ a[start+j]! * ἂ b[start+j]!:=by have c:∀ a b:ὥ,((sv a:ℚ)*sv b*(2:ℚ)^(idxOf a+idxOf b))*2^(-298:Int) =ἂ a*ἂ b:=λa b=>by simp only[rationalWord,decodeD_toRat] rw[show (-298:Int)=-149+-149 by (norm_num1),Ἓ ἓ] rw[zpow_sub₀ ἓ,zpow_sub₀ ἓ,Ἡ,Ἡ,pow_add] norm_num [zpow_neg,zpow_natCast] ring induction n generalizing start with | zero=>simp[dsum] | succ n ih => rw[dsum,Int.cast_add,Int.cast_mul,Int.cast_mul,Int.cast_pow,Int.cast_ofNat,add_mul,ih,Finset.sum_range_succ',Ἵ,c,add_comm] refine congrArg (· + _) ?_ apply Ἷ rfl intro j _ rw[ὢ,Nat.add_comm 1 j] lemma qEc (n:Ὣ) (fa fb:Ὣ->ὥ) (hf:∀ j,j< n->expOf (fa j)≠255∧expOf (fb j)≠255) (hn:(∑ j∈Ἣ n,ἂ (fa j)*ἂ (fb j))≠0) : ∃ d:FloatLib.Numerics.Dyadic, d.toRat=(∑ j∈Ἣ n,ἂ (fa j)*ἂ (fb j)) ∧ dotOf n fa fb=toWord (ἕ Fmt d):=by let a:=Array.ofFn (n:=n) λi=>fa i let b:=Array.ofFn (n:=n) λi=>fb i have e:ѧa=n:=by simp[a] have g:ѧb=n:=by simp[b] have c:(dsum a b 0 n:ℚ)*2^(-298:Int) =∑ j∈Ἣ n,ἂ (fa j)*ἂ (fb j):=by rw[qEl] refine Ἷ rfl λj m=>?_ have h:=Ὁ.mp m rw[Ἇ,qAb n fa j h,qAb n fb j h] have l:dsum a b 0 n≠0:=λh=>hn (by rw[<-c,h];simp) have Z:=qEg a b (by rw[e,g]) λk f=>by rw[e] at f rw[qAb n fa k f,qAb n fb k f];exact hf k f rw[e] at Z refine ⟨ofIntDyadic (dsum a b 0 n) (-298),by rw[toRat_ofIntDyadic,c],?_⟩ show dotSpec a b=_ rw[<-Z];simp[finishWord,l] lemma qIg:ἂ oneW=1:=by norm_num [rationalWord,decodeD,show expOf oneW=127 by decide,show fracOf oneW=0 by decide,show signOf oneW=false by decide,FloatLib.Numerics.Dyadic.toRat,FloatLib.Numerics.Dyadic.signedSignificand] lemma qM1 (y:ὧ) (hy:yᶠ) : y*dv oneW=y:=by obtain ⟨h1,h2⟩:=qAm oneW (by decide) obtain ⟨x,hx,-⟩:=qDk y hy obtain ⟨o,ho,eo⟩:=qDk _ h1 have e1:o.toReal=1:=by rw[eo,h2,qAx oneW (by decide),qIg];norm_num have os:o.significand≠0:=λh=>by have:=(A_s o).2 h;rw[e1] at this;norm_num at this have on:o.negative=false:=by cases hn:o.negative · rfl · have q:=qD4 o;rw[hn,e1] at q;have:=qE9 o os;simp only[A_r,↓reduceIte] at q;linarith apply qIe rw[qCq hx ho hy h1] have hy':=Model.Internal.Directed.roundDyadic_toDyadic? qAj .nearest hx split · rename_i z have xs:x.significand=0:=by rcases Nat.mul_eq_zero.1 z with h|h;exact h;exact absurd h os rw[<-hy',on,Bool.xor_false] obtain ⟨n,m,e⟩:=x simp only at xs subst xs rw[Model.Internal.Directed.roundDyadic_zero] · rename_i z rw[<-hy'] exact ExactRuntime.roundDyadic_congr _ qAj _ _ z (λh=>z (by rw[h,Nat.zero_mul])) (Rat.cast_injective (α:=ℝ) (by rw[Ἠ,Ἠ,Model.Dyadic.toReal_mul,e1,mul_one])) lemma qHv (n:Ὣ) (xw ww:Ὣ->ὥ) (bw:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) : ((∑ j∈Ἣ (n+1),ἂ (if j< n then xw j else oneW) * ἂ (if j< n then ww j else bw):ℚ):ℝ)=exactS n xw ww bw:=by rw[Finset.sum_range_succ] simp only[lt_self_iff_false,ite_false,qIg,one_mul] rw[Rat.cast_add,Rat.cast_sum,exactS,qAx bw (qAe bw hb)] congr 1 refine Ἷ rfl λt b=>?_ have a:=Ὁ.mp b simp only[a,ite_true] rw[qAx _ (qAe _ (hx t a)),qAx _ (qAe _ (hw t a)),Rat.cast_mul] section variable (s e:ὧ) (V:ℝ) (hlo:R (s-e)< V) (hhi:V< R (s+e)) (h:ziv s e≠Е) include s e V hlo hhi h lemma qB8 : ∃ (S:Ὡ) (ex fr:Ὣ) (W:ℝ),897<=ex∧ex<1151∧fr<2^23 ∧ ziv s e=UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr) ∧ V=(if S then -W else W) ∧ W<(2^53+fr*2^30+2^29)*2^((ex:Int)-1076) ∧ (fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)< W) ∧ (2^53-2^28)*2^((ex:Int)-1076)< W:=by obtain ⟨S,ex,fr,h1,h2,h3,hz,ha,hb'⟩:=qB6 s e h obtain ⟨-,va,hva,hia,loa1,loa⟩:=qA4 _ S ex fr h1 h2 h3 ha obtain ⟨-,vb,hvb,hib,lob1,lob⟩:=qA4 _ S ex fr h1 h2 h3 hb' rw[hva] at hhi rw[hvb] at hlo refine ⟨S,ex,fr,if S then -V else V,h1,h2,h3,hz,?_,?_,?_,?_⟩ all_goals cases S all_goals simp only[Bool.false_eq_true,ite_false,ite_true,neg_neg] at hhi hlo ⊢ . exact Ἥ hhi hia . linarith only [hib, hlo] . exact λh=>(lob1 h).trans hlo . exact λh=>by linarith [loa1 h] . exact lob.trans hlo . linarith only [loa, hhi] lemma qG5:V≠0:=by obtain ⟨S,ex,fr,W,-,-,-,-,hV,-,-,hW3⟩:=qB8 s e V hlo hhi h;have hb0:(0:ℝ)<2^((ex:Int)-1076):=ἵ (by positivity) _;have hA:(0:ℝ)<=(2^53-2^28)*2^((ex:Int)-1076):=Ἆ (by positivity) hb0.le;intro h0;rw[h0] at hV;cases S;. simp only[Bool.false_eq_true,ite_false] at hV;linarith only [hW3, hA, hV] . simp only[ite_true] at hV;linarith only [hW3, hA, hV] end lemma qEo (d:FloatLib.Numerics.Dyadic) (S:Ὡ) (ex fr:Ὣ) (h1:897<=ex) (h2:ex<1151) (h3:fr<2^23) (W:ℝ) (hd:(d.toRat:ℝ)=if S then -W else W) (hW1:W<(2^53+fr*2^30+2^29)*2^((ex:Int)-1076)) (hW2:fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)< W) (hW3:(2^53-2^28)*2^((ex:Int)-1076)< W) : toWord (ἕ Fmt d) =UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr):=by have hb0:(0:ℝ)<2^((ex:Int)-1076):=ἵ (by positivity) _ have hE:(2:ℝ)^((ex:Int)-1046)=2^30*2^((ex:Int)-1076):=by rw[<-Ἡ,<-Ἓ ἓ] congr 1;push_cast;ring have hW0:0< W:=ἷ (Ἆ (by positivity) hb0.le) hW3 obtain ⟨neg,m,q⟩:=d have hdV:(FloatLib.Numerics.Dyadic.mk neg m q).toReal=if S then -W else W:=by rw[<-Ἠ,hd] have hq:(0:ℝ)<2^q:=ἵ (by positivity) _ have hm0:(0:ℝ)<=m:=Ἔ _ have hmq:=Ἆ hm0 hq.le have hMW:(m:ℝ)*2^q=W∧neg=S:=by simp only[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand] at hdV cases neg<;>cases S <;> simp only[Bool.false_eq_true,ite_false,ite_true,Int.ofNat_eq_natCast,Int.cast_neg,Int.cast_natCast] at hdV . exact ⟨by linarith only [hdV],rfl⟩ . exfalso;linarith only [hW0, hmq, hdV] . exfalso;linarith only [hW0, hmq, hdV] . exact ⟨by linarith only [hdV],rfl⟩ obtain ⟨hMW,rfl⟩:=hMW have hm:m≠0:=by rintro rfl simp at hMW linarith only [hW0, hMW] have hword:=qE4 neg m q (2^23+fr) ((ex:Int)-1046) hm (by clear h1 h2 hm; exact omS125) (by clear h1 h2 hm; exact omS126 h3) (by clear h3 hm; exact omS127 h1) (by clear h3 hm; exact omS128 h2) (by rw[hMW,hE];push_cast;linarith only [hW0, hW1]) (by intro hfr have hfr':fr≠0:=by intro h0;exact hfr (by clear h1 h2 h3 hm hfr; exact omS129 h0) have:=hW2 hfr' rw[hMW,hE];push_cast;linarith only [this]) (by intro _ rw[hMW,hE];linarith only [hW3]) have e1:((ex:Int)-1046+150).toNat=ex-896 :=(by clear h3 hm hword; exact omS130) have e2:(2^23+fr)%2^23=fr :=(by clear h1 h2 hm hword e1; exact omS131 h3) rw[hword,e1,e2] lemma qIq (s e:ὧ) (d:FloatLib.Numerics.Dyadic) (hlo:R (s-e)<(d.toRat:ℝ)) (hhi:(d.toRat:ℝ)< R (s+e)) (h:ziv s e≠Е) : ziv s e=toWord (ἕ Fmt d):=by obtain ⟨S,ex,fr,W,h1,h2,h3,hz,hV,hW1,hW2,hW3⟩:=qB8 s e _ hlo hhi h;rw[hz];exact (qEo d S ex fr h1 h2 h3 W hV hW1 hW2 hW3).symm lemma qCn (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) (bw:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (s e:ὧ) (hlo:R (s-e)< exactS n xw ww bw) (hhi:exactS n xw ww bw< R (s+e)) (h:ziv s e≠Е) : ziv s e=dotOf (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw):=by have hsum:=qHv n xw ww bw hx hw hb obtain ⟨d,hd,hw'⟩:=qEc (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw) (λj _=>by by_cases hj:j< n . simp only[hj,ite_true];exact ⟨qAe _ (hx j hj),qAe _ (hw j hj)⟩ . simp only[hj,ite_false] exact ⟨by decide,qAe _ hb⟩) λh0=>qG5 s e _ hlo hhi h (by rw[<-hsum,h0,Rat.cast_zero]) have q:(d.toRat:ℝ)=exactS n xw ww bw:=by rw[hd,hsum] rw[hw'] exact qIq s e d (by rw[q];exact hlo) (by rw[q];exact hhi) h end section lemma qDn (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) (bw:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (l:љ) (hl:l.Nodup) (hl2:∀ t∈l,t< n) (hz:∀ t,t< n->t∉l->xw t &&& В=0∨ww t &&& В=0) (s e:ὧ) (hs:let r:=l.foldl (λ(acc:F1) t=>let q:=dv (xw t)*dv (ww t) F1.mk (acc.s+q) (acc.t+q.abs)) ⟨0,0⟩;s=r.s+dv bw∧e=nfOf n*(r.t+(dv bw).abs)) (h:ziv s e≠Е) : ziv s e=dotOf (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw):=by obtain ⟨-,-,hbig⟩:=qBw s e h obtain ⟨hlo,hhi⟩:=qDm n hn xw ww bw hx hw hb l hl hl2 hz s e hs hbig exact qCn n hn xw ww bw hx hw hb s e hlo hhi h end section end section lemma C_z:(0:ὦ).toNat=0:=rfl lemma qAd (k:Ὣ) (h:k<2^32):k.toUSize.toNat=k:=by rw[Nat.toUSize_eq];exact uk k h lemma qBa (a b:ὦ) (h:Ѥa*Ѥb<2^32) : (a*b).toNat=Ѥa*Ѥb:=by have h1:2^32<=USize.size:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl;rw[USize.toNat_mul];exact Ἁ (by exact Nat.lt_of_lt_of_le ‹_› ‹_›) lemma qBe {α:Type} (a:Array α) (h:ѧa<2^32):a.usize.toNat=ѧa :=qAd _ h lemma qAg (a:ѐ) (i:ὦ) (hs:ѧa<2^32):rdW a i=a[Ѥi]!:=by unfold rdW;split;. rename_i h;have h2:=qBd a i h;rw[Ἕ a Ѥi h2];rfl . rename_i h;have h':¬ Ѥi< ѧa:=by intro h2;apply h;rw[А,qBe a hs];exact h2 rw[ὑ a Ѥi h'];rfl lemma qBh (a:ѐ) (i:ὦ) (v:ὥ):(wrW a i v).size=ѧa:=by unfold wrW;split<;>simp lemma qFo {α:Type} [Inhabited α] (a:Array α) (i q:Ὣ) (v:α) (hi:i< ѧa) : (a.set i v hi)[q]! = if q=i then v else a[q]!:=by by_cases hq:q< ѧa . rw[Ἕ _ q (by simpa using hq),getElem!_pos a q hq,Array.getElem_set];by_cases e:q=i;. simp[e] . rw[ἐ e,ἐ (λh=>e h.symm)] . rw[ὑ _ q (by simpa using hq),getElem!_neg a q hq,ite_eq_right (by exact omS132 hi hq)] lemma qBu (a:ѐ) (i:ὦ) (v:ὥ) (q:Ὣ) (hs:ѧa<2^32) (hi:Ѥi< ѧa):(wrW a i v)[q]! = if q=Ѥi then v else a[q]!:=by have h:i< a.usize:=by rw[А,qBe a hs];exact hi unfold wrW;rw[Ἄ h];exact qFo a _ q v hi def C_Inv (N:Ὣ) (sp:Ὣ->Ὢ) (S:Ὣ->Prop) (out:ё):Prop := ѧout=N∧∀ q,q< N->S q->out[q]! = sp q section variable {N:Ὣ} {sp:Ὣ->Ὢ} include N sp lemma qAk {S:Ὣ->Prop} {out:ё} (hN:N<2^32) (h:C_Inv N sp S out) {u:ὦ} {p:Ὣ} {v:Ὢ} (hu:Ѥu=p) (hp:p< N) (hv:v=sp p):C_Inv N sp (λq=>q=p∨S q) (wrW out u v):=by obtain ⟨h1,h2⟩:=h;refine ⟨by rw[qBh,h1],λq hq hS=>?_⟩;rw[qBu _ _ _ _ (by clear hu hp hq; omega) (by clear hN hq; omega),hu];by_cases e:q=p;. rw[ἱ e,e,hv] . rw[ἐ e];exact h2 q hq (hS.resolve_left e) lemma qA5 {S S':Ὣ->Prop} {out:ё} (h:C_Inv N sp S out) (hS:∀ q,q< N->S' q->S q):C_Inv N sp S' out :=⟨h.1,λq hq h'=>h.2 q hq (hS q hq h')⟩ lemma qBv {S:Ὣ->Prop} {out:ё} (h:C_Inv N sp S out) (hS:∀ q,q< N->S q) : out=Array.ofFn (n:=N) λq=>sp q.val:=by obtain ⟨h1,h2⟩:=h;apply Array.ext;. simp[h1] . intro q h3 h4;have h5:q< N :=(by clear h4; (exact Nat.lt_of_lt_of_eq ‹_› ‹_›));have:=h2 q h5 (hS q h5);rw[Ἕ out q h3] at this;simp[this] end lemma qEn (v:ὥ) (h1:(0x7FFFFF:ὥ)<=v-1) (h2:v<У) : (v == 0 || v-(0x00800000:ὥ)<=(0x7EFFFFFF:ὥ))=true:=by have a1:(0x7FFFFF:ὥ).toNat=0x7FFFFF:=rfl;have a2:(У:ὥ).toNat=У:=rfl;have a3:(0x00800000:ὥ).toNat=0x00800000:=rfl;have a4:(0x7EFFFFFF:ὥ).toNat=0x7EFFFFFF:=rfl;have a5:(1:ὥ).toNat=1:=rfl;by_cases h0:v=0;. simp[h0] . have h3:(1:ὥ)<=v:=by rw[ἃ];have:ѥv≠0:=λh=>h0 (ἠ.mp h);(clear h1 h2 a1 a2 a3 a4 h0; omega) rw[ἃ,ὓ _ _ h3] at h1;rw[ἳ] at h2;have h4:(0x00800000:ὥ)<=v:=by rw[ἃ];(clear h2 a2 a4 h0 h3; exact omS133 h1 a1 a3 a5) simp only[Bool.or_eq_true,decide_eq_true_eq];right;rw[ἃ,ὓ _ _ h4];(clear h1 a1 a5 h0 h3 h4; exact omS134 h2 a2 a3 a4) lemma qHu (c u lo:ὥ) (h:c<=if u< lo then u else lo):c<=u∧c<=lo:=by simp only[UInt32.le_iff_toNat_le,UInt32.lt_iff_toNat_lt] at *;split at h<;>omega lemma qH2 (c v hi:ὥ) (h:(if hi< v then v else hi)< c):v< c∧hi< c:=by simp only[UInt32.lt_iff_toNat_lt] at *;split at h<;>omega lemma qB2 (w:ὥ) (h:good w=true):good (w &&& В)=true:=by have e:(w &&& В) &&& В=w &&& В:=by rw[UInt32.and_assoc,UInt32.and_self] unfold good at h ⊢;simpa only [e] using h lemma qCx {h:ὥ} (h1:h<У):h<=В:=by have a1:(У:ὥ).toNat=У:=rfl;have a2:(В:ὥ).toNat=В:=rfl;rw[ἳ] at h1;rw[ἃ];(exact Nat.le_of_lt (Nat.lt_of_lt_of_le ‹_› (by decide))) def C_Hv (A:ё) (h:Ὢ):Prop := good h=true∧h<=В∧(∀ k,k< ѧA->good A[k]! = true) ∧ ∀ k,k< ѧA->A[k]! &&& В<=h lemma qFa (r v hi:ὥ) (h:(if hi< v then v else hi)<=r):v<=r∧hi<=r:=by simp only[UInt32.le_iff_toNat_le,UInt32.lt_iff_toNat_lt] at *;split at h<;>omega lemma qHj (A:ѐ) (n:ὦ) (hn:Ѥn<=ѧA) (d:Ὣ) : ∀ (i:ὦ) (lo hi:ὥ),Ѥi+d=Ѥn->scan A n i hn lo hi≠Е → (0x7FFFFF:ὥ)<=lo∧hi<У∧hi<=scan A n i hn lo hi ∧ scan A n i hn lo hi<У∧(good hi=true->good (scan A n i hn lo hi)=true) ∧ ∀ k,Ѥi<=k->k< Ѥn → good A[k]! = true∧A[k]! &&& В<=scan A n i hn lo hi:=by induction d with | zero => intro i lo hi he h have e:scan A n i hn lo hi =if 0x007FFFFF<=lo∧hi<У then hi else Е:=by rw[scan,ἔ (by rw[А];(clear hn h; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))] rw[e] at h ⊢ by_cases c:0x007FFFFF<=lo∧hi<У . rw[ἱ c];exact ⟨c.1,c.2,Ὓ _,c.2,id,λk h1 h2=>by (clear hn h e c; exact omS135 he h1 h2)⟩ . rw[ἐ c] at h;exact absurd rfl h | succ d ih => intro i lo hi he h have hi':i< n:=by rw[А];(clear h; exact omS136 he) have hb:Ѥi< ѧA :=(by exact Nat.lt_of_lt_of_le ‹_› ‹_›) have e:scan A n i hn lo hi=scan A n (i+1) hn (if (A.uget i hb &&& В)-1< lo then (A.uget i hb &&& В)-1 else lo) (if hi< A.uget i hb &&& В then A.uget i hb &&& В else hi):=by rw[scan,Ἄ hi'] rw[e] at h ⊢ obtain ⟨h1,h2,h3,h4,h5,h6⟩:=ih (i+1) _ _ (by rw[usz i n hi'];(clear hi' hb h e; exact omS137 he)) h obtain ⟨h7,h8⟩:=qHu _ _ _ h1 obtain ⟨h9,h10⟩:=qH2 _ _ _ h2 obtain ⟨h11,h12⟩:=qFa _ _ _ h3 have hg:good (A.uget i hb)=true:=qEn _ h7 h9 refine ⟨h8,h10,h12,h4,λg0=>h5 ?_,λk hk1 hk2=>?_⟩ . split;. exact qB2 _ hg . exact g0 . by_cases e2:k=Ѥi;. subst e2;rw[Ἕ A Ѥi hb];exact ⟨hg,h11⟩ . exact h6 k (by rw[usz i n hi'];(clear he hi' h e h1 h2 h3 h4 h7 h8 h9 h10 h11 h12 hk2; exact omS138 hk1 e2)) hk2 lemma qBi (A:ѐ) (hs:ѧA<2^32) (h:scan A A.usize 0 (qAc A) Е 0≠Е) : C_Hv A (scan A A.usize 0 (qAc A) Е 0):=by have e:=qBe A hs;have h0:(0:ὦ).toNat=0:=rfl;obtain ⟨-,-,-,h4,h5,h6⟩ :=qHj A A.usize (qAc A) ѧA 0 _ _ (by rw[h0,e];(clear hs h e h0; exact omS139)) h;have h7:∀ k,k< ѧA->good A[k]! = true ∧ A[k]! &&& В<=scan A A.usize 0 (qAc A) Е 0 :=λk hk=>h6 k (by exact Nat.zero_le _) (by clear hs h h0 h4; exact omS140 e hk);exact ⟨h5 rfl,qCx h4,λk hk=>(h7 k hk).1,λk hk=>(h7 k hk).2⟩ lemma qF6 (a b:ὥ):a<=a ||| b∧b<=a ||| b:=by rw[ἃ,ἃ,UInt32.toNat_or];exact ⟨Nat.left_le_or,Nat.right_le_or⟩ lemma qBt (v:ὥ) (h1:v=0∨0x800000<=v) (h2:v<У) : (v == 0 || v-(0x00800000:ὥ)<=(0x7EFFFFFF:ὥ))=true:=by rcases h1 with rfl | h1;. rfl . have a1:(У:ὥ).toNat=У:=rfl;have a2:(0x00800000:ὥ).toNat=0x00800000:=rfl;have a3:(0x7EFFFFFF:ὥ).toNat=0x7EFFFFFF:=rfl;simp only[Bool.or_eq_true,decide_eq_true_eq];right;rw[ἃ,ὓ _ _ h1];rw[ἳ] at h2;rw[ἃ] at h1;exact omS134 h2 a1 a2 a3 lemma qFe (a b:ὥ):a &&& b<=a∧a &&& b<=b:=by rw[ἃ,ἃ,Ἧ];exact ⟨Nat.and_le_left,Nat.and_le_right⟩ lemma qGi (v:ὥ) (h:0x7FFFFF<=v-1):v=0∨0x800000<=v:=by by_cases z:v=0;. exact .inl z . right;have a1:(0x7FFFFF:ὥ).toNat=0x7FFFFF:=rfl;have a2:(0x800000:ὥ).toNat=0x800000:=rfl;have a3:(1:ὥ).toNat=1:=rfl;have a4:ѥv≠0:=λe=>z (ἠ.mp (by rw[e];rfl));have a5:=v.toNat_lt;have h1:=ἃ.mp h;rw[a1,UInt32.toNat_sub,a3] at h1;rw[ἃ,a2];(clear h z a1 a2 a3; exact omS141 a4 h1) lemma qF3 (A:ѐ) (n:ὦ) (hn:Ѥn<=ѧA) (d:Ὣ) : ∀ (i:ὦ) (o s:ὥ),Ѥi+d=Ѥn->scanF A n i hn o s≠Е → o<=scanF A n i hn o s∧scanF A n i hn o s<У∧0x7FFFFF<=s ∧ ((o=0∨0x800000<=o)->scanF A n i hn o s=0∨0x800000<=scanF A n i hn o s) ∧ ∀ k,Ѥi<=k->k< Ѥn → good A[k]! = true∧A[k]! &&& В<=scanF A n i hn o s:=by induction d with | zero => intro i o s he h rw[scanF,ἔ (by rw[А];(clear hn h; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))] at h ⊢ by_cases c:0x7FFFFF<=s∧o<У . rw[ἱ c];exact ⟨Ὓ _,c.2,c.1,id,λk h1 h2=>by (clear hn h c; exact omS135 he h1 h2)⟩ . rw[ἐ c] at h;exact absurd rfl h | succ d ih => intro i o s he h have hi':i< n:=by rw[А];(clear h; exact omS136 he) have hb:Ѥi< ѧA :=(by exact Nat.lt_of_lt_of_le ‹_› ‹_›) rw[scanF,Ἄ hi'] at h ⊢ obtain ⟨h1,h2,h3,h4,h5⟩:=ih (i+1) _ _ (by rw[usz i n hi'];(clear hi' h hb; exact omS137 he)) h obtain ⟨h6,h7⟩:=qF6 o _ obtain ⟨h8,h9⟩:=qFe s ((A.uget i hb &&& В)-1) have hv:=qGi _ (UInt32.le_trans h3 h9) have hl:=UInt32.le_trans h7 h1 refine ⟨UInt32.le_trans h6 h1,h2,UInt32.le_trans h3 h8,λg0=>h4 ?_,λk hk1 hk2=>?_⟩ . rcases hv with hv | hv . rcases g0 with g0 | g0;. left;rw[g0,hv];rfl . right;exact UInt32.le_trans g0 h6 . right;exact UInt32.le_trans hv h7 . by_cases e2:k=Ѥi;. subst e2;rw[Ἕ A Ѥi hb];exact ⟨qBt _ hv (UInt32.lt_of_le_of_lt hl h2),hl⟩ . exact h5 k (by rw[usz i n hi'];(clear he h hb h1 h2 h3 h6 h7 h8 h9 hv hl hk2; exact omS138 hk1 e2)) hk2 lemma qB1 (A:ѐ) (hs:ѧA<2^32) (h:scanF A A.usize 0 (qAc A) 0 Е≠Е) : C_Hv A (scanF A A.usize 0 (qAc A) 0 Е):=by have e:=qBe A hs;have h0:(0:ὦ).toNat=0:=rfl;obtain ⟨-,h2,-,h4,h5⟩ :=qF3 A A.usize (qAc A) ѧA 0 _ _ (by rw[h0,e];(clear hs h e h0; exact omS139)) h;generalize scanF A A.usize 0 (qAc A) 0 Е=S at *;have hp:=qCx h2;have hm:S &&& В=S:=by have a:(В:ὥ).toNat=2^31-1:=rfl;apply ἠ.mp;rw[ἃ,a] at hp;rw[Ἧ,a,Ἂ];(clear hs e h0 h h2 a; exact omS142 hp) have hg:good S=true:=by unfold good;dsimp only;rw[hm];exact qBt _ (h4 (Or.inl rfl)) h2 exact ⟨hg,hp,λk hk=>(h5 k (by exact Nat.zero_le _) (by clear hs h0 h h2 hp hm; omega)).1,λk hk=>(h5 k (by exact Nat.zero_le _) (by clear hs h0 h h2 hp hm; omega)).2⟩ lemma qA8 (r:Ὣ) (A:ѐ) (hs:ѧA<2^32) (h:scanH r A≠Е) : C_Hv A (scanH r A):=by revert h;unfold scanH;dsimp only;by_cases c:(r == 1)=true . rw[ἱ c];split;. exact qBi A hs . exact qB1 A hs . rw[ἐ c];exact qBi A hs lemma qGd (r:Ὣ) (A:ѐ) (h8:r≠8) (h1:r≠1) (h4:r≠4) (hs:ѧA<2^32) (h:scanW r A≠Е):C_Hv A (scanW r A):=by have e:scanW r A=scanH r A:=by unfold scanW;rw[ἐ (by simp[h8,h1,h4])] rw[e] at h ⊢;exact qA8 r A hs h def C_out (I:Ὣ) (Y:Ὡ) (X W b:ё) (i j:Ὣ):Ὢ := act Y (dotOf (I+1) (λt=>if t< I then X[i*I+t]! else oneW) (λt=>if t< I then W[j*I+t]! else b[j]!)) lemma qCj {R I i t:Ὣ} (hi:i< R) (ht:t< I):i*I+t< R*I:=by have h:(i+1)*I<=R*I:=Ἒ _ hi;rw[Nat.add_mul,Ὑ] at h;(clear hi; omega) lemma qBc {R I i t:Ὣ} (hi:i< R) (ht:t<=I) : i*I+t<=R*I:=by have h:(i+1)*I<=R*I:=Ἒ _ hi;rw[Nat.add_mul,Ὑ] at h;(clear hi; omega) section variable {R I O:Ὣ} {X W b:ё} section variable (G:C_G R I O X W b) include G lemma C_G.gx {i:Ὣ} (hi:i< R) : ∀ t,t< I->good X[i*I+t]! = true :=λ_ ht=>G.gX _ (by rw[<-G.hX];exact qCj hi ht) lemma C_G.gw {j:Ὣ} (hj:j< O) : ∀ t,t< I->good W[j*I+t]! = true :=λ_ ht=>G.gW _ (by rw[<-G.hW];exact qCj hj ht) lemma qHx (Y:Ὡ) {i j:Ὣ} (hi:i< R) (hj:j< O) {s e:ὧ} (hs:let r:=(ἄ I).foldl (λ(acc:F1) t => let q:=dv X[i*I+t]! * dv W[j*I+t]! F1.mk (acc.s+q) (acc.t+q.abs)) ⟨0,0⟩;s=r.s∧e=r.t) : fin I Y X W b i j s (nfOf I) e b[j]! = C_out I Y X W b i j:=by obtain ⟨h1,h2⟩:=hs unfold fin dsimp only split . unfold slowOut C_out;rw[qAi] . rename_i h;unfold C_out;congr 1;exact qDn I G.ni (λt=>X[i*I+t]!) (λt=>W[j*I+t]!) b[j]! (G.gx hi) (G.gw hj) (G.gb j (by rw[<-G.hb];exact hj)) _ Ὂ (λt ht=>Ἅ.mp ht) (λt ht h3=>absurd (Ἅ.mpr ht) h3) _ _ ⟨by rw[h1],by rw[h2]⟩ (by simpa using h) end lemma qE2 {X W:ѐ} {xo wo n:ὦ} (hX:ѧX<2^32) (hW:ѧW<2^32) (h1:Ѥxo+Ѥn<=ѧX) (h2:Ѥwo+Ѥn<=ѧW) (d:Ὣ):∀ (t:ὦ) (s a:ὧ),Ѥt+d=Ѥn → tightGo X W xo wo n t s a=(List.range' Ѥt d).foldl (λ(acc:F1) k =>let q:=dv X[Ѥxo+k]! * dv W[Ѥwo+k]! F1.mk (acc.s+q) (acc.t+q.abs)) ⟨s,a⟩:=by induction d with | zero => intro t s a he rw[tightGo,ἔ (by rw[А];(clear hX hW h1 h2; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))] rfl | succ d ih => intro t s a he have ht:t< n:=by rw[А];(clear hX hW h1 h2; exact omS136 he) rw[tightGo,Ἄ ht,List.range'_succ,ὔ] dsimp only rw[qAg _ _ hX,qAg _ _ hW,qAf _ _ (by clear hW h2 ht; omega),qAf _ _ (by clear hX h1 ht; omega)] rw[ih (t+1) _ _ (by rw[usz t n ht];(clear hX hW h1 h2 ht; omega)),usz t n ht] section variable (G:C_G R I O X W b) (Y:Ὡ) {i j:Ὣ} (hi:i< R) (hj:j< O) include G Y i j hi hj lemma qDw {s a:ὧ} {hh:Ὢ} (hc:ziv (s+dv b[j]!) (nfOf I*(dv hh*a+(dv b[j]!).abs))≠Е → ziv (s+dv b[j]!) (nfOf I*(dv hh*a+(dv b[j]!).abs)) = dotOf (I+1) (λt=>if t< I then X[i*I+t]! else oneW) (λt=>if t< I then W[j*I+t]! else b[j]!)) : fin8 I Y X W b i j s (nfOf I) a hh b[j]! ѩI=C_out I Y X W b i j:=by have hin:I<2^32:=lt_trans G.ni (by norm_num1) have hX1:i*I+I<=ѧX:=by rw[<-G.hX];exact qBc hi (Ὗ _) have hW1:j*I+I<=ѧW:=by rw[<-G.hW];exact qBc hj (Ὗ _) have sX:=G.sX have sW:=G.sW have e1:(i*I).toUSize.toNat=i*I:=qAd _ (by clear hi hj hW1 sW; exact omS143 hX1 sX) have e2:(j*I).toUSize.toNat=j*I:=qAd _ (by clear hi hj hX1 sX e1; exact omS143 hW1 sW) have e3:I.toUSize.toNat=I:=qAd _ hin unfold fin8 dsimp only split . unfold fin8s;dsimp only;have e:=qE2 (xo:=(i*I).toUSize) (wo:=(j*I).toUSize) (n:=ѩI) G.sX G.sW (by rw[e1,e3];exact hX1) (by rw[e2,e3];exact hW1) I 0 0 0 (by rw[e3,C_z,Ἇ]);rw[C_z,e1,e2,<-ὗ] at e;rw[qHx G Y hi hj (s:=(tightGo X W (i*I).toUSize (j*I).toUSize ѩI 0 0 0).s) (e:=(tightGo X W (i*I).toUSize (j*I).toUSize ѩI 0 0 0).t) ⟨by rw[e],by rw[e]⟩] . rename_i h have hn:=(by simpa using h:ziv (s+dv b[j]!) (nfOf I*(dv hh*a+(dv b[j]!).abs))≠Е) obtain ⟨S,ex,fr,a1,a2,a3,hz,-⟩:=qB6 _ _ hn rw[qR0 _ _ (qR1 _ S ex fr a1 a2 a3 hz)];unfold C_out;congr 1;exact hc hn lemma qDL {s:ὧ} {hv:Ὢ} (g1:good hv=true) (g2:hv<=В) (L:љ) (hl:L.Nodup) (hl2:∀ t∈L,t< I) (g4:∀ t∈L,W[j*I+t]! &&& В<=hv) (hz:∀ t,t< I->t∉L->X[i*I+t]! &&& В=0) (hs:s=L.foldl (λ(acc:ὧ) t=>acc+dv X[i*I+t]! * dv W[j*I+t]!) 0) : fin8 I Y X W b i j s (nfOf I) (L.foldl (λ(a:ὧ) t=>a+(dv X[i*I+t]!).abs) 0) hv b[j]! ѩI=C_out I Y X W b i j:=by have gb:=G.gb j (by rw[<-G.hb];exact hj) exact qDw G Y hi hj λh=>by obtain ⟨-,-,k⟩:=qBw _ _ h obtain ⟨c1,c2⟩:=qC8 I G.ni (λt=>X[i*I+t]!) (λt=>W[j*I+t]!) b[j]! hv (G.gx hi) (G.gw hj) gb g1 g2 L hl hl2 g4 hz _ _ ⟨by rw[hs],rfl⟩ k exact qCn I G.ni _ _ _ (G.gx hi) (G.gw hj) gb _ _ c1 c2 h lemma qDu {s:ὧ} {hv:Ὢ} (g1:good hv=true) (g2:hv<=В) (g4:∀ t,t< I->W[j*I+t]! &&& В<=hv) (L:љ) (hl:L.Nodup) (hl2:∀ t∈L,t< I) (hz:∀ t,t< I->t∉L->X[i*I+t]! &&& В=0) (hs:s=L.foldl (λ(acc:ὧ) t=>acc+dv X[i*I+t]! * dv W[j*I+t]!) 0) : fin8 I Y X W b i j s (nfOf I) (L.foldl (λ(a:ὧ) t=>a+(dv X[i*I+t]!).abs) 0) hv b[j]! ѩI=C_out I Y X W b i j:= qDL G Y hi hj g1 g2 L hl hl2 (λt ht=>g4 t (hl2 t ht)) hz hs end end lemma qC5 (x:ὤ) (i:ὦ) (h:Ѥi< Ѩx) : x.uget i h=x.data[Ѥi]!:=by obtain ⟨ds⟩:=x;have h':Ѥi< ѧds:=h;rw[Ἕ ds Ѥi h'];rfl lemma qC3 (a:ѐ) (i:ὦ) (h:Ѥi< ѧa) : a.uget i h=a[Ѥi]!:=by rw[Ἕ a Ѥi h];rfl lemma qD6 (a:ὤ) (i:ὦ) (v:ὧ):(wrF a i v).size=Ѩa:=by unfold wrF;split;. obtain ⟨ds⟩:=a;exact Array.size_uset _ . rfl lemma qEt (a:ὤ) (i:ὦ) (v:ὧ) (q:Ὣ) (hs:Ѩa<2^32) (hi:Ѥi< Ѩa) : (wrF a i v).data[q]! = if q=Ѥi then v else a.data[q]!:=by have h:i< a.usize:=by rw[А,FloatArray.usize];rwa [qAd _ hs] unfold wrF;rw[Ἄ h];obtain ⟨ds⟩:=a;exact qFo ds _ q v hi def C_keep (xw:Ὣ->Ὢ) (t:Ὣ):љ := (ἄ t).filter (λp=>xw p &&& В != 0) section variable (xw:Ὣ->Ὢ) (t:Ὣ) include xw t lemma qBj:(C_keep xw t).length<=t:=by have h:=List.length_filter_le (λp=>xw p &&& В != 0) (ἄ t);simpa [C_keep] using h lemma qDp (h:xw t &&& В=0) : C_keep xw (t+1)=C_keep xw t:=by simp[C_keep,List.range_succ,List.filter_append,h] lemma qD5 (h:¬ xw t &&& В=0) : C_keep xw (t+1)=C_keep xw t ++ [t]:=by simp[C_keep,List.range_succ,List.filter_append,h] end lemma qAu (a:ὤ) (v:ὧ):(a.push v).size=Ѩa+1:=by obtain ⟨ds⟩:=a;exact Array.size_push _ lemma qDy (n:ὦ) (d:Ὣ):∀ (k:ὦ) (a:ὤ),Ѥk+d=Ѥn → (pushZ n k a).size=Ѩa+d:=by induction d with | zero => intro k a he;rw[pushZ,ἔ (by rw[А];(exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))))];rfl | succ d ih => intro k a he;have ht:k< n:=by rw[А];exact omS136 he rw[pushZ,Ἄ ht,ih (k+1) _ (by rw[usz k n ht];(clear ht; omega)),qAu];(clear he ht; omega) lemma qH6 {x:ὤ} {ix W:ѐ} {w0 m n:ὦ} (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hs:ѧW<2^32) (h0:Ѥw0+Ѥm<=ѧW) (xf:Ὣ->ὧ) (ww:Ὣ->Ὢ) (hww:∀ p,p< Ѥm->W[Ѥw0+p]! = ww p) (L:љ):∀ (t:ὦ) (a:ὧ),Ѥt+ѣL=Ѥn → (∀ k p:Ὣ,L[k]?=some p->p< Ѥm∧(ix[Ѥt+k]! : ὥ).toNat=p ∧ x.data[Ѥt+k]! = xf p) → go1 x ix W w0 m n t hx hi hs h0 a =L.foldl (λ(acc:ὧ) p=>acc+xf p*dv (ww p)) a:=by induction L with | nil => intro t a he _ rw[go1,ἔ (by rw[А];simp at he;(clear hx hi hs h0; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))] rfl | cons p L ih => intro t a he H simp only[List.length_cons] at he have ht:t< n:=by rw[А];exact omS136 he have htn:Ѥt< Ѥn :=(by exact Nat.succ_le_of_lt ‹_›) obtain ⟨h1,h2,h3⟩:=H 0 p rfl rw[Ἵ] at h2 h3 have hit:Ѥt< ѧix :=(by exact Nat.lt_of_lt_of_le ‹_› ‹_›) have e0:(ix.uget t hit).toUSize.toNat=p:=by rw[ὃ,qC3];exact h2 have hm:(ix.uget t hit).toUSize< m:=by rw[А,e0];exact h1 have e1:x.uget t (by clear ht htn h1 h2 e0 hm; (clear hit; exact omS144 hx he))=xf p:=by rw[qC5,h3] have e2:∀ pf,W.uget (w0+(ix.uget t hit).toUSize) pf=ww p:=by intro pf rw[qC3,qAf _ _ (by rw[e0];(clear ht htn hm pf; exact omS145 hs h0 h1)),e0,hww p h1] rw[go1,Ἄ ht] dsimp only rw[Ἄ hm] rw[e1,e2,ih (t+1) _ (by rw[usz t n ht];(clear ht htn h1 h2 e0 hm; exact omS137 he)),ὔ] intro k q hq have:=H (k+1) q (by simpa using hq) rw[usz t n ht,show Ѥt+1+k=Ѥt+(k+1) by (clear ht htn h1 h2 e0 hm this; exact omS146)] exact this def C_Dw (wd:ὤ) (W:ё):Prop := Ѩwd=ѧW->∀ q,q< ѧW->wd.data[q]! = dv W[q]! section variable {x:ὤ} {ix W:ѐ} {w0 w1 w2 w3 m n:ὦ} (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hs:ѧW<2^32) (h0:Ѥw0+Ѥm<=ѧW) (h1:Ѥw1+Ѥm<=ѧW) (h2:Ѥw2+Ѥm<=ѧW) (h3:Ѥw3+Ѥm<=ѧW) lemma qH0 (hv:∀ j,j< Ѥn->∃ w,good w=true∧x.data[j]! = dv w) (k:Ὣ) : ∀ (t:ὦ) (a b c d:ὧ),Ѥt+k=Ѥn → go4B x ix W w0 w1 w2 w3 m n t hx hi hs h0 h1 h2 h3 a b c d = ⟨go1 x ix W w0 m n t hx hi hs h0 a,go1 x ix W w1 m n t hx hi hs h1 b,go1 x ix W w2 m n t hx hi hs h2 c,go1 x ix W w3 m n t hx hi hs h3 d⟩:=by induction k with | zero => intro t a b c d he have hn:¬ t< n:=by rw[А];(exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))) unfold go4B go1 simp only[dite_eq_right hn] | succ k ih => intro t a b c d he have ht:t< n:=by rw[А];exact omS136 he have htn:Ѥt< Ѥn :=(by exact Nat.succ_le_of_lt ‹_›) unfold go4B go1 simp only[dite_eq_left ht] obtain ⟨w,g,e⟩:=hv _ htn have B:∀ (u:ὥ) p0,dvB (x.uget t p0) u=x.uget t p0*dv u:=by intro u p0 rw[qC5,e] exact qFw w u g have J:=λa b c d=>ih (t+1) a b c d (by rw[usz t n ht];(clear ht htn; exact omS137 he)) split<;>simp only[B,J] end def C_sp (I O:Ὣ) (Y:Ὡ) (X W b:ё) (q:Ὣ):Ὢ := C_out I Y X W b (q/O) (q%O) lemma qCi (I O:Ὣ) (Y:Ὡ) (X W b:ё) {i j:Ὣ} (hj:j< O) : C_sp I O Y X W b (i*O+j)=C_out I Y X W b i j:=by unfold C_sp;have h0:0< O :=(by exact omS147 hj);rw[ἥ i O,Nat.mul_add_div h0,Nat.mul_add_mod,Ὃ hj,Ἁ hj,Ἵ] lemma qAp {N:Ὣ} {sp:Ὣ->Ὢ} {p:Ὣ} {out:ё} (hN:N<2^32) (h:C_Inv N sp (λq=>q< p) out) {u:ὦ} {v:Ὢ} (hu:Ѥu=p) (hp:p< N) (hv:v=sp p):C_Inv N sp (λq=>q< p+1) (wrW out u v) := qA5 (qAk hN h hu hp hv) (λq _ (hq:q< p+1) =>(by exact omS148 hq:q=p∨q< p)) lemma qFk {u:ὦ} {p:Ὣ} (hu:Ѥu=p) (h:p+3<2^32) : (u+1).toNat=p+1∧(u+2).toNat=p+2∧(u+3).toNat=p+3 ∧ (p+4<2^32->(u+4).toNat=p+4):=by have l:∀ k,k<5->p+k<2^32->(u+USize.ofNat k).toNat=p+k:=λk hk h=>by rw[qAf _ _ (by rw[uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];exact omS149 hu h),uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide)),hu] exact ⟨l 1 (by decide) (by exact omS150 h),l 2 (by decide) (by exact Nat.le_of_lt ‹_›),l 3 (by decide) (by exact Nat.succ_le_of_lt ‹_›),l 4 (by exact Nat.le_refl _)⟩ lemma qEq {N:Ὣ} {sp:Ὣ->Ὢ} {p:Ὣ} {out:ё} (hN:N<2^32) (h:C_Inv N sp (λq=>q< p) out) {u:ὦ} {v0 v1 v2 v3:Ὢ} (hu:Ѥu=p) (hp:p+4<=N) (h0:v0=sp p) (h1:v1=sp (p+1)) (h2:v2=sp (p+2)) (h3:v3=sp (p+3)):C_Inv N sp (λq=>q< p+4) (wrW (wrW (wrW (wrW out u v0) (u+1) v1) (u+2) v2) (u+3) v3):=by obtain ⟨a1,a2,a3,-⟩:=qFk hu (by clear hu; exact omS151 hN hp) exact qAp hN (qAp hN (qAp hN (qAp hN h hu (by clear hN hu; exact omS152 hp) h0) a1 (by clear hN hu; exact omS153 hp) h1) a2 (by exact Nat.le_of_lt ‹_›) h2) a3 (by exact Nat.succ_le_of_lt ‹_›) h3 lemma qIA (k:Ὣ) (h:k<8192):(idA[k]!).toNat=k:=by rw[Ἕ idA k (by simp[idA];exact h)];simp only[idA,Array.getElem_ofFn];rw[Nat.toUInt32_eq,UInt32.toNat_ofNat'];exact Ἁ (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) lemma qIs:ѧidA=8192:=by simp[idA] lemma qRd (X:ѐ) (n:Ὣ) (buf:ὤ) (h:n<=8192) (hv:∀ k,k< n->buf.data[k]! = dv X[0*n+k]!):∀ k p:Ὣ,(ἄ n)[k]? = some p→(idA[k]!).toNat=p∧buf.data[k]! = dv X[0*n+p]!:=λk p hk=>by by_cases hk2:k< n . rw[List.getElem?_range hk2] at hk;injection hk with e;subst e;exact ⟨qIA k (by (exact Nat.lt_of_lt_of_le ‹_› ‹_›)),hv k hk2⟩ . rw[List.getElem?_eq_none (by simpa using hk2)] at hk;exact absurd hk (by simp) lemma qVz {X:ѐ} {a:Ὣ} {n:ὦ} (hX:ѧX<2^32) (hn:a+Ѥn<=ѧX) (d:Ὣ) : ∀ (t:ὦ) (buf:ὤ) (l:ὧ),Ѥt+d=Ѥn → Ѥn<=Ѩbuf → Ѩbuf<2^32 → (∀ k,k< Ѥt->buf.data[k]! = dv X[a+k]!) → l=(ἄ Ѥt).foldl (λ(acc:ὧ) p=>acc+(dv X[a+p]!).abs) 0 → (decD X ѩa n t buf l).ok=true → Ѩ(decD X ѩa n t buf l).buf=Ѩbuf ∧ (∀ k,k< Ѥn->(decD X ѩa n t buf l).buf.data[k]! = dv X[a+k]!) ∧ (decD X ѩa n t buf l).l=(ἄ Ѥn).foldl (λ(acc:ὧ) p=>acc+(dv X[a+p]!).abs) 0:=by have ea:Ѥ(ѩa)=a:=qAd a (by exact omS154 hX hn) induction d with | zero=> intro t buf l he hb hs hd hl hok have hn':¬ t< n:=by rw[А];(clear hX hn ea hb hs; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))) rw[decD,ἔ hn'];have e:Ѥt=Ѥn:=by exact omS155 he rw[e] at hd hl;exact ⟨rfl,hd,hl⟩ | succ d ih=> intro t buf l he hb hs hd hl hok have ht:t< n:=by rw[А];(clear hX hn ea hb hs; exact omS136 he) have h1:=А.mp ht have u:=usz t n ht have er:rdW X (ѩa+t)=X[a+Ѥt]!:=by rw[qAg _ _ hX,qAf _ _ (by (clear hb hs ht h1; exact omS156 hX hn ea he)),ea] rw[decD,Ἄ ht] at hok ⊢;dsimp only at hok ⊢;rw[er] at hok ⊢ have R:=ih (t+1) (wrF buf t (dv X[a+Ѥt]!)) (l+(dv X[a+Ѥt]!).abs) (by (clear hX hn ea hb hs ht h1 er; exact omS157 he u)) (by rw[qD6];exact hb) (by rw[qD6];exact hs) (λk hk=>by rw[u] at hk;rw[qEt buf t _ k hs (by (exact Nat.lt_of_lt_of_le ‹_› ‹_›))];split . rename_i e;rw[e] . exact hd k (by (clear hX hn ea he hb hs ht h1 er; (clear u; omega)))) (by rw[u,List.range_succ,List.foldl_append,hl];rfl) hok rw[qD6] at R;exact R lemma qDs (xw:Ὣ->Ὢ) (n:Ὣ):(C_keep xw n).Nodup∧(∀ t∈C_keep xw n,t< n) ∧ ∀ t,t< n->t∉C_keep xw n->xw t &&& В=0 := ⟨Ὂ.filter _,λt ht=>Ἅ.mp (List.mem_filter.mp ht).1, λt ht hn=>by by_contra hc exact hn (List.mem_filter.mpr ⟨Ἅ.mpr ht,by simpa using hc⟩)⟩ lemma qW8p (a:ὤ) (v0 v1 v2 v3 v4 v5 v6 v7:ὧ) (q:Ὣ) (h:q< Ѩa):((((((((a.push v0).push v1).push v2).push v3).push v4).push v5).push v6).push v7).data[q]! = a.data[q]!:=by obtain ⟨ds⟩:=a;have h':q< ds.size:=h;simp [FloatArray.push,getElem!_def,Array.getElem?_push,show q≠ds.size by (clear h; exact omS158 h'),show q≠ds.size+1 by (clear h; exact omS159 h'),show q≠ds.size+1+1 by (clear h; exact omS160 h'),show q≠ds.size+1+1+1 by (clear h; exact omS161 h'),show q≠ds.size+1+1+1+1 by (clear h; exact omS162 h'),show q≠ds.size+1+1+1+1+1 by (clear h; exact omS163 h'),show q≠ds.size+1+1+1+1+1+1 by (clear h; exact omS164 h'),show q≠ds.size+1+1+1+1+1+1+1 by (clear h; exact omS165 h')] lemma wbIs (W:ѐ) (m r i:Ὣ) (a:ὤ):(wbI W m r i a).size=Ѩa+8*(m-i):=by rw[wbI];split . rw[wbIs];simp only[qAu];omega . omega termination_by m-i decreasing_by all_goals omega lemma wbIp (W:ѐ) (m r i:Ὣ) (a:ὤ) (q:Ὣ) (hq:q< Ѩa):(wbI W m r i a).data[q]! = a.data[q]!:=by rw[wbI];split . rw[wbIp _ _ _ _ _ _ (by simp only[qAu];exact omS166 hq),qW8p _ _ _ _ _ _ _ _ _ _ hq] . rfl termination_by m-i decreasing_by all_goals omega lemma qW8k (a:FloatArray) (v0 v1 v2 v3 v4 v5 v6 v7:Float) (k:Nat) (hk:k<8) : ((((((((a.push v0).push v1).push v2).push v3).push v4).push v5).push v6).push v7).data[a.size+k]! = (#[v0,v1,v2,v3,v4,v5,v6,v7]:Array Float)[k]!:=by have e:((((((((a.push v0).push v1).push v2).push v3).push v4).push v5).push v6).push v7).data=a.data ++ #[v0,v1,v2,v3,v4,v5,v6,v7]:=by simp only [FloatArray.push,Array.push_eq_append,Array.append_assoc,List.append_toArray,List.cons_append,List.nil_append] rw[e,getElem!_pos _ _ (by simp [FloatArray.size];(exact Nat.succ_le_of_lt ‹_›)),getElem!_pos _ _ (by simp;(exact Nat.succ_le_of_lt ‹_›)),Array.getElem_append_right (by simp [FloatArray.size])] simp [FloatArray.size] lemma wbIn (W:ѐ) (m r i:Ὣ) (a:ὤ) (i':Ὣ) (h1:i<=i') (h2:i'< m) (k:Ὣ) (hk:k<8) (q:Ὣ) (hq:q=Ѩa+8*(i'-i)+k):(wbI W m r i a).data[q]! = dv W[(r+k)*m+i']!:=by rw[wbI,ἱ (by (exact Nat.lt_of_le_of_lt ‹_› ‹_›):i< m)] by_cases e:i'=i . subst e;rw[wbIp _ _ _ _ _ _ (by simp only[qAu];(clear h2 h1; exact omS167 hk hq))];rw[show q=Ѩa+k by (clear h2 hk h1; exact omS168 hq)] rw[qW8k _ _ _ _ _ _ _ _ _ k hk];interval_cases k<;>rfl . exact wbIn W m r (i+1) _ i' (by (clear h2 hk hq; exact omS138 h1 e)) h2 k hk q (by simp only[qAu];(clear h2 hk; exact omS169 h1 hq e)) termination_by m-i decreasing_by all_goals (clear hk e; exact omS170 h2 h1) lemma wbOp (W:ѐ) (m nb c:Ὣ) (a:ὤ) (q:Ὣ) (hq:q< Ѩa):(wbO W m nb c a).data[q]! = a.data[q]!:=by rw[wbO];split . rw[wbOp _ _ _ _ _ _ (by rw[wbIs];exact omS171 hq),wbIp _ _ _ _ _ _ hq] . rfl termination_by nb-c decreasing_by all_goals omega lemma wbOn (W:ѐ) (m nb c:Ὣ) (a:ὤ) (c':Ὣ) (h1:c<=c') (h2:c'< nb) (i:Ὣ) (hi:i< m) (k:Ὣ) (hk:k<8) (q:Ὣ) (hq:q=Ѩa+(c'-c)*(8*m)+8*i+k):(wbO W m nb c a).data[q]! = dv W[(8*c'+k)*m+i]!:=by rw[wbO,ἱ (by (exact Nat.lt_of_le_of_lt ‹_› ‹_›):c< nb)] by_cases e:c'=c . subst e;rw[Nat.sub_self,Nat.zero_mul] at hq;rw[wbOp _ _ _ _ _ _ (by rw[wbIs];(clear h2 h1; exact omS172 hi hk hq))];exact wbIn W m (8*c') 0 a i (Nat.zero_le _) hi k hk q (by exact omS173 hq) . have e2:c'-c=(c'-(c+1))+1:=by (clear h2 hi hk hq; exact omS174 h1 e) rw[e2,Nat.add_mul,Nat.one_mul] at hq exact wbOn W m nb (c+1) _ c' (by (clear h2 hi hk hq e; exact omS175 e2)) h2 i hi k hk q (by rw[wbIs];(clear h1 h2 hi hk e e2; exact omS176 hq)) termination_by nb-c decreasing_by all_goals (clear hi hk e e2; exact omS170 h2 h1) lemma wbITp (W:ѐ) (m r o i:Ὣ) (a:ὤ) (q:Ὣ) (hq:q< Ѩa):(wbIT W m r o i a).data[q]! = a.data[q]!:=by rw[wbIT];split . rw[wbITp _ _ _ _ _ _ _ (by simp only[qAu];exact omS166 hq),qW8p _ _ _ _ _ _ _ _ _ _ hq] . rfl termination_by m-i decreasing_by all_goals omega lemma wbITn (W:ѐ) (m r o i:Ὣ) (a:ὤ) (i':Ὣ) (h1:i<=i') (h2:i'< m) (k:Ὣ) (hk:k<8) (q:Ὣ) (hq:q=Ѩa+8*(i'-i)+k):(wbIT W m r o i a).data[q]! = dv W[(min (r+k) (o-1))*m+i']!:=by rw[wbIT,ἱ (by (exact Nat.lt_of_le_of_lt ‹_› ‹_›):i< m)] by_cases e:i'=i . subst e;rw[wbITp _ _ _ _ _ _ _ (by simp only[qAu];(clear h2 h1; exact omS167 hk hq))];rw[show q=Ѩa+k by (clear h2 hk h1; exact omS168 hq)] rw[qW8k _ _ _ _ _ _ _ _ _ k hk];interval_cases k<;>rfl . exact wbITn W m r o (i+1) _ i' (by (clear h2 hk hq; exact omS138 h1 e)) h2 k hk q (by simp only[qAu];(clear h2 hk; exact omS169 h1 hq e)) termination_by m-i decreasing_by all_goals (clear hk e; exact omS170 h2 h1) lemma wbOs (W:ѐ) (m nb c:Ὣ) (a:ὤ):(wbO W m nb c a).size=Ѩa+(nb-c)*(8*m):=by rw[wbO];split . rename_i h;rw[wbOs,wbIs];have:(nb-c)=(nb-(c+1))+1:=by exact omS177 h rw[this,Nat.add_mul,Nat.one_mul,Nat.sub_zero];omega . rename_i h;rw[show nb-c=0 by exact omS178 h,Nat.zero_mul,Nat.add_zero] termination_by nb-c decreasing_by all_goals omega lemma wbZs (n:Ὣ):(wbZ n).size=5:=by simp only[wbZ,qAu];simp[FloatArray.emptyWithCapacity,FloatArray.size] lemma wbP0 (W:ѐ) (m o j i k:Ὣ) (hj:j%8=0) (ho:j+8<=o) (hi:i< m) (hk:k<8):(wbO W m (o/8) 0 (wbZ ѧW)).data[j*m+5+8*i+k]! = dv W[(j+k)*m+i]!:=by have e1:8*(j/8)=j:=by (clear ho hi hk; exact omS179 hj) have e0:(wbZ ѧW).size=5:=wbZs _ have e3:j/8*(8*m)=j*m:=by rw[<-Nat.mul_assoc,Nat.mul_comm (j/8) 8,e1] have:=wbOn W m (o/8) 0 (wbZ ѧW) (j/8) (Nat.zero_le _) (by (clear hi hk e1 e0 e3; exact omS180 ho)) i hi k hk (j*m+5+8*i+k) (by rw[e0,Nat.sub_zero,e3];(clear hj ho hi hk e1 e0 e3; exact omS181)) rw[e1] at this;exact this lemma wbP (W:ѐ) (m o j i k:Ὣ) (hj:j%8=0) (ho:j+8<=o) (hi:i< m) (hk:k<8):(wbOf m o W).data[j*m+5+8*i+k]! = dv W[(j+k)*m+i]!:=by unfold wbOf;dsimp only;split . exact wbP0 W m o j i k hj ho hi hk . rw[wbITp _ _ _ _ _ _ _ (by rw[wbOs];have e0:(wbZ ѧW).size=5:=wbZs _ rw[e0,Nat.sub_zero] have e1:8*(j/8)=j:=by (clear ho hi hk; exact omS179 hj) have:j/8+1<=o/8:=by exact omS182 ho have:(j/8+1)*(8*m)<=(o/8)*(8*m):=Nat.mul_le_mul_right _ this have e3:j*m+8*m=(j/8+1)*(8*m):=by rw[Nat.add_mul,Nat.one_mul,<-Nat.mul_assoc,Nat.mul_comm (j/8) 8,e1] have:j*m+8*i+kwb.data[Ѥp+8*i+0]! = dv W[Ѥw0+i]!∧wb.data[Ѥp+8*i+1]! = dv W[Ѥw1+i]!∧wb.data[Ѥp+8*i+2]! = dv W[Ѥw2+i]!∧wb.data[Ѥp+8*i+3]! = dv W[Ѥw3+i]!∧ wb.data[Ѥp+8*i+4]! = dv W[Ѥv0+i]!∧wb.data[Ѥp+8*i+5]! = dv W[Ѥv1+i]!∧wb.data[Ѥp+8*i+6]! = dv W[Ѥv2+i]!∧wb.data[Ѥp+8*i+7]! = dv W[Ѥv3+i]!) (k:Ὣ):∀ (t:ὦ) (a b c d e f g z:ὧ),Ѥt+k=Ѥn → go8W x wb ix p m n t hx hi hb hs a b c d e f g z=(⟨go1 x ix W w0 m n t hx hi hs' h0 a,go1 x ix W w1 m n t hx hi hs' h1 b,go1 x ix W w2 m n t hx hi hs' h2 c,go1 x ix W w3 m n t hx hi hs' h3 d⟩,⟨go1 x ix W v0 m n t hx hi hs' g0 e,go1 x ix W v1 m n t hx hi hs' g1 f,go1 x ix W v2 m n t hx hi hs' g2 g,go1 x ix W v3 m n t hx hi hs' g3 z⟩):=by induction k with | zero=> intro t a b c d e f g z he have hn:¬ t< n:=by rw[А];(clear hx hi hb hs hs' h0 h1 h2 h3 g0 g1 g2 g3; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))) unfold go8W go1 simp only[dite_eq_right hn] | succ k ih=> intro t a b c d e f g z he have ht:t< n:=by rw[А];exact omS136 he unfold go8W go1 simp only[dite_eq_left ht] have J:=λa b c d e f g z=>ih (t+1) a b c d e f g z (by rw[usz t n ht];(clear ht; exact omS137 he)) split . rename_i hm simp only[qC5,qC3] at hm ⊢ generalize (ix[Ѥt]!).toUSize=i at hm ⊢ have him:=А.mp hm obtain ⟨E0,E1,E2,E3,E4,E5,E6,E7⟩:=HB _ him have e8:(USize.ofNat 8*i).toNat=8*Ѥi:=by rw[qWm _ _ (by rw[uk 8 (by decide)];(clear he ht hm; exact omS16 hb hs him)),uk 8 (by decide)] have T:∀ kk,kk<8->(p+USize.ofNat 8*i+USize.ofNat kk).toNat=Ѥp+8*Ѥi+kk:=λkk hk=>by rw[qAf _ _ (by rw[qAf _ _ (by rw[e8];(clear he ht hm e8; exact omS17 hb hs him)),e8,uk kk (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];(clear he ht hm e8; omega)),qAf _ _ (by rw[e8];(clear he ht hm e8; exact omS17 hb hs him)),e8,uk kk (by exact Nat.lt_of_lt_of_le ‹_› (by decide))] have V:∀ w:ὦ,Ѥw+Ѥm<=ѧW->(w+i).toNat=Ѥw+Ѥi:=λw hw=>qAf _ _ (by (clear he ht hm e8; exact omS184 hs' him hw)) rw[T 0 (by decide),T 1 (by decide),T 2 (by decide),T 3 (by decide),T 4 (by decide),T 5 (by decide),T 6 (by decide),T 7 (by exact Nat.le_refl _),V w0 h0,V w1 h1,V w2 h2,V w3 h3,V v0 g0,V v1 g1,V v2 g2,V v3 g3,E0,E1,E2,E3,E4,E5,E6,E7] exact J _ _ _ _ _ _ _ _ . exact J _ _ _ _ _ _ _ _ lemma qR4 {x:ὤ} {ix W:ѐ} {wd:ὤ} {w0 w1 w2 w3 m n:ὦ} (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hs:ѧW<2^32) (h0:Ѥw0+Ѥm<=ѧW) (h1:Ѥw1+Ѥm<=ѧW) (h2:Ѥw2+Ѥm<=ѧW) (h3:Ѥw3+Ѥm<=ѧW) (HX:∀ j,j< Ѥn->∃ w,good w=true∧x.data[j]! = dv w) (Hd:C_Dw wd W): go4B x ix W w0 w1 w2 w3 m n 0 hx hi hs h0 h1 h2 h3 0 0 0 0=⟨go1 x ix W w0 m n 0 hx hi hs h0 0,go1 x ix W w1 m n 0 hx hi hs h1 0,go1 x ix W w2 m n 0 hx hi hs h2 0,go1 x ix W w3 m n 0 hx hi hs h3 0⟩:=by exact qH0 hx hi hs h0 h1 h2 h3 HX Ѥn 0 0 0 0 0 (Ἇ _) set_option maxRecDepth 8192 in theorem cT_eq (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (rr:G8) (j0:Ὣ) (HX:∀ j,j< Ѥn->∃ w,good w=true∧x.data[j]! = dv w) (Hd:C_Dw wd W) (hxn:Ѥn<=Ѩx) (hin:Ѥn<=ѧix) (hsW:ѧW<2^32) (HO:outW*Ѥm<=ѧW) (HO2:outW<2^32) (HL:∀ (k:Ὣ) (w:ὦ) (hw:Ѥw=(j0+k)*Ѥm) (h0:Ѥw+Ѥm<=ѧW),j0+k< outW → C_g8 rr k=go1 x ix W w m n 0 hxn hin hsW h0 0) (j:Ὣ) (hj:j0<=j) (base:ὦ) (out:ѐ) : cols1T inW outW relu X W b i nf a hx lo m rr j0 j base out=cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out:=by induction hd:outW-j using Nat.strong_induction_on generalizing j out with | _ d ih=> have M:∀ (u:ὦ) (r:Ὣ),Ѥu=r->r+1<=outW->Ѥ(u*m)=r*Ѥm:=λu r hu hr=>by rw[qWm _ _ (by rw[hu];exact lt_of_le_of_lt (le_trans (Nat.mul_le_mul_right _ (by (exact Nat.le_of_lt ‹_›))) HO) hsW),hu] have B:∀ (u:ὦ) (r:Ὣ),Ѥu=r->r+1<=outW->Ѥ(u*m)+Ѥm<=ѧW:=λu r hu hr=>by rw[M u r hu hr];have:=Nat.mul_le_mul_right Ѥm hr;rw[Nat.add_mul,Nat.one_mul] at this;exact this.trans HO have hW32:ѧW<=4294967295:=by exact omS185 hsW rw[cols1T,cols1] by_cases h4:j+4<=outW . rw[Ἄ h4,Ἄ h4] dsimp only have ej:Ѥ(ѩj)=j:=uk j (by exact omS186 HO2 h4) obtain ⟨e1,e2,e3,-⟩:=qFk ej (by exact omS151 HO2 h4) rw[Ἄ ⟨hxn,hin,hW32,B _ _ ej (by exact omS187 h4),B _ _ e1 (by exact omS188 h4),B _ _ e2 (by exact omS189 h4),B _ _ e3 (by exact omS190 h4)⟩] rw[qR4 _ _ _ _ _ _ _ HX Hd] dsimp only rw[HL (j-j0) (ѩj*m) (by rw[M _ _ ej (by exact omS187 h4)];congr 1;exact omS191 hj) (B _ _ ej (by exact omS187 h4)) (by exact omS192 hj h4), HL (j+1-j0) ((ѩj+1)*m) (by rw[M _ _ e1 (by exact omS188 h4)];congr 1;exact omS193 hj) (B _ _ e1 (by exact omS188 h4)) (by exact omS194 hj h4), HL (j+2-j0) ((ѩj+2)*m) (by rw[M _ _ e2 (by exact omS189 h4)];congr 1;exact omS195 hj) (B _ _ e2 (by exact omS189 h4)) (by exact omS196 hj h4), HL (j+3-j0) ((ѩj+3)*m) (by rw[M _ _ e3 (by exact omS190 h4)];congr 1;exact omS197 hj) (B _ _ e3 (by exact omS190 h4)) (by exact omS198 hj h4)] exact ih _ (by exact omS199 hd h4) (j+4) (by exact omS200 hj) _ rfl . rw[ἔ h4,ἔ h4] by_cases h1:j< outW . rw[Ἄ h1,Ἄ h1] dsimp only have ej:Ѥ(ѩj)=j:=uk j (by exact omS201 HO2 h1) rw[Ἄ ⟨hxn,hin,hW32,B _ _ ej (by exact omS202 h1)⟩] rw[HL (j-j0) (ѩj*m) (by rw[M _ _ ej (by exact omS202 h1)];congr 1;exact omS191 hj) (B _ _ ej (by exact omS202 h1)) (by exact omS203 hj h1)] exact ih _ (by exact omS204 hd h1) (j+1) (by exact omS205 hj) _ rfl . rw[ἔ h1,ἔ h1] set_option maxRecDepth 8192 in set_option maxHeartbeats 1000000 in lemma cTL (x wb:ὤ) (ix W:ѐ) (outW:Ὣ) (m n:ὦ) (j:Ὣ) (hj:j=8*(outW/8)) (hxn:Ѥn<=Ѩx) (hin:Ѥn<=ѧix) (hb:Ѥ(ѩj*m+USize.ofNat 5)+8*Ѥm<=Ѩwb) (he:Ѥ(ѩj*m+USize.ofNat 5)=Ѥ(ѩj*m)+5) (hs:Ѩwb<2^32) (hsW:ѧW<2^32) (HO:outW*Ѥm<=ѧW) (HO2:outW<2^32) (HBt:∀ i k,i< Ѥm → k<8 → wb.data[(8*(outW/8))*Ѥm+5+8*i+k]! = dv W[(min (8*(outW/8)+k) (outW-1))*Ѥm+i]!) : ∀ (k:Ὣ) (w:ὦ) (hw:Ѥw=(j+k)*Ѥm) (h0:Ѥw+Ѥm<=ѧW),j+k< outW → C_g8 (g8of (go8W x wb ix (ѩj*m+USize.ofNat 5) m n 0 hxn hin hb hs 0 0 0 0 0 0 0 0)) k=go1 x ix W w m n 0 hxn hin hsW h0 0:=by intro k w hw h0 hk have hk8:k<8:=by exact omS206 hj hk have hjm:Ѥ(ѩj*m)=j*Ѥm:=by rw[qWm _ _ (by rw[qAd j (by exact omS207 hj HO2)];exact lt_of_le_of_lt (le_trans (Nat.mul_le_mul_right _ (by exact omS208 hj)) HO) hsW),qAd j (by exact omS207 hj HO2)] have twk:∀ kk,kk<8 → Ѥ((ѩ(min (j+kk) (outW-1)))*m)=(min (j+kk) (outW-1))*Ѥm:=λkk hkk=>by rw[qWm _ _ (by rw[qAd _ (by omega)];exact lt_of_le_of_lt (le_trans (Nat.mul_le_mul_right _ (by omega)) HO) hsW),qAd _ (by omega)] have bwk:∀ kk,kk<8 → Ѥ((ѩ(min (j+kk) (outW-1)))*m)+Ѥm<=ѧW:=λkk hkk=>by rw[twk kk hkk];have:min (j+kk) (outW-1)+1<=outW:=by exact omS209 hk have:=Nat.mul_le_mul_right Ѥm this;rw[Nat.add_mul,Nat.one_mul] at this;exact this.trans HO have HB8:∀ i,i< Ѥm->wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+0]! = dv W[Ѥ((ѩ(min (j+0) (outW-1)))*m)+i]!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+1]! = dv W[Ѥ((ѩ(min (j+1) (outW-1)))*m)+i]!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+2]! = dv W[Ѥ((ѩ(min (j+2) (outW-1)))*m)+i]!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+3]! = dv W[Ѥ((ѩ(min (j+3) (outW-1)))*m)+i]!∧ wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+4]! = dv W[Ѥ((ѩ(min (j+4) (outW-1)))*m)+i]!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+5]! = dv W[Ѥ((ѩ(min (j+5) (outW-1)))*m)+i]!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+6]! = dv W[Ѥ((ѩ(min (j+6) (outW-1)))*m)+i]!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i+7]! = dv W[Ѥ((ѩ(min (j+7) (outW-1)))*m)+i]!:=λi hi=>by rw[he,hjm,twk 0 (by decide),twk 1 (by decide),twk 2 (by decide),twk 3 (by decide),twk 4 (by decide),twk 5 (by decide),twk 6 (by decide),twk 7 (by decide)] have Q:=λkk (hkk:kk<8)=>HBt i kk hi hkk subst hj exact ⟨Q 0 (by decide),Q 1 (by decide),Q 2 (by decide),Q 3 (by decide),Q 4 (by decide),Q 5 (by decide),Q 6 (by decide),Q 7 (by decide)⟩ rw[g8WE x wb ix W (ѩj*m+USize.ofNat 5) _ _ _ _ _ _ _ _ m n hxn hin hb hs hsW (bwk 0 (by decide)) (bwk 1 (by decide)) (bwk 2 (by decide)) (bwk 3 (by decide)) (bwk 4 (by decide)) (bwk 5 (by decide)) (bwk 6 (by decide)) (bwk 7 (by decide)) HB8 Ѥn 0 0 0 0 0 0 0 0 0 (by simp)] have ew:w=(ѩ(min (j+k) (outW-1)))*m:=USize.toNat_inj.mp (by rw[hw,twk k hk8];congr 1;exact omS210 hk) subst ew interval_cases k<;>rfl theorem c1WE (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (HX:∀ j,j< Ѥn->∃ w,good w=true∧x.data[j]! = dv w) (Hd:C_Dw wd W) (HO:outW*Ѥm<=ѧW) (HO2:outW<2^32) (HB:∀ j i k,j%8=0->j+8<=outW->i< Ѥm->k<8->wb.data[j*Ѥm+5+8*i+k]! = dv W[(j+k)*Ѥm+i]!) (HBt:outW%8≠0 → ∀ i k,i< Ѥm → k<8 → wb.data[(8*(outW/8))*Ѥm+5+8*i+k]! = dv W[(min (8*(outW/8)+k) (outW-1))*Ѥm+i]!) (j:Ὣ) (hj:j%8=0) (base:ὦ) (out:ѐ): cols1W inW outW relu X W b i ix x wd wb nf a hx lo m n j base out=cols1 inW outW relu X W b i ix x wd nf a hx lo m n j base out:=by induction hd:outW-j using Nat.strong_induction_on generalizing j hj out with | _ d ih=> rw[cols1W];split . rename_i h8;dsimp only;split . rename_i hg have sW:ѧW<2^32:=qA9 hg.2.2.1 have ej:Ѥ(ѩj)=j:=uk j (by (clear HO hd hg sW; exact omS211 HO2 h8)) have ej4:Ѥ((j+4).toUSize)=j+4:=uk (j+4) (by (clear HO hd hg sW ej; exact omS212 HO2 h8)) obtain ⟨e1,e2,e3,-⟩:=qFk ej (by (clear HO hd hg sW ej ej4; exact omS213 HO2 h8)) obtain ⟨f1,f2,f3,-⟩:=qFk ej4 (by (clear HO hd hg sW ej ej4 e1 e2 e3; exact omS214 HO2 h8)) have M:∀ (u:ὦ) (r:Ὣ),Ѥu=r->r+1<=outW->Ѥ(u*m)=r*Ѥm:=λu r hu hr=>by rw[qWm _ _ (by rw[hu];exact lt_of_le_of_lt (le_trans (Nat.mul_le_mul_right _ (by (exact Nat.le_of_lt ‹_›))) HO) sW),hu] have HB8:∀ i',i'< Ѥm->wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+0]! = dv W[Ѥ(ѩj*m)+i']!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+1]! = dv W[((ѩj+1)*m).toNat+i']!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+2]! = dv W[((ѩj+2)*m).toNat+i']!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+3]! = dv W[((ѩj+3)*m).toNat+i']!∧ wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+4]! = dv W[((j+4).toUSize*m).toNat+i']!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+5]! = dv W[(((j+4).toUSize+1)*m).toNat+i']!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+6]! = dv W[(((j+4).toUSize+2)*m).toNat+i']!∧wb.data[Ѥ(ѩj*m+USize.ofNat 5)+8*i'+7]! = dv W[(((j+4).toUSize+3)*m).toNat+i']!:=λi' hi'=>by rw[(pk (ѩj*m) m wb hg.2.2.2.2.2.2.2.2.2.2.2.2 hg.2.2.2.2.2.2.2.2.2.2.2.1).2,M _ _ ej (by (clear HO HO2 hd hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS215 h8)),M _ _ e1 (by (clear HO HO2 hd hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS216 h8)),M _ _ e2 (by (clear HO HO2 hd hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS217 h8)),M _ _ e3 (by (clear HO HO2 hd hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS218 h8)),M _ _ ej4 (by (clear HO HO2 hd hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS219 h8)),M _ _ f1 (by (clear HO HO2 hd hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS220 h8)),M _ _ f2 (by (exact Nat.le_of_lt ‹_›)),M _ _ f3 (by (exact Nat.succ_le_of_lt ‹_›))] have Q:=λk hk=>HB j i' k hj h8 hi' hk refine ⟨by simpa using Q 0 (by decide),Q 1 (by decide),Q 2 (by decide),Q 3 (by decide),Q 4 (by decide),?_,?_,?_⟩ . have:=Q 5 (by decide);rwa[show j+5=j+4+1 by (clear HO HO2 hj hd h8 hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS221)] at this . have:=Q 6 (by decide);rwa[show j+6=j+4+2 by (clear HO HO2 hj hd h8 hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS222)] at this . have:=Q 7 (by exact Nat.le_refl _);rwa[show j+7=j+4+3 by (clear HO HO2 hj hd h8 hg sW ej ej4 e1 e2 e3 f1 f2 f3 hi'; exact omS223)] at this rw[g8WE x wb ix W (ѩj*m+USize.ofNat 5) (ѩj*m) ((ѩj+1)*m) ((ѩj+2)*m) ((ѩj+3)*m) ((j+4).toUSize*m) (((j+4).toUSize+1)*m) (((j+4).toUSize+2)*m) (((j+4).toUSize+3)*m) m n hg.1 hg.2.1 (pk (ѩj*m) m wb hg.2.2.2.2.2.2.2.2.2.2.2.2 hg.2.2.2.2.2.2.2.2.2.2.2.1).1 (qA9 hg.2.2.2.2.2.2.2.2.2.2.2.1) sW hg.2.2.2.1 hg.2.2.2.2.1 hg.2.2.2.2.2.1 hg.2.2.2.2.2.2.1 hg.2.2.2.2.2.2.2.1 hg.2.2.2.2.2.2.2.2.1 hg.2.2.2.2.2.2.2.2.2.1 hg.2.2.2.2.2.2.2.2.2.2.1 HB8 Ѥn 0 0 0 0 0 0 0 0 0 (Ἇ _)] rw[cols1,Ἄ (by (clear HO HO2 hd hg sW ej ej4 e1 e2 e3 f1 f2 f3; exact omS224 h8):j+4<=outW)];dsimp only;rw[Ἄ ⟨hg.1,hg.2.1,hg.2.2.1,hg.2.2.2.1,hg.2.2.2.2.1,hg.2.2.2.2.2.1,hg.2.2.2.2.2.2.1⟩] rw[qR4 _ _ _ _ _ _ _ HX Hd];dsimp only rw[cols1,Ἄ (by (exact Nat.succ_le_of_lt ‹_›):j+4+4<=outW)];dsimp only;rw[Ἄ ⟨hg.1,hg.2.1,hg.2.2.1,hg.2.2.2.2.2.2.2.1,hg.2.2.2.2.2.2.2.2.1,hg.2.2.2.2.2.2.2.2.2.1,hg.2.2.2.2.2.2.2.2.2.2.1⟩] rw[qR4 _ _ _ _ _ _ _ HX Hd];dsimp only exact ih (outW-(j+8)) (by (clear HO HO2 hg sW ej ej4 e1 e2 e3 f1 f2 f3; exact omS226 hd h8)) (j+8) (by (clear HO HO2 hd h8 hg sW ej ej4 e1 e2 e3 f1 f2 f3; exact omS227 hj)) _ rfl . rfl . rename_i h8 by_cases ht:j< outW . rw[Ἄ ht] by_cases hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb . rw[Ἄ hg] have hj8:j=8*(outW/8):=by exact omS228 hj h8 ht have sW:ѧW<2^32:=qA9 hg.2.2.1 exact cT_eq inW outW relu X W b i ix x wd nf a hx lo m n _ j HX Hd hg.1 hg.2.1 sW HO HO2 (cTL x wb ix W outW m n j hj8 hg.1 hg.2.1 (pk (ѩj*m) m wb hg.2.2.2.2.2 hg.2.2.2.1).1 (pk (ѩj*m) m wb hg.2.2.2.2.2 hg.2.2.2.1).2 (qA9 hg.2.2.2.1) sW HO HO2 (HBt (by exact omS229 ht hj8))) j (le_refl _) base out . rw[ἔ hg] . rw[ἔ ht] theorem g8VW (x wb:ὤ) (ix:ѐ) (p m n:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hn:Ѥn<=Ѥm) (hb:Ѥp+8*Ѥm<=Ѩwb) (hs:Ѩwb<2^32) (HI:∀ k,k< Ѥn->(ix[k]!).toNat=k) (k:Ὣ):∀ (t:ὦ) (a b c d e f g z:ὧ),Ѥt+k=Ѥn → go8V x wb p m n t hx hn hb hs a b c d e f g z=g8of (go8W x wb ix p m n t hx hi hb hs a b c d e f g z):=by induction k with | zero=> intro t a b c d e f g z he have hn':¬ t< n:=by rw[А];(clear hx hi hn hb hs; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))) rw[go8V,go8W,ἔ hn',ἔ hn'];rfl | succ k ih=> intro t a b c d e f g z he have ht:t< n:=by rw[А];exact omS136 he have J:=λa b c d e f g z=>ih (t+1) a b c d e f g z (by rw[usz t n ht];(clear ht; exact omS137 he)) have E:(ix[Ѥt]!).toUSize=t:=USize.toNat_inj.mp (by rw[ὃ];exact HI _ (А.mp ht)) rw[go8V,go8W,Ἄ ht,Ἄ ht];dsimp only;split . rename_i hm simp only[qC3] at hm ⊢ rw[J];simp only[E] . rename_i hm simp only[qC3,E] at hm exact absurd (by rw[А];have:=А.mp ht;(exact Nat.lt_of_lt_of_le ‹_› ‹_›)) hm theorem c1VW (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (HI:∀ k,k< Ѥn->(ix[k]!).toNat=k) (hn:Ѥn<=Ѥm) (j:Ὣ) (base:ὦ) (out:ѐ): cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n j base out=cols1W inW outW relu X W b i ix x wd wb nf a hx lo m n j base out:=by rw[cols1V];split . rename_i h8;rw[cols1W,Ἄ h8];dsimp only;split . rename_i hg obtain ⟨a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14⟩:=hg rw[Ἄ ⟨a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a14⟩] rw[g8VW x wb ix _ m n a1 a2 a13 _ _ HI Ѥn 0 0 0 0 0 0 0 0 0 (Ἇ _)];dsimp only[g8of] exact c1VW inW outW relu X W b i ix x wd wb nf a hx lo m n HI hn (j+8) base _ . rename_i hg rw[ἔ (λh=>hg (by obtain ⟨a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a14⟩:=h;exact ⟨a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,hn,a14⟩))] . rename_i h8;rw[cols1W,ἔ h8] by_cases ht:j< outW . rw[Ἄ ht,Ἄ ht] by_cases hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb . rw[Ἄ hg,Ἄ hg,g8VW x wb ix _ m n hg.1 hg.2.1 hg.2.2.2.2.1 _ _ HI Ѥn 0 0 0 0 0 0 0 0 0 (Ἇ _)] . rw[ἔ hg,ἔ hg] . rw[ἔ ht,ἔ ht] termination_by outW-j decreasing_by all_goals omega @[inline] def zivT (th:Ὠ) (s:ὧ):ὥ := let a:=s.toBits if th<=a <<< (1:Ὠ) then zivW (a+0x200000) (a-0x200000) else Е lemma qI8 (A P Q T g:Ὣ) (hg:g=0∨g=2^63) (ha:A<2^64) (e1:(A+2097152)%2^64=g+P) (e2:(2^64-2097152+A)%2^64=g+Q) (t1:2^61<=T) (t2:T<2^63-2^60) (l1:T< P+2^28) (u1:P<=T+2^28) (l2:T< Q+2^28) (u2:Q<=T+2^28) : A=g+(Q+2097152)∧T+2097152< Q+2097152+2^28 ∧ Q+2097152+2097152<=T+2^28:=by (clear hg t1 t2; exact omS230 ha e1 e2 l1 u1 l2 u2) lemma qJh (G f F:Ὣ) (hl:G+f+2097152< G+F+2^28) (hu:G+F+2097152<=G+f+2^28) : F+2097152<=f+2^28∧f+2097152< F+2^28:=by exact omS231 hl hu lemma kFh (th:Ὠ) (s:ὧ) (h:zivT th s≠Е) : th<=s.toBits <<< (1:Ὠ)∧∃ (S:Ὡ) (ex fr M:Ὣ),897<=ex∧ex<1151∧fr<2^23 ∧ zivT th s=ὺ ((if S then 2^31 else 0)+(ex-896)*2^23+fr) ∧ s.toBits.toNat=(if S then 2^63 else 0)+M ∧ (ex*2^23+fr)*2^29+2097152< M+2^28 ∧ M+2097152<=(ex*2^23+fr)*2^29+2^28:=by unfold zivT at h ⊢ dsimp only at h ⊢ split at h . rename_i ht;rw[ἱ ht];refine ⟨ht,?_⟩;obtain ⟨S,ex,fr,h1,h2,h3,hz,⟨P,e1,l1,u1⟩,⟨Q,e2,l2,u2⟩⟩:=qEs _ _ h;rw[ἤ] at e1;rw[ὲ] at e2;obtain ⟨a,b,c⟩:=qI8 _ P Q ((ex*2^23+fr)*2^29) _ (by cases S<;>simp) s.toBits.toNat_lt e1 e2 (by clear ht h hz e1 l1 u1 e2 l2 u2; exact omS232 h1) (by clear ht h hz e1 l1 u1 e2 l2 u2; exact omS233 h2 h3) l1 u1 l2 u2;exact ⟨S,ex,fr,Q+2097152,h1,h2,h3,hz,a,b,c⟩ . exact absurd rfl h lemma qI5 (v W z u:ℝ) (hu:0< u) (hz:z<=u) (h0:0<=v) (hv:v<=2^53*u) (h : |v-W| ≤ 1/2^33*(|W| + z)):v-2^21*u< W∧W< v+2^21*u:=by have h1 : |W| ≤ v + |v-W|:=by have a:=Ὥ W v;rw[abs_sub_comm W v,ἅ h0] at a;linarith only [a] have h2:=abs_lt.mp ((by linarith only [h1, h, hv, hz, hu]):|v-W| < 2^21*u);constructor<;>linarith [h2.1,h2.2] set_option maxRecDepth 8192 in lemma qJi (ex fr E F:Ὣ) (h1:897<=ex) (h2:ex<1151) (hfr:fr<2^23) (hF:F<2^52) (hl:(ex*2^23+fr)*2^29+2097152< E*2^52+F+2^28) (hu:E*2^52+F+2097152<=(ex*2^23+fr)*2^29+2^28) (W:ℝ) (h : |((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-W| ≤ 1/2^33*(|W| + A_z)) : W<(2^53+fr*2^30+2^29)*2^((ex:Int)-1076) ∧ (fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)< W) ∧ (2^53-2^28)*2^((ex:Int)-1076)< W:=by have hE:E=ex∨(E+1=ex∧fr=0) :=(by clear h1 h2; exact omS234 hfr hF hl hu) have hu0:(0:ℝ)<2^((E:Int)-1075):=ἵ (by positivity) _ have hz:A_z<=2^((E:Int)-1075):=by have e:A_z=2^(-1021:ℤ):=rfl rw[e] exact ἒ (by norm_num1) (by clear hE; exact omS235 h1 hF hl) have hN:((2^52+F:Ὣ):ℝ)<=2^53:=by have:2^52+F<=2^53 :=(by clear h1 h2 hfr hl hu hE; exact omS236 hF) exact_mod_cast this have hN0:(0:ℝ)<=((2^52+F:Ὣ):ℝ):=Ἔ _ obtain ⟨a,b⟩:=qI5 _ W A_z _ hu0 hz (Ἆ hN0 hu0.le) (ἀ hN hu0.le) h push_cast at a b rcases hE with rfl | ⟨rfl,rfl⟩ . have e:(2:ℝ)^((E:Int)-1075)=2*2^((E:Int)-1076):=by rw[show (E:Int)-1075=1+((E:Int)-1076) by ring,Ἓ ἓ,zpow_one] rw[e] at a b;have hb:(0:ℝ)<2^((E:Int)-1076):=ἵ (by positivity) _;generalize (2:ℝ)^((E:Int)-1076)=c at a b hb ⊢;have e1:(E*2^23+fr)*2^29=E*2^52+fr*2^29:=by ring rw[e1] at hl hu;obtain ⟨n3,n4⟩:=qJh _ _ _ hl hu;have h3:(F:ℝ)+2097152<=fr*2^29+2^28:=by exact_mod_cast n3 have h4:(fr:ℝ)*2^29+2097152< F+2^28:=by exact_mod_cast n4 have h5:(0:ℝ)<=F:=Ἔ _;have h6:(0:ℝ)<=fr:=Ἔ _;have h7:=ἀ h3 hb.le;have h8:=Ἦ h4 hb;have h9:=Ἆ h5 hb.le;have h10:=Ἆ h6 hb.le;refine ⟨?_,?_,?_⟩;. linarith only [b, h7] . intro _;linarith only [a, h8] . linarith only [a, h8, h9, h10] . have e:(2:ℝ)^(((E+1:Ὣ):Int)-1076)=2^((E:Int)-1075):=by congr 1;push_cast;ring rw[e];generalize (2:ℝ)^((E:Int)-1075)=c at a b hu0 ⊢;have h3:(F:ℝ)<=2^52:=by exact_mod_cast hF.le have h4:(2:ℝ)^52+2097152< F+2^28:=by exact_mod_cast (by (clear h1 h2 hfr; exact omS237 hl):2^52+2097152< F+2^28) have h7:=ἀ h3 hu0.le;have h8:=Ἦ h4 hu0;refine ⟨?_,?_,?_⟩;. simp only[Nat.cast_zero,zero_mul,add_zero];linarith only [b, h7, h8] . intro h0;exact absurd rfl h0 . linarith only [a, h8] lemma kHv (th:Ὠ) (s:ὧ) (d:FloatLib.Numerics.Dyadic) (hV : |R s-(d.toRat:ℝ)| ≤ 1/2^33*(|(d.toRat:ℝ)| + A_z)) (h:zivT th s≠Е):zivT th s=toWord (ἕ Fmt d):=by obtain ⟨-,S,ex,fr,M,h1,h2,h3,hz,hb,hl,hu⟩:=kFh th s h;have hM:M=(M/2^52)*2^52+M%2^52 :=(by clear h h1 h2 h3 hz hb hl hu; exact omS114);have hF:M%2^52<2^52:=ὀ _ (by positivity);generalize M/2^52=E at hM;generalize M%2^52=F at hM hF;subst hM;obtain ⟨-,hR⟩:=B_R s S E F (by clear h hz; exact omS238 h1 hF hl) (by clear h hz; exact omS239 h2 h3 hu) hF (by rw[hb,ὢ]);rw[hR] at hV obtain ⟨W,hVW,hW⟩:∃ W:ℝ,(d.toRat:ℝ)=(if S then -W else W) ∧ |((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-W| ≤ 1/2^33*(|W| + A_z):=by cases S . simp only[false_eq_true,ite_false,one_mul] at hV ⊢;exact ⟨_,rfl,hV⟩ . simp only[ite_true] at hV ⊢;refine ⟨-(d.toRat:ℝ),by simp,?_⟩;rw[abs_neg,show ((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075) - -(d.toRat:ℝ) =-(-1*((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-(d.toRat:ℝ)) by ring,abs_neg];exact hV obtain ⟨a,b,c⟩:=qJi ex fr E F h1 h2 h3 hF (by exact omS240 hl) (by exact omS241 hu) W hW;rw[hz];exact (qEo d S ex fr h1 h2 h3 W hVW a b c).symm lemma qJc (x:Ὠ) : ((x >>> (52:Ὠ)) &&& (0x7FF:Ὠ)).toNat=Ѧx/2^52%2^11:=by rw[Ὅ,ἰ];have:=Ἂ (Ѧx >>> 52) 11;norm_num [Nat.shiftRight_eq_div_pow] at this ⊢;exact this lemma qGj (b:Ὡ) (x y:ℝ) (hx:0<=x) (hy:0<=y) : |(if b=true then (-1:ℝ) else 1)*x*y| = x*y:=by have h:=ἅ (Ἆ hx hy) cases b . rw[show (if false=true then (-1:ℝ) else 1)*x*y=x*y by simp];exact h . rw[show (if true=true then (-1:ℝ) else 1)*x*y=-(x*y) by simp,abs_neg];exact h lemma qJb (a:Ὠ) (S:Ὡ) (M:Ὣ) (hM:M<2^63) (h:Ѧa=(if S then 2^63 else 0)+M):(a <<< (1:Ὠ)).toNat=2*M:=by rw[UInt64.toNat_shiftLeft,h];norm_num [Nat.shiftLeft_eq];cases S<;>simp<;>omega lemma kGw (e s:ὧ) (S:Ὡ) (M:Ὣ) (hM2:M<2047*2^52) (hs:s.toBits.toNat=(if S then 2^63 else 0)+M) (h:thOf e<=s.toBits <<< (1:Ὠ)) : e.isFinite=true∧|R e| ≤ 1/2^34 * |R s|:=by have hl:=qJb s.toBits S M (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) hs;unfold thOf at h;dsimp only at h;have hx:=qJc e.toBits;generalize (e.toBits >>> (52:Ὠ)) &&& (0x7FF:Ὠ)=E at h hx;rw[Ὤ,hl] at h;split at h . rename_i hc;rw[ἴ,ὲ] at hc;rw[UInt64.toNat_shiftLeft,ἤ] at h;have hA:=e.toBits.toNat_lt;norm_num [Nat.shiftLeft_eq] at hc h hA;obtain ⟨sg,hsg⟩:∃ sg:Ὡ,e.toBits.toNat =(if sg then 2^63 else 0)+ѦE*2^52+e.toBits.toNat%2^52:=by refine ⟨decide (2^63<=e.toBits.toNat),?_⟩;by_cases h6:2^63<=e.toBits.toNat<;>simp only[h6,decide_true,decide_false,ite_true,ite_false,false_eq_true]<;>(clear hM2 hs hl hc h; omega) have hFe:e.toBits.toNat%2^52<2^52:=ὀ _ ב;generalize e.toBits.toNat%2^52=Fe at hsg hFe;have hE1:1<=ѦE∧ѦE<=1900 :=(by clear hM2 hs hl h hA hsg hFe; exact omS242 hx hc);have hEs:M=(M/2^52)*2^52+M%2^52 :=(by clear hM2 hs hl hx hc h hA hsg hFe hE1; exact omS114);have hFs:M%2^52<2^52:=ὀ _ ב;generalize M/2^52=Es at hEs;generalize M%2^52=Fs at hEs hFs;subst hEs;have hle:ѦE+35<=Es :=(by clear hc hA hsg hFe hl; exact omS243 hE1 hFs h);obtain ⟨fe,re⟩:=B_R e sg ѦE Fe hE1.1 (by clear hc hA hsg hFe hFs hM2 hs hl h hle; exact omS244 hE1) hFe hsg;obtain ⟨-,rs⟩:=B_R s S Es Fs (by clear hA hsg hFe hE1 hM2 hl hle; exact omS245 hc hFs h) (by clear hx hc hA hsg hFe hE1 hl h hle; exact omS246 hM2) hFs (by rw[hs,ὢ]);refine ⟨fe,?_⟩;have hc0:(0:ℝ)<2^((ѦE:Int)-1075):=ἵ ב _;have h1:(2:ℝ)^((ѦE:Int)+35-1075)<=2^((Es:Int)-1075) :=ἒ ב (by clear hc hA hsg hFe hE1 hFs hM2 hs hl h; exact omS247 hle);have h2:(2:ℝ)^((ѦE:Int)+35-1075)=2^35*2^((ѦE:Int)-1075):=by rw[show (ѦE:Int)+35-1075=35+((ѦE:Int)-1075) by ring,Ἓ ἓ];norm_num have hae : |R e| = ((2^52+Fe:Ὣ):ℝ)*2^((ѦE:Int)-1075):=by rw[re];exact qGj _ _ _ (Ἔ _) hc0.le have has : |R s| = ((2^52+Fs:Ὣ):ℝ)*2^((Es:Int)-1075):=by rw[rs];exact qGj _ _ _ (Ἔ _) (ἵ ב _).le rw[hae,has];have n1:((2^52+Fe:Ὣ):ℝ)<=2^53:=by have:2^52+Fe<=2^53 :=(by clear hx hc hA hsg hE1 hFs hM2 hs hl h hle; exact omS236 hFe);exact_mod_cast this have n2:(2:ℝ)^52<=((2^52+Fs:Ὣ):ℝ):=by have:2^52<=2^52+Fs :=(by clear hx hc hA hsg hFe hE1 hM2 hl h hle; exact omS248);exact_mod_cast this generalize (2:ℝ)^((ѦE:Int)-1075)=c at *;generalize (2:ℝ)^((Es:Int)-1075)=d at *;rw[h2] at h1;have n3:=ἀ n1 hc0.le;have n0:0<=d :=(by linarith only [hc0, h1]);have n4:=ἁ (ἀ n2 n0) (by norm_num:(0:ℝ)<=1/2^34);have n5:(2:ℝ)^53*c<=1/2^34*(2^52*d) :=(by linarith only [h1]);exact n3.trans (n5.trans n4) . exfalso;norm_num at h;exact omS249 hM2 h lemma qHs (s e:ὧ) (V:ℝ) (fs:s.isFinite=true) (fe:e.isFinite=true) (hrel : |R e| ≤ 1/2^34 * |R s|) (hB : |R s| ≤ 2^(130:ℤ)) (hlo:R (s-e)< V) (hhi:V< R (s+e)) : |R s-V| ≤ 1/2^33*(|V| + A_z):=by have sck:∀ {k a b:ℝ},0(le_div_iff₀' hk).mp (h.trans_eq (one_div_mul_eq_div _ _)) have hA:(2:ℝ)^(130:ℤ)<=A_B:=by unfold A_B;exact ἒ (by norm_num1) (by norm_num1) have h1 : |R e| ≤ A_B:=hrel.trans ((mul_le_of_le_one_left (Ἀ _) (by norm_num1)).trans (hB.trans hA)) obtain ⟨-,p⟩:=qBf s e fs fe (hB.trans hA) h1;obtain ⟨-,m⟩:=qDf s e fs fe (hB.trans hA) h1 have p':=sck (by norm_num1) p;have m':=sck (by norm_num1) m;have p2:=le_abs_self (R (s+e)-(R s+R e));have m2:=neg_abs_le (R (s-e)-(R s-R e)) have q1:=Ἐ (R s) (R e);have q2:=abs_sub (R s) (R e);have a1 : |R s| ≤ |V| + |R s-V|:=sub_le_iff_le_add'.mp (Ὥ (R s) V) have a2:=le_abs_self (R e);have a3:=neg_abs_le (R e);have hz:(0:ℝ)<=A_z:=by show (0:ℝ)<=(2:ℝ)^(-1021:ℤ);exact (ἵ two_pos _).le have hQ2:|2^53*(R s-V)| ≤ 2^53 * |R e| + (|R s| + |R e| + A_z):=abs_le.mpr ⟨by linarith only [a2, a3, q1, p', p2, hhi],by linarith only [a2, a3, q2, m', m2, hlo]⟩ rw[ἢ,abs_of_pos (by norm_num1:(0:ℝ)<2^53)] at hQ2 have hrel2:=sck (by norm_num1) hrel rw[one_div_mul_eq_div,le_div_iff₀' (by norm_num1)] linarith only [hQ2, hz, a1, hrel2, Ἀ V] lemma U_w (T M:Ὣ) (h1:T+2097152< M+2^28) (h2:M+2097152<=T+2^28) : T< M+2^28∧M<=T+2^28:=by exact omS250 h1 h2 set_option maxRecDepth 8192 in lemma qI4 (e s:ὧ) (h:zivT (thOf e) s≠Е) : s.isFinite=true∧e.isFinite=true∧|R e| ≤ 1/2^34 * |R s|∧|R s| ≤ 2^(130:ℤ) ∧ (2:ℝ)^(-127:ℤ) ≤ |R (s+e)|∧(2:ℝ)^(-127:ℤ) ≤ |R s|:=by obtain ⟨ht,S,ex,fr,M,h1,h2,h3,-,hbt,hl',hu'⟩:=kFh _ s h have hnr:B_near s.toBits.toNat S ex fr:=⟨M,hbt,(U_w _ _ hl' hu').1,(U_w _ _ hl' hu').2⟩ obtain ⟨fs,v,hv,hv1,-,hv3⟩:=qA4 _ S ex fr h1 h2 h3 hnr obtain ⟨fe,hrel⟩:=kGw e s S M (by clear h ht hbt; exact omS251 h2 h3 hu') hbt ht have hb0:(2:ℝ)^(-179:ℤ)<=2^((ex:Int)-1076) :=ἒ (by norm_num1) (by clear h ht h3 hbt hl' hu'; exact omS124 h1) have hb1:(2:ℝ)^((ex:Int)-1076)<=2^(74:ℤ) :=ἒ (by norm_num1) (by clear h ht h3 hbt hl' hu'; exact omS252 h2) have hpos:(0:ℝ)<2^(-179:ℤ):=ἵ (by positivity) _ have e179:(2:ℝ)^(-127:ℤ)=2^52*2^(-179:ℤ):=by rw[show (-127:ℤ)=52+(-179) by (norm_num1),Ἓ ἓ];(norm_num1) have e130:(2:ℝ)^(130:ℤ)=2^56*2^(74:ℤ):=by rw[show (130:ℤ)=56+74 by (norm_num1),Ἓ ἓ];(norm_num1) have hc0:(0:ℝ)<2^((ex:Int)-1076):=ἵ (by positivity) _ have hv0:(2^53-2^28:ℝ)*2^(-179:ℤ)<=v :=(ἁ hb0 (by positivity)).trans hv3.le have hfr:(fr:ℝ)<=2^23:=by exact_mod_cast h3.le have hfr0:(0:ℝ)<=fr:=Ἔ _ have hzs:A_z<=2^(-179:ℤ):=by have e':A_z=2^(-1021:ℤ):=rfl rw[e'];exact ἒ (by norm_num1) (by norm_num1) generalize (2:ℝ)^(-179:ℤ)=u at * have hvpos:0< v :=(by linarith only [hpos, hv0]) have hRs : |R s| = v:=by rw[hv];cases S . simp[abs_of_pos hvpos] . simp[abs_of_pos hvpos] have hF:(2^53+(fr:ℝ)*2^30+2^29)<=2^56 :=(by linarith only [hfr]) have hB : |R s| ≤ 2^(130:ℤ):=by rw[hRs,e130] exact hv1.trans ((ἀ hF hc0.le).trans (ἁ hb1 (by positivity))) have hA:(2:ℝ)^(130:ℤ)<=A_B:=by unfold A_B;exact ἒ (by norm_num1) (by norm_num1) have hR : |R e| ≤ 1/2^34*v:=by rw[<-hRs];exact hrel have hvB:v<=A_B:=by rw[<-hRs];exact hB.trans hA have hfin : |R s| ≤ A_B:=by rw[hRs];exact hvB obtain ⟨-,p⟩:=qBf s e fs fe hfin (hR.trans (by linarith only [hfin, hvB, hA, h3])) have q2 : |R s| - |R e| ≤ |R s+R e|:=by have:=Ὥ (R s) (-R e) rwa [abs_neg,sub_neg_eq_add] at this have q1:=Ἐ (R s) (R e) have q3:=Ὥ (R s+R e) (R (s+e)) rw[abs_sub_comm] at q3 rw[hRs] at q1 q2 refine ⟨fs,fe,hrel,hB,?_,?_⟩ . rw[e179];linarith only [Ἀ (R e), hv0, hpos, hR, q1, q2, q3, p, hzs, hvpos] . rw[hRs,e179];linarith only [hv0, hR, q2, q1] lemma qJr (s:ὧ) (V:ℝ) (hV : |R s-V| ≤ 1/2^33*(|V| + A_z)) (h2:(2:ℝ)^(-127:ℤ) ≤ |R s|):V≠0:=by rintro rfl;rw[abs_zero,zero_add,sub_zero] at hV;have e':A_z=2^(-1021:ℤ):=rfl;have hle:(2:ℝ)^(-1021:ℤ)<=2^(-127:ℤ):=ἒ (by norm_num1) (by norm_num1);have h0:(0:ℝ)<2^(-1021:ℤ):=ἵ (by positivity) _;rw[e'] at hV;linarith only [h0, hle, hV, h2] lemma kD1 (lo t:Ὠ) (h:t-lo< spOf lo):lo<=t∧t<0x8FA0000000000000:=by unfold spOf at h;split at h<;>rename_i hl . have a:=lo.toNat_lt;have b:=t.toNat_lt;rw[ἴ,ὲ,ὲ] at h;rw[ἴ] at hl;norm_num at h hl a b;constructor;. rw[Ὤ];(clear a; exact omS253 hl h) . rw[ἴ];norm_num;(clear a; exact omS254 hl h b) . exact absurd h ג lemma qIj (a:Ὠ) (h0:(0x7040000000000000:Ὠ)<=a <<< (1:Ὠ)) (h1:a <<< (1:Ὠ)<0x8FA0000000000000) (h2:(a+0x0FDFFFFF) &&& 0x1FFFFFFF<0x1FC00000) : zivW (a+0x200000) (a-0x200000)=zivC ((a+0x0FDFFFFF) >>> (29:Ὠ)) ∧ zivC ((a+0x0FDFFFFF) >>> (29:Ὠ))≠Е:=by have ha:=a.toNat_lt have e0:(a <<< (1:Ὠ)).toNat=Ѧa*2%2^64:=by rw[UInt64.toNat_shiftLeft];norm_num [Nat.shiftLeft_eq] rw[Ὤ,e0] at h0 rw[ἴ,e0] at h1 norm_num at h0 h1 ha have eu:(a+0x0FDFFFFF).toNat=Ѧa+266338303:=by rw[ἤ];norm_num;(clear h2; exact omS255 h1 ha) have em:((a+0x0FDFFFFF) &&& 0x1FFFFFFF).toNat=(Ѧa+266338303)%2^29:=by rw[Ὅ,eu] have:=Ἂ (Ѧa+266338303) 29 norm_num at this ⊢ exact this rw[ἴ,em] at h2 norm_num at h2 generalize hx:(a+0x0FDFFFFF) >>> (29:Ὠ)=x have ex:Ѧx=(Ѧa+266338303)/2^29:=by rw[<-hx,ἰ,eu];norm_num [Nat.shiftRight_eq_div_pow] have e1:(a+0x200000+0x0FFFFFFF) >>> (29:Ὠ)=x:=by apply UInt64.toNat_inj.mp rw[ex,ἰ,ἤ,ἤ] norm_num [Nat.shiftRight_eq_div_pow] (clear hx; exact omS256 h1 ha h2) have e2:(a-0x200000+0x0FFFFFFF) >>> (29:Ὠ)=x:=by apply UInt64.toNat_inj.mp rw[ex,ἰ,ἤ,ὲ] norm_num [Nat.shiftRight_eq_div_pow] (clear hx e1; exact omS257 h1 ha) have hE:((x >>> (23:Ὠ)) &&& (0x7FF:Ὠ)).toNat=Ѧx/2^23%2^11:=by rw[Ὅ,ἰ] have:=Ἂ (Ѧx >>> 23) 11 norm_num [Nat.shiftRight_eq_div_pow] at this ⊢ exact this have r1:898<=Ѧx/2^23%2^11:=by rw[ex];norm_num;(clear ha hx e1 e2 hE; exact omS258 h0 h1) have r2:Ѧx/2^23%2^11<1151:=by rw[ex];norm_num;(clear ha hx e1 e2 hE r1; exact omS259 h1) have r3:Ѧx<2^35:=by rw[ex];norm_num;(clear hx e1 e2 hE r1 r2; exact omS260 h1 ha) constructor . unfold zivW zivC;dsimp only;rw[e1,e2];have hc:((x >>> (23:Ὠ)) &&& (0x7FF:Ὠ))-(897:Ὠ)<(254:Ὠ):=by rw[ἴ,ὲ,hE];norm_num;norm_num at r1 r2;(clear e0 h0 h1 ha eu em h2 hx ex e1 e2 hE r3; exact omS261 r1 r2) simp[hc] . unfold zivC;rw[show ((x >>> (34:Ὠ)) <<< (31:Ὠ)) ||| ((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< (23:Ὠ))) =((x >>> 34) <<< 31) ||| ((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< 23)) from rfl,qHw x r3 (by clear e0 h0 h1 ha eu em h2 hx ex e1 e2 r3; (exact Nat.le_of_lt ‹_›)) r2];intro h;have h':=congrArg UInt32.toNat h;rw[ὡ] at h';have f:=ὀ Ѧx (ב:0<2^23);split at h'<;>norm_num at h' f r1 r2<;>(clear e0 h0 h1 ha eu em h2 hx ex e1 e2 hE r3 h f; omega) lemma qHy (e s:ὧ) (h1:(s.toBits <<< (1:Ὠ))-loOf e< spOf (loOf e)) (h2:(s.toBits+0x0FDFFFFF) &&& 0x1FFFFFFF<0x1FC00000) : zivT (thOf e) s=zivC ((s.toBits+0x0FDFFFFF) >>> (29:Ὠ)) ∧ zivT (thOf e) s≠Е:=by obtain ⟨l1,l2⟩:=kD1 _ _ h1 have l3:thOf e<=s.toBits <<< (1:Ὠ)∧(0x7040000000000000:Ὠ)<=s.toBits <<< (1:Ὠ):=by unfold loOf at l1 dsimp only at l1 rw[Ὤ] at l1 ⊢ split at l1<;>rename_i hc . rw[ἴ] at hc;constructor;. (clear h1 h2 l2; exact omS262 hc l1) . exact l1 . rw[ἴ] at hc;constructor;. exact l1 . rw[Ὤ];(clear h1 h2 l2; exact omS263 hc l1) have b:=qIj s.toBits l3.2 l2 h2 have e1:zivT (thOf e) s=zivC ((s.toBits+0x0FDFFFFF) >>> (29:Ὠ)):=by unfold zivT dsimp only rw[ἱ l3.1] exact b.1 exact ⟨e1,e1 ▸ b.2⟩ lemma qCnF (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) (bw:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (s e E:ὧ) (hlo:R (s-e)< exactS n xw ww bw) (hhi:exactS n xw ww bw< R (s+e)) (fe:e.isFinite=true) (hE : |R e| ≤ |R E|) (h1:(s.toBits <<< (1:Ὠ))-loOf E< spOf (loOf E)) (h2:(s.toBits+0x0FDFFFFF) &&& 0x1FFFFFFF<0x1FC00000) : zivC ((s.toBits+0x0FDFFFFF) >>> (29:Ὠ))=dotOf (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw):=by have hsum:=qHv n xw ww bw hx hw hb obtain ⟨a,b⟩:=qHy E s h1 h2 obtain ⟨fs,-,hr,hB,-,hs1⟩:=qI4 E s b have hV:=qHs s e _ fs fe (hE.trans hr) hB hlo hhi obtain ⟨d,hd,hw'⟩:=qEc (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw) (λj _=>by by_cases hj:j< n . simp only[hj,ite_true];exact ⟨qAe _ (hx j hj),qAe _ (hw j hj)⟩ . simp only[hj,ite_false] exact ⟨by decide,qAe _ hb⟩) λh0=>qJr s _ hV hs1 (by rw[<-hsum,h0,Rat.cast_zero]) have q:(d.toRat:ℝ)=exactS n xw ww bw:=by rw[hd,hsum] rw[hw',<-a] exact kHv _ s d (by rw[q];exact hV) b set_option maxRecDepth 8192 in lemma qBgF (E s e:ὧ) (h1:(s.toBits <<< (1:Ὠ))-loOf E< spOf (loOf E)) (h2:(s.toBits+0x0FDFFFFF) &&& 0x1FFFFFFF<0x1FC00000) (fe:e.isFinite=true) (hE : |R e| ≤ |R E|) : (2:ℝ)^(-127:ℤ) ≤ |R (s+e)|:=by obtain ⟨-,h⟩:=qHy E s h1 h2 obtain ⟨fs,-,hr,hB,-,-⟩:=qI4 E s h obtain ⟨-,S,ex,fr,M,a1,a2,a3,-,hb,hl,hu⟩:=kFh _ s h have hlo:=(kD1 _ _ h1).1 have hl0:(0x7040000000000000:Ὠ)<=loOf E:=by unfold loOf;dsimp only;split . exact UInt64.le_refl _ . rename_i hh;exact UInt64.not_lt.mp hh have hM63:M<2^63:=by clear h h1 h2 hlo hl0; exact omS264 a2 a3 hu have hsh:=qJb s.toBits S M hM63 hb have h898:0x7040000000000000<=2*M:=by have:=Ὤ.mp (UInt64.le_trans hl0 hlo);rw[hsh] at this;exact this have hM:M=(M/2^52)*2^52+M%2^52 :=(by clear h h1 h2 hb hl hu hlo hl0 hsh h898; exact omS114) have hF:M%2^52<2^52:=ὀ _ (by positivity) generalize M/2^52=E' at hM generalize M%2^52=F at hM hF subst hM have hE1:898<=E':=by clear h h1 h2 hb hl hu hlo hl0 hsh; exact omS265 hF h898 have hE2:E'<2047:=by clear h h1 h2 hb hl hlo hl0 hsh; exact omS239 a2 a3 hu obtain ⟨-,hR⟩:=B_R s S E' F (by exact omS266 hE1) hE2 hF (by rw[hb,ὢ]) have hk:(2:ℝ)^(-125:ℤ)=4*2^(-127:ℤ):=by rw[show (-125:ℤ)=2+(-127) by norm_num,zpow_add₀ two_ne_zero];norm_num have hs125:(2:ℝ)^(-125:ℤ) ≤ |R s|:=by rw[hR] have p:(0:ℝ)<2^((E':ℤ)-1075):=by positivity have q2:(2:ℝ)^(-125:ℤ)<=2^(52:ℤ)*2^((E':ℤ)-1075):=by rw[<-zpow_add₀ (by norm_num)];exact zpow_le_zpow_right₀ (by norm_num) (by exact omS267 hE1) have q3:(2^(52:ℤ):ℝ)<=((2^52+F:Ὣ):ℝ):=by push_cast;norm_num have q4:(2:ℝ)^(52:ℤ)*2^((E':ℤ)-1075)<=((2^52+F:Ὣ):ℝ)*2^((E':ℤ)-1075):=mul_le_mul_of_nonneg_right q3 p.le cases S<;>simp only[Bool.false_eq_true, ite_false, ite_true, one_mul, neg_mul, abs_neg, abs_mul, abs_of_pos p]<;>rw[abs_of_nonneg (by positivity)]<;>linarith only [q2, q4] have heb : |R e| ≤ 1/2^34 * |R s|:=hE.trans hr have hA:(2:ℝ)^(130:ℤ)<=A_B:=by unfold A_B;exact ἒ (by norm_num1) (by norm_num1) have hsA : |R s| ≤ A_B:=hB.trans hA have heA : |R e| ≤ A_B:=heb.trans (le_trans (by linarith only [Ἀ (R s)]) hsA) obtain ⟨-,hadd⟩:=qBf s e fs fe hsA heA have hzk:A_z<=(2:ℝ)^(-127:ℤ):=by show (2:ℝ)^(-1021:ℤ)<=_;exact zpow_le_zpow_right₀ (by norm_num) (by norm_num) have t0:=abs_sub_abs_le_abs_sub (R s) (-(R e)) rw[sub_neg_eq_add,abs_neg] at t0 have t1 : |R s| * (1-1/2^34) ≤ |R s+R e|:=by linarith only [le_abs_self (|R s|-|R e|), t0, heb] have t3:=abs_sub_abs_le_abs_sub (R s+R e) (R (s+e)) rw[abs_sub_comm (R s+R e) (R (s+e))] at t3 linarith only [le_abs_self (|R s+R e|-|R (s+e)|), t3, hadd, hzk, t1, hs125, hk, Ἀ (R s+R e)] lemma qAddE (x y:ὧ) (hx:xᶠ) (hy:yᶠ) (h1 : |R x| ≤ A_B) (h2 : |R y| ≤ A_B) : (x+y)ᶠ ∧ R (x+y)=Model.roundAt ⟡ (R x+R y) := A_E _ (toModel_ofFloat_add_of_isFinite x y hx hy) (Model.isFinite_add_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2)) (Model.toReal_add_eq_roundAt_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2)) set_option maxRecDepth 8192 in lemma qEmo (nf X v bm:ὧ) (fnf:nfᶠ) (fX:Xᶠ) (fv:vᶠ) (fbm:bmᶠ) (pnf:0<=R nf) (pX:0<=R X) (hvb : |R v| ≤ R bm) (bX:R X<=2^(290:ℤ)) (bb:R bm<=2^(290:ℤ)) (bnf:R nf<=1) : (nf*(X+v.abs))ᶠ ∧ |R (nf*(X+v.abs))| ≤ |R (nf*(X+bm))| := by obtain ⟨fa,Ra⟩:=qBl v fv have hA:(2:ℝ)^(290:ℤ)<=A_B:=by unfold A_B;exact ἒ (by norm_num1) (by norm_num1) have pb:0<=R bm:=(abs_nonneg _).trans hvb obtain ⟨f1,R1⟩:=qAddE X v.abs fX fa (by rw[abs_of_nonneg pX];exact bX.trans hA) (by rw[Ra,abs_abs];exact (hvb.trans bb).trans hA) obtain ⟨f2,R2⟩:=qAddE X bm fX fbm (by rw[abs_of_nonneg pX];exact bX.trans hA) (by rw[abs_of_nonneg pb];exact bb.trans hA) have m1:R (X+v.abs)<=R (X+bm):=by rw[R1,R2,Ra];exact Model.roundAt_mono _ (by linarith only [hvb]) have p1:0<=R (X+v.abs):=by rw[R1,<-Model.roundAt_zero ⟡];exact Model.roundAt_mono _ (by rw[Ra];linarith only [pX,abs_nonneg (R v)]) have b2:R (X+bm)<=2^(292:ℤ):=by obtain ⟨-,e2⟩:=qFc ⟨f2,R2⟩ rw[abs_of_nonneg (add_nonneg pX pb)] at e2 have r1:=sub_le_iff_le_add'.mp ((le_abs_self _).trans e2) have hz:=qBo have q6:(1:ℝ)<=2^(290:ℤ):=one_le_zpow₀ (by norm_num1) (by norm_num1) rw[show (2:ℝ)^(292:ℤ)=4*2^(290:ℤ) by rw[show (292:ℤ)=2+290 by norm_num1,zpow_add₀ two_ne_zero];norm_num] generalize (2:ℝ)^(290:ℤ)=P at * linarith only [r1, bX, bb, q6, hz, pX, pb] have bp:|R nf| * |R (X+bm)|<=2^(1000:ℤ):=by rw[abs_of_nonneg pnf,abs_of_nonneg (p1.trans m1)] have:(2:ℝ)^(292:ℤ)<=2^(1000:ℤ):=zpow_le_zpow_right₀ (by norm_num) (by norm_num) have hm:=mul_le_mul_of_nonneg_right bnf (p1.trans m1) exact hm.trans ((one_mul _).le.trans (b2.trans this)) have bp1:|R nf| * |R (X+v.abs)|<=2^(1000:ℤ):=by refine le_trans ?_ bp;rw[abs_of_nonneg p1,abs_of_nonneg (p1.trans m1)];exact mul_le_mul_of_nonneg_left m1 (abs_nonneg _) obtain ⟨f3,R3⟩:=qEd nf (X+v.abs) fnf f1 bp1 obtain ⟨-,R4⟩:=qEd nf (X+bm) fnf f2 bp have m2:R (nf*(X+v.abs))<=R (nf*(X+bm)):=by rw[R3,R4];exact Model.roundAt_mono _ (mul_le_mul_of_nonneg_left m1 pnf) have p2:0<=R (nf*(X+v.abs)):=by rw[R3,<-Model.roundAt_zero ⟡];exact Model.roundAt_mono _ (mul_nonneg pnf p1) exact ⟨f3,by rw[abs_of_nonneg p2,abs_of_nonneg (p2.trans m2)];exact m2⟩ set_option maxRecDepth 8192 in lemma qFoldA (g:ℕ->ὧ) : ∀ (l:List ℕ) (c:ὧ), (∀ t∈l,(g t)ᶠ ∧ |R (g t)| ≤ 2^(128:ℤ)) → cᶠ → 0<=R c → R c<=2^(150:ℤ)-(ѣl:ℝ)*2^(129:ℤ) → (l.foldl (λ(a:ὧ) t=>a+(g t).abs) c)ᶠ ∧ 0<=R (l.foldl (λ(a:ὧ) t=>a+(g t).abs) c) ∧ R (l.foldl (λ(a:ὧ) t=>a+(g t).abs) c)<=2^(150:ℤ) := by intro l induction l with | nil=>intro c _ fc p b;simp only[List.foldl_nil,List.length_nil,Nat.cast_zero,zero_mul,sub_zero] at b ⊢;exact ⟨fc,p,b⟩ | cons t l ih=> intro c hg fc p b simp only[List.foldl_cons] obtain ⟨ft,bt⟩:=hg t (List.mem_cons_self ..) obtain ⟨fa,Ra⟩:=qBl (g t) ft have hA:(2:ℝ)^(150:ℤ)<=A_B:=by unfold A_B;exact ἒ (by norm_num1) (by norm_num1) have hA2:(2:ℝ)^(128:ℤ)<=A_B:=by unfold A_B;exact ἒ (by norm_num1) (by norm_num1) have h129:(0:ℝ)<=2^(129:ℤ):=(ἵ two_pos _).le have hl:(0:ℝ)<=(ѣl:ℝ):=Nat.cast_nonneg _ simp only[List.length_cons,Nat.cast_add,Nat.cast_one] at b have bc:R c<=2^(150:ℤ):=b.trans (sub_le_self _ (Ἆ (add_nonneg hl zero_le_one) h129)) obtain ⟨f1,R1⟩:=qAddE c (g t).abs fc fa (by rw[abs_of_nonneg p];exact bc.trans hA) (by rw[Ra,abs_abs];exact bt.trans hA2) obtain ⟨-,e1⟩:=qFc ⟨f1,R1⟩ have p1:0<=R (c+(g t).abs):=by rw[R1,<-Model.roundAt_zero ⟡];exact Model.roundAt_mono _ (by rw[Ra];linarith only [p,abs_nonneg (R (g t))]) refine ih _ (λu hu=>hg u (List.mem_cons_of_mem _ hu)) f1 p1 ?_ have hz:A_z<=1:=by show (2:ℝ)^(-1021:ℤ)<=1;exact zpow_le_one_of_nonpos₀ (by norm_num) (by norm_num) have q1:(2:ℝ)^(129:ℤ)=2*2^(128:ℤ):=by rw[show (129:ℤ)=1+128 by norm_num,zpow_add₀ two_ne_zero];norm_num have q2:(2:ℝ)^(150:ℤ)=2^22*2^(128:ℤ):=by rw[show (150:ℤ)=22+128 by norm_num,zpow_add₀ two_ne_zero];norm_num have q3:(1:ℝ)<=2^(128:ℤ):=one_le_zpow₀ (by norm_num) (by norm_num) rw[Ra,abs_of_nonneg (show (0:ℝ)<=R c+|R (g t)| by linarith only [p,abs_nonneg (R (g t))])] at e1 have:=le_abs_self (R (c+(g t).abs)-(R c+|R (g t)|)) have e1':=(le_div_iff₀' (by norm_num1:(0:ℝ)<2^53)).mp (e1.trans_eq (one_div_mul_eq_div _ _)) linarith only [e1',this,b,bt,hz,q1,q2,q3,p,abs_nonneg (R (g t)),hl] section variable {Rr I O:Ὣ} {X W b:ё} set_option maxRecDepth 8192 in lemma qDuF (G:C_G Rr I O X W b) (Y:Ὡ) {i j:Ὣ} (hi:i< Rr) (hj:j< O) {s:ὧ} {hv:Ὢ} (g1:good hv=true) (g2:hv<=В) (g4:∀ t,t< I->W[j*I+t]! &&& В<=hv) (L:љ) (hl:L.Nodup) (hl2:∀ t∈L,t< I) (hz:∀ t,t< I->t∉L->X[i*I+t]! &&& В=0) (hs:s=L.foldl (λ(acc:ὧ) t=>acc+dv X[i*I+t]! * dv W[j*I+t]!) 0) (bm:ὧ) (fbm:bmᶠ) (hbm : |R (dv b[j]!)| ≤ R bm) (bb:R bm<=2^(290:ℤ)) (lo:Ὠ) (hlo:lo=loOf (nfOf I*(dv hv*(L.foldl (λ(a:ὧ) t=>a+(dv X[i*I+t]!).abs) 0)+bm))) : (if fin1 lo (spOf lo) (s+dv b[j]!) == Е then fin8 I Y X W b i j s (nfOf I) (L.foldl (λ(a:ὧ) t=>a+(dv X[i*I+t]!).abs) 0) hv b[j]! ѩI else fz Y (fin1 lo (spOf lo) (s+dv b[j]!)))=C_out I Y X W b i j:=by split . exact qDu G Y hi hj g1 g2 g4 L hl hl2 hz hs . rename_i hne have hgx:=G.gx hi have hgw:=G.gw hj have gb:=G.gb j (by rw[<-G.hb];exact hj) have hlen:ѣL<=I:=qFu hl hl2 have ni:=G.ni obtain ⟨fA,pA,bA⟩:=qFoldA (λt=>dv X[i*I+t]!) L 0 (λt ht=>⟨(qAm _ (hgx t (hl2 t ht))).1,by rw[(qAm _ (hgx t (hl2 t ht))).2];exact qAo _ (hgx t (hl2 t ht))⟩) qHg.1 (by rw[qHg.2]) (by have:(ѣL:ℝ)<=2^20:=by exact_mod_cast (by exact omS268 hlen ni:ѣL<=2^20) have q:(2:ℝ)^(150:ℤ)=2^21*2^(129:ℤ):=by rw[show (150:ℤ)=21+129 by norm_num,zpow_add₀ two_ne_zero];norm_num have q2:(0:ℝ)<2^(129:ℤ):=ἵ two_pos _ rw[qHg.2,q,sub_nonneg];exact ἀ (this.trans (by norm_num1)) q2.le) generalize hA:L.foldl (λ(a:ὧ) t=>a+(dv X[i*I+t]!).abs) 0=A at hlo fA pA bA ⊢ obtain ⟨fh,Rh⟩:=qAm hv g1 obtain ⟨ph,bh,-⟩:=qCs g1 g2 have hp:|R (dv hv)| * |R A| ≤ 2^(1000:ℤ):=by rw[Rh,abs_of_nonneg ph,abs_of_nonneg pA] have:(2:ℝ)^128*2^(150:ℤ)<=2^(1000:ℤ):=by rw[show (2:ℝ)^128=2^(128:ℤ) by norm_num,<-zpow_add₀ two_ne_zero];exact zpow_le_zpow_right₀ (by norm_num) (by norm_num) exact (mul_le_mul bh bA pA (by positivity)).trans this obtain ⟨fX,RX⟩:=qEd (dv hv) A fh fA hp have pX:0<=R (dv hv*A):=by rw[RX,<-Model.roundAt_zero ⟡];exact Model.roundAt_mono _ (by rw[Rh];exact mul_nonneg ph pA) have bX:R (dv hv*A)<=2^(290:ℤ):=by obtain ⟨-,e⟩:=qFc ⟨fX,RX⟩ have c0:R (dv hv)*R A<=2^(278:ℤ):=by have:(2:ℝ)^128*2^(150:ℤ)=2^(278:ℤ):=by rw[show (2:ℝ)^128=2^(128:ℤ) by norm_num,<-zpow_add₀ two_ne_zero];norm_num rw[Rh,<-this];exact mul_le_mul bh bA pA (by positivity) have c1:(0:ℝ)<=R (dv hv)*R A:=by rw[Rh];exact mul_nonneg ph pA have hz:A_z<=1:=by show (2:ℝ)^(-1021:ℤ)<=1;exact zpow_le_one_of_nonpos₀ (by norm_num) (by norm_num) have q1:(2:ℝ)^(290:ℤ)=2^12*2^(278:ℤ):=by rw[show (290:ℤ)=12+278 by norm_num,zpow_add₀ two_ne_zero];norm_num have q2:(1:ℝ)<=2^(278:ℤ):=one_le_zpow₀ (by norm_num) (by norm_num) rw[abs_of_nonneg c1] at e have:=le_abs_self (R (dv hv*A)-R (dv hv)*R A) rw[q1];clear hp;generalize (2:ℝ)^(278:ℤ)=P at *;generalize R (dv hv)*R A=Q at *;linarith only [e,this,c0,c1,hz,q2] obtain ⟨fnf,Rnf⟩:=qIn I ni have pnf:0<=R (nfOf I):=by rw[Rnf];exact div_nonneg (add_nonneg (Ἔ _) (by norm_num1)) (by norm_num1) have bnf:R (nfOf I)<=1:=by have hI:(I:ℝ)<2^20:=by exact_mod_cast ni rw[Rnf,div_le_one (by positivity)];linarith only [hI] obtain ⟨fv,-⟩:=qAm _ gb obtain ⟨fe,hE⟩:=qEmo (nfOf I) (dv hv*A) (dv b[j]!) bm fnf fX fv fbm pnf pX hbm bX bb bnf have key:fin1 lo (spOf lo) (s+dv b[j]!)≠Е:=by simpa using hne unfold fin1 at key ⊢ dsimp only at key ⊢ split at key . rename_i ht simp only[Bool.and_eq_true,decide_eq_true_eq] at ht obtain ⟨h1,h2⟩:=ht rw[ἱ (by simp only[Bool.and_eq_true,decide_eq_true_eq];exact ⟨h1,h2⟩)] subst hlo have hbig:=qBgF _ _ _ h1 h2 fe hE obtain ⟨c1,c2⟩:=qC8 I ni (λt=>X[i*I+t]!) (λt=>W[j*I+t]!) b[j]! hv hgx hgw gb g1 g2 L hl hl2 (λt ht=>g4 t (hl2 t ht)) hz (s+dv b[j]!) (nfOf I*(dv hv*A+(dv b[j]!).abs)) ⟨by rw[hs],by rw[hA]⟩ hbig have e:=qCnF I ni _ _ _ hgx hgw gb _ _ _ c1 c2 fe hE h1 h2 obtain ⟨a,b'⟩:=qHy _ _ h1 h2 obtain ⟨-,S,ex,fr,M,a1,a2,a3,hz',-⟩:=kFh _ _ b' rw[a] at hz' have he:=qR1 _ S ex fr a1 a2 a3 hz' unfold fz C_out rw[qR0 Y _ he,e] . exact absurd rfl key end section variable {R I O:Ὣ} {X W b:ё} section variable (G:C_G R I O X W b) include G lemma C_G.nm:I.toUSize.toNat=I :=qAd _ (lt_trans G.ni (by norm_num1)) lemma C_G.wj {j:Ὣ} {u:ὦ} (hu:Ѥu=j) (hj:j< O):(u*ѩI).toNat=j*I ∧ (u*ѩI).toNat+I.toUSize.toNat<=ѧW:=by have h1:j*I+I<=O*I:=qBc hj (Ὗ _) have h2:=G.hW have h3:=G.sW have e:(u*ѩI).toNat=j*I:=by rw[qBa _ _ (by rw[hu,G.nm];(clear hu hj; exact omS269 h1 h2 h3)),hu,G.nm] exact ⟨e,by rw[e,G.nm];(clear hu hj h3; exact omS270 h1 h2)⟩ lemma qB9 (Y:Ὡ) {i j:Ὣ} (hi:i< R) (hj:j< O) {hv:Ὢ} (Hv:C_Hv W hv) {ix:ѐ} {x:ὤ} {c:ὦ} {L:љ} {l:ὧ} (Rw:C_Row I X i ix x c L l) {u:ὦ} (hu:Ѥu=j) (hx:Ѥc<=Ѩx) (hi':Ѥc<=ѧix) (hs:ѧW<2^32) (h0:(u*ѩI).toNat+I.toUSize.toNat<=ѧW) (bm:ὧ) (fbm:bmᶠ) (hbm:∀ j,j< O → |D.R (dv b[j]!)| ≤ D.R bm) (bb:D.R bm<=2^(290:ℤ)) {lo:Ὠ} (hlo:lo=loOf (nfOf I*(dv hv*l+bm))) : fin8L I Y X W b i j (go1 x ix W (u*ѩI) ѩI c 0 hx hi' hs h0 0) (nfOf I) l hv lo (rdW b u) ѩI=C_out I Y X W b i j:=by have e:=qH6 hx hi' hs h0 (λp=>dv X[i*I+p]!) (λp=>W[j*I+p]!) (λp _=>by rw[(G.wj hu hj).1]) L 0 0 (by rw[C_z,Ἇ];exact Rw.len.symm) (λk p hk=>by have h1:=Rw.rd k p hk rw[C_z,Ἇ,G.nm] exact ⟨Rw.lt p (List.mem_of_getElem? hk),h1⟩) rw[qAg _ _ G.sb,hu,Rw.ok] rw[Rw.ok] at hlo unfold fin8L fin8n;dsimp only exact qDuF G Y hi hj Hv.1 Hv.2.1 (λt ht=>Hv.2.2.2 _ (by rw[<-G.hW];exact qCj hj ht)) L Rw.nd Rw.lt Rw.hz e bm fbm (hbm j hj) bb lo hlo lemma qD0 (Y:Ὡ) {i:Ὣ} (hi:i< R) {hv:Ὢ} (Hv:C_Hv W hv) {ix:ѐ} {x wd:ὤ} {c:ὦ} {L:љ} {l:ὧ} (Rw:C_Row I X i ix x c L l) {base:ὦ} (hb:Ѥbase=i*O) (Hd:C_Dw wd W) (bm:ὧ) (fbm:bmᶠ) (hbm:∀ j,j< O → |D.R (dv b[j]!)| ≤ D.R bm) (bb:D.R bm<=2^(290:ℤ)) {lo:Ὠ} (hlo:lo=loOf (nfOf I*(dv hv*l+bm))) (d:Ὣ):∀ (j:Ὣ) (out:ё),j+d=O → C_Inv (R*O) (C_sp I O Y X W b) (λq=>q< i*O+j) out → C_Inv (R*O) (C_sp I O Y X W b) (λq=>q< i*O+O) (cols1 I O Y X W b i ix x wd (nfOf I) l hv lo ѩI c j base out):=by induction d using Nat.strong_induction_on with | _ d ih => intro j out he H have hN:=G.sO have sW:ѧW<=4294967295:=by have:=G.sW;(exact Nat.le_of_lt_succ ‹_›) have hbs:=G.sb have hob:=G.hb have hle:=Rw.cle have h1c:Ѥc<=Ѩx:=by rw[Rw.len];exact hle.trans Rw.sx.1 have h2c:Ѥc<=ѧix:=by rw[Rw.len];exact hle.trans Rw.six have hsp:∀ k,j+k< O->C_out I Y X W b i (j+k) =C_sp I O Y X W b (i*O+j+k):=λk hk=>by rw[ὢ];exact (qCi I O Y X W b hk).symm by_cases h4:j+4<=O . have hP:=qCj hi ((by exact Nat.succ_le_of_lt ‹_›):j+3< O);have e0:j.toUSize.toNat=j:=qAd _ (by clear hi sW hbs hle h1c h2c h4; exact omS271 hN hP);obtain ⟨e1,e2,e3,-⟩:=qFk e0 (by clear hi sW hbs hle h1c h2c h4; exact omS272 hN hP);have g0:=(G.wj e0 (by clear hi hb hN sW hbs hle h1c h2c hP; exact omS152 h4)).2;have g1:=(G.wj e1 (by clear hi hb hN sW hbs hle h1c h2c hP g0; exact omS153 h4)).2;have g2:=(G.wj e2 (by exact Nat.le_of_lt ‹_›)).2;have g3:=(G.wj e3 (by exact Nat.succ_le_of_lt ‹_›)).2;have a0:(base+ѩj).toNat=i*O+j:=by rw[qAf _ _ (by rw[hb,e0];(clear hi hb sW hbs hle h1c h2c h4 g0 g1 g2 g3; exact omS273 hN hP)),hb,e0] have o0:=qB9 G Y hi ((by clear hi hb hN sW hbs hle h1c h2c hP g0 g1 g2 g3 a0; exact omS152 h4):j< O) Hv Rw e0 h1c h2c G.sW g0 bm fbm hbm bb hlo;have o1:=qB9 G Y hi ((by clear hi hb hN sW hbs hle h1c h2c hP g0 g1 g2 g3 a0 o0; exact omS153 h4):j+1< O) Hv Rw e1 h1c h2c G.sW g1 bm fbm hbm bb hlo;have o2:=qB9 G Y hi ((by exact Nat.le_of_lt ‹_›):j+2< O) Hv Rw e2 h1c h2c G.sW g2 bm fbm hbm bb hlo;have o3:=qB9 G Y hi ((by exact Nat.succ_le_of_lt ‹_›):j+3< O) Hv Rw e3 h1c h2c G.sW g3 bm fbm hbm bb hlo;rw[cols1,Ἄ h4];dsimp only;rw[Ἄ ⟨h1c,h2c,sW,g0,g1,g2,g3⟩] rw[qH0 _ _ _ _ _ _ _ (λj hj=>by rw[Rw.len] at hj;have hp:=List.getElem?_eq_getElem hj exact ⟨_,G.gx hi _ (Rw.lt _ (List.mem_of_getElem? hp)),(Rw.rd j _ hp).2⟩) Ѥc 0 _ _ _ _ (Ἇ _)] dsimp only;rw[o0,o1,o2,o3];refine ih (d-4) (by clear hi hb hN sW hbs hle h1c h2c hP g0 g1 g2 g3 a0 o0 o1 o2 o3; exact omS274 he h4) (j+4) _ (by clear hi hb hN sW hbs hle h1c h2c hP g0 g1 g2 g3 a0 o0 o1 o2 o3; exact omS275 he h4) ?_;rw[show i*O+(j+4)=i*O+j+4 by (clear hi hb he hN sW hbs hob hle h1c h2c h4 hP e0 e1 e2 e3 g0 g1 g2 g3 a0 o0 o1 o2 o3; exact omS276)];exact qEq hN H a0 (by exact Nat.succ_le_of_lt ‹_›) (hsp 0 (by clear hi hb hN sW hbs hle h1c h2c hP g0 g1 g2 g3 a0 o0 o1 o2 o3; exact omS277 h4)) (hsp 1 (by clear hi hb hN sW hbs hle h1c h2c hP g0 g1 g2 g3 a0 o0 o1 o2 o3; exact omS153 h4)) (hsp 2 (by exact Nat.le_of_lt ‹_›)) (hsp 3 (by exact Nat.succ_le_of_lt ‹_›)) . by_cases h1:j< O . have hP:=qCj hi h1;have e0:j.toUSize.toNat=j:=qAd _ (by clear hi sW hbs hle h1c h2c h4 h1; exact omS278 hN hP);have g0:=(G.wj e0 h1).2;have a0:(base+ѩj).toNat=i*O+j:=by rw[qAf _ _ (by rw[hb,e0];(clear hi hb sW hbs hle h1c h2c h4 h1 g0; exact omS279 hN hP)),hb,e0] have o0:=qB9 G Y hi h1 Hv Rw e0 h1c h2c G.sW g0 bm fbm hbm bb hlo;rw[cols1,ἔ h4,Ἄ h1];dsimp only;rw[Ἄ ⟨h1c,h2c,sW,g0⟩];rw[o0];exact ih (d-1) (by clear hi hb hN sW hbs hle h1c h2c hP g0 a0 o0; exact omS280 he h1) (j+1) _ (by clear hi hb hN sW hbs hle h1c h2c hP g0 a0 o0; exact omS281 he h1) (qAp hN H a0 hP (hsp 0 (by exact Nat.succ_le_of_lt ‹_›))) . rw[cols1,ἔ h4,ἔ h1];have e:j=O :=(by clear hi hb hN sW hbs hob hle h1c h2c h4; exact omS282 he h1);rw[e] at H;exact H end end section variable {rows inW outW:Ὣ} {X W b:ё} def C_hf (d:H8):Ὣ->ὧ | 0=>d.h0 | 1=>d.h1 | 2=>d.h2 | 3=>d.h3 | 4=>d.h4 | 5=>d.h5 | 6=>d.h6 | _=>d.h7 def C_fs (d:F8):Ὣ->ὧ | 0=>d.s0 | 1=>d.s1 | 2=>d.s2 | 3=>d.s3 | 4=>d.s4 | 5=>d.s5 | 6=>d.s6 | _=>d.s7 def C_lo (d:L8):Ὣ->Ὠ | 0=>d.l0 | 1=>d.l1 | 2=>d.l2 | 3=>d.l3 | 4=>d.l4 | 5=>d.l5 | 6=>d.l6 | _=>d.l7 @[inline] def mkL8 (nf hvv bm:ὧ) (d:H8):L8:=⟨loOf (nf*(hvv*d.h0+bm)),loOf (nf*(hvv*d.h1+bm)),loOf (nf*(hvv*d.h2+bm)),loOf (nf*(hvv*d.h3+bm)),loOf (nf*(hvv*d.h4+bm)),loOf (nf*(hvv*d.h5+bm)),loOf (nf*(hvv*d.h6+bm)),loOf (nf*(hvv*d.h7+bm))⟩ lemma qB3 {n t c:ὦ} {k:Ὣ} (hc:Ѥc=k) (h:k*Ѥn+Ѥt<2^32) : (c*n+t).toNat=k*Ѥn+Ѥt:=by have h0:k*Ѥn<2^32 :=(by clear hc; exact omS283 h);rw[qAf _ _ (by rw[qBa _ _ (by rw[hc];exact h0),hc];exact h),qBa _ _ (by rw[hc];exact h0),hc] lemma qWc (a:ὤ) (i:ὦ) (j:Ὣ) (hj:Ѥi=j) (v:ὧ) (hs:Ѩa<2^32) (hi:j< Ѩa) (q:Ὣ):(wrF a i v).data[q]! = if q=j then v else a.data[q]!:=by rw[qEt a i v q hs (by rw[hj];exact hi),hj] lemma qW8 (xs:ὤ) (t:ὦ) (a0 a1 a2 a3 a4 a5 a6 a7:ὧ) (hs:Ѩxs<2^32) (hb:8*Ѥt+9<=Ѩxs) : (wr8 xs (8*t+USize.ofNat 1) a0 a1 a2 a3 a4 a5 a6 a7).size=Ѩxs∧∀ q,(wr8 xs (8*t+USize.ofNat 1) a0 a1 a2 a3 a4 a5 a6 a7).data[q]! = if q=8*Ѥt+1+7 then a7 else if q=8*Ѥt+1+6 then a6 else if q=8*Ѥt+1+5 then a5 else if q=8*Ѥt+1+4 then a4 else if q=8*Ѥt+1+3 then a3 else if q=8*Ѥt+1+2 then a2 else if q=8*Ѥt+1+1 then a1 else if q=8*Ѥt+1+0 then a0 else xs.data[q]!:=by have l8:(8:ὦ).toNat=8:=uk 8 (by norm_num1) have e80:(8*t).toNat=8*Ѥt:=by rw[qBa _ _ (by rw[l8];(clear l8; exact omS284 hs hb)),l8] have e8:(8*t+USize.ofNat 1).toNat=8*Ѥt+1:=by rw[qAf _ _ (by rw[e80,uk 1 (by decide)];(clear l8 e80; exact omS285 hs hb)),e80,uk 1 (by decide)] have E:∀ k,k<8->(8*t+USize.ofNat 1+USize.ofNat k).toNat=8*Ѥt+1+k:=λk hk=>by rw[qAf _ _ (by rw[e8,uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];(clear l8 e8; omega)),e8,uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))] unfold wr8 refine ⟨by simp only[qD6],λq=>?_⟩ rw[qWc _ _ _ (E 7 (by exact Nat.le_refl _)) _ (by simp only[qD6];exact hs) (by simp only[qD6];(clear l8 e8 e80; exact omS286 hb)) q, qWc _ _ _ (E 6 (by decide)) _ (by simp only[qD6];exact hs) (by simp only[qD6];(clear l8 e8 e80; exact omS287 hb)) q, qWc _ _ _ (E 5 (by decide)) _ (by simp only[qD6];exact hs) (by simp only[qD6];(clear hs l8 e8 e80; exact omS288 hb)) q, qWc _ _ _ (E 4 (by decide)) _ (by simp only[qD6];exact hs) (by simp only[qD6];(clear hs l8 e8 e80; exact omS289 hb)) q, qWc _ _ _ (E 3 (by decide)) _ (by simp only[qD6];exact hs) (by simp only[qD6];(clear hs l8 e8 e80; exact omS290 hb)) q, qWc _ _ _ (E 2 (by decide)) _ (by simp only[qD6];exact hs) (by simp only[qD6];(clear hs l8 e8 e80; exact omS291 hb)) q, qWc _ _ _ (E 1 (by decide)) _ (by simp only[qD6];exact hs) (by simp only[qD6];(clear hs l8 e8 e80; exact omS292 hb)) q, qWc _ _ _ (E 0 (by decide)) _ hs (by (clear hs l8 e8 e80; exact omS293 hb)) q] lemma qZs (m:Ὣ) (h:m<2^32):(pushZ (USize.ofNat m) 0 (ἆ m)).size=m:=by rw[qDy (USize.ofNat m) m 0 _ (by rw[uk m h,C_z,Ἇ])];exact Ἇ _ lemma qZf (m:Ὣ) (h:m<2^32):m<=(zFor m).size∧(zFor m).size<2^32:=by unfold zFor by_cases hc32:m<=32 · rw[ἱ hc32];have e:ѨzA=32:=qZs 32 (by norm_num1);rw[e];omega rw[ἐ hc32] by_cases hc128:m<=128 · rw[ἱ hc128];have e:Ѩz0=128:=qZs 128 (by norm_num1);rw[e];omega rw[ἐ hc128] by_cases hc256:m<=256 · rw[ἱ hc256];have e:ѨzB=256:=qZs 256 (by norm_num1);rw[e];omega rw[ἐ hc256] by_cases hc512:m<=512 · rw[ἱ hc512];have e:ѨzC=512:=qZs 512 (by norm_num1);rw[e];omega rw[ἐ hc512] by_cases hc1024:m<=1024 · rw[ἱ hc1024];have e:Ѩz1=1024:=qZs 1024 (by norm_num1);rw[e];omega rw[ἐ hc1024] by_cases hc4096:m<=4096 · rw[ἱ hc4096];have e:Ѩz4=4096:=qZs 4096 (by norm_num1);rw[e];omega rw[ἐ hc4096] by_cases hc8192:m<=8192 · rw[ἱ hc8192];have e:Ѩz8=8192:=qZs 8192 (by norm_num1);rw[e];omega rw[ἐ hc8192] have e:(pushZ ѩm 0 (ἆ m)).size=m:=qZs m h;rw[e];omega lemma qBq {xs:ὤ} {i t n:ὦ} {xf:Ὣ->Ὣ->ὧ} (hxf:∀ r k:Ὣ,r<8->k< Ѥn->xs.data[8*k+1+r]! = xf r k) (hi:Ѥi=8*Ѥt+1) (ht:Ѥt< Ѥn) (hsx:Ѩxs<2^32) (hx:8*Ѥn+1<=Ѩxs) (r:Ὣ) (hr:r<8) (pf:(i+USize.ofNat r).toNat< Ѩxs) : xs.uget (i+USize.ofNat r) pf=xf r Ѥt:=by rw[qC5,qAf _ _ (by rw[uk r (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];(clear pf; exact omS294 hi ht hsx hx hr)),uk r (by exact Nat.lt_of_lt_of_le ‹_› (by decide)),hi,hxf r _ hr ht] end section open Float.Model Float.Model.UnpackedFloat lemma qD2 (s:Sign):(Float.Model.pack (UnpackedFloat.infinity s)).unpack.isFinite=false:=by cases s<;>decide +kernel lemma qFh:(Float.Model.pack UnpackedFloat.notANumber).unpack.isFinite=false:=by decide +kernel lemma qC1 (x y:ὧ) (h:(x*y)ᶠ):xᶠ∧yᶠ:=by change (Float.Model.mul x.toModel y.toModel).unpack.isFinite=true at h;change x.toModel.unpack.isFinite=true∧y.toModel.unpack.isFinite=true;rw[Float.Model.mul] at h;cases a:x.toModel.unpack<;>cases b:y.toModel.unpack <;>simp only[a,b,UnpackedFloat.mul,qD2,qFh,Bool.false_eq_true] at h<;>exact ⟨rfl,rfl⟩ lemma qC2 (x y:ὧ) (h:(x+y)ᶠ):xᶠ∧yᶠ:=by change (Float.Model.add x.toModel y.toModel).unpack.isFinite=true at h;change x.toModel.unpack.isFinite=true∧y.toModel.unpack.isFinite=true;rw[Float.Model.add] at h cases a:x.toModel.unpack<;>cases b:y.toModel.unpack <;>simp only[a,b,UnpackedFloat.add,qD2,qFh,Bool.false_eq_true] at h <;> first | exact ⟨rfl,rfl⟩ | (split at h<;>simp only[qD2,qFh,Bool.false_eq_true] at h) @[inline] def okF (t:ὧ):Ὡ:=t-t==t-t lemma fS1 (s:Sign): (Float.Model.pack (UnpackedFloat.sub ⟠ (UnpackedFloat.infinity s) (UnpackedFloat.infinity s))).unpack.beq (Float.Model.pack (UnpackedFloat.sub ⟠ (UnpackedFloat.infinity s) (UnpackedFloat.infinity s))).unpack = false := by cases s <;> decide +kernel lemma fS2 : (Float.Model.pack (UnpackedFloat.sub ⟠ UnpackedFloat.notANumber UnpackedFloat.notANumber)).unpack.beq (Float.Model.pack (UnpackedFloat.sub ⟠ UnpackedFloat.notANumber UnpackedFloat.notANumber)).unpack = false := by decide +kernel lemma finSub (t:ὧ) (h:okF t=true): tᶠ := by unfold okF at h change (Float.Model.beq (Float.Model.sub t.toModel t.toModel) (Float.Model.sub t.toModel t.toModel))=true at h change t.toModel.unpack.isFinite=true rw [Float.Model.sub, Float.Model.beq] at h cases a : t.toModel.unpack . rename_i s; rw [a, fS1] at h; exact absurd h (by decide) . rw [a, fS2] at h; exact absurd h (by decide) . rfl . rfl lemma qHz:(Ἃ 0x7FF8000000000000).isFinite=false:=by decide +kernel def N_ok (w:ὥ):Prop:=0x800000<=w &&& В∧w &&& В<0x40000000 lemma qEx {w:ὥ} (h:N_ok w):good w=true :=qBt _ (Or.inr h.1) (by have t:w &&& В<0x40000000:=h.2;have a:(0x40000000:ὥ).toNat=0x40000000:=rfl;have b:(У:ὥ).toNat=У:=rfl;rw[ἳ,a] at t;rw[ἳ,b];(exact Nat.lt_of_lt_of_le ‹_› (by decide))) def Z_ok (hv w:ὥ):Prop:=w &&& В<=hv lemma qTb {z:Ὣ} {T:ὤ} {h:ὥ} (o:TOK z T h):ѥh<0x40000000:=by obtain ⟨k,-,-,k2,k3,e⟩:=o;exact omS295 k3 e lemma qTg {z:Ὣ} {T:ὤ} {h:ὥ} (o:TOK z T h):good h=true∧h<=В:=by obtain ⟨k,-,-,k2,k3,e⟩:=o have a:=qAq h refine ⟨qEx ⟨?_,?_⟩,?_⟩ . rw[ἃ,a,show (0x800000:ὥ).toNat=0x800000 from rfl];exact omS296 k2 k3 e . rw[ἳ,a,show (0x40000000:ὥ).toNat=0x40000000 from rfl];exact omS297 k3 e . rw[ἃ,show (В:ὥ).toNat=0x7FFFFFFF from rfl];(clear a; exact omS298 k3 e) lemma N_w {z:Ὣ} {T:ὤ} {h:ὥ} (o:TOK z T h) (hT:ѨT=512) (w:ὥ) (f:(T.uget (w >>> (23:ὥ)).toUSize (qBx hT w))ᶠ) : T.uget (w >>> (23:ὥ)).toUSize (qBx hT w)=pw.uget (w >>> (23:ὥ)).toUSize (qCh w) ∧ z*0x800000<=(w &&& В).toNat ∧ w &&& В<=h:=by obtain ⟨k,-,eT,k2,k3,hk⟩:=o have s:=qD8 w rw[eT,ὃ,s] at f rw[eT,qDc,ὃ,s] unfold pwEntryN at f ⊢ have e:=qAq w have g:=w.toNat_lt by_cases c:(decide (ѥw/2^23%256ὧ) (L:љ) (a:ὧ):ὧ := L.foldl (λacc s=>acc+f s) a lemma qB4 (f:Ὣ->ὧ) (L:љ) : ∀ a,(N_ff f L a)ᶠ->aᶠ∧∀ s∈L,(f s)ᶠ:=by induction L with | nil=>exact λa h=>⟨h,λs hs=>by simp at hs⟩ | cons p L ih => intro a h;obtain ⟨h1,h2⟩:=ih _ h;obtain ⟨h3,h4⟩:=qC2 _ _ h1;refine ⟨h3,λs hs=>?_⟩;rcases List.mem_cons.mp hs with e | e;. rw[e];exact h4 . exact h2 s e section variable {T:ὤ} {hT:ѨT=512} {x:ὤ} {ix W:ѐ} {w0 w1 w2 w3 m n:ὦ} (f:ὧ->ὥ->ὧ) end section variable {T:ὤ} {hT:ѨT=512} {hv:ὥ} {x:ὤ} {W:ѐ} {u:Ὣ} {L:љ} include x W u L end section variable {T:ὤ} {hT:ѨT=512} {hv:ὥ} {I O:Ὣ} {X W b:ё} set_option maxRecDepth 8000 in lemma qS8 (R:F8) (H:(R.s0+R.s1+R.s2+R.s3+R.s4+R.s5+R.s6+R.s7)ᶠ):∀ r,r<8->(C_fs R r)ᶠ:=by obtain ⟨h1,h7⟩:=qC2 _ _ H obtain ⟨h2,h6⟩:=qC2 _ _ h1 obtain ⟨h3,h5⟩:=qC2 _ _ h2 obtain ⟨h4,h4'⟩:=qC2 _ _ h3 obtain ⟨h9,h3'⟩:=qC2 _ _ h4 obtain ⟨h10,h2'⟩:=qC2 _ _ h9 obtain ⟨h0,h1'⟩:=qC2 _ _ h10 intro r hr interval_cases r . exact h0 . exact h1' . exact h2' . exact h3' . exact h4' . exact h5 . exact h6 . exact h7 lemma qZn (oT:TOK 0 T hv) (f:Ὣ->ὧ) (ww:Ὣ->ὥ) (L:љ) (h:(N_ff (λs=>f s*dvN T hT (ww s)) L 0)ᶠ) : (∀ s∈L,Z_ok hv (ww s))∧N_ff (λs=>f s*dvN T hT (ww s)) L 0=L.foldl (λacc s=>acc+f s*dv (ww s)) 0:=by have F:=(qB4 _ _ _ h).2 have G:=λs hs=>qZk oT (qC1 _ _ (F s hs)).2 exact ⟨λs hs=>(G s hs).2,List.foldl_ext _ _ _ λacc s hs=>by show acc+f s*dvN T hT (ww s)=_ rw[(G s hs).1]⟩ lemma qZg {hv w:ὥ} (t:ѥhv<0x40000000) (h:Z_ok hv w) (g:w &&& В=0∨0x800000<=w &&& В):good w=true:=qBt _ g (by have c:=ἃ.mp h;have b:(У:ὥ).toNat=У:=rfl;rw[ἳ,b];(clear g b; exact omS312 t c)) lemma qZm (ww:Ὣ->ὥ) (L:љ):∀ q,0x7FFFFF<=L.foldl (λq s=>q &&& ((ww s &&& В)-1)) q->0x7FFFFF<=q∧∀ s∈L,ww s &&& В=0∨0x800000<=ww s &&& В:=by induction L with | nil=>exact λq h=>⟨h,λs hs=>by simp at hs⟩ | cons p L ih=> intro q h obtain ⟨h1,h2⟩:=ih _ h obtain ⟨h8,h9⟩:=qFe q ((ww p &&& В)-1) refine ⟨UInt32.le_trans h1 h8,λs hs=>?_⟩ rcases List.mem_cons.mp hs with e | e . rw[e];exact qGi _ (UInt32.le_trans h1 h9) . exact h2 s e lemma qZ1 {xs:ὤ} {W:ѐ} {wo n:ὦ} (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw:Ѥwo+Ѥn<=ѧW) (ww:Ὣ->Ὢ) (hww:∀ k,k< Ѥn->W[Ѥwo+k]! = ww k) (d:Ὣ) : ∀ (t i:ὦ) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (q:ὥ) (r0:F8),Ѥt+d=Ѥn → (∀ r,r<8->C_fs (go8Z T hT xs W wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q r0) r = N_ff (λs=>xs.data[8*s+1+r]! * dvN T hT (ww s)) (List.range' Ѥt d) (C_fs ⟨0,s0,s1,s2,s3,s4,s5,s6,s7,0,0⟩ r)) ∧ (go8Z T hT xs W wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q r0).q=(List.range' Ѥt d).foldl (λq s=>q &&& ((ww s &&& В)-1)) q:=by induction d with | zero => intro t i hi s0 s1 s2 s3 s4 s5 s6 s7 q r0 he rw[go8Z,ἔ (by rw[А];(clear hx hsx hs hw hi; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))] cases r0 exact ⟨λr hr=>by interval_cases r<;>rfl,rfl⟩ | succ d ih => intro t i hi s0 s1 s2 s3 s4 s5 s6 s7 q r0 he have ht:t< n:=by rw[А];(clear hi; exact omS136 he) have htn:Ѥt< Ѥn :=(by exact Nat.succ_le_of_lt ‹_›) have hu:=usz t n ht have e:W.uget (wo+t) (wi wo t n W hw hs htn)=ww Ѥt:=by rw[qC3,qAf _ _ (by clear hi ht htn; exact omS313 hs hw he),hww _ htn] have B:=λ(k:Ὣ) (hk:k<8)=>qBq (xf:=λr k=>xs.data[8*k+1+r]!) (λ_ _ _ _=>rfl) hi htn hsx hx k hk rw[go8Z,Ἄ ht] dsimp only rw[e,B 0 (by decide),B 1 (by decide),B 2 (by decide),B 3 (by decide),B 4 (by decide),B 5 (by decide),B 6 (by decide),B 7 (by exact Nat.le_refl _)] obtain ⟨J1,J2⟩:=ih (t+1) (i+USize.ofNat 8) (by rw[hu,qAf _ _ (by rw[uk 8 (by decide)];(clear ht htn e; exact omS314 hx hsx hi he)),uk 8 (by decide)];(clear he ht htn hu e; exact omS315 hi)) _ _ _ _ _ _ _ _ _ r0 (by rw[hu];(clear hi ht htn hu e; exact omS137 he)) have e5:List.range' (t+1).toNat d=List.range' (Ѥt+1) d:=by rw[hu] rw[e5] at J1 J2 refine ⟨λr hr=>(J1 r hr).trans ?_,J2.trans ?_⟩ . rw[List.range'_succ] unfold N_ff rw[ὔ] interval_cases r<;>rfl . rw[List.range'_succ];rfl @[noinline] def fin8o (inW:Ὣ) (relu:Ὡ) (X W b:ё) (ri K j:Ὣ) (s nf a:ὧ) (hx bw:ὥ) (n:ὦ):ὥ := let bv:=dv bw let r:=ziv (s+bv) (nf*(dv hx*a+bv.abs)) if r == Е then let i:=ri+K let q:=tightGo X W (i*inW).toUSize (j*inW).toUSize n 0 0 0 fin inW relu X W b i j q.s nf q.t bw else r &&& ((if relu then (0:ὥ) else Е) ||| ((r >>> (31:ὥ))-1)) local instance ecNe8:Nonempty H8:=⟨by constructor <;> exact default⟩ def dec8o (X:ѐ) (o n t:ὦ) (xs:ὤ) (h0 h1 h2 h3 h4 h5 h6 h7:ὧ):H8 := if h:t< n then let v0:=dv (rdW X (o+(0*n+t))) let v1:=dv (rdW X (o+(1*n+t))) let v2:=dv (rdW X (o+(2*n+t))) let v3:=dv (rdW X (o+(3*n+t))) let v4:=dv (rdW X (o+(4*n+t))) let v5:=dv (rdW X (o+(5*n+t))) let v6:=dv (rdW X (o+(6*n+t))) let v7:=dv (rdW X (o+(7*n+t))) dec8o X o n (t+1) (wr8 xs (8*t+USize.ofNat 1) v0 v1 v2 v3 v4 v5 v6 v7) (h0+v0.abs) (h1+v1.abs) (h2+v2.abs) (h3+v3.abs) (h4+v4.abs) (h5+v5.abs) (h6+v6.abs) (h7+v7.abs) else ⟨xs,h0,h1,h2,h3,h4,h5,h6,h7⟩ termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];exact Nat.sub_lt_sub_left (А.mp h) (Nat.lt_succ_self _) local instance ecNe9:Nonempty CN:=⟨by constructor <;> exact default⟩ def cols8Zo (T:ὤ) (hT:ѨT=512) (hv:ὥ) (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (d:H8) (nf:ὧ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (j:Ὣ) (out:ѐ) (q:ὥ) (th:L8) (r0:F8):CN := if hj:j< outW then let ju:=ѩj let wo:=ju*n if hg:8*Ѥn+1<=d.xs.size∧d.xs.size<=4294967295∧ѧW<=4294967295∧Ѥwo+Ѥn<=ѧW then let r:=go8Z T hT d.xs W wo n 0 (USize.ofNat 1) hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2 (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 q r0 if okF (r.s0+r.s1+r.s2+r.s3+r.s4+r.s5+r.s6+r.s7) then let bw:=rdW b ju let ow:=ѩoutW let bv:=dv bw let t0:=fin1 th.l0 (spOf th.l0) (r.s0+bv) let out:=wrW out (ob+ju) (if t0 == Е then fin8 inW relu X W b (ri+0) j r.s0 nf d.h0 hv bw n else fz relu t0) let t1:=fin1 th.l1 (spOf th.l1) (r.s1+bv) let out:=wrW out (ob+(ow+ju)) (if t1 == Е then fin8 inW relu X W b (ri+1) j r.s1 nf d.h1 hv bw n else fz relu t1) let t2:=fin1 th.l2 (spOf th.l2) (r.s2+bv) let out:=wrW out (ob+(2*ow+ju)) (if t2 == Е then fin8 inW relu X W b (ri+2) j r.s2 nf d.h2 hv bw n else fz relu t2) let t3:=fin1 th.l3 (spOf th.l3) (r.s3+bv) let out:=wrW out (ob+(3*ow+ju)) (if t3 == Е then fin8 inW relu X W b (ri+3) j r.s3 nf d.h3 hv bw n else fz relu t3) let t4:=fin1 th.l4 (spOf th.l4) (r.s4+bv) let out:=wrW out (ob+(4*ow+ju)) (if t4 == Е then fin8 inW relu X W b (ri+4) j r.s4 nf d.h4 hv bw n else fz relu t4) let t5:=fin1 th.l5 (spOf th.l5) (r.s5+bv) let out:=wrW out (ob+(5*ow+ju)) (if t5 == Е then fin8 inW relu X W b (ri+5) j r.s5 nf d.h5 hv bw n else fz relu t5) let t6:=fin1 th.l6 (spOf th.l6) (r.s6+bv) let out:=wrW out (ob+(6*ow+ju)) (if t6 == Е then fin8 inW relu X W b (ri+6) j r.s6 nf d.h6 hv bw n else fz relu t6) let t7:=fin1 th.l7 (spOf th.l7) (r.s7+bv) let out:=wrW out (ob+(7*ow+ju)) (if t7 == Е then fin8 inW relu X W b (ri+7) j r.s7 nf d.h7 hv bw n else fz relu t7) cols8Zo T hT hv inW outW relu X W b d nf n ri ob (j+1) out r.q th r else ⟨out,false⟩ else ⟨out,false⟩ else ⟨out,decide (0x7FFFFF<=q)⟩ termination_by outW-j decreasing_by all_goals omega def cols8ZDo (D:ὤ) (hv:ὥ) (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (hd:ѨD=ѧW) (d:H8) (nf:ὧ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (j:Ὣ) (out:ѐ) (q:ὥ) (th:L8) (r0:F8):CN := if hj:j< outW then let ju:=ѩj let wo:=ju*n if hg:8*Ѥn+1<=d.xs.size∧d.xs.size<=4294967295∧ѧW<=4294967295∧Ѥwo+Ѥn<=ѧW then let r:=go8ZS D d.xs W hd wo n 0 (USize.ofNat 1) hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2 (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 q r0 if okF (r.s0+r.s1+r.s2+r.s3+r.s4+r.s5+r.s6+r.s7) then let bw:=rdW b ju let ow:=ѩoutW let bv:=dv bw let t0:=fin1 th.l0 (spOf th.l0) (r.s0+bv) let out:=wrW out (ob+ju) (if t0 == Е then fin8o inW relu X W b ri 0 j r.s0 nf d.h0 hv bw n else fz relu t0) let t1:=fin1 th.l1 (spOf th.l1) (r.s1+bv) let out:=wrW out (ob+(ow+ju)) (if t1 == Е then fin8o inW relu X W b ri 1 j r.s1 nf d.h1 hv bw n else fz relu t1) let t2:=fin1 th.l2 (spOf th.l2) (r.s2+bv) let out:=wrW out (ob+(2*ow+ju)) (if t2 == Е then fin8o inW relu X W b ri 2 j r.s2 nf d.h2 hv bw n else fz relu t2) let t3:=fin1 th.l3 (spOf th.l3) (r.s3+bv) let out:=wrW out (ob+(3*ow+ju)) (if t3 == Е then fin8o inW relu X W b ri 3 j r.s3 nf d.h3 hv bw n else fz relu t3) let t4:=fin1 th.l4 (spOf th.l4) (r.s4+bv) let out:=wrW out (ob+(4*ow+ju)) (if t4 == Е then fin8o inW relu X W b ri 4 j r.s4 nf d.h4 hv bw n else fz relu t4) let t5:=fin1 th.l5 (spOf th.l5) (r.s5+bv) let out:=wrW out (ob+(5*ow+ju)) (if t5 == Е then fin8o inW relu X W b ri 5 j r.s5 nf d.h5 hv bw n else fz relu t5) let t6:=fin1 th.l6 (spOf th.l6) (r.s6+bv) let out:=wrW out (ob+(6*ow+ju)) (if t6 == Е then fin8o inW relu X W b ri 6 j r.s6 nf d.h6 hv bw n else fz relu t6) let t7:=fin1 th.l7 (spOf th.l7) (r.s7+bv) let out:=wrW out (ob+(7*ow+ju)) (if t7 == Е then fin8o inW relu X W b ri 7 j r.s7 nf d.h7 hv bw n else fz relu t7) cols8ZDo D hv inW outW relu X W b hd d nf n ri ob (j+1) out q th r else ⟨out,false⟩ else ⟨out,false⟩ else ⟨out,decide (0x7FFFFF<=q)⟩ termination_by outW-j decreasing_by all_goals omega def C_D8o (X:ё) (ri m t:Ὣ) (d:H8):Prop := (8*m+1<=d.xs.size∧d.xs.size<2^32)∧(∀ k r:Ὣ,k< t->r<8->d.xs.data[8*k+1+r]! = dv X[(ri+r)*m+k]!) ∧ ∀ r:Ὣ,r<8->C_hf d r=(List.range t).foldl (λ(a:ὧ) k=>a+(dv X[(ri+r)*m+k]!).abs) 0 lemma qRo {X:ё} {o n t c:ὦ} {ri k:Ὣ} (hs:ѧX<2^32) (ho:Ѥo=ri*Ѥn) (hc:Ѥc=k) (h:(ri+k)*Ѥn+Ѥt<2^32) : rdW X (o+(c*n+t))=X[(ri+k)*Ѥn+Ѥt]!:=by have h0:(ri+k)*Ѥn=ri*Ѥn+k*Ѥn:=Nat.add_mul _ _ _ have h1:k*Ѥn+Ѥt<2^32:=by (clear hs hc; exact omS316 h h0) rw[qAg _ _ hs,qAf _ _ (by rw[qB3 hc h1,ho];(clear hs ho hc h1; exact omS317 h h0)),qB3 hc h1,ho,h0,Nat.add_assoc] lemma qGqo {X:ё} {o n:ὦ} {ri:Ὣ} (hs:ѧX<2^32) (ho:Ѥo=ri*Ѥn) (h8:(ri+8)*Ѥn<=ѧX) (d:Ὣ) : ∀ (t:ὦ) (xs:ὤ) (h0 h1 h2 h3 h4 h5 h6 h7:ὧ),Ѥt+d=Ѥn → C_D8o X ri Ѥn Ѥt ⟨xs,h0,h1,h2,h3,h4,h5,h6,h7⟩ → C_D8o X ri Ѥn Ѥn (dec8o X o n t xs h0 h1 h2 h3 h4 h5 h6 h7):=by induction d with | zero => intro t xs h0 h1 h2 h3 h4 h5 h6 h7 he H rw[dec8o,ἔ (by rw[А];(clear hs ho h8; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))] have e:Ѥt=Ѥn :=(by omega) rw[e] at H;exact H | succ d ih => intro t xs h0 h1 h2 h3 h4 h5 h6 h7 he H have ht:t< n:=by rw[А];(clear hs ho h8; exact omS136 he) have hu:=usz t n ht have bnd:∀ k,k<8->(ri+k)*Ѥn+Ѥt<2^32:=λk hk=>by have a1:=Nat.mul_le_mul_right Ѥn (show ri+k+1<=ri+8 by (clear hs ho h8 he ht hu; exact omS318 hk)) have a2:(ri+k+1)*Ѥn=(ri+k)*Ѥn+Ѥn:=by rw[Nat.add_mul,Nat.one_mul] (clear ho ht hk; omega) rw[dec8o,Ἄ ht] dsimp only rw[qRo hs ho (show (0:ὦ).toNat=0 from uk 0 (by positivity)) (bnd 0 (by positivity)),qRo hs ho (show (1:ὦ).toNat=1 from uk 1 (by norm_num1)) (bnd 1 (by norm_num1)),qRo hs ho (show (2:ὦ).toNat=2 from uk 2 (by norm_num1)) (bnd 2 (by norm_num1)),qRo hs ho (show (3:ὦ).toNat=3 from uk 3 (by norm_num1)) (bnd 3 (by norm_num1)),qRo hs ho (show (4:ὦ).toNat=4 from uk 4 (by norm_num1)) (bnd 4 (by norm_num1)),qRo hs ho (show (5:ὦ).toNat=5 from uk 5 (by norm_num1)) (bnd 5 (by norm_num1)),qRo hs ho (show (6:ὦ).toNat=6 from uk 6 (by norm_num1)) (bnd 6 (by norm_num1)),qRo hs ho (show (7:ὦ).toNat=7 from uk 7 (by norm_num1)) (bnd 7 (by norm_num1))] obtain ⟨H1,H2,H3⟩:=H dsimp only at H1 H2 obtain ⟨Z1,Z2⟩:=qW8 xs t (dv X[(ri+0)*Ѥn+Ѥt]!) (dv X[(ri+1)*Ѥn+Ѥt]!) (dv X[(ri+2)*Ѥn+Ѥt]!) (dv X[(ri+3)*Ѥn+Ѥt]!) (dv X[(ri+4)*Ѥn+Ѥt]!) (dv X[(ri+5)*Ѥn+Ѥt]!) (dv X[(ri+6)*Ѥn+Ѥt]!) (dv X[(ri+7)*Ѥn+Ѥt]!) H1.2 (by have:=H1.1;(clear hs ho h8 ht this; omega)) refine ih (t+1) _ _ _ _ _ _ _ _ _ (by clear hs ho h8 ht H1 Z1; omega) ⟨?_,?_,?_⟩ . dsimp only;rw[Z1];exact H1 . intro k r hk hr;rw[hu] at hk;dsimp only;rw[Z2];by_cases e:k=Ѥt . subst e;interval_cases r<;>simp . have hk':k< Ѥt:=Nat.lt_of_le_of_ne (Nat.le_of_lt_succ hk) e have hlt:8*k+1+r<8*Ѥt+1:=by (clear hs ho h8 ht H1 Z1 hk e; omega) rw[ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _))),ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _))),ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _))),ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _))),ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _))),ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _))),ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _))),ἐ (Nat.ne_of_lt (hlt.trans_le (Nat.le_add_right _ _)))];exact H2 k r hk' hr . intro r hr;have h9:=H3 r hr;rw[hu,List.range_succ,List.foldl_append,<-h9];interval_cases r<;>rfl def C_B (ri O j q:Ὣ):Prop:=q< ri*O∨(ri*O<=q∧q<(ri+8)*O∧q%O< j) lemma qF4o {O q j ri:Ὣ} (hj:j< O) (h:C_B ri O (j+1) q) : q=(ri+7)*O+j∨q=(ri+6)*O+j∨q=(ri+5)*O+j∨q=(ri+4)*O+j∨q=(ri+3)*O+j∨q=(ri+2)*O+j∨q=(ri+1)*O+j∨q=(ri+0)*O+j∨C_B ri O j q:=by unfold C_B at h ⊢ rcases h with h|⟨h1,h2,h3⟩ . simp only[h,true_or,or_true] . by_cases e:q%O< j . simp only[h1,h2,e,and_self,or_true] . have e2:q%O=j :=(by clear hj h1 h2; exact omS309 h3 e) have hO:0< O:=by (clear h1 h2 e2; exact omS147 hj) have e3:=Nat.div_add_mod q O have e5:ri<=q/O:=(Nat.le_div_iff_mul_le hO).2 h1 have e4:q/O< ri+8:=(Nat.div_lt_iff_lt_mul hO).2 h2 rw[e2,ἥ] at e3 obtain ⟨a,ha⟩:∃ a,q/O=ri+a:=⟨q/O-ri,by (clear hj h1 h2 h3 e e2 hO e3; exact omS191 e5)⟩ have a8:a<8:=by (clear hj h1 h2 h3 e e2 hO e3; exact omS319 e4 ha) rw[ha] at e3 interval_cases a<;>simp only[e3.symm,true_or,or_true] lemma qW9o {N O ri j:Ὣ} {sp:Ὣ->Ὢ} {out:ё} {ob:ὦ} (hN:N<2^32) (hR:(ri+8)*O<=N) (hob:Ѥob=ri*O) (hj:j< O) (H:C_Inv N sp (C_B ri O j) out) : C_Inv N sp (C_B ri O (j+1)) (wrW (wrW (wrW (wrW (wrW (wrW (wrW (wrW out (ob+ѩj) (sp ((ri+0)*O+j))) (ob+(ѩO+ѩj)) (sp ((ri+1)*O+j))) (ob+(2*ѩO+ѩj)) (sp ((ri+2)*O+j))) (ob+(3*ѩO+ѩj)) (sp ((ri+3)*O+j))) (ob+(4*ѩO+ѩj)) (sp ((ri+4)*O+j))) (ob+(5*ѩO+ѩj)) (sp ((ri+5)*O+j))) (ob+(6*ѩO+ѩj)) (sp ((ri+6)*O+j))) (ob+(7*ѩO+ѩj)) (sp ((ri+7)*O+j))):=by have bk:∀ k,k<8->(ri+k)*O+j< N∧k*O+j<2^32:=λk hk=>by have a1:=Nat.mul_le_mul_right O (show ri+k+1<=ri+8 by (clear hN hR hob hj; exact omS318 hk)) have a2:(ri+k+1)*O=(ri+k)*O+O:=by rw[Nat.add_mul,Nat.one_mul] have a3:(ri+k)*O=ri*O+k*O:=Nat.add_mul _ _ _ constructor<;>(clear hk; omega) have e0:j.toUSize.toNat=j:=qAd _ (by have:=bk 0 (by positivity);(clear hN hR hob hj; omega)) have eo:O.toUSize.toNat=O:=qAd _ (by have:=bk 1 (by norm_num1);(clear hN hR hob; (clear hj; omega))) have pk:∀ (c:ὦ) (k:Ὣ),k<8->Ѥc=k->(ob+(c*ѩO+ѩj)).toNat=(ri+k)*O+j:=λc k hk hc=>by obtain ⟨b1,b2⟩:=bk k hk have a3:(ri+k)*O=ri*O+k*O:=Nat.add_mul _ _ _ have i1:(c*ѩO+ѩj).toNat=k*O+j:=by rw[qB3 hc (by rw[eo,e0];(exact Nat.succ_le_of_lt ‹_›)),eo,e0] rw[qAf _ _ (by rw[i1,hob];(clear hR hob hj eo hk hc b2; (clear e0; exact omS320 hN b1 a3))),i1,hob];(clear hN hR hob hj e0 eo hk hc b1 b2 i1; omega) have u0:(ob+ѩj).toNat=(ri+0)*O+j:=by obtain ⟨b1,b2⟩:=bk 0 (by positivity) have a0:(ri+0)*O=ri*O:=by rw[Nat.add_zero] rw[qAf _ _ (by rw[hob,e0];(clear hR hob hj eo b2; (clear e0; exact omS321 hN b1 a0))),hob,e0];(clear hN hR hob hj e0 eo b1 b2; omega) have u1:(ob+(ѩO+ѩj)).toNat=(ri+1)*O+j:=by obtain ⟨b1,b2⟩:=bk 1 (by norm_num1) have a1:(ri+1)*O=ri*O+O:=by rw[Nat.add_mul,Nat.one_mul] have i1:(ѩO+ѩj).toNat=O+j:=by rw[qAf _ _ (by rw[eo,e0];(clear hN hR hob hj b1 a1; (clear e0 eo; exact omS322 b2))),eo,e0] rw[qAf _ _ (by rw[i1,hob];(clear hR hob hj b2 i1; (clear e0 eo; exact omS320 hN b1 a1))),i1,hob];(clear hN hR hob hj e0 u0 b1 b2 i1; (clear eo; omega)) have I0:=qAk hN H u0 (bk 0 (by positivity)).1 rfl have I1:=qAk hN I0 u1 (bk 1 (by norm_num1)).1 rfl have I2:=qAk hN I1 (pk 2 2 (by norm_num1) (uk 2 (by norm_num1))) (bk 2 (by norm_num1)).1 rfl have I3:=qAk hN I2 (pk 3 3 (by norm_num1) (uk 3 (by norm_num1))) (bk 3 (by norm_num1)).1 rfl have I4:=qAk hN I3 (pk 4 4 (by norm_num1) (uk 4 (by norm_num1))) (bk 4 (by norm_num1)).1 rfl have I5:=qAk hN I4 (pk 5 5 (by norm_num1) (uk 5 (by norm_num1))) (bk 5 (by norm_num1)).1 rfl have I6:=qAk hN I5 (pk 6 6 (by norm_num1) (uk 6 (by norm_num1))) (bk 6 (by norm_num1)).1 rfl have I7:=qAk hN I6 (pk 7 7 (by norm_num1) (uk 7 (by norm_num1))) (bk 7 (by norm_num1)).1 rfl exact qA5 I7 (λq _ hq'=>qF4o hj hq') set_option maxHeartbeats 1000000 in set_option maxRecDepth 8000 in lemma qZ8o (oT:TOK 0 T hv) {Y:Ὡ} {d:H8} {R ri:Ὣ} {ob:ὦ} (hob:Ѥob=ri*O) (hR:ri+8<=R) (hW:O*I=ѧW) (pi:0< I) (ni:I<2^20) (sW:ѧW<2^32) (hd:8*I+1<=d.xs.size∧d.xs.size<2^32) (th:L8) (bm:ὧ) (fbm:bmᶠ) (hbm:∀ j,j< O → |Submission.D.R (dv b[j]!)| ≤ Submission.D.R bm) (bb:Submission.D.R bm<=2^(290:ℤ)) (hth:∀ r,r<8 → C_lo th r=loOf (nfOf I*(dv hv*C_hf d r+bm))) (k:Ὣ) : ∀ (j:Ὣ) (out:ё) (q:ὥ) (r0:F8),j+k=O → (cols8Zo T hT hv I O Y X W b d (nfOf I) ѩI ri ob j out q th r0).ok=true → 0x7FFFFF<=q∧(∀ j',j<=j'->j'< O->∀ s,s< I->good W[j'*I+s]! = true∧W[j'*I+s]! &&& В<=hv) ∧ ∀ (G:C_G R I O X W b),C_D8o X ri I I d → C_Inv (R*O) (C_sp I O Y X W b) (C_B ri O j) out → C_Inv (R*O) (C_sp I O Y X W b) (C_B ri O O) (cols8Zo T hT hv I O Y X W b d (nfOf I) ѩI ri ob j out q th r0).out:=by have hnm:I.toUSize.toNat=I:=qAd _ (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) have hO:O<2^32:=by have:=Ὄ O pi (clear hob hR pi ni hd hnm; omega) have W1:∀ j,j<=O->(ѩj*ѩI).toNat=j*I:=λj hj=>by have h1:j*I<=O*I:=Ἒ _ hj rw[qBa _ _ (by rw[qAd _ (by exact Nat.lt_of_le_of_lt ‹_› ‹_›),hnm];(clear hob hR pi ni hd hnm hO hj; exact omS323 hW sW h1)),qAd _ (by exact Nat.lt_of_le_of_lt ‹_› ‹_›),hnm] induction k with | zero => intro j out q r0 he ok rw[cols8Zo,ἔ (by clear hob hR hW pi ni sW hd hnm hO; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))))] at ok ⊢ have e:j=O :=(by exact omS155 he) rw[e] exact ⟨of_decide_eq_true ok,λj' a b'=>by (clear hob hR hW pi ni sW hd hnm hO e; (clear he; omega)),λ_ _ H=>H⟩ | succ k ih => intro j out q r0 he ok have hj:j< O :=(by clear hob hR hW pi ni sW hd hnm hO; exact omS136 he) have hlt:j*I+I<=ѧW:=by rw[<-hW];exact qBc hj (Ὗ _) have w1:=W1 j hj.le have hg:(ѩj*ѩI).toNat+I.toUSize.toNat<=ѧW:=by rw[w1,hnm];exact hlt have hx:8*I.toUSize.toNat+1<=d.xs.size:=by rw[hnm];exact hd.1 have hsx:d.xs.size<2^32:=hd.2 have hi0:(USize.ofNat 1).toNat=8*(0:ὦ).toNat+1:=by rw[C_z,uk 1 (by decide)] obtain ⟨key,kq⟩:=qZ1 (T:=T) (hT:=hT) hx hsx sW hg (λk=>W[j*I+k]!) (λk _=>by rw[w1]) I 0 (USize.ofNat 1) hi0 0 0 0 0 0 0 0 0 q r0 (by rw[hnm,C_z,Ἇ]) rw[C_z,<-ὗ] at key kq rw[cols8Zo,Ἄ hj] at ok ⊢ dsimp only at ok ⊢ rw[Ἄ ⟨hx,by (exact Nat.le_of_lt_succ ‹_›),by (exact Nat.le_of_lt_succ ‹_›),hg⟩] at ok ⊢ generalize go8Z T hT d.xs W (ѩj*ѩI) ѩI 0 (USize.ofNat 1) hx hsx sW hg hi0 0 0 0 0 0 0 0 0 q r0=RR at key kq ok ⊢ by_cases c':okF (RR.s0+RR.s1+RR.s2+RR.s3+RR.s4+RR.s5+RR.s6+RR.s7)=true . rw[ἱ c'] at ok ⊢ have c:=finSub _ c' have F:=qS8 RR c have Ks:∀ r,r<8->C_fs RR r=N_ff (λs=>d.xs.data[8*s+1+r]! * dvN T hT W[j*I+s]!) (ἄ I) 0:=λr hr=>by have k1:=key r hr have e1:C_fs ⟨0,0,0,0,0,0,0,0,0,0,0⟩ r=0:=by interval_cases r<;>rfl rw[e1] at k1 exact k1 have Zs:=λ(r:Ὣ) (hr:r<8)=>qZn oT (λs=>d.xs.data[8*s+1+r]!) (λs=>W[j*I+s]!) (ἄ I) (by have f:=F r hr;rw[Ks r hr] at f;exact f) obtain ⟨q1,IH,-⟩:=ih (j+1) _ _ _ (by clear hob hR hW pi ni sW hd hnm hO hj hlt w1 hg hx hsx hi0 kq; exact omS137 he) ok rw[kq] at q1 obtain ⟨q2,q3⟩:=qZm (λs=>W[j*I+s]!) (ἄ I) q q1 refine ⟨q2,λj' a b' s hs=>?_,λG D H=>?_⟩ . by_cases e:j'=j . rw[e];exact ⟨qZg (qTb oT) ((Zs 0 (by decide)).1 s (Ἅ.2 hs)) (q3 s (Ἅ.2 hs)),(Zs 0 (by decide)).1 s (Ἅ.2 hs)⟩ . exact IH j' (by clear hob hR hW pi ni sW hd hnm hO he hj hlt w1 hg hx hsx hi0 kq q1 q2 b' hs; exact omS138 a e) b' s hs . have hbs:=G.sb have e0:j.toUSize.toNat=j:=qAd _ (by clear hob hR hW pi ni sW hd hnm hj hlt w1 hg hx hsx hi0 kq q1 q2 hbs; exact omS324 hO he) have hN:R*O<2^32:=G.sO have hOR:O<=R*O:=Nat.le_mul_of_pos_left O (by (clear hob hW pi ni sW hd hnm hO he hj hlt w1 hg hx hsx hi0 kq q1 q2 hbs e0 hN; exact omS325 hR)) have gv:=(qTg oT).1 have hv1:=(qTg oT).2 have O':∀ r,r<8->(if fin1 (C_lo th r) (spOf (C_lo th r)) (C_fs RR r+dv b[j]!) == Е then fin8 I Y X W b (ri+r) j (C_fs RR r) (nfOf I) (C_hf d r) hv b[j]! ѩI else fz Y (fin1 (C_lo th r) (spOf (C_lo th r)) (C_fs RR r+dv b[j]!)))=C_sp I O Y X W b ((ri+r)*O+j):=by intro r hr have hl:=hth r hr rw[qCi _ _ _ _ _ _ hj,D.2.2 r hr] rw[D.2.2 r hr] at hl obtain ⟨z1,z2⟩:=Zs r hr exact qDuF G Y (by (clear hob hW pi ni sW hd hnm hO he hj hlt w1 hg hx hsx hi0 kq q1 q2 hbs e0 hN hOR hv1; exact omS326 hR hr):ri+r< R) hj gv hv1 (λt ht=>z1 t (Ἅ.2 ht)) (ἄ I) Ὂ (λt h=>Ἅ.1 h) (λt ht hn=>absurd (Ἅ.2 ht) hn) ((Ks r hr).trans (z2.trans (List.foldl_ext _ _ _ λacc t ht=>by show acc+d.xs.data[8*t+1+r]! * _=_ rw[D.2.1 t r (Ἅ.1 ht) hr]))) bm fbm (hbm j hj) bb _ hl have o0:(if fin1 th.l0 (spOf th.l0) (RR.s0+dv b[j]!) == Е then fin8 I Y X W b (ri+0) j RR.s0 (nfOf I) d.h0 hv b[j]! ѩI else fz Y (fin1 th.l0 (spOf th.l0) (RR.s0+dv b[j]!)))=_ :=O' 0 (by decide) have o1:(if fin1 th.l1 (spOf th.l1) (RR.s1+dv b[j]!) == Е then fin8 I Y X W b (ri+1) j RR.s1 (nfOf I) d.h1 hv b[j]! ѩI else fz Y (fin1 th.l1 (spOf th.l1) (RR.s1+dv b[j]!)))=_ :=O' 1 (by decide) have o2:(if fin1 th.l2 (spOf th.l2) (RR.s2+dv b[j]!) == Е then fin8 I Y X W b (ri+2) j RR.s2 (nfOf I) d.h2 hv b[j]! ѩI else fz Y (fin1 th.l2 (spOf th.l2) (RR.s2+dv b[j]!)))=_ :=O' 2 (by decide) have o3:(if fin1 th.l3 (spOf th.l3) (RR.s3+dv b[j]!) == Е then fin8 I Y X W b (ri+3) j RR.s3 (nfOf I) d.h3 hv b[j]! ѩI else fz Y (fin1 th.l3 (spOf th.l3) (RR.s3+dv b[j]!)))=_ :=O' 3 (by decide) have o4:(if fin1 th.l4 (spOf th.l4) (RR.s4+dv b[j]!) == Е then fin8 I Y X W b (ri+4) j RR.s4 (nfOf I) d.h4 hv b[j]! ѩI else fz Y (fin1 th.l4 (spOf th.l4) (RR.s4+dv b[j]!)))=_ :=O' 4 (by decide) have o5:(if fin1 th.l5 (spOf th.l5) (RR.s5+dv b[j]!) == Е then fin8 I Y X W b (ri+5) j RR.s5 (nfOf I) d.h5 hv b[j]! ѩI else fz Y (fin1 th.l5 (spOf th.l5) (RR.s5+dv b[j]!)))=_ :=O' 5 (by decide) have o6:(if fin1 th.l6 (spOf th.l6) (RR.s6+dv b[j]!) == Е then fin8 I Y X W b (ri+6) j RR.s6 (nfOf I) d.h6 hv b[j]! ѩI else fz Y (fin1 th.l6 (spOf th.l6) (RR.s6+dv b[j]!)))=_ :=O' 6 (by decide) have o7:(if fin1 th.l7 (spOf th.l7) (RR.s7+dv b[j]!) == Е then fin8 I Y X W b (ri+7) j RR.s7 (nfOf I) d.h7 hv b[j]! ѩI else fz Y (fin1 th.l7 (spOf th.l7) (RR.s7+dv b[j]!)))=_ :=O' 7 (by exact Nat.le_refl _) simp only[qAg _ _ hbs,e0,o0,o1,o2,o3,o4,o5,o6,o7] at ok ⊢ exact (ih (j+1) _ _ _ (by clear hob hR hW pi ni sW hd hnm hO hj hlt w1 hg hx hsx hi0 kq q1 q2 hbs e0 hN hOR hv1 o0 o1 o2 o3 o4 o5 o6 o7; exact omS137 he) ok).2.2 G D (qW9o hN (Nat.mul_le_mul_right O hR) hob hj H) . rw[ἐ c'] at ok;exact absurd ok ג end section open Float.Model Float.Model.UnpackedFloat lemma d8ix {o n t c:ὦ} {k:Ὣ} (hc:Ѥc=k) (hb:Ѥo+(k*Ѥn+Ѥt)<2^32) : Ѥ(o+(c*n+t))=Ѥo+(k*Ѥn+Ѥt):=by rw[qAf _ _ (by rw[qB3 hc (by omega)];exact hb),qB3 hc (by omega)] lemma d8rd {X:ѐ} {o n t c:ὦ} {k:Ὣ} (hc:Ѥc=k) (hb1:Ѥo+(k*Ѥn+Ѥt)< ѧX) (hb2:Ѥo+(k*Ѥn+Ѥt)<2^32) : Ѥ(o+(c*n+t))< ѧX:=by rw[d8ix hc hb2];exact hb1 local instance ecNe10:Nonempty H8:=⟨by constructor <;> exact default⟩ lemma d8b {o n t:ὦ} {N:Ὣ} (k:Ὣ) (hk:k<8) (h:Ѥt<Ѥn) (hx:Ѥo+8*Ѥn<=N) : Ѥo+(k*Ѥn+Ѥt)< N:=by have:=Nat.mul_le_mul_right (Ѥn) (show k+1<=8 from hk);rw[Nat.succ_mul] at this;omega def dec8oI (X:ѐ) (o n t:ὦ) (xs:ὤ) (h0 h1 h2 h3 h4 h5 h6 h7:ὧ) (hx:Ѥo+8*Ѥn<=ѧX) (hs:Ѥo+8*Ѥn<2^32):H8 := if h:t< n then let v0:=dv (X.uget (o+(0*n+t)) (d8rd (k:=0) (uk 0 (by positivity)) (d8b 0 (by decide) (А.mp h) hx) (d8b 0 (by decide) (А.mp h) (Nat.le_of_lt hs)))) let v1:=dv (X.uget (o+(1*n+t)) (d8rd (k:=1) (uk 1 (by norm_num1)) (d8b 1 (by decide) (А.mp h) hx) (d8b 1 (by decide) (А.mp h) (Nat.le_of_lt hs)))) let v2:=dv (X.uget (o+(2*n+t)) (d8rd (k:=2) (uk 2 (by norm_num1)) (d8b 2 (by decide) (А.mp h) hx) (d8b 2 (by decide) (А.mp h) (Nat.le_of_lt hs)))) let v3:=dv (X.uget (o+(3*n+t)) (d8rd (k:=3) (uk 3 (by norm_num1)) (d8b 3 (by decide) (А.mp h) hx) (d8b 3 (by decide) (А.mp h) (Nat.le_of_lt hs)))) let v4:=dv (X.uget (o+(4*n+t)) (d8rd (k:=4) (uk 4 (by norm_num1)) (d8b 4 (by decide) (А.mp h) hx) (d8b 4 (by decide) (А.mp h) (Nat.le_of_lt hs)))) let v5:=dv (X.uget (o+(5*n+t)) (d8rd (k:=5) (uk 5 (by norm_num1)) (d8b 5 (by decide) (А.mp h) hx) (d8b 5 (by decide) (А.mp h) (Nat.le_of_lt hs)))) let v6:=dv (X.uget (o+(6*n+t)) (d8rd (k:=6) (uk 6 (by norm_num1)) (d8b 6 (by decide) (А.mp h) hx) (d8b 6 (by decide) (А.mp h) (Nat.le_of_lt hs)))) let v7:=dv (X.uget (o+(7*n+t)) (d8rd (k:=7) (uk 7 (by norm_num1)) (d8b 7 (by decide) (А.mp h) hx) (d8b 7 (by decide) (А.mp h) (Nat.le_of_lt hs)))) dec8oI X o n (t+1) (wr8 xs (8*t+USize.ofNat 1) v0 v1 v2 v3 v4 v5 v6 v7) (h0+v0.abs) (h1+v1.abs) (h2+v2.abs) (h3+v3.abs) (h4+v4.abs) (h5+v5.abs) (h6+v6.abs) (h7+v7.abs) hx hs else ⟨xs,h0,h1,h2,h3,h4,h5,h6,h7⟩ termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];exact Nat.sub_lt_sub_left (А.mp h) (Nat.lt_succ_self _) lemma aU (a:ѐ) (hs:ѧa<2^32) (i:ὦ) (h:Ѥi< ѧa):a.uget i h=rdW a i:=by unfold rdW;rw[Ἄ (by rw[А,Array.usize,qAd _ hs];exact h)] lemma dec8oI_eq (X:ѐ) (o n:ὦ) (hx:Ѥo+8*Ѥn<=ѧX) (hs:Ѥo+8*Ѥn<2^32) (hxs:ѧX<2^32) (d:Ὣ) : ∀ (t:ὦ) (xs:ὤ) (h0 h1 h2 h3 h4 h5 h6 h7:ὧ),Ѥt+d=Ѥn → dec8oI X o n t xs h0 h1 h2 h3 h4 h5 h6 h7 hx hs=dec8o X o n t xs h0 h1 h2 h3 h4 h5 h6 h7:=by induction d with | zero=> intro t xs h0 h1 h2 h3 h4 h5 h6 h7 e rw[dec8oI,dec8o,ἔ (by rw[А];omega),ἔ (by rw[А];omega)] | succ d ih=> intro t xs h0 h1 h2 h3 h4 h5 h6 h7 e have ht:t< n:=А.2 (by omega) rw[dec8oI,dec8o,Ἄ ht,Ἄ ht] dsimp only rw[ih (t+1) _ _ _ _ _ _ _ _ _ (by rw[usz t n ht];omega)] simp only[aU X hxs] @[inline] def dec8oC (X:ѐ) (o n:ὦ) (xs:ὤ):H8 := if h:Ѥo+8*Ѥn<=ѧX∧Ѥo+8*Ѥn<=4294967295 then dec8oI X o n 0 xs 0 0 0 0 0 0 0 0 h.1 (by omega) else dec8o X o n 0 xs 0 0 0 0 0 0 0 0 lemma dec8oC_eq (X:ѐ) (o n:ὦ) (xs:ὤ) (hxs:ѧX<2^32):dec8oC X o n xs=dec8o X o n 0 xs 0 0 0 0 0 0 0 0:=by unfold dec8oC;split . rename_i h;exact dec8oI_eq X o n h.1 (by omega) hxs (Ѥn) 0 xs 0 0 0 0 0 0 0 0 (by simp) . rfl end end lemma qZsh (W:ѐ) (c N:Ὣ):∀ (a:Ὣ) (q:ὥ),(List.range' a N).foldl (λ(q:ὥ) (s:Ὣ)=>q &&& ((W[c+s]! &&& В)-1)) q=(List.range' (c+a) N).foldl (λ(q:ὥ) (s:Ὣ)=>q &&& ((W[s]! &&& В)-1)) q:=by induction N with | zero=>intro a q;rfl | succ N ih=>intro a q;rw[List.range'_succ,List.range'_succ,ὔ,ὔ,ih (a+1),show c+(a+1)=c+a+1 by exact omS329] lemma qZsp (W:ѐ) (m N:Ὣ):∀ (s:Ὣ) (q:ὥ),(List.range' s (m+N)).foldl (λ(q:ὥ) (s:Ὣ)=>q &&& ((W[s]! &&& В)-1)) q=(List.range' (s+m) N).foldl (λ(q:ὥ) (s:Ὣ)=>q &&& ((W[s]! &&& В)-1)) ((List.range' s m).foldl (λ(q:ὥ) (s:Ὣ)=>q &&& ((W[s]! &&& В)-1)) q):=by induction m with | zero=>intro s q;rw[Ἇ,Nat.add_zero];rfl | succ m ih=>intro s q;rw[show m+1+N=(m+N)+1 by exact omS330,List.range'_succ,List.range'_succ,ὔ,ὔ,ih (s+1),show s+1+m=s+(m+1) by exact omS146] lemma qScanE (W:ѐ) (hs:ѧW<2^32) (d:Ὣ):∀ (i:ὦ) (q:ὥ),Ѥi+d=ѧW->qScan W W.usize i q=(List.range' Ѥi d).foldl (λ(q:ὥ) (s:Ὣ)=>q &&& ((W[s]! &&& В)-1)) q:=by have hu:W.usize.toNat=ѧW:=qBe _ hs induction d with | zero=>intro i q e;rw[qScan,ἔ (by rw[А,hu];(clear hs; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))];rfl | succ d ih=> intro i q e have hi:i< W.usize:=by rw[А,hu];(clear hs; (clear hu; exact omS136 e)) rw[qScan,Ἄ hi,ih (i+1) _ (by rw[usz i _ hi];(clear hs hi; (clear hu; omega))),usz i _ hi,List.range'_succ,ὔ,qAg W i hs] set_option maxHeartbeats 1000000 in theorem c8ZEo (T:ὤ) (hT:ѨT=512) (hv:ὥ) (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (hd:(dnOf T hT W).size=ѧW) (d:H8) (nf:ὧ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (hn:Ѥn=inW) (hW:outW*inW=ѧW) (hs:ѧW<2^32) (pi:0< inW) (th:L8) (k:Ὣ) : ∀ (j:Ὣ) (out:ѐ) (q:ὥ) (r0 r0':F8),j+k=outW-> cols8ZDo (dnOf T hT W) hv inW outW relu X W b hd d nf n ri ob j out ((List.range' (j*inW) (k*inW)).foldl (λ(q:ὥ) (s:Ὣ)=>q &&& ((W[s]! &&& В)-1)) q) th r0'=cols8Zo T hT hv inW outW relu X W b d nf n ri ob j out q th r0:=by have hO:outW<2^32:=by have:=Ὄ outW pi;(clear hn pi; omega) have W1:∀ j,j<=outW->(ѩj*n).toNat=j*inW:=λj hj=>by have h1:j*inW<=outW*inW:=Ἒ _ hj rw[qBa _ _ (by rw[qAd _ (by (exact Nat.lt_of_le_of_lt ‹_› ‹_›)),hn];(clear hn pi hO hj; exact omS323 hW hs h1)),qAd _ (by (exact Nat.lt_of_le_of_lt ‹_› ‹_›)),hn] induction k with | zero=> intro j out q r0 r0' e rw[cols8ZDo,cols8Zo,ἔ (by (clear hd hn hW hs pi hO; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))))),ἔ (by (clear hd hn hW hs pi hO; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))))),ὒ] rfl | succ k ih=> intro j out q r0 r0' e have hj:j< outW:=by (clear hn hW hs pi hO; exact omS136 e) rw[cols8ZDo,cols8Zo,Ἄ hj,Ἄ hj] dsimp only by_cases hg:8*Ѥn+1<=d.xs.size∧d.xs.size<=4294967295∧ѧW<=4294967295∧(ѩj*n).toNat+Ѥn<=ѧW . rw[Ἄ hg,Ἄ hg,g8ZS,g8ZE (q:=q) (r:=r0)] have hi0:(USize.ofNat 1).toNat=8*(0:ὦ).toNat+1:=by rw[C_z,uk 1 (by decide)] have hq:=(qZ1 (T:=T) (hT:=hT) hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2 (λk=>W[j*inW+k]!) (λk _=>by rw[W1 j hj.le]) Ѥn 0 (USize.ofNat 1) hi0 0 0 0 0 0 0 0 0 q r0 (by rw[C_z,Ἇ])).2 generalize go8Z T hT d.xs W (ѩj*n) n 0 (USize.ofNat 1) hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2 hi0 0 0 0 0 0 0 0 0 q r0=R at hq ⊢ rw[C_z,hn,qZsh W (j*inW) inW 0 q,Nat.add_zero] at hq rw[show (k+1)*inW=inW+k*inW by ring,qZsp W inW (k*inW) (j*inW) q,<-hq,show j*inW+inW=(j+1)*inW by ring] dsimp only[F8q] exact if_congr Iff.rfl (ih (j+1) _ R.q R _ (by (clear hn hW hs pi hO hj hg hi0 hq; exact omS137 e))) rfl . rw[ἔ hg,ἔ hg] lemma c8ZSo (T:ὤ) (hT:ѨT=512) (hv:ὥ) (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (d:H8) (nf:ὧ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (hn:Ѥn=inW) (hW:outW*inW=ѧW) (hs:ѧW<2^32) (pi:0< inW) (out:ѐ) (th:L8) (r0:F8): (if hd:(dnOf T hT W).size=ѧW then cols8ZDo (dnOf T hT W) hv inW outW relu X W b hd d nf n ri ob 0 out (qScan W W.usize 0 Е) th r0 else cols8Zo T hT hv inW outW relu X W b d nf n ri ob 0 out Е th r0)=cols8Zo T hT hv inW outW relu X W b d nf n ri ob 0 out Е th r0:=by split . rename_i hd have e:=c8ZEo T hT hv inW outW relu X W b hd d nf n ri ob hn hW hs pi th outW 0 out Е r0 r0 (by (clear hn hW hs pi hd; (clear hT; exact omS139))) rw[ὒ] at e rw[qScanE W hs ѧW 0 Е (by rw[C_z,Ἇ]),C_z,<-hW] exact e . rfl theorem qDE (X:ѐ) (o n:ὦ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (t:ὦ) (buf:ὤ) (l:ὧ) (hb:Ѥn<=Ѩbuf) (hbs:Ѩbuf<2^32) : decE X o n t buf l hX hs hb=decD X o n t buf l:=by rw[decE,decD];by_cases h:t< n . rw[Ἄ h,Ἄ h];dsimp only have ht:=А.mp h have c1:o+t< X.usize:=by rw[А,qBe X hs];exact wi o t n X hX hs ht have c2:t< buf.usize:=by rw[А,FloatArray.usize,qAd _ hbs];omega have e1:rdW X (o+t)=X.uget (o+t) (wi o t n X hX hs ht):=by unfold rdW;rw[Ἄ c1] rw[e1] have e2:wrF buf t (dv (X.uget (o+t) (wi o t n X hX hs ht)))=buf.uset t (dv (X.uget (o+t) (wi o t n X hX hs ht))) (by omega):=by unfold wrF;rw[Ἄ c2] rw[e2];exact qDE X o n hX hs (t+1) _ _ _ (by rw[qUs];exact hbs) . rw[ἔ h,ἔ h] termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];have:=А.mp h;(clear h; omega) lemma qDF (X:ѐ) (o n:ὦ) (buf:ὤ) (l:ὧ):decF X o n buf l=decD X o n 0 buf l:=by unfold decF;split . rename_i hh;exact qDE X o n hh.1 (by have:=hh.2.1;omega) 0 buf l hh.2.2.1 (by have:=hh.2.2.2;omega) . rfl lemma qEr0:linF0=linearSpec:=by funext rows inW outW relu X W b;unfold linF0;simp only[qDF];(try dsimp only);have Hs:=qGd rows W;generalize scanW rows W=hw at Hs ⊢;split . rename_i h;obtain ⟨h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13⟩:=h;replace h7:=qA9 h7;replace h8:=qA9 h8;replace h9:=qA9 h9;replace h10:=qA9 h10 have G0:=λ(A:∀ q,q< ѧW->good W[q]! = true) => (⟨h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,(qA8 0 X h7 h11).2.2.1,A,(qA8 1 b h9 h13).2.2.1⟩:C_G rows inW outW X W b) have e:linearSpec rows inW outW relu X W b=Array.ofFn (n:=rows*outW) λq =>C_sp inW outW relu X W b q.val:=rfl;have hnf:(inW.toUInt64+8).toFloat*Ἃ 0x3CA0000000000000=nfOf inW:=rfl;rw[e,hnf];split . rename_i hr1;have e1:rows=1:=by simpa using hr1 subst e1;have GX:=(qA8 0 X h7 h11).2.2.1;have sX1:0*inW+inW<=ѧX :=(by clear h2 h3 h4 h5 h6 h11 h12 h13 h7 h8 h9 h10; exact omS332 h1);have nm:inW.toUSize.toNat=inW:=qAd _ (by exact Nat.lt_of_lt_of_le ‹_› (by decide));have P0:=qZf inW (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) have H0:C_Inv (1*outW) (C_sp inW outW relu X W b) (λq=>q<0) (ἇ (1*outW) 0) :=⟨by simp,λq _ h=>absurd h (Ἲ _)⟩ rw[(wbGet inW outW W).2];dsimp only;split . rename_i hv;have Hv:=qA8 2 W h8 hv;have G:=G0 Hv.2.2.1;have hb0:(0*outW).toUSize.toNat=0*outW:=qAd _ (by clear h2 h3 h4 h5 h6 h11 h12 h13 h7 h8 h9 h1 h10 sX1 nm P0 hv; exact omS333);have HdE:C_Dw (ἆ 0) W:=λh q hq=>by have e:0=ѧW:=h;(clear h2 h3 h4 h5 h6 h11 h12 h13 h7 h8 h9 h1 h10 sX1 nm P0 hv hb0; (clear h; omega)) split . rename_i hok;obtain ⟨o1,o2⟩:=Bool.and_eq_true_iff.mp hok;have h8k:inW<=8192:=by simpa using o2 obtain ⟨v1,v2,v3⟩:=qVz (a:=0*inW) (n:=ѩinW) h7 (by rw[nm];exact sX1) inW 0 (zFor inW) 0 (by rw[C_z,Ἇ,nm]) (by rw[nm];exact P0.1) P0.2 (λk hk=>absurd hk (Ἲ _)) rfl o1 rw[nm] at v2 v3 have Rd:=qRd X inW _ h8k v2 have Rw:C_Row inW X 0 idA (decD X (0*inW).toUSize ѩinW 0 (zFor inW) 0).buf ѩinW (ἄ inW) (decD X (0*inW).toUSize ѩinW 0 (zFor inW) 0).l:=⟨by rw[nm,List.length_range],by simp,by rw[qIs];exact h8k,⟨by rw[v1];exact P0.1,by rw[v1];exact P0.2⟩,Ὂ,λt ht=>Ἅ.1 ht,λt ht hn=>absurd (Ἅ.2 ht) hn,Rd,v3⟩ have HI:∀ k,k< Ѥ(ѩinW)->(idA[k]!).toNat=k:=λk hk=>qIA k (Nat.lt_of_lt_of_le (by rwa[nm] at hk) h8k) rw[c1VS',c1VW _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ HI (le_refl _)] rw[c1WE _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ (λj hj=>by rw[Rw.len] at hj;have hp:=List.getElem?_eq_getElem hj;exact ⟨_,G.gx ((by exact Nat.le_refl _):0<1) _ (Rw.lt _ (List.mem_of_getElem? hp)),(Rw.rd j _ hp).2⟩) HdE (by rw[nm,h2]) (by rw[h3];exact h9) (λj i k a b c d=>by rw[nm] at c ⊢;exact wbP W inW outW j i k a b c d) (λho i k hi hk=>by rw[nm] at hi ⊢;exact wbPt W inW outW i k ho hi hk) 0 rfl] obtain ⟨gb1,gb2,-,gb4⟩:=qA8 1 b h9 h13 obtain ⟨pb0,pb1,pb2⟩:=qCs gb1 gb2 obtain ⟨fbm,Rbm⟩:=qAm _ gb1 have hbm:∀ j,j< outW → |R (dv b[j]!)| ≤ R (dv (scanH 1 b)):=λj hj=>by have gj:=(qA8 1 b h9 h13).2.2.1 j (by rw[<-h3];exact hj) rw[(qAm _ gj).2,Rbm];exact pb2 _ gj (gb4 j (by rw[<-h3];exact hj)) have bb:R (dv (scanH 1 b))<=2^(290:ℤ):=by rw[Rbm];exact pb1.trans (by rw[show (2:ℝ)^128=2^(128:ℤ) by norm_num];exact zpow_le_zpow_right₀ (by norm_num) (by norm_num)) refine qBv (qD0 G relu ((by exact Nat.le_refl _):0<1) Hv Rw hb0 HdE (dv (scanH 1 b)) fbm hbm bb rfl outW 0 _ (Ἇ _) (by rw[ὒ,Ἵ];exact H0)) (λq hq=>by (clear h2 h4 h5 h6 h11 h12 h13 h7 h8 h9 h1 h10 sX1 nm P0 hv hb0 h8k v1; exact omS334 hq)) . rw[qAi];rfl . rw[qAi];rfl . rw[qAi];rfl . rw[qAi];rfl end lemma bOfS (b:ѐ):Ѩ(bOf b)=ѧb:=by simp[bOf,FloatArray.size] lemma rdBOf (b:ѐ) (u:ὦ) (h:Ѥu< ѧb) (hs:ѧb<2^32):rdB (bOf b) u=dv (rdW b u):=by have h2:u< b.usize:=А.mpr (by rw[Array.usize,qAd _ hs];exact h) have h1:u< (bOf b).usize:=А.mpr (by rw[FloatArray.usize,bOfS,qAd _ hs];exact h) unfold rdB rdW;rw[Ἄ h1,Ἄ h2] simp [bOf,FloatArray.uget,Array.uget] lemma fLB (inW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i j:Ὣ) (s nf a:ὧ) (hx:ὥ) (lo:Ὠ) (u n:ὦ) (h:Ѥu< ѧb) (hs:ѧb<2^32): fin8LB inW relu X W b i j s nf a hx lo (spOf lo) (bOf b) u n=fin8L inW relu X W b i j s nf a hx lo (rdW b u) n:=by unfold fin8LB fin8L;rw[rdBOf b u h hs] lemma fLU (inW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i k:Ὣ) (s nf a:ὧ) (hx:ὥ) (lo:Ὠ) (u n:ὦ) (hu:Ѥu=k) (h:Ѥu< ѧb) (hs:ѧb<2^32): fin8LU inW relu X W b i s nf a hx lo (spOf lo) (bOf b) u n=fin8L inW relu X W b i k s nf a hx lo (rdW b u) n:=by unfold fin8LU fin8L fin8u fin8n;rw[rdBOf b u h hs,hu] lemma lt8 (j k:Ὣ) (hk:k<=8) (h:j+8<2^32):j+k<2^32:=by omega lemma lk8 (j c:Ὣ) (hc:c+1<=8):j+c+1<=j+8:=by omega lemma fb (u:ὦ) (k j n:Ὣ) (hu:Ѥu=k) (hk:k+1<=j+8) (hj:j+8<=n):Ѥu< n:=by omega lemma fNw (inW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m:ὦ) (j:Ὣ) (base:ὦ) (out:ѐ) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (hj:j+8<=ѧb) (hs:ѧb<2^32): fN8 inW relu X W b i (bOf b) nf a hx lo (spOf lo) m j base out s0 s1 s2 s3 s4 s5 s6 s7=fw8 inW relu X W b i nf a hx lo m j base out s0 s1 s2 s3 s4 s5 s6 s7:=by have hj32:j+8<2^32:=Nat.lt_of_le_of_lt hj hs have e0:(ѩj).toNat=j:=qAd _ (lt8 j 0 (by decide) hj32) obtain ⟨e1,e2,e3,-⟩:=qFk e0 (lt8 j 3 (by decide) hj32) have f0:((j+4).toUSize).toNat=j+4:=qAd _ (lt8 j 4 (by decide) hj32) obtain ⟨f1,f2,f3,-⟩:=qFk f0 (lt8 j 7 (by decide) hj32) unfold fN8 fw8 simp only[fLU inW relu X W b i j _ nf a hx lo (ѩj) m e0 (fb _ _ j _ e0 (lk8 j 0 (by decide)) hj) hs,fLU inW relu X W b i (j+1) _ nf a hx lo (ѩj+1) m e1 (fb _ _ j _ e1 (lk8 j 1 (by decide)) hj) hs, fLU inW relu X W b i (j+2) _ nf a hx lo (ѩj+2) m e2 (fb _ _ j _ e2 (lk8 j 2 (by decide)) hj) hs,fLU inW relu X W b i (j+3) _ nf a hx lo (ѩj+3) m e3 (fb _ _ j _ e3 (lk8 j 3 (by decide)) hj) hs, fLU inW relu X W b i (j+4) _ nf a hx lo ((j+4).toUSize) m f0 (fb _ _ j _ f0 (lk8 j 4 (by decide)) hj) hs,fLU inW relu X W b i (j+4+1) _ nf a hx lo ((j+4).toUSize+1) m f1 (fb _ _ j _ f1 (lk8 j 5 (by decide)) hj) hs, fLU inW relu X W b i (j+4+2) _ nf a hx lo ((j+4).toUSize+2) m f2 (fb _ _ j _ f2 (lk8 j 6 (by decide)) hj) hs,fLU inW relu X W b i (j+4+3) _ nf a hx lo ((j+4).toUSize+3) m f3 (fb _ _ j _ f3 (lk8 j 7 (by decide)) hj) hs] lemma rowB (u m:ὦ) (k outW:Ὣ) (W:ѐ) (hu:Ѥu=k) (hk:k+1<=outW) (hW:outW*Ѥm<=ѧW) (hs:ѧW<2^32):Ѥ(u*m)+Ѥm<=ѧW:=by have h1:(k+1)*Ѥm<=outW*Ѥm:=Nat.mul_le_mul_right _ hk rw[Nat.succ_mul] at h1 have h2:Ѥ(u*m)=k*Ѥm:=by rw[qWm _ _ (by rw[hu];omega),hu] omega lemma lk (j c outW:Ὣ) (hc:c+1<=8) (hj:j+8<=outW):j+c+1<=outW:=by omega lemma tG0 (j outW m W:Ὣ) (hj:j+8<=outW) (hOW:outW*m<=W) (hW:W<=4294967295) (hm:0< m):j+8<2^32:=by have:=Nat.le_mul_of_pos_right outW hm;omega lemma tileG (j outW:Ὣ) (m n:ὦ) (x wb:ὤ) (ix W:ѐ) (hj:j+8<=outW) (hx:Ѥn<=Ѩx) (hix:Ѥn<=ѧix) (hW:ѧW<=4294967295) (hOW:outW*Ѥm<=ѧW) (hwb:Ѩwb<=4294967295) (hnm:Ѥn<=Ѥm) (hp:Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb) (hm:0<Ѥm): Ѥn<=Ѩx∧Ѥn<=ѧix∧ѧW<=4294967295∧Ѥ(ѩj*m)+Ѥm<=ѧW∧Ѥ((ѩj+1)*m)+Ѥm<=ѧW∧Ѥ((ѩj+2)*m)+Ѥm<=ѧW∧Ѥ((ѩj+3)*m)+Ѥm<=ѧW∧ Ѥ((j+4).toUSize*m)+Ѥm<=ѧW∧Ѥ(((j+4).toUSize+1)*m)+Ѥm<=ѧW∧Ѥ(((j+4).toUSize+2)*m)+Ѥm<=ѧW∧Ѥ(((j+4).toUSize+3)*m)+Ѥm<=ѧW∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb:=by have hs:ѧW<2^32:=Nat.lt_of_le_of_lt hW (by decide) have hj32:=tG0 j outW (Ѥm) (ѧW) hj hOW hW hm have e0:(ѩj).toNat=j:=qAd _ (lt8 j 0 (by decide) hj32) obtain ⟨e1,e2,e3,-⟩:=qFk e0 (lt8 j 3 (by decide) hj32) have f0:((j+4).toUSize).toNat=j+4:=qAd _ (lt8 j 4 (by decide) hj32) obtain ⟨f1,f2,f3,-⟩:=qFk f0 (lt8 j 7 (by decide) hj32) exact ⟨hx,hix,hW,rowB _ m j outW W e0 (lk j 0 outW (by decide) hj) hOW hs,rowB _ m (j+1) outW W e1 (lk j 1 outW (by decide) hj) hOW hs,rowB _ m (j+2) outW W e2 (lk j 2 outW (by decide) hj) hOW hs, rowB _ m (j+3) outW W e3 (lk j 3 outW (by decide) hj) hOW hs,rowB _ m (j+4) outW W f0 (lk j 4 outW (by decide) hj) hOW hs,rowB _ m (j+4+1) outW W f1 (lk j 5 outW (by decide) hj) hOW hs, rowB _ m (j+4+2) outW W f2 (lk j 6 outW (by decide) hj) hOW hs,rowB _ m (j+4+3) outW W f3 (lk j 7 outW (by decide) hj) hOW hs,hwb,hnm,hp⟩ theorem cN2W (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (base:ὦ) (hob:outW<=ѧb) (hs:ѧb<2^32) (hix:Ѥn<=ѧix) (hW:ѧW<=4294967295) (hOW:outW*Ѥm<=ѧW) (hm:0<Ѥm) : ∀ (d j:Ὣ) (out:ѐ),outW-j=d → colsN2 inW outW relu X W b i ix x wd wb (bOf b) nf a hx lo (spOf lo) m n j base out=cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n j base out:=by intro d;induction d using Nat.strong_induction_on with | _ d ih=> intro j out hd rw[colsN2];by_cases h16:j+16<=outW . rw[Ἄ h16];dsimp only by_cases hg:Ѥn<=Ѩx∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb∧Ѥ((j+8).toUSize*m)+5+8*Ѥm<=Ѩwb . rw[Ἄ hg,fNw _ _ _ _ _ _ _ _ _ _ _ j _ _ _ _ _ _ _ _ _ _ (by omega) hs,fNw _ _ _ _ _ _ _ _ _ _ _ (j+8) _ _ _ _ _ _ _ _ _ _ (by omega) hs] rw[g16V];dsimp only[g16of,fw8] rw[cols1V,Ἄ (by omega:j+8<=outW)];dsimp only;rw[Ἄ (tileG j outW m n x wb ix W (by omega) hg.1 hix hW hOW hg.2.1 hg.2.2.1 hg.2.2.2.1 hm)] rw[cols1V,Ἄ (by omega:j+8+8<=outW)];dsimp only;rw[Ἄ (tileG (j+8) outW m n x wb ix W (by omega) hg.1 hix hW hOW hg.2.1 hg.2.2.1 hg.2.2.2.2 hm)] exact ih _ (by omega) _ _ rfl . rw[ἔ hg] . rw[ἔ h16] theorem cN3W (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (i:Ὣ) (ix:ѐ) (x wd wb:ὤ) (nf a:ὧ) (hx:ὥ) (lo:Ὠ) (m n:ὦ) (base:ὦ) (hob:outW<=ѧb) (hs:ѧb<2^32) (hix:Ѥn<=ѧix) (hW:ѧW<=4294967295) (hOW:outW*Ѥm<=ѧW) (hm:0<Ѥm) : ∀ (d j:Ὣ) (out:ѐ),outW-j=d → colsN3 inW outW relu X W b i ix x wd wb (bOf b) nf a hx lo (spOf lo) m n j base out=cols1V inW outW relu X W b i ix x wd wb nf a hx lo m n j base out:=by intro d;induction d using Nat.strong_induction_on with | _ d ih=> intro j out hd rw[colsN3];by_cases h24:j+24<=outW . rw[Ἄ h24];dsimp only by_cases hg:Ѥn<=Ѩx∧Ѩwb<=4294967295∧Ѥn<=Ѥm∧Ѥ(ѩj*m)+5+8*Ѥm<=Ѩwb∧Ѥ((j+8).toUSize*m)+5+8*Ѥm<=Ѩwb∧Ѥ((j+8+8).toUSize*m)+5+8*Ѥm<=Ѩwb . rw[Ἄ hg,fNw _ _ _ _ _ _ _ _ _ _ _ j _ _ _ _ _ _ _ _ _ _ (by omega) hs,fNw _ _ _ _ _ _ _ _ _ _ _ (j+8) _ _ _ _ _ _ _ _ _ _ (by omega) hs,fNw _ _ _ _ _ _ _ _ _ _ _ (j+8+8) _ _ _ _ _ _ _ _ _ _ (by omega) hs] rw[g24V];dsimp only[g24of,fw8] rw[cols1V,Ἄ (by omega:j+8<=outW)];dsimp only;rw[Ἄ (tileG j outW m n x wb ix W (by omega) hg.1 hix hW hOW hg.2.1 hg.2.2.1 hg.2.2.2.1 hm)] rw[cols1V,Ἄ (by omega:j+8+8<=outW)];dsimp only;rw[Ἄ (tileG (j+8) outW m n x wb ix W (by omega) hg.1 hix hW hOW hg.2.1 hg.2.2.1 hg.2.2.2.2.1 hm)] rw[cols1V,Ἄ (by omega:j+8+8+8<=outW)];dsimp only;rw[Ἄ (tileG (j+8+8) outW m n x wb ix W (by omega) hg.1 hix hW hOW hg.2.1 hg.2.2.1 hg.2.2.2.2.2 hm)] exact ih _ (by omega) _ _ rfl . rw[ἔ hg];exact cN2W inW outW relu X W b i ix x wd wb nf a hx lo m n base hob hs hix hW hOW hm _ j out rfl . rw[ἔ h24];exact cN2W inW outW relu X W b i ix x wd wb nf a hx lo m n base hob hs hix hW hOW hm _ j out rfl theorem dVE (X:ѐ) (o n t:ὦ) (buf:ὤ) (l:ὧ) (lo hi:ὥ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (hb:Ѥn<=Ѩbuf): (decV X o n t buf l lo hi hX hs hb).buf=(decE X o n t buf l hX hs hb).buf∧(decV X o n t buf l lo hi hX hs hb).l=(decE X o n t buf l hX hs hb).l:=by rw[decV,decE];by_cases h:t< n . rw[Ἄ h,Ἄ h];dsimp only;exact dVE X o n (t+1) _ _ _ _ hX hs _ . rw[ἔ h,ἔ h];exact ⟨rfl,rfl⟩ termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];have:=А.mp h;(clear h; omega) theorem dEok (X:ѐ) (o n t:ὦ) (buf:ὤ) (l:ὧ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (hb:Ѥn<=Ѩbuf):(decE X o n t buf l hX hs hb).ok=true:=by rw[decE];by_cases h:t< n . rw[Ἄ h];dsimp only;exact dEok X o n (t+1) _ _ hX hs _ . rw[ἔ h] termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];have:=А.mp h;(clear h; omega) theorem dVS (X:ѐ) (o n N:ὦ) (hNn:N=n) (ho:o=0) (hN:Ѥn<=ѧX) (hN':ѤN<=ѧX) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (t:ὦ) (buf:ὤ) (l:ὧ) (lo hi:ὥ) (hb:Ѥn<=Ѩbuf): scan X N t hN' lo hi=(if 0x007FFFFF<=(decV X o n t buf l lo hi hX hs hb).lo∧(decV X o n t buf l lo hi hX hs hb).hi<У then (decV X o n t buf l lo hi hX hs hb).hi else Е):=by rw[scan,decV];by_cases h:t< n . have h':t< N:=hNn ▸ h rw[Ἄ h',Ἄ h];dsimp only have e:o+t=t:=by rw[ho,USize.zero_add] simp only[e] exact dVS X o n N hNn ho hN hN' hX hs (t+1) _ _ _ _ _ . have h':¬ t< N:=hNn ▸ h rw[ἔ h',ἔ h] termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];have:=А.mp h;(clear h; omega) lemma ltUne (x:ὥ) (h:x<У):x≠Е:=by intro e;rw[e] at h;exact absurd h (by decide) section variable {n:ℕ} {ts:List ℕ} {g:ℕ->ὧ} {p:ℕ->ℝ} {bw hh:ὥ} {X Y J:ℝ} {s t a e:ὧ} (A:n<2^20) (B:ѣts<=n) (C:A_G ts g p) (D:good bw=true) (E:X=(ts.map p).sum+wv bw) (F:s=ts.foldl (λ(c:ὧ) t=>c+g t) 0+dv bw) (G:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) include A B C D E F G end section variable (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) include n hn xw ww end section variable {R I O:Ὣ} {X W b:ё} section variable (G:C_G R I O X W b) (Y:Ὡ) {i j:Ὣ} (hi:i< R) (hj:j< O) include G Y i j hi hj end end section variable {Rr I O:Ὣ} {X W b:ё} end section variable {R I O:Ὣ} {X W b:ё} section variable (G:C_G R I O X W b) include G end end theorem linNe (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ):linN inW outW relu X W b=linF0 1 inW outW relu X W b:=by unfold linN linNc;rw[(wnGet inW outW W b).2];dsimp only;rw[show fz0=(0:ὧ) from rfl] split . rename_i hh split . rename_i hz split . rename_i hc obtain ⟨h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13,h14⟩:=hh have hs:ѧX<2^32:=by omega have en:X.usize=ѩinW:=by rw[Array.usize];congr 1;omega have hsc:scan X X.usize 0 (qAc X) Е 0≠Е:=by rw[dVS X _ _ X.usize en (by rw[Nat.zero_mul];rfl) (by have:=hz.1;omega) (qAc X) hz.1 hs 0 (zFor inW) 0 Е 0 hz.2.1] rw[ἱ hc];exact ltUne _ hc.2 have hS:scanH 0 X≠Е:=by unfold scanH;simp only[show ((0:Ὣ)==1)=false by decide,Bool.false_eq_true,ite_false,beq_self_eq_true,ite_true];exact hsc unfold linF0;rw[(wbGet inW outW W).2];dsimp only have hG:1*inW=ѧX∧outW*inW=ѧW∧outW=ѧb∧0< inW∧0< outW∧inW<2^20∧ѧX<=4294967295∧ѧW<=4294967295∧ѧb<=4294967295∧1*outW<=4294967295∧scanH 0 X≠Е∧scanW 1 W≠Е∧scanH 1 b≠Е:=⟨h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,hS,h11,h12⟩ rw[ἱ hG] simp only[show ((1:Ὣ)==1)=true by decide, Bool.false_eq_true, ite_true] rw[ἱ h13] have hdF:decF X (0*inW).toUSize (ѩinW) (zFor inW) 0=decE X (0*inW).toUSize (ѩinW) 0 (zFor inW) 0 hz.1 hs hz.2.1:=by unfold decF;rw[Ἄ ⟨hz.1,h7,hz.2.1,hz.2.2.1⟩] rw[hdF,dEok,←(dVE X _ _ 0 (zFor inW) 0 Е 0 hz.1 hs hz.2.1).1,←(dVE X _ _ 0 (zFor inW) 0 Е 0 hz.1 hs hz.2.1).2] rw[ἱ (show (true && decide (inW<=8192))=true by simp[h14])] have hix:Ѥ(ѩinW)<=ѧidA:=by rw[qIs,qAd _ (by omega)];omega have hOW:outW*Ѥ(ѩinW)<=ѧW:=by rw[qAd _ (by omega)];omega have hm0:0<Ѥ(ѩinW):=by rw[qAd _ (by omega)];omega (try split);(all_goals first|rw[cN3W inW outW relu X W b 0 idA _ (ἆ 0) _ _ _ _ _ _ _ _ (by omega) (by omega) hix h8 hOW hm0 _ 0 _ rfl,c1VS']|rw[cN2W inW outW relu X W b 0 idA _ (ἆ 0) _ _ _ _ _ _ _ _ (by omega) (by omega) hix h8 hOW hm0 _ 0 _ rfl,c1VS']|rw[cNV inW outW relu X W b 0 idA _ (ἆ 0) _ _ _ _ _ _ _ _ (by omega) (by omega) _ 0 _ rfl,c1VS']|rw[cN3V inW outW relu X W b 0 idA _ (ἆ 0) _ _ _ _ _ _ _ _ (by omega) (by omega) _ 0 _ rfl,c1VS']|rw[cN2V inW outW relu X W b 0 idA _ (ἆ 0) _ _ _ _ _ _ _ _ (by omega) (by omega) _ 0 _ rfl,c1VS']) . rfl . rfl . rfl lemma qEr:linF=linearSpec:=by funext rows inW outW relu X W b;unfold linF;split . rename_i h;have e:rows=1:=by simpa using h subst e;rw[linNe,qEr0] . rw[qEr0] lemma qDz:linF=linearSpec:=qEr @[inline] def sm (w:ὥ):Ὡ:=good w && (w &&& В)<=0x70FFFFFF section open Float.Model Float.Model.UnpackedFloat set_option maxRecDepth 8192 in end section open Float.Model Float.Model.UnpackedFloat end section lemma qGm (S:Ὡ) (ex fr m:Ὣ) (q:Int) (h1:897<=ex) (h2:ex<1151) (h3:fr<2^23) (hm:m≠0) (hW1:(m:ℝ)*2^q<(2^53+fr*2^30+2^29)*2^((ex:Int)-1076)) (hW2:fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)<(m:ℝ)*2^q) (hW3:(2^53-2^28)*2^((ex:Int)-1076)<(m:ℝ)*2^q) : toWord (ἕ Fmt ⟨S,m,q⟩) =UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr):=by have hE:(2:ℝ)^((ex:Int)-1046)=2^30*2^((ex:Int)-1076):=by rw[<-Ἡ,<-Ἓ ἓ] congr 1;(clear h1 h2 h3 hm; exact omS335) rw[qE4 S m q (2^23+fr) ((ex:Int)-1046) hm (by clear h1 h2 hm; exact omS125) (by clear h1 h2 hm; exact omS126 h3) (by clear h3 hm; exact omS127 h1) (by clear h3 hm; exact omS128 h2) (by rw[hE];push_cast;linarith only [hW1]) (λ_=>by rw[hE];push_cast;linarith [hW2 (by clear h1 h2 h3 hm; omega)]) (λ_=>by rw[hE];linarith only [hW3]),show ((ex:Int)-1046+150).toNat=ex-896 by (clear h3 hm; exact omS130),show (2^23+fr)%2^23=fr by (clear h1 h2 hm; exact omS131 h3)] lemma qFt (a b:ℝ) (ha:0<=a) (h:a< b) : ∃ (m:Ὣ) (q:Int),m≠0∧a<(m:ℝ)*2^q∧(m:ℝ)*2^q<=b:=by obtain ⟨k,hk⟩:=exists_pow_lt_of_lt_one (sub_pos.2 h) one_half_lt_one;have h2:(0:ℝ)<2^k:=by positivity rw[one_div_pow,div_lt_iff₀ h2] at hk;refine ⟨⌊b*2^k⌋₊,-k,?_⟩;rw[zpow_neg,Ἡ,<-div_eq_mul_inv,lt_div_iff₀ h2,div_le_iff₀ h2];have h1:=Nat.lt_floor_add_one (b*2^k);have h5:a*2^k<⌊b*2^k⌋₊ :=(by linarith only [hk, h1]);exact ⟨(Nat.cast_pos.1 ((Ἆ ha h2.le).trans_lt h5)).ne',h5,Nat.floor_le (Ἆ (ha.trans h.le) h2.le)⟩ lemma qGz (z:Model Fmt):ofW (toWord z)=z:=qEb z lemma qIm (w:ὥ) (h0:expOf w≠0) (h1:expOf w≠255):wv w≠0:=by have:sv w≠0:=by unfold sv mantOf;split<;>simp[]<;>(clear h0 h1; omega) simp[qAx w h1,rationalWord,decodeD_toRat,this,zpow_ne_zero] lemma qDqW (S:Ὡ) (ex fr:Ὣ) (h1:897<=ex) (h2:ex<1151) (h3:fr<2^23) (V W:ℝ) (hV:V=if S then -W else W) (hW1:W<(2^53+fr*2^30+2^29)*2^((ex:Int)-1076)) (hW2:fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)< W) (hW3:(2^53-2^28)*2^((ex:Int)-1076)< W) (M:Model Fmt) (hf:Ἑ M=true) (hM:Ἢ M=Model.roundAt Fmt V):toWord M=UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr):=by have e2zw:(if S then 2^31 else 0)+(ex-896)*2^23+fr<2^32 ∧ ((if S then 2^31 else 0)+(ex-896)*2^23+fr)/2^23%2^8=ex-896:=by constructor<;>split<;>omega have hb0:(0:ℝ)<2^((ex:Int)-1076):=ἵ (by positivity) _;have hA2:(0:ℝ)<=(2^53-2^28)*2^((ex:Int)-1076) :=Ἆ (by positivity) hb0.le obtain ⟨Lo,hLo0,hLoW,hLo1,hLo2⟩:∃ Lo:ℝ,0<=Lo∧Lo< W ∧ (fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)<=Lo) ∧ (2^53-2^28)*2^((ex:Int)-1076)<=Lo:=by by_cases hfr:fr=0;. exact ⟨_,hA2,hW3,λh=>absurd hfr h,le_rfl⟩ . have hfr1:(1:ℝ)<=fr:=by exact_mod_cast Nat.one_le_iff_ne_zero.mpr hfr refine ⟨_,?_,hW2 hfr,λ_=>le_rfl,?_⟩;. exact Ἆ (sub_nonneg.mpr ((pow_le_pow_right₀ one_le_two (Nat.le_of_ble_eq_true rfl:29<=53)).trans (le_add_of_nonneg_right (by positivity)))) hb0.le . exact ἀ (by linarith only [hfr1]) hb0.le have hW0:0< W:=ἷ hLo0 hLoW;obtain ⟨m1,q1,hm1,hd1,hd1'⟩:=qFt Lo W hLo0 hLoW;set B:ℝ:=(2^53+fr*2^30+2^29)*2^((ex:Int)-1076) with hB;obtain ⟨m2,q2,hm2,hd2,hd2'⟩:=qFt W ((W+B)/2) hW0.le (left_lt_add_div_two.mpr hW1);have w1:=qGm S ex fr m1 q1 h1 h2 h3 hm1 (hd1'.trans_lt (left_lt_add_div_two.mp (hd2.trans_le hd2'))) (λh=>ἷ (hLo1 h) hd1) (ἷ hLo2 hd1) have w2:=qGm S ex fr m2 q2 h1 h2 h3 hm2 (hd2'.trans_lt (add_div_two_lt_right.mpr (left_lt_add_div_two.mp (hd2.trans_le hd2')))) (λh=>by exact ἷ (hLo1 h) ((hd1.trans_le hd1').trans hd2)) (ἷ hLo2 ((hd1.trans_le hd1').trans hd2)) set z:=UInt32.ofNat ((if S then 2^31 else 0)+(ex-896)*2^23+fr) with hzd;have hzn:ѥz=(if S then 2^31 else 0)+(ex-896)*2^23+fr:=by rw[hzd,ὡ,Ἁ];exact e2zw.1 have hexp:(expOf z).toNat=ex-896:=by rw[qCa,hzn];exact e2zw.2 have he0:expOf z≠0:=λh=>by rw[h] at hexp;exact absurd (Nat.sub_eq_zero_iff_le.mp hexp.symm) (Nat.not_le.mpr h1) have he1:expOf z≠255:=λh=>by rw[h] at hexp;exact absurd ((Nat.sub_eq_iff_eq_add (Nat.le_of_succ_le h1)).mp hexp.symm) (Nat.ne_of_lt h2) have r1:ἕ Fmt ⟨S,m1,q1⟩=ofW z:=by rw[<-w1,qGz] have r2:ἕ Fmt ⟨S,m2,q2⟩=ofW z:=by rw[<-w2,qGz] have fz:Ἑ (ofW z)=true:=by simp[ofW,isFinite_ofUInt32,he1] have t1:=Model.toReal_roundDyadic_eq_roundAt Fmt (by decide) ⟨S,m1,q1⟩ (by rw[r1];exact fz);have t2:=Model.toReal_roundDyadic_eq_roundAt Fmt (by decide) ⟨S,m2,q2⟩ (by rw[r2];exact fz);rw[r1] at t1;rw[r2] at t2 have hv:Ἢ (ofW z)=Model.roundAt Fmt V:=by apply le_antisymm . cases S;. rw[t1];apply Model.roundAt_mono;simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,hV];linarith only [hd1'] . rw[t2];apply Model.roundAt_mono;simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,hV];linarith only [hd2] . cases S;. rw[t2];apply Model.roundAt_mono;simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,hV];linarith only [hd2] . rw[t1];apply Model.roundAt_mono;simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,hV];linarith only [hd1'] have hnz:Ἢ M≠0:=by rw[hM,<-hv];exact qIm z he0 he1 have:=Model.eq_of_toReal_eq_of_nonzero (hM.trans hv.symm) hnz;rw[this];have hr:toWord (ofW z)=z:=by rw[<-r1,w1] exact hr set_option maxRecDepth 8192 in lemma qDq (s e:ὧ) (V:ℝ) (hlo:R (s-e)< V) (hhi:V< R (s+e)) (h:ziv s e≠Е) (M:Model Fmt) (hf:Ἑ M=true) (hM:Ἢ M=Model.roundAt Fmt V):toWord M=ziv s e:=by obtain ⟨S,ex,fr,W,h1,h2,h3,hz,hV,hW1,hW2,hW3⟩:=qB8 s e V hlo hhi h;rw[hz];exact qDqW S ex fr h1 h2 h3 V W hV hW1 hW2 hW3 M hf hM lemma qIx:(2:ℝ)^(127:ℤ)<=Ἢ (Model.posMaxFinite Fmt):=by rw[Model.toReal_posMaxFinite,show Model.pow2 Fmt.fracWidth+Fmt.maxFiniteFracField=2^24-1 by decide +kernel,show Fmt.maxNormalExponent-Int.ofNat Fmt.fracWidth=104 by decide +kernel,Model.bpow,qA0];(norm_num1) lemma qFn (q:ℚ) : Model.signedScaledRatToReal (decide (q<0)) q.num.natAbs q.den 0=(q:ℝ):=by rw[Model.signedScaledRatToReal,Model.scaledRatToReal,Nat.cast_natAbs,Rat.cast_def];by_cases hq:q<0;. simp[hq,abs_of_neg (Rat.num_neg.2 hq)];ring . simp[hq,abs_of_nonneg (Rat.num_nonneg.2 (not_lt.1 hq))] lemma qH7 (s e:ὧ) (q:ℚ) (hlo:R (s-e)<(q:ℝ)) (hhi:(q:ℝ)< R (s+e)) (h:ziv s e≠Е) (hb : |(q:ℝ)| ≤ 2^(127:ℤ)):roundRational q=ziv s e:=by have hf:=Model.isFinite_roundRatScaled_of_abs_le_posMaxFinite Fmt (decide (q<0)) q.num.natAbs q.den 0 (by decide) q.den_nz (qFn q ▸ hb.trans qIx);have hM:=Model.toReal_roundRatScaled_eq_roundAt Fmt _ _ _ 0 (by decide) hf;exact qDq s e q hlo hhi h _ hf (qFn q ▸ hM) lemma qH4 (N d:Ὣ) (x:Int) (hr:sqrtLower N d≠0) (hd:0< d) (hs:x<=(FloatFormat.toModel Fmt).targetExponent (Float.Model.totalExponent (sqrtLower N d) x)) (hb:ἧ ((N:ℝ)/d)*FloatLib.Floats.Formats.Flocq.bpow ἲ x < 2^(127:ℤ)) : Ἑ (Model.ofModel Fmt (Float.Model.UnpackedFloat.roundWithAccuracy (FloatFormat.toModel Fmt) .positive (sqrtLower N d) x (sqrtAccuracy N d)))=true := Model.isFinite_ofModel_roundWithAccuracy_of_lt_bpow Fmt rfl .positive _ _ _ (ἧ ((N:ℝ)/d)) (sqrtAccuracy_correct N d hd) hs (hb.trans_eq (qA0 127).symm) lemma qIp (q:ℚ) (hq:0< q) (hb:ἧ (q:ℝ)<2^(127:ℤ)) : Ἑ (sqrtModel q)=true := qH4 _ _ _ (ne_of_gt (sqrtRoot_pos q hq)) q.pos (sqrtStep_le_target q) (by rwa [sqrtScale_correct q hq]) lemma qGs (s e:ὧ) (q:ℚ) (hq:0< q) (hlo:R (s-e)< ἧ (q:ℝ)) (hhi:ἧ (q:ℝ)< R (s+e)) (h:ziv s e≠Е) (hb:ἧ (q:ℝ)<2^(127:ℤ)):sqrtRational q=ziv s e:=by have hf:=qIp q hq hb;exact (ἐ (not_le.2 hq)).trans (qDq s e _ hlo hhi h _ hf (sqrtModel_correct q hq hf)) lemma qA1 (w:ὥ) (h:sm w=true):good w=true∧|wv w| ≤ 2^99:=by obtain ⟨hg,hl⟩:=ὕ.1 h;have h1:=ἃ.1 (of_decide_eq_true hl);rw[qAq] at h1;have h2:=qAz w hg;rw[qB5 w hg];refine ⟨hg,(qA6 _ _ h1 (by clear h1; exact omS336 h2)).trans ?_⟩;unfold A_mag;norm_num set_option maxRecDepth 8192 in end section section open Float.Model Float.Model.UnpackedFloat end end @[specialize] def fC {σ:Type} (f:σ->ὦ->ὦ->Ὢ) (s:σ) (b j:ὦ) (o:ё):Ὣ->ё | 0=>o | k+1=>fC f s b (j+1) (wrW o (b+j) (f s (b+j) j)) k @[specialize] def fR {σ:Type} (h:Ὣ->σ) (f:σ->ὦ->ὦ->Ὢ) (n r:Ὣ) (o:ё):Ὣ->ё | 0=>o | k+1=>fR h f n (r+1) (fC f (h r) (r*n).toUSize 0 o n) k def lnSum (x:ё) (base n i:ὦ) (s t:ὧ):F1 := if h:i< n then let v:=dv (rdW x (base+i)) lnSum x base n (i+1) (s+v) (t+v.abs) else ⟨s,t⟩ partial_fixpoint def lnVar (x:ё) (base n i:ὦ) (m v:ὧ):ὧ := if h:i< n then let d:=dv (rdW x (base+i))-m lnVar x base n (i+1) m (v+d*d) else v partial_fixpoint @[inline] def invOK (a b:ὧ):Ὡ := decide ((a.toBits >>> 52)-1<1222) && decide ((((a*b-Ἃ 0x3FF0000000000000)+Ἃ 0x3CD0000000000000).toBits >>> 52)-972<2) @[inline] def lnQ (b:Ὡ) (n:Ὣ) (x:ё) (r:Ὣ):ℚ:=if b then 0 else rowMean n x r @[inline] def lnStat (b:Ὡ) (n:Ὣ) (eps:Ὢ) (x:ё) (r:Ὣ):LnS := let base:=(r*n).toUSize let nu:=ѩn let nd:=n.toUInt64.toFloat let nf:=(n.toUInt64+8).toFloat*Ἃ ь let ind:=1.0/nd let a:=if b then F1.mk 0 0 else lnSum x base nu 0 0 0 let m:=if b then 0 else a.s*ind let v:=lnVar x base nu 0 m 0 let em:=(nf*a.t)*ind+Ἃ ظ let tt:=v*ind+dv eps let d:=Ἤ tt let z:=ziv d ((nf+nf)*d+em) let ir:=1.0/dv z if sm z && decide ((0x1F800000:ὥ)<=z) && decide (z<=(0x70FFFFFF:ὥ)) && decide ((tt.toBits >>> 52)-1<1222) && invOK ind nd && invOK ir (dv z) then ⟨true,m,ir,em,z⟩ else ⟨false,0,0,0,sqrtRational (rowVariance n x r (lnQ b n x r)+ἂ eps)⟩ def meanI (n:Ὣ) (x:ё) (r:Ὣ):ℤ:= (ἄ n).foldl (λt j=>t+sv x[r*n+j]!*((2^idxOf x[r*n+j]!:ℕ):ℤ)) 0 def meanQ (n:Ὣ) (x:ё) (r:Ὣ):ℚ:=(meanI n x r:ℚ)/((2^149*n:ℕ):ℚ) @[noinline] def lnSlow (x g b den:Ὢ) (mean:Unit->ℚ):Ὢ := roundRational ((ἂ x-mean ())*ἂ g/ἂ den+ἂ b) @[inline] def lnFa (m ir em:ὧ) (den w gw bw:Ὢ) (gv bv:ὧ) (lo:Ὠ) (mean:Unit->ℚ):Ὢ := let gd:=gv*ir let q:=(dv w-m)*gd let t:=fin1 lo (spOf lo) (q+bv) if t == Е then let r:=ziv (q+bv) (Ἃ 0x3D10000000000000*(q.abs+bv.abs)+em*gd.abs) if 0x7EFFFFFF<(r &&& В) then lnSlow w gw bw den mean else r else t @[inline] def lnFb (m ir em:ὧ) (den:Ὢ) (x g b:ё) (p j:ὦ) (gv bv:ὧ) (lo sp:Ὠ) (mean:Unit->ℚ):Ὢ := let w:=rdW x p let gd:=gv*ir let q:=(dv w-m)*gd let t:=fin1 lo sp (q+bv) if t == Е then let r:=ziv (q+bv) (Ἃ 0x3D10000000000000*(q.abs+bv.abs)+em*gd.abs) if 0x7EFFFFFF<(r &&& В) then lnSlow w (rdW g j) (rdW b j) den mean else r else t @[inline] def lnFc (m ir em:ὧ) (den w:Ὢ) (g:ё) (j:ὦ) (gv:ὧ) (lo sp:Ὠ):Ὢ := let gd:=gv*ir let q:=(dv w-m)*gd let t:=fin1 lo sp (q+dv 0) if t == Е then let r:=ziv (q+dv 0) (Ἃ 0x3D10000000000000*(q.abs+(dv 0).abs)+em*gd.abs) if 0x7EFFFFFF<(r &&& В) then lnSlow w (rdW g j) 0 den (λ_=>0) else r else t @[inline] def lnOutF (s:LnS) (lo:Ὠ) (w gw bw:Ὢ) (gv bv:ὧ) (mean:Unit->ℚ):Ὢ := if s.fast then lnFa s.m s.ir s.em s.den w gw bw gv bv lo mean else lnSlow w gw bw s.den mean @[inline] def lnOut (s:LnS) (lo:Ὠ) (w gw bw:Ὢ) (mean:Unit->ℚ):Ὢ :=lnOutF s lo w gw bw (dv gw) (dv bw) mean @[inline] def lnEB (s:LnS) (xm gm bm:ὧ):ὧ := Ἃ 0x3D10000000000000*((xm+s.m.abs)*(gm*s.ir)+bm)+s.em*(gm*s.ir) @[inline] def rdF (a:ὤ) (i:ὦ):ὧ:= if h:i< a.usize then a.uget i (qDo a i h) else 0 def decG (A:ё) (n t:ὦ) (o:ὤ):ὤ := if h:t< n then decG A n (t+1) (wrF o t (dv (rdW A t))) else o partial_fixpoint @[inline] def gdF (r:Ὣ) (g:ё) (n:Ὣ):ὤ:= if r == 1 then ἆ 0 else decG g ѩn 0 (zFor n) @[inline] def gdR (r:Ὣ) (g:ё) (G:ὤ) (j:ὦ):ὧ:= if r == 1 then dv (rdW g j) else rdF G j @[inline] def smA (A:ё):Ὡ:= let h:=scan A A.usize 0 (qAc A) Е 0 h != Е && decide (h<=0x70FFFFFF) @[inline] def normOK (rows n:Ὣ) (eps:Ὢ) (x g:ё):Ὡ:= decide (0< rows) && decide (0< n) && ѧx == rows*n && ѧg == n && decide (n<2^20) && decide (rows*n<=4294967295) && smA x && smA g && sm eps && !signOf eps && decide (0< mantOf eps) def lnRF (x g b:ё) (G B:ὤ) (m ir em:ὧ) (den:Ὢ) (mean:Unit->ℚ) (lo sp:Ὠ) (base n j:ὦ) (o:ё):ё := if h:j< n then lnRF x g b G B m ir em den mean lo sp base n (j+1) (wrW o (base+j) (lnFb m ir em den x g b (base+j) j (rdF G j) (rdF B j) lo sp mean)) else o partial_fixpoint def lnRS (x g b:ё) (den:Ὢ) (mean:Unit->ℚ) (base n j:ὦ) (o:ё):ё := if h:j< n then lnRS x g b den mean base n (j+1) (wrW o (base+j) (lnSlow (rdW x (base+j)) (rdW g j) (rdW b j) den mean)) else o partial_fixpoint @[noinline] def lnSlowM (w gw bw den:Ὢ) (nN:Ὣ) (x:ё) (rR:Ὣ):Ὢ :=lnSlow w gw bw den (λ_=>meanQ nN x rR) @[noinline] def lnRSM (x g b:ё) (den:Ὢ) (nN rR:Ὣ) (base n j:ὦ) (o:ё):ё :=lnRS x g b den (λ_=>meanQ nN x rR) base n j o @[noinline] def lnRFM (x g b:ё) (G B:ὤ) (m ir em:ὧ) (den:Ὢ) (nN rR:Ὣ) (lo sp:Ὠ) (base n j:ὦ) (o:ё):ё :=lnRF x g b G B m ir em den (λ_=>meanQ nN x rR) lo sp base n j o def lnRows (x g b:ё) (G B:ὤ) (eps:Ὢ) (xm gm bm:ὧ) (n r:Ὣ) (o:ё):Ὣ->ё | 0=>o | d+1=> let s:=lnStat false n eps x r lnRows x g b G B eps xm gm bm n (r+1) (if s.fast then lnRF x g b G B s.m s.ir s.em s.den (λ_=>meanQ n x r) (loOf (lnEB s xm gm bm)) (spOf (loOf (lnEB s xm gm bm))) (r*n).toUSize ѩn 0 o else lnRS x g b s.den (λ_=>meanQ n x r) (r*n).toUSize ѩn 0 o) d def lnDecB (x:ё) (base n j:ὦ) (buf:ὤ) (t s:ὧ):ὤ := if h:j< n then let v:=dv (rdW x (base+j)) lnDecB x base n (j+1) (wrF buf j v) (t+v.abs) (s+v) else wrF (wrF buf n t) (n+1) s partial_fixpoint lemma lnDecB_size (x:ё) (base n:ὦ) (k:Ὣ) : ∀ (j:ὦ) (buf:ὤ) (t s:ὧ),Ѥj+k=Ѥn → (lnDecB x base n j buf t s).size=Ѩbuf:=by induction k with | zero=> intro j buf t s e rw[lnDecB,ἔ (by rw[А];omega),qD6,qD6] | succ k ih=> intro j buf t s e have hj:j< n:=А.2 (by omega) rw[lnDecB,Ἄ hj];dsimp only;rw[ih (j+1) _ _ _ (by rw[usz j n hj];omega),qD6] lemma lnDecB_sz0 (x:ё) (base:ὦ) (n:Ὣ) (buf:ὤ) : (lnDecB x base ѩn 0 buf 0 0).size=Ѩbuf:=lnDecB_size x base ѩn (Ѥ(ѩn)) 0 buf 0 0 (by simp) lemma uS1 (n:ὦ) (h:Ѥn+1<2^32):Ѥ(n+1)=Ѥn+1:=by rw[qAf n 1 (by rw[ὄ];exact h),ὄ] def lnDecI (x:ё) (base n j:ὦ) (buf:ὤ) (t s:ὧ) (hx:Ѥbase+Ѥn<=ѧx) (hs:Ѥbase+Ѥn<2^32):ὤ := if h:j< n then let v:=dv (x.uget (base+j) (by rw[qAf base j (by have:=А.mp h;omega)];have:=А.mp h;omega)) lnDecI x base n (j+1) (wrF buf j v) (t+v.abs) (s+v) hx hs else wrF (wrF buf n t) (n+1) s partial_fixpoint lemma lnDecI_eq (x:ё) (base n:ὦ) (hx:Ѥbase+Ѥn<=ѧx) (hs:Ѥbase+Ѥn<2^32) (hxs:ѧx<2^32) (k:Ὣ) : ∀ (j:ὦ) (buf:ὤ) (t s:ὧ),Ѥj+k=Ѥn → lnDecI x base n j buf t s hx hs=lnDecB x base n j buf t s:=by induction k with | zero=> intro j buf t s e rw[lnDecI,lnDecB,ἔ (by rw[А];omega),ἔ (by rw[А];omega)] | succ k ih=> intro j buf t s e have hj:j< n:=А.2 (by omega) rw[lnDecI,lnDecB,Ἄ hj,Ἄ hj] dsimp only rw[ih (j+1) _ _ _ (by rw[usz j n hj];omega)] simp only[aU x hxs] @[inline] def lnDecC (x:ё) (base n:ὦ) (buf:ὤ):ὤ := if h:Ѥbase+Ѥn<=ѧx∧ѧx<=4294967295 then lnDecI x base n 0 buf 0 0 h.1 (by omega) else lnDecB x base n 0 buf 0 0 lemma lnDecC_eq (x:ё) (base n:ὦ) (buf:ὤ):lnDecC x base n buf=lnDecB x base n 0 buf 0 0:=by unfold lnDecC;split . rename_i h;exact lnDecI_eq x base n h.1 (by omega) (by omega) (Ѥn) 0 buf 0 0 (by simp) . rfl lemma lnDecC_sz0 (x:ё) (base:ὦ) (n:Ὣ) (buf:ὤ):(lnDecC x base ѩn buf).size=Ѩbuf:=by rw[lnDecC_eq];exact lnDecB_sz0 x base n buf def lnVarB (buf:ὤ) (n j:ὦ) (m v:ὧ) (hb:Ѥn<=Ѩbuf):ὧ := if h:j< n then let d:=buf.uget j (by have:=А.mp h;omega)-m lnVarB buf n (j+1) m (v+d*d) hb else v partial_fixpoint def oneF:ὧ:=1.0 @[inline] def lnStatB (n:Ὣ) (eps:Ὢ) (x:ё) (r:Ὣ) (ind:ὧ) (okI:Ὡ) (buf:ὤ) (hb:n+2<=Ѩbuf) (hbs:Ѩbuf<2^32):LnS := let nu:=ѩn let nf:=(n.toUInt64+8).toFloat*Ἃ ь let s:=buf.uget (ѩ(n+1)) (by rw[qAd (n+1) (by omega)];omega) let t:=buf.uget nu (by rw[qAd n (by omega)];omega) let m:=s*ind let v:=lnVarB buf nu 0 m 0 (by rw[qAd n (by omega)];omega) let em:=(nf*t)*ind+Ἃ ظ let tt:=v*ind+dv eps let d:=Ἤ tt let z:=ziv d ((nf+nf)*d+em) let ir:=oneF/dv z if sm z && decide ((0x1F800000:ὥ)<=z) && decide (z<=(0x70FFFFFF:ὥ)) && decide ((tt.toBits >>> 52)-1<1222) && okI && invOK ir (dv z) then ⟨true,m,ir,em,z⟩ else ⟨false,0,0,0,sqrtRational (rowVariance n x r (lnQ false n x r)+ἂ eps)⟩ @[inline] def lnFvM (m ir em:ὧ) (den w:Ὢ) (v:ὧ) (g b:ё) (j:ὦ) (gv bv:ὧ) (lo sp:Ὠ) (nN:Ὣ) (x:ё) (rR:Ὣ):Ὢ := let gd:=gv*ir let q:=(v-m)*gd let t:=fin1 lo sp (q+bv) if t == Е then let r:=ziv (q+bv) (Ἃ 0x3D10000000000000*(q.abs+bv.abs)+em*gd.abs) if 0x7EFFFFFF<(r &&& В) then lnSlowM w (rdW g j) (rdW b j) den nN x rR else r else t def lnRB (x g b:ё) (buf G B:ὤ) (m ir em:ὧ) (den:Ὢ) (nN rR:Ὣ) (lo sp:Ὠ) (base n j:ὦ) (o:ё) (hb:Ѥn<=Ѩbuf) (hG:Ѥn<=ѨG) (hB:Ѥn<=ѨB):ё := if h:j< n then lnRB x g b buf G B m ir em den nN rR lo sp base n (j+1) (wrW o (base+j) (lnFvM m ir em den (rdW x (base+j)) (buf.uget j (by have:=А.mp h;omega)) g b j (G.uget j (by have:=А.mp h;omega)) (B.uget j (by have:=А.mp h;omega)) lo sp nN x rR)) hb hG hB else o partial_fixpoint def lnRowsB (x g b:ё) (G B:ὤ) (eps:Ὢ) (xm gm bm:ὧ) (n:Ὣ) (ind:ὧ) (okI:Ὡ) (r:Ὣ) (buf:ὤ) (o:ё):Ὣ->ё | 0=>o | d+1=> if h:n+2<=Ѩbuf∧Ѩbuf<=4294967295∧n<=ѨG∧ѨG<=4294967295∧n<=ѨB∧ѨB<=4294967295∧r*n+n<=ѧx∧ѧx<=4294967295 then let base:=(r*n).toUSize let bf:=lnDecC x base ѩn buf let s:=lnStatB n eps x r ind okI bf (by rw[lnDecC_sz0];omega) (by rw[lnDecC_sz0];omega) lnRowsB x g b G B eps xm gm bm n ind okI (r+1) bf (if s.fast then lnRB x g b bf G B s.m s.ir s.em s.den n r (loOf (lnEB s xm gm bm)) (spOf (loOf (lnEB s xm gm bm))) base ѩn 0 o (by rw[lnDecC_sz0,qAd n (by omega)];omega) (by rw[qAd n (by omega)];omega) (by rw[qAd n (by omega)];omega) else lnRSM x g b s.den n r base ѩn 0 o) d else let s:=lnStat false n eps x r lnRowsB x g b G B eps xm gm bm n ind okI (r+1) buf (if s.fast then lnRFM x g b G B s.m s.ir s.em s.den n r (loOf (lnEB s xm gm bm)) (spOf (loOf (lnEB s xm gm bm))) (r*n).toUSize ѩn 0 o else lnRSM x g b s.den n r (r*n).toUSize ѩn 0 o) d def rmsRF (rows:Ὣ) (x g:ё) (G:ὤ) (m ir em:ὧ) (den:Ὢ) (lo sp:Ὠ) (base n j:ὦ) (o:ё):ё := if h:j< n then let w:=rdW x (base+j) rmsRF rows x g G m ir em den lo sp base n (j+1) (wrW o (base+j) (if w &&& В == 0 then 0 else lnFc m ir em den w g j (gdR rows g G j) lo sp)) else o partial_fixpoint def rmsRows (rows:Ὣ) (x g:ё) (G:ὤ) (eps:Ὢ) (xm gm:ὧ) (n r:Ὣ) (o:ё):Ὣ->ё | 0=>o | d+1=> let s:=lnStat true n eps x r rmsRows rows x g G eps xm gm n (r+1) (if s.fast then rmsRF rows x g G s.m s.ir s.em s.den (loOf (lnEB s xm gm (dv 0))) (spOf (loOf (lnEB s xm gm (dv 0)))) (r*n).toUSize ѩn 0 o else fC (λs p j=>let w:=rdW x p if w &&& В == 0 then 0 else lnOutF s.1 s.2 w (rdW g j) 0 (gdR rows g G j) (dv 0) λ_=>0) (s,loOf (lnEB s xm gm (dv 0))) (r*n).toUSize 0 o n) d @[inline] def okX (h:ὥ):Ὡ:=h != Е && decide (h<=0x70FFFFFF) @[inline] def normOK2 (rows n:Ὣ) (eps:Ὢ) (x g:ё) (hx hg:ὥ):Ὡ:= decide (0< rows) && decide (0< n) && ѧx == rows*n && ѧg == n && decide (n<2^20) && decide (rows*n<=4294967295) && okX hx && okX hg && sm eps && !signOf eps && decide (0< mantOf eps) abbrev LNV (n:Ὣ) (g b:ё):=({p:(ὤ×ὤ)×(ὥ×ὥ)//p=((decG g ѩn 0 (zFor n),decG b ѩn 0 (zFor n)),(scan g g.usize 0 (qAc g) Е 0,scan b b.usize 0 (qAc b) Е 0))}) structure LNE where (g b:ё) (n:Ὣ) (p:(ὤ×ὤ)×(ὥ×ὥ)) (k:ὦ) (ok:p=((decG g ѩn 0 (zFor n),decG b ѩn 0 (zFor n)),(scan g g.usize 0 (qAc g) Е 0,scan b b.usize 0 (qAc b) Е 0))) def lnFd (n:Ὣ) (g b:ё) (k:ὦ) (s:Array LNE) (i:Ὣ):Option (LNV n g b):= if h:i< s.size then if s[i].k==k then if ho:s[i].n=n then if hk:withPtrEq s[i].g g (λ_=>s[i].g==g) (λe=>by rw[e];exact beq_self_eq_true g) then if hk2:withPtrEq s[i].b b (λ_=>s[i].b==b) (λe=>by rw[e];exact beq_self_eq_true b) then some ⟨s[i].p,by rw[←ho,←eq_of_beq hk,←eq_of_beq hk2];exact s[i].ok⟩ else lnFd n g b k s (i+1) else lnFd n g b k s (i+1) else lnFd n g b k s (i+1) else lnFd n g b k s (i+1) else none partial_fixpoint @[noinline] def lnS:ST.Ref Unit (Array LNE):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def lnGet (n:Ὣ) (g b:ё):LNV n g b:= withPtrAddr g (λk=> let s:=(ST.Prim.Ref.get lnS (Void.mk ())).val match lnFd n g b k s 0 with | some v=>v | none=> let p:=((decG g ѩn 0 (zFor n),decG b ѩn 0 (zFor n)),(scan g g.usize 0 (qAc g) Е 0,scan b b.usize 0 (qAc b) Е 0)) let old:=(ST.Prim.Ref.swap lnS (#[⟨g,b,n,p,k,rfl⟩]++(if s.size<256 then s else s.pop)) (Void.mk ())).val match lnFd n g b k old 0 with | some v=>v | none=>⟨p,rfl⟩) (λ_ _=>Subsingleton.elim _ _) abbrev RNV (g:ё):=({h:ὥ//h=scan g g.usize 0 (qAc g) Е 0}) structure RNE where (g:ё) (h:ὥ) (k:ὦ) (ok:h=scan g g.usize 0 (qAc g) Е 0) def rnFd (g:ё) (k:ὦ) (s:Array RNE) (i:Ὣ):Option (RNV g):= if h:i< s.size then if s[i].k==k then if hk:withPtrEq s[i].g g (λ_=>s[i].g==g) (λe=>by rw[e];exact beq_self_eq_true g) then some ⟨s[i].h,by rw[←eq_of_beq hk];exact s[i].ok⟩ else rnFd g k s (i+1) else rnFd g k s (i+1) else none partial_fixpoint @[noinline] def rnS:ST.Ref Unit (Array RNE):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def rnGet (g:ё):RNV g:= withPtrAddr g (λk=> let s:=(ST.Prim.Ref.get rnS (Void.mk ())).val match rnFd g k s 0 with | some v=>v | none=> let h:=scan g g.usize 0 (qAc g) Е 0 let old:=(ST.Prim.Ref.swap rnS (#[⟨g,h,k,rfl⟩]++(if s.size<256 then s else s.pop)) (Void.mk ())).val match rnFd g k old 0 with | some v=>v | none=>⟨h,rfl⟩) (λ_ _=>Subsingleton.elim _ _) def lnFq (rows n:Ὣ) (eps:Ὢ) (x g b:ё) (hx:ὥ) (c:(ὤ×ὤ)×(ὥ×ὥ)):ё := if normOK2 rows n eps x g hx c.2.1 && ѧb == n && okX c.2.2 then let nd:=n.toUInt64.toFloat let ind:=oneF/nd lnRowsB x g b c.1.1 c.1.2 eps (dv hx) (dv c.2.1) (dv c.2.2) n ind (invOK ind nd) 0 (zFor (n+2)) (ἇ (rows*n) 0) rows else layernormSpec rows n eps x g b def lnFz (rows n:Ὣ) (eps:Ὢ) (x g b:ё) (hx hg hb:ὥ):ё := if normOK2 rows n eps x g hx hg && ѧb == n && okX hb then let nd:=n.toUInt64.toFloat let ind:=oneF/nd lnRowsB x g b (decG g ѩn 0 (zFor n)) (decG b ѩn 0 (zFor n)) eps (dv hx) (dv hg) (dv hb) n ind (invOK ind nd) 0 (zFor (n+2)) (ἇ (rows*n) 0) rows else layernormSpec rows n eps x g b def lnF (rows n:Ὣ) (eps:Ὢ) (x g b:ё):ё :=lnFq rows n eps x g b (scan x x.usize 0 (qAc x) Е 0) (lnGet n g b).1 def rmsFz (rows n:Ὣ) (eps:Ὢ) (x g:ё) (hx hg:ὥ):ё := if normOK2 rows n eps x g hx hg then rmsRows rows x g (gdF rows g n) eps (dv hx) (dv hg) n 0 (ἇ (rows*n) 0) rows else rmsnormSpec rows n eps x g def rmsF (rows n:Ὣ) (eps:Ὢ) (x g:ё):ё :=rmsFz rows n eps x g (scan x x.usize 0 (qAc x) Е 0) (rnGet g).1 section lemma qFv (x:Ὠ):(x >>> 52).toNat=Ѧx/2^52:=by rw[ἰ,Ἱ];rfl lemma qEj (x k N:Ὠ) (h:x-k< N) (hN:Ѧk+ѦN<2^64) : Ѧk<=Ѧx∧Ѧx< Ѧk+ѦN:=by have h1:=ἴ.mp h;rw[UInt64.toNat_sub] at h1;have h2:=x.toNat_lt;have h3:=k.toNat_lt;(clear h; omega) lemma qEi (a b:ℤ) (n:ℕ) (h:a=n+b):(2:ℝ)^a=2^n*2^b:=by rw[h,Ἓ ἓ,Ἡ] lemma qCz {f:ὧ} {E:Ὣ} (h:(f.toBits >>> 52).toNat=E) (hE1:1<=E) (hE:E<2047) : f.isFinite=true∧(2:ℝ)^((E:ℤ)-1023)<=R f∧R f<2^((E:ℤ)-1022):=by rw[qFv] at h;obtain ⟨F,hF,hM⟩:∃ F<2^52,f.toBits.toNat=E*2^52+F :=⟨f.toBits.toNat%2^52,by (clear hE1 hE; exact omS337),by (clear hE1 hE; exact omS338 h)⟩;obtain ⟨h1,h2⟩:=B_R f false E F hE1 hE hF (by simpa using hM);have hb:(0:ℝ)<2^((E:ℤ)-1075):=ἵ (by positivity) _;have hF0:(0:ℝ)<=F:=Ἔ _;have hF2:(F:ℝ)<2^52:=by exact_mod_cast hF simp only[Bool.false_eq_true,ite_false,one_mul] at h2;push_cast at h2;rw[h2,qEi ((E:ℤ)-1023) (E-1075) 52 (by clear h hE1 hE hF hM; exact omS339),qEi ((E:ℤ)-1022) (E-1075) 53 (by clear h hE1 hE hF hM; exact omS340)];exact ⟨h1,ἀ (by linarith only [hF]) hb.le,Ἦ (by linarith only [hF2]) hb⟩ lemma L_k (c:Ὠ) (E n:Ὣ) (hE1:1<=E) (hn:E+n=1023) (h:(Ἃ c).toBits.toNat=E*2^52) : (Ἃ c).isFinite=true∧R (Ἃ c)=1/2^n:=by obtain ⟨h1,h2⟩:=B_R (Ἃ c) false E 0 hE1 (by clear h; exact omS341 hn) ב (by simpa using h);refine ⟨h1,?_⟩;rw[h2,show (E:ℤ)-1075=-(52+(n:ℤ)) by (clear hE1 h; exact omS342 hn),zpow_neg,Ἓ ἓ];norm_num;field_simp lemma qGk {f:ὧ} {E:Ὣ} (h:(f.toBits >>> 52).toNat=E) (hE1:1<=E) (hE:E<2047) : (Ἤ f).isFinite=true∧0< R f ∧ |R (Ἤ f)-ἧ (R f)| ≤ 1/2^53*(ἧ (R f)+A_z):=by obtain ⟨hf,hl,-⟩:=qCz h hE1 hE have hp:0< R f:=Ἥ (ἵ (by positivity) _) hl rw[qFv] at h have hs:Model.signBit (toModel (ofFloat f : Binary64))=false:=by rw[qFs];simp only[decide_eq_false_iff_not,not_le];exact omS343 h hE have hm:toModel (ofFloat f : Binary64)=A_M f:=toModel_ofFloat f have hfm:Ἑ (A_M f)=true:=by rw[qAh,hf] rw[hm] at hs have hr:=Model.toReal_sqrt_eq_roundAt (A_M f) (by decide) hfm (Or.inr hs) have hq:=Model.isFinite_sqrt_of_isFinite (A_M f) (by decide) hfm (Or.inr hs) have hd:A_M (Ἤ f)=Model.canonicalizeModel (Model.sqrt (A_M f)):=by have h3:=toModel_ofFloat_sqrt f rw[hm,toModel_ofFloat] at h3 exact h3 have ht:Model.toModel (A_M (Ἤ f))=Model.toModel (Model.sqrt (A_M f)):=by rw[hd,Model.toModel_canonicalizeModel] have hR:R (Ἤ f)=Model.roundAt FloatFormat.binary64 (ἧ (R f)):=by rw[A_R,ἦ qAj,ht,<-ἦ qAj] exact hr refine ⟨?_,hp,?_⟩ . rw[<-qAh,qAy,ht,<-qAy];exact hq . rw[hR];have:=qFp (ἧ (R f));rwa [ἅ (Real.sqrt_nonneg _)] at this lemma qAa (x y:ℝ) : |x| ≤ |y| + |x-y|:=by have:=abs_sub_abs_le_abs_sub x y;linarith only [this] lemma qAt {k:ℝ} (h:k<=2^256*2^44):k<=A_B :=h.trans_eq ((qEi 300 44 256 rfl).trans (by norm_num1)).symm lemma qBg (a:ѐ) (p:ὥ->Ὡ) (h:a.all p=true) (i:ℕ) (hi:i< ѧa) : p a[i]! = true:=by rw[Ἕ a i hi];simpa using Array.all_eq_true.1 h i hi lemma qE6 (w:ὥ) (g:good w=true) (h:w &&& В=0):ἂ w=0:=by exact_mod_cast (qAx w (qAe _ g)).symm.trans (qBr w g h) lemma qIu (s e:ὧ) (V:ℝ) (hlo:R (s-e)< V) (hhi:V< R (s+e)) (h0:ziv s e≠Е) (h:¬ (0x7EFFFFFF:ὥ)<(ziv s e &&& В)) : |V| ≤ 2^(127:ℤ):=by obtain ⟨S,ex,fr,W,h1,h2,h3,hz,hV,hW1,-,hW3⟩:=qB8 s e V hlo hhi h0 have hb:(0:ℝ)<2^((ex:Int)-1076):=ἵ (by positivity) _ have hW0:0< W:=lt_trans (mul_pos (by positivity) hb) hW3 have hN:((if S then 2^31 else 0)+(ex-896)*2^23+fr)<2^32:=by split<;>(clear h0 h hz; omega) have hex:ex<=1149:=by by_contra hc apply h apply ἳ.mpr rw[qAq,hz,UInt32.toNat_ofNat_of_lt' hN,((by clear h0 h h3 hz hN; exact omS344 h2 hc):ex=1150)] show 2130706431< _ split<;>(clear h0 h h1 h2 hz hN hc; omega) have hF:(fr:ℝ)+1<=2^23:=by exact_mod_cast ((by clear h0 h h1 h2 hz hN hex; (exact Nat.succ_le_of_lt ‹_›)):fr+1<=2^23) rw[hV] have hW:W<=2^54*2^(73:ℤ):=hW1.le.trans (ἑ (by linarith only [hF]) (ἒ (by norm_num1) (by clear h0 h h3 hz hN; exact omS345 hex)) hb.le (by positivity)) rw[<-qEi 127 73 54 rfl] at hW split<;>simp only[abs_neg,abs_of_pos hW0,hW] lemma L_I {n I:ℝ} (hn:1<=n) (h3:0< I) (h4 : |I*n-1| ≤ 1/2^48):I<=2:=by have:=ἁ hn h3.le;linarith [(abs_le.mp h4).2] lemma qF0 (n I v t Sb E T:ℝ) (h3:0< I) (h4 : |I*n-1| ≤ 1/2^48) (ht : |t| ≤ Sb) (hv : |v-n*t| ≤ n*E+T) (hE:0<=E) : |v*I-t| ≤ E*(1+1/2^48)+T*I+Sb*(1/2^48):=by have a1 : |(v-n*t)*I| ≤ (n*E+T)*I:=by rw[ἢ,ἡ h3];exact ἀ hv h3.le have a2:=ἁ (abs_le.mp h4).2 hE have a3 : |t*(I*n-1)| ≤ Sb*(1/2^48):=by rw[ἢ];exact ἑ ht h4 (Ἀ _) ((Ἀ _).trans ht) have a4:=Ἐ ((v-n*t)*I) (t*(I*n-1)) rw[show (v-n*t)*I+t*(I*n-1)=v*I-t by ring] at a4 linarith only [a4, a3, a2, a1] section variable {z:ℝ} (hz0:0<=z) (hz:z<=1/2^200*(1/2^200)) include hz0 hz lemma qD9 {P rp rs rc:ℝ} (h1 : |rp-P| ≤ 1/2^53*(|P| + z)) (h2 : |rs-(rp-1)| ≤ 1/2^53*(|rp-1| + z)) (h3 : |rc-(rs+1/2^50)| ≤ 1/2^53*(|rs+1/2^50| + z)) (lo:1/2^51<=rc) (hi:rc<=1/2^49) : |P-1| ≤ 1/2^48:=by have sck:∀ {k a b:ℝ},0(le_div_iff₀' hk).mp (h.trans_eq (one_div_mul_eq_div _ _)) have hz1:z<=1:=hz.trans (by norm_num1) have lo':1 ≤ 2^51*rc:=(div_le_iff₀' (by norm_num1)).mp lo;have hi':2^49*rc ≤ 1:=(le_div_iff₀' (by norm_num1)).mp hi have a1:=qAa (rs+1/2^50) rc;rw[ἣ (rs+1/2^50) rc] at a1;have a2 : |rc| = rc:=ἅ (ὂ (by norm_num1) lo) generalize hq:(1:ℝ)/2^50=q at h3 a1;have hq':(2:ℝ)^50*q=1:=by rw[<-hq];exact mul_one_div_cancel (by norm_num1) have h1':=sck (by norm_num1) h1;have h2':=sck (by norm_num1) h2;have h3':=sck (by norm_num1) h3 have c1:=neg_abs_le (rc-(rs+q));have c2:=le_abs_self (rc-(rs+q)) have a3:2^49*|rs| ≤ 1:=by rw[<-abs_of_pos (by norm_num1:(0:ℝ)<2^49),<-ἢ];exact abs_le.mpr ⟨by linarith only [c1, c2, a1, a2, h3', lo', hi', hq', hz1, hz0],by linarith only [c1, c2, a1, a2, h3', lo', hi', hq', hz1, hz0]⟩ have b1:=qAa (rp-1) rs;rw[ἣ (rp-1) rs] at b1;have b2:2^50*|rp-1| ≤ 3:=by linarith only [b1, a3, h2', hz1, hz0] have c3:=qAa (P-1) (rp-1);rw[sub_sub_sub_cancel_right,ἣ P rp] at c3;have c4:=qAa P 1;rw[abs_one] at c4 exact (le_div_iff₀' (by norm_num1)).mpr (by linarith only [c3, c4, b2, h1', hz1, hz0]) lemma qG0 {a Mr Rm Em g D b I RA Rg Rq RY RE Rsa Rcs Reg Hi Lo:ℝ} (hE0:0<=Em) (hE1:Em<=2^120) (hM:2 * |Mr-Rm| ≤ Em) (hD:1/2^64<=D) (ha : |a| ≤ 2^99) (hg : |g| ≤ 2^99) (hm : |Rm| ≤ 2^110) (h1 : |RA-(a-Rm)| ≤ 1/2^53*(|a-Rm| + z)) (h2 : |I*D-1| ≤ 1/2^48) (h3 : |Rg-g*I| ≤ 1/2^53*(|g*I| + z)) (h4 : |Rq-RA*Rg| ≤ 1/2^53*(|RA*Rg| + z)) (h5 : |RY-(Rq+b)| ≤ 1/2^53*(|Rq+b| + z)) (h6 : |Rsa-(|Rq| + |b|)| ≤ 1/2^53*(|(|Rq| + |b|)| + z)) (h7 : |Rcs-1/2^46*Rsa| ≤ 1/2^53*(|1/2^46*Rsa| + z)) (h8 : |Reg-Em*(|Rg|)| ≤ 1/2^53*(|Em*(|Rg|)| + z)) (h9 : |RE-(Rcs+Reg)| ≤ 1/2^53*(|Rcs+Reg| + z)) (h10 : |Hi-(RY+RE)| ≤ 1/2^53*(|RY+RE| + z)) (h11 : |Lo-(RY-RE)| ≤ 1/2^53*(|RY-RE| + z)) (hbig:1/2^127 ≤ |Hi|) : Lo<(a-Mr)*g/D+b∧(a-Mr)*g/D+b< Hi:=by have sck:∀ {k a b:ℝ},0(le_div_iff₀' hk).mp (h.trans_eq (one_div_mul_eq_div _ _)) have scu:∀ {a b:ℝ},a ≤ 1/2^53*b → 2^53*a ≤ b:=sck (by norm_num1) have hDp:0< D:=Ἥ (div_pos one_pos (pow_pos two_pos 64)) hD rw[mul_div_assoc,<-sub_add_sub_cancel a Rm Mr,add_mul] have hGb : |g/D| ≤ 2^163:=by rw[abs_div,ἡ hDp,div_le_iff₀ hDp];exact hg.trans ((by norm_num1:(2:ℝ)^99=2^163*(1/2^64)).trans_le (ἁ hD (pow_nonneg zero_le_two 163))) have hXb : |a-Rm| ≤ 2^111:=(Ὕ _ _).trans ((add_le_add ha hm).trans (by norm_num1)) have hgI:2^48*|g*I-g/D| ≤ |g/D|:=by rw[show g*I-g/D=g/D*(I*D-1) by rw[mul_sub,mul_one,mul_comm I D,<-mul_assoc,div_mul_cancel₀ g hDp.ne'],ἢ,mul_left_comm];exact (ἁ (sck (by norm_num1) (h2.trans_eq (mul_one _).symm)) (Ἀ _)).trans_eq (mul_one _) generalize g/D=G at hGb hgI ⊢;generalize a-Rm=X at h1 hXb ⊢;generalize g*I=Y at h3 hgI;clear hDp hD ha hg hm h2 have rU:∀ {R x:ℝ},|R-x| ≤ 1/2^53*(|x| + z)->|R| ≤ 2*|x|+z:=fun {R x} h=>((qAa R x).trans (add_le_add le_rfl (h.trans (mul_le_of_le_one_left (add_nonneg (Ἀ x) hz0) (by norm_num1))))).trans_eq (by rw[<-add_assoc,two_mul]) have hz':(2:ℝ)^200*(2^200*z) ≤ 1:=(le_div_iff₀' (by norm_num1)).mp ((le_div_iff₀' (by norm_num1)).mp (hz.trans_eq (one_div_mul_eq_div _ _))) have hz1:z<=1:=hz.trans (by norm_num1) have S1:=scu h1;have S3:=scu h3;have S4:=scu h4;have S5:=scu h5;have S6:=scu h6;have S9:=scu h9;have S10:=scu h10;have S11:=scu h11 have nX:=Ἀ X;have nG:=Ἀ G;have nA:=Ἀ RA;have nR:=Ἀ Rg;have a1:=qAa X RA;rw[ἣ X RA] at a1 have a4:2^53*|RA-X| ≤ 2*|RA|+2*z:=by linarith only [a1, nX, S1, hz0] have a5 : |RA| ≤ 2^165:=((rU h1).trans (add_le_add (ἁ hXb zero_le_two) hz1)).trans (by norm_num1) have b1:=qAa Y G;have b2:=qAa G Rg;have b3:=abs_sub_le G Y Rg;rw[ἣ G Y,ἣ Y Rg] at b3 have b4:2^53*|G| ≤ (2^53+2^6)*|Rg|+2*z:=by linarith only [b3, b2, b1, nG, hgI, S3, hz0] have b5:2^53*|G-Rg| ≤ 2^6*|Rg|+2*z:=by linarith only [b3, b2, b1, nR, hgI, S3, hz0] have c1 : |Rg| ≤ 2^165:=by have:=qAa Rg G;rw[ἣ] at this;linarith only [this, b3, b1, hgI, S3, hGb, hz'] have f1:=Ἐ ((X-RA)*G) (RA*(G-Rg));rw[ἢ,ἢ,show (X-RA)*G+RA*(G-Rg)=X*G-RA*Rg by rw[sub_mul,mul_sub,sub_add_sub_cancel],ἣ X RA] at f1 have f2:=ἑ a4 b4 (Ἆ (by norm_num1) nG) (add_nonneg (Ἆ (by norm_num1) nA) (Ἆ (by norm_num1) hz0));have f3:=ἁ b5 nA have zr:z * |RA| ≤ z*2^165:=ἁ a5 hz0;have zg:z * |Rg| ≤ z*2^165:=ἁ c1 hz0;have zz:z*z<=z*2^165:=ἁ (hz1.trans (by norm_num1)) hz0;have ze:z*Em<=z*2^165:=ἁ (hE1.trans (by norm_num1)) hz0;have nP:=Ἆ nA nR have f4:2^230*|X*G-RA*Rg| ≤ 9*2^180*(|RA| * |Rg|)+1:=by linarith only [nP, zz, zg, zr, f3, f2, f1, hz'] have p1:2^53*|RA*Rg| ≤ (2^53+2)*|Rq|+2*z:=by have:=qAa (RA*Rg) Rq;rw[ἣ (RA*Rg) Rq] at this;have nq:=Ἀ (RA*Rg);linarith only [nq, this, S4, hz0] rw[<-ἢ] at f4;have q1:2^229*|X*G-Rq| ≤ 5*2^180*|Rq|+1:=by have:=Ὕ (X*G-RA*Rg) (Rq-RA*Rg);rw[sub_sub_sub_cancel_right] at this;have nq:=Ἀ Rq;linarith only [nq, this, p1, f4, S4, hz'] generalize hT:Em * |Rg| = T at h8;have nT:0<=T:=hT ▸ Ἆ hE0 nR have e1:2^230*|(Rm-Mr)*G| ≤ 5*2^227*T+1:=by rw[ἢ,ἣ];have h:=ἑ hM b4 (Ἆ (by norm_num1) nG) hE0;subst hT;linarith only [nT, h, ze, hz'] have s3:=rU h8;rw[ἅ nT] at h8 s3;have S8:=scu h8;have nq:=Ἀ Rq;have nb:=Ἀ b;have nS:0 ≤ |Rq| + |b| :=add_nonneg nq nb;have s1:=rU h6;rw[ἅ nS] at h6 s1 S6;have s0 : |Rq+b| ≤ |Rq| + |b|:=Ἐ _ _ generalize hV:(1:ℝ)/2^46*Rsa=V at h7;have hV':2^46*|V| = |Rsa|:=by rw[<-hV,ἢ,ἡ (div_pos one_pos (pow_pos two_pos 46):(0:ℝ)<1/2^46),<-mul_assoc,mul_one_div_cancel (by norm_num1),one_mul] have S7:=scu h7;have hV2:2^46*V=Rsa:=by rw[<-hV,<-mul_assoc,mul_one_div_cancel (by norm_num1),one_mul] have s2:2^44*|Rcs| ≤ (|Rq| + |b|)+2^44*z:=by have:=qAa Rcs V;linarith only [this, s1, nb, nq, S7, hV', hz0] have s4 : |RY| ≤ 2*(|Rq| + |b|)+z:=(rU h5).trans (add_le_add (ἁ s0 zero_le_two) le_rfl) have s5:=Ἐ Rcs Reg;have s6:2^43*|RE| ≤ (|Rq| + |b|)+2^45*T+2^45*z:=by have:=qAa RE (Rcs+Reg);linarith only [this, s5, s3, s2, nb, nq, nT, S9, hz0] have s7:=Ἐ RY RE;have s8:=Ὕ RY RE;have hb0:=qAa Hi (RY+RE) have hbig':1 ≤ 2^127*|Hi|:=(div_le_iff₀' (by norm_num1)).mp hbig have n9:=neg_abs_le (RE-(Rcs+Reg));have n8:=neg_abs_le (Reg-T);have n7:=neg_abs_le (Rcs-V);have n6:=neg_abs_le (Rsa-(|Rq|+|b|));have n10:=neg_abs_le (Hi-(RY+RE));have p10:=le_abs_self (Hi-(RY+RE));have n11:=neg_abs_le (Lo-(RY-RE));have p11:=le_abs_self (Lo-(RY-RE));have nq1:=neg_abs_le (X*G-Rq);have pq1:=le_abs_self (X*G-Rq);have ne1:=neg_abs_le ((Rm-Mr)*G);have pe1:=le_abs_self ((Rm-Mr)*G);have n5:=neg_abs_le (RY-(Rq+b));have p5:=le_abs_self (RY-(Rq+b)) have M:5*2^181*|Rq|+3+5*2^227*T+2^177*(|Rq+b|+z)+2^177*(|RY|+|RE|+z) < 2^230*RE:=by linarith only [S9, n9, S8, n8, S7, n7, hV', hV2, S6, n6, hb0, s7, S10, n10, hbig', s6, s5, s4, s3, s2, s1, s0, nb, nq, nT, hz', hz0] constructor . linarith only [S11, p11, s8, S5, n5, p5, q1, nq1, e1, ne1, M] . linarith only [S10, n10, s7, S5, n5, p5, q1, pq1, e1, pe1, M] lemma qG3 {n Rs Rt I Rm N Y Em c:ℝ} (r Sb:ℝ) (hn1:1<=n) (hn2:n<=2^20) (hc:c=(n+8)/2^49) (hr : |r| ≤ Sb) (hS:Sb<=2^99) (h1 : |Rs-n*r| ≤ 2*n*(1/2^53*(n*Sb+z))) (h2 : |Rt-n*Sb| ≤ 2*n*(1/2^53*(n*Sb+z))) (h3:0< I) (h4 : |I*n-1| ≤ 1/2^48) (h5 : |Rm-Rs*I| ≤ 1/2^53*(|Rs*I| + z)) (h6 : |N-c*Rt| ≤ 1/2^53*(|c*Rt| + z)) (h7 : |Y-N*I| ≤ 1/2^53*(|N*I| + z)) (h8 : |Em-(Y+1/2^200)| ≤ 1/2^53*(|Y+1/2^200| + z)) : 2 * |r-Rm| ≤ Em∧Em<=2^120∧1/2^201<=Em∧|Rm| ≤ 2^110:=by have scu:∀ {a b:ℝ},a ≤ 1/2^53*b → 2^53*a ≤ b:=fun h=>(le_div_iff₀' (by norm_num1)).mp (h.trans_eq (one_div_mul_eq_div _ _)) have hS0:0<=Sb:=ὂ (Ἀ _) hr;have n0:0<=n:=ὂ zero_le_one hn1;have nS:0<=n*Sb:=Ἆ n0 hS0;have nSb:n*Sb<=2^20*2^99:=ἑ hn2 hS hS0 (pow_nonneg zero_le_two 20);generalize hW:n*Sb+z=W at h1 h2;have nW:0<=W :=hW ▸ add_nonneg nS hz0;have hI2:=L_I hn1 h3 h4;generalize hE:201/100/2^53*W+Sb/2^48=E have hE':100*2^53*E=201*W+3200*Sb:=by rw[<-hE];ring have key:∀ v t:ℝ,|t| ≤ Sb->|v-n*t| ≤ 2*n*(1/2^53*W)->|v*I-t| ≤ E := λv t ht hv=>by have:=qF0 n I v t Sb (2*(1/2^53*W)) 0 h3 h4 ht (hv.trans_eq (((mul_assoc 2 n _).trans (mul_left_comm 2 n _)).trans (add_zero _).symm)) (Ἆ zero_le_two (Ἆ (by norm_num1) nW));linarith only [this, hE', nW] have hr1:=key Rs r hr h1;have hA1:=key Rt Sb (by rw[ἅ hS0]) h2;generalize hA:Rt*I=A at hA1 have hc0:0<=c:=hc ▸ div_nonneg (add_nonneg n0 (by norm_num1)) (by norm_num1) have hc':n+8=c*2^49:=(div_eq_iff (by norm_num1)).mp hc.symm have hc1:2^28*c<=1:=by linarith only [hc', hn2] have b0:=qAa A Sb;rw[ἅ hS0] at b0 have b1:2^53*|N*I-c*A| ≤ |c*A|+2*z:=by rw[<-hA,show N*I-c*(Rt*I)=(N-c*Rt)*I by rw[sub_mul,mul_assoc],ἢ,ἡ h3,show |c*(Rt*I)| = |c*Rt| * I by rw[<-mul_assoc,ἢ (c*Rt),ἡ h3]];have u1:=ἀ (scu h6) h3.le;have u2:=ἁ hI2 hz0;linarith only [u1, u2] have b2:2^28*|c*A| ≤ Sb+E:=by rw[ἢ,ἅ hc0,<-mul_assoc];exact (ἑ hc1 (b0.trans (add_le_add le_rfl hA1)) (Ἀ _) zero_le_one).trans_eq (one_mul _) have h9:2^28*|c*(A-Sb)| ≤ E:=by rw[ἢ,ἅ hc0,<-mul_assoc];exact (ἑ hc1 hA1 (Ἀ _) zero_le_one).trans_eq (one_mul _) have b4:(n+8)*Sb=c*2^49*Sb:=by rw[hc'] have c1:=qAa (N*I) (c*A);have c2:=qAa Y (N*I);have c3:=Ἐ Y (1/2^200);rw[ἡ (by norm_num1:(0:ℝ)<1/2^200)] at c3;generalize hq:(1:ℝ)/2^200=q at h8 c3;have hq':2^200*q=1:=by rw[<-hq];exact mul_one_div_cancel (by norm_num1) have d1:=qAa Rm (Rs*I);have d2:=qAa (Rs*I) r;have d3:=abs_sub_le r (Rs*I) Rm;rw[ἣ r (Rs*I),ἣ (Rs*I) Rm] at d3 have s5:=scu h5;have s7:=scu h7;have s8:=scu h8;have hz':(2:ℝ)^200*(2^200*z) ≤ 1:=(le_div_iff₀' (by norm_num1)).mp ((le_div_iff₀' (by norm_num1)).mp (hz.trans_eq (one_div_mul_eq_div _ _))) have g1:=le_abs_self (c*A);have n1:=neg_abs_le (N*I-c*A);have p1:=le_abs_self (N*I-c*A);have n7:=neg_abs_le (Y-N*I);have p7:=le_abs_self (Y-N*I);have n8:=neg_abs_le (Em-(Y+q));have p8:=le_abs_self (Em-(Y+q));have n9:=neg_abs_le (c*(A-Sb)) refine ⟨?_,?_,(div_le_iff₀' (by norm_num1)).mpr ?_,?_⟩ . linarith only [h9, n9, b2, hr1, s8, n8, s7, n7, b1, n1, d3, d2, c3, c2, c1, b4, nS, hS0, hr, hz', hq', hE', hW, s5] . linarith only [g1, b2, s8, p8, s7, p7, b1, p1, c3, c2, c1, nSb, hS, hz', hq', hE', hW] . linarith only [h9, n9, b2, s8, n8, s7, n7, b1, n1, c3, c2, c1, b4, nS, hS0, hz', hq', hE', hW] . linarith only [hr1, d2, d1, nSb, s5, hS, hr, hz', hW, hE'] lemma qHr {s c Em dd Rn2 Rmu ee hi lo:ℝ} (hs0:0<=s) (hs1:s<=2^101) (hc0:9/2^49<=c) (hc1:c<=1/2^20) (hE:1/2^201<=Em) (hE1:Em<=2^120) (h1 : |dd-s| ≤ 1/2^53*(s+z)) (h2 : |Rn2-(c+c)| ≤ 1/2^53*(|c+c| + z)) (h3 : |Rmu-Rn2*dd| ≤ 1/2^53*(|Rn2*dd| + z)) (h4 : |ee-(Rmu+Em)| ≤ 1/2^53*(|Rmu+Em| + z)) (h5 : |hi-(dd+ee)| ≤ 1/2^53*(|dd+ee| + z)) (h6 : |lo-(dd-ee)| ≤ 1/2^53*(|dd-ee| + z)) : s*(1+3/2*c)+9/10*Em<=hi∧lo<=s*(1-3/2*c)-9/10*Em:=by have sc:∀ {a b:ℝ},a ≤ 1/2^53*b → 2^53*a ≤ b:=fun h=>(le_div_iff₀' (by norm_num1)).mp (h.trans_eq (one_div_mul_eq_div _ _)) have hcp:0< c:=Ἥ (div_pos (Nat.ofNat_pos) (pow_pos two_pos 49)) hc0;have hcs:0<=c*s:=Ἆ hcp.le hs0;have hcs2:=ἀ ((div_le_iff₀' (by norm_num1:(0:ℝ)<2^49)).mp hc0) hs0;have hcc : |c+c| = c+c:=ἡ (add_pos hcp hcp);rw[hcc] at h2 have hz':(2^200*2^200:ℝ)*z<=1:=(le_div_iff₀' (mul_pos (pow_pos two_pos 200) (pow_pos two_pos 200))).mp (hz.trans_eq (one_div_mul_one_div _ _));have hE':=(div_le_iff₀' (by norm_num1:(0:ℝ)<2^201)).mp hE have h1':=sc h1;have d1:=(qAa dd s).trans (add_le_add (ἅ hs0).le le_rfl);have d2:=d1.trans (add_le_add le_rfl ((le_mul_of_one_le_left (Ἀ _) (by norm_num1)).trans h1')) have m1:=Ἐ ((Rn2-(c+c))*dd) ((c+c)*(dd-s));rw[ἢ,ἢ,hcc,show (Rn2-(c+c))*dd+(c+c)*(dd-s)=Rn2*dd-(c+c)*s by rw[sub_mul,mul_sub,sub_add_sub_cancel]] at m1;have m2:=ἑ (sc h2) d2 (Ἀ _) (add_nonneg (add_nonneg hcp.le hcp.le) hz0);have m3:=ἁ h1' (add_nonneg hcp.le hcp.le);have zs:=ἑ hz' hs1 hs0 zero_le_one;have zc:z*c<=z*1:=ἁ (hc1.trans (by norm_num1)) hz0;have zz:z*z<=z*1:=ἁ (hz.trans (by norm_num1)) hz0 have m4 : 2^230*|Rn2*dd-(c+c)*s| ≤ 2^181*(c*s)+1:=by linarith only [zs, zz, zc, m3, m2, m1, hcs, hz'] generalize Rn2*dd=M at h3 m4;rw[show (c+c)*s=2*(c*s) by rw[<-two_mul,mul_assoc]] at m4;have n1:=(qAa M (2*(c*s))).trans (add_le_add (ἅ (Ἆ zero_le_two hcs)).le le_rfl);have n2:=qAa Rmu M;have n3:=(Ἐ Rmu Em).trans (add_le_add le_rfl (ἡ (lt_of_lt_of_le (by norm_num1) hE)).le);have n4:=qAa ee (Rmu+Em) have Mg:10*2^53*(|dd-s|+|ee-(Rmu+Em)|+|Rmu-M|+|M-2*(c*s)|)+10*(|dd|+|ee|+z)<=2^53*(5*(c*s)+Em):=by linarith only [h1', sc h4, sc h3, m4, d1, n4, n3, n2, n1, hcs2, hcs, hE', hz', hz0, hs0] constructor . linarith only [neg_abs_le (hi-(dd+ee)), neg_abs_le (dd-s), neg_abs_le (ee-(Rmu+Em)), neg_abs_le (Rmu-M), neg_abs_le (M-2*(c*s)), (sc h5).trans (add_le_add (Ἐ dd ee) le_rfl), Mg] . linarith only [le_abs_self (lo-(dd-ee)), le_abs_self (dd-s), neg_abs_le (ee-(Rmu+Em)), neg_abs_le (Rmu-M), neg_abs_le (M-2*(c*s)), (sc h6).trans (add_le_add (Ὕ dd ee) le_rfl), Mg] lemma qIw {x Rd RQ:ℝ} (hx : |x| ≤ 2^111) (h1 : |Rd-x| ≤ 1/2^53*(|x| + z)) (h2 : |RQ-Rd*Rd| ≤ 1/2^53*(|Rd*Rd| + z)) : |RQ-x^2| ≤ 4/2^53*x^2+1/2^250:=by have sck:∀ {k a b:ℝ},0(le_div_iff₀' hk).mp (h.trans_eq (one_div_mul_eq_div _ _)) have nA:=Ἀ x have hz':(2:ℝ)^200*(2^200*z) ≤ 1:=(le_div_iff₀' (by norm_num1)).mp ((le_div_iff₀' (by norm_num1)).mp (hz.trans_eq (one_div_mul_eq_div _ _))) have zA:=ἑ hz' hx (Ἀ x) zero_le_one have zz:z*z<=z*1:=ἁ (hz.trans (by norm_num1)) hz0 have hsq : |x| ^ 2=x^2:=sq_abs x generalize he:Rd-x=e at h1 have h1':=sck (by norm_num1) h1;have h2':=sck (by norm_num1) h2 have q1:=Ἳ (Ἆ (by norm_num1) (Ἀ e)) h1' 2 have q3:2^53 * |2*x*e| ≤ 2 * |x| * (|x| + z):=by rw[ἢ,ἢ,abs_two,mul_left_comm] exact ἁ h1' (Ἆ zero_le_two nA) have q6 : |Rd*Rd-x^2| ≤ |2*x*e| + |e| ^ 2:=by rw[show Rd*Rd-x^2=2*x*e+e^2 by rw[<-he];ring,<-abs_pow] exact Ἐ _ _ have q8:=qAa (Rd*Rd) (x^2) rw[ἅ (ὅ x)] at q8 have q9:=qAa (RQ-x^2) (RQ-Rd*Rd) rw[show RQ-x^2-(RQ-Rd*Rd)=Rd*Rd-x^2 by ring] at q9 have nX:=ὅ x have G:2^250*|RQ-x^2| ≤ 2^199*x^2+1:=by linarith only [nX, q9, q8, q6, q3, q1, hsq, zz, zA, h2', hz', hz0, nA] exact ((le_div_iff₀' (by norm_num1)).mpr G).trans_eq (by ring) lemma qH9 {n Rv I Rp Rt ep c:ℝ} (Ws tau:ℝ) (hn1:1<=n) (hn2:n<=2^20) (hc:c=(n+8)/2^49) (hWs:0<=Ws) (hep:1/2^126<=ep) (ht0:0<=tau) (ht:tau<=1/2^229) (h1 : |Rv-n*Ws| ≤ (2*n+6)/2^53*(n*Ws)+tau) (h3:0< I) (h4 : |I*n-1| ≤ 1/2^48) (h5 : |Rp-Rv*I| ≤ 1/2^53*(|Rv*I| + z)) (h6 : |Rt-(Rp+ep)| ≤ 1/2^53*(|Rp+ep| + z)) : |Rt-(Ws+ep)| ≤ c/2*(Ws+ep):=by have hep0:0< ep:=Ἥ (by positivity) hep have hI2:=L_I hn1 h3 h4 have hX:0<=(2*n+6)/2^53*Ws:=Ἆ (by linarith only [hn1]) hWs have b1:=qF0 n I Rv Ws Ws _ tau h3 h4 (by rw[ἅ hWs]) (by linarith only [h1]) hX have a3:=ἁ hI2 ht0 have nnW:=Ἆ (by linarith only [hn1]:0<=n) hWs have nnE:=Ἆ (by linarith only [hn1]:0<=n) hep0.le have nnW2:=ἀ hn2 hWs have b2:=qAa (Rv*I) Ws rw[ἅ hWs] at b2 have b3:=Ἐ Rp ep rw[ἡ hep0] at b3 have b4:=qAa Rp (Rv*I) have b5:=Ἐ (Rt-(Rp+ep)) ((Rp-Rv*I)+(Rv*I-Ws)) have b6:=Ἐ (Rp-Rv*I) (Rv*I-Ws) rw[show Rt-(Rp+ep)+(Rp-Rv*I+(Rv*I-Ws))=Rt-(Ws+ep) by ring] at b5 rw[hc] linarith only [b6, b5, b4, b3, b2, nnE, a3, b1, hX, hep0, h6, h5, ht, hep, hWs, hz] lemma qG8 {n W Rv Sq Si:ℝ} (hn1:1<=n) (hn2:n<=2^20) (hW:0<=W) (h1 : |Rv-Sq| ≤ 2*n*(1/2^53*(Si+z))) (h2 : |Sq-W| ≤ 4/2^53*W+n*(1/2^250)) (h3:Si<=(1+4/2^53)*W+n*(1/2^250)) : |Rv-W| ≤ (2*n+6)/2^53*W+1/2^229:=by have hn0:0<=n :=(by linarith only [hn1]) have a1:=ἁ h3 hn0 have a3:=ἀ hn2 hW have a4:=ἑ hn2 hn2 hn0 (by positivity) have a5:=ἑ hn2 hz hz0 (by positivity) have a6:=abs_sub_le Rv Sq W linarith only [a6, a5, a4, a3, a1, h2, h1, hW, hn2] end lemma qHl {T s c Em lo hi:ℝ} (hT:0< T) (hs:0< s) (hc0:0< c) (hc1:c<=1/2^20) (hE:0<=Em) (h1:T<=s^2*(1+c)) (h2:s^2*(1-c)-Em^2/4<=T) (h3:s*(1+3/2*c)+9/10*Em<=hi) (h4:lo<=s*(1-3/2*c)-9/10*Em) : lo< ἧ T∧ἧ T< hi:=by have hsT:=Real.sqrt_pos.mpr hT;have hq:0< s^2*c:=mul_pos (pow_pos hs 2) hc0 have hc15:(0:ℝ)<=1+3/2*c:=(add_pos_of_pos_of_nonneg one_pos (Ἆ (by norm_num1) hc0.le)).le have h5:0< s*(1+3/2*c):=mul_pos hs (add_pos_of_pos_of_nonneg one_pos (Ἆ (by norm_num1) hc0.le)) constructor . by_cases hl:lo<0;. linarith only [hl, hsT] . rw[not_lt] at hl;rw[Real.lt_sqrt hl];generalize hk:s*(1-3/2*c)=k at h4;have hk0:0<=k-9/10*Em :=(by linarith only [h4, hl]);have q1:=Ἳ hl h4 2;have q3:=Ἆ hE hk0 have q4:k^2<=s^2*(1-3/2*c):=by have h6:(1-3/2*c)^2<=1-3/2*c:=by have:=ἁ hc1 hc0.le;linarith only [this, hc0] calc k^2=s^2*(1-3/2*c)^2:=by rw[<-hk,mul_pow] _<=_:=ἁ h6 (ὅ _) have q5:=ὅ Em;linarith only [h2, hq, q1, q3, q4, q5] . have hh:0< hi:=by linarith only [h5, h3, hE] rw[Real.sqrt_lt' hh];have q1:=Ἳ (add_nonneg h5.le (Ἆ (by norm_num1) hE)) h3 2;have r1:0<=s^2*c^2:=Ἆ (ὅ s) (ὅ c) have r2:0<=s*Em*(1+3/2*c):=Ἆ (Ἆ hs.le hE) hc15 have r3:=ὅ Em;linarith only [h1, hq, q1, r1, r2, r3] lemma qHp (l:List ℕ) (a:ℕ->ℝ) (c:ℝ) : (l.map λj=>(a j-c)^2).sum =(l.map λj=>a j^2).sum-2*c*(l.map a).sum+ѣl*c^2:=by induction l with | nil=>simp | cons j l ih => simp only[List.map_cons,List.sum_cons,List.length_cons,ih] push_cast ring lemma qGh (l:List ℕ) (a:ℕ->ℝ) (m:ℝ) (hl:(ѣl:ℝ)≠0) : (l.map λj=>(a j-m)^2).sum = (l.map λj=>(a j-(l.map a).sum/ѣl)^2).sum + ѣl*((l.map a).sum/ѣl-m)^2:=by rw[qHp,qHp] field_simp ring lemma qGx (l:List ℕ) (f w:ℕ->ℝ) (u t:ℝ) (hw:∀ j∈l,0<=w j) (h:∀ j∈l,|f j-w j| ≤ u*w j+t) (hu:0<=u) (ht:0<=t) : |(l.map f).sum-(l.map w).sum| ≤ u*(l.map w).sum+ѣl*t ∧ (l.map λj=>|f j|).sum<=(1+u)*(l.map w).sum+ѣl*t∧0<=(l.map w).sum:=by induction l with | nil=>simp | cons j l ih => obtain ⟨i1,i2,i3⟩:=ih (λk hk=>hw k (ὖ _ hk)) (λk hk=>h k (ὖ _ hk)) have h0:=hw j ὣ have h1:=h j ὣ simp only[List.map_cons,List.sum_cons,List.length_cons] push_cast have a1:=Ἐ (f j-w j) ((l.map f).sum-(l.map w).sum) rw[show f j-w j+((l.map f).sum-(l.map w).sum)=f j+(l.map f).sum-(w j+(l.map w).sum) by ring] at a1 have a2:=qAa (f j) (w j) rw[ἅ h0] at a2 exact ⟨by linarith only [i1, h1, a1],by linarith only [i2, h1, a2],by linarith only [i3, h0]⟩ lemma qIr {σ:Type} {N n c:Ὣ} {sp:Ὣ->Ὢ} {f:σ->ὦ->ὦ->Ὢ} {s:σ} {b:ὦ} (hN:N<2^32) (hb:Ѥb=c) (hn:c+n<=N) (hf:∀ p u:ὦ,Ѥp=c+Ѥu->Ѥu< n->f s p u=sp Ѥp) (k:Ὣ) : ∀ (j:ὦ) (o:ё),Ѥj+k=n->C_Inv N sp (λq=>q< c+Ѥj) o → C_Inv N sp (λq=>q< c+n) (fC f s b j o k):=by induction k with | zero => intro j o e h rw[fC,<-e];exact h | succ k ih => intro j o e h have a0:(b+j).toNat=c+Ѥj:=by rw[<-hb];exact qAf _ _ (by exact omS346 hN hb hn e) have a1:(j+1).toNat=Ѥj+1:=by rw[qAf _ _ (by rw[ὄ];exact omS347 hN hn e),ὄ] rw[fC] refine ih _ _ (by clear hN hb hn a0; exact omS157 e a1) ?_ rw[a1] exact qAp hN h a0 (by clear hN hb a1; exact omS348 hn e) (by rw[hf _ _ a0 (by clear hN hb hn a0 a1; exact omS136 e),a0]) lemma qDb {σ:Type} {R n:Ὣ} (F:Ὣ->Ὣ->Ὣ->Ὢ) {h:Ὣ->σ} {f:σ->ὦ->ὦ->Ὢ} (hN:R*n<2^32) (hn:0< n) (hf:∀ (r:Ὣ) (p u:ὦ),r< R->Ѥp=r*n+Ѥu->Ѥu< n → f (h r) p u=F r Ѥu Ѥp) : fR h f n 0 (ἇ (R*n) 0) R =Array.ofFn (n:=R*n) λq=>F (q.val/n) (q.val%n) q.val:=by let sp q:=F (q/n) (q%n) q have K:∀ (d r:Ὣ) (o:ё),r+d=R->C_Inv (R*n) sp (λq=>q< r*n) o → C_Inv (R*n) sp (λq=>q< R*n) (fR h f n r o d):=λd=>by induction d with | zero => intro r o e H subst e exact H | succ d ih => intro r o e H have h1:r*n+n<=R*n:=qBc ((by clear hN hn; exact omS136 e):r< R) (Ὗ _) rw[fR] refine ih _ _ (by clear hN hn h1; exact omS137 e) ?_ rw[Nat.succ_mul] exact qIr hN (qAd _ (by clear e; exact omS154 hN h1)) h1 (λp u h2 h3=>by rw[hf r p u (by clear hN hn h1 h2 h3; exact omS136 e) h2 h3] show F _ _ _=F _ _ _ rw[h2,ἥ r n,Nat.mul_add_div hn,Nat.mul_add_mod,Ὃ h3,Ἁ h3,Ἵ]) n 0 o (Ἇ _) H exact qBv (K R 0 _ (by clear hN hn; exact omS139) ⟨by simp,λq _ (h:q<0*n)=>by omega⟩) λq hq=>hq section variable (x:ѐ) (hx:ѧx<2^32) (base nu:ὦ) include x hx base nu lemma qG9 (hb:Ѥbase+Ѥnu<2^32) (d:ℕ) (i:ὦ) (s t:ὧ) (h:Ѥi+d=Ѥnu) : lnSum x base nu i s t = ⟨((List.range' Ѥi d).map λj=>dv x[Ѥbase+j]!).foldl (.+·) s,((List.range' Ѥi d).map λj=>(dv x[Ѥbase+j]!).abs).foldl (.+·) t⟩:=by induction d generalizing i s t with | zero => rw[lnSum,ἔ (by rw[А];(clear hx hb; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))];simp | succ d ih => have hn:i< nu:=by rw[А];(clear hx hb; exact omS136 h) have e1:=usz i nu hn rw[lnSum,Ἄ hn,ih (i+1) _ _ (by rw[e1];(clear hx hb hn e1; omega)),e1,qAg x _ hx,qAf base i (by clear hx hn; omega)] simp[List.range'_succ] lemma qG2 (m:ὧ) (hb:Ѥbase+Ѥnu<2^32) (d:ℕ) (i:ὦ) (v:ὧ) (h:Ѥi+d=Ѥnu) : lnVar x base nu i m v = ((List.range' Ѥi d).map λj =>(dv x[Ѥbase+j]! - m)*(dv x[Ѥbase+j]! - m)).foldl (.+·) v:=by induction d generalizing i v with | zero => rw[lnVar,ἔ (by rw[А];(clear hx hb; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))];simp | succ d ih => have hn:i< nu:=by rw[А];(clear hx hb; exact omS136 h) have e1:=usz i nu hn rw[lnVar,Ἄ hn,ih (i+1) _ (by rw[e1];(clear hx hb hn e1; omega)),e1,qAg x _ hx,qAf base i (by clear hx hn; omega)] simp[List.range'_succ] end lemma qEp (l:List ℕ) (f:ℕ->ℚ) (u:ℕ->ℝ) (c:ℚ) (h:∀ j∈l,(f j:ℝ)=u j) : ((l.foldl (λt j=>t+f j) c:ℚ):ℝ)=c+(l.map u).sum:=by induction l generalizing c with | nil=>simp | cons j l ih => simp only[List.foldl_cons,List.map_cons,List.sum_cons];rw[ih _ λk hk=>h k (ὖ _ hk),<-h j ὣ];push_cast;ring lemma qIb (w:ὥ) (hg:good w=true) (h1:(0x1F800000:ὥ)<=w) (h2:w<=(0x70FFFFFF:ὥ)):1/2^64<=wv w:=by have a1:528482304<=ѥw:=ἃ.mp h1;have a2:ѥw<=1895825407:=ἃ.mp h2;rw[qA7 w hg,ἐ (by clear h1 h2; exact omS349 a2),one_mul];have h3:=qA6 528482304 (ѥw%2^31) (by clear h1 h2; exact omS350 a1 a2) (by decide);have:A_mag 528482304=1/2^64:=by unfold A_mag;norm_num rwa [this] at h3 lemma qH3 (w:ὥ) (hg:good w=true) (h0:0< wv w):1/2^126<=wv w:=by have hn:=qAz w hg;rw[qA7 w hg] at h0 ⊢;rcases hn with hn | ⟨hn,-⟩;. rw[hn] at h0;simp[A_mag] at h0 . have hs:¬ 2^31<=ѥw:=λhc=>by rw[ἱ hc] at h0;linarith [qAs (ѥw%2^31)] rw[ἐ hs,one_mul];have h3:=qA6 (2^23) (ѥw%2^31) hn (by decide);have:A_mag (2^23)=1/2^126:=by unfold A_mag;norm_num rwa [this] at h3 lemma qIi (n:ℕ) (hn:n<2^20) : ((n.toUInt64+8).toFloat*Ἃ ь).isFinite=true ∧ R ((n.toUInt64+8).toFloat*Ἃ ь)=((n:ℝ)+8)/2^49:=by have ht:(n.toUInt64+8).toNat=n+8:=by have h8:(8:Ὠ).toNat=8:=rfl simp[UInt64.toNat_add,h8] (clear h8; exact omS57 hn) have h1:=qCk (n.toUInt64+8) (by rw[ht];exact omS58 hn) obtain ⟨h2,h3⟩:=L_k ь 974 49 (by norm_num1) rfl (by rfl) have h4:(n:ℝ)+8<=2^21:=by exact_mod_cast ((by exact omS351 hn):n+8<=2^21) obtain ⟨hf,he⟩:=qEd _ _ h1.1 h2 (by rw[h1.2,h3,ht] refine ὂ (ἑ (qAt ?_) (qAt (by rw[ἅ (by positivity)];(norm_num1))) (Ἀ _) qI1.le) qDe rw[Nat.cast_add,ἅ (by positivity)] push_cast linarith only [h4]) refine ⟨hf,?_⟩ rw[he,h1.2,h3,ht] have:=qA2 ((n:ℤ)+8) (-49) (by exact omS352 hn) (by norm_num1) push_cast at this ⊢ rw[show (2:ℝ)^(-49:ℤ)=1/2^49 by (norm_num1)] at this rw[this] ring lemma qD7 {r x B:ℝ} (e : |r-x| ≤ 1/2^53*(|x| + A_z)) (h : |x| ≤ B) : |r| ≤ 9/8*B+A_z:=by linarith [qAa r x,Ἀ x,qAr] section variable (x y:ὧ) (B:ℝ) (hx:x.isFinite=true) (hy:y.isFinite=true) (h1 : |R x| ≤ B) (h2 : |R y| ≤ B) (hB:B<=2^256*2^44:=by norm_num) include x y B hx hy h1 h2 hB lemma qAv : (x+y).isFinite=true∧|R (x+y)-(R x+R y)| ≤ 1/2^53*(|R x+R y| + A_z) ∧ |R (x+y)| ≤ 9/8*(B+B)+A_z:=by obtain ⟨f,e⟩:=qBf x y hx hy (h1.trans (qAt hB)) (h2.trans (qAt hB)) exact ⟨f,e,qD7 e ((Ἐ _ _).trans (add_le_add h1 h2))⟩ lemma qCg : (x-y).isFinite=true∧|R (x-y)-(R x-R y)| ≤ 1/2^53*(|R x-R y| + A_z) ∧ |R (x-y)| ≤ 9/8*(B+B)+A_z:=by obtain ⟨f,e⟩:=qDf x y hx hy (h1.trans (qAt hB)) (h2.trans (qAt hB)) exact ⟨f,e,qD7 e ((Ὕ _ _).trans (add_le_add h1 h2))⟩ end lemma qAl (x y:ὧ) (B C:ℝ) (hx:x.isFinite=true) (hy:y.isFinite=true) (h1 : |R x| ≤ B) (h2 : |R y| ≤ C) (hB:B<=2^256*2^44:=by norm_num) (hC:C<=2^256*2^44:=by norm_num) : (x*y).isFinite=true∧|R (x*y)-R x*R y| ≤ 1/2^53*(|R x*R y| + A_z) ∧ |R (x*y)| ≤ 9/8*(B*C)+A_z:=by obtain ⟨f,e⟩:=qCf x y hx hy (h1.trans (qAt hB)) (h2.trans (qAt hC)) exact ⟨f,e,qD7 e (ἢ (R x) (R y) ▸ ἑ h1 h2 (Ἀ _) ((Ἀ _).trans h1))⟩ lemma qFy (a b:ὧ) (hb:b.isFinite=true) (hb2 : |R b| ≤ 2^99) (h:invOK a b=true) : a.isFinite=true∧0< R a∧R a<=2^200∧|R a*R b-1| ≤ 1/2^48:=by simp only[invOK,Bool.and_eq_true,decide_eq_true_eq] at h;obtain ⟨r1,r2⟩:1<=_∧_<1+1222:=qEj _ 1 1222 h.1 (by decide);obtain ⟨r3,r4⟩:972<=_∧_<972+2:=qEj _ 972 2 h.2 (by decide);obtain ⟨f1,l1,u1⟩:=qCz rfl r1 (by exact Nat.lt_of_lt_of_le ‹_› (by decide));have hp:0< R a:=Ἥ (ἵ (by positivity) _) l1;have ha2:R a<=2^200:=u1.le.trans ((ἒ (by norm_num1) (by clear h r3 r4; exact omS353 r2)).trans_eq (by (norm_num1):(2:ℝ)^(200:ℤ)=2^200));obtain ⟨k1,k2⟩:=L_k 0x3FF0000000000000 1023 0 (by norm_num1) rfl (by rfl);obtain ⟨k3,k4⟩:=L_k 0x3CD0000000000000 973 50 (by norm_num1) rfl (by rfl);rw[pow_zero,div_one] at k2;have hz1:=qBo;obtain ⟨f2,g1,q1⟩:=qAl a b (2^200) (2^99) f1 hb (by rwa [ἡ hp]) hb2 (by norm_num1) (by norm_num1);obtain ⟨f3,g2⟩:=qDf _ _ f2 k1 (qAt (q1.trans ((add_le_add le_rfl hz1).trans (by norm_num1)))) (qAt (by rw[k2];(norm_num1)));rw[k2] at g2;have q3:=Ὕ (R (a*b)) 1;rw[abs_one] at q3;have q2:=qD7 g2 q3;obtain ⟨f4,g3⟩:=qBf _ _ f3 k3 (qAt (q2.trans ((add_le_add (mul_le_mul_of_nonneg_left (add_le_add (q1.trans (add_le_add le_rfl hz1)) le_rfl) (by norm_num1)) hz1).trans (by norm_num1)))) (qAt (by rw[k4];(norm_num1)));rw[k4] at g3;obtain ⟨-,l2,u2⟩:=qCz rfl (ὂ (by norm_num1) r3) (by exact Nat.lt_of_lt_of_le ‹_› (by decide));refine ⟨f1,hp,ha2,qD9 qAr.le qAw g1 g2 g3 ?_ ?_⟩;. exact (by (norm_num1):(1/2^51:ℝ)=2^(-51:ℤ)).trans_le ((ἒ (by norm_num1) (by clear h r1 r2; exact omS354 r3)).trans l2) . exact u2.le.trans ((ἒ (by norm_num1) (by clear h r1 r2; exact omS355 r4)).trans_eq (by (norm_num1):(2:ℝ)^(-49:ℤ)=1/2^49)) lemma qDr (n:ℕ) (f:ℕ->ℝ) (B:ℝ) (h:∀ j,j< n->f j<=B) : ((ἄ n).map f).sum<=n*B:=by simpa using List.sum_le_length_nsmul ((List.range n).map f) B (by simpa using λj hj=>h j hj) lemma qFm (n:ℕ) (hn:n<2^20) (f:ℕ->ὧ) (a b:ℕ->ℝ) (hf:∀ j,j< n->(f j).isFinite=true∧R (f j)=a j∧|a j| = b j) (hb:((ἄ n).map b).sum<=A_B/4) : (A_fsum ((ἄ n).map f)).isFinite=true ∧ |R (A_fsum ((ἄ n).map f))-((ἄ n).map a).sum| ≤ 2*n*(1/2^53*(((ἄ n).map b).sum+A_z)):=by have s:∀ (u:ὧ->ℝ) (v:ℕ->ℝ),(∀ j,j< n->u (f j)=v j) → (((ἄ n).map f).map u).sum=((ἄ n).map v).sum:=λu v h=>by simp only[List.map_map] exact congrArg _ (ὠ λj hj=>h j (Ἅ.1 hj)) have e1:=s (λq=>|R q|) b λj h=>by simp only[(hf j h).2.1,(hf j h).2.2] have e2:=s R a λj h=>(hf j h).2.1 have:=qBz ((ἄ n).map f) (λq hq=>by obtain ⟨j,hj,rfl⟩:=List.mem_map.1 hq exact (hf j (Ἅ.1 hj)).1) (by simp;(exact Nat.le_of_lt (Nat.lt_of_lt_of_le ‹_› (by decide)))) (by rw[A_sa,e1];exact hb) rwa [A_sa,A_sr,e1,e2,List.length_map,List.length_range] at this lemma qGp (n:ℕ) (hn:n<2^20) (hn0:0< n) (g:ℕ->ὧ) (m v:ὧ) (W:ℝ) (hv:v=A_fsum ((ἄ n).map λj=>(g j-m)*(g j-m))) (hW:W=((ἄ n).map λj=>(R (g j)-R m)^2).sum) (hg:∀ j,j< n->(g j).isFinite=true∧|R (g j)| ≤ 2^99) (hm:m.isFinite=true) (hm2 : |R m| ≤ 2^110) : v.isFinite=true∧|R v-W| ≤ (2*n+6)/2^53*W+1/2^229∧W<=n*2^222∧0<=W:=by have hz0:=qAr.le;have hzl:=qAw;have hzb:=qBo have hq:∀ j,j< n->((g j-m)*(g j-m)).isFinite=true ∧ |R ((g j-m)*(g j-m))-(R (g j)-R m)^2| ≤ 4/2^53*(R (g j)-R m)^2+1/2^250∧(R (g j)-R m)^2<=2^222:=by intro j hj obtain ⟨f,b⟩:=hg j hj have B1 : |R (g j)| ≤ 2^110:=b.trans (by norm_num1) obtain ⟨f1,e1,b1⟩:=qCg (g j) m (2^110) f hm B1 hm2 (by norm_num1) have b2 : |R (g j-m)| ≤ 2^112 :=b1.trans ((add_le_add le_rfl hzb).trans (by norm_num1)) obtain ⟨f2,e2,-⟩:=qAl _ _ (2^112) (2^112) f1 f1 b2 b2 (by norm_num1) (by norm_num1) have hx : |R (g j)-R m| ≤ 2^111:=(Ὕ _ _).trans ((add_le_add B1 hm2).trans (by norm_num1)) refine ⟨f2,qIw hz0 hzl hx e1 e2,?_⟩ have:=Ἳ (Ἀ _) hx 2 rw[sq_abs] at this exact this.trans (by norm_num1) obtain ⟨a1,a2,a3⟩:=qGx (ἄ n) (λj=>R ((g j-m)*(g j-m))) (λj=>(R (g j)-R m)^2) (4/2^53) (1/2^250) (λj _=>ὅ _) (λj hj=>(hq j (Ἅ.1 hj)).2.1) (by positivity) (by positivity);simp only[List.length_range] at a1 a2;rw[<-hW] at a1 a2 a3;have hW':W<=n*2^222:=hW ▸ qDr n _ _ λj h=>(hq j h).2.2;have hnR:(n:ℝ)<=2^20:=by exact_mod_cast hn.le have hnR1:(1:ℝ)<=n:=by exact_mod_cast hn0 have h1:(n:ℝ)*2^222<=2^20*2^222:=ἀ hnR (pow_nonneg zero_le_two 222) have h2:(n:ℝ)*(1/2^250)<=2^20*(1/2^250):=ἀ hnR (div_nonneg zero_le_one (pow_nonneg zero_le_two 250)) obtain ⟨f2,e2⟩:=qFm n hn _ _ (λj=>|R ((g j-m)*(g j-m))|) (λj h=>⟨(hq j h).1,rfl,rfl⟩) (by exact ὂ a2 ((add_le_add (ἁ (hW'.trans h1) (by norm_num1)) h2).trans (le_trans (by norm_num1) (div_le_div_of_nonneg_right (qAt (k:=2^256*2^44) le_rfl) (by norm_num1))))) rw[<-hv] at e2 f2;exact ⟨f2,qG8 hz0 hzl hnR1 hnR a3 e2 a1 a2,hW',a3⟩ lemma qF2 (l:List ℕ) (f:ℕ->ℝ) : |(l.map f).sum| ≤ (l.map λj=>|f j|).sum:=by induction l with | nil=>simp | cons j l ih => simp only[List.map_cons,List.sum_cons];exact (Ἐ _ _).trans (add_le_add le_rfl ih) def L_oF (s:LnS) (M:ℝ):Prop := s.fast=true->s.m.isFinite=true∧s.ir.isFinite=true∧s.em.isFinite=true ∧ R s.em<=2^120∧1/2^201<=R s.em∧2 * |M-R s.m| ≤ R s.em ∧ |R s.m| ≤ 2^110∧good s.den=true∧1/2^64<=wv s.den ∧ |R s.ir*wv s.den-1| ≤ 1/2^48 def L_ok (b:Ὡ) (n:ℕ) (eps:Ὢ) (x:ё) (r:ℕ) (s:LnS):Prop := s.den=sqrtRational (rowVariance n x r (lnQ b n x r)+ἂ eps) ∧ L_oF s (lnQ b n x r:ℚ) lemma qHi (n r:ℕ) (x:ё) (g:ℕ->ὧ) (h:∀ j,j< n → R (g j)=(ἂ x[r*n+j]! : ℝ)) (q:ℚ) : ((rowMean n x r:ℚ):ℝ)=((ἄ n).map λj=>R (g j)).sum/n ∧ ((rowVariance n x r q:ℚ):ℝ) =((ἄ n).map λj=>(R (g j)-(q:ℝ))^2).sum/n:=by constructor . rw[rowMean,Rat.cast_div,qEp _ _ (λj=>R (g j)) 0 λj hj=>(h j (Ἅ.1 hj)).symm];simp . rw[rowVariance,Rat.cast_div,qEp _ _ (λj=>(R (g j)-(q:ℝ))^2) 0 λj hj=>by rw[h j (Ἅ.1 hj)];push_cast;rfl] simp section variable (n:ℕ) (hnR1:(1:ℝ)<=n) (hnR2:(n:ℝ)<=2^20) include n hnR1 hnR2 lemma qG1 (Fs Ft ind nf m em:ὧ) (S Sa c:ℝ) (hc:c=((n:ℝ)+8)/2^49) (o1:Fs.isFinite=true) (o2:Ft.isFinite=true) (o3 : |S| ≤ Sa) (o4:Sa<=n*2^99) (o5 : |R Fs-S| ≤ 2*n*(1/2^53*(Sa+A_z))) (o6 : |R Ft-Sa| ≤ 2*n*(1/2^53*(Sa+A_z))) (fnf:nf.isFinite=true) (Rnf:R nf=c) (fi:ind.isFinite=true) (pi:0< R ind) (ei : |R ind*n-1| ≤ 1/2^48) (hm:Fs*ind=m) (hem:nf*Ft*ind+Ἃ ظ=em) : m.isFinite=true∧em.isFinite=true∧R em<=2^120∧1/2^201<=R em ∧ 2 * |S/n-R m| ≤ R em∧|R m| ≤ 2^110:=by have hz0:=qAr.le have hzb:=qBo have hn0:(0:ℝ)<=n:=ὂ zero_le_one hnR1 have hc0:0< c:=hc ▸ div_pos (add_pos_of_nonneg_of_pos hn0 (by norm_num1)) (by norm_num1) have hc1:c<=1/2^20:=by rw[hc];exact (div_le_div_of_nonneg_right (add_le_add hnR2 le_rfl) (pow_nonneg zero_le_two 49)).trans (by norm_num1) have bI : |R ind| ≤ 2:=by rw[ἡ pi];exact L_I hnR1 pi ei have hSa0:0<=Sa:=(Ἀ _).trans o3 have hSb:=ἀ hnR2 (pow_nonneg zero_le_two 99:(0:ℝ)<=2^99) have hSA:Sa+A_z<=2^119+1:=add_le_add (o4.trans (hSb.trans_eq (by norm_num1))) hzb have E5:2*(n:ℝ)*(1/2^53*(Sa+A_z))<=2*2^20*(1/2^53*(2^119+1)):=ἑ (ἁ hnR2 zero_le_two) (ἁ hSA (by norm_num1)) (Ἆ (by norm_num1) (add_nonneg hSa0 hz0)) (by norm_num1) have bs : |R Fs| ≤ 2^120:=(qAa (R Fs) S).trans ((add_le_add (o3.trans (o4.trans hSb)) (o5.trans E5)).trans (by norm_num1)) have bt : |R Ft| ≤ 2^120:=(qAa (R Ft) Sa).trans ((add_le_add ((ἅ hSa0).le.trans (o4.trans hSb)) (o6.trans E5)).trans (by norm_num1)) have bnf : |R nf| ≤ 1:=by rw[Rnf,ἡ hc0];exact hc1.trans (by norm_num1) obtain ⟨fm,em1,-⟩:=qAl Fs ind (2^120) 2 o1 fi bs bI (by norm_num1) (by norm_num1) rw[hm] at fm em1 obtain ⟨fN,emN,bN⟩:=qAl nf Ft 1 (2^120) fnf o2 bnf bt (by norm_num1) (by norm_num1) rw[Rnf] at emN obtain ⟨fY,emY,bY⟩:=qAl (nf*Ft) ind (2^122) 2 fN fi (bN.trans ((add_le_add le_rfl hzb).trans (by norm_num1))) bI (by norm_num1) (by norm_num1) obtain ⟨k1,k2⟩:=L_k ظ 823 200 (by norm_num1) rfl (by rfl) obtain ⟨fE,emE,-⟩:=qAv (nf*Ft*ind) _ (2^125) fY k1 (bY.trans ((add_le_add le_rfl hzb).trans (by norm_num1))) (by rw[k2];(norm_num1)) (by norm_num1) rw[k2,hem] at emE rw[hem] at fE have hnpos:(0:ℝ)< n :=zero_lt_one.trans_le hnR1 have hnp:=hnpos.ne' have eS:(n:ℝ)*(S/n)=S:=mul_div_cancel₀ S hnp have eA:(n:ℝ)*(Sa/n)=Sa:=mul_div_cancel₀ Sa hnp obtain ⟨m1,m2,m3,m4⟩:=qG3 hz0 qAw (S/n) (Sa/n) hnR1 hnR2 hc (by rw[abs_div,ἡ hnpos];exact div_le_div_of_nonneg_right o3 hnpos.le) (by rw[div_le_iff₀ hnpos,mul_comm];exact o4) (by rw[eS,eA];exact o5) (by rw[eA];exact o6) pi ei em1 emN emY emE exact ⟨fm,fE,m2,m3,m1,m4⟩ lemma qIv (v ind tt:ὧ) (eps:Ὢ) (W c:ℝ) (hc:c=((n:ℝ)+8)/2^49) (p1:v.isFinite=true) (p2 : |R v-W| ≤ (2*n+6)/2^53*W+1/2^229) (p3:W<=n*2^222) (hW0:0<=W) (fi:ind.isFinite=true) (pi:0< R ind) (ei : |R ind*n-1| ≤ 1/2^48) (gE:good eps=true) (bE : |wv eps| ≤ 2^99) (hep0:0< wv eps) (htt:v*ind+dv eps=tt) : tt.isFinite=true∧|R tt-(W/n+wv eps)| ≤ c/2*(W/n+wv eps):=by have hnpos:(0:ℝ)< n :=zero_lt_one.trans_le hnR1;have hnp:=hnpos.ne';have hzb:=qBo;have bI : |R ind| ≤ 2:=by rw[ἡ pi];exact L_I hnR1 pi ei have bW:=ἀ hnR2 (by (positivity):(0:ℝ)<=2^222);have hW2:=p3.trans bW;have bv : |R v| ≤ 2^250:=(qAa (R v) W).trans ((add_le_add ((ἅ hW0).le.trans hW2) (p2.trans (add_le_add ((ἀ (div_le_div_of_nonneg_right (add_le_add (ἁ hnR2 zero_le_two) le_rfl) (by norm_num1)) hW0).trans (ἁ hW2 (by norm_num1))) le_rfl))).trans (by norm_num1)) obtain ⟨fp,ep1,bp⟩:=qAl v ind (2^250) 2 p1 fi bv bI (by norm_num1) (by norm_num1);obtain ⟨de1,de2⟩:=qAm eps gE;obtain ⟨ft,et,-⟩:=qAv (v*ind) (dv eps) (2^253) fp de1 (bp.trans ((add_le_add le_rfl hzb).trans (by norm_num1))) (by rw[de2];exact bE.trans (by norm_num1)) (by norm_num1);rw[de2,htt] at et;rw[htt] at ft;exact ⟨ft,qH9 qAr.le qAw (W/n) (1/2^229) hnR1 hnR2 hc (div_nonneg hW0 hnpos.le) (qH3 eps gE hep0) (by positivity) le_rfl (by rw[mul_div_cancel₀ W hnp];exact p2) pi ei ep1 et⟩ end lemma qIk (tt nf em:ὧ) (E:ℕ) (hE1:1<=E) (hE:E<=1222) (hEe:(tt.toBits >>> 52).toNat=E) (c P δ T:ℝ) (hc1:c<=1/2^20) (hc2:9/2^49<=c) (fnf:nf.isFinite=true) (Rnf:R nf=c) (fE:em.isFinite=true) (m2:R em<=2^120) (m3:1/2^201<=R em) (hP0:0< P) (hq1 : |R tt-P| ≤ c/2*P) (m1:2 * |δ| ≤ R em) (hT:T=P-δ^2) (hT0:0< T) : R (Ἤ tt-((nf+nf)*Ἤ tt+em))< ἧ T ∧ ἧ T< R (Ἤ tt+((nf+nf)*Ἤ tt+em)) ∧ ἧ T<2^(127:ℤ):=by have e2le:∀ {k:ℕ},k<=300->(2:ℝ)^k<=2^256*2^44:=fun h=>(pow_le_pow_right₀ one_le_two h).trans_eq (pow_add 2 256 44) have e2pf:∀ {x P:ℝ},x<=9/8*P+A_z->1<=P->x<=2^2*P:=fun {x P} h h1=>h.trans ((add_le_add (mul_le_mul_of_nonneg_right (by norm_num1:(9:ℝ)/8<=3) (zero_le_one.trans h1)) (qBo.trans h1)).trans ((add_one_mul (3:ℝ) P).symm.trans (congrArg (·*P) (by norm_num1:(3:ℝ)+1=2^2))).le) have e2pk:∀ {x:ℝ} {a k:ℕ},x<=9/8*((2:ℝ)^a+2^a)+A_z->2+(a+1)<=k->x<=2^k:=fun {x a k} h hk=>(e2pf (h.trans_eq (congrArg (fun P:ℝ=>9/8*P+A_z) ((two_mul _).symm.trans (pow_succ' 2 a).symm))) (one_le_pow₀ one_le_two)).trans ((pow_add 2 2 (a+1)).symm.trans_le (pow_le_pow_right₀ one_le_two hk)) have e2pm:∀ {x:ℝ} {a b k:ℕ},x<=9/8*((2:ℝ)^a*2^b)+A_z->2+(a+b)<=k->x<=2^k:=fun {x a b k} h hk=>(e2pf (h.trans_eq (congrArg (fun P:ℝ=>9/8*P+A_z) (pow_add 2 a b).symm)) (one_le_pow₀ one_le_two)).trans ((pow_add 2 2 (a+b)).symm.trans_le (pow_le_pow_right₀ one_le_two hk)) have e2pa:∀ {x y:ℝ} {a b j:ℕ},x<=2^a->y<=2^b->a<=j->b<=j->x+y<=2^(j+1):=fun {x y a b j} hx hy ha hb=>(add_le_add (hx.trans (pow_le_pow_right₀ one_le_two ha)) (hy.trans (pow_le_pow_right₀ one_le_two hb))).trans_eq ((two_mul _).symm.trans (pow_succ' 2 j).symm) have e2z0:A_z<=2^0:=qBo.trans_eq (pow_zero 2).symm have e2d:∀ {x:ℝ} (n:ℕ),0<=x->1/2^n*x<=x:=fun n h0=>mul_le_of_le_one_left h0 (div_le_one_of_le₀ (one_le_pow₀ one_le_two) (pow_nonneg zero_le_two n)) have e2c1:∀ {c:ℝ} {n:ℕ},c<=1/2^n->c<=1:=fun {c n} h=>h.trans (div_le_one_of_le₀ (one_le_pow₀ one_le_two) (pow_nonneg zero_le_two n)) have hzb:=qBo have hc0:0< c:=Ἥ (by positivity) hc2 obtain ⟨-,-,u1⟩:=qCz hEe hE1 (by exact Nat.lt_of_le_of_lt ‹_› (by decide)) obtain ⟨fd,ptt,ed⟩:=qGk hEe hE1 (by exact Nat.lt_of_le_of_lt ‹_› (by decide)) generalize Ἤ tt=d at fd ed ⊢ have ht2:R tt<=2^200:=u1.le.trans ((ἒ (by norm_num1) (by exact omS356 hE)).trans_eq (by (norm_num1):(2:ℝ)^(200:ℤ)=2^200)) generalize hs':ἧ (R tt)=s' at ed have hs0:0< s':=by rw[<-hs'];exact Real.sqrt_pos.mpr ptt have hsq:s'^2=R tt:=by rw[<-hs'];exact Real.sq_sqrt ptt.le have hs1:s'<=2^100:=by rw[<-hs',Real.sqrt_le_iff] exact ⟨by (positivity),ht2.trans_eq (pow_mul 2 100 2)⟩ have bd : |R d| ≤ 2^102:=by have a1:=qAa (R d) s' rw[ἡ hs0] at a1 exact a1.trans (e2pa (j:=101) hs1 (ed.trans ((e2d 53 (add_nonneg hs0.le qAr.le)).trans (e2pa (j:=100) hs1 e2z0 le_rfl (Nat.le_of_ble_eq_true rfl)))) (Nat.le_of_ble_eq_true rfl) le_rfl) have bnf : |R nf| ≤ 2^0:=by rw[Rnf,ἡ hc0,pow_zero];exact e2c1 hc1 obtain ⟨f2n,e2n,b2n⟩:=qAv nf nf (2^0) fnf fnf bnf bnf (e2le (Nat.le_of_ble_eq_true rfl)) rw[Rnf] at e2n obtain ⟨fmu,emu,bmu⟩:=qAl (nf+nf) d (2^3) (2^102) f2n fd (e2pk b2n le_rfl) bd (e2le (Nat.le_of_ble_eq_true rfl)) (e2le (Nat.le_of_ble_eq_true rfl)) have hEm0:0<=R em:=ὂ (by positivity) m3 have bEm : |R em| ≤ 2^120:=by rw[ἅ hEm0];exact m2 obtain ⟨fe,ee,be⟩:=qAv ((nf+nf)*d) em (2^120) fmu fE (e2pm bmu (Nat.le_of_ble_eq_true rfl)) bEm (e2le (Nat.le_of_ble_eq_true rfl)) have bd3:=bd.trans (pow_le_pow_right₀ one_le_two (Nat.le_of_ble_eq_true rfl:102<=123)) have be3:=e2pk (k:=123) be le_rfl obtain ⟨fh,eh,-⟩:=qAv d _ (2^123) fd fe bd3 be3 (e2le (Nat.le_of_ble_eq_true rfl)) obtain ⟨fl,el,-⟩:=qCg d _ (2^123) fd fe bd3 be3 (e2le (Nat.le_of_ble_eq_true rfl)) obtain ⟨hhi,hlo⟩:=qHr qAr.le qAw hs0.le (hs1.trans (pow_le_pow_right₀ one_le_two (Nat.le_of_ble_eq_true rfl))) hc2 hc1 m3 m2 ed e2n emu ee eh el obtain ⟨b1,b2⟩:=abs_le.mp hq1 have hδ2:δ^2*4<=R em^2:=by have a1:(2 * |δ|)^2<=R em^2:=Ἳ (Ἆ zero_le_two (Ἀ δ)) m1 2 rw[mul_pow,sq_abs] at a1 linarith only [a1] have nP:0<=c*P:=(mul_pos hc0 hP0).le have a3:=ἀ (e2c1 hc1) nP have a4:=Ἆ hc0.le nP have nd2:=ὅ δ have h1':T<=s'^2*(1+c):=by rw[hsq,hT] have a1:=ἀ ((div_le_iff₀' two_pos).mp (by rwa[div_mul_eq_mul_div,<-neg_div] at b1):-(c*P)<=2*(R tt-P)) (add_pos one_pos hc0).le linarith only [a3, nd2, a1] have h2':s'^2*(1-c)-R em^2/4<=T:=by rw[hsq,hT] have a1:=ἀ ((le_div_iff₀' two_pos).mp (by rwa[div_mul_eq_mul_div] at b2):2*(R tt-P)<=c*P) (sub_nonneg.mpr (e2c1 hc1)) linarith only [hδ2, a3, a4, a1] obtain ⟨l1,l2⟩:=qHl hT0 hs0 hc0 hc1 hEm0 h1' h2' hhi hlo refine ⟨l1,l2,?_⟩ rw[Real.sqrt_lt' (by positivity),zpow_ofNat,<-pow_mul] have a1:=ἑ (hsq.trans_le ht2) ((add_le_add le_rfl (e2c1 hc1)).trans_eq one_add_one_eq_two:1+c<=2) (add_pos one_pos hc0).le (by positivity) exact h1'.trans_lt (a1.trans_lt ((pow_succ 2 200).symm.trans_lt (pow_lt_pow_right₀ one_lt_two (Nat.le_of_ble_eq_true rfl)))) lemma qE1 (b:Ὡ) (rows n:ℕ) (eps:Ὢ) (x:ё) (r:ℕ) (hr:r< rows) (hn0:0< n) (hn:n<2^20) (hs:ѧx=rows*n) (hrn:rows*n<2^32) (hx:x.all sm=true) (he:sm eps=true) (he0:0< ἂ eps) : L_ok b n eps x r (lnStat b n eps x r):=by have e2AB:∀ {x:ℝ} {k:ℕ},x<=2^k->k+3<=256+42->x<=A_B/8:=fun {x k} h hk=>(le_div_iff₀ (by norm_num:(0:ℝ)<8)).mpr ((mul_le_mul_of_nonneg_right h (by norm_num:(0:ℝ)<=8)).trans ((((congrArg ((2:ℝ)^k*·) (by norm_num:(8:ℝ)=2^3)).trans (pow_add 2 k 3).symm).trans_le ((pow_le_pow_right₀ one_le_two hk).trans_eq (pow_add 2 256 42))).trans qCc)) have e2AB4:A_B/8<=A_B/4:=div_le_div_of_nonneg_left qI1.le (by norm_num) (by norm_num) have hmul:r*n+n<=rows*n:=by have:=Ἒ n hr;rwa [Nat.succ_mul] at this generalize hgd:(λj:ℕ=>dv x[r*n+j]!)=g;have hg0:∀ j,j< n->(g j).isFinite=true∧|R (g j)| ≤ 2^99 ∧ R (g j)=(ἂ x[r*n+j]! : ℝ):=λj h=>by obtain ⟨a1,a2⟩:=qA1 _ (qBg x sm hx (r*n+j) (by rw[hs];exact (Nat.add_lt_add_left h _).trans_le hmul));obtain ⟨a3,a4⟩:=qAm _ a1;rw[<-hgd];beta_reduce;rw[a4];exact ⟨a3,a2,qAx _ (qAe _ a1)⟩ have hnR1:(1:ℝ)<=n:=by exact_mod_cast hn0 have hnR2:(n:ℝ)<=2^20:=by exact_mod_cast hn.le have o4:((ἄ n).map λj=>|R (g j)|).sum<=n*2^99 :=qDr n _ _ λj h=>(hg0 j h).2.1;have hA2:((ἄ n).map λj=>|R (g j)|).sum<=A_B/4:=(e2AB (k:=20+99) (o4.trans ((ἀ hnR2 (by (positivity):(0:ℝ)<=2^99)).trans_eq (pow_add 2 20 99).symm)) (Nat.le_of_ble_eq_true rfl)).trans e2AB4 obtain ⟨o1,o5⟩:=qFm n hn g (λj=>R (g j)) (λj=>|R (g j)|) (λj h=>⟨(hg0 j h).1,rfl,rfl⟩) hA2 obtain ⟨o2,o6⟩:=qFm n hn (λj=>(g j).abs) (λj=>|R (g j)|) (λj=>|R (g j)|) (λj h=>by obtain ⟨p,q⟩:=qBl _ (hg0 j h).1 exact ⟨p,q,abs_abs _⟩) hA2 have o3:=qF2 (ἄ n) λj=>R (g j);obtain ⟨hMc,hVc⟩:=qHi n r x g (λj h=>(hg0 j h).2.2) (lnQ b n x r);generalize hQ:((lnQ b n x r:ℚ):ℝ)=Q at hVc;generalize hS:((ἄ n).map λj=>R (g j)).sum=S at o3 o5 hMc;generalize ((ἄ n).map λj=>|R (g j)|).sum=Sa at o3 o4 o5 o6;unfold lnStat;dsimp only;generalize hnu:ѩn=nu;generalize hbase:(r*n).toUSize=base;generalize hnd:n.toUInt64.toFloat=nd;generalize hnf:(n.toUInt64+8).toFloat*Ἃ ь=nf;generalize hind:(1.0:ὧ)/nd=ind;generalize ha:(if b=true then F1.mk 0 0 else lnSum x base nu 0 0 0)=a;generalize hm:(if b=true then (0:ὧ) else a.s*ind)=m;generalize hv:lnVar x base nu 0 m 0=v;generalize hem:nf*a.t*ind+Ἃ ظ=em;generalize htt:v*ind+dv eps=tt;generalize hd:Ἤ tt=d;generalize hz:ziv d ((nf+nf)*d+em)=z;generalize hir:(1.0:ὧ)/dv z=ir;split . rename_i hc;simp only[Bool.and_eq_true,decide_eq_true_eq] at hc;obtain ⟨⟨⟨⟨⟨c1,c2⟩,c3⟩,c4⟩,c5⟩,c6⟩:=hc;have hnp:(n:ℝ)≠0 :=(zero_lt_one.trans_le hnR1).ne';have hzb:=qBo;have hz0:=qAr.le;have hu:Ѥnu=n:=by rw[<-hnu];exact qAd n (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) have hb:Ѥbase=r*n:=by rw[<-hbase];exact qAd _ (((Nat.le_add_right _ _).trans hmul).trans_lt hrn) have hxs:ѧx<2^32 :=hs.trans_lt hrn;obtain ⟨fnf,Rnf⟩:=hnf ▸ qIi n hn;obtain ⟨c,hc⟩:∃ c:ℝ,c=((n:ℝ)+8)/2^49:=⟨_,rfl⟩;rw[<-hc] at Rnf;have hc1:c<=1/2^20:=by rw[hc];exact (div_le_div_of_nonneg_right (add_le_add hnR2 le_rfl) (by norm_num1)).trans (by norm_num1) have hc2:9/2^49<=c:=by rw[hc];exact div_le_div_of_nonneg_right ((show (9:ℝ)=1+8 by norm_num1).trans_le (add_le_add hnR1 le_rfl)) (by norm_num1) obtain ⟨fnd,Rnd⟩:nd.isFinite=true∧R nd=n:=by rw[<-hnd];have e:n.toUInt64.toNat=n:=by simp;(exact Nat.lt_of_lt_of_le ‹_› (by decide)) have:=qCk n.toUInt64 (by rw[e];exact hn.trans (by decide));rwa [e] at this obtain ⟨fi,pi,-,ei⟩:=qFy ind nd fnd (by rw[Rnd,ἅ (zero_le_one.trans hnR1)];exact hnR2.trans (by norm_num1)) c5 rw[Rnd] at ei;obtain ⟨z1,z2⟩:=qHg obtain ⟨fm,fE,m2,m3,m1,m4⟩:m.isFinite=true∧em.isFinite=true∧R em<=2^120 ∧ 1/2^201<=R em∧2 * |Q-R m| ≤ R em∧|R m| ≤ 2^110:=by cases b with | true => have e1:a=F1.mk 0 0:=ha.symm;have e2:m=0:=hm.symm;have e3:Q=0:=by rw[<-hQ];simp[lnQ] subst e1;obtain ⟨-,fE,m2,m3,-,-⟩:=qG1 n hnR1 hnR2 0 0 ind nf _ em 0 0 c hc z1 z1 ג (by positivity) (by rw[z2,sub_self,abs_zero];exact Ἆ (Ἆ zero_le_two (Ἔ n)) (Ἆ (div_nonneg zero_le_one (pow_nonneg zero_le_two 53)) (add_nonneg le_rfl hz0))) (by rw[z2,sub_self,abs_zero];exact Ἆ (Ἆ zero_le_two (Ἔ n)) (Ἆ (div_nonneg zero_le_one (pow_nonneg zero_le_two 53)) (add_nonneg le_rfl hz0))) fnf Rnf fi pi ei rfl hem;rw[e2,e3,z2];refine ⟨z1,fE,m2,m3,?_,by (norm_num1)⟩;simp only[sub_zero,abs_zero,mul_zero];exact ὂ (by positivity) m3 | false => replace ha:lnSum x base nu 0 0 0=a:=ha;replace hm:a.s*ind=m:=hm;have hA:a=⟨A_fsum ((ἄ n).map g),A_fsum ((ἄ n).map λj=>(g j).abs)⟩:=by rw[<-ha,qG9 x hxs base nu (by rw[hb,hu];exact hmul.trans_lt hrn) n 0 0 0 (by simp[hu])];simp only[USize.toNat_zero,hb,<-hgd,A_fsum,List.range_eq_range'] subst hA;rw[hQ.symm.trans hMc];exact qG1 n hnR1 hnR2 _ _ ind nf m em S Sa c hc o1 o2 o3 o4 o5 o6 fnf Rnf fi pi ei hm hem obtain ⟨p1,p2,p3,hW0⟩:=qGp n hn hn0 g m v _ (by rw[<-hv,qG2 x hxs base nu m (by rw[hb,hu];exact hmul.trans_lt hrn) n 0 0 (by simp[hu])] simp only[USize.toNat_zero,hb,<-hgd,A_fsum,List.range_eq_range']) rfl (λj h=>⟨(hg0 j h).1,(hg0 j h).2.1⟩) fm m4 generalize hW:((ἄ n).map λj=>(R (g j)-R m)^2).sum=W at p2 p3 hW0;generalize hV0:((ἄ n).map λj=>(R (g j)-Q)^2).sum=V0 at hVc;generalize hδ:Q-R m=δ at m1;have hnpos:(0:ℝ)< n :=zero_lt_one.trans_le hnR1 have hWs:W/n=V0/n+δ^2:=by cases b with | true => have e2:m=0:=hm.symm;have e3:Q=0:=by rw[<-hQ];simp[lnQ] rw[<-hδ,<-hW,<-hV0,e2,e3,z2];simp | false => have hs2:=qGh (ἄ n) (λj=>R (g j)) (R m) (by rw[List.length_range];exact hnp);simp only[List.length_range] at hs2;rw[hS,hW,show S/n=Q from (hQ.symm.trans hMc).symm,hV0,hδ] at hs2;rw[hs2,add_div,mul_div_cancel_left₀ _ hnp] obtain ⟨gE,bE⟩:=qA1 eps he;have epsv:wv eps=(ἂ eps:ℝ):=qAx _ (qAe _ gE);have hep0:0< wv eps:=by rw[epsv];exact_mod_cast he0 obtain ⟨ft,hq1⟩:=qIv n hnR1 hnR2 v ind tt eps W c hc p1 p2 p3 hW0 fi pi ei gE bE hep0 htt;generalize hq:rowVariance n x r (lnQ b n x r)+ἂ eps=q;have hV1:0<=V0/n:=by rw[<-hV0];refine div_nonneg (List.sum_nonneg λy hy=>?_) hnpos.le;obtain ⟨j,-,rfl⟩:=List.mem_map.1 hy;exact ὅ _ have hT:(q:ℝ)=(W/n+wv eps)-δ^2:=by rw[<-hq,Rat.cast_add,hVc,epsv,hWs];ring have hT0:(0:ℝ)< q:=by rw[hT,hWs,add_sub_right_comm,add_sub_cancel_right];exact add_pos_of_nonneg_of_pos hV1 hep0 have hP0:0< W/n+wv eps:=add_pos_of_nonneg_of_pos (div_nonneg hW0 hnpos.le) hep0 obtain ⟨r1,r2⟩:1<=_∧_<1+1222:=qEj _ 1 1222 c4 (by decide);obtain ⟨l1,l2,hb127⟩:=qIk tt nf em _ r1 (by exact Nat.le_of_lt_succ ‹_›) rfl c _ δ (q:ℝ) hc1 hc2 fnf Rnf fE m2 m3 hP0 hq1 m1 hT hT0;rw[hd] at l1 l2;have hq0:0< q:=by exact_mod_cast hT0 have hzne:ziv d ((nf+nf)*d+em)≠Е:=by rw[hz];intro e0;rw[e0] at c3;exact absurd c3 (by decide) have hden:=((qGs d _ q hq0 l1 l2 hzne hb127).trans hz).symm;rw[<-hq] at hden;obtain ⟨gZ,bZ⟩:=qA1 z c1;obtain ⟨dz1,dz2⟩:=qAm z gZ;obtain ⟨fi2,-,-,ei2⟩:=qFy ir (dv z) dz1 (by rw[dz2];exact bZ) c6;rw[dz2] at ei2;refine ⟨hden,λ_=>⟨fm,fi2,fE,m2,m3,?_,m4,gZ,qIb z gZ c2 c3,ei2⟩⟩;dsimp only;rw[hQ,hδ];exact m1 . exact ⟨rfl,λh=>Bool.noConfusion h⟩ lemma qI0b (m ir em:ὧ) (w gw bw:Ὢ) (M D:ℝ) (fm:m.isFinite=true) (fi:ir.isFinite=true) (fe:em.isFinite=true) (e1:R em<=2^120) (e2:1/2^201<=R em) (e3:2 * |M-R m| ≤ R em) (e4 : |R m| ≤ 2^110) (hD:1/2^64<=D) (hI : |R ir*D-1| ≤ 1/2^48) (hw:sm w=true) (hg:sm gw=true) (hb:sm bw=true) (s e:ὧ) (hs:s=(dv w-m)*(dv gw*ir)+dv bw) (he:e=Ἃ 0x3D10000000000000*(((dv w-m)*(dv gw*ir)).abs+(dv bw).abs) + em*(dv gw*ir).abs) (big0:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) : R (s-e)<(wv w-M)*wv gw/D+wv bw∧(wv w-M)*wv gw/D+wv bw< R (s+e):=by have e2le:∀ {k:ℕ},k<=300->(2:ℝ)^k<=2^256*2^44:=fun h=>(pow_le_pow_right₀ one_le_two h).trans_eq (pow_add 2 256 44) have e2pf:∀ {x P:ℝ},x<=9/8*P+A_z->1<=P->x<=2^2*P:=fun {x P} h h1=>h.trans ((add_le_add (mul_le_mul_of_nonneg_right (by norm_num1:(9:ℝ)/8<=3) (zero_le_one.trans h1)) (qBo.trans h1)).trans ((add_one_mul (3:ℝ) P).symm.trans (congrArg (·*P) (by norm_num1:(3:ℝ)+1=2^2))).le) have e2pk:∀ {x:ℝ} {a k:ℕ},x<=9/8*((2:ℝ)^a+2^a)+A_z->2+(a+1)<=k->x<=2^k:=fun {x a k} h hk=>(e2pf (h.trans_eq (congrArg (fun P:ℝ=>9/8*P+A_z) ((two_mul _).symm.trans (pow_succ' 2 a).symm))) (one_le_pow₀ one_le_two)).trans ((pow_add 2 2 (a+1)).symm.trans_le (pow_le_pow_right₀ one_le_two hk)) have e2pm:∀ {x:ℝ} {a b k:ℕ},x<=9/8*((2:ℝ)^a*2^b)+A_z->2+(a+b)<=k->x<=2^k:=fun {x a b k} h hk=>(e2pf (h.trans_eq (congrArg (fun P:ℝ=>9/8*P+A_z) (pow_add 2 a b).symm)) (one_le_pow₀ one_le_two)).trans ((pow_add 2 2 (a+b)).symm.trans_le (pow_le_pow_right₀ one_le_two hk)) have e2p1:∀ {x:ℝ} {b k:ℕ},x<=9/8*(1*(2:ℝ)^b)+A_z->2+b<=k->x<=2^k:=fun {x b k} h hk=>(e2pf (h.trans_eq (congrArg (fun P:ℝ=>9/8*P+A_z) (one_mul _))) (one_le_pow₀ one_le_two)).trans ((pow_add 2 2 b).symm.trans_le (pow_le_pow_right₀ one_le_two hk)) have hzb:=qBo obtain ⟨gw1,bw1⟩:=qA1 w hw obtain ⟨gg1,bg1⟩:=qA1 gw hg obtain ⟨gb1,bb1⟩:=qA1 bw hb obtain ⟨fw,Rw⟩:=qAm w gw1 obtain ⟨fg,Rg⟩:=qAm gw gg1 obtain ⟨fb,Rb⟩:=qAm bw gb1 have hD0:0< D:=Ἥ (by positivity) hD have bI : |R ir| ≤ 2^65:=by have a1:=qAa (R ir*D) 1 rw[abs_one,ἢ,ἡ hD0] at a1 have a2:=ἁ hD (Ἀ (R ir)) have a3:=(a2.trans (a1.trans (add_le_add le_rfl (hI.trans (div_le_one_of_le₀ (one_le_pow₀ one_le_two) (pow_nonneg zero_le_two 48)))))).trans_eq one_add_one_eq_two rw[mul_one_div] at a3 exact ((div_le_iff₀ (pow_pos two_pos 64)).mp a3).trans_eq (pow_succ' 2 64).symm obtain ⟨f1,h1,b1⟩:=qCg (dv w) m (2^111) fw fm (by rw[Rw];exact bw1.trans (pow_le_pow_right₀ one_le_two (Nat.le_of_ble_eq_true rfl))) (e4.trans (pow_le_pow_right₀ one_le_two (Nat.le_of_ble_eq_true rfl))) (e2le (Nat.le_of_ble_eq_true rfl)) rw[Rw] at h1 obtain ⟨f2,h3,b2⟩:=qAl (dv gw) ir (2^99) (2^65) fg fi (by rw[Rg];exact bg1) bI (e2le (Nat.le_of_ble_eq_true rfl)) (e2le (Nat.le_of_ble_eq_true rfl)) rw[Rg] at h3 obtain ⟨f3,h4,b3⟩:=qAl _ _ (2^114) (2^166) f1 f2 (e2pk b1 le_rfl) (e2pm b2 (Nat.le_of_ble_eq_true rfl)) (e2le (Nat.le_of_ble_eq_true rfl)) (e2le (Nat.le_of_ble_eq_true rfl)) generalize hQ:(dv w-m)*(dv gw*ir)=Q at hs he f3 h4 b3 generalize dv gw*ir=G at he f2 h3 b2 h4 hQ have bQ:=e2pm (k:=282) b3 (Nat.le_of_ble_eq_true rfl) have bB : |R (dv bw)| ≤ 2^282:=by rw[Rb];exact bb1.trans (pow_le_pow_right₀ one_le_two (Nat.le_of_ble_eq_true rfl)) obtain ⟨f4,h5,b4⟩:=qAv Q (dv bw) (2^282) f3 fb bQ bB (e2le (Nat.le_of_ble_eq_true rfl)) rw[Rb,<-hs] at h5 rw[<-hs] at f4 b4 obtain ⟨fa1,Ra1⟩:=qBl Q f3 obtain ⟨fa2,Ra2⟩:=qBl (dv bw) fb rw[Rb] at Ra2 obtain ⟨fa3,Ra3⟩:=qBl G f2 obtain ⟨f5,h6,b5⟩:=qAv Q.abs (dv bw).abs (2^282) fa1 fa2 (by rw[Ra1,abs_abs];exact bQ) (by rw[Ra2,abs_abs,<-Rb];exact bB) (e2le (Nat.le_of_ble_eq_true rfl)) rw[Ra1,Ra2] at h6 obtain ⟨k1,k2⟩:=L_k 0x3D10000000000000 977 46 (Nat.le_of_ble_eq_true rfl) rfl (by rfl) obtain ⟨f6,h7,b6⟩:=qAl _ _ 1 (2^285) k1 f5 (by rw[k2,abs_of_nonneg (by positivity)];exact div_le_one_of_le₀ (one_le_pow₀ one_le_two) (by positivity)) (e2pk b5 le_rfl) ((pow_zero (2:ℝ)).symm.trans_le (e2le (Nat.le_of_ble_eq_true rfl))) (e2le (Nat.le_of_ble_eq_true rfl)) rw[k2] at h7 have bE : |R em| ≤ 2^120:=by rw[ἅ (ὂ (by positivity) e2)];exact e1 obtain ⟨f7,h8,b7⟩:=qAl em G.abs (2^120) (2^166) fe fa3 bE (by rw[Ra3,abs_abs];exact e2pm b2 (Nat.le_of_ble_eq_true rfl)) (e2le (Nat.le_of_ble_eq_true rfl)) (e2le (Nat.le_of_ble_eq_true rfl)) rw[Ra3] at h8 obtain ⟨f8,h9,b8⟩:=qAv _ _ (2^288) f6 f7 (e2p1 b6 (Nat.le_of_ble_eq_true rfl)) (e2pm b7 (Nat.le_of_ble_eq_true rfl)) (e2le (Nat.le_of_ble_eq_true rfl)) rw[<-he] at f8 h9 b8 have bs:=e2pk (k:=291) b4 (Nat.le_of_ble_eq_true rfl) have be:=e2pk (k:=291) b8 (Nat.le_of_ble_eq_true rfl) obtain ⟨f9,h10,-⟩:=qAv s e (2^291) f4 f8 bs be (e2le (Nat.le_of_ble_eq_true rfl)) obtain ⟨f10,h11,-⟩:=qCg s e (2^291) f4 f8 bs be (e2le (Nat.le_of_ble_eq_true rfl)) have big:=big0 rw[zpow_neg,zpow_ofNat,<-one_div] at big exact qG0 qAr.le qAw (ὂ (by positivity) e2) e1 e3 hD bw1 bg1 e4 h1 hI h3 h4 h5 h6 h7 h8 h9 h10 h11 big lemma kHq (th:Ὠ) (s:ὧ) (q:ℚ) (hV : |R s-(q:ℝ)| ≤ 1/2^33*(|(q:ℝ)| + A_z)) (hb : |(q:ℝ)| ≤ 2^(127:ℤ)) (h:zivT th s≠Е):roundRational q=zivT th s:=by obtain ⟨-,S,ex,fr,M,h1,h2,h3,hz,hbt,hl,hu⟩:=kFh th s h have hM:M=(M/2^52)*2^52+M%2^52 :=(by clear h h1 h2 h3 hz hbt hl hu; exact omS114) have hF:M%2^52<2^52:=ὀ _ (by positivity) generalize M/2^52=E at hM generalize M%2^52=F at hM hF subst hM obtain ⟨-,hR⟩:=B_R s S E F (by clear h hz; exact omS238 h1 hF hl) (by clear h hz; exact omS239 h2 h3 hu) hF (by rw[hbt,ὢ]) rw[hR] at hV obtain ⟨W,hVW,hW⟩:∃ W:ℝ,(q:ℝ)=(if S then -W else W) ∧ |((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-W| ≤ 1/2^33*(|W| + A_z):=by cases S . simp only[false_eq_true,ite_false,one_mul] at hV ⊢;exact ⟨_,rfl,hV⟩ . simp only[ite_true] at hV ⊢;refine ⟨-(q:ℝ),by simp,?_⟩;rw[abs_neg,show ((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075) - -(q:ℝ) =-(-1*((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-(q:ℝ)) by ring,abs_neg];exact hV obtain ⟨a,b,c⟩:=qJi ex fr E F h1 h2 h3 hF (by exact omS240 hl) (by exact omS241 hu) W hW have hb0:(0:ℝ)<2^((ex:Int)-1076):=ἵ (by positivity) _ have hW0:0simp at hVW<;>linarith only [hW0, hVW] have hf:=Model.isFinite_roundRatScaled_of_abs_le_posMaxFinite Fmt (decide (q<0)) q.num.natAbs q.den 0 (by decide) q.den_nz (qFn q ▸ hb.trans qIx) have hMr:=Model.toReal_roundRatScaled_eq_roundAt Fmt _ _ _ 0 (by decide) hf rw[hz] exact qDqW S ex fr h1 h2 h3 (q:ℝ) W hVW a b c _ hf (qFn q ▸ hMr) lemma qSubE (x y:ὧ) (hx:xᶠ) (hy:yᶠ) (h1 : |R x| ≤ A_B) (h2 : |R y| ≤ A_B) : (x-y)ᶠ ∧ R (x-y)=Model.roundAt ⟡ (R x-R y) := A_E _ (toModel_ofFloat_sub_of_isFinite x y hx hy) (Model.isFinite_sub_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2)) (Model.toReal_sub_eq_roundAt_of_abs_add_le_posMaxFinite _ _ qAj (qA3 hx) (qA3 hy) (qEe h1 h2)) lemma rAbs (x:ℝ) : |Model.roundAt ⟡ x| = Model.roundAt ⟡ |x| := by rcases le_or_gt 0 x with h|h . rw[abs_of_nonneg h,abs_of_nonneg];rw[<-Model.roundAt_zero ⟡];exact Model.roundAt_mono _ h . rw[abs_of_neg h,abs_of_nonpos];. rw[Model.roundAt_neg ⟡ x .nearest];rfl . rw[<-Model.roundAt_zero ⟡];exact Model.roundAt_mono _ h.le lemma rUp (y:ℝ) (h:0<=y) : Model.roundAt ⟡ y<=2*y+1 := by have e:=qFp y have hz:A_z<=1:=by show (2:ℝ)^(-1021:ℤ)<=1;exact zpow_le_one_of_nonpos₀ (by norm_num) (by norm_num) rw[abs_of_nonneg h] at e have:=le_abs_self (Model.roundAt ⟡ y-y) nlinarith only [e,this,hz,h] set_option maxRecDepth 8192 in lemma mMul (a b c d:ὧ) (fa:aᶠ) (fb:bᶠ) (fc:cᶠ) (fd:dᶠ) (ha : |R a| ≤ R c) (hb : |R b| ≤ R d) (Bc Bd:ℝ) (hc:R c<=Bc) (hd:R d<=Bd) (hB:Bc*Bd<=2^256*2^256*2^256) : (a*b)ᶠ ∧ (c*d)ᶠ ∧ |R (a*b)| ≤ R (c*d) ∧ R (c*d)<=2*(Bc*Bd)+1 := by have pc:0<=R c:=(abs_nonneg _).trans ha have pd:0<=R d:=(abs_nonneg _).trans hb have k9:(2:ℝ)^256*2^256*2^256<=2^(1000:ℤ):=by rw[<-pow_add,<-pow_add,<-zpow_natCast];exact zpow_le_zpow_right₀ (by norm_num) (by norm_num) have hcd:R c*R d<=Bc*Bd:=mul_le_mul hc hd pd (pc.trans hc) obtain ⟨f1,R1⟩:=qEd a b fa fb ((mul_le_mul ha hb (abs_nonneg _) pc).trans (hcd.trans (hB.trans k9))) obtain ⟨f2,R2⟩:=qEd c d fc fd (by rw[abs_of_nonneg pc,abs_of_nonneg pd];exact hcd.trans (hB.trans k9)) refine ⟨f1,f2,?_,?_⟩ . rw[R1,R2,rAbs,abs_mul];exact Model.roundAt_mono _ (mul_le_mul ha hb (abs_nonneg _) pc) . rw[R2];exact (rUp _ (mul_nonneg pc pd)).trans (by linarith only [hcd]) set_option maxRecDepth 8192 in lemma mAdd (a b c d:ὧ) (fa:aᶠ) (fb:bᶠ) (fc:cᶠ) (fd:dᶠ) (ha : |R a| ≤ R c) (hb : |R b| ≤ R d) (Bc Bd:ℝ) (hc:R c<=Bc) (hd:R d<=Bd) (hB:Bc+Bd<=2^256*2^40) : (a+b)ᶠ ∧ (c+d)ᶠ ∧ |R (a+b)| ≤ R (c+d) ∧ R (c+d)<=2*(Bc+Bd)+1 := by have pc:0<=R c:=(abs_nonneg _).trans ha have pd:0<=R d:=(abs_nonneg _).trans hb have k1:Bc<=2^256*2^44:=by nlinarith only [hB,pc,pd,hc,hd] have k2:Bd<=2^256*2^44:=by nlinarith only [hB,pc,pd,hc,hd] obtain ⟨f1,R1⟩:=qAddE a b fa fb (qAt (ha.trans (hc.trans k1))) (qAt (hb.trans (hd.trans k2))) obtain ⟨f2,R2⟩:=qAddE c d fc fd (qAt (by rw[abs_of_nonneg pc];exact hc.trans k1)) (qAt (by rw[abs_of_nonneg pd];exact hd.trans k2)) refine ⟨f1,f2,?_,?_⟩ . rw[R1,R2,rAbs];exact Model.roundAt_mono _ ((abs_add_le _ _).trans (add_le_add ha hb)) . rw[R2];exact (rUp _ (add_nonneg pc pd)).trans (by linarith only [hc,hd]) set_option maxRecDepth 8192 in lemma mSub (a b c d:ὧ) (fa:aᶠ) (fb:bᶠ) (fc:cᶠ) (fd:dᶠ) (ha : |R a| ≤ R c) (hb : |R b| ≤ R d) (Bc Bd:ℝ) (hc:R c<=Bc) (hd:R d<=Bd) (hB:Bc+Bd<=2^256*2^40) : (a-b)ᶠ ∧ (c+d)ᶠ ∧ |R (a-b)| ≤ R (c+d) ∧ R (c+d)<=2*(Bc+Bd)+1 := by have pc:0<=R c:=(abs_nonneg _).trans ha have pd:0<=R d:=(abs_nonneg _).trans hb have k1:Bc<=2^256*2^44:=by nlinarith only [hB,pc,pd,hc,hd] have k2:Bd<=2^256*2^44:=by nlinarith only [hB,pc,pd,hc,hd] obtain ⟨f1,R1⟩:=qSubE a b fa fb (qAt (ha.trans (hc.trans k1))) (qAt (hb.trans (hd.trans k2))) obtain ⟨f2,R2⟩:=qAddE c d fc fd (qAt (by rw[abs_of_nonneg pc];exact hc.trans k1)) (qAt (by rw[abs_of_nonneg pd];exact hd.trans k2)) refine ⟨f1,f2,?_,?_⟩ . rw[R1,R2,rAbs];exact Model.roundAt_mono _ ((abs_sub _ _).trans (add_le_add ha hb)) . rw[R2];exact (rUp _ (add_nonneg pc pd)).trans (by linarith only [hc,hd]) set_option maxRecDepth 8192 in lemma qLmo (m ir em xm gm bm:ὧ) (w gw bw:Ὢ) (fm:mᶠ) (fi:irᶠ) (fe:emᶠ) (fxm:xmᶠ) (fgm:gmᶠ) (fbm:bmᶠ) (hw:sm w=true) (hg:sm gw=true) (hb:sm bw=true) (pir:0?_⟩ . rw[Rf];exact (le_abs_self _).trans b99 . obtain ⟨-,Rk⟩:=qAm _ (g3 k hk);rw[Rk,Rf];exact mono _ (g3 k hk) (g4 k hk) set_option maxRecDepth 8192 in lemma qUb (E s:ὧ) (h1:(s.toBits <<< (1:Ὠ))-loOf E< spOf (loOf E)) (h2:(s.toBits+0x0FDFFFFF) &&& 0x1FFFFFFF<0x1FC00000) : |R s| ≤ 2^(126:ℤ):=by obtain ⟨-,h⟩:=qHy E s h1 h2 obtain ⟨-,S,ex,fr,M,a1,a2,a3,-,hb,hl,hu⟩:=kFh _ s h have hhi:=(kD1 _ _ h1).2 have hM63:M<2^63:=by clear h h1 h2 hhi; exact omS264 a2 a3 hu have hsh:=qJb s.toBits S M hM63 hb have hlt:2*M<0x8FA0000000000000:=by have:=ἴ.mp hhi;rw[hsh] at this;exact this have hM:M=(M/2^52)*2^52+M%2^52 :=(by clear h h1 h2 hb hl hu hhi hsh hlt; exact omS114) have hF:M%2^52<2^52:=ὀ _ (by positivity) generalize M/2^52=E' at hM generalize M%2^52=F at hM hF subst hM have hE1:E'<=1148:=by clear h h1 h2 hb hl hu hhi hsh; exact omS357 hlt have hE0:1<=E':=by clear h h1 h2 hb hhi hsh hlt; exact omS238 a1 hF hl obtain ⟨-,hR⟩:=B_R s S E' F hE0 (by exact omS358 hE1) hF (by rw[hb,ὢ]) rw[hR] have p:(0:ℝ)<2^((E':ℤ)-1075):=by positivity have q3:((2^52+F:Ὣ):ℝ)<=2^(53:ℤ):=by push_cast;have:(F:ℝ)<2^52:=by exact_mod_cast hF rw[show (2:ℝ)^(53:ℤ)=2^52+2^52 by norm_num];linarith only [this] have q4:(2:ℝ)^(53:ℤ)*2^((E':ℤ)-1075)<=2^(126:ℤ):=by rw[<-zpow_add₀ (by norm_num)];exact zpow_le_zpow_right₀ (by norm_num) (by exact omS359 hE1) have q5:((2^52+F:Ὣ):ℝ)*2^((E':ℤ)-1075)<=2^(126:ℤ):=(mul_le_mul_of_nonneg_right q3 p.le).trans q4 cases S<;>simp only[Bool.false_eq_true,ite_false,ite_true,one_mul,neg_mul,abs_neg,abs_mul,abs_of_pos p]<;>rw[abs_of_nonneg (by positivity)]<;>exact q5 set_option maxRecDepth 8192 in lemma qEkF (s:LnS) (M:ℚ) (mean:Unit->ℚ) (hmean:mean ()=M) (w gw bw:Ὢ) (hw:sm w=true) (hg:sm gw=true) (hb:sm bw=true) (h:L_oF s (M:ℝ)) (xm gm bm:ὧ) (fxm:xmᶠ) (fgm:gmᶠ) (fbm:bmᶠ) (hxm : |R (dv w)| ≤ R xm) (hgm : |R (dv gw)| ≤ R gm) (hbm : |R (dv bw)| ≤ R bm) (bxm:R xm<=2^99) (bgm:R gm<=2^99) (bbm:R bm<=2^99) : lnOut s (loOf (lnEB s xm gm bm)) w gw bw mean=roundRational ((ἂ w-M)*ἂ gw/ἂ s.den+ἂ bw):=by unfold lnOut lnOutF split . rename_i hf;obtain ⟨fm,fi,fe,e1,e2,e3,e4,gd,hD,hI⟩:=h hf have ew:=qAx w (qAe _ (qA1 w hw).1);have eg:=qAx gw (qAe _ (qA1 gw hg).1);have eb:=qAx bw (qAe _ (qA1 bw hb).1);have ed:=qAx s.den (qAe _ gd);have hV:(((ἂ w-M)*ἂ gw/ἂ s.den+ἂ bw:ℚ):ℝ) =(wv w-M)*wv gw/wv s.den+wv bw:=by rw[ew,eg,eb,ed];push_cast;ring unfold lnFa;dsimp only;split . split;. unfold lnSlow;rw[hmean] . rename_i _ hc have hne:ziv ((dv w-s.m)*(dv gw*s.ir)+dv bw) (Ἃ 0x3D10000000000000*(((dv w-s.m)*(dv gw*s.ir)).abs+(dv bw).abs) + s.em*(dv gw*s.ir).abs)≠Е:=λe0=>by rw[e0] at hc exact hc (by decide) obtain ⟨l1,l2⟩:=qI0b s.m s.ir s.em w gw bw M (wv s.den) fm fi fe e1 e2 e3 e4 hD hI hw hg hb _ _ rfl rfl (qBw _ _ hne).2.2 rw[<-hV] at l1 l2;exact (qH7 _ _ _ l1 l2 hne (qIu _ _ _ l1 l2 hne hc)).symm . rename_i hne have key:fin1 (loOf (lnEB s xm gm bm)) (spOf (loOf (lnEB s xm gm bm))) ((dv w-s.m)*(dv gw*s.ir)+dv bw)≠Е:=by simpa using hne unfold fin1 at key ⊢ dsimp only at key ⊢ split at key . rename_i ht simp only[Bool.and_eq_true,decide_eq_true_eq] at ht obtain ⟨h1,h2⟩:=ht rw[if_pos (by simp only[Bool.and_eq_true,decide_eq_true_eq];exact ⟨h1,h2⟩)] have hD0:0< wv s.den:=lt_of_lt_of_le (by positivity) hD have pir:0< R s.ir:=by have q:0α) (hk:k< rows) : (Array.ofFn (n:=rows) λr=>f r.val)[k]! = f k:=by rw[Ἕ _ k (by simpa using hk),Array.getElem_ofFn] lemma qMf (f:Ὣ->Ὢ) (L:љ) (a:ℤ): L.foldl (λt j=>t+ἂ (f j)) ((a:ℚ)/2^149)=((L.foldl (λt j=>t+sv (f j)*((2^idxOf (f j):ℕ):ℤ)) a:ℤ):ℚ)/2^149:=by induction L generalizing a with | nil=>rfl | cons p L ih=> simp only[List.foldl_cons] rw[<-ih] congr 1 have e:ἂ (f p)=(sv (f p):ℚ)*2^((idxOf (f p):ℤ)-149):=by rw[rationalWord,decodeD_toRat] rw[e,zpow_sub₀ (by (positivity):(2:ℚ)≠0),zpow_natCast] push_cast ring lemma qMq (n:Ὣ) (x:ё) (r:Ὣ):meanQ n x r=rowMean n x r:=by have h:=qMf (λj=>x[r*n+j]!) (ἄ n) 0 simp only[Int.cast_zero,zero_div] at h unfold meanQ meanI rowMean rw[h] by_cases c:(n:ℚ)=0 . simp[c] . push_cast;rw[div_div];norm_num lemma qGD {A:ё} {n:ὦ} (hs:ѧA<2^32) (d:Ὣ) : ∀ (t:ὦ) (o:ὤ),Ѥt+d=Ѥn→(Ѥn<=Ѩo∧Ѩo<2^32)→(∀ k,k< Ѥt->o.data[k]! = dv A[k]!) → (Ѥn<=(decG A n t o).size∧(decG A n t o).size<2^32)∧∀ k,k< Ѥn->(decG A n t o).data[k]! = dv A[k]!:=by induction d with | zero=> intro t o he H1 H2 rw[decG,ἔ (by rw[А];(clear hs H1; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))))] have e:Ѥt=Ѥn:=(by omega) rw[e] at H2 exact ⟨H1,H2⟩ | succ d ih=> intro t o he H1 H2 have ht:t< n:=by rw[А];(clear hs H1; exact omS136 he) have hu:=usz t n ht have r0:rdW A t=A[Ѥt]!:=qAg _ _ hs rw[decG,Ἄ ht,r0] refine ih (t+1) _ (by rw[hu];(clear hs H1 ht hu r0; omega)) ⟨by rw[qD6];exact H1.1,by rw[qD6];exact H1.2⟩ ?_ intro k hk rw[hu] at hk rw[qEt _ _ _ _ H1.2 (by have:=H1.1;have:=А.mp ht;(exact Nat.lt_of_lt_of_le ‹_› ‹_›))] by_cases e:k=Ѥt . rw[ἱ e,e] . rw[ἐ e];exact H2 k (by (clear hs H1 ht r0; omega)) lemma qGR {A:ё} {n:Ὣ} (hs:ѧA<2^32) (hn:n<2^32) (u:ὦ) (hu:Ѥu< n):rdF (decG A ѩn 0 (zFor n)) u=dv A[Ѥu]!:=by have ek:n.toUSize.toNat=n:=qAd _ (by exact Nat.succ_le_of_lt ‹_›) have P0:=qZf n hn obtain ⟨⟨D1,D2⟩,D3⟩:=qGD (A:=A) (n:=ѩn) hs n 0 (zFor n) (by rw[ek,C_z,Ἇ]) (by rw[ek];exact P0) (λk hk=>by rw[C_z] at hk;(clear hs hn hu ek P0; omega)) rw[ek] at D1 D3 generalize decG A ѩn 0 (zFor n)=a at D1 D2 D3 ⊢ have h:u< a.usize:=by rw[А];have e:a.usize.toNat=Ѩa:=by show (a.size.toUSize).toNat=Ѩa exact qAd _ D2 rw[e];(exact Nat.lt_of_lt_of_le ‹_› ‹_›) unfold rdF rw[Ἄ h,qC5,D3 _ hu] lemma qGS {r:Ὣ} {A:ё} {n:Ὣ} (hs:ѧA<2^32) (hn:n<2^32) (u:ὦ) (hu:Ѥu< n):gdR r A (gdF r A n) u=dv A[Ѥu]!:=by unfold gdR gdF by_cases c:(r == 1)=true . rw[ἱ c,qAg _ _ hs] . rw[ἐ c,ἐ c];exact qGR hs hn u hu lemma qSm (A:ё) (hs:ѧA<2^32) (h:smA A=true):A.all sm=true∧A.all finiteWord=true:=by unfold smA at h dsimp only at h rw[Bool.and_eq_true] at h obtain ⟨h1,h2⟩:=h have hh:=of_decide_eq_true h2 obtain ⟨-,-,c3,c4⟩:=qBi A hs (by simpa using h1) constructor . rw[Array.all_eq_true] intro i hi have g:=c3 i hi have l:=c4 i hi rw[Ἕ A i hi] at g l unfold sm rw[Bool.and_eq_true] exact ⟨g,decide_eq_true (UInt32.le_trans l hh)⟩ . rw[Array.all_eq_true] intro i hi have g:=c3 i hi rw[Ἕ A i hi] at g simp[finiteWord,qAe _ g] lemma qEq0 (w:ὥ) (h1:signOf w=false) (h2:0< mantOf w):0ℚ):lnOutF s lo w gw bw gv bv mean=lnFa s.m s.ir s.em s.den w gw bw gv bv lo mean:=by unfold lnOutF;rw[ἱ h] lemma lnRF_eq {rows:Ὣ} {x g b:ё} {G B G0 B0:ὤ} {s:LnS} {mean:Unit->ℚ} {lo:Ὠ} {base n:ὦ} (hf:s.fast=true) (hG:∀ u:ὦ,Ѥu<Ѥn->rdF G u=gdR rows g G0 u) (hB:∀ u:ὦ,Ѥu<Ѥn->rdF B u=gdR rows b B0 u) (k:Ὣ) : ∀ (j:ὦ) (o:ё),Ѥj+k=Ѥn->lnRF x g b G B s.m s.ir s.em s.den mean lo (spOf lo) base n j o= fC (λs p j=>lnOutF s.1 s.2.2 (rdW x p) (rdW g j) (rdW b j) (gdR rows g G0 j) (gdR rows b B0 j) s.2.1) (s,mean,lo) base j o k:=by induction k with | zero=> intro j o e rw[lnRF,ἔ (by rw[А];(exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))),fC] | succ k ih=> intro j o e have hj:j< n:=А.2 (by exact omS136 e) rw[lnRF,Ἄ hj,fC,ih (j+1) _ (by rw[usz j n hj];(clear hj; omega))] dsimp only rw[lnFa_eq s hf lo,hG j (by (exact Nat.succ_le_of_lt ‹_›)),hB j (by (exact Nat.succ_le_of_lt ‹_›))] try rfl lemma lnRS_eq {rows:Ὣ} {x g b:ё} {G0 B0:ὤ} {s:LnS} {mean:Unit->ℚ} {lo:Ὠ} {base n:ὦ} (hf:s.fast=false) (k:Ὣ) : ∀ (j:ὦ) (o:ё),Ѥj+k=Ѥn->lnRS x g b s.den mean base n j o= fC (λs p j=>lnOutF s.1 s.2.2 (rdW x p) (rdW g j) (rdW b j) (gdR rows g G0 j) (gdR rows b B0 j) s.2.1) (s,mean,lo) base j o k:=by have e:∀ (w gw bw:Ὢ) (gv bv:ὧ),lnOutF s lo w gw bw gv bv mean=lnSlow w gw bw s.den mean:=by intro w gw bw gv bv;unfold lnOutF;rw[ἐ (by rw[hf];decide)] induction k with | zero=> intro j o e rw[lnRS,ἔ (by rw[А];(exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))),fC] | succ k ih=> intro j o e' have hj:j< n:=А.2 (by exact omS136 e') rw[lnRS,Ἄ hj,fC,ih (j+1) _ (by rw[usz j n hj];(clear hj; omega))] dsimp only rw[e] lemma lnRows_eq {rows n:Ὣ} {x g b:ё} {G B G0 B0:ὤ} {eps:Ὢ} {xm gm bm:ὧ} (hn:n<2^32) (hG:∀ u:ὦ,Ѥu< n->rdF G u=gdR rows g G0 u) (hB:∀ u:ὦ,Ѥu< n->rdF B u=gdR rows b B0 u) (d:Ὣ) : ∀ (r:Ὣ) (o:ё),lnRows x g b G B eps xm gm bm n r o d=fR (λr=>(lnStat false n eps x r,λ_:Unit=>meanQ n x r,loOf (lnEB (lnStat false n eps x r) xm gm bm))) (λs p j=>lnOutF s.1 s.2.2 (rdW x p) (rdW g j) (rdW b j) (gdR rows g G0 j) (gdR rows b B0 j) s.2.1) n r o d:=by have hu:(ѩn:ὦ).toNat=n:=qAd n hn induction d with | zero=>intro r o;rfl | succ d ih=> intro r o rw[lnRows,fR,ih] try dsimp only congr 1 split . rename_i hf exact lnRF_eq hf (λu h=>hG u (by rw[hu] at h;exact h)) (λu h=>hB u (by rw[hu] at h;exact h)) n 0 o (by rw[hu];simp) . rename_i hf exact lnRS_eq (by simpa using hf) n 0 o (by rw[hu];simp) lemma lnDecB_dat (x:ё) (base n:ὦ) (hs:Ѥbase+Ѥn<2^32) (hxs:ѧx<2^32) (k:Ὣ) : ∀ (j:ὦ) (buf:ὤ) (t s:ὧ),Ѥn+1< Ѩbuf → Ѩbuf<2^32 → Ѥj+k=Ѥn → ∀ q,q< Ѥn → (lnDecB x base n j buf t s).data[q]! = if Ѥj<=q then dv x[Ѥbase+q]! else buf.data[q]!:=by induction k with | zero=> intro j buf t s hb hbs e q hq have e1:=uS1 n (by omega) rw[lnDecB,ἔ (by rw[А];omega),qEt _ _ _ _ (by rw[qD6];exact hbs) (by rw[qD6,e1];exact hb),ἐ (by rw[e1];omega),qEt _ _ _ _ hbs (by omega),ἐ (by omega),ἐ (by omega)] | succ k ih=> intro j buf t s hb hbs e q hq have hj:j< n:=А.2 (by omega) have hj1:=А.mp hj rw[lnDecB,Ἄ hj];dsimp only rw[ih (j+1) _ _ _ (by rw[qD6];exact hb) (by rw[qD6];exact hbs) (by rw[usz j n hj];omega) q hq,qEt _ _ _ _ hbs (by omega),usz j n hj,qAg _ _ hxs,qAf base j (by omega)] by_cases h1:q=Ѥj . subst h1;rw[ἐ (by omega),ἱ rfl,ἱ (by omega)] . by_cases h2:Ѥj+1<=q . rw[ἱ h2,ἱ (by omega)] . rw[ἐ h2,ἐ h1,ἐ (by omega)] lemma lnDecB_t (x:ё) (base n:ὦ) (k:Ὣ) : ∀ (j:ὦ) (buf:ὤ) (s t:ὧ),Ѥn+1< Ѩbuf → Ѩbuf<2^32 → Ѥj+k=Ѥn → (lnDecB x base n j buf t s).data[Ѥn]! = (lnSum x base n j s t).t:=by induction k with | zero=> intro j buf s t hb hbs e have e1:=uS1 n (by omega) rw[lnDecB,lnSum,ἔ (by rw[А];omega),ἔ (by rw[А];omega),qEt _ _ _ _ (by rw[qD6];exact hbs) (by rw[qD6,e1];exact hb),ἐ (by rw[e1];omega),qEt _ _ _ _ hbs (by omega),ἱ rfl] | succ k ih=> intro j buf s t hb hbs e have hj:j< n:=А.2 (by omega) rw[lnDecB,lnSum,Ἄ hj,Ἄ hj];dsimp only exact ih (j+1) _ _ _ (by rw[qD6];exact hb) (by rw[qD6];exact hbs) (by rw[usz j n hj];omega) lemma lnDecB_s (x:ё) (base n:ὦ) (k:Ὣ) : ∀ (j:ὦ) (buf:ὤ) (s t:ὧ),Ѥn+1< Ѩbuf → Ѩbuf<2^32 → Ѥj+k=Ѥn → (lnDecB x base n j buf t s).data[Ѥn+1]! = (lnSum x base n j s t).s:=by induction k with | zero=> intro j buf s t hb hbs e have e1:=uS1 n (by omega) rw[lnDecB,lnSum,ἔ (by rw[А];omega),ἔ (by rw[А];omega),qEt _ _ _ _ (by rw[qD6];exact hbs) (by rw[qD6,e1];exact hb),ἱ (by rw[e1])] | succ k ih=> intro j buf s t hb hbs e have hj:j< n:=А.2 (by omega) rw[lnDecB,lnSum,Ἄ hj,Ἄ hj];dsimp only exact ih (j+1) _ _ _ (by rw[qD6];exact hb) (by rw[qD6];exact hbs) (by rw[usz j n hj];omega) lemma lnVarB_eq (x:ё) (buf:ὤ) (base n:ὦ) (hb:Ѥn<=Ѩbuf) (hs:Ѥbase+Ѥn<2^32) (hxs:ѧx<2^32) (hc:∀ q,q< Ѥn → buf.data[q]! = dv x[Ѥbase+q]!) (m:ὧ) (k:Ὣ) : ∀ (j:ὦ) (v:ὧ),Ѥj+k=Ѥn → lnVarB buf n j m v hb=lnVar x base n j m v:=by induction k with | zero=> intro j v e rw[lnVarB,lnVar,ἔ (by rw[А];omega),ἔ (by rw[А];omega)] | succ k ih=> intro j v e have hj:j< n:=А.2 (by omega) have hj1:=А.mp hj rw[lnVarB,lnVar,Ἄ hj,Ἄ hj] dsimp only rw[qC5,hc _ hj1,qAg _ _ hxs,qAf base j (by omega),ih (j+1) _ (by rw[usz j n hj];omega)] lemma lnStatB_eq (n:Ὣ) (eps:Ὢ) (x:ё) (r:Ὣ) (buf:ὤ) (hb:n+2<=Ѩbuf) (hbs:Ѩbuf<2^32) (hs:r*n+n<2^32) (hxs:ѧx<2^32) (hc:∀ q,q< n → buf.data[q]! = dv x[r*n+q]!) (ht:buf.data[n]! = (lnSum x ((r*n).toUSize) ѩn 0 0 0).t) (hs2:buf.data[n+1]! = (lnSum x ((r*n).toUSize) ѩn 0 0 0).s) : lnStatB n eps x r (oneF/n.toUInt64.toFloat) (invOK (oneF/n.toUInt64.toFloat) n.toUInt64.toFloat) buf hb hbs=lnStat false n eps x r:=by have e1:Ѥ(ѩn)=n:=qAd n (by omega) have e2:Ѥ((r*n).toUSize)=r*n:=qAd _ (by omega) have hs':Ѥ((r*n).toUSize)+Ѥ(ѩn)<2^32:=by rw[e1,e2];exact hs have hc':∀ q,q< Ѥ(ѩn) → buf.data[q]! = dv x[Ѥ((r*n).toUSize)+q]!:=λq h=>by rw[e2];exact hc q (by rw[e1] at h;exact h) have e3:Ѥ(ѩ(n+1))=n+1:=qAd (n+1) (by omega) unfold lnStatB lnStat oneF simp only[Bool.false_eq_true,ite_false,qC5,e1,e3,ht,hs2] rw[lnVarB_eq x buf _ _ (by rw[e1];omega) hs' hxs hc' _ (Ѥ(ѩn)) 0 0 (by simp)] lemma lnRB_eq (x g b:ё) (buf G B:ὤ) (m ir em:ὧ) (den:Ὢ) (nN rR:Ὣ) (lo sp:Ὠ) (base n:ὦ) (hb:Ѥn<=Ѩbuf) (hG:Ѥn<=ѨG) (hB:Ѥn<=ѨB) (hs:Ѥbase+Ѥn<2^32) (hxs:ѧx<2^32) (hGs:ѨG<2^32) (hBs:ѨB<2^32) (hc:∀ q,q< Ѥn → buf.data[q]! = dv x[Ѥbase+q]!) (k:Ὣ) : ∀ (j:ὦ) (o:ё),Ѥj+k=Ѥn → lnRB x g b buf G B m ir em den nN rR lo sp base n j o hb hG hB=lnRF x g b G B m ir em den (λ_=>meanQ nN x rR) lo sp base n j o:=by induction k with | zero=> intro j o e rw[lnRB,lnRF,ἔ (by rw[А];omega),ἔ (by rw[А];omega)] | succ k ih=> intro j o e have hj:j< n:=А.2 (by omega) have hj1:=А.mp hj have p3:j< G.usize:=by rw[А,FloatArray.usize,qAd _ hGs];omega have p4:j< B.usize:=by rw[А,FloatArray.usize,qAd _ hBs];omega have ev:lnFvM m ir em den (rdW x (base+j)) (buf.uget j (by omega)) g b j (G.uget j (by omega)) (B.uget j (by omega)) lo sp nN x rR=lnFb m ir em den x g b (base+j) j (rdF G j) (rdF B j) lo sp (λ_=>meanQ nN x rR):=by unfold lnFb lnFvM lnSlowM rdF dsimp only rw[Ἄ p3,Ἄ p4,qC5,hc _ hj1,qAg x _ hxs,qAf base j (by omega)] rw[lnRB,lnRF,Ἄ hj,Ἄ hj,ev,ih (j+1) _ (by rw[usz j n hj];omega)] lemma lnRowsB_eq (x g b:ё) (G B:ὤ) (eps:Ὢ) (xm gm bm:ὧ) (n:Ὣ) (d:Ὣ) : ∀ (r:Ὣ) (buf:ὤ) (o:ё),lnRowsB x g b G B eps xm gm bm n (oneF/n.toUInt64.toFloat) (invOK (oneF/n.toUInt64.toFloat) n.toUInt64.toFloat) r buf o d=lnRows x g b G B eps xm gm bm n r o d:=by induction d with | zero=>intro r buf o;rfl | succ d ih=> intro r buf o rw[lnRowsB,lnRows] simp only[lnRSM,lnRFM] split . rename_i h obtain ⟨h1,h2,h3,h3',h4,h4',h5,h6⟩:=h have e1:Ѥ(ѩn)=n:=qAd n (by omega) have e2:Ѥ((r*n).toUSize)=r*n:=qAd _ (by omega) have hbs:Ѩbuf<2^32:=by omega have hxs:ѧx<2^32:=by omega have hs':Ѥ((r*n).toUSize)+Ѥ(ѩn)<2^32:=by rw[e1,e2];omega have hc:∀ q,q< n → (lnDecB x ((r*n).toUSize) ѩn 0 buf 0 0).data[q]! = dv x[r*n+q]!:=λq hq=>by rw[lnDecB_dat x _ _ hs' hxs (Ѥ(ѩn)) 0 buf 0 0 (by rw[e1];omega) hbs (by simp) q (by rw[e1];exact hq),ἱ (by simp),e2] have hc':∀ q,q< Ѥ(ѩn) → (lnDecB x ((r*n).toUSize) ѩn 0 buf 0 0).data[q]! = dv x[Ѥ((r*n).toUSize)+q]!:=λq hq=>by rw[e2];exact hc q (by rw[e1] at hq;exact hq) have ht:(lnDecB x ((r*n).toUSize) ѩn 0 buf 0 0).data[n]! = (lnSum x ((r*n).toUSize) ѩn 0 0 0).t:=by have:=lnDecB_t x ((r*n).toUSize) ѩn (Ѥ(ѩn)) 0 buf 0 0 (by rw[e1];omega) hbs (by simp);rw[e1] at this;exact this have hs2:(lnDecB x ((r*n).toUSize) ѩn 0 buf 0 0).data[n+1]! = (lnSum x ((r*n).toUSize) ѩn 0 0 0).s:=by have:=lnDecB_s x ((r*n).toUSize) ѩn (Ѥ(ѩn)) 0 buf 0 0 (by rw[e1];omega) hbs (by simp);rw[e1] at this;exact this simp only[lnDecC_eq] try dsimp only rw[lnStatB_eq n eps x r _ (by rw[lnDecB_sz0];omega) (by rw[lnDecB_sz0];omega) (by omega) hxs hc ht hs2,ih] congr 1 split . rw[lnRB_eq x g b _ G B _ _ _ _ _ _ _ _ _ ѩn _ _ _ hs' hxs (by omega) (by omega) hc' (Ѥ(ѩn)) 0 o (by simp)] . rfl . rw[ih] lemma rmsRF_eq {rows:Ὣ} {x g:ё} {G:ὤ} {s:LnS} {lo:Ὠ} {base n:ὦ} (hf:s.fast=true) (k:Ὣ) : ∀ (j:ὦ) (o:ё),Ѥj+k=Ѥn->rmsRF rows x g G s.m s.ir s.em s.den lo (spOf lo) base n j o= fC (λs p j=>let w:=rdW x p if w &&& В == 0 then 0 else lnOutF s.1 s.2 w (rdW g j) 0 (gdR rows g G j) (dv 0) λ_=>0) (s,lo) base j o k:=by induction k with | zero=> intro j o e rw[rmsRF,ἔ (by rw[А];(exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))),fC] | succ k ih=> intro j o e have hj:j< n:=А.2 (by exact omS136 e) rw[rmsRF,Ἄ hj,fC,ih (j+1) _ (by rw[usz j n hj];(clear hj; omega))] dsimp only rw[lnFa_eq s hf lo] try rfl lemma rmsRows_eq {rows n:Ὣ} {x g:ё} {G:ὤ} {eps:Ὢ} {xm gm:ὧ} (hn:n<2^32) (d:Ὣ) : ∀ (r:Ὣ) (o:ё),rmsRows rows x g G eps xm gm n r o d=fR (λr=>(lnStat true n eps x r,loOf (lnEB (lnStat true n eps x r) xm gm (dv 0)))) (λs p j=>let w:=rdW x p if w &&& В == 0 then 0 else lnOutF s.1 s.2 w (rdW g j) 0 (gdR rows g G j) (dv 0) λ_=>0) n r o d:=by have hu:(ѩn:ὦ).toNat=n:=qAd n hn induction d with | zero=>intro r o;rfl | succ d ih=> intro r o rw[rmsRows,fR,ih] try dsimp only congr 1 split . rename_i hf exact rmsRF_eq hf n 0 o (by rw[hu];simp) . rfl lemma qGc:lnF=layernormSpec:=by funext rows n eps x g b;unfold lnF;rw[(lnGet n g b).2];unfold lnFq;try simp only[] simp only[lnRowsB_eq] split . rename_i hc;simp only[Bool.and_eq_true,beq_iff_eq] at hc;obtain ⟨⟨h0',h2⟩,hb'⟩:=hc;have h0:normOK rows n eps x g=true:=h0';have hb:smA b=true:=hb';obtain ⟨hD,h4,h5,h7,h8,h9⟩:=qNO h0;obtain ⟨h6,h3⟩:=qSm b (by (clear h9; exact omS362 h2 h8)) hb;have hs:(stableNormDomain rows n eps x g && ѧb == n && b.all finiteWord)=true:=by simp only[Bool.and_eq_true,beq_iff_eq];exact ⟨⟨hD,h2⟩,h3⟩ unfold layernormSpec layernormWith;rw[ἱ hs];unfold layernormStable;dsimp only;unfold stableNormDomain at hD;simp only[Bool.and_eq_true,beq_iff_eq,gt_iff_lt,decide_eq_true_eq] at hD;obtain ⟨⟨⟨⟨⟨⟨⟨h10,h11⟩,h12⟩,h13⟩,-⟩,-⟩,-⟩,h14⟩:=hD have hsx:smA x=true:=by unfold normOK at h0;simp only[Bool.and_eq_true] at h0;exact h0.1.1.1.1.2 have hsg:smA g=true:=by unfold normOK at h0;simp only[Bool.and_eq_true] at h0;exact h0.1.1.1.2 obtain ⟨fxm,bxm,hxm⟩:=qSmx x (by rw[h12];exact h9) hsx obtain ⟨fgm,bgm,hgm⟩:=qSmx g (by rw[h13];(clear h9 h12 h10; exact omS363 h8)) hsg obtain ⟨fbm,bbm,hbm⟩:=qSmx b (by rw[h2];(clear h9 h12 h10; exact omS363 h8)) hb rw[lnRows_eq (G0:=gdF rows g n) (B0:=gdF rows b n) (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) (λu hu=>(qGR (by (clear h9 h12 h10 hu; omega)) (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) u hu).trans (qGS (by (clear h9 h12 h10 hu; omega)) (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) u hu).symm) (λu hu=>(qGR (by (clear h9 h12 h10 hu; exact omS362 h2 h8)) (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) u hu).trans (qGS (by (clear h9 h12 h10 hu; exact omS362 h2 h8)) (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) u hu).symm)] simp only[qMq] rw[qDb (λr c q=>lnOut (lnStat false n eps x r) (loOf (lnEB (lnStat false n eps x r) (dv (scan x x.usize 0 (qAc x) Е 0)) (dv (scan g g.usize 0 (qAc g) Е 0)) (dv (scan b b.usize 0 (qAc b) Е 0)))) x[q]! g[c]! b[c]! λ_=>rowMean n x r) h9 h11 λr p u hr hp hu=>by rw[qGS (by clear h9 h12 h10 hr hp hu; omega) (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) u hu,qGS (by clear h9 h12 h10 hr hp hu; exact omS362 h2 h8) (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) u hu] repeat rw[qAg _ _ (by clear h10 hr hp hu; omega)] rfl] apply Array.ext ג;intro q h1 h1';simp only[Array.getElem_ofFn,Array.size_ofFn] at h1 h1' ⊢;have hr:q/n< rows:=Ἰ (by rwa [ἥ]);have hj:q%n< n:=ὀ _ h11;have e2:=qBp rows (q/n) (λr=>rowMean n x r) hr have e3:=qBp rows (q/n) (λr=>sqrtRational (rowVariance n x r ((Array.ofFn (n:=rows) λr=>rowMean n x r.val)[r]!)+ἂ eps)) hr beta_reduce at e2 e3;rw[e3,e2];obtain ⟨o1,o2⟩:=qE1 false rows n eps x (q/n) hr h11 h8 h12 h9 h4 h7 h14;rw[qEkF _ (rowMean n x (q/n)) _ rfl _ _ _ (qBg x sm h4 q (by clear h2 h8 h9 h13 h10 h11 h1' hr hj e3 o1; exact omS140 h12 h1)) (qBg g sm h5 _ (by clear h2 h8 h9 h12 h10 h11 h1 h1' hr e3 o1; exact omS140 h13 hj)) (qBg b sm h6 _ (by clear h8 h9 h12 h10 h11 h1 h1' hr e3 o1; omega)) o2 _ _ _ fxm fgm fbm (hxm q (by clear h2 h8 h9 h13 h10 h11 h1' hr hj e3 o1; omega)) (hgm _ (by clear h2 h8 h9 h12 h10 h11 h1 h1' hr e3 o1; omega)) (hbm _ (by clear h8 h9 h12 h10 h11 h1 h1' hr e3 o1; exact omS140 h2 hj)) bxm bgm bbm,o1];rfl . rfl lemma qFf:rmsF=rmsnormSpec:=by funext rows n eps x g;unfold rmsF;rw[(rnGet g).2];unfold rmsFz;split . rename_i hc';have hc:normOK rows n eps x g=true:=hc';obtain ⟨hD,h4,h5,h7,h8,h9⟩:=qNO hc;unfold rmsnormSpec rmsnormWith;rw[ἱ hD];unfold rmsnormStable;dsimp only;unfold stableNormDomain at hD;simp only[Bool.and_eq_true,beq_iff_eq,gt_iff_lt,decide_eq_true_eq] at hD;obtain ⟨⟨⟨⟨⟨⟨⟨h10,h11⟩,h12⟩,h13⟩,-⟩,-⟩,-⟩,h14⟩:=hD have hsx:smA x=true:=by unfold normOK at hc;simp only[Bool.and_eq_true] at hc;exact hc.1.1.1.1.2 have hsg:smA g=true:=by unfold normOK at hc;simp only[Bool.and_eq_true] at hc;exact hc.1.1.1.2 obtain ⟨fxm,bxm,hxm⟩:=qSmx x (by rw[h12];exact h9) hsx obtain ⟨fgm,bgm,hgm⟩:=qSmx g (by rw[h13];(clear h9 h12 h10; exact omS363 h8)) hsg obtain ⟨f0,R0⟩:=qAm 0 (by decide) have z0:R (dv 0)=0:=by rw[R0,qAx 0 (qAe _ (by decide))];exact_mod_cast qE6 0 (by decide) rfl rw[rmsRows_eq (by (exact Nat.lt_of_lt_of_le ‹_› (by decide)))] rw[qDb (λr c q=>if x[q]! &&& В == 0 then 0 else lnOut (lnStat true n eps x r) (loOf (lnEB (lnStat true n eps x r) (dv (scan x x.usize 0 (qAc x) Е 0)) (dv (scan g g.usize 0 (qAc g) Е 0)) (dv 0))) x[q]! g[c]! 0 λ_=>0) h9 h11 λr p u hr hp hu=>by rw[qGS (by clear h9 h12 h10 hr hp hu; omega) (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) u hu] repeat rw[qAg _ _ (by clear h10 hr hp hu; omega)] rfl] apply Array.ext ג;intro q h1 h1';simp only[Array.getElem_ofFn,Array.size_ofFn] at h1 h1' ⊢;have hr:q/n< rows:=Ἰ (by rwa [ἥ]);have hj:q%n< n:=ὀ _ h11;have e3:=qBp rows (q/n) (λr=>sqrtRational (rowVariance n x r 0+ἂ eps)) hr;beta_reduce at e3;rw[e3];have hw:=qBg x sm h4 q (by clear h8 h9 h13 h10 h11 h1' hr hj e3; exact omS140 h12 h1);split;. rename_i h0;rw[qE6 _ (qA1 _ hw).1 (by simpa using h0),zero_mul,zero_div];rfl . obtain ⟨o1,o2⟩:=qE1 true rows n eps x (q/n) hr h11 h8 h12 h9 h4 h7 h14;rw[qEkF _ 0 _ rfl _ _ _ hw (qBg g sm h5 _ (by clear h8 h9 h12 h10 h11 h1 h1' hr e3 o1; exact omS140 h13 hj)) (by decide) o2 _ _ _ fxm fgm f0 (hxm q (by clear h8 h9 h13 h10 h11 h1' hr hj e3 o1; omega)) (hgm _ (by clear h8 h9 h12 h10 h11 h1 h1' hr e3 o1; omega)) (by rw[z0,abs_zero]) bxm bgm (by rw[z0];norm_num),o1,qE6 0 (by decide) rfl,sub_zero,add_zero];rfl . rfl end end D namespace C open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Floats.ExecFloat.Binary open FloatLib.Numerics.Dyadic (signedSignificand toRat_eq_zero_iff add_toRat mul_toRat mulFields) open UInt64 (toNat_sub_of_le) open Bool (false_eq_true and_eq_true or_eq_true) open USize (toNat) open UInt32 (toNat) open UInt64 (toNat) open Array (size) open FloatArray (size) open Nat (toUSize) open UInt32 (toUSize) open Submission.D renaming Acc → Acc, Acc.total → Acc.total, Acc.add → Acc.add, dotStep → dotStep, dotLoop → dotLoop, Y_low → Y_low, dotFn → dotFn, rdW → rdW, wrF → wrF, wrW → wrW, pwEntry → pwEntry, pw → pw, dv → dv, dvB → dvB, good → good, scan → scan, scanF → scanF, pushZ → pushZ, zivW → zivW, ziv → ziv, F1 → F1, F4 → F4, go4B → go4B, go1 → go1, R → R, wv → wv, exactS → exactS, nfOf → nfOf, A_M → A_M, A_z → A_z, A_B → A_B, A_bits → A_bits, A_chk → A_chk, A_mag → A_mag, A_mf → A_mf, A_fsum → A_fsum, A_sa → A_sa, A_sr → A_sr, A_G → A_G, B_D → B_D, B_near → B_near, C_Inv → C_Inv, C_Hv → C_Hv, C_keep → C_keep, qAb → qAb, qEb → qAy, qGw → qBi, qEg → qEk, Acc.add_spec → Acc.add_spec, qCb → qCd, qC6 → qC0, qD3 → qEm, qHd → qH1, qFr → qGq, qIo → qJz, qAi → qAg, usz → usz, qAf → qAv, uk → uk, qDo → qDm, qBd → qAp, qDx → qDy, qGe → qG8, qCh → qB4, qAc → qAd, wi → wi, qWm → qJu, qAj → qAj, qAy → qBy, A_R → A_R, qAh → qAl, qA3 → qAu, qA0 → qBf, qCd → qB6, qDv → qD3, qH1 → qIz, qB0 → qDk, A_E → A_E, qEd → qD7, qAr → qAn, A_p → A_p, qAw → qB3, qI1 → qJ0, qCc → qBl, qAn → qAe, qE7 → qEo, qE3 → qFj, qDe → qDi, qFp → qIw, qFc → qF9, qEe → qEp, qBf → qA4, qDf → qC9, qCf → qB8, qA2 → qAt, qBk → qBj, qE0 → qE3, qBl → qCx, qCl → qCo, qCk → qDz, qHg → qJ1, qCu → qBb, qEm → qFk, qDa → qCm, qCw → qEu, qCm → qBu, qDc → qC2, qAq → qA0, qCo → qBt, qD8 → qEc, qCa → qAx, qGl → qEx, qHa → qH3, qAz → qBd, qAe → qAc, qAs → qA3, qA7 → qBe, qFb → qFs, qA6 → qD8, qD1 → qI2, qAm → qAs, qC4 → qC6, qCe → qB2, qGr → qHt, qC7 → qDc, qBo → qJm, qDd → qCy, qBz → qDj, qB7 → qB5, qIn → qJp, qGb → qGx, qEv → qHm, qC9 → qDb, qB5 → qCz, qAo → qAh, qBr → qA8, qHc → qEv, qBs → qCq, qFu → qGf, qFj → qH9, qCr → qCj, qHh → qH8, qHf → qId, qCs → qDw, qEz → qFg, qDi → qDe, qBm → qCw, qFq → qGo, B_z → B_z, qDg → qC8, qEa → qEs, qEf → qEf, qBb → qA5, qBn → qBk, qE4 → qHj, qFs → qIr, B_R → B_R, B_x → B_x, qHw → qEl, qEs → qCg, qB6 → qCa, qA4 → qAk, qBw → qCp, qAx → qA6, qEl → qE8, qEc → qBa, qIg → qGk, qHv → qGh, qB8 → qDd, qG5 → qH6, qEo → qDh, qIq → qEa, qCn → qD4, qDn → qDq, C_z → C_z, qAd → qAa, qBe → qBs, qAg → qAo, qBh → qAm, qFo → qGi, qBu → qAq, qAk → qF2, qA5 → qBg, qBv → qCe, qEn → qFl, qHu → qIs, qH2 → qI7, qB2 → qDt, qCx → qCt, qFa → qF1, qHj → qIa, qBi → qBh, qF6 → qGy, qBt → qBo, qFe → qFr, qGi → qHf, qF3 → qHe, qB1 → qDl, qCj → qDf, qBc → qBv, qC5 → qIg, qC3 → qFx, qD6 → qB9, qEt → qCr, qBj → qCb, qDp → qDs, qD5 → qEb, qAu → qA2, qDy → qG6, qAp → qBn, qDs → qG5, qIm → qFm, qD2 → qEt, qFh → qFn, qC1 → qGl, qC2 → qIu, qHz → qI6, qBg → qI1, qE6 → qJk, Acc.pos → Acc.pos, Acc.neg → Acc.neg, Acc.special → Acc.special, Acc.negZero → Acc.negZero, Acc.mk → Acc.mk, F1.s → F1.s, F1.t → F1.t, F1.mk → F1.mk, F4.a → F4.a, F4.b → F4.b, F4.c → F4.c, F4.d → F4.d, F4.mk → F4.mk, zivT → zivT, thOf → thOf, zivC → zivC, loOf → loOf, spOf → spOf, spR → spR, qI8 → qI8, qJh → qJh, kFh → qFh, qI5 → qI5, qJi → qJi, kHv → qHv, qJc → qJc, qGj → qGj, qJb → qJb, kGw → qGw, qHs → qHs, U_w → U_w, qI4 → qI4, qJr → qJr, kD1 → qD1, qIj → qIj, qHy → qHy section open FloatLib.Numerics end lemma qAw (w:Ὢ):toWord (ofW w)=w:=by apply ἠ.mp;simp only[toWord,ofW,Model.toNatBits,ofUInt32_bits,UInt32.toNat_ofNat'];exact Ἁ w.toBitVec.isLt @[inline] def keyOf (w:Ὢ):Int := if signOf w then -((mantOf w <<< idxOf w:Ὣ):Int) else ((mantOf w <<< idxOf w:Ὣ):Int) lemma qGb (w:Ὢ):keyOf w=sv w*2^idxOf w:=by unfold keyOf sv;split<;>simp[Nat.shiftLeft_eq] lemma qAf (w:Ὢ) : (decodeD w).toReal=(keyOf w:ℝ)*2^(-149:Int):=by rw[<-Ἠ,decodeD_toRat,qGb];push_cast;rw[ᾂ ἓ,Ἡ];ring @[inline] def maxW (a b:Ὢ):Ὢ := if expOf a=255∨expOf b=255 then toWord (Model.maximum (ofW a) (ofW b)) else match compare (keyOf a) (keyOf b) with | .lt=>b | .gt=>a | .eq=>toWord (if Model.isZero (ofW a) && Model.isZero (ofW b) then Model.zero Fmt (Model.signBit (ofW a) && Model.signBit (ofW b)) else ofW a) lemma qDo (a b:Ὢ) : Model.cmpDyadic (decodeD a) (decodeD b)=compare (keyOf a) (keyOf b):=by have hs:(0:ℝ)<2^(-149:Int):=ἵ two_pos _;cases h:compare (keyOf a) (keyOf b);. rw[Model.cmpDyadic_lt_iff,qAf,qAf];exact Ἦ (by exact_mod_cast compare_lt_iff_lt.mp h) hs . rw[Model.cmpDyadic_eq_iff,qAf,qAf,compare_eq_iff_eq.mp h] . rw[Model.cmpDyadic_gt_iff,qAf,qAf];exact Ἦ (by exact_mod_cast compare_gt_iff_gt.mp h) hs lemma qFd (a b:Ὢ):ofW (maxW a b)=Model.maximum (ofW a) (ofW b):=by unfold maxW;split;. exact qAy _ . rename_i hs;have ha:=ἶ a (λh=>hs (Or.inl h));have hb:=ἶ b (λh=>hs (Or.inr h));have hna:=Model.isNaN_eq_false_of_toDyadic?_some ha;have hnb:=Model.isNaN_eq_false_of_toDyadic?_some hb;have hc:Model.compare (ofW a) (ofW b)=some _ :=Model.compare_eq_some_cmpDyadic_of_toDyadic? _ _ ha hb;rw[qDo] at hc;have hnone:Model.chooseNaN2 (ofW a) (ofW b)=none :=(Model.chooseNaN2_eq_none_iff _ _).2 ⟨hna,hnb⟩;unfold Model.maximum Model.Internal.Value.maximum;rw[Model.withNaNSelection_of_none _ _ hnone];dsimp only;rw[Model.compareNonNaN_eq_of_compare_eq_some _ _ _ _ hc];cases compare (keyOf a) (keyOf b)<;>simp only[qAy] def maxpoolW (c h w k:Ὣ) (inp:ё):ё := Array.ofFn (n:=c*(h/k*(w/k))) λq => let ch:=q.val/(h/k*(w/k)) let y:=q.val/(w/k)%(h/k) let x:=q.val%(w/k) (ἄ (k*k)).foldl (λacc t=>maxW acc (poolAtO h w k inp ch y x t)) (poolAtO h w k inp ch y x 0) lemma qEj (p:Ὣ->Ὢ) (l:љ) (acc:Ὢ) : l.foldl (λm t=>Model.maximum m (ofW (p t))) (ofW acc) =ofW (l.foldl (λa t=>maxW a (p t)) acc):=by induction l generalizing acc with | nil=>rfl | cons t l ih=>simp only[List.foldl_cons,<-qFd,ih] lemma qDn:maxpoolW=maxpoolSpecO:=by funext c h w k inp;simp only[maxpoolW,maxpoolSpecO,qEj,qAw] @[noinline] def E_div (n:Ὣ) (s:ὥ):ὥ := toWord (Model.div (ofW s) (ofW (natW n))) lemma qIt:∀ k:Fin 13,0< k.val->expOf (natW (k.val*k.val))≠255 ∧ signOf (natW (k.val*k.val))=false∧mantOf (natW (k.val*k.val))≠0 ∧ mantOf (natW (k.val*k.val))*2^idxOf (natW (k.val*k.val))=k.val*k.val*2^149:=by decide +kernel lemma qJo:∀ k,k<13->0< k->E_div (k*k) (dotFn (k*k) (λ_=>0) (λ_=>oneW))=0:=by decide +kernel def pwEntryN (i:Ὣ):ὧ := if i%256 == 0 || i%256 == 255 then Ἃ 0x7FF8000000000000 else pwEntry i def pwN:ὤ := (ἄ 512).foldl (λa i=>a.push (pwEntryN i)) (ἆ 512) lemma qDg:pwN.data=(ἄ 512).toArray.map pwEntryN:=by have key:∀ (l:љ) (a:ὤ),(l.foldl (λa i=>a.push (pwEntryN i)) a).data=a.data ++ (l.toArray.map pwEntryN):=by intro l;induction l with | nil=>intro a;simp | cons x l ih => intro a;simp only[List.foldl_cons,ih];simp[FloatArray.push] simp only[pwN,key];simp[FloatArray.emptyWithCapacity] lemma qCl (w:ὥ):(w >>> (23:ὥ)).toUSize.toNat< ѨpwN:=by have e:ѨpwN=512:=by simp[FloatArray.size,qDg] rw[e];have h:=w.toNat_lt_size;simp only[UInt32.toNat_toUSize,UInt32.toNat_shiftRight];norm_num [Nat.shiftRight_eq_div_pow] at h ⊢;(clear e; exact omS13 h) @[inline] def dvN (w:ὥ):ὧ := ((w &&& 0x7FFFFF) ||| 0x800000).toFloat*pwN.uget (w >>> (23:ὥ)).toUSize (qCl w) @[inline] def scanH (A:ѐ):ὥ := let h:=scanF A A.usize 0 (qAd A) 0 Е if h == Е then scan A A.usize 0 (qAd A) Е 0 else h @[inline] def zivS (s:ὧ):ὥ := let a:=s.toBits zivW (a+2) (a-2) section open Float.Model.UnpackedFloat in open Float.Model.UnpackedFloat in section variable (x y:ὧ) (hx:xᶠ) (hy:yᶠ) (h1 : |R x| ≤ A_B) (h2 : |R y| ≤ A_B) include x y hx hy h1 h2 end section variable (w:ὥ) include w end section variable (l:List ὧ) (hf:∀ q∈l,qᶠ) (hlen:ѣl<=2^21) (hb:A_sa l<=A_B/4) include l hf hlen hb end section variable (w:ὥ) (hg:good w=true) include w hg end section variable {n:ℕ} {ts:List ℕ} {g:ℕ->ὧ} {p:ℕ->ℝ} {bw hh:ὥ} {X Y J:ℝ} {s t a e:ὧ} (A:n<2^20) (B:ѣts<=n) (C:A_G ts g p) (D:good bw=true) (E:X=(ts.map p).sum+wv bw) (F:s=ts.foldl (λ(c:ὧ) t=>c+g t) 0+dv bw) (G:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) include A B C D E F G end section variable (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) (bw:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (l:љ) (hl:l.Nodup) (hl2:∀ t∈l,t< n) include n hn xw ww bw hx hw hb l hl hl2 lemma qBx (hz:∀ t,t< n->t∉l->xw t &&& В=0∨ww t &&& В=0) (s e:ὧ) (hs:let r:=l.foldl (λ(acc:F1) t=>let q:=dv (xw t)*dv (ww t) F1.mk (acc.s+q) (acc.t+q.abs)) ⟨0,0⟩;s=r.s+dv bw∧e=nfOf n*(r.t+(dv bw).abs)) (hbig:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) : R (s-e)< exactS n xw ww bw∧exactS n xw ww bw< R (s+e):= Submission.D.qDm n hn xw ww bw hx hw hb l hl hl2 hz s e hs hbig lemma qEd (hz:∀ t,t< n->t∉l->xw t &&& В=0) (s e:ὧ) (hs:let r:=l.foldl (λ(acc:F1) t=>let q:=dv (xw t)*dv (ww t) F1.mk (acc.s+q) (acc.t+q.abs)) ⟨0,0⟩;s=r.s+dv bw∧e=nfOf n*(r.t+(dv bw).abs)) (hbig:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) : R (s-e)< exactS n xw ww bw∧exactS n xw ww bw< R (s+e) := qBx n hn xw ww bw hx hw hb l hl hl2 (λt b a=>.inl (hz t b a)) s e hs hbig end lemma qBr (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) (bw hh:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (hg:good hh=true) (hm:∀ t,t< n->xw t &&& В<=hh) (hp:hh<=В) (l:љ) (hl:l.Nodup) (hl2:∀ t∈l,t< n) (hz:∀ t,t< n->t∉l->xw t &&& В=0∨ww t &&& В=0) (s e:ὧ) (hs:s=l.foldl (λ(acc:ὧ) t=>acc+dv (xw t)*dv (ww t)) 0+dv bw ∧ e=nfOf n*(dv hh*(l.foldl (λ(acc:ὧ) t=>acc+(dv (ww t)).abs) 0)+(dv bw).abs)) (hbig:(2:ℝ)^(-127:ℤ) ≤ |R (s+e)|) : R (s-e)< exactS n xw ww bw∧exactS n xw ww bw< R (s+e):=by obtain ⟨hs,b⟩:=hs obtain ⟨-,-,c⟩:=qDw hg hp exact qCw hn (qGf hl hl2) (qH9 hl2 hx hw) hb (qCq hx hw hl hl2 hz) hs hbig hg hp (λt a=>hw t (hl2 t a)) (λt a=>by rw[ἢ] exact ἀ (c _ (hx t (hl2 t a)) (hm t (hl2 t a))) (Ἀ _)) b end section end section section open Float.Model Float.Model.UnpackedFloat lemma qC1 (H a b:Ὣ) (hb:b< H):(H*a+b)/H=a∧(H*a+b)%H=b:=by have c:0< H :=(by exact omS147 hb);constructor;. rw[Nat.mul_add_div c,Ὃ hb,Ἵ] . rw[Nat.mul_add_mod,Ἁ hb] end set_option maxRecDepth 8192 in section variable (s e:ὧ) (V:ℝ) (hlo:R (s-e)< V) (hhi:V< R (s+e)) (h:ziv s e≠Е) include s e V hlo hhi h end end section lemma qC3 (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) (bw hh:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (hg:good hh=true) (hm:∀ t,t< n->xw t &&& В<=hh) (hp:hh<=В) (l:љ) (hl:l.Nodup) (hl2:∀ t∈l,t< n) (hz:∀ t,t< n->t∉l->xw t &&& В=0∨ww t &&& В=0) (s e:ὧ) (hs:s=l.foldl (λ(acc:ὧ) t=>acc+dv (xw t)*dv (ww t)) 0+dv bw ∧ e=nfOf n*(dv hh*(l.foldl (λ(acc:ὧ) t=>acc+(dv (ww t)).abs) 0)+(dv bw).abs)) (h:ziv s e≠Е) : ziv s e=dotOf (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw):=by obtain ⟨-,-,hbig⟩:=qCp s e h obtain ⟨hlo,hhi⟩:=qBr n hn xw ww bw hh hx hw hb hg hm hp l hl hl2 hz s e hs hbig exact qD4 n hn xw ww bw hx hw hb s e hlo hhi h end section lemma qDa (n:Ὣ) (hn:n<2^20) (xw ww:Ὣ->ὥ) (bw hh:ὥ) (hx:∀ t,t< n->good (xw t)=true) (hw:∀ t,t< n->good (ww t)=true) (hb:good bw=true) (hg:good hh=true) (hm:∀ t,t< n->xw t &&& В<=hh) (hp:hh<=В) (l:љ) (hl:l.Nodup) (hl2:∀ t∈l,t< n) (hz:∀ t,t< n->t∉l->xw t &&& В=0∨ww t &&& В=0) (s e:ὧ) (hs:s=l.foldl (λ(acc:ὧ) t=>acc+dv (xw t)*dv (ww t)) 0+dv bw ∧ e=nfOf n*(dv hh*(l.foldl (λ(acc:ὧ) t=>acc+(dv (ww t)).abs) 0)+(dv bw).abs)) (h:zivT (thOf e) s≠Е) : zivT (thOf e) s=dotOf (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw):=by obtain ⟨fs,fe,hrel,hB,hbig,hl2'⟩:=qI4 e s h obtain ⟨hlo,hhi⟩:=qBr n hn xw ww bw hh hx hw hb hg hm hp l hl hl2 hz s e hs hbig have hV:=qHs s e _ fs fe hrel hB hlo hhi have hsum:=qGh n xw ww bw hx hw hb have hne:(∑ j∈Ἣ (n+1),ἂ (if j< n then xw j else oneW) * ἂ (if j< n then ww j else bw):ℚ)≠0:=by intro h0 rw[h0,Rat.cast_zero] at hsum exact qJr s _ hV hl2' hsum.symm obtain ⟨d,hd,hw'⟩:=qBa (n+1) (λt=>if t< n then xw t else oneW) (λt=>if t< n then ww t else bw) (by intro j _ have hone:expOf oneW≠255:=by decide by_cases hj:j< n . simp only[hj,ite_true];exact ⟨qAc _ (hx j hj),qAc _ (hw j hj)⟩ . simp only[hj,ite_false] exact ⟨hone,qAc _ hb⟩) hne rw[hw'] refine qHv _ s d ?_ h rw[hd,hsum] exact hV lemma qH2 (a:Ὠ) (h0:(0x7040000000000000:Ὠ)<=a <<< (1:Ὠ)) (h1:a <<< (1:Ὠ)<0x8FA0000000000000) (h2:(a+0x0FFFFFFD) &&& 0x1FFFFFFF<0x1FFFFFFC) : zivW (a+2) (a-2)=zivC ((a+0x0FFFFFFD) >>> (29:Ὠ)) ∧ zivC ((a+0x0FFFFFFD) >>> (29:Ὠ))≠Е:=by have ha:=a.toNat_lt have e0:(a <<< (1:Ὠ)).toNat=Ѧa*2%2^64:=by rw[UInt64.toNat_shiftLeft];norm_num [Nat.shiftLeft_eq] rw[Ὤ,e0] at h0 rw[ἴ,e0] at h1 norm_num at h0 h1 ha have eu:(a+0x0FFFFFFD).toNat=Ѧa+268435453:=by rw[ἤ];norm_num;(clear h2; exact omS364 h1 ha) have em:((a+0x0FFFFFFD) &&& 0x1FFFFFFF).toNat=(Ѧa+268435453)%2^29:=by rw[Ὅ,eu] have:=Ἂ (Ѧa+268435453) 29 norm_num at this ⊢ exact this rw[ἴ,em] at h2 norm_num at h2 generalize hx:(a+0x0FFFFFFD) >>> (29:Ὠ)=x have ex:Ѧx=(Ѧa+268435453)/2^29:=by rw[<-hx,ἰ,eu];norm_num [Nat.shiftRight_eq_div_pow] have e1:(a+2+0x0FFFFFFF) >>> (29:Ὠ)=x:=by apply UInt64.toNat_inj.mp rw[ex,ἰ,ἤ,ἤ] norm_num [Nat.shiftRight_eq_div_pow] (clear hx; exact omS365 h1 ha h2) have e2:(a-2+0x0FFFFFFF) >>> (29:Ὠ)=x:=by apply UInt64.toNat_inj.mp rw[ex,ἰ,ἤ,ὲ] norm_num [Nat.shiftRight_eq_div_pow] (clear hx e1; exact omS366 h1 ha) have hE:((x >>> (23:Ὠ)) &&& (0x7FF:Ὠ)).toNat=Ѧx/2^23%2^11:=by rw[Ὅ,ἰ] have:=Ἂ (Ѧx >>> 23) 11 norm_num [Nat.shiftRight_eq_div_pow] at this ⊢ exact this have r1:898<=Ѧx/2^23%2^11:=by rw[ex];norm_num;(clear ha hx e1 e2 hE; exact omS367 h0 h1) have r2:Ѧx/2^23%2^11<1151:=by rw[ex];norm_num;(clear ha hx e1 e2 hE r1; exact omS368 h1) have r3:Ѧx<2^35:=by rw[ex];norm_num;(clear hx e1 e2 hE r1 r2; exact omS369 h1 ha) constructor . unfold zivW zivC;dsimp only;rw[e1,e2];have hc:((x >>> (23:Ὠ)) &&& (0x7FF:Ὠ))-(897:Ὠ)<(254:Ὠ):=by rw[ἴ,ὲ,hE];norm_num;norm_num at r1 r2;(clear e0 h0 h1 ha eu em h2 hx ex e1 e2 hE r3; exact omS261 r1 r2) simp[hc] . unfold zivC;rw[show ((x >>> (34:Ὠ)) <<< (31:Ὠ)) ||| ((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< (23:Ὠ))) =((x >>> 34) <<< 31) ||| ((x &&& (0x3FFFFFFFF:Ὠ))-((896:Ὠ) <<< 23)) from rfl,qEl x r3 (by clear e0 h0 h1 ha eu em h2 hx ex e1 e2 r3; (exact Nat.le_of_lt ‹_›)) r2];intro h;have h':=congrArg UInt32.toNat h;rw[ὡ] at h';have f:=ὀ Ѧx (ב:0<2^23);split at h'<;>norm_num at h' f r1 r2<;>(clear e0 h0 h1 ha eu em h2 hx ex e1 e2 hE r3 h f; omega) lemma qIf (s:ὧ) (h1:(s.toBits <<< (1:Ὠ))-0x7040000000000000<0x1F60000000000000) (h2:(s.toBits+0x0FFFFFFD) &&& 0x1FFFFFFF<0x1FFFFFFC) : zivS s=zivC ((s.toBits+0x0FFFFFFD) >>> (29:Ὠ))∧zivS s≠Е:=by have sp0:spOf 0x7040000000000000=0x1F60000000000000:=by decide obtain ⟨l1,l2⟩:=qD1 _ _ (sp0.symm ▸ h1);have b:=qH2 s.toBits l1 l2 h2;have e1:zivS s=zivC ((s.toBits+0x0FFFFFFD) >>> (29:Ὠ)):=b.1;exact ⟨e1,e1 ▸ b.2⟩ end section lemma qIb (a b:ὦ) (h:Ѥa*Ѥb<2^32) : (a*b).toNat=Ѥa*Ѥb:=qJu a b h section variable {N:Ὣ} {sp:Ὣ->Ὢ} include N sp end lemma qD0 (A:ѐ) (hs:ѧA<2^32) (h:scanH A≠Е) : C_Hv A (scanH A):=by revert h;unfold scanH;dsimp only;split;. exact qBh A hs . exact qDl A hs section variable {R I O:Ὣ} {X W b:ё} end section variable (xw:Ὣ->Ὢ) (t:Ὣ) include xw t end section variable {x:ὤ} {ix W:ѐ} {w0 w1 w2 w3 m n:ὦ} (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hs:ѧW<2^32) (h0:Ѥw0+Ѥm<=ѧW) (h1:Ѥw1+Ѥm<=ѧW) (h2:Ѥw2+Ѥm<=ѧW) (h3:Ѥw3+Ѥm<=ѧW) end section variable {R I O:Ὣ} {X W b:ё} end lemma qGr (xs:ὤ) (v:ὧ) (q:Ὣ) : (xs.push v).data[q]! = if q=Ѩxs then v else xs.data[q]!:=by obtain ⟨ds⟩:=xs;show (ds.push v)[q]! = if q=ѧds then v else ds[q]!;by_cases hq:q< ѧds . have h3:q<(ds.push v).size:=by simp;(exact Nat.le_of_lt ‹_›) rw[Ἕ _ q h3,Ἕ ds q hq,ἐ (by clear h3; exact omS370 hq),Array.getElem_push_lt] . by_cases e:q=ѧds . subst e;have h3:ѧds<(ds.push v).size:=by simp rw[Ἕ (ds.push v) ѧds h3,ἱ rfl,Array.getElem_push_eq] . have h3:¬ q<(ds.push v).size:=by simp;exact omS371 hq e rw[ὑ _ q h3,ὑ ds q hq,ἐ e] section variable {I O:Ὣ} {X W b:ё} end end section local instance ecNe11:Nonempty D_Sc:=⟨by constructor <;> exact default⟩ def D_scan (A:ѐ) (n i:ὦ) (hn:Ѥn<=ѧA) (lo hi:ὥ):D_Sc := if h:i< n then have ht:=А.mp h let v:=A.uget i א &&& В let u:=v-1 D_scan A n (i+1) hn (if u< lo then u else lo) (if hi< v then v else hi) else ⟨lo,hi⟩ partial_fixpoint def D_fill (v:ὧ) (n k:ὦ) (a:ὤ):ὤ := if h:k< n then D_fill v n (k+1) (a.push v) else a partial_fixpoint def D_copy (X:ѐ) (o n t:ὦ) (hs:ѧX<2^32) (ho:Ѥo+Ѥn<=ѧX) (a:ὤ):ὤ := if h:t< n then D_copy X o n (t+1) hs ho (a.push (dv (X.uget (o+t) (wi o t n X ho hs (А.mp h))))) else a partial_fixpoint def D_z0:ὤ:=D_fill (dv 0) 512 0 (ἆ 512) def D_z1:ὤ:=D_fill (dv 0) 1024 0 (ἆ 1024) def D_z2:ὤ:=D_fill (dv 0) 2048 0 (ἆ 2048) def D_z3:ὤ:=D_fill (dv 0) 4096 0 (ἆ 4096) def D_z4:ὤ:=D_fill (dv 0) 8192 0 (ἆ 8192) def D_z5:ὤ:=D_fill (dv 0) 16384 0 (ἆ 16384) @[inline] def D_zs (n:Ὣ):ὤ := if n<=512 then D_z0 else if n<=1024 then D_z1 else if n<=2048 then D_z2 else if n<=4096 then D_z3 else if n<=8192 then D_z4 else D_z5 def D_cpz (X:ѐ) (o n t q:ὦ) (hs:ѧX<2^32) (ho:Ѥo+Ѥn<=ѧX) (a:ὤ):ὤ := if h:t< n then D_cpz X o n (t+1) (q+1) hs ho (wrF a q (dv (X.uget (o+t) (wi o t n X ho hs (А.mp h))))) else a partial_fixpoint def D_imz (s:OS) (X:ѐ) (hs:ѧX<2^32) (wp R r:Ὣ) (a:ὤ):ὤ := if hr:r< R then let hp:=s.h+2*s.pad let yy:=r%hp let o:=((r/hp*s.h+(yy-s.pad))*s.w).toUSize if hg:s.pad<=yy∧yy-s.pad< s.h∧Ѥo+s.w.toUSize.toNat<=ѧX then D_imz s X hs wp R (r+1) (D_cpz X o s.w.toUSize 0 (r*wp+s.pad).toUSize hs hg.2.2 a) else D_imz s X hs wp R (r+1) a else a partial_fixpoint def D_tq (k kw kh hp wp t c r q:Ὣ) (a:ѐ):ѐ := if t< k then let a:=a.push ((c*hp+r)*wp+q).toUInt32 if q+1< kw then D_tq k kw kh hp wp (t+1) c r (q+1) a else if r+1< kh then D_tq k kw kh hp wp (t+1) c (r+1) 0 a else D_tq k kw kh hp wp (t+1) (c+1) 0 0 a else a partial_fixpoint def D_img (s:OS) (X:ѐ) (hs:ѧX<2^32) (z:ὧ) (R r:Ὣ) (a:ὤ):ὤ := if hr:r< R then let hp:=s.h+2*s.pad let yy:=r%hp let o:=((r/hp*s.h+(yy-s.pad))*s.w).toUSize let pu:=s.pad.toUSize if hg:s.pad<=yy∧yy-s.pad< s.h∧Ѥo+s.w.toUSize.toNat<=ѧX then D_img s X hs z R (r+1) (D_fill z pu 0 (D_copy X o s.w.toUSize 0 hs hg.2.2 (D_fill z pu 0 a))) else D_img s X hs z R (r+1) (D_fill z (s.w+2*s.pad).toUSize 0 a) else a partial_fixpoint /-- copy `k` consecutive valid rows of one channel (source `o`, destination `q`, steps `w`/`wp`) -/ def D_rw2 (X:Array UInt32) (hs:X.size<2^32) (w wp:USize) (o q:USize) (k:Nat) (a:FloatArray):FloatArray := match k with | 0 => a | k+1 => if hg:USize.toNat o+w.toNat<=X.size then D_rw2 X hs w wp (o+w) (q+wp) k (D_cpz X o w 0 q hs hg a) else D_rw2 X hs w wp (o+w) (q+wp) k a /-- all channels: only the `h` valid rows of each padded channel plane are visited -/ def D_ch2 (s:OS) (X:Array UInt32) (hs:X.size<2^32) (wp:Nat) (c k:Nat) (a:FloatArray):FloatArray := match k with | 0 => a | k+1 => D_ch2 s X hs wp (c+1) k (D_rw2 X hs s.w.toUSize wp.toUSize ((c*s.h)*s.w).toUSize ((c*(s.h+2*s.pad)+s.pad)*wp+s.pad).toUSize s.h a) theorem imz_skip (s:OS) (X:Array UInt32) (hs:X.size<2^32) (wp R r:Nat) (a:FloatArray) (hr:r hn ⟨h.1, h.2.1⟩)] theorem imz_skipk (s:OS) (X:Array UInt32) (hs:X.size<2^32) (wp R:Nat) (k:Nat) : ∀ (r:Nat) (a:FloatArray), r+k ≤ R → (∀ i, i < k → ¬(s.pad ≤ (r+i)%(s.h+2*s.pad) ∧ (r+i)%(s.h+2*s.pad)-s.pad < s.h)) → D_imz s X hs wp R r a = D_imz s X hs wp R (r+k) a := by induction k with | zero => intro r a _ _; rfl | succ k ih => intro r a hk hi rw [imz_skip s X hs wp R r a (by omega) (by simpa using hi 0 (by omega))] rw [ih (r+1) a (by omega) (fun i hi' => by have := hi (i+1) (by omega); rwa [show r+(i+1) = r+1+i by omega] at this)] rw [show r+1+k = r+(k+1) by omega] theorem cpz_congr (X:Array UInt32) (o1 o2 n t q:USize) (hs:X.size<2^32) (h1:USize.toNat o1+n.toNat<=X.size) (h2:USize.toNat o2+n.toNat<=X.size) (a:FloatArray) (e:o1=o2) : D_cpz X o1 n t q hs h1 a = D_cpz X o2 n t q hs h2 a := by subst e; rfl theorem imz_rows (s:OS) (X:Array UInt32) (hs:X.size<2^32) (wp R c:Nat) (k:Nat) : ∀ (yy:Nat) (a:FloatArray), s.pad ≤ yy → yy + k = s.pad + s.h → (c*(s.h+2*s.pad)+yy)+k ≤ R → D_imz s X hs wp R (c*(s.h+2*s.pad)+yy) a = D_imz s X hs wp R (c*(s.h+2*s.pad)+yy+k) (D_rw2 X hs s.w.toUSize wp.toUSize ((c*s.h+(yy-s.pad))*s.w).toUSize ((c*(s.h+2*s.pad)+yy)*wp+s.pad).toUSize k a) := by induction k with | zero => intro yy a _ _ _; rfl | succ k ih => intro yy a h1 h2 h3 have hp : 0 < s.h+2*s.pad := by omega have ey : (c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad) = yy := by rw [Nat.mul_comm, Nat.mul_add_mod]; exact Nat.mod_eq_of_lt (by omega) have ec : (c*(s.h+2*s.pad)+yy) / (s.h+2*s.pad) = c := by rw [Nat.mul_comm, Nat.mul_add_div hp, Nat.div_eq_of_lt (by omega), Nat.add_zero] have eo1 : (((c*(s.h+2*s.pad)+yy) / (s.h+2*s.pad)*s.h + ((c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad)-s.pad))*s.w).toUSize = ((c*s.h+(yy-s.pad))*s.w).toUSize := by rw [ey, ec] have eo : ((c*s.h+(yy-s.pad))*s.w).toUSize + s.w.toUSize = ((c*s.h+(yy+1-s.pad))*s.w).toUSize := by rw [← USize.ofNat_add]; congr 1; rw [show yy+1-s.pad = (yy-s.pad)+1 by omega]; simp only [Nat.add_mul, Nat.one_mul, Nat.add_assoc] have eq : ((c*(s.h+2*s.pad)+yy)*wp+s.pad).toUSize + wp.toUSize = ((c*(s.h+2*s.pad)+(yy+1))*wp+s.pad).toUSize := by rw [← USize.ofNat_add]; congr 1; simp only [Nat.add_mul, Nat.one_mul]; omega have e3 : c*(s.h+2*s.pad)+yy+(k+1) = c*(s.h+2*s.pad)+(yy+1)+k := by omega rw [D_imz, dif_pos (by omega)] dsimp only simp only [D_rw2] by_cases hg : USize.toNat ((c*s.h+(yy-s.pad))*s.w).toUSize + s.w.toUSize.toNat ≤ X.size · have hc : s.pad ≤ (c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad) ∧ (c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad) - s.pad < s.h ∧ USize.toNat (((c*(s.h+2*s.pad)+yy) / (s.h+2*s.pad)*s.h + ((c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad)-s.pad))*s.w).toUSize + s.w.toUSize.toNat ≤ X.size := ⟨by omega, by omega, by rw [eo1]; exact hg⟩ rw [dif_pos hc, dif_pos hg, eo, eq, e3, cpz_congr X _ _ _ _ _ hs _ hg a eo1] exact ih (yy+1) _ (by omega) (by omega) (by omega) · have hc : ¬ (s.pad ≤ (c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad) ∧ (c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad) - s.pad < s.h ∧ USize.toNat (((c*(s.h+2*s.pad)+yy) / (s.h+2*s.pad)*s.h + ((c*(s.h+2*s.pad)+yy) % (s.h+2*s.pad)-s.pad))*s.w).toUSize + s.w.toUSize.toNat ≤ X.size) := fun h => hg (by rw [← eo1]; exact h.2.2) rw [dif_neg hc, dif_neg hg, eo, eq, e3] exact ih (yy+1) _ (by omega) (by omega) (by omega) theorem imz_chan (s:OS) (X:Array UInt32) (hs:X.size<2^32) (wp R c:Nat) (a:FloatArray) (hR:(c+1)*(s.h+2*s.pad) ≤ R) : D_imz s X hs wp R (c*(s.h+2*s.pad)) a = D_imz s X hs wp R ((c+1)*(s.h+2*s.pad)) (D_rw2 X hs s.w.toUSize wp.toUSize ((c*s.h)*s.w).toUSize ((c*(s.h+2*s.pad)+s.pad)*wp+s.pad).toUSize s.h a) := by have hR' : c*(s.h+2*s.pad) + s.h + 2*s.pad ≤ R := by rw [Nat.add_mul, Nat.one_mul] at hR; omega rw [imz_skipk s X hs wp R s.pad (c*(s.h+2*s.pad)) a (by omega) (fun i hi => by rw [Nat.mul_comm, Nat.mul_add_mod, Nat.mod_eq_of_lt (by omega)]; omega)] rw [imz_rows s X hs wp R c s.h s.pad a (Nat.le_refl _) (by omega) (by omega)] rw [Nat.sub_self, Nat.add_zero] rw [imz_skipk s X hs wp R s.pad _ _ (by omega) (fun i hi => by rw [show c*(s.h+2*s.pad)+s.pad+s.h+i = (s.pad+s.h+i) + (s.h+2*s.pad)*c by ring, Nat.add_mul_mod_self_left, Nat.mod_eq_of_lt (by omega)]; omega)] congr 1 rw [Nat.add_mul, Nat.one_mul]; omega theorem ch2_eq (s:OS) (X:Array UInt32) (hs:X.size<2^32) (wp R:Nat) (hR:R=s.cin*(s.h+2*s.pad)) (k:Nat) : ∀ (c:Nat) (a:FloatArray), c+k=s.cin → D_ch2 s X hs wp c k a = D_imz s X hs wp R (c*(s.h+2*s.pad)) a := by induction k with | zero => intro c a h simp only [D_ch2] rw [D_imz, dif_neg (by subst hR; rw [← h, Nat.add_zero]; omega)] | succ k ih => intro c a h simp only [D_ch2] rw [ih (c+1) _ (by omega), imz_chan s X hs wp R c a (by subst hR; exact Nat.mul_le_mul_right _ (by omega))] @[inline] def D_xs (s:OS) (X:ѐ) (hs:ѧX<2^32) (wp R:Ὣ):ὤ := if R*wp+7<=16384 then D_ch2 s X hs wp 0 s.cin (D_zs (R*wp+7)) else pushZ 7 0 (D_img s X hs (dv 0) R 0 (ἆ (R*wp+7))) def D_off (s:OS) (t:Ὣ):Ὣ := (t/(s.kh*s.kw)*(s.h+2*s.pad)+t/s.kw%s.kh)*(s.w+2*s.pad)+t%s.kw lemma qIo {n d:Ὣ} (b:ὦ) (u:ὥ) (hs:n<2^32) (h:Ѥb+ѥu+d< n):(b+Ѫu).toNat+d< n:=by rw[qAv _ _ (by rw[ὃ];exact omS372 hs h),ὃ];exact h lemma qB1 {n:Ὣ} (p:ὦ) (k:Ὣ) (hs:n<2^32) (h:Ѥp+k< n) : (p+ὴ k).toNat< n:=by rw[qAv _ _ (by rw[uk k (by exact omS278 hs h)];exact omS279 hs h),uk k (by exact omS278 hs h)];exact h local instance ecNe12:Nonempty D_R:=⟨by constructor <;> exact default⟩ def D_go8R (xd wd:ὤ) (off:ѐ) (b e i:ὦ) (he:Ѥe<=ѧoff) (hw:Ѥe<=Ѩwd) (hs:Ѩxd<2^32) (hb:∀ j (h:j< ѧoff),Ѥb+off[j].toNat+7< Ѩxd) (A B C D E F G I:ὧ) (r:D_R):D_R := if h:i< e then have ht:=А.mp h let p:=b+(off.uget i (Nat.lt_of_lt_of_le ht he)).toUSize have hp:Ѥp+7< Ѩxd:=qIo _ _ hs (hb Ѥi (Nat.lt_of_lt_of_le ht he)) let v:=wd.uget i (Nat.lt_of_lt_of_le ht hw) D_go8R xd wd off b e (i+1) he hw hs hb (A+xd.uget p (Nat.lt_of_le_of_lt (Nat.le_add_right _ 7) hp)*v) (B+xd.uget (p+ὴ 1) (qB1 p 1 hs (Nat.lt_of_le_of_lt (Nat.add_le_add_left ה _) hp))*v) (C+xd.uget (p+ὴ 2) (qB1 p 2 hs (Nat.lt_of_le_of_lt (Nat.add_le_add_left ה _) hp))*v) (D+xd.uget (p+ὴ 3) (qB1 p 3 hs (Nat.lt_of_le_of_lt (Nat.add_le_add_left ה _) hp))*v) (E+xd.uget (p+ὴ 4) (qB1 p 4 hs (Nat.lt_of_le_of_lt (Nat.add_le_add_left ה _) hp))*v) (F+xd.uget (p+ὴ 5) (qB1 p 5 hs (Nat.lt_of_le_of_lt (Nat.add_le_add_left ה _) hp))*v) (G+xd.uget (p+ὴ 6) (qB1 p 6 hs (Nat.lt_of_le_of_lt (Nat.add_le_add_left ה _) hp))*v) (I+xd.uget (p+ὴ 7) (qB1 p 7 hs hp)*v) r else match r with | ⟨t,_,_,_,_,_,_,_,_⟩=>⟨t,A,B,C,D,E,F,G,I⟩ partial_fixpoint local instance ecNe13:Nonempty F1:=⟨by constructor <;> exact default⟩ def D_goT (xd wd:ὤ) (off:ѐ) (b e i:ὦ) (he:Ѥe<=ѧoff) (hw:Ѥe<=Ѩwd) (hs:Ѩxd<2^32) (hb:∀ j (h:j< ѧoff),Ѥb+off[j].toNat+0< Ѩxd) (a t:ὧ):F1 := if h:i< e then have ht:=А.mp h let q:=xd.uget (b+(off.uget i (Nat.lt_of_lt_of_le ht he)).toUSize) (qIo (d:=0) _ _ hs (hb Ѥi (Nat.lt_of_lt_of_le ht he)))*wd.uget i (Nat.lt_of_lt_of_le ht hw) D_goT xd wd off b e (i+1) he hw hs hb (a+q) (t+q.abs) else ⟨a,t⟩ termination_by Ѥe-Ѥi decreasing_by rw[usz i e h];omega /-- Every product `fa t · fb t`, `t ∈ [i, i+n)`, is a zero of finite factors. -/ @[specialize] def zAll (fa fb:Nat->UInt32) (i:Nat) : Nat → Bool | 0 => true | n+1 => (let a:=fa i; let b:=fb i; expOf a != 255 && expOf b != 255 && mantOf a * mantOf b == 0) && zAll fa fb (i+1) n /-- Every product's sign is negative. -/ @[specialize] def zNeg (fa fb:Nat->UInt32) (i:Nat) : Nat → Bool | 0 => true | n+1 => (let a:=fa i; let b:=fb i; Bool.xor (signOf a) (signOf b)) && zNeg fa fb (i+1) n /-- The exact dot product, with an all-zero-products sum answered directly (the IEEE signed zero: -0 only for a nonempty sum of negative zeros). -/ @[inline] def zdotFn (n:Nat) (fa fb:Nat->UInt32) : UInt32 := if zAll fa fb 0 n then (if n ≠ 0 && zNeg fa fb 0 n then 0x80000000 else 0) else dotFn n fa fb def zCols (s:OS) (X:Array UInt32) (c yy x0:Nat) (i:Nat) : Nat → Bool | 0 => true | n+1 => pixZ s X c yy (x0+i) && zCols s X c yy x0 (i+1) n def zRows (s:OS) (X:Array UInt32) (c y0 x0:Nat) (i:Nat) : Nat → Bool | 0 => true | n+1 => zCols s X c (y0+i) x0 0 s.kw && zRows s X c y0 x0 (i+1) n def wFin (W:Array UInt32) (base:Nat) (i:Nat) : Nat → Bool | 0 => true | n+1 => expOf W[base+i]! != 255 && wFin W base (i+1) n /-- A depthwise output whose window is all zero words, with finite weights and a +0 bias: the sum is +0. -/ def zWin (g:D_C) (o y x:Nat) : Bool := g.dw && g.k == g.s.kh * g.s.kw && decide (0 < g.s.kw) && g.b[o]! == 0 && wFin g.W (o*g.k) 0 g.k && zRows g.s g.X o (y*g.s.stride) (x*g.s.stride) 0 g.s.kh def zChans (s:OS) (X:Array UInt32) (y0 x0:Nat) (i:Nat) : Nat → Bool | 0 => true | n+1 => zRows s X i y0 x0 0 s.kh && zChans s X y0 x0 (i+1) n /-- A convolution output whose window (all input channels) is all zero words, with finite weights and a +0 bias. -/ def zWinC (g:D_C) (o y x:Nat) : Bool := !g.dw && g.k == g.s.cin * (g.s.kh * g.s.kw) && decide (0 < g.s.kw) && g.b[o]! == 0 && wFin g.W (o*g.k) 0 g.k && zChans g.s g.X (y*g.s.stride) (x*g.s.stride) 0 g.s.cin @[noinline] def D_slow (g:D_C) (o y x:Ὣ):ὥ := act g.relu (dotFn (g.k+1) (λt=>if t< g.k then windowAtO g.s g.X y x ((if g.dw then o*g.k else 0)+t) else oneW) (λt=>if t< g.k then g.W[o*g.k+t]! else g.b[o]!)) @[noinline] def D_slowZ (g:D_C) (o y x:Nat):UInt32 := if zWin g o y x || zWinC g o y x then 0 else D_slow g o y x /-- zero window by the per-output-row column hull (zero bias) -/ def zWinX (g:D_C) (o y x:Nat) : Bool := (x*g.s.stride+g.s.kw ≤ g.ex.1.getD (2*((if g.dw then o else 0)*g.ho+y)) 0 || g.wp ≤ x*g.s.stride+g.ex.1.getD (2*((if g.dw then o else 0)*g.ho+y)+1) 0) && g.b[o]! == 0 /-- all eight lanes `x..x+7` (stride 1) have zero windows by the hull (zero bias) -/ @[noinline] def zBlkG (g:D_C) (o y x:Nat) : Bool := (x*g.s.stride+g.s.kw+7 ≤ g.ex.1.getD (2*((if g.dw then o else 0)*g.ho+y)) 0 || g.wp ≤ x*g.s.stride+g.ex.1.getD (2*((if g.dw then o else 0)*g.ho+y)+1) 0) && g.b[o]! == 0 @[inline] def zBlk (g:D_C) (o y x:Nat) : Bool := !g.ex.1.isEmpty && zBlkG g o y x @[noinline] def D_slowX (g:D_C) (o y x:Nat):UInt32 := if zWinX g o y x then 0 else D_slowZ g o y x /-- every tap word `xd[b+off[i]], …` (`n` taps from `i`) of a lane is a signed zero -/ def D_zt (xd:FloatArray) (off:Array UInt32) (b:Nat) (i:Nat) : Nat → Bool | 0 => true | n+1 => (decide (b+(off[i]!).toNat < xd.size) && (xd.get! (b+(off[i]!).toNat)).toBits <<< (1:UInt64) == 0) && D_zt xd off b (i+1) n @[noinline] def D_slowY (c:D_P) (o y x:Nat) (b:USize) : UInt32 := if zWinX c.g o y x then 0 else if c.g.b[o]! == 0 && D_zt c.g.xd c.off b.toNat 0 c.e.toNat then 0 else D_slowZ c.g o y x @[inline] def D_zl (q n:ὦ) (k:Ὣ) (out:ѐ):ѐ := if ὴ k< n then wrW out (q+ὴ k) 0 else out @[inline] def D_z8 (q n:ὦ) (out:ѐ):ѐ := D_zl q n 7 (D_zl q n 6 (D_zl q n 5 (D_zl q n 4 (D_zl q n 3 (D_zl q n 2 (D_zl q n 1 (D_zl q n 0 out))))))) @[noinline] def D_finT (c:D_P) (o y x:Ὣ) (b:ὦ):ὥ := if hb:b< c.l1 then let q:=D_goT c.g.xd c.wd c.off b c.e 0 c.he c.hw c.hs (c.h1 b hb) c.ze c.ze let r:=ziv (q.s+c.bv) (c.g.nf*(q.t+c.bv.abs)) if r == Е then (if q.t.toBits == 0 then D_slowY c o y x b else D_slow c.g o y x) else act c.g.relu r else D_slow c.g o y x @[inline] def D_fin (c:D_P) (o y x:Ὣ) (b:ὦ) (a:ὧ):ὥ := let r:=ziv (a+c.bv) c.e0 if r == Е then (if (a+c.bv).toBits == 0 then D_slowY c o y x b else D_finT c o y x b) else act c.g.relu r @[noinline] def D_finK (c:D_P) (o y x k:Ὣ) (b:ὦ) (a:ὧ):ὥ := D_fin c o y (x+k) (b+ὴ k) a @[inline] def D_w (c:D_P) (lo sp:Ὠ) (o y x:Ὣ) (b:ὦ) (k:Ὣ) (a:ὧ):ὥ := let w:=(a+c.bv).toBits let u:=w+0x0FDFFFFF if (w <<< (1:Ὠ))-lo< sp && u &&& 0x1FFFFFFF<0x1FC00000 then zivC (u >>> (29:Ὠ)) else if w <<< (1:Ὠ) == 0 then D_slowY c o y (x+k) (b+ὴ k) else D_finK c o y x k b a @[inline] def D_l (c:D_P) (lo sp:Ὠ) (o y x:Ὣ) (b q n:ὦ) (k:Ὣ) (a:ὧ) (out:ѐ) : ѐ := if ὴ k< n then wrW out (q+ὴ k) (D_w c lo sp o y x b k a) else out lemma lcGq {a:ѐ} {q:ὦ} (h:q< a.usize∧8<=a.usize-q) (k:Ὣ) (hk:k<8) : (q+ὴ k).toNat< ѧa:=by have h1:=А.mp h.1 have h2:=USize.le_iff_toNat_le.mp h.2 have h8:(8:ὦ).toNat=8:=uk 8 ה rw[USize.toNat_sub_of_le _ _ (USize.le_iff_toNat_le.mpr (Nat.le_of_lt h1)),h8] at h2 have h3:a.usize.toNat<=ѧa:=by simp only[Array.usize,Nat.toUSize_eq,USize.toNat_ofNat'];exact Nat.mod_le _ _ have h4:=a.usize.toNat_lt_size;have h5:USize.size=2^System.Platform.numBits:=rfl rw[USize.toNat_add,uk k (by omega),Nat.mod_eq_of_lt (by omega)] omega lemma lcN8 {n:ὦ} (h8:8<=n) (k:Ὣ) (hk:k<8) : ὴ k< n:=by have h:=USize.le_iff_toNat_le.mp h8;rw[show (8:ὦ).toNat=8 from uk 8 ה] at h;exact А.mpr (by rw[uk k (by omega)];omega) lemma lcWU (a:ѐ) (i:ὦ) (v:ὥ) (h:Ѥi< ѧa) (hs:ѧa<2^32) : a.uset i v h=wrW a i v:=by have h2:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl unfold wrW;rw[Ἄ (А.mpr (by simp only[Array.usize,Nat.toUSize_eq,USize.toNat_ofNat'];rw[Nat.mod_eq_of_lt (by omega)];exact h))] @[inline] def D_g8 (c:D_P) (lo sp:Ὠ) (o y x:Ὣ) (b q n:ὦ) (r:D_R) (out:ѐ):ѐ := if hq:8<=n∧q< out.usize∧8<=out.usize-q then ((((((((out.uset (q+ὴ 0) (D_w c lo sp o y x b 0 r.A) (lcGq hq.2 0 ה)).uset (q+ὴ 1) (D_w c lo sp o y x b 1 r.B) (by simp only[Array.size_uset];exact lcGq hq.2 1 ה)).uset (q+ὴ 2) (D_w c lo sp o y x b 2 r.C) (by simp only[Array.size_uset];exact lcGq hq.2 2 ה)).uset (q+ὴ 3) (D_w c lo sp o y x b 3 r.D) (by simp only[Array.size_uset];exact lcGq hq.2 3 ה)).uset (q+ὴ 4) (D_w c lo sp o y x b 4 r.E) (by simp only[Array.size_uset];exact lcGq hq.2 4 ה)).uset (q+ὴ 5) (D_w c lo sp o y x b 5 r.F) (by simp only[Array.size_uset];exact lcGq hq.2 5 ה)).uset (q+ὴ 6) (D_w c lo sp o y x b 6 r.G) (by simp only[Array.size_uset];exact lcGq hq.2 6 ה)).uset (q+ὴ 7) (D_w c lo sp o y x b 7 r.I) (by simp only[Array.size_uset];exact lcGq hq.2 7 ה)) else let out:=D_l c lo sp o y x b q n 0 r.A out let out:=D_l c lo sp o y x b q n 1 r.B out let out:=D_l c lo sp o y x b q n 2 r.C out let out:=D_l c lo sp o y x b q n 3 r.D out let out:=D_l c lo sp o y x b q n 4 r.E out let out:=D_l c lo sp o y x b q n 5 r.F out let out:=D_l c lo sp o y x b q n 6 r.G out let out:=D_l c lo sp o y x b q n 7 r.I out out def D_cols (c:D_P) (lo sp:Ὠ) (o y x:Ὣ) (b q:ὦ) (rr:D_R) (out:ѐ) : ѐ := if h8:x< c.g.wo∧c.g.f4=true∧b< c.l8 then let r:=D_go8R c.g.xd c.wd c.off b c.e 0 c.he c.hw c.hs (c.h8 b h8.2.2) c.ze c.ze c.ze c.ze c.ze c.ze c.ze c.ze rr let n:=(c.g.wo-x).toUSize D_cols c lo sp o y (x+8) (b+8) (q+8) r (D_g8 c lo sp o y x b q n r out) else if x< c.g.wo then D_cols c lo sp o y (x+1) (b+c.g.step) (q+1) rr (wrW out q (D_finT c o y x b)) else out partial_fixpoint def D_rc (c:D_P) (lo sp:Ὠ) (o y x:Ὣ) (b q q0:ὦ) (rr:D_R) (out:ѐ) : ѐ := if hy:y< c.g.ho then if h8:x< c.g.wo∧c.g.f4=true∧b< c.l8 then let r:=D_go8R c.g.xd c.wd c.off b c.e 0 c.he c.hw c.hs (c.h8 b h8.2.2) c.ze c.ze c.ze c.ze c.ze c.ze c.ze c.ze rr let n:=(c.g.wo-x).toUSize D_rc c lo sp o y (x+8) (b+8) (q+8) q0 r (D_g8 c lo sp o y x b q n r out) else if x< c.g.wo then D_rc c lo sp o y (x+1) (b+c.g.step) (q+1) q0 rr (wrW out q (D_finT c o y x b)) else D_rc c lo sp o (y+1) 0 ((y+1).toUSize*c.g.step*c.g.wp.toUSize) (q0+c.g.wo.toUSize) (q0+c.g.wo.toUSize) rr out else out partial_fixpoint def D_rows (c:D_P) (lo sp:Ὠ) (o y:Ὣ) (q:ὦ) (rs:List D_R) (out:ѐ):ѐ := if y< c.g.ho then D_rows c lo sp o (y+1) (q+c.g.wo.toUSize) rs.tail (D_cols c lo sp o y 0 (ѩy*c.g.step*c.g.wp.toUSize) q (rs.headD ⟨0,0,0,0,0,0,0,0,0⟩) out) else out partial_fixpoint def D_colsZ (c:D_P) (lo sp:Ὠ) (o y x:Ὣ) (b q:ὦ) (rr:D_R) (out:ѐ) : ѐ := if h8:x< c.g.wo∧c.g.f4=true∧b< c.l8 then if zBlk c.g o y x then D_colsZ c lo sp o y (x+8) (b+8) (q+8) rr (D_z8 q (c.g.wo-x).toUSize out) else let r:=D_go8R c.g.xd c.wd c.off b c.e 0 c.he c.hw c.hs (c.h8 b h8.2.2) c.ze c.ze c.ze c.ze c.ze c.ze c.ze c.ze rr let n:=(c.g.wo-x).toUSize D_colsZ c lo sp o y (x+8) (b+8) (q+8) r (D_g8 c lo sp o y x b q n r out) else if x< c.g.wo then D_colsZ c lo sp o y (x+1) (b+c.g.step) (q+1) rr (wrW out q (D_finT c o y x b)) else out partial_fixpoint def D_rcZ (c:D_P) (lo sp:Ὠ) (o y x:Ὣ) (b q q0:ὦ) (rr:D_R) (out:ѐ) : ѐ := if hy:y< c.g.ho then if h8:x< c.g.wo∧c.g.f4=true∧b< c.l8 then if zBlk c.g o y x then D_rcZ c lo sp o y (x+8) (b+8) (q+8) q0 rr (D_z8 q (c.g.wo-x).toUSize out) else let r:=D_go8R c.g.xd c.wd c.off b c.e 0 c.he c.hw c.hs (c.h8 b h8.2.2) c.ze c.ze c.ze c.ze c.ze c.ze c.ze c.ze rr let n:=(c.g.wo-x).toUSize D_rcZ c lo sp o y (x+8) (b+8) (q+8) q0 r (D_g8 c lo sp o y x b q n r out) else if x< c.g.wo then D_rcZ c lo sp o y (x+1) (b+c.g.step) (q+1) q0 rr (wrW out q (D_finT c o y x b)) else D_rcZ c lo sp o (y+1) 0 ((y+1).toUSize*c.g.step*c.g.wp.toUSize) (q0+c.g.wo.toUSize) (q0+c.g.wo.toUSize) rr out else out partial_fixpoint def D_rowsZ (c:D_P) (lo sp:Ὠ) (o y:Ὣ) (q:ὦ) (rs:List D_R) (out:ѐ):ѐ := if y< c.g.ho then D_rowsZ c lo sp o (y+1) (q+c.g.wo.toUSize) rs.tail (D_colsZ c lo sp o y 0 (ѩy*c.g.step*c.g.wp.toUSize) q (rs.headD ⟨0,0,0,0,0,0,0,0,0⟩) out) else out partial_fixpoint lemma qGn {n m:Ὣ} (d:Ὣ) (off:ѐ) (hs:n<2^32) (hm:∀ j (h:j< ѧoff),off[j].toNat<=m) (b:ὦ) (hb:b<(n-(m+d)).toUSize) (j:Ὣ) (h:j< ѧoff):Ѥb+off[j].toNat+d< n:=by have h1:=А.1 hb;rw[qAa _ (by clear hb h h1; exact omS373 hs)] at h1;have:=hm j h;(clear hs hb; omega) lemma qJv {off:ѐ} {m f:ὥ} {c:ὦ} (hm:∀ j (h:j< ѧoff),off[j].toNat<=ѥm) : ∀ j (h:j<(wrW off c f).size),(wrW off c f)[j].toNat<=(if m< f then f else m).toNat:=by intro j h;have e:(if m< f then f else m).toNat=max ѥm ѥf:=by split<;>rename_i hc<;>rw[ἳ] at hc<;>(clear h; omega) rw[e];by_cases hc:c< off.usize . have e2:wrW off c f=off.uset c f (qAp off c hc):=by unfold wrW;rw[Ἄ hc] have h0:j< ѧoff:=by rw[e2] at h;simpa using h have g:=hm j h0;simp only[e2,Array.uset,Array.getElem_set];split<;>omega . have e2:wrW off c f=off:=by unfold wrW;rw[ἔ hc] have h0:j< ѧoff:=by rw[e2] at h;exact h have g:=hm j h0;simp only[e2];(clear e hc; omega) lemma qF0 (k:Ὣ):∀ j (h:j<(ἇ k (0:ὥ)).size),(ἇ k (0:ὥ))[j].toNat<=(0:ὥ).toNat:=by intro j h;simp def D_dec (tab W:ѐ) (base:ὥ) (o n t:ὦ) (off:ѐ) (buf:ὤ) (c:ὦ) (l:ὧ) (m:ὥ) (hm:∀ j (h:j< ѧoff),off[j].toNat<=ѥm):R2 := if h:t< n then let w:=rdW W (o+t) if w &&& В == 0 then D_dec tab W base o n (t+1) off buf c l m hm else let v:=dv w let f:=base+rdW tab t D_dec tab W base o n (t+1) (wrW off c f) (wrF buf c v) (c+1) (l+v.abs) (if m< f then f else m) (qJv hm) else ⟨off,buf,c,l,m,hm⟩ termination_by Ѥn-Ѥt decreasing_by all_goals (rw[usz t n h];have:=А.mp h;omega) local instance:Inhabited R2:=⟨⟨#[],FloatArray.empty,0,0,0,λ_ h=>absurd h (Ἲ _)⟩⟩ def D_decAll (tab W:ѐ) (dw:Ὡ) (s:OS) (wp k C:Ὣ):Array R2 := Array.ofFn (n:=C) λo=>D_dec tab W (if dw then (o.val*((s.h+2*s.pad)*wp)).toUInt32 else 0) (o.val*k).toUSize ѩk 0 (ἇ k 0) (pushZ ѩk 0 (ἆ k)) 0 0 0 (qF0 k) def mkCV (W b:ѐ) (s:OS) (dw:Ὡ) (k C:Ὣ):CV := let tab:=D_tq k s.kw s.kh (s.h+2*s.pad) (s.w+2*s.pad) 0 0 0 0 (Array.emptyWithCapacity k) ⟨scanH W,scanH b,tab,D_decAll tab W dw s (s.w+2*s.pad) k C⟩ abbrev CVV (W b:ѐ) (s:OS) (dw:Ὡ) (k C:Ὣ) := {v:CV // v=mkCV W b s dw k C} local instance cvSub (W b:ѐ) (s:OS) (dw:Ὡ) (k C:Ὣ) : Subsingleton (CVV W b s dw k C):=⟨λa b=>Subtype.ext (a.2.trans b.2.symm)⟩ structure CE where (W b:ѐ) (s:OS) (dw:Ὡ) (k C:Ὣ) (v:CV) (g:ὦ) (ok:v=mkCV W b s dw k C) @[inline] def sEq (a b:OS):Ὡ := a.cin == b.cin && a.h == b.h && a.w == b.w && a.cout == b.cout && a.kh == b.kh && a.kw == b.kw && a.stride == b.stride && a.pad == b.pad lemma qH4 {a b:OS} (h:sEq a b=true):a=b:=by cases a;cases b;simp only[sEq,and_eq_true,beq_iff_eq] at h;obtain ⟨⟨⟨⟨⟨⟨⟨h1,h2⟩,h3⟩,h4⟩,h5⟩,h6⟩,h7⟩,h8⟩:=h;subst h1 h2 h3 h4 h5 h6 h7 h8;rfl def cvF (W b:ѐ) (s:OS) (dw:Ὡ) (k C:Ὣ) (g:ὦ) (es:Array CE) (i:Ὣ):Option (CVV W b s dw k C) := if h:i< ѧes then if es[i].g == g then if hk:withPtrEq es[i].W W (λ_=>es[i].W == W) (λe=>by rw[e];exact beq_self_eq_true W) then if hb:withPtrEq es[i].b b (λ_=>es[i].b == b) (λe=>by rw[e];exact beq_self_eq_true b) then if hs:sEq es[i].s s && es[i].dw == dw && es[i].k == k && es[i].C == C then some ⟨es[i].v,by simp only[and_eq_true,beq_iff_eq] at hs obtain ⟨⟨⟨h1,h2⟩,h3⟩,h4⟩:=hs rw[<-eq_of_beq hk,<-eq_of_beq hb,<-qH4 h1,<-h2,<-h3,<-h4];exact es[i].ok⟩ else cvF W b s dw k C g es (i+1) else cvF W b s dw k C g es (i+1) else cvF W b s dw k C g es (i+1) else cvF W b s dw k C g es (i+1) else none partial_fixpoint @[noinline] def cvS:ST.Ref Unit (Array CE):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def cvGet (W b:ѐ) (s:OS) (dw:Ὡ) (k C:Ὣ):CVV W b s dw k C := withPtrAddr W (λg => let es:=(ST.Prim.Ref.get cvS (Void.mk ())).val match cvF W b s dw k C g es 0 with | some v=>v | none => let v:=mkCV W b s dw k C let old:=(ST.Prim.Ref.swap cvS (#[⟨W,b,s,dw,k,C,v,g,rfl⟩] ++ (if ѧes<256 then es else es.pop)) (Void.mk ())).val match cvF W b s dw k C g old 0 with | some v=>v | none=>⟨v,rfl⟩) (λ_ _=>Subsingleton.elim _ _) def D_outsC (g:D_C) (hs:g.xd.size<2^32) (o:Ὣ) (q:ὦ) (rs:Array R2) (out:ѐ):ѐ := if o< g.C then let r:=rs[o]! if h:r.c.toNat<=r.off.size∧r.c.toNat<=r.buf.size then let c:D_P:=⟨g,r.buf,r.off,r.c,(g.xd.size-(r.m.toNat+0)).toUSize, (g.xd.size-(r.m.toNat+7)).toUSize,g.nf*(dv g.hi*r.l+(dv (rdW g.b ѩo)).abs), dv (rdW g.b ѩo),0,h.1,h.2,hs, qGn 0 r.off hs r.hm,qGn 7 r.off hs r.hm,rfl⟩ D_outsC g hs (o+1) (q+(g.ho*g.wo).toUSize) rs (if g.ex.1.isEmpty then D_rc c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o 0 0 ((0:Ὣ).toUSize*c.g.step*c.g.wp.toUSize) q q ⟨0,0,0,0,0,0,0,0,0⟩ out else D_rcZ c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o 0 0 ((0:Ὣ).toUSize*c.g.step*c.g.wp.toUSize) q q ⟨0,0,0,0,0,0,0,0,0⟩ out) else out else out partial_fixpoint def D_Fc (dw:Ὡ) (s:OS) (relu:Ὡ) (X W b:ѐ) (k C:Ὣ) (cv:CV) : ѐ := let hp:=s.h+2*s.pad let wp:=s.w+2*s.pad let rx:=D_scan X X.usize 0 (qAd X) Е 0 if hg:ѧX<=4294967295∧0x007FFFFF<=rx.lo∧rx.hi<У∧ѧX=s.cin*s.h*s.w ∧ ѧW=C*k∧ѧb=C∧0< s.stride∧s.stride<=4294967295∧0< k∧k<2^20 ∧ s.kh<=hp∧s.kw<=wp∧hp<=4294967295∧wp<=4294967295∧ѧW<=4294967295∧ѧb<=4294967295 ∧ C*(s.ho*s.wo)<=4294967295∧s.cin*hp*wp<=4294967295 ∧ cv.hW≠Е ∧ cv.hb≠Е then let tight:=(rx.hi >>> (23:ὥ))-((rx.lo+1) >>> (23:ὥ)) > 99 let R:=s.cin*hp let xd:=D_xs s X (Nat.lt_of_le_of_lt hg.1 (by norm_num)) wp R if hs:Ѩxd<=4294967295 then let g:D_C:=⟨dw,relu,s.stride == 1 && !tight,s,X,W,b,k,C,s.ho,s.wo,wp, s.stride.toUSize,rx.hi,xd,(k.toUInt64+8).toFloat*Ἃ 0x3CA0000000000000, cv.tab,mkExS s X b dw s.ho⟩ D_outsC g (Nat.lt_of_le_of_lt hs (by norm_num)) 0 0 cv.rs (ἇ (C*(s.ho*s.wo)) 0) else if dw then depthwiseWithO dotFn s relu X W b else conv2dWithO dotFn s relu X W b else if dw then depthwiseWithO dotFn s relu X W b else conv2dWithO dotFn s relu X W b def D_F (dw:Ὡ) (s:OS) (relu:Ὡ) (X W b:ѐ) (k C:Ὣ) : ѐ := D_Fc dw s relu X W b k C (cvGet W b s dw k C).1 def Cn1 (s:OS):OS := if s.kh=1∧s.kw=1∧s.stride=1∧s.pad=0∧0< s.h∧0< s.w then {s with h:=1,w:=s.h*s.w} else s def convF (s:OS) (relu:Ὡ) (X W b:ѐ):ѐ := D_F false (Cn1 s) relu X W b (s.cin*s.kh*s.kw) s.cout def depthF (s:OS) (relu:Ὡ) (X W b:ѐ):ѐ := D_F true s relu X W b (s.kh*s.kw) s.cin def D_px (s:OS) (X:ё) (c yy xx:Ὣ):Ὢ := if yy< s.pad∨xx< s.pad∨yy-s.pad ≥ s.h∨xx-s.pad ≥ s.w then 0 else X[(c*s.h+(yy-s.pad))*s.w+(xx-s.pad)]! def D_Fx (s:OS) (X:ё) (q:Ὣ):ὧ := dv (D_px s X (q/(s.w+2*s.pad)/(s.h+2*s.pad)) (q/(s.w+2*s.pad)%(s.h+2*s.pad)) (q%(s.w+2*s.pad))) def D_Pre (F:Ὣ->ὧ) (m:Ὣ) (a:ὤ):Prop := Ѩa=m∧∀ q,q< m->a.data[q]! = F q lemma qCh {F:Ὣ->ὧ} {m:Ὣ} {a:ὤ} {v:ὧ} (h:D_Pre F m a) (hv:v=F m):D_Pre F (m+1) (a.push v):=by refine ⟨by rw[qA2,h.1],λq hq=>?_⟩;rw[qGr,h.1];split<;>rename_i e;. rw[e,hv] exact h.2 q (by exact omS374 hq e) lemma qFp (m d:Ὣ):m+(d+1)=m+1+d :=(by exact omS375) def D_Sp (F:Ὣ->ὧ) (m:Ὣ) (a:ὤ):Prop := m<=Ѩa∧∀ q,q< m->a.data[q]! = F q structure D_Ok (g:D_C):Prop where hk:g.k=if g.dw then g.s.kh*g.s.kw else g.s.cin*g.s.kh*g.s.kw hC:g.C=if g.dw then g.s.cin else g.s.cout ho:g.ho=g.s.ho wo:g.wo=g.s.wo wp:g.wp=g.s.w+2*g.s.pad st:g.step.toNat=g.s.stride nf:g.nf=nfOf g.k f4:g.f4=true->g.s.stride=1 p0:0< g.s.stride pk:0< g.k nk:g.k<2^20 kh:g.s.kh<=g.s.h+2*g.s.pad kw:g.s.kw<=g.s.w+2*g.s.pad xd:D_Sp (D_Fx g.s g.X) (g.s.cin*(g.s.h+2*g.s.pad)*(g.s.w+2*g.s.pad)) g.xd xs:g.xd.size<2^32 Hx:C_Hv g.X g.hi HW:∀ q:Ὣ,good g.W[q]! = true Hb:∀ q:Ὣ,good g.b[q]! = true sW:g.W.size=g.C*g.k sW2:g.W.size<2^32 sb:g.b.size<2^32 sN:g.C*(g.ho*g.wo)<2^32 wp2:g.wp<2^32 tb:g.tab=Array.ofFn (n:=g.k) λt=>(D_off g.s t.val).toUInt32 lemma qJt {F:Ὣ->ὧ} {m:Ὣ} (n:ὦ) (d:Ὣ):∀ (k:ὦ) (a:ὤ),Ѥk+d=Ѥn->D_Sp F m a->D_Sp F m (pushZ n k a):=by induction d with | zero => intro k a h H;rw[pushZ,ἔ (by rw[А];omega)];exact H | succ d ih => intro k a h H;have ht:k< n:=by rw[А];exact omS136 h rw[pushZ,Ἄ ht];refine ih (k+1) _ (by rw[usz k n ht];(clear ht; omega)) ⟨by rw[qA2];have:=H.1;(clear h ht; omega),λq hq=>?_⟩;have:=H.1;rw[qGr,ἐ (by clear h ht; omega)];exact H.2 q hq lemma qCk {i e:ὦ} (h:Ѥe<=Ѥi):¬i< e :=mt А.1 (Nat.not_lt.2 h) lemma qBz {i e:ὦ} {d:Ὣ} (h:Ѥi+(d+1)=Ѥe) : i< e∧(i+1).toNat+d=Ѥe:=by have t:=А.2 ((by exact omS136 h):Ѡi< Ѡe);exact ⟨t,by rw[usz i e t];(clear t; exact omS137 h)⟩ lemma qCc {F:Ὣ->ὧ} {v:ὧ} {n:ὦ} (d:Ὣ) : ∀ (k:ὦ) (m:Ὣ) (a:ὤ),Ѥk+d=Ѥn->D_Pre F m a → (∀ i,m<=i->i< m+d->F i=v)->D_Pre F (m+d) (D_fill v n k a):=by induction' d with d ih<;>intro k m a he H hv . rw[D_fill,ἔ (qCk he.ge)];exact H obtain ⟨ht,hu⟩:=qBz he rw[D_fill,Ἄ ht,qFp] exact ih (k+1) (m+1) _ hu (qCh H (hv m (by exact Nat.le_refl _) (by clear he ht; (clear hu; omega))).symm) λi h1 h2=>hv i (by exact Nat.le_of_lt ‹_›) (by clear he ht h1; (clear hu; omega)) lemma qEr {F:Ὣ->ὧ} {X:ѐ} {o n:ὦ} (hs:ѧX<2^32) (ho:Ѥo+Ѥn<=ѧX) (d:Ὣ) : ∀ (t:ὦ) (m:Ὣ) (a:ὤ),Ѥt+d=Ѥn->D_Pre F m a → (∀ j,j< d->F (m+j)=dv X[Ѥo+Ѥt+j]!) → D_Pre F (m+d) (D_copy X o n t hs ho a):=by induction' d with d ih<;>intro t m a he H hv . rw[D_copy,ἔ (qCk he.ge)];exact H obtain ⟨ht,hu⟩:=qBz he rw[D_copy,Ἄ ht,qFp] refine ih (t+1) (m+1) _ hu (qCh H ?_) λj hj=>?_ . rw[qFx,qAv _ _ (by clear ht; omega)];exact (hv 0 (by clear he ht hu; omega)).symm simpa only [usz t n ht,Nat.add_assoc,Nat.add_comm 1] using hv (j+1) (by exact Nat.lt_succ_of_le ‹_›) lemma qCn {c:Ὣ} (a:Ὣ) {b:Ὣ} (h:b< c):(a*c+b)/c=a∧(a*c+b)%c=b:=by rw[ἥ a c,Nat.mul_add_div (by exact omS376 h),Nat.mul_add_mod,Ὃ h,Ἁ h];exact ⟨rfl,rfl⟩ lemma qAi (s:OS) (X:ё) (r:Ὣ) {i:Ὣ} (hi:i< s.w+2*s.pad) : D_Fx s X (r*(s.w+2*s.pad)+i) =dv (D_px s X (r/(s.h+2*s.pad)) (r%(s.h+2*s.pad)) i):=by simp only[D_Fx,qCn r hi] lemma qFo {F:Ὣ->ὧ} {v:ὧ} {n:ὦ} {m d:Ὣ} {a:ὤ} (hn:Ѥn=d) (H:D_Pre F m a) (hv:∀ u,u< d->F (m+u)=v):D_Pre F (m+d) (D_fill v n 0 a) := qCc d 0 m a (by rw[hn];exact Ἇ d) H λi h1 h2=>by obtain ⟨u,rfl⟩:=Nat.exists_eq_add_of_le h1 exact hv u (by clear hn h1; exact omS377 h2) lemma qF5 (m p w:Ὣ):m+(w+2*p)=m+p+w+p :=(by exact omS378) lemma qE0 (s:OS) (X:ѐ) (hs:ѧX<2^32) (hX:ѧX=s.cin*s.h*s.w) (hh:s.h+2*s.pad<2^32) (hw:s.w+2*s.pad<2^32) {R:Ὣ} (hR:R=s.cin*(s.h+2*s.pad)) (d:Ὣ) : ∀ (r:Ὣ) (a:ὤ),r+d=R → D_Pre (D_Fx s X) (r*(s.w+2*s.pad)) a → D_Pre (D_Fx s X) (R*(s.w+2*s.pad)) (D_img s X hs (dv 0) R r a):=by induction' d with d ih<;>intro r a he H . rw[D_img,ἔ (by clear hs hX hh hw; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))),<-he];exact H have hr:r< R :=(by clear hX hh hw; exact omS136 he) have hc:=Ἰ (hr.trans_eq (hR.trans (ἥ _ _))) have ep:=qAa s.pad (by clear hX hw hR he hr hc; exact omS379 hh) have ew:=qAa s.w (by clear hX hR he hr hc; exact omS380 hw) have hO:=λg:r%(s.h+2*s.pad)-s.pad< s.h=>qBv (qDf hc g) (Nat.le_refl s.w) rw[D_img,Ἄ hr] dsimp only split<;>rename_i g . obtain ⟨g1,g2,g3⟩:=g;have:=hO g2;apply ih (r+1) _ (by clear hX hh hw hr hc ep ew g1 g2 g3 this; exact omS137 he);rw[ᾀ,qF5];refine qFo ep (qEr hs g3 s.w 0 _ _ (by rw[ew];exact Ἇ _) (qFo ep H λu hu=>?_) λj hj=>?_) λu hu=>?_;. rw[qAi _ _ _ (by clear hX hh hw hR he hr hc g1 g2 g3 this; (clear ep; exact omS381 hu)),D_px,ἱ (by clear hX hh hw hR he hr hc ew g1 g2 g3 this; (clear ep; exact omS382 hu))] . rw[ὢ,qAi _ _ _ (by clear hX hw hR he hr hc g1 g2 g3 this; (clear ew; exact omS383 hj)),D_px,ἐ (by clear hX hh hw hR he hr hc g3 this; (clear ep ew; exact omS384 g1 g2 hj)),Nat.add_sub_cancel_left,qAa _ (by clear hR he hr hc g1 g2 g3 hj; exact omS385 hs hX this)];rfl . rw[ὢ,ὢ,qAi _ _ _ (by clear hX hh hw hR he hr hc ew g1 g2 g3 this; (clear ep; exact omS386 hu)),D_px,ἱ (by clear hh hw hR he hr hc ep g1 g2 this hu; exact omS387)] apply ih (r+1) _ (by clear hX hh hw hr hc ep ew g; exact omS137 he) rw[ᾀ] exact qFo (qAa _ hw) H λu hu=>by rw[qAi _ _ _ hu,D_px,ἱ] by_contra n have:=hO (by clear hX hh hw hR he hr hc ep ew g hu; exact omS388 n) exact g ⟨by (clear hX hh hw hR he hr hc ew g hu this; (clear ep; exact omS389 n)),by (clear hX hh hw hR he hr hc ep ew g hu this; exact omS388 n),by rw[qAa _ (by clear hh hw hR he hr hc ep g hu n; exact omS385 hs hX this),ew,hX];exact this⟩ def D_t0 (g:D_C) (o:Ὣ):Ὣ:=if g.dw then o*g.k else 0 def D_xw (g:D_C) (o y x t:Ὣ):Ὢ:=windowAtO g.s g.X y x (D_t0 g o+t) def D_out (g:D_C) (o y x:Ὣ):Ὢ := act g.relu (dotOf (g.k+1) (λt=>if t< g.k then D_xw g o y x t else oneW) (λt=>if t< g.k then g.W[o*g.k+t]! else g.b[o]!)) structure D_PO (c:D_P) (o:Ὣ) (L:љ):Prop where ok:D_Ok c.g hC:o< c.g.C len:c.e.toNat=ѣL nd:L.Nodup lt:∀ t∈L,t< c.g.k hz:∀ t,t< c.g.k->t∉L->c.g.W[o*c.g.k+t]! &&& В=0 rd:∀ j p:Ὣ,L[j]?=some p → (c.off[j]! : ὥ).toNat=D_off c.g.s (D_t0 c.g o+p) ∧ c.wd.data[j]! = dv c.g.W[o*c.g.k+p]! e0:c.e0=nfOf c.g.k*(dv c.g.hi*L.foldl (λacc t=>acc+(dv c.g.W[o*c.g.k+t]!).abs) 0 + (dv c.g.b[o]!).abs) bv:c.bv=dv c.g.b[o]! lemma qCv (g:D_C) (o y x:Ὣ):D_slow g o y x=D_out g o y x:=by unfold D_slow D_out D_xw D_t0;rw[qAg] theorem zAll_spec (fa fb:Nat->UInt32) (N:Nat) : ∀ n i, i + n ≤ N → zAll fa fb i n = true → dsum (Array.ofFn (n:=N) fun j => fa j) (Array.ofFn (n:=N) fun j => fb j) i n = 0 ∧ dallNZ (Array.ofFn (n:=N) fun j => fa j) (Array.ofFn (n:=N) fun j => fb j) i n = zNeg fa fb i n ∧ (∀ j, i ≤ j → j < i + n → expOf (fa j) ≠ 255 ∧ expOf (fb j) ≠ 255) := by intro n induction n with | zero => intro i _ _; exact ⟨rfl, rfl, fun j h1 h2 => absurd h2 (by omega)⟩ | succ n ih => intro i hi h simp only [zAll, Bool.and_eq_true, bne_iff_ne, ne_eq, beq_iff_eq] at h obtain ⟨⟨⟨h1, h2⟩, h3⟩, h4⟩ := h obtain ⟨r1, r2, r3⟩ := ih (i+1) (by omega) h4 have ea : (Array.ofFn (n:=N) fun j => fa j)[i]! = fa i := Pinned.getElem!_ofFn N fa i (by omega) have eb : (Array.ofFn (n:=N) fun j => fb j)[i]! = fb i := Pinned.getElem!_ofFn N fb i (by omega) have hsv : sv (fa i) * sv (fb i) = 0 := by rcases Nat.mul_eq_zero.1 h3 with h | h <;> simp [sv, h] refine ⟨?_, ?_, ?_⟩ · simp only [dsum, ea, eb, hsv, zero_mul, r1, add_zero] · simp only [dallNZ, ea, eb, h3, r2, zNeg, decide_true, Bool.true_and] · intro j hj1 hj2 by_cases hji : j = i · subst hji; exact ⟨h1, h2⟩ · exact r3 j (by omega) (by omega) theorem zdotFn_eq : zdotFn = dotFn := by funext n fa fb unfold zdotFn split · rename_i hz obtain ⟨r1, r2, r3⟩ := zAll_spec fa fb n n 0 (by omega) hz rw [D.qAi] unfold dotOf have hs : (Array.ofFn (n:=n) fun i => fb i).size = (Array.ofFn (n:=n) fun i => fa i).size := by simp have hall : ∀ k, k < (Array.ofFn (n:=n) fun i => fa i).size → expOf (Array.ofFn (n:=n) fun i => fa i)[k]! ≠ 255 ∧ expOf (Array.ofFn (n:=n) fun i => fb i)[k]! ≠ 255 := by intro k hk simp only [Array.size_ofFn] at hk rw [Pinned.getElem!_ofFn n fa k hk, Pinned.getElem!_ofFn n fb k hk] exact r3 k (by omega) (by omega) rw [← D.qEg _ _ hs hall] simp only [Array.size_ofFn, r1, r2] unfold finishWord simp · rfl theorem zCols_spec (s:OS) (X:Array UInt32) (c yy x0:Nat) : ∀ n i, zCols s X c yy x0 i n = true → ∀ d, i ≤ d → d < i + n → pixZ s X c yy (x0+d) = true := by intro n induction n with | zero => intro i _ d h1 h2; omega | succ n ih => intro i h d h1 h2 simp only [zCols, Bool.and_eq_true] at h by_cases hd : d = i · subst hd; exact h.1 · exact ih (i+1) h.2 d (by omega) (by omega) theorem zRows_spec (s:OS) (X:Array UInt32) (c y0 x0:Nat) : ∀ n i, zRows s X c y0 x0 i n = true → ∀ e, i ≤ e → e < i + n → zCols s X c (y0+e) x0 0 s.kw = true := by intro n induction n with | zero => intro i _ e h1 h2; omega | succ n ih => intro i h e h1 h2 simp only [zRows, Bool.and_eq_true] at h by_cases he : e = i · subst he; exact h.1 · exact ih (i+1) h.2 e (by omega) (by omega) theorem wFin_spec (W:Array UInt32) (base:Nat) : ∀ n i, wFin W base i n = true → ∀ d, i ≤ d → d < i + n → expOf W[base+d]! ≠ 255 := by intro n induction n with | zero => intro i _ d h1 h2; omega | succ n ih => intro i h d h1 h2 simp only [wFin, Bool.and_eq_true, bne_iff_ne, ne_eq] at h by_cases hd : d = i · subst hd; exact h.1 · exact ih (i+1) h.2 d (by omega) (by omega) theorem mantOf_fin {w:UInt32} (h:mantOf w = 0) : expOf w ≠ 255 := by unfold mantOf at h split at h · rename_i he; rw [he]; decide · omega theorem win_mant (s:OS) (X:Array UInt32) (o y x:Nat) (hk:0 < s.kw) (h:zRows s X o (y*s.stride) (x*s.stride) 0 s.kh = true) (t:Nat) (ht:t < s.kh*s.kw) : mantOf (windowAtO s X y x (o*(s.kh*s.kw)+t)) = 0 := by have hdy : t / s.kw < s.kh := (Nat.div_lt_iff_lt_mul hk).2 ht have hr := zRows_spec s X o (y*s.stride) (x*s.stride) s.kh 0 h (t / s.kw) (Nat.zero_le _) (by omega) have hp := zCols_spec s X o (y*s.stride + t / s.kw) (x*s.stride) s.kw 0 hr (t % s.kw) (Nat.zero_le _) (by have := Nat.mod_lt t hk; omega) have hkk : 0 < s.kh*s.kw := by omega have e1 : (o*(s.kh*s.kw)+t)/(s.kh*s.kw) = o := by rw [Nat.mul_comm, Nat.mul_add_div hkk, Nat.div_eq_of_lt ht, Nat.add_zero] have e2 : (o*(s.kh*s.kw)+t)/s.kw%s.kh = t/s.kw := by rw [show o*(s.kh*s.kw)+t = t + s.kw*(o*s.kh) by ring, Nat.add_mul_div_left _ _ hk, Nat.add_mul_mod_self_right, Nat.mod_eq_of_lt hdy] have e3 : (o*(s.kh*s.kw)+t)%s.kw = t%s.kw := by rw [show o*(s.kh*s.kw)+t = t + s.kw*(o*s.kh) by ring, Nat.add_mul_mod_self_left] simp only [windowAtO, e1, e2, e3] simp only [pixZ, Bool.or_eq_true, decide_eq_true_eq, beq_iff_eq] at hp split · decide · rename_i hc rcases hp with (((h1 | h1) | h1) | h1) | h1 · exact absurd (Or.inl h1) hc · exact absurd (Or.inr (Or.inl h1)) hc · exact absurd (Or.inr (Or.inr (Or.inl h1))) hc · exact absurd (Or.inr (Or.inr (Or.inr h1))) hc · exact h1 theorem zAll_of (fa fb:Nat->UInt32) : ∀ n i, (∀ t, i ≤ t → t < i + n → expOf (fa t) ≠ 255 ∧ expOf (fb t) ≠ 255 ∧ mantOf (fa t) * mantOf (fb t) = 0) → zAll fa fb i n = true := by intro n induction n with | zero => intro i _; rfl | succ n ih => intro i h obtain ⟨h1, h2, h3⟩ := h i (Nat.le_refl _) (by omega) simp only [zAll, Bool.and_eq_true, bne_iff_ne, ne_eq, beq_iff_eq] exact ⟨⟨⟨h1, h2⟩, h3⟩, ih (i+1) (fun t a b => h t (by omega) (by omega))⟩ theorem zNeg_spec (fa fb:Nat->UInt32) : ∀ n i, zNeg fa fb i n = true → ∀ t, i ≤ t → t < i + n → Bool.xor (signOf (fa t)) (signOf (fb t)) = true := by intro n induction n with | zero => intro i _ t h1 h2; omega | succ n ih => intro i h t h1 h2 simp only [zNeg, Bool.and_eq_true] at h by_cases ht : t = i · subst ht; exact h.1 · exact ih (i+1) h.2 t (by omega) (by omega) theorem zWin_out (g:D_C) (o y x:Nat) (h:zWin g o y x = true) : D_out g o y x = 0 := by simp only [zWin, Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq] at h obtain ⟨⟨⟨⟨⟨hdw, hk⟩, hkw⟩, hb⟩, hw⟩, hr⟩ := h have hza : zAll (fun t => if t < g.k then D_xw g o y x t else oneW) (fun t => if t < g.k then g.W[o*g.k+t]! else g.b[o]!) 0 (g.k+1) = true := by apply zAll_of intro t _ ht by_cases htk : t < g.k · have hm : mantOf (D_xw g o y x t) = 0 := by simp only [D_xw, D_t0, hdw, ite_true, hk] exact win_mant g.s g.X o y x hkw hr t (hk ▸ htk) simp only [htk, ite_true, hm, Nat.zero_mul, and_true] exact ⟨mantOf_fin hm, wFin_spec g.W (o*g.k) g.k 0 hw t (Nat.zero_le _) (by omega)⟩ · have htk' : t = g.k := by omega subst htk' simp only [Nat.lt_irrefl, ite_false, hb] decide have hzn : zNeg (fun t => if t < g.k then D_xw g o y x t else oneW) (fun t => if t < g.k then g.W[o*g.k+t]! else g.b[o]!) 0 (g.k+1) = false := by cases hz : zNeg (fun t => if t < g.k then D_xw g o y x t else oneW) (fun t => if t < g.k then g.W[o*g.k+t]! else g.b[o]!) 0 (g.k+1) · rfl · have := zNeg_spec _ _ (g.k+1) 0 hz g.k (Nat.zero_le _) (by omega) simp only [Nat.lt_irrefl, ite_false, hb] at this exact absurd this (by decide) unfold D_out rw [← D.qAi, ← zdotFn_eq] unfold zdotFn rw [if_pos hza] simp only [hzn, Bool.and_false] cases g.relu <;> rfl theorem zChans_spec (s:OS) (X:Array UInt32) (y0 x0:Nat) : ∀ n i, zChans s X y0 x0 i n = true → ∀ c, i ≤ c → c < i + n → zRows s X c y0 x0 0 s.kh = true := by intro n induction n with | zero => intro i _ c h1 h2; omega | succ n ih => intro i h c h1 h2 simp only [zChans, Bool.and_eq_true] at h by_cases hc : c = i · subst hc; exact h.1 · exact ih (i+1) h.2 c (by omega) (by omega) theorem zWinC_out (g:D_C) (o y x:Nat) (h:zWinC g o y x = true) : D_out g o y x = 0 := by simp only [zWinC, Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq, Bool.not_eq_true'] at h obtain ⟨⟨⟨⟨⟨hdw, hk⟩, hkw⟩, hb⟩, hw⟩, hr⟩ := h have hza : zAll (fun t => if t < g.k then D_xw g o y x t else oneW) (fun t => if t < g.k then g.W[o*g.k+t]! else g.b[o]!) 0 (g.k+1) = true := by apply zAll_of intro t _ ht by_cases htk : t < g.k · have hkk : 0 < g.s.kh * g.s.kw := by rcases Nat.eq_zero_or_pos (g.s.kh * g.s.kw) with h0 | h0 · rw [hk, h0, Nat.mul_zero] at htk; omega · exact h0 have hc : t / (g.s.kh * g.s.kw) < g.s.cin := by rw [hk] at htk exact (Nat.div_lt_iff_lt_mul hkk).2 htk have ht' : t % (g.s.kh * g.s.kw) < g.s.kh * g.s.kw := Nat.mod_lt _ hkk have hdec : t = t / (g.s.kh * g.s.kw) * (g.s.kh * g.s.kw) + t % (g.s.kh * g.s.kw) := by rw [Nat.mul_comm]; exact (Nat.div_add_mod t _).symm have hm : mantOf (D_xw g o y x t) = 0 := by simp only [D_xw, D_t0, hdw, Bool.false_eq_true, ite_false, Nat.zero_add] rw [hdec] exact win_mant g.s g.X (t / (g.s.kh * g.s.kw)) y x hkw (zChans_spec g.s g.X _ _ g.s.cin 0 hr _ (Nat.zero_le _) (by omega)) _ ht' simp only [htk, ite_true, hm, Nat.zero_mul, and_true] exact ⟨mantOf_fin hm, wFin_spec g.W (o*g.k) g.k 0 hw t (Nat.zero_le _) (by omega)⟩ · have htk' : t = g.k := by omega subst htk' simp only [Nat.lt_irrefl, ite_false, hb] decide have hzn : zNeg (fun t => if t < g.k then D_xw g o y x t else oneW) (fun t => if t < g.k then g.W[o*g.k+t]! else g.b[o]!) 0 (g.k+1) = false := by cases hz : zNeg (fun t => if t < g.k then D_xw g o y x t else oneW) (fun t => if t < g.k then g.W[o*g.k+t]! else g.b[o]!) 0 (g.k+1) · rfl · have := zNeg_spec _ _ (g.k+1) 0 hz g.k (Nat.zero_le _) (by omega) simp only [Nat.lt_irrefl, ite_false, hb] at this exact absurd this (by decide) unfold D_out rw [← D.qAi, ← zdotFn_eq] unfold zdotFn rw [if_pos hza] simp only [hzn, Bool.and_false] cases g.relu <;> rfl lemma qCvZ (g:D_C) (o y x:Ὣ):D_slowZ g o y x=D_out g o y x:=by unfold D_slowZ;split · rename_i h;rcases Bool.or_eq_true_iff.1 h with h|h · exact (zWin_out g o y x h).symm · exact (zWinC_out g o y x h).symm · exact qCv .. theorem zCols_of (s:OS) (X:Array UInt32) (c yy x0:Nat) : ∀ n i, (∀ d, i ≤ d → d < i + n → pixZ s X c yy (x0+d) = true) → zCols s X c yy x0 i n = true := by intro n induction n with | zero => intro i _; rfl | succ n ih => intro i h simp only [zCols, Bool.and_eq_true] exact ⟨h i (Nat.le_refl _) (by omega), ih (i+1) (fun d h1 h2 => h d (by omega) (by omega))⟩ theorem zRows_of (s:OS) (X:Array UInt32) (c y0 x0:Nat) : ∀ n i, (∀ e, i ≤ e → e < i + n → zCols s X c (y0+e) x0 0 s.kw = true) → zRows s X c y0 x0 i n = true := by intro n induction n with | zero => intro i _; rfl | succ n ih => intro i h simp only [zRows, Bool.and_eq_true] exact ⟨h i (Nat.le_refl _) (by omega), ih (i+1) (fun d h1 h2 => h d (by omega) (by omega))⟩ theorem zChans_of (s:OS) (X:Array UInt32) (y0 x0:Nat) : ∀ n i, (∀ c, i ≤ c → c < i + n → zRows s X c y0 x0 0 s.kh = true) → zChans s X y0 x0 i n = true := by intro n induction n with | zero => intro i _; rfl | succ n ih => intro i h simp only [zChans, Bool.and_eq_true] exact ⟨h i (Nat.le_refl _) (by omega), ih (i+1) (fun d h1 h2 => h d (by omega) (by omega))⟩ theorem wFin_of (W:Array UInt32) (base:Nat) (hW:∀ q:Nat, good W[q]! = true) : ∀ n i, wFin W base i n = true := by intro n induction n with | zero => intro i; rfl | succ n ih => intro i simp only [wFin, Bool.and_eq_true, bne_iff_ne, ne_eq] exact ⟨D.qAe _ (hW _), ih (i+1)⟩ /-- the window of lane `(c, y, x)` is zero by the hull entries of output row `y` -/ theorem win_hull (g:D_C) (hwp:g.wp=g.s.w+2*g.s.pad) (c y x:Nat) (hc:c< g.s.cin) (hy:y< g.ho) (h:(x*g.s.stride+g.s.kw ≤ g.ex.1.getD (2*((if g.dw then c else 0)*g.ho+y)) 0 || g.wp ≤ x*g.s.stride+g.ex.1.getD (2*((if g.dw then c else 0)*g.ho+y)+1) 0) = true) : zRows g.s g.X c (y*g.s.stride) (x*g.s.stride) 0 g.s.kh = true := by simp only [Bool.or_eq_true, decide_eq_true_eq] at h apply zRows_of intro i _ hi apply zCols_of intro d _ hd apply g.ex.2 c y _ i hc hy (by omega) rcases h with h | h · exact Or.inl (by omega) · exact Or.inr (by omega) theorem zWinX_out (g:D_C) (hk:g.k=if g.dw then g.s.kh*g.s.kw else g.s.cin*g.s.kh*g.s.kw) (pk:0< g.k) (HW:∀ q:Nat, good g.W[q]! = true) (hwp:g.wp=g.s.w+2*g.s.pad) (o y x:Nat) (hC:g.dw=true → o< g.s.cin) (hy:y< g.ho) (h:zWinX g o y x = true) : D_out g o y x = 0 := by unfold zWinX at h simp only [Bool.and_eq_true, beq_iff_eq] at h obtain ⟨hr, hb⟩ := h cases hd : g.dw · rw [hd] at hk simp only [Bool.false_eq_true, ite_false] at hk apply zWinC_out g o y x have kw : 0 < g.s.kw := by rw [hk] at pk; exact Nat.pos_of_mul_pos_left pk simp only [zWinC, hd, Bool.not_false, Bool.true_and, Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq] refine ⟨⟨⟨⟨by rw [hk, Nat.mul_assoc], kw⟩, hb⟩, wFin_of _ _ HW _ _⟩, ?_⟩ apply zChans_of intro c _ hc apply win_hull g hwp c y x (by omega) hy simp only [hd, Bool.false_eq_true, ite_false] at hr ⊢ exact hr · rw [hd] at hk simp only [ite_true] at hk apply zWin_out g o y x have kw : 0 < g.s.kw := by rw [hk] at pk; exact Nat.pos_of_mul_pos_left pk simp only [zWin, hd, Bool.true_and, Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq] refine ⟨⟨⟨⟨hk, kw⟩, hb⟩, wFin_of _ _ HW _ _⟩, ?_⟩ apply win_hull g hwp o y x (hC hd) hy simp only [hd, ite_true] at hr ⊢ exact hr theorem zBlk_lane (g:D_C) (hs:g.s.stride=1) (o y x k:Nat) (hk:k<8) (h:zBlk g o y x = true) : zWinX g o y (x+k) = true := by unfold zBlk zBlkG at h unfold zWinX simp only [Bool.and_eq_true, beq_iff_eq, Bool.or_eq_true, decide_eq_true_eq] at h ⊢ obtain ⟨_, hr, hb⟩ := h refine ⟨?_, hb⟩ simp only [hs, Nat.mul_one] at hr ⊢ rcases hr with hr | hr · exact Or.inl (by omega) · exact Or.inr (by omega) theorem qCvX (g:D_C) (hk:g.k=if g.dw then g.s.kh*g.s.kw else g.s.cin*g.s.kh*g.s.kw) (pk:0< g.k) (HW:∀ q:Nat, good g.W[q]! = true) (hwp:g.wp=g.s.w+2*g.s.pad) (o y x:Nat) (hC:g.dw=true → o< g.s.cin) (hy:y< g.ho) : D_slowX g o y x = D_out g o y x := by unfold D_slowX split · rename_i h; exact (zWinX_out g hk pk HW hwp o y x hC hy h).symm · exact qCvZ .. def D_B (g:D_C) (y x:Ὣ):Ὣ:=y*g.s.stride*g.wp+x*g.s.stride lemma qE1 {A:ё} {h:Ὢ}:good (0:Ὢ)=true∧(0:Ὢ) &&& В<=h :=⟨rfl,ἃ.2 (Nat.zero_le _)⟩ lemma qGp {A:ё} (H:∀ k:Ὣ,k< ѧA->good A[k]! = true) (q:Ὣ) : good A[q]! = true:=by by_cases h:q< ѧA;. exact H q h rw[ὑ A q h];rfl lemma qBc {s:OS} {X:ё} {hi:Ὢ} (H:C_Hv X hi) (c yy xx:Ὣ) : good (D_px s X c yy xx)=true∧D_px s X c yy xx &&& В<=hi:=by unfold D_px;split;. exact qE1 (A:=X) generalize (c*s.h+(yy-s.pad))*s.w+(xx-s.pad)=n;by_cases h:n< ѧX;. exact ⟨H.2.2.1 n h,H.2.2.2 n h⟩ rw[ὑ X n h];exact qE1 (A:=X) lemma qHk {g:D_C} (ok:D_Ok g) {o t:Ὣ} (hC:o< g.C) (ht:t< g.k) : D_t0 g o+t< g.s.cin*(g.s.kh*g.s.kw):=by have h1:=ok.hk;have h2:=ok.hC;unfold D_t0;cases hd:g.dw<;>simp[hd] at h1 h2 ⊢;. rwa [<-Nat.mul_assoc,<-h1] exact h1 ▸ qDf (h2 ▸ hC) (h1 ▸ ht) lemma qHl {n a b c:Ὣ} (h:n< a*(b*c)):0< b∧0< c:=by constructor<;>refine ὼ λe=>?_<;>simp[e] at h lemma qGd {a b st n m:Ὣ} (h0:0< st) (hk:b<=a) (hy:n<(a-b)/st+1) (hm:m< b) : n*st+m< a:=by have:=Ἒ st (show n<=(a-b)/st by (exact Nat.le_of_lt_succ ‹_›));have:=Nat.div_mul_le_self (a-b) st;(clear h0 hy; omega) lemma qJs (a p w v u y x:Ὣ) : v*w+u+((a*p+y)*w+x)=(a*p+(v+y))*w+(u+x):=by ring lemma qCf {g:D_C} (ok:D_Ok g) {o y x t:Ὣ} (hC:o< g.C) (hy:y< g.ho) (hx:x< g.wo) (ht:t< g.k) : D_B g y x+D_off g.s (D_t0 g o+t)< g.xd.size ∧ g.xd.data[D_B g y x+D_off g.s (D_t0 g o+t)]! = dv (D_xw g o y x t):=by have hb:=qHk ok hC ht have hk:=qHl hb unfold D_xw generalize D_t0 g o+t=u at hb ⊢ have hyy:=qGd ok.p0 ok.kh (hy.trans_eq ok.ho) (ὀ (u/g.s.kw) hk.1) have hxx:=qGd ok.p0 ok.kw (hx.trans_eq ok.wo) (ὀ u hk.2) have hq:=qDf (qDf (Ἰ (hb.trans_eq (ἥ _ _))) hyy) hxx rw[D_B,D_off,ok.wp,qJs] refine ⟨Nat.lt_of_lt_of_le hq ok.xd.1,?_⟩ rw[ok.xd.2 _ hq] simp only[D_Fx,qCn _ hxx,qCn _ hyy] rfl lemma qBm {u v:ὦ} {a b:Ὣ} (hu:Ѥu=a) (hv:Ѥv=b) (h:a+b<2^32) : (u+v).toNat=a+b:=by rw[qAv _ _ (by exact omS390 hu hv h),hu,hv] lemma qH0 {n d:Ὣ} {b i:ὦ} {off:ѐ} (hs:n<2^32) (hb:∀ j (h:j< ѧoff),Ѥb+off[j].toNat+d< n) (hi:Ѥi< ѧoff) : (b+(off.uget i hi).toUSize).toNat=Ѥb+(off[Ѥi]! : ὥ).toNat ∧ Ѥb+(off[Ѥi]! : ὥ).toNat+d< n:=by have h:Ѥb+(off.uget i hi).toNat+d< n:=hb _ hi rw[<-qFx _ _ hi] exact ⟨qBm rfl (ὃ _) (by exact omS372 hs h),h⟩ lemma qGc {c:D_P} {b:ὦ} (hb:∀ j (h:j< c.off.size),Ѥb+c.off[j].toNat+0< c.g.xd.size) (xf wf:Ὣ->ὧ) (L:љ):∀ (i:ὦ) (a t:ὧ),Ѥi+ѣL=c.e.toNat → (∀ j p:Ὣ,L[j]?=some p->c.g.xd.data[Ѥb+(c.off[Ѥi+j]! : ὥ).toNat]! = xf p ∧ c.wd.data[Ѥi+j]! = wf p) → D_goT c.g.xd c.wd c.off b c.e i c.he c.hw c.hs hb a t=L.foldl (λ(acc:F1) p =>let q:=xf p*wf p F1.mk (acc.s+q) (acc.t+q.abs)) ⟨a,t⟩:=by have:=c.he induction' L with p L ih<;>intro i a t h0 H . rw[D_goT,ἔ (qCk h0.ge)];rfl rw[List.length_cons] at h0 obtain ⟨ht,hu⟩:=qBz h0 have h1:=H 0 p rfl rw[Ἵ] at h1 rw[D_goT,Ἄ ht] simp only[qIg] rw[(qH0 c.hs hb (by exact Nat.lt_of_lt_of_le ‹_› ‹_›)).1,h1.1,h1.2,ih (i+1) _ _ hu,@List.foldl_cons] intro j q hq rw[usz i _ ht,Nat.add_right_comm,ὢ] exact H (j+1) q hq def D_ff (xf:Ὣ->Ὣ->ὧ) (wf:Ὣ->ὧ) (L:љ) (k:Ὣ) (a:ὧ):ὧ := L.foldl (λacc p=>acc+xf k p*wf p) a lemma qF7 {c:D_P} {b:ὦ} (hb:∀ j (h:j< c.off.size),Ѥb+c.off[j].toNat+7< c.g.xd.size) (r:D_R) (xf:Ὣ->Ὣ->ὧ) (wf:Ὣ->ὧ) (L:љ):∀ (i:ὦ) (A B C D E F G I:ὧ),Ѥi+ѣL=c.e.toNat → (∀ j p:Ὣ,L[j]?=some p->c.wd.data[Ѥi+j]! = wf p∧∀ d,d<8 → c.g.xd.data[Ѥb+(c.off[Ѥi+j]! : ὥ).toNat+d]! = xf d p) → D_go8R c.g.xd c.wd c.off b c.e i c.he c.hw c.hs hb A B C D E F G I r=⟨r.t,D_ff xf wf L 0 A,D_ff xf wf L 1 B,D_ff xf wf L 2 C,D_ff xf wf L 3 D,D_ff xf wf L 4 E,D_ff xf wf L 5 F,D_ff xf wf L 6 G,D_ff xf wf L 7 I⟩:=by have:=c.he have:=c.hs induction' L with p L ih<;>intro i A B C D E F G I h0 J . rw[D_go8R,ἔ (qCk h0.ge)];cases r;rfl rw[List.length_cons] at h0 obtain ⟨ht,hu⟩:=qBz h0 obtain ⟨h1,h2⟩:=J 0 p rfl rw[Ἵ] at h1 h2 obtain ⟨ep,hbd⟩:=qH0 c.hs hb ((by exact Nat.lt_of_lt_of_le ‹_› ‹_›):Ѡi< c.off.size) have U:=λ(k:Ὣ) (hk:k<8)=>(qBm ep (uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide))) (by clear h0 hu; omega)).symm ▸ h2 k hk rw[D_go8R,Ἄ ht] simp only[qIg] rw[ep,h1,U 1 (by decide),U 2 (by decide),U 3 (by decide),U 4 (by decide),U 5 (by decide),U 6 (by decide),U 7 (by exact Nat.le_refl _),<-Ἵ (_+_),h2 0 (by decide)] refine ih (i+1) _ _ _ _ _ _ _ _ hu λj q hq=>?_ rw[usz i _ ht,Nat.add_right_comm,ὢ] exact J (j+1) q hq theorem D_zt_spec (xd:FloatArray) (off:Array UInt32) (b:Nat) : ∀ n i, D_zt xd off b i n = true → ∀ j, i ≤ j → j < i+n → (xd.data[b+(off[j]!).toNat]!).toBits <<< (1:UInt64) = 0 := by intro n induction n with | zero => intro i _ j h1 h2; omega | succ n ih => intro i h j h1 h2 simp only [D_zt, Bool.and_eq_true, decide_eq_true_eq, beq_iff_eq] at h by_cases hj : j = i · subst hj have e := h.1.2 have g : xd.get! (b+(off[j]!).toNat) = xd.data[b+(off[j]!).toNat]! := by cases xd; rfl rw [g] at e exact e · exact ih (i+1) h.2 j (by omega) (by omega) theorem Rz0 (f:Float) (h:f.toBits <<< (1:UInt64) = 0) : D.R f = 0 := by have h0 : (f.toBits <<< (1:UInt64)).toNat = 0 := by rw [h]; rfl rw [UInt64.toNat_shiftLeft] at h0 have hl := f.toBits.toNat_lt have h1 : (1:UInt64).toNat % 64 = 1 := rfl rw [h1, Nat.shiftLeft_eq] at h0 have g:Model.expField (toModel (ofFloat f : Binary64))=f.toBits.toNat/2^52%2^11:=by show ((f.toBits.toBitVec >>> 52) &&& BitVec.ofNat 64 2047).toNat=_ rw[BitVec.toNat_and,BitVec.toNat_ushiftRight,BitVec.toNat_ofNat,Nat.shiftRight_eq_div_pow] exact Nat.and_two_pow_sub_one_eq_mod _ 11 have e:Model.fracField (toModel (ofFloat f : Binary64))=f.toBits.toNat%2^52:=by show (f.toBits.toBitVec &&& BitVec.ofNat 64 (2^52-1)).toNat=_ rw[BitVec.toNat_and,BitVec.toNat_ofNat] exact Nat.and_two_pow_sub_one_eq_mod _ 52 have g0 : f.toBits.toNat/2^52%2^11 = 0 := by omega have e0 : f.toBits.toNat%2^52 = 0 := by omega have c:=Model.ofFields_signBit_expField_fracField (toModel (ofFloat f : Binary64)) rw[g,e,g0,e0] at c have a:Model.isFinite (Model.ofFields D.B_D (Model.signBit (toModel (ofFloat f : Binary64))) 0 0)=true:=by rw[Model.isFinite_ofFields D.B_D _ _ _ (by decide) (by decide)] rfl have d:=Model.toDyadic?_ofFields_of_isFinite D.B_D _ _ _ (by decide) (by decide) a rw[c] at d rw[D.R,Model.toReal_eq,d] simp [FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand] theorem mant_of_dv0 (w:UInt32) (hg:D.good w=true) (h:(D.dv w).toBits <<< (1:UInt64) = 0) : mantOf w = 0 := by have h1 := (D.qAm w hg).2 rw [Rz0 _ h, D.qA7 w hg] at h1 have h2 : D.A_mag (w.toNat%2^31) = 0 := by split at h1 <;> linarith unfold D.A_mag at h2 split at h2 · rename_i hv apply zw_mant apply UInt32.toNat_inj.mp rw [UInt32.toNat_and] have h3 : (0x7FFFFFFF:UInt32).toNat = 2^31-1 := rfl rw [h3, Nat.and_two_pow_sub_one_eq_mod, hv]; rfl · exfalso have : (0:ℝ) < ((2^23+w.toNat%2^31%2^23:ℕ):ℝ)*2^((((w.toNat%2^31)/2^23:ℕ):ℤ)-150) := by positivity linarith theorem zt_out {c:D_P} {o:Nat} {L:List Nat} (h:D_PO c o L) {y x:Nat} {b:USize} (hy:y< c.g.ho) (hx:x< c.g.wo) (hb:b.toNat=D_B c.g y x) (hz:D_zt c.g.xd c.off b.toNat 0 c.e.toNat = true) (hbz:c.g.b[o]! = 0) : D_out c.g o y x = 0 := by have hzt := D_zt_spec _ _ _ _ 0 hz have hza : zAll (fun t => if t < c.g.k then D_xw c.g o y x t else oneW) (fun t => if t < c.g.k then c.g.W[o*c.g.k+t]! else c.g.b[o]!) 0 (c.g.k+1) = true := by apply zAll_of intro t _ ht by_cases htk : t < c.g.k · simp only [htk, ite_true] have gx : D.good (D_xw c.g o y x t) = true := (qBc h.ok.Hx _ _ _).1 have gw : D.good c.g.W[o*c.g.k+t]! = true := h.ok.HW _ refine ⟨D.qAe _ gx, D.qAe _ gw, ?_⟩ by_cases hm : t ∈ L · obtain ⟨j, hj⟩ := List.mem_iff_getElem?.mp hm have hjl : j < L.length := (List.getElem?_eq_some_iff.mp hj).1 have r := h.rd j t hj have e1 := hzt j (Nat.zero_le _) (by rw [h.len]; omega) rw [hb, r.1, (qCf h.ok h.hC hy hx (h.lt t hm)).2] at e1 rw [mant_of_dv0 _ gx e1, Nat.zero_mul] · rw [zw_mant (h.hz t htk hm), Nat.mul_zero] · have htk' : t = c.g.k := by omega subst htk' simp only [Nat.lt_irrefl, ite_false, hbz] decide have hzn : zNeg (fun t => if t < c.g.k then D_xw c.g o y x t else oneW) (fun t => if t < c.g.k then c.g.W[o*c.g.k+t]! else c.g.b[o]!) 0 (c.g.k+1) = false := by cases hq : zNeg (fun t => if t < c.g.k then D_xw c.g o y x t else oneW) (fun t => if t < c.g.k then c.g.W[o*c.g.k+t]! else c.g.b[o]!) 0 (c.g.k+1) · rfl · have := zNeg_spec _ _ (c.g.k+1) 0 hq c.g.k (Nat.zero_le _) (by omega) simp only [Nat.lt_irrefl, ite_false, hbz] at this exact absurd this (by decide) unfold D_out rw [← D.qAi, ← zdotFn_eq] unfold zdotFn rw [if_pos hza] simp only [hzn, Bool.and_false] cases c.g.relu <;> rfl section variable {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) {y x:Ὣ} {b:ὦ} (hy:y< c.g.ho) (hx:x< c.g.wo) (hb:Ѥb=D_B c.g y x) include c o L h y x b hy hx hb lemma qCvY : D_slowY c o y x b = D_out c.g o y x := by unfold D_slowY split · rename_i hz; exact (zWinX_out c.g h.ok.hk h.ok.pk h.ok.HW h.ok.wp o y x (λhd=>by have e:=h.ok.hC;simp only[hd,ite_true] at e;exact e ▸ h.hC) hy hz).symm split · rename_i hz; simp only [Bool.and_eq_true, beq_iff_eq] at hz; exact (zt_out h hy hx hb hz.2 hz.1).symm · exact qCvZ .. lemma qCu : D_finT c o y x b=D_out c.g o y x:=by unfold D_finT;split<;>rename_i hl;swap;. exact qCv .. have e:=qGc (c.h1 b hl) (dv ∘ D_xw c.g o y x) (λp=>dv c.g.W[o*c.g.k+p]!) L 0 0 0 ((Ἇ _).trans h.len.symm) λj p hj=>by have h1:=h.rd j p hj;rw[C_z,Ἇ,h1.1,hb];exact ⟨(qCf h.ok h.hC hy hx (h.lt p (List.mem_of_getElem? hj))).2,h1.2⟩ simp only[c.hz,e,h.bv,h.ok.nf];split<;>rename_i hz;. split;exact qCvY h hy hx hb;exact qCv .. exact congrArg (act _) (qDq c.g.k h.ok.nk _ _ _ (λt _=>(qBc h.ok.Hx _ _ _).1) (λt _=>h.ok.HW _) (h.ok.Hb _) L h.nd h.lt (λt a b=>.inr (h.hz t a b)) _ _ ⟨rfl,rfl⟩ (by simpa using hz)) lemma qF6 {a:ὧ} (ha:a=L.foldl (λacc t=>acc+dv (D_xw c.g o y x t)*dv c.g.W[o*c.g.k+t]!) 0) : D_fin c o y x b a=D_out c.g o y x:=by subst ha;simp only[D_fin,h.bv,h.e0];split<;>rename_i hz;. split;exact qCvY h hy hx hb;exact qCu h hy hx hb exact congrArg (act _) (qC3 c.g.k h.ok.nk _ _ _ _ (λt _=>(qBc h.ok.Hx _ _ _).1) (λt _=>h.ok.HW _) (h.ok.Hb _) h.ok.Hx.1 (λt _=>(qBc h.ok.Hx _ _ _).2) h.ok.Hx.2.1 L h.nd h.lt (λt a b=>.inr (h.hz t a b)) _ _ ⟨rfl,rfl⟩ (by simpa using hz)) end lemma qIk {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) {y x k:Ὣ} {b:ὦ} (hy:y< c.g.ho) (hx:x+k< c.g.wo) (hb:(b+ὴ k).toNat=D_B c.g y (x+k)) {a:ὧ} (ha:a=L.foldl (λacc t=>acc+dv (D_xw c.g o y (x+k) t)*dv c.g.W[o*c.g.k+t]!) 0) : D_w c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y x b k a=D_out c.g o y (x+k):=by unfold D_w;dsimp only;split<;>rename_i hc . obtain ⟨h1,h2⟩:=ὕ.mp hc;have h1:((a+c.bv).toBits <<< (1:Ὠ))-loOf c.e0< spR c.g.relu (loOf c.e0):=by simpa using h1 have hr:c.g.relu=false:=by cases hq:c.g.relu;. rfl . rw[hq] at h1;exact absurd h1 (by simp[spR]) rw[hr] at h1;have h1:((a+c.bv).toBits <<< (1:Ὠ))-loOf c.e0< spOf (loOf c.e0):=by simpa [spR] using h1 have h2:((a+c.bv).toBits+0x0FDFFFFF) &&& 0x1FFFFFFF<0x1FC00000:=by simpa using h2 obtain ⟨e1,e2⟩:=qHy _ _ h1 h2;rw[<-e1];refine (show act c.g.relu (zivT (thOf c.e0) (a+c.bv))=zivT (thOf c.e0) (a+c.bv) by rw[hr];rfl).symm.trans ?_;subst ha;simp only[h.bv,h.e0] at e2 ⊢;exact congrArg (act _) (qDa c.g.k h.ok.nk _ _ _ _ (λt _=>(qBc h.ok.Hx _ _ _).1) (λt _=>h.ok.HW _) (h.ok.Hb _) h.ok.Hx.1 (λt _=>(qBc h.ok.Hx _ _ _).2) h.ok.Hx.2.1 L h.nd h.lt (λt a b=>.inr (h.hz t a b)) _ _ ⟨rfl,rfl⟩ e2) . split;. exact qCvY h hy hx hb . unfold D_finK;exact qF6 h hy hx hb ha def D_sp (g:D_C) (q:Ὣ):Ὢ := D_out g (q/(g.ho*g.wo)) (q/g.wo%g.ho) (q%g.wo) lemma qG9 (g:D_C) {o y x:Ὣ} (hy:y< g.ho) (hx:x< g.wo) : D_out g o y x=D_sp g ((o*g.ho+y)*g.wo+x):=by simp only[D_sp,Nat.mul_comm g.ho g.wo,<-Nat.div_div_eq_div_mul,qCn _ hx,qCn _ hy] lemma qGa {g:D_C} (ok:D_Ok g) {o y x:Ὣ} (hC:o< g.C) (hy:y< g.ho) (hx:x< g.wo):D_B g y x<2^32:=by have h:=(qCf ok hC hy hx ok.pk).1;have:=ok.xs;(clear hC hy hx; omega) lemma qIn (g:D_C) (y x k:Ὣ):D_B g y (x+k)=D_B g y x+k*g.s.stride:=by unfold D_B;rw[ὰ];exact omS391 def D_xf (c:D_P) (o:Ὣ) (b:ὦ) (k p:Ὣ):ὧ := c.g.xd.data[Ѥb+D_off c.g.s (D_t0 c.g o+p)+k]! def D_I (c:D_P) (Q x:Ὣ) (out:ё):Prop := C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p< Q+min x c.g.wo) out lemma qFe {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) {y Q:Ὣ} (hy:y< c.g.ho) (hQ:Q=(o*c.g.ho+y)*c.g.wo) (hN:Q+c.g.wo<=c.g.C*(c.g.ho*c.g.wo)) (d:Ὣ) : ∀ (x:Ὣ) (b q:ὦ) (rr:D_R) (out:ё),c.g.wo-x=d → (x< c.g.wo->Ѥb=D_B c.g y x)->(x< c.g.wo->Ѥq=Q+x)->D_I c Q x out → C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p< Q+c.g.wo) (D_cols c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y x b q rr out):=by induction' d using Nat.strong_induction_on with d ih intro x b q rr out he hb hq H have sN:=h.ok.sN have S:∀ x',x'< c.g.wo->D_out c.g o y x'=D_sp c.g (Q+x'):=λ_ hx=>hQ ▸ qG9 c.g hy hx rw[D_cols] split<;>rename_i h8 . obtain ⟨hx,hf,hl⟩:=h8;have hb0:=hb hx;have hq0:=hq hx;have hB:=λk=>(qIn c.g y x k).trans (by rw[h.ok.f4 hf,Nat.mul_one]);have G:=λk (hk:x+k< c.g.wo) =>qBm hb0 (uk k (by clear hy he hx hl hb0; exact omS392 hN sN hk)) (hB k ▸ qGa h.ok h.hC hy hk);have V:=λk (hk:x+k<=c.g.wo) =>(qBm hq0 (uk k (by clear hy he hx hl hb0; exact omS393 hN sN hk)) (by clear hy he hx hl hb0; exact omS394 hN sN hk)).trans (ὢ Q x k) have R:=qF7 (c.h8 b hl) rr (D_xf c o b) (λp=>dv c.g.W[o*c.g.k+p]!) L 0 0 0 0 0 0 0 0 0 ((Ἇ _).trans h.len.symm) λj p hj=>by have h1:=h.rd j p hj;rw[C_z,Ἇ,h1.1];exact ⟨h1.2,λ_ _=>rfl⟩ have wL:c.g.wo<2^32:=by have:=Nat.le_mul_of_pos_left c.g.wo ((by clear hQ hN he sN hx hb0 hq0; exact omS147 hy):0< c.g.ho);have:=Nat.le_mul_of_pos_left (c.g.ho*c.g.wo) (show 0< c.g.C by have:=h.hC;omega);omega have A:∀ k,k<8->∀ u,D_I c Q (x+k) u->D_I c Q (x+k+1) (D_l c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y x b q (c.g.wo-x).toUSize k (D_ff (D_xf c o b) (λp=>dv c.g.W[o*c.g.k+p]!) L k 0) u):=λk k8 u H=>by have hN:(ὴ k<(c.g.wo-x).toUSize) ↔ x+k< c.g.wo:=by rw[А,uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide)),qAa _ (by clear hy hQ hN sN hb0 hq0 k8; exact omS395 wL)];(clear hy hQ hN sN hb0 hq0 wL k8; exact omS396) unfold D_l D_I at *;simp only[hN];split<;>rename_i hk;. rw[Nat.min_eq_left hk.le] at H;rw[Nat.min_eq_left hk];refine qBn sN H (V k (by exact Nat.le_of_lt ‹_›)) (by clear hy he sN hx hb0 wL k8 hN; exact omS397 hN hk) ((qIk h hy hk ((G k hk).trans (hB k).symm) (List.foldl_ext _ _ _ λ_ p hp=>?_)).trans (S _ hk));simp only[D_xf];rw[Nat.add_right_comm,hb0,<-hB,(qCf h.ok h.hC hy hk (h.lt p hp)).2] . rw[Nat.min_eq_right (Nat.not_lt.1 hk)] at H;rwa [Nat.min_eq_right (by exact omS398 hk)] simp only[c.hz,R];refine ih (c.g.wo-(x+8)) (by clear hy hQ hN sN hb0 hq0 wL; exact omS399 he hx) (x+8) _ _ _ _ rfl (λhk=>(G 8 hk).trans (hB 8).symm) (λhk=>V 8 hk.le) ?_ have A':∀ k,k<8->8<=(c.g.wo-x).toUSize->∀ u (hu:(q+ὴ k).toNat< ѧu),D_I c Q (x+k) u->D_I c Q (x+k+1) (u.uset (q+ὴ k) (D_w c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y x b k (D_ff (D_xf c o b) (λp=>dv c.g.W[o*c.g.k+p]!) L k 0)) hu):=λk k8 h8 u hu H0=>by have h0:=A k k8 u H0;unfold D_l at h0;rw[ἱ (lcN8 h8 k k8)] at h0;unfold D_I C_Inv at H0;rwa[lcWU _ _ _ hu (by rw[H0.1];exact sN)] unfold D_g8;split . rename_i hq;exact A' 7 ה hq.1 _ _ (A' 6 ה hq.1 _ _ (A' 5 ה hq.1 _ _ (A' 4 ה hq.1 _ _ (A' 3 ה hq.1 _ _ (A' 2 ה hq.1 _ _ (A' 1 ה hq.1 _ _ (A' 0 ה hq.1 _ _ H))))))) . exact (A 7 (by exact Nat.le_refl _) _ (A 6 (by decide) _ (A 5 (by decide) _ (A 4 (by decide) _ (A 3 (by decide) _ (A 2 (by decide) _ (A 1 (by decide) _ (A 0 (by decide) _ H)))))))) split<;>rename_i h1 . have hb0:=hb h1;unfold D_I at *;rw[Nat.min_eq_left h1.le] at H;refine ih (c.g.wo-(x+1)) (by clear hy hQ hN sN hb0; exact omS204 he h1) (x+1) _ _ _ _ rfl (λhx=>?_) (λ_=>(qBm (hq h1) ὄ (by clear hy he h8 h1 hb0; omega)).trans rfl) ?_;. have:=qGa h.ok h.hC hy hx;rw[qIn,Nat.one_mul] at this ⊢;exact qBm hb0 h.ok.st this . rw[qCu h hy h1 hb0,Nat.min_eq_left h1];exact qBn sN H (hq h1) (by clear hy he sN h8 hb0; exact omS15 hN h1) (S _ h1) unfold D_I at H rwa [Nat.min_eq_right (by clear hy hQ hN he sN h8; exact omS400 h1)] at H lemma qFeZ {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) {y Q:Ὣ} (hy:y< c.g.ho) (hQ:Q=(o*c.g.ho+y)*c.g.wo) (hN:Q+c.g.wo<=c.g.C*(c.g.ho*c.g.wo)) (d:Ὣ) : ∀ (x:Ὣ) (b q:ὦ) (rr:D_R) (out:ё),c.g.wo-x=d → (x< c.g.wo->Ѥb=D_B c.g y x)->(x< c.g.wo->Ѥq=Q+x)->D_I c Q x out → C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p< Q+c.g.wo) (D_colsZ c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y x b q rr out):=by induction' d using Nat.strong_induction_on with d ih intro x b q rr out he hb hq H have sN:=h.ok.sN have S:∀ x',x'< c.g.wo->D_out c.g o y x'=D_sp c.g (Q+x'):=λ_ hx=>hQ ▸ qG9 c.g hy hx rw[D_colsZ] split<;>rename_i h8 . obtain ⟨hx,hf,hl⟩:=h8;have hb0:=hb hx;have hq0:=hq hx;have hB:=λk=>(qIn c.g y x k).trans (by rw[h.ok.f4 hf,Nat.mul_one]);have G:=λk (hk:x+k< c.g.wo) =>qBm hb0 (uk k (by clear hy he hx hl hb0; exact omS392 hN sN hk)) (hB k ▸ qGa h.ok h.hC hy hk);have V:=λk (hk:x+k<=c.g.wo) =>(qBm hq0 (uk k (by clear hy he hx hl hb0; exact omS393 hN sN hk)) (by clear hy he hx hl hb0; exact omS394 hN sN hk)).trans (ὢ Q x k) have R:=qF7 (c.h8 b hl) rr (D_xf c o b) (λp=>dv c.g.W[o*c.g.k+p]!) L 0 0 0 0 0 0 0 0 0 ((Ἇ _).trans h.len.symm) λj p hj=>by have h1:=h.rd j p hj;rw[C_z,Ἇ,h1.1];exact ⟨h1.2,λ_ _=>rfl⟩ have wL:c.g.wo<2^32:=by have:=Nat.le_mul_of_pos_left c.g.wo ((by clear hQ hN he sN hx hb0 hq0; exact omS147 hy):0< c.g.ho);have:=Nat.le_mul_of_pos_left (c.g.ho*c.g.wo) (show 0< c.g.C by have:=h.hC;omega);omega by_cases hz:zBlk c.g o y x=true . simp only[hz,↓reduceIte] have A0:∀ k,k<8->∀ u,D_I c Q (x+k) u->D_I c Q (x+k+1) (D_zl q (c.g.wo-x).toUSize k u):=λk k8 u H=>by have hN:(ὴ k<(c.g.wo-x).toUSize) ↔ x+k< c.g.wo:=by rw[А,uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide)),qAa _ (by clear hy hQ hN sN hb0 hq0 k8; exact omS395 wL)];(clear hy hQ hN sN hb0 hq0 wL k8; exact omS396) unfold D_zl D_I at *;simp only[hN];split<;>rename_i hk . rw[Nat.min_eq_left hk.le] at H;rw[Nat.min_eq_left hk];exact qBn sN H (V k (by exact Nat.le_of_lt ‹_›)) (by clear hy he sN hx hb0 wL k8 hN; exact omS397 hN hk) ((zWinX_out c.g h.ok.hk h.ok.pk h.ok.HW h.ok.wp o y (x+k) (λhd=>by have e:=h.ok.hC;simp only[hd,ite_true] at e;exact e ▸ h.hC) hy (zBlk_lane c.g (h.ok.f4 hf) o y x k k8 hz)).symm.trans (S _ hk)) . rw[Nat.min_eq_right (Nat.not_lt.1 hk)] at H;rwa [Nat.min_eq_right (by exact omS398 hk)] exact ih (c.g.wo-(x+8)) (by clear hy hQ hN sN hb0 hq0 wL; exact omS399 he hx) (x+8) _ _ _ _ rfl (λhk=>(G 8 hk).trans (hB 8).symm) (λhk=>V 8 hk.le) (A0 7 (by decide) _ (A0 6 (by decide) _ (A0 5 (by decide) _ (A0 4 (by decide) _ (A0 3 (by decide) _ (A0 2 (by decide) _ (A0 1 (by decide) _ (A0 0 (by decide) _ H)))))))) simp only[hz,Bool.false_eq_true,↓reduceIte] have A:∀ k,k<8->∀ u,D_I c Q (x+k) u->D_I c Q (x+k+1) (D_l c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y x b q (c.g.wo-x).toUSize k (D_ff (D_xf c o b) (λp=>dv c.g.W[o*c.g.k+p]!) L k 0) u):=λk k8 u H=>by have hN:(ὴ k<(c.g.wo-x).toUSize) ↔ x+k< c.g.wo:=by rw[А,uk k (by exact Nat.lt_of_lt_of_le ‹_› (by decide)),qAa _ (by clear hy hQ hN sN hb0 hq0 k8; exact omS395 wL)];(clear hy hQ hN sN hb0 hq0 wL k8; exact omS396) unfold D_l D_I at *;simp only[hN];split<;>rename_i hk;. rw[Nat.min_eq_left hk.le] at H;rw[Nat.min_eq_left hk];refine qBn sN H (V k (by exact Nat.le_of_lt ‹_›)) (by clear hy he sN hx hb0 wL k8 hN; exact omS397 hN hk) ((qIk h hy hk ((G k hk).trans (hB k).symm) (List.foldl_ext _ _ _ λ_ p hp=>?_)).trans (S _ hk));simp only[D_xf];rw[Nat.add_right_comm,hb0,<-hB,(qCf h.ok h.hC hy hk (h.lt p hp)).2] . rw[Nat.min_eq_right (Nat.not_lt.1 hk)] at H;rwa [Nat.min_eq_right (by exact omS398 hk)] simp only[c.hz,R];refine ih (c.g.wo-(x+8)) (by clear hy hQ hN sN hb0 hq0 wL; exact omS399 he hx) (x+8) _ _ _ _ rfl (λhk=>(G 8 hk).trans (hB 8).symm) (λhk=>V 8 hk.le) ?_ have A':∀ k,k<8->8<=(c.g.wo-x).toUSize->∀ u (hu:(q+ὴ k).toNat< ѧu),D_I c Q (x+k) u->D_I c Q (x+k+1) (u.uset (q+ὴ k) (D_w c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y x b k (D_ff (D_xf c o b) (λp=>dv c.g.W[o*c.g.k+p]!) L k 0)) hu):=λk k8 h8 u hu H0=>by have h0:=A k k8 u H0;unfold D_l at h0;rw[ἱ (lcN8 h8 k k8)] at h0;unfold D_I C_Inv at H0;rwa[lcWU _ _ _ hu (by rw[H0.1];exact sN)] unfold D_g8;split . rename_i hq;exact A' 7 ה hq.1 _ _ (A' 6 ה hq.1 _ _ (A' 5 ה hq.1 _ _ (A' 4 ה hq.1 _ _ (A' 3 ה hq.1 _ _ (A' 2 ה hq.1 _ _ (A' 1 ה hq.1 _ _ (A' 0 ה hq.1 _ _ H))))))) . exact (A 7 (by exact Nat.le_refl _) _ (A 6 (by decide) _ (A 5 (by decide) _ (A 4 (by decide) _ (A 3 (by decide) _ (A 2 (by decide) _ (A 1 (by decide) _ (A 0 (by decide) _ H)))))))) split<;>rename_i h1 . have hb0:=hb h1;unfold D_I at *;rw[Nat.min_eq_left h1.le] at H;refine ih (c.g.wo-(x+1)) (by clear hy hQ hN sN hb0; exact omS204 he h1) (x+1) _ _ _ _ rfl (λhx=>?_) (λ_=>(qBm (hq h1) ὄ (by clear hy he h8 h1 hb0; omega)).trans rfl) ?_;. have:=qGa h.ok h.hC hy hx;rw[qIn,Nat.one_mul] at this ⊢;exact qBm hb0 h.ok.st this . rw[qCu h hy h1 hb0,Nat.min_eq_left h1];exact qBn sN H (hq h1) (by clear hy he sN h8 hb0; exact omS15 hN h1) (S _ h1) unfold D_I at H rwa [Nat.min_eq_right (by clear hy hQ hN he sN h8; exact omS400 h1)] at H lemma qHu {u v:ὦ} {a b:Ὣ} (hu:Ѥu=a) (hv:Ѥv=b) (h:a*b<2^32) : (u*v).toNat=a*b:=by rw[qIb _ _ (by rw[hu,hv];exact h),hu,hv] lemma qEy {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) (hN:(o*c.g.ho+c.g.ho)*c.g.wo<=c.g.C*(c.g.ho*c.g.wo)) (d:Ὣ) : ∀ (y:Ὣ) (q:ὦ) (rs:List D_R) (out:ё),y+d=c.g.ho → Ѥq=(o*c.g.ho+y)*c.g.wo → C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+y)*c.g.wo) out → C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+c.g.ho)*c.g.wo) (D_rows c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y q rs out):=by induction' d with d ih<;>intro y q rs out he hq H . rw[D_rows,ἐ (by clear hN hq; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))))];rwa [((by exact omS155 he):y=c.g.ho)] at H have hy:y< c.g.ho :=(by clear hN hq; exact omS136 he) have sN:=h.ok.sN have hA:=qBv ((by clear hN hq sN; (clear hy; exact omS401 he)):o*c.g.ho+y< o*c.g.ho+c.g.ho) (Nat.le_refl c.g.wo) have eW:=qAa c.g.wo (by clear he hy; exact omS402 hN sN hA) have bB:=qGa h.ok h.hC hy (x:=0) (h.ok.wo ▸ Nat.succ_pos _) have hwp:0< c.g.wp:=h.ok.wp ▸ (qHl (qHk h.ok h.hC h.ok.pk)).2.trans_le h.ok.kw simp[D_B] at bB have:=Ὄ (y*c.g.s.stride) hwp have:=Ὄ y h.ok.p0 rw[D_rows,ἱ hy] refine ih (y+1) _ _ _ (by exact omS137 he) ?_ ?_<;>rw[<-ὢ,Nat.add_one_mul] . exact qBm hq eW (by exact omS403 hN sN hA) exact qFe h hy rfl (by exact Nat.le_trans ‹_› ‹_›) c.g.wo 0 _ _ _ _ (Nat.sub_zero _) (λ_ =>(qHu (qHu (qAa y (by omega)) h.ok.st (by exact Nat.lt_of_le_of_lt ‹_› ‹_›)) (qAa _ h.ok.wp2) bB).trans (by simp[D_B])) (λ_=>hq) (by unfold D_I;rw[Nat.zero_min];exact H) lemma qEyZ {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) (hN:(o*c.g.ho+c.g.ho)*c.g.wo<=c.g.C*(c.g.ho*c.g.wo)) (d:Ὣ) : ∀ (y:Ὣ) (q:ὦ) (rs:List D_R) (out:ё),y+d=c.g.ho → Ѥq=(o*c.g.ho+y)*c.g.wo → C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+y)*c.g.wo) out → C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+c.g.ho)*c.g.wo) (D_rowsZ c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o y q rs out):=by induction' d with d ih<;>intro y q rs out he hq H . rw[D_rowsZ,ἐ (by clear hN hq; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))))];rwa [((by exact omS155 he):y=c.g.ho)] at H have hy:y< c.g.ho :=(by clear hN hq; exact omS136 he) have sN:=h.ok.sN have hA:=qBv ((by clear hN hq sN; (clear hy; exact omS401 he)):o*c.g.ho+y< o*c.g.ho+c.g.ho) (Nat.le_refl c.g.wo) have eW:=qAa c.g.wo (by clear he hy; exact omS402 hN sN hA) have bB:=qGa h.ok h.hC hy (x:=0) (h.ok.wo ▸ Nat.succ_pos _) have hwp:0< c.g.wp:=h.ok.wp ▸ (qHl (qHk h.ok h.hC h.ok.pk)).2.trans_le h.ok.kw simp[D_B] at bB have:=Ὄ (y*c.g.s.stride) hwp have:=Ὄ y h.ok.p0 rw[D_rowsZ,ἱ hy] refine ih (y+1) _ _ _ (by exact omS137 he) ?_ ?_<;>rw[<-ὢ,Nat.add_one_mul] . exact qBm hq eW (by exact omS403 hN sN hA) exact qFeZ h hy rfl (by exact Nat.le_trans ‹_› ‹_›) c.g.wo 0 _ _ _ _ (Nat.sub_zero _) (λ_ =>(qHu (qHu (qAa y (by omega)) h.ok.st (by exact Nat.lt_of_le_of_lt ‹_› ‹_›)) (qAa _ h.ok.wp2) bB).trans (by simp[D_B])) (λ_=>hq) (by unfold D_I;rw[Nat.zero_min];exact H) lemma qGt (s:OS) (o:Ὣ) {p:Ὣ} (hp:p< s.kh*s.kw) : D_off s (o*(s.kh*s.kw)+p) =o*((s.h+2*s.pad)*(s.w+2*s.pad))+D_off s p:=by unfold D_off rw[(qCn o hp).1,Ὃ hp,<-Nat.mul_assoc,Nat.add_comm (o*s.kh*s.kw),Nat.add_mul_div_right _ _ (Nat.pos_of_mul_pos_left (Nat.zero_lt_of_lt hp)),Nat.add_mul_mod_self_right,Nat.add_mul_mod_self_right] ring lemma qIq (a b:Ὣ):a.toUInt32+b.toUInt32=(a+b).toUInt32 :=(UInt32.ofNat_add a b).symm lemma qHp {g:D_C} (ok:D_Ok g) (o:Ὣ) {t:ὦ} (hp:Ѥt< g.k) : (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0)+rdW g.tab t =(D_off g.s (D_t0 g o+Ѥt)).toUInt32:=by have h2:=ok.nk rw[qAo _ _ (by simp[ok.tb];(exact Nat.lt_of_lt_of_le ‹_› (by decide))),ok.tb] generalize Ѥt=p at hp ⊢ rw[Ἕ _ p (by simpa using hp),Array.getElem_ofFn] have h1:=ok.hk unfold D_t0 cases hd:g.dw . simp simp only[hd,ite_true] at h1 ⊢ rw[h1,qGt g.s o (h1 ▸ hp),ok.wp,qIq] def D_Dc (g:D_C) (o:Ὣ) (xw:Ὣ->Ὢ) (sz t:Ὣ) (off:ѐ) (buf:ὤ) (c:ὦ) (l:ὧ):Prop := Ѥc=(C_keep xw t).length∧ѧoff=sz∧Ѩbuf=sz ∧ (∀ k p:Ὣ,(C_keep xw t)[k]?=some p → (off[k]! : ὥ)=(D_off g.s (D_t0 g o+p)).toUInt32∧buf.data[k]! = dv (xw p)) ∧ l=(C_keep xw t).foldl (λ(a:ὧ) p=>a+(dv (xw p)).abs) 0 lemma qHn {g:D_C} (ok:D_Ok g) {o' n:ὦ} (o:Ὣ) (xw:Ὣ->Ὢ) (hk:Ѥn=g.k) (hn:Ѥn<2^32) (hxw:∀ t:ὦ,t< n->rdW g.W (o'+t)=xw Ѥt) (d:Ὣ) : ∀ (t:ὦ) (off:ѐ) (buf:ὤ) (c:ὦ) (l:ὧ) (m:ὥ) (hm:∀ j (h:j< ѧoff),off[j].toNat<=ѥm),Ѥt+d=Ѥn->D_Dc g o xw Ѥn Ѥt off buf c l → D_Dc g o xw Ѥn Ѥn (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) o' n t off buf c l m hm).off (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) o' n t off buf c l m hm).buf (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) o' n t off buf c l m hm).c (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) o' n t off buf c l m hm).l:=by induction d with | zero => intro t off buf c l m hm he H rw[D_dec,ἔ (by rw[А];exact omS404 he)] have e:Ѥt=Ѥn :=(by exact omS155 he) rw[e] at H;exact H | succ d ih => intro t off buf c l m hm he H have ht:t< n:=by rw[А];(clear hn; exact omS136 he) have hu:=usz t n ht rw[D_dec,Ἄ ht] dsimp only rw[hxw t ht] obtain ⟨h1,h2,h3,h4,h5⟩:=H by_cases hz:xw Ѥt &&& В=0 . rw[ἱ (by simpa using hz)];apply ih (t+1) _ _ _ _ _ _ (by clear hn ht h1 h2 h3; exact omS157 he hu);rw[hu,D_Dc,qDs xw _ hz];exact ⟨h1,h2,h3,h4,h5⟩ . rw[ἐ (by simpa using hz)];apply ih (t+1) _ _ _ _ _ _ (by clear hn ht h1 h2 h3; exact omS157 he hu);have hl:=qCb xw Ѥt;have hc:Ѥc< Ѥt+1 :=(by clear hk hn he ht h2 h3; (clear hu; exact omS405 h1 hl));rw[hu,D_Dc,qEb xw _ hz];have hcn:Ѥc< Ѥn :=(by exact Nat.lt_of_lt_of_le ‹_› ‹_›);refine ⟨?_,by rw[qAm];exact h2,by rw[qB9];exact h3,λk p hk2=>?_,by rw[List.foldl_append,<-h5];rfl⟩;. rw[qAv _ _ (by rw[ὄ];(exact Nat.lt_of_le_of_lt ‹_› ‹_›)),ὄ,h1];simp . rw[qAq _ _ _ _ (by clear ht h1 hl hc hcn; exact omS360 hn h2) (by clear hn ht hl hc; exact omS140 h2 hcn),qCr _ _ _ _ (by clear ht h1 hl hc hcn; exact omS360 hn h3) (by clear hn ht hl hc; exact omS140 h3 hcn)];rw[List.getElem?_append,<-h1] at hk2;by_cases e:k=Ѥc;. subst e;simp at hk2;subst hk2;rw[ἱ rfl,ἱ rfl];exact ⟨qHp ok o (by clear hn ht h1 hl hc hcn; exact omS406 hk he),rfl⟩ . rw[ἐ e,ἐ e];by_cases e2:k< Ѥc;. rw[ἱ e2] at hk2;exact h4 k p hk2 . rw[ἐ e2] at hk2;obtain ⟨z,hz'⟩:∃ z,k-Ѥc=z+1:=⟨k-Ѥc-1,by (clear hk hn he ht hu h2 h3 hl hc hcn; exact omS407 e e2)⟩;rw[hz'] at hk2;simp at hk2 lemma qIi {g:D_C} (ok:D_Ok g) {o:Ὣ} (hC:o< g.C) {off:ѐ} {buf:ὤ} (h2:ѧoff=g.k) (h3:Ѩbuf=g.k) (m:ὥ) (hm:∀ j (h:j< ѧoff),off[j].toNat<=ѥm) : D_Dc g o (λp=>g.W[o*g.k+p]!) g.k g.k (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) (o*g.k).toUSize g.k.toUSize 0 off buf 0 0 m hm).off (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) (o*g.k).toUSize g.k.toUSize 0 off buf 0 0 m hm).buf (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) (o*g.k).toUSize g.k.toUSize 0 off buf 0 0 m hm).c (D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) (o*g.k).toUSize g.k.toUSize 0 off buf 0 0 m hm).l:=by have hX:=ok.sW2 have hP:=(qBv hC (Nat.le_refl g.k)).trans_eq ok.sW.symm have eo:(o*g.k).toUSize.toNat=o*g.k:=qAa _ (by clear hC; exact omS154 hX hP) have ek:g.k.toUSize.toNat=g.k:=qAa _ (by clear hC h2; (clear h3; exact omS408 hX hP)) have D:=qHn (o':=(o*g.k).toUSize) (n:=g.k.toUSize) ok o (λp=>g.W[o*g.k+p]!) ek (by rw[ek];(clear hC h2; (clear h3; exact omS408 hX hP))) (λt ht=>by have h4:=А.mp ht rw[ek] at h4 rw[qAo _ _ hX,qAv _ _ (by rw[eo];(clear hC h2 ht; (clear h3; exact omS145 hX hP h4))),eo]) g.k 0 off buf 0 0 m hm (by rw[C_z,ek,Ἇ]) ⟨by simp[C_keep],by rw[ek];exact h2,by rw[ek];exact h3,λk p hk=>by simp[C_keep] at hk,by simp[C_keep]⟩ rw[ek] at D exact D lemma qFi (A:ѐ) (n:ὦ) (hn:Ѥn<=ѧA) (d:Ὣ) : ∀ (i:ὦ) (lo hi:ὥ),Ѥi+d=Ѥn->scan A n i hn lo hi = if 0x007FFFFF<=(D_scan A n i hn lo hi).lo∧(D_scan A n i hn lo hi).hi<У then (D_scan A n i hn lo hi).hi else Е:=by induction' d with d ih<;>intro i lo hi he<;>rw[scan,D_scan] . simp only[dite_eq_right (qCk he.ge)] simp only[dite_eq_left (qBz he).1] exact ih (i+1) _ _ (qBz he).2 lemma qFw (s:OS) {c r q:Ὣ} (hr:r< s.kh) (hq:q< s.kw) : D_off s ((c*s.kh+r)*s.kw+q)=(c*(s.h+2*s.pad)+r)*(s.w+2*s.pad)+q:=by have k0:0< s.kw :=(by clear hr; exact omS147 hq);have h0:0< s.kh :=(by clear hq k0; exact omS147 hr);have e1:((c*s.kh+r)*s.kw+q)/s.kw=c*s.kh+r:=by rw[Nat.add_comm,Nat.add_mul_div_right _ _ k0,Ὃ hq,Ἇ] have e2:((c*s.kh+r)*s.kw+q)%s.kw=q:=by rw[Nat.add_comm,Nat.add_mul_mod_self_right,Ἁ hq] have e3:(c*s.kh+r)%s.kh=r:=by rw[Nat.add_comm,Nat.add_mul_mod_self_right,Ἁ hr] have e4:(c*s.kh+r)/s.kh=c:=by rw[Nat.add_comm,Nat.add_mul_div_right _ _ h0,Ὃ hr,Ἇ] unfold D_off;rw[ἥ s.kh s.kw,<-Nat.div_div_eq_div_mul,e1,e4,e3,e2] lemma qGz (s:OS) (k d:Ὣ):∀ (t c r q:Ὣ) (a:ѐ),t+d=k → t=(c*s.kh+r)*s.kw+q->r< s.kh->q< s.kw → a=(Array.ofFn (n:=t) λi=>(D_off s i.val).toUInt32) → D_tq k s.kw s.kh (s.h+2*s.pad) (s.w+2*s.pad) t c r q a =Array.ofFn (n:=k) λi=>(D_off s i.val).toUInt32:=by induction d with | zero => intro t c r q a h1 _ _ _ h5 have e:t=k:=h1 subst e rw[D_tq,ἐ (Nat.lt_irrefl _)] exact h5 | succ d ih => intro t c r q a h1 h2 h3 h4 h5 have hp:a.push ((c*(s.h+2*s.pad)+r)*(s.w+2*s.pad)+q).toUInt32 =Array.ofFn (n:=t+1) λi=>(D_off s i.val).toUInt32:=by rw[<-qFw s h3 h4,<-h2,h5,Array.ofFn_succ] rfl rw[D_tq,ἱ (by clear h3 h4; exact omS136 h1)] dsimp only rw[hp] split . exact ih (t+1) c r (q+1) _ (by exact omS137 h1) (by exact omS409 h2) h3 (by assumption) rfl split . have e:(c*s.kh+(r+1))*s.kw=(c*s.kh+r)*s.kw+s.kw:=by ring exact ih (t+1) c (r+1) 0 _ (by exact omS137 h1) (by omega) (by assumption) (by omega) rfl . have e2:s.kh=r+1 :=(by omega);have e:((c+1)*s.kh+0)*s.kw=(c*s.kh+r)*s.kw+s.kw:=by rw[e2];ring exact ih (t+1) (c+1) 0 0 _ (by exact omS137 h1) (by omega) (by omega) (by omega) rfl lemma qFz (c:D_P) (lo sp:Ὠ) (o y:Ὣ) (q0:ὦ) (hy:y< c.g.ho) (d:Ὣ) : ∀ (x:Ὣ) (b q:ὦ) (rr:D_R) (out:ѐ),c.g.wo-x=d → ∃ rr':D_R,D_rc c lo sp o y x b q q0 rr out = D_rc c lo sp o (y+1) 0 ((y+1).toUSize*c.g.step*c.g.wp.toUSize) (q0+c.g.wo.toUSize) (q0+c.g.wo.toUSize) rr' (D_cols c lo sp o y x b q rr out):=by induction' d using Nat.strong_induction_on with d ih intro x b q rr out he rw[D_rc,D_cols,Ἄ hy] by_cases h8:x< c.g.wo∧c.g.f4=true∧b< c.l8 . simp only[Ἄ h8];exact ih _ (by clear hy; exact omS410 he h8) _ _ _ _ _ rfl . simp only[ἔ h8];by_cases h1:x< c.g.wo;. simp only[ἱ h1];exact ih _ (by clear hy; exact omS204 he h1) _ _ _ _ _ rfl . simp only[ἐ h1];exact ⟨rr,rfl⟩ lemma qFa (c:D_P) (lo sp:Ὠ) (o:Ὣ) (d:Ὣ) : ∀ (y:Ὣ) (q0:ὦ) (rr:D_R) (out:ѐ),c.g.ho-y=d → ∃ rs:List D_R,D_rc c lo sp o y 0 (ѩy*c.g.step*c.g.wp.toUSize) q0 q0 rr out =D_rows c lo sp o y q0 rs out:=by induction d with | zero => intro y q0 rr out he have hy:¬ y< c.g.ho :=(by exact omS411 he) exact ⟨[],by rw[D_rc,ἔ hy,D_rows,ἐ hy]⟩ | succ d ih => intro y q0 rr out he have hy:y< c.g.ho :=(by exact omS412 he) obtain ⟨rr',h⟩:=qFz c lo sp o y q0 hy _ 0 (ѩy*c.g.step*c.g.wp.toUSize) q0 rr out rfl obtain ⟨rs,h2⟩:=ih (y+1) (q0+c.g.wo.toUSize) rr' _ (by exact omS413 he) refine ⟨rr :: rs,?_⟩ rw[h,h2] conv_rhs=>rw[D_rows,ἱ hy] rfl lemma qF8 {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) (hN:(o*c.g.ho+c.g.ho)*c.g.wo<=c.g.C*(c.g.ho*c.g.wo)) {q:ὦ} {out:ё} (hq:Ѥq=(o*c.g.ho+0)*c.g.wo) (H:C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+0)*c.g.wo) out) : C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+c.g.ho)*c.g.wo) (D_rc c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o 0 0 ((0:Ὣ).toUSize*c.g.step*c.g.wp.toUSize) q q ⟨0,0,0,0,0,0,0,0,0⟩ out):=by obtain ⟨rs,hrs⟩:=qFa c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o _ 0 q ⟨0,0,0,0,0,0,0,0,0⟩ out rfl rw[hrs] exact qEy h hN c.g.ho 0 q rs out (Ἇ _) hq H lemma qFzZ (c:D_P) (lo sp:Ὠ) (o y:Ὣ) (q0:ὦ) (hy:y< c.g.ho) (d:Ὣ) : ∀ (x:Ὣ) (b q:ὦ) (rr:D_R) (out:ѐ),c.g.wo-x=d → ∃ rr':D_R,D_rcZ c lo sp o y x b q q0 rr out = D_rcZ c lo sp o (y+1) 0 ((y+1).toUSize*c.g.step*c.g.wp.toUSize) (q0+c.g.wo.toUSize) (q0+c.g.wo.toUSize) rr' (D_colsZ c lo sp o y x b q rr out):=by induction' d using Nat.strong_induction_on with d ih intro x b q rr out he rw[D_rcZ,D_colsZ,Ἄ hy] by_cases h8:x< c.g.wo∧c.g.f4=true∧b< c.l8 . simp only[Ἄ h8];by_cases hz:zBlk c.g o y x=true . simp only[hz,↓reduceIte];exact ih _ (by clear hy; exact omS410 he h8) _ _ _ _ _ rfl . simp only[hz,Bool.false_eq_true,↓reduceIte];exact ih _ (by clear hy; exact omS410 he h8) _ _ _ _ _ rfl . simp only[ἔ h8];by_cases h1:x< c.g.wo;. simp only[ἱ h1];exact ih _ (by clear hy; exact omS204 he h1) _ _ _ _ _ rfl . simp only[ἐ h1];exact ⟨rr,rfl⟩ lemma qFaZ (c:D_P) (lo sp:Ὠ) (o:Ὣ) (d:Ὣ) : ∀ (y:Ὣ) (q0:ὦ) (rr:D_R) (out:ѐ),c.g.ho-y=d → ∃ rs:List D_R,D_rcZ c lo sp o y 0 (ѩy*c.g.step*c.g.wp.toUSize) q0 q0 rr out =D_rowsZ c lo sp o y q0 rs out:=by induction d with | zero => intro y q0 rr out he have hy:¬ y< c.g.ho :=(by exact omS411 he) exact ⟨[],by rw[D_rcZ,ἔ hy,D_rowsZ,ἐ hy]⟩ | succ d ih => intro y q0 rr out he have hy:y< c.g.ho :=(by exact omS412 he) obtain ⟨rr',h⟩:=qFzZ c lo sp o y q0 hy _ 0 (ѩy*c.g.step*c.g.wp.toUSize) q0 rr out rfl obtain ⟨rs,h2⟩:=ih (y+1) (q0+c.g.wo.toUSize) rr' _ (by exact omS413 he) refine ⟨rr :: rs,?_⟩ rw[h,h2] conv_rhs=>rw[D_rowsZ,ἱ hy] rfl lemma qF8Z {c:D_P} {o:Ὣ} {L:љ} (h:D_PO c o L) (hN:(o*c.g.ho+c.g.ho)*c.g.wo<=c.g.C*(c.g.ho*c.g.wo)) {q:ὦ} {out:ё} (hq:Ѥq=(o*c.g.ho+0)*c.g.wo) (H:C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+0)*c.g.wo) out) : C_Inv (c.g.C*(c.g.ho*c.g.wo)) (D_sp c.g) (λp=>p<(o*c.g.ho+c.g.ho)*c.g.wo) (D_rcZ c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o 0 0 ((0:Ὣ).toUSize*c.g.step*c.g.wp.toUSize) q q ⟨0,0,0,0,0,0,0,0,0⟩ out):=by obtain ⟨rs,hrs⟩:=qFaZ c (loOf c.e0) (spR c.g.relu (loOf c.e0)) o _ 0 q ⟨0,0,0,0,0,0,0,0,0⟩ out rfl rw[hrs] exact qEyZ h hN c.g.ho 0 q rs out (Ἇ _) hq H section variable {g:D_C} (ok:D_Ok g) include g ok lemma qC4 {o:Ὣ} (hC:o< g.C) : (D_decAll g.tab g.W g.dw g.s g.wp g.k g.C)[o]! = D_dec g.tab g.W (if g.dw then (o*((g.s.h+2*g.s.pad)*g.wp)).toUInt32 else 0) (o*g.k).toUSize g.k.toUSize 0 (ἇ g.k 0) (pushZ g.k.toUSize 0 (ἆ g.k)) 0 0 0 (qF0 g.k):=by unfold D_decAll rw[Ἕ _ _ (by simp;exact hC),Array.getElem_ofFn] lemma qEg (hs:g.xd.size<2^32) (d:Ὣ) : ∀ (o:Ὣ) (q:ὦ) (out:ё),o+d=g.C->Ѥq=o*(g.ho*g.wo) → C_Inv (g.C*(g.ho*g.wo)) (D_sp g) (λp=>p< o*(g.ho*g.wo)) out → C_Inv (g.C*(g.ho*g.wo)) (D_sp g) (λp=>p< g.C*(g.ho*g.wo)) (D_outsC g hs o q (D_decAll g.tab g.W g.dw g.s g.wp g.k g.C) out):=by induction' d with d ih<;>intro o q out he hq H . rw[D_outsC,ἐ (by clear hs hq; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))))];rwa [((by exact omS155 he):o=g.C)] at H have hC:o< g.C :=(by clear hq; exact omS136 he) have hkn:=ok.nk have sW2:=ok.sW2 have sN:=ok.sN have hP:=(qBv hC (Nat.le_refl g.k)).trans_eq ok.sW.symm have hO:=qBv hC (Nat.le_refl (g.ho*g.wo)) have eB:rdW g.b ѩo=g.b[o]!:=by rw[qAo _ _ ok.sb,qAa _ (by have:=Ὄ o ok.pk;(clear hq hC sN hO; omega))] have h2:(ἇ g.k (0:ὥ)).size=g.k:=by simp have h3:(pushZ g.k.toUSize 0 (ἆ g.k)).size=g.k := (qG6 g.k.toUSize g.k 0 _ ((Ἇ _).trans (qAa g.k (ok.nk.trans (by norm_num1))).symm)).trans (Ἇ _) obtain ⟨d1,d2,d3,d4,d5⟩:=qIi ok hC h2 h3 0 (qF0 g.k) obtain ⟨k1,k2,k3⟩:=qG5 (λp=>g.W[o*g.k+p]!) g.k have hlen:=d1.trans_le (qCb _ _) rw[D_outsC,ἱ hC] dsimp only simp only[qC4 ok hC] rw[Ἄ (by clear he hq hC hkn sW2 sN hP hO eB; (clear h2; exact omS414 d2 d3 hlen)),eB] refine ih (o+1) _ _ (by clear hq hC hkn sW2 sN hP hO eB h2 h3 d1 d2 d3 hlen; exact omS137 he) (Nat.add_one_mul o _ ▸ qBm hq (qAa _ (by clear he hC hkn sW2 hP eB h2 h3 d1 d2 d3 hlen; exact omS408 sN hO)) (by exact Nat.lt_of_le_of_lt ‹_› ‹_›)) ?_ have E:(o*g.ho+g.ho)*g.wo=o*(g.ho*g.wo)+g.ho*g.wo:=by ring rw[Nat.add_one_mul,<-E] rw[<-Nat.mul_assoc o] at hq H by_cases hE:g.ex.1.isEmpty=true . rw[ἱ hE] refine qF8 (L:=C_keep _ g.k) ⟨ok,hC,d1,k1,k2,k3,λj p hj=>?_,by dsimp only;rw[ok.nf,d5],rfl⟩ (by dsimp only;(clear he hq hC hkn sW2 sN hP eB h2 h3 d1 d2 d3 hlen; exact omS415 hO E)) hq H have hjl:=(List.getElem?_eq_some_iff.mp hj).1 refine ⟨?_,(d4 j p hj).2⟩ dsimp only rw[(d4 j p hj).1] simpa using Nat.mod_eq_of_lt ((Nat.lt_of_add_left_lt (qCf ok hC (y:=0) (x:=0) (ok.ho ▸ Nat.succ_pos _) (ok.wo ▸ Nat.succ_pos _) (k2 _ (List.mem_of_getElem? hj))).1).trans ok.xs) . rw[ἐ hE] refine qF8Z (L:=C_keep _ g.k) ⟨ok,hC,d1,k1,k2,k3,λj p hj=>?_,by dsimp only;rw[ok.nf,d5],rfl⟩ (by dsimp only;(clear he hq hC hkn sW2 sN hP eB h2 h3 d1 d2 d3 hlen; exact omS415 hO E)) hq H have hjl:=(List.getElem?_eq_some_iff.mp hj).1 refine ⟨?_,(d4 j p hj).2⟩ dsimp only rw[(d4 j p hj).1] simpa using Nat.mod_eq_of_lt ((Nat.lt_of_add_left_lt (qCf ok hC (y:=0) (x:=0) (ok.ho ▸ Nat.succ_pos _) (ok.wo ▸ Nat.succ_pos _) (k2 _ (List.mem_of_getElem? hj))).1).trans ok.xs) lemma qHh (hs:g.xd.size<2^32) : D_outsC g hs 0 0 (D_decAll g.tab g.W g.dw g.s g.wp g.k g.C) (ἇ (g.C*(g.ho*g.wo)) 0) =if g.dw then depthwiseSpecO g.s g.relu g.X g.W g.b else conv2dSpecO g.s g.relu g.X g.W g.b:=by refine (qCe (qEg ok hs g.C 0 0 _ (Ἇ _) ג ⟨by simp,λq _ h=>(by omega)⟩) λq h=>h).trans ?_ obtain ⟨dw,_,_,s,_,_,_,k,C,ho,wo⟩:=g obtain ⟨h1,h2,h3,h4⟩:=ok cases dw<;>simp at h1 h2 h3 h4<;>subst h1 h2 h3 h4 <;>refine congrArg (Array.ofFn (n:=_)) (funext λq=>?_)<;>simp[D_sp,D_out,D_xw,D_t0] end def D_Zs (F:Ὣ->ὧ) (S m:Ὣ) (a:ὤ):Prop := Ѩa=S∧S<2^32∧∀ q,q< S->a.data[q]! = if q< m then F q else dv 0 section variable {F:Ὣ->ὧ} {S m:Ὣ} {a:ὤ} include F S m a lemma qBq (d:Ὣ) (H:D_Zs F S m a) (hv:∀ u,u< d->F (m+u)=dv 0):D_Zs F S (m+d) a:=by refine ⟨H.1,H.2.1,λq hq=>?_⟩;rw[H.2.2 q hq];by_cases h1:q< m;. rw[ἱ h1,ἱ (Nat.lt_add_right d h1)] rw[ἐ h1];by_cases h2:q< m+d;. have e:=hv (q-m) (by clear hq; exact omS416 h1 h2);rw[Nat.add_sub_cancel' (Nat.not_lt.1 h1)] at e;rw[ἱ h2,e] rw[ἐ h2] lemma qGs (H:D_Zs F S m a) (i:ὦ) (hi:Ѥi=m) (hm:m< S):D_Zs F S (m+1) (wrF a i (F m)):=by have hz:Ѩa<2^32:=H.1 ▸ H.2.1;refine ⟨(qB9 ..).trans H.1,H.2.1,λq hq=>?_⟩;rw[qCr _ _ _ _ hz (by rw[hi,H.1];exact hm),hi];by_cases e:q=m;. rw[ἱ e,ἱ (by clear hi hm hz hq; exact omS417 e),e] rw[ἐ e,H.2.2 q hq];by_cases h:q< m;. rw[ἱ h,ἱ (by clear hi hm hz hq e; exact omS418 h)] rw[ἐ h,ἐ (by clear hi hm hz hq; exact omS419 e h)] end lemma qE5 {F:Ὣ->ὧ} {S:Ὣ} {X:ѐ} {o n:ὦ} (hs:ѧX<2^32) (ho:Ѥo+Ѥn<=ѧX) (d:Ὣ) : ∀ (t q:ὦ) (m:Ὣ) (a:ὤ),Ѥt+d=Ѥn->Ѥq=m->m+d<=S → D_Zs F S m a->(∀ j,j< d->F (m+j)=dv X[Ѥo+Ѥt+j]!) → D_Zs F S (m+d) (D_cpz X o n t q hs ho a):=by induction' d with d ih<;>intro t q m a he hq hm H hv . rw[D_cpz,ἔ (qCk he.ge)];exact H obtain ⟨ht,hu⟩:=qBz he rw[D_cpz,Ἄ ht,qFp] have hS:=H.2.1 have e:∀ h',dv (X.uget (o+t) h')=F m:=λh'=>by rw[qFx,qAv _ _ (by clear hq hm ht hS h'; omega)];exact (hv 0 (by clear he hq hm ht hu hS h'; omega)).symm rw[e] refine ih (t+1) (q+1) (m+1) _ hu ?_ (by clear he hq ht hu hS; omega) (qGs H q hq (by clear he hq ht hu hS; omega)) λj hj=>?_ . exact (qAv q 1 (by rw[ὄ];(clear he ht hu; omega))).trans (by rw[ὄ,hq]) simpa only [usz t n ht,Nat.add_assoc,Nat.add_comm 1] using hv (j+1) (by exact Nat.lt_succ_of_le ‹_›) lemma qE6 (s:OS) (X:ѐ) (hs:ѧX<2^32) (hX:ѧX=s.cin*s.h*s.w) (hh:s.h+2*s.pad<2^32) (hw:s.w+2*s.pad<2^32) {R S:Ὣ} (hR:R=s.cin*(s.h+2*s.pad)) (hS:R*(s.w+2*s.pad)<=S) (d:Ὣ) : ∀ (r:Ὣ) (a:ὤ),r+d=R → D_Zs (D_Fx s X) S (r*(s.w+2*s.pad)) a → D_Zs (D_Fx s X) S (R*(s.w+2*s.pad)) (D_imz s X hs (s.w+2*s.pad) R r a):=by induction' d with d ih<;>intro r a he H . rw[D_imz,ἔ (by clear hs hX hh hw hS; (exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›)))),<-he];exact H have hr:r< R :=(by clear hX hh hw hS; exact omS136 he) have hc:=Ἰ (hr.trans_eq (hR.trans (ἥ _ _))) have ep:=qAa s.pad (by clear hX hw hR hS he hr hc; exact omS379 hh) have ew:=qAa s.w (by clear hX hR hS he hr hc; exact omS380 hw) have hO:=λg:r%(s.h+2*s.pad)-s.pad< s.h=>qBv (qDf hc g) (Nat.le_refl s.w) have hT:=H.2.1 rw[D_imz,Ἄ hr] dsimp only split<;>rename_i g . obtain ⟨g1,g2,g3⟩:=g;have:=hO g2;have hl:(r+1)*(s.w+2*s.pad)<=R*(s.w+2*s.pad):=Ἒ _ hr;rw[ᾀ,qF5] at hl;apply ih (r+1) _ (by clear hX hh hw hS hr hc ep ew hT g1 g2 g3 this hl; exact omS137 he);rw[ᾀ,qF5];refine qBq s.pad (qE5 hs g3 s.w 0 _ _ _ (by rw[ew];exact Ἇ _) (qAa _ (by clear hX hR he hr hc g1 g2 g3 this; (clear hw; exact omS420 hS hT hl))) (by clear hX hw hR he hr hc hT g1 g2 g3 this; (clear ew; exact omS421 hS hl)) (qBq s.pad H λu hu=>?_) λj hj=>?_) λu hu=>?_;. rw[qAi _ _ _ (by clear hX hh hw hR hS he hr hc hT g1 g2 g3 this hl; (clear ep; exact omS381 hu)),D_px,ἱ (by clear hX hh hw hR hS he hr hc ew hT g1 g2 g3 this hl; (clear ep; exact omS382 hu))] . rw[ὢ,qAi _ _ _ (by clear hX hw hR hS he hr hc hT g1 g2 g3 this hl; (clear ew; exact omS383 hj)),D_px,ἐ (by clear hX hh hw hR hS he hr hc hT g3 this hl; (clear ep ew; exact omS384 g1 g2 hj)),Nat.add_sub_cancel_left,qAa _ (by clear hh hw hR hS he hr hc ep hT g1 g2 g3 hl; (clear hj; exact omS385 hs hX this))];rfl . rw[ὢ,ὢ,qAi _ _ _ (by clear hX hh hw hR hS he hr hc ew hT g1 g2 g3 this hl; (clear ep; exact omS386 hu)),D_px,ἱ (by clear hh hw hR hS he hr hc ep hT g1 g2 this hl hu; exact omS387)] apply ih (r+1) _ (by clear hX hh hw hS hr hc ep ew hT g; exact omS137 he) rw[ᾀ] exact qBq _ H λu hu=>by rw[qAi _ _ _ hu,D_px,ἱ] by_contra n have:=hO (by clear hX hh hw hR hS he hr hc ep ew hT g hu; exact omS388 n) exact g ⟨by (clear hX hh hw hR hS he hr hc ew hT g hu this; (clear ep; exact omS389 n)),by (clear hX hh hw hR hS he hr hc ep ew hT g hu this; exact omS388 n),by rw[qAa _ (by clear hh hw hR hS he hr hc ep hT g hu; (clear n; exact omS385 hs hX this)),ew,hX];exact this⟩ lemma qA1 (F:Ὣ->ὧ) {S:Ὣ} (N:ὦ) (c:Ὣ) (hN:ѤN=S) (hS:S<2^32) : D_Zs F S 0 (D_fill (dv 0) N 0 (ἆ c)):=by have h:=qCc (F:=λ_=>dv 0) (v:=dv 0) (n:=N) S 0 0 (ἆ c) (by rw[C_z,hN,Ἇ]) ⟨rfl,λq hq=>absurd hq (Ἲ q)⟩ λ_ _ _=>rfl;rw[Ἇ] at h;exact ⟨h.1,hS,λq hq=>by rw[ἐ (Ἲ q)];exact h.2 q hq⟩ lemma qHd (F:Ὣ->ὧ) (n:Ὣ) (h:n<=16384):∃ S,n<=S∧D_Zs F S 0 (D_zs n):=by unfold D_zs;split;. exact ⟨512,‹_›,qA1 F 512 512 (uk 512 (by norm_num1)) (by norm_num1)⟩ split;. exact ⟨1024,‹_›,qA1 F 1024 1024 (uk 1024 (by norm_num1)) (by norm_num1)⟩ split;. exact ⟨2048,‹_›,qA1 F 2048 2048 (uk 2048 (by norm_num1)) (by norm_num1)⟩ split;. exact ⟨4096,‹_›,qA1 F 4096 4096 (uk 4096 (by norm_num1)) (by norm_num1)⟩ split;. exact ⟨8192,‹_›,qA1 F 8192 8192 (uk 8192 (by norm_num1)) (by norm_num1)⟩ exact ⟨16384,h,qA1 F 16384 16384 (uk 16384 (by norm_num1)) (by norm_num1)⟩ lemma qG7 (s:OS) (X:ѐ) (a:ѧX<2^32) (e:ѧX=s.cin*s.h*s.w) (p:s.h+2*s.pad<2^32) (q:s.w+2*s.pad<2^32) : D_Sp (D_Fx s X) (s.cin*(s.h+2*s.pad)*(s.w+2*s.pad)) (D_xs s X a (s.w+2*s.pad) (s.cin*(s.h+2*s.pad))):=by unfold D_xs split<;>rename_i hz . rw [ch2_eq s X a (s.w+2*s.pad) (s.cin*(s.h+2*s.pad)) rfl s.cin 0 _ (Nat.zero_add _), Nat.zero_mul] obtain ⟨S,h1,h2⟩:=qHd (D_Fx s X) _ hz;have P:=qE6 s X a e p q (S:=S) rfl (by clear a e p q hz; exact omS422 h1) _ 0 _ (Ἇ _) (by rw[Nat.zero_mul];exact h2);exact ⟨by rw[P.1];(clear e p q hz; exact omS422 h1),λt ht=>by rw[P.2.2 t (by clear e p q hz; exact omS423 h1 ht),ἱ ht]⟩ have Pz:=qE0 s X a e p q rfl _ 0 (ἆ (s.cin*(s.h+2*s.pad)*(s.w+2*s.pad)+7)) (Ἇ _) ⟨by rw[Nat.zero_mul];rfl,λq hq=>(by omega)⟩ exact qJt 7 7 0 _ (by rw[C_z,Ἇ];exact (uk 7 (by norm_num1)).symm) ⟨Nat.le_of_eq Pz.1.symm,Pz.2⟩ lemma qFb (dw:Ὡ) (s:OS) (relu:Ὡ) (X W b:ѐ) {k C:Ὣ} (hk:k=if dw then s.kh*s.kw else s.cin*s.kh*s.kw) (hC:C=if dw then s.cin else s.cout) : D_F dw s relu X W b k C =if dw then depthwiseSpecO s relu X W b else conv2dSpecO s relu X W b:=by unfold D_F rw[(cvGet W b s dw k C).2] unfold D_Fc dsimp only rw[qAg] split;swap;rfl split;swap;rfl rename_i hg hs obtain ⟨a,c,d,e,f,-,i,j,l,m,n,o,p,q,r,t,u,-,v,x⟩:=hg replace hs:=Nat.lt_of_le_of_lt hs (show 4294967295<2^32 by norm_num) replace a:=Nat.lt_of_le_of_lt a (show 4294967295<2^32 by norm_num) replace j:=Nat.lt_of_le_of_lt j (show 4294967295<2^32 by norm_num) replace p:=Nat.lt_of_le_of_lt p (show 4294967295<2^32 by norm_num) replace q:=Nat.lt_of_le_of_lt q (show 4294967295<2^32 by norm_num) replace r:=Nat.lt_of_le_of_lt r (show 4294967295<2^32 by norm_num) replace t:=Nat.lt_of_le_of_lt t (show 4294967295<2^32 by norm_num) replace u:=Nat.lt_of_le_of_lt u (show 4294967295<2^32 by norm_num) have y:=qFi X X.usize (qAd X) X.usize.toNat 0 Е 0 (Ἇ _) rw[ἱ ⟨c,d⟩] at y have Hx:=y ▸ qBh X a (by rw[y];intro h;rw[h] at d;exact absurd d ה) refine (qHh ?_ _).trans ?_ have hk0:k≠0 :=(by clear hC hs y; exact omS424 l) rw[hk] at hk0 have k1:0< s.kh:=ὼ λz=>hk0 (by rw[z];simp) have k2:0< s.kw:=ὼ λz=>hk0 (by rw[z];simp) exact ⟨hk,hC,rfl,rfl,rfl,qAa _ j,rfl,λh=>beq_iff_eq.1 (ὕ.1 h).1,i,l,m,n,o,qG7 s X a e p q,hs,Hx,qGp (qD0 W r v).2.2.1,qGp (qD0 b t x).2.2.1,f,r,t,u,q,qGz s k k 0 0 0 0 _ (Ἇ _) ג k1 k2 (by simp[Array.emptyWithCapacity_eq])⟩ rfl lemma qC1x (d:DotFn) (s:OS) (r:Ὡ) (X W b:ё) : conv2dWithO d (Cn1 s) r X W b=conv2dWithO d s r X W b:=by unfold Cn1 split · rename_i H obtain ⟨cin,h,w,co,kh,kw,st,pd⟩:=s obtain ⟨rfl,rfl,rfl,rfl,u,v⟩:=H simp only at u v have P:=Nat.mul_pos u v have e:∀ n,0< n → (n+2*0-1)/1+1=n:=fun n h=>by omega simp only[conv2dWithO,OS.ho,OS.wo,e _ u,e _ v,e _ P,e 1 Nat.one_pos,Nat.one_mul,Nat.mul_one] refine Array.ext (by simp[Nat.sub_add_cancel u,Nat.sub_add_cancel v,Nat.sub_add_cancel P]) fun q _ _=>?_ simp only[Array.getElem_ofFn,windowAtO,Nat.mul_one,Nat.div_one,Nat.mod_one,Nat.add_zero,Nat.sub_zero,Nat.not_lt_zero,false_or] have:=Nat.mod_lt q P have m:q%(h*w)=q%w+w*(q/w%h):=by rw[Nat.mul_comm h w,Nat.mod_mul] have:=Nat.mod_lt (q/w) u have:=Nat.mod_lt q v congr 2 funext t split · rw[ἐ (by omega),ἐ (by omega),m] congr 1 ring · rfl · rfl lemma qB7:convF=conv2dSpecO:=by funext s r X W b;exact (qFb false (Cn1 s) r X W b (k:=s.cin*s.kh*s.kw) (C:=s.cout) (by unfold Cn1;split<;>split<;>simp_all) (by unfold Cn1;split<;>split<;>simp_all)).trans (qC1x _ s r X W b) lemma qDr:depthF=depthwiseSpecO:=by funext s r X W b;exact qFb true s r X W b rfl rfl end section open Float.Model Float.Model.UnpackedFloat @[noinline] def P39:Ὣ:=2^39 @[noinline] def P38:Ὣ:=2^38 def T_r (N:Ὣ):Ὣ := N/P39+if P38< N%P39∨(N%P39=P38∧(N/P39)%2=1) then 1 else 0 lemma qIv (N:Ὣ):FloatLib.Numerics.roundShiftRightEven N 39=T_r N:=by have a:Nat.shiftRight N 39=N/2^39:=Ἱ N 39;have b:N-Nat.shiftLeft (N/2^39) 39=N%2^39:=by rw[show Nat.shiftLeft (N/2^39) 39=N/2^39*2^39 from ὁ _ _];(clear a; exact omS425) rw[FloatLib.Numerics.roundShiftRightEven_def];simp only[show (39 == 0)=false from rfl,false_eq_true,ite_false,a,b,beq_iff_eq];unfold T_r P39 P38;split_ifs<;>omega set_option maxRecDepth 8192 in lemma qIc (neg:Ὡ) (N:Ὣ) (e':Int) (hN1:2^62<=N) (hN2:N<2^63) (h1:-148<=e'+39) (h2:e'+39+150<=253) : toWord (Model.ofModel Fmt (UnpackedFloat.round Format.binary32 (ὶ neg) N e')) =ὺ ((if neg then 2^31 else 0)+(e'+39+149).toNat*2^23+T_r N):=by have hr1:2^23<=T_r N:=by unfold T_r P39 P38;split<;>omega have hr2:T_r N<=2^24:=by unfold T_r P39 P38;split<;>omega have hT:Format.binary32.targetExponent (totalExponent N e')=e'+39:=by simp only[totalExponent,qC8 N 62 hN1 hN2,qGo];(clear hN1 hN2 hr1 hr2; exact omS426 h1) have K:∀ (P:Ὣ) (E:Int) (hp:0< P),2^23<=P->P<2^24->-149<=E->E<=104 → (E+150).toNat*2^23+P%2^23=(e'+39+149).toNat*2^23+T_r N → toWord (Model.ofModel Fmt (.finite (ὶ neg) P E hp)) =ὺ ((if neg then 2^31 else 0)+(e'+39+149).toNat*2^23+T_r N):=by intro P E hp a b c d e simp only[toWord,Model.toNatBits,Model.ofModel,Model.ofModelBits] congr 1 show (UnpackedFloat.pack Format.binary32 _).toNat=_ rw[qBk _ _ _ _ a b (by clear hN1 hN2 h1 h2 hr1 hr2 hT hp a b e; exact omS92 c) (by clear hN1 hN2 h1 h2 hr1 hr2 hT hp a b e; exact omS427 d)] cases neg<;>simp[Model.modelSign]<;>(clear hN1 hN2 h1 h2 hr1 hr2 hT hp a b c d; omega) rw[Model.round_exact_eq_finishRoundedMantissa _ _ _ _,hT,Model.roundMantissaAtExponentEven,ἱ (by clear hN1 hN2 h1 h2 hr1 hr2 hT; exact omS429),show (e'+39-e').toNat=39 by (clear hN1 hN2 h1 h2 hr1 hr2 hT; exact omS430),qIv] by_cases hc:T_r N=2^24 . have h:=Model.finishRoundedMantissa_normalized_carry FloatFormat.binary32 (ὶ neg) (e'+39+23) (by show -126<=e'+39+23;(clear hN1 hN2 hr1 hr2 hc; exact omS431 h1));rw[show e'+39+23-(FloatFormat.binary32.fracWidth:ℤ)=e'+39 by show e'+39+23-23=_;(clear hN1 hN2 h1 h2 hr1 hr2 hT hc; exact omS432),show e'+39+23+1-(FloatFormat.binary32.fracWidth:ℤ)=e'+40 by show e'+39+23+1-23=_;(clear hN1 hN2 h1 h2 hr1 hr2 hT hc; exact omS433)] at h;rw[show Model.finishRoundedMantissa Format.binary32 (ὶ neg) (T_r N,e'+39) =.finite (ὶ neg) (2^23) (e'+40) (by positivity) by rw[hc];exact h] exact K (2^23) (e'+40) (by positivity) le_rfl (by norm_num1) (by clear hN1 hN2 hr1 hr2 hc; exact omS434 h1) (by clear hN1 hN2 hr1 hr2 hc; exact omS435 h2) (by rw[hc,show (e'+40+150).toNat=(e'+39+149).toNat+2 by (clear hN1 hN2 hr1 hr2 hc; exact omS436 h1)];(clear hN1 hN2 h1 h2 hr1 hr2 hT hc; exact omS437)) . rw[qEf _ _ _ hr1 (by clear hN1 hN2 h1 h2 hT; exact omS438 hr2 hc) (by clear hN1 hN2 hr1 hr2 hc; exact omS439 h1) (by clear hN1 hN2 h1 h2 hT hc; exact omS71 hr1)] exact K _ _ _ hr1 (by clear hN1 hN2 h1 h2 hT; exact omS438 hr2 hc) (by clear hN1 hN2 hr1 hr2 hc; exact omS439 h1) (by clear hN1 hN2 hr1 hr2 hc; exact omS440 h2) (by rw[show (e'+39+150).toNat=(e'+39+149).toNat+1 by (clear hN1 hN2 hr1 hr2 hc; exact omS441 h1)];(clear hN1 hN2; exact omS442 hr1 hr2 hc)) @[inline] def T_rd (neg:Ὡ) (mag e0 L:Ὠ):ὥ := let n:=mag <<< (62-L) let q:=n >>> 39 let rm:=n &&& 0x7FFFFFFFFF let w:=((e0+L-24) <<< 23)+q + (if rm > 0x4000000000 || (rm == 0x4000000000 && q &&& 1 == 1) then 1 else 0) (if neg then w ||| س else w).toUInt32 lemma qG4 (neg:Ὡ) (mag e0:Ὠ) (h0:Ѧmag≠0) (h1:Ѧmag<2^63) (h2:24< Ѧe0+mag.toNat.log2) (h3:Ѧe0+mag.toNat.log2<277) : T_rd neg mag e0 mag.log2=toWord (ἕ Fmt ⟨neg,Ѧmag,(Ѧe0:Int)-150⟩):=by have l0:=Nat.log2_self_le h0;have l1:Ѧmag<2^(mag.toNat.log2+1):=Nat.lt_log2_self;have hL:mag.toNat.log2<=62:=Nat.lt_succ_iff.1 ((Nat.log2_lt h0).2 h1);obtain ⟨L,hLd⟩:∃ L,L=mag.toNat.log2:=⟨_,rfl⟩;rw[<-hLd] at l0 l1 hL h2 h3;have eL:mag.log2.toNat=L:=hLd.symm;obtain ⟨N,hN⟩:∃ N,N=Ѧmag*2^(62-L):=⟨_,rfl⟩;have p:2^L*2^(62-L)=2^62:=by rw[<-Nat.pow_add,Nat.add_sub_of_le hL] have hN1:2^62<=N:=by rw[hN,<-p];exact Ἒ _ l0 have hN2:N<2^63:=by have:=Nat.mul_lt_mul_of_pos_right l1 (Nat.two_pow_pos (62-L));rwa [<-hN,<-Nat.pow_add,show L+1+(62-L)=63 from (Nat.add_right_comm L 1 (62-L)).trans (congrArg (·+1) (Nat.add_sub_of_le hL))] at this have s4:Ѧe0+L-24<=252:=Nat.sub_le_iff_le_add.mpr (Nat.le_of_lt_succ h3) obtain ⟨i1,i2,i3⟩:(-148:Int)<=(Ѧe0:Int)-150-((62-L:Ὣ):Int)+39∧(Ѧe0:Int)-150-((62-L:Ὣ):Int)+39+150<=253∧((Ѧe0:Int)-150-((62-L:Ὣ):Int)+39+149).toNat=Ѧe0+L-24:=by (clear h0 h1 l1 l0 hN p hN1 hN2 hLd eL; omega) rw[qA5,<-ExactRuntime.round_scale _ _ _ _ (62-L) h0,<-hN,qIc neg N _ hN1 hN2 i1 i2];have eT:((Ѧe0:Int)-150-((62-L:Ὣ):Int)+39+149).toNat=Ѧe0+L-24:=i3 rw[eT];unfold T_rd;dsimp only;have e1:(62-mag.log2).toNat=62-L:=by rw[toNat_sub_of_le _ _ (Ὤ.2 (by rw[eL];exact hL)),eL];rfl have a1:(mag <<< (62-mag.log2)).toNat=N:=by rw[UInt64.toNat_shiftLeft,e1,Ἁ (Nat.lt_of_le_of_lt (Nat.sub_le 62 L) (by decide):62-L<64),ὁ,<-hN,Ἁ (by exact Nat.lt_of_lt_of_le ‹_› (by decide))] generalize mag <<< (62-mag.log2)=n at a1;have a2:(n >>> 39).toNat=N/2^39:=by rw[ἰ,a1];simp[Nat.shiftRight_eq_div_pow] have a3:(n &&& 0x7FFFFFFFFF).toNat=N%2^39:=by rw[Ὅ,a1];exact Ἂ N 39 generalize n >>> 39=q at a2;generalize n &&& 0x7FFFFFFFFF=rm at a3;have a4:(q &&& 1).toNat=Ѧq%2:=by rw[Ὅ];exact Ἂ _ 1 have a5:(e0+mag.log2-24).toNat=Ѧe0+L-24:=by rw[toNat_sub_of_le _ _ (Ὤ.2 (by rw[ἤ,eL,Ἁ (by exact Nat.lt_of_lt_of_le ‹_› (by decide))];show 24<=_;(exact Nat.le_of_lt ‹_›))), ἤ,eL,Ἁ (by exact Nat.lt_of_lt_of_le ‹_› (by decide))] rfl have a6:((e0+mag.log2-24) <<< 23).toNat=(Ѧe0+L-24)*2^23:=by rw[UInt64.toNat_shiftLeft,a5,ὁ];show _*2^23%_=_;rw[Ἁ (Nat.lt_of_le_of_lt (Nat.mul_le_mul_right (2^23) s4) (by decide))] generalize (e0+mag.log2-24) <<< 23=hi at a6;have hup:(decide (rm > 0x4000000000) || (rm == 0x4000000000 && q &&& 1 == 1)) =decide (2^38< N%2^39∨(N%2^39=2^38∧(N/2^39)%2=1)):=by apply Bool.eq_iff_iff.2;simp only[or_eq_true,and_eq_true,decide_eq_true_eq,beq_iff_eq,gt_iff_lt,UInt64.lt_iff_toNat_lt,<-UInt64.toNat_inj,a3,a4,a2];rfl rw[hup];obtain ⟨c,hc⟩:∃ c,c=decide (2^38< N%2^39∨(N%2^39=2^38∧(N/2^39)%2=1)):=⟨_,rfl⟩;rw[<-hc];have hr:T_r N=N/2^39+if c=true then 1 else 0:=by rw[hc,T_r,P39,P38];simp only[decide_eq_true_eq] have hq:N/2^39<2^24 :=Nat.div_lt_of_lt_mul (Nat.lt_of_lt_of_le hN2 (by decide));have U':(Ѧe0+L-24)*2^23+(N/2^39+1)<2^31:=Nat.lt_of_le_of_lt (Nat.add_le_add (Nat.mul_le_mul_right (2^23) s4) (hq:N/2^39+1<=2^24)) (by decide);have U:(Ѧe0+L-24)*2^23+N/2^39+1<2^31:=lt_of_eq_of_lt (Nat.add_assoc _ _ _) U';have W1:(Ѧe0+L-24)*2^23+N/2^39+1<2^64:=Nat.lt_trans U (by decide);have W0:(Ѧe0+L-24)*2^23+N/2^39<2^64:=Nat.lt_of_succ_lt W1 have hw:(hi+q+(if c=true then (1:Ὠ) else 0)).toNat=(Ѧe0+L-24)*2^23+T_r N:=by rw[ἤ,ἤ,a6,a2,hr];cases c<;>simp only[false_eq_true,ite_false,ite_true] <;>(try rw[show (1:Ὠ).toNat=1 from rfl])<;>(try rw[show (0:Ὠ).toNat=0 from rfl]) . rw[Nat.add_zero,Nat.add_zero,Ἁ W0,Ἁ W0] . rw[Ἁ W0,Ἁ W1,Nat.add_assoc] generalize hi+q+(if c=true then (1:Ὠ) else 0)=w at hw;have hw2:Ѧw<2^31:=by rw[hw,hr];split;exact U';exact Nat.lt_of_succ_lt U apply ἠ.mp;rw[ὡ];cases neg;. simp only[false_eq_true,ite_false,UInt64.toNat_toUInt32,Nat.zero_add,hw] . simp only[ite_true,UInt64.toNat_toUInt32,UInt64.toNat_or];have h5:Ѧw ||| (2147483648:Ὠ).toNat=2^31+Ѧw:=by have:=Nat.two_pow_add_eq_or_of_lt hw2 1;simp only[Nat.mul_one] at this;rw[this,Nat.or_comm];rfl rw[h5];congr 1;rw[hw];exact (Nat.add_assoc _ _ _).symm lemma qJf (w:ὥ) (h:(w &&& В)=0):ἂ w=0:=by have h1:=qA0 w;rw[h] at h1;have h2:=w.toNat_lt have h3:w=0∨w=س:=by have:ѥw=0∨ѥw=2147483648:=by simp at h1;(clear h; exact omS452 h2 h1) rcases this with e | e;. exact Or.inl (ἠ.mp (by simpa using e)) . exact Or.inr (ἠ.mp (by simpa using e)) have h4:expOf w=0∧fracOf w=0:=by rcases h3 with rfl | rfl<;>decide simp[rationalWord, decodeD, h4] @[inline] def T_e (w:ὥ):Ὠ := if w &&& В == 0 then 255 else (expOf w).toUInt64 @[inline] def T_m (w:ὥ):Ὠ := if w &&& В == 0 then 0 else (fracOf w+0x800000).toUInt64 @[inline] def T_s (e0:Ὠ) (w:ὥ):Ὠ:=T_m w <<< (T_e w-e0) @[inline] def T_ok (e0:Ὠ) (w:ὥ):Ὡ := good w && (w &&& В == 0 || (e0<=T_e w && T_e w-e0<=37)) @[inline] def T_p (e0:Ὠ) (w:ὥ) (p:Ὠ):Ὠ := if signOf w then p else p+T_s e0 w @[inline] def T_n (e0:Ὠ) (w:ὥ) (n:Ὠ):Ὠ := if signOf w then n+T_s e0 w else n lemma qJa (e0:Ὠ) (w:ὥ) (h:T_ok e0 w=true) : (T_s e0 w).toNat<2^61∧ἂ w = (if signOf w then -((T_s e0 w).toNat:ℚ) else ((T_s e0 w).toNat:ℚ)) * 2^((Ѧe0:Int)-150):=by unfold T_ok at h simp only[and_eq_true,or_eq_true,beq_iff_eq,decide_eq_true_eq] at h obtain ⟨hg,hz⟩:=h by_cases h0:w &&& В=0 . have hs:T_s e0 w=0:=by unfold T_s T_m;simp[h0] rw[hs,qJf w h0];simp . obtain ⟨h1,h2⟩:=hz.resolve_left h0;have g:=qBd w hg;have a0:(w &&& В).toNat≠0:=λe=>h0 (ἠ.mp (by simpa using e));rw[qA0] at a0;have hx:=qAx w;have hf:(fracOf w).toNat=ѥw%2^23:=qBt w;have hl:=w.toNat_lt;have x1:1<=(expOf w).toNat :=(by clear hz h0 h1 h2 hl; exact omS453 g a0 hx);have x2:(expOf w).toNat<=254 :=(by clear hz h0 h1 h2 hl; exact omS454 g hx);have f1:(fracOf w).toNat<2^23 :=(by clear hz h0 h1 h2 g a0 hx hl x1 x2; exact omS455 hf);have ee:(T_e w).toNat=(expOf w).toNat:=by unfold T_e;simp[h0] have em:(T_m w).toNat=2^23+(fracOf w).toNat:=by unfold T_m;simp only[h0,beq_iff_eq,ite_false,UInt32.toNat_toUInt64];rw[UInt32.toNat_add,Ἁ (by show _+8388608< _;(clear hz h0 h1 h2 g a0 hx hl x1 x2 f1 ee; exact omS456 hf))];show _+8388608=_;(clear hz h0 h1 h2 g a0 hx hf hl x1 x2 f1 ee; exact omS457) have l1:=Ὤ.1 h1;have l2:=Ὤ.1 h2;rw[toNat_sub_of_le _ _ h1,ee] at l2;rw[ee] at l1;have l3:(expOf w).toNat-Ѧe0<=37:=l2 have es:(T_s e0 w).toNat=(2^23+(fracOf w).toNat)*2^((expOf w).toNat-Ѧe0):=by unfold T_s;have sh:(T_e w-e0).toNat%64=(expOf w).toNat-Ѧe0:=by rw[toNat_sub_of_le _ _ h1,ee];exact Ἁ (by exact Nat.lt_of_le_of_lt ‹_› (by decide)) rw[UInt64.toNat_shiftLeft,em,sh,ὁ];apply Ἁ;have:2^((expOf w).toNat-Ѧe0)<=2^37:=Nat.pow_le_pow_right (by positivity) l3;have:(2^23+(fracOf w).toNat)*2^((expOf w).toNat-Ѧe0)<=2^24*2^37 :=Nat.mul_le_mul (by clear hz h0 h1 h2 g a0 hx hl x1 x2 f1 ee l1 l2 l3 sh this; exact omS458 hf) this;(exact Nat.lt_of_le_of_lt ‹_› (by decide)) refine ⟨?_,?_⟩;. have a:2^((expOf w).toNat-Ѧe0)<=2^37:=Nat.pow_le_pow_right (by positivity) l3;have b:(2^23+(fracOf w).toNat)*2^((expOf w).toNat-Ѧe0)<=(2^24-1)*2^37 :=Nat.mul_le_mul (by clear hz h0 h1 h2 g a0 hx hl x1 x2 f1 ee l1 l2 l3 es a; exact omS459 hf) a;rw[es];(exact Nat.lt_of_le_of_lt ‹_› (by decide)) . have nz:expOf w≠0:=λe=>by rw[e] at x1;simp at x1 have ew:(2:ℚ)^(((expOf w).toNat:Int)-150) =2^((expOf w).toNat-Ѧe0)*2^((Ѧe0:Int)-150):=by rw[<-Ἡ,<-Ἓ ἓ];congr 1;(clear hz h0 h1 h2 g a0 hf hl x1 x2 f1 em l2 l3 es nz; exact omS460 l1) rw[es];simp only[rationalWord,decodeD,nz,ite_false,FloatLib.Numerics.Dyadic.toRat,signedSignificand,ew];cases signOf w<;>simp<;>ring lemma qEn (e0:Ὠ) (w:ὥ) (p n:Ὠ) (V:ℚ) (B C:Ὣ) (hC:C=2^61-1) (hB:B+C<2^63) (hw:T_ok e0 w=true) (hp:Ѧp<=B) (hn:Ѧn<=B) (hV:V=((Ѧp:ℚ)-Ѧn)*2^((Ѧe0:Int)-150)) : (T_p e0 w p).toNat<=B+C∧(T_n e0 w n).toNat<=B+C ∧ V+ἂ w=(((T_p e0 w p).toNat:ℚ)-(T_n e0 w n).toNat) * 2^((Ѧe0:Int)-150):=by obtain ⟨h1,h2⟩:=qJa e0 w hw have h3:(T_s e0 w).toNat<=C :=(by clear hB hp hn; exact omS461 hC h1) unfold T_p T_n rw[h2,hV] cases signOf w . simp only[false_eq_true,ite_false];have e:(p+T_s e0 w).toNat=Ѧp+(T_s e0 w).toNat:=by rw[ἤ];exact Ἁ (by clear hn h3; exact omS462 hB hp h1) rw[e];refine ⟨by (clear hB hn h3; exact omS463 hC hp h1),by (clear hB hp h1 h3 e; exact omS464 hn),?_⟩;push_cast;ring . simp only[ite_true];have e:(n+T_s e0 w).toNat=Ѧn+(T_s e0 w).toNat:=by rw[ἤ];exact Ἁ (by clear hp h3; exact omS462 hB hn h1) rw[e];refine ⟨by (clear hB hn h1 h3 e; exact omS464 hp),by (clear hB hp h3; exact omS463 hC hn h1),?_⟩;push_cast;ring @[inline] def T_lg (x:UInt64):UInt64 := let a:UInt64:=if 0x100000000<=x then 32 else 0 let y:=x >>> a let b:UInt64:=if 0x10000<=y then 16 else 0 let y:=y >>> b let c:UInt64:=if 0x100<=y then 8 else 0 let y:=y >>> c let d:UInt64:=if 0x10<=y then 4 else 0 let y:=y >>> d let e:UInt64:=if 4<=y then 2 else 0 let y:=y >>> e a+b+c+d+e+(if 2<=y then 1 else 0) lemma lgS (n s:Nat) (h:2^s<=n) : n.log2=(n/2^s).log2+s:=by have hn:n≠0:=by have:=Nat.one_le_two_pow (n:=s);omega have h1:=Nat.log2_self_le hn have h2:n<2^(n.log2+1):=Nat.lt_log2_self have hsL:s<=n.log2:=(Nat.le_log2 hn).2 h have q1:2^(n.log2-s)<=n/2^s:=by rw[Nat.le_div_iff_mul_le (Nat.two_pow_pos s),<-Nat.pow_add,Nat.sub_add_cancel hsL];exact h1 have q2:n/2^s<2^(n.log2-s+1):=by rw[Nat.div_lt_iff_lt_mul (Nat.two_pow_pos s),<-Nat.pow_add,show n.log2-s+1+s=n.log2+1 by omega];exact h2 have q0:n/2^s≠0:=by have:=Nat.one_le_two_pow (n:=n.log2-s);omega have:=(Nat.log2_eq_iff q0).2 ⟨q1,q2⟩ omega lemma lgU (y T c:UInt64) (hT:T.toNat=2^c.toNat) (hc:c.toNat<64) (hy:y.toNat<2^(2*c.toNat)) : (y >>> (if T<=y then c else 0)).toNat<2^c.toNat ∧ y.toNat.log2=(y >>> (if T<=y then c else 0)).toNat.log2+(if T<=y then c else 0).toNat:=by by_cases hTy:T<=y . rw[ἱ hTy] have e:(y >>> c).toNat=y.toNat/2^c.toNat:=by rw[UInt64.toNat_shiftRight,Nat.mod_eq_of_lt hc];exact Nat.shiftRight_eq_div_pow _ _ rw[e];constructor . rw[Nat.div_lt_iff_lt_mul (Nat.two_pow_pos _),<-Nat.pow_add];rw[show c.toNat+c.toNat=2*c.toNat by omega];exact hy . exact lgS _ _ (by rw[<-hT];exact UInt64.le_iff_toNat_le.mp hTy) . rw[ἐ hTy] have e:(y >>> (0:UInt64)).toNat=y.toNat:=by simp rw[e];refine ⟨?_,by simp⟩ have:=UInt64.lt_iff_toNat_lt.mp (UInt64.not_le.mp hTy);omega lemma lgF (y:UInt64) (h:y.toNat<2^2) : y.toNat.log2=(if 2<=y then (1:UInt64) else 0).toNat:=by have h4:y.toNat<4:=by simpa using h by_cases h2:(2:UInt64)<=y . rw[ἱ h2];have:=UInt64.le_iff_toNat_le.mp h2 have e:(2:UInt64).toNat=2:=rfl;rw[e] at this exact (Nat.log2_eq_iff (by omega)).2 ⟨by simpa using this,by simpa using h4⟩ . rw[ἐ h2];have:=UInt64.lt_iff_toNat_lt.mp (UInt64.not_le.mp h2) have e:(2:UInt64).toNat=2:=rfl;rw[e] at this have:y.toNat=0∨y.toNat=1:=by omega rcases this with e|e<;>rw[e]<;>decide lemma qLg (x:UInt64):T_lg x=x.log2:=by apply UInt64.toNat_inj.mp have eL:x.log2.toNat=x.toNat.log2:=rfl rw[eL];unfold T_lg;dsimp only obtain ⟨y1,e1⟩:=lgU x 0x100000000 32 (by decide) (by decide) (by have:=x.toNat_lt;simpa using this) generalize (if (0x100000000:UInt64)<=x then (32:UInt64) else 0)=a at y1 e1 ⊢ generalize x >>> a=x1 at y1 e1 ⊢ obtain ⟨y2,e2⟩:=lgU x1 0x10000 16 (by decide) (by decide) (by simpa using y1) generalize (if (0x10000:UInt64)<=x1 then (16:UInt64) else 0)=b at y2 e2 ⊢ generalize x1 >>> b=x2 at y2 e2 ⊢ obtain ⟨y3,e3⟩:=lgU x2 0x100 8 (by decide) (by decide) (by simpa using y2) generalize (if (0x100:UInt64)<=x2 then (8:UInt64) else 0)=c at y3 e3 ⊢ generalize x2 >>> c=x3 at y3 e3 ⊢ obtain ⟨y4,e4⟩:=lgU x3 0x10 4 (by decide) (by decide) (by simpa using y3) generalize (if (0x10:UInt64)<=x3 then (4:UInt64) else 0)=d at y4 e4 ⊢ generalize x3 >>> d=x4 at y4 e4 ⊢ obtain ⟨y5,e5⟩:=lgU x4 4 2 (by decide) (by decide) (by simpa using y4) generalize (if (4:UInt64)<=x4 then (2:UInt64) else 0)=e at y5 e5 ⊢ generalize x4 >>> e=x5 at y5 e5 ⊢ have e6:=lgF x5 (by simpa using y5) generalize (if (2:UInt64)<=x5 then (1:UInt64) else 0)=f at e6 ⊢ have hb:x.toNat.log2<2^64:=Nat.lt_of_le_of_lt (Nat.log2_le_self _) x.toNat_lt simp only[UInt64.toNat_add] omega @[inline] def T_fin (p n e0:Ὠ) (f:Unit->ὥ):ὥ := if p == n then f () else let mag:=if p< n then n-p else p-n let L:=T_lg mag if e0+L<=24 || e0+L ≥ 277 then f () else T_rd (decide (p< n)) mag e0 L lemma qFy (p n e0:Ὠ) (f:Unit->ὥ) (hp:Ѧp<2^63) (hn:Ѧn<2^63) (he:Ѧe0<=255) (R:ὥ) (hf:f ()=R) (hR:p≠n->∃ d:FloatLib.Numerics.Dyadic, d.toRat=((Ѧp:ℚ)-Ѧn)*2^((Ѧe0:Int)-150) ∧ R=toWord (ἕ Fmt d)):T_fin p n e0 f=R:=by unfold T_fin simp only[qLg] split . exact hf . rename_i hne;have hne':p≠n:=λe=>hne (by simp[e]);have hnn:Ѧp≠Ѧn:=λe=>hne' (UInt64.toNat_inj.mp e);obtain ⟨d,hd,hR⟩:=hR hne';(try dsimp only);obtain ⟨mag,hm⟩:∃ m,m=if p< n then n-p else p-n:=⟨_,rfl⟩;rw[<-hm] have hm1:Ѧmag≠0∧Ѧmag<2^63 ∧ (((if decide (p< n)=true then -(Ѧmag:ℚ) else (Ѧmag:ℚ))) =(Ѧp:ℚ)-Ѧn):=by by_cases c:p< n . have c':=ἴ.1 c;have:Ѧmag=Ѧn-Ѧp:=by rw[hm,ἱ c,toNat_sub_of_le _ _ (Ὤ.2 c'.le)] refine ⟨by (clear hp hn he hf hne' hnn hR hm c; exact omS465 c' this),by (clear he hf hne' hnn hR hm c; exact omS466 hn this),?_⟩;rw[this,Nat.cast_sub c'.le];simp[c] . have c':Ѧn<=Ѧp:=by have:=ἴ.not.1 c;(clear hp hn he hf hne' hnn hR hm c; omega) have:Ѧmag=Ѧp-Ѧn:=by rw[hm,ἐ c,toNat_sub_of_le _ _ (Ὤ.2 c')] refine ⟨by (clear hp hn he hf hne' hR hm c; exact omS467 hnn c' this),by (clear he hf hne' hnn hR hm c; exact omS466 hp this),?_⟩;rw[this,Nat.cast_sub c'];simp[c] obtain ⟨m0,m1,m2⟩:=hm1;split;. exact hf . rename_i hb;simp only[or_eq_true,decide_eq_true_eq,not_or,ge_iff_le] at hb;obtain ⟨b1,b2⟩:=hb;have eL:mag.log2.toNat=mag.toNat.log2:=rfl;have hL:mag.toNat.log2<=62:=by have:=(Nat.log2_lt m0).2 m1;(exact Nat.le_of_lt_succ ‹_›) have eA:(e0+mag.log2).toNat=Ѧe0+mag.toNat.log2:=by rw[ἤ,eL];exact Ἁ (by clear hp hn hf hne' hnn hR hm m0 m1 b1 b2; exact omS468 he hL) have b3:¬ (e0+mag.log2).toNat<=(24:Ὠ).toNat:=λh=>b1 (Ὤ.2 h);have b4:¬ (277:Ὠ).toNat<=(e0+mag.log2).toNat:=λh=>b2 (Ὤ.2 h);rw[eA] at b3 b4;have t1:(24:Ὠ).toNat=24:=rfl;have t2:(277:Ὠ).toNat=277:=rfl;rw[qG4 _ _ _ m0 m1 (by clear hp hn he hf hne' hnn hR hm m0 m1 b1 b2 eL hL b4 t2; exact omS469 b3 t1) (by clear hp hn hf hne' hnn hR hm m0 m1 b1 b2 b3 t1; exact omS470 b4 t2),hR];refine congrArg toWord ?_ have s0:d.significand≠0:=by intro h0;have:d.toRat=0:=(ὐ d).2 h0;rw[hd] at this;have q:(Ѧp:ℚ)-Ѧn≠0:=by rw[sub_ne_zero];exact_mod_cast hnn exact (mul_ne_zero q (zpow_ne_zero _ ἓ)) this refine roundDyadic_congr Fmt ה _ _ m0 s0 ?_;rw[hd,<-m2];simp only[FloatLib.Numerics.Dyadic.toRat,signedSignificand];cases decide (p< n)<;>simp lemma qHq (w:ὥ):(T_e w).toNat<=255:=by unfold T_e;split;. decide . have:=qAx w;simp only[UInt32.toNat_toUInt64];omega @[inline] def T_min (x y:Ὠ):Ὠ:=if x< y then x else y lemma qC5 (x y:Ὠ):(T_min x y).toNat<=Ѧx:=by unfold T_min;split;. exact le_rfl . have:=ἴ.not.1 ‹_›;omega lemma qGv (e0:Ὠ) (w0 w1:ὥ) (h0:T_ok e0 w0=true) (h1:T_ok e0 w1=true) : (T_p e0 w1 (T_p e0 w0 0)).toNat<=2*(2^61-1)∧(T_n e0 w1 (T_n e0 w0 0)).toNat<=2*(2^61-1) ∧ ἂ w0+ἂ w1=(((T_p e0 w1 (T_p e0 w0 0)).toNat:ℚ) - (T_n e0 w1 (T_n e0 w0 0)).toNat)*2^((Ѧe0:Int)-150):=by obtain ⟨a1,a2,a3⟩:=qEn e0 w0 0 0 0 0 _ rfl (by norm_num1) h0 ג ג ג obtain ⟨b1,b2,b3⟩:=qEn e0 w1 _ _ _ _ _ rfl (by norm_num1) h1 a1 a2 a3 rw[zero_add] at b3 exact ⟨by (exact Nat.le_trans ‹_› (by decide)),by (exact Nat.le_trans ‹_› (by decide)),b3⟩ lemma qF4 (e0:Ὠ) (w0 w1:ὥ) (p n:Ὠ) (V:ℚ) (hp:Ѧp<=2*(2^61-1)) (hn:Ѧn<=2*(2^61-1)) (hV:V=((Ѧp:ℚ)-Ѧn)*2^((Ѧe0:Int)-150)) (h0:T_ok e0 w0=true) (h1:T_ok e0 w1=true) : (T_p e0 w1 (T_p e0 w0 p)).toNat<2^63∧(T_n e0 w1 (T_n e0 w0 n)).toNat<2^63 ∧ V+ἂ w0+ἂ w1=(((T_p e0 w1 (T_p e0 w0 p)).toNat:ℚ) - (T_n e0 w1 (T_n e0 w0 n)).toNat)*2^((Ѧe0:Int)-150):=by obtain ⟨a1,a2,a3⟩:=qEn e0 w0 p n V _ _ rfl (by norm_num1) h0 hp hn hV obtain ⟨b1,b2,b3⟩:=qEn e0 w1 _ _ _ _ _ rfl (by norm_num1) h1 a1 a2 a3 exact ⟨by (exact Nat.lt_of_le_of_lt ‹_› (by decide)),by (exact Nat.lt_of_le_of_lt ‹_› (by decide)),b3⟩ lemma qCi (e0:Ὠ) (w:ὥ) (h:T_ok e0 w=true):expOf w≠255:=by unfold T_ok at h;simp only[and_eq_true] at h;exact qAc w h.1 end @[noinline] def addSlow (relu:Ὡ) (x y:Ὢ):Ὢ := act relu (toWord (FloatLib.Floats.Formats.BinaryInterchange.Model.add (ofW x) (ofW y))) section open Float.Model Float.Model.UnpackedFloat end @[inline] def E_act (relu:Ὡ) (r:ὥ):ὥ := if relu && signOf r then 0 else r @[inline] def addOne (relu:Ὡ) (x y:Ὢ):Ὢ := if expOf x != 255 && expOf y != 255 then let r:=(Float32.ofBits x+Float32.ofBits y).toBits if expOf r != 255 then E_act relu r else act relu r else addSlow relu x y section lemma qJe (A P Q T g:Ὣ) (hg:g=0∨g=2^63) (ha:A<2^64) (e1:(A+2)%2^64=g+P) (e2:(2^64-2+A)%2^64=g+Q) (t1:2^61<=T) (t2:T<2^63-2^60) (l1:T< P+2^28) (u1:P<=T+2^28) (l2:T< Q+2^28) (u2:Q<=T+2^28) : A=g+(Q+2)∧T+2< Q+2+2^28∧Q+2+2<=T+2^28:=by (clear hg t1 t2; exact omS471 ha e1 e2 l1 u1 l2 u2) lemma qJg (G f F:Ὣ) (hl:G+f+2< G+F+2^28) (hu:G+F+2<=G+f+2^28) : F+2<=f+2^28∧f+2< F+2^28:=by exact omS472 hl hu lemma qEw (s:ὧ) (h:zivS s≠Е) : ∃ (S:Ὡ) (ex fr M:Ὣ),897<=ex∧ex<1151∧fr<2^23 ∧ zivS s=ὺ ((if S then 2^31 else 0)+(ex-896)*2^23+fr) ∧ s.toBits.toNat=(if S then 2^63 else 0)+M ∧ (ex*2^23+fr)*2^29+2< M+2^28 ∧ M+2<=(ex*2^23+fr)*2^29+2^28:=by obtain ⟨S,ex,fr,h1,h2,h3,hz,⟨P,e1,l1,u1⟩,⟨Q,e2,l2,u2⟩⟩:=qCg _ _ h rw[ἤ] at e1 rw[ὲ] at e2 obtain ⟨a,b,c⟩:=qJe _ P Q ((ex*2^23+fr)*2^29) _ (by cases S<;>simp) s.toBits.toNat_lt e1 e2 (by clear h hz e1 l1 u1 e2 l2 u2; exact omS232 h1) (by clear h hz e1 l1 u1 e2 l2 u2; exact omS233 h2 h3) l1 u1 l2 u2 exact ⟨S,ex,fr,Q+2,h1,h2,h3,hz,a,b,c⟩ lemma qJd (v W z u:ℝ) (hu:0< u) (hz:z<=u) (h0:0<=v) (hv:v<=2^53*u) (h : |v-W| ≤ 1/2^53*(|W| + z)):v-2*u< W∧W< v+2*u:=by have h1 : |W| ≤ v + |v-W|:=by have:=Ἐ (v-(v-W)) (-(v-W)+(v-W));have e:W=v-(v-W):=by ring have a:=Ὥ W v;rw[abs_sub_comm W v,ἅ h0] at a;linarith only [a] have h2:=abs_lt.mp (show |v-W| < 2*u by linarith);constructor<;>linarith [h2.1,h2.2] set_option maxRecDepth 8192 in lemma qJq (ex fr E F:Ὣ) (h1:897<=ex) (h2:ex<1151) (hfr:fr<2^23) (hF:F<2^52) (hl:(ex*2^23+fr)*2^29+2< E*2^52+F+2^28) (hu:E*2^52+F+2<=(ex*2^23+fr)*2^29+2^28) (W:ℝ) (h : |((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-W| ≤ 1/2^53*(|W| + A_z)) : W<(2^53+fr*2^30+2^29)*2^((ex:Int)-1076) ∧ (fr≠0->(2^53+fr*2^30-2^29)*2^((ex:Int)-1076)< W) ∧ (2^53-2^28)*2^((ex:Int)-1076)< W:=by have hE:E=ex∨(E+1=ex∧fr=0) :=(by clear h1 h2; exact omS473 hfr hF hl hu) have hu0:(0:ℝ)<2^((E:Int)-1075):=ἵ (by positivity) _ have hz:A_z<=2^((E:Int)-1075):=by have e:A_z=2^(-1021:ℤ):=rfl rw[e] exact ἒ (by norm_num1) (by clear hE; exact omS474 h1 hF hl) have hN:((2^52+F:Ὣ):ℝ)<=2^53:=by have:2^52+F<=2^53 :=(by clear h1 h2 hfr hl hu hE; exact omS236 hF) exact_mod_cast this have hN0:(0:ℝ)<=((2^52+F:Ὣ):ℝ):=Ἔ _ obtain ⟨a,b⟩:=qJd _ W A_z _ hu0 hz (Ἆ hN0 hu0.le) (ἀ hN hu0.le) h push_cast at a b rcases hE with rfl | ⟨rfl,rfl⟩ . have e:(2:ℝ)^((E:Int)-1075)=2*2^((E:Int)-1076):=by rw[show (E:Int)-1075=1+((E:Int)-1076) by ring,Ἓ ἓ,zpow_one] rw[e] at a b;have hb:(0:ℝ)<2^((E:Int)-1076):=ἵ (by positivity) _;generalize (2:ℝ)^((E:Int)-1076)=c at a b hb ⊢;have e1:(E*2^23+fr)*2^29=E*2^52+fr*2^29:=by ring rw[e1] at hl hu;obtain ⟨n3,n4⟩:=qJg _ _ _ hl hu;have h3:(F:ℝ)+2<=fr*2^29+2^28:=by exact_mod_cast n3 have h4:(fr:ℝ)*2^29+2< F+2^28:=by exact_mod_cast n4 have h5:(0:ℝ)<=F:=Ἔ _;have h7:=ἀ h3 hb.le;have h8:=Ἦ h4 hb;have h9:=Ἆ h5 hb.le;refine ⟨?_,?_,?_⟩;. linarith only [b,h7] . intro _;linarith only [a,h8] . linarith only [a,h9,hb] . have e:(2:ℝ)^(((E+1:Ὣ):Int)-1076)=2^((E:Int)-1075):=by congr 1;push_cast;ring rw[e];generalize (2:ℝ)^((E:Int)-1075)=c at a b hu0 ⊢;have h3:(F:ℝ)<=2^52:=by exact_mod_cast hF.le have h4:(2:ℝ)^52+2< F+2^28:=by exact_mod_cast (by (clear h1 h2 hfr; exact omS475 hl):2^52+2< F+2^28) have h7:=ἀ h3 hu0.le;have h8:=Ἦ h4 hu0;refine ⟨?_,?_,?_⟩;. rw[Nat.cast_zero,zero_mul,add_zero];linarith only [b,h7,hu0] . intro h0;exact absurd rfl h0 . linarith only [a,h8] lemma qEz (s:ὧ) (d:FloatLib.Numerics.Dyadic) (hV : |R s-(d.toRat:ℝ)| ≤ 1/2^53*(|(d.toRat:ℝ)| + A_z)) (h:zivS s≠Е):zivS s=toWord (ἕ Fmt d):=by obtain ⟨S,ex,fr,M,h1,h2,h3,hz,hb,hl,hu⟩:=qEw s h;have hM:M=(M/2^52)*2^52+M%2^52 :=(by clear h h1 h2 h3 hz hb hl hu; exact omS114);have hF:M%2^52<2^52:=ὀ _ (by positivity);generalize M/2^52=E at hM;generalize M%2^52=F at hM hF;subst hM;obtain ⟨-,hR⟩:=B_R s S E F (by clear h hz; exact omS476 h1 hF hl) (by clear h hz; exact omS477 h2 h3 hu) hF (by rw[hb,ὢ]);rw[hR] at hV obtain ⟨W,hVW,hW⟩:∃ W:ℝ,(d.toRat:ℝ)=(if S then -W else W) ∧ |((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-W| ≤ 1/2^53*(|W| + A_z):=by cases S . simp only[false_eq_true,ite_false,one_mul] at hV ⊢;exact ⟨_,rfl,hV⟩ . simp only[ite_true] at hV ⊢;refine ⟨-(d.toRat:ℝ),by simp,?_⟩;rw[abs_neg,show ((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075) - -(d.toRat:ℝ) =-(-1*((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-(d.toRat:ℝ)) by ring,abs_neg];exact hV obtain ⟨a,b,c⟩:=qJq ex fr E F h1 h2 h3 hF (by exact omS478 hl) (by exact omS479 hu) W hW;rw[hz];exact (qDh d S ex fr h1 h2 h3 W hVW a b c).symm lemma qE7 (w:ὥ) (hg:good w=true) : ∃ (m k:ℤ),wv w=(m:ℝ)*2^k∧m.natAbs<2^25∧-160<=k:=by have hN:=w.toNat_lt;rw[qBe w hg];unfold A_mag;by_cases h0:ѥw%2^31=0;. exact ⟨0,0,by rw[ἱ h0];simp,by (positivity),by (norm_num1)⟩ . simp only[h0,ite_false];have hk:-160<=(((ѥw%2^31/2^23:ℕ):ℤ)-150) :=(by clear hN h0; exact omS480);have hM:2^23+ѥw%2^31%2^23<2^25 :=(by clear hN h0 hk; exact omS481);generalize ((ѥw%2^31/2^23:ℕ):ℤ)-150=k at hk ⊢;generalize 2^23+ѥw%2^31%2^23=M at hM ⊢;by_cases hs:2^31<=ѥw;. exact ⟨-(M:ℤ),k,by rw[ἱ hs];push_cast;ring,by simpa using hM,hk⟩ . exact ⟨(M:ℤ),k,by rw[ἐ hs];push_cast;ring,by simpa using hM,hk⟩ lemma qHw (a b:ὥ) (ha:good a=true) (hb:good b=true) : (dv a*dv b).isFinite=true∧R (dv a*dv b)=wv a*wv b:=by obtain ⟨fa,ra⟩:=qAs a ha;obtain ⟨fb,rb⟩:=qAs b hb;have la:=(qAh a ha).trans qAe;have lb:=(qAh b hb).trans qAe obtain ⟨h1,h2⟩:=qD7 _ _ fa fb (by rw[ra,rb] exact (ἑ la lb (Ἀ _) qJ0.le).trans qDi) refine ⟨h1,?_⟩;obtain ⟨m,k,e1,h3,h4⟩:=qE7 a ha;obtain ⟨n,l,e2,h5,h6⟩:=qE7 b hb;have e:wv a*wv b=((m*n:ℤ):ℝ)*2^(k+l):=by rw[e1,e2,Ἓ ἓ];push_cast;ring rw[h2,ra,rb,e];refine qAt _ _ ?_ (by clear h3 h5; exact omS482 h4 h6);rw[Int.natAbs_mul];have:=Nat.mul_lt_mul'' h3 h5;(exact Nat.lt_of_lt_of_le ‹_› (by decide)) lemma S_E (x y z:ὥ) (hx:good x=true) (hy:good y=true) (hz:good z=true) (d:FloatLib.Numerics.Dyadic) (hd:(d.toRat:ℝ)=wv x*wv y+wv z) : |R (dv x*dv y+dv z)-(d.toRat:ℝ)| ≤ 1/2^53*(|(d.toRat:ℝ)| + A_z):=by obtain ⟨f1,r1⟩:=qHw x y hx hy obtain ⟨-,-,l⟩:=qEv x y hx hy obtain ⟨f2,r2⟩:=qAs z hz have h256:(2:ℝ)^256<=A_B:=by have:(2:ℝ)^256<=2^256*2^42 :=(by norm_num1) linarith [qBl] obtain ⟨-,he⟩:=qA4 _ _ f1 f2 (by rw[r1];exact l.trans h256) (by rw[r2];exact (qAh z hz).trans qAe) rw[r1,r2] at he rw[hd] exact he lemma qDx (relu:Ὡ) (r:ὥ) (hf:expOf r≠255):E_act relu r=act relu r:=by cases relu<;>simp[E_act,act,reluW,hf,signOf] lemma qGg (relu:Ὡ) (s:ὧ) (h:zivS s≠Е) : E_act relu (zivS s)=act relu (zivS s):=by apply qDx;obtain ⟨S,ex,fr,h1,h2,h3,hz,-,-⟩:=qCg _ _ h;have hz':zivS s=_:=hz;intro h0;have h4:(expOf (zivS s)).toNat=255:=by rw[h0];rfl rw[qAx,hz',ὡ] at h4;split at h4<;>(clear h hz hz' h0; omega) lemma qAr (z:Model FloatFormat.binary32) : Ἑ z=(Model.toModel z).isFinite:=by have he:=Model.unpackExponent_toNat z;have ha:=Model.toNat_neg_one_exponentBits FloatFormat.binary32;have hm:Ἑ z=(Model.expField z != FloatFormat.expAllOnesNat FloatFormat.binary32):=rfl;rw[hm];unfold Model.toModel Float.Model.UnpackedFloat.unpack;simp only[];by_cases h:Float.Model.UnpackedFloat.unpackExponent (spec:=FloatFormat.toModel FloatFormat.binary32) (Model.toModelBits z)=-BitVec.ofNat _ 1 . rw[ἱ h];have h2:Model.expField z=FloatFormat.expAllOnesNat FloatFormat.binary32:=by rw[<-he,h,ha] rw[h2];split<;>rfl . rw[ἐ h];have h2:Model.expField z≠FloatFormat.expAllOnesNat FloatFormat.binary32:=by intro h3;apply h;apply BitVec.eq_of_toNat_eq;rw[he,h3,<-ha] have h4:(Model.expField z != FloatFormat.expAllOnesNat FloatFormat.binary32)=true:=by simpa using h2 rw[h4];split;. split<;>rfl . rfl def m32 (f:Float32):Model FloatFormat.binary32:=Model.ofFloat32Model f.toModel lemma qDu (f:Float32):Ἑ (m32 f)=f.isFinite:=by rw[qAr];rfl lemma qG3 (y:Model FloatFormat.binary32) (h:Ἑ y=true):Model.IsModelCanonical y:=by refine ⟨λhe _=>?_⟩;have hf:=qAr y;rw[h] at hf;unfold Model.toModel Float.Model.UnpackedFloat.unpack at hf;simp only[] at hf;rw[ἱ he] at hf;split at hf<;>simp[Float.Model.UnpackedFloat.isFinite] at hf lemma qAz (w:Ὢ) (h:expOf w≠255):m32 (Float32.ofBits w)=ofW w:=by have hf:Ἑ (ofW w)=true:=by simp[ofW,isFinite_ofUInt32,h] rw[<-Model.canonicalizeModel_eq_self _ (qG3 _ hf)];unfold m32 Model.canonicalizeModel;change Model.ofFloat32Model (Float32.Model.pack _)=_;rw[Model.ofFloat32Model_pack];congr 1;unfold Model.toModel;congr 1;apply BitVec.eq_of_toNat_eq;simp[ofW,Model.ofUInt32,Model.ofNatBits,Model.toModelBits,Model.ofBits,FloatFormat.ofWordNat];show ѥw=ѥw%2^32;have:=w.toNat_lt;(clear h; omega) lemma qEi (f:Float32):f.toBits=toWord (m32 f):=by unfold toWord m32 Model.ofFloat32Model Model.ofModelBits Model.toNatBits;simp only[Float32.toBits];exact UInt32.ofNat_toNat.symm lemma qD2 (x y:Ὢ) (hx:expOf x≠255) (hy:expOf y≠255) : (Float32.ofBits x+Float32.ofBits y).toBits=toWord (Model.add (ofW x) (ofW y)):=by have hfx:Ἑ (ofW x)=true:=by simp[ofW,isFinite_ofUInt32,hx] have hfy:Ἑ (ofW y)=true:=by simp[ofW,isFinite_ofUInt32,hy] have fx:(Float32.ofBits x).isFinite=true:=by rw[<-qDu,qAz x hx];exact hfx have fy:(Float32.ofBits y).isFinite=true:=by rw[<-qDu,qAz y hy];exact hfy rw[qEi,show m32 (Float32.ofBits x+Float32.ofBits y) = Model.add (m32 (Float32.ofBits x)) (m32 (Float32.ofBits y)) from toModel_ofFloat32_add_of_isFinite _ _ fx fy,qAz x hx,qAz y hy] lemma qCs (relu:Ὡ) (x y:Ὢ) : addOne relu x y=act relu (toWord (Model.add (ofW x) (ofW y))):=by unfold addOne;split . rename_i hc;simp only[and_eq_true,bne_iff_ne,ne_eq] at hc;dsimp only;split;. rename_i h2;rw[qDx _ _ (by simpa using h2),qD2 x y hc.1 hc.2] . rw[qD2 x y hc.1 hc.2] . rfl lemma qE4 {L:ὦ->ѐ->ѐ} (f:ὦ->ὥ->ὥ) {e:ὦ} (hL:∀ i x,L i x=if i< e then L (i+1) (wrW x i (f i (rdW x i))) else x) (d:Ὣ) : ∀ (i:ὦ) (x:ѐ),Ѥi+d=Ѥe->Ѥe<=ѧx->ѧx<2^32 → (L i x).size=ѧx∧∀ q,(L i x)[q]! =if Ѥi<=q∧q< Ѥe then f (ὴ q) x[q]! else x[q]!:=by induction d with | zero => intro i x h1 _ _ rw[hL,ἐ (by rw[А];exact omS404 h1)] exact ⟨rfl,λq=>(ἐ (by exact omS483 h1)).symm⟩ | succ d ih => intro i x h1 h2 h3 have hi:i< e:=А.2 (by clear h2 h3; exact omS136 h1) have hs:=qAm x i (f i (rdW x i)) rw[hL,ἱ hi] obtain ⟨h4,h5⟩:=ih (i+1) (wrW x i (f i (rdW x i))) (by rw[usz i e hi];(clear h2 h3 hi hs; exact omS137 h1)) (by clear h1 h3 hi; exact omS484 h2 hs) (by clear h1 h2 hi; exact omS360 h3 hs) refine ⟨h4.trans hs,λq=>?_⟩ rw[h5,qAq _ _ _ _ h3 (by exact Nat.lt_of_lt_of_le ‹_› ‹_›),usz i e hi,qAo _ _ h3] by_cases h6:q=Ѥi . subst h6;rw[ἐ (by clear h1 h2 h3 hi hs h4; exact omS485),ἱ rfl,ἱ (by clear h2 h3 hi hs h4; exact omS486 h1),USize.ofNat_toNat] . rw[ἐ h6];exact if_congr (by clear h2 h3 hi hs h4; exact omS487 h6) rfl rfl def addGo (relu:Ὡ) (y:ё) (e i:ὦ) (x:ё) : ё := if h:i< e then addGo relu y e (i+1) (wrW x i (addOne relu (rdW x i) (rdW y i))) else x partial_fixpoint def addGu (relu:Ὡ) (y:ё) (e i:ὦ) (x:ё) (hx:ѧx=Ѥe) (hy:ѧy=Ѥe) : ё := if h:i< e then addGu relu y e (i+1) (x.uset i (addOne relu (x.uget i (hx ▸ А.mp h)) (y.uget i (hy ▸ А.mp h))) (hx ▸ А.mp h)) ((Array.size_uset ..).trans hx) hy else x partial_fixpoint lemma addGu_eq (relu:Ὡ) (y:ё) (e:ὦ) (k:Ὣ) : ∀ (i:ὦ) (x:ё) (hx:ѧx=Ѥe) (hy:ѧy=Ѥe),Ѥi+k=Ѥe → addGu relu y e i x hx hy=addGo relu y e i x:=by induction k with | zero=> intro i x hx hy h0 rw[addGu,addGo,ἔ (by rw[А];omega),ἔ (by rw[А];omega)] | succ k ih=> intro i x hx hy h0 have hi:i< e:=А.2 (by omega) have hxu:Ѥx.usize=ѧx:=by simp only[Array.usize,Nat.toUSize_eq,USize.toNat_ofNat'];exact Nat.mod_eq_of_lt (by rw[hx];exact e.toNat_lt_size) have hyu:Ѥy.usize=ѧy:=by simp only[Array.usize,Nat.toUSize_eq,USize.toNat_ofNat'];exact Nat.mod_eq_of_lt (by rw[hy];exact e.toNat_lt_size) have hi1:i< x.usize:=by rw[А,hxu,hx];exact А.mp hi have hi2:i< y.usize:=by rw[А,hyu,hy];exact А.mp hi rw[addGu,addGo,Ἄ hi,Ἄ hi,ih (i+1) _ (by rw[Array.size_uset];exact hx) hy (by rw[usz i e hi];omega)] unfold wrW rdW rw[Ἄ hi1,Ἄ hi2,Ἄ hi1] @[noinline] def addFb (relu:Ὡ) (a b:ё):ё:=Array.ofFn (n:=ѧa) λi=>addOne relu a[i] b[i.val]! def addF (relu:Ὡ) (a b:ё):ё := if h:ѧa=ѧb∧ѧa<=4294967295 then addGu relu b a.usize 0 a (by have:=h.2;simp only[Array.usize,Nat.toUSize_eq];exact (uk _ (by omega)).symm) (by have:=h.2;rw[<-h.1];simp only[Array.usize,Nat.toUSize_eq];exact (uk _ (by omega)).symm) else addFb relu a b lemma qFu:addF=addReluSpec:=by funext relu a b;unfold addF;split . rename_i h;obtain ⟨h1,h2'⟩:=h;have h2:ѧa<2^32:=(by omega);have hu:a.usize.toNat=ѧa:=qAa _ h2;rw[addGu_eq relu b a.usize ѧa 0 a _ _ (by rw[hu];simp)];have hg:=qE4 (L:=addGo relu b a.usize) (λi w=>addOne relu w (rdW b i)) (λ_ _=>by rw[addGo];rfl) ѧa 0 a (by rw[hu,show (0:ὦ).toNat=0 from rfl,Ἇ]) (by clear h2; (exact Nat.le_of_eq ‹_›)) h2;apply Մ (by rw[hg.1];simp[addReluSpec]);intro i h3 h4;have hi:i< ѧa:=by rwa [hg.1] at h3 rw[<-Ἕ _ i h3,hg.2 i,ἱ ⟨Nat.zero_le _,by (clear h2 h4 hi; omega)⟩,qCs,Ἕ a i hi,qAo _ _ (by clear h3 h4 hi; omega),uk i (by clear h4 hi; omega)];simp[addReluSpec] . simp only[addFb,addReluSpec,qCs] end section @[noinline] def E_fma (relu:Ὡ) (w sw tw:ὥ):ὥ := act relu (toWord (Model.fma (ofW w) (ofW sw) (ofW tw))) @[noinline] def E_fz (relu g:Ὡ) (sw tw:ὥ) (y z:ὧ) (w:ὥ):ὥ := if g && good w then let r:=zivS (dv w*y+z) if r == Е then E_fma relu w sw tw else E_act relu r else E_fma relu w sw tw @[inline] def E_el (relu g:Ὡ) (sw tw:ὥ) (y z:ὧ) (w:ὥ):ὥ := let a:=(dvN w*y+z).toBits let u:=a+0x0FFFFFFD if g && (a <<< (1:Ὠ))-0x7040000000000000<0x1F60000000000000 && u &&& 0x1FFFFFFF<0x1FFFFFFC then E_act relu (zivC (u >>> (29:Ὠ))) else E_fz relu g sw tw y z w @[specialize] def E_map (f:ὥ->ὥ) (e i:ὦ) (x:ѐ):ѐ := if h:i< e then E_map f e (i+1) (wrW x i (f (rdW x i))) else x partial_fixpoint @[specialize] def E_mU (f:ὥ->ὥ) (e i:ὦ) (x:ѐ) (he:Ѥe<=ѧx):ѐ := if h:i< e then E_mU f e (i+1) (x.uset i (f (x.uget i (Nat.lt_of_lt_of_le (А.mp h) he))) (Nat.lt_of_lt_of_le (А.mp h) he)) (by rw[Array.size_uset];exact he) else x partial_fixpoint lemma lcRU (a:ѐ) (i:ὦ) (h:Ѥi< ѧa) (hs:ѧa<2^32) : a.uget i h=rdW a i:=by have h2:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl unfold rdW;rw[Ἄ (А.mpr (by simp only[Array.usize,Nat.toUSize_eq,USize.toNat_ofNat'];rw[Nat.mod_eq_of_lt (by omega)];exact h))] lemma lcMU (f:ὥ->ὥ) (e:ὦ) (d:Ὣ) : ∀ (i:ὦ) (x:ѐ) (he:Ѥe<=ѧx),Ѥe-Ѥi=d->ѧx<2^32 → E_mU f e i x he=E_map f e i x:=by induction d using Nat.strong_induction_on with | _ d ih=> intro i x he hd hs rw[E_mU,E_map] by_cases h:i< e . rw[Ἄ h,Ἄ h] have e1:=usz i e h;have t:=А.mp h have hs':ѧ(x.uset i (f (x.uget i (Nat.lt_of_lt_of_le t he))) (Nat.lt_of_lt_of_le t he))<2^32:=by rw[Array.size_uset];exact hs rw[ih _ (by omega) (i+1) _ _ rfl hs',lcRU _ _ _ hs,lcWU _ _ _ _ hs] . rw[ἔ h,ἔ h] @[inline] def E_elTT (sw tw:ὥ) (y z:ὧ) (w:ὥ):ὥ:=E_el true true sw tw y z w @[inline] def E_elTF (sw tw:ὥ) (y z:ὧ) (w:ὥ):ὥ:=E_el true false sw tw y z w @[inline] def E_elFT (sw tw:ὥ) (y z:ὧ) (w:ὥ):ὥ:=E_el false true sw tw y z w @[inline] def E_elFF (sw tw:ὥ) (y z:ὧ) (w:ὥ):ὥ:=E_el false false sw tw y z w @[noinline] def E_mTT (sw tw:ὥ) (y z:ὧ) (e i:ὦ) (x:ѐ) (he:Ѥe<=ѧx):ѐ:=E_mU (E_elTT sw tw y z) e i x he @[noinline] def E_mTF (sw tw:ὥ) (y z:ὧ) (e i:ὦ) (x:ѐ) (he:Ѥe<=ѧx):ѐ:=E_mU (E_elTF sw tw y z) e i x he @[noinline] def E_mFT (sw tw:ὥ) (y z:ὧ) (e i:ὦ) (x:ѐ) (he:Ѥe<=ѧx):ѐ:=E_mU (E_elFT sw tw y z) e i x he @[noinline] def E_mFF (sw tw:ὥ) (y z:ὧ) (e i:ὦ) (x:ѐ) (he:Ѥe<=ѧx):ѐ:=E_mU (E_elFF sw tw y z) e i x he @[inline] def E_bnU (relu g:Ὡ) (sw tw:ὥ) (y z:ὧ) (e i:ὦ) (x:ѐ) (he:Ѥe<=ѧx):ѐ := if relu then (if g then E_mTT sw tw y z e i x he else E_mTF sw tw y z e i x he) else (if g then E_mFT sw tw y z e i x he else E_mFF sw tw y z e i x he) lemma lcBU (relu g:Ὡ) (sw tw:ὥ) (y z:ὧ) (e i:ὦ) (x:ѐ) (he:Ѥe<=ѧx) : E_bnU relu g sw tw y z e i x he=E_mU (E_el relu g sw tw y z) e i x he:=by cases relu<;>cases g<;>rfl def E_chs (relu:Ὡ) (c hw:Ὣ) (s t:ѐ) (ch:Ὣ) (x:ѐ):ѐ := if ch< c then let sw:=s[ch]! let tw:=t[ch]! let y:=dv sw let z:=dv tw E_chs relu c hw s t (ch+1) (if hE:Ѥ((ch+1)*hw).toUSize<=ѧx then E_bnU relu (good sw && good tw) sw tw y z ((ch+1)*hw).toUSize (ch*hw).toUSize x hE else E_map (E_el relu (good sw && good tw) sw tw y z) ((ch+1)*hw).toUSize (ch*hw).toUSize x) else x partial_fixpoint def scaleF (relu:Ὡ) (c hw:Ὣ) (x s t:ѐ):ѐ := if ѧx=c*hw∧ѧx<=4294967295 then E_chs relu c hw s t 0 x else scaleShiftSpec relu c hw x s t @[noinline] def E_dot (X:ѐ) (b:ὦ) (k w:Ὣ):ὥ := dotFn (k*k) (λt=>X[Ѥb+(t/k*w+t%k)]!) (λ_=>oneW) section open Float.Model Float.Model.UnpackedFloat def E_dotT (X:ѐ) (b:ὦ) (k w:Ὣ):ὥ := if k=2 then let i:=Ѥb let a0:=X[i]! let a1:=X[i+1]! let a2:=X[i+w]! let a3:=X[i+(w+1)]! let e0:=T_min (T_min (T_e a0) (T_e a1)) (T_min (T_e a2) (T_e a3)) if T_ok e0 a0 && T_ok e0 a1 && T_ok e0 a2 && T_ok e0 a3 then T_fin (T_p e0 a3 (T_p e0 a2 (T_p e0 a1 (T_p e0 a0 0)))) (T_n e0 a3 (T_n e0 a2 (T_n e0 a1 (T_n e0 a0 0)))) e0 λ_=>E_dot X b k w else E_dot X b k w else E_dot X b k w lemma qE9 (X:ѐ) (b:ὦ) (k w:Ὣ):E_dotT X b k w=E_dot X b k w:=by unfold E_dotT;split;swap;rfl;subst_vars;dsimp only;split;swap;rfl;rename_i hc;simp at hc;obtain ⟨⟨⟨h0,h1⟩,h2⟩,h3⟩:=hc;obtain ⟨p1,n1,v⟩:=qGv _ _ _ h0 h1;obtain ⟨p2,n2,v⟩:=qF4 _ _ _ _ _ _ p1 n1 v h2 h3;refine qFy _ _ _ _ p2 n2 ((qC5 _ _).trans ((qC5 _ _).trans (qHq _))) _ rfl λe=>?_;have B:=qBa (2*2) (λj=>X[Ѥb+(j/2*w+j%2)]!) (λ_=>oneW) λj g =>⟨by interval_cases j<;>simp[qCi _ _ h0,qCi _ _ h1,qCi _ _ h2,qCi _ _ h3],by decide⟩;simp[Finset.sum_range_succ,qGk] at B;rw[v] at B;rw[E_dot,qAg];exact B (mul_ne_zero (sub_ne_zero.2 λh=>e (UInt64.toNat_inj.1 (Nat.cast_injective h))) (zpow_ne_zero _ ἓ)) end def E_dq (n:Ὣ) (s:ὥ):ὥ := if 1< n∧n<=144∧n.sqrt*n.sqrt=n∧expOf s≠255∧expOf s≠0 then let d:=dv s let r:=ziv (d*(((0x20000000000000:Ὠ)/n.toUInt64).toFloat*Ἃ 0x3CA0000000000000)) (d.abs*Ἃ 0x3CC0000000000000) if r == Е then E_div n s else r else E_div n s @[inline] def E_quo (n:Ὣ) (j s:ὥ):ὥ := if j< expOf s∧expOf s≠255 then s-(j <<< (23:ὥ)) else E_dq n s @[inline] def E_tl (X:ѐ) (b:ὦ) (k w n:Ὣ) (j z:ὥ) (nf zb s a:ὧ) (o:ὥ):ὥ := if o=0 then z else let r:=ziv (s+zb) (nf*(a+zb.abs)) E_quo n j (if r == Е then E_dotT X b k w else r) def E_win (X off:ѐ) (k w n:Ὣ) (j z:ὥ) (u nf zb:ὧ) (b m t:ὦ) (s a:ὧ) (o:ὥ):ὥ := if h:t< m then let v:=rdW X (b+(rdW off t).toUSize) let d:=dv v*u E_win X off k w n j z u nf zb b m (t+1) (s+d) (a+d.abs) (o ||| v) else E_tl X b k w n j z nf zb s a o partial_fixpoint @[specialize] def G_x (f:ὦ->ὥ) (sx:ὦ) (W x:Ὣ) (b q:ὦ) (out:ѐ):ѐ := if x< W then G_x f sx W (x+1) (b+sx) (q+1) (wrW out q (f b)) else out partial_fixpoint @[specialize] def G_y (f:ὦ->ὥ) (sy sx:ὦ) (W H y:Ὣ) (b q:ὦ) (out:ѐ):ѐ := if y< H then G_y f sy sx W H (y+1) (b+sy) (q+ѩW) (G_x f sx W 0 b q out) else out partial_fixpoint @[specialize] def G_c (f:ὦ->ὥ) (sc sy sx:ὦ) (W H c ch:Ὣ) (b q:ὦ) (out:ѐ):ѐ := if ch< c then G_c f sc sy sx W H c (ch+1) (b+sc) (q+(H*W).toUSize) (G_y f sy sx W H 0 b q out) else out partial_fixpoint def E_off (k w:Ὣ):ѐ := Array.ofFn (n:=k*k) λt=>(t.val/k*w+t.val%k).toUInt32 @[noinline] def E_grid (c h w k n:Ὣ) (X off:ѐ) (j z:ὥ) (u nf zb zr:ὧ) : ѐ := G_c (λb=>E_win X off k w n j z u nf zb b ѩn 0 zr zr 0) (h*w).toUSize (k*w).toUSize ѩk (w/k) (h/k) c 0 0 0 (ἇ (c*(h/k*(w/k))) 0) @[inline] def E_w4 (X:ѐ) (k w n:Ὣ) (j z:ὥ) (u nf zb zr:ὧ) (a0 a1 a2 a3 b:ὦ):ὥ := let v0:=rdW X (b+a0) let d0:=dv v0*u let v1:=rdW X (b+a1) let d1:=dv v1*u let v2:=rdW X (b+a2) let d2:=dv v2*u let v3:=rdW X (b+a3) let d3:=dv v3*u E_tl X b k w n j z nf zb (zr+d0+d1+d2+d3) (zr+d0.abs+d1.abs+d2.abs+d3.abs) (0 ||| v0 ||| v1 ||| v2 ||| v3) @[inline] def E_w4u (X:ѐ) (k w n:Ὣ) (j z:ὥ) (nf zb zr:ὧ) (a0 a1 a2 a3 b:ὦ):ὥ := let v0:=rdW X (b+a0) let d0:=dv v0 let v1:=rdW X (b+a1) let d1:=dv v1 let v2:=rdW X (b+a2) let d2:=dv v2 let v3:=rdW X (b+a3) let d3:=dv v3 E_tl X b k w n j z nf zb (zr+d0+d1+d2+d3) (zr+d0.abs+d1.abs+d2.abs+d3.abs) (0 ||| v0 ||| v1 ||| v2 ||| v3) lemma qW4u (X:ѐ) (k w n:Ὣ) (j z:ὥ) (nf zb zr:ὧ) (a0 a1 a2 a3 b:ὦ) : E_w4u X k w n j z nf zb zr a0 a1 a2 a3 b=E_w4 X k w n j z (dv oneW) nf zb zr a0 a1 a2 a3 b:=by unfold E_w4u E_w4;simp only[D.qM1 _ (D.qDvF _)] @[noinline] def E_gridK (c h w k n:Ὣ) (X off:ѐ) (j z:ὥ) (u nf zb zr:ὧ) : ѐ := if k == 2 then let a0:=(rdW off 0).toUSize let a1:=(rdW off (0+1)).toUSize let a2:=(rdW off (0+1+1)).toUSize let a3:=(rdW off (0+1+1+1)).toUSize G_c (λb=>E_w4 X k w n j z u nf zb zr a0 a1 a2 a3 b) (h*w).toUSize (k*w).toUSize ѩk (w/k) (h/k) c 0 0 0 (ἇ (c*(h/k*(w/k))) 0) else E_grid c h w k n X off j z u nf zb zr def E_winC (X:ѐ) (k w n:Ὣ) (j z:ὥ) (u nf zb:ὧ) (b m t:ὦ) (s a:ὧ) (o:ὥ):ὥ := if h:t< m then let v:=rdW X (b+t) let d:=dv v E_winC X k w n j z u nf zb b m (t+1) (s+d) (a+d.abs) (o ||| v) else E_tl X b k w n j z nf zb s a o partial_fixpoint @[noinline] def E_gridC (c h w k n:Ὣ) (X:ѐ) (j z:ὥ) (u nf zb zr:ὧ) : ѐ := G_c (λb=>E_winC X k w n j z u nf zb b ѩn 0 zr zr 0) (h*w).toUSize (k*w).toUSize ѩk (w/k) (h/k) c 0 0 0 (ἇ (c*(h/k*(w/k))) 0) def A_x (X:ѐ) (w:Ὣ) (wu:ὦ) (u nf zb zr:ὧ) (b q e:ὦ) (out:ѐ):ѐ := if h:q< e then A_x X w wu u nf zb zr (b+2) (q+1) e (wrW out q (E_w4u X 2 w 4 2 0 nf zb zr 0 1 wu (wu+1) b)) else out partial_fixpoint def A_y (X:ѐ) (w:Ὣ) (wu:ὦ) (u nf zb zr:ὧ) (W H y:Ὣ) (b q:ὦ) (out:ѐ):ѐ := if y< H then A_y X w wu u nf zb zr W H (y+1) (b+wu+wu) (q+ѩW) (A_x X w wu u nf zb zr b q (q+ѩW) out) else out partial_fixpoint def A_c (X:ѐ) (w:Ὣ) (wu:ὦ) (u nf zb zr:ὧ) (sc:ὦ) (W H c ch:Ὣ) (b q:ὦ) (out:ѐ):ѐ := if ch< c then A_c X w wu u nf zb zr sc W H c (ch+1) (b+sc) (q+(H*W).toUSize) (A_y X w wu u nf zb zr W H 0 b q out) else out partial_fixpoint @[noinline] def E_grid2 (c h w:Ὣ) (X:ѐ) (u nf zb zr:ὧ):ѐ := A_c X w ѩw u nf zb zr (h*w).toUSize (w/2) (h/2) c 0 0 0 (ἇ (c*(h/2*(w/2))) 0) def E_gridX (c h w k n:Ὣ) (X:ѐ) (j z:ὥ) (u nf zb zr:ὧ):ѐ := if k=w then E_gridC c h w k n X j z u nf zb zr else if k=2∧w<2^31∧c*(h/2*(w/2))<=4294967295 then E_grid2 c h w X u nf zb zr else E_gridK c h w k n X (E_off k w) j z u nf zb zr def avgF (c h w k:Ὣ) (X:ѐ):ѐ := if c*h*w<=ѧX∧ѧX<=4294967295∧k*k<2^20 ∧ scan X X.usize 0 (qAd X) Е 0≠Е then let n:=k*k let j:ὥ:=if n=4 then 2 else if n=64 then 6 else 255 let z:ὥ:=if 0< k∧k<13 then 0 else E_div n (dotFn n (λ_=>0) (λ_=>oneW)) E_gridX c h w k n X j z (dv oneW) (nfOf n) (dv 0) D.fz0 else avgpoolSpecO c h w k X def E_d (x y z:ὥ):FloatLib.Numerics.Dyadic := Model.addDyadic ⟨Bool.xor (decodeD x).negative (decodeD y).negative, (decodeD x).significand*(decodeD y).significand, (decodeD x).exponent+(decodeD y).exponent⟩ (decodeD z) section variable (x y z:ὥ) (hx:expOf x≠255) (hy:expOf y≠255) (hz:expOf z≠255) include x y z hx hy hz lemma qC7 : Model.fma (ofW x) (ofW y) (ofW z)=ἕ Fmt (E_d x y z):=by rw[Model.Proof.fma_eq_spec];have e:=ἶ x hx;have f:=ἶ y hy;have g:=ἶ z hz;simp[Model.Spec.fma,ofW,(Model.chooseNaN3_eq_none_iff _ _ _).2 ⟨Model.isNaN_eq_false_of_toDyadic?_some e,Model.isNaN_eq_false_of_toDyadic?_some f,Model.isNaN_eq_false_of_toDyadic?_some g⟩,Model.isInf_eq_false_of_toDyadic?_some e,Model.isInf_eq_false_of_toDyadic?_some f,Model.isInf_eq_false_of_toDyadic?_some g,e,f,g];rfl lemma qDv : ((E_d x y z).toRat:ℝ)=wv x*wv y+wv z:=by have j:=mul_toRat (decodeD x) (decodeD y);simp only[FloatLib.Numerics.Dyadic.mul,mulFields] at j;rw[E_d,Model.addDyadic,add_toRat,j,qA6 x hx,qA6 y hy,qA6 z hz];simp[rationalWord] end section open Float.Model Float.Model.UnpackedFloat lemma qGe (i:ὦ) (h:Ѥi< ѨpwN):pwN.uget i h=pwEntryN Ѥi:=by simp[FloatArray.uget,qDg] def N_ok (w:ὥ):Prop:=0x800000<=w &&& В∧w &&& В<У lemma qHr {w:ὥ} (h:N_ok w):good w=true :=qBo _ (Or.inr h.1) h.2 lemma N_w (w:ὥ) (h:(pwN.uget (w >>> (23:ὥ)).toUSize (qCl w))ᶠ) : pwN.uget (w >>> (23:ὥ)).toUSize (qCl w)=pw.uget (w >>> (23:ὥ)).toUSize (qB4 w) ∧ N_ok w:=by have s:=qEc w rw[qGe,ὃ,s] at h rw[qGe,qC2,ὃ,s] unfold pwEntryN at h ⊢ have e:=qA0 w have g:=w.toNat_lt by_cases c:(ѥw/2^23%256 == 0 || ѥw/2^23%256 == 255)=true . rw[ἱ c,qI6] at h;exact absurd h ה . rw[ἐ c];simp only[or_eq_true,beq_iff_eq,not_or] at c;refine ⟨rfl,?_,?_⟩;. rw[ἃ,e,show (0x800000:ὥ).toNat=0x800000 from rfl];(clear s g; exact omS488 c) . rw[ἳ,e,show (У:ὥ).toNat=У from rfl];(clear s g; exact omS489 c) lemma qJy {w:ὥ} (h:(dvN w)ᶠ):dvN w=dv w∧N_ok w:=by obtain ⟨e,o⟩:=N_w w (qGl _ _ h).2;exact ⟨by unfold dvN dv;rw[e],o⟩ end lemma S_w (T M:Ὣ) (h1:T+2< M+2^28) (h2:M+2<=T+2^28) : T< M+2^28∧M<=T+2^28:=by exact omS490 h1 h2 lemma qIx (s:ὧ) (h:zivS s≠Е):s.isFinite=true:=by obtain ⟨S,ex,fr,M,h1,h2,h3,-,hb,hl,hu⟩:=qEw s h;exact (qAk _ S ex fr h1 h2 h3 ⟨M,hb,(S_w _ _ hl hu).1,(S_w _ _ hl hu).2⟩).1 section variable (relu g:Ὡ) (sw tw w:ὥ) (hg:g=true->good sw=true∧good tw=true) include relu g sw tw w hg lemma qGu : E_fz relu g sw tw (dv sw) (dv tw) w=E_fma relu w sw tw:=by unfold E_fz;split;swap;rfl;rename_i hc;obtain ⟨h1,h2⟩:=ὕ.1 hc;obtain ⟨h3,h4⟩:=hg h1;dsimp only;split;rfl;rename_i hr;have r:=mt beq_iff_eq.2 hr;have hf:=qAc _ h2;have g1:=qAc _ h3;have g2:=qAc _ h4;rw[qGg _ _ r,qEz _ (E_d w sw tw) (S_E w sw tw h2 h3 h4 _ (qDv _ _ _ hf g1 g2)) r,E_fma,qC7 _ _ _ hf g1 g2] lemma qHa : E_el relu g sw tw (dv sw) (dv tw) w=E_fma relu w sw tw:=by unfold E_el;dsimp only;split;. rename_i hc;obtain ⟨hA,h9⟩:=ὕ.1 hc;obtain ⟨h1,h8⟩:=ὕ.1 hA;obtain ⟨h3,h4⟩:=hg h1;obtain ⟨e9,hr0⟩:=qIf (dvN w*dv sw+dv tw) (by simpa using h8) (by simpa using h9);rw[<-e9];obtain ⟨e,o⟩:=qJy (qGl _ _ (qIu _ _ (qIx _ hr0)).1).1;rw[e] at hr0 ⊢;have hr':=hr0;have h2:=qHr o;have hf:=qAc _ h2;have g1:=qAc _ h3;have g2:=qAc _ h4;rw[qGg _ _ hr',qEz _ (E_d w sw tw) (S_E w sw tw h2 h3 h4 _ (qDv _ _ _ hf g1 g2)) hr',E_fma,qC7 _ _ _ hf g1 g2] . exact qGu relu g sw tw w hg end lemma qEh (relu:Ὡ) (c hw:Ὣ) (s t:ѐ) (d:Ὣ) : ∀ (ch:Ὣ) (x:ѐ),ch+d=c->ѧx=c*hw->ѧx<2^32 → (E_chs relu c hw s t ch x).size=ѧx∧∀ q,q< c*hw → (E_chs relu c hw s t ch x)[q]! =if ch*hw<=q then E_fma relu x[q]! s[q/hw]! t[q/hw]! else x[q]!:=by induction d with | zero => rintro ch x rfl _ _ rw[E_chs,ἐ (by exact omS491)] exact ⟨rfl,λq hq=>(ἐ (by simpa using hq)).symm⟩ | succ d ih => intro ch x h1 h2 h3 rw[E_chs,ἱ (by clear h2 h3; exact omS136 h1)] dsimp only have h4:=Ἒ hw ((by clear h2 h3; exact omS492 h1):ch+1<=c) have h5:=Nat.add_one_mul ch hw have e1:=qAa ((ch+1)*hw) (by clear h1; exact omS493 h2 h3 h4) have e0:=qAa (ch*hw) (by clear h1; exact omS494 h2 h3 h4 h5) rw[Ἄ (show Ѥ((ch+1)*hw).toUSize<=ѧx by rw[e1,h2];exact h4),lcBU,lcMU _ _ _ _ _ _ rfl h3] obtain ⟨h6,h7⟩:=qE4 (λ_=>E_el relu (good s[ch]! && good t[ch]!) s[ch]! t[ch]! (dv s[ch]!) (dv t[ch]!)) (L:=E_map _ ((ch+1)*hw).toUSize) (λ_ _=>by rw[E_map];rfl) hw (ch*hw).toUSize x (by clear h1 h2 h3 h4; omega) (by clear h1 h3 e0; omega) h3 obtain ⟨h8,h9⟩:=ih (ch+1) _ (by clear h2 h3 h4 h5 e1 e0 h6; omega) (h6.trans h2) (by clear h1 h4 h5 e1 e0; omega) refine ⟨h8.trans h6,λq hq=>?_⟩ rw[h9 q hq,h7,e0,e1,qHa _ _ _ _ _ ὕ.1] by_cases a:(ch+1)*hw<=q . rw[ἱ a,ἐ (by clear h1 h2 h3 h4 e0 h6 h8 hq; omega),ἱ (by clear h1 h2 h3 h4 h6 h8 hq; omega)] . rw[ἐ a];by_cases b:ch*hw<=q;. rw[ἱ (by clear h1 h2 h3 h4 h6 h8 hq; omega),ἱ b,Nat.div_eq_of_lt_le b (by clear h1 h2 h3 h4 e0 h6 h8 hq b; omega)] . rw[ἐ (by clear h1 h2 h3 h4 h6 h8 hq a; omega),ἐ b] lemma qFf:scaleF=scaleShiftSpec:=by funext relu c hw x s t;unfold scaleF;split . rename_i h;obtain ⟨h1,h2⟩:=h;replace h2:=Nat.lt_of_le_of_lt h2 (show 4294967295<2^32 by norm_num);obtain ⟨h3,h4⟩:=qEh relu c hw s t c 0 x (by clear h1 h2; omega) h1 h2;apply Մ;. simp[scaleShiftSpec,h3,h1] . intro i hi hj;have hi':i< c*hw:=by rwa [h3,h1] at hi rw[<-Ἕ _ i hi,h4 i hi',ἱ ג];simp[scaleShiftSpec,E_fma] . rfl lemma qBp (w:ὥ) (h:expOf w≠255) : Ἢ (ofW w)=(sv w:ℝ)*2^((idxOf w:ℤ)-149):=by simp[show Model.toReal (ofW w)=wv w from rfl,qA6 w h,rationalWord,decodeD_toRat] lemma qI3 (s j:ὥ) (hj:ѥj<=6) (a:ѥj<(expOf s).toNat) : (expOf (s-(j <<< (23:ὥ)))).toNat=(expOf s).toNat-ѥj ∧ fracOf (s-(j <<< (23:ὥ)))=fracOf s ∧ signOf (s-(j <<< (23:ὥ)))=signOf s:=by rw[qAx] at a have hs:=s.toNat_lt have e:(j <<< (23:ὥ)).toNat=ѥj*2^23:=by rw[UInt32.toNat_shiftLeft,ὁ] exact Ἁ (by simp;omega) generalize j <<< (23:ὥ)=J at e ⊢ have d:=ὓ s J (by rw[ἃ,e];(clear e; omega)) rw[e] at d simp only[qAx,fracOf,<-UInt32.toNat_inj,qBt,qEx,d,decide_eq_decide] (clear e; omega) lemma qE2 (s y j:ὥ) (f:ѥj<=6) (a:expOf s≠255) (b:ѥj<(expOf s).toNat) (d:expOf y≠255) (g:signOf y=false) (e:mantOf y=2^23) (k:idxOf y=126+ѥj) : toWord (Model.div (ofW s) (ofW y))=s-(j <<< (23:ὥ)):=by have B:Model.isZero (ofW y)=false:=by rw[ofW,Model.isZero_eq_beq_zero_of_toDyadic?_some (ἶ y d),decodeD_sig_zero,e];decide obtain ⟨C,D,E⟩:=qI3 s j f b;generalize s-(j <<< (23:ὥ))=r at C D E ⊢;have N:=expOf_toNat_lt s;have O:=mt ἠ.1 a;simp at O;have l:expOf r≠255:=λh=>by simp[h] at C;(clear a d e D h; omega) have q:expOf r≠0:=λh=>by simp[h] at C;(clear f a d e D N O l h; omega) have t:expOf s≠0:=λh=>by simp[h] at b have x:Ἢ (ofW y)=2^ѥj:=by rw[qBp _ d,sv,g,e,k];push_cast;rw[show (126+ѥj-149:ℤ)=ѥj-23 by ring,ᾂ ἓ,Ἡ];field_simp;(norm_num1) have I:Ἢ (ofW r)=Ἢ (ofW s)/Ἢ (ofW y):=by rw[x,qBp _ l,qBp _ a,show sv r=sv s by unfold sv mantOf;rw[E,D,ἐ q,ἐ t],show (idxOf r:ℤ)=idxOf s-ѥj by unfold idxOf;rw[ἐ q,ἐ t,C];(clear a d e C D O l q t; omega),sub_right_comm,ᾂ ἓ,Ἡ,mul_div_assoc] have o:=qBi a;have u:=qBi d;have v:=qBi l;have z:=Model.isFinite_div_of_abs_div_le_posMaxFinite _ _ ה o u B (I ▸ Model.abs_toReal_le_posMaxFinite_of_isFinite _ v);have p:=Model.toReal_div_eq_roundAt _ _ ה u z;rw[<-I,Model.roundAt_toReal_eq _ v] at p;rw[Model.eq_of_toReal_eq_of_nonzero p (p ▸ qFm r q l),qAw] lemma qH5 {a b:ℝ} (h:a< b) : ∃ d:FloatLib.Numerics.Dyadic,a<(d.toRat:ℝ)∧(d.toRat:ℝ)< b:=by obtain ⟨n,hn⟩:=exists_pow_lt_of_lt_one (sub_pos.2 h) (one_half_lt_one:(1/2:ℝ)<1);have h2:(0:ℝ)<2^n:=by positivity have hm1:a*2^n<((⌊a*2^n⌋+1:ℤ):ℝ):=by push_cast;exact Int.lt_floor_add_one _ have hm2:((⌊a*2^n⌋+1:ℤ):ℝ)<=a*2^n+1:=by have:=Int.floor_le (a*2^n);push_cast;linarith only [this] generalize (⌊a*2^n⌋+1:ℤ)=m at hm1 hm2;refine ⟨⟨decide (m<0),m.natAbs,-(n:ℤ)⟩,?_⟩ have e:((⟨decide (m<0),m.natAbs,-(n:ℤ)⟩:FloatLib.Numerics.Dyadic).toRat:ℝ)=m/2^n:=by rw[Ἠ,FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.cast_signedSignificand,zpow_neg,Ἡ];by_cases g:m<0 . have c:(m.natAbs:ℝ)=-(m:ℝ):=by rw[Nat.cast_natAbs,abs_of_neg g,Int.cast_neg] simp only[g,decide_true,ite_true,c];ring . have c:(m.natAbs:ℝ)=(m:ℝ):=by rw[Nat.cast_natAbs,ἅ (not_lt.1 g)] simp only[g,decide_false,false_eq_true,ite_false,c];ring rw[e];constructor;. rwa [lt_div_iff₀ h2] . rw[div_lt_iff₀ h2];have u:(1/2:ℝ)^n*2^n=1:=by rw[<-mul_pow];norm_num have:=Ἦ hn h2;rw[sub_mul,u] at this;linarith only [this, hm2] lemma qHx (q e:ὧ) (x y:Model Fmt) (hlo:R (q-e)< Ἢ x/Ἢ y) (hhi:Ἢ x/Ἢ y< R (q+e)) (h:ziv q e≠Е) (hx:Ἑ x=true) (hy:Ἑ y=true) (hy0:Model.isZero y=false) (hb : |Ἢ x/Ἢ y| ≤ Ἢ (Model.posMaxFinite Fmt)) : toWord (Model.div x y)=ziv q e:=by generalize hV:Ἢ x/Ἢ y=V at hlo hhi hb;obtain ⟨d1,a1,a2⟩:=qH5 hlo;obtain ⟨d2,b1,b2⟩:=qH5 hhi;have w1:=qEa q e d1 a1 (a2.trans hhi) h;have w2:=qEa q e d2 (hlo.trans b1) b2 h;obtain ⟨S,ex,fr,W,h1,h2,h3,hz,-⟩:=qDd q e V hlo hhi h;generalize ziv q e=r at w1 w2 hz ⊢;have l:(expOf r).toNat=ex-896:=by rw[qAx,hz,ὡ];cases S<;>simp only[false_eq_true,ite_true,ite_false]<;>(norm_num1)<;>(clear h w1 w2 hz; omega) have n255:expOf r≠255:=λg=>by rw[g] at l;simp at l;(clear h h3 w1 w2 hz g; omega) have n0:expOf r≠0:=λg=>by rw[g] at l;simp at l;(clear h h3 w1 w2 hz n255 g; omega) have f:=qBi n255;have m1:ἕ Fmt d1=ofW r:=by rw[w1,qAy] have m2:ἕ Fmt d2=ofW r:=by rw[w2,qAy] have t1:=Model.toReal_roundDyadic_eq_roundAt Fmt ה d1 (m1 ▸ f);have t2:=Model.toReal_roundDyadic_eq_roundAt Fmt ה d2 (m2 ▸ f);rw[m1] at t1;rw[m2] at t2;rw[Ἠ] at a2 b1;have c1:=Model.roundAt_mono Fmt a2.le;have c2:=Model.roundAt_mono Fmt b1.le;have E:ᾁ Fmt V=Ἢ (ofW r):=le_antisymm (t2 ▸ c2) (t1 ▸ c1);have z:=Model.isFinite_div_of_abs_div_le_posMaxFinite x y ה hx hy hy0 (hV ▸ hb);have p:=Model.toReal_div_eq_roundAt _ _ ה hy z;rw[hV,E] at p;rw[Model.eq_of_toReal_eq_of_nonzero p (p ▸ qFm r n0 n255),qAw] lemma qJx {a V W Q E P P' z:ℝ} (ha:0< a) (hz0:0<=z) (hz:z<=a/2^53) (hW : |W| ≤ a/2) (h4 : |V-W| ≤ a/2^53) (h2 : |Q-W| ≤ 1/2^53*(|W| + z)) (hE:E=a/2^51) (hP : |P-(Q+E)| ≤ 1/2^53*(|Q+E| + z)) (hN : |P'-(Q-E)| ≤ 1/2^53*(|Q-E| + z)):P'< V∧V< P:=by have sck:∀ {k a b:ℝ},0(le_div_iff₀' hk).mp (h.trans_eq (one_div_mul_eq_div _ _)) have hz':(2:ℝ)^53*z ≤ a:=(le_div_iff₀' (by norm_num1)).mp hz;have hW':(2:ℝ)*|W| ≤ a:=(le_div_iff₀' (by norm_num1)).mp hW;have h4':(2:ℝ)^53*|V-W| ≤ a:=(le_div_iff₀' (by norm_num1)).mp h4 have h2':=sck (by norm_num1) h2;have hP':=sck (by norm_num1) hP;have hN':=sck (by norm_num1) hN;have hE':a=E*2^51:=(div_eq_iff (by norm_num1)).mp hE.symm have pQ:=le_abs_self (Q-W);have nQ:=neg_abs_le (Q-W);have pW:=le_abs_self W;have nW:=neg_abs_le W have b1 : |Q+E| ≤ a:=ὸ.2 ⟨by linarith only [nQ, nW, h2', hW', hz', hE', ha, hz0],by linarith only [pQ, pW, h2', hW', hz', hE', ha, hz0]⟩ have b2 : |Q-E| ≤ a:=ὸ.2 ⟨by linarith only [nQ, nW, h2', hW', hz', hE', ha, hz0],by linarith only [pQ, pW, h2', hW', hz', hE', ha, hz0]⟩ constructor . linarith only [le_abs_self (P'-(Q-E)), hN', b2, pQ, pW, h2', hW', neg_abs_le (V-W), h4', hz', hE', ha, hz0] . linarith only [neg_abs_le (P-(Q+E)), hP', b1, nQ, nW, h2', hW', le_abs_self (V-W), h4', hz', hE', ha, hz0] lemma qJn (s:ὥ) (h1:expOf s≠255) (h0:expOf s≠0):good s=true:=by have e:=qAx s;have b:=s.toNat_lt;have n1:(expOf s).toNat≠255:=λg=>h1 (ἠ.1 g);have n0:(expOf s).toNat≠0:=λg=>h0 (ἠ.1 g);have v:(s &&& В).toNat=ѥs%2^31:=by rw[Ἧ];exact Ἂ ѥs 31 unfold good;simp only[or_eq_true,decide_eq_true_eq,beq_iff_eq];right;have g:(0x00800000:ὥ)<=s &&& В:=by rw[ἃ,v];show 8388608<=_;(clear h1 h0 b n1; omega) rw[ἃ,ὓ _ _ g,v];show _-8388608<=2130706431;(clear h1 h0 b g; omega) lemma qG0 (n:Ὣ) (s:ὥ):E_dq n s=E_div n s:=by have e2pa:∀ {x y:ℝ} {a b j:ℕ},x<=2^a->y<=2^b->a<=j->b<=j->x+y<=2^(j+1):=fun {x y a b j} hx hy ha hb=>(add_le_add (hx.trans (pow_le_pow_right₀ one_le_two ha)) (hy.trans (pow_le_pow_right₀ one_le_two hb))).trans_eq ((two_mul _).symm.trans (pow_succ' 2 j).symm) have e2z0:A_z<=2^0:=Submission.D.qBo.trans_eq (pow_zero 2).symm have e2d:∀ {x:ℝ} (n:ℕ),0<=x->1/2^n*x<=x:=fun n h0=>mul_le_of_le_one_left h0 (div_le_one_of_le₀ (one_le_pow₀ one_le_two) (pow_nonneg zero_le_two n)) have e2AB1:∀ {x:ℝ} {k:ℕ},x<=2^k->k<=256+42->x<=A_B:=fun h hk=>h.trans (((pow_le_pow_right₀ one_le_two hk).trans_eq (pow_add 2 256 42)).trans Submission.D.qCc) have e2aa:∀ (x y:ℝ),|x| ≤ |y| + |x-y|:=fun x y=>sub_le_iff_le_add'.mp (abs_sub_abs_le_abs_sub x y) unfold E_dq;split;swap;. rfl rename_i h;obtain ⟨n1,n2,nsq,h255,h0⟩:=h;dsimp only;split;. rfl rename_i hr;have hr':ziv (dv s*(((0x20000000000000:Ὠ)/n.toUInt64).toFloat*Ἃ 0x3CA0000000000000)) ((dv s).abs*Ἃ 0x3CC0000000000000)≠Е:=by simpa using hr have hg:=qJn s h255 h0;obtain ⟨df,dR⟩:=qAs s hg;have wl:=qAh s hg;have wn:=qFm s h0 h255;have k13:n.sqrt<13:=by by_contra hc;have:=Nat.mul_le_mul (Nat.le_of_not_lt hc) (Nat.le_of_not_lt hc);(clear h255 h0 hr' hc; omega) have k0:0< n.sqrt:=by rcases Nat.eq_zero_or_pos n.sqrt with h | h;. rw[h] at nsq;(clear h255 h0 hr' k13 h; omega) . exact h obtain ⟨y1,y2,y3,y4⟩:=qIt ⟨n.sqrt,k13⟩ k0;simp only[nsq] at y1 y2 y3 y4;have ys:(sv (natW n):ℝ)=mantOf (natW n):=by rw[sv,y2];simp have hq:(mantOf (natW n):ℝ)*2^idxOf (natW n)=n*2^149:=by exact_mod_cast y4 have e149:(2:ℝ)^(149:ℤ)=2^149 :=ב;have yV:Ἢ (ofW (natW n))=n:=by rw[qBp _ y1,ys,ᾂ ἓ,Ἡ,e149,<-mul_div_assoc,hq];exact mul_div_cancel_right₀ _ (pow_ne_zero _ two_ne_zero) have hy0:Model.isZero (ofW (natW n))=false:=by rw[ofW,Model.isZero_eq_beq_zero_of_toDyadic?_some (ἶ _ y1),decodeD_sig_zero];simp[y3] generalize hm:((0x20000000000000:Ὠ)/n.toUInt64)=m at hr' have mN:Ѧm=2^53/n:=by rw[<-hm,UInt64.toNat_div];have:(n.toUInt64).toNat=n:=by simp;(exact Nat.lt_of_le_of_lt ‹_› (by decide)) rw[this];rfl have m1:n*(2^53/n)<=2^53:=Nat.mul_div_le _ _;have m2:2^53< n*(2^53/n+1):=Nat.lt_mul_div_succ _ (by exact Nat.le_of_lt ‹_›);have m3:Ѧm<2^53:=by rw[mN];exact Nat.div_lt_self ב (by exact Nat.succ_le_of_lt ‹_›) obtain ⟨f,a⟩:=qDz m m3 obtain ⟨ue,ud⟩:=qBu _ 97 ב f (Ѧm:ℤ) 0 (by exact Nat.succ_le_of_lt ‹_›) ב (by rw[a,ἅ (Ἔ (Ѧm))] exact qEo (by exact Nat.le_of_lt (Nat.lt_of_lt_of_le ‹_› (by decide)))) (by rw[a];simp) rw[show m.toFloat*Ἃ 0x3CA0000000000000=m.toFloat*pwEntry 97 by rw[qBb];rfl,show Ἃ 0x3CC0000000000000=pwEntry 99 by rw[qBb];rfl] at hr';have Ru:R (m.toFloat*pwEntry 97)=(Ѧm:ℝ)/2^53:=by rw[ud,a,(qCm 97 ב).2];norm_num;ring have Rp:R (pwEntry 99)=1/2^51:=by rw[(qCm 99 ב).2];norm_num have sA : |wv s| = (mantOf s:ℝ)*2^((idxOf s:ℤ)-149):=by rw[show wv s=_ from qBp s h255,ἢ,abs_of_pos (ἵ (two_pos:(0:ℝ)<2) _)];congr 1;unfold sv;split<;>simp have a0:0 < |wv s|:=abs_pos.2 wn have mS:1<=mantOf s:=by rcases Nat.eq_zero_or_pos (mantOf s) with g | g;. rw[g] at sA;simp at sA;exact absurd sA wn . exact g have aL:(2:ℝ)^(-149:ℤ) ≤ |wv s|:=by rw[sA];have c:(1:ℝ)<=mantOf s:=by exact_mod_cast mS have d:(2:ℝ)^(-149:ℤ)<=2^((idxOf s:ℤ)-149) :=ἒ one_le_two (neg_le_sub_iff_le_add.mpr (le_add_of_nonneg_left (Int.natCast_nonneg _)));exact d.trans (le_mul_of_one_le_left (ἵ (show (0:ℝ)<2 by norm_num) _).le c) obtain ⟨af,aR⟩:=qCx (dv s) df;have aB : |R (dv s).abs| ≤ A_B:=by rw[aR,dR,abs_abs];exact wl.trans qAe obtain ⟨ee,ed⟩:=qBu (dv s).abs 99 ב af (mantOf s:ℤ) ((idxOf s:ℤ)-149) (by have:=mantOf_lt_24 s;(exact Nat.lt_of_lt_of_le ‹_› (by decide))) (neg_le_sub_iff_le_add.mpr ((by norm_num1:(149:ℤ)<=900).trans (le_add_of_nonneg_left (Int.natCast_nonneg _)))) aB (by rw[aR,dR,sA];simp) have Re:R ((dv s).abs*pwEntry 99) = |wv s| / 2^51:=by rw[ed,aR,dR,Rp];ring have dB : |R (dv s)| ≤ A_B:=by rw[dR];exact wl.trans qAe have uB0:(0:ℝ)<=(Ѧm:ℝ)/2^53:=div_nonneg (Ἔ _) (by norm_num1) have n2R:(2:ℝ)<=n:=by exact_mod_cast n1 have m1R:(n:ℝ)*Ѧm<=2^53:=by rw[mN];exact_mod_cast m1 have m2R:(2:ℝ)^53< n*(Ѧm+1):=by rw[mN];exact_mod_cast m2 have uH:(Ѧm:ℝ)/2^53<=1/2:=by rw[div_le_iff₀ ב];have g:=ἀ n2R (show (0:ℝ)<=Ѧm from Ἔ _);linarith only [g,m1R] have uB : |R (m.toFloat*pwEntry 97)| ≤ A_B:=by rw[Ru,ἅ uB0];exact uH.trans ((by norm_num1:(1/2:ℝ)<=2^128).trans qAe) obtain ⟨qf,qE⟩:=qB8 _ _ df ue dB uB;rw[dR,Ru] at qE;have W0 : |wv s*((Ѧm:ℝ)/2^53)| ≤ |wv s| / 2:=by rw[ἢ,ἅ uB0];exact (ἁ uH (Ἀ (wv s))).trans_eq (mul_one_div _ _) have V0 : |wv s/n-wv s*((Ѧm:ℝ)/2^53)| ≤ |wv s| / 2^53:=by have n0R:(0:ℝ)< n :=zero_lt_two.trans_le n2R;have c1:wv s/n-wv s*((Ѧm:ℝ)/2^53)=wv s*(1/n-(Ѧm:ℝ)/2^53):=by ring have c2:0<=1/(n:ℝ)-(Ѧm:ℝ)/2^53:=by rw[sub_nonneg,div_le_div_iff₀ ב n0R];linarith only [m1R] have c3:1/(n:ℝ)-(Ѧm:ℝ)/2^53<=1/2^53:=by rw[sub_le_iff_le_add,<-add_div,div_le_div_iff₀ n0R ב];linarith only [m2R] rw[c1,ἢ,ἅ c2];have g:=ἁ c3 (Ἀ (wv s));rwa [mul_one_div] at g have zA:A_z ≤ |wv s| / 2^53:=by have g:=qB3;have k:(2:ℝ)^(-149:ℤ)/2^53 ≤ |wv s| / 2^53 :=div_le_div_of_nonneg_right aL ב;refine g.trans (le_trans ?_ k);norm_num have lim : |wv s| ≤ A_B:=wl.trans qAe;have qB : |R (dv s*(m.toFloat*pwEntry 97))| ≤ A_B:=by have hc:=W0.trans ((half_le_self (Ἀ _)).trans wl);exact e2AB1 ((e2aa _ _).trans (e2pa (j:=129) hc (qE.trans ((e2d 53 (add_nonneg (Ἀ _) qAn.le)).trans (e2pa (j:=128) hc e2z0 le_rfl (Nat.le_of_ble_eq_true rfl)))) (Nat.le_of_ble_eq_true rfl) le_rfl)) (Nat.le_of_ble_eq_true rfl) have eB : |R ((dv s).abs*pwEntry 99)| ≤ A_B:=by rw[Re,ἅ (div_nonneg (Ἀ (wv s)) (pow_nonneg zero_le_two 51))];exact (div_le_self (Ἀ (wv s)) (one_le_pow₀ one_le_two:(1:ℝ)≤2^51)).trans lim obtain ⟨-,pE⟩:=qA4 _ _ qf ee qB eB;obtain ⟨-,nE⟩:=qC9 _ _ qf ee qB eB;obtain ⟨lo,hi⟩:=qJx a0 qAn.le zA W0 V0 qE Re pE nE;refine (qHx _ _ (ofW s) (ofW (natW n)) ?_ ?_ hr' (qBi h255) (qBi y1) hy0 ?_).symm;. rw[yV];exact lo . rw[yV];exact hi . rw[yV,abs_div,Nat.abs_cast];exact (div_le_self (Ἀ _) (one_le_two.trans n2R)).trans (Model.abs_toReal_le_posMaxFinite_of_isFinite _ (qBi h255)) lemma qFt (n:Ὣ) (j s:ὥ) (hj:j=255∨(j=2∧n=4)∨(j=6∧n=64)) : E_quo n j s=E_div n s:=by unfold E_quo;split;swap;exact qG0 n s;rename_i h;have h1:=ἳ.1 h.1;have h3:=expOf_toNat_lt s;rcases hj with rfl | ⟨rfl,rfl⟩ | ⟨rfl,rfl⟩;. simp at h1;(clear h; omega) all_goals exact (qE2 s _ _ ה h.2 h1 ה ה ה ה).symm def E_f (xw:Ὣ->ὥ) (l:љ) (c:F1):F1 := l.foldl (λ(acc:F1) t=>let q:=dv (xw t)*dv oneW F1.mk (acc.s+q) (acc.t+q.abs)) c lemma qG2 (X off:ѐ) (k w n:Ὣ) (j z:ὥ) (u nf zb zr:ὧ) (b:ὦ) (hn:n.toUSize.toNat=4) : E_win X off k w n j z u nf zb b ѩn 0 zr zr 0=E_w4 X k w n j z u nf zb zr (rdW off 0).toUSize (rdW off (0+1)).toUSize (rdW off (0+1+1)).toUSize (rdW off (0+1+1+1)).toUSize b:=by have h0:(0:ὦ)< ѩn:=by rw[А,hn];decide have e1:=usz _ _ h0 have h1:(0+1:ὦ)< ѩn:=by rw[А,hn,e1];decide have e2:=usz _ _ h1 have h2:(0+1+1:ὦ)< ѩn:=by rw[А,hn,e2,e1];decide have e3:=usz _ _ h2 have h3:(0+1+1+1:ὦ)< ѩn:=by rw[А,hn,e3,e2,e1];decide have e4:=usz _ _ h3 have h4:¬ (0+1+1+1+1:ὦ)< ѩn:=by rw[А,hn,e4,e3,e2,e1];decide rw[E_win,Ἄ h0] dsimp only rw[E_win,Ἄ h1] dsimp only rw[E_win,Ἄ h2] dsimp only rw[E_win,Ἄ h3] dsimp only rw[E_win,ἔ h4] rfl lemma qEq (c h w k:Ὣ) (X off:ѐ) (j z:ὥ) (u nf zb zr:ὧ) : E_gridK c h w k (k*k) X off j z u nf zb zr=E_grid c h w k (k*k) X off j z u nf zb zr:=by unfold E_gridK;split;. rename_i hk;have hk:=eq_of_beq hk;subst hk;have e:(λb=>E_w4 X 2 w (2*2) j z u nf zb zr (rdW off 0).toUSize (rdW off (0+1)).toUSize (rdW off (0+1+1)).toUSize (rdW off (0+1+1+1)).toUSize b) =λb=>E_win X off 2 w (2*2) j z u nf zb b (2*2).toUSize 0 zr zr 0 :=funext λb=>(qG2 X off 2 w (2*2) j z u nf zb zr b (qAa _ (by norm_num1))).symm;dsimp only;rw[e,E_grid] . rfl lemma qF3 (X off:ѐ) (k w n:Ὣ) (j z:ὥ) (nf zb:ὧ) (b m:ὦ) (xw:Ὣ->ὥ) (hx:∀ t:ὦ,t< m->rdW X (b+(rdW off t).toUSize)=xw Ѥt) (d:Ὣ):∀ (t:ὦ) (s a:ὧ) (o:ὥ),Ѥt+d=Ѥm → E_win X off k w n j z (dv oneW) nf zb b m t s a o=E_tl X b k w n j z nf zb (E_f xw (List.range' Ѥt d) ⟨s,a⟩).s (E_f xw (List.range' Ѥt d) ⟨s,a⟩).t ((List.range' Ѥt d).foldl (λc i=>c ||| xw i) o):=by induction d with | zero => intro t s a o h rw[E_win,ἔ (by rw[А];omega)] rfl | succ d ih => intro t s a o h have ht:t< m:=А.2 (by omega) rw[E_win,Ἄ ht] dsimp only rw[hx t ht,ih (t+1) _ _ _ (by rw[usz t m ht];(clear ht; omega)),usz t m ht,List.range'_succ] rfl lemma qIy (xw:Ὣ->ὥ) (l:љ):∀ o:ὥ,l.foldl (λc i=>c ||| xw i) o=0->o=0∧∀ i∈l,xw i=0:=by induction l with | nil=>simp | cons i l ih => intro o h;obtain ⟨h1,h2⟩:=ih _ h;obtain ⟨h3,h4⟩:=UInt32.or_eq_zero_iff.1 h1;exact ⟨h3,List.forall_mem_cons.2 ⟨h4,h2⟩⟩ lemma qIm (n:Ὣ) (hn:n<2^20) (xw:Ὣ->ὥ) (hg:∀ t,t< n->good (xw t)=true) (r:ziv ((E_f xw (ἄ n) ⟨0,0⟩).s+dv 0) (nfOf n*((E_f xw (ἄ n) ⟨0,0⟩).t+(dv 0).abs))≠Е) : ziv ((E_f xw (ἄ n) ⟨0,0⟩).s+dv 0) (nfOf n*((E_f xw (ἄ n) ⟨0,0⟩).t+(dv 0).abs))=dotOf n xw (λ_=>oneW):=by obtain ⟨-,-,hbig⟩:=qCp _ _ r obtain ⟨hlo,hhi⟩:=qEd n hn xw (λ_=>oneW) 0 hg (λ_ _=>by decide) ה (ἄ n) List.nodup_range ג (λt h1 h2=>absurd (Ἅ.mpr h1) h2) _ _ ⟨rfl,rfl⟩ hbig have hsum:((∑ j∈Ἣ n,ἂ (xw j)*ἂ oneW:ℚ):ℝ) =exactS n xw (λ_=>oneW) 0:=by rw[exactS,qA8 0 ה ה,add_zero,Rat.cast_sum] refine Ἷ rfl λt ht=>?_ rw[Rat.cast_mul,qA6 _ (qAc _ (hg t (Ὁ.mp ht))),qA6 oneW ה] obtain ⟨d,hd,hw⟩:=qBa n xw (λ_=>oneW) (λj hj=>⟨qAc _ (hg j hj),by decide⟩) λh=>qH6 _ _ _ hlo hhi r (by rw[<-hsum,h,Rat.cast_zero]) have q:(d.toRat:ℝ)=exactS n xw (λ_=>oneW) 0:=by rw[hd,hsum] rw[hw] exact qEa _ _ d (by rw[q];exact hlo) (by rw[q];exact hhi) r lemma qHc (X:ѐ) (b:ὦ) (k w n:Ὣ) (hn:n<2^20) (j:ὥ) (hj:j=255∨(j=2∧n=4)∨(j=6∧n=64)) (xw:Ὣ->ὥ) (hg:∀ t,t< n->good (xw t)=true) (hs:E_dot X b k w=dotOf n xw (λ_=>oneW)) : E_tl X b k w n j (E_div n (dotFn n (λ_=>0) (λ_=>oneW))) (nfOf n) (dv 0) (E_f xw (ἄ n) ⟨0,0⟩).s (E_f xw (ἄ n) ⟨0,0⟩).t ((ἄ n).foldl (λc i=>c ||| xw i) 0)=E_div n (dotOf n xw (λ_=>oneW)):=by unfold E_tl split next h1 => rw[qAg] unfold dotOf congr 3 funext i exact ((qIy xw _ _ h1).2 _ (Ἅ.2 i.2)).symm . dsimp only;rw[qFt _ _ _ hj];congr 1;split;. rwa [qE9] next hr=>exact qIm _ hn xw hg (mt beq_iff_eq.2 hr) lemma qEe {c h w k ch y x t:Ὣ} (hc:ch< c) (hy:y< h/k) (hx:x< w/k) (ht:t< k*k):(ch*h+y*k+t/k)*w+x*k+t%k< c*h*w:=by have hk:0< k:=ὼ (by rintro rfl;(clear hc hx ht; omega));have h1:=Ἰ ht;have h2:=ὀ t hk;have h3:=(Nat.le_div_iff_mul_le hk).1 hy;have h4:=(Nat.le_div_iff_mul_le hk).1 hx;have h5:=Ἒ h hc;rw[ᾀ] at h3 h4 h5;have h6:=Ἒ w ((by clear hc hy hx ht hk h2 h4; omega):ch*h+y*k+t/k+1<=c*h);rw[ᾀ] at h6;(clear hc hy hx ht hk h1 h3 h5; omega) def G_P (N:Ὣ) (sp:Ὣ->ὥ) (out:ѐ) (p:Ὣ):Prop := ѧout=N∧N<2^32∧∀ i,i< p->out[i]! = sp i lemma qJl {N p:Ὣ} {sp:Ὣ->ὥ} {out:ѐ} (h:G_P N sp out p) (hp:p< N) (q:ὦ) (hq:Ѥq=p):G_P N sp (wrW out q (sp p)) (p+1):=by obtain ⟨h1,h2,h3⟩:=h;refine ⟨(qAm _ _ _).trans h1,h2,λi hi=>?_⟩;rw[qAq _ _ _ _ (by clear hp hq hi; omega) (by clear h2 hi; omega),hq];by_cases e:i=p;. rw[ἱ e,e] . rw[ἐ e];exact h3 i (by clear hp h1 h2; (clear hq; omega)) lemma qH7 (a s i:Ὣ):(a+(i+1)*s).toUSize=(a+i*s).toUSize+ѩs:=by rw[show a+(i+1)*s=a+i*s+s by ring];simp only[Nat.toUSize_eq,USize.ofNat_add] lemma qD5 {L:Ὣ->ὦ->ὦ->ѐ->ѐ} {g:ὦ->ὦ->ѐ->ѐ} {sb S n N q0 b0:Ὣ} {sp:Ὣ->ὥ} (hL:∀ i b q o,L i b q o =if i< n then L (i+1) (b+ѩsb) (q+ѩS) (g b q o) else o) (hs:∀ i o,i< n->G_P N sp o (q0+i*S) → G_P N sp (g (b0+i*sb).toUSize (q0+i*S).toUSize o) (q0+(i+1)*S)) (d:Ὣ) : ∀ i o,i+d=n->G_P N sp o (q0+i*S) → G_P N sp (L i (b0+i*sb).toUSize (q0+i*S).toUSize o) (q0+n*S):=by induction d with | zero => intro i o h1 h2 rw[hL,ἐ (by exact Nat.not_lt.mpr (Nat.le_of_eq (Eq.symm ‹_›))),<-h1] exact h2 | succ d ih => intro i o h1 h2 rw[hL,ἱ (by omega),<-qH7,<-qH7] exact ih (i+1) _ (by omega) (hs i o (by omega) h2) lemma qIe {f:ὦ->ὥ} {sc sy sx W H c N:Ὣ} {sp:Ὣ->ὥ} (hN:c*(H*W)=N) (hs:∀ ch y t,ch< c->y< H->t< W → f (ch*sc+y*sy+t*sx).toUSize=sp (ch*(H*W)+y*W+t)) (o:ѐ) (ho:G_P N sp o 0) : G_P N sp (G_c f ѩsc ѩsy ѩsx W H c 0 0 0 o) N:=by have:=qD5 (L:=G_c f ѩsc ѩsy ѩsx W H c) (sb:=sc) (S:=H*W) (n:=c) (N:=N) (q0:=0) (b0:=0) (sp:=sp) (λ_ _ _ _=>by rw[G_c]) (λch o a1 h=>by have h4:(ch+1)*(H*W)<=N:=hN ▸ Ἒ _ a1 have:=qD5 (L:=G_y f ѩsy ѩsx W H) (sb:=sy) (S:=W) (n:=H) (N:=N) (q0:=ch*(H*W)) (b0:=ch*sc) (sp:=sp) (λ_ _ _ _=>by rw[G_y]) (λy o a2 h=>by have h5:(y+1)*W<=H*W:=Ἒ _ a2 rw[ᾀ] at h4 h5 have:=qD5 (L:=G_x f ѩsx W) (g:=λb q o=>wrW o q (f b)) (sb:=sx) (S:=1) (n:=W) (N:=N) (q0:=ch*(H*W)+y*W) (b0:=ch*sc+y*sy) (sp:=sp) (λ_ _ _ _=>by rw[G_x];rfl) (λi o a3 h=>by have e1:ch*(H*W)+y*W+(i+1)*1 =ch*(H*W)+y*W+i*1+1 :=(by clear hN a1 h4 a2 h5 a3; omega) have e2:ch*(H*W)+y*W+i=ch*(H*W)+y*W+i*1 :=(by clear hN a1 h4 a2 h5 a3 e1; omega) rw[e1,hs ch y i a1 a2 a3,e2] exact qJl h (by clear hN a1 a2 e1 e2; omega) _ (qAa _ (by have:=h.2.1;(clear a1 a2 e1 e2; omega)))) W 0 o (by clear hN a1 h4 a2 h5; omega) (by simpa using h) simpa [Nat.succ_mul,Nat.add_assoc] using this) H 0 o (by clear hN a1 h4; omega) (by simpa using h) simpa [Nat.succ_mul,Nat.add_assoc] using this) c 0 o (by clear hN; omega) (by simpa using ho) simp only[Nat.zero_mul,Nat.zero_add,Nat.add_zero,hN] at this exact this lemma qHz {c H W q:Ὣ} (hq:q< c*(H*W)) : q/(H*W)< c∧q/W%H< H∧q%W< W:=by have hp:0< H*W:=ὼ (by rintro e;simp[e] at hq);exact ⟨Ἰ (by rwa [ἥ]),ὀ _ (Nat.pos_of_mul_pos_right hp),ὀ _ (Nat.pos_of_mul_pos_left hp)⟩ lemma qIl (f:ὦ->ὥ) (c h w k:Ὣ) (hs:c*h*w<2^32) : G_c f (h*w).toUSize (k*w).toUSize ѩk (w/k) (h/k) c 0 0 0 (ἇ (c*(h/k*(w/k))) 0) = Array.ofFn (n:=c*(h/k*(w/k))) λq =>let ch:=q.val/(h/k*(w/k)) let y:=q.val/(w/k)%(h/k) let x:=q.val%(w/k) f ((ch*h+y*k)*w+x*k).toUSize:=by have hN:c*(h/k*(w/k))<2^32:=by have h1:h/k*(w/k)<=h*w:=Nat.mul_le_mul (Nat.div_le_self _ _) (Nat.div_le_self _ _) exact lt_of_le_of_lt ((Nat.mul_le_mul_left c h1).trans (Nat.mul_assoc c h w).symm.le) hs generalize hH:h/k=H at * generalize hW:w/k=W at * have hp:=qIe (f:=f) (sc:=h*w) (sy:=k*w) (sx:=k) (W:=W) (H:=H) (c:=c) (sp:=λq=>f ((q/(H*W)*h+q/W%H*k)*w+q%W*k).toUSize) rfl (λch y t h1 h2 h3=>by obtain ⟨d1,d2⟩:=qC1 W (H*ch+y) t h3 obtain ⟨d3,d4⟩:=qC1 H ch y h2 have e:ch*(H*W)+y*W+t=W*(H*ch+y)+t:=by ring rw[e,d2,ἥ H W,<-Nat.div_div_eq_div_mul,d1,d3,d4] congr 2 ring) (ἇ (c*(H*W)) 0) ⟨by simp,hN,by simp⟩ apply Մ (by rw[hp.1,Array.size_ofFn]) intro i h1 h2 rw[<-Ἕ _ i h1,hp.2.2 i (by simpa using h2),Array.getElem_ofFn] lemma qGm {c h w k ch y x:Ὣ} {X:ѐ} (h1:c*h*w<2^32) (h2:ѧX<2^32) (h3:k*k<2^32) (hc:ch< c) (hy:y< h/k) (hx:x< w/k) (t:ὦ) (ht:Ѥt< k*k) : rdW X (((ch*h+y*k)*w+x*k).toUSize+(rdW (E_off k w) t).toUSize) =poolAtO h w k X ch y x Ѥt:=by have e0:=ὰ (ch*h+y*k) (Ѥt/k) w have h4:=qEe hc hy hx ht rw[qAo _ _ h2,qAo _ _ (by rwa [E_off,Array.size_ofFn]),E_off,qAb _ (λt=>(t/k*w+t%k).toUInt32) _ ht,poolAtO] generalize hu:Ѥt/k*w+Ѥt%k=u have e1:u.toUInt32.toUSize.toNat=u:=by rw[ὃ,Nat.toUInt32_eq,ὡ,Ἁ (by clear h2 h3 hc hy hx ht; omega)] rw[qAv _ _ (by rw[e1,qAa _ (by clear h2 h3 hc hy hx ht; omega)];(clear h2 h3 hc hy hx ht; omega)),e1,qAa _ (by clear h2 h3 hc hy hx ht; omega)] congr 1 (clear h1 h2 h3 hc hy hx ht h4 e1; omega) lemma qI9 {c h w k ch y x:Ὣ} {X:ѐ} (h1:c*h*w<=ѧX) (h2:ѧX<2^32) (h3:k*k<2^20) (hg:∀ i,i< ѧX->good X[i]! = true) (hc:ch< c) (hy:y< h/k) (hx:x< w/k) (j:ὥ) (hj:j=255∨(j=2∧k*k=4)∨(j=6∧k*k=64)) : E_win X (E_off k w) k w (k*k) j (E_div (k*k) (dotFn (k*k) (λ_=>0) (λ_=>oneW))) (dv oneW) (nfOf (k*k)) (dv 0) ((ch*h+y*k)*w+x*k).toUSize (k*k).toUSize 0 0 0 0 = E_div (k*k) (dotOf (k*k) (poolAtO h w k X ch y x) (λ_=>oneW)):=by have hn:=qAa (k*k) (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) have hk:0< k:=ὼ (by rintro rfl;simp at hy) have hI t (ht:t< k*k):=qEe hc hy hx ht have e2:=qAa ((ch*h+y*k)*w+x*k) (by have:=hI 0 (Nat.mul_pos hk hk);simp at this;(clear h3 hc hy hx hj hn hk; omega)) rw[qF3 X _ k w (k*k) j _ _ _ _ _ (poolAtO h w k X ch y x) (λt ht=>qGm (by exact Nat.lt_of_le_of_lt ‹_› ‹_›) h2 (by exact Nat.lt_of_lt_of_le ‹_› (by decide)) hc hy hx t (hn ▸ А.1 ht)) (k*k) 0 0 0 0 ((Ἇ _).trans hn.symm),USize.toNat_zero,<-List.range_eq_range'] refine qHc X _ k w _ h3 j hj _ (λt ht=>hg _ (by have:=hI t ht;(exact Nat.lt_of_lt_of_le ‹_› ‹_›))) ?_ rw[E_dot,qAg] congr 1 funext t rw[e2,poolAtO] congr 1 ring lemma qWc (X off:ѐ) (k w n:Ὣ) (j z:ὥ) (u nf zb:ὧ) (hu:u=dv oneW) (b m:ὦ) (hx:∀ t:ὦ,t< m->(rdW off t).toUSize=t) (d:Ὣ):∀ (t:ὦ) (s a:ὧ) (o:ὥ),Ѥt+d=Ѥm → E_winC X k w n j z u nf zb b m t s a o=E_win X off k w n j z u nf zb b m t s a o:=by subst hu induction d with | zero => intro t s a o h rw[E_winC,E_win,ἔ (by rw[А];omega),ἔ (by rw[А];omega)] | succ d ih => intro t s a o h have ht:t< m:=А.2 (by omega) rw[E_winC,E_win,Ἄ ht,Ἄ ht] dsimp only rw[hx t ht,D.qM1 _ (D.qDvF _),ih (t+1) _ _ _ (by rw[usz t m ht];omega)] lemma qOC (k:Ὣ) (hk:k*k<2^32) (t:ὦ) (ht:Ѥt< k*k):(rdW (E_off k k) t).toUSize=t:=by rw[qAo _ _ (by rwa [E_off,Array.size_ofFn]),E_off,qAb _ (λt=>(t/k*k+t%k).toUInt32) _ ht,Nat.div_add_mod'] apply USize.toNat_inj.mp rw[ὃ,Nat.toUInt32_eq,ὡ,Ἁ (by omega)] lemma qAX (X:ѐ) (w:Ὣ) (wu:ὦ) (u nf zb zr:ὧ) (hu:u=dv oneW) (W:Ὣ) (e:ὦ) (d:Ὣ) : ∀ (x:Ὣ) (b q:ὦ) (out:ѐ),W-x=d → x<=W → Ѥq+(W-x)=Ѥe → A_x X w wu u nf zb zr b q e out=G_x (λb=>E_w4 X 2 w 4 2 0 u nf zb zr 0 1 wu (wu+1) b) 2 W x b q out:=by subst hu induction d with | zero => intro x b q out h1 h2 h3 rw[A_x,G_x,ἔ (by rw[А];omega),ἐ (by omega)] | succ d ih => intro x b q out h1 h2 h3 have hq:q< e:=А.2 (by omega) rw[A_x,G_x,Ἄ hq,ἱ (by omega),qW4u] exact ih (x+1) _ _ _ (by omega) (by omega) (by rw[usz q e hq];omega) lemma qAY (X:ѐ) (w:Ὣ) (u nf zb zr:ὧ) (hu:u=dv oneW) (W H:Ὣ) (d:Ὣ) : ∀ (y:Ὣ) (b q:ὦ) (out:ѐ),H-y=d → Ѥq+(H-y)*W<2^32 → A_y X w ѩw u nf zb zr W H y b q out=G_y (λb=>E_w4 X 2 w 4 2 0 u nf zb zr 0 1 ѩw (ѩw+1) b) (2*w).toUSize 2 W H y b q out:=by induction d with | zero => intro y b q out h1 h2 rw[A_y,G_y,ἐ (by omega),ἐ (by omega)] | succ d ih => intro y b q out h1 h2 rw[h1,Nat.succ_mul] at h2 rw[A_y,G_y,ἱ (by omega),ἱ (by omega)] have e1:b+ѩw+ѩw=b+(2*w).toUSize:=by rw[add_assoc,two_mul];simp only[Nat.toUSize_eq,USize.ofNat_add] have hW:Ѥ(q+ѩW)=Ѥq+W:=by rw[qAv _ _ (by rw[qAa _ (by omega)];omega),qAa _ (by omega)] rw[e1,qAX X w ѩw u nf zb zr hu W (q+ѩW) W 0 b q out (by omega) (by omega) (by rw[hW];omega)] exact ih (y+1) _ _ _ (by omega) (by rw[hW,show H-(y+1)=d by omega];omega) lemma qAC (X:ѐ) (w:Ὣ) (u nf zb zr:ὧ) (hu:u=dv oneW) (sc:ὦ) (W H c:Ὣ) (d:Ὣ) : ∀ (ch:Ὣ) (b q:ὦ) (out:ѐ),c-ch=d → Ѥq+(c-ch)*(H*W)<2^32 → A_c X w ѩw u nf zb zr sc W H c ch b q out=G_c (λb=>E_w4 X 2 w 4 2 0 u nf zb zr 0 1 ѩw (ѩw+1) b) sc (2*w).toUSize 2 W H c ch b q out:=by induction d with | zero => intro ch b q out h1 h2 rw[A_c,G_c,ἐ (by omega),ἐ (by omega)] | succ d ih => intro ch b q out h1 h2 rw[h1,Nat.succ_mul] at h2 rw[A_c,G_c,ἱ (by omega),ἱ (by omega)] have hHW:Ѥ(q+(H*W).toUSize)=Ѥq+H*W:=by rw[qAv _ _ (by rw[qAa _ (by omega)];omega),qAa _ (by omega)] rw[qAY X w u nf zb zr hu W H H 0 b q out (by omega) (by rw[Nat.sub_zero];omega)] exact ih (ch+1) _ _ _ (by omega) (by rw[hHW,show c-(ch+1)=d by omega];omega) lemma qO2 (w t:Ὣ) (ht:t<4) (hw:t/2*w+t%2<2^32) (i:ὦ) (hi:Ѥi=t) : (rdW (E_off 2 w) i).toUSize=ѩ(t/2*w+t%2):=by rw[qAo _ _ (by rw[E_off,Array.size_ofFn];norm_num),hi,E_off,qAb _ (λt=>(t/2*w+t%2).toUInt32) _ ht] apply USize.toNat_inj.mp rw[ὃ,Nat.toUInt32_eq,ὡ,Ἁ hw,qAa _ hw] lemma qZ2 (c h w:Ὣ) (X:ѐ) (u nf zb zr:ὧ) (hu:u=dv oneW) (hN:c*(h/2*(w/2))<2^32) (hw:w<2^31) : E_grid2 c h w X u nf zb zr=E_gridK c h w 2 (2*2) X (E_off 2 w) 2 0 u nf zb zr:=by have i1:Ѥ(0+1:ὦ)=1:=by rw[qAv _ _ (by rw[USize.toNat_zero,ὄ];norm_num),USize.toNat_zero,ὄ] have i2:Ѥ(0+1+1:ὦ)=2:=by rw[qAv _ _ (by rw[i1,ὄ];norm_num),i1,ὄ] have i3:Ѥ(0+1+1+1:ὦ)=3:=by rw[qAv _ _ (by rw[i2,ὄ];norm_num),i2,ὄ] have o0:(rdW (E_off 2 w) 0).toUSize=0:=by rw[qO2 w 0 (by norm_num) (by omega) 0 (by decide),show 0/2*w+0%2=0 by omega];decide have o1:(rdW (E_off 2 w) (0+1)).toUSize=1:=by rw[qO2 w 1 (by norm_num) (by omega) (0+1) i1,show 1/2*w+1%2=1 by omega];simp only[Nat.toUSize_eq];rfl have o2:(rdW (E_off 2 w) (0+1+1)).toUSize=ѩw:=by rw[qO2 w 2 (by norm_num) (by omega) (0+1+1) i2,show 2/2*w+2%2=w by omega] have o3:(rdW (E_off 2 w) (0+1+1+1)).toUSize=ѩw+1:=by rw[qO2 w 3 (by norm_num) (by omega) (0+1+1+1) i3,show 3/2*w+3%2=w+1 by omega];simp only[Nat.toUSize_eq,USize.ofNat_add];rfl unfold E_grid2 E_gridK rw[qAC X w u nf zb zr hu _ (w/2) (h/2) c c 0 0 0 _ (by omega) (by simp;omega)] simp only[beq_self_eq_true,ite_true] rw[o0,o1,o2,o3] rfl lemma qGX (c h w k:Ὣ) (X:ѐ) (j z:ὥ) (u nf zb zr:ὧ) (hu:u=dv oneW) (hk:k*k<2^32) (hj:k=2→j=2) (hz:k=2→z=0) : E_gridX c h w k (k*k) X j z u nf zb zr=E_gridK c h w k (k*k) X (E_off k w) j z u nf zb zr:=by unfold E_gridX;split . rename_i e;subst e;rw[qEq];unfold E_gridC E_grid;congr 1;funext b exact qWc X (E_off k k) k k (k*k) j z u nf zb hu b ѩ(k*k) (λt ht=>qOC k hk t (by have:=А.mp ht;rwa [qAa _ hk] at this)) (k*k) 0 zr zr 0 (by rw[qAa _ hk];simp) . split . rename_i _ e;obtain ⟨rfl,h1,h2⟩:=e;rw[hj rfl,hz rfl];exact qZ2 c h w X u nf zb zr hu (Nat.lt_of_le_of_lt h2 (show 4294967295<2^32 by norm_num)) h1 . rfl lemma qG1:avgF=avgpoolSpecO:=by funext c h w k X;unfold avgF;rw[show D.fz0=(0:ὧ) from rfl];split . rename_i hc;obtain ⟨h1,h2,h3,h4⟩:=hc;replace h2:=Nat.lt_of_le_of_lt h2 (show 4294967295<2^32 by norm_num);simp only[avgpoolSpecO,avgpoolWithO] rw[show (if 0< k∧k<13 then (0:ὥ) else E_div (k*k) (dotFn (k*k) (λ_=>0) (λ_=>oneW)))=E_div (k*k) (dotFn (k*k) (λ_=>0) (λ_=>oneW)) by split;. rename_i e;exact (qJo k e.2 e.1).symm . rfl] rw[qGX _ _ _ _ _ _ _ _ _ _ _ rfl (by omega) (λe=>by subst e;rfl) (λe=>by subst e;exact qJo 2 (by decide) (by decide)),qEq,E_grid,qIl _ c h w k (by exact Nat.lt_of_le_of_lt ‹_› ‹_›)];apply congrArg Array.ofFn;funext ⟨q,hq⟩;obtain ⟨a1,a2,a3⟩:=qHz hq;dsimp only;refine qI9 h1 h2 h3 (qBh X h2 h4).2.2.1 a1 a2 a3 _ ?_;split_ifs with e1 e2;. exact Or.inr (Or.inl ⟨rfl,e1⟩) . exact Or.inr (Or.inr ⟨rfl,e2⟩) . exact Or.inl rfl . rfl end section @[inline] def maxF (a b:Ὢ):Ὢ := if a<У∧b<У then (if a?_;unfold Mk;by_cases hc:m%2^23+1<2^23 . rw[show (m+1)/2^23=m/2^23 by omega,show (m+1)%2^23=m%2^23+1 by omega];split;. (exact Nat.le_refl _) . exact Ἦ (by exact Nat.le_refl _) (Nat.two_pow_pos _) . rw[show (m+1)/2^23=m/2^23+1 by omega,show (m+1)%2^23=0 by omega,((by omega):m%2^23=2^23-1)];cases m/2^23 with | zero=>norm_num | succ e=>have:=Nat.two_pow_pos e;rw[ἐ (by clear hc this; omega),ἐ (by clear hc this; omega),Nat.add_sub_cancel,Nat.add_sub_cancel,pow_succ];(clear hc; omega) lemma Mk2 (w:Ὢ) (h:ѥw<2^31):(expOf w).toNat=ѥw/2^23∧(fracOf w).toNat=ѥw%2^23∧signOf w=false:=by have a2:(0xFF:ὥ).toNat=2^8-1:=rfl;have a3:(0x7FFFFF:ὥ).toNat=2^23-1:=rfl;have a4:(23:ὥ).toNat%32=23:=rfl;have a5:(س:ὥ).toNat=2^31:=rfl;unfold expOf fracOf signOf;rw[Ἧ,Ἧ,UInt32.toNat_shiftRight,a2,a3,a4,Ἂ,Ἂ,Ἱ];refine ⟨by (clear a2 a3 a4 a5; omega),rfl,?_⟩;rw[bne_eq_false_iff_eq,<-ἠ,Ἧ,a5,Nat.and_two_pow,Nat.testBit_lt_two_pow h];rfl lemma Mk3 (w:Ὢ) (h:ѥw<2^31):keyOf w=(Mk ѥw:Int):=by obtain ⟨h1,h2,h3⟩:=Mk2 w h;unfold keyOf;rw[ἐ (by simp[h3])];congr 1;unfold mantOf idxOf Mk;rw[ὁ];by_cases e:expOf w=0;. rw[ἱ e,ἱ e,ἱ (by rw[<-h1,e];rfl),h2,pow_zero,Nat.mul_one] . rw[ἐ e,ἐ e,ἐ (λz=>e (ἠ.mp (by rw[h1,z];rfl))),h1,h2] lemma Mk4 (a b:Ὢ) (h:ѥa<ѥb) (hb:ѥb<2^31):keyOf a?_,by (exact Nat.lt_of_lt_of_le ‹_› (by decide))⟩;have:=(Mk2 w (by exact Nat.lt_of_lt_of_le ‹_› (by decide))).1;rw[z] at this;have u:(255:ὥ).toNat=255:=rfl;(clear z; omega) lemma Mk7 (a:Ὢ) (h:ѥa<2^31) (n:¬a=0) (hz:Model.isZero (ofW a)=true):False:=by obtain ⟨h1,h2,-⟩:=Mk2 a h;have e:ofW a=_:=ofUInt32_eq_ofFields a;rw[e,Model.isZero_ofFields Fmt _ _ _ (expOf_toNat_lt a) (fracOf_toNat_lt a)] at hz;have y:((expOf a).toNat == 0 && (fracOf a).toNat == 0)=true:=hz;simp only[and_eq_true,beq_iff_eq] at y;rw[h1,h2] at y;exact n (ἠ.mp (by rw[UInt32.toNat_zero];(clear h h1; (clear h2; omega)))) lemma Mk8 (a:Ὢ) (e:expOf a≠255) (h:ѥa<2^31) (n:¬a=0):maxW a a=a:=by unfold maxW;rw[ἐ (by simpa using e),compare_eq_iff_eq.mpr rfl];dsimp only;rw[ἐ (by simpa using Mk7 a h n)];exact qAw a lemma qHi (a b:Ὢ):maxF a b=maxW a b:=by unfold maxF;split . rename_i h;obtain ⟨ha,hb⟩:=h;obtain ⟨e1,a1⟩:=Mk5 a ha;obtain ⟨e2,b1⟩:=Mk5 b hb;have d:¬(expOf a=255∨expOf b=255):=by simp[e1,e2] by_cases c:ampWin inp off b (k*k).toUSize 0 (rdW inp b)) (h*w).toUSize (k*w).toUSize ѩk (w/k) (h/k) c 0 0 0 (ἇ (c*(h/k*(w/k))) 0) else maxpoolW c h w k inp lemma qFv (X off:ѐ) (b m:ὦ) (xw:Ὣ->ὥ) (hx:∀ t:ὦ,t< m->rdW X (b+(rdW off t).toUSize)=xw Ѥt) (d:Ὣ) : ∀ (t:ὦ) (a:ὥ),Ѥt+d=Ѥm → mpWin X off b m t a=(List.range' Ѥt d).foldl (λa i=>maxF a (xw i)) a:=by induction d with | zero => intro t a h rw[mpWin,ἔ (by rw[А];omega)] rfl | succ d ih => intro t a h have ht:t< m:=by rw[А];omega rw[mpWin,Ἄ ht,hx t ht,ih (t+1) _ (by rw[usz t m ht];(clear ht; omega)),usz t m ht,List.range'_succ,List.foldl_cons] @[inline] def mp4 (X:Array UInt32) (w b:USize):UInt32 := let v0:=D.rdW X b maxF (maxF (maxF (maxF v0 v0) (D.rdW X (b+1))) (D.rdW X (b+w))) (D.rdW X (b+w+1)) theorem rdOff (w k : Nat) (hk : k < 4) : D.rdW (E_off 2 w) k.toUSize = (k/2*w+k%2).toUInt32 := by have hs : (E_off 2 w).size = 4 := by simp [E_off] have hku : (k.toUSize).toNat = k := D.uk k (by omega) have hlt : k.toUSize < (E_off 2 w).usize := by rw [USize.lt_iff_toNat_lt, hku]; simp only [Array.usize, hs]; rw [D.uk 4 (by norm_num)]; exact hk unfold D.rdW; rw [dif_pos hlt] simp [Array.uget, E_off, hku] theorem mp4_eq (X:Array UInt32) (w:Nat) (hw:w<2^31) (b:USize) : mp4 X w.toUSize b = mpWin X (E_off 2 w) b (2*2:Nat).toUSize 0 (D.rdW X b) := by have hm : USize.toNat (2*2:Nat).toUSize = 4 := D.uk 4 (by norm_num) rw [qFv X (E_off 2 w) b (2*2:Nat).toUSize (fun j => D.rdW X (b + (D.rdW (E_off 2 w) j.toUSize).toUSize)) (fun t _ => by simp only [USize.ofNat_toNat]) 4 0 (D.rdW X b) (by rw [hm]; rfl)] have o0 : D.rdW (E_off 2 w) (0:Nat).toUSize = 0 := by rw [rdOff w 0 (by norm_num)]; simp have o1 : D.rdW (E_off 2 w) (1:Nat).toUSize = 1 := by rw [rdOff w 1 (by norm_num)]; simp have o2 : D.rdW (E_off 2 w) (2:Nat).toUSize = w.toUInt32 := by rw [rdOff w 2 (by norm_num)]; simp have o3 : D.rdW (E_off 2 w) (3:Nat).toUSize = (w+1).toUInt32 := by rw [rdOff w 3 (by norm_num)]; simp have e2 : w.toUInt32.toUSize = w.toUSize := by apply USize.toNat_inj.mp; rw [UInt32.toNat_toUSize, UInt32.toNat_ofNat', D.uk w (by omega)]; omega have e3 : (w+1).toUInt32.toUSize = w.toUSize + 1 := by apply USize.toNat_inj.mp; rw [UInt32.toNat_toUSize, UInt32.toNat_ofNat', USize.toNat_add, D.uk w (by omega), USize.toNat_one] have : 2^32 ≤ USize.size := USize.le_size have h1 : (w+1) % 2^32 = w+1 := Nat.mod_eq_of_lt (by omega) have h2 : (w+1) % USize.size = w+1 := Nat.mod_eq_of_lt (by omega) simp only [h1, h2] have z0 : USize.toNat 0 = 0 := rfl have u0 : (0:UInt32).toUSize = 0 := rfl have u1 : (1:UInt32).toUSize = 1 := by apply USize.toNat_inj.mp; rw [UInt32.toNat_toUSize, USize.toNat_one]; rfl simp only [List.range', List.foldl, mp4, z0, Nat.reduceAdd, o0, o1, o2, o3, e2, e3, u0, u1, add_zero, USize.add_assoc] /-- 2×2 max pooling: the four window words read directly (no offset table, no window loop). -/ def maxpoolF2 (c h w k:Nat) (inp:Array UInt32):Array UInt32 := if k = 2 ∧ w < 2^31 ∧ c*h*w ≤ 4294967295 ∧ inp.size ≤ 4294967295 then G_c (λb => mp4 inp w.toUSize b) (h*w).toUSize (2*w).toUSize (2:Nat).toUSize (w/2) (h/2) c 0 0 0 (Array.replicate (c*(h/2*(w/2))) 0) else maxpoolF c h w k inp theorem maxpoolF2_eq : maxpoolF2 = maxpoolF := by funext c h w k inp unfold maxpoolF2 split · rename_i hc obtain ⟨rfl, hw, h1, h2⟩ := hc unfold maxpoolF rw [if_pos ⟨h1, h2, by norm_num⟩] dsimp only congr 1 funext b exact mp4_eq inp w hw b · rfl lemma qDp:maxpoolF=maxpoolSpecO:=by rw[<-qDn];funext c h w k inp;unfold maxpoolF;split . rename_i hc;obtain ⟨h1,h2,h3⟩:=hc;replace h1:=Nat.lt_of_le_of_lt h1 (show 4294967295<2^32 by norm_num);replace h2:=Nat.lt_of_le_of_lt h2 (show 4294967295<2^32 by norm_num);replace h3:=Nat.lt_of_le_of_lt h3 (show 4294967295<2^32 by norm_num);rw[qIl _ c h w k h1];simp only[maxpoolW];apply congrArg Array.ofFn;funext ⟨q,hq⟩;obtain ⟨a1,a2,a3⟩:=qHz hq;dsimp only;have hn:(k*k).toUSize.toNat=k*k:=qAa _ h3 have e:∀ {ch y x:Ὣ},ch< c->y< h/k->x< w/k → rdW inp ((ch*h+y*k)*w+x*k).toUSize=poolAtO h w k inp ch y x 0:=by intro ch y x b1 b2 b3 have h4:=qEe (t:=0) b1 b2 b3 (by rcases Nat.eq_zero_or_pos k with rfl | h0;. simp at b2 . exact Nat.mul_pos h0 h0) simp only[Nat.zero_div,Nat.zero_mod,Nat.add_zero] at h4;rw[qAo _ _ h2,qAa _ (by clear h2 h3 hq a1 a2 a3 hn b1 b2 b3; omega)];simp[poolAtO] rw[e a1 a2 a3,qFv inp _ _ _ (poolAtO h w k inp _ _ _) (λt ht=>qGm h1 h2 h3 a1 a2 a3 t (by rw[А,hn] at ht;exact ht)) (k*k) 0 _ (by rw[hn,show (0:ὦ).toNat=0 from rfl,Ἇ]),show (0:ὦ).toNat=0 from rfl,<-List.range_eq_range'];simp only[qHi] . rfl end section section variable {z:ℝ} (hz0:0<=z) (hz:z<=1/2^200*(1/2^200)) include hz0 hz end lemma qHo (a b:ѐ) (hs:ѧa=ѧb) (hf:∀ j,j< ѧa->expOf a[j]!≠255∧expOf b[j]!≠255) (hz:(dsum a b 0 ѧa:ℚ)*2^(-298:Int)=0) : dotSpec a b=toWord (Model.zero Fmt (decide (ѧa≠0) && dallNZ a b 0 ѧa)):=by rw[<-qEk a b hs.symm hf,show dsum a b 0 ѧa=0 by simpa using hz,finishWord_zero] lemma qD6 (n:Ὣ) (a b:Ὣ->ὥ) (hf:∀ t,t< n->expOf (a t)≠255∧expOf (b t)≠255) (hS:∑ j∈Ἣ n,ἂ (a j)*ἂ (b j)=0) : dotOf n a b=toWord (Model.zero Fmt (decide (n≠0) && dallNZ (Array.ofFn (n:=n) λi=>a i.val) (Array.ofFn (n:=n) λi=>b i.val) 0 n)):=by have gA:=qAb n a have gB:=qAb n b have s:(Array.ofFn (n:=n) λi=>a i.val).size=n:=by simp have e:=qHo (Array.ofFn (n:=n) λi=>a i.val) (Array.ofFn (n:=n) λi=>b i.val) ג (λj hj=>by rw[s] at hj;rw[gA j hj,gB j hj];exact hf j hj) (by rw[s,qE8,<-hS] refine Ἷ rfl λj hj=>?_ have h:=Ὁ.mp hj rw[Ἇ,gA j h,gB j h]) rw[s] at e exact e lemma qJw (a b:ѐ) (r i:Ὣ) : dallNZ a b i (r+1)=(dallNZ a b i r && (decide (mantOf a[i+r]! * mantOf b[i+r]! = 0) && Bool.xor (signOf a[i+r]!) (signOf b[i+r]!))):=by induction r generalizing i with | zero=>simp[dallNZ] | succ r ih => rw[dallNZ,ih (i+1),dallNZ] simp only[Bool.and_assoc,show i+1+r=i+(r+1) by omega] lemma qIp (a b u v:ѐ) (r i:Ὣ) (h:∀ j,i<=j->j< i+r->a[j]! = u[j]!∧b[j]! = v[j]!) : dallNZ a b i r=dallNZ u v i r:=by induction r generalizing i with | zero=>rfl | succ r ih => rw[dallNZ,dallNZ,ih (i+1) (λj h1 h2=>h j (by exact Nat.le_of_lt ‹_›) (by clear h1; omega)),(h i (by exact Nat.le_refl _) (by omega)).1,(h i (by exact Nat.le_refl _) (by omega)).2] lemma qI0 (k:Ὣ) (a b:Ὣ->ὥ) (hk:0< k) (hf:∀ t,t< k->expOf (a t)≠255∧expOf (b t)≠255) : dotOf (k+1) (λt=>if t< k then a t else oneW) (λt=>if t< k then b t else س)=dotOf k a b:=by have hf':∀ j,j< k+1->expOf (if j< k then a j else oneW)≠255 ∧ expOf (if j< k then b j else س)≠255:=λj _=>by by_cases h:j< k . simpa [h] using hf j h . simp only[h,ite_false];exact ⟨by decide,by decide⟩ have hsum:(∑ j∈Ἣ (k+1),ἂ (if j< k then a j else oneW) * ἂ (if j< k then b j else س)) =∑ j∈Ἣ k,ἂ (a j)*ἂ (b j):=by rw[Finset.sum_range_succ] simp only[lt_self_iff_false,ite_false,qJk 0x80000000 ה ה,mul_zero,add_zero] exact Ἷ rfl λj hj=>by simp[Finset.mem_range.mp hj] by_cases hS:(∑ j∈Ἣ k,ἂ (a j)*ἂ (b j))=0 . have g1:=qAb (k+1) λt=>if t< k then a t else oneW;have g2:=qAb (k+1) λt=>if t< k then b t else س rw[qD6 _ _ _ hf' (hsum.trans hS),qD6 k a b hf hS,qJw,Ἇ,g1 k (by exact Nat.le_refl _),g2 k (by exact Nat.le_refl _), qIp _ _ (Array.ofFn (n:=k) λi=>a i.val) (Array.ofFn (n:=k) λi=>b i.val) k 0 (λj _ h2=>by rw[g1 j (by omega),g2 j (by omega),qAb k a j (by omega),qAb k b j (by omega)] simp[show j< k by omega])] simp[show mantOf (0x80000000:ὥ)=0 by decide,show signOf oneW=false by decide,show signOf (0x80000000:ὥ)=true by decide,hk.ne'] . obtain ⟨d,hd,hw⟩:=qBa k a b hf hS;obtain ⟨e,he,hw'⟩:=qBa (k+1) _ _ hf' (by rw[hsum];exact hS);have t:=@toRat_eq_zero_iff;have h3:e.toRat=d.toRat:=by rw[he,hd,hsum] rw[hw,hw',roundDyadic_congr Fmt ה e d (λh=>hS (hd.symm.trans (h3.symm.trans ((t _).2 h)))) (λh=>hS (hd.symm.trans ((t _).2 h))) h3] lemma qD9 (A:ѐ) (h:A.all finiteWord=true) (t:Ὣ):expOf A[t]!≠255:=by by_cases ht:t< ѧA;. simpa [finiteWord] using qI1 A _ h t ht . rw[ὑ A t ht];decide end def linRg (inW m outW:Ὣ) (relu:Ὡ) (X W b:ё) (Dw:ὤ) (hd:ѨDw=ѧW) (q:ὥ) (nf bm:ὧ) (n:ὦ) : Ὣ → Ὣ → ё → ὤ → D.CN | 0, _, out, _ => ⟨out,true⟩ | k+1, r0, out, xs => let d:=D.dec8oC X (r0*inW).toUSize n xs let c:=D.cols8ZDo Dw (D.hvI m) inW outW relu X W b hd d nf n r0 (r0*outW).toUSize 0 out q (D.mkL8 nf (D.dv (D.hvI m)) bm d) ⟨0,0,0,0,0,0,0,0,0,0,0⟩ if c.ok then linRg inW m outW relu X W b Dw hd q nf bm n k (r0+8) c.out d.xs else ⟨c.out,false⟩ def linR (rows inW outW:Ὣ) (relu:Ὡ) (X W b:ё):ё := if rows*inW=ѧX∧outW*inW=ѧW∧outW=ѧb∧0< inW∧0< outW∧inW<2^20 ∧ ѧX<=4294967295∧ѧW<=4294967295∧ѧb<=4294967295∧rows*outW<=4294967295 ∧ D.scanH 0 X≠Е∧D.scanH 1 b≠Е∧8<=rows then let n:=ѩinW let nf:ὧ:=(inW.toUInt64+8).toFloat*Ἃ 0x3CA0000000000000 let p:=(D.wd8Get inW W).1 if hd:p.1.size=ѧW then let bm:=D.dv (D.scanH 1 b) let c:=linRg inW p.2.2 outW relu X W b p.1 hd p.2.1 nf bm n (rows/8) 0 (ἇ (rows*outW) 0) (D.zFor (8*inW+1)) if c.ok then if rows%8=0 then c.out else if 1<=rows%8 then let c2:=linRg inW p.2.2 outW relu X W b p.1 hd p.2.1 nf bm n 1 (rows-8) c.out (D.zFor (8*inW+1)) if c2.ok then c2.out else D.linF rows inW outW relu X W b else D.linF rows inW outW relu X W b else D.linF rows inW outW relu X W b else D.linF rows inW outW relu X W b else D.linF rows inW outW relu X W b def linG (rows inW outW:Ὣ) (relu:Ὡ) (X W b:ё):ё := if rows<=1 then D.linF rows inW outW relu X W b else if ѧX=rows*inW∧rows*outW+8*outW<=4294967295∧rows*inW+8*inW<=4294967295 then linR rows inW outW relu X W b else D.linF rows inW outW relu X W b def linSp (inW outW:Ὣ) (relu:Ὡ) (X W b:ё) (q:Ὣ):Ὢ := act relu (dotOf (inW+1) (λt=>if t< inW then X[q/outW*inW+t]! else oneW) (λt=>if t< inW then W[q%outW*inW+t]! else b[q%outW]!)) lemma qRgE {m:Ὣ} (inW outW:Ὣ) (relu:Ὡ) (X W b:ё) (HD:(D.dnOf (D.tZ m) (D.qTs (D.qTZ m)) W).size=ѧW) (d:D.H8) (n:ὦ) (hn:Ѥn=inW) (hW:outW*inW=ѧW) (hs:ѧW<2^32) (pi:0< inW) (ri:Ὣ) (ob:ὦ) (out:ё) (th:D.L8) (r0:D.F8) : D.cols8ZDo (D.dnOf (D.tZ m) (D.qTs (D.qTZ m)) W) (D.hvI m) inW outW relu X W b HD d (D.nfOf inW) n ri ob 0 out (D.qScan W W.usize 0 Е) th r0 =D.cols8Zo (D.tZ m) (D.qTs (D.qTZ m)) (D.hvI m) inW outW relu X W b d (D.nfOf inW) n ri ob 0 out Е th r0:=by have e:=D.c8ZSo (D.tZ m) (D.qTs (D.qTZ m)) (D.hvI m) inW outW relu X W b d (D.nfOf inW) n ri ob hn hW hs pi out th r0 rw[Ἄ HD] at e;exact e lemma qRg {rows inW outW m:Ὣ} {relu:Ὡ} {X W b:ё} (G:D.C_G rows inW outW X W b) (HD:(D.dnOf (D.tZ m) (D.qTs (D.qTZ m)) W).size=ѧW) (bm:ὧ) (fbm:bmᶠ) (hbm:∀ j,j< outW → |R (D.dv b[j]!)| ≤ R bm) (bb:R bm<=2^(290:ℤ)) : ∀ k r0 (out:ё) (xs:ὤ),8*inW+1<=xs.size → xs.size<2^32 → r0+8*k<=rows → D.C_Inv (rows*outW) (D.C_sp inW outW relu X W b) (λq=>qq<(r0+8*k)*outW) (linRg inW m outW relu X W b (D.dnOf (D.tZ m) (D.qTs (D.qTZ m)) W) HD (D.qScan W W.usize 0 Е) (D.nfOf inW) bm (ѩinW) k r0 out xs).out:=by intro k induction k with | zero=> intro r0 out xs _ _ _ H _ simp only[linRg,Nat.mul_zero,Nat.add_zero];exact H | succ k ih=> intro r0 out xs hx1 hx2 hk H ok have hni:=G.ni have hpi:=G.pi have hpo:=G.po have hr8:r0+8<=rows:=by (clear hni hpi hpo; omega) have nm:inW.toUSize.toNat=inW:=D.qAd _ (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) have hX32:ѧX<2^32:=G.sX have hrO:(r0+8)*outW<=rows*outW:=Nat.mul_le_mul_right _ hr8 have hrI:(r0+8)*inW<=rows*inW:=Nat.mul_le_mul_right _ hr8 have hRO:=G.sO have hRI:rows*inW<2^32:=by rw[G.hX];exact hX32 have e8:(r0+8)*outW=r0*outW+8*outW:=Nat.add_mul _ _ _ have e8i:(r0+8)*inW=r0*inW+8*inW:=Nat.add_mul _ _ _ have hob:((r0*outW).toUSize).toNat=r0*outW:=D.qAd _ (by (clear hk hni hpi hr8 nm hX32 hrI hRI e8i; omega)) have ho:((r0*inW).toUSize).toNat=r0*(ѩinW).toNat:=by rw[nm];exact D.qAd _ (by (clear hk hpo hr8 hX32 hrO hRO e8 hob; omega)) have h8X:(r0+8)*(ѩinW).toNat<=ѧX:=by rw[nm,<-G.hX];exact hrI have P0:8*inW+1<=xs.size∧xs.size<2^32:=⟨hx1,hx2⟩ have D0:D.C_D8o X r0 (ѩinW).toNat (0:ὦ).toNat ⟨xs,0,0,0,0,0,0,0,0⟩:=by rw[nm,D.C_z];exact ⟨P0,λk r hk=>absurd hk (Nat.not_lt_zero _),λr hr=>by interval_cases r<;>rfl⟩ have Dd:=D.qGqo hX32 ho h8X (ѩinW).toNat 0 _ 0 0 0 0 0 0 0 0 (by rw[D.C_z,Nat.zero_add]) D0 rw[nm] at Dd simp only[linRg] at ok ⊢ simp only[D.dec8oC_eq _ _ _ _ hX32] at ok ⊢ rw[qRgE inW outW relu X W b HD _ _ nm G.hW G.sW hpi] at ok ⊢ by_cases hc:(D.cols8Zo (D.tZ m) (D.qTs (D.qTZ m)) (D.hvI m) inW outW relu X W b (D.dec8o X (r0*inW).toUSize (ѩinW) 0 xs 0 0 0 0 0 0 0 0) (D.nfOf inW) (ѩinW) r0 (r0*outW).toUSize 0 out Е (D.mkL8 (D.nfOf inW) (D.dv (D.hvI m)) bm (D.dec8o X (r0*inW).toUSize (ѩinW) 0 xs 0 0 0 0 0 0 0 0)) ⟨0,0,0,0,0,0,0,0,0,0,0⟩).ok=true . rw[ἱ hc] at ok ⊢ obtain ⟨-,-,A2⟩:=D.qZ8o (D.qTZ m) hob hr8 G.hW hpi hni G.sW Dd.1 _ bm fbm hbm bb (λr hr=>by interval_cases r<;>rfl) outW 0 _ _ _ (Nat.zero_add _) hc have H1:=A2 G Dd (D.qA5 H (λq _ hq=>by unfold D.C_B at hq;rcases hq with h|⟨_,_,h⟩;exact h;exact absurd h (Nat.not_lt_zero _))) have H2:D.C_Inv (rows*outW) (D.C_sp inW outW relu X W b) (λq=>q<(r0+8)*outW) _:=D.qA5 H1 (λq _ hq=>by unfold D.C_B;by_cases e:q< r0*outW;. exact Or.inl e . exact Or.inr ⟨by omega,hq,Nat.mod_lt _ hpo⟩) have R:=ih (r0+8) _ _ Dd.1.1 Dd.1.2 (by (clear hni hpi hpo hr8 nm hX32 hrO hrI hRO hRI e8 e8i hob ho h8X P0; omega)) H2 ok have e:r0+8*(k+1)=r0+8+8*k:=by (clear hk hni hpi hpo hr8 nm hX32 hrO hrI hRO hRI e8 e8i hob ho h8X P0; omega) rw[e];exact R . rw[ἐ hc] at ok;exact absurd ok (by simp) lemma qRg1 {inW outW m:Ὣ} {relu:Ὡ} {X W b:ё} (HD:(D.dnOf (D.tZ m) (D.qTs (D.qTZ m)) W).size=ѧW) (hW:outW*inW=ѧW) (hs:ѧW<2^32) (pi:0< inW) (nm:inW.toUSize.toNat=inW) (bm:ὧ) (k r0:Ὣ) (out:ё) (xs:ὤ) (hX32:ѧX<2^32) (ok:(linRg inW m outW relu X W b (D.dnOf (D.tZ m) (D.qTs (D.qTZ m)) W) HD (D.qScan W W.usize 0 Е) (D.nfOf inW) bm (ѩinW) (k+1) r0 out xs).ok=true) : (D.cols8Zo (D.tZ m) (D.qTs (D.qTZ m)) (D.hvI m) inW outW relu X W b (D.dec8o X (r0*inW).toUSize (ѩinW) 0 xs 0 0 0 0 0 0 0 0) (D.nfOf inW) (ѩinW) r0 (r0*outW).toUSize 0 out Е (D.mkL8 (D.nfOf inW) (D.dv (D.hvI m)) bm (D.dec8o X (r0*inW).toUSize (ѩinW) 0 xs 0 0 0 0 0 0 0 0)) ⟨0,0,0,0,0,0,0,0,0,0,0⟩).ok=true:=by simp only[linRg] at ok simp only[D.dec8oC_eq _ _ _ _ hX32] at ok rw[qRgE inW outW relu X W b HD _ _ nm hW hs pi] at ok by_cases hc:(D.cols8Zo (D.tZ m) (D.qTs (D.qTZ m)) (D.hvI m) inW outW relu X W b (D.dec8o X (r0*inW).toUSize (ѩinW) 0 xs 0 0 0 0 0 0 0 0) (D.nfOf inW) (ѩinW) r0 (r0*outW).toUSize 0 out Е (D.mkL8 (D.nfOf inW) (D.dv (D.hvI m)) bm (D.dec8o X (r0*inW).toUSize (ѩinW) 0 xs 0 0 0 0 0 0 0 0)) ⟨0,0,0,0,0,0,0,0,0,0,0⟩).ok=true . exact hc . rw[ἐ hc] at ok;exact absurd ok (by simp) lemma qRR (rows inW outW:Ὣ) (relu:Ὡ) (X W b:ё) (hX:ѧX=rows*inW) (hN:rows*outW+8*outW<2^32) (hNi:rows*inW+8*inW<2^32) : linR rows inW outW relu X W b=Array.ofFn (n:=rows*outW) λq=>linSp inW outW relu X W b q.val:=by have FB:D.linF rows inW outW relu X W b=Array.ofFn (n:=rows*outW) λq=>linSp inW outW relu X W b q.val:=by rw[D.qDz];rfl unfold linR;dsimp only by_cases h:rows*inW=ѧX∧outW*inW=ѧW∧outW=ѧb∧0< inW∧0< outW∧inW<2^20∧ѧX<=4294967295∧ѧW<=4294967295∧ѧb<=4294967295∧rows*outW<=4294967295∧D.scanH 0 X≠Е∧D.scanH 1 b≠Е∧8<=rows . rw[ἱ h];obtain ⟨h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h13,hr8⟩:=h;replace h7:=D.qA9 h7;replace h8:=D.qA9 h8;replace h9:=D.qA9 h9;replace h10:=D.qA9 h10 have hnf:(inW.toUInt64+8).toFloat*Ἃ 0x3CA0000000000000=D.nfOf inW:=rfl have nm:inW.toUSize.toNat=inW:=D.qAd _ (by (exact Nat.lt_of_lt_of_le ‹_› (by decide))) have e:linSp inW outW relu X W b=D.C_sp inW outW relu X W b:=rfl rw[hnf,(D.wd8Get inW W).2];dsimp only;by_cases HD:(D.dnOf (D.tZ (D.nE inW W)) (D.qTs (D.qTZ (D.nE inW W))) W).size=ѧW . rw[Ἄ HD] by_cases hok:(linRg inW (D.nE inW W) outW relu X W b (D.dnOf (D.tZ (D.nE inW W)) (D.qTs (D.qTZ (D.nE inW W))) W) HD (D.qScan W W.usize 0 Е) (D.nfOf inW) (D.dv (D.scanH 1 b)) (ѩinW) (rows/8) 0 (ἇ (rows*outW) 0) (D.zFor (8*inW+1))).ok=true . rw[ἱ hok] have hk:rows/8=(rows/8-1)+1:=by (clear hX hN hNi h1 h2 h3 h4 h5 h6 h11 h13 h7 h8 h9 h10 nm; omega) have ok1:=hok;rw[hk] at ok1 have c1:=qRg1 HD h2 h8 h4 nm _ (rows/8-1) 0 _ (D.zFor (8*inW+1)) h7 ok1 have hob0:((0*outW).toUSize).toNat=0*outW:=D.qAd _ (by (clear hX hN hNi h1 h2 h3 h4 h5 h6 h11 h13 hr8 h7 h8 h9 h10 nm hk; omega)) have P0:=D.qZf (8*inW+1) (by (clear hX hN hNi h1 h2 h3 h5 h11 h13 hr8 h7 h8 h9 h10 hk hob0; omega)) have ho0:((0*inW).toUSize).toNat=0*(ѩinW).toNat:=by rw[nm];exact D.qAd _ (by (clear hX hN hNi h1 h2 h3 h4 h5 h6 h11 h13 hr8 h7 h8 h9 h10 nm hk hob0 P0; omega)) have h8X0:(0+8)*(ѩinW).toNat<=ѧX:=by rw[nm,<-h1];exact Nat.mul_le_mul_right _ hr8 have D00:D.C_D8o X 0 (ѩinW).toNat (0:ὦ).toNat ⟨D.zFor (8*inW+1),0,0,0,0,0,0,0,0⟩:=by rw[nm,D.C_z];exact ⟨P0,λk r hk=>absurd hk (Nat.not_lt_zero _),λr hr=>by interval_cases r<;>rfl⟩ have Dd0:=D.qGqo h7 ho0 h8X0 (ѩinW).toNat 0 _ 0 0 0 0 0 0 0 0 (by rw[D.C_z,Nat.zero_add]) D00 rw[nm] at Dd0 obtain ⟨gb1,gb2,-,gb4⟩:=D.qA8 1 b h9 h13 obtain ⟨pb0,pb1,pb2⟩:=D.qCs gb1 gb2 obtain ⟨fbm,Rbm⟩:=D.qAm _ gb1 have hbm:∀ j,j< outW → |R (D.dv b[j]!)| ≤ R (D.dv (D.scanH 1 b)):=λj hj=>by have gj:=(D.qA8 1 b h9 h13).2.2.1 j (by rw[<-h3];exact hj) rw[(D.qAm _ gj).2,Rbm];exact pb2 _ gj (gb4 j (by rw[<-h3];exact hj)) have bb:R (D.dv (D.scanH 1 b))<=2^(290:ℤ):=by rw[Rbm];exact pb1.trans (by rw[show (2:ℝ)^128=2^(128:ℤ) by norm_num];exact zpow_le_zpow_right₀ (by norm_num) (by norm_num)) obtain ⟨-,A1,-⟩:=D.qZ8o (R:=rows) (D.qTZ (D.nE inW W)) hob0 (by (exact Nat.succ_le_of_lt ‹_›)) h2 h4 h6 h8 Dd0.1 _ (D.dv (D.scanH 1 b)) fbm hbm bb (λr hr=>by interval_cases r<;>rfl) outW 0 _ _ _ (Nat.zero_add _) c1 have A:∀ q,q< ѧW->D.good W[q]! = true:=λq hq=>by have e1:=(A1 (q/inW) (Nat.zero_le _) (Nat.div_lt_of_lt_mul (by rw[Nat.mul_comm,h2];exact hq)) (q%inW) (Nat.mod_lt _ h4)).1 rwa [Nat.div_add_mod' q inW] at e1 have G:D.C_G rows inW outW X W b:=⟨h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,(D.qA8 0 X h7 h11).2.2.1,A,(D.qA8 1 b h9 h13).2.2.1⟩ have R1:=qRg G HD (D.dv (D.scanH 1 b)) fbm hbm bb (rows/8) 0 _ (D.zFor (8*inW+1)) P0.1 P0.2 (by (clear hX hN hNi h1 h2 h3 h4 h5 h6 h11 h13 hr8 h7 h8 h9 h10 nm hob0 P0 ho0 h8X0; omega)) ⟨by simp,λq _ hq=>absurd hq (by simp)⟩ hok rw[Nat.zero_add] at R1 rw[e] by_cases hm:rows%8=0 . rw[ἱ hm];have e2:8*(rows/8)=rows:=by (clear hX hN hNi h1 h2 h3 h4 h5 h6 h11 h13 hr8 h7 h8 h9 h10 nm hob0 P0 ho0 h8X0; omega) rw[e2] at R1;exact D.qBv R1 (λq hq=>hq) . rw[ἐ hm];by_cases h5:1<=rows%8 . rw[ἱ h5] split . rename_i hok2 have R2:=qRg G HD (D.dv (D.scanH 1 b)) fbm hbm bb 1 (rows-8) _ (D.zFor (8*inW+1)) P0.1 P0.2 (by omega) (D.qA5 R1 (λq _ hq=>by have:=Nat.mul_le_mul_right outW (show rows-8<=8*(rows/8) by omega);(exact Nat.lt_of_lt_of_le ‹_› ‹_›))) hok2 have e3:rows-8+8*1=rows:=by omega rw[e3] at R2;exact D.qBv R2 (λq hq=>hq) . rw[<-e];exact FB . rw[ἐ h5] rw[<-e];exact FB . rw[ἐ hok];exact FB . rw[ἔ HD];exact FB . rw[ἐ h];exact FB lemma qHb:linG=linearSpec:=by funext rows inW outW relu X W b;unfold linG;split;. rw[D.qDz] . split;. rename_i _ h;obtain ⟨hs,hN,hNi⟩:=h;rw[qRR rows inW outW relu X W b hs (Nat.lt_of_le_of_lt hN (show 4294967295<2^32 by norm_num)) (Nat.lt_of_le_of_lt hNi (show 4294967295<2^32 by norm_num))];rfl . rw[D.qDz] lemma qJj (a b:ѐ) (i r:Ὣ):dallNZ a b i r=dallNZ b a i r:=by induction r generalizing i with | zero=>rfl | succ r ih=>rw[dallNZ,dallNZ,ih (i+1),ἥ (mantOf a[i]!),Bool.xor_comm] lemma qIh (n:Ὣ) (fa fb:Ὣ->ὥ) (hf:∀ j,j< n->expOf (fa j)≠255∧expOf (fb j)≠255) : dotOf n fa fb=dotOf n fb fa:=by have hf':∀ j,j< n->expOf (fb j)≠255∧expOf (fa j)≠255:=λj h=>(hf j h).symm;have hs:(∑ j∈Ἣ n,ἂ (fb j)*ἂ (fa j)) =∑ j∈Ἣ n,ἂ (fa j)*ἂ (fb j) :=Ἷ rfl (λj _=>mul_comm _ _);by_cases hS:(∑ j∈Ἣ n,ἂ (fa j)*ἂ (fb j))=0;. rw[qD6 n fa fb hf hS,qD6 n fb fa hf' (hs.trans hS),qJj] . obtain ⟨d,hd,hw⟩:=qBa n fa fb hf hS;obtain ⟨e,he,hw'⟩:=qBa n fb fa hf' (by rw[hs];exact hS);have t:=@toRat_eq_zero_iff;have h3:d.toRat=e.toRat:=by rw[hd,he,hs] rw[hw,hw',roundDyadic_congr Fmt ה d e (λh=>hS (hd.symm.trans ((t _).2 h))) (λh=>hS (hd.symm.trans (h3.trans ((t _).2 h)))) h3] def gemmC (batch m k n:Ὣ) (A B:ё):ё := if batch == 1 && ѧA == m*k && ѧB == k*n && decide (0< n) && decide (0< k) && decide (0< m) && A.all finiteWord && B.all finiteWord then convF ⟨k,1,n,m,1,1,1,0⟩ false B A (ἇ m س) else gemmSpec batch m k n A B lemma qFq:gemmC=gemmSpec:=by funext batch m k n A B;unfold gemmC;split . rename_i hc;simp only[and_eq_true,beq_iff_eq,decide_eq_true_eq] at hc;obtain ⟨⟨⟨⟨⟨⟨⟨h1,h2⟩,h3⟩,h4⟩,h5⟩,hm0⟩,h6⟩,h7⟩:=hc;subst h1;rw[qB7];unfold conv2dSpecO conv2dWithO gemmSpec gemmWith;have eho:OS.ho ⟨k,1,n,m,1,1,1,0⟩=1:=by simp[OS.ho] have ewo:OS.wo ⟨k,1,n,m,1,1,1,0⟩=n:=by simp[OS.wo];(clear hm0 h5 h3 h2 eho; omega) apply Մ (by simp[eho,ewo]);intro q hq1 hq2;simp only[Array.getElem_ofFn,Array.size_ofFn] at hq1 hq2 ⊢;have hq:q< m*n:=by simpa using hq2 simp only[eho,ewo,Nat.mul_one,Nat.one_mul,Nat.mod_one];have hi:q/n< m:=Ἰ (by rwa [ἥ]);have hj:q%n< n:=ὀ _ h4;have e1:q/(m*n)=0:=Ὃ hq;have e2:q/n%m=q/n:=Ἁ hi;have gz:(ἇ m (س:ὥ))[q/n]! = س:=by rw[Ἕ _ _ (by simpa using hi)];simp have hx:(λt=>if t< k then windowAtO ⟨k,1,n,m,1,1,1,0⟩ B 0 (q%n) t else oneW) =(λt=>if t< k then B[t*n+q%n]! else oneW):=by funext t;split;. simp only[windowAtO,Nat.mod_one,Nat.div_one,Nat.mul_one,Nat.add_zero,Nat.sub_zero];rw[ἐ (by omega)] . rfl have hw:(λt=>if t< k then A[q/n*k+t]! else (ἇ m (س:ὥ))[q/n]!) =(λt=>if t< k then A[q/n*k+t]! else س):=by funext t;rw[gz] simp only[act,false_eq_true,ite_false];rw[hx,hw,qI0 k (λt=>B[t*n+q%n]!) (λt=>A[q/n*k+t]!) h5 (λt _=>⟨qD9 B h7 _,qD9 A h6 _⟩),qIh k _ _ (λt _=>⟨qD9 B h7 _,qD9 A h6 _⟩)];simp only[e1,e2,Nat.zero_mul,Nat.zero_add] . rfl end C open ExactRuntime open ExactRuntime /-! ## Fast convolution and pooling: the season-1 kernels behind a shape test The models use `ConvShape.simple` and `PoolShape.square` only. On those shapes the season-2 specs are the season-1 specs (O-suffixed, on `OS`) of the corresponding old shape, so the season-1 kernels and proofs apply; every other shape takes the pinned generic path. -/ namespace ConvFast open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats /-- A convolution's season-1 shape (stride and padding read from the first axis/side). -/ def toOld (s : ConvShape) : OS := ⟨s.cin, s.h, s.w, s.cout, s.kh, s.kw, s.strideH, s.padT⟩ /-- A `h × 1` image with a `kh × 1` filter, read as a `1 × h` image with a `1 × kh` filter (same memory layout). -/ def swapO (s : OS) : OS := ⟨s.cin, 1, s.h, s.cout, 1, s.kh, s.stride, s.pad⟩ /-- Column images (`w = kw = 1`, no padding) become row images, which the engine vectorizes. -/ def fixO (s : OS) : OS := if s.w = 1 ∧ s.kw = 1 ∧ s.pad = 0 then swapO s else s def conv2dF (s : ConvShape) (relu : Bool) (inp wts b : Array Word) : Array Word := if s.strideW = s.strideH ∧ s.padL = s.padT ∧ s.padB = s.padT ∧ s.padR = s.padT ∧ s.dilH = 1 ∧ s.dilW = 1 ∧ s.groups = 1 ∧ 0 < s.kh ∧ 0 < s.kw then C.convF (fixO (toOld s)) relu inp wts b else conv2dWith Pinned.dotFn s relu inp wts b def depthwiseF (s : ConvShape) (relu : Bool) (inp wts b : Array Word) : Array Word := if s.strideW = s.strideH ∧ s.padL = s.padT ∧ s.padB = s.padT ∧ s.padR = s.padT ∧ s.dilH = 1 ∧ s.dilW = 1 ∧ 0 < s.kh ∧ 0 < s.kw then C.depthF (fixO (toOld s)) relu inp wts b else depthwiseWith Pinned.dotFn s relu inp wts b def avgpoolF (s : PoolShape) (inp : Array Word) : Array Word := if s.kw = s.kh ∧ s.strideH = s.kh ∧ s.strideW = s.kh ∧ s.padT = 0 ∧ s.padL = 0 ∧ s.padB = 0 ∧ s.padR = 0 ∧ s.ceilMode = false ∧ s.countIncludePad = false ∧ 0 < s.kh ∧ s.kh ≤ s.h ∧ s.kh ≤ s.w then C.avgF s.c s.h s.w s.kh inp else avgpoolWith Pinned.dotFn s inp def maxpoolF (s : PoolShape) (inp : Array Word) : Array Word := if s.kw = s.kh ∧ s.strideH = s.kh ∧ s.strideW = s.kh ∧ s.padT = 0 ∧ s.padL = 0 ∧ s.padB = 0 ∧ s.padR = 0 ∧ s.ceilMode = false ∧ 0 < s.kh ∧ s.kh ≤ s.h ∧ s.kh ≤ s.w then C.maxpoolF2 s.c s.h s.w s.kh inp else Pinned.maxpoolW s inp /-! ## Bridges: on simple shapes the season-2 specs are the season-1 specs -/ theorem conv_bridge (s : ConvShape) (relu : Bool) (inp wts b : Array Word) (h : s.strideW = s.strideH ∧ s.padL = s.padT ∧ s.padB = s.padT ∧ s.padR = s.padT ∧ s.dilH = 1 ∧ s.dilW = 1 ∧ s.groups = 1 ∧ 0 < s.kh ∧ 0 < s.kw) : conv2dSpecO (toOld s) relu inp wts b = conv2dSpec s relu inp wts b := by obtain ⟨h1, h2, h3, h4, h5, h6, h7, h8, h9⟩ := h have hho : (toOld s).ho = s.ho := by simp only [OS.ho, ConvShape.ho, ConvShape.ekh, toOld, h3, h5] congr 2; omega have hwo : (toOld s).wo = s.wo := by simp only [OS.wo, ConvShape.wo, ConvShape.ekw, toOld, h2, h4, h6, h1] congr 2; omega have htaps : s.taps = s.cin * s.kh * s.kw := by simp [ConvShape.taps, ConvShape.cpg, h7] have hopg : s.opg = s.cout := by simp [ConvShape.opg, h7] have hcpg : s.cpg = s.cin := by simp [ConvShape.cpg, h7] apply Array.ext · simp only [conv2dSpecO, conv2dWithO, conv2dSpec, conv2dWith, Array.size_ofFn, hho, hwo] simp [toOld] · intro q hq1 hq2 have hq : q < s.cout * (s.ho * s.wo) := by simpa [conv2dSpec, conv2dWith] using hq2 have hp : 0 < s.ho * s.wo := Nat.mul_pos (by simp [ConvShape.ho]) (by simp [ConvShape.wo]) have hg : q / (s.ho * s.wo) / s.cout = 0 := Nat.div_eq_of_lt ((Nat.div_lt_iff_lt_mul hp).2 hq) simp only [conv2dSpecO, conv2dWithO, conv2dSpec, conv2dWith, Array.getElem_ofFn, hho, hwo, htaps, hopg, hg] simp only [toOld] congr 2 funext t by_cases ht : t < s.cin * s.kh * s.kw · simp only [ht, ↓reduceIte] simp only [windowAtO, windowAt, hcpg, h1, h2, h5, h6, Nat.mul_one, Nat.zero_mul, Nat.zero_add] · simp only [ht, ↓reduceIte] theorem depth_bridge (s : ConvShape) (relu : Bool) (inp wts b : Array Word) (h : s.strideW = s.strideH ∧ s.padL = s.padT ∧ s.padB = s.padT ∧ s.padR = s.padT ∧ s.dilH = 1 ∧ s.dilW = 1 ∧ 0 < s.kh ∧ 0 < s.kw) : depthwiseSpecO (toOld s) relu inp wts b = depthwiseSpec s relu inp wts b := by obtain ⟨h1, h2, h3, h4, h5, h6, h8, h9⟩ := h have hho : (toOld s).ho = s.depthwise.ho := by simp only [OS.ho, ConvShape.ho, ConvShape.ekh, ConvShape.depthwise, toOld, h3, h5] congr 2; omega have hwo : (toOld s).wo = s.depthwise.wo := by simp only [OS.wo, ConvShape.wo, ConvShape.ekw, ConvShape.depthwise, toOld, h2, h4, h6, h1] congr 2; omega apply Array.ext · simp only [depthwiseSpecO, depthwiseWithO, depthwiseSpec, depthwiseWith, conv2dWith, Array.size_ofFn, hho, hwo] simp [toOld, ConvShape.depthwise] · intro q hq1 hq2 have hq : q < s.cin * (s.depthwise.ho * s.depthwise.wo) := by simpa [depthwiseSpec, depthwiseWith, conv2dWith, ConvShape.depthwise] using hq2 have hcin : 0 < s.cin := by rcases Nat.eq_zero_or_pos s.cin with h0 | h0 · simp [h0] at hq · exact h0 have hcpg : s.depthwise.cpg = 1 := by simp [ConvShape.cpg, ConvShape.depthwise, Nat.div_self hcin] have hopg : s.depthwise.opg = 1 := by simp [ConvShape.opg, ConvShape.depthwise, Nat.div_self hcin] have htaps : s.depthwise.taps = s.kh * s.kw := by simp only [ConvShape.taps, hcpg, Nat.one_mul]; rfl simp only [depthwiseSpecO, depthwiseWithO, depthwiseSpec, depthwiseWith, conv2dWith, Array.getElem_ofFn, hho, hwo, htaps, hopg, Nat.div_one] simp only [toOld] congr 2 funext t by_cases ht : t < s.kh * s.kw · simp only [ht, ↓reduceIte] have hk : 0 < s.kh * s.kw := Nat.mul_pos h8 h9 have e1 : (q / (s.depthwise.ho * s.depthwise.wo) * (s.kh * s.kw) + t) / (s.kh * s.kw) = q / (s.depthwise.ho * s.depthwise.wo) := by rw [Nat.mul_comm, Nat.mul_add_div hk, Nat.div_eq_of_lt ht, Nat.add_zero] have e2 : (q / (s.depthwise.ho * s.depthwise.wo) * (s.kh * s.kw) + t) / s.kw % s.kh = t / s.kw % s.kh := by rw [show q / (s.depthwise.ho * s.depthwise.wo) * (s.kh * s.kw) + t = t + s.kw * (q / (s.depthwise.ho * s.depthwise.wo) * s.kh) by ring, Nat.add_mul_div_left _ _ h9, Nat.add_mul_mod_self_right] have e3 : (q / (s.depthwise.ho * s.depthwise.wo) * (s.kh * s.kw) + t) % s.kw = t % s.kw := by rw [show q / (s.depthwise.ho * s.depthwise.wo) * (s.kh * s.kw) + t = t + s.kw * (q / (s.depthwise.ho * s.depthwise.wo) * s.kh) by ring, Nat.add_mul_mod_self_left] have f1 : s.depthwise.kh = s.kh := rfl have f2 : s.depthwise.kw = s.kw := rfl have f3 : s.depthwise.h = s.h := rfl have f4 : s.depthwise.w = s.w := rfl have f5 : s.depthwise.strideH = s.strideH := rfl have f6 : s.depthwise.strideW = s.strideH := h1 have f7 : s.depthwise.padT = s.padT := rfl have f8 : s.depthwise.padL = s.padT := h2 have f9 : s.depthwise.dilH = 1 := h5 have f10 : s.depthwise.dilW = 1 := h6 simp only [windowAtO, windowAt, e1, e2, e3, hcpg, Nat.mul_one, Nat.div_eq_of_lt ht, Nat.add_zero, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10] · simp only [ht, ↓reduceIte] theorem pool_out (n k : Nat) (hk : 0 < k) (hn : k ≤ n) : poolOut n 0 0 k k false = n / k := by simp only [poolOut, Nat.add_zero, Bool.false_eq_true, ite_false] exact (Nat.div_eq_sub_div hk hn).symm theorem pool_span (i k n : Nat) (hi : i < n / k) : poolSpan i k 0 k n = (i * k, i * k + k) := by have : (i + 1) * k ≤ n / k * k := Nat.mul_le_mul_right _ hi have := Nat.div_mul_le_self n k simp only [poolSpan, Nat.sub_zero, Nat.zero_add, Prod.mk.injEq, true_and] rw [Nat.min_eq_left (by rw [Nat.succ_mul] at *; omega)] theorem pool_window (s : PoolShape) (y x : Nat) (h : s.kw = s.kh ∧ s.strideH = s.kh ∧ s.strideW = s.kh ∧ s.padT = 0 ∧ s.padL = 0) (hy : y < s.h / s.kh) (hx : x < s.w / s.kh) : s.window y x = ⟨y * s.kh, x * s.kh, s.kh, s.kh⟩ := by obtain ⟨h1, h2, h3, h4, h5⟩ := h simp only [PoolShape.window, h1, h2, h3, h4, h5, pool_span y s.kh s.h hy, pool_span x s.kh s.w hx] simp theorem avg_bridge (s : PoolShape) (inp : Array Word) (h : s.kw = s.kh ∧ s.strideH = s.kh ∧ s.strideW = s.kh ∧ s.padT = 0 ∧ s.padL = 0 ∧ s.padB = 0 ∧ s.padR = 0 ∧ s.ceilMode = false ∧ s.countIncludePad = false ∧ 0 < s.kh ∧ s.kh ≤ s.h ∧ s.kh ≤ s.w) : avgpoolSpecO s.c s.h s.w s.kh inp = avgpoolSpec s inp := by obtain ⟨h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11, h12⟩ := h have hho : s.ho = s.h / s.kh := by simp only [PoolShape.ho, h2, h4, h6, h8]; exact pool_out _ _ h10 h11 have hwo : s.wo = s.w / s.kh := by simp only [PoolShape.wo, h3, h5, h7, h8, h1]; exact pool_out _ _ h10 h12 apply Array.ext · simp [avgpoolSpecO, avgpoolWithO, avgpoolSpec, avgpoolWith, hho, hwo] · intro q hq1 hq2 simp only [avgpoolSpecO, avgpoolWithO, avgpoolSpec, avgpoolWith, Array.getElem_ofFn] rw [hho, hwo] have hy := Nat.mod_lt (q / (s.w / s.kh)) (Nat.div_pos h11 h10) have hx := Nat.mod_lt q (Nat.div_pos h12 h10) have hwin := pool_window s _ _ ⟨h1, h2, h3, h4, h5⟩ hy hx have hdiv : s.divisor (q / (s.w / s.kh) % (s.h / s.kh)) (q % (s.w / s.kh)) = s.kh * s.kh := by simp only [PoolShape.divisor, h9, Bool.false_eq_true, ↓reduceIte, hwin] rw [hwin, hdiv] rfl theorem max_bridge (s : PoolShape) (inp : Array Word) (h : s.kw = s.kh ∧ s.strideH = s.kh ∧ s.strideW = s.kh ∧ s.padT = 0 ∧ s.padL = 0 ∧ s.padB = 0 ∧ s.padR = 0 ∧ s.ceilMode = false ∧ 0 < s.kh ∧ s.kh ≤ s.h ∧ s.kh ≤ s.w) : maxpoolSpecO s.c s.h s.w s.kh inp = maxpoolSpec s inp := by obtain ⟨h1, h2, h3, h4, h5, h6, h7, h8, h10, h11, h12⟩ := h have hho : s.ho = s.h / s.kh := by simp only [PoolShape.ho, h2, h4, h6, h8]; exact pool_out _ _ h10 h11 have hwo : s.wo = s.w / s.kh := by simp only [PoolShape.wo, h3, h5, h7, h8, h1]; exact pool_out _ _ h10 h12 apply Array.ext · simp [maxpoolSpecO, maxpoolSpec, hho, hwo] · intro q hq1 hq2 simp only [maxpoolSpecO, maxpoolSpec, Array.getElem_ofFn] rw [hho, hwo] have hy := Nat.mod_lt (q / (s.w / s.kh)) (Nat.div_pos h11 h10) have hx := Nat.mod_lt q (Nat.div_pos h12 h10) rw [pool_window s _ _ ⟨h1, h2, h3, h4, h5⟩ hy hx] rfl theorem swap_win (s : OS) (inp : Array Word) (hw : s.w = 1) (hkw : s.kw = 1) (hp : s.pad = 0) (y t : Nat) : windowAtO (swapO s) inp 0 y t = windowAtO s inp y 0 t := by simp only [windowAtO, swapO, hw, hkw, hp, Nat.mul_one, Nat.one_mul, Nat.mod_one, Nat.div_one, Nat.zero_mul, Nat.add_zero, Nat.sub_zero, Nat.not_lt_zero, false_or, Nat.lt_irrefl] by_cases h1 : s.h ≤ y * s.stride + t % s.kh · simp [h1] · simp [h1] theorem conv_swap (s : OS) (relu : Bool) (inp wts b : Array Word) (hw : s.w = 1) (hkw : s.kw = 1) (hp : s.pad = 0) : conv2dSpecO (swapO s) relu inp wts b = conv2dSpecO s relu inp wts b := by have hho : (swapO s).ho = 1 := by simp [OS.ho, swapO, hp] have hwo : (swapO s).wo = s.ho := by simp [OS.wo, OS.ho, swapO, hp] have hwo' : s.wo = 1 := by simp [OS.wo, hw, hkw, hp] have hk : (swapO s).cin * (swapO s).kh * (swapO s).kw = s.cin * s.kh * s.kw := by simp [swapO, hkw] apply Array.ext · simp only [conv2dSpecO, conv2dWithO, Array.size_ofFn, hho, hwo, hwo']; simp [swapO] · intro q hq1 hq2 simp only [conv2dSpecO, conv2dWithO, Array.getElem_ofFn, hho, hwo, hwo', hk, Nat.one_mul, Nat.mul_one, Nat.div_one, Nat.mod_one] simp only [swapO] congr 2 funext t by_cases ht : t < s.cin * s.kh * s.kw · simp only [ht, ↓reduceIte] have := swap_win s inp hw hkw hp (q % s.ho) t simp only [swapO] at this exact this · simp only [ht, ↓reduceIte] theorem depth_swap (s : OS) (relu : Bool) (inp wts b : Array Word) (hw : s.w = 1) (hkw : s.kw = 1) (hp : s.pad = 0) : depthwiseSpecO (swapO s) relu inp wts b = depthwiseSpecO s relu inp wts b := by have hho : (swapO s).ho = 1 := by simp [OS.ho, swapO, hp] have hwo : (swapO s).wo = s.ho := by simp [OS.wo, OS.ho, swapO, hp] have hwo' : s.wo = 1 := by simp [OS.wo, hw, hkw, hp] have hk : (swapO s).kh * (swapO s).kw = s.kh * s.kw := by simp [swapO, hkw] apply Array.ext · simp only [depthwiseSpecO, depthwiseWithO, Array.size_ofFn, hho, hwo, hwo']; simp [swapO] · intro q hq1 hq2 simp only [depthwiseSpecO, depthwiseWithO, Array.getElem_ofFn, hho, hwo, hwo', hk, Nat.one_mul, Nat.mul_one, Nat.div_one, Nat.mod_one] simp only [swapO] congr 2 funext t by_cases ht : t < s.kh * s.kw · simp only [ht, ↓reduceIte] have := swap_win s inp hw hkw hp (q % s.ho) (q / s.ho * (s.kh * s.kw) + t) simp only [swapO] at this exact this · simp only [ht, ↓reduceIte] theorem conv_fix (s : OS) (relu : Bool) (inp wts b : Array Word) : conv2dSpecO (fixO s) relu inp wts b = conv2dSpecO s relu inp wts b := by unfold fixO; split_ifs with h · exact conv_swap s relu inp wts b h.1 h.2.1 h.2.2 · rfl theorem depth_fix (s : OS) (relu : Bool) (inp wts b : Array Word) : depthwiseSpecO (fixO s) relu inp wts b = depthwiseSpecO s relu inp wts b := by unfold fixO; split_ifs with h · exact depth_swap s relu inp wts b h.1 h.2.1 h.2.2 · rfl theorem conv2dF_eq : conv2dF = conv2dSpec := by funext s relu inp wts b unfold conv2dF split_ifs with h · rw [C.qB7, conv_fix]; exact conv_bridge s relu inp wts b h · rw [Pinned.dotFn_eq_dotOf]; rfl theorem depthwiseF_eq : depthwiseF = depthwiseSpec := by funext s relu inp wts b unfold depthwiseF split_ifs with h · rw [C.qDr, depth_fix]; exact depth_bridge s relu inp wts b h · rw [Pinned.dotFn_eq_dotOf]; rfl theorem avgpoolF_eq : avgpoolF = avgpoolSpec := by funext s inp unfold avgpoolF split_ifs with h · rw [C.qG1]; exact avg_bridge s inp h · rw [Pinned.dotFn_eq_dotOf]; rfl theorem maxpoolF_eq : maxpoolF = maxpoolSpec := by funext s inp unfold maxpoolF split_ifs with h · rw [C.maxpoolF2_eq, C.qDp]; exact max_bridge s inp h · rw [Pinned.maxpoolW_eq] end ConvFast namespace RnnFast open D (dv good ziv nfOf F1 qDo wv exactS A_mag R qBw qDm qIg qAx qAe qG5 qIq qB5 qAq qA6 qAz qA0 qDq qAf uk qEl qAb) theorem dotLoop_special_false (fa fb : Nat → UInt32) : ∀ (count index : Nat) (pos neg : Array Nat) (nz : Bool), (∀ k, index ≤ k → k < index + count → expOf (fa k) ≠ 255 ∧ expOf (fb k) ≠ 255) → (Pinned.dotLoop fa fb pos neg false nz index count).special = false | 0, _, _, _, _, _ => by simp [Pinned.dotLoop] | count + 1, index, pos, neg, nz, hfin => by have h := hfin index le_rfl (by omega) simp only [Pinned.dotLoop] have hstep : (Pinned.dotStep ⟨pos, neg, false, nz⟩ (fa index) (fb index)).special = false := by unfold Pinned.dotStep rw [if_neg (by push_neg; exact h)] simp only [Pinned.Acc.add] split_ifs <;> rfl generalize Pinned.dotStep ⟨pos, neg, false, nz⟩ (fa index) (fb index) = acc at hstep obtain ⟨p, n, sp, z⟩ := acc simp only at hstep subst hstep exact dotLoop_special_false fa fb count (index + 1) p n z (fun k h1 h2 => hfin k (by omega) (by omega)) /-- On finite inputs, `Pinned.dotFn` rounds the exact total once. -/ theorem dotFn_finite (n : Nat) (fa fb : Nat → UInt32) (hfin : ∀ k, k < n → expOf (fa k) ≠ 255 ∧ expOf (fb k) ≠ 255) : Pinned.dotFn n fa fb = finishWord (dsum (Array.ofFn (n := n) fun i => fa i) (Array.ofFn (n := n) fun i => fb i) 0 n) (-298) (n ≠ 0 && dallNZ (Array.ofFn (n := n) fun i => fa i) (Array.ofFn (n := n) fun i => fb i) 0 n) := by unfold Pinned.dotFn have hsp := dotLoop_special_false fa fb n 0 (Array.replicate 18 0) (Array.replicate 18 0) true (fun k _ hk => hfin k (by omega)) obtain ⟨-, -, hD, hz⟩ := Pinned.dotLoopFacts fa fb (Array.ofFn (n := n) fun i => fa i) (Array.ofFn (n := n) fun i => fb i) n (Pinned.getElem!_ofFn n fa) (Pinned.getElem!_ofFn n fb) Pinned.Acc.empty 0 n (by omega) (by simp [Pinned.Acc.empty]) (by simp [Pinned.Acc.empty]) hsp simp only [Pinned.Acc.empty] at hD hz hsp simp only [hsp, Bool.false_eq_true, ite_false] rw [Pinned.finishFast_eq] change finishWord (Pinned.Acc.total _) _ _ = _ have h0 : (⟨Array.replicate 18 0, Array.replicate 18 0, false, true⟩ : Pinned.Acc).total = 0 := Pinned.Acc.total_empty rw [hD, hz, h0] simp theorem qEcP (n : Nat) (fa fb : Nat → UInt32) (hf : ∀ j, j < n → expOf (fa j) ≠ 255 ∧ expOf (fb j) ≠ 255) (hn : (∑ j ∈ Finset.range n, rationalWord (fa j) * rationalWord (fb j)) ≠ 0) : ∃ d : FloatLib.Numerics.Dyadic, d.toRat = (∑ j ∈ Finset.range n, rationalWord (fa j) * rationalWord (fb j)) ∧ Pinned.dotFn n fa fb = toWord (Model.roundDyadic Fmt d) := by let a := Array.ofFn (n := n) fun i => fa i let b := Array.ofFn (n := n) fun i => fb i have c : (dsum a b 0 n : ℚ) * 2 ^ (-298 : Int) = ∑ j ∈ Finset.range n, rationalWord (fa j) * rationalWord (fb j) := by rw [qEl] refine Finset.sum_congr rfl fun j m => ?_ have h := Finset.mem_range.mp m rw [Nat.zero_add, qAb n fa j h, qAb n fb j h] have l : dsum a b 0 n ≠ 0 := fun h => hn (by rw [← c, h]; simp) refine ⟨ofIntDyadic (dsum a b 0 n) (-298), by rw [toRat_ofIntDyadic, c], ?_⟩ rw [dotFn_finite n fa fb hf] exact finishWord_of_ne _ _ _ _ l (toRat_ofIntDyadic _ _) /-! ## Recurrent kernels with float gate dots Each dot product is summed in binary64 over exactly decoded words (`dv`), with the sum of the absolute products; `ziv` returns the binary32 word only when both ends of the error enclosure round alike (season-1 `qDm`, `qIq`, `qDq`). Otherwise the pinned exact `Pinned.dotFn` decides. Weights are decoded once per kernel call, the step vector `[x_t; h; 1]` once per step. -/ /-! ## Recurrent kernels with float gate dots Each dot product is summed in binary64 over exactly decoded words (`dv`), with the sum of the absolute products; `ziv` returns the binary32 word only when both ends of the error enclosure round alike (season-1 `qDm`, `qIq`, `qDq`). Otherwise the pinned exact `Pinned.dotFn` decides. Weights are decoded once per kernel call (row segments, no division), the step vector `[x_t; h; 1]` once per step. LSTM: the four gates of a unit are adjacent rows, computed by one 4-row dot, and the unit's cell and hidden words follow at once. GRU: four units at a time. The output is appended step by step (`recFlat`). -/ section RnnK theorem qAd (k : Nat) (h : k < 2 ^ 32) : k.toUSize.toNat = k := by rw [Nat.toUSize_eq]; exact uk k h @[inline] def stp (acc : F1) (q : Float) : F1 := ⟨acc.s + q, acc.t + q.abs⟩ @[inline] def fget (a : FloatArray) (i : USize) : Float := if h : i < a.usize then a.uget i (qDo a i h) else 0 /-- `k` terms `V[i+j]·W[w+j]` with word indices, accumulated into `s`, `t`. -/ def rdotU (V W : FloatArray) (i w : USize) : Nat → Float → Float → F1 | 0, s, t => ⟨s, t⟩ | k + 1, s, t => let q := fget V i * fget W w rdotU V W (i + 1) (w + 1) k (s + q) (t + q.abs) /-- Push `f i, …, f (i+k-1)`. -/ @[specialize] def fpush (f : Nat → Float) : Nat → Nat → FloatArray → FloatArray | _, 0, a => a | i, k + 1, a => fpush f (i + 1) k (a.push (f i)) @[inline] def fbuild (n : Nat) (f : Nat → Float) : FloatArray := fpush f 0 n (FloatArray.emptyWithCapacity n) /-- `f j` for every `j < n`. -/ @[specialize] def allLt (f : Nat → Bool) : Nat → Bool | 0 => true | k + 1 => f k && allLt f k /-- The gate operands (as in `gateWith`). -/ @[inline] def gA (inW H : Nat) (x h : Array Word) (t j : Nat) : Word := if j < inW then x[t * inW + j]! else if j < inW + H then h[j - inW]! else oneW @[inline] def gB (inW H : Nat) (wih whh bih bhh : Array Word) (k j : Nat) : Word := if j < inW then wih[k * inW + j]! else if j < inW + H then whh[k * H + (j - inW)]! else if j = inW + H then bih[k]! else bhh[k]! @[noinline] def gateSlow (inW H : Nat) (x wih whh bih bhh h : Array Word) (t k : Nat) : Word := gateWith Pinned.dotFn inW H x wih whh bih bhh h t k /-- The end of a gate from its sums `s` (products) and `tt` (absolute products): row `r` of the decoded weights (and of `Bh`) holds the gate's row `k`. -/ @[inline] def gfinR (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (Bh : FloatArray) (r k : Nat) (s tt : Float) : Word := let bv := Bh.get! r let w := ziv (s + bv) (nfOf (inW + H + 1) * (tt + bv.abs)) if w == 0xFFFFFFFF then gateSlow inW H x wih whh bih bhh h t k else w structure F4 where s0 : Float s1 : Float s2 : Float s3 : Float t0 : Float t1 : Float t2 : Float t3 : Float /-- Four rows `w0 … w3` against the same `V` slice. -/ def rdot4U (V W : FloatArray) (i w0 w1 w2 w3 : USize) : Nat → Float → Float → Float → Float → Float → Float → Float → Float → F4 | 0, s0, s1, s2, s3, t0, t1, t2, t3 => ⟨s0, s1, s2, s3, t0, t1, t2, t3⟩ | k + 1, s0, s1, s2, s3, t0, t1, t2, t3 => let v := fget V i let q0 := v * fget W w0 let q1 := v * fget W w1 let q2 := v * fget W w2 let q3 := v * fget W w3 rdot4U V W (i + 1) (w0 + 1) (w1 + 1) (w2 + 1) (w3 + 1) k (s0 + q0) (s1 + q1) (s2 + q2) (s3 + q3) (t0 + q0.abs) (t1 + q1.abs) (t2 + q2.abs) (t3 + q3.abs) theorem ulim {i j n : USize} {m : Nat} (hj : j < n) (h : i.toNat + n.toNat ≤ m) (hm : m < 2 ^ 32) : (i + j).toNat < m := by have a := USize.lt_iff_toNat_lt.mp hj rw [qAf i j (by omega)]; omega /-- `rdot4U` without bounds checks: the reads are proved in range. -/ def rdot4T (V W : FloatArray) (i w0 w1 w2 w3 n : USize) (hs : V.size < 2 ^ 32) (hw : W.size < 2 ^ 32) (hV : i.toNat + n.toNat ≤ V.size) (h0 : w0.toNat + n.toNat ≤ W.size) (h1 : w1.toNat + n.toNat ≤ W.size) (h2 : w2.toNat + n.toNat ≤ W.size) (h3 : w3.toNat + n.toNat ≤ W.size) (j : USize) (s0 s1 s2 s3 t0 t1 t2 t3 : Float) : F4 := if hj : j < n then let v := V.uget (i + j) (ulim hj hV hs) let q0 := v * W.uget (w0 + j) (ulim hj h0 hw) let q1 := v * W.uget (w1 + j) (ulim hj h1 hw) let q2 := v * W.uget (w2 + j) (ulim hj h2 hw) let q3 := v * W.uget (w3 + j) (ulim hj h3 hw) rdot4T V W i w0 w1 w2 w3 n hs hw hV h0 h1 h2 h3 (j + 1) (s0 + q0) (s1 + q1) (s2 + q2) (s3 + q3) (t0 + q0.abs) (t1 + q1.abs) (t2 + q2.abs) (t3 + q3.abs) else ⟨s0, s1, s2, s3, t0, t1, t2, t3⟩ termination_by n.toNat - j.toNat decreasing_by rw [D.usz j n hj]; exact Nat.sub_lt_sub_left (USize.lt_iff_toNat_lt.mp hj) (Nat.lt_succ_self _) /-- Four rows from word offsets `w0 … w3`, `n` terms of `V` from `i`: the unchecked loop when every read is in range (checked once), else `rdot4U`. -/ @[inline] def dot4 (V W : FloatArray) (i w0 w1 w2 w3 n : Nat) : F4 := if h : V.size ≤ 4294967295 ∧ W.size ≤ 4294967295 ∧ i + n ≤ V.size ∧ w0 + n ≤ W.size ∧ w1 + n ≤ W.size ∧ w2 + n ≤ W.size ∧ w3 + n ≤ W.size then rdot4T V W i.toUSize w0.toUSize w1.toUSize w2.toUSize w3.toUSize n.toUSize (by omega) (by omega) (by rw [qAd i (by omega), qAd n (by omega)]; exact h.2.2.1) (by rw [qAd w0 (by omega), qAd n (by omega)]; exact h.2.2.2.1) (by rw [qAd w1 (by omega), qAd n (by omega)]; exact h.2.2.2.2.1) (by rw [qAd w2 (by omega), qAd n (by omega)]; exact h.2.2.2.2.2.1) (by rw [qAd w3 (by omega), qAd n (by omega)]; exact h.2.2.2.2.2.2) 0 0 0 0 0 0 0 0 0 else rdot4U V W i.toUSize w0.toUSize w1.toUSize w2.toUSize w3.toUSize n 0 0 0 0 0 0 0 0 structure Q4 where a : Word b : Word c : Word d : Word /-- Rows `k, …` of `rows`, four at a time while four remain. -/ @[specialize] def build4 (rows : Nat) (f4 : Nat → Q4) (f1 : Nat → Word) : Nat → Nat → Array Word → Array Word | _, 0, acc => acc | k, fuel + 1, acc => if k + 4 ≤ rows then let q := f4 k build4 rows f4 f1 (k + 4) fuel ((((acc.push q.a).push q.b).push q.c).push q.d) else if k < rows then build4 rows f4 f1 (k + 1) fuel (acc.push (f1 k)) else acc /-- Two arrays `(f k).1 …`, `(f k).2 …`. -/ @[specialize] def build2 (f : Nat → Word × Word) : Nat → Nat → Array Word → Array Word → Array Word × Array Word | _, 0, a, b => (a, b) | k, n + 1, a, b => let p := f k build2 f (k + 1) n (a.push p.1) (b.push p.2) /-- Rows `r, …, r + n − 1`, each appended by `row`. -/ @[specialize] def rowsB (row : Nat → FloatArray → FloatArray) : Nat → Nat → FloatArray → FloatArray | _, 0, acc => acc | r, n + 1, acc => rowsB row (r + 1) n (row r acc) /-- Weight row `[wih k; whh k; bih k]`, decoded. -/ @[inline] def row3 (inW H : Nat) (wih whh bih : Array Word) (k : Nat) (acc : FloatArray) : FloatArray := (fpush (fun q => dv whh[q]!) (k * H) H (fpush (fun q => dv wih[q]!) (k * inW) inW acc)).push (dv bih[k]!) /-- Run `step` for `t, …, t + n − 1`, appending each hidden state to `out`. -/ @[specialize] def recFlat (step : Nat → Array Word × Array Word → Array Word × Array Word) : Nat → Nat → Array Word × Array Word → Array Word → Array Word | _, 0, _, out => out | t, n + 1, st, out => let st' := step t st recFlat step (t + 1) n st' (out ++ st'.1) @[noinline] def cellSlow (f i c g : Word) : Word := Pinned.dotFn 2 (fun j => if j = 0 then f else i) (fun j => if j = 0 then c else g) /-- `R(f·c + i·g)` (the LSTM cell). -/ @[inline] def cellF (f i c g : Word) : Word := if good f && good i && good c && good g then let r := stp (stp ⟨0, 0⟩ (dv f * dv c)) (dv i * dv g) let z := dv 0 let w := ziv (r.s + z) (nfOf 2 * (r.t + z.abs)) if w == 0xFFFFFFFF then cellSlow f i c g else w else cellSlow f i c g @[inline] def small (w : Word) : Bool := (w &&& 0x7FFFFFFF) < 0x40000000 @[noinline] def mulSlow (o t : Word) : Word := toWord (Model.mul (ofW o) (ofW t)) /-- `R(o·t)` (the LSTM hidden state). -/ @[inline] def mulF (o t : Word) : Word := if good o && good t && small o && small t then let r := stp ⟨0, 0⟩ (dv o * dv t) let z := dv 0 let w := ziv (r.s + z) (nfOf 1 * (r.t + z.abs)) if w == 0xFFFFFFFF then mulSlow o t else w else mulSlow o t /-- LSTM unit `u`: rows `4u … 4u+3` of `W` hold its gates `i f g o` (rows `u, H+u, 2H+u, 3H+u`); the new hidden and cell words. -/ @[inline] def lstmU (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h cs : Array Word) (t : Nat) (V W Bh : FloatArray) (u : Nat) : Word × Word := let N := inW + H + 1 let r := dot4 V W 0 (4 * u * N) ((4 * u + 1) * N) ((4 * u + 2) * N) ((4 * u + 3) * N) N let gi := gfinR inW H x wih whh bih bhh h t Bh (4 * u) u r.s0 r.t0 let gf := gfinR inW H x wih whh bih bhh h t Bh (4 * u + 1) (H + u) r.s1 r.t1 let gg := gfinR inW H x wih whh bih bhh h t Bh (4 * u + 2) (2 * H + u) r.s2 r.t2 let go := gfinR inW H x wih whh bih bhh h t Bh (4 * u + 3) (3 * H + u) r.s3 r.t3 let c' := cellF (sig gf) (sig gi) cs[u]! (tanh gg) (mulF (sig go) (tanh c'), c') @[specialize] def lstmStepF (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh : Array Word) (W Bh : FloatArray) (t : Nat) (st : Array Word × Array Word) : Array Word × Array Word := if allLt (fun j => good (gA inW H x st.1 t j)) (inW + H) then let V := fbuild (inW + H + 1) (fun j => dv (gA inW H x st.1 t j)) build2 (lstmU sig tanh inW H x wih whh bih bhh st.1 st.2 t V W Bh) 0 H (Array.emptyWithCapacity H) (Array.emptyWithCapacity H) else lstmStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t st @[specialize] def lstmF (sig tanh : Word → Word) (T inW H : Nat) (x wih whh bih bhh : Array Word) : Array Word := if wih.all good && whh.all good && bih.all good && bhh.all good && decide (inW + H + 3 < 2 ^ 20) && decide (H < 1024) then let W := rowsB (fun r acc => row3 inW H wih whh bih ((r % 4) * H + r / 4) acc) 0 (4 * H) (FloatArray.emptyWithCapacity (4 * H * (inW + H + 1))) let Bh := fbuild (4 * H) (fun r => dv bhh[(r % 4) * H + r / 4]!) recFlat (lstmStepF sig tanh inW H x wih whh bih bhh W Bh) 0 T (Array.replicate H 0, Array.replicate H 0) (Array.emptyWithCapacity (T * H)) else lstmWith Pinned.dotFn sig tanh T inW H x wih whh bih bhh @[noinline] def hnSlow (H : Nat) (whh bhh h : Array Word) (u : Nat) : Word := Pinned.dotFn (H + 1) (fun j => if j < H then h[j]! else oneW) (fun j => if j < H then whh[(2 * H + u) * H + j]! else bhh[2 * H + u]!) /-- `hn` row `u`: `R(whh[2H+u]·h + bhh[2H+u])`; `Wh` rows of `H`, `Bn` the biases. -/ @[inline] def hnFin (H : Nat) (whh bhh h : Array Word) (Bn : FloatArray) (u : Nat) (s tt : Float) : Word := let bv := Bn.get! u let w := ziv (s + bv) (nfOf H * (tt + bv.abs)) if w == 0xFFFFFFFF then hnSlow H whh bhh h u else w @[inline] def hnF (inW H : Nat) (whh bhh h : Array Word) (V Wh Bn : FloatArray) (u : Nat) : Word := let r := rdotU V Wh inW.toUSize (u * H).toUSize H 0 0 hnFin H whh bhh h Bn u r.s r.t @[noinline] def candSlow (inW H : Nat) (x wih bih : Array Word) (t u : Nat) (hu ru : Word) : Word := Pinned.dotFn (inW + 2) (fun j => if j < inW then x[t * inW + j]! else if j = inW then oneW else hu) (fun j => if j < inW then wih[(2 * H + u) * inW + j]! else if j = inW then bih[2 * H + u]! else ru) /-- The GRU candidate's pre-activation `R(wih[2H+u]·x_t + bih[2H+u] + r·hn)`; `Wc` rows of `[wih (2H+u); bih (2H+u)]` (stride `inW + 1`). -/ @[inline] def candFin (inW H : Nat) (x wih bih : Array Word) (t : Nat) (V Wc : FloatArray) (u : Nat) (hu ru : Word) (r0 : F1) : Word := if good hu && good ru then let r1 := stp r0 (V.get! (inW + H) * Wc.get! (u * (inW + 1) + inW)) let r := stp r1 (dv hu * dv ru) let z := dv 0 let w := ziv (r.s + z) (nfOf (inW + 2) * (r.t + z.abs)) if w == 0xFFFFFFFF then candSlow inW H x wih bih t u hu ru else w else candSlow inW H x wih bih t u hu ru @[inline] def candF (inW H : Nat) (x wih bih : Array Word) (t : Nat) (V Wc : FloatArray) (u : Nat) (hu ru : Word) : Word := candFin inW H x wih bih t V Wc u hu ru (rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0) @[noinline] def upd3Slow (nu zu hu : Word) : Word := Pinned.dotFn 3 (fun j => if j = 2 then hu else nu) (fun j => if j = 0 then oneW else if j = 1 then negW zu else zu) /-- `R(n − z·n + z·h)`. -/ @[inline] def updF (nu zu hu : Word) : Word := if good nu && good zu && good hu && good (negW zu) then let r := stp (stp (stp ⟨0, 0⟩ (dv nu * dv oneW)) (dv nu * dv (negW zu))) (dv hu * dv zu) let z := dv 0 let w := ziv (r.s + z) (nfOf 3 * (r.t + z.abs)) if w == 0xFFFFFFFF then upd3Slow nu zu hu else w else upd3Slow nu zu hu /-- GRU unit `u` from its sums: `r`, `z` (rows `2u`, `2u+1` of the decoded gate weights), `hn` and the candidate's input part. -/ @[inline] def gruUnit (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (V Brz Bn Wc : FloatArray) (u : Nat) (sr tr sz tz sh th sc tc : Float) : Word := let rr := sig (gfinR inW H x wih whh bih bhh h t Brz (2 * u) u sr tr) let zz := sig (gfinR inW H x wih whh bih bhh h t Brz (2 * u + 1) (H + u) sz tz) updF (tanh (candFin inW H x wih bih t V Wc u (hnFin H whh bhh h Bn u sh th) rr ⟨sc, tc⟩)) zz h[u]! /-- GRU units `u … u+3`. -/ @[inline] def gru4 (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (V Wrz Brz Wh Bn Wc : FloatArray) (u : Nat) : Q4 := let N := inW + H + 1 let a := dot4 V Wrz 0 (2 * u * N) ((2 * u + 1) * N) ((2 * u + 2) * N) ((2 * u + 3) * N) N let b := dot4 V Wrz 0 ((2 * u + 4) * N) ((2 * u + 5) * N) ((2 * u + 6) * N) ((2 * u + 7) * N) N let hh := dot4 V Wh inW (u * H) ((u + 1) * H) ((u + 2) * H) ((u + 3) * H) H let c := dot4 V Wc 0 (u * (inW + 1)) ((u + 1) * (inW + 1)) ((u + 2) * (inW + 1)) ((u + 3) * (inW + 1)) inW ⟨gruUnit sig tanh inW H x wih whh bih bhh h t V Brz Bn Wc u a.s0 a.t0 a.s1 a.t1 hh.s0 hh.t0 c.s0 c.t0, gruUnit sig tanh inW H x wih whh bih bhh h t V Brz Bn Wc (u + 1) a.s2 a.t2 a.s3 a.t3 hh.s1 hh.t1 c.s1 c.t1, gruUnit sig tanh inW H x wih whh bih bhh h t V Brz Bn Wc (u + 2) b.s0 b.t0 b.s1 b.t1 hh.s2 hh.t2 c.s2 c.t2, gruUnit sig tanh inW H x wih whh bih bhh h t V Brz Bn Wc (u + 3) b.s2 b.t2 b.s3 b.t3 hh.s3 hh.t3 c.s3 c.t3⟩ /-- GRU unit `u` alone. -/ @[inline] def gru1 (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (V Wrz Brz Wh Bn Wc : FloatArray) (u : Nat) : Word := let N := inW + H + 1 let a := rdotU V Wrz 0 (2 * u * N).toUSize N 0 0 let b := rdotU V Wrz 0 ((2 * u + 1) * N).toUSize N 0 0 let hh := rdotU V Wh inW.toUSize (u * H).toUSize H 0 0 let c := rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0 gruUnit sig tanh inW H x wih whh bih bhh h t V Brz Bn Wc u a.s a.t b.s b.t hh.s hh.t c.s c.t @[specialize] def gruStepF (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh : Array Word) (Wrz Brz Wh Bn Wc : FloatArray) (t : Nat) (st : Array Word × Array Word) : Array Word × Array Word := if allLt (fun j => good (gA inW H x st.1 t j)) (inW + H) then let V := fbuild (inW + H + 1) (fun j => dv (gA inW H x st.1 t j)) (build4 H (gru4 sig tanh inW H x wih whh bih bhh st.1 t V Wrz Brz Wh Bn Wc) (gru1 sig tanh inW H x wih whh bih bhh st.1 t V Wrz Brz Wh Bn Wc) 0 H (Array.emptyWithCapacity H), st.2) else gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t st @[specialize] def gruF (sig tanh : Word → Word) (T inW H : Nat) (x wih whh bih bhh : Array Word) : Array Word := if wih.all good && whh.all good && bih.all good && bhh.all good && decide (inW + H + 3 < 2 ^ 20) && decide (H < 1024) then let Wrz := rowsB (fun r acc => row3 inW H wih whh bih ((r % 2) * H + r / 2) acc) 0 (2 * H) (FloatArray.emptyWithCapacity (2 * H * (inW + H + 1))) let Brz := fbuild (2 * H) (fun r => dv bhh[(r % 2) * H + r / 2]!) let Wh := rowsB (fun u acc => fpush (fun q => dv whh[q]!) ((2 * H + u) * H) H acc) 0 H (FloatArray.emptyWithCapacity (H * H)) let Bn := fbuild H (fun u => dv bhh[2 * H + u]!) let Wc := rowsB (fun u acc => (fpush (fun q => dv wih[q]!) ((2 * H + u) * inW) inW acc).push (dv bih[2 * H + u]!)) 0 H (FloatArray.emptyWithCapacity (H * (inW + 1))) recFlat (gruStepF sig tanh inW H x wih whh bih bhh Wrz Brz Wh Bn Wc) 0 T (Array.replicate H 0, #[]) (Array.emptyWithCapacity (T * H)) else gruWith Pinned.dotFn sig tanh T inW H x wih whh bih bhh end RnnK section RnnP theorem fa_push_get (a : FloatArray) (v : Float) (j : Nat) : (a.push v).get! j = if j < a.size then a.get! j else if j = a.size then v else default := by obtain ⟨ds⟩ := a show (ds.push v)[j]! = if j < ds.size then ds[j]! else if j = ds.size then v else default split_ifs with h1 h2 · rw [getElem!_pos (ds.push v) j (by simp; omega), getElem!_pos ds j h1, Array.getElem_push_lt h1] · subst h2; rw [getElem!_pos (ds.push v) ds.size (by simp), Array.getElem_push_eq] · rw [getElem!_neg (ds.push v) j (by simp; omega)] theorem fa_push_size (a : FloatArray) (v : Float) : (a.push v).size = a.size + 1 := by obtain ⟨ds⟩ := a simp [FloatArray.push, FloatArray.size] theorem fpush_size (f : Nat → Float) : ∀ (i k : Nat) (a : FloatArray), (fpush f i k a).size = a.size + k | _, 0, _ => rfl | i, k + 1, a => by rw [fpush, fpush_size f (i + 1) k, fa_push_size]; omega theorem fpush_get (f : Nat → Float) : ∀ (i k : Nat) (a : FloatArray) (j : Nat), (j < a.size → (fpush f i k a).get! j = a.get! j) ∧ (a.size ≤ j → j < a.size + k → (fpush f i k a).get! j = f (i + (j - a.size))) | _, 0, a, j => ⟨fun _ => rfl, fun h1 h2 => by omega⟩ | i, k + 1, a, j => by obtain ⟨ih1, ih2⟩ := fpush_get f (i + 1) k (a.push (f i)) j rw [fa_push_size] at ih1 ih2 refine ⟨fun h => ?_, fun h1 h2 => ?_⟩ · rw [fpush, ih1 (by omega), fa_push_get, if_pos h] · rw [fpush] by_cases hj : j = a.size · subst hj rw [ih1 (by omega), fa_push_get, if_neg (by omega), if_pos rfl]; simp · rw [ih2 (by omega) (by omega)]; congr 1; omega theorem fbuild_get (n : Nat) (f : Nat → Float) (j : Nat) (hj : j < n) : (fbuild n f).get! j = f j := by have h0 : (FloatArray.emptyWithCapacity n).size = 0 := rfl have := (fpush_get f 0 n (FloatArray.emptyWithCapacity n) j).2 (by omega) (by omega) rw [fbuild, this, h0]; simp theorem fget_eq (a : FloatArray) (i : USize) (h : i.toNat < a.size) (hs : a.size < 2 ^ 32) : fget a i = a.get! i.toNat := by have hu : i < a.usize := by rw [USize.lt_iff_toNat_lt] simp only [FloatArray.usize, Nat.toUSize_eq] have h1 : 2 ^ 32 ≤ USize.size := USize.le_size have h3 : USize.size = 2 ^ System.Platform.numBits := rfl rw [USize.toNat_ofNat', Nat.mod_eq_of_lt (by omega)] exact h unfold fget rw [dif_pos hu] obtain ⟨ds⟩ := a show ds[i.toNat] = ds[i.toNat]! rw [getElem!_pos ds i.toNat h] theorem rdotU_eq (V W : FloatArray) (hV : V.size < 2 ^ 32) (hW : W.size < 2 ^ 32) : ∀ (k : Nat) (i w : USize) (s t : Float), i.toNat + k ≤ V.size → w.toNat + k ≤ W.size → rdotU V W i w k s t = (List.range k).foldl (fun acc j => stp acc (V.get! (i.toNat + j) * W.get! (w.toNat + j))) ⟨s, t⟩ | 0, _, _, _, _, _, _ => rfl | k + 1, i, w, s, t, hi, hw => by have hi1 : (i + 1).toNat = i.toNat + 1 := by have := qAf i 1 (by simp; omega); simpa using this have hw1 : (w + 1).toNat = w.toNat + 1 := by have := qAf w 1 (by simp; omega); simpa using this rw [rdotU, rdotU_eq V W hV hW k (i + 1) (w + 1) _ _ (by omega) (by omega), List.range_succ_eq_map, List.foldl_cons, List.foldl_map, fget_eq V i (by omega) hV, fget_eq W w (by omega) hW] simp only [hi1, hw1, Nat.add_zero] congr 1 funext acc j rw [show i.toNat + 1 + j = i.toNat + (j + 1) by omega, show w.toNat + 1 + j = w.toNat + (j + 1) by omega] theorem fbuild_size (n : Nat) (f : Nat → Float) : (fbuild n f).size = n := by rw [fbuild, fpush_size, show (FloatArray.emptyWithCapacity n).size = 0 from rfl, Nat.zero_add] theorem foldl_stp_congr (g g' : Nat → Float) : ∀ (l : List Nat) (acc : F1), (∀ t ∈ l, g t = g' t) → l.foldl (fun acc t => stp acc (g t)) acc = l.foldl (fun acc t => stp acc (g' t)) acc | [], _, _ => rfl | t :: l, acc, h => by rw [List.foldl_cons, List.foldl_cons, h t (List.mem_cons_self ..)] exact foldl_stp_congr g g' l _ fun u hu => h u (List.mem_cons_of_mem _ hu) theorem allLt_spec (f : Nat → Bool) : ∀ n, allLt f n = true → ∀ j, j < n → f j = true | 0, _, j, hj => by omega | n + 1, h, j, hj => by simp only [allLt, Bool.and_eq_true] at h rcases Nat.lt_succ_iff_lt_or_eq.mp hj with hj | hj · exact allLt_spec f n h.2 j hj · subst hj; exact h.1 theorem good_zero : good 0 = true := by decide theorem good_one : good oneW = true := by decide theorem all_good (a : Array Word) (h : a.all good = true) (i : Nat) : good a[i]! = true := by by_cases hi : i < a.size · rw [getElem!_pos a i hi] exact (Array.all_eq_true.mp h) i hi · rw [getElem!_neg a i hi]; exact good_zero theorem rat_zero : rationalWord (0 : Word) = 0 := by norm_num [rationalWord, decodeD, show expOf 0 = 0 by decide, show fracOf 0 = 0 by decide, FloatLib.Numerics.Dyadic.toRat, FloatLib.Numerics.Dyadic.signedSignificand] theorem fin_ofW {w : Word} (h : expOf w ≠ 255) : Model.isFinite (ofW w) = true := by simp [ofW, isFinite_ofUInt32, h] /-- The float path for a dot whose last term is `oneW · fb N`. -/ theorem fastBias (N : Nat) (hN : N < 2 ^ 20) (fa fb : Nat → Word) (hx : ∀ t, t < N → good (fa t) = true) (hw : ∀ t, t < N → good (fb t) = true) (hb : good (fb N) = true) (h1 : fa N = oneW) (g : Nat → Float) (hg : ∀ t, t < N → g t = dv (fa t) * dv (fb t)) (bv : Float) (hbv : bv = dv (fb N)) (h : ziv (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).s + bv) (nfOf N * (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).t + bv.abs)) ≠ 0xFFFFFFFF) : ziv (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).s + bv) (nfOf N * (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).t + bv.abs)) = Pinned.dotFn (N + 1) fa fb := by subst hbv have hr : (List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩ = (List.range N).foldl (fun acc t => stp acc (dv (fa t) * dv (fb t))) ⟨0, 0⟩ := foldl_stp_congr _ _ _ _ fun t ht => hg t (List.mem_range.mp ht) rw [hr] at h ⊢ obtain ⟨-, -, hbig⟩ := qBw _ _ h obtain ⟨hlo, hhi⟩ := qDm N hN fa fb (fb N) hx hw hb (List.range N) List.nodup_range (fun t ht => List.mem_range.mp ht) (fun t ht hn => absurd (List.mem_range.mpr ht) hn) _ _ ⟨rfl, rfl⟩ hbig have hsum : ((∑ j ∈ Finset.range (N + 1), rationalWord (fa j) * rationalWord (fb j) : ℚ) : ℝ) = exactS N fa fb (fb N) := by rw [Finset.sum_range_succ, h1, qIg, one_mul, Rat.cast_add, Rat.cast_sum, exactS, qAx (fb N) (qAe _ hb)] congr 1 refine Finset.sum_congr rfl fun t ht => ?_ have a := Finset.mem_range.mp ht rw [qAx _ (qAe _ (hx t a)), qAx _ (qAe _ (hw t a)), Rat.cast_mul] have hne : (∑ j ∈ Finset.range (N + 1), rationalWord (fa j) * rationalWord (fb j)) ≠ 0 := fun h0 => qG5 _ _ _ hlo hhi h (by rw [← hsum, h0, Rat.cast_zero]) obtain ⟨d, hd, hD⟩ := qEcP (N + 1) fa fb (fun j hj => by rcases Nat.lt_succ_iff_lt_or_eq.mp hj with hj | hj · exact ⟨qAe _ (hx j hj), qAe _ (hw j hj)⟩ · subst hj; rw [h1]; exact ⟨by decide, qAe _ hb⟩) hne rw [hD] exact qIq _ _ d (by rw [hd, hsum]; exact hlo) (by rw [hd, hsum]; exact hhi) h /-- The float path for a dot of `N` terms (no bias): the sum carries `dv 0`. -/ theorem fastNB (N : Nat) (hN : N < 2 ^ 20) (fa fb : Nat → Word) (hx : ∀ t, t < N → good (fa t) = true) (hw : ∀ t, t < N → good (fb t) = true) (g : Nat → Float) (hg : ∀ t, t < N → g t = dv (fa t) * dv (fb t)) (h : ziv (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).s + dv 0) (nfOf N * (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).t + (dv 0).abs)) ≠ 0xFFFFFFFF) : ziv (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).s + dv 0) (nfOf N * (((List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩).t + (dv 0).abs)) = Pinned.dotFn N fa fb := by have hr : (List.range N).foldl (fun acc t => stp acc (g t)) ⟨0, 0⟩ = (List.range N).foldl (fun acc t => stp acc (dv (fa t) * dv (fb t))) ⟨0, 0⟩ := foldl_stp_congr _ _ _ _ fun t ht => hg t (List.mem_range.mp ht) rw [hr] at h ⊢ obtain ⟨-, -, hbig⟩ := qBw _ _ h obtain ⟨hlo, hhi⟩ := qDm N hN fa fb 0 hx hw good_zero (List.range N) List.nodup_range (fun t ht => List.mem_range.mp ht) (fun t ht hn => absurd (List.mem_range.mpr ht) hn) _ _ ⟨rfl, rfl⟩ hbig have hsum : ((∑ j ∈ Finset.range N, rationalWord (fa j) * rationalWord (fb j) : ℚ) : ℝ) = exactS N fa fb 0 := by rw [Rat.cast_sum, exactS, qAx 0 (qAe _ good_zero), rat_zero, Rat.cast_zero, add_zero] refine Finset.sum_congr rfl fun t ht => ?_ have a := Finset.mem_range.mp ht rw [qAx _ (qAe _ (hx t a)), qAx _ (qAe _ (hw t a)), Rat.cast_mul] have hne : (∑ j ∈ Finset.range N, rationalWord (fa j) * rationalWord (fb j)) ≠ 0 := fun h0 => qG5 _ _ _ hlo hhi h (by rw [← hsum, h0, Rat.cast_zero]) obtain ⟨d, hd, hD⟩ := qEcP N fa fb (fun j hj => ⟨qAe _ (hx j hj), qAe _ (hw j hj)⟩) hne rw [hD] exact qIq _ _ d (by rw [hd, hsum]; exact hlo) (by rw [hd, hsum]; exact hhi) h theorem small_le (w : Word) (hg : good w = true) (hs : small w = true) : |wv w| ≤ 2 := by have h1 := qB5 w hg have hq := qAq w have hlt : (w &&& 0x7FFFFFFF).toNat < 2 ^ 30 := by have : (w &&& 0x7FFFFFFF) < 0x40000000 := by simpa [small] using hs exact (UInt32.lt_iff_toNat_lt.mp this) rw [hq] at hlt rw [h1] have h2 := qA6 (w.toNat % 2 ^ 31) (2 ^ 30) hlt.le (by rcases qAz w hg with h | h <;> omega) refine h2.trans (le_of_eq ?_) norm_num [A_mag] theorem posMax32 : (4 : ℝ) ≤ Model.toReal (Model.posMaxFinite Fmt) := by rw [Model.toReal_posMaxFinite, show Model.pow2 Fmt.fracWidth + Fmt.maxFiniteFracField = 2 ^ 24 - 1 by decide +kernel, show Fmt.maxNormalExponent - Int.ofNat Fmt.fracWidth = 104 by decide +kernel, Model.bpow, qA0] norm_num /-- The float path for one product, against FloatLib's `mul`. -/ theorem fastMul (o t : Word) (ho : good o = true) (ht : good t = true) (so : small o = true) (st : small t = true) (h : ziv ((stp ⟨0, 0⟩ (dv o * dv t)).s + dv 0) (nfOf 1 * ((stp ⟨0, 0⟩ (dv o * dv t)).t + (dv 0).abs)) ≠ 0xFFFFFFFF) : ziv ((stp ⟨0, 0⟩ (dv o * dv t)).s + dv 0) (nfOf 1 * ((stp ⟨0, 0⟩ (dv o * dv t)).t + (dv 0).abs)) = toWord (Model.mul (ofW o) (ofW t)) := by have hl : (List.range 1).foldl (fun acc j => stp acc (dv ((fun _ => o) j) * dv ((fun _ => t) j))) ⟨0, 0⟩ = stp ⟨0, 0⟩ (dv o * dv t) := by simp only [List.range_one, List.foldl_cons, List.foldl_nil] rw [← hl] at h ⊢ obtain ⟨-, -, hbig⟩ := qBw _ _ h obtain ⟨hlo, hhi⟩ := qDm 1 (by norm_num) (fun _ => o) (fun _ => t) 0 (fun _ _ => ho) (fun _ _ => ht) good_zero (List.range 1) List.nodup_range (fun t ht => List.mem_range.mp ht) (fun t ht hn => absurd (List.mem_range.mpr ht) hn) _ _ ⟨rfl, rfl⟩ hbig have hv : exactS 1 (fun _ => o) (fun _ => t) 0 = Model.toReal (ofW o) * Model.toReal (ofW t) := by have h0 : Model.toReal (ofW 0) = 0 := by have := qAx 0 (qAe _ good_zero) rw [wv] at this; rw [this, rat_zero, Rat.cast_zero] simp [exactS, h0, wv] rw [hv] at hlo hhi have hfo := fin_ofW (qAe _ ho) have hft := fin_ofW (qAe _ ht) have hbound : |Model.toReal (ofW o)| * |Model.toReal (ofW t)| ≤ Model.toReal (Model.posMaxFinite Fmt) := by have a := small_le o ho so have b := small_le t ht st simp only [wv] at a b exact le_trans (mul_le_mul a b (abs_nonneg _) zero_le_two) (le_trans (le_of_eq (by norm_num)) posMax32) have hf := Model.isFinite_mul_of_abs_mul_le_posMaxFinite (ofW o) (ofW t) (by decide) hfo hft hbound have hM := Model.toReal_mul_eq_roundAt_of_abs_mul_le_posMaxFinite (ofW o) (ofW t) (by decide) hfo hft hbound exact (qDq _ _ _ hlo hhi h _ hf hM).symm theorem rdot4U_spec (V W : FloatArray) : ∀ (k : Nat) (i w0 w1 w2 w3 : USize) (s0 s1 s2 s3 t0 t1 t2 t3 : Float), rdot4U V W i w0 w1 w2 w3 k s0 s1 s2 s3 t0 t1 t2 t3 = ⟨(rdotU V W i w0 k s0 t0).s, (rdotU V W i w1 k s1 t1).s, (rdotU V W i w2 k s2 t2).s, (rdotU V W i w3 k s3 t3).s, (rdotU V W i w0 k s0 t0).t, (rdotU V W i w1 k s1 t1).t, (rdotU V W i w2 k s2 t2).t, (rdotU V W i w3 k s3 t3).t⟩ | 0, _, _, _, _, _, _, _, _, _, _, _, _, _ => rfl | k + 1, i, w0, w1, w2, w3, s0, s1, s2, s3, t0, t1, t2, t3 => by rw [rdot4U, rdot4U_spec V W k] rfl theorem push_ofFn (g : Nat → Word) (k : Nat) : (Array.ofFn (n := k) fun i => g i.val).push (g k) = Array.ofFn (n := k + 1) fun i => g i.val := by apply Array.ext · simp · intro i h1 h2 simp only [Array.size_push, Array.size_ofFn] at h1 rw [Array.getElem_ofFn] by_cases hi : i < k · rw [Array.getElem_push_lt (by simpa using hi), Array.getElem_ofFn] · have : i = k := by omega subst this simp [Array.getElem_push] theorem build4_spec (rows : Nat) (f4 : Nat → Q4) (f1 : Nat → Word) (g : Nat → Word) (h4 : ∀ k, k + 4 ≤ rows → f4 k = ⟨g k, g (k + 1), g (k + 2), g (k + 3)⟩) (h1 : ∀ k, k < rows → f1 k = g k) : ∀ (fuel k : Nat) (acc : Array Word), k ≤ rows → rows ≤ k + fuel → acc = (Array.ofFn (n := k) fun i => g i.val) → build4 rows f4 f1 k fuel acc = Array.ofFn (n := rows) fun i => g i.val | 0, k, acc, hk, hf, ha => by have : k = rows := by omega subst this; rw [build4, ha] | fuel + 1, k, acc, hk, hf, ha => by rw [build4] split_ifs with c1 c2 · rw [h4 k c1] apply build4_spec rows f4 f1 g h4 h1 fuel (k + 4) _ c1 (by omega) simp only [] rw [ha, push_ofFn, push_ofFn, push_ofFn, push_ofFn] · rw [h1 k c2] apply build4_spec rows f4 f1 g h4 h1 fuel (k + 1) _ (by omega) (by omega) rw [ha, push_ofFn] · have : k = rows := by omega subst this; exact ha theorem ofFn_get! (n : Nat) (g : Nat → Word) (i : Nat) (h : i < n) : (Array.ofFn (n := n) fun j => g j.val)[i]! = g i := by rw [getElem!_pos _ i (by simpa using h), Array.getElem_ofFn] theorem fget_uget (a : FloatArray) (i : USize) (h : i.toNat < a.size) (hs : a.size < 2 ^ 32) : fget a i = a.uget i h := by have hu : i < a.usize := by rw [USize.lt_iff_toNat_lt] simp only [FloatArray.usize, Nat.toUSize_eq] have h1 : 2 ^ 32 ≤ USize.size := USize.le_size have h3 : USize.size = 2 ^ System.Platform.numBits := rfl rw [USize.toNat_ofNat', Nat.mod_eq_of_lt (by omega)] exact h unfold fget rw [dif_pos hu] theorem stepIdx0 (j n : Nat) (hk : n - j = 0) (h : j < n) : False := by omega theorem stepIdx (k j n : Nat) (hk : n - j = k + 1) (hj : j ≤ n) : j < n ∧ n - (j + 1) = k ∧ j + 1 ≤ n := by omega theorem rdot4T_eq (V W : FloatArray) (i w0 w1 w2 w3 n : USize) (hs : V.size < 2 ^ 32) (hw : W.size < 2 ^ 32) (hV : i.toNat + n.toNat ≤ V.size) (h0 : w0.toNat + n.toNat ≤ W.size) (h1 : w1.toNat + n.toNat ≤ W.size) (h2 : w2.toNat + n.toNat ≤ W.size) (h3 : w3.toNat + n.toNat ≤ W.size) : ∀ (k : Nat) (j : USize) (s0 s1 s2 s3 t0 t1 t2 t3 : Float), n.toNat - j.toNat = k → j.toNat ≤ n.toNat → rdot4T V W i w0 w1 w2 w3 n hs hw hV h0 h1 h2 h3 j s0 s1 s2 s3 t0 t1 t2 t3 = rdot4U V W (i + j) (w0 + j) (w1 + j) (w2 + j) (w3 + j) k s0 s1 s2 s3 t0 t1 t2 t3 | 0, j, s0, s1, s2, s3, t0, t1, t2, t3, hk, hj => by rw [rdot4T, dif_neg (fun h => stepIdx0 _ _ hk (USize.lt_iff_toNat_lt.mp h)), rdot4U] | k + 1, j, s0, s1, s2, s3, t0, t1, t2, t3, hk, hj => by obtain ⟨a, b, c⟩ := stepIdx k j.toNat n.toNat hk hj have hjn : j < n := USize.lt_iff_toNat_lt.mpr a have e1 := D.usz j n hjn rw [rdot4T, dif_pos hjn] try dsimp only rw [rdot4T_eq V W i w0 w1 w2 w3 n hs hw hV h0 h1 h2 h3 k (j + 1) _ _ _ _ _ _ _ _ (by rw [e1]; exact b) (by rw [e1]; exact c), rdot4U] try dsimp only rw [fget_uget V (i + j) (ulim hjn hV hs) hs, fget_uget W (w0 + j) (ulim hjn h0 hw) hw, fget_uget W (w1 + j) (ulim hjn h1 hw) hw, fget_uget W (w2 + j) (ulim hjn h2 hw) hw, fget_uget W (w3 + j) (ulim hjn h3 hw) hw] simp only [USize.add_assoc] theorem dot4_eq (V W : FloatArray) (i w0 w1 w2 w3 n : Nat) : dot4 V W i w0 w1 w2 w3 n = rdot4U V W i.toUSize w0.toUSize w1.toUSize w2.toUSize w3.toUSize n 0 0 0 0 0 0 0 0 := by unfold dot4 split_ifs with h · rw [rdot4T_eq _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ n 0 _ _ _ _ _ _ _ _ (by rw [qAd n (by omega)]; rfl) (by simp)] simp only [USize.add_zero] · rfl theorem push_ofFnA {α : Type} (g : Nat → α) (k : Nat) : (Array.ofFn (n := k) fun i => g i.val).push (g k) = Array.ofFn (n := k + 1) fun i => g i.val := by apply Array.ext · simp · intro i h1 h2 simp only [Array.size_push, Array.size_ofFn] at h1 rw [Array.getElem_ofFn] by_cases hi : i < k · rw [Array.getElem_push_lt (by simpa using hi), Array.getElem_ofFn] · have : i = k := by omega subst this simp [Array.getElem_push] theorem ofFn_get!A {α : Type} [Inhabited α] (n : Nat) (g : Nat → α) (i : Nat) (h : i < n) : (Array.ofFn (n := n) fun j => g j.val)[i]! = g i := by rw [getElem!_pos _ i (by simpa using h), Array.getElem_ofFn] theorem ofFn_get!F {α : Type} [Inhabited α] {n : Nat} (f : Fin n → α) (i : Nat) (h : i < n) : (Array.ofFn f)[i]! = f ⟨i, h⟩ := by rw [getElem!_pos _ i (by simpa using h), Array.getElem_ofFn] theorem build2_spec (f : Nat → Word × Word) : ∀ (n k : Nat) (a b : Array Word), a = Array.ofFn (n := k) (fun i => (f i.val).1) → b = Array.ofFn (n := k) (fun i => (f i.val).2) → build2 f k n a b = (Array.ofFn (n := k + n) (fun i => (f i.val).1), Array.ofFn (n := k + n) (fun i => (f i.val).2)) | 0, k, a, b, ha, hb => by rw [build2, ha, hb]; rfl | n + 1, k, a, b, ha, hb => by rw [build2] try dsimp only rw [build2_spec f n (k + 1) _ _ (by rw [ha]; exact push_ofFnA (fun i => (f i).1) k) (by rw [hb]; exact push_ofFnA (fun i => (f i).2) k), show k + 1 + n = k + (n + 1) by omega] theorem build2_zero (f : Nat → Word × Word) (n c : Nat) : build2 f 0 n (Array.emptyWithCapacity c) (Array.emptyWithCapacity c) = (Array.ofFn (n := n) (fun i => (f i.val).1), Array.ofFn (n := n) (fun i => (f i.val).2)) := by rw [build2_spec f n 0 _ _ (by simp) (by simp), Nat.zero_add] theorem rowsB_spec (N : Nat) (row : Nat → FloatArray → FloatArray) (g : Nat → Nat → Float) (hsz : ∀ r acc, (row r acc).size = acc.size + N) (hold : ∀ r acc j, j < acc.size → (row r acc).get! j = acc.get! j) (hnew : ∀ r acc j, j < N → (row r acc).get! (acc.size + j) = g r j) : ∀ (n r : Nat) (acc : FloatArray), acc.size = r * N → (∀ r' j, r' < r → j < N → acc.get! (r' * N + j) = g r' j) → (rowsB row r n acc).size = (r + n) * N ∧ ∀ r' j, r' < r + n → j < N → (rowsB row r n acc).get! (r' * N + j) = g r' j | 0, r, acc, hs, hg => by rw [rowsB, Nat.add_zero]; exact ⟨hs, hg⟩ | n + 1, r, acc, hs, hg => by rw [rowsB] have := rowsB_spec N row g hsz hold hnew n (r + 1) (row r acc) (by rw [hsz, hs, Nat.add_mul, Nat.one_mul]) (fun r' j hr hj => by rcases Nat.lt_succ_iff_lt_or_eq.mp hr with hr | hr · have hlt : r' * N + j < acc.size := by rw [hs]; have := Nat.mul_le_mul_right N (show r' + 1 ≤ r by omega) rw [Nat.add_mul, Nat.one_mul] at this; omega rw [hold r acc _ hlt, hg r' j hr hj] · rw [hr, ← hs, hnew r acc j hj]) rw [show r + 1 + n = r + (n + 1) by omega] at this exact this theorem emp_size (c : Nat) : (FloatArray.emptyWithCapacity c).size = 0 := rfl theorem seg_spec (f : Nat → Float) (o n : Nat) (a : FloatArray) : (fpush f o n a).size = a.size + n ∧ (∀ j, j < a.size → (fpush f o n a).get! j = a.get! j) ∧ ∀ j, j < n → (fpush f o n a).get! (a.size + j) = f (o + j) := ⟨fpush_size f o n a, fun j hj => (fpush_get f o n a j).1 hj, fun j hj => by rw [(fpush_get f o n a _).2 (Nat.le_add_right _ _) (Nat.add_lt_add_left hj _), Nat.add_sub_cancel_left]⟩ theorem row3Idx (S A1 A2 inW H : Nat) (z1 : A1 = S + inW) (z2 : A2 = A1 + H) : A2 + 1 = S + (inW + H + 1) ∧ (∀ j, j < S → j < A2 ∧ j < A1) ∧ (∀ j, j < inW → S + j < A2) ∧ (∀ j, ¬ j < inW → j < inW + H → S + j < A2 ∧ S + j = A1 + (j - inW) ∧ j - inW < H) ∧ (∀ j, j < inW + H + 1 → ¬ j < inW → ¬ j < inW + H → ¬ S + j < A2 ∧ S + j = A2 ∧ j = inW + H) := by subst z1 z2 exact ⟨by omega, fun j hj => ⟨by omega, by omega⟩, fun j hj => by omega, fun j a b => ⟨by omega, by omega, by omega⟩, fun j h a b => ⟨by omega, by omega, by omega⟩⟩ theorem row3_spec (inW H : Nat) (wih whh bih bhh : Array Word) (k : Nat) (acc : FloatArray) : (row3 inW H wih whh bih k acc).size = acc.size + (inW + H + 1) ∧ (∀ j, j < acc.size → (row3 inW H wih whh bih k acc).get! j = acc.get! j) ∧ (∀ j, j < inW + H + 1 → (row3 inW H wih whh bih k acc).get! (acc.size + j) = dv (gB inW H wih whh bih bhh k j)) := by unfold row3 obtain ⟨z1, o1, n1⟩ := seg_spec (fun q => dv wih[q]!) (k * inW) inW acc generalize fpush (fun q => dv wih[q]!) (k * inW) inW acc = a1 at z1 o1 n1 ⊢ obtain ⟨z2, o2, n2⟩ := seg_spec (fun q => dv whh[q]!) (k * H) H a1 generalize fpush (fun q => dv whh[q]!) (k * H) H a1 = a2 at z2 o2 n2 ⊢ obtain ⟨y0, y1, y2, y3, y4⟩ := row3Idx acc.size a1.size a2.size inW H z1 z2 refine ⟨by rw [fa_push_size]; exact y0, fun j hj => ?_, fun j hj => ?_⟩ · rw [fa_push_get, if_pos (y1 j hj).1, o2 j (y1 j hj).2, o1 j hj] · rw [fa_push_get] unfold gB by_cases a : j < inW · rw [if_pos (y2 j a), o2 _ (by rw [z1]; exact Nat.add_lt_add_left a _), n1 j a, if_pos a] · by_cases b : j < inW + H · obtain ⟨c1, c2, c3⟩ := y3 j a b rw [if_pos c1, c2, n2 _ c3, if_neg a, if_pos b] · obtain ⟨c1, c2, c3⟩ := y4 j hj a b rw [if_neg c1, if_pos c2, if_neg a, if_neg b, if_pos c3] /-- The state after `t` steps. -/ def traj (step : Nat → Array Word × Array Word → Array Word × Array Word) (iniS : Array Word × Array Word) : Nat → Array Word × Array Word | 0 => iniS | t + 1 => step t (traj step iniS t) theorem foldl_traj (step : Nat → Array Word × Array Word → Array Word × Array Word) (iniS : Array Word × Array Word) : ∀ T, (List.range T).foldl (fun (acc : (Array Word × Array Word) × Array (Array Word)) t => let st := step t acc.1 (st, acc.2.push st.1)) (iniS, #[]) = (traj step iniS T, Array.ofFn (n := T) fun t => (traj step iniS (t.val + 1)).1) | 0 => by simp [traj] | T + 1 => by rw [List.range_succ, List.foldl_append, foldl_traj step iniS T] simp only [List.foldl_cons, List.foldl_nil] rw [show step T (traj step iniS T) = traj step iniS (T + 1) from rfl, push_ofFnA (fun t => (traj step iniS (t + 1)).1) T] theorem divH (q t H : Nat) (h1 : t * H ≤ q) (h2 : q < (t + 1) * H) : q / H = t ∧ q % H = q - t * H := by have hH : 0 < H := by rcases Nat.eq_zero_or_pos H with h | h · subst h; simp at h2 · exact h have e : q / H = t := Nat.div_eq_of_lt_le h1 h2 refine ⟨e, ?_⟩ have := Nat.mod_add_div q H rw [e, Nat.mul_comm] at this omega theorem recFlat_traj (step : Nat → Array Word × Array Word → Array Word × Array Word) (iniS : Array Word × Array Word) (H : Nat) (hsz : ∀ t st, (step t st).1.size = H) : ∀ (n t : Nat) (out : Array Word), out = Array.ofFn (n := t * H) (fun q => (traj step iniS (q.val / H + 1)).1[q.val % H]!) → recFlat step t n (traj step iniS t) out = Array.ofFn (n := (t + n) * H) (fun q => (traj step iniS (q.val / H + 1)).1[q.val % H]!) | 0, t, out, ho => by rw [recFlat, ho, Nat.add_zero] | n + 1, t, out, ho => by rw [recFlat] try dsimp only rw [show step t (traj step iniS t) = traj step iniS (t + 1) from rfl] rw [recFlat_traj step iniS H hsz n (t + 1) _ ?_, show t + 1 + n = t + (n + 1) by omega] rw [ho] have hs : (traj step iniS (t + 1)).1.size = H := hsz _ _ apply Array.ext · simp [hs, Nat.add_mul] · intro q h1 h2 simp only [Array.size_append, Array.size_ofFn, hs] at h1 rw [Array.getElem_ofFn] by_cases hq : q < t * H · rw [Array.getElem_append_left (by simpa using hq), Array.getElem_ofFn] · rw [Array.getElem_append_right (by simp; omega)] obtain ⟨d1, d2⟩ := divH q t H (by omega) (by rw [Nat.add_mul, Nat.one_mul]; omega) simp only [Array.size_ofFn] rw [d1, d2, getElem!_pos _ _ (by rw [hs]; omega)] theorem recFlat_eq (T H : Nat) (step : Nat → Array Word × Array Word → Array Word × Array Word) (iniS : Array Word × Array Word) (hsz : ∀ t st, (step t st).1.size = H) : recFlat step 0 T iniS (Array.emptyWithCapacity (T * H)) = recurWith T H step iniS := by have := recFlat_traj step iniS H hsz T 0 (Array.emptyWithCapacity (T * H)) (by simp) rw [show traj step iniS 0 = iniS from rfl, Nat.zero_add] at this rw [this, recurWith] simp only [foldl_traj] congr 1 funext q have hq : q.val / H < T := Nat.div_lt_of_lt_mul (Nat.lt_of_lt_of_eq q.isLt (Nat.mul_comm T H)) rw [ofFn_get!A T (fun t => (traj step iniS (t + 1)).1) _ hq] end RnnP section RnnS theorem idx_lt (k j n m : Nat) (hk : k < m) (hj : j < n) : k * n + j < m * n := by have : (k + 1) * n ≤ m * n := Nat.mul_le_mul_right _ hk rw [Nat.add_mul, Nat.one_mul] at this omega theorem gB_good (inW H : Nat) (wih whh bih bhh : Array Word) (h1 : wih.all good = true) (h2 : whh.all good = true) (h3 : bih.all good = true) (h4 : bhh.all good = true) (k j : Nat) : good (gB inW H wih whh bih bhh k j) = true := by unfold gB split_ifs · exact all_good _ h1 _ · exact all_good _ h2 _ · exact all_good _ h3 _ · exact all_good _ h4 _ theorem gA_good (inW H : Nat) (x h : Array Word) (t : Nat) (hv : allLt (fun j => good (gA inW H x h t j)) (inW + H) = true) (j : Nat) (hj : j < inW + H + 1) : good (gA inW H x h t j) = true := by rcases Nat.lt_succ_iff_lt_or_eq.mp hj with hj | hj · exact allLt_spec _ _ hv j hj · subst hj; simp [gA, good_one] theorem cellF_eq (f i c g : Word) : cellF f i c g = Pinned.dotFn 2 (fun j => if j = 0 then f else i) (fun j => if j = 0 then c else g) := by unfold cellF cellSlow simp only [] split_ifs with hg hw · rfl · rw [beq_iff_eq] at hw simp only [Bool.and_eq_true] at hg obtain ⟨⟨⟨h1, h2⟩, h3⟩, h4⟩ := hg have hl : (List.range 2).foldl (fun acc j => stp acc (dv ((fun j => if j = 0 then f else i) j) * dv ((fun j => if j = 0 then c else g) j))) ⟨0, 0⟩ = stp (stp ⟨0, 0⟩ (dv f * dv c)) (dv i * dv g) := by simp [List.range_succ] rw [← hl] at hw ⊢ exact fastNB 2 (by decide) _ _ (fun j hj => by rcases (by omega : j = 0 ∨ j = 1) with rfl | rfl <;> simp [h1, h2]) (fun j hj => by rcases (by omega : j = 0 ∨ j = 1) with rfl | rfl <;> simp [h3, h4]) _ (fun _ _ => rfl) hw · rfl theorem mulF_eq (o t : Word) : mulF o t = toWord (Model.mul (ofW o) (ofW t)) := by unfold mulF mulSlow simp only [] split_ifs with hg hw · rfl · rw [beq_iff_eq] at hw simp only [Bool.and_eq_true] at hg obtain ⟨⟨⟨h1, h2⟩, h3⟩, h4⟩ := hg exact fastMul o t h1 h2 h3 h4 hw · rfl theorem updF_eq (nu zu hu : Word) : updF nu zu hu = Pinned.dotFn 3 (fun j => if j = 2 then hu else nu) (fun j => if j = 0 then oneW else if j = 1 then negW zu else zu) := by unfold updF upd3Slow simp only [] split_ifs with hg hw · rfl · rw [beq_iff_eq] at hw simp only [Bool.and_eq_true] at hg obtain ⟨⟨⟨h1, h2⟩, h3⟩, h4⟩ := hg have hl : (List.range 3).foldl (fun acc j => stp acc (dv ((fun j => if j = 2 then hu else nu) j) * dv ((fun j => if j = 0 then oneW else if j = 1 then negW zu else zu) j))) ⟨0, 0⟩ = stp (stp (stp ⟨0, 0⟩ (dv nu * dv oneW)) (dv nu * dv (negW zu))) (dv hu * dv zu) := by simp [List.range_succ] rw [← hl] at hw ⊢ exact fastNB 3 (by decide) _ _ (fun j hj => by rcases (by omega : j = 0 ∨ j = 1 ∨ j = 2) with rfl | rfl | rfl <;> simp [h1, h3]) (fun j hj => by rcases (by omega : j = 0 ∨ j = 1 ∨ j = 2) with rfl | rfl | rfl <;> simp [h2, h4, good_one]) _ (fun _ _ => rfl) hw · rfl theorem hnIdx (inW H u : Nat) (hu : u < H) (hWl : H * H < 2 ^ 32) (hVl : inW + H + 1 < 2 ^ 32) : u * H < 2 ^ 32 ∧ u * H + H ≤ H * H ∧ inW < 2 ^ 32 ∧ ∀ j, j < H → inW + j < inW + H + 1 := by have hb1 : (u + 1) * H ≤ H * H := Nat.mul_le_mul_right _ hu rw [Nat.add_mul, Nat.one_mul] at hb1 exact ⟨by omega, hb1, by omega, fun j hj => by omega⟩ theorem hnF_eq (inW H : Nat) (x whh bhh h : Array Word) (t : Nat) (hN : H < 2 ^ 20) (hgw : ∀ i : Nat, good whh[i]! = true) (hgb : ∀ i : Nat, good bhh[i]! = true) (hgv : ∀ j, j < inW + H + 1 → good (gA inW H x h t j) = true) (V Wh Bn : FloatArray) (hV : ∀ j, j < inW + H + 1 → V.get! j = dv (gA inW H x h t j)) (hW : ∀ u j, u < H → j < H → Wh.get! (u * H + j) = dv whh[(2 * H + u) * H + j]!) (hB : ∀ u, u < H → Bn.get! u = dv bhh[2 * H + u]!) (hVs : V.size = inW + H + 1) (hWs : Wh.size = H * H) (hWl : H * H < 2 ^ 32) (hVl : inW + H + 1 < 2 ^ 32) (u : Nat) (hu : u < H) : hnF inW H whh bhh h V Wh Bn u = Pinned.dotFn (H + 1) (fun j => if j < H then h[j]! else oneW) (fun j => if j < H then whh[(2 * H + u) * H + j]! else bhh[2 * H + u]!) := by obtain ⟨k1, k2, k3, k4⟩ := hnIdx inW H u hu hWl hVl have hh : ∀ j, j < H → gA inW H x h t (inW + j) = h[j]! := fun j hj => by unfold gA; rw [if_neg (Nat.not_lt.mpr (Nat.le_add_right _ _)), if_pos (Nat.add_lt_add_left hj inW), Nat.add_sub_cancel_left] have hun : (u * H).toUSize.toNat = u * H := qAd _ k1 have hin : inW.toUSize.toNat = inW := qAd _ k3 have hfold : rdotU V Wh inW.toUSize (u * H).toUSize H 0 0 = (List.range H).foldl (fun acc j => stp acc (dv ((fun j => if j < H then h[j]! else oneW) j) * dv ((fun j => if j < H then whh[(2 * H + u) * H + j]! else bhh[2 * H + u]!) j))) ⟨0, 0⟩ := by have hb2 : (u * H).toUSize.toNat + H ≤ Wh.size := by rw [hun, hWs]; exact k2 rw [rdotU_eq V Wh (hVs ▸ hVl) (hWs ▸ hWl) _ _ _ _ _ (by rw [hin, hVs]; exact Nat.le_succ _) hb2] exact foldl_stp_congr _ _ _ _ fun j hj => by have hj := List.mem_range.mp hj simp only [hj, ite_true] rw [hin, hun, hV (inW + j) (k4 j hj), hh j hj, hW u j hu hj] unfold hnF hnFin hnSlow simp only [] split_ifs with hw · rfl · rw [beq_iff_eq] at hw rw [hfold] at hw ⊢ exact fastBias H hN (fun j => if j < H then h[j]! else oneW) (fun j => if j < H then whh[(2 * H + u) * H + j]! else bhh[2 * H + u]!) (fun j hj => by simp only [hj, ite_true]; rw [← hh j hj]; exact hgv _ (k4 j hj)) (fun j hj => by simp only [hj, ite_true]; exact hgw _) (by simp only [Nat.lt_irrefl, ite_false]; exact hgb _) (by simp only [Nat.lt_irrefl, ite_false]) _ (fun _ _ => rfl) _ (by rw [hB u hu]; simp only [Nat.lt_irrefl, ite_false]) hw theorem foldl_range_add2 (g : Nat → Float) (n : Nat) (a : F1) : (List.range (n + 2)).foldl (fun acc j => stp acc (g j)) a = stp (stp ((List.range n).foldl (fun acc j => stp acc (g j)) a) (g n)) (g (n + 1)) := by rw [show n + 2 = n + 1 + 1 by omega, List.range_succ, List.range_succ, List.foldl_append, List.foldl_append] rfl theorem candIdx (inW H u : Nat) (hu : u < H) (hWl : H * (inW + 1) < 2 ^ 32) (hVl : inW + H + 1 < 2 ^ 32) : ¬ inW + 1 < inW ∧ ¬ inW + 1 = inW ∧ u * (inW + 1) < 2 ^ 32 ∧ u * (inW + 1) + inW ≤ H * (inW + 1) ∧ (∀ j, j < inW → j < inW + H + 1 ∧ j < inW + 1) ∧ ¬ inW + H < inW ∧ ¬ inW + H < inW + H ∧ 0 + inW ≤ inW + H + 1 ∧ (∀ j, j < inW + 2 → ¬ j < inW → ¬ j = inW → j = inW + 1) := by have hb1 : (u + 1) * (inW + 1) ≤ H * (inW + 1) := Nat.mul_le_mul_right _ hu rw [Nat.add_mul, Nat.one_mul] at hb1 exact ⟨by omega, by omega, by omega, by omega, fun j hj => ⟨by omega, by omega⟩, by omega, by omega, by omega, fun j h1 h2 h3 => by omega⟩ theorem candF_eq (inW H : Nat) (x wih bih : Array Word) (t : Nat) (hN : inW + 2 < 2 ^ 20) (hgw : ∀ i : Nat, good wih[i]! = true) (hgb : ∀ i : Nat, good bih[i]! = true) (h : Array Word) (hgv : ∀ j, j < inW + H + 1 → good (gA inW H x h t j) = true) (V Wc : FloatArray) (hV : ∀ j, j < inW + H + 1 → V.get! j = dv (gA inW H x h t j)) (hW : ∀ u j, u < H → j < inW + 1 → Wc.get! (u * (inW + 1) + j) = dv (if j < inW then wih[(2 * H + u) * inW + j]! else bih[2 * H + u]!)) (hVs : V.size = inW + H + 1) (hWs : Wc.size = H * (inW + 1)) (hWl : H * (inW + 1) < 2 ^ 32) (hVl : inW + H + 1 < 2 ^ 32) (u : Nat) (hu : u < H) (hn r : Word) : candF inW H x wih bih t V Wc u hn r = Pinned.dotFn (inW + 2) (fun j => if j < inW then x[t * inW + j]! else if j = inW then oneW else hn) (fun j => if j < inW then wih[(2 * H + u) * inW + j]! else if j = inW then bih[2 * H + u]! else r) := by obtain ⟨nb, nc, k1, k2, k3, k4, k5, k6, k7⟩ := candIdx inW H u hu hWl hVl have na : ¬ inW < inW := Nat.lt_irrefl _ let fa : Nat → Word := fun j => if j < inW then x[t * inW + j]! else if j = inW then oneW else hn let fb : Nat → Word := fun j => if j < inW then wih[(2 * H + u) * inW + j]! else if j = inW then bih[2 * H + u]! else r have a0 : ∀ j, j < inW → fa j = x[t * inW + j]! := fun j hj => if_pos hj have a1 : fa inW = oneW := by show ite _ _ _ = _; rw [if_neg na, if_pos rfl] have a2 : fa (inW + 1) = hn := by show ite _ _ _ = _; rw [if_neg nb, if_neg nc] have b0 : ∀ j, j < inW → fb j = wih[(2 * H + u) * inW + j]! := fun j hj => if_pos hj have b1 : fb inW = bih[2 * H + u]! := by show ite _ _ _ = _; rw [if_neg na, if_pos rfl] have b2 : fb (inW + 1) = r := by show ite _ _ _ = _; rw [if_neg nb, if_neg nc] have hx : ∀ j, j < inW → gA inW H x h t j = fa j := fun j hj => by rw [a0 j hj]; unfold gA; rw [if_pos hj] have hun : (u * (inW + 1)).toUSize.toNat = u * (inW + 1) := qAd _ k1 have hb2 : (u * (inW + 1)).toUSize.toNat + inW ≤ Wc.size := by rw [hun, hWs]; exact k2 have e1 : (List.range inW).foldl (fun acc j => stp acc (V.get! (0 + j) * Wc.get! (u * (inW + 1) + j))) ⟨0, 0⟩ = (List.range inW).foldl (fun acc j => stp acc (dv (fa j) * dv (fb j))) ⟨0, 0⟩ := foldl_stp_congr _ _ _ _ fun j hj => by have hj := List.mem_range.mp hj rw [Nat.zero_add, hV j (k3 j hj).1, hx j hj, hW u j hu (k3 j hj).2, if_pos hj, b0 j hj] have e2 : V.get! (inW + H) * Wc.get! (u * (inW + 1) + inW) = dv (fa inW) * dv (fb inW) := by rw [hV (inW + H) (Nat.lt_succ_self _), hW u inW hu (Nat.lt_succ_self _), a1, b1, if_neg na] unfold gA; rw [if_neg k4, if_neg k5] have hfold : stp (stp (rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0) (V.get! (inW + H) * Wc.get! (u * (inW + 1) + inW))) (dv hn * dv r) = (List.range (inW + 2)).foldl (fun acc j => stp acc (dv (fa j) * dv (fb j))) ⟨0, 0⟩ := by rw [foldl_range_add2 (fun j => dv (fa j) * dv (fb j)), rdotU_eq V Wc (hVs ▸ hVl) (hWs ▸ hWl) _ _ _ _ _ (by rw [show (0 : USize).toNat = 0 from rfl, hVs]; exact k6) hb2, hun, show (0 : USize).toNat = 0 from rfl, e1, e2, a2, b2] unfold candF candFin candSlow simp only [] split_ifs with hg hw · rfl · rw [beq_iff_eq] at hw simp only [Bool.and_eq_true] at hg obtain ⟨h1, h2⟩ := hg rw [hfold] at hw ⊢ have gx : ∀ j, j < inW + 2 → good (fa j) = true := fun j hj => by by_cases a : j < inW · rw [← hx j a]; exact hgv j (k3 j a).1 · by_cases b : j = inW · rw [b, a1]; exact good_one · rw [k7 j hj a b, a2]; exact h1 have gw : ∀ j, j < inW + 2 → good (fb j) = true := fun j hj => by by_cases a : j < inW · rw [b0 j a]; exact hgw _ · by_cases b : j = inW · rw [b, b1]; exact hgb _ · rw [k7 j hj a b, b2]; exact h2 exact fastNB (inW + 2) hN fa fb gx gw (fun j => dv (fa j) * dv (fb j)) (fun _ _ => rfl) hw · rfl theorem gateIdx (inW H r S : Nat) (hN : inW + H + 1 < 2 ^ 20) (hWr : (r + 1) * (inW + H + 1) ≤ S) (hWl : S < 2 ^ 32) : r * (inW + H + 1) < 2 ^ 32 ∧ r * (inW + H + 1) + (inW + H + 1) ≤ S ∧ inW + H + 1 < 2 ^ 32 ∧ ¬ inW + H + 1 < inW ∧ ¬ inW + H + 1 < inW + H ∧ ¬ inW + H + 1 = inW + H := by rw [Nat.add_mul, Nat.one_mul] at hWr exact ⟨by omega, by omega, by omega, by omega, by omega, by omega⟩ theorem gateRow_eq (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (hgw : ∀ k j, good (gB inW H wih whh bih bhh k j) = true) (hgv : ∀ j, j < inW + H + 1 → good (gA inW H x h t j) = true) (hN : inW + H + 1 < 2 ^ 20) (V W Bh : FloatArray) (hV : ∀ j, j < inW + H + 1 → V.get! j = dv (gA inW H x h t j)) (r k : Nat) (hW : ∀ j, j < inW + H + 1 → W.get! (r * (inW + H + 1) + j) = dv (gB inW H wih whh bih bhh k j)) (hB : Bh.get! r = dv bhh[k]!) (hVs : V.size = inW + H + 1) (hWr : (r + 1) * (inW + H + 1) ≤ W.size) (hWl : W.size < 2 ^ 32) : gfinR inW H x wih whh bih bhh h t Bh r k (rdotU V W 0 (r * (inW + H + 1)).toUSize (inW + H + 1) 0 0).s (rdotU V W 0 (r * (inW + H + 1)).toUSize (inW + H + 1) 0 0).t = gateWith Pinned.dotFn inW H x wih whh bih bhh h t k := by obtain ⟨k1, k2, k3, k4, k5, k6⟩ := gateIdx inW H r W.size hN hWr hWl have hVl : V.size < 2 ^ 32 := hVs ▸ k3 have hkn : (r * (inW + H + 1)).toUSize.toNat = r * (inW + H + 1) := qAd _ k1 have hb2 : (r * (inW + H + 1)).toUSize.toNat + (inW + H + 1) ≤ W.size := by rw [hkn]; exact k2 have hfold : rdotU V W 0 (r * (inW + H + 1)).toUSize (inW + H + 1) 0 0 = (List.range (inW + H + 1)).foldl (fun acc j => stp acc (dv (gA inW H x h t j) * dv (gB inW H wih whh bih bhh k j))) ⟨0, 0⟩ := by rw [rdotU_eq V W hVl hWl _ _ _ _ _ (by rw [hVs]; exact Nat.le_of_eq (Nat.zero_add _)) hb2] exact foldl_stp_congr _ _ _ _ fun j hj => by have hj := List.mem_range.mp hj rw [hkn, show (0 : USize).toNat = 0 from rfl, Nat.zero_add, hV j hj, hW j hj] have hb : gB inW H wih whh bih bhh k (inW + H + 1) = bhh[k]! := by unfold gB; rw [if_neg k4, if_neg k5, if_neg k6] have h1 : gA inW H x h t (inW + H + 1) = oneW := by unfold gA; rw [if_neg k4, if_neg k5] unfold gfinR gateSlow simp only [] split_ifs with hw · rfl · rw [beq_iff_eq] at hw rw [hfold] at hw ⊢ have key := fastBias (inW + H + 1) hN (gA inW H x h t) (gB inW H wih whh bih bhh k) hgv (fun j _ => hgw k j) (hgw k _) h1 (fun j => dv (gA inW H x h t j) * dv (gB inW H wih whh bih bhh k j)) (fun _ _ => rfl) (Bh.get! r) (by rw [hB, hb]) hw rw [key] rfl theorem lstmIdx (H u i : Nat) (hu : u < H) (hi : i < 4) : 4 * u + i < 4 * H ∧ ((4 * u + i) % 4) * H + (4 * u + i) / 4 = i * H + u ∧ 4 * u + i + 1 ≤ 4 * H := by refine ⟨by omega, ?_, by omega⟩ rw [show (4 * u + i) % 4 = i by omega, show (4 * u + i) / 4 = u by omega] theorem lstmU_eq (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h cs : Array Word) (t : Nat) (hgw : ∀ k j, good (gB inW H wih whh bih bhh k j) = true) (hgv : ∀ j, j < inW + H + 1 → good (gA inW H x h t j) = true) (hN : inW + H + 1 < 2 ^ 20) (V W Bh : FloatArray) (hV : ∀ j, j < inW + H + 1 → V.get! j = dv (gA inW H x h t j)) (hW : ∀ r j, r < 4 * H → j < inW + H + 1 → W.get! (r * (inW + H + 1) + j) = dv (gB inW H wih whh bih bhh ((r % 4) * H + r / 4) j)) (hB : ∀ r, r < 4 * H → Bh.get! r = dv bhh[(r % 4) * H + r / 4]!) (hVs : V.size = inW + H + 1) (hWs : W.size = 4 * H * (inW + H + 1)) (hWl : W.size < 2 ^ 32) (u : Nat) (hu : u < H) : lstmU sig tanh inW H x wih whh bih bhh h cs t V W Bh u = (mulF (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (3 * H + u))) (tanh (cellF (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (H + u))) (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t u)) cs[u]! (tanh (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (2 * H + u))))), cellF (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (H + u))) (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t u)) cs[u]! (tanh (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (2 * H + u)))) := by have g : ∀ i, i < 4 → gfinR inW H x wih whh bih bhh h t Bh (4 * u + i) (i * H + u) (rdotU V W 0 ((4 * u + i) * (inW + H + 1)).toUSize (inW + H + 1) 0 0).s (rdotU V W 0 ((4 * u + i) * (inW + H + 1)).toUSize (inW + H + 1) 0 0).t = gateWith Pinned.dotFn inW H x wih whh bih bhh h t (i * H + u) := by intro i hi obtain ⟨hr, hp, hq⟩ := lstmIdx H u i hu hi exact gateRow_eq inW H x wih whh bih bhh h t hgw hgv hN V W Bh hV (4 * u + i) (i * H + u) (fun j hj => by rw [hW _ j hr hj, hp]) (by rw [hB _ hr, hp]) hVs (by rw [hWs]; exact Nat.mul_le_mul_right (inW + H + 1) hq) hWl have g0 := g 0 (by decide) have g1 := g 1 (by decide) have g2 := g 2 (by decide) have g3 := g 3 (by decide) simp only [Nat.zero_mul, Nat.zero_add, Nat.add_zero, Nat.one_mul] at g0 g1 g2 g3 unfold lstmU dsimp only rw [dot4_eq, rdot4U_spec] dsimp only rw [show (0 : Nat).toUSize = (0 : USize) from rfl, g0, g1, g2, g3] /-- The decoded GRU weights. -/ structure GW (inW H : Nat) (wih whh bih bhh : Array Word) (Wrz Brz Wh Bn Wc : FloatArray) : Prop where gw : ∀ k j, good (gB inW H wih whh bih bhh k j) = true g1 : ∀ i : Nat, good wih[i]! = true g2 : ∀ i : Nat, good whh[i]! = true g3 : ∀ i : Nat, good bih[i]! = true g4 : ∀ i : Nat, good bhh[i]! = true hN : inW + H + 3 < 2 ^ 20 hW : ∀ r j, r < 2 * H → j < inW + H + 1 → Wrz.get! (r * (inW + H + 1) + j) = dv (gB inW H wih whh bih bhh ((r % 2) * H + r / 2) j) hB : ∀ r, r < 2 * H → Brz.get! r = dv bhh[(r % 2) * H + r / 2]! hWh : ∀ u j, u < H → j < H → Wh.get! (u * H + j) = dv whh[(2 * H + u) * H + j]! hBn : ∀ u, u < H → Bn.get! u = dv bhh[2 * H + u]! hWc : ∀ u j, u < H → j < inW + 1 → Wc.get! (u * (inW + 1) + j) = dv (if j < inW then wih[(2 * H + u) * inW + j]! else bih[2 * H + u]!) hWs : Wrz.size = 2 * H * (inW + H + 1) hWhs : Wh.size = H * H hWcs : Wc.size = H * (inW + 1) hl1 : 2 * H * (inW + H + 1) < 2 ^ 32 hl2 : H * H < 2 ^ 32 hl3 : H * (inW + 1) < 2 ^ 32 /-- The GRU spec's new hidden word `u`. -/ def gS (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h : Array Word) (t u : Nat) : Word := Pinned.dotFn 3 (fun j => if j = 2 then h[u]! else tanh (Pinned.dotFn (inW + 2) (fun j => if j < inW then x[t * inW + j]! else if j = inW then oneW else Pinned.dotFn (H + 1) (fun j => if j < H then h[j]! else oneW) (fun j => if j < H then whh[(2 * H + u) * H + j]! else bhh[2 * H + u]!)) (fun j => if j < inW then wih[(2 * H + u) * inW + j]! else if j = inW then bih[2 * H + u]! else sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t u)))) (fun j => if j = 0 then oneW else if j = 1 then negW (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (H + u))) else sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (H + u))) theorem hnFin_rdot (inW H : Nat) (whh bhh h : Array Word) (V Wh Bn : FloatArray) (u : Nat) : hnFin H whh bhh h Bn u (rdotU V Wh inW.toUSize (u * H).toUSize H 0 0).s (rdotU V Wh inW.toUSize (u * H).toUSize H 0 0).t = hnF inW H whh bhh h V Wh Bn u := rfl theorem candFin_rdot (inW H : Nat) (x wih bih : Array Word) (t : Nat) (V Wc : FloatArray) (u : Nat) (hu ru : Word) : candFin inW H x wih bih t V Wc u hu ru ⟨(rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0).s, (rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0).t⟩ = candF inW H x wih bih t V Wc u hu ru := rfl theorem candFin_rdot' (inW H : Nat) (x wih bih : Array Word) (t : Nat) (V Wc : FloatArray) (u : Nat) (hu ru : Word) : candFin inW H x wih bih t V Wc u hu ru (rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0) = candF inW H x wih bih t V Wc u hu ru := rfl theorem gruIdx (inW H u : Nat) (hN : inW + H + 3 < 2 ^ 20) (hu : u < H) : inW + H + 1 < 2 ^ 20 ∧ H < 2 ^ 20 ∧ inW + 2 < 2 ^ 20 ∧ 2 * u < 2 * H ∧ 2 * u + 1 < 2 * H ∧ (2 * u % 2) * H + 2 * u / 2 = u ∧ ((2 * u + 1) % 2) * H + (2 * u + 1) / 2 = H + u := by refine ⟨by omega, by omega, by omega, by omega, by omega, ?_, ?_⟩ · rw [show 2 * u % 2 = 0 by omega, show 2 * u / 2 = u by omega]; omega · rw [show (2 * u + 1) % 2 = 1 by omega, show (2 * u + 1) / 2 = u by omega]; omega theorem gruUnit_eq (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (V Wrz Brz Wh Bn Wc : FloatArray) (o : GW inW H wih whh bih bhh Wrz Brz Wh Bn Wc) (hgv : ∀ j, j < inW + H + 1 → good (gA inW H x h t j) = true) (hV : ∀ j, j < inW + H + 1 → V.get! j = dv (gA inW H x h t j)) (hVs : V.size = inW + H + 1) (u r0 r1 : Nat) (hu : u < H) (e0 : r0 = 2 * u) (e1 : r1 = 2 * u + 1) : gruUnit sig tanh inW H x wih whh bih bhh h t V Brz Bn Wc u (rdotU V Wrz 0 (r0 * (inW + H + 1)).toUSize (inW + H + 1) 0 0).s (rdotU V Wrz 0 (r0 * (inW + H + 1)).toUSize (inW + H + 1) 0 0).t (rdotU V Wrz 0 (r1 * (inW + H + 1)).toUSize (inW + H + 1) 0 0).s (rdotU V Wrz 0 (r1 * (inW + H + 1)).toUSize (inW + H + 1) 0 0).t (rdotU V Wh inW.toUSize (u * H).toUSize H 0 0).s (rdotU V Wh inW.toUSize (u * H).toUSize H 0 0).t (rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0).s (rdotU V Wc 0 (u * (inW + 1)).toUSize inW 0 0).t = gS sig tanh inW H x wih whh bih bhh h t u := by subst e0 e1 obtain ⟨hN1, hNH, hN2, a0, a1, p0, p1⟩ := gruIdx inW H u o.hN hu have hl : Wrz.size < 2 ^ 32 := o.hWs ▸ o.hl1 have r0 := gateRow_eq inW H x wih whh bih bhh h t o.gw hgv hN1 V Wrz Brz hV (2 * u) u (fun j hj => by rw [o.hW _ j a0 hj, p0]) (by rw [o.hB _ a0, p0]) hVs (by rw [o.hWs]; exact Nat.mul_le_mul_right (inW + H + 1) a0) hl have r1 := gateRow_eq inW H x wih whh bih bhh h t o.gw hgv hN1 V Wrz Brz hV (2 * u + 1) (H + u) (fun j hj => by rw [o.hW _ j a1 hj, p1]) (by rw [o.hB _ a1, p1]) hVs (by rw [o.hWs]; exact Nat.mul_le_mul_right (inW + H + 1) a1) hl have r2 := hnF_eq inW H x whh bhh h t hNH o.g2 o.g4 hgv V Wh Bn hV o.hWh o.hBn hVs o.hWhs o.hl2 (Nat.lt_trans hN1 (by decide)) u hu have r3 := candF_eq inW H x wih bih t hN2 o.g1 o.g3 h hgv V Wc hV o.hWc hVs o.hWcs o.hl3 (Nat.lt_trans hN1 (by decide)) u hu unfold gruUnit gS try dsimp only rw [r0, r1, hnFin_rdot, r2] first | rw [candFin_rdot] | rw [candFin_rdot'] rw [r3, updF_eq] end RnnS section RnnT theorem stepIdx4 (H u : Nat) (hu : u < H) : H + u < 4 * H ∧ u < 4 * H ∧ 2 * H + u < 4 * H ∧ 3 * H + u < 4 * H := by omega theorem blk4Idx (H u : Nat) (hu : u + 4 ≤ H) : u < H ∧ u + 1 < H ∧ u + 2 < H ∧ u + 3 < H := by omega theorem lstmStepF_eq (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh : Array Word) (W Bh : FloatArray) (hgw : ∀ k j, good (gB inW H wih whh bih bhh k j) = true) (hN : inW + H + 1 < 2 ^ 20) (hW : ∀ r j, r < 4 * H → j < inW + H + 1 → W.get! (r * (inW + H + 1) + j) = dv (gB inW H wih whh bih bhh ((r % 4) * H + r / 4) j)) (hB : ∀ r, r < 4 * H → Bh.get! r = dv bhh[(r % 4) * H + r / 4]!) (hWs : W.size = 4 * H * (inW + H + 1)) (hWl : W.size < 2 ^ 32) : lstmStepF sig tanh inW H x wih whh bih bhh W Bh = lstmStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh := by funext t st unfold lstmStepF split_ifs with hv · have hgv := gA_good inW H x st.1 t hv have hV : ∀ j, j < inW + H + 1 → (fbuild (inW + H + 1) (fun j => dv (gA inW H x st.1 t j))).get! j = dv (gA inW H x st.1 t j) := fun j hj => fbuild_get _ _ _ hj have hu := fun u hu => lstmU_eq sig tanh inW H x wih whh bih bhh st.1 st.2 t hgw hgv hN _ W Bh hV hW hB (fbuild_size _ _) hWs hWl u hu rw [build2_zero] unfold lstmStepWith simp only [] congr 1 · congr 1; funext u rw [hu u.val u.isLt] obtain ⟨i1, i2, i3, i4⟩ := stepIdx4 H u.val u.isLt simp only [cellF_eq, mulF_eq] rw [ofFn_get!F _ u.val u.isLt] try dsimp only rw [ofFn_get! _ _ _ i4, ofFn_get! _ _ _ i1, ofFn_get! _ _ _ i2, ofFn_get! _ _ _ i3] · congr 1; funext u rw [hu u.val u.isLt] obtain ⟨i1, i2, i3, i4⟩ := stepIdx4 H u.val u.isLt simp only [cellF_eq] rw [ofFn_get! _ _ _ i1, ofFn_get! _ _ _ i2, ofFn_get! _ _ _ i3] · rfl theorem rows3_facts (inW H R : Nat) (wih whh bih bhh : Array Word) (p : Nat → Nat) : (rowsB (fun r acc => row3 inW H wih whh bih (p r) acc) 0 R (FloatArray.emptyWithCapacity (R * (inW + H + 1)))).size = R * (inW + H + 1) ∧ ∀ r j, r < R → j < inW + H + 1 → (rowsB (fun r acc => row3 inW H wih whh bih (p r) acc) 0 R (FloatArray.emptyWithCapacity (R * (inW + H + 1)))).get! (r * (inW + H + 1) + j) = dv (gB inW H wih whh bih bhh (p r) j) := by have := rowsB_spec (inW + H + 1) (fun r acc => row3 inW H wih whh bih (p r) acc) (fun r j => dv (gB inW H wih whh bih bhh (p r) j)) (fun r acc => (row3_spec inW H wih whh bih bhh (p r) acc).1) (fun r acc => (row3_spec inW H wih whh bih bhh (p r) acc).2.1) (fun r acc => (row3_spec inW H wih whh bih bhh (p r) acc).2.2) R 0 (FloatArray.emptyWithCapacity (R * (inW + H + 1))) (by rw [emp_size]; omega) (fun r' j h => absurd h (Nat.not_lt_zero _)) rw [Nat.zero_add] at this exact ⟨this.1, fun r j hr hj => this.2 r j hr hj⟩ theorem lstmBound (inW H : Nat) (h5 : inW + H + 3 < 2 ^ 20) (h6 : H < 1024) : 4 * H * (inW + H + 1) < 2 ^ 32 := by have : 4 * H * (inW + H + 1) ≤ 4 * 1023 * 2 ^ 20 := Nat.mul_le_mul (Nat.mul_le_mul_left _ (show H ≤ 1023 by omega)) (by omega) omega theorem lstmF_eq (sig tanh : Word → Word) : lstmF sig tanh = lstmWith Pinned.dotFn sig tanh := by funext T inW H x wih whh bih bhh unfold lstmF split_ifs with hc · simp only [Bool.and_eq_true, decide_eq_true_eq] at hc obtain ⟨⟨⟨⟨⟨h1, h2⟩, h3⟩, h4⟩, h5⟩, h6⟩ := hc obtain ⟨hWs, hW⟩ := rows3_facts inW H (4 * H) wih whh bih bhh (fun r => (r % 4) * H + r / 4) have hl := lstmBound inW H h5 h6 simp only [] rw [lstmStepF_eq sig tanh inW H x wih whh bih bhh _ _ (gB_good inW H wih whh bih bhh h1 h2 h3 h4) (Nat.lt_of_le_of_lt (Nat.le_add_right _ 2) h5) hW (fun r hr => fbuild_get _ _ _ hr) hWs (by rw [hWs]; exact hl), recFlat_eq T H _ _ (fun t st => by unfold lstmStepWith; exact Array.size_ofFn)] rfl · rfl theorem gru4_eq (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (V Wrz Brz Wh Bn Wc : FloatArray) (o : GW inW H wih whh bih bhh Wrz Brz Wh Bn Wc) (hgv : ∀ j, j < inW + H + 1 → good (gA inW H x h t j) = true) (hV : ∀ j, j < inW + H + 1 → V.get! j = dv (gA inW H x h t j)) (hVs : V.size = inW + H + 1) (u : Nat) (hu : u + 4 ≤ H) : gru4 sig tanh inW H x wih whh bih bhh h t V Wrz Brz Wh Bn Wc u = ⟨gS sig tanh inW H x wih whh bih bhh h t u, gS sig tanh inW H x wih whh bih bhh h t (u + 1), gS sig tanh inW H x wih whh bih bhh h t (u + 2), gS sig tanh inW H x wih whh bih bhh h t (u + 3)⟩ := by have G := fun v r0 r1 hv e0 e1 => gruUnit_eq sig tanh inW H x wih whh bih bhh h t V Wrz Brz Wh Bn Wc o hgv hV hVs v r0 r1 hv e0 e1 unfold gru4 simp only [dot4_eq, rdot4U_spec] obtain ⟨i0, i1, i2, i3⟩ := blk4Idx H u hu rw [show (0 : Nat).toUSize = (0 : USize) from rfl, G u (2 * u) (2 * u + 1) i0 rfl rfl, G (u + 1) (2 * u + 2) (2 * u + 3) i1 rfl rfl, G (u + 2) (2 * u + 4) (2 * u + 5) i2 rfl rfl, G (u + 3) (2 * u + 6) (2 * u + 7) i3 rfl rfl] theorem gru1_eq (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh h : Array Word) (t : Nat) (V Wrz Brz Wh Bn Wc : FloatArray) (o : GW inW H wih whh bih bhh Wrz Brz Wh Bn Wc) (hgv : ∀ j, j < inW + H + 1 → good (gA inW H x h t j) = true) (hV : ∀ j, j < inW + H + 1 → V.get! j = dv (gA inW H x h t j)) (hVs : V.size = inW + H + 1) (u : Nat) (hu : u < H) : gru1 sig tanh inW H x wih whh bih bhh h t V Wrz Brz Wh Bn Wc u = gS sig tanh inW H x wih whh bih bhh h t u := by unfold gru1 exact gruUnit_eq sig tanh inW H x wih whh bih bhh h t V Wrz Brz Wh Bn Wc o hgv hV hVs u (2 * u) (2 * u + 1) hu rfl rfl theorem gruStepF_eq (sig tanh : Word → Word) (inW H : Nat) (x wih whh bih bhh : Array Word) (Wrz Brz Wh Bn Wc : FloatArray) (o : GW inW H wih whh bih bhh Wrz Brz Wh Bn Wc) : gruStepF sig tanh inW H x wih whh bih bhh Wrz Brz Wh Bn Wc = gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh := by funext t st unfold gruStepF split_ifs with hv · try dsimp only have hgv := gA_good inW H x st.1 t hv have hV : ∀ j, j < inW + H + 1 → (fbuild (inW + H + 1) (fun j => dv (gA inW H x st.1 t j))).get! j = dv (gA inW H x st.1 t j) := fun j hj => fbuild_get _ _ _ hj rw [build4_spec H _ _ (gS sig tanh inW H x wih whh bih bhh st.1 t) (fun u hu => gru4_eq sig tanh inW H x wih whh bih bhh st.1 t _ Wrz Brz Wh Bn Wc o hgv hV (fbuild_size _ _) u hu) (fun u hu => gru1_eq sig tanh inW H x wih whh bih bhh st.1 t _ Wrz Brz Wh Bn Wc o hgv hV (fbuild_size _ _) u hu) H 0 _ (Nat.zero_le _) (Nat.le_of_eq (Nat.zero_add H).symm) (by simp)] unfold gruStepWith simp only [] congr 1 congr 1; funext u unfold gS repeat (rw [ofFn_get!F _ _ u.isLt]; try dsimp only) · rfl theorem rowsWh_facts (H : Nat) (whh : Array Word) : (rowsB (fun u acc => fpush (fun q => dv whh[q]!) ((2 * H + u) * H) H acc) 0 H (FloatArray.emptyWithCapacity (H * H))).size = H * H ∧ ∀ u j, u < H → j < H → (rowsB (fun u acc => fpush (fun q => dv whh[q]!) ((2 * H + u) * H) H acc) 0 H (FloatArray.emptyWithCapacity (H * H))).get! (u * H + j) = dv whh[(2 * H + u) * H + j]! := by have sh := rowsB_spec H (fun u acc => fpush (fun q => dv whh[q]!) ((2 * H + u) * H) H acc) (fun u j => dv whh[(2 * H + u) * H + j]!) (fun u acc => fpush_size _ _ _ _) (fun u acc j hj => (fpush_get _ _ _ _ j).1 hj) (fun u acc j hj => by rw [(fpush_get _ _ _ _ _).2 (by omega) (by omega)]; congr 2; omega) H 0 (FloatArray.emptyWithCapacity (H * H)) (by rw [emp_size]; omega) (fun r' j h => absurd h (Nat.not_lt_zero _)) rw [Nat.zero_add] at sh exact sh theorem rowsWc_facts (inW H : Nat) (wih bih : Array Word) : (rowsB (fun u acc => (fpush (fun q => dv wih[q]!) ((2 * H + u) * inW) inW acc).push (dv bih[2 * H + u]!)) 0 H (FloatArray.emptyWithCapacity (H * (inW + 1)))).size = H * (inW + 1) ∧ ∀ u j, u < H → j < inW + 1 → (rowsB (fun u acc => (fpush (fun q => dv wih[q]!) ((2 * H + u) * inW) inW acc).push (dv bih[2 * H + u]!)) 0 H (FloatArray.emptyWithCapacity (H * (inW + 1)))).get! (u * (inW + 1) + j) = dv (if j < inW then wih[(2 * H + u) * inW + j]! else bih[2 * H + u]!) := by have sc := rowsB_spec (inW + 1) (fun u acc => (fpush (fun q => dv wih[q]!) ((2 * H + u) * inW) inW acc).push (dv bih[2 * H + u]!)) (fun u j => dv (if j < inW then wih[(2 * H + u) * inW + j]! else bih[2 * H + u]!)) (fun u acc => by rw [fa_push_size, fpush_size]; omega) (fun u acc j hj => by rw [fa_push_get, if_pos (by rw [fpush_size]; omega), (fpush_get _ _ _ _ j).1 hj]) (fun u acc j hj => by rw [fa_push_get] by_cases a : j < inW · rw [if_pos (by rw [fpush_size]; omega), (fpush_get _ _ _ _ _).2 (by omega) (by omega), if_pos a] congr 2; omega · rw [if_neg (by rw [fpush_size]; omega), if_pos (by rw [fpush_size]; omega), if_neg a]) H 0 (FloatArray.emptyWithCapacity (H * (inW + 1))) (by rw [emp_size]; omega) (fun r' j h => absurd h (Nat.not_lt_zero _)) rw [Nat.zero_add] at sc exact sc theorem gruBounds (inW H : Nat) (h5 : inW + H + 3 < 2 ^ 20) (h6 : H < 1024) : 2 * H * (inW + H + 1) < 2 ^ 32 ∧ H * H < 2 ^ 32 ∧ H * (inW + 1) < 2 ^ 32 := by have a : 2 * H * (inW + H + 1) ≤ 2 * 1023 * 2 ^ 20 := Nat.mul_le_mul (Nat.mul_le_mul_left _ (show H ≤ 1023 by omega)) (by omega) have b : H * H ≤ 1023 * 1023 := Nat.mul_le_mul (show H ≤ 1023 by omega) (show H ≤ 1023 by omega) have c : H * (inW + 1) ≤ 1023 * 2 ^ 20 := Nat.mul_le_mul (show H ≤ 1023 by omega) (by omega) omega theorem gruF_eq (sig tanh : Word → Word) : gruF sig tanh = gruWith Pinned.dotFn sig tanh := by funext T inW H x wih whh bih bhh unfold gruF split_ifs with hc · simp only [Bool.and_eq_true, decide_eq_true_eq] at hc obtain ⟨⟨⟨⟨⟨h1, h2⟩, h3⟩, h4⟩, h5⟩, h6⟩ := hc obtain ⟨hWs, hW⟩ := rows3_facts inW H (2 * H) wih whh bih bhh (fun r => (r % 2) * H + r / 2) obtain ⟨hl1, hl2, hl3⟩ := gruBounds inW H h5 h6 have sh := rowsWh_facts H whh have sc := rowsWc_facts inW H wih bih simp only [] rw [gruStepF_eq sig tanh inW H x wih whh bih bhh _ _ _ _ _ ⟨gB_good inW H wih whh bih bhh h1 h2 h3 h4, all_good _ h1, all_good _ h2, all_good _ h3, all_good _ h4, h5, hW, fun r hr => fbuild_get _ _ _ hr, sh.2, fun u hu => fbuild_get _ _ _ hu, sc.2, hWs, sh.1, sc.1, hl1, hl2, hl3⟩, recFlat_eq T H _ _ (fun t st => by unfold gruStepWith; exact Array.size_ofFn)] rfl · rfl end RnnT section ActF open FastAct in /-- `σ(−c)` for `c < 34` from `t = e^(−c/2)²` (the incumbent's enclosure routines): the fallback for large negative inputs, which `FastAct.sigmoidF` sends to the spec for `c ≥ 17`. -/ def sigmoidFastX (w : UInt32) : Option UInt32 := if expOf w = 255 then none else let d := decodeD w match expNeg d.significand (d.exponent - 1) with | none => none | some e1 => let t := (mulDn e1.1 e1.1, min one (mulUp e1.2 e1.2)) if d.negative then match divLo t.1 (one + t.1), divHi t.2 (one + t.2) with | some ql, some qh => settle false ql qh | _, _ => none else none open FastAct in theorem sigmoidFastX_spec {w a : UInt32} (h : sigmoidFastX w = some a) : sigmoidCR w = a := by unfold sigmoidFastX at h split at h · simp at h rename_i hfin dsimp only at h have hx := toReal_ofW_decode hfin generalize decodeD w = d at h hx have hspec := (toReal_sigmoidModel (fmt := Fmt) (by decide) (input := Model.ofUInt32 w) (by simp [isFinite_ofUInt32, hfin])).2 change Model.toReal (sigmoidModel (ofW w)) = Model.roundAt Fmt (realSigmoid (Model.toReal (ofW w))) at hspec rw [hx] at hspec change toWord (sigmoidModel (ofW w)) = a split at h · simp at h rename_i e1 he1 have hE1 := expNeg_spec he1 set C := (d.significand : ℝ) * (2 : ℝ) ^ d.exponent have hE := hE1.mul hE1 have hC : (d.significand : ℝ) * (2 : ℝ) ^ (d.exponent - 1) + (d.significand : ℝ) * (2 : ℝ) ^ (d.exponent - 1) = C := by simp only [C]; rw [zpow_sub₀ two_ne_zero, zpow_one]; ring rw [hC] at hE set T := Real.exp (-C) have hT : 0 < T := Real.exp_pos _ obtain ⟨h1, h2, h3⟩ := hE simp only at h1 h2 h3 set t1 := mulDn e1.1 e1.1 with ht1d set t2 := min one (mulUp e1.2 e1.2) with ht2d have v1 := V_nonneg t1 have v2 := V_nonneg t2 split at h · rename_i hneg split at h · rename_i ql qh hql hqh have bl := divLo_spec hql have bh := divHi_spec hqh rw [V_add, V_one] at bl bh rw [settle_eq] at h simp only [Bool.false_eq_true, ite_false] at h refine settleInt_spec h (v := realSigmoid (-C)) ?_ ?_ (by rw [hspec, hneg]; simp) · rw [int_scale] have : realSigmoid (-C) = T / (1 + T) := realSigmoid_neg_eq C rw [this, le_div_iff₀ (by linarith)] nlinarith · rw [int_scale] have : realSigmoid (-C) = T / (1 + T) := realSigmoid_neg_eq C rw [this, div_le_iff₀ (by linarith)] nlinarith · simp at h · simp at h /-- Fallbacks of the binary64 path: the X path for large negative inputs, then the incumbent's. -/ @[noinline] def sigmoidF9 (w : UInt32) : UInt32 := match sigmoidFastX w with | some a => a | none => FastAct.sigmoidF w @[noinline] def tanhF9 (w : UInt32) : UInt32 := FastAct.tanhF w theorem sigmoidF9_eq (w : UInt32) : sigmoidF9 w = sigmoidCR w := by unfold sigmoidF9 cases h : sigmoidFastX w with | some a => exact (sigmoidFastX_spec h).symm | none => exact congrFun FastAct.sigmoidF_eq w theorem tanhF9_eq (w : UInt32) : tanhF9 w = tanhCR w := by unfold tanhF9; exact congrFun FastAct.tanhF_eq w end ActF /-! ## Binary64 sigmoid/tanh: `e^(−c) = e^(−k/64) · e^(−r)`, table + degree-5 Taylor, ziv check -/ section ActG /-- Enclosure of `e^(−k/64)` (`k < 1280`) from FastAct's proved tables. -/ def enclK (k : Nat) : Nat × Nat := let n := k / 64 let F := FastAct.fracTab[k % 64]! let I := if n ≤ 16 then FastAct.intTab[n]! else (FastAct.mulDn FastAct.intTab[16]!.1 FastAct.intTab[n - 16]!.1, min FastAct.one (FastAct.mulUp FastAct.intTab[16]!.2 FastAct.intTab[n - 16]!.2)) (FastAct.mulDn I.1 F.1, min FastAct.one (FastAct.mulUp I.2 F.2)) /-- `lo · 2^−62` truncated to 53 significant bits, as a binary64 value. -/ def toF62 (lo : Nat) : Float := let sh := lo.log2 - 52 (lo >>> sh).toUInt64.toFloat * D.pwEntry (88 + sh) /-- The table `e^(−k/64) ≈ toF62 lo`. -/ def expTabG : FloatArray := ⟨Array.ofFn (n := 1280) fun k => toF62 (enclK k.val).1⟩ /-- Every table enclosure is narrow: absolute width `≤ 2^−48`, relative `≤ 2^−36` for `k < 1088`. -/ def tabOK : Bool := (List.range 1280).all fun k => let e := enclK k decide (e.2 - e.1 ≤ 2 ^ 14) && (decide (1088 ≤ k) || decide ((e.2 - e.1) * 2 ^ 36 ≤ e.1)) def oneG : Float := (1 : UInt64).toFloat def halfG : Float := oneG / (2 : UInt64).toFloat def c6G : Float := oneG / (6 : UInt64).toFloat def c24G : Float := oneG / (24 : UInt64).toFloat def c120G : Float := oneG / (120 : UInt64).toFloat /-- `2^−34`, `2^−41`, `2^−26`. -/ def m34G : Float := D.pwEntry 116 def m41G : Float := D.pwEntry 109 def m26G : Float := D.pwEntry 124 def negOneG : Float := 0 - oneG /-- Degree-5 Taylor polynomial of `e^(−r)`, Horner form. -/ @[inline] def polyG (r : Float) : Float := oneG - r * (oneG - r * (halfG - r * (c6G - r * (c24G - r * c120G)))) theorem tabG_size : expTabG.size = 1280 := by simp [expTabG, FloatArray.size] theorem kidx {k b : UInt32} (h : k < b) (hb : b.toNat ≤ 1280) : k.toUSize.toNat < expTabG.size := by rw [tabG_size]; simp only [UInt32.toNat_toUSize]; have := UInt32.lt_iff_toNat_lt.mp h; omega theorem kLt {k b : UInt32} (h : k < b) (hb : b ≤ 1280) : k < 1280 := by rw [UInt32.lt_iff_toNat_lt] at *; rw [UInt32.le_iff_toNat_le] at hb; simp only [UInt32.reduceToNat] at *; omega theorem eidx (a : UInt32) : (a >>> 23).toUSize.toNat < D.pw.size := D.qCh a /-- For `c = m · 2^(F−150)`: the shift giving `k = ⌊64 c⌋` (capped at 31). -/ @[inline] def sOfG (F : UInt32) : UInt32 := if 144 - F < 31 then 144 - F else 31 @[inline] def kOfG (m F : UInt32) : UInt32 := m >>> sOfG F /-- `r = c − k/64`, exact. -/ @[inline] def rOfG (m F : UInt32) (h : F.toUSize.toNat < D.pw.size) : Float := (m - (kOfG m F <<< sOfG F)).toUInt64.toFloat * D.pw.uget F.toUSize h /-- `e^(−c) ≈ T[k] · p(r)`. -/ @[inline] def tOfG (m F : UInt32) (h : F.toUSize.toNat < D.pw.size) (hk : kOfG m F < 1280) : Float := expTabG.uget (kOfG m F).toUSize (kidx hk (by decide)) * polyG (rOfG m F h) /-- `σ(x)` through the table; `0xFFFFFFFF` when not settled. -/ @[inline] def sigG (w : UInt32) : UInt32 := let a := w &&& 0x7FFFFFFF let F := a >>> 23 if F - 1 < 131 then let m := (a &&& 0x7FFFFF) ||| 0x800000 if w < 0x80000000 then if h : kOfG m F < 1216 then let t := tOfG m F (eidx a) (kLt h (by decide)) let q := oneG / (oneG + t) ziv q m41G else ziv oneG m26G else if h : kOfG m F < 1088 then let t := tOfG m F (eidx a) (kLt h (by decide)) let q := t / (oneG + t) ziv q (q * m34G) else 0xFFFFFFFF else if 131 < F && F < 255 && w < 0x80000000 then ziv oneG m26G else 0xFFFFFFFF /-- `tanh x` through the table (`e^(−2|x|)`); `0xFFFFFFFF` when not settled. -/ @[inline] def tanhG (w : UInt32) : UInt32 := let a := w &&& 0x7FFFFFFF let F := (a + 0x800000) >>> 23 if F - 2 < 131 then let m := (a &&& 0x7FFFFF) ||| 0x800000 if h : kOfG m F < 1280 then let t := tOfG m F (eidx _) h let q := (if w < 0x80000000 then oneG - t else t - oneG) / (oneG + t) ziv q m41G else ziv (if w < 0x80000000 then oneG else negOneG) m26G else if 132 < F && F < 256 then ziv (if w < 0x80000000 then oneG else negOneG) m26G else 0xFFFFFFFF def sigmoidF2 (w : UInt32) : UInt32 := let v := if tabOK then sigG w else 0xFFFFFFFF if v == 0xFFFFFFFF then sigmoidF9 w else v def tanhF2 (w : UInt32) : UInt32 := let v := if tabOK then tanhG w else 0xFFFFFFFF if v == 0xFFFFFFFF then tanhF9 w else v end ActG /-! ## Binary64 error toolkit -/ section GTool /-- `x` is finite and within `ε` of `X`. -/ def gAp (x : Float) (X ε : ℝ) : Prop := x.isFinite = true ∧ |D.R x - X| ≤ ε theorem gAz : D.A_z ≤ 1 / 2 ^ 100 := by unfold D.A_z rw [show (1 : ℝ) / 2 ^ 100 = (2 : ℝ) ^ (-100 : ℤ) by norm_num] exact zpow_le_zpow_right₀ (by norm_num) (by norm_num) theorem gAB : (2 : ℝ) ^ 100 ≤ D.A_B := by unfold D.A_B rw [show (2 : ℝ) ^ 100 = (2 : ℝ) ^ (100 : ℤ) by norm_num] exact zpow_le_zpow_right₀ (by norm_num) (by norm_num) theorem gAp.mono {x : Float} {X ε ε' : ℝ} (h : gAp x X ε) (he : ε ≤ ε') : gAp x X ε' := ⟨h.1, h.2.trans he⟩ theorem gAp.absR {x : Float} {X ε : ℝ} (h : gAp x X ε) : |D.R x| ≤ |X| + ε := by have := abs_sub_abs_le_abs_sub (D.R x) X linarith [h.2] theorem gAp.bnd {x : Float} {X ε M : ℝ} (h : gAp x X ε) (hX : |X| ≤ M) (hM : M + ε ≤ 2 ^ 100) : |D.R x| ≤ D.A_B := by have := h.absR; linarith [gAB] theorem gAp_add {x y : Float} {X Y ε δ M N : ℝ} (hx : gAp x X ε) (hy : gAp y Y δ) (hX : |X| ≤ M) (hY : |Y| ≤ N) (hM : M + ε ≤ 2 ^ 100) (hN : N + δ ≤ 2 ^ 100) : gAp (x + y) (X + Y) (ε + δ + 1 / 2 ^ 53 * (M + N + ε + δ) + 1 / 2 ^ 153) := by obtain ⟨f, e⟩ := D.qBf x y hx.1 hy.1 (hx.bnd hX hM) (hy.bnd hY hN) refine ⟨f, ?_⟩ have h1 := hx.absR; have h2 := hy.absR have hz := gAz have ha : |D.R x + D.R y| ≤ M + N + ε + δ := (abs_add_le _ _).trans (by linarith) have hb : |D.R x + D.R y - (X + Y)| ≤ ε + δ := by have := abs_add_le (D.R x - X) (D.R y - Y) rw [show D.R x - X + (D.R y - Y) = D.R x + D.R y - (X + Y) by ring] at this linarith [hx.2, hy.2] have hc := abs_sub_le (D.R (x + y)) (D.R x + D.R y) (X + Y) have : 1 / 2 ^ 53 * (|D.R x + D.R y| + D.A_z) ≤ 1 / 2 ^ 53 * (M + N + ε + δ) + 1 / 2 ^ 153 := by have : (1 : ℝ) / 2 ^ 153 = 1 / 2 ^ 53 * (1 / 2 ^ 100) := by norm_num rw [this, ← mul_add] exact mul_le_mul_of_nonneg_left (by linarith) (by norm_num) linarith theorem gAp_sub {x y : Float} {X Y ε δ M N : ℝ} (hx : gAp x X ε) (hy : gAp y Y δ) (hX : |X| ≤ M) (hY : |Y| ≤ N) (hM : M + ε ≤ 2 ^ 100) (hN : N + δ ≤ 2 ^ 100) : gAp (x - y) (X - Y) (ε + δ + 1 / 2 ^ 53 * (M + N + ε + δ) + 1 / 2 ^ 153) := by obtain ⟨f, e⟩ := D.qDf x y hx.1 hy.1 (hx.bnd hX hM) (hy.bnd hY hN) refine ⟨f, ?_⟩ have h1 := hx.absR; have h2 := hy.absR have hz := gAz have ha : |D.R x - D.R y| ≤ M + N + ε + δ := (abs_sub _ _).trans (by linarith) have hb : |D.R x - D.R y - (X - Y)| ≤ ε + δ := by have := abs_sub (D.R x - X) (D.R y - Y) rw [show D.R x - X - (D.R y - Y) = D.R x - D.R y - (X - Y) by ring] at this linarith [hx.2, hy.2] have hc := abs_sub_le (D.R (x - y)) (D.R x - D.R y) (X - Y) have : 1 / 2 ^ 53 * (|D.R x - D.R y| + D.A_z) ≤ 1 / 2 ^ 53 * (M + N + ε + δ) + 1 / 2 ^ 153 := by have : (1 : ℝ) / 2 ^ 153 = 1 / 2 ^ 53 * (1 / 2 ^ 100) := by norm_num rw [this, ← mul_add] exact mul_le_mul_of_nonneg_left (by linarith) (by norm_num) linarith theorem gAp_mul {x y : Float} {X Y ε δ M N : ℝ} (hx : gAp x X ε) (hy : gAp y Y δ) (hX : |X| ≤ M) (hY : |Y| ≤ N) (hM : M + ε ≤ 2 ^ 100) (hN : N + δ ≤ 2 ^ 100) : gAp (x * y) (X * Y) ((M + ε) * δ + N * ε + 1 / 2 ^ 53 * ((M + ε) * (N + δ)) + 1 / 2 ^ 153) := by obtain ⟨f, e⟩ := D.qCf x y hx.1 hy.1 (hx.bnd hX hM) (hy.bnd hY hN) refine ⟨f, ?_⟩ have h1 := hx.absR; have h2 := hy.absR have hz := gAz have e0 : 0 ≤ ε := (abs_nonneg _).trans hx.2 have d0 : 0 ≤ δ := (abs_nonneg _).trans hy.2 have ha : |D.R x * D.R y| ≤ (M + ε) * (N + δ) := by rw [abs_mul]; exact mul_le_mul (by linarith) (by linarith) (abs_nonneg _) (by linarith [abs_nonneg X]) have hb : |D.R x * D.R y - X * Y| ≤ (M + ε) * δ + N * ε := by have : D.R x * D.R y - X * Y = D.R x * (D.R y - Y) + Y * (D.R x - X) := by ring rw [this] refine (abs_add_le _ _).trans ?_ rw [abs_mul, abs_mul] exact add_le_add (mul_le_mul (by linarith) hy.2 (abs_nonneg _) (by linarith [abs_nonneg X])) (mul_le_mul hY hx.2 (abs_nonneg _) (by linarith [abs_nonneg Y])) have hc := abs_sub_le (D.R (x * y)) (D.R x * D.R y) (X * Y) have : 1 / 2 ^ 53 * (|D.R x * D.R y| + D.A_z) ≤ 1 / 2 ^ 53 * ((M + ε) * (N + δ)) + 1 / 2 ^ 153 := by have : (1 : ℝ) / 2 ^ 153 = 1 / 2 ^ 53 * (1 / 2 ^ 100) := by norm_num rw [this, ← mul_add] exact mul_le_mul_of_nonneg_left (by linarith) (by norm_num) linarith theorem gDiv (x y : Float) (hx : x.isFinite = true) (hy : y.isFinite = true) (hy0 : D.R y ≠ 0) (hb : |D.R x / D.R y| ≤ D.A_B) : (x / y).isFinite = true ∧ |D.R (x / y) - D.R x / D.R y| ≤ 1 / 2 ^ 53 * (|D.R x / D.R y| + D.A_z) := by have hz : Model.isZero (D.A_M y) = false := by cases h : Model.isZero (D.A_M y) with | false => rfl | true => exact absurd (Model.toReal_eq_zero_of_isZero _ h) hy0 have hB : |Model.toReal (D.A_M x) / Model.toReal (D.A_M y)| ≤ Model.toReal (Model.posMaxFinite FloatFormat.binary64) := have h1 := le_trans (by linarith [gAB] : D.A_B ≤ D.A_B * 2) D.qE3 hb.trans (h1.trans D.qCd) exact D.qFc (D.A_E _ (toModel_ofFloat_div_of_isFinite x y hx hy) (Model.isFinite_div_of_abs_div_le_posMaxFinite _ _ D.qAj (D.qA3 hx) (D.qA3 hy) hz hB) (Model.toReal_div_eq_roundAt_of_abs_div_le_posMaxFinite _ _ D.qAj (D.qA3 hx) (D.qA3 hy) hz hB)) end GTool section GTool2 theorem gAp_div {x y : Float} {X Y ε δ M m : ℝ} (hx : gAp x X ε) (hy : gAp y Y δ) (hX : |X| ≤ M) (hm : m ≤ Y) (hδ : δ < m) (hq : (M + ε) / (m - δ) ≤ 2 ^ 100) : gAp (x / y) (X / Y) (ε / (m - δ) + M * δ / ((m - δ) * m) + 1 / 2 ^ 53 * ((M + ε) / (m - δ)) + 1 / 2 ^ 153) := by have h1 := hx.absR have e0 : 0 ≤ ε := (abs_nonneg _).trans hx.2 have d0 : 0 ≤ δ := (abs_nonneg _).trans hy.2 have hmd : 0 < m - δ := by linarith have hm0 : 0 < m := by linarith have hY0 : 0 < Y := by linarith have hRy : m - δ ≤ D.R y := by have := abs_le.mp hy.2; linarith have hRy0 : 0 < D.R y := by linarith have hqa : |D.R x / D.R y| ≤ (M + ε) / (m - δ) := by rw [abs_div, abs_of_pos hRy0] exact div_le_div₀ (by linarith [abs_nonneg X]) (by linarith) hmd hRy obtain ⟨f, e⟩ := gDiv x y hx.1 hy.1 hRy0.ne' (hqa.trans (hq.trans gAB)) refine ⟨f, ?_⟩ have hz := gAz have hb : |D.R x / D.R y - X / Y| ≤ ε / (m - δ) + M * δ / ((m - δ) * m) := by rw [div_sub_div _ _ hRy0.ne' hY0.ne', abs_div, abs_of_pos (mul_pos hRy0 hY0)] have hn : |D.R x * Y - D.R y * X| ≤ ε * Y + M * δ := by have : D.R x * Y - D.R y * X = (D.R x - X) * Y + X * (Y - D.R y) := by ring rw [this] refine (abs_add_le _ _).trans ?_ rw [abs_mul, abs_mul, abs_of_pos hY0] exact add_le_add (mul_le_mul_of_nonneg_right hx.2 hY0.le) (mul_le_mul hX (by rw [abs_sub_comm]; exact hy.2) (abs_nonneg _) (by linarith [abs_nonneg X])) rw [div_le_iff₀ (mul_pos hRy0 hY0)] have hA : ε * Y ≤ ε / (m - δ) * (D.R y * Y) := by rw [div_mul_eq_mul_div, le_div_iff₀ hmd] have := mul_le_mul_of_nonneg_left hRy (mul_nonneg e0 hY0.le) linarith have hB : M * δ ≤ M * δ / ((m - δ) * m) * (D.R y * Y) := by have hM0 : 0 ≤ M := (abs_nonneg _).trans hX rw [div_mul_eq_mul_div, le_div_iff₀ (mul_pos hmd hm0)] have := mul_le_mul hRy hm hm0.le hRy0.le have := mul_le_mul_of_nonneg_left this (mul_nonneg hM0 d0) linarith rw [add_mul]; linarith have hc := abs_sub_le (D.R (x / y)) (D.R x / D.R y) (X / Y) have : 1 / 2 ^ 53 * (|D.R x / D.R y| + D.A_z) ≤ 1 / 2 ^ 53 * ((M + ε) / (m - δ)) + 1 / 2 ^ 153 := by have : (1 : ℝ) / 2 ^ 153 = 1 / 2 ^ 53 * (1 / 2 ^ 100) := by norm_num rw [this, ← mul_add] exact mul_le_mul_of_nonneg_left (by linarith) (by norm_num) linarith theorem gAp_exact {x : Float} {X : ℝ} (hf : x.isFinite = true) (h : D.R x = X) : gAp x X 0 := ⟨hf, by rw [h, sub_self, abs_zero]⟩ /-- `1/n` for a small positive integer `n`. -/ theorem gAp_inv (n : UInt64) (hn0 : 0 < n.toNat) (hn : n.toNat < 2 ^ 53) : gAp ((1 : UInt64).toFloat / n.toFloat) (1 / n.toNat) (1 / 2 ^ 53 * (1 / n.toNat) + 1 / 2 ^ 153) := by obtain ⟨f1, r1⟩ := D.qCk 1 (by decide) obtain ⟨fn, rn⟩ := D.qCk n hn have hn0' : (0 : ℝ) < n.toNat := by exact_mod_cast hn0 have h1n : (1 : ℝ) ≤ n.toNat := by exact_mod_cast hn0 have hb : |D.R (1 : UInt64).toFloat / D.R n.toFloat| ≤ D.A_B := by rw [r1, rn]; simp only [UInt64.toNat_one, Nat.cast_one] rw [abs_of_pos (by positivity)] exact ((div_le_one hn0').mpr h1n).trans (le_trans (by norm_num) gAB) obtain ⟨f, e⟩ := gDiv _ _ f1 fn (by rw [rn]; exact hn0'.ne') hb refine ⟨f, ?_⟩ rw [r1, rn] at e; simp only [UInt64.toNat_one, Nat.cast_one] at e rw [abs_of_pos (show (0:ℝ) < 1 / (n.toNat : ℝ) by positivity)] at e have hz := gAz have : 1 / 2 ^ 53 * (1 / (n.toNat : ℝ) + D.A_z) ≤ 1 / 2 ^ 53 * (1 / n.toNat) + 1 / 2 ^ 153 := by have : (1 : ℝ) / 2 ^ 153 = 1 / 2 ^ 53 * (1 / 2 ^ 100) := by norm_num rw [this, ← mul_add] exact mul_le_mul_of_nonneg_left (by linarith) (by norm_num) linarith theorem gOne : gAp oneG 1 0 := by obtain ⟨f, r⟩ := D.qCk 1 (by decide) exact gAp_exact f (by rw [oneG, r]; simp) theorem gHalf : gAp halfG (1 / 2) (1 / 2 ^ 53) := by have h := gAp_inv 2 (by decide) (by decide) have e : ((UInt64.toNat 2 : Nat) : ℝ) = 2 := by norm_num rw [e] at h exact h.mono (by norm_num) end GTool2 section GPoly theorem gC6 : gAp c6G (1 / 6) (1 / 2 ^ 55) := by have h := gAp_inv 6 (by decide) (by decide) have e : ((UInt64.toNat 6 : Nat) : ℝ) = 6 := by norm_num rw [e] at h; exact h.mono (by norm_num) theorem gC24 : gAp c24G (1 / 24) (1 / 2 ^ 57) := by have h := gAp_inv 24 (by decide) (by decide) have e : ((UInt64.toNat 24 : Nat) : ℝ) = 24 := by norm_num rw [e] at h; exact h.mono (by norm_num) theorem gC120 : gAp c120G (1 / 120) (1 / 2 ^ 59) := by have h := gAp_inv 120 (by decide) (by decide) have e : ((UInt64.toNat 120 : Nat) : ℝ) = 120 := by norm_num rw [e] at h; exact h.mono (by norm_num) theorem exp_neg_taylor5 {r : ℝ} (h0 : 0 ≤ r) (h1 : r ≤ 1) : |Real.exp (-r) - (1 - r * (1 - r * (1 / 2 - r * (1 / 6 - r * (1 / 24 - r * (1 / 120))))))| ≤ r ^ 6 * (7 / 4320) := by have h := Real.exp_bound (x := -r) (by rw [abs_neg, abs_of_nonneg h0]; exact h1) (n := 6) (by norm_num) simp only [Finset.sum_range_succ, Finset.sum_range_zero, Nat.factorial] at h rw [abs_neg, abs_of_nonneg h0] at h convert h using 2 · norm_num; ring · norm_num theorem gPoly {r : Float} {ρ : ℝ} (hr : gAp r ρ 0) (h0 : 0 ≤ ρ) (h1 : ρ ≤ 1 / 64) : gAp (polyG r) (Real.exp (-ρ)) (1 / 2 ^ 45) := by have hρ : |ρ| ≤ 1 / 64 := by rw [abs_of_nonneg h0]; exact h1 have s5 := (gAp_mul hr gC120 hρ (by norm_num : |(1:ℝ)/120| ≤ 1/120) (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 64 by norm_num) have b5 : |ρ * (1 / 120)| ≤ 1 / 7680 := by rw [abs_mul, abs_of_nonneg h0]; norm_num; linarith have s4 := (gAp_sub gC24 s5 (by norm_num : |(1:ℝ)/24| ≤ 1/24) b5 (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 56 by norm_num) have b4 : |1 / 24 - ρ * (1 / 120)| ≤ 1 / 24 := by rw [abs_le]; constructor <;> linarith have s4' := (gAp_mul hr s4 hρ b4 (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 61 by norm_num) have b4' : |ρ * (1 / 24 - ρ * (1 / 120))| ≤ 1 / 1536 := by rw [abs_mul, abs_of_nonneg h0] calc ρ * |1 / 24 - ρ * (1 / 120)| ≤ (1 / 64) * (1 / 24) := mul_le_mul h1 b4 (abs_nonneg _) (by norm_num) _ = 1 / 1536 := by norm_num have s3 := (gAp_sub gC6 s4' (by norm_num : |(1:ℝ)/6| ≤ 1/6) b4' (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 54 by norm_num) have b3 : |1 / 6 - ρ * (1 / 24 - ρ * (1 / 120))| ≤ 1 / 6 := by have := abs_le.mp b4' have n4 : 0 ≤ ρ * (1 / 24 - ρ * (1 / 120)) := mul_nonneg h0 (by linarith) rw [abs_le]; constructor <;> linarith have s3' := (gAp_mul hr s3 hρ b3 (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 59 by norm_num) have b3' : |ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120)))| ≤ 1 / 384 := by rw [abs_mul, abs_of_nonneg h0] calc ρ * |1 / 6 - ρ * (1 / 24 - ρ * (1 / 120))| ≤ (1 / 64) * (1 / 6) := mul_le_mul h1 b3 (abs_nonneg _) (by norm_num) _ = 1 / 384 := by norm_num have s2 := (gAp_sub gHalf s3' (by norm_num : |(1:ℝ)/2| ≤ 1/2) b3' (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 52 by norm_num) have b2 : |1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120)))| ≤ 1 / 2 := by have := abs_le.mp b3' have n3 : 0 ≤ ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120))) := mul_nonneg h0 (by linarith [(abs_le.mp b4').2]) rw [abs_le]; constructor <;> linarith have s2' := (gAp_mul hr s2 hρ b2 (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 57 by norm_num) have b2' : |ρ * (1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120))))| ≤ 1 / 128 := by rw [abs_mul, abs_of_nonneg h0] calc ρ * |1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120)))| ≤ (1 / 64) * (1 / 2) := mul_le_mul h1 b2 (abs_nonneg _) (by norm_num) _ = 1 / 128 := by norm_num have s1 := (gAp_sub gOne s2' (by norm_num : |(1:ℝ)| ≤ 1) b2' (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 52 by norm_num) have b1 : |1 - ρ * (1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120))))| ≤ 1 := by have := abs_le.mp b2' have n2 : 0 ≤ ρ * (1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120)))) := mul_nonneg h0 (by linarith [(abs_le.mp b3').2]) rw [abs_le]; constructor <;> linarith have s1' := (gAp_mul hr s1 hρ b1 (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 57 by norm_num) have b1' : |ρ * (1 - ρ * (1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120)))))| ≤ 1 / 64 := by rw [abs_mul, abs_of_nonneg h0] calc ρ * |1 - ρ * (1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120))))| ≤ (1 / 64) * 1 := mul_le_mul h1 b1 (abs_nonneg _) (by norm_num) _ = 1 / 64 := by norm_num have s0 := (gAp_sub gOne s1' (by norm_num : |(1:ℝ)| ≤ 1) b1' (by norm_num) (by norm_num)).mono (show _ ≤ (1:ℝ) / 2 ^ 52 by norm_num) refine ⟨s0.1, ?_⟩ have hT := exp_neg_taylor5 h0 (by linarith) have h6 : ρ ^ 6 ≤ (1 / 64) ^ 6 := pow_le_pow_left₀ h0 h1 6 have := abs_sub_le (D.R (polyG r)) (1 - ρ * (1 - ρ * (1 / 2 - ρ * (1 / 6 - ρ * (1 / 24 - ρ * (1 / 120)))))) (Real.exp (-ρ)) rw [abs_sub_comm (1 - _) (Real.exp _)] at this have e2 : D.R (polyG r) = D.R (oneG - r * (oneG - r * (halfG - r * (c6G - r * (c24G - r * c120G))))) := rfl have := s0.2 rw [← e2] at this have h7 := mul_le_mul_of_nonneg_right h6 (by norm_num : (0:ℝ) ≤ 7 / 4320) have h8 : (1 / 2 ^ 52 : ℝ) + (1 / 64) ^ 6 * (7 / 4320) ≤ 1 / 2 ^ 45 := by norm_num linarith end GPoly section GTab theorem gPw (i : Nat) (h0 : 0 < i) (h1 : i < 256) : (D.pwEntry i).isFinite = true ∧ D.R (D.pwEntry i) = (2 : ℝ) ^ ((i : ℤ) - 150) := by obtain ⟨f, e⟩ := D.qDa i (by omega) refine ⟨f, ?_⟩ rw [e, if_neg (by omega), if_neg (by omega), Nat.mod_eq_of_lt h1, one_mul] theorem toF62_spec (lo : Nat) (h : lo ≤ 2 ^ 62) : (toF62 lo).isFinite = true ∧ D.R (toF62 lo) ≤ FastAct.V lo ∧ FastAct.V lo - D.R (toF62 lo) ≤ FastAct.V lo / 2 ^ 52 := by unfold toF62 generalize hsh : lo.log2 - 52 = sh have hL : lo.log2 ≤ 62 := by rcases Nat.eq_zero_or_pos lo with h0 | h0 · subst h0; simp · exact Nat.lt_succ_iff.mp ((Nat.log2_lt h0.ne').mpr (lt_of_le_of_lt h (by norm_num))) have hsh10 : sh ≤ 10 := by omega have hq : lo >>> sh = lo / 2 ^ sh := Nat.shiftRight_eq_div_pow lo sh have hlt := (Nat.lt_log2_self (n := lo)) have hq53 : lo / 2 ^ sh < 2 ^ 53 := by rw [Nat.div_lt_iff_lt_mul (by positivity), ← pow_add] exact lt_of_lt_of_le hlt (Nat.pow_le_pow_right (by norm_num) (by omega)) have hqu : (lo >>> sh).toUInt64.toNat = lo / 2 ^ sh := by rw [hq, Nat.toUInt64, UInt64.toNat_ofNat']; exact Nat.mod_eq_of_lt (lt_trans hq53 (by norm_num)) obtain ⟨fq, rq⟩ := D.qCk (lo >>> sh).toUInt64 (by rw [hqu]; exact hq53) rw [hqu] at rq obtain ⟨fp, rp⟩ := gPw (88 + sh) (by omega) (by omega) obtain ⟨f, e⟩ := D.qCm _ (88 + sh) (by omega) fq ((lo / 2 ^ sh : Nat) : ℤ) 0 (by omega) (by norm_num) (by rw [rq, abs_of_nonneg (by positivity)] exact le_trans (show ((lo / 2 ^ sh : Nat) : ℝ) ≤ 2 ^ 53 by exact_mod_cast hq53.le) (le_trans (by norm_num) gAB)) (by rw [rq, zpow_zero, mul_one, Int.cast_natCast]) refine ⟨f, ?_⟩ rw [e, rq, rp] have hval : ((lo / 2 ^ sh : Nat) : ℝ) * (2 : ℝ) ^ (((88 + sh : Nat) : ℤ) - 150) = ((lo / 2 ^ sh * 2 ^ sh : Nat) : ℝ) / 2 ^ 62 := by rw [show (((88 + sh : Nat) : ℤ) - 150) = (sh : ℤ) - 62 by push_cast; ring, zpow_sub₀ (by norm_num), zpow_natCast] push_cast; ring rw [hval] unfold FastAct.V have hm : lo / 2 ^ sh * 2 ^ sh ≤ lo := Nat.div_mul_le_self lo _ have hr : lo - lo / 2 ^ sh * 2 ^ sh < 2 ^ sh := by have := Nat.mod_lt lo (show 0 < 2 ^ sh by positivity) have := Nat.div_add_mod lo (2 ^ sh) rw [Nat.mul_comm] at this; omega refine ⟨div_le_div_of_nonneg_right (by exact_mod_cast hm) (by positivity), ?_⟩ rcases Nat.eq_zero_or_pos sh with h0 | h0 · subst h0; simp positivity · have hlo : 2 ^ (sh + 52) ≤ lo := by have hne : lo ≠ 0 := by rintro rfl; simp at hsh; omega exact (Nat.le_log2 hne).mp (by omega) rw [div_div, ← sub_div, div_le_div_iff₀ (by positivity) (by positivity)] have h1 : ((lo : ℝ) - ((lo / 2 ^ sh * 2 ^ sh : Nat) : ℝ)) ≤ 2 ^ sh := by rw [← Nat.cast_sub hm]; exact_mod_cast hr.le have h2 : (2 : ℝ) ^ (sh + 52) ≤ lo := by exact_mod_cast hlo rw [pow_add] at h2 nlinarith theorem Encl_congr {iv : Nat × Nat} {a b : ℝ} (h : FastAct.Encl iv a) (e : a = b) : FastAct.Encl iv b := e ▸ h theorem enclK_spec {k : Nat} (hk : k < 1280) : FastAct.Encl (enclK k) (k * (1 / 64)) := by unfold enclK have hj : k % 64 < 64 := Nat.mod_lt _ (by norm_num) have hF := FastAct.fracTab_spec hj have hkd : (k : ℝ) = ((k / 64 : Nat) : ℝ) * 64 + ((k % 64 : Nat) : ℝ) := by have := Nat.div_add_mod k 64; exact_mod_cast (by omega : k = k / 64 * 64 + k % 64) dsimp only split · rename_i hn exact Encl_congr ((FastAct.intTab_spec (by omega)).mul hF) (by rw [hkd]; ring) · rename_i hn have hI := (FastAct.intTab_spec (n := 16) (by norm_num)).mul (FastAct.intTab_spec (n := k / 64 - 16) (by omega)) refine Encl_congr (hI.mul hF) ?_ rw [hkd, Nat.cast_sub (by omega)]; push_cast; ring theorem tabOK_spec (h : tabOK = true) {k : Nat} (hk : k < 1280) : (enclK k).2 - (enclK k).1 ≤ 2 ^ 14 ∧ (k < 1088 → ((enclK k).2 - (enclK k).1) * 2 ^ 36 ≤ (enclK k).1) := by unfold tabOK at h have := List.all_eq_true.mp h k (List.mem_range.mpr hk) simp only [Bool.and_eq_true, Bool.or_eq_true, decide_eq_true_eq] at this refine ⟨this.1, fun h2 => ?_⟩ rcases this.2 with h3 | h3 · omega · exact h3 theorem tabG_get {k : UInt32} (hk : k.toUSize.toNat < expTabG.size) : expTabG.uget k.toUSize hk = toF62 (enclK k.toNat).1 := by have hk' : k.toNat < 1280 := by rw [tabG_size] at hk; simpa using hk have e : expTabG.uget k.toUSize hk = (Array.ofFn (n := 1280) fun k => toF62 (enclK k.val).1)[k.toNat]'(by simpa using hk') := rfl rw [e] simp only [Array.getElem_ofFn] /-- The table entry: one-sided, absolute error `≤ 2^−48 + 2^−52`, relative `≤ 2^−36 + 2^−52` below 1088. -/ theorem tabG_spec (hok : tabOK = true) {k : UInt32} (hk : k.toUSize.toNat < expTabG.size) : gAp (expTabG.uget k.toUSize hk) (Real.exp (-(k.toNat * (1 / 64)))) (1 / 2 ^ 48 + 1 / 2 ^ 52) ∧ D.R (expTabG.uget k.toUSize hk) ≤ Real.exp (-(k.toNat * (1 / 64))) ∧ (k.toNat < 1088 → Real.exp (-(k.toNat * (1 / 64))) - D.R (expTabG.uget k.toUSize hk) ≤ (1 / 2 ^ 36 + 1 / 2 ^ 52) * Real.exp (-(k.toNat * (1 / 64)))) := by have hk' : k.toNat < 1280 := by rw [tabG_size] at hk; simpa using hk rw [tabG_get] obtain ⟨e1, e2, e3⟩ := enclK_spec hk' obtain ⟨w1, w2⟩ := tabOK_spec hok hk' generalize enclK k.toNat = iv at e1 e2 e3 w1 w2 obtain ⟨lo, hi⟩ := iv simp only at e1 e2 e3 w1 w2 ⊢ have hlohi : lo ≤ hi := by by_contra hc have : FastAct.V hi < FastAct.V lo := by unfold FastAct.V; exact div_lt_div_of_pos_right (by exact_mod_cast (not_le.mp hc)) (by positivity) linarith have hhi : hi ≤ 2 ^ 62 := e3 obtain ⟨f, r1, r2⟩ := toF62_spec lo (le_trans hlohi hhi) set E := Real.exp (-(k.toNat * (1 / 64 : ℝ))) have hVlo : FastAct.V lo ≤ 1 := by unfold FastAct.V; rw [div_le_one (by positivity)]; exact_mod_cast le_trans hlohi hhi have hw : FastAct.V hi - FastAct.V lo = ((hi - lo : Nat) : ℝ) / 2 ^ 62 := by unfold FastAct.V; rw [Nat.cast_sub hlohi]; ring have hw1 : FastAct.V hi - FastAct.V lo ≤ 1 / 2 ^ 48 := by rw [hw] have : ((hi - lo : Nat) : ℝ) ≤ 2 ^ 14 := by exact_mod_cast w1 calc ((hi - lo : Nat) : ℝ) / 2 ^ 62 ≤ 2 ^ 14 / 2 ^ 62 := div_le_div_of_nonneg_right this (by positivity) _ = 1 / 2 ^ 48 := by norm_num have hR : D.R (toF62 lo) ≤ E := r1.trans e1 refine ⟨⟨f, ?_⟩, hR, fun h2 => ?_⟩ · rw [abs_sub_comm, abs_of_nonneg (by linarith)] have : FastAct.V lo / 2 ^ 52 ≤ 1 / 2 ^ 52 := div_le_div_of_nonneg_right hVlo (by positivity) linarith · have w3 := w2 h2 have hw2 : FastAct.V hi - FastAct.V lo ≤ FastAct.V lo / 2 ^ 36 := by rw [hw]; unfold FastAct.V have : ((hi - lo : Nat) : ℝ) ≤ lo / 2 ^ 36 := by rw [le_div_iff₀ (by positivity)]; exact_mod_cast w3 calc ((hi - lo : Nat) : ℝ) / 2 ^ 62 ≤ (lo / 2 ^ 36) / 2 ^ 62 := div_le_div_of_nonneg_right this (by positivity) _ = lo / 2 ^ 62 / 2 ^ 36 := by ring have : FastAct.V lo / 2 ^ 36 ≤ E / 2 ^ 36 := div_le_div_of_nonneg_right e1 (by positivity) have : FastAct.V lo / 2 ^ 52 ≤ E / 2 ^ 52 := div_le_div_of_nonneg_right e1 (by positivity) linarith end GTab section GSplit theorem sOfG_toNat (F : UInt32) (hF : F.toNat ≤ 144) : (sOfG F).toNat = min (144 - F.toNat) 31 := by unfold sOfG have e : (144 - F).toNat = 144 - F.toNat := by rw [UInt32.toNat_sub_of_le _ _ (UInt32.le_iff_toNat_le.mpr (by simpa using hF))]; simp split · rename_i h rw [UInt32.lt_iff_toNat_lt, e] at h simp at h rw [e]; omega · rename_i h rw [UInt32.lt_iff_toNat_lt, e] at h simp at h simp; omega theorem kOfG_toNat (m F : UInt32) (hF : F.toNat ≤ 144) : (kOfG m F).toNat = m.toNat / 2 ^ (sOfG F).toNat := by unfold kOfG have hs := sOfG_toNat F hF rw [UInt32.toNat_shiftRight, Nat.shiftRight_eq_div_pow, Nat.mod_eq_of_lt (by omega)] /-- The split `c = k/64 + r`: `r` is exact and `0 ≤ r < 1/64`. -/ theorem split_spec (m F : UInt32) (hm2 : m.toNat < 2 ^ 24) (hF1 : 1 ≤ F.toNat) (hF2 : F.toNat ≤ 144) (h : F.toUSize.toNat < D.pw.size) : gAp (rOfG m F h) ((m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) - (kOfG m F).toNat * (1 / 64)) 0 ∧ 0 ≤ (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) - (kOfG m F).toNat * (1 / 64) ∧ (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) - (kOfG m F).toNat * (1 / 64) < 1 / 64 := by have hs := sOfG_toNat F hF2 have hk := kOfG_toNat m F hF2 set s := (sOfG F).toNat with hsdef set M := m.toNat set f := F.toNat have hs31 : s ≤ 31 := by omega have hks : (kOfG m F <<< sOfG F).toNat = M / 2 ^ s * 2 ^ s := by rw [UInt32.toNat_shiftLeft, hk, Nat.shiftLeft_eq] have e32 : s % 32 = s := by omega rw [e32] exact Nat.mod_eq_of_lt (lt_of_le_of_lt (Nat.div_mul_le_self M _) (by omega)) have hle : kOfG m F <<< sOfG F ≤ m := by rw [UInt32.le_iff_toNat_le, hks]; exact Nat.div_mul_le_self M _ have hrr : (m - (kOfG m F <<< sOfG F)).toUInt64.toNat = M % 2 ^ s := by rw [UInt32.toNat_toUInt64, UInt32.toNat_sub_of_le _ _ hle, hks] have := Nat.div_add_mod M (2 ^ s); rw [Nat.mul_comm] at this; omega have hmod : M % 2 ^ s < 2 ^ 24 := lt_of_le_of_lt (Nat.mod_le _ _) hm2 obtain ⟨fq, rq⟩ := D.qCk (m - (kOfG m F <<< sOfG F)).toUInt64 (by rw [hrr]; omega) rw [hrr] at rq have hpw : D.pw.uget F.toUSize h = D.pwEntry f := by rw [D.qDc]; simp [f] obtain ⟨fp, rp⟩ := gPw f hF1 (by omega) obtain ⟨fr, er⟩ := D.qCm _ f (by omega) fq ((M % 2 ^ s : Nat) : ℤ) 0 (by omega) (by norm_num) (by rw [rq, abs_of_nonneg (by positivity)] exact le_trans (show ((M % 2 ^ s : Nat) : ℝ) ≤ 2 ^ 24 by exact_mod_cast hmod.le) (le_trans (by norm_num) gAB)) (by rw [rq, zpow_zero, mul_one, Int.cast_natCast]) have hr : D.R (rOfG m F h) = ((M % 2 ^ s : Nat) : ℝ) * 2 ^ ((f : ℤ) - 150) := by unfold rOfG; rw [hpw, er, rq, rp] replace fr : (rOfG m F h).isFinite = true := by unfold rOfG; rw [hpw]; exact fr have hdm : (M : ℝ) = ((M / 2 ^ s : Nat) : ℝ) * 2 ^ s + ((M % 2 ^ s : Nat) : ℝ) := by have := Nat.div_add_mod M (2 ^ s); rw [Nat.mul_comm] at this; exact_mod_cast this.symm have hp0 : (0 : ℝ) < 2 ^ ((f : ℤ) - 150) := by positivity rcases Nat.lt_or_ge (144 - f) 31 with hc | hc · have hse : s = 144 - f := by omega have h6 : (2 : ℝ) ^ s * 2 ^ ((f : ℤ) - 150) = 1 / 64 := by rw [← zpow_natCast, ← zpow_add₀ (by norm_num), hse, Nat.cast_sub (by omega)] norm_num have hid : (M : ℝ) * 2 ^ ((f : ℤ) - 150) - ((kOfG m F).toNat : ℝ) * (1 / 64) = ((M % 2 ^ s : Nat) : ℝ) * 2 ^ ((f : ℤ) - 150) := by rw [hk, hdm, ← h6]; ring rw [hid] refine ⟨gAp_exact fr hr, mul_nonneg (Nat.cast_nonneg _) hp0.le, ?_⟩ rw [← h6] exact mul_lt_mul_of_pos_right (by exact_mod_cast Nat.mod_lt _ (by positivity)) hp0 · have hse : s = 31 := by omega have hk0 : (kOfG m F).toNat = 0 := by rw [hk, hse]; exact Nat.div_eq_of_lt (by omega) have hm0 : M % 2 ^ s = M := Nat.mod_eq_of_lt (by rw [hse]; omega) rw [hk0] rw [hm0] at hr simp only [Nat.cast_zero, zero_mul, sub_zero] refine ⟨gAp_exact fr hr, mul_nonneg (Nat.cast_nonneg _) hp0.le, ?_⟩ have h1 : (M : ℝ) < 2 ^ 24 := by exact_mod_cast hm2 have h2 : (2 : ℝ) ^ ((f : ℤ) - 150) ≤ 2 ^ (-37 : ℤ) := zpow_le_zpow_right₀ (by norm_num) (by omega) calc (M : ℝ) * 2 ^ ((f : ℤ) - 150) ≤ 2 ^ 24 * 2 ^ (-37 : ℤ) := mul_le_mul h1.le h2 hp0.le (by norm_num) _ < 1 / 64 := by norm_num end GSplit section GCore theorem tOfG_def (m F : UInt32) (h : F.toUSize.toNat < D.pw.size) (hk : kOfG m F < 1280) : tOfG m F h hk = expTabG.uget (kOfG m F).toUSize (kidx hk (by decide)) * polyG (rOfG m F h) := by unfold tOfG; rfl theorem exp17 : (1 : ℝ) / 2 ^ 25 ≤ Real.exp (-17) := by rw [Real.exp_neg, one_div, inv_le_inv₀ (by norm_num) (Real.exp_pos _)] have h1 := Real.exp_one_lt_d9 have h2 : Real.exp 17 = Real.exp 1 ^ 17 := by rw [← Real.exp_nat_mul]; norm_num rw [h2] calc Real.exp 1 ^ 17 ≤ 2.7182818286 ^ 17 := pow_le_pow_left₀ (Real.exp_pos 1).le h1.le 17 _ ≤ 2 ^ 25 := by norm_num /-- The core: `t = T[k] · p(r)` approximates `e^(−c)`, `c = m · 2^(F−150)`. -/ theorem tOfG_spec (hok : tabOK = true) (m F : UInt32) (hm2 : m.toNat < 2 ^ 24) (hF1 : 1 ≤ F.toNat) (hF2 : F.toNat ≤ 144) (h : F.toUSize.toNat < D.pw.size) (hk : kOfG m F < 1280) : gAp (tOfG m F h hk) (Real.exp (-((m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150)))) (1 / 2 ^ 44) ∧ ((kOfG m F).toNat < 1088 → |D.R (tOfG m F h hk) - Real.exp (-((m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150)))| ≤ (1 / 2 ^ 36 + 1 / 2 ^ 44) * Real.exp (-((m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150)))) ∧ (kOfG m F).toNat * (1 / 64 : ℝ) ≤ (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) ∧ (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) < ((kOfG m F).toNat + 1) * (1 / 64) := by obtain ⟨hr, r0, r1⟩ := split_spec m F hm2 hF1 hF2 h set C := (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) set kk := (kOfG m F).toNat set ρ := C - kk * (1 / 64) with hρ have r0' : (kk : ℝ) * (1 / 64) ≤ C := by rw [hρ] at r0; linarith have r1' : C < ((kk : ℝ) + 1) * (1 / 64) := by rw [hρ] at r1; linarith have hP := gPoly hr r0 r1.le obtain ⟨hT, hT1, hT2⟩ := tabG_spec hok (k := kOfG m F) (kidx hk (by decide)) set E := Real.exp (-(kk * (1 / 64 : ℝ))) have hE1 : E ≤ 1 := Real.exp_le_one_iff.mpr (by have : (0:ℝ) ≤ kk := Nat.cast_nonneg _; linarith) have hE0 : 0 < E := Real.exp_pos _ have hp1 : Real.exp (-ρ) ≤ 1 := Real.exp_le_one_iff.mpr (by linarith) have hp0 : 0 < Real.exp (-ρ) := Real.exp_pos _ have hp63 : 63 / 64 ≤ Real.exp (-ρ) := by linarith [Real.add_one_le_exp (-ρ)] have hX : E * Real.exp (-ρ) = Real.exp (-C) := by rw [hρ, ← Real.exp_add]; ring_nf have hm : gAp (tOfG m F h hk) (Real.exp (-C)) (1 / 2 ^ 44) := by have := gAp_mul hT hP (M := 1) (N := 1) (by rw [abs_of_pos hE0]; exact hE1) (by rw [abs_of_pos hp0]; exact hp1) (by norm_num) (by norm_num) rw [hX, ← tOfG_def] at this; exact this.mono (by norm_num) refine ⟨hm, fun h1088 => ?_, r0', r1'⟩ -- relative bound have hC17 : C < 17 := by have : (kk : ℝ) + 1 ≤ 1088 := by exact_mod_cast h1088 linarith have hEC : 1 / 2 ^ 25 ≤ Real.exp (-C) := exp17.trans (Real.exp_le_exp.mpr (by linarith)) have hrel := hT2 h1088 set T := expTabG.uget (kOfG m F).toUSize (kidx hk (by decide)) set P := polyG (rOfG m F h) have hPab := abs_le.mp hP.2 have hRP0 : 0 ≤ D.R P := by linarith obtain ⟨-, eR⟩ := D.qCf T P hT.1 hP.1 (hT.bnd (M := 1) (by rw [abs_of_pos hE0]; exact hE1) (by norm_num)) (hP.bnd (M := 1) (by rw [abs_of_pos hp0]; exact hp1) (by norm_num)) have hTP : |D.R T * D.R P - E * Real.exp (-ρ)| ≤ (1 / 2 ^ 36 + 1 / 2 ^ 52) * E * (Real.exp (-ρ) + 1 / 2 ^ 45) + E * (1 / 2 ^ 45) := by have : D.R T * D.R P - E * Real.exp (-ρ) = (D.R T - E) * D.R P + E * (D.R P - Real.exp (-ρ)) := by ring rw [this] refine (abs_add_le _ _).trans (add_le_add ?_ ?_) · rw [abs_mul, abs_of_nonneg hRP0, abs_sub_comm, abs_of_nonneg (by linarith)] exact mul_le_mul hrel (by linarith) hRP0 (by positivity) · rw [abs_mul, abs_of_pos hE0]; exact mul_le_mul_of_nonneg_left hP.2 hE0.le have hEQ : E ≤ (64 / 63) * (E * Real.exp (-ρ)) := by have := mul_le_mul_of_nonneg_left hp63 hE0.le; linarith have hTPa : |D.R T * D.R P| ≤ 2 * Real.exp (-C) := by have := abs_sub_abs_le_abs_sub (D.R T * D.R P) (E * Real.exp (-ρ)) rw [abs_of_pos (mul_pos hE0 hp0)] at this have : (1 / 2 ^ 36 + 1 / 2 ^ 52) * E * (Real.exp (-ρ) + 1 / 2 ^ 45) + E * (1 / 2 ^ 45) ≤ E * Real.exp (-ρ) := by linarith rw [← hX]; linarith have hz := gAz have hc := abs_sub_le (D.R (T * P)) (D.R T * D.R P) (Real.exp (-C)) rw [← hX] at hc hEC hTPa ⊢ have key : (1 / 2 ^ 36 + 1 / 2 ^ 52) * E * (Real.exp (-ρ) + 1 / 2 ^ 45) + E * (1 / 2 ^ 45) + 1 / 2 ^ 53 * (2 * (E * Real.exp (-ρ)) + 1 / 2 ^ 100) ≤ (1 / 2 ^ 36 + 1 / 2 ^ 44) * (E * Real.exp (-ρ)) := by have h100 : (1 : ℝ) / 2 ^ 100 ≤ 1 / 2 ^ 75 * (E * Real.exp (-ρ)) := by have : (1 : ℝ) / 2 ^ 100 = 1 / 2 ^ 75 * (1 / 2 ^ 25) := by norm_num rw [this]; exact mul_le_mul_of_nonneg_left hEC (by norm_num) linarith have e1 : 1 / 2 ^ 53 * (|D.R T * D.R P| + D.A_z) ≤ 1 / 2 ^ 53 * (2 * (E * Real.exp (-ρ)) + 1 / 2 ^ 100) := mul_le_mul_of_nonneg_left (by linarith) (by norm_num) rw [tOfG_def] linarith end GCore section GFin /-- The final check: `q ± e` brackets `V` strictly, so a settled `ziv` is the rounding of `V`. -/ theorem gZiv {q e : Float} {V δ : ℝ} (hq : gAp q V δ) (he : e.isFinite = true) (hqB : |D.R q| ≤ 2 ^ 90) (heB : |D.R e| ≤ 2 ^ 90) (hm : δ + 1 / 2 ^ 53 * (|D.R q| + |D.R e|) + 1 / 2 ^ 150 < D.R e) (hz : D.ziv q e ≠ 0xFFFFFFFF) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt V) : toWord M = D.ziv q e := by have hz0 := gAz have hqA : |D.R q| ≤ D.A_B := hqB.trans (le_trans (by norm_num) gAB) have heA : |D.R e| ≤ D.A_B := heB.trans (le_trans (by norm_num) gAB) obtain ⟨-, e1⟩ := D.qBf q e hq.1 he hqA heA obtain ⟨-, e2⟩ := D.qDf q e hq.1 he hqA heA have hqv := abs_le.mp hq.2 have a1 : |D.R q + D.R e| ≤ |D.R q| + |D.R e| := abs_add_le _ _ have a2 : |D.R q - D.R e| ≤ |D.R q| + |D.R e| := abs_sub _ _ have b1 := abs_le.mp e1 have b2 := abs_le.mp e2 have c0 : 1 / 2 ^ 53 * (|D.R q| + |D.R e| + 1 / 2 ^ 100) ≤ 1 / 2 ^ 53 * (|D.R q| + |D.R e|) + 1 / 2 ^ 150 := by rw [mul_add]; have : (1 : ℝ) / 2 ^ 53 * (1 / 2 ^ 100) ≤ 1 / 2 ^ 150 := by norm_num linarith have c1 : 1 / 2 ^ 53 * (|D.R q + D.R e| + D.A_z) ≤ 1 / 2 ^ 53 * (|D.R q| + |D.R e|) + 1 / 2 ^ 150 := le_trans (mul_le_mul_of_nonneg_left (by linarith) (by norm_num)) c0 have c2 : 1 / 2 ^ 53 * (|D.R q - D.R e| + D.A_z) ≤ 1 / 2 ^ 53 * (|D.R q| + |D.R e|) + 1 / 2 ^ 150 := le_trans (mul_le_mul_of_nonneg_left (by linarith) (by norm_num)) c0 exact D.qDq q e V (by linarith) (by linarith) hz M hf hM /-- Relative approximation. -/ def gApR (x : Float) (X a : ℝ) : Prop := x.isFinite = true ∧ |D.R x - X| ≤ a * X theorem gApR_div {x y : Float} {X Y a b : ℝ} (hx : gApR x X a) (hy : gApR y Y b) (hX : 0 < X) (hY : 0 < Y) (ha : 0 ≤ a) (hb0 : 0 ≤ b) (hb : b ≤ 1 / 2) (hXY : 1 / 2 ^ 30 ≤ X / Y) (hB : X / Y ≤ 2 ^ 80) (hab : a ≤ 1 / 2) : gApR (x / y) (X / Y) ((a + b) / (1 - b) + 1 / 2 ^ 53 * (1 + (a + b) / (1 - b)) + 1 / 2 ^ 120) := by have hz := gAz have hb1 : 0 < 1 - b := by linarith have hRy : (1 - b) * Y ≤ D.R y := by have := abs_le.mp hy.2; rw [sub_mul, one_mul]; linarith have hRy0 : 0 < D.R y := lt_of_lt_of_le (mul_pos hb1 hY) hRy have hRx : |D.R x| ≤ (1 + a) * X := by have := abs_sub_abs_le_abs_sub (D.R x) X; rw [abs_of_pos hX] at this; rw [add_mul, one_mul]; linarith [hx.2] set Q := X / Y have hQ0 : 0 < Q := div_pos hX hY have hd : |D.R x / D.R y - Q| ≤ (a + b) / (1 - b) * Q := by simp only [Q] rw [div_sub_div _ _ hRy0.ne' hY.ne', abs_div, abs_of_pos (mul_pos hRy0 hY)] rw [div_le_iff₀ (mul_pos hRy0 hY)] have hn : |D.R x * Y - D.R y * X| ≤ (a + b) * X * Y := by have : D.R x * Y - D.R y * X = (D.R x - X) * Y + X * (Y - D.R y) := by ring rw [this] refine (abs_add_le _ _).trans ?_ rw [abs_mul, abs_mul, abs_of_pos hY, abs_of_pos hX, abs_sub_comm Y] have p1 := mul_le_mul_of_nonneg_right hx.2 hY.le have p2 := mul_le_mul_of_nonneg_left hy.2 hX.le linarith have : (a + b) * X * Y ≤ (a + b) / (1 - b) * (X / Y) * (D.R y * Y) := by rw [show (a + b) / (1 - b) * (X / Y) * (D.R y * Y) = (a + b) * X * (D.R y / (1 - b)) by field_simp] apply mul_le_mul_of_nonneg_left _ (by positivity) rw [le_div_iff₀ hb1]; linarith linarith have hqa : |D.R x / D.R y| ≤ (1 + (a + b) / (1 - b)) * Q := by have := abs_sub_abs_le_abs_sub (D.R x / D.R y) Q rw [abs_of_pos hQ0] at this; rw [add_mul, one_mul]; linarith have hfac : (a + b) / (1 - b) ≤ 2 := by rw [div_le_iff₀ hb1]; linarith obtain ⟨f, e⟩ := gDiv x y hx.1 hy.1 hRy0.ne' (hqa.trans (by have : (1 + (a + b) / (1 - b)) * Q ≤ 3 * 2 ^ 80 := by have := mul_le_mul_of_nonneg_right hfac hQ0.le rw [add_mul, one_mul]; linarith linarith [gAB, show (3:ℝ) * 2 ^ 80 ≤ 2 ^ 100 by norm_num])) refine ⟨f, ?_⟩ have hc := abs_sub_le (D.R (x / y)) (D.R x / D.R y) Q have : 1 / 2 ^ 53 * (|D.R x / D.R y| + D.A_z) ≤ 1 / 2 ^ 53 * (1 + (a + b) / (1 - b)) * Q + 1 / 2 ^ 120 * Q := by have h1 : D.A_z ≤ 1 / 2 ^ 67 * Q := by calc D.A_z ≤ 1 / 2 ^ 100 := hz _ = 1 / 2 ^ 67 * (1 / 2 ^ 30) * (1 / 2 ^ 3) := by norm_num _ ≤ 1 / 2 ^ 67 * Q * 1 := by gcongr; norm_num _ = _ := by ring have : 1 / 2 ^ 53 * (|D.R x / D.R y| + D.A_z) ≤ 1 / 2 ^ 53 * ((1 + (a + b) / (1 - b)) * Q + 1 / 2 ^ 67 * Q) := mul_le_mul_of_nonneg_left (by linarith) (by norm_num) have e3 : 1 / 2 ^ 53 * ((1 + (a + b) / (1 - b)) * Q + 1 / 2 ^ 67 * Q) = 1 / 2 ^ 53 * (1 + (a + b) / (1 - b)) * Q + 1 / 2 ^ 120 * Q := by ring linarith linarith /-- The decoded input: `x = ±m · 2^(F−150)` for a normal word. -/ theorem decW (w : UInt32) (h1 : 1 ≤ ((w &&& 0x7FFFFFFF) >>> 23).toNat) (h2 : ((w &&& 0x7FFFFFFF) >>> 23).toNat ≤ 254) : expOf w ≠ 255 ∧ 2 ^ 23 ≤ (((w &&& 0x7FFFFFFF) &&& 0x7FFFFF) ||| 0x800000).toNat ∧ (((w &&& 0x7FFFFFFF) &&& 0x7FFFFF) ||| 0x800000).toNat < 2 ^ 24 ∧ D.wv w = (if w < 0x80000000 then (1 : ℝ) else -1) * ((((w &&& 0x7FFFFFFF) &&& 0x7FFFFF) ||| 0x800000).toNat * (2 : ℝ) ^ ((((w &&& 0x7FFFFFFF) >>> 23).toNat : ℤ) - 150)) := by have ha := D.qAq w have hm := D.qHa (w &&& 0x7FFFFFFF) have hF : ((w &&& 0x7FFFFFFF) >>> 23).toNat = w.toNat % 2 ^ 31 / 2 ^ 23 := by rw [UInt32.toNat_shiftRight, Nat.shiftRight_eq_div_pow, ha]; rfl rw [ha] at hm rw [hm] rw [hF] at h1 h2 ⊢ have hw := w.toNat_lt have hg : D.good w = true := by unfold D.good simp only [Bool.or_eq_true, beq_iff_eq, decide_eq_true_eq] right rw [UInt32.le_iff_toNat_le, UInt32.toNat_sub_of_le _ _ (by rw [UInt32.le_iff_toNat_le, ha]; simp; omega), ha] simp; omega have he := D.qAe w hg refine ⟨he, by omega, by omega, ?_⟩ rw [D.qA7 w hg] unfold D.A_mag rw [if_neg (show ¬ (w.toNat % 2 ^ 31 = 0) by omega)] have hs : (w < 0x80000000) ↔ ¬ (2 ^ 31 ≤ w.toNat) := by rw [UInt32.lt_iff_toNat_lt]; simp by_cases hneg : 2 ^ 31 ≤ w.toNat · rw [if_pos hneg, if_neg (hs.not.mpr (not_not.mpr hneg))] · rw [if_neg hneg, if_pos (hs.mpr hneg)] end GFin section GSig theorem gOneR : oneG.isFinite = true ∧ D.R oneG = 1 := by obtain ⟨f, r⟩ := D.qCk 1 (by decide) exact ⟨f, by rw [oneG, r]; simp⟩ theorem gPwA (i : Nat) (h0 : 0 < i) (h1 : i < 256) : gAp (D.pwEntry i) ((2 : ℝ) ^ ((i : ℤ) - 150)) 0 := gAp_exact (gPw i h0 h1).1 (gPw i h0 h1).2 theorem gM34 : (m34G).isFinite = true ∧ D.R m34G = 1 / 2 ^ 34 := by obtain ⟨f, e⟩ := gPw 116 (by norm_num) (by norm_num) exact ⟨f, by rw [m34G, e]; norm_num⟩ theorem gM41 : (m41G).isFinite = true ∧ D.R m41G = 1 / 2 ^ 41 := by obtain ⟨f, e⟩ := gPw 109 (by norm_num) (by norm_num) exact ⟨f, by rw [m41G, e]; norm_num⟩ theorem gM26 : (m26G).isFinite = true ∧ D.R m26G = 1 / 2 ^ 26 := by obtain ⟨f, e⟩ := gPw 124 (by norm_num) (by norm_num) exact ⟨f, by rw [m26G, e]; norm_num⟩ /-- σ(c), c ≥ 0 in the table range. -/ theorem sigPos (hok : tabOK = true) (m F : UInt32) (hm2 : m.toNat < 2 ^ 24) (hF1 : 1 ≤ F.toNat) (hF2 : F.toNat ≤ 144) (h : F.toUSize.toNat < D.pw.size) (hk : kOfG m F < 1280) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt (realSigmoid ((m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150)))) (hz : D.ziv (oneG / (oneG + tOfG m F h hk)) m41G ≠ 0xFFFFFFFF) : toWord M = D.ziv (oneG / (oneG + tOfG m F h hk)) m41G := by obtain ⟨ht, -, -, -⟩ := tOfG_spec hok m F hm2 hF1 hF2 h hk set C := (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) set T := Real.exp (-C) have hC0 : 0 ≤ C := by positivity have hT0 : 0 < T := Real.exp_pos _ have hT1 : T ≤ 1 := Real.exp_le_one_iff.mpr (by linarith) have hd := (gAp_add gOne ht (M := 1) (N := 1) (by norm_num) (by rw [abs_of_pos hT0]; exact hT1) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 43 by norm_num) have hq := (gAp_div gOne hd (M := 1) (m := 1) (by norm_num) (by linarith) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 42 by norm_num) obtain ⟨f41, r41⟩ := gM41 have hqa := hq.absR have hV : |(1 : ℝ) / (1 + T)| ≤ 1 := by rw [abs_of_pos (by positivity), div_le_one (by linarith)]; linarith refine gZiv hq f41 (by linarith) (by rw [r41]; norm_num) ?_ hz hf hM rw [r41, abs_of_pos (show (0:ℝ) < 1 / 2 ^ 41 by norm_num)] have : |D.R (oneG / (oneG + tOfG m F h hk))| ≤ 1 + 1 / 2 ^ 42 := by linarith have : 1 / 2 ^ 53 * (|D.R (oneG / (oneG + tOfG m F h hk))| + 1 / 2 ^ 41) ≤ 1 / 2 ^ 53 * (1 + 1 / 2 ^ 42 + 1 / 2 ^ 41) := by gcongr have : (1 : ℝ) / 2 ^ 42 + 1 / 2 ^ 53 * (1 + 1 / 2 ^ 42 + 1 / 2 ^ 41) + 1 / 2 ^ 150 < 1 / 2 ^ 41 := by norm_num linarith /-- σ(−c) in the table range below 17. -/ theorem sigNeg (hok : tabOK = true) (m F : UInt32) (hm2 : m.toNat < 2 ^ 24) (hF1 : 1 ≤ F.toNat) (hF2 : F.toNat ≤ 144) (h : F.toUSize.toNat < D.pw.size) (hk : kOfG m F < 1280) (h1088 : (kOfG m F).toNat < 1088) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt (realSigmoid (-((m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150))))) (hz : D.ziv (tOfG m F h hk / (oneG + tOfG m F h hk)) (tOfG m F h hk / (oneG + tOfG m F h hk) * m34G) ≠ 0xFFFFFFFF) : toWord M = D.ziv (tOfG m F h hk / (oneG + tOfG m F h hk)) (tOfG m F h hk / (oneG + tOfG m F h hk) * m34G) := by obtain ⟨ht, hrel, -, hCk⟩ := tOfG_spec hok m F hm2 hF1 hF2 h hk have hrel' := hrel h1088 clear hrel obtain ⟨ρ, hρdef⟩ : ∃ ρ : ℝ, ρ = 1 / 2 ^ 36 + 1 / 2 ^ 44 := ⟨_, rfl⟩ rw [← hρdef] at hrel' set C := (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) set T := Real.exp (-C) set t := tOfG m F h hk have hz0 := gAz have hC0 : 0 ≤ C := by positivity have hT0 : 0 < T := Real.exp_pos _ have hT1 : T ≤ 1 := Real.exp_le_one_iff.mpr (by linarith) have hC17 : C < 17 := by have : ((kOfG m F).toNat : ℝ) + 1 ≤ 1088 := by exact_mod_cast h1088 linarith have hT25 : 1 / 2 ^ 25 ≤ T := exp17.trans (Real.exp_le_exp.mpr (by linarith)) have hρ0 : 0 ≤ ρ := by norm_num [hρdef] have hρ1 : ρ ≤ 1 / 2 ^ 35 := by norm_num [hρdef] have hρT : ρ * T ≤ ρ := by have := mul_le_mul_of_nonneg_left hT1 hρ0; linarith have hρT0 : 0 ≤ ρ * T := mul_nonneg hρ0 hT0.le have htR : gApR t T ρ := ⟨ht.1, hrel'⟩ -- the denominator, relative have hRt := abs_le.mp hrel' obtain ⟨fd, ed⟩ := D.qBf oneG t gOneR.1 ht.1 (by rw [gOneR.2]; norm_num; linarith [gAB]) (ht.bnd (M := 1) (by rw [abs_of_pos hT0]; exact hT1) (by norm_num)) rw [gOneR.2] at ed obtain ⟨b, hbdef⟩ : ∃ b : ℝ, b = ρ / 2 + 1 / 2 ^ 51 := ⟨_, rfl⟩ have hdR : gApR (oneG + t) (1 + T) b := by refine ⟨fd, ?_⟩ have h1 : |1 + D.R t| ≤ 2 + ρ := by rw [abs_le]; constructor <;> linarith have h2 := abs_sub_le (D.R (oneG + t)) (1 + D.R t) (1 + T) have h3 : |1 + D.R t - (1 + T)| ≤ ρ * T := by rw [show 1 + D.R t - (1 + T) = D.R t - T by ring]; exact hrel' have h4 : 1 / 2 ^ 53 * (|1 + D.R t| + D.A_z) ≤ 1 / 2 ^ 53 * (2 + ρ + 1 / 2 ^ 100) := mul_le_mul_of_nonneg_left (by linarith) (by norm_num) have h6 : 1 / 2 ^ 53 * (2 + ρ + 1 / 2 ^ 100) ≤ 1 / 2 ^ 51 := by have : 1 / 2 ^ 53 * (2 + 1 / 2 ^ 35 + 1 / 2 ^ 100) ≤ (1:ℝ) / 2 ^ 51 := by norm_num have : 1 / 2 ^ 53 * (2 + ρ + 1 / 2 ^ 100) ≤ 1 / 2 ^ 53 * (2 + 1 / 2 ^ 35 + 1 / 2 ^ 100) := mul_le_mul_of_nonneg_left (by linarith) (by norm_num) linarith have h7 : (0:ℝ) ≤ 1 / 2 ^ 51 * T := by positivity have : b * (1 + T) = ρ / 2 + ρ * T / 2 + 1 / 2 ^ 51 + 1 / 2 ^ 51 * T := by rw [hbdef]; ring linarith have hb0 : 0 ≤ b := by rw [hbdef]; positivity have hb1 : b ≤ 1 / 2 := by rw [hbdef]; linarith have hq := gApR_div htR hdR hT0 (by linarith) hρ0 hb0 hb1 (by rw [le_div_iff₀ (by linarith)]; linarith) (by rw [div_le_iff₀ (by linarith)]; linarith) (by linarith) obtain ⟨r, hrdef⟩ : ∃ r : ℝ, r = (ρ + b) / (1 - b) + 1 / 2 ^ 53 * (1 + (ρ + b) / (1 - b)) + 1 / 2 ^ 120 := ⟨_, rfl⟩ rw [← hrdef] at hq have hr : r ≤ (4 / 5) / 2 ^ 35 := by rw [hrdef, hbdef, hρdef]; norm_num have hV : realSigmoid (-C) = T / (1 + T) := FastAct.realSigmoid_neg_eq C rw [hV] at hM set V := T / (1 + T) have hV0 : 0 < V := by positivity have hV1 : V ≤ 1 := by rw [div_le_one (by linarith)]; linarith have hV26 : 1 / 2 ^ 26 ≤ V := by rw [le_div_iff₀ (by linarith)]; linarith set q := t / (oneG + t) have hqA : gAp q V (r * V) := hq have hqv := abs_le.mp hq.2 have k7 : r * V ≤ (4 / 5) / 2 ^ 35 * V := mul_le_mul_of_nonneg_right hr hV0.le have hr0 : 0 ≤ r * V := (abs_nonneg _).trans hq.2 have hRq0 : 0 < D.R q := by linarith obtain ⟨f34, r34⟩ := gM34 obtain ⟨fe, ee⟩ := D.qCf q m34G hq.1 f34 (hqA.bnd (M := 1) (by rw [abs_of_pos hV0]; exact hV1) (by linarith)) (by rw [r34]; norm_num; linarith [gAB]) rw [r34] at ee have he := abs_le.mp ee rw [abs_of_pos (mul_pos hRq0 (by norm_num) : 0 < D.R q * (1 / 2 ^ 34))] at he have hRe0 : 0 < D.R (q * m34G) := by linarith refine gZiv hqA fe (by rw [abs_of_pos hRq0]; linarith) (by rw [abs_of_pos hRe0]; linarith) ?_ hz hf hM rw [abs_of_pos hRq0, abs_of_pos hRe0] have k5 : (1:ℝ) / 2 ^ 150 ≤ 1 / 2 ^ 124 * V := by have : (1:ℝ) / 2 ^ 150 = 1 / 2 ^ 124 * (1 / 2 ^ 26) := by norm_num rw [this]; exact mul_le_mul_of_nonneg_left hV26 (by norm_num) have k6 : (1:ℝ) / 2 ^ 153 ≤ 1 / 2 ^ 127 * V := by have : (1:ℝ) / 2 ^ 153 = 1 / 2 ^ 127 * (1 / 2 ^ 26) := by norm_num rw [this]; exact mul_le_mul_of_nonneg_left hV26 (by norm_num) linarith /-- Saturation: σ(c) for c ≥ 19 rounds to 1. -/ theorem sigSat {C : ℝ} (hC : 19 ≤ C) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt (realSigmoid C)) (hz : D.ziv oneG m26G ≠ 0xFFFFFFFF) : toWord M = D.ziv oneG m26G := by have hT0 := Real.exp_pos (-C) have hT : Real.exp (-C) ≤ 1 / 2 ^ 27 := exp_neg_le_inv_two_pow 27 (by norm_num; linarith) have hq : gAp oneG (realSigmoid C) (1 / 2 ^ 27) := by refine ⟨gOneR.1, ?_⟩ rw [gOneR.2]; unfold realSigmoid rw [abs_of_nonneg (by rw [sub_nonneg, div_le_one (by linarith)]; linarith)] rw [show (1:ℝ) - 1 / (1 + Real.exp (-C)) = Real.exp (-C) / (1 + Real.exp (-C)) by field_simp; ring] rw [div_le_iff₀ (by linarith)]; linarith obtain ⟨f26, r26⟩ := gM26 refine gZiv hq f26 (by rw [gOneR.2]; norm_num) (by rw [r26]; norm_num) ?_ hz hf hM rw [r26, gOneR.2]; norm_num end GSig section GTanh theorem tanhPos (hok : tabOK = true) (m F : UInt32) (hm2 : m.toNat < 2 ^ 24) (hF1 : 1 ≤ F.toNat) (hF2 : F.toNat ≤ 144) (h : F.toUSize.toNat < D.pw.size) (hk : kOfG m F < 1280) {C : ℝ} (hC : (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) = 2 * C) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt (Real.tanh C)) (hz : D.ziv ((oneG - tOfG m F h hk) / (oneG + tOfG m F h hk)) m41G ≠ 0xFFFFFFFF) : toWord M = D.ziv ((oneG - tOfG m F h hk) / (oneG + tOfG m F h hk)) m41G := by obtain ⟨ht, -, -, -⟩ := tOfG_spec hok m F hm2 hF1 hF2 h hk rw [hC] at ht have hC0 : 0 ≤ 2 * C := by rw [← hC]; positivity have hT0 := Real.exp_pos (-(2 * C)) have hT1 : Real.exp (-(2 * C)) ≤ 1 := Real.exp_le_one_iff.mpr (by linarith) have hn := (gAp_sub gOne ht (M := 1) (N := 1) (by norm_num) (by rw [abs_of_pos hT0]; exact hT1) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 44 + 1 / 2 ^ 51 by norm_num) have hd := (gAp_add gOne ht (M := 1) (N := 1) (by norm_num) (by rw [abs_of_pos hT0]; exact hT1) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 44 + 1 / 2 ^ 51 by norm_num) have hq := (gAp_div hn hd (M := 1) (m := 1) (by rw [abs_le]; constructor <;> linarith) (by linarith) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 42 by norm_num) rw [show -(2 * C) = -2 * C by ring, ← tanh_eq_exp_neg_two] at hq obtain ⟨f41, r41⟩ := gM41 have hqa := hq.absR have hV : |Real.tanh C| ≤ 1 := abs_le.mpr ⟨(Real.neg_one_lt_tanh C).le, (Real.tanh_lt_one C).le⟩ refine gZiv hq f41 (by linarith) (by rw [r41]; norm_num) ?_ hz hf hM rw [r41, abs_of_pos (show (0:ℝ) < 1 / 2 ^ 41 by norm_num)] have : 1 / 2 ^ 53 * (|D.R ((oneG - tOfG m F h hk) / (oneG + tOfG m F h hk))| + 1 / 2 ^ 41) ≤ 1 / 2 ^ 53 * (1 + 1 / 2 ^ 42 + 1 / 2 ^ 41) := by gcongr; linarith have : (1 : ℝ) / 2 ^ 42 + 1 / 2 ^ 53 * (1 + 1 / 2 ^ 42 + 1 / 2 ^ 41) + 1 / 2 ^ 150 < 1 / 2 ^ 41 := by norm_num linarith theorem tanhNeg (hok : tabOK = true) (m F : UInt32) (hm2 : m.toNat < 2 ^ 24) (hF1 : 1 ≤ F.toNat) (hF2 : F.toNat ≤ 144) (h : F.toUSize.toNat < D.pw.size) (hk : kOfG m F < 1280) {C : ℝ} (hC : (m.toNat : ℝ) * 2 ^ ((F.toNat : ℤ) - 150) = 2 * C) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt (Real.tanh (-C))) (hz : D.ziv ((tOfG m F h hk - oneG) / (oneG + tOfG m F h hk)) m41G ≠ 0xFFFFFFFF) : toWord M = D.ziv ((tOfG m F h hk - oneG) / (oneG + tOfG m F h hk)) m41G := by obtain ⟨ht, -, -, -⟩ := tOfG_spec hok m F hm2 hF1 hF2 h hk rw [hC] at ht have hC0 : 0 ≤ 2 * C := by rw [← hC]; positivity have hT0 := Real.exp_pos (-(2 * C)) have hT1 : Real.exp (-(2 * C)) ≤ 1 := Real.exp_le_one_iff.mpr (by linarith) have hn := (gAp_sub ht gOne (M := 1) (N := 1) (by rw [abs_of_pos hT0]; exact hT1) (by norm_num) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 44 + 1 / 2 ^ 51 by norm_num) have hd := (gAp_add gOne ht (M := 1) (N := 1) (by norm_num) (by rw [abs_of_pos hT0]; exact hT1) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 44 + 1 / 2 ^ 51 by norm_num) have hq := (gAp_div hn hd (M := 1) (m := 1) (by rw [abs_le]; constructor <;> linarith) (by linarith) (by norm_num) (by norm_num)).mono (show _ ≤ (1 : ℝ) / 2 ^ 42 by norm_num) have hV : (Real.exp (-(2 * C)) - 1) / (1 + Real.exp (-(2 * C))) = Real.tanh (-C) := by rw [Real.tanh_neg, tanh_eq_exp_neg_two, show -2 * C = -(2 * C) by ring, ← neg_div]; ring_nf rw [hV] at hq obtain ⟨f41, r41⟩ := gM41 have hqa := hq.absR have hV1 : |Real.tanh (-C)| ≤ 1 := abs_le.mpr ⟨(Real.neg_one_lt_tanh _).le, (Real.tanh_lt_one _).le⟩ refine gZiv hq f41 (by linarith) (by rw [r41]; norm_num) ?_ hz hf hM rw [r41, abs_of_pos (show (0:ℝ) < 1 / 2 ^ 41 by norm_num)] have : 1 / 2 ^ 53 * (|D.R ((tOfG m F h hk - oneG) / (oneG + tOfG m F h hk))| + 1 / 2 ^ 41) ≤ 1 / 2 ^ 53 * (1 + 1 / 2 ^ 42 + 1 / 2 ^ 41) := by gcongr; linarith have : (1 : ℝ) / 2 ^ 42 + 1 / 2 ^ 53 * (1 + 1 / 2 ^ 42 + 1 / 2 ^ 41) + 1 / 2 ^ 150 < 1 / 2 ^ 41 := by norm_num linarith theorem tanh_sat {C : ℝ} (hC : 10 ≤ C) : 1 - 1 / 2 ^ 27 ≤ Real.tanh C ∧ Real.tanh C < 1 := by refine ⟨?_, Real.tanh_lt_one C⟩ have hT0 := Real.exp_pos (-(2 * C)) have hT : Real.exp (-(2 * C)) ≤ 1 / 2 ^ 28 := exp_neg_le_inv_two_pow 28 (by norm_num; linarith) rw [tanh_eq_exp_neg_two, show -2 * C = -(2 * C) by ring, le_div_iff₀ (by linarith)] linarith theorem gNegOne : gAp negOneG (-1) (1 / 2 ^ 52) := by have h0 : gAp (0 : Float) 0 0 := gAp_exact D.qHg.1 D.qHg.2 have := gAp_sub h0 gOne (M := 0) (N := 1) (by norm_num) (by norm_num) (by norm_num) (by norm_num) exact (by simpa using this.mono (show _ ≤ (1 : ℝ) / 2 ^ 52 by norm_num) : gAp (0 - oneG) (-1) (1 / 2 ^ 52)) theorem tanhSatPos {C : ℝ} (hC : 10 ≤ C) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt (Real.tanh C)) (hz : D.ziv oneG m26G ≠ 0xFFFFFFFF) : toWord M = D.ziv oneG m26G := by obtain ⟨t1, t2⟩ := tanh_sat hC have hq : gAp oneG (Real.tanh C) (1 / 2 ^ 27) := ⟨gOneR.1, by rw [gOneR.2, abs_le]; constructor <;> linarith⟩ obtain ⟨f26, r26⟩ := gM26 refine gZiv hq f26 (by rw [gOneR.2]; norm_num) (by rw [r26]; norm_num) ?_ hz hf hM rw [r26, gOneR.2]; norm_num theorem tanhSatNeg {C : ℝ} (hC : 10 ≤ C) {M : Model Fmt} (hf : M.isFinite = true) (hM : M.toReal = Model.roundAt Fmt (Real.tanh (-C))) (hz : D.ziv negOneG m26G ≠ 0xFFFFFFFF) : toWord M = D.ziv negOneG m26G := by obtain ⟨t1, t2⟩ := tanh_sat hC have hn := gNegOne have hq : gAp negOneG (Real.tanh (-C)) (1 / 2 ^ 27 + 1 / 2 ^ 52) := by refine ⟨hn.1, ?_⟩ rw [Real.tanh_neg] have := abs_le.mp hn.2 rw [abs_le]; constructor <;> linarith have hqa := hq.absR have hV1 : |Real.tanh (-C)| ≤ 1 := abs_le.mpr ⟨(Real.neg_one_lt_tanh _).le, (Real.tanh_lt_one _).le⟩ obtain ⟨f26, r26⟩ := gM26 refine gZiv hq f26 (by linarith) (by rw [r26]; norm_num) ?_ hz hf hM rw [r26, abs_of_pos (show (0:ℝ) < 1 / 2 ^ 26 by norm_num)] have : 1 / 2 ^ 53 * (|D.R negOneG| + 1 / 2 ^ 26) ≤ 1 / 2 ^ 53 * (2 + 1 / 2 ^ 26) := by gcongr; linarith have : (1 : ℝ) / 2 ^ 27 + 1 / 2 ^ 52 + 1 / 2 ^ 53 * (2 + 1 / 2 ^ 26) + 1 / 2 ^ 150 < 1 / 2 ^ 26 := by norm_num linarith end GTanh section GMain theorem sigModel (w : UInt32) (hfin : expOf w ≠ 255) : (sigmoidModel (ofW w)).isFinite = true ∧ (sigmoidModel (ofW w)).toReal = Model.roundAt Fmt (realSigmoid (D.wv w)) := toReal_sigmoidModel (fmt := Fmt) (by decide) (input := Model.ofUInt32 w) (by simp [isFinite_ofUInt32, hfin]) theorem tanhModel' (w : UInt32) (hfin : expOf w ≠ 255) : (tanhModel (ofW w)).isFinite = true ∧ (tanhModel (ofW w)).toReal = Model.roundAt Fmt (Real.tanh (D.wv w)) := toReal_tanhModel (fmt := Fmt) (by decide) (input := Model.ofUInt32 w) (by simp [isFinite_ofUInt32, hfin]) theorem sigCR_eq (w : UInt32) : sigmoidCR w = toWord (sigmoidModel (ofW w)) := rfl theorem tanhCR_eq (w : UInt32) : tanhCR w = toWord (tanhModel (ofW w)) := rfl theorem fRange {F : UInt32} (h : F - 1 < 131) : 1 ≤ F.toNat ∧ F.toNat ≤ 131 := by rw [UInt32.lt_iff_toNat_lt, UInt32.toNat_sub] at h have := F.toNat_lt; simp at h; omega theorem fRange2 {F : UInt32} (h : F - 2 < 131) : 2 ≤ F.toNat ∧ F.toNat ≤ 132 := by rw [UInt32.lt_iff_toNat_lt, UInt32.toNat_sub] at h have := F.toNat_lt; simp at h; omega theorem sigG_spec (hok : tabOK = true) (w : UInt32) : sigG w ≠ 0xFFFFFFFF → sigG w = sigmoidCR w := by unfold sigG dsimp only rw [sigCR_eq] split · rename_i hE obtain ⟨hF1, hF2⟩ := fRange hE obtain ⟨he, hm1, hm2, hx⟩ := decW w hF1 (by omega) obtain ⟨hf, hM⟩ := sigModel w he rw [hx] at hM split · rename_i hs rw [if_pos hs, one_mul] at hM split · rename_i hk intro hz exact (sigPos hok _ _ hm2 hF1 (by omega) _ _ hf hM hz).symm · rename_i hk intro hz refine (sigSat ?_ hf hM hz).symm obtain ⟨-, hlo, -⟩ := split_spec _ _ hm2 hF1 (by omega) (eidx _) rw [UInt32.lt_iff_toNat_lt] at hk; simp only [UInt32.reduceToNat, not_lt] at hk have : (1216 : ℝ) ≤ ((kOfG ((w &&& 2147483647) &&& 8388607 ||| 8388608) ((w &&& 2147483647) >>> 23)).toNat : ℝ) := by exact_mod_cast hk linarith · rename_i hs rw [if_neg hs, neg_one_mul] at hM split · rename_i hk intro hz exact (sigNeg hok _ _ hm2 hF1 (by omega) _ _ (by rw [UInt32.lt_iff_toNat_lt] at hk; simpa using hk) hf hM hz).symm · intro hz; exact absurd rfl hz · rename_i hE split · rename_i hc simp only [Bool.and_eq_true, decide_eq_true_eq] at hc obtain ⟨⟨h1, h2⟩, hs⟩ := hc rw [UInt32.lt_iff_toNat_lt] at h1 h2 simp only [UInt32.reduceToNat] at h1 h2 obtain ⟨he, hm1, hm2, hx⟩ := decW w (by omega) (by omega) obtain ⟨hf, hM⟩ := sigModel w he rw [hx, if_pos hs, one_mul] at hM intro hz refine (sigSat ?_ hf hM hz).symm have hp : (2 : ℝ) ^ (5 : ℤ) ≤ 2 ^ ((((w &&& 2147483647) >>> 23).toNat : ℤ) - 150 + 23) := zpow_le_zpow_right₀ (by norm_num) (by omega) have hm : (2 : ℝ) ^ 23 ≤ (((w &&& 2147483647) &&& 8388607 ||| 8388608).toNat : ℝ) := by exact_mod_cast hm1 rw [zpow_add₀ (by norm_num)] at hp have : (2 : ℝ) ^ ((((w &&& 2147483647) >>> 23).toNat : ℤ) - 150) * 2 ^ 23 ≤ (((w &&& 2147483647) &&& 8388607 ||| 8388608).toNat : ℝ) * 2 ^ ((((w &&& 2147483647) >>> 23).toNat : ℤ) - 150) := by rw [mul_comm]; exact mul_le_mul_of_nonneg_right hm (by positivity) norm_num at hp this ⊢ linarith · intro hz; exact absurd rfl hz end GMain section GMain2 theorem fPlus (w : UInt32) : (((w &&& 0x7FFFFFFF) + 0x800000) >>> 23).toNat = ((w &&& 0x7FFFFFFF) >>> 23).toNat + 1 := by have ha := D.qAq w have hw := w.toNat_lt rw [UInt32.toNat_shiftRight, UInt32.toNat_shiftRight, Nat.shiftRight_eq_div_pow, Nat.shiftRight_eq_div_pow, UInt32.toNat_add, ha] simp only [UInt32.reduceToNat, Nat.reduceMod, Nat.reducePow] have : w.toNat % 2 ^ 31 < 2 ^ 31 := Nat.mod_lt _ (by norm_num) rw [Nat.mod_eq_of_lt (by omega)] omega theorem twoC (mm : ℝ) (E F : Nat) (h : F = E + 1) : mm * (2 : ℝ) ^ ((F : ℤ) - 150) = 2 * (mm * 2 ^ ((E : ℤ) - 150)) := by subst h rw [show ((E + 1 : Nat) : ℤ) - 150 = ((E : ℤ) - 150) + 1 by push_cast; ring, zpow_add_one₀ (by norm_num)] ring theorem bigC (mm E : Nat) (hm : 2 ^ 23 ≤ mm) (hE : 132 ≤ E) : (10 : ℝ) ≤ (mm : ℝ) * 2 ^ ((E : ℤ) - 150) := by have h1 : (2 : ℝ) ^ 23 ≤ (mm : ℝ) := by exact_mod_cast hm have h2 : (2 : ℝ) ^ (-18 : ℤ) ≤ 2 ^ ((E : ℤ) - 150) := zpow_le_zpow_right₀ (by norm_num) (by omega) have h3 : (2 : ℝ) ^ 23 * 2 ^ (-18 : ℤ) ≤ (mm : ℝ) * 2 ^ ((E : ℤ) - 150) := mul_le_mul h1 h2 (by positivity) (by positivity) have h4 : (2 : ℝ) ^ 23 * 2 ^ (-18 : ℤ) = 32 := by norm_num linarith theorem tanhG_spec (hok : tabOK = true) (w : UInt32) : tanhG w ≠ 0xFFFFFFFF → tanhG w = tanhCR w := by unfold tanhG dsimp only rw [tanhCR_eq] have hFE := fPlus w split · rename_i hE obtain ⟨hF1, hF2⟩ := fRange2 hE obtain ⟨he, hm1, hm2, hx⟩ := decW w (by omega) (by omega) obtain ⟨hf, hM⟩ := tanhModel' w he rw [hx] at hM have hC := twoC ((((w &&& 2147483647) &&& 8388607 ||| 8388608).toNat : ℝ)) _ _ hFE split · rename_i hk split · rename_i hs rw [if_pos hs, one_mul] at hM intro hz refine (tanhPos hok _ _ hm2 ?_ ?_ _ _ hC hf hM hz).symm <;> omega · rename_i hs rw [if_neg hs, neg_one_mul] at hM intro hz refine (tanhNeg hok _ _ hm2 ?_ ?_ _ _ hC hf hM hz).symm <;> omega · rename_i hk obtain ⟨-, hlo, -⟩ := split_spec ((w &&& 2147483647) &&& 8388607 ||| 8388608) (((w &&& 2147483647) + 8388608) >>> 23) hm2 (by omega) (by omega) (eidx _) rw [UInt32.lt_iff_toNat_lt] at hk; simp only [UInt32.reduceToNat, not_lt] at hk have h1280 : (1280 : ℝ) ≤ ((kOfG ((w &&& 2147483647) &&& 8388607 ||| 8388608) (((w &&& 2147483647) + 8388608) >>> 23)).toNat : ℝ) := by exact_mod_cast hk rw [hC] at hlo have hC10 : (10 : ℝ) ≤ (((w &&& 2147483647) &&& 8388607 ||| 8388608).toNat : ℝ) * (2 : ℝ) ^ ((((w &&& 2147483647) >>> 23).toNat : ℤ) - 150) := by linarith split · rename_i hs rw [if_pos hs, one_mul] at hM intro hz exact (tanhSatPos hC10 hf hM hz).symm · rename_i hs rw [if_neg hs, neg_one_mul] at hM intro hz exact (tanhSatNeg hC10 hf hM hz).symm · rename_i hE split · rename_i hc simp only [Bool.and_eq_true, decide_eq_true_eq] at hc obtain ⟨h1, h2⟩ := hc rw [UInt32.lt_iff_toNat_lt] at h1 h2 simp only [UInt32.reduceToNat] at h1 h2 obtain ⟨he, hm1, hm2, hx⟩ := decW w (by omega) (by omega) obtain ⟨hf, hM⟩ := tanhModel' w he rw [hx] at hM have hC10 := bigC _ _ hm1 (show 132 ≤ ((w &&& 2147483647) >>> 23).toNat by omega) split · rename_i hs rw [if_pos hs, one_mul] at hM intro hz exact (tanhSatPos hC10 hf hM hz).symm · rename_i hs rw [if_neg hs, neg_one_mul] at hM intro hz exact (tanhSatNeg hC10 hf hM hz).symm · intro hz; exact absurd rfl hz theorem sigmoidF2_eq' (w : UInt32) : sigmoidF2 w = sigmoidCR w := by unfold sigmoidF2 dsimp only split · rename_i hok split · rw [sigmoidF9_eq] · rename_i hne exact sigG_spec hok w (by simpa using hne) · simp only [beq_self_eq_true, ite_true]; exact sigmoidF9_eq w theorem tanhF2_eq' (w : UInt32) : tanhF2 w = tanhCR w := by unfold tanhF2 dsimp only split · rename_i hok split · rw [tanhF9_eq] · rename_i hne exact tanhG_spec hok w (by simpa using hne) · simp only [beq_self_eq_true, ite_true]; exact tanhF9_eq w theorem sigmoidF2_eq : sigmoidF2 = FastAct.sigmoidF := by rw [FastAct.sigmoidF_eq]; funext w; exact sigmoidF2_eq' w theorem tanhF2_eq : tanhF2 = FastAct.tanhF := by rw [FastAct.tanhF_eq]; funext w; exact tanhF2_eq' w end GMain2 end RnnFast def kernels:Kernels where core:=specCore dense:=⟨C.linG,C.gemmC⟩ conv:=⟨ConvFast.conv2dF,ConvFast.depthwiseF,Pinned.kernels.conv.convTranspose⟩ elem:=⟨ConvFast.avgpoolF,ConvFast.maxpoolF,C.addF,C.scaleF⟩ norm:=⟨D.rmsF,D.lnF⟩ attn:=specAttn rnn:=⟨RnnFast.lstmF RnnFast.sigmoidF2 RnnFast.tanhF2,RnnFast.gruF RnnFast.sigmoidF2 RnnFast.tanhF2⟩ theorem correct:Obligation kernels:=by have hP:=Pinned.correct have hc:Pinned.kernels.conv=specConv:=congrArg Kernels.conv hP refine obligation_of_families kernels rfl ?_ ?_ ?_ ?_ ?_ ?_ · show (⟨C.linG,C.gemmC⟩:DenseKernels)=specDense rw[C.qHb,C.qFq];rfl · show (⟨ConvFast.conv2dF,ConvFast.depthwiseF,Pinned.kernels.conv.convTranspose⟩:ConvKernels)=specConv rw[ConvFast.conv2dF_eq,ConvFast.depthwiseF_eq, show Pinned.kernels.conv.convTranspose=convTransposeSpec from congrArg ConvKernels.convTranspose hc];rfl · show (⟨ConvFast.avgpoolF,ConvFast.maxpoolF,C.addF,C.scaleF⟩:ElementKernels)=specElem rw[ConvFast.avgpoolF_eq,ConvFast.maxpoolF_eq,C.qFu,C.qFf];rfl · show (⟨D.rmsF,D.lnF⟩:NormKernels)=specNorm rw[D.qFf,D.qGc];rfl · exact rfl · show (⟨RnnFast.lstmF RnnFast.sigmoidF2 RnnFast.tanhF2,RnnFast.gruF RnnFast.sigmoidF2 RnnFast.tanhF2⟩:RecurrentKernels)=specRnn rw[RnnFast.lstmF_eq,RnnFast.gruF_eq,RnnFast.sigmoidF2_eq,RnnFast.tanhF2_eq,FastAct.sigmoidF_eq,FastAct.tanhF_eq,Pinned.dotFn_eq_dotOf];rfl end Submission