import ContractExact namespace FastAct @[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)) @[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)) @[inline] def mulLoW (a b:UInt64):UInt64 := (midW a b <<< (32:UInt64))+((a &&& (0xffffffff:UInt64))*(b &&& (0xffffffff:UInt64)) &&& (0xffffffff:UInt64)) def mul128 (a b:UInt64):UInt64 × UInt64:=(mulHiW a b,mulLoW a b) mutual 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] end 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 def one:Nat:=2 ^ 62 noncomputable def V (a:Nat):ℝ:=(a:ℝ) / 2 ^ 62 mutual 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 exact sub_nonpos.mpr this) (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 end @[inline] def mulDnW (a b:UInt64):UInt64:=(mulHiW a b <<< 2)+(mulLoW a b >>> 62) @[inline] def mulUpW (a b:UInt64):UInt64 := if mulLoW a b &&& 0x3fffffffffffffff=0 then mulDnW a b else mulDnW a b+1 @[inline] def mulDn (a b:Nat):Nat:=(mulDnW a.toUInt64 b.toUInt64).toNat @[inline] def mulUp (a b:Nat):Nat:=(mulUpW a.toUInt64 b.toUInt64).toNat mutual 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 end mutual 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 end 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; exact Nat.lt_of_le_of_lt ha (by decide)) (by unfold one at hb; exact Nat.lt_of_le_of_lt hb (by decide)) 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 mutual 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 only [this,this] end mutual 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 only [this,this] 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)) end mutual 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 only [hc,this] 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 only [hc,this] end 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 def remF:Nat:=(one+35280-1) / 35280*8 @[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) mutual 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 end 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 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 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 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 only [h] 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 exact neg_nonpos.mpr h0) 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 only [hh,c2,c4,c6,d3,d5,d7,hab] · 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 only [hl,c3,c5,d2,d4,d6,d7,hab,hab.2] def Encl (iv:Nat × Nat) (b:ℝ):Prop := V iv.1≤ Real.exp (-b)∧Real.exp (-b)≤ V iv.2∧iv.2≤ one 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)) mutual 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 end def sixtyFourth:Nat:=2 ^ 56 theorem V_sixtyFourth:V sixtyFourth=1 / 64:=by norm_num [V,sixtyFourth] 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]) def fracTab:Array (Nat × Nat):=Array.ofFn (n:=64) fun j=>powOf base64 j.val def baseOne:Nat × Nat:=powOf base64 64 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 mutual 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 end @[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 only [this] 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 @[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 only [hlo,hqr,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 only [hhi,hqr,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 def two62f:Float:=4611686018427387904.0 @[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) @[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 exact Nat.lt_of_lt_of_le h4 (by decide))] have:(62:UInt64).toNat % 64=62:=by decide rw [this,Nat.shiftLeft_eq,Nat.mod_eq_of_lt (by omega)] mutual 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 end @[inline] def guess (num den:Nat):Nat := ((num.toUInt64.toFloat*two62f) / den.toUInt64.toFloat).toUInt64.toNat def lim64:Nat:=2 ^ 64 @[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 @[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 only [h] 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 only [this] mutual 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 only [this] · simp at h end open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Numerics open ExactRuntime.FastRound 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 mutual 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'] 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 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 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 end 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 match divLo t.1 (one+t.1),divHi t.2 (one+t.2) with | some ql,some qh=>settle false ql qh | _,_=>none else 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 exact hT.trans (by norm_num))] nlinarith only [hT,h1,v1,bl] · rw [int_scale] have:realSigmoid (-C)=T / (1+T):=realSigmoid_neg_eq C rw [this,div_le_iff₀ (by exact hT.trans (by norm_num))] nlinarith only [hT,h2,bh] · 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 exact hT.trans (by norm_num))] nlinarith only [hT,h2,bl] · rw [int_scale,hs,div_le_iff₀ (by exact hT.trans (by norm_num))] nlinarith only [hT,h1,v1,bh] · simp at h 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 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 exact hT.trans (by norm_num))]; nlinarith only [hT,h2,bl] have hi:Real.tanh C≤ V qh:=by rw [htanh,div_le_iff₀ (by exact hT.trans (by norm_num))]; nlinarith only [hT,h1,v1,bh] 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]; exact neg_le_neg hi · rw [neg_int_scale,Real.tanh_neg]; exact neg_le_neg lo · simp at h 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 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 mutual theorem omS3 {x0 x1:ℕ} (h0:x0 / 32+1< 18) (h1:x1=18):x0 / 32+1< x1:=by subst_vars; assumption 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 simp only [Nat.add_comm,Nat.add_left_comm] 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 simp only [Nat.add_comm,Nat.add_left_comm] at *; assumption theorem omS8 {x0 x1:ℕ} (h0:x0< x1+1) (h1:x0 ≥ x1):x0=x1:=by omega theorem omS9 {x0:ℕ}:0< x0+1:=by simp theorem omS10 {x0:ℕ}:0+x0≤ x0:=by simp end mutual 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_comm,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 end mutual 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 end mutual 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 end mutual 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 exact Nat.le_add_right _ _ theorem omS47 {x0:ℕ}:2 ^ 23+x0 % 2 ^ 23≤ 2 ^ 23*2:=by omega end mutual 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 end mutual 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 exact Nat.le_of_lt (Nat.lt_of_le_of_lt h1 h0) 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 end mutual 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 simp at *; omega theorem omS70 {x0:ℤ} (h0:x0+(150:ℤ)≤ (254:ℤ)):(x0+(150:ℤ)).toNat< (2:ℕ) ^ (8:ℕ):=by simp at *; omega theorem omS71 {x0:ℕ} (h0:2 ^ 23≤ x0):0< x0:=by exact Nat.lt_of_lt_of_le (by decide) h0 theorem omS72 {x0:ℤ} {x1:ℤ}:x0-x1+(2:ℤ) ≤ ↑(x0-x1+(2:ℤ)).toNat:=by simp theorem omS73 {x0:ℤ} {x1:ℕ} {x2:ℤ} (h0:x0-x2+(2:ℤ) ≤ ↑x1):x0 - ↑x1 + ↑((x2-(x0 - ↑x1)-(2:ℤ)).toNat+(2:ℕ))=x2:=by omega end mutual theorem omS74 {x0:ℤ} {x1:ℕ}:x0 = ↑x1+(x0 - ↑x1):=by 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 end mutual 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 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 end mutual 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 assumption theorem omS94 {x0:ℕ} (h0:x0< 2047) : ¬x0=2047:=by exact Nat.ne_of_lt h0 theorem omS95 {x0:ℕ} (h0:1≤ x0) : ¬x0=0:=by exact Nat.ne_of_gt h0 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 end mutual 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 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 end mutual 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 end mutual 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 end mutual theorem omS125 {x0:ℕ}:2 ^ 23≤ 2 ^ 23+x0:=by exact Nat.le_add_right _ _ 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; decide 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 end mutual 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 simp at *; omega theorem omS139 {x0:ℕ}:0+x0=x0:=by simp theorem omS140 {x0 x1 x2:ℕ} (h0:x1=x2) (h1:x0< x2):x0< x1:=by subst_vars; assumption end mutual 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 end mutual theorem omS149 {x0 x1 x2:ℕ} (h0:x0=x2) (h1:x2+x1< 2 ^ 32):x0+x1< 2 ^ 32:=by subst_vars; assumption 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 exact Nat.lt_trans h1 h0 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 assumption 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 end mutual 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 exact Nat.ne_of_lt h0 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 simp +arith at * ; omega theorem omS162 {x0 x1:ℕ} (h0:x0< x1):x0≠ x1+1+1+1+1:=by simp +arith at * ; omega theorem omS163 {x0 x1:ℕ} (h0:x0< x1):x0≠ x1+1+1+1+1+1:=by simp +arith at * ; omega theorem omS164 {x0 x1:ℕ} (h0:x0< x1):x0≠ x1+1+1+1+1+1+1:=by simp +arith at * ; omega end mutual theorem omS165 {x0 x1:ℕ} (h0:x0< x1):x0≠ x1+1+1+1+1+1+1+1:=by simp +arith at * ; omega theorem omS166 {x0 x1:ℕ} (h0:x0< x1):x0< x1+1+1+1+1+1+1+1+1:=by 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 exact Nat.lt_of_lt_of_le h0 (Nat.le_add_right _ _) 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 end mutual theorem omS173 {x0 x1 x2 x3:ℕ} (h0:x0=x1+0+8*x2+x3):x0=x1+8*(x2-0)+x3:=by assumption 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 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 end mutual 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 exact Nat.le_of_lt_succ h0 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 simp at *; omega theorem omS188 {x0 x1:ℕ} (h0:x0+4≤ x1):x0+1+1≤ x1:=by simp at *; omega end mutual theorem omS189 {x0 x1:ℕ} (h0:x0+4≤ x1):x0+2+1≤ x1:=by exact le_of_lt ‹_› theorem omS190 {x0 x1:ℕ} (h0:x0+4≤ x1):x0+3+1≤ x1:=by assumption 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 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 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 end mutual theorem omS197 {x0 x1:ℕ} (h0:x1≤ x0):x0+3=x1+(x0+3-x1):=by 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 exact Nat.le_trans h0 (Nat.le_add_right _ _) theorem omS201 {x0 x1:ℕ} (h0:x1< 2 ^ 32) (h1:x0< x1):x0< 2 ^ 32:=by exact Nat.lt_trans h1 h0 theorem omS202 {x0 x1:ℕ} (h0:x0< x1):x0+1≤ x1:=by 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 _) end mutual theorem omS205 {x0 x1:ℕ} (h0:x0≤ x1):x0≤ x1+1:=by exact Nat.le_succ_of_le h0 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 simp at *; omega theorem omS210 {x0 x1 x2:ℕ} (h0:x0+x1< x2):x0+x1=Min.min (x0+x1) (x2-1):=by 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 end mutual 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 exact Nat.lt_trans h1 h0 theorem omS215 {x0 x1:ℕ} (h0:x0+8≤ x1):x0+1≤ x1:=by simp at *; omega theorem omS216 {x0 x1:ℕ} (h0:x0+8≤ x1):x0+1+1≤ x1:=by simp at *; omega theorem omS217 {x0 x1:ℕ} (h0:x0+8≤ x1):x0+2+1≤ x1:=by simp at *; omega theorem omS218 {x0 x1:ℕ} (h0:x0+8≤ x1):x0+3+1≤ x1:=by simp at *; omega theorem omS219 {x0 x1:ℕ} (h0:x0+8≤ x1):x0+4+1≤ x1:=by simp at *; omega theorem omS220 {x0 x1:ℕ} (h0:x0+8≤ x1):x0+4+1+1≤ x1:=by simp at *; omega end mutual theorem omS221 {x0:ℕ}:x0+5=x0+4+1:=by rfl theorem omS222 {x0:ℕ}:x0+6=x0+4+2:=by rfl theorem omS223 {x0:ℕ}:x0+7=x0+4+3:=by 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 end mutual 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 end mutual 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 assumption 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 assumption 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 end mutual 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 simp at *; omega theorem omS248 {x0:ℕ}:2 ^ 52≤ 2 ^ 52+x0:=by exact Nat.le_add_right _ _ 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 end mutual 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 end mutual theorem omS262 {x0 x1:ℕ} (h0:x0< Ѧ(8088464930757410816:UInt64)) (h1:Ѧ(8088464930757410816:UInt64)≤ x1):x0≤ x1:=by exact Nat.le_of_lt (Nat.lt_of_lt_of_le h0 h1) 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 exact Nat.lt_of_lt_of_le (by decide) h0 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 exact Nat.le_of_lt (Nat.lt_of_le_of_lt h0 h1) theorem omS269 {x0 x1 x2 x3:ℕ} (h0:x0+x1≤ x2) (h1:x2=x3) (h2:x3< 2 ^ 32):x0< 2 ^ 32:=by subst_vars; omega end mutual theorem omS270 {x0 x1 x2 x3:ℕ} (h0:x0+x1≤ x3) (h1:x3=x2):x0+x1≤ x2:=by subst_vars; assumption 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 *; exact Nat.lt_of_lt_of_le (by decide) h1 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 rfl theorem omS277 {x0 x1:ℕ} (h0:x0+4≤ x1):x0+0< x1:=by simp at *; omega end mutual 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 exact Nat.lt_trans h1 h0 theorem omS280 {x0 x1 x2:ℕ} (h0:x1+x0=x2) (h1:x1< x2):x0-1< x0:=by subst_vars; simp at *; assumption 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 *; assumption 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 end mutual theorem omS286 {x0 x1:ℕ} (h0:8*x0+9≤ x1):8*x0+1+7< x1:=by assumption theorem omS287 {x0 x1:ℕ} (h0:8*x0+9≤ x1):8*x0+1+6< x1:=by exact Nat.le_of_lt ‹_› 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 simp at *; omega end mutual 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 end mutual 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 simp +arith at * ; assumption theorem omS319 {x0 x1 x2:ℕ} (h0:x1< x2+8) (h1:x1=x2+x0):x0< 8:=by subst_vars; simp at *; assumption end mutual 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; exact Nat.lt_trans h1 h0 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; exact Nat.lt_of_le_of_lt h2 h1 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 rfl end mutual 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 simp at *; assumption theorem omS335 {x0:ℕ} : ↑x0-(1046:ℤ) = ↑(30:ℕ)+(↑x0-(1076:ℤ)):=by ring 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 omS378 {x0 x1 x2:ℕ}:x0+(x1+2*x2)=x0+x2+x1+x2:=by simp +arith at * end mutual 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 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 simp +arith at * ; assumption end mutual theorem omS387 {x0 x1 x2 x3 x4:ℕ}:x0< x1 ∨ x1+(x2+x3)< x1 ∨ x0-x1 ≥ x4 ∨ x1+(x2+x3)-x1 ≥ x2:=by 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 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 exact Nat.le_succ_of_le h0 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 end mutual theorem omS421 {x0 x1 x2 x3 x4:ℕ} (h0:x4≤ x3) (h1:x0+x1+x2+x1≤ x4):x0+x1+x2≤ x3:=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 end 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 namespace C @[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 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 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 F16 where (u:UInt8) (s0 s1 s2 s3 s4 s5 s6 s7 t0 t1 t2 t3 t4 t5 t6 t7:ὧ) (q:ὥ) @[inline] def F16.a (r:F16):F8:=⟨r.u,r.s0,r.s1,r.s2,r.s3,r.s4,r.s5,r.s6,r.s7,0,r.q⟩ @[inline] def F16.b (r:F16):F8:=⟨r.u,r.t0,r.t1,r.t2,r.t3,r.t4,r.t5,r.t6,r.t7,0,r.q⟩ structure H8 where (xs:ὤ) (h0 h1 h2 h3 h4 h5 h6 h7:ὧ) structure L8 where (l0 l1 l2 l3 l4 l5 l6 l7:Ὠ) mutual theorem 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] theorem 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 theorem qGw {w:ὥ} (h:expOf w≠255):Ἑ (ofW w)=true:=by simp[ofW,isFinite_ofUInt32,h] theorem 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]) end 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 mutual theorem 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 theorem 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 end mutual theorem 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 theorem 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] end @[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) mutual theorem 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 theorem 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 ‹_› ‹_›) theorem 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 ‹_› ‹_›) theorem 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 ‹_› ‹_›) theorem 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 ‹_› ‹_›) theorem 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 ‹_› ‹_›) end @[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] mutual theorem qTd (z k:Ὣ):(pwTb z k).size=512:=by simp only[FloatArray.size,qDj,Array.size_map,List.size_toArray,List.length_range] theorem 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) end 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 mutual theorem qTs {z:Ὣ} {T:ὤ} {h:ὥ} (o:TOK z T h):ѨT=512:=by obtain ⟨k,e,-⟩:=o;exact e theorem 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⟩ end @[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 structure TR where (p n E:Ὣ) (ok:Ὡ) @[inline] def fsh (x d:Nat):Nat:=if d<63∧x>>>(63-d)=0 then (x.toUInt64 <<< d.toUInt64).toNat else x<<>> 1) &&& 1) != 0 || fsh r a != v then q+1 else q) else q theorem rsre_eq (v s:Ὣ):rsre v s=FloatLib.Numerics.roundShiftRightEven v s:=by unfold rsre FloatLib.Numerics.roundShiftRightEven;simp only [fsh_eq];rfl @[inline] def roundWf (neg:Ὡ) (m:Ὣ) (e:Int):ὥ := let L:=m.log2 let T:Int:=L+e let r:=rsre m (L-23) if 23≤ L ∧ -126≤ T∧T≤ 126∧FastRound.p23≤ r∧r≤ FastRound.p24 then let E:Ὣ:=if r=FastRound.p24 then (T+128).toNat else (T+127).toNat let F:Ὣ:=if r=FastRound.p24 then 0 else r-FastRound.p23 (if neg then (0x80000000:ὥ) else 0)+(E.toUInt32 <<< 23)+F.toUInt32 else toWord (Model.roundDyadic Fmt ⟨neg,m,e⟩) theorem roundWf_eq (neg:Ὡ) (m:Ὣ) (e:Int):roundWf neg m e=FastRound.roundW neg m e:=by unfold roundWf FastRound.roundW;simp only [rsre_eq] @[inline] def shz (p d:Ὣ):Ὣ:=if p=0 then 0 else fsh p d @[specialize] def tAcc (fa fb:Ὣ->ὥ) (p n E i:Ὣ):Ὣ->TR | 0=>⟨p,n,E,true⟩ | c+1=> let wa:=fa i let wb:=fb i if wa &&& В=0 then (if expOf wb=255 then ⟨p,n,E,false⟩ else tAcc fa fb p n E (i+1) c) else if expOf wa=255 ∨ expOf wb=255 then ⟨p,n,E,false⟩ else let m:=mantOf wa*mantOf wb if m=0 then tAcc fa fb p n E (i+1) c else let e:=idxOf wa+idxOf wb if E<=e then if m>>>(E+62-e)≠0 then ⟨p,n,E,false⟩ else let q:=fsh m (e-E) if Bool.xor (signOf wa) (signOf wb) then (if (n+q)>>>62=0 then tAcc fa fb p (n+q) E (i+1) c else ⟨p,n,E,false⟩) else (if (p+q)>>>62=0 then tAcc fa fb (p+q) n E (i+1) c else ⟨p,n,E,false⟩) else let d:=E-e if (p|||n)>>>(62-d)≠0 then ⟨p,n,E,false⟩ else let p':=shz p d let n':=shz n d if Bool.xor (signOf wa) (signOf wb) then tAcc fa fb p' (n'+m) e (i+1) c else tAcc fa fb (p'+m) n' e (i+1) c @[inline] def tFin (r:TR):ὥ := if r.ok then if r.nX[xo+t]!) (λt=>W[wo+t]!) 0 0 1000 0 inW tFin (if r.ok then tAcc (λ_=>oneW) (λ_=>b[j]!) r.p r.n r.E inW 1 else r) mutual theorem zW (w:UInt32) (h:w &&& 0x7FFFFFFF=0):mantOf w=0∧expOf w≠ 255:=by have h1:w.toNat % 2^31=0:=by have:=congrArg UInt32.toNat h rw [UInt32.toNat_and,show (0x7FFFFFFF:UInt32).toNat=2^31-1 from rfl,Nat.and_two_pow_sub_one_eq_mod] at this simpa using this have he:(expOf w).toNat=0:=by unfold expOf rw [UInt32.toNat_and,UInt32.toNat_shiftRight,show (0xFF:UInt32).toNat=2^8-1 from rfl,Nat.and_two_pow_sub_one_eq_mod,Nat.shiftRight_eq_div_pow] simp only [show (23:UInt32).toNat % 32=23 from rfl]; omega have hf:(fracOf w).toNat=0:=by unfold fracOf rw [UInt32.toNat_and,show (0x7FFFFF:UInt32).toNat=2^23-1 from rfl,Nat.and_two_pow_sub_one_eq_mod]; omega have he0:expOf w=0:=UInt32.toNat_inj.mp (by simpa using he) refine ⟨by simp [mantOf,he0,hf], ?_⟩ rw [he0]; decide theorem tSh (p d:Nat):((shz p d:Nat):Int)=(p:Int)*2^d:=by unfold shz; split_ifs with h · simp [h] · rw [fsh_eq,Nat.shiftLeft_eq]; push_cast; rfl end mutual theorem tAcc_spec (fa fb:Nat->UInt32) (A B:Array UInt32) : ∀ (c p n E i:Nat), (∀ k,i≤ k→ k< i+c→ A[k]! = fa k∧B[k]! = fb k)→ (tAcc fa fb p n E i c).ok=true → (∀ k,i≤ k→ k< i+c→ expOf A[k]! ≠ 255∧expOf B[k]! ≠ 255) ∧ (((tAcc fa fb p n E i c).p:Int)-(tAcc fa fb p n E i c).n)*2^(tAcc fa fb p n E i c).E=((p:Int)-n)*2^E+dsum A B i c:=by intro c induction c with | zero=>intro p n E i _ _; simp only [tAcc,dsum]; exact ⟨fun k h1 h2=>by omega,by simp⟩ | succ c ih => intro p n E i hab hok obtain ⟨ha,hb⟩:=hab i le_rfl (by omega) have hab' : ∀ k,i+1≤ k→ k< i+1+c→ A[k]! = fa k∧B[k]! = fb k:=fun k k1 k2=>hab k (by exact Nat.le_of_lt ‹_›) (by omega) have hsv:sv A[i]! * sv B[i]! = (if Bool.xor (signOf (fa i)) (signOf (fb i)) then -((mantOf (fa i)*mantOf (fb i):Nat):Int) else ((mantOf (fa i)*mantOf (fb i):Nat):Int)):=by rw [ha,hb]; unfold sv; cases signOf (fa i) <;> cases signOf (fb i) <;> simp have hds:dsum A B i (c+1)=sv A[i]! * sv B[i]! * 2^(idxOf A[i]! + idxOf B[i]!)+dsum A B (i+1) c:=rfl have hfi : ¬(expOf (fa i)=255 ∨ expOf (fb i)=255) → ∀ k,i≤ k→ k< i+1→ expOf A[k]! ≠ 255∧expOf B[k]! ≠ 255:=by intro h1 k k1 k2; obtain rfl:k=i:=by omega rw [ha,hb]; exact not_or.mp h1 simp only [tAcc] at hok ⊢ by_cases hz:fa i &&& 0x7FFFFFFF=0 · obtain ⟨hm0,he0⟩:=zW _ hz simp only [hz,ite_true] at hok ⊢ split_ifs at hok ⊢ with hw obtain ⟨hf,hv⟩:=ih _ _ _ (i+1) hab' hok refine ⟨fun k k1 k2 => ?_, ?_⟩ · rcases Nat.lt_or_ge k (i+1) with hk | hk · exact hfi (by rintro (h|h) <;> contradiction) k k1 hk · exact hf k hk (by omega) · rw [hv,hds,hsv,ha,hb,hm0]; simp simp only [hz,ite_false] at hok ⊢ rw [hds,hsv,ha,hb] split_ifs at hok ⊢ with h1 h2 h5 h3 h4 h6 h6 h4 h6 h6 <;> obtain ⟨hf,hv⟩:=ih _ _ _ (i+1) hab' hok <;> refine ⟨fun k k1 k2 => ?_, ?_⟩ <;> (try (rcases Nat.lt_or_ge k (i+1) with hk | hk · exact hfi h1 k k1 hk · exact hf k hk (by omega))) all_goals rw [hv] first | (simp [h2]; done) | (have he:(2:Int)^(idxOf (fa i)+idxOf (fb i))=2^(idxOf (fa i)+idxOf (fb i)-E)*2^E:=by rw [← pow_add]; congr 1; omega rw [fsh_eq,Nat.shiftLeft_eq,he]; push_cast; ring) | (have he:(2:Int)^E=2^(E-(idxOf (fa i)+idxOf (fb i)))*2^(idxOf (fa i)+idxOf (fb i)):=by rw [← pow_add]; congr 1; omega push_cast; rw [tSh,tSh,he]; ring) theorem dsum_add (a b:Array UInt32) : ∀ c i d,dsum a b i (c+d)=dsum a b i c+dsum a b (i+c) d:=by intro c; induction c with | zero=>intro i d; simp [dsum] | succ c ih=>intro i d; rw [show c+1+d=(c+d)+1 by omega]; simp only [dsum]; rw [ih (i+1) d]; rw [show i+1+c=i+(c+1) by omega]; ring theorem tFin_eq (S:Int) (r:TR) (hS:((r.p:Int)-r.n)*2^r.E=S) (z:Bool) (h:tFin r≠ 0xFFFFFFFF) : tFin r=finishWord S (-298) z:=by rw [← hS, ← finishWord_scale,show (-298:Int)+r.E=r.E-298 by ring] unfold tFin at h ⊢ split_ifs at h ⊢ with c0 c1 c2 · rw [roundWf_eq,FastRound.roundW_eq] refine (finishWord_of_ne _ ((r.p:Int)-r.n) _ _ (by omega) ?_).symm simp [FloatLib.Numerics.Dyadic.toRat,FloatLib.Numerics.Dyadic.signedSignificand] left; rw [Nat.cast_sub c1.le] · rw [roundWf_eq,FastRound.roundW_eq] refine (finishWord_of_ne _ ((r.p:Int)-r.n) _ _ (by omega) ?_).symm simp [FloatLib.Numerics.Dyadic.toRat,FloatLib.Numerics.Dyadic.signedSignificand] try (rw [Nat.cast_sub c2.le]; ring) · exact absurd rfl h · exact absurd rfl h end theorem tieL_spec (inW:Ὣ) (X W b:ё) (i j:Ὣ) (h:tieL inW X W b i j≠Е):tieL inW X W b i j=dotOf (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]!):=by unfold tieL at h ⊢ dsimp only at h ⊢ unfold dotOf set fa0:Nat->UInt32:=(λt=>if t< inW then X[i*inW+t]! else oneW) with hfa0 set fb0:Nat->UInt32:=(λt=>if t< inW then W[j*inW+t]! else b[j]!) with hfb0 set A:=Array.ofFn (n:=inW+1) (λk=>fa0 k.val) with hA set B:=Array.ofFn (n:=inW+1) (λk=>fb0 k.val) with hB have hAs:A.size=inW+1:=by simp [hA] generalize hr1:tAcc (λt=>X[i*inW+t]!) (λt=>W[j*inW+t]!) 0 0 1000 0 inW=r1 at h ⊢ by_cases hok1:r1.ok=true · simp only [hok1,ite_true] at h ⊢ generalize hr2:tAcc (λ_=>oneW) (λ_=>b[j]!) r1.p r1.n r1.E inW 1=r2 at h ⊢ have hok2:r2.ok=true:=by by_contra hc; unfold tFin at h; simp [hc] at h obtain ⟨f1,v1⟩:=tAcc_spec (λt=>X[i*inW+t]!) (λt=>W[j*inW+t]!) A B inW 0 0 1000 0 (fun k _ k2=>by rw [hA,hB,qAb _ _ _ (by omega),qAb _ _ _ (by omega)] simp only [hfa0,hfb0]; simp [show k< inW by omega]) (hr1 ▸ hok1) obtain ⟨f2,v2⟩:=tAcc_spec (λ_=>oneW) (λ_=>b[j]!) A B 1 r1.p r1.n r1.E inW (fun k k1 k2=>by rw [hA,hB,qAb _ _ _ (by assumption),qAb _ _ _ (by assumption)] simp only [hfa0,hfb0]; simp [show ¬ k< inW by exact Nat.not_lt_of_ge k1]) (hr2 ▸ hok2) rw [hr1] at v1; rw [hr2] at v2 have hall : ∀ k,k< A.size→ expOf A[k]! ≠ 255∧expOf B[k]! ≠ 255:=by intro k hk; rw [hAs] at hk rcases Nat.lt_or_ge k inW with h1 | h1 · exact f1 k (by exact Nat.zero_le _) (by omega) · exact f2 k h1 (by assumption) rw [← qEg A B (by simp [hA,hB]) hall,hAs] refine tFin_eq _ r2 ?_ _ h rw [v2,v1,show dsum A B 0 (inW+1)=dsum A B 0 inW+dsum A B (0+inW) 1 from dsum_add A B inW 0 1] simp only [Nat.cast_zero,sub_self,zero_mul,zero_add] · simp only [hok1] at h ⊢ unfold tFin at h; simp [hok1] at h @[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,irreducible] def tieG (x:ὧ) (inW:Ὣ) (X W b:ё) (i j:Ὣ):ὥ := if (x.toBits &&& 0x1FFFFFFF) == 0x10000000 then tieL inW X W b i j else Е theorem tieG_spec (x:ὧ) (inW:Ὣ) (X W b:ё) (i j:Ὣ) (h:tieG x inW X W b i j≠Е):tieG x inW X W b i j=dotOf (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]!):=by unfold tieG at h ⊢ by_cases c:(x.toBits &&& 0x1FFFFFFF) == 0x10000000 · rw [ite_eq_left c] at h ⊢; exact tieL_spec _ _ _ _ _ _ h · rw [ite_eq_right c] at h; exact absurd rfl h @[noinline,irreducible] def fin8t (inW:Ὣ) (relu:Ὡ) (X W b:@& ё) (i j:Ὣ) (nf:ὧ) (bw:ὥ) (n:ὦ) (x:ὧ):ὥ := let r:=tieG x inW X W b i j if r != Е then act relu r else fin8s inW relu X W b i j nf bw n @[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 fin8t inW relu X W b i j nf bw n (s+bv) 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) mutual theorem 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 theorem 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 theorem 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 theorem 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 theorem 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 theorem 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 theorem 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 theorem 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 end 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 mutual theorem wrUs (a:ὤ) (i:ὦ) (v:ὧ) (h:Ѥi< Ѩa):(a.uset i v h).size=Ѩa:=by obtain ⟨ds⟩:=a;exact Array.size_uset _ theorem wr8k (i:ὦ) (k:Ὣ) (hk:k<8) (h:Ѥi+8<=2^32):Ѥ(i+USize.ofNat k)=Ѥi+k:=by have h2:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl rw[USize.toNat_add,USize.toNat_ofNat',Nat.mod_eq_of_lt (show k<2^System.Platform.numBits by cases System.Platform.numBits_eq<;>simp_all<;>exact Nat.lt_of_lt_of_le hk (by decide)),Nat.mod_eq_of_lt (by omega)] end @[inline] def wr8u (xs:ὤ) (i:ὦ) (h:Ѥi+8<=Ѩxs) (hs:Ѩxs<2^32) (a0 a1 a2 a3 a4 a5 a6 a7:ὧ):ὤ := let x:=xs.uset (i+USize.ofNat 0) a0 (by rw[wr8k i 0 (by decide) (by omega)];omega) let x:=x.uset (i+USize.ofNat 1) a1 (by rw[wrUs,wr8k i 1 (by decide) (by omega)];omega) let x:=x.uset (i+USize.ofNat 2) a2 (by rw[wrUs,wrUs,wr8k i 2 (by decide) (by omega)];omega) let x:=x.uset (i+USize.ofNat 3) a3 (by rw[wrUs,wrUs,wrUs,wr8k i 3 (by decide) (by omega)];omega) let x:=x.uset (i+USize.ofNat 4) a4 (by rw[wrUs,wrUs,wrUs,wrUs,wr8k i 4 (by decide) (by omega)];omega) let x:=x.uset (i+USize.ofNat 5) a5 (by rw[wrUs,wrUs,wrUs,wrUs,wrUs,wr8k i 5 (by decide) (by omega)];omega) let x:=x.uset (i+USize.ofNat 6) a6 (by rw[wrUs,wrUs,wrUs,wrUs,wrUs,wrUs,wr8k i 6 (by decide) (by omega)];omega) x.uset (i+USize.ofNat 7) a7 (by rw[wrUs,wrUs,wrUs,wrUs,wrUs,wrUs,wrUs,wr8k i 7 (by decide) (by omega)];omega) mutual theorem wr8u_size (xs:ὤ) (i:ὦ) (h:Ѥi+8<=Ѩxs) (hs:Ѩxs<2^32) (a0 a1 a2 a3 a4 a5 a6 a7:ὧ):Ѩ(wr8u xs i h hs a0 a1 a2 a3 a4 a5 a6 a7)=Ѩxs:=by unfold wr8u;simp only[wrUs] theorem wr8u_eq (xs:ὤ) (i:ὦ) (h:Ѥi+8<=Ѩxs) (hs:Ѩxs<2^32) (a0 a1 a2 a3 a4 a5 a6 a7:ὧ):wr8u xs i h hs a0 a1 a2 a3 a4 a5 a6 a7=wr8 xs i a0 a1 a2 a3 a4 a5 a6 a7:=by have g:∀ (a:ὤ) (k:Ὣ) (v:ὧ) (hk:k<8) (ha:Ѩa=Ѩxs) (hb),wrF a (i+USize.ofNat k) v=a.uset (i+USize.ofNat k) v hb:=by intro a k v hk ha hb unfold wrF;rw[dite_eq_left (by rw[USize.lt_iff_toNat_lt,FloatArray.usize,USize.toNat_ofNat_of_lt_32 (by omega)];exact hb)] unfold wr8u wr8;dsimp only rw[g _ 0 _ (by decide) rfl,g _ 1 _ (by decide) (wrUs ..),g _ 2 _ (by decide) (by rw[wrUs,wrUs]),g _ 3 _ (by decide) (by rw[wrUs,wrUs,wrUs]), g _ 4 _ (by decide) (by rw[wrUs,wrUs,wrUs,wrUs]),g _ 5 _ (by decide) (by rw[wrUs,wrUs,wrUs,wrUs,wrUs]),g _ 6 _ (by decide) (by rw[wrUs,wrUs,wrUs,wrUs,wrUs,wrUs]), g _ 7 _ (by decide) (by rw[wrUs,wrUs,wrUs,wrUs,wrUs,wrUs,wrUs])] end 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 go82 (D:ὤ) (xs:ὤ) (W:ѐ) (hd:ѨD=ѧW) (wo1 wo2 n t i:ὦ) (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw1:Ѥwo1+Ѥn<=ѧW) (hw2:Ѥwo2+Ѥn<=ѧW) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7 u0 u1 u2 u3 u4 u5 u6 u7:ὧ) (q:ὥ) (r:F16):F16 := if h:t< n then have ht:=А.mp h let v:=D.uget (wo1+t) (hd ▸ wi wo1 t n W hw1 hs ht) let w:=D.uget (wo2+t) (hd ▸ wi wo2 t n W hw2 hs ht) let x0:=xs.uget (i+USize.ofNat 0) (xi xs i t n 0 (by decide) ht hi hx hsx) let x1:=xs.uget (i+USize.ofNat 1) (xi xs i t n 1 (by decide) ht hi hx hsx) let x2:=xs.uget (i+USize.ofNat 2) (xi xs i t n 2 (by decide) ht hi hx hsx) let x3:=xs.uget (i+USize.ofNat 3) (xi xs i t n 3 (by decide) ht hi hx hsx) let x4:=xs.uget (i+USize.ofNat 4) (xi xs i t n 4 (by decide) ht hi hx hsx) let x5:=xs.uget (i+USize.ofNat 5) (xi xs i t n 5 (by decide) ht hi hx hsx) let x6:=xs.uget (i+USize.ofNat 6) (xi xs i t n 6 (by decide) ht hi hx hsx) let x7:=xs.uget (i+USize.ofNat 7) (xi xs i t n 7 (by decide) ht hi hx hsx) go82 D xs W hd wo1 wo2 n (t+1) (i+USize.ofNat 8) hx hsx hs hw1 hw2 (by rw[usz t n h,qAf _ _ (by rw[uk 8 (by decide)];omega),uk 8 (by decide)];omega) (s0+x0*v) (s1+x1*v) (s2+x2*v) (s3+x3*v) (s4+x4*v) (s5+x5*v) (s6+x6*v) (s7+x7*v) (u0+x0*w) (u1+x1*w) (u2+x2*w) (u3+x3*w) (u4+x4*w) (u5+x5*w) (u6+x6*w) (u7+x7*w) q r else match r with | ⟨u,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_⟩=>⟨u,s0,s1,s2,s3,s4,s5,s6,s7,u0,u1,u2,u3,u4,u5,u6,u7,q⟩ partial_fixpoint mutual theorem go8ZD_u (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) (q:ὥ) (r r':F8) (hr:r.u=r'.u) : ∀ (m:Ὣ) (t i:ὦ) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ),Ѥn-Ѥt=m → go8ZD 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 intro m induction m using Nat.strong_induction_on with | _ m ih=> intro t i hi s0 s1 s2 s3 s4 s5 s6 s7 hm rw[go8ZD,go8ZD];split . rename_i h;have:=usz t n h;have:=А.mp h;exact ih _ (by omega) (t+1) _ _ _ _ _ _ _ _ _ _ rfl . cases r;cases r';simp only at hr;subst hr;rfl theorem go8ZD_uu (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) (q:ὥ) (r:F8) : ∀ (m:Ὣ) (t i:ὦ) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ),Ѥn-Ѥt=m → (go8ZD D xs W hd wo n t i hx hsx hs hw hi s0 s1 s2 s3 s4 s5 s6 s7 q r).u=r.u:=by intro m induction m using Nat.strong_induction_on with | _ m ih=> intro t i hi s0 s1 s2 s3 s4 s5 s6 s7 hm rw[go8ZD];split . rename_i h;have:=usz t n h;have:=А.mp h;exact ih _ (by omega) (t+1) _ _ _ _ _ _ _ _ _ _ rfl . cases r;rfl theorem go82_a (D:ὤ) (xs:ὤ) (W:ѐ) (hd:ѨD=ѧW) (wo1 wo2 n:ὦ) (hx:8*Ѥn+1<=Ѩxs) (hsx:Ѩxs<2^32) (hs:ѧW<2^32) (hw1:Ѥwo1+Ѥn<=ѧW) (hw2:Ѥwo2+Ѥn<=ѧW) (q:ὥ) (r:F16) : ∀ (m:Ὣ) (t i:ὦ) (hi:Ѥi=8*Ѥt+1) (s0 s1 s2 s3 s4 s5 s6 s7 u0 u1 u2 u3 u4 u5 u6 u7:ὧ),Ѥn-Ѥt=m → (go82 D xs W hd wo1 wo2 n t i hx hsx hs hw1 hw2 hi s0 s1 s2 s3 s4 s5 s6 s7 u0 u1 u2 u3 u4 u5 u6 u7 q r).a=go8ZD D xs W hd wo1 n t i hx hsx hs hw1 hi s0 s1 s2 s3 s4 s5 s6 s7 q r.a ∧ (go82 D xs W hd wo1 wo2 n t i hx hsx hs hw1 hw2 hi s0 s1 s2 s3 s4 s5 s6 s7 u0 u1 u2 u3 u4 u5 u6 u7 q r).b=go8ZD D xs W hd wo2 n t i hx hsx hs hw2 hi u0 u1 u2 u3 u4 u5 u6 u7 q r.a:=by intro m induction m using Nat.strong_induction_on with | _ m ih=> intro t i hi s0 s1 s2 s3 s4 s5 s6 s7 u0 u1 u2 u3 u4 u5 u6 u7 hm rw[go82,go8ZD,go8ZD];split . rename_i h;have:=usz t n h;have:=А.mp h;exact ih _ (by omega) (t+1) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ rfl . cases r;exact ⟨rfl,rfl⟩ end 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) 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:ὥ) (z:ὦ) local instance ecNe7:Nonempty R3:=⟨by constructor <;> exact default⟩ def decV (X:ѐ) (o n t:ὦ) (buf:ὤ) (l:ὧ) (lo hi:ὥ) (z:ὦ) (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) (z+(u >>> (31:ὥ)).toUSize) hX hs (by rw[qUs];exact hb) else ⟨buf,l,lo,hi,z⟩ 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 @[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 local instance ecNeZ1:Nonempty G16:=⟨by constructor <;> exact default⟩ def go16W (x wb:ὤ) (ix:ѐ) (p p' m n t:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (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 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 let q':=p'+USize.ofNat 8*i go16W x wb ix p p' m n (t+1) hx hi hb 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)) (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 go16W x wb ix p p' m n (t+1) hx hi hb hb' hs a b c d e f g k a' b' c' d' e' f' g' k' 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) local instance ecNeZ2:Nonempty G24:=⟨by constructor <;> exact default⟩ def go24W (x wb:ὤ) (ix:ѐ) (p p' p'' m n t:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (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 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 let q':=p'+USize.ofNat 8*i let q'':=p''+USize.ofNat 8*i go24W x wb ix p p' p'' m n (t+1) hx hi hb hb' 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)) (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)) (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 go24W x wb ix p p' p'' m n (t+1) hx hi 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'' 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) def colsZ2 (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∧Ѥn<=ѧix∧Ѩwb<=4294967295∧Ѥw0+5+8*Ѥm<=Ѩwb∧Ѥyw0+5+8*Ѥm<=Ѩwb then let rr:=go16W x wb ix (w0+USize.ofNat 5) (yw0+USize.ofNat 5) m n 0 hg.1 hg.2.1 (pk w0 m wb hg.2.2.2.1 hg.2.2.1).1 (pk yw0 m wb hg.2.2.2.2 hg.2.2.1).1 (qA9 hg.2.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' colsZ2 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 cols1W inW outW relu X W b i ix x wd wb nf a hx lo m n j base out else cols1W inW outW relu X W b i ix x wd wb nf a hx lo m n j base out partial_fixpoint def colsZ3 (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∧Ѥn<=ѧix∧Ѩwb<=4294967295∧Ѥw0+5+8*Ѥm<=Ѩwb∧Ѥyw0+5+8*Ѥm<=Ѩwb∧Ѥzw0+5+8*Ѥm<=Ѩwb then let rr:=go24W x wb ix (w0+USize.ofNat 5) (yw0+USize.ofNat 5) (zw0+USize.ofNat 5) m n 0 hg.1 hg.2.1 (pk w0 m wb hg.2.2.2.1 hg.2.2.1).1 (pk yw0 m wb hg.2.2.2.2.1 hg.2.2.1).1 (pk zw0 m wb hg.2.2.2.2.2 hg.2.2.1).1 (qA9 hg.2.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'' colsZ3 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 colsZ2 inW outW relu X W b i ix x wd wb B nf a hx lo sp m n j base out else colsZ2 inW outW relu X W b i ix x wd wb B nf a hx lo sp m n j base out partial_fixpoint structure R5 where (x:ὤ) (ix:ѐ) (c:ὦ) local instance ecNeZ3:Nonempty R5:=⟨by constructor <;> exact default⟩ def cpZ (X:ѐ) (o n t:ὦ) (x:ὤ) (ix:ѐ) (c:ὦ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hc:Ѥc<=Ѥt):R5 := if h:t< n then have ht:=А.mp h have hcn:c< n:=А.mpr (by omega) let w:=X.uget (o+t) (wi o t n X hX hs ht) cpZ X o n (t+1) (x.uset c (x.uget t (by omega)) (by omega)) (ix.uset c t.toUInt32 (by omega)) (if w &&& В==0 then c else c+1) hX hs (by rw[qUs];exact hx) (by rw[Array.size_uset];exact hi) (by split <;> [(rw[usz t n h];omega);(rw[usz t n h,usz c n hcn];omega)]) else ⟨x,ix,c⟩ termination_by Ѥn-Ѥt decreasing_by rw[usz t n h];exact Nat.sub_lt_sub_left (А.mp h) (Nat.lt_succ_self _) def sA (x:ὤ) (c t:ὦ) (l:ὧ):ὧ := if h:t< c then sA x c (t+1) (l+(rdB x t).abs) else l termination_by Ѥc-Ѥt decreasing_by rw[usz t c h];exact Nat.sub_lt_sub_left (А.mp h) (Nat.lt_succ_self _) def linZ (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (c:((ὤ×ὥ)×(ὤ×ὥ))) (nf:ὧ) (o n:ὦ) (buf:ὤ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (hb:Ѥn<=Ѩbuf) (hi:Ѥn<=ѧ(ἇ inW (0:ὥ))):ѐ := let q:=cpZ X o n 0 buf (ἇ inW 0) 0 hX hs hb hi (Nat.le_refl _) let l:=sA q.x q.c 0 0 let lo:=loOf (nf*(dv c.1.2*l+dv c.2.2)) if 128<=inW then colsZ3 inW outW relu X W b 0 q.ix q.x (ἆ 0) c.1.1 c.2.1 nf l c.1.2 lo (spOf lo) n q.c 0 (0*outW).toUSize (ἇ (1*outW) 0) else colsZ2 inW outW relu X W b 0 q.ix q.x (ἆ 0) c.1.1 c.2.1 nf l c.1.2 lo (spOf lo) n q.c 0 (0*outW).toUSize (ἇ (1*outW) 0) 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 0 hz.1 (by have:=hz.2.2.2;omega) hz.2.1 if 0x007FFFFF<=v.lo∧v.hi<У then if v.z*8< n ∨ v.z.toNat*outW< 32*inW ∨ (v.z*4< 3*n∧outW< inW) 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 if hq:Ѥn<=Ѩv.buf∧Ѥn<=ѧ(ἇ inW (0:ὥ)) then linZ inW outW relu X W b c nf o n v.buf hz.1 (by have:=hz.2.2.2;omega) hq.1 hq.2 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 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 mutual theorem A_R (x:ὧ):R x=Ἢ (A_M x):=rfl theorem qAh (x:ὧ):Ἑ (A_M x)=x.isFinite:=by rw[qAy,Ὀ];rfl end mutual theorem qA3 {x:ὧ} (h:xᶠ):Ἑ (A_M x)=true :=(qAh x).trans h theorem qA0 (e:ℤ):Formats.Flocq.bpow ἲ e=(2:ℝ)^e:=by simp[Formats.Flocq.bpow,FloatLib.Numerics.binaryRadix,FloatLib.Numerics.Radix.toReal] end 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 mutual theorem 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] theorem 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⟩ end 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:ℤ) mutual theorem qAr:0< A_z:=by unfold A_z;positivity theorem 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 end mutual theorem qAw:A_z<=1/2^200*(1/2^200):=by simpa [A_z] using A_p (-1021) 0 (-200) (-200) (by norm_num1) theorem qI1:0< A_B:=by unfold A_B;positivity theorem qCc:(2:ℝ)^256*2^42<=A_B:=by simpa [A_B] using A_p 256 42 300 0 (by norm_num1) end lemma qAn:(2:ℝ)^128<=A_B :=(by (norm_num1):(2:ℝ)^128<=2^256*2^42).trans qCc mutual theorem qE7 {k:ℕ} (h:k<=2^128):(k:ℝ)<=A_B :=(show (k:ℝ)<=2^128 by exact_mod_cast h).trans qAn theorem qE3:A_B*2<=2^(1000:ℤ):=by simpa [A_B] using A_p 300 1 1000 0 (by norm_num1) theorem qDe:A_B*A_B<=2^(1000:ℤ):=by simpa [A_B] using A_p 300 300 1000 0 (by norm_num1) theorem 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]] exact (ἁ b (show (0:ℝ)<=2^(-53:ℤ) by positivity)).trans (by norm_num) . rw[max_eq_right h];exact (half_le_self c.le).trans (le_add_of_nonneg_left d) end mutual theorem 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⟩ theorem qEe {a b:ℝ} (d : |a| ≤ A_B) (c : |b| ≤ A_B) : |a| + |b| ≤ Ἢ (Model.posMaxFinite ⟡):=by have:=qE3 have:=qCd linarith end 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 mutual theorem 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⟩ theorem qBk (x:ὧ):R x=Model.unpackedToReal x.toModel.unpack:=by rw[A_R,ἦ qAj,Ὀ] theorem 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 _ end 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) mutual theorem qCk (m:Ὠ) (h:Ѧm<2^53):m.toFloatᶠ∧R m.toFloat=Ѧm :=qCl _ _ h rfl theorem qHg:(0:ὧ)ᶠ∧R 0=0:=by simpa using qCl 0 0 (by positivity) rfl end 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⟩] mutual theorem 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 theorem qDc (i:ὦ) (h:Ѥi< Ѩpw):pw.uget i h=pwEntry Ѥi:=by simp[FloatArray.uget,qDx] end 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) mutual theorem qAs (v:ℕ):0<=A_mag v:=by unfold A_mag;split_ifs<;>positivity theorem 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 theorem 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) end 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 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 Ἀ _) mutual theorem qCe (l:List ὧ):0<=A_sa l:=qC4 l R theorem 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] theorem 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 exact add_le_add_right ih _) theorem qBo:A_z<=1:=qAw.trans (by norm_num1) 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 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 mutual theorem 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 theorem 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 end mutual theorem 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 positivity 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] theorem 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] theorem 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 end 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 mutual theorem 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)⟩ theorem 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] theorem 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 end 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 mutual theorem 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)) theorem 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] theorem qHh (l:List ℕ) (g:ℕ->ὧ) (b:ὧ):((l.map g ++ [b]).length:ℝ)=ѣl+1:=by simp theorem 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 theorem 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)) 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 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 mutual theorem qF9 (s t:Ὡ):A_r (s ^^ t)=A_r s*A_r t:=by cases s<;>cases t<;>simp[A_r] theorem 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] end 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 mutual theorem qIe (a b:ὧ) (h:A_M a=A_M b):a=b:=by have:=Model.ofFloatModel_injective h;cases a;cases b;simp_all theorem 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]⟩ theorem 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 end 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 mutual theorem qFq (t:Int):Format.binary32.targetExponent t=max (t-24) (-149):=by simp[Format.targetExponent,Format.mantissaBits,Format.minExponent] theorem B_z (a b:ℤ) (n:ℕ) (h:a=n+b):(2:ℝ)^a=2^n*2^b:=by rw[h,Ἓ ἓ,Ἡ] theorem 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⟩ theorem 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 theorem 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 theorem 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 end 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 mutual theorem 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)⟩ theorem 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] end mutual theorem 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 theorem 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] theorem 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] end mutual theorem 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) theorem 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 end 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 mutual theorem 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]))) theorem 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] theorem 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] end mutual theorem 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] theorem 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] end 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 only [loa1,hhi,h,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 assumption,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 mutual theorem C_z:(0:ὦ).toNat=0:=rfl theorem qAd (k:Ὣ) (h:k<2^32):k.toUSize.toNat=k:=by rw[Nat.toUSize_eq];exact uk k h theorem 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 ‹_› ‹_›) end lemma qBe {α:Type} (a:Array α) (h:ѧa<2^32):a.usize.toNat=ѧa :=qAd _ h mutual theorem 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 theorem qBh (a:ѐ) (i:ὦ) (v:ὥ):(wrW a i v).size=ѧa:=by unfold wrW;split<;>simp theorem 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)] end 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; exact h1 ▸ hN) (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 mutual theorem 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; exact Nat.pos_of_ne_zero this) 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) theorem 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 theorem 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 theorem 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 theorem 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))) end 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 mutual theorem 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⟩ theorem qF6 (a b:ὥ):a<=a ||| b∧b<=a ||| b:=by rw[ἃ,ἃ,UInt32.toNat_or];exact ⟨Nat.left_le_or,Nat.right_le_or⟩ theorem 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 theorem qFe (a b:ὥ):a &&& b<=a∧a &&& b<=b:=by rw[ἃ,ἃ,Ἧ];exact ⟨Nat.and_le_left,Nat.and_le_right⟩ theorem 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) end 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; exact e ▸ hk)).1,λk hk=>(h5 k (by exact Nat.zero_le _) (by clear hs h0 h h2 hp hm; exact e ▸ hk)).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]!)) mutual theorem 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) theorem 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) 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.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 fin8t;dsimp only;split;{rename_i h;unfold C_out;rw[tieG_spec _ _ _ _ _ _ _ (by simpa using h)]};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 mutual theorem 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 theorem qC3 (a:ѐ) (i:ὦ) (h:Ѥi< ѧa):a.uget i h=a[Ѥi]!:=by rw[Ἕ a Ѥi h];rfl theorem qD6 (a:ὤ) (i:ὦ) (v:ὧ):(wrF a i v).size=Ѩa:=by unfold wrF;split;. obtain ⟨ds⟩:=a;exact Array.size_uset _ . rfl theorem 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 end 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 _ mutual theorem 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) theorem 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 end 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) mutual theorem 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,Ἵ] theorem 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)) theorem 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 _)⟩ end mutual theorem 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 theorem 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))) theorem qIs:ѧidA=8192:=by simp[idA] end mutual theorem 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) theorem 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 theorem 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⟩)⟩ theorem 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')] end 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 mutual theorem 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 _ _ _ _ _ _ _ _ theorem 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 (Ἇ _) end 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 mutual 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 end 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 Е mutual theorem 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) theorem 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 end mutual theorem 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 theorem 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 only [h2,h2.1,h2.2] end 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] mutual theorem 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 theorem 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 theorem 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 theorem 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 end mutual theorem 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 theorem 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] theorem 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 end 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] mutual theorem 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] theorem 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 ג theorem 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) end 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)]<;>exact q2.trans 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 exact add_le_add_right hvb _) have p1:0<=R (X+v.abs):=by rw[R1,<-Model.roundAt_zero ⟡];exact Model.roundAt_mono _ (by rw[Ra];exact pX.trans (by norm_num)) 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];exact p.trans (by norm_num)) 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 exact p.trans (by norm_num))] 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 mutual theorem qD2 (s:Sign):(Float.Model.pack (UnpackedFloat.infinity s)).unpack.isFinite=false:=by cases s<;>decide +kernel theorem qFh:(Float.Model.pack UnpackedFloat.notANumber).unpack.isFinite=false:=by decide +kernel end mutual theorem 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⟩ theorem 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) end @[inline] def okF (t:ὧ):Ὡ:=t-t==t-t mutual theorem 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 theorem 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 end mutual theorem 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 theorem qHz:(Ἃ 0x7FF8000000000000).isFinite=false:=by decide +kernel end 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 mutual theorem qTb {z:Ὣ} {T:ὤ} {h:ὥ} (o:TOK z T h):ѥh<0x40000000:=by obtain ⟨k,-,-,k2,k3,e⟩:=o;exact omS295 k3 e theorem 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) theorem 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 fin8t inW relu X W b (ri+K) j nf bw n (s+bv) 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 @[inline] def col8F (inW outW:Ὣ) (relu:Ὡ) (X W b:@& ѐ) (d:@& H8) (nf:ὧ) (hv:ὥ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (j:Ὣ) (th:@& L8) (s0 s1 s2 s3 s4 s5 s6 s7:ὧ) (out:ѐ):ѐ := let ju:=ѩj let bw:=rdW b ju let ow:=ѩoutW let bv:=dv bw let t0:=fin1 th.l0 (spOf th.l0) (s0+bv) let out:=wrW out (ob+ju) (if t0 == Е then fin8o inW relu X W b ri 0 j s0 nf d.h0 hv bw n else fz relu t0) let t1:=fin1 th.l1 (spOf th.l1) (s1+bv) let out:=wrW out (ob+(ow+ju)) (if t1 == Е then fin8o inW relu X W b ri 1 j s1 nf d.h1 hv bw n else fz relu t1) let t2:=fin1 th.l2 (spOf th.l2) (s2+bv) let out:=wrW out (ob+(2*ow+ju)) (if t2 == Е then fin8o inW relu X W b ri 2 j s2 nf d.h2 hv bw n else fz relu t2) let t3:=fin1 th.l3 (spOf th.l3) (s3+bv) let out:=wrW out (ob+(3*ow+ju)) (if t3 == Е then fin8o inW relu X W b ri 3 j s3 nf d.h3 hv bw n else fz relu t3) let t4:=fin1 th.l4 (spOf th.l4) (s4+bv) let out:=wrW out (ob+(4*ow+ju)) (if t4 == Е then fin8o inW relu X W b ri 4 j s4 nf d.h4 hv bw n else fz relu t4) let t5:=fin1 th.l5 (spOf th.l5) (s5+bv) let out:=wrW out (ob+(5*ow+ju)) (if t5 == Е then fin8o inW relu X W b ri 5 j s5 nf d.h5 hv bw n else fz relu t5) let t6:=fin1 th.l6 (spOf th.l6) (s6+bv) let out:=wrW out (ob+(6*ow+ju)) (if t6 == Е then fin8o inW relu X W b ri 6 j s6 nf d.h6 hv bw n else fz relu t6) let t7:=fin1 th.l7 (spOf th.l7) (s7+bv) let out:=wrW out (ob+(7*ow+ju)) (if t7 == Е then fin8o inW relu X W b ri 7 j s7 nf d.h7 hv bw n else fz relu t7) out def cols8ZD2 (D:ὤ) (hv:ὥ) (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (hd:ѨD=ѧW) (d:H8) (nf:ὧ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (j:Ὣ) (out:ѐ) (q:ὥ) (th:L8) (r0:F16):CN := if hj:j+1< outW then if hg:8*Ѥn+1<=d.xs.size∧d.xs.size<=4294967295∧ѧW<=4294967295∧Ѥ(ѩj*n)+Ѥn<=ѧW∧Ѥ(ѩ(j+1)*n)+Ѥn<=ѧW then let rr:=go82 D d.xs W hd (ѩj*n) (ѩ(j+1)*n) n 0 (USize.ofNat 1) hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2.1 hg.2.2.2.2 (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 q r0 let r:=rr.a if okF (r.s0+r.s1+r.s2+r.s3+r.s4+r.s5+r.s6+r.s7) then let out:=col8F inW outW relu X W b d nf hv n ri ob j th r.s0 r.s1 r.s2 r.s3 r.s4 r.s5 r.s6 r.s7 out let r2:=rr.b if okF (r2.s0+r2.s1+r2.s2+r2.s3+r2.s4+r2.s5+r2.s6+r2.s7) then cols8ZD2 D hv inW outW relu X W b hd d nf n ri ob (j+2) (col8F inW outW relu X W b d nf hv n ri ob (j+1) th r2.s0 r2.s1 r2.s2 r2.s3 r2.s4 r2.s5 r2.s6 r2.s7 out) q th rr else ⟨out,false⟩ else ⟨out,false⟩ else cols8ZDo D hv inW outW relu X W b hd d nf n ri ob j out q th r0.b else cols8ZDo D hv inW outW relu X W b hd d nf n ri ob j out q th r0.b termination_by outW-j decreasing_by all_goals omega theorem c8step (D:ὤ) (hv:ὥ) (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (hd:ѨD=ѧW) (d:H8) (nf:ὧ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (q:ὥ) (th:L8) (j:Ὣ) (out:ѐ) (r0:F8) (hj:j< outW) (hg:8*Ѥn+1<=d.xs.size∧d.xs.size<=4294967295∧ѧW<=4294967295∧Ѥ(ѩj*n)+Ѥn<=ѧW) : cols8ZDo D hv inW outW relu X W b hd d nf n ri ob j out q th r0= (let r:=go8ZD D d.xs W hd (ѩj*n) 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 cols8ZDo D hv inW outW relu X W b hd d nf n ri ob (j+1) (col8F inW outW relu X W b d nf hv n ri ob j th r.s0 r.s1 r.s2 r.s3 r.s4 r.s5 r.s6 r.s7 out) q th r else ⟨out,false⟩):=by rw[cols8ZDo,dif_pos hj];dsimp only;rw[dif_pos hg,g8ZS];rfl theorem cols8ZD2_eq (D:ὤ) (hv:ὥ) (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (hd:ѨD=ѧW) (d:H8) (nf:ὧ) (n:ὦ) (ri:Ὣ) (ob:ὦ) (q:ὥ) (th:L8) : ∀ (m j:Ὣ) (out:ѐ) (r0:F16),outW-j=m→ cols8ZD2 D hv inW outW relu X W b hd d nf n ri ob j out q th r0=cols8ZDo D hv inW outW relu X W b hd d nf n ri ob j out q th r0.b:=by intro m induction m using Nat.strong_induction_on with | _ m ih=> intro j out r0 hm rw[cols8ZD2] split . rename_i hj split . rename_i hg have hj1:j< outW:=by omega obtain ⟨ea,eb⟩:=go82_a D d.xs W hd (ѩj*n) (ѩ(j+1)*n) n hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2.1 hg.2.2.2.2 q r0 _ 0 (USize.ofNat 1) (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rfl have u1:=go8ZD_uu D d.xs W hd (ѩj*n) n hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2.1 q r0.a _ 0 (USize.ofNat 1) (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 rfl have e1:=go8ZD_u D d.xs W hd (ѩj*n) n hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2.1 q r0.b r0.a rfl _ 0 (USize.ofNat 1) (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 rfl have e2:=go8ZD_u D d.xs W hd (ѩ(j+1)*n) n hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2.2 q (go8ZD D d.xs W hd (ѩj*n) n 0 (USize.ofNat 1) hg.1 (qA9 hg.2.1) (qA9 hg.2.2.1) hg.2.2.2.1 (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 q r0.a) r0.a u1 _ 0 (USize.ofNat 1) (by rw[show (0:ὦ).toNat=0 from rfl,uk 1 (by decide)]) 0 0 0 0 0 0 0 0 rfl rw[c8step D hv inW outW relu X W b hd d nf n ri ob q th j out r0.b hj1 ⟨hg.1,hg.2.1,hg.2.2.1,hg.2.2.2.1⟩] dsimp only rw[ea,eb,e1] split . rw[c8step D hv inW outW relu X W b hd d nf n ri ob q th (j+1) _ _ hj ⟨hg.1,hg.2.1,hg.2.2.1,hg.2.2.2.2⟩] dsimp only rw[e2] split . rw[ih _ (by omega) (j+2) _ _ rfl,eb] . rfl . rfl . rfl . rfl 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 assumption) 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) (hb:8*Ѥn+1<=Ѩxs) (hb2:Ѩxs<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)))) have hi:Ѥ(8*t+USize.ofNat 1)+8<=Ѩxs:=by have ht:=А.mp h have e8:(8:ὦ).toNat=8:=uk 8 (by decide) have em:(8*t).toNat=8*Ѥt:=by rw[USize.toNat_mul,e8];exact Nat.mod_eq_of_lt (by have:=USize.le_size;have h3:USize.size=2^System.Platform.numBits:=rfl;omega) rw[qAf _ _ (by rw[em,uk 1 (by decide)];omega),em,uk 1 (by decide)];omega dec8oI X o n (t+1) (wr8u xs (8*t+USize.ofNat 1) hi hb2 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 (by rw[wr8u_size];exact hb) (by rw[wr8u_size];exact hb2) 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:ὧ) (hb:8*Ѥn+1<=Ѩxs) (hb2:Ѩxs<2^32),Ѥt+d=Ѥn→ dec8oI X o n t xs h0 h1 h2 h3 h4 h5 h6 h7 hx hs hb hb2=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 hb hb2 e rw[dec8oI,dec8o,ἔ (by rw[А];omega),ἔ (by rw[А];omega)] | succ d ih=> intro t xs h0 h1 h2 h3 h4 h5 h6 h7 hb hb2 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),wr8u_eq] simp only[aU X hxs] @[inline] def dec8oC (X:ѐ) (o n:ὦ) (xs:ὤ):H8 := if h:Ѥo+8*Ѥn<=ѧX∧Ѥo+8*Ѥn<=4294967295∧8*Ѥn+1<=Ѩxs∧Ѩxs<=4294967295 then dec8oI X o n 0 xs 0 0 0 0 0 0 0 0 h.1 (by omega) h.2.2.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 h.2.2.1 (by omega) (by simp) . rfl end end mutual theorem 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] theorem 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] theorem 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] end 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];exact Nat.lt_of_lt_of_le ht hb 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 exact Nat.lt_of_lt_of_le ht hb):=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];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] mutual theorem 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] theorem lt8 (j k:Ὣ) (hk:k<=8) (h:j+8<2^32):j+k<2^32:=by omega theorem lk8 (j c:Ὣ) (hc:c+1<=8):j+c+1<=j+8:=by omega theorem fb (u:ὦ) (k j n:Ὣ) (hu:Ѥu=k) (hk:k+1<=j+8) (hj:j+8<=n):Ѥu< n:=by omega end mutual theorem 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] theorem 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 theorem lk (j c outW:Ὣ) (hc:c+1<=8) (hj:j+8<=outW):j+c+1<=outW:=by omega theorem 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 end 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 exact Nat.lt_of_lt_of_le h16 hob) 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 assumption:j+8+8<=outW)];dsimp only;rw[Ἄ (tileG (j+8) outW m n x wb ix W (by assumption) 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 exact Nat.lt_of_lt_of_le h24 hob) 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 assumption:j+8+8+8<=outW)];dsimp only;rw[Ἄ (tileG (j+8+8) outW m n x wb ix W (by assumption) 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:ὥ) (z:ὦ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (hb:Ѥn<=Ѩbuf): (decV X o n t buf l lo hi z hX hs hb).buf=(decE X o n t buf l hX hs hb).buf∧(decV X o n t buf l lo hi z 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:ὥ) (z:ὦ) (hb:Ѥn<=Ѩbuf): scan X N t hN' lo hi=(if 0x007FFFFF<=(decV X o n t buf l lo hi z hX hs hb).lo∧(decV X o n t buf l lo hi z hX hs hb).hi<У then (decV X o n t buf l lo hi z 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 mutual theorem g16W (x wb:ὤ) (ix:ѐ) (p p' m n t:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (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':ὧ): go16W x wb ix p p' m n t hx hi hb hb' hs a b c d e f g k a' b' c' d' e' f' g' k'=g16of (g8of (go8W x wb ix p m n t hx hi hb hs a b c d e f g k)) (g8of (go8W x wb ix p' m n t hx hi 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[go16W,go8W.eq_1 x wb ix p m n t,go8W.eq_1 x wb ix p' m n t,ἔ h,ἔ h,ἔ h];rfl | succ N ih=> have h:t< n:=А.mpr (by omega) rw[go16W,go8W.eq_1 x wb ix p m n t,go8W.eq_1 x wb ix p' m n t,Ἄ h,Ἄ h,Ἄ h];dsimp only split_ifs<;>exact ih (t+1) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ (by rw[usz t n h];omega) theorem g24W (x wb:ὤ) (ix:ѐ) (p p' p'' m n t:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (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'':ὧ): go24W x wb ix p p' p'' m n t hx hi 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 (g8of (go8W x wb ix p m n t hx hi hb hs a b c d e f g k)) (g8of (go8W x wb ix p' m n t hx hi hb' hs a' b' c' d' e' f' g' k')) (g8of (go8W x wb ix p'' m n t hx hi 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[go24W,go8W.eq_1 x wb ix p m n t,go8W.eq_1 x wb ix p' m n t,go8W.eq_1 x wb ix p'' m n t,ἔ h,ἔ h,ἔ h,ἔ h];rfl | succ N ih=> have h:t< n:=А.mpr (by omega) rw[go24W,go8W.eq_1 x wb ix p m n t,go8W.eq_1 x wb ix p' m n t,go8W.eq_1 x wb ix p'' m n t,Ἄ h,Ἄ h,Ἄ h,Ἄ h];dsimp only split_ifs<;>exact ih (t+1) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ (by rw[usz t n h];omega) theorem tileW (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) (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∧Ѥ(ѩ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,hp⟩ end theorem cZ2W (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) (hW:ѧW<=4294967295) (hOW:outW*Ѥm<=ѧW) (hm:0<Ѥm) : ∀ (d j:Ὣ) (out:ѐ),outW-j=d→ colsZ2 inW outW relu X W b i ix x wd wb (bOf b) nf a hx lo (spOf 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 intro d;induction d using Nat.strong_induction_on with | _ d ih=> intro j out hd rw[colsZ2];by_cases h16:j+16<=outW . rw[Ἄ h16];dsimp only by_cases hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧Ѩwb<=4294967295∧Ѥ(ѩ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[g16W];dsimp only[g16of,g8of,fw8] rw[cols1W,Ἄ (by omega:j+8<=outW)];dsimp only;rw[Ἄ (tileW j outW m n x wb ix W (by omega) hg.1 hg.2.1 hW hOW hg.2.2.1 hg.2.2.2.1 hm)] rw[cols1W,Ἄ (by omega:j+8+8<=outW)];dsimp only;rw[Ἄ (tileW (j+8) outW m n x wb ix W (by omega) hg.1 hg.2.1 hW hOW hg.2.2.1 hg.2.2.2.2 hm)] exact ih _ (by omega) _ _ rfl . rw[ἔ hg] . rw[ἔ h16] mutual theorem cZ3W (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) (hW:ѧW<=4294967295) (hOW:outW*Ѥm<=ѧW) (hm:0<Ѥm) : ∀ (d j:Ὣ) (out:ѐ),outW-j=d→ colsZ3 inW outW relu X W b i ix x wd wb (bOf b) nf a hx lo (spOf 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 intro d;induction d using Nat.strong_induction_on with | _ d ih=> intro j out hd rw[colsZ3];by_cases h24:j+24<=outW . rw[Ἄ h24];dsimp only by_cases hg:Ѥn<=Ѩx∧Ѥn<=ѧix∧Ѩwb<=4294967295∧Ѥ(ѩ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[g24W];dsimp only[g24of,g8of,fw8] rw[cols1W,Ἄ (by omega:j+8<=outW)];dsimp only;rw[Ἄ (tileW j outW m n x wb ix W (by omega) hg.1 hg.2.1 hW hOW hg.2.2.1 hg.2.2.2.1 hm)] rw[cols1W,Ἄ (by omega:j+8+8<=outW)];dsimp only;rw[Ἄ (tileW (j+8) outW m n x wb ix W (by omega) hg.1 hg.2.1 hW hOW hg.2.2.1 hg.2.2.2.2.1 hm)] rw[cols1W,Ἄ (by omega:j+8+8+8<=outW)];dsimp only;rw[Ἄ (tileW (j+8+8) outW m n x wb ix W (by omega) hg.1 hg.2.1 hW hOW hg.2.2.1 hg.2.2.2.2.2 hm)] exact ih _ (by omega) _ _ rfl . rw[ἔ hg];exact cZ2W inW outW relu X W b i ix x wd wb nf a hx lo m n base hob hs hW hOW hm _ j out rfl . rw[ἔ h24];exact cZ2W inW outW relu X W b i ix x wd wb nf a hx lo m n base hob hs hW hOW hm _ j out rfl theorem uFd (x:ὤ) (i:ὦ) (v:ὧ) (h:Ѥi< Ѩx) (q:Ὣ):(x.uset i v h).data[q]! = if q=Ѥi then v else x.data[q]!:=by obtain ⟨ds⟩:=x;exact qFo ds _ q v h theorem uAd (a:ѐ) (i:ὦ) (v:ὥ) (h:Ѥi< ѧa) (q:Ὣ):(a.uset i v h)[q]! = if q=Ѥi then v else a[q]!:=qFo a _ q v h end theorem cpZs (X:ѐ) (o n:ὦ) (hX:Ѥo+Ѥn<=ѧX) (hs:ѧX<2^32) (a:Ὣ) (ho:Ѥo=a) (B:Ὣ->ὧ) (N0 M0:Ὣ) (d:Ὣ) : ∀ (t:ὦ) (x:ὤ) (ix:ѐ) (c:ὦ) (hx:Ѥn<=Ѩx) (hi:Ѥn<=ѧix) (hc:Ѥc<=Ѥt),Ѥt+d=Ѥn→ Ѩx=N0→ ѧix=M0 → Ѥc=(C_keep (λp=>X[a+p]!) Ѥt).length → (∀ k p:Ὣ,(C_keep (λp=>X[a+p]!) Ѥt)[k]?=some p→ (ix[k]!).toNat=p∧x.data[k]! = B p) → (∀ q,Ѥt<=q→ q< Ѥn→ x.data[q]! = B q) → Ѩ(cpZ X o n t x ix c hX hs hx hi hc).x=N0∧ѧ(cpZ X o n t x ix c hX hs hx hi hc).ix=M0∧Ѥ(cpZ X o n t x ix c hX hs hx hi hc).c=(C_keep (λp=>X[a+p]!) Ѥn).length ∧ (∀ k p:Ὣ,(C_keep (λp=>X[a+p]!) Ѥn)[k]?=some p→ ((cpZ X o n t x ix c hX hs hx hi hc).ix[k]!).toNat=p∧(cpZ X o n t x ix c hX hs hx hi hc).x.data[k]! = B p):=by induction d with | zero=> intro t x ix c hx hi hc he e1 e2 H1 H2 _ have hn:¬ t< n:=by rw[А];omega rw[cpZ,ἔ hn] have e:Ѥt=Ѥn:=by omega rw[e] at H1 H2;exact ⟨e1,e2,H1,H2⟩ | succ d ih=> intro t x ix c hx hi hc he e1 e2 H1 H2 H3 have ht:t< n:=by rw[А];omega have htn:=А.mp ht have hu:=usz t n ht have hcn:c< n:=А.mpr (by omega) have hcu:=usz c n hcn have ew:X.uget (o+t) (wi o t n X hX hs htn)=X[a+Ѥt]!:=by rw[qC3,qAf _ _ (by omega),ho] have ex:x.uget t (by omega)=B Ѥt:=by rw[qC5];exact H3 _ (Nat.le_refl _) htn have et:(t.toUInt32).toNat=Ѥt:=by simp only[USize.toNat_toUInt32];omega rw[cpZ,Ἄ ht];dsimp only;simp only[ew,ex] have hcx:Ѥc< Ѩx:=by omega have hci:Ѥc< ѧix:=by omega by_cases hz:X[a+Ѥt]! &&& В=0 . have hk:C_keep (λp=>X[a+p]!) (Ѥt+1)=C_keep (λp=>X[a+p]!) Ѥt:=qDp (λp=>X[a+p]!) Ѥt hz simp only[hz,beq_self_eq_true,ite_true] apply ih (t+1) _ _ _ _ _ _ (by rw[hu];omega) (by rw[qUs];exact e1) (by rw[Array.size_uset];exact e2) . rw[hu,hk];exact H1 . intro k p hp;rw[hu,hk] at hp have hkl:k< Ѥc:=by rw[H1];exact (List.getElem?_eq_some_iff.mp hp).1 rw[uFd,uAd,if_neg (by omega),if_neg (by omega)];exact H2 k p hp . intro q hq1 hq2;rw[uFd,if_neg (by rw[hu] at hq1;omega)];exact H3 q (by rw[hu] at hq1;omega) hq2 . have hk:C_keep (λp=>X[a+p]!) (Ѥt+1)=C_keep (λp=>X[a+p]!) Ѥt++[Ѥt]:=qD5 (λp=>X[a+p]!) Ѥt hz have hz':(X[a+Ѥt]! &&& В==0)=false:=by simpa using hz simp only[hz',Bool.false_eq_true,ite_false] apply ih (t+1) _ _ _ _ _ _ (by rw[hu];omega) (by rw[qUs];exact e1) (by rw[Array.size_uset];exact e2) . rw[hu,hk,hcu,List.length_append,H1];rfl . intro k p hp;rw[hu,hk,List.getElem?_append] at hp by_cases hkl:k< Ѥc . rw[←H1] at hp;rw[if_pos hkl] at hp rw[uFd,uAd,if_neg (by omega),if_neg (by omega)];exact H2 k p hp . rw[←H1,if_neg hkl] at hp have hk0:k=Ѥc:=by rcases Nat.lt_or_ge (k-Ѥc) 1 with h|h . omega . rw[List.getElem?_eq_none (by simp;assumption)] at hp;exact absurd hp (by simp) subst hk0;simp at hp;subst hp rw[uFd,uAd,if_pos rfl,if_pos rfl];exact ⟨et,rfl⟩ . intro q hq1 hq2;rw[uFd,if_neg (by rw[hu] at hq1;omega)];exact H3 q (by rw[hu] at hq1;omega) hq2 termination_by Ѥn-Ѥt lemma rdBd (x:ὤ) (k:ὦ) (h:Ѥk< Ѩx) (hs:Ѩx<2^32):rdB x k=x.data[Ѥk]!:=by have h1:k< x.usize:=А.mpr (by rw[FloatArray.usize,qAd _ hs];exact h) unfold rdB;rw[Ἄ h1,qC5] theorem sAs (x:ὤ) (c:ὦ) (L:љ) (g:Ὣ->ὧ) (hL:ѣL=Ѥc) (hc:Ѥc<=Ѩx) (hx:Ѩx<2^32) (H:∀ k p:Ὣ,L[k]?=some p→ x.data[k]! = g p) (d:Ὣ): ∀ (t:ὦ) (l:ὧ),Ѥt+d=Ѥc→ sA x c t l=(L.drop Ѥt).foldl (λ(a:ὧ) p=>a+(g p).abs) l:=by induction d with | zero=> intro t l he have hn:¬ t< c:=by rw[А];omega rw[sA,ἔ hn,List.drop_eq_nil_of_le (by omega)];rfl | succ d ih=> intro t l he have ht:t< c:=by rw[А];omega have htc:=А.mp ht have hlt:Ѥt< ѣL:=by omega have e1:rdB x t=g L[Ѥt]:=by rw[rdBd x t (Nat.lt_of_lt_of_le htc hc) hx];exact H _ _ (List.getElem?_eq_getElem hlt) rw[sA,Ἄ ht,e1,ih (t+1) _ (by rw[usz t c ht];omega),usz t c ht,List.drop_eq_getElem_cons (i:=Ѥt) hlt,List.foldl_cons] set_option maxRecDepth 8192 in lemma rowSpec (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (ix:ѐ) (x:ὤ) (c:ὦ) (L:љ) (l:ὧ) (h1:1*inW=ѧX) (h2:outW*inW=ѧW) (h3:outW=ѧb) (h4:0< inW) (h5:0< outW) (h6:inW<2^20) (h7:ѧX<2^32) (h8:ѧW<2^32) (h9:ѧb<2^32) (h10:1*outW<2^32) (h11:scanH 0 X≠Е) (hv:scanH 2 W≠Е) (h13:scanH 1 b≠Е) (Rw:C_Row inW X 0 ix x c L l) : cols1W inW outW relu X W b 0 ix x (ἆ 0) (wbOf inW outW W) (nfOf inW) l (scanH 2 W) (loOf (nfOf inW*(dv (scanH 2 W)*l+dv (scanH 1 b)))) ѩinW c 0 (0*outW).toUSize (ἇ (1*outW) 0)=linearSpec 1 inW outW relu X W b:=by have Hv:=qA8 2 W h8 hv have G:C_G 1 inW outW X W b:=⟨h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,(qA8 0 X h7 h11).2.2.1,Hv.2.2.1,(qA8 1 b h9 h13).2.2.1⟩ have e:linearSpec 1 inW outW relu X W b=Array.ofFn (n:=1*outW) λq =>C_sp inW outW relu X W b q.val:=rfl rw[e] have nm:inW.toUSize.toNat=inW:=qAd _ (by omega) have hb0:(0*outW).toUSize.toNat=0*outW:=qAd _ (by omega) have HdE:C_Dw (ἆ 0) W:=λh q hq=>by have e:0=ѧW:=h;omega 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[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)) exact 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 exact omS334 hq) theorem linZs (inW outW:Ὣ) (relu:Ὡ) (X W b:ѐ) (o:ὦ) (buf:ὤ) (hX:Ѥo+Ѥ(ѩinW)<=ѧX) (hs:ѧX<2^32) (hb:Ѥ(ѩinW)<=Ѩbuf) (hi:Ѥ(ѩinW)<=ѧ(ἇ inW (0:ὥ))) (h1:1*inW=ѧX) (h2:outW*inW=ѧW) (h3:outW=ѧb) (h4:0< inW) (h5:0< outW) (h6:inW<2^20) (h8:ѧW<2^32) (h9:ѧb<2^32) (h10:1*outW<2^32) (h11:scanH 0 X≠Е) (hv:scanH 2 W≠Е) (h13:scanH 1 b≠Е) (ho:Ѥo=0*inW) (hbs:Ѩbuf<2^32) (HB:∀ k,k< inW->buf.data[k]! = dv X[0*inW+k]!) : linZ inW outW relu X W b ((wbOf inW outW W,scanH 2 W),(bOf b,scanH 1 b)) (nfOf inW) o (ѩinW) buf hX hs hb hi=linearSpec 1 inW outW relu X W b:=by have nm:Ѥ(ѩinW)=inW:=qAd _ (by omega) have hiz:ѧ(ἇ inW (0:ὥ))=inW:=by simp obtain ⟨r1,r2,r3,r4⟩:=cpZs X o (ѩinW) hX hs (0*inW) ho (λp=>dv X[0*inW+p]!) Ѩbuf (ѧ(ἇ inW (0:ὥ))) (Ѥ(ѩinW)) 0 buf (ἇ inW 0) 0 hb hi (Nat.le_refl _) (by simp) rfl rfl (by simp[C_keep]) (λk p hk=>by simp[C_keep] at hk) (λq _ hq=>HB q (by omega)) unfold linZ;dsimp only generalize cpZ X o (ѩinW) 0 buf (ἇ inW 0) 0 hX hs hb hi _=Q at r1 r2 r3 r4 ⊢ rw[nm] at r3 r4;rw[hiz] at r2 obtain ⟨d1,d2,d3⟩:=qDs (λp=>X[0*inW+p]!) inW have Rw:C_Row inW X 0 Q.ix Q.x Q.c (C_keep (λp=>X[0*inW+p]!) inW) (sA Q.x Q.c 0 0):= ⟨r3,qBj _ _,by rw[r2],⟨by rw[r1];omega,by rw[r1];exact hbs⟩,d1,d2,d3,r4, by rw[sAs Q.x Q.c (C_keep (λp=>X[0*inW+p]!) inW) (λp=>dv X[0*inW+p]!) r3.symm (by rw[r3,r1];exact (qBj _ _).trans (by omega)) (by rw[r1];exact hbs) (λk p hk=>(r4 k p hk).2) (ѤQ.c) 0 0 (by simp)];rfl⟩ have hm:0<Ѥ(ѩinW):=by omega have hOW:outW*Ѥ(ѩinW)<=ѧW:=by rw[nm];omega split . rw[cZ3W inW outW relu X W b 0 Q.ix Q.x (ἆ 0) _ _ _ _ _ _ _ _ (by omega) h9 (by omega) hOW hm _ 0 _ rfl] exact rowSpec inW outW relu X W b Q.ix Q.x Q.c _ _ h1 h2 h3 h4 h5 h6 hs h8 h9 h10 h11 hv h13 Rw . rw[cZ2W inW outW relu X W b 0 Q.ix Q.x (ἆ 0) _ _ _ _ _ _ _ _ (by omega) h9 (by omega) hOW hm _ 0 _ rfl] exact rowSpec inW outW relu X W b Q.ix Q.x Q.c _ _ h1 h2 h3 h4 h5 h6 hs h8 h9 h10 h11 hv h13 Rw 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;delta fz0 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 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 split . 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,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 0 hz.1 hs hz.2.1).1,←(dVE X _ _ 0 (zFor inW) 0 Е 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']) . split . rename_i hq rw[qEr0] have nm:inW.toUSize.toNat=inW:=qAd _ (by omega) have hbz:Ѩ(zFor inW)<2^32:=(qZf inW (by omega)).2 have ok:(decD X (0*inW).toUSize ѩinW 0 (zFor inW) 0).ok=true:=by rw[←qDE X _ _ hz.1 hs 0 (zFor inW) 0 hz.2.1 hbz];exact dEok _ _ _ _ _ _ _ _ _ have sX1:0*inW+Ѥ(ѩinW)<=ѧX:=by rw[nm];omega have P0:=qZf inW (by omega) obtain ⟨v1,v2,-⟩:=qVz (a:=0*inW) (n:=ѩinW) hs sX1 inW 0 (zFor inW) 0 (by rw[C_z,Ἇ,nm]) (by rw[nm];exact P0.1) P0.2 (λk hk=>absurd hk (Ἲ _)) rfl ok have eb:(decV X (0*inW).toUSize (ѩinW) 0 (zFor inW) 0 Е 0 0 hz.1 hs hz.2.1).buf=(decD X (0*inW).toUSize (ѩinW) 0 (zFor inW) 0).buf:=by rw[(dVE X _ _ 0 (zFor inW) 0 Е 0 0 hz.1 hs hz.2.1).1,qDE X _ _ hz.1 hs 0 (zFor inW) 0 hz.2.1 hbz] exact linZs inW outW relu X W b _ _ _ _ _ _ h1 h2 h3 h4 h5 h6 (by omega) (by omega) (by omega) hS h13 h12 (qAd _ (by omega)) (by rw[eb,v1];exact hbz) (λk hk=>by rw[eb];exact v2 k (by rw[nm];exact hk)) . rfl . 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 section open Float.Model Float.Model.UnpackedFloat set_option maxRecDepth 8192 in end section open Float.Model Float.Model.UnpackedFloat end section mutual theorem 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)] theorem 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)⟩ theorem qGz (z:Model Fmt):ofW (toWord z)=z:=qEb z theorem 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] end 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];assumption . rw[t2];apply Model.roundAt_mono;simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,hV];exact hd2.le . cases S;. rw[t2];apply Model.roundAt_mono;simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,hV];exact hd2.le . rw[t1];apply Model.roundAt_mono;simp[FloatLib.Numerics.Dyadic.toReal,FloatLib.Numerics.Dyadic.signedSignificand,hV];assumption 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 mutual theorem kHvR (th:Ὠ) (s:ὧ) (V:ℝ) (hV : |R s-V| ≤ 1/2^33*(|V| + A_z)) (h:zivT th s≠Е) (MM:Model Fmt) (hf:Ἑ MM=true) (hM:Ἢ MM=Model.roundAt Fmt V):toWord MM=zivT th s:=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 hM; 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 hM; exact omS238 h1 hF hl) (by clear h hz hM; exact omS239 h2 h3 hu) hF (by rw[hb,ὢ]);rw[hR] at hV obtain ⟨W,hVW,hW⟩:∃ W:ℝ,V=(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 ⟨-V,by simp,?_⟩;rw[abs_neg,show ((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075) - -V =-(-1*((2^52+F:Ὣ):ℝ)*2^((E:Int)-1075)-V) 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 qDqW S ex fr h1 h2 h3 V W hVW a b c MM hf hM theorem 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) end 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)) set_option maxRecDepth 8192 in end section section open Float.Model Float.Model.UnpackedFloat end end 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 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))) structure RNE where (g:ё) (h:ὥ) (k:ὦ) (ok:h=scan g g.usize 0 (qAc g) Е 0) section mutual theorem qAa (x y:ℝ) : |x| ≤ |y| + |x-y|:=by have:=abs_sub_abs_le_abs_sub x y;linarith only [this] theorem 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 theorem 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) theorem 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] end section variable {z:ℝ} (hz0:0<=z) (hz:z<=1/2^200*(1/2^200)) include hz0 hz end section variable (x:ѐ) (hx:ѧx<2^32) (base nu:ὦ) include x hx base nu end 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 end section variable (n:ℕ) (hnR1:(1:ℝ)<=n) (hnR2:(n:ℝ)<=2^20) include n hnR1 hnR2 end set_option maxRecDepth 8192 in set_option maxRecDepth 8192 in set_option maxRecDepth 8192 in set_option maxRecDepth 8192 in set_option maxRecDepth 8192 in set_option maxRecDepth 8192 in 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 @[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 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 end end section end section section open Float.Model Float.Model.UnpackedFloat 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 end section end section section variable {N:Ὣ} {sp:Ὣ->Ὢ} include N sp end 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 section variable {I O:Ὣ} {X W b:ё} end end section local instance ecNe11:Nonempty D_Sc:=⟨by constructor <;> exact default⟩ 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_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 local instance ecNe12:Nonempty D_R:=⟨by constructor <;> exact default⟩ local instance ecNe13:Nonempty F1:=⟨by constructor <;> exact default⟩ structure WS where (t c r q:Nat) section open Float.Model Float.Model.UnpackedFloat end mutual theorem 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) theorem qF0 (k:Ὣ):∀ j (h:j<(ἇ k (0:ὥ)).size),(ἇ k (0:ὥ))[j].toNat<=(0:ὥ).toNat:=by intro j h;simp end 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 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))) 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 mutual theorem qCk {i e:ὦ} (h:Ѥe<=Ѥi):¬i< e :=mt А.1 (Nat.not_lt.2 h) theorem 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)⟩ theorem 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⟩ end mutual theorem 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] theorem qF5 (m p w:Ὣ):m+(w+2*p)=m+p+w+p :=(by exact omS378) end def D_t0 (g:D_C) (o:Ὣ):Ὣ:=if g.dw then o*g.k else 0 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]! def D_B (g:D_C) (y x:Ὣ):Ὣ:=y*g.s.stride*g.wp+x*g.s.stride 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 end section variable {g:D_C} (ok:D_Ok g) include g ok 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'; exact Nat.succ_pos _)).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⟩ end section open Float.Model Float.Model.UnpackedFloat set_option maxRecDepth 8192 in end section open Float.Model Float.Model.UnpackedFloat end section set_option maxRecDepth 8192 in 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)) end section section open Float.Model Float.Model.UnpackedFloat end section variable (x y z:ὥ) (hx:expOf x≠255) (hy:expOf y≠255) (hz:expOf z≠255) include x y z hx hy hz end section open Float.Model Float.Model.UnpackedFloat end section variable (relu g:Ὡ) (sw tw w:ὥ) (hg:g=true->good sw=true∧good tw=true) include relu g sw tw w hg end end section end section section variable {z:ℝ} (hz0:0<=z) (hz:z<=1/2^200*(1/2^200)) include hz0 hz end 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] 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.cols8ZD2 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,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 mutual theorem 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.cols8ZD2_eq _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ rfl,D.F16.b] 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) theorem 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.cols8ZD2_eq _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ rfl,D.F16.b] 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) end 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] end C open ExactRuntime open ExactRuntime namespace ConvFast open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats 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 [ite_eq_right (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 exact Nat.le_of_lt ‹_›) (by omega)) 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 _ _) 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 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) @[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 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 structure F4 where s0:Float s1:Float s2:Float s3:Float t0:Float t1:Float t2:Float t3:Float 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 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 _) structure Q4 where a:Word b:Word c:Word d:Word @[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) def wcpW (a:Array Word) (o d n t:USize) (buf:Array Word):Array Word := if h:t< n then wcpW a o d n (t+1) (D.wrW buf (d+t) (D.rdW a (o+t))) else buf termination_by n.toNat-t.toNat decreasing_by rw [D.usz t n h]; exact Nat.sub_lt_sub_left (USize.lt_iff_toNat_lt.mp h) (Nat.lt_succ_self _) theorem wcpW_spec (a:Array Word) (o d n:USize) (ha:a.size< 2 ^ 32) (hon:o.toNat+n.toNat< 2 ^ 32) (hdn:d.toNat+n.toNat< 2 ^ 32) : ∀ (k:Nat) (t:USize) (buf:Array Word),n.toNat-t.toNat=k → t.toNat≤ n.toNat→ buf.size< 2 ^ 32→ d.toNat+n.toNat≤ buf.size → (wcpW a o d n t buf).size=buf.size ∧ ∀ q,(wcpW a o d n t buf)[q]! = if d.toNat+t.toNat≤ q∧q< d.toNat+n.toNat then a[o.toNat+(q-d.toNat)]! else buf[q]! := by intro k induction k with | zero => intro t buf hk ht _ _ rw [wcpW,dite_eq_right (fun h=>by have:=USize.lt_iff_toNat_lt.mp h; omega)] exact ⟨rfl,fun q=>by rw [ite_eq_right (by omega)]⟩ | succ k ih => intro t buf hk ht hb hdb have h:t< n:=USize.lt_iff_toNat_lt.mpr (by omega) rw [wcpW,dite_eq_left h] have e1:(d+t).toNat=d.toNat+t.toNat:=D.qAf d t (by omega) have e2:(o+t).toNat=o.toNat+t.toNat:=D.qAf o t (by omega) have hs':=D.qBh buf (d+t) (D.rdW a (o+t)) obtain ⟨i1,i2⟩:=ih (t+1) _ (by rw [D.usz t n h]; omega) (by rw [D.usz t n h]; assumption) (by rw [hs']; exact hb) (by rw [hs']; exact hdb) refine ⟨by rw [i1,hs'],fun q => ?_⟩ rw [i2 q,D.usz t n h,D.qBu buf (d+t) _ q hb (by rw [e1]; omega),D.qAg a _ ha,e1,e2] by_cases c1:d.toNat+(t.toNat+1)≤ q∧q< d.toNat+n.toNat · rw [ite_eq_left c1,ite_eq_left (by omega)] · rw [ite_eq_right c1] by_cases c2:q=d.toNat+t.toNat · rw [ite_eq_left c2,ite_eq_left (by omega),c2]; congr 1; omega · rw [ite_eq_right c2] by_cases c3:d.toNat+t.toNat≤ q∧q< d.toNat+n.toNat · exfalso; omega · rw [ite_eq_right c3] @[specialize] def recW (H:Nat) (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 recW H step (t+1) n st' (wcpW st'.1 0 (t*H).toUSize H.toUSize 0 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) @[inline] def recRun (T H:Nat) (step:Nat→ Array Word × Array Word→ Array Word × Array Word) (iniS:Array Word × Array Word):Array Word := if T*H≤ 4294967295 then recW H step 0 T iniS (Array.replicate (T*H) 0) else recFlat step 0 T iniS (Array.emptyWithCapacity (T*H)) @[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) @[noinline] def cellZ (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 cellF (f i c g:Word):Word := if good f && good i && good c && good g then let a:=(dv f*dv c+dv i*dv g).toBits let w:=D.zivW (a+0x200000) (a-0x200000) if w == 0xFFFFFFFF then cellZ 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)) @[noinline] def mulZ (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 @[inline] def mulF (o t:Word):Word := if good o && good t && small o && small t then let a:=(dv o*dv t).toBits let w:=D.zivW (a+0x200000) (a-0x200000) if w == 0xFFFFFFFF then mulZ o t else w else mulSlow o 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) @[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) @[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 end RnnK section RnnP mutual 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; exact Nat.le_of_lt ‹_›),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] end mutual 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 exact Nat.le_succ_of_le h),fa_push_get,ite_eq_left h] · rw [fpush] by_cases hj:j=a.size · subst hj rw [ih1 (by exact Nat.le_refl _),fa_push_get,ite_eq_right (by omega),ite_eq_left rfl]; simp · rw [ih2 (by omega) (by omega)]; congr 1; omega 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 exact Nat.lt_of_lt_of_le hs h1)] exact h unfold fget rw [dite_eq_left hu] obtain ⟨ds⟩:=a show ds[i.toNat]=ds[i.toNat]! rw [getElem!_pos ds i.toNat h] end mutual 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 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 good_zero:good 0=true:=by decide theorem good_one:good oneW=true:=by decide end mutual 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] end mutual 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 end mutual 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 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 exact Nat.lt_of_lt_of_le hs h1)] exact h unfold fget rw [dite_eq_left 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 end mutual 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,dite_eq_right (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,dite_eq_left 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 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 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 assumption) 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 end 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) mutual 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 end mutual 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]; assumption) simp only [Array.size_ofFn] rw [d1,d2,getElem!_pos _ _ (by rw [hs]; omega)] theorem recW_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.size=(t+n)*H→ (t+n)*H< 2 ^ 32 → (∀ q,q< t*H→ out[q]! = (traj step iniS (q / H+1)).1[q % H]!) → recW H 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,hs,_,ho=>by rw [recW] apply Array.ext · rw [hs,Array.size_ofFn,Nat.add_zero] · intro q h1 h2 rw [Array.getElem_ofFn, ← getElem!_pos out q h1] exact ho q (by rw [hs,Nat.add_zero] at h1; exact h1) | n+1,t,out,hs,hl,ho=>by rw [recW] try dsimp only rw [show step t (traj step iniS t)=traj step iniS (t+1) from rfl] have hb:(t+1)*H≤ (t+(n+1))*H:=Nat.mul_le_mul_right _ (by omega) rw [Nat.add_mul,Nat.one_mul] at hb have hsH:(traj step iniS (t+1)).1.size=H:=hsz _ _ have u0:(0:USize).toNat=0:=rfl have uH:H.toUSize.toNat=H:=qAd H (by omega) have uT:(t*H).toUSize.toNat=t*H:=qAd _ (by omega) obtain ⟨s1,g1⟩:=wcpW_spec (traj step iniS (t+1)).1 0 (t*H).toUSize H.toUSize (by omega) (by rw [u0,uH]; omega) (by rw [uT,uH]; exact Nat.lt_of_le_of_lt hb hl) _ 0 out rfl (by rw [u0]; exact Nat.zero_le _) (by exact hs ▸ hl) (by rw [hs,uT,uH]; assumption) have e3:t+1+n=t+(n+1):=by omega rw [recW_traj step iniS H hsz n (t+1) _ (by rw [s1,hs,e3]) (by rw [e3]; exact hl) ?_,e3] intro q hq rw [g1 q,u0,uT,uH] simp only [Nat.add_zero,Nat.zero_add] by_cases c:t*H≤ q∧q< t*H+H · rw [ite_eq_left c] obtain ⟨d1,d2⟩:=divH q t H c.1 (by rw [Nat.add_mul,Nat.one_mul]; exact c.2) rw [d1,d2] · rw [ite_eq_right c] exact ho q (by rw [Nat.add_mul,Nat.one_mul] at hq; omega) end 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] theorem recRun_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) : recRun T H step iniS=recurWith T H step iniS:=by rw [← recFlat_eq T H step iniS hsz] unfold recRun split_ifs with hl · have e1:=recW_traj step iniS H hsz T 0 (Array.replicate (T*H) 0) (by simp) (by rw [Nat.zero_add]; exact Nat.lt_succ_of_le hl) (fun q hq=>by simp at hq) have e2:=recFlat_traj step iniS H hsz T 0 (Array.emptyWithCapacity (T*H)) (by simp) rw [show traj step iniS 0=iniS from rfl] at e1 e2 rw [e1,e2] · rfl end RnnP section RnnS mutual 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 cellZ_eq (f i c g:Word) : cellZ 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 cellZ 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 zivT0_ne_zero (s:Float) (h:D.zivT 0 s≠ 0xFFFFFFFF):D.zivT 0 s≠ 0:=by obtain ⟨-, S,ex,fr,M,h1,h2,h3,hz, -⟩:=D.kFh 0 s h rw [hz] intro e have:=congrArg UInt32.toNat e rw [UInt32.toNat_ofNat'] at this simp only [UInt32.toNat_zero] at this split at this <;> omega end mutual 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 simp only [] split_ifs with hg hw · exact cellZ_eq f i c g · rw [beq_iff_eq] at hw simp only [Bool.and_eq_true] at hg obtain ⟨⟨⟨h1,h2⟩,h3⟩,h4⟩:=hg have ez:D.zivW ((dv f*dv c+dv i*dv g).toBits+0x200000) ((dv f*dv c+dv i*dv g).toBits-0x200000)=D.zivT 0 (dv f*dv c+dv i*dv g):=by unfold D.zivT; rw [ite_eq_left (by rw [UInt64.le_iff_toNat_le]; simp)] rw [ez] at hw ⊢ obtain ⟨fx,rx⟩:=C.qHw f c h1 h3 obtain ⟨fy,ry⟩:=C.qHw i g h2 h4 have bd : ∀ a b:Word,good a=true→ good b=true → |wv a*wv b| ≤ D.A_B:=fun a b ha hb=>by rw [abs_mul] exact (mul_le_mul (D.qAo a ha) (D.qAo b hb) (abs_nonneg _) (by positivity)).trans ((by norm_num:(2:ℝ) ^ 128*2 ^ 128≤ 2 ^ 256*2 ^ 42).trans D.qCc) obtain ⟨-, hb⟩:=D.qBf _ _ fx fy (by rw [rx]; exact bd f c h1 h3) (by rw [ry]; exact bd i g h2 h4) rw [rx,ry] at hb set V:=wv f*wv c+wv i*wv g with hVd have hV : |D.R (dv f*dv c+dv i*dv g)-V| ≤ 1 / 2 ^ 33*(|V| + D.A_z) := hb.trans (mul_le_mul_of_nonneg_right (by norm_num) (add_nonneg (abs_nonneg _) D.qAr.le)) let fa:Nat→ Word:=fun j=>if j=0 then f else i let fb:Nat→ Word:=fun j=>if j=0 then c else g have hsum:((∑ j ∈ Finset.range 2,rationalWord (fa j)*rationalWord (fb j):ℚ):ℝ)=V:=by simp only [Finset.sum_range_succ,Finset.sum_range_zero,fa,fb,ite_eq_left,zero_add,Rat.cast_add, Rat.cast_mul,show (1:Nat)≠ 0 by decide,ite_false] rw [hVd,qAx _ (qAe _ h1),qAx _ (qAe _ h2),qAx _ (qAe _ h3),qAx _ (qAe _ h4)] have hne:(∑ j ∈ Finset.range 2,rationalWord (fa j)*rationalWord (fb j))≠ 0:=by intro h0 have V0:V=0:=by rw [← hsum,h0,Rat.cast_zero] have hf0:Model.isFinite (ofW 0)=true:=fin_ofW (qAe _ good_zero) have hM0:Model.toReal (ofW 0)=Model.roundAt Fmt V:=by have:=qAx 0 (qAe _ good_zero) rw [wv] at this; rw [this,rat_zero,Rat.cast_zero,V0,Model.roundAt_zero] have k:=D.kHvR 0 _ V hV hw (ofW 0) hf0 hM0 exact zivT0_ne_zero _ hw (by rw [← k]; rfl) obtain ⟨d,hd,hD⟩:=qEcP 2 fa fb (fun j hj=>by rcases (by omega:j=0 ∨ j=1) with rfl | rfl · exact ⟨qAe _ h1,qAe _ h3⟩ · exact ⟨qAe _ h2,qAe _ h4⟩) hne rw [hD] exact D.kHv 0 _ d (by rw [hd,hsum]; exact hV) hw · rfl theorem mulZ_eq (o t:Word):mulZ o t=toWord (Model.mul (ofW o) (ofW t)):=by unfold mulZ 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 end mutual 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 · exact mulZ_eq o t · rw [beq_iff_eq] at hw simp only [Bool.and_eq_true] at hg obtain ⟨⟨⟨h1,h2⟩,h3⟩,h4⟩:=hg have ez:D.zivW ((dv o*dv t).toBits+0x200000) ((dv o*dv t).toBits-0x200000) = D.zivT 0 (dv o*dv t):=by unfold D.zivT; rw [ite_eq_left (by rw [UInt64.le_iff_toNat_le]; simp)] rw [ez] at hw ⊢ have hfo:=fin_ofW (qAe _ h1) have hft:=fin_ofW (qAe _ h2) have hbound : |Model.toReal (ofW o)| * |Model.toReal (ofW t)| ≤ Model.toReal (Model.posMaxFinite Fmt):=by have a:=small_le o h1 h3 have b:=small_le t h2 h4 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 obtain ⟨-, hr⟩:=C.qHw o t h1 h2 refine (D.kHvR 0 _ _ ?_ hw _ hf hM).symm rw [hr] simp only [wv,sub_self,abs_zero] exact mul_nonneg (by norm_num) (add_nonneg (abs_nonneg _) D.qAr.le) · 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 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 end 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))) end RnnS section RnnT mutual 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 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,ite_eq_left (by rw [fpush_size]; exact Nat.lt_of_lt_of_le hj (Nat.le_add_right _ _)),(fpush_get _ _ _ _ j).1 hj]) (fun u acc j hj=>by rw [fa_push_get] by_cases a:j< inW · rw [ite_eq_left (by rw [fpush_size]; omega),(fpush_get _ _ _ _ _).2 (by exact Nat.le_add_right _ _) (by omega),ite_eq_left a] congr 2; omega · rw [ite_eq_right (by rw [fpush_size]; omega),ite_eq_left (by rw [fpush_size]; omega),ite_eq_right 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 exact Nat.le_of_lt_succ h6)) (by omega) have b:H*H≤ 1023*1023:=Nat.mul_le_mul (show H≤ 1023 by exact Nat.le_of_lt_succ h6) (show H≤ 1023 by exact Nat.le_of_lt_succ h6) have c:H*(inW+1)≤ 1023*2 ^ 20:=Nat.mul_le_mul (show H≤ 1023 by exact Nat.le_of_lt_succ h6) (by omega) omega end end RnnT section ActF open FastAct in 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 exact hT.trans (by norm_num))] nlinarith only [hT,h1,v1,bl] · rw [int_scale] have:realSigmoid (-C)=T / (1+T):=realSigmoid_neg_eq C rw [this,div_le_iff₀ (by exact hT.trans (by norm_num))] nlinarith only [hT,h2,bh] · simp at h · simp at h @[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 mutual 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 end ActF section ActG 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)) def toF62 (lo:Nat):Float := let sh:=lo.log2-52 (lo >>> sh).toUInt64.toFloat*D.pwEntry (88+sh) def expTabG:FloatArray:=⟨Array.ofFn (n:=1280) fun k=>toF62 (enclK k.val).1⟩ 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 def m34G:Float:=D.pwEntry 116 def m41G:Float:=D.pwEntry 109 def m26G:Float:=D.pwEntry 124 def negOneG:Float:=0-oneG @[inline] def polyG (r:Float):Float := (oneG-r)+r*r*((halfG-r*c6G)+r*r*(c24G-r*c120G)) theorem tabG_size:expTabG.size=1280:=by simp [expTabG,FloatArray.size] mutual 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; exact Nat.lt_of_lt_of_le this hb 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 *; exact Nat.lt_of_lt_of_le h hb theorem eidx (a:UInt32):(a >>> 23).toUSize.toNat< D.pw.size:=D.qCh a end @[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 @[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 @[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) @[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 @[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 section GTool def gAp (x:Float) (X ε:ℝ):Prop:=x.isFinite=true ∧ |D.R x-X| ≤ ε mutual 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 only [h,this,h.2] end mutual 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 only [hX,hM,this,gAB] theorem gApFin {R r V B Dv:ℝ} (e : |R-r| ≤ 1 / 2 ^ 53*(|r| + D.A_z)) (ha : |r| ≤ B) (hb : |r-V| ≤ Dv) : |R-V| ≤ Dv+1 / 2 ^ 53*B+1 / 2 ^ 153:=by have hz:=gAz have hc:=abs_sub_le R r V have:1 / 2 ^ 53*(|r| + D.A_z)≤ 1 / 2 ^ 53*B+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 only [hz,ha]) (by norm_num) linarith only [e,this,hb,hc] end mutual 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 ha : |D.R x+D.R y| ≤ M+N+ε+δ:=(abs_add_le _ _).trans (by linarith only [hX,hY,h1,h2]) 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 only [hx,hy,this,hx.2,hy.2] exact gApFin e ha hb 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 ha : |D.R x-D.R y| ≤ M+N+ε+δ:=(abs_sub _ _).trans (by linarith only [hX,hY,h1,h2]) 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 only [hx,hy,this,hx.2,hy.2] exact gApFin e ha hb 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 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 only [hX,h1]) (by linarith only [hY,h2]) (abs_nonneg _) (by linarith only [hX,e0,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 only [hX,h1]) hy.2 (abs_nonneg _) (by linarith only [hX,e0,abs_nonneg X])) (mul_le_mul hY hx.2 (abs_nonneg _) (by exact (abs_nonneg Y).trans hY)) exact gApFin e ha hb 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 only [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 end GTool section GTool2 mutual 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 exact sub_pos.mpr hδ have hm0:0< m:=by exact d0.trans_lt hδ have hY0:0< Y:=by linarith only [hm,hδ,d0] have hRy:m-δ≤ D.R y:=by have:=abs_le.mp hy.2; linarith only [hm,this] have hRy0:0< D.R y:=by linarith only [hδ,hRy] have hqa : |D.R x / D.R y| ≤ (M+ε) / (m-δ):=by rw [abs_div,abs_of_pos hRy0] exact div_le_div₀ (by linarith only [hX,e0,abs_nonneg X]) (by linarith only [hX,h1]) hmd hRy obtain ⟨f,e⟩:=gDiv x y hx.1 hy.1 hRy0.ne' (hqa.trans (hq.trans gAB)) refine ⟨f, ?_⟩ 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 exact (abs_nonneg X).trans hX)) 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 only [this] 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) assumption rw [add_mul]; linarith only [hn,hA,hB] exact gApFin e hqa hb 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]⟩ 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 exact add_le_add_right hz _) (by norm_num) linarith only [e,hz] end mutual 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 end GTool2 section GPoly mutual 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 end 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 hρρ0:0≤ ρ*ρ:=mul_nonneg h0 h0 have hρρ1:ρ*ρ≤ 1 / 4096:=by have:=mul_le_mul h1 h1 h0 (by norm_num); exact this.trans (by norm_num) have hρρ : |ρ*ρ| ≤ 1 / 4096:=by rw [abs_of_nonneg hρρ0]; exact hρρ1 have a1:=(gAp_sub gOne hr (by norm_num : |(1:ℝ)| ≤ 1) hρ (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 52 by norm_num) have s2:=(gAp_mul hr hr hρ hρ (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 64 by norm_num) have b1:=(gAp_mul hr gC6 hρ (by norm_num : |(1:ℝ)/6| ≤ 1/6) (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 60 by norm_num) have hb1 : |ρ*(1 / 6)| ≤ 1 / 384:=by rw [abs_mul,abs_of_nonneg h0]; norm_num; linarith only [h1] have b2:=(gAp_sub gHalf b1 (by norm_num : |(1:ℝ)/2| ≤ 1/2) hb1 (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 52 by norm_num) have hb2 : |1 / 2-ρ*(1 / 6)| ≤ 1 / 2:=by rw [abs_le]; constructor <;> linarith only [h1,h0] have c1:=(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 hc1 : |ρ*(1 / 120)| ≤ 1 / 7680:=by rw [abs_mul,abs_of_nonneg h0]; norm_num; linarith only [h1] have c2:=(gAp_sub gC24 c1 (by norm_num : |(1:ℝ)/24| ≤ 1/24) hc1 (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 55 by norm_num) have hc2 : |1 / 24-ρ*(1 / 120)| ≤ 1 / 24:=by rw [abs_le]; constructor <;> linarith only [h1,h0] have c3:=(gAp_mul s2 c2 hρρ hc2 (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 66 by norm_num) have hc3 : |ρ*ρ*(1 / 24-ρ*(1 / 120))| ≤ 1 / 2 ^ 16:=by rw [abs_mul] have:=mul_le_mul hρρ hc2 (abs_nonneg _) (by norm_num) exact this.trans (by norm_num) have b3:=(gAp_add b2 c3 hb2 hc3 (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 51 by norm_num) have hb3 : |1 / 2-ρ*(1 / 6)+ρ*ρ*(1 / 24-ρ*(1 / 120))| ≤ 1:=by have:=abs_add_le (1 / 2-ρ*(1 / 6)) (ρ*ρ*(1 / 24-ρ*(1 / 120))) linarith only [hb2,hc3,this] have d:=(gAp_mul s2 b3 hρρ hb3 (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 62 by norm_num) have hd : |ρ*ρ*(1 / 2-ρ*(1 / 6)+ρ*ρ*(1 / 24-ρ*(1 / 120)))| ≤ 1 / 4096:=by rw [abs_mul] have:=mul_le_mul hρρ hb3 (abs_nonneg _) (by norm_num) exact this.trans (by norm_num) have ha1 : |1-ρ| ≤ 1:=by rw [abs_le]; constructor <;> linarith only [h1,h0] have e:=(gAp_add a1 d ha1 hd (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 51 by norm_num) refine ⟨e.1, ?_⟩ have hT:=exp_neg_taylor5 h0 (by exact h1.trans (by norm_num)) have h6:ρ ^ 6≤ (1 / 64) ^ 6:=pow_le_pow_left₀ h0 h1 6 have hpoly:1-ρ+ρ*ρ*(1 / 2-ρ*(1 / 6)+ρ*ρ*(1 / 24-ρ*(1 / 120))) = 1-ρ*(1-ρ*(1 / 2-ρ*(1 / 6-ρ*(1 / 24-ρ*(1 / 120))))):=by ring 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)+r*r*((halfG-r*c6G)+r*r*(c24G-r*c120G))):=rfl have:=e.2 rw [← e2,hpoly] at this have h7:=mul_le_mul_of_nonneg_right h6 (by norm_num:(0:ℝ)≤ 7 / 4320) have h8:(1 / 2 ^ 51:ℝ)+(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 exact Nat.lt_of_lt_of_le h1 (by decide)) refine ⟨f, ?_⟩ rw [e,ite_eq_right (by omega),ite_eq_right (by exact Nat.not_le_of_gt h1),Nat.mod_eq_of_lt h1,one_mul] mutual 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 assumption) (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 only [h1,h2] theorem Encl_congr {iv:Nat × Nat} {a b:ℝ} (h:FastAct.Encl iv a) (e:a=b):FastAct.Encl iv b := e ▸ h end mutual 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 exact Nat.lt_succ_of_le hn)).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] end 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 only [e1,e2,this] 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 positivity)] have:FastAct.V lo / 2 ^ 52≤ 1 / 2 ^ 52:=div_le_div_of_nonneg_right hVlo (by positivity) linarith only [r2,e2,hVlo,hw1] · 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 only [r1,r2,e2,hw2] 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; assumption 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)] 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 exact Nat.lt_of_lt_of_le hm2 (by decide))) 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]; exact Nat.lt_of_lt_of_le hmod (by decide)) 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 exact Nat.lt_of_le_of_lt hF2 (by decide)) obtain ⟨fr,er⟩:=D.qCm _ f (by exact Nat.lt_of_le_of_lt hF2 (by decide)) fq ((M % 2 ^ s:Nat):ℤ) 0 (by exact Nat.lt_of_lt_of_le hmod (by decide)) (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 assumption)] 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 exact Nat.lt_of_lt_of_le hm2 (by decide)) have hm0:M % 2 ^ s=M:=Nat.mod_eq_of_lt (by rw [hse]; exact Nat.lt_of_lt_of_le hm2 (by decide)) 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 mutual 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 end 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 only [r0] have r1':C< ((kk:ℝ)+1)*(1 / 64):=by rw [hρ] at r1; linarith only [r1] 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 _; norm_num) have hE0:0< E:=Real.exp_pos _ have hp1:Real.exp (-ρ)≤ 1:=Real.exp_le_one_iff.mpr (by exact neg_nonpos.mpr r0) have hp0:0< Real.exp (-ρ):=Real.exp_pos _ have hp63:63 / 64≤ Real.exp (-ρ):=by linarith only [r1,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'⟩ have hC17:C< 17:=by have:(kk:ℝ)+1≤ 1088:=by exact_mod_cast h1088 linarith only [r1,hρ,this] have hEC:1 / 2 ^ 25≤ Real.exp (-C):=exp17.trans (Real.exp_le_exp.mpr (by linarith only [hC17])) 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 only [hp0,hp63,hPab] 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 exact sub_nonneg.mpr hT1)] exact mul_le_mul hrel (by linarith only [hPab]) 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 only [this] 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 only [hE0,hEQ] 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 only [hE0,hEC,hEQ] 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 exact add_le_add hTPa hz) (by norm_num) rw [tOfG_def] linarith only [h,hk,hE0,hEC,eR,hTP,hEQ,hTPa,hz,hc] end GCore section GFin 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 norm_num 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 exact add_le_add a1 hz0) (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 exact add_le_add a2 hz0) (by norm_num)) c0 exact D.qDq q e V (by linarith only [hm,hz0,hqv,a2,b2]) (by linarith only [hm,hz0,hqv,a1,b1]) hz M hf hM def gApR (x:Float) (X a:ℝ):Prop:=x.isFinite=true ∧ |D.R x-X| ≤ a*X mutual 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 only [hb] have hRy:(1-b)*Y≤ D.R y:=by have:=abs_le.mp hy.2; rw [sub_mul,one_mul]; linarith only [this] 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 only [hx,this,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 only [p1,p2] 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 only [hRy] exact hn.trans this 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 only [hd,this] have hfac:(a+b) / (1-b)≤ 2:=by rw [div_le_iff₀ hb1]; linarith only [hb,hab] 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 only [hB,this] linarith only [this,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 only [hz,hXY,hQ0,hqa]) (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 only [hz,hXY,hQ0,hqa] linarith only [hz,hXY,hQ0,hd,hqa,e,hc] 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 exact Nat.le_add_right _ _,by omega, ?_⟩ rw [D.qA7 w hg] unfold D.A_mag rw [ite_eq_right (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 [ite_eq_left hneg,ite_eq_right (hs.not.mpr (not_not.mpr hneg))] · rw [ite_eq_right hneg,ite_eq_left (hs.mpr hneg)] end end GFin section GSig mutual 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 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⟩ end mutual theorem finZ41 {q:Float} {V:ℝ} (hq:gAp q V (1 / 2 ^ 42)) (hV : |V| ≤ 1) (hz:D.ziv q m41G≠ 0xFFFFFFFF) {M:Model Fmt} (hf:M.isFinite=true) (hM:M.toReal=Model.roundAt Fmt V):toWord M=D.ziv q m41G:=by obtain ⟨f41,r41⟩:=gM41 have hqa:=hq.absR refine gZiv hq f41 (by linarith only [hV,hqa]) (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 q| + 1 / 2 ^ 41)≤ 1 / 2 ^ 53*(1+1 / 2 ^ 42+1 / 2 ^ 41):=by gcongr; linarith only [hV,hqa] have:(1:ℝ) / 2 ^ 42+1 / 2 ^ 53*(1+1 / 2 ^ 42+1 / 2 ^ 41)+1 / 2 ^ 150< 1 / 2 ^ 41:=by norm_num linarith only [hV,hqa] theorem finZ34 {q:Float} {V r:ℝ} (hq:gApR q V r) (hr:r≤ (4 / 5) / 2 ^ 35) (hV26:1 / 2 ^ 26≤ V) (hV1:V≤ 1) (hz:D.ziv q (q*m34G)≠ 0xFFFFFFFF) {M:Model Fmt} (hf:M.isFinite=true) (hM:M.toReal=Model.roundAt Fmt V) : toWord M=D.ziv q (q*m34G):=by have hV0:0< V:=lt_of_lt_of_le (by norm_num) hV26 have k7:r*V≤ (4 / 5) / 2 ^ 35*V:=mul_le_mul_of_nonneg_right hr hV0.le have hqA:gAp q V (r*V):=hq have hz0:=gAz have hqv:=abs_le.mp hq.2 have hRq0:0< D.R q:=by linarith only [hV0,k7,hqv] 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 only [hV1,k7])) (by rw [r34]; norm_num; linarith only [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 only [hV26,hV0,k7,hz0,hqv,he] refine gZiv hqA fe (by rw [abs_of_pos hRq0]; linarith only [hV1,k7,hqv]) (by rw [abs_of_pos hRe0]; linarith only [hV1,k7,hz0,hqv,he]) ?_ 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 only [hV26,k7,hz0,hqv,he,hRe0] 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⟩ end mutual 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 exact neg_nonpos.mpr hC0) 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 only [hT0]) (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 42 by norm_num) have hV : |(1:ℝ) / (1+T)| ≤ 1:=by rw [abs_of_pos (by positivity),div_le_one (by exact hT0.trans (by norm_num))]; linarith only [hT0] exact finZ41 hq hV hz hf hM 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 exact neg_nonpos.mpr hC0) have hC17:C< 17:=by have:((kOfG m F).toNat:ℝ)+1≤ 1088:=by exact_mod_cast h1088 linarith only [hCk,this] have hT25:1 / 2 ^ 25≤ T:=exp17.trans (Real.exp_le_exp.mpr (by linarith only [hC17])) 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; exact this.trans (by norm_num) have hρT0:0≤ ρ*T:=mul_nonneg hρ0 hT0.le have htR:gApR t T ρ:=⟨ht.1,hrel'⟩ have hRt:=abs_le.mp hrel' obtain ⟨fd,ed⟩:=D.qBf oneG t gOneR.1 ht.1 (by rw [gOneR.2]; norm_num; linarith only [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 only [hT0,hρT,hRt,hT1] 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 exact add_le_add h1 hz0) (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 only [hρdef]) (by norm_num) linarith only [hρdef] 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 only [hρdef,hz0,hT0,hρT,ed,h1,h2,h3,this] have hb0:0≤ b:=by rw [hbdef]; positivity have hb1:b≤ 1 / 2:=by rw [hbdef]; linarith only [hρdef] have hq:=gApR_div htR hdR hT0 (by exact hT0.trans (by norm_num)) hρ0 hb0 hb1 (by rw [le_div_iff₀ (by exact hT0.trans (by norm_num))]; linarith only [hT0,hT25]) (by rw [div_le_iff₀ (by exact hT0.trans (by norm_num))]; linarith only [hT0]) (by exact hρdef.trans_le (by norm_num)) 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 have hV1:T / (1+T)≤ 1:=by rw [div_le_one (by exact hT0.trans (by norm_num))]; norm_num have hV26:1 / 2 ^ 26≤ T / (1+T):=by rw [le_div_iff₀ (by exact hT0.trans (by norm_num))]; linarith only [hT0,hT25] exact finZ34 hq hr hV26 hV1 hz hf hM 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 only [hC]) 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 exact hT0.trans (by norm_num))]; linarith only [hT0])] rw [show (1:ℝ)-1 / (1+Real.exp (-C))=Real.exp (-C) / (1+Real.exp (-C)) by field_simp; ring] rw [div_le_iff₀ (by exact hT0.trans (by norm_num))]; linarith only [hT0,hT] 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 end GSig section GTanh mutual 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 exact neg_nonpos.mpr hC0) 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 only [hT1,hT0]) (by linarith only [hT0]) (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 have hV : |Real.tanh C| ≤ 1:=abs_le.mpr ⟨(Real.neg_one_lt_tanh C).le,(Real.tanh_lt_one C).le⟩ exact finZ41 hq hV hz hf hM 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 exact neg_nonpos.mpr hC0) 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 only [hT0,hT1]) (by linarith only [hT0]) (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 have hV1 : |Real.tanh (-C)| ≤ 1:=abs_le.mpr ⟨(Real.neg_one_lt_tanh _).le,(Real.tanh_lt_one _).le⟩ exact finZ41 hq hV1 hz hf hM 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 only [hC]) rw [tanh_eq_exp_neg_two,show -2*C = -(2*C) by ring,le_div_iff₀ (by exact hT0.trans (by norm_num))] linarith only [hT0,hT] 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)) end mutual 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 only [t1,t2]⟩ 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 only [t1,this,t2] 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 only [t1,t2,hqa,hV1]) (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 only [t1,t2,hqa,hV1] have:(1:ℝ) / 2 ^ 27+1 / 2 ^ 52+1 / 2 ^ 53*(2+1 / 2 ^ 26)+1 / 2 ^ 150< 1 / 2 ^ 26:=by norm_num linarith only [t1,t2,hqa,hV1] end end GTanh section GMain mutual 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 end 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 exact Nat.le_trans hF2 (by decide)) obtain ⟨hf,hM⟩:=sigModel w he rw [hx] at hM split · rename_i hs rw [ite_eq_left hs,one_mul] at hM split · rename_i hk intro hz exact (sigPos hok _ _ hm2 hF1 (by exact Nat.le_trans hF2 (by decide)) _ _ hf hM hz).symm · rename_i hk intro hz refine (sigSat ?_ hf hM hz).symm obtain ⟨-, hlo, -⟩:=split_spec _ _ hm2 hF1 (by exact Nat.le_trans hF2 (by decide)) (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 only [hlo,this] · rename_i hs rw [ite_eq_right hs,neg_one_mul] at hM split · rename_i hk intro hz exact (sigNeg hok _ _ hm2 hF1 (by exact Nat.le_trans hF2 (by decide)) _ _ (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 exact Nat.lt_of_lt_of_le (by decide) h1) (by exact Nat.le_of_lt_succ h2) obtain ⟨hf,hM⟩:=sigModel w he rw [hx,ite_eq_left 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 only [hp,this] · intro hz; exact absurd rfl hz end GMain section GMain2 mutual 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 only [h3,h4] end mutual 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 [ite_eq_left hs,one_mul] at hM intro hz refine (tanhPos hok _ _ hm2 ?_ ?_ _ _ hC hf hM hz).symm <;> omega · rename_i hs rw [ite_eq_right 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 only [hlo,h1280] split · rename_i hs rw [ite_eq_left hs,one_mul] at hM intro hz exact (tanhSatPos hC10 hf hM hz).symm · rename_i hs rw [ite_eq_right 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 [ite_eq_left hs,one_mul] at hM intro hz exact (tanhSatPos hC10 hf hM hz).symm · rename_i hs rw [ite_eq_right 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 end 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 end GMain2 section ActH def selA:FloatArray:=⟨#[0,oneG]⟩ def selB:FloatArray:=⟨#[oneG,0]⟩ def sgnT:FloatArray:=⟨#[oneG,negOneG]⟩ @[inline] def zivT0 (s:Float):UInt32 := let a:=s.toBits D.zivW (a+0x200000) (a-0x200000) theorem zivT0_eq (s:Float):zivT0 s=D.zivT 0 s:=by unfold zivT0 D.zivT rw [ite_eq_left (by rw [UInt64.le_iff_toNat_le]; simp)] @[inline] def sigH (w:UInt32):UInt32 := let a:=w &&& 0x7FFFFFFF let F:=a >>> 23 let m:=(a &&& 0x7FFFFF) ||| 0x800000 if F-1< 131 then if h:kOfG m F< 1088 then let t:=tOfG m F (eidx a) (kLt h (by decide)) let s:=(w >>> 31).toNat let q:=(selA.get! s*t+selB.get! s) / (oneG+t) let r:=zivT0 q if r == 0xFFFFFFFF then D.ziv q (q*m34G) else r else 0xFFFFFFFF else 0xFFFFFFFF @[inline] def tanhH (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:=sgnT.get! (w >>> 31).toNat*(oneG-t) / (oneG+t) let r:=if 0x3B800000≤ a then zivT0 q else 0xFFFFFFFF if r == 0xFFFFFFFF then D.ziv q m41G else r else 0xFFFFFFFF else 0xFFFFFFFF def sigmoidF3 (w:UInt32):UInt32 := let v:=if tabOK then sigH w else 0xFFFFFFFF if v == 0xFFFFFFFF then sigmoidF2 w else v def tanhF3 (w:UInt32):UInt32 := let v:=if tabOK then tanhH w else 0xFFFFFFFF if v == 0xFFFFFFFF then tanhF2 w else v mutual theorem sgnBit0 {w:UInt32} (h:w< 0x80000000):(w >>> 31).toNat=0:=by rw [UInt32.lt_iff_toNat_lt] at h rw [UInt32.toNat_shiftRight]; simp only [UInt32.reduceToNat,Nat.reduceMod] at h ⊢ rw [Nat.shiftRight_eq_div_pow]; omega theorem sgnBit1 {w:UInt32} (h : ¬ w< 0x80000000):(w >>> 31).toNat=1:=by rw [UInt32.lt_iff_toNat_lt] at h have:=w.toNat_lt rw [UInt32.toNat_shiftRight]; simp only [UInt32.reduceToNat,Nat.reduceMod] at h this ⊢ rw [Nat.shiftRight_eq_div_pow]; omega theorem selA0:selA.get! 0=0:=rfl theorem selA1:selA.get! 1=oneG:=rfl theorem selB0:selB.get! 0=oneG:=rfl theorem selB1:selB.get! 1=0:=rfl theorem sgnT0:sgnT.get! 0=oneG:=rfl theorem sgnT1:sgnT.get! 1=negOneG:=rfl end theorem finT {q:Float} {V ε:ℝ} (hq:gAp q V ε) (hε:ε≤ 1 / 2 ^ 33 * |V|) (hz:zivT0 q≠ 0xFFFFFFFF) {M:Model Fmt} (hf:M.isFinite=true) (hM:M.toReal=Model.roundAt Fmt V):toWord M=zivT0 q:=by rw [zivT0_eq] at hz ⊢ refine D.kHvR 0 q V ?_ hz M hf hM have hz0:(0:ℝ)≤ D.A_z:=le_of_lt (by unfold D.A_z; positivity) have:=hq.2 have:1 / 2 ^ 33 * |V| ≤ 1 / 2 ^ 33*(|V| + D.A_z):=by apply mul_le_mul_of_nonneg_left _ (by norm_num); linarith only [hz0] linarith theorem finTZ {q:Float} {V r:ℝ} (hq:gApR q V r) (hr:r≤ (4 / 5) / 2 ^ 35) (hV26:1 / 2 ^ 26≤ V) (hV1:V≤ 1) (hz:(if zivT0 q == 0xFFFFFFFF then D.ziv q (q*m34G) else zivT0 q)≠ 0xFFFFFFFF) {M:Model Fmt} (hf:M.isFinite=true) (hM:M.toReal=Model.roundAt Fmt V) : toWord M=(if zivT0 q == 0xFFFFFFFF then D.ziv q (q*m34G) else zivT0 q):=by have hV0:0< V:=lt_of_lt_of_le (by norm_num) hV26 have hr0:0≤ r*V:=(abs_nonneg _).trans hq.2 have k7:r*V≤ (4 / 5) / 2 ^ 35*V:=mul_le_mul_of_nonneg_right hr hV0.le have hqA:gAp q V (r*V):=hq split · rename_i hE rw [ite_eq_left hE] at hz exact finZ34 hq hr hV26 hV1 hz hf hM · rename_i hE rw [ite_eq_right hE] at hz refine finT hqA ?_ hz hf hM rw [abs_of_pos hV0] have:(4 / 5) / 2 ^ 35*V≤ 1 / 2 ^ 33*V:=mul_le_mul_of_nonneg_right (by norm_num) hV0.le linarith only [hV0,k7] mutual theorem sigPosT (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:(if zivT0 (((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk)) == 0xFFFFFFFF then D.ziv (((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk)) ((((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk))*m34G) else zivT0 (((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk)))≠ 0xFFFFFFFF) : toWord M=(if zivT0 (((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk)) == 0xFFFFFFFF then D.ziv (((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk)) ((((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk))*m34G) else zivT0 (((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk))):=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 exact neg_nonpos.mpr hC0) have h0:gAp (0:Float) 0 0:=gAp_exact D.qHg.1 D.qHg.2 have hm0:=gAp_mul h0 ht (M:=0) (N:=1) (by norm_num) (by rw [abs_of_pos hT0]; exact hT1) (by norm_num) (by norm_num) have hn:=(gAp_add hm0 gOne (M:=0) (N:=1) (by simp) (by norm_num) (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 52 by norm_num) rw [zero_mul,zero_add] at hn 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 hn hd (M:=1) (m:=1) (by norm_num) (by linarith only [hT0]) (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 42 by norm_num) have hV:(1:ℝ) / 2≤ 1 / (1+T):=by rw [div_le_div_iff₀ (by norm_num) (by exact hT0.trans (by norm_num))]; linarith only [hT1] have hV1:1 / (1+T)≤ (1:ℝ):=by rw [div_le_one (by exact hT0.trans (by norm_num))]; linarith only [hT0] have hqR:gApR (((0:Float)*tOfG m F h hk+oneG) / (oneG+tOfG m F h hk)) (1 / (1+T)) (1 / 2 ^ 41):=by refine ⟨hq.1, ?_⟩ have:(1:ℝ) / 2 ^ 41*(1 / 2)≤ 1 / 2 ^ 41*(1 / (1+T)) := mul_le_mul_of_nonneg_left hV (by norm_num) have:(1:ℝ) / 2 ^ 42=1 / 2 ^ 41*(1 / 2):=by norm_num linarith only [h,hk,hq,hV,hq.2] exact finTZ hqR (by norm_num) (by linarith only [hV]) hV1 hz hf hM theorem sigNegT (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:(if zivT0 ((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk)) == 0xFFFFFFFF then D.ziv ((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk)) (((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk))*m34G) else zivT0 ((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk)))≠ 0xFFFFFFFF) : toWord M=(if zivT0 ((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk)) == 0xFFFFFFFF then D.ziv ((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk)) (((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk))*m34G) else zivT0 ((oneG*tOfG m F h hk+0) / (oneG+tOfG m F h hk))):=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 hz00:(0:ℝ)≤ D.A_z:=le_of_lt (by unfold D.A_z; positivity) have hC0:0≤ C:=by positivity have hT0:0< T:=Real.exp_pos _ have hT1:T≤ 1:=Real.exp_le_one_iff.mpr (by exact neg_nonpos.mpr hC0) have hC17:C< 17:=by have:((kOfG m F).toNat:ℝ)+1≤ 1088:=by exact_mod_cast h1088 linarith only [hCk,this] have hT25:1 / 2 ^ 25≤ T:=exp17.trans (Real.exp_le_exp.mpr (by linarith only [hC17])) 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; exact this.trans (by norm_num) have hρT0:0≤ ρ*T:=mul_nonneg hρ0 hT0.le have hρT35:ρ*T≤ 1 / 2 ^ 35*T:=mul_le_mul_of_nonneg_right hρ1 hT0.le have htR:gApR t T ρ:=⟨ht.1,hrel'⟩ have hRt:=abs_le.mp hrel' have hRtA : |D.R t| ≤ 2:=by rw [abs_le]; constructor <;> linarith only [hρdef,hT0,hρT,hRt,hT1] have hRtT : |D.R t| ≤ T+1 / 2 ^ 35*T:=by rw [abs_le]; constructor <;> linarith only [hρdef,hT0,hT25,hρT,hRt,hρT35] obtain ⟨f1,e1⟩:=D.qCf oneG t gOneR.1 ht.1 (by rw [gOneR.2]; norm_num; linarith only [gAB]) (by linarith only [hT1,hRtT,gAB]) rw [gOneR.2,one_mul] at e1 have e1':=abs_le.mp e1 have hR1 : |D.R (oneG*t)| ≤ 3:=by have:1 / 2 ^ 53*(|D.R t| + D.A_z)≤ 1:=by have:1 / 2 ^ 53*(|D.R t| + D.A_z)≤ 1 / 2 ^ 53*(2+1) := mul_le_mul_of_nonneg_left (by linarith only [hz0,hT1,hRtT]) (by norm_num) linarith only [hz0,hT1,hRtT] rw [abs_le]; constructor <;> linarith only [hρdef,hz0,hT0,hρT,hRt,hRtT,e1',hT1,hRtA,(abs_le.mp hRtA).1,(abs_le.mp hRtA).2] obtain ⟨f2,e2⟩:=D.qBf (oneG*t) 0 f1 D.qHg.1 (by linarith only [hR1,gAB]) (by rw [D.qHg.2]; simp; linarith only [gAB]) rw [D.qHg.2,add_zero] at e2 have e2':=abs_le.mp e2 obtain ⟨ρn,hρndef⟩ : ∃ ρn:ℝ,ρn=ρ+1 / 2 ^ 50:=⟨_,rfl⟩ have hnR:gApR (oneG*t+0) T ρn:=by refine ⟨f2, ?_⟩ have a1:1 / 2 ^ 53*(|D.R t| + D.A_z)≤ 1 / 2 ^ 52*T:=by have:1 / 2 ^ 53*(|D.R t| + D.A_z)≤ 1 / 2 ^ 53*(T+1 / 2 ^ 35*T+1 / 2 ^ 100) := mul_le_mul_of_nonneg_left (by exact add_le_add hRtT hz0) (by norm_num) have:(1:ℝ) / 2 ^ 100≤ 1 / 2 ^ 75*T:=by have:(1:ℝ) / 2 ^ 100=1 / 2 ^ 75*(1 / 2 ^ 25):=by norm_num rw [this]; exact mul_le_mul_of_nonneg_left hT25 (by norm_num) linarith only [hz0,hT0,hT25,hRtT] have hR1T : |D.R (oneG*t)| ≤ 2*T:=by rw [abs_le]; constructor <;> linarith only [hρdef,hz0,hT0,hT25,hρT,hRt,hRtT,e1',hρT35,hRtA] have a2:1 / 2 ^ 53*(|D.R (oneG*t)| + D.A_z)≤ 1 / 2 ^ 51*T:=by have:1 / 2 ^ 53*(|D.R (oneG*t)| + D.A_z)≤ 1 / 2 ^ 53*(2*T+1 / 2 ^ 100) := mul_le_mul_of_nonneg_left (by exact add_le_add hR1T hz0) (by norm_num) have:(1:ℝ) / 2 ^ 100≤ 1 / 2 ^ 75*T:=by have:(1:ℝ) / 2 ^ 100=1 / 2 ^ 75*(1 / 2 ^ 25):=by norm_num rw [this]; exact mul_le_mul_of_nonneg_left hT25 (by norm_num) linarith only [hz0,hT0,hT25,hR1T] have:ρn*T=ρ*T+1 / 2 ^ 50*T:=by rw [hρndef]; ring rw [this,abs_le]; constructor <;> linarith only [hz0,hT0,hT25,hRt,hRtT,e1',e2',hR1T] obtain ⟨fd,ed⟩:=D.qBf oneG t gOneR.1 ht.1 (by rw [gOneR.2]; norm_num; linarith only [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 only [hT0,hρT,hRt,hT1] 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 exact add_le_add h1 hz0) (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 only [hρdef]) (by norm_num) linarith only [hρdef] 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 only [hρdef,hz0,hT0,hρT,ed,h1,h2,h3,this] have hb0:0≤ b:=by rw [hbdef]; positivity have hb1:b≤ 1 / 2:=by rw [hbdef]; linarith only [hρdef] have hρn0:0≤ ρn:=by rw [hρndef]; positivity have hq:=gApR_div hnR hdR hT0 (by exact hT0.trans (by norm_num)) hρn0 hb0 hb1 (by rw [le_div_iff₀ (by exact hT0.trans (by norm_num))]; linarith only [hT0,hT25]) (by rw [div_le_iff₀ (by exact hT0.trans (by norm_num))]; linarith only [hT0]) (by rw [hρndef]; linarith only [hρdef]) obtain ⟨r,hrdef⟩ : ∃ r:ℝ,r=(ρn+b) / (1-b)+1 / 2 ^ 53*(1+(ρn+b) / (1-b))+1 / 2 ^ 120 := ⟨_,rfl⟩ rw [← hrdef] at hq have hr:r≤ (4 / 5) / 2 ^ 35:=by rw [hrdef,hbdef,hρndef,hρdef]; norm_num have hV:realSigmoid (-C)=T / (1+T):=FastAct.realSigmoid_neg_eq C rw [hV] at hM have hV0:0< T / (1+T):=by positivity have hV1:T / (1+T)≤ 1:=by rw [div_le_one (by exact hT0.trans (by norm_num))]; norm_num have hV26:1 / 2 ^ 26≤ T / (1+T):=by rw [le_div_iff₀ (by exact hT0.trans (by norm_num))]; linarith only [hT0,hT25] exact finTZ hq hr hV26 hV1 hz hf hM theorem tanh_lb {C:ℝ} (hC:1 / 2 ^ 8≤ C):1 / 2 ^ 9≤ Real.tanh C:=by rw [tanh_eq_exp_neg_two] set u:=Real.exp (-2*C) have hu0:0< u:=Real.exp_pos _ have he:u*Real.exp (2*C)=1:=by rw [← Real.exp_add]; simp have h1:1+2*C≤ Real.exp (2*C):=by linarith only [Real.add_one_le_exp (2*C)] have hu:u*(1+1 / 2 ^ 7)≤ 1:=by have:u*(1+1 / 2 ^ 7)≤ u*Real.exp (2*C) := mul_le_mul_of_nonneg_left (by linarith only [hC,h1]) hu0.le linarith only [he,this] rw [le_div_iff₀ (by exact hu0.trans (by norm_num))] linarith only [hu0,hu] theorem tanhQ (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) : gAp (oneG*(oneG-tOfG m F h hk) / (oneG+tOfG m F h hk)) (Real.tanh C) (1 / 2 ^ 42) ∧ gAp (negOneG*(oneG-tOfG m F h hk) / (oneG+tOfG m F h hk)) (Real.tanh (-C)) (1 / 2 ^ 42):=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 exact neg_nonpos.mpr hC0) 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 hnb : |1-Real.exp (-(2*C))| ≤ 1:=by rw [abs_le]; constructor <;> linarith only [hT1,hT0] have hp:=(gAp_mul gOne hn (M:=1) (N:=1) (by norm_num) hnb (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 44+1 / 2 ^ 50 by norm_num) have hm:=(gAp_mul gNegOne hn (M:=1) (N:=1) (by norm_num) hnb (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 44+1 / 2 ^ 50 by norm_num) have hpb : |1*(1-Real.exp (-(2*C)))| ≤ 1:=by rw [one_mul]; exact hnb have hmb : |-1*(1-Real.exp (-(2*C)))| ≤ 1:=by rw [neg_one_mul,abs_neg]; exact hnb have hq1:=(gAp_div hp hd (M:=1) (m:=1) hpb (by linarith only [hT0]) (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 42 by norm_num) have hq2:=(gAp_div hm hd (M:=1) (m:=1) hmb (by linarith only [hT0]) (by norm_num) (by norm_num)).mono (show _≤ (1:ℝ) / 2 ^ 42 by norm_num) have e1:1*(1-Real.exp (-(2*C))) / (1+Real.exp (-(2*C)))=Real.tanh C:=by rw [one_mul,tanh_eq_exp_neg_two,show -2*C = -(2*C) by ring] have e2 : -1*(1-Real.exp (-(2*C))) / (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]; ring rw [e1] at hq1; rw [e2] at hq2 exact ⟨hq1,hq2⟩ theorem finTanh {q:Float} {V:ℝ} (c:Prop) [Decidable c] (hq:gAp q V (1 / 2 ^ 42)) (hV : |V| ≤ 1) (hc:c→ 1 / 2 ^ 42≤ 1 / 2 ^ 33 * |V|) (hz:(if (if c then zivT0 q else 0xFFFFFFFF) == 0xFFFFFFFF then D.ziv q m41G else (if c then zivT0 q else 0xFFFFFFFF))≠ 0xFFFFFFFF) {M:Model Fmt} (hf:M.isFinite=true) (hM:M.toReal=Model.roundAt Fmt V) : toWord M=(if (if c then zivT0 q else 0xFFFFFFFF) == 0xFFFFFFFF then D.ziv q m41G else (if c then zivT0 q else 0xFFFFFFFF)):=by by_cases hcc:c · simp only [ite_eq_left hcc] at hz ⊢ split · rename_i hE rw [ite_eq_left hE] at hz exact finZ41 hq hV hz hf hM · rename_i hE rw [ite_eq_right hE] at hz exact finT hq (hc hcc) hz hf hM · simp only [ite_eq_right hcc,beq_self_eq_true,ite_true] at hz ⊢ exact finZ41 hq hV hz hf hM theorem smallC (mm E:Nat) (hm:2 ^ 23≤ mm) (hE:119≤ E) : (1:ℝ) / 2 ^ 8≤ (mm:ℝ)*2 ^ ((E:ℤ)-150):=by have h1:(2:ℝ) ^ 23≤ (mm:ℝ):=by exact_mod_cast hm have h2:(2:ℝ) ^ (-31:ℤ)≤ 2 ^ ((E:ℤ)-150):=zpow_le_zpow_right₀ (by norm_num) (by omega) have h3:(2:ℝ) ^ 23*2 ^ (-31:ℤ)≤ (mm:ℝ)*2 ^ ((E:ℤ)-150) := mul_le_mul h1 h2 (by positivity) (by positivity) have h4:(2:ℝ) ^ 23*2 ^ (-31:ℤ)=1 / 2 ^ 8:=by norm_num rw [← h4]; exact h3 theorem expGe {a:UInt32} (h:0x3B800000≤ a):119≤ (a >>> 23).toNat:=by rw [UInt32.le_iff_toNat_le] at h rw [UInt32.toNat_shiftRight,Nat.shiftRight_eq_div_pow] simp only [UInt32.reduceToNat,Nat.reduceMod] at h ⊢ omega end mutual theorem tanhRelC (mm E:Nat) (hm:2 ^ 23≤ mm) (hE:119≤ E) : (1:ℝ) / 2 ^ 42≤ 1 / 2 ^ 33 * |Real.tanh ((mm:ℝ)*2 ^ ((E:ℤ)-150))| ∧ (1:ℝ) / 2 ^ 42≤ 1 / 2 ^ 33 * |Real.tanh (-((mm:ℝ)*2 ^ ((E:ℤ)-150)))| := by have h:=tanh_lb (smallC mm E hm hE) rw [Real.tanh_neg,abs_neg,abs_of_pos (by exact lt_of_lt_of_le (by norm_num) h)] have:(1:ℝ) / 2 ^ 33*(1 / 2 ^ 9)≤ 1 / 2 ^ 33*Real.tanh ((mm:ℝ)*2 ^ ((E:ℤ)-150)) := mul_le_mul_of_nonneg_left h (by norm_num) have:(1:ℝ) / 2 ^ 42=1 / 2 ^ 33*(1 / 2 ^ 9):=by norm_num constructor <;> linarith only [h] theorem sigH_spec (hok:tabOK=true) (w:UInt32):sigH w≠ 0xFFFFFFFF→ sigH w=sigmoidCR w:=by unfold sigH dsimp only rw [sigCR_eq] split · rename_i hE obtain ⟨hF1,hF2⟩:=fRange hE obtain ⟨he,hm1,hm2,hx⟩:=decW w hF1 (by exact Nat.le_trans hF2 (by decide)) obtain ⟨hf,hM⟩:=sigModel w he rw [hx] at hM split · rename_i hk intro hz by_cases hs:w< 0x80000000 · rw [ite_eq_left hs,one_mul] at hM rw [sgnBit0 hs,selA0,selB0] at hz ⊢ exact (sigPosT hok _ _ hm2 hF1 (by exact Nat.le_trans hF2 (by decide)) _ _ hf hM hz).symm · rw [ite_eq_right hs,neg_one_mul] at hM rw [sgnBit1 hs,selA1,selB1] at hz ⊢ exact (sigNegT hok _ _ hm2 hF1 (by exact Nat.le_trans hF2 (by decide)) _ _ (by rw [UInt32.lt_iff_toNat_lt] at hk; simpa using hk) hf hM hz).symm · intro hz; exact absurd rfl hz · intro hz; exact absurd rfl hz end mutual theorem tanhH_spec (hok:tabOK=true) (w:UInt32):tanhH w≠ 0xFFFFFFFF→ tanhH w=tanhCR w:=by unfold tanhH 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 obtain ⟨hq1,hq2⟩:=tanhQ hok _ _ hm2 (by exact Nat.le_of_lt ‹_›) (by exact Nat.le_trans hF2 (by decide)) _ hk hC intro hz have hV1 : ∀ y:ℝ, |Real.tanh y| ≤ 1:=fun y => abs_le.mpr ⟨(Real.neg_one_lt_tanh y).le,(Real.tanh_lt_one y).le⟩ by_cases hs:w< 0x80000000 · rw [ite_eq_left hs,one_mul] at hM rw [sgnBit0 hs,sgnT0] at hz ⊢ exact (finTanh _ hq1 (hV1 _) (fun ha=>(tanhRelC _ _ hm1 (expGe ha)).1) hz hf hM).symm · rw [ite_eq_right hs,neg_one_mul] at hM rw [sgnBit1 hs,sgnT1] at hz ⊢ exact (finTanh _ hq2 (hV1 _) (fun ha=>(tanhRelC _ _ hm1 (expGe ha)).2) hz hf hM).symm · intro hz; exact absurd rfl hz · intro hz; exact absurd rfl hz theorem sigmoidF3_eq' (w:UInt32):sigmoidF3 w=sigmoidCR w:=by unfold sigmoidF3 dsimp only split · rename_i hok split · exact sigmoidF2_eq' w · rename_i hne exact sigH_spec hok w (by simpa using hne) · simp only [beq_self_eq_true,ite_true]; exact sigmoidF2_eq' w end mutual theorem tanhF3_eq' (w:UInt32):tanhF3 w=tanhCR w:=by unfold tanhF3 dsimp only split · rename_i hok split · exact tanhF2_eq' w · rename_i hne exact tanhH_spec hok w (by simpa using hne) · simp only [beq_self_eq_true,ite_true]; exact tanhF2_eq' w theorem sigmoidF3_eq:sigmoidF3=FastAct.sigmoidF:=by rw [FastAct.sigmoidF_eq]; funext w; exact sigmoidF3_eq' w end mutual theorem tanhF3_eq:tanhF3=FastAct.tanhF:=by rw [FastAct.tanhF_eq]; funext w; exact tanhF3_eq' w theorem sgnIdx (w:UInt32) (A:FloatArray) (hA:A.size=2):(w >>> 31).toUSize.toNat< A.size:=by rw [hA,UInt32.toNat_toUSize,UInt32.toNat_shiftRight] have:=w.toNat_lt simp only [UInt32.reduceToNat,Nat.reduceMod] rw [Nat.shiftRight_eq_div_pow]; omega theorem ugetG (A:FloatArray) (i:USize) (h:i.toNat< A.size):A.uget i h=A.get! i.toNat:=by cases A; simp [FloatArray.uget,FloatArray.get!, getElem!_def,Array.getElem?_eq_getElem h] ; rfl end structure AK where one:Float half:Float c6:Float c24:Float c120:Float tab:FloatArray pw:FloatArray sA:FloatArray sB:FloatArray sT:FloatArray etab:tab=expTabG epw:pw=D.pw esA:sA=selA esB:sB=selB esT:sT=sgnT def akG:AK:=⟨oneG,halfG,c6G,c24G,c120G,expTabG,D.pw,selA,selB,sgnT,rfl,rfl,rfl,rfl,rfl⟩ @[inline] def tOfK (K:AK) (m F:UInt32) (h:F.toUSize.toNat< D.pw.size) (hk:kOfG m F< 1280):Float := let r:=(m-(kOfG m F <<< sOfG F)).toUInt64.toFloat*K.pw.uget F.toUSize (by rw [K.epw]; exact h) K.tab.uget (kOfG m F).toUSize (by rw [K.etab]; exact kidx hk (by decide)) * ((K.one-r)+r*r*((K.half-r*K.c6)+r*r*(K.c24-r*K.c120))) @[inline] def sigA (K:AK) (w:UInt32):UInt32 := let a:=w &&& 0x7FFFFFFF let F:=a >>> 23 let m:=(a &&& 0x7FFFFF) ||| 0x800000 if F-1< 131 then if h:kOfG m F< 1088 then let t:=tOfK K m F (eidx a) (kLt h (by decide)) let s:=(w >>> 31).toUSize let q:=(K.sA.uget s (by rw [K.esA]; exact sgnIdx w selA rfl)*t + K.sB.uget s (by rw [K.esB]; exact sgnIdx w selB rfl)) / (K.one+t) let r:=zivT0 q if r == 0xFFFFFFFF then D.ziv q (q*m34G) else r else 0xFFFFFFFF else 0xFFFFFFFF @[inline] def tanhA (K:AK) (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:=tOfK K m F (eidx _) h let q:=K.sT.uget (w >>> 31).toUSize (by rw [K.esT]; exact sgnIdx w sgnT rfl)*(K.one-t) / (K.one+t) if 0x3B800000≤ a then let r:=zivT0 q if r == 0xFFFFFFFF then D.ziv q m41G else r else D.ziv q m41G else 0xFFFFFFFF else 0xFFFFFFFF mutual theorem sigA_eq (w:UInt32):sigA akG w=sigH w:=by unfold sigA sigH tOfK tOfG rOfG polyG; simp only [akG,ugetG,UInt32.toNat_toUSize] theorem tanhA_eq (w:UInt32):tanhA akG w=tanhH w:=by unfold tanhA tanhH tOfK tOfG rOfG polyG; simp only [akG,ugetG,UInt32.toNat_toUSize] split <;> (try split) <;> (try split) <;> simp end end ActH section RnnL def catW (inW H R:Nat) (wih whh bih:Array Word):Array Word := Array.ofFn (n:=R*(inW+H+1)) fun q => if q.val % (inW+H+1)< inW then wih[q.val / (inW+H+1)*inW+q.val % (inW+H+1)]! else if q.val % (inW+H+1)< inW+H then whh[q.val / (inW+H+1)*H+(q.val % (inW+H+1)-inW)]! else bih[q.val / (inW+H+1)]! theorem catIdx (N k j:Nat) (hj:j< N):(k*N+j) % N=j∧(k*N+j) / N=k:=by refine ⟨by rw [Nat.add_comm,Nat.add_mul_mod_self_right,Nat.mod_eq_of_lt hj], ?_⟩ rw [Nat.add_comm,Nat.add_mul_div_right _ _ (by omega),Nat.div_eq_of_lt hj,Nat.zero_add] theorem catW_get (inW H R:Nat) (wih whh bih:Array Word) (k j:Nat) (hk:k< R) (hj:j< inW+H+1) : (catW inW H R wih whh bih)[k*(inW+H+1)+j]! = if j< inW then wih[k*inW+j]! else if j< inW+H then whh[k*H+(j-inW)]! else bih[k]! := by obtain ⟨hm,hd⟩:=catIdx (inW+H+1) k j hj unfold catW rw [ofFn_get!F _ _ (idx_lt k j _ R hk hj)] simp only [hm,hd] @[inline] def xhOf (inW H:Nat) (x h:Array Word) (t:Nat):Array Word := Array.ofFn (n:=inW+H+1) fun j=>gA inW H x h t j.val @[noinline] def xhOfN (inW H:Nat) (x h:Array Word) (t:Nat):Array Word:=xhOf inW H x h t @[inline] def xhS (inW H:Nat) (x h:Array Word) (t:Nat):Array Word := if x.size≤ 4294967295∧h.size≤ 4294967295∧t*inW+inW≤ 4294967295∧inW+H+1≤ 4294967295 then wcpW h 0 inW.toUSize H.toUSize 0 (wcpW x (t*inW).toUSize 0 inW.toUSize 0 (Array.replicate (inW+H+1) oneW)) else xhOfN inW H x h t mutual theorem xhS_get (inW H:Nat) (x h:Array Word) (t j:Nat) (hj:j< inW+H+1) : (xhS inW H x h t)[j]! = gA inW H x h t j:=by unfold xhS split_ifs with hc · obtain ⟨hx,hh,ht,hN⟩:=hc have u0:(0:USize).toNat=0:=rfl have uI:inW.toUSize.toNat=inW:=qAd inW (by omega) have uH:H.toUSize.toNat=H:=qAd H (by omega) have uO:(t*inW).toUSize.toNat=t*inW:=qAd _ (by omega) have hs0:(Array.replicate (inW+H+1) oneW).size=inW+H+1:=Array.size_replicate obtain ⟨s1,g1⟩:=wcpW_spec x (t*inW).toUSize 0 inW.toUSize (by exact Nat.lt_succ_of_le hx) (by rw [uO,uI]; exact Nat.lt_succ_of_le ht) (by rw [u0,uI]; omega) _ 0 (Array.replicate (inW+H+1) oneW) rfl (by rw [u0]; exact Nat.zero_le _) (by rw [hs0]; exact Nat.lt_succ_of_le hN) (by rw [hs0,u0,uI]; omega) obtain ⟨-, g2⟩:=wcpW_spec h 0 inW.toUSize H.toUSize (by exact Nat.lt_succ_of_le hh) (by rw [u0,uH]; omega) (by rw [uI,uH]; exact Nat.le_succ_of_le hN) _ 0 _ rfl (by rw [u0]; exact Nat.zero_le _) (by rw [s1,hs0]; exact Nat.lt_succ_of_le hN) (by rw [s1,hs0,uI,uH]; exact Nat.le_add_right _ _) rw [g2 j,g1 j] simp only [u0,uI,uH,uO,Nat.add_zero,Nat.zero_add,Nat.sub_zero] unfold gA by_cases h1:j< inW · rw [ite_eq_right (by omega),ite_eq_left ⟨Nat.zero_le _,h1⟩,ite_eq_left h1] · by_cases h2:j< inW+H · rw [ite_eq_left ⟨by omega,h2⟩,ite_eq_right h1,ite_eq_left h2] · rw [ite_eq_right (by omega),ite_eq_right (by omega),ite_eq_right h1,ite_eq_right h2, getElem!_pos _ j (by rw [hs0]; exact hj),Array.getElem_replicate] · unfold xhOfN xhOf; exact ofFn_get! _ _ _ hj theorem dotOf_congr (n:Nat) (fa fb ga gb:Nat→ Word) (h : ∀ j,j< n→ fa j=ga j∧fb j=gb j) : dotOf n fa fb=dotOf n ga gb:=by unfold dotOf have e1:(fun i:Fin n=>fa i.val)=fun i=>ga i.val:=funext fun i=>(h i.val i.isLt).1 have e2:(fun i:Fin n=>fb i.val)=fun i=>gb i.val:=funext fun i=>(h i.val i.isLt).2 rw [e1,e2] end structure Q8 where (h0 h1 h2 h3 c0 c1 c2 c3:Word) @[specialize] def build8 (H:Nat) (f4:Nat→ Q8) (f:Nat→ Word × Word) : Nat→ Nat→ Array Word→ Array Word→ Array Word × Array Word | _,0,a,b=>(a,b) | k,n+1,a,b => if k+4≤ H then let q:=f4 k build8 H f4 f (k+4) n ((((a.push q.h0).push q.h1).push q.h2).push q.h3) ((((b.push q.c0).push q.c1).push q.c2).push q.c3) else if k< H then let p:=f k build8 H f4 f (k+1) n (a.push p.1) (b.push p.2) else (a,b) theorem build8_spec (H:Nat) (f4:Nat→ Q8) (f:Nat→ Word × Word) (h4 : ∀ k,k+4≤ H→ f4 k=⟨(f k).1,(f (k+1)).1,(f (k+2)).1,(f (k+3)).1, (f k).2,(f (k+1)).2,(f (k+2)).2,(f (k+3)).2⟩) : ∀ (n k:Nat) (a b:Array Word),k≤ H→ H≤ k+n → a=Array.ofFn (n:=k) (fun i=>(f i.val).1)→ b=Array.ofFn (n:=k) (fun i=>(f i.val).2) → build8 H f4 f k n a b=(Array.ofFn (n:=H) (fun i=>(f i.val).1),Array.ofFn (n:=H) (fun i=>(f i.val).2)) | 0,k,a,b,hk,hn,ha,hb=>by have:k=H:=by omega subst this; rw [build8,ha,hb] | n+1,k,a,b,hk,hn,ha,hb=>by rw [build8] split_ifs with c1 c2 · rw [h4 k c1] dsimp only refine build8_spec H f4 f h4 n (k+4) _ _ (by assumption) (by omega) ?_ ?_ · rw [ha,push_ofFnA (fun i=>(f i).1) k,push_ofFnA (fun i=>(f i).1) (k+1), push_ofFnA (fun i=>(f i).1) (k+2),push_ofFnA (fun i=>(f i).1) (k+3)] · rw [hb,push_ofFnA (fun i=>(f i).2) k,push_ofFnA (fun i=>(f i).2) (k+1), push_ofFnA (fun i=>(f i).2) (k+2),push_ofFnA (fun i=>(f i).2) (k+3)] · exact build8_spec H f4 f h4 n (k+1) _ _ (by assumption) (by omega) (by rw [ha]; exact push_ofFnA (fun i=>(f i).1) k) (by rw [hb]; exact push_ofFnA (fun i=>(f i).2) k) · have:k=H:=by omega subst this; rw [ha,hb] abbrev LWc (inW H:Nat) (wih whh bih:Array Word) := {p:Array Word // p=catW inW H (4*H) wih whh bih} local instance lwcSub (inW H:Nat) (wih whh bih:Array Word):Subsingleton (LWc inW H wih whh bih) := ⟨fun a b=>Subtype.ext (a.2.trans b.2.symm)⟩ structure LWE where (nI nH:Nat) (a b c:Array Word) (g:USize) (p:Array Word) (ok:p=catW nI nH (4*nH) a b c) end RnnL section RnnG theorem candIdxX (inW H u:Nat) (hu:u< H) (hWl:H*(inW+1)< 2 ^ 32) : ¬ inW+1< inW ∧ ¬ inW+1=inW∧u*(inW+1)< 2 ^ 32∧u*(inW+1)+inW≤ H*(inW+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 exact Nat.le_of_lt ‹_›, fun j h1 h2 h3=>by omega⟩ def wnOf (H:Nat) (whh:Array Word):Array Word := Array.ofFn (n:=H*H) fun q=>whh[(2*H+q.val / H)*H+q.val % H]! theorem wnOf_get (H:Nat) (whh:Array Word) (u j:Nat) (hu:u< H) (hj:j< H) : (wnOf H whh)[u*H+j]! = whh[(2*H+u)*H+j]! := by obtain ⟨hm,hd⟩:=catIdx H u j hj unfold wnOf rw [ofFn_get!F _ _ (idx_lt u j H H hu hj)] simp only [hm,hd] @[inline] def candFinU (inW H:Nat) (x wih bih:Array Word) (t u:Nat) (v1 wb nfc z0:Float) (hu ru:Word) (r0:F1):Word := if good hu && good ru then let r:=stp (stp r0 (v1*wb)) (dv hu*dv ru) let w:=ziv (r.s+z0) (nfc*(r.t+z0.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 updU (nu zu hu:Word) (one z0 nf3:Float):Word := if good nu && good zu && good hu && good (negW zu) then let r:=stp (stp (stp ⟨0,0⟩ (dv nu*one)) (dv nu*dv (negW zu))) (dv hu*dv zu) let w:=ziv (r.s+z0) (nf3*(r.t+z0.abs)) if w == 0xFFFFFFFF then upd3Slow nu zu hu else w else upd3Slow nu zu hu theorem fget_data (a:FloatArray) (i:Nat):a.get! i=a.data[i]! := by cases a; rfl structure GLq (inW H:Nat) (wih whh bih bhh Wrz Brz Wn Bn:Array Word) (Wc:FloatArray):Prop where g1 : ∀ i:Nat,good wih[i]! = true g3 : ∀ i:Nat,good bih[i]! = true hN:inW+H+3< 2 ^ 20 hW : ∀ k j,k< 2*H→ j< inW+H+1→ Wrz[k*(inW+H+1)+j]! = if j< inW then wih[k*inW+j]! else if j< inW+H then whh[k*H+(j-inW)]! else bih[k]! hB : ∀ k,k< 2*H→ Brz[k]! = bhh[k]! hWn : ∀ u j,u< H→ j< H→ Wn[u*H+j]! = whh[(2*H+u)*H+j]! hBn : ∀ u,u< H→ Bn[u]! = 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]!) hWcs:Wc.size=H*(inW+1) hl3:H*(inW+1)< 2 ^ 32 def gruPrepL (inW H:Nat) (wih whh bih bhh:Array Word) : Bool × Array Word × Array Word × Array Word × Array Word × FloatArray × ((FloatArray × UInt32) × (FloatArray × UInt32)) × ((FloatArray × UInt32) × (FloatArray × UInt32)) := (wih.all good && bih.all good && decide (inW+H+3< 2 ^ 20) && decide (H< 1024), catW inW H (2*H) wih whh bih,Array.ofFn (n:=2*H) (fun k=>bhh[k.val]!),wnOf H whh, Array.ofFn (n:=H) (fun u=>bhh[2*H+u.val]!), 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))), ((D.wbOf (inW+H+1) (2*H) (catW inW H (2*H) wih whh bih),D.scanH 2 (catW inW H (2*H) wih whh bih)), (D.bOf (Array.ofFn (n:=2*H) (fun k=>bhh[k.val]!)),D.scanH 1 (Array.ofFn (n:=2*H) (fun k=>bhh[k.val]!)))), ((D.wbOf H H (wnOf H whh),D.scanH 2 (wnOf H whh)), (D.bOf (Array.ofFn (n:=H) (fun u=>bhh[2*H+u.val]!)), D.scanH 1 (Array.ofFn (n:=H) (fun u=>bhh[2*H+u.val]!))))) abbrev GLc (inW H:Nat) (wih whh bih bhh:Array Word) := {p:Bool × Array Word × Array Word × Array Word × Array Word × FloatArray × ((FloatArray × UInt32) × (FloatArray × UInt32)) × ((FloatArray × UInt32) × (FloatArray × UInt32)) // p=gruPrepL inW H wih whh bih bhh} local instance glcSub (inW H:Nat) (wih whh bih bhh:Array Word) : Subsingleton (GLc inW H wih whh bih bhh) := ⟨fun a b=>Subtype.ext (a.2.trans b.2.symm)⟩ structure GLE where (nI nH:Nat) (a b c d:Array Word) (g:USize) (p:Bool × Array Word × Array Word × Array Word × Array Word × FloatArray × ((FloatArray × UInt32) × (FloatArray × UInt32)) × ((FloatArray × UInt32) × (FloatArray × UInt32))) (ok:p=gruPrepL nI nH a b c d) theorem bnOf_get (H:Nat) (bhh:Array Word) (u:Nat) (hu:u< H) : (Array.ofFn (n:=H) (fun u=>bhh[2*H+u.val]!))[u]! = bhh[2*H+u]! := ofFn_get!F _ u hu @[inline] def sigI (w:Word):Word:=let v:=sigA akG w; if v == 0xFFFFFFFF then sigmoidF3 w else v @[inline] def tanhI (w:Word):Word:=let v:=tanhA akG w; if v == 0xFFFFFFFF then tanhF3 w else v mutual theorem sigI_eq (hok:tabOK=true):sigI=sigmoidF3:=by funext w; unfold sigI; dsimp only; split · rfl · rename_i hne; rw [sigA_eq] at hne ⊢; rw [sigH_spec hok w (by simpa using hne),sigmoidF3_eq' w] theorem tanhI_eq (hok:tabOK=true):tanhI=tanhF3:=by funext w; unfold tanhI; dsimp only; split · rfl · rename_i hne; rw [tanhA_eq] at hne ⊢; rw [tanhH_spec hok w (by simpa using hne),tanhF3_eq' w] end end RnnG section RnnZ def wnN (inW H:Nat) (whh:Array Word):Array Word := Array.ofFn (n:=H*(inW+H+1)) fun q => if inW≤ q.val % (inW+H+1)∧q.val % (inW+H+1)< inW+H then whh[(2*H+q.val / (inW+H+1))*H+(q.val % (inW+H+1)-inW)]! else 0 structure GZq where ok:Bool Wrz:Array Word Brz:Array Word Pr:FloatArray Br:FloatArray hvr:Word bmr:Float Wn:Array Word Bn:Array Word Pn:FloatArray Bnf:FloatArray hvn:Word bmn:Float Wc:FloatArray def gzOK (inW H:Nat) (wih whh bih bhh:Array Word):Bool := wih.all good && bih.all good && D.scanH 2 (catW inW H (2*H) wih whh bih) != 0xFFFFFFFF && D.scanH 1 (Array.ofFn (n:=2*H) fun k=>bhh[k.val]!) != 0xFFFFFFFF && D.scanH 2 (wnOf H whh) != 0xFFFFFFFF && D.scanH 1 (Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!) != 0xFFFFFFFF && decide (inW+H+3< 1048576) && decide (inW+H+1≤ 8192) && decide (0< H) && decide (H< 1024) def gzPrep (inW H:Nat) (wih whh bih bhh:Array Word):GZq := ⟨gzOK inW H wih whh bih bhh, catW inW H (2*H) wih whh bih,Array.ofFn (n:=2*H) (fun k=>bhh[k.val]!), D.wbOf (inW+H+1) (2*H) (catW inW H (2*H) wih whh bih),D.bOf (Array.ofFn (n:=2*H) fun k=>bhh[k.val]!), D.scanH 2 (catW inW H (2*H) wih whh bih),dv (D.scanH 1 (Array.ofFn (n:=2*H) fun k=>bhh[k.val]!)), wnOf H whh,Array.ofFn (n:=H) (fun u=>bhh[2*H+u.val]!), D.wbOf (inW+H+1) H (wnN inW H whh),D.bOf (Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!), D.scanH 2 (wnOf H whh),dv (D.scanH 1 (Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!)), 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)))⟩ abbrev GZc (inW H:Nat) (wih whh bih bhh:Array Word) := {q:GZq // q=gzPrep inW H wih whh bih bhh} local instance gzcSub (inW H:Nat) (wih whh bih bhh:Array Word):Subsingleton (GZc inW H wih whh bih bhh) := ⟨fun a b=>Subtype.ext (a.2.trans b.2.symm)⟩ structure GZE where (nI nH:Nat) (a b c d:Array Word) (g:USize) (p:GZq) (ok:p=gzPrep nI nH a b c d) @[inline] def gzF1 (inW H:Nat) (wih whh bih bhh:Array Word) (g:USize) (e:GZE) : Option (GZc inW H wih whh bih bhh) := if e.g == g then if hn:e.nI=inW∧e.nH=H then if ha:withPtrEq e.a wih (fun _=>e.a == wih) (fun h=>by rw [h]; exact beq_self_eq_true wih) then if hb:withPtrEq e.b whh (fun _=>e.b == whh) (fun h=>by rw [h]; exact beq_self_eq_true whh) then if hc:withPtrEq e.c bih (fun _=>e.c == bih) (fun h=>by rw [h]; exact beq_self_eq_true bih) then if hd:withPtrEq e.d bhh (fun _=>e.d == bhh) (fun h=>by rw [h]; exact beq_self_eq_true bhh) then some ⟨e.p,by rw [← hn.1, ← hn.2, ← eq_of_beq ha, ← eq_of_beq hb, ← eq_of_beq hc, ← eq_of_beq hd] exact e.ok⟩ else none else none else none else none else none else none @[inline] def gzF (inW H:Nat) (wih whh bih bhh:Array Word) (g:USize) (s:Array GZE) : Option (GZc inW H wih whh bih bhh) := if h:0< s.size then match gzF1 inW H wih whh bih bhh g s[0] with | some v=>some v | none=>if h1:1< s.size then gzF1 inW H wih whh bih bhh g s[1] else none else none @[noinline] def gzS:ST.Ref Unit (Array GZE):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def gzGet (inW H:Nat) (wih whh bih bhh:Array Word):GZc inW H wih whh bih bhh := withPtrAddr wih (fun g => let s:=(ST.Prim.Ref.get gzS (Void.mk ())).val match gzF inW H wih whh bih bhh g s with | some v=>v | none => let p:=gzPrep inW H wih whh bih bhh let old:=(ST.Prim.Ref.swap gzS (#[⟨inW,H,wih,whh,bih,bhh,g,p,rfl⟩] ++ (if h:0< s.size then #[s[0]] else #[])) (Void.mk ())).val match gzF inW H wih whh bih bhh g old with | some v=>v | none=>⟨p,rfl⟩) (fun _ _=>Subsingleton.elim _ _) def z64:FloatArray:=D.pushZ 64 0 (FloatArray.emptyWithCapacity 64) @[inline] def zS (n:Nat):FloatArray:=if n≤ 32 then D.zA else if n≤ 64 then z64 else D.zFor n structure DZ where V:FloatArray A:Float Ah:Float ok:Bool def dxZ (x:Array Word) (o:USize):Nat→ USize→ FloatArray→ Float→ Bool→ DZ | 0,_,V,A,ok=>⟨V,A,0,ok⟩ | n+1,j,V,A,ok => let w:=D.rdW x (o+j) let d:=dv w dxZ x o n (j+1) (D.wrF V j d) (A+d.abs) (ok && good w) def dhZ (h:Array Word) (i0:USize):Nat→ USize→ FloatArray→ Float→ Float→ Bool→ DZ | 0,j,V,A,Ah,ok=>⟨D.wrF V (i0+j) (dv oneW),A+(dv oneW).abs,Ah,ok⟩ | n+1,j,V,A,Ah,ok => let w:=D.rdW h j let d:=dv w dhZ h i0 n (j+1) (D.wrF V (i0+j) d) (A+d.abs) (Ah+d.abs) (ok && good w) @[inline] def put8 (S:FloatArray) (k:USize) (a b c d e f g l:Float):FloatArray := D.wrF (D.wrF (D.wrF (D.wrF (D.wrF (D.wrF (D.wrF (D.wrF S k a) (k+1) b) (k+2) c) (k+3) d) (k+4) e) (k+5) f) (k+6) g) (k+7) l def sumsOK (vs ws:Nat) (m n:USize):Nat→ USize→ Bool | 0,_=>true | nb+1,p => if nb≠ 0 then decide (n.toNat≤ vs∧n.toNat≤ m.toNat∧p.toNat+8*m.toNat≤ ws ∧ (p+8*m).toNat+8*m.toNat≤ ws∧ws≤ 4294967295) && sumsOK vs ws m n (nb-1) (p+8*m+8*m) else decide (n.toNat≤ vs∧n.toNat≤ m.toNat∧p.toNat+8*m.toNat≤ ws∧ws≤ 4294967295) def sumsZ (V wb:FloatArray) (m n t0:USize):Nat→ USize→ USize→ FloatArray→ FloatArray | 0,_,_,S=>S | nb+1,p,k,S => let p':=p+8*m if nb≠ 0 then if hg:n.toNat≤ V.size∧n.toNat≤ m.toNat∧p.toNat+8*m.toNat≤ wb.size ∧ p'.toNat+8*m.toNat≤ wb.size∧wb.size≤ 4294967295 then let r:=D.go16V V wb p p' m n t0 hg.1 hg.2.1 hg.2.2.1 hg.2.2.2.1 (D.qA9 hg.2.2.2.2) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 sumsZ V wb m n t0 (nb-1) (p'+8*m) (k+16) (put8 (put8 S k r.a r.b r.c r.d r.e r.f r.g r.k) (k+8) r.a' r.b' r.c' r.d' r.e' r.f' r.g' r.k') else S else if hg:n.toNat≤ V.size∧n.toNat≤ m.toNat∧p.toNat+8*m.toNat≤ wb.size∧wb.size≤ 4294967295 then let r:=D.go8V V wb p m n t0 hg.1 hg.2.1 hg.2.2.1 (D.qA9 hg.2.2.2) 0 0 0 0 0 0 0 0 put8 S k r.a r.b r.c r.d r.e r.f r.g r.k else S @[inline] def p4 (S:FloatArray) (k:USize) (c:F4):FloatArray:=put8 S k c.s0 c.t0 c.s1 c.t1 c.s2 c.t2 c.s3 c.t3 def cd4 (V W:FloatArray) (w0 w1 w2 w3 n:USize) (hs:V.size< 2 ^ 32) (hw:W.size< 2 ^ 32) (hV:(0:USize).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) (S:FloatArray) (k:USize) (j:USize) (s0 s1 s2 s3 t0 t1 t2 t3:Float) : FloatArray := if hj:j< n then let v:=V.uget (0+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) cd4 V W w0 w1 w2 w3 n hs hw hV h0 h1 h2 h3 S k (j+1) (s0+q0) (s1+q1) (s2+q2) (s3+q3) (t0+q0.abs) (t1+q1.abs) (t2+q2.abs) (t3+q3.abs) else p4 S k ⟨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 _) def cdZ (V W:FloatArray) (m n Hs:USize):Nat→ USize→ FloatArray→ FloatArray | 0,_,S=>S | fuel+1,u,S => if u+4≤ Hs then if h:V.size≤ 4294967295∧W.size≤ 4294967295∧(0:USize).toNat+n.toNat≤ V.size ∧ (u*m).toNat+n.toNat≤ W.size∧((u+1)*m).toNat+n.toNat≤ W.size ∧ ((u+2)*m).toNat+n.toNat≤ W.size∧((u+3)*m).toNat+n.toNat≤ W.size then cdZ V W m n Hs fuel (u+4) (cd4 V W (u*m) ((u+1)*m) ((u+2)*m) ((u+3)*m) n (D.qA9 h.1) (D.qA9 h.2.1) h.2.2.1 h.2.2.2.1 h.2.2.2.2.1 h.2.2.2.2.2.1 h.2.2.2.2.2.2 S (2*u) 0 0 0 0 0 0 0 0 0) else S else if u< Hs then let c:=rdotU V W 0 (u*m) n.toNat 0 0 cdZ V W m n Hs fuel (u+1) (D.wrF (D.wrF S (2*u) c.s) (2*u+1) c.t) else S def cdOK (vs ws:Nat) (m n Hs:USize):Nat→ USize→ Bool | 0,_=>true | fuel+1,u => if u+4≤ Hs then decide (vs≤ 4294967295∧ws≤ 4294967295∧(0:USize).toNat+n.toNat≤ vs ∧ (u*m).toNat+n.toNat≤ ws∧((u+1)*m).toNat+n.toNat≤ ws ∧ ((u+2)*m).toNat+n.toNat≤ ws∧((u+3)*m).toNat+n.toNat≤ ws) && cdOK vs ws m n Hs fuel (u+4) else if u< Hs then cdOK vs ws m n Hs fuel (u+1) else true @[noinline] def rzSlow (inW H:Nat) (x h:Array Word) (t:Nat) (W b:Array Word) (u:USize) (s nf A:Float) (hv:Word):Word := D.fin8u (inW+H+1) false (xhS inW H x h t) W b 0 u s nf A hv (inW+H+1).toUSize @[noinline] def hnSlow (H:Nat) (h W b:Array Word) (u:USize) (s nf A:Float) (hv:Word):Word := D.fin8u H false h W b 0 u s nf A hv H.toUSize structure GW where S:FloatArray Sc:FloatArray lo:UInt64 sp:UInt64 loh:UInt64 sph:UInt64 nf:Float A:Float nfh:Float Ah:Float @[inline] def gwZ (inW H:Nat) (x h:Array Word) (t:Nat) (Q:GZq) (g:GW) (k:USize):Word := let s:=D.rdB g.S k let w:=D.fin1 g.lo g.sp (s+D.rdB Q.Br k) if w == 0xFFFFFFFF then rzSlow inW H x h t Q.Wrz Q.Brz k s g.nf g.A Q.hvr else w @[inline] def hwZ (H:Nat) (h:Array Word) (Q:GZq) (g:GW) (o u:USize):Word := let s:=D.rdB g.S (o+u) let w:=D.fin1 g.loh g.sph (s+D.rdB Q.Bnf u) if w == 0xFFFFFFFF then hnSlow H h Q.Wn Q.Bn u s g.nfh g.Ah Q.hvn else w @[inline] def uZ (sig tanh:Word→ Word) (inW H:Nat) (x wih bih h:Array Word) (t:Nat) (Q:GZq) (g:GW) (v1 nfc z0 one nf3:Float) (Hs mI i o:USize) (u:USize):Word := let r:=sig (gwZ inW H x h t Q g u) let z:=sig (gwZ inW H x h t Q g (Hs+u)) let hn:=hwZ H h Q g o u let n:=tanh (candFinU inW H x wih bih t u.toNat v1 (D.rdB Q.Wc (u*mI+i)) nfc z0 hn r ⟨D.rdB g.Sc (2*u),D.rdB g.Sc (2*u+1)⟩) updU n z (D.rdW h u) one z0 nf3 def hOf (H:Nat) (B:Array Word) (t:Nat):Array Word := if t=0 then Array.replicate H 0 else B.extract ((t-1)*H) ((t-1)*H+H) @[noinline] def rzSlowX (inW H:Nat) (x : @& Array Word) (B : @& Array Word) (t:Nat) (W b : @& Array Word) (u:USize) (s nf A:Float) (hv:Word):Word := D.fin8u (inW+H+1) false (xhS inW H x (hOf H B t) t) W b 0 u s nf A hv (inW+H+1).toUSize @[noinline] def hnSlowX (H:Nat) (B : @& Array Word) (t:Nat) (W b : @& Array Word) (u:USize) (s nf A:Float) (hv:Word):Word := D.fin8u H false (hOf H B t) W b 0 u s nf A hv H.toUSize @[noinline] def rzSlowO (inW H:Nat) (x : @& Array Word) (B : @& Array Word) (t:Nat) (W b : @& Array Word) (u:USize) (s nf A:Float) (hv:Word):Word := let bv:=dv (D.rdW b u) let r:=ziv (s+bv) (nf*(dv hv*A+bv.abs)) if r == 0xFFFFFFFF then rzSlowX inW H x B t W b u s nf A hv else r @[noinline] def hnSlowO (H:Nat) (B : @& Array Word) (t:Nat) (W b : @& Array Word) (u:USize) (s nf A:Float) (hv:Word):Word := let bv:=dv (D.rdW b u) let r:=ziv (s+bv) (nf*(dv hv*A+bv.abs)) if r == 0xFFFFFFFF then hnSlowX H B t W b u s nf A hv else r @[inline] def gwF (inW H:Nat) (x B:Array Word) (t:Nat) (Q:GZq) (S:FloatArray) (lo sp:UInt64) (nf A:Float) (k:USize):Word := let s:=D.rdB S k let w:=D.fin1 lo sp (s+D.rdB Q.Br k) if w == 0xFFFFFFFF then rzSlowO inW H x B t Q.Wrz Q.Brz k s nf A Q.hvr else w @[inline] def hwF (H:Nat) (B:Array Word) (t:Nat) (Q:GZq) (S:FloatArray) (loh sph:UInt64) (nfh Ah0:Float) (o u:USize):Word := let s:=D.rdB S (o+u) let w:=D.fin1 loh sph (s+D.rdB Q.Bnf u) if w == 0xFFFFFFFF then hnSlowO H B t Q.Wn Q.Bn u s nfh Ah0 Q.hvn else w def dhB (B:Array Word) (rb i0:USize):Nat→ USize→ FloatArray→ Float→ Float→ Bool→ DZ | 0,j,V,A,Ah,ok=>⟨D.wrF V (i0+j) (dv oneW),A+(dv oneW).abs,Ah,ok⟩ | n+1,j,V,A,Ah,ok => let w:=D.rdW B (rb+j) let d:=dv w dhB B rb i0 n (j+1) (D.wrF V (i0+j) d) (A+d.abs) (Ah+d.abs) (ok && good w) @[inline] def uF (sig tanh:Word→ Word) (inW H:Nat) (x wih bih:Array Word) (t:Nat) (Q:GZq) (S Sc:FloatArray) (lo sp loh sph:UInt64) (nf A nfh Ah:Float) (v1 nfc z0 one nf3:Float) (Hs mI i o rb:USize) (B:Array Word) (u:USize):Word := let r:=sig (gwF inW H x B t Q S lo sp nf A u) let z:=sig (gwF inW H x B t Q S lo sp nf A (Hs+u)) let hn:=hwF H B t Q S loh sph nfh Ah o u let n:=tanh (candFinU inW H x wih bih t u.toNat v1 (D.rdB Q.Wc (u*mI+i)) nfc z0 hn r ⟨D.rdB Sc (2*u),D.rdB Sc (2*u+1)⟩) updU n z (D.rdW B (rb+u)) one z0 nf3 @[specialize] def unitsF (sig tanh:Word→ Word) (inW H:Nat) (x wih bih:Array Word) (t:Nat) (Q:GZq) (S Sc:FloatArray) (lo sp loh sph:UInt64) (nf A nfh Ah:Float) (v1 nfc z0 one nf3:Float) (Hs mI i o rb wb:USize):Nat→ USize→ Array Word→ Array Word | 0,_,B=>B | fuel+1,u,B => if u+4≤ Hs then let r0:=sig (gwF inW H x B t Q S lo sp nf A u) let r1:=sig (gwF inW H x B t Q S lo sp nf A (u+1)) let r2:=sig (gwF inW H x B t Q S lo sp nf A (u+2)) let r3:=sig (gwF inW H x B t Q S lo sp nf A (u+3)) let z0':=sig (gwF inW H x B t Q S lo sp nf A (Hs+u)) let z1:=sig (gwF inW H x B t Q S lo sp nf A (Hs+(u+1))) let z2:=sig (gwF inW H x B t Q S lo sp nf A (Hs+(u+2))) let z3:=sig (gwF inW H x B t Q S lo sp nf A (Hs+(u+3))) let h0:=hwF H B t Q S loh sph nfh Ah o u let h1:=hwF H B t Q S loh sph nfh Ah o (u+1) let h2:=hwF H B t Q S loh sph nfh Ah o (u+2) let h3:=hwF H B t Q S loh sph nfh Ah o (u+3) let n0:=tanh (candFinU inW H x wih bih t u.toNat v1 (D.rdB Q.Wc (u*mI+i)) nfc z0 h0 r0 ⟨D.rdB Sc (2*u),D.rdB Sc (2*u+1)⟩) let n1:=tanh (candFinU inW H x wih bih t (u+1).toNat v1 (D.rdB Q.Wc ((u+1)*mI+i)) nfc z0 h1 r1 ⟨D.rdB Sc (2*(u+1)),D.rdB Sc (2*(u+1)+1)⟩) let n2:=tanh (candFinU inW H x wih bih t (u+2).toNat v1 (D.rdB Q.Wc ((u+2)*mI+i)) nfc z0 h2 r2 ⟨D.rdB Sc (2*(u+2)),D.rdB Sc (2*(u+2)+1)⟩) let n3:=tanh (candFinU inW H x wih bih t (u+3).toNat v1 (D.rdB Q.Wc ((u+3)*mI+i)) nfc z0 h3 r3 ⟨D.rdB Sc (2*(u+3)),D.rdB Sc (2*(u+3)+1)⟩) let o0:=updU n0 z0' (D.rdW B (rb+u)) one z0 nf3 let o1:=updU n1 z1 (D.rdW B (rb+(u+1))) one z0 nf3 let o2:=updU n2 z2 (D.rdW B (rb+(u+2))) one z0 nf3 let o3:=updU n3 z3 (D.rdW B (rb+(u+3))) one z0 nf3 unitsF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah v1 nfc z0 one nf3 Hs mI i o rb wb fuel (u+4) (D.wrW (D.wrW (D.wrW (D.wrW B (wb+u) o0) (wb+(u+1)) o1) (wb+(u+2)) o2) (wb+(u+3)) o3) else if u< Hs then unitsF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah v1 nfc z0 one nf3 Hs mI i o rb wb fuel (u+1) (D.wrW B (wb+u) (uF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah v1 nfc z0 one nf3 Hs mI i o rb B u)) else B @[specialize] def loopF (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh:Array Word) (Q:GZq) : Nat→ Nat→ Array Word→ FloatArray→ FloatArray→ FloatArray→ Array Word | _,0,B,_,_,_=>B | t,n+1,B,V,S,Sc => let wb:=(t*H).toUSize let rb:=if t=0 then B.usize else wb-H.toUSize if t*inW+inW+H+1≤ 4294967295 then let d:=dxZ x (t*inW).toUSize inW 0 V 0 true let d:=dhB B rb inW.toUSize H 0 d.V d.A 0 d.ok if d.ok then let o:=8*((2*H+7) / 8) let N:=(inW+H+1).toUSize let S:=sumsZ d.V Q.Pr N N 0 ((2*H+7) / 8) 5 0 S let S:=sumsZ d.V Q.Pn N (inW+H).toUSize inW.toUSize ((H+7) / 8) 5 o.toUSize S let Sc:=cdZ d.V Q.Wc (inW+1).toUSize inW.toUSize H.toUSize H 0 Sc let nf:=nfOf (inW+H+1) let lo:=D.loOf (nf*(dv Q.hvr*d.A+Q.bmr)) let nfh:=nfOf H let loh:=D.loOf (nfh*(dv Q.hvn*d.Ah+Q.bmn)) loopF sig tanh inW H x wih whh bih bhh Q (t+1) n (unitsF sig tanh inW H x wih bih t Q S Sc lo (D.spOf lo) loh (D.spOf loh) nf d.A nfh d.Ah (dv oneW) (nfOf (inW+2)) (dv 0) (dv oneW) (nfOf 3) H.toUSize (inW+1).toUSize inW.toUSize o.toUSize rb wb H 0 B) d.V S Sc else loopF sig tanh inW H x wih whh bih bhh Q (t+1) n (wcpW (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (hOf H B t, #[])).1 0 wb H.toUSize 0 B) d.V S Sc else loopF sig tanh inW H x wih whh bih bhh Q (t+1) n (wcpW (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (hOf H B t, #[])).1 0 wb H.toUSize 0 B) V S Sc @[specialize] def gruZ (sig tanh:Word→ Word) (T inW H:Nat) (x wih whh bih bhh:Array Word):Array Word := let Q:=(gzGet inW H wih whh bih bhh).1 let N:=(inW+H+1).toUSize let vs:=(zS (inW+H+1)).size if Q.ok && decide (x.size≤ 4294967295) && decide (T*H+H+4≤ 4294967295) && sumsOK vs Q.Pr.size N N ((2*H+7) / 8) 5 && sumsOK vs Q.Pn.size N (inW+H).toUSize ((H+7) / 8) 5 && cdOK vs Q.Wc.size (inW+1).toUSize inW.toUSize H.toUSize H 0 then loopF sig tanh inW H x wih whh bih bhh Q 0 T (Array.replicate (T*H) 0) (zS (inW+H+1)) (zS (8*((2*H+7) / 8)+8*((H+7) / 8))) (zS (2*H)) else gruWith Pinned.dotFn sig tanh T inW H x wih whh bih bhh def gruXZ (T inW H:Nat) (x wih whh bih bhh:Array Word):Array Word := if tabOK then gruZ sigI tanhI T inW H x wih whh bih bhh else gruWith Pinned.dotFn sigmoidF3 tanhF3 T inW H x wih whh bih bhh mutual theorem zS_size (n:Nat) (h:n< 2 ^ 32):n≤ (zS n).size∧(zS n).size< 2 ^ 32:=by unfold zS split · have e:D.zA.size=32:=D.qZs 32 (by norm_num) rw [e]; omega · split · have e:z64.size=64:=D.qZs 64 (by norm_num) rw [e]; omega · exact D.qZf n h theorem uadd (a:USize) (k:Nat) (h:a.toNat+k< 2 ^ 32):(a+USize.ofNat k).toNat=a.toNat+k:=by rw [D.qAf _ _ (by rw [D.uk k (by omega)]; exact h),D.uk k (by omega)] end theorem uadd1 (a:USize) (h:a.toNat+1< 2 ^ 32):(a+1).toNat=a.toNat+1:=uadd a 1 h mutual theorem dxZ_spec (x:Array Word) (o:USize) (hx:x.size< 2 ^ 32) : ∀ (n:Nat) (j:USize) (V:FloatArray) (A:Float) (ok:Bool),j.toNat+n≤ V.size→ V.size< 2 ^ 32 → o.toNat+j.toNat+n< 2 ^ 32 → (dxZ x o n j V A ok).V.size=V.size ∧ (∀ q,(dxZ x o n j V A ok).V.data[q]! = if j.toNat≤ q∧q< j.toNat+n then dv x[o.toNat+q]! else V.data[q]!) ∧ (dxZ x o n j V A ok).A=(List.range' j.toNat n).foldl (fun a q=>a+(dv x[o.toNat+q]!).abs) A ∧ (dxZ x o n j V A ok).Ah=0 ∧ ((dxZ x o n j V A ok).ok=true→ ok=true ∧ ∀ q,j.toNat≤ q→ q< j.toNat+n→ good x[o.toNat+q]! = true) | 0,j,V,A,ok,_,_,_=>by refine ⟨rfl,fun q => ?_,rfl,rfl,fun h=>⟨h,fun q h1 h2=>by omega⟩⟩ rw [ite_eq_right (by omega)]; rfl | n+1,j,V,A,ok,hjV,hV,ho=>by have ej:(j+1).toNat=j.toNat+1:=uadd1 j (by omega) have eo:(o+j).toNat=o.toNat+j.toNat:=D.qAf o j (by omega) have hj:j.toNat< V.size:=by omega have ew:D.rdW x (o+j)=x[o.toNat+j.toNat]! := by rw [D.qAg x _ hx,eo] have hs:=D.qD6 V j (dv (D.rdW x (o+j))) obtain ⟨i1,i2,i3,i4,i5⟩:=dxZ_spec x o hx n (j+1) (D.wrF V j (dv (D.rdW x (o+j)))) (A+(dv (D.rdW x (o+j))).abs) (ok && good (D.rdW x (o+j))) (by rw [hs,ej]; omega) (by rw [hs]; exact hV) (by rw [ej]; omega) simp only [dxZ] refine ⟨by rw [i1,hs],fun q => ?_, ?_,i4,fun h => ?_⟩ · rw [i2 q,ej,D.qEt V j _ q hV hj,ew] by_cases c1:j.toNat+1≤ q∧q< j.toNat+1+n · rw [ite_eq_left c1,ite_eq_left (by omega)] · rw [ite_eq_right c1] by_cases c2:q=j.toNat · rw [ite_eq_left c2,ite_eq_left (by omega),c2] · rw [ite_eq_right c2,ite_eq_right (by omega)] · rw [i3,ej,List.range'_succ,List.foldl_cons,ew] · obtain ⟨h1,h2⟩:=i5 h simp only [Bool.and_eq_true] at h1 refine ⟨h1.1,fun q q1 q2 => ?_⟩ by_cases c:q=j.toNat · rw [c, ← ew]; exact h1.2 · exact h2 q (by rw [ej]; omega) (by rw [ej]; omega) theorem dhZ_spec (h:Array Word) (i0:USize) (hh:h.size< 2 ^ 32) : ∀ (n:Nat) (j:USize) (V:FloatArray) (A Ah:Float) (ok:Bool),i0.toNat+j.toNat+n+1≤ V.size → V.size< 2 ^ 32→ j.toNat+n< 2 ^ 32 → (dhZ h i0 n j V A Ah ok).V.size=V.size ∧ (∀ q,(dhZ h i0 n j V A Ah ok).V.data[q]! = if i0.toNat+j.toNat≤ q∧q< i0.toNat+j.toNat+n then dv h[q-i0.toNat]! else if q=i0.toNat+j.toNat+n then dv oneW else V.data[q]!) ∧ (dhZ h i0 n j V A Ah ok).A=(List.range' j.toNat n).foldl (fun a q=>a+(dv h[q]!).abs) A+(dv oneW).abs ∧ (dhZ h i0 n j V A Ah ok).Ah=(List.range' j.toNat n).foldl (fun a q=>a+(dv h[q]!).abs) Ah ∧ ((dhZ h i0 n j V A Ah ok).ok=true→ ok=true ∧ ∀ q,j.toNat≤ q→ q< j.toNat+n→ good h[q]! = true) | 0,j,V,A,Ah,ok,hjV,hV,_=>by have ei:(i0+j).toNat=i0.toNat+j.toNat:=D.qAf i0 j (by omega) simp only [dhZ] refine ⟨D.qD6 _ _ _,fun q => ?_,rfl,rfl,fun e=>⟨e,fun q a b=>by omega⟩⟩ rw [D.qEt V _ _ q hV (by rw [ei]; omega),ei,ite_eq_right (show ¬ (i0.toNat+j.toNat≤ q∧q< i0.toNat+j.toNat+0) by omega)] simp only [Nat.add_zero] | n+1,j,V,A,Ah,ok,hjV,hV,hjn=>by have ej:(j+1).toNat=j.toNat+1:=uadd1 j (by omega) have ei:(i0+j).toNat=i0.toNat+j.toNat:=D.qAf i0 j (by omega) have ew:D.rdW h j=h[j.toNat]! := D.qAg h _ hh have hs:=D.qD6 V (i0+j) (dv (D.rdW h j)) obtain ⟨i1,i2,i3,i4,i5⟩:=dhZ_spec h i0 hh n (j+1) (D.wrF V (i0+j) (dv (D.rdW h j))) (A+(dv (D.rdW h j)).abs) (Ah+(dv (D.rdW h j)).abs) (ok && good (D.rdW h j)) (by rw [hs,ej]; omega) (by rw [hs]; exact hV) (by rw [ej]; omega) simp only [dhZ] refine ⟨by rw [i1,hs],fun q => ?_, ?_, ?_,fun e => ?_⟩ · rw [i2 q,ej,D.qEt V _ _ q hV (by rw [ei]; omega),ei,ew] clear i1 i2 i3 i4 i5 hs by_cases c1:i0.toNat+(j.toNat+1)≤ q∧q< i0.toNat+(j.toNat+1)+n · rw [if_pos c1,if_pos ⟨by omega,by omega⟩] · rw [if_neg c1] by_cases c2:q=i0.toNat+(j.toNat+1)+n · rw [if_pos c2,if_neg (by omega),if_pos (by omega)] · rw [if_neg c2] by_cases c3:q=i0.toNat+j.toNat · rw [if_pos c3,if_pos ⟨by omega,by omega⟩,c3,Nat.add_sub_cancel_left] · rw [if_neg c3,if_neg (by omega),if_neg (by omega)] · rw [i3,ej,List.range'_succ,List.foldl_cons,ew] · rw [i4,ej,List.range'_succ,List.foldl_cons,ew] · obtain ⟨h1,h2⟩:=i5 e simp only [Bool.and_eq_true] at h1 refine ⟨h1.1,fun q q1 q2 => ?_⟩ by_cases c:q=j.toNat · rw [c, ← ew]; exact h1.2 · exact h2 q (by rw [ej]; omega) (by rw [ej]; omega) theorem foldl_cgm {β:Type} (f g:β→ Nat→ β) : ∀ (l:List Nat) (a:β), (∀ q ∈ l, ∀ a,f a q=g a q)→ l.foldl f a=l.foldl g a | [],_,_=>rfl | q :: l,a,h=>by rw [List.foldl_cons,List.foldl_cons,h q (List.mem_cons_self ..)] exact foldl_cgm f g l _ fun u hu=>h u (List.mem_cons_of_mem _ hu) theorem range3 (a b:Nat):List.range (a+b+1)=List.range' 0 a ++ List.range' a b ++ [a+b]:=by have e:=List.range'_append (s:=0) (m:=a) (n:=b) (step:=1) simp only [Nat.one_mul,Nat.zero_add] at e rw [List.range_succ,List.range_eq_range', ← e] end mutual theorem decV_spec (inW H:Nat) (x h:Array Word) (t:Nat) (hx:x.size< 2 ^ 32) (hh:h.size< 2 ^ 32) (hb:t*inW+inW+H+1≤ 4294967295) (V:FloatArray) (z1:inW+H+1≤ V.size) (z2:V.size< 2 ^ 32) : (dhZ h inW.toUSize H 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).V (dxZ x (t*inW).toUSize inW 0 V 0 true).A 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).ok).V.size=V.size ∧ (∀ q,q< inW+H+1→ (dhZ h inW.toUSize H 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).V (dxZ x (t*inW).toUSize inW 0 V 0 true).A 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).ok).V.data[q]! = dv (gA inW H x h t q)) ∧ (dhZ h inW.toUSize H 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).V (dxZ x (t*inW).toUSize inW 0 V 0 true).A 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).ok).A=(List.range (inW+H+1)).foldl (fun a q=>a+(dv (gA inW H x h t q)).abs) 0 ∧ (dhZ h inW.toUSize H 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).V (dxZ x (t*inW).toUSize inW 0 V 0 true).A 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).ok).Ah=(List.range H).foldl (fun a j=>a+(dv h[j]!).abs) 0 ∧ ((dhZ h inW.toUSize H 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).V (dxZ x (t*inW).toUSize inW 0 V 0 true).A 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).ok).ok=true→ (∀ j,j< inW→ good x[t*inW+j]! = true) ∧ ∀ j,j< H→ good h[j]! = true):=by have eo:(t*inW).toUSize.toNat=t*inW:=qAd _ (by omega) have ei:inW.toUSize.toNat=inW:=qAd _ (by omega) have e0:(0:USize).toNat=0:=rfl obtain ⟨a1,a2,a3,a4,a5⟩:=dxZ_spec x (t*inW).toUSize hx inW 0 V 0 true (by rw [e0]; omega) z2 (by rw [eo,e0]; omega) obtain ⟨b1,b2,b3,b4,b5⟩:=dhZ_spec h inW.toUSize hh H 0 _ (dxZ x (t*inW).toUSize inW 0 V 0 true).A 0 (dxZ x (t*inW).toUSize inW 0 V 0 true).ok (by rw [a1,ei,e0]; omega) (by rw [a1]; exact z2) (by rw [e0]; omega) rw [ei,e0] at b2 rw [e0] at b3 b4 b5 a2 a3 a5 rw [eo] at a2 a3 a5 refine ⟨by rw [b1,a1],fun q hq => ?_, ?_, ?_,fun e => ?_⟩ · rw [b2 q,a2 q] unfold gA clear * - hq by_cases c1:inW+0≤ q∧q< inW+0+H · rw [if_pos c1,if_neg (by omega),if_pos (by omega)] · rw [if_neg c1] by_cases c2:q=inW+0+H · rw [if_pos c2,if_neg (by omega),if_neg (by omega)] · rw [if_neg c2,if_pos ⟨Nat.zero_le _,by omega⟩,if_pos (by omega)] · rw [b3,a3] rw [range3] rw [List.foldl_append,List.foldl_append,List.foldl_cons,List.foldl_nil] have g1:=foldl_cgm (fun a q=>a+(dv (gA inW H x h t q)).abs) (fun a q=>a+(dv x[t*inW+q]!).abs) (List.range' 0 inW) 0 (fun q hq a=>by rw [List.mem_range'_1] at hq; unfold gA; rw [ite_eq_left (show q< inW by omega)]) have g2 : ∀ c:Float,List.foldl (fun a q=>a+(dv (gA inW H x h t q)).abs) c (List.range' inW H) = List.foldl (fun a q=>a+(dv h[q]!).abs) c (List.range' 0 H):=fun c=>by rw [List.range'_eq_map_range,List.foldl_map,List.range'_eq_map_range,List.foldl_map] refine foldl_cgm _ _ _ _ (fun q hq a => ?_) rw [List.mem_range] at hq show a+(dv (gA inW H x h t (inW+q))).abs=a+(dv h[0+q]!).abs unfold gA; rw [ite_eq_right (show ¬ inW+q< inW by omega),ite_eq_left (show inW+q< inW+H by omega), show inW+q-inW=q by omega,Nat.zero_add] have g3:gA inW H x h t (inW+H)=oneW:=by unfold gA; rw [ite_eq_right (show ¬ inW+H< inW by omega),ite_eq_right (show ¬ inW+H< inW+H by omega)] rw [g1,g2,g3] · rw [b4,List.range_eq_range'] · obtain ⟨c1,c2⟩:=b5 e obtain ⟨-, c3⟩:=a5 c1 exact ⟨fun j hj=>c3 j (Nat.zero_le _) (by omega),fun j hj=>c2 j (Nat.zero_le _) (by omega)⟩ theorem dhB_eq (B h:Array Word) (rb i0:USize) (J:Nat) (hr : ∀ j:USize,j.toNat< J→ D.rdW B (rb+j)=D.rdW h j) : ∀ (n:Nat) (j:USize) (V:FloatArray) (A Ah:Float) (ok:Bool),j.toNat+n≤ J→ J< 2 ^ 32 → dhB B rb i0 n j V A Ah ok=dhZ h i0 n j V A Ah ok | 0,_,_,_,_,_,_,_=>rfl | n+1,j,V,A,Ah,ok,h1,h2=>by rw [dhB,dhZ] rw [hr j (by omega)] exact dhB_eq B h rb i0 J hr n (j+1) _ _ _ _ (by rw [uadd1 j (by omega)]; omega) h2 theorem stepF (T S:FloatArray) (i:USize) (K m:Nat) (L:Nat→ Float) (hi:i.toNat=K+m) (hT:T.size< 2 ^ 32) (hiT:K+m< T.size) (h : ∀ q,T.data[q]! = if K≤ q∧q< K+m then L (q-K) else S.data[q]!) : ∀ q,(D.wrF T i (L m)).data[q]! = if K≤ q∧q< K+(m+1) then L (q-K) else S.data[q]! := by intro q rw [D.qEt T i _ q hT (by rw [hi]; exact hiT),h q,hi] by_cases e:q=K+m · rw [if_pos e,if_pos ⟨by omega,by omega⟩,e,Nat.add_sub_cancel_left] · rw [if_neg e] by_cases r:K≤ q∧q< K+m · rw [if_pos r,if_pos ⟨r.1,by omega⟩] · rw [if_neg r,if_neg (by omega)] end theorem put8L (S:FloatArray) (k:USize) (L:Nat→ Float) (hk:k.toNat+8≤ S.size) (hS:S.size< 2 ^ 32) : (put8 S k (L 0) (L 1) (L 2) (L 3) (L 4) (L 5) (L 6) (L 7)).size=S.size ∧ ∀ q,(put8 S k (L 0) (L 1) (L 2) (L 3) (L 4) (L 5) (L 6) (L 7)).data[q]! = if k.toNat≤ q∧q< k.toNat+8 then L (q-k.toNat) else S.data[q]! := by have hb : ∀ j:Nat,j< 8→ (k+USize.ofNat j).toNat=k.toNat+j∧k.toNat+j< S.size := fun j hj=>⟨uadd k j (by omega),by omega⟩ have u1:(k+1).toNat=k.toNat+1∧k.toNat+1< S.size:=hb 1 (by decide) have u2:(k+2).toNat=k.toNat+2∧k.toNat+2< S.size:=hb 2 (by decide) have u3:(k+3).toNat=k.toNat+3∧k.toNat+3< S.size:=hb 3 (by decide) have u4:(k+4).toNat=k.toNat+4∧k.toNat+4< S.size:=hb 4 (by decide) have u5:(k+5).toNat=k.toNat+5∧k.toNat+5< S.size:=hb 5 (by decide) have u6:(k+6).toNat=k.toNat+6∧k.toNat+6< S.size:=hb 6 (by decide) have u7:(k+7).toNat=k.toNat+7∧k.toNat+7< S.size:=hb 7 (by decide) have u0:k.toNat+0< S.size:=Nat.lt_of_lt_of_le (Nat.lt_add_of_pos_right (by decide)) hk have sz : ∀ (T:FloatArray) (i:USize) (v:Float),(D.wrF T i v).size=T.size:=D.qD6 refine ⟨by unfold put8; simp only [sz], ?_⟩ have h0 : ∀ q,S.data[q]! = if k.toNat≤ q∧q< k.toNat+0 then L (q-k.toNat) else S.data[q]! := fun q=>(if_neg (fun h=>Nat.lt_irrefl _ (Nat.lt_of_le_of_lt h.1 h.2))).symm have h1:=stepF S S k k.toNat 0 L rfl hS u0 h0 have h2:=stepF _ S (k+1) k.toNat 1 L u1.1 (by simp only [sz]; exact hS) (by simp only [sz]; exact u1.2) h1 have h3:=stepF _ S (k+2) k.toNat 2 L u2.1 (by simp only [sz]; exact hS) (by simp only [sz]; exact u2.2) h2 have h4:=stepF _ S (k+3) k.toNat 3 L u3.1 (by simp only [sz]; exact hS) (by simp only [sz]; exact u3.2) h3 have h5:=stepF _ S (k+4) k.toNat 4 L u4.1 (by simp only [sz]; exact hS) (by simp only [sz]; exact u4.2) h4 have h6:=stepF _ S (k+5) k.toNat 5 L u5.1 (by simp only [sz]; exact hS) (by simp only [sz]; exact u5.2) h5 have h7:=stepF _ S (k+6) k.toNat 6 L u6.1 (by simp only [sz]; exact hS) (by simp only [sz]; exact u6.2) h6 exact stepF _ S (k+7) k.toNat 7 L u7.1 (by simp only [sz]; exact hS) (by simp only [sz]; exact u7.2) h7 def laneZ (V:FloatArray) (W:Array Word) (M o t0 n c l:Nat):Float := (List.range' t0 (n-t0)).foldl (fun acc q=>acc+V.data[q]! * dv W[min (8*c+l) (o-1)*M+q]!) 0 theorem go8Z (V:FloatArray) (W:Array Word) (M o:Nat) (m n t0 p:USize) (c:Nat) (hm:m.toNat=M) (hc:c< (o+7) / 8) (hp:p.toNat=8*c*M+5) (hx:n.toNat≤ V.size) (hnm:n.toNat≤ m.toNat) (hb:p.toNat+8*m.toNat≤ (D.wbOf M o W).size) (hs:(D.wbOf M o W).size< 2 ^ 32) (hWs:W.size< 2 ^ 32) (hoW:o*M≤ W.size) (hn8:n.toNat≤ 8192) (ht0:t0.toNat≤ n.toNat) : D.go8V V (D.wbOf M o W) p m n t0 hx hnm hb hs 0 0 0 0 0 0 0 0 = ⟨laneZ V W M o t0.toNat n.toNat c 0,laneZ V W M o t0.toNat n.toNat c 1,laneZ V W M o t0.toNat n.toNat c 2, laneZ V W M o t0.toNat n.toNat c 3,laneZ V W M o t0.toNat n.toNat c 4,laneZ V W M o t0.toNat n.toNat c 5, laneZ V W M o t0.toNat n.toNat c 6,laneZ V W M o t0.toNat n.toNat c 7⟩:=by have hi:n.toNat≤ D.idA.size:=by rw [D.qIs]; exact hn8 have ho:0< o:=by omega have row : ∀ l,l< 8→ min (8*c+l) (o-1)< o:=fun l _=>by omega have rl : ∀ l,l< 8→ (min (8*c+l) (o-1)*M)+M≤ W.size:=fun l hl=>by have:=Nat.mul_le_mul_right M (row l hl); rw [Nat.succ_mul] at this; omega have wl : ∀ l,l< 8→ ((min (8*c+l) (o-1)*M).toUSize).toNat=min (8*c+l) (o-1)*M := fun l hl=>qAd _ (by have:=rl l hl; omega) have wb : ∀ l,l< 8→ ((min (8*c+l) (o-1)*M).toUSize).toNat+m.toNat≤ W.size:=fun l hl=>by rw [wl l hl,hm]; exact rl l hl have HB : ∀ i,i< m.toNat → ∀ l,l< 8 → (D.wbOf M o W).data[p.toNat+8*i+l]! = dv W[((min (8*c+l) (o-1)*M).toUSize).toNat+i]! := by intro i hi' l hl rw [hm] at hi' rw [wl l hl,hp] by_cases hf:8*c+8≤ o · have e:=D.wbP W M o (8*c) i l (by omega) hf hi' hl rw [show 8*c*M+5+8*i+l=8*c*M+5+8*i+l from rfl,e, show min (8*c+l) (o-1)=8*c+l by omega] · have hco:c=o / 8:=by omega have hr:o % 8≠ 0:=by omega have e:=D.wbPt W M o i l hr hi' hl rw [hco]; exact e rw [D.g8VW V (D.wbOf M o W) D.idA p m n hx hi hnm hb hs (fun k hk=>D.qIA k (by omega)) (n.toNat-t0.toNat) t0 0 0 0 0 0 0 0 0 (by omega)] rw [D.g8WE V (D.wbOf M o W) D.idA W p _ _ _ _ _ _ _ _ m n hx hi hb hs hWs (wb 0 (by decide)) (wb 1 (by decide)) (wb 2 (by decide)) (wb 3 (by decide)) (wb 4 (by decide)) (wb 5 (by decide)) (wb 6 (by decide)) (wb 7 (by decide)) (fun i hi'=>⟨HB i hi' 0 (by decide),HB i hi' 1 (by decide),HB i hi' 2 (by decide),HB i hi' 3 (by decide), HB i hi' 4 (by decide),HB i hi' 5 (by decide),HB i hi' 6 (by decide),HB i hi' 7 (by decide)⟩) (n.toNat-t0.toNat) t0 0 0 0 0 0 0 0 0 (by omega)] have G : ∀ l (hl:l< 8),D.go1 V D.idA W ((min (8*c+l) (o-1)*M).toUSize) m n t0 hx hi hWs (wb l hl) 0 = laneZ V W M o t0.toNat n.toNat c l:=fun l hl=>by unfold laneZ refine D.qH6 hx hi hWs (wb l hl) (fun q=>V.data[q]!) (fun q=>W[min (8*c+l) (o-1)*M+q]!) (fun q _=>by rw [wl l hl]) (List.range' t0.toNat (n.toNat-t0.toNat)) t0 0 (by simp; omega) ?_ intro k q hq have hk:k< n.toNat-t0.toNat:=by obtain ⟨h1, -⟩:=List.getElem?_eq_some_iff.mp hq; simpa using h1 rw [List.getElem?_range' hk] at hq simp only [Option.some.injEq,Nat.one_mul] at hq subst hq exact ⟨by omega,D.qIA _ (by omega),rfl⟩ simp only [D.g8of] rw [G 0 (by decide),G 1 (by decide),G 2 (by decide),G 3 (by decide),G 4 (by decide),G 5 (by decide), G 6 (by decide),G 7 (by decide)] mutual theorem sumsZ_spec (V:FloatArray) (W:Array Word) (M o:Nat) (m n t0:USize) (hm:m.toNat=M) (hs:(D.wbOf M o W).size< 2 ^ 32) (hWs:W.size< 2 ^ 32) (hoW:o*M≤ W.size) (hn8:n.toNat≤ 8192) (ht0:t0.toNat≤ n.toNat) : ∀ nb c (p k:USize) (S:FloatArray),nb+c=(o+7) / 8→ p.toNat=8*c*M+5 → k.toNat+8*nb≤ S.size→ S.size< 2 ^ 32→ sumsOK V.size (D.wbOf M o W).size m n nb p=true → (sumsZ V (D.wbOf M o W) m n t0 nb p k S).size=S.size ∧ ∀ q,(sumsZ V (D.wbOf M o W) m n t0 nb p k S).data[q]! = if k.toNat≤ q∧q< k.toNat+8*nb then laneZ V W M o t0.toNat n.toNat (c+(q-k.toNat) / 8) ((q-k.toNat) % 8) else S.data[q]! := by intro nb induction nb using Nat.strong_induction_on with | _ nb ih => intro c p k S hnb hp hk hS hok match nb,ih,hnb,hk,hok with | 0,_,_,_,_ => refine ⟨by unfold sumsZ; rfl,fun q => ?_⟩ rw [ite_eq_right (by omega)]; unfold sumsZ; rfl | nb+1,ih,hnb,hk,hok => unfold sumsOK at hok unfold sumsZ by_cases h0:nb≠ 0 · rw [ite_eq_left h0] at hok ⊢ simp only [Bool.and_eq_true,decide_eq_true_eq] at hok obtain ⟨hg,hrest⟩:=hok rw [dite_eq_left hg] dsimp only obtain ⟨g1,g2,g3,g4,g5⟩:=hg have e8:(8:USize).toNat=8:=D.uk 8 (by decide) have em:(8*m).toNat=8*M:=by rw [D.qWm _ _ (by rw [e8]; omega),e8,hm] have ep':(p+8*m).toNat=8*(c+1)*M+5:=by rw [D.qAf _ _ (by rw [em]; omega),em,hp]; ring have ep'':(p+8*m+8*m).toNat=8*(c+2)*M+5:=by rw [D.qAf _ _ (by rw [em,ep']; omega),em,ep']; ring have ek8:(k+8).toNat=k.toNat+8:=uadd k 8 (by omega) have ek16:(k+16).toNat=k.toNat+16:=uadd k 16 (by omega) rw [D.g16V] rw [go8Z V W M o m n t0 p c hm (by omega) hp g1 g2 g3 hs hWs hoW hn8 ht0, go8Z V W M o m n t0 (p+8*m) (c+1) hm (by omega) ep' g1 g2 g4 hs hWs hoW hn8 ht0] simp only [D.g16of] obtain ⟨s1,d1⟩:=put8L S k (laneZ V W M o t0.toNat n.toNat c) (by omega) hS obtain ⟨s2,d2⟩:=put8L _ (k+8) (laneZ V W M o t0.toNat n.toNat (c+1)) (by rw [s1,ek8]; omega) (by rw [s1]; exact hS) obtain ⟨s3,d3⟩:=ih (nb-1) (by omega) (c+2) (p+8*m+8*m) (k+16) _ (by omega) ep'' (by rw [s2,s1,ek16]; omega) (by rw [s2,s1]; exact hS) hrest refine ⟨by rw [s3,s2,s1],fun q => ?_⟩ rw [d3 q,ek16,d2 q,ek8,d1 q] clear d1 d2 d3 s1 s2 s3 ih hrest by_cases r3:k.toNat+16≤ q∧q< k.toNat+16+8*(nb-1) · rw [ite_eq_left r3,ite_eq_left (show k.toNat≤ q∧q< k.toNat+8*(nb+1) by omega), show c+2+(q-(k.toNat+16)) / 8=c+(q-k.toNat) / 8 by omega, show (q-(k.toNat+16)) % 8=(q-k.toNat) % 8 by omega] · rw [ite_eq_right r3] by_cases r2:k.toNat+8≤ q∧q< k.toNat+8+8 · rw [ite_eq_left r2,ite_eq_left (show k.toNat≤ q∧q< k.toNat+8*(nb+1) by omega), show c+(q-k.toNat) / 8=c+1 by omega,show (q-k.toNat) % 8=q-(k.toNat+8) by omega] · rw [ite_eq_right r2] by_cases r1:k.toNat≤ q∧q< k.toNat+8 · rw [ite_eq_left r1,ite_eq_left (show k.toNat≤ q∧q< k.toNat+8*(nb+1) by omega), show c+(q-k.toNat) / 8=c by omega,show (q-k.toNat) % 8=q-k.toNat by omega] · rw [ite_eq_right r1,ite_eq_right (show ¬ (k.toNat≤ q∧q< k.toNat+8*(nb+1)) by omega)] · have h0':nb=0:=by omega subst h0' rw [ite_eq_right h0] at hok ⊢ simp only [decide_eq_true_eq] at hok rw [dite_eq_left hok] dsimp only obtain ⟨g1,g2,g3,g5⟩:=hok rw [go8Z V W M o m n t0 p c hm (by omega) hp g1 g2 g3 hs hWs hoW hn8 ht0] obtain ⟨s1,d1⟩:=put8L S k (laneZ V W M o t0.toNat n.toNat c) (by omega) hS refine ⟨s1,fun q => ?_⟩ rw [d1 q] by_cases r1:k.toNat≤ q∧q< k.toNat+8 · rw [ite_eq_left r1,ite_eq_left (show k.toNat≤ q∧q< k.toNat+8*(0+1) by omega), show c+(q-k.toNat) / 8=c by omega,show (q-k.toNat) % 8=q-k.toNat by omega] · rw [ite_eq_right r1,ite_eq_right (show ¬ (k.toNat≤ q∧q< k.toNat+8*(0+1)) by omega)] theorem cd4_eq (V W:FloatArray) (w0 w1 w2 w3 n:USize) (hs:V.size< 2 ^ 32) (hw:W.size< 2 ^ 32) (hV:(0:USize).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) (S:FloatArray) (kk:USize) : ∀ (k:Nat) (j:USize) (s0 s1 s2 s3 t0 t1 t2 t3:Float),n.toNat-j.toNat=k → cd4 V W w0 w1 w2 w3 n hs hw hV h0 h1 h2 h3 S kk j s0 s1 s2 s3 t0 t1 t2 t3 = p4 S kk (rdot4T V W 0 w0 w1 w2 w3 n hs hw hV h0 h1 h2 h3 j s0 s1 s2 s3 t0 t1 t2 t3) | 0,j,s0,s1,s2,s3,t0,t1,t2,t3,hk=>by have hj : ¬ j< n:=fun h=>by have:=USize.lt_iff_toNat_lt.mp h; omega rw [cd4,rdot4T,dif_neg hj,dif_neg hj] | k+1,j,s0,s1,s2,s3,t0,t1,t2,t3,hk=>by have hj:j< n:=USize.lt_iff_toNat_lt.mpr (by omega) rw [cd4,rdot4T,dif_pos hj,dif_pos hj] exact cd4_eq V W w0 w1 w2 w3 n hs hw hV h0 h1 h2 h3 S kk k (j+1) _ _ _ _ _ _ _ _ (by rw [D.usz j n hj]; omega) end def cdv (V W:FloatArray) (m n:USize) (q:Nat):Float := if q % 2=0 then (rdotU V W 0 (USize.ofNat (q / 2)*m) n.toNat 0 0).s else (rdotU V W 0 (USize.ofNat (q / 2)*m) n.toNat 0 0).t theorem cd4_put (V W:FloatArray) (m n u:USize) (hs:V.size< 2 ^ 32) (hw:W.size< 2 ^ 32) (hV:(0:USize).toNat+n.toNat≤ V.size) (h0:(u*m).toNat+n.toNat≤ W.size) (h1:((u+1)*m).toNat+n.toNat≤ W.size) (h2:((u+2)*m).toNat+n.toNat≤ W.size) (h3:((u+3)*m).toNat+n.toNat≤ W.size) (S:FloatArray) (hu:u.toNat+4< 2 ^ 32) (h2u:2*u.toNat+8≤ S.size) (hS:S.size< 2 ^ 32) : (cd4 V W (u*m) ((u+1)*m) ((u+2)*m) ((u+3)*m) n hs hw hV h0 h1 h2 h3 S (2*u) 0 0 0 0 0 0 0 0 0).size=S.size ∧ ∀ q,(cd4 V W (u*m) ((u+1)*m) ((u+2)*m) ((u+3)*m) n hs hw hV h0 h1 h2 h3 S (2*u) 0 0 0 0 0 0 0 0 0).data[q]! = if 2*u.toNat≤ q∧q< 2*u.toNat+8 then cdv V W m n q else S.data[q]! := by have e2:(2*u).toNat=2*u.toNat:=by have e:(2:USize).toNat=2:=D.uk 2 (by decide) rw [D.qWm _ _ (by rw [e]; omega),e] rw [cd4_eq V W _ _ _ _ n hs hw hV h0 h1 h2 h3 S (2*u) n.toNat 0 0 0 0 0 0 0 0 0 (by rfl)] rw [rdot4T_eq V W 0 _ _ _ _ n hs hw hV h0 h1 h2 h3 n.toNat 0 0 0 0 0 0 0 0 0 (by rfl) (Nat.zero_le _), rdot4U_spec] unfold p4 simp only [add_zero] have L : ∀ i:Nat,i< 4→ rdotU V W 0 ((u+USize.ofNat i)*m) n.toNat 0 0 = rdotU V W 0 (USize.ofNat (u.toNat+i)*m) n.toNat 0 0:=fun i hi=>by congr 2 apply USize.toNat_inj.mp rw [uadd u i (by omega),D.uk _ (by omega)] have l0:rdotU V W 0 (u*m) n.toNat 0 0=rdotU V W 0 (USize.ofNat (u.toNat+0)*m) n.toNat 0 0:=by rw [← L 0 (by decide)]; congr 2; apply USize.toNat_inj.mp; rw [uadd u 0 (by omega)]; rfl have l1:rdotU V W 0 ((u+1)*m) n.toNat 0 0=rdotU V W 0 (USize.ofNat (u.toNat+1)*m) n.toNat 0 0 := L 1 (by decide) have l2:rdotU V W 0 ((u+2)*m) n.toNat 0 0=rdotU V W 0 (USize.ofNat (u.toNat+2)*m) n.toNat 0 0 := L 2 (by decide) have l3:rdotU V W 0 ((u+3)*m) n.toNat 0 0=rdotU V W 0 (USize.ofNat (u.toNat+3)*m) n.toNat 0 0 := L 3 (by decide) let F:Nat→ Float:=fun j=>if j % 2=0 then (rdotU V W 0 (USize.ofNat (u.toNat+j / 2)*m) n.toNat 0 0).s else (rdotU V W 0 (USize.ofNat (u.toNat+j / 2)*m) n.toNat 0 0).t have f0:F 0=(rdotU V W 0 (u*m) n.toNat 0 0).s:=by show (if 0 % 2=0 then _ else _)=_; rw [ite_eq_left (by decide),l0] have f1:F 1=(rdotU V W 0 (u*m) n.toNat 0 0).t:=by show (if 1 % 2=0 then _ else _)=_; rw [ite_eq_right (by decide),l0] have f2:F 2=(rdotU V W 0 ((u+1)*m) n.toNat 0 0).s:=by show (if 2 % 2=0 then _ else _)=_; rw [ite_eq_left (by decide),l1] have f3:F 3=(rdotU V W 0 ((u+1)*m) n.toNat 0 0).t:=by show (if 3 % 2=0 then _ else _)=_; rw [ite_eq_right (by decide),l1] have f4:F 4=(rdotU V W 0 ((u+2)*m) n.toNat 0 0).s:=by show (if 4 % 2=0 then _ else _)=_; rw [ite_eq_left (by decide),l2] have f5:F 5=(rdotU V W 0 ((u+2)*m) n.toNat 0 0).t:=by show (if 5 % 2=0 then _ else _)=_; rw [ite_eq_right (by decide),l2] have f6:F 6=(rdotU V W 0 ((u+3)*m) n.toNat 0 0).s:=by show (if 6 % 2=0 then _ else _)=_; rw [ite_eq_left (by decide),l3] have f7:F 7=(rdotU V W 0 ((u+3)*m) n.toNat 0 0).t:=by show (if 7 % 2=0 then _ else _)=_; rw [ite_eq_right (by decide),l3] rw [← f0, ← f1, ← f2, ← f3, ← f4, ← f5, ← f6, ← f7] have P:=put8L S (2*u) F (by rw [e2]; omega) hS rw [e2] at P refine ⟨P.1,fun q => ?_⟩ rw [P.2 q] split_ifs with hq · show (if (q-2*u.toNat) % 2=0 then _ else _)=cdv V W m n q unfold cdv rw [show (q-2*u.toNat) % 2=q % 2 by omega,show u.toNat+(q-2*u.toNat) / 2=q / 2 by omega] · rfl mutual theorem cdZ_spec (V W:FloatArray) (m n Hs:USize) (hHs:Hs.toNat+4< 2 ^ 32) : ∀ (fuel:Nat) (u:USize) (S:FloatArray),cdOK V.size W.size m n Hs fuel u=true → Hs.toNat≤ u.toNat+fuel→ u.toNat≤ Hs.toNat→ 2*Hs.toNat≤ S.size→ S.size< 2 ^ 32 → (cdZ V W m n Hs fuel u S).size=S.size ∧ ∀ q,(cdZ V W m n Hs fuel u S).data[q]! = if 2*u.toNat≤ q∧q< 2*Hs.toNat then cdv V W m n q else S.data[q]! | 0,u,S,_,h1,h2,_,_=>by refine ⟨rfl,fun q => ?_⟩ rw [ite_eq_right (by omega)]; rfl | fuel+1,u,S,hok,h1,h2,h3,h4=>by unfold cdOK at hok unfold cdZ have e4:(u+4).toNat=u.toNat+4:=uadd u 4 (by omega) by_cases c4:u+4≤ Hs · have c4':u.toNat+4≤ Hs.toNat:=by have:=USize.le_iff_toNat_le.mp c4; rwa [e4] at this rw [if_pos c4] at hok ⊢ simp only [Bool.and_eq_true,decide_eq_true_eq] at hok obtain ⟨hg,hrest⟩:=hok rw [dif_pos hg] obtain ⟨p1,p2⟩:=cd4_put V W m n u (D.qA9 hg.1) (D.qA9 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 S (by omega) (by omega) h4 obtain ⟨q1,q2⟩:=cdZ_spec V W m n Hs hHs fuel (u+4) _ hrest (by omega) (by omega) (by rw [p1]; exact h3) (by rw [p1]; exact h4) refine ⟨by rw [q1,p1],fun q => ?_⟩ rw [q2 q,e4,p2 q] clear * - c4' h2 by_cases a:2*(u.toNat+4)≤ q∧q< 2*Hs.toNat · rw [if_pos a,if_pos ⟨by omega,a.2⟩] · rw [if_neg a] by_cases b:2*u.toNat≤ q∧q< 2*u.toNat+8 · rw [if_pos b,if_pos ⟨b.1,by omega⟩] · rw [if_neg b,if_neg (by omega)] · rw [if_neg c4] at hok ⊢ have c4' : ¬ u.toNat+4≤ Hs.toNat:=fun h=>c4 (USize.le_iff_toNat_le.mpr (by rw [e4]; exact h)) by_cases c1:u< Hs · have c1':=USize.lt_iff_toNat_lt.mp c1 rw [if_pos c1] at hok ⊢ dsimp only have e1:(u+1).toNat=u.toNat+1:=uadd1 u (by omega) have e2:(2*u).toNat=2*u.toNat:=by have e:(2:USize).toNat=2:=D.uk 2 (by decide) rw [D.qWm _ _ (by rw [e]; omega),e] have e3:(2*u+1).toNat=2*u.toNat+1:=by rw [uadd1 _ (by rw [e2]; omega),e2] have s1:=D.qD6 S (2*u) (rdotU V W 0 (u*m) n.toNat 0 0).s have s2:=D.qD6 (D.wrF S (2*u) (rdotU V W 0 (u*m) n.toNat 0 0).s) (2*u+1) (rdotU V W 0 (u*m) n.toNat 0 0).t obtain ⟨q1,q2⟩:=cdZ_spec V W m n Hs hHs fuel (u+1) _ hok (by omega) (by omega) (by rw [s2,s1]; exact h3) (by rw [s2,s1]; exact h4) refine ⟨by rw [q1,s2,s1],fun q => ?_⟩ rw [q2 q,e1,D.qEt _ _ _ q (by rw [s1]; exact h4) (by rw [s1,e3]; omega),e3, D.qEt _ _ _ q h4 (by rw [e2]; omega),e2] have eu:USize.ofNat u.toNat=u:=USize.ofNat_toNat clear * - c1' c4' eu by_cases a:2*(u.toNat+1)≤ q∧q< 2*Hs.toNat · rw [if_pos a,if_pos ⟨by omega,a.2⟩] · rw [if_neg a] by_cases b:q=2*u.toNat+1 · rw [if_pos b,if_pos ⟨by omega,by omega⟩] unfold cdv; rw [if_neg (by omega),show q / 2=u.toNat by omega,eu] · rw [if_neg b] by_cases c:q=2*u.toNat · rw [if_pos c,if_pos ⟨by omega,by omega⟩] unfold cdv; rw [if_pos (by omega),show q / 2=u.toNat by omega,eu] · rw [if_neg c,if_neg (by omega)] · rw [if_neg c1] have c1' : ¬ u.toNat< Hs.toNat:=fun h=>c1 (USize.lt_iff_toNat_lt.mpr h) refine ⟨rfl,fun q => ?_⟩ rw [ite_eq_right (by omega)] theorem cout_gate2 (inW H R:Nat) (x wih whh bih bhh h X:Array Word) (t k:Nat) (hk:k< R) (hX : ∀ j,j< inW+H+1→ X[j]! = gA inW H x h t j) : D.C_out (inW+H+1) false X (catW inW H R wih whh bih) (Array.ofFn (n:=R) fun k=>bhh[k.val]!) 0 k = gateWith Pinned.dotFn inW H x wih whh bih bhh h t k:=by unfold D.C_out gateWith rw [Pinned.dotFn_eq_dotOf] simp only [act,Bool.false_eq_true,ite_false,Nat.zero_mul,Nat.zero_add] have n1 : ∀ j, ¬ j< inW+H+1 → ¬ j< inW:=fun j hj h => hj (Nat.lt_of_lt_of_le h (Nat.le_trans (Nat.le_add_right inW H) (Nat.le_add_right _ 1))) have n2 : ∀ j, ¬ j< inW+H+1 → ¬ j< inW+H:=fun j hj h=>hj (Nat.lt_succ_of_lt h) apply dotOf_congr intro j _ constructor · by_cases hj:j< inW+H+1 · rw [if_pos hj,hX j hj]; rfl · rw [if_neg hj,if_neg (n1 j hj),if_neg (n2 j hj)] · by_cases hj:j< inW+H+1 · rw [if_pos hj,catW_get inW H R wih whh bih k j hk hj] by_cases h3:j< inW · rw [if_pos h3,if_pos h3] · by_cases h4:j< inW+H · rw [if_neg h3,if_pos h4,if_neg h3,if_pos h4] · rw [if_neg h3,if_neg h4,if_neg h3,if_neg h4,if_pos (Nat.le_antisymm (Nat.le_of_lt_succ hj) (Nat.le_of_not_lt h4))] · rw [if_neg hj,ofFn_get!F _ k hk,if_neg (n1 j hj),if_neg (n2 j hj), if_neg (fun h=>hj (by rw [h]; exact Nat.lt_succ_self _))] theorem cout_hn (H u:Nat) (h whh bhh:Array Word) (hu:u< H) : D.C_out H false h (wnOf H whh) (Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!) 0 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 unfold D.C_out rw [Pinned.dotFn_eq_dotOf] simp only [act,Bool.false_eq_true,ite_false,Nat.zero_mul,Nat.zero_add] apply dotOf_congr intro j _ refine ⟨rfl, ?_⟩ by_cases hj:j< H · rw [if_pos hj,if_pos hj,wnOf_get H whh u j hu hj] · rw [if_neg hj,if_neg hj,bnOf_get H bhh u hu] theorem bOf_get (b:Array Word) (k:USize) (hk:k.toNat< b.size) (hs:b.size< 2 ^ 32) : D.rdB (D.bOf b) k=dv b[k.toNat]! := by have hsz:(D.bOf b).size=b.size:=by simp [D.bOf,FloatArray.size] rw [D.rdBd _ _ (by rw [hsz]; exact hk) (by rw [hsz]; exact hs)] simp only [D.bOf] rw [getElem!_pos (Array.map dv b) k.toNat (by rw [Array.size_map]; exact hk),getElem!_pos b k.toNat hk, Array.getElem_map] theorem zor1 (y:UInt32):(0xFFFFFFFF:UInt32) ||| y=0xFFFFFFFF:=by apply UInt32.toNat_inj.mp rw [UInt32.toNat_or] have:=y.toNat_lt show 4294967295 ||| y.toNat=4294967295 have e:(4294967295:Nat)=2 ^ 32-1:=rfl rw [e] apply Nat.eq_of_testBit_eq intro i rw [Nat.testBit_or,Nat.testBit_two_pow_sub_one] by_cases hi:i< 32 · simp [hi] · simp only [hi,decide_false] exact Nat.testBit_lt_two_pow (Nat.lt_of_lt_of_le this (Nat.pow_le_pow_right (by norm_num) (by omega))) theorem zand1 (u:UInt32):u &&& 0xFFFFFFFF=u := UInt32.toNat_inj.mp (by rw [UInt32.toNat_and] show u.toNat &&& (2 ^ 32-1)=_ rw [Nat.and_two_pow_sub_one_eq_mod]; exact Nat.mod_eq_of_lt u.toNat_lt) end mutual theorem fzF0 (r:UInt32):D.fz false r=r:=by unfold D.fz; simp only [Bool.false_eq_true,ite_false]; rw [zor1,zand1] theorem xhS_size (inW H:Nat) (x h:Array Word) (t:Nat) (hx:x.size≤ 4294967295) (hh:h.size≤ 4294967295) (hb:t*inW+inW+H+1≤ 4294967295):(xhS inW H x h t).size=inW+H+1:=by unfold xhS rw [if_pos ⟨hx,hh,by omega,by omega⟩] have u0:(0:USize).toNat=0:=rfl have uI:inW.toUSize.toNat=inW:=qAd inW (by omega) have uH:H.toUSize.toNat=H:=qAd H (by omega) have uO:(t*inW).toUSize.toNat=t*inW:=qAd _ (by omega) have hs0:(Array.replicate (inW+H+1) oneW).size=inW+H+1:=Array.size_replicate obtain ⟨s1, -⟩:=wcpW_spec x (t*inW).toUSize 0 inW.toUSize (by omega) (by rw [uO,uI]; omega) (by rw [u0,uI]; omega) _ 0 (Array.replicate (inW+H+1) oneW) rfl (by rw [u0]; exact Nat.zero_le _) (by rw [hs0]; omega) (by rw [hs0,u0,uI]; omega) obtain ⟨s2, -⟩:=wcpW_spec h 0 inW.toUSize H.toUSize (by omega) (by rw [u0,uH]; omega) (by rw [uI,uH]; omega) _ 0 _ rfl (by rw [u0]; exact Nat.zero_le _) (by rw [s1,hs0]; omega) (by rw [s1,hs0,uI,uH]; omega) rw [s2,s1,hs0] end structure GZok (inW H:Nat) (wih whh bih bhh:Array Word):Prop where gw : ∀ i:Nat,good wih[i]! = true gb : ∀ i:Nat,good bih[i]! = true hvr:D.scanH 2 (catW inW H (2*H) wih whh bih)≠ 0xFFFFFFFF bmr:D.scanH 1 (Array.ofFn (n:=2*H) fun k=>bhh[k.val]!)≠ 0xFFFFFFFF hvn:D.scanH 2 (wnOf H whh)≠ 0xFFFFFFFF bmn:D.scanH 1 (Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!)≠ 0xFFFFFFFF hN:inW+H+3< 1048576 h8:inW+H+1≤ 8192 hH:0< H hH1:H< 1024 mutual theorem gzOk (inW H:Nat) (wih whh bih bhh:Array Word) (h:(gzPrep inW H wih whh bih bhh).ok=true) : GZok inW H wih whh bih bhh:=by change gzOK inW H wih whh bih bhh=true at h simp only [gzOK,Bool.and_eq_true,bne_iff_ne,ne_eq,decide_eq_true_eq] at h obtain ⟨⟨⟨⟨⟨⟨⟨⟨⟨a1,a2⟩,a3⟩,a4⟩,a5⟩,a6⟩,a7⟩,a8⟩,a9⟩,a10⟩:=h exact ⟨all_good _ a1,all_good _ a2,a3,a4,a5,a6,a7,a8,a9,a10⟩ theorem finG {I O:Nat} {X W b:Array Word} (hX:X.size=I) (hW:W.size=O*I) (hb:b.size=O) (hI:0< I) (hI2:I< 2 ^ 20) (hOI:O*I< 2 ^ 32) (gX : ∀ q,q< I→ good X[q]! = true) (hv:D.scanH 2 W≠ 0xFFFFFFFF) (hbv:D.scanH 1 b≠ 0xFFFFFFFF) (k:Nat) (hk:k< O) (s A:Float) (hs:s=(List.range I).foldl (fun acc p=>acc+dv X[0*I+p]! * dv W[k*I+p]!) 0) (hA:A=(List.range I).foldl (fun a p=>a+(dv X[0*I+p]!).abs) 0) (slow:Float→ Word) (hsl:slow s=D.fin8 I false X W b 0 k s (nfOf I) A (D.scanH 2 W) b[k]! I.toUSize) : (if (D.fin1 (D.loOf (nfOf I*(dv (D.scanH 2 W)*A+dv (D.scanH 1 b)))) (D.spOf (D.loOf (nfOf I*(dv (D.scanH 2 W)*A+dv (D.scanH 1 b))))) (s+dv b[k]!) == 4294967295)=true then slow s else D.fin1 (D.loOf (nfOf I*(dv (D.scanH 2 W)*A+dv (D.scanH 1 b)))) (D.spOf (D.loOf (nfOf I*(dv (D.scanH 2 W)*A+dv (D.scanH 1 b))))) (s+dv b[k]!)) = D.C_out I false X W b 0 k:=by have hO:O< 2 ^ 32:=by have:O≤ O*I:=Nat.le_mul_of_pos_right _ hI omega have hsW:W.size< 2 ^ 32:=by rw [hW]; exact hOI have hsb:b.size< 2 ^ 32:=by rw [hb]; exact hO have Hv:=D.qA8 2 W hsW hv have Hb:=D.qA8 1 b hsb hbv have G:D.C_G 1 I O X W b:=⟨by rw [hX,Nat.one_mul],hW.symm,hb.symm,hI,by omega,hI2,by rw [hX]; omega, hsW,hsb,by rw [Nat.one_mul]; exact hO,fun q hq=>gX q (by rw [hX] at hq; exact hq),Hv.2.2.1,Hb.2.2.1⟩ obtain ⟨gb1,gb2, -, gb4⟩:=id Hb obtain ⟨pb0,pb1,pb2⟩:=D.qCs gb1 gb2 obtain ⟨fbm,Rbm⟩:=D.qAm _ gb1 have hbm : |D.R (dv b[k]!)| ≤ D.R (dv (D.scanH 1 b)):=by have gj:=Hb.2.2.1 k (by rw [hb]; exact hk) rw [(D.qAm _ gj).2,Rbm]; exact pb2 _ gj (gb4 k (by rw [hb]; exact hk)) have bb:D.R (dv (D.scanH 1 b))≤ 2 ^ (290:ℤ):=by rw [Rbm]; exact pb1.trans (by rw [← zpow_natCast]; exact zpow_le_zpow_right₀ one_le_two (by decide)) have key:=D.qDuF G false (i:=0) (j:=k) (by decide) hk Hv.1 Hv.2.1 (fun q hq=>Hv.2.2.2 _ (by rw [hW]; exact D.qCj hk hq)) (List.range I) List.nodup_range (fun q hq=>List.mem_range.mp hq) (fun q hq hn=>absurd (List.mem_range.mpr hq) hn) hs (dv (D.scanH 1 b)) fbm hbm bb _ rfl rw [← key, ← hA] split · exact hsl · rw [fzF0] end mutual theorem gwZ_eq (inW H:Nat) (x wih whh bih bhh h:Array Word) (t:Nat) (Q:GZq) (g:GW) (hQ:Q=gzPrep inW H wih whh bih bhh) (o:GZok inW H wih whh bih bhh) (hgx : ∀ j,j< inW→ good x[t*inW+j]! = true) (hgh : ∀ j,j< H→ good h[j]! = true) (hxs:x.size≤ 4294967295) (hhs:h.size=H) (hb:t*inW+inW+H+1≤ 4294967295) (k:Nat) (hk:k< 2*H) (hSs:2*H≤ g.S.size) (hSl:g.S.size< 2 ^ 32) (hS:g.S.data[k]! = (List.range (inW+H+1)).foldl (fun acc p=>acc+dv (xhS inW H x h t)[0*(inW+H+1)+p]! * dv Q.Wrz[k*(inW+H+1)+p]!) 0) (hA:g.A=(List.range (inW+H+1)).foldl (fun a p=>a+(dv (xhS inW H x h t)[0*(inW+H+1)+p]!).abs) 0) (hlo:g.lo=D.loOf (nfOf (inW+H+1)*(dv Q.hvr*g.A+Q.bmr))) (hsp:g.sp=D.spOf g.lo) (hnf:g.nf=nfOf (inW+H+1)) : gwZ inW H x h t Q g k.toUSize=gateWith Pinned.dotFn inW H x wih whh bih bhh h t k:=by subst hQ have hN:=o.hN obtain ⟨a1, -, -⟩:=gruBounds inW H (by omega) o.hH1 have hku:k.toUSize.toNat=k:=qAd k (by omega) have sb:(Array.ofFn (n:=2*H) fun k=>bhh[k.val]!).size=2*H:=Array.size_ofFn rw [← cout_gate2 inW H (2*H) x wih whh bih bhh h _ t k hk (fun j hj=>xhS_get inW H x h t j hj), ← finG (xhS_size inW H x h t (by omega) (by omega) hb) (by unfold catW; exact Array.size_ofFn) sb (by omega) (by omega) a1 (fun q hq=>by rw [xhS_get inW H x h t q hq]; unfold gA split_ifs with h1 h2 · exact hgx q h1 · exact hgh (q-inW) (Nat.sub_lt_left_of_lt_add (Nat.le_of_not_lt h1) h2) · exact good_one) o.hvr o.bmr k hk _ _ hS hA (fun s=>rzSlow inW H x h t (catW inW H (2*H) wih whh bih) (Array.ofFn (n:=2*H) fun k=>bhh[k.val]!) k.toUSize s g.nf g.A (D.scanH 2 (catW inW H (2*H) wih whh bih))) (by unfold rzSlow D.fin8u; rw [hku,D.qAg _ _ (by rw [sb]; omega),hku,hnf])] unfold gwZ dsimp only have eB:(gzPrep inW H wih whh bih bhh).Br=D.bOf (Array.ofFn (n:=2*H) fun k=>bhh[k.val]!):=rfl rw [eB,D.rdBd _ _ (by rw [hku]; omega) hSl,hku,bOf_get _ _ (by rw [hku,sb]; exact hk) (by rw [sb]; omega),hku,hsp,hlo] rfl theorem hwZ_eq (inW H:Nat) (wih whh bih bhh h:Array Word) (Q:GZq) (g:GW) (hQ:Q=gzPrep inW H wih whh bih bhh) (o:GZok inW H wih whh bih bhh) (hgh : ∀ j,j< H→ good h[j]! = true) (hhs:h.size=H) (u:Nat) (hu:u< H) (oo:USize) (hoo:oo.toNat+H≤ g.S.size) (hSl:g.S.size< 2 ^ 32) (hS:g.S.data[oo.toNat+u]! = (List.range H).foldl (fun acc p=>acc+dv h[0*H+p]! * dv Q.Wn[u*H+p]!) 0) (hA:g.Ah=(List.range H).foldl (fun a p=>a+(dv h[0*H+p]!).abs) 0) (hlo:g.loh=D.loOf (nfOf H*(dv Q.hvn*g.Ah+Q.bmn))) (hsp:g.sph=D.spOf g.loh) (hnf:g.nfh=nfOf H) : hwZ H h Q g oo u.toUSize=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 subst hQ have hN:=o.hN obtain ⟨-, a2, -⟩:=gruBounds inW H (by omega) o.hH1 have hku:u.toUSize.toNat=u:=qAd u (by omega) have sb:(Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!).size=H:=Array.size_ofFn have hou:(oo+u.toUSize).toNat=oo.toNat+u:=by rw [D.qAf _ _ (by rw [hku]; omega),hku] rw [← cout_hn H u h whh bhh hu, ← finG hhs (by unfold wnOf; exact Array.size_ofFn) sb o.hH (by omega) a2 (fun q hq=>hgh q hq) o.hvn o.bmn u hu _ _ hS hA (fun s=>hnSlow H h (wnOf H whh) (Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!) u.toUSize s g.nfh g.Ah (D.scanH 2 (wnOf H whh))) (by unfold hnSlow D.fin8u; rw [hku,D.qAg _ _ (by rw [sb]; omega),hku,hnf])] unfold hwZ dsimp only have eB:(gzPrep inW H wih whh bih bhh).Bnf=D.bOf (Array.ofFn (n:=H) fun u=>bhh[2*H+u.val]!):=rfl rw [eB,D.rdBd _ _ (by rw [hou]; omega) hSl,hou,bOf_get _ _ (by rw [hku,sb]; exact hu) (by rw [sb]; omega),hku,hsp,hlo] rfl theorem candFU_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) (hgx : ∀ j,j< inW→ good x[t*inW+j]! = true) (V Wc:FloatArray) (hV : ∀ j,j< inW→ V.get! j=dv x[t*inW+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:inW≤ V.size) (hVl:V.size< 2 ^ 32) (hWs:Wc.size=H*(inW+1)) (hWl:H*(inW+1)< 2 ^ 32) (u:Nat) (hu:u< H) (hn r:Word) : candFinU inW H x wih bih t u (dv oneW) (Wc.get! (u*(inW+1)+inW)) (nfOf (inW+2)) (dv 0) hn r (rdotU V Wc 0 (u*(inW+1)).toUSize inW 0 0)=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,k7⟩:=candIdxX inW H u hu hWl 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=>ite_eq_left hj have a1:fa inW=oneW:=by show ite _ _ _=_; rw [ite_eq_right na,ite_eq_left rfl] have a2:fa (inW+1)=hn:=by show ite _ _ _=_; rw [ite_eq_right nb,ite_eq_right nc] have b0 : ∀ j,j< inW→ fb j=wih[(2*H+u)*inW+j]! := fun j hj=>ite_eq_left hj have b1:fb inW=bih[2*H+u]! := by show ite _ _ _=_; rw [ite_eq_right na,ite_eq_left rfl] have b2:fb (inW+1)=r:=by show ite _ _ _=_; rw [ite_eq_right nb,ite_eq_right nc] 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 hj,a0 j hj,hW u j hu (by omega),ite_eq_left hj,b0 j hj] have e2:dv oneW*Wc.get! (u*(inW+1)+inW)=dv (fa inW)*dv (fb inW):=by rw [hW u inW hu (Nat.lt_succ_self _),a1,b1,ite_eq_right na] have hfold:stp (stp (rdotU V Wc 0 (u*(inW+1)).toUSize inW 0 0) (dv oneW*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 hVl (hWs ▸ hWl) _ _ _ _ _ (by rw [show (0:USize).toNat=0 from rfl]; omega) hb2,hun,show (0:USize).toNat=0 from rfl, e1,e2,a2,b2] unfold candFinU 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 [a0 j a]; exact hgx j a · 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 end structure SZ (inW H:Nat) (x wih whh bih bhh h:Array Word) (t:Nat) (Q:GZq) (g:GW) (oo:USize) (V:FloatArray):Prop where hQ:Q=gzPrep inW H wih whh bih bhh o:GZok inW H wih whh bih bhh hgx : ∀ j,j< inW→ good x[t*inW+j]! = true hgh : ∀ j,j< H→ good h[j]! = true hxs:x.size≤ 4294967295 hhs:h.size=H hb:t*inW+inW+H+1≤ 4294967295 hoo:2*H≤ oo.toNat hSs:oo.toNat+H≤ g.S.size hSl:g.S.size< 2 ^ 32 hS : ∀ k,k< 2*H→ g.S.data[k]! = (List.range (inW+H+1)).foldl (fun acc p=>acc+dv (xhS inW H x h t)[0*(inW+H+1)+p]! * dv Q.Wrz[k*(inW+H+1)+p]!) 0 hSn : ∀ u,u< H→ g.S.data[oo.toNat+u]! = (List.range H).foldl (fun acc p=>acc+dv h[0*H+p]! * dv Q.Wn[u*H+p]!) 0 hA:g.A=(List.range (inW+H+1)).foldl (fun a p=>a+(dv (xhS inW H x h t)[0*(inW+H+1)+p]!).abs) 0 hAh:g.Ah=(List.range H).foldl (fun a p=>a+(dv h[0*H+p]!).abs) 0 hlo:g.lo=D.loOf (nfOf (inW+H+1)*(dv Q.hvr*g.A+Q.bmr)) hsp:g.sp=D.spOf g.lo hloh:g.loh=D.loOf (nfOf H*(dv Q.hvn*g.Ah+Q.bmn)) hsph:g.sph=D.spOf g.loh hnf:g.nf=nfOf (inW+H+1) hnfh:g.nfh=nfOf H hScs:2*H≤ g.Sc.size hScl:g.Sc.size< 2 ^ 32 hSc : ∀ u,u< H→ g.Sc.data[2*u]! = (rdotU V Q.Wc 0 (u*(inW+1)).toUSize inW 0 0).s ∧ g.Sc.data[2*u+1]! = (rdotU V Q.Wc 0 (u*(inW+1)).toUSize inW 0 0).t hV : ∀ j,j< inW→ V.get! j=dv x[t*inW+j]! hVs:inW≤ V.size hVl:V.size< 2 ^ 32 theorem uZ_eq (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh h:Array Word) (t:Nat) (Q:GZq) (g:GW) (oo:USize) (V:FloatArray) (z:SZ inW H x wih whh bih bhh h t Q g oo V) (u:Nat) (hu:u< H) : uZ sig tanh inW H x wih bih h t Q g (dv oneW) (nfOf (inW+2)) (dv 0) (dv oneW) (nfOf 3) H.toUSize (inW+1).toUSize inW.toUSize oo u.toUSize=gS sig tanh inW H x wih whh bih bhh h t u:=by have hQ:=z.hQ have o:=z.o have hN:=o.hN obtain ⟨-, -, hl3⟩:=gruBounds inW H (by omega) o.hH1 have sc:=rowsWc_facts inW H wih bih have hWc:Q.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))):=by rw [hQ]; rfl rw [← hWc] at sc have hku:u.toUSize.toNat=u:=qAd u (by omega) have eH:(H.toUSize+u.toUSize)=(H+u).toUSize:=USize.toNat_inj.mp (by rw [D.qAf _ _ (by rw [qAd H (by omega),hku]; omega),qAd H (by omega),hku,qAd _ (by omega)]) have g1:=gwZ_eq inW H x wih whh bih bhh h t Q g hQ o z.hgx z.hgh z.hxs z.hhs z.hb u (by omega) (by have:=z.hSs; have:=z.hoo; omega) z.hSl (z.hS u (by omega)) z.hA z.hlo z.hsp z.hnf have g2:=gwZ_eq inW H x wih whh bih bhh h t Q g hQ o z.hgx z.hgh z.hxs z.hhs z.hb (H+u) (by omega) (by have:=z.hSs; have:=z.hoo; omega) z.hSl (z.hS (H+u) (by omega)) z.hA z.hlo z.hsp z.hnf have g3:=hwZ_eq inW H wih whh bih bhh h Q g hQ o z.hgh z.hhs u hu oo z.hSs z.hSl (z.hSn u hu) z.hAh z.hloh z.hsph z.hnfh have eW:D.rdB Q.Wc (u.toUSize*(inW+1).toUSize+inW.toUSize)=Q.Wc.get! (u*(inW+1)+inW):=by have b1:(u+1)*(inW+1)≤ H*(inW+1):=Nat.mul_le_mul_right _ hu rw [Nat.add_mul,Nat.one_mul] at b1 have m1:(u.toUSize*(inW+1).toUSize).toNat=u*(inW+1):=by rw [D.qWm _ _ (by rw [hku,qAd _ (by omega)]; omega),hku,qAd _ (by omega)] have m2:(u.toUSize*(inW+1).toUSize+inW.toUSize).toNat=u*(inW+1)+inW:=by rw [D.qAf _ _ (by rw [m1,qAd inW (by omega)]; omega),m1,qAd inW (by omega)] rw [D.rdBd _ _ (by rw [m2,sc.1]; omega) (by rw [sc.1]; exact hl3),m2, ← fget_data] have e2u:(2*u.toUSize).toNat=2*u:=by have e:(2:USize).toNat=2:=D.uk 2 (by decide) rw [D.qWm _ _ (by rw [e,hku]; omega),e,hku] have e2u1:(2*u.toUSize+1).toNat=2*u+1:=by rw [uadd1 _ (by rw [e2u]; omega),e2u] obtain ⟨c1,c2⟩:=z.hSc u hu have eS:(⟨D.rdB g.Sc (2*u.toUSize),D.rdB g.Sc (2*u.toUSize+1)⟩:F1) = rdotU V Q.Wc 0 (u*(inW+1)).toUSize inW 0 0:=by rw [D.rdBd _ _ (by rw [e2u]; have:=z.hScs; omega) z.hScl,D.rdBd _ _ (by rw [e2u1]; have:=z.hScs; omega) z.hScl, e2u,e2u1,c1,c2] have hc:=candFU_eq inW H x wih bih t (by omega) o.gw o.gb z.hgx V Q.Wc z.hV sc.2 z.hVs z.hVl sc.1 hl3 u hu have eh:D.rdW h u.toUSize=h[u]! := by rw [D.qAg h _ (by rw [z.hhs]; omega),hku] unfold uZ dsimp only rw [g1,eH,g2,g3,eW,eS,hku,hc,eh] have eu : ∀ a b c:Word,updU a b c (dv oneW) (dv 0) (nfOf 3)=updF a b c:=fun a b c=>rfl rw [eu,updF_eq] unfold gS rfl mutual theorem uZ_eq' (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh h:Array Word) (t:Nat) (Q:GZq) (g:GW) (oo:USize) (V:FloatArray) (z:SZ inW H x wih whh bih bhh h t Q g oo V) (u:USize) (hu:u.toNat< H) : uZ sig tanh inW H x wih bih h t Q g (dv oneW) (nfOf (inW+2)) (dv 0) (dv oneW) (nfOf 3) H.toUSize (inW+1).toUSize inW.toUSize oo u=gS sig tanh inW H x wih whh bih bhh h t u.toNat:=by rw [← uZ_eq sig tanh inW H x wih whh bih bhh h t Q g oo V z u.toNat hu] congr 1 exact (USize.ofNat_toNat).symm theorem stepW (T S:Array Word) (i:USize) (K m:Nat) (g:Nat→ Word) (v:Word) (hv:g (K+m)=v) (hi:i.toNat=K+m) (hT:T.size< 2 ^ 32) (hiT:K+m< T.size) (h : ∀ q,T[q]! = if K≤ q∧q< K+m then g q else S[q]!) : ∀ q,(D.wrW T i v)[q]! = if K≤ q∧q< K+(m+1) then g q else S[q]! := by intro q rw [D.qBu T i _ q hT (by rw [hi]; exact hiT),h q,hi, ← hv] by_cases e:q=K+m · rw [if_pos e,if_pos ⟨by omega,by omega⟩,e] · rw [if_neg e] by_cases r:K≤ q∧q< K+m · rw [if_pos r,if_pos ⟨r.1,by omega⟩] · rw [if_neg r,if_neg (by omega)] end mutual theorem loop4B (H K:Nat) (Hs wb:USize) (eH:Hs.toNat=H) (ew:wb.toNat=K) (hH:K+H+4< 2 ^ 32) (B0:Array Word) (f:Array Word→ USize→ Word) (gv:Nat→ Word) (hf : ∀ (B:Array Word) (u:USize),B.size=B0.size→ (∀ q,q< K→ B[q]! = B0[q]!)→ u.toNat< H → f B u=gv u.toNat) (F:Nat→ USize→ Array Word→ Array Word) (h0 : ∀ u B,F 0 u B=B) (h4 : ∀ fuel u B,u+4≤ Hs→ F (fuel+1) u B = F fuel (u+4) (D.wrW (D.wrW (D.wrW (D.wrW B (wb+u) (f B u)) (wb+(u+1)) (f B (u+1))) (wb+(u+2)) (f B (u+2))) (wb+(u+3)) (f B (u+3)))) (h1 : ∀ fuel u B, ¬ u+4≤ Hs→ u< Hs→ F (fuel+1) u B=F fuel (u+1) (D.wrW B (wb+u) (f B u))) (hE : ∀ fuel u B, ¬ u+4≤ Hs → ¬ u< Hs→ F (fuel+1) u B=B) (hB0:K+H≤ B0.size) (hB0l:B0.size< 2 ^ 32) : ∀ (fuel:Nat) (u:USize) (B:Array Word),B.size=B0.size→ (∀ q,q< K→ B[q]! = B0[q]!) → H≤ u.toNat+fuel→ u.toNat≤ H → (F fuel u B).size=B0.size ∧ ∀ q,(F fuel u B)[q]! = if K+u.toNat≤ q∧q< K+H then gv (q-K) else B[q]! | 0,u,B,hs,hk,h1',h2=>by refine ⟨by rw [h0]; exact hs,fun q => ?_⟩ rw [h0,ite_eq_right (by omega)] | fuel+1,u,B,hs,hk,h1',h2=>by have e4:(u+4).toNat=u.toNat+4:=uadd u 4 (by omega) have e1:(u+1).toNat=u.toNat+1:=uadd u 1 (by omega) have e2:(u+2).toNat=u.toNat+2:=uadd u 2 (by omega) have e3:(u+3).toNat=u.toNat+3:=uadd u 3 (by omega) have hl:B.size< 2 ^ 32:=by omega have sz : ∀ (T:Array Word) (i:USize) (v:Word),(D.wrW T i v).size=T.size:=D.qBh have g : ∀ q,gv (q-K)=(fun q=>gv (q-K)) q:=fun q=>rfl have h00 : ∀ q,B[q]! = if K+u.toNat≤ q∧q< K+u.toNat+0 then gv (q-K) else B[q]! := fun q=>(if_neg (fun h=>Nat.lt_irrefl _ (Nat.lt_of_le_of_lt h.1 h.2))).symm have ea : ∀ m:Nat,m< 4→ (wb+(u+USize.ofNat m)).toNat=K+u.toNat+m:=fun m hm=>by rw [D.qAf _ _ (by rw [ew,uadd u m (by omega)]; omega),ew,uadd u m (by omega)]; omega have ea0:(wb+u).toNat=K+u.toNat+0:=by rw [D.qAf _ _ (by rw [ew]; omega),ew]; rfl have ea1:(wb+(u+1)).toNat=K+u.toNat+1:=ea 1 (by decide) have ea2:(wb+(u+2)).toNat=K+u.toNat+2:=ea 2 (by decide) have ea3:(wb+(u+3)).toNat=K+u.toNat+3:=ea 3 (by decide) by_cases c4:u+4≤ Hs · have c4':u.toNat+4≤ H:=by have:=USize.le_iff_toNat_le.mp c4; rwa [e4,eH] at this rw [h4 fuel u B c4,hf B u hs hk (by omega),hf B (u+1) hs hk (by omega),hf B (u+2) hs hk (by omega), hf B (u+3) hs hk (by omega),e1,e2,e3] have w1:=stepW B B (wb+u) (K+u.toNat) 0 (fun q=>gv (q-K)) (gv u.toNat) (by simp) ea0 hl (by omega) h00 have w2:=stepW _ B (wb+(u+1)) (K+u.toNat) 1 (fun q=>gv (q-K)) (gv (u.toNat+1)) (by show gv _=_; congr 1; omega) ea1 (by rw [sz]; exact hl) (by rw [sz]; omega) w1 have w3:=stepW _ B (wb+(u+2)) (K+u.toNat) 2 (fun q=>gv (q-K)) (gv (u.toNat+2)) (by show gv _=_; congr 1; omega) ea2 (by rw [sz,sz]; exact hl) (by rw [sz,sz]; omega) w2 have w4:=stepW _ B (wb+(u+3)) (K+u.toNat) 3 (fun q=>gv (q-K)) (gv (u.toNat+3)) (by show gv _=_; congr 1; omega) ea3 (by rw [sz,sz,sz]; exact hl) (by rw [sz,sz,sz]; omega) w3 obtain ⟨r1,r2⟩:=loop4B H K Hs wb eH ew hH B0 f gv hf F h0 h4 h1 hE hB0 hB0l fuel (u+4) (D.wrW (D.wrW (D.wrW (D.wrW B (wb+u) (gv u.toNat)) (wb+(u+1)) (gv (u.toNat+1))) (wb+(u+2)) (gv (u.toNat+2))) (wb+(u+3)) (gv (u.toNat+3))) (by rw [sz,sz,sz,sz,hs]) (fun q hq=>by rw [w4 q,if_neg (by omega)]; exact hk q hq) (by omega) (by omega) refine ⟨r1,fun q => ?_⟩ rw [r2 q,e4,w4 q] clear * - c4' h2 by_cases a:K+(u.toNat+4)≤ q∧q< K+H · rw [if_pos a,if_pos ⟨by omega,a.2⟩] · rw [if_neg a] by_cases b:K+u.toNat≤ q∧q< K+u.toNat+(3+1) · rw [if_pos b,if_pos ⟨b.1,by omega⟩] · rw [if_neg b,if_neg (by omega)] · have c4' : ¬ u.toNat+4≤ H:=fun h=>c4 (USize.le_iff_toNat_le.mpr (by rw [e4,eH]; exact h)) by_cases c1:u< Hs · have c1':u.toNat< H:=by have:=USize.lt_iff_toNat_lt.mp c1; rwa [eH] at this rw [h1 fuel u B c4 c1,hf B u hs hk c1'] have w1:=stepW B B (wb+u) (K+u.toNat) 0 (fun q=>gv (q-K)) (gv u.toNat) (by simp) ea0 hl (by omega) h00 obtain ⟨r1,r2⟩:=loop4B H K Hs wb eH ew hH B0 f gv hf F h0 h4 h1 hE hB0 hB0l fuel (u+1) (D.wrW B (wb+u) (gv u.toNat)) (by rw [sz,hs]) (fun q hq=>by rw [w1 q,if_neg (by omega)]; exact hk q hq) (by omega) (by omega) refine ⟨r1,fun q => ?_⟩ rw [r2 q,e1,w1 q] clear * - c1' h2 by_cases a:K+(u.toNat+1)≤ q∧q< K+H · rw [if_pos a,if_pos ⟨by omega,a.2⟩] · rw [if_neg a] by_cases b:K+u.toNat≤ q∧q< K+u.toNat+(0+1) · rw [if_pos b,if_pos ⟨b.1,by omega⟩] · rw [if_neg b,if_neg (by omega)] · have c1' : ¬ u.toNat< H:=fun h=>c1 (USize.lt_iff_toNat_lt.mpr (by rw [eH]; exact h)) rw [hE fuel u B c4 c1] refine ⟨hs,fun q => ?_⟩ rw [ite_eq_right (by omega)] theorem hOf_size (H:Nat) (B:Array Word) (t:Nat) (ht:t*H≤ B.size):(hOf H B t).size=H:=by unfold hOf split · exact Array.size_replicate · rename_i h0 have e:(t-1)*H+H=t*H:=by obtain ⟨s,rfl⟩ : ∃ s,t=s+1:=⟨t-1,by omega⟩ rw [Nat.add_sub_cancel,Nat.succ_mul] rw [Array.size_extract,e,Nat.min_eq_left ht] obtain ⟨s,rfl⟩ : ∃ s,t=s+1:=⟨t-1,by omega⟩ rw [Nat.add_sub_cancel,Nat.succ_mul]; omega end theorem hOf_get (H:Nat) (B:Array Word) (t j:Nat) (hj:j< H) (ht:t*H≤ B.size) : (hOf H B t)[j]! = if t=0 then 0 else B[(t-1)*H+j]! := by have hs:=hOf_size H B t ht unfold hOf at hs ⊢ split · rw [getElem!_pos _ j (by rw [Array.size_replicate]; exact hj),Array.getElem_replicate] · rename_i h0 have e:(t-1)*H+H=t*H:=by obtain ⟨s,rfl⟩ : ∃ s,t=s+1:=⟨t-1,by omega⟩ rw [Nat.add_sub_cancel,Nat.succ_mul] rw [getElem!_pos _ j (by rw [Array.size_extract]; omega),Array.getElem_extract,getElem!_pos _ _ (by omega)] mutual theorem hOf_agree (H:Nat) (B B':Array Word) (t:Nat) (hs:B'.size=B.size) (ht:t*H≤ B.size) (hk : ∀ q,q< t*H→ B'[q]! = B[q]!):hOf H B' t=hOf H B t:=by have s1:=hOf_size H B t ht have s2:=hOf_size H B' t (by rw [hs]; exact ht) apply Array.ext · rw [s1,s2] · intro j h1 h2 rw [← getElem!_pos _ j h1, ← getElem!_pos _ j h2,hOf_get H B' t j (by omega) (by rw [hs]; exact ht), hOf_get H B t j (by omega) ht] split · rfl · have e:(t-1)*H+H=t*H:=by obtain ⟨s,rfl⟩ : ∃ s,t=s+1:=⟨t-1,by omega⟩ rw [Nat.add_sub_cancel,Nat.succ_mul] have:=s2 ▸ h1 exact hk _ (by omega) theorem rd_hOf (H:Nat) (B:Array Word) (t:Nat) (u:USize) (hu:u.toNat< H) (ht:t*H≤ B.size) (hl:B.size+H< 2 ^ 32) : D.rdW B ((if t=0 then B.usize else (t*H).toUSize-H.toUSize)+u)=(hOf H B t)[u.toNat]! := by rw [hOf_get H B t u.toNat hu ht,D.qAg B _ (by omega)] split · rename_i h0 have e:B.usize.toNat=B.size:=qAd _ (by omega) rw [D.qAf _ _ (by rw [e]; omega),e,getElem!_neg _ _ (by omega)] rfl · rename_i h0 have e:(t-1)*H+H=t*H:=by obtain ⟨s,rfl⟩ : ∃ s,t=s+1:=⟨t-1,by omega⟩ rw [Nat.add_sub_cancel,Nat.succ_mul] have eT:(t*H).toUSize.toNat=t*H:=qAd _ (by omega) have eH:H.toUSize.toNat=H:=qAd _ (by omega) have es:((t*H).toUSize-H.toUSize).toNat=(t-1)*H:=by rw [USize.toNat_sub_of_le _ _ (USize.le_iff_toNat_le.mpr (by rw [eT,eH]; omega)),eT,eH]; omega rw [D.qAf _ _ (by rw [es]; omega),es] theorem rzSlowO_eq (inW H:Nat) (x B:Array Word) (t:Nat) (W b:Array Word) (u:USize) (s nf A:Float) (hv:Word):rzSlowO inW H x B t W b u s nf A hv=rzSlow inW H x (hOf H B t) t W b u s nf A hv:=by unfold rzSlowO rzSlowX rzSlow dsimp only split · rfl · rename_i hr unfold D.fin8u D.fin8 dsimp only rw [if_neg hr] exact (fzF0 _).symm theorem hnSlowO_eq (H:Nat) (B:Array Word) (t:Nat) (W b:Array Word) (u:USize) (s nf A:Float) (hv:Word):hnSlowO H B t W b u s nf A hv=hnSlow H (hOf H B t) W b u s nf A hv:=by unfold hnSlowO hnSlowX hnSlow dsimp only split · rfl · rename_i hr unfold D.fin8u D.fin8 dsimp only rw [if_neg hr] exact (fzF0 _).symm end theorem uF_eq (sig tanh:Word→ Word) (inW H:Nat) (x wih bih:Array Word) (t:Nat) (Q:GZq) (S Sc:FloatArray) (lo sp loh sph:UInt64) (nf A nfh Ah:Float) (v1 nfc z0 one nf3:Float) (Hs mI i o rb:USize) (B:Array Word) (u:USize) (hr:D.rdW B (rb+u)=D.rdW (hOf H B t) u) : uF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah v1 nfc z0 one nf3 Hs mI i o rb B u = uZ sig tanh inW H x wih bih (hOf H B t) t Q ⟨S,Sc,lo,sp,loh,sph,nf,A,nfh,Ah⟩ v1 nfc z0 one nf3 Hs mI i o u:=by unfold uF uZ gwF hwF gwZ hwZ dsimp only rw [hr] simp only [rzSlowO_eq,hnSlowO_eq] mutual theorem unitsF_spec (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh:Array Word) (t:Nat) (Q:GZq) (S Sc:FloatArray) (lo sp loh sph:UInt64) (nf A nfh Ah:Float) (oo:USize) (V:FloatArray) (B0:Array Word) (z:SZ inW H x wih whh bih bhh (hOf H B0 t) t Q ⟨S,Sc,lo,sp,loh,sph,nf,A,nfh,Ah⟩ oo V) (hB0:t*H+H≤ B0.size) (hB0l:B0.size+H+4< 2 ^ 32) : (unitsF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah (dv oneW) (nfOf (inW+2)) (dv 0) (dv oneW) (nfOf 3) H.toUSize (inW+1).toUSize inW.toUSize oo (if t=0 then B0.usize else (t*H).toUSize-H.toUSize) (t*H).toUSize H 0 B0).size=B0.size ∧ ∀ q,(unitsF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah (dv oneW) (nfOf (inW+2)) (dv 0) (dv oneW) (nfOf 3) H.toUSize (inW+1).toUSize inW.toUSize oo (if t=0 then B0.usize else (t*H).toUSize-H.toUSize) (t*H).toUSize H 0 B0)[q]! = if t*H≤ q∧q< t*H+H then gS sig tanh inW H x wih whh bih bhh (hOf H B0 t) t (q-t*H) else B0[q]! := by have hN:=z.o.hN have r:=loop4B H (t*H) H.toUSize (t*H).toUSize (qAd H (by omega)) (qAd _ (by omega)) (by omega) B0 (fun B u=>uF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah (dv oneW) (nfOf (inW+2)) (dv 0) (dv oneW) (nfOf 3) H.toUSize (inW+1).toUSize inW.toUSize oo (if t=0 then B0.usize else (t*H).toUSize-H.toUSize) B u) (fun u=>gS sig tanh inW H x wih whh bih bhh (hOf H B0 t) t u) (fun B u hs hk hu=>by have ag:=hOf_agree H B0 B t hs (by omega) hk have eu:B0.usize=B.usize:=by unfold Array.usize; rw [hs] rw [uF_eq _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ (by rw [eu,rd_hOf H B t u hu (by omega) (by omega),D.qAg _ _ (by rw [hOf_size H B t (by omega)]; omega)]),ag] exact uZ_eq' sig tanh inW H x wih whh bih bhh _ t Q _ oo V z u hu) (unitsF sig tanh inW H x wih bih t Q S Sc lo sp loh sph nf A nfh Ah (dv oneW) (nfOf (inW+2)) (dv 0) (dv oneW) (nfOf 3) H.toUSize (inW+1).toUSize inW.toUSize oo (if t=0 then B0.usize else (t*H).toUSize-H.toUSize) (t*H).toUSize) (fun _ _=>rfl) (fun fuel u B c4=>by rw [unitsF,if_pos c4]; rfl) (fun fuel u B c4 c1=>by rw [unitsF,if_neg c4,if_pos c1]) (fun fuel u B c4 c1=>by rw [unitsF,if_neg c4,if_neg c1]) (by omega) (by omega) H 0 B0 rfl (fun _ _=>rfl) (by simp) (by simp) simpa using r theorem wnN_get (inW H:Nat) (whh:Array Word) (u p:Nat) (hu:u< H) (hp:p< H) : (wnN inW H whh)[u*(inW+H+1)+(inW+p)]! = whh[(2*H+u)*H+p]! := by obtain ⟨hm,hd⟩:=catIdx (inW+H+1) u (inW+p) (by omega) unfold wnN rw [ofFn_get!F _ _ (idx_lt u (inW+p) _ H hu (by omega))] simp only [hm,hd] rw [if_pos ⟨by omega,by omega⟩,show inW+p-inW=p by omega] theorem umulE (u a:Nat) (hu:u< 2 ^ 32) (ha:a< 2 ^ 32) (h:u*a< 2 ^ 32) : USize.ofNat u*a.toUSize=(u*a).toUSize:=by apply USize.toNat_inj.mp have e1:(USize.ofNat u).toNat=u:=D.uk u hu have e2:a.toUSize.toNat=a:=qAd a ha rw [D.qWm _ _ (by rw [e1,e2]; exact h),e1,e2,qAd _ h] theorem sumsOK_ws (vs ws:Nat) (m n:USize) (nb:Nat) (p:USize) (h:sumsOK vs ws m n (nb+1) p=true) : ws≤ 4294967295:=by unfold sumsOK at h split at h · simp only [Bool.and_eq_true,decide_eq_true_eq] at h; exact h.1.2.2.2.2 · simp only [decide_eq_true_eq] at h; exact h.2.2.2 theorem gruStep_ofFn (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh:Array Word) (t:Nat) (st:Array Word × Array Word) : (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t st).1 = Array.ofFn (n:=H) fun i=>gS sig tanh inW H x wih whh bih bhh st.1 t i.val:=by unfold gruStepWith dsimp only congr 1; funext u unfold gS repeat (rw [ofFn_get!F _ _ u.isLt]; try dsimp only) end mutual theorem loopF_step (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh:Array Word) (Q:GZq) (hQ:Q=gzPrep inW H wih whh bih bhh) (hok:Q.ok=true) (hxs:x.size≤ 4294967295) (hsR:sumsOK (zS (inW+H+1)).size Q.Pr.size (inW+H+1).toUSize (inW+H+1).toUSize ((2*H+7) / 8) 5=true) (hsN:sumsOK (zS (inW+H+1)).size Q.Pn.size (inW+H+1).toUSize (inW+H).toUSize ((H+7) / 8) 5=true) (hcd:cdOK (zS (inW+H+1)).size Q.Wc.size (inW+1).toUSize inW.toUSize H.toUSize H 0=true) (t n:Nat) (B:Array Word) (V0 S0 Sc0:FloatArray) (hV0:V0.size=(zS (inW+H+1)).size) (hS0:S0.size=(zS (8*((2*H+7) / 8)+8*((H+7) / 8))).size) (hSc0:Sc0.size=(zS (2*H)).size) (hBt:t*H+H≤ B.size) (hBl:B.size+H+4< 2 ^ 32) : ∃ V' S' Sc':FloatArray,V'.size=V0.size∧S'.size=S0.size∧Sc'.size=Sc0.size ∧ loopF sig tanh inW H x wih whh bih bhh Q t (n+1) B V0 S0 Sc0 = loopF sig tanh inW H x wih whh bih bhh Q (t+1) n (wcpW (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (hOf H B t, #[])).1 0 (t*H).toUSize H.toUSize 0 B) V' S' Sc':=by have o:=gzOk inW H wih whh bih bhh (hQ ▸ hok) have hN:=o.hN have h8:=o.h8 have hH0:=o.hH obtain ⟨a1,a2,a3⟩:=gruBounds inW H (by omega) o.hH1 have hhs:(hOf H B t).size=H:=hOf_size H B t (by omega) have hrd : ∀ j:USize,j.toNat< H→ D.rdW B ((if t=0 then B.usize else (t*H).toUSize-H.toUSize)+j) = D.rdW (hOf H B t) j:=fun j hj=>by rw [rd_hOf H B t j hj (by omega) (by omega),D.qAg _ j (by rw [hhs]; omega)] have edh:=dhB_eq B (hOf H B t) (if t=0 then B.usize else (t*H).toUSize-H.toUSize) inW.toUSize H hrd H 0 rw [loopF] dsimp only generalize hrb:(if t=0 then B.usize else (t*H).toUSize-H.toUSize)=rb at hrd edh ⊢ split_ifs with hb hd · subst hrb rw [edh _ _ _ _ (by simp) (by omega)] at hd ⊢ set N:=inW+H+1 with hNdef set h:=hOf H B t with hhdef obtain ⟨z1,z2⟩:=zS_size N (by omega) obtain ⟨d1,d2,d3,d4,d5⟩:=decV_spec inW H x h t (by omega) (by omega) hb V0 (by rw [hV0]; exact z1) (by rw [hV0]; exact z2) set d:=dhZ h inW.toUSize H 0 (dxZ x (t*inW).toUSize inW 0 V0 0 true).V (dxZ x (t*inW).toUSize inW 0 V0 0 true).A 0 (dxZ x (t*inW).toUSize inW 0 V0 0 true).ok with hddef obtain ⟨gx,gh⟩:=d5 hd set V:=d.V with hVdef have eN:N.toUSize.toNat=N:=qAd N (by omega) have eI:inW.toUSize.toNat=inW:=qAd inW (by omega) have eIH:(inW+H).toUSize.toNat=inW+H:=qAd _ (by omega) have e5:(5:USize).toNat=8*0*N+5:=by have e:(5:USize).toNat=5:=D.uk 5 (by decide) rw [e]; simp have hPr:Q.Pr=D.wbOf N (2*H) Q.Wrz:=by rw [hQ]; rfl have hWrz:Q.Wrz=catW inW H (2*H) wih whh bih:=by rw [hQ]; rfl have sWrz:Q.Wrz.size=2*H*N:=by rw [hWrz]; unfold catW; exact Array.size_ofFn have hnbR:(2*H+7) / 8=(2*H-1) / 8+1:=by omega have wsR:Q.Pr.size≤ 4294967295:=sumsOK_ws _ _ _ _ ((2*H-1) / 8) 5 (by rw [← hnbR]; exact hsR) obtain ⟨zz1,zz2⟩:8*((2*H+7) / 8)+8*((H+7) / 8)≤ S0.size∧S0.size< 2 ^ 32:=by rw [hS0]; exact zS_size _ (by omega) obtain ⟨sR1,sR2⟩:=sumsZ_spec V Q.Wrz N (2*H) N.toUSize N.toUSize 0 eN (by rw [← hPr]; omega) (by rw [sWrz]; exact a1) (by rw [sWrz]) (by rw [eN]; exact h8) (by rw [eN]; exact Nat.zero_le _) ((2*H+7) / 8) 0 5 0 S0 (by omega) e5 (by show 0+_≤ _; omega) zz2 (by rw [← hPr,hVdef,d1,hV0]; exact hsR) have hPn:Q.Pn=D.wbOf N H (wnN inW H whh):=by rw [hQ]; rfl have sWn:(wnN inW H whh).size=H*N:=by unfold wnN; exact Array.size_ofFn have hnbN:(H+7) / 8=(H-1) / 8+1:=by omega have wsN:Q.Pn.size≤ 4294967295:=sumsOK_ws _ _ _ _ ((H-1) / 8) 5 (by rw [← hnbN]; exact hsN) have eo:(8*((2*H+7) / 8)).toUSize.toNat=8*((2*H+7) / 8):=qAd _ (by omega) obtain ⟨sN1,sN2⟩:=sumsZ_spec V (wnN inW H whh) N H N.toUSize (inW+H).toUSize inW.toUSize eN (by rw [← hPn]; omega) (by rw [sWn]; exact Nat.lt_of_le_of_lt (Nat.le_mul_of_pos_left (H*N) (show 0< 2 by decide)) (by rw [← Nat.mul_assoc]; exact a1)) (by rw [sWn]) (by rw [eIH]; omega) (by rw [eI,eIH]; omega) ((H+7) / 8) 0 5 (8*((2*H+7) / 8)).toUSize _ (by omega) e5 (by rw [eo,sR1]; omega) (by rw [sR1]; exact zz2) (by rw [← hPn,hVdef,d1,hV0]; exact hsN) rw [← hPr] at sR1 sR2 sN1 sN2 rw [← hPn] at sN1 sN2 have hWcq:Q.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))):=by rw [hQ]; rfl have sc:=rowsWc_facts inW H wih bih rw [← hWcq] at sc obtain ⟨y1,y2⟩:2*H≤ Sc0.size∧Sc0.size< 2 ^ 32:=by rw [hSc0]; exact zS_size _ (by omega) have eH:H.toUSize.toNat=H:=qAd H (by omega) obtain ⟨c1,c2⟩:=cdZ_spec V Q.Wc (inW+1).toUSize inW.toUSize H.toUSize (by rw [eH]; omega) H 0 Sc0 (by rw [hVdef,d1,hV0]; exact hcd) (by rw [eH]; simp) (by rw [eH]; simp) (by rw [eH]; exact y1) y2 set S1:=sumsZ V Q.Pr N.toUSize N.toUSize 0 ((2*H+7) / 8) 5 0 S0 with hS1 set S2:=sumsZ V Q.Pn N.toUSize (inW+H).toUSize inW.toUSize ((H+7) / 8) 5 (8*((2*H+7) / 8)).toUSize S1 with hS2 set Sc:=cdZ V Q.Wc (inW+1).toUSize inW.toUSize H.toUSize H 0 Sc0 with hSc set gg:GW:=⟨S2,Sc,D.loOf (nfOf N*(dv Q.hvr*d.A+Q.bmr)),D.spOf (D.loOf (nfOf N*(dv Q.hvr*d.A+Q.bmr))), D.loOf (nfOf H*(dv Q.hvn*d.Ah+Q.bmn)),D.spOf (D.loOf (nfOf H*(dv Q.hvn*d.Ah+Q.bmn))),nfOf N,d.A, nfOf H,d.Ah⟩ with hgg have z:SZ inW H x wih whh bih bhh h t Q gg (8*((2*H+7) / 8)).toUSize V := { hQ:=hQ,o:=o,hgx:=gx,hgh:=gh,hxs:=hxs,hhs:=hhs,hb:=hb hoo:=by rw [eo]; omega hSs:=by show _≤ S2.size; rw [sN1,sR1,eo]; omega hSl:=by show S2.size< _; rw [sN1,sR1]; exact zz2 hS:=fun k hk=>by show S2.data[k]! = _ rw [sN2 k,eo,if_neg (by omega),sR2 k,if_pos (by show 0≤ k∧k< 0+8*_; omega)] unfold laneZ simp only [show (0:USize).toNat=0 from rfl,eN,Nat.sub_zero,Nat.zero_add] rw [← List.range_eq_range',show min (8*(k / 8)+k % 8) (2*H-1)=k by omega] refine foldl_cgm _ _ _ _ (fun q hq a => ?_) rw [List.mem_range] at hq rw [Nat.zero_mul,Nat.zero_add,xhS_get inW H x h t q hq,d2 q hq] hSn:=fun u hu=>by show S2.data[_]! = _ rw [sN2 _,eo,if_pos (by omega)] unfold laneZ rw [eI,eIH,show inW+H-inW=H by omega,show 8*((2*H+7) / 8)+u-8*((2*H+7) / 8)=u by omega, show min (8*(0+u / 8)+u % 8) (H-1)=u by omega,List.range'_eq_map_range,List.foldl_map] refine foldl_cgm _ _ _ _ (fun q hq a => ?_) rw [List.mem_range] at hq rw [d2 (inW+q) (by omega),wnN_get inW H whh u q hu hq,Nat.zero_mul,Nat.zero_add, show (Q.Wn)[u*H+q]! = whh[(2*H+u)*H+q]! by rw [hQ]; exact wnOf_get H whh u q hu hq] unfold gA rw [if_neg (by omega),if_pos (by omega),show inW+q-inW=q by omega] hA:=by show d.A=_ rw [d3] refine foldl_cgm _ _ _ _ (fun q hq a => ?_) rw [List.mem_range] at hq rw [Nat.zero_mul,Nat.zero_add,xhS_get inW H x h t q hq] hAh:=by show d.Ah=_; rw [d4]; simp only [Nat.zero_mul,Nat.zero_add] hlo:=rfl,hsp:=rfl,hloh:=rfl,hsph:=rfl,hnf:=rfl,hnfh:=rfl hScs:=by show 2*H≤ Sc.size; rw [c1]; exact y1 hScl:=by show Sc.size< _; rw [c1]; exact y2 hSc:=fun u hu=>by have hua:u*(inW+1)< 2 ^ 32:=by have:u*(inW+1)≤ H*(inW+1):=Nat.mul_le_mul_right _ (Nat.le_of_lt hu) omega have eu:USize.ofNat u*(inW+1).toUSize=(u*(inW+1)).toUSize:=umulE u (inW+1) (by omega) (by omega) hua show Sc.data[2*u]! = _∧Sc.data[2*u+1]! = _ rw [c2,c2,if_pos (by rw [eH]; simp; omega),if_pos (by rw [eH]; simp; omega)] unfold cdv rw [if_pos (by omega),if_neg (by omega),show 2*u / 2=u by omega,show (2*u+1) / 2=u by omega,eu,eI] exact ⟨rfl,rfl⟩ hV:=fun j hj=>by rw [fget_data,d2 j (by omega)] unfold gA; rw [if_pos hj] hVs:=by rw [hVdef,d1,hV0]; have:=(zS_size (inW+H+1) (by omega)).1; omega hVl:=by rw [hVdef,d1,hV0]; exact (zS_size (inW+H+1) (by omega)).2 } obtain ⟨u1,u2⟩:=unitsF_spec sig tanh inW H x wih whh bih bhh t Q S2 Sc _ _ _ _ _ _ _ _ _ V B z (by omega) hBl refine ⟨V,S2,Sc,by rw [hVdef,d1],by rw [hS2,sN1,sR1],by rw [hSc,c1], ?_⟩ congr 1 have ha:(gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (h, #[])).1.size=H:=by rw [gruStep_ofFn,Array.size_ofFn] have eT:(t*H).toUSize.toNat=t*H:=qAd _ (by omega) have eH:H.toUSize.toNat=H:=qAd _ (by omega) obtain ⟨w1,w2⟩:=wcpW_spec (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (h, #[])).1 0 (t*H).toUSize H.toUSize (by omega) (by rw [eH]; simp; omega) (by rw [eT,eH]; omega) _ 0 B rfl (by simp) (by omega) (by rw [eT,eH]; omega) apply Array.ext · rw [u1,w1] · intro q q1 q2 rw [← getElem!_pos _ q q1, ← getElem!_pos _ q q2,u2 q,w2 q,eT,eH] simp only [show (0:USize).toNat=0 from rfl,Nat.add_zero,Nat.zero_add] split · rename_i hq rw [gruStep_ofFn,getElem!_pos _ _ (by rw [Array.size_ofFn]; omega),Array.getElem_ofFn] · rfl · exact ⟨_,S0,Sc0,by rw [edh _ _ _ _ (by simp) (by omega)] obtain ⟨z1,z2⟩:=zS_size (inW+H+1) (by omega) exact (decV_spec inW H x (hOf H B t) t (by omega) (by omega) hb V0 (by rw [hV0]; exact z1) (by rw [hV0]; exact z2)).1, rfl,rfl,rfl⟩ · exact ⟨V0,S0,Sc0,rfl,rfl,rfl,rfl⟩ theorem hOf_wcp (H t:Nat) (a B:Array Word) (ha:a.size=H) (hB:t*H+H≤ B.size) (hl:B.size+H< 2 ^ 32) : hOf H (wcpW a 0 (t*H).toUSize H.toUSize 0 B) (t+1)=a:=by have eT:(t*H).toUSize.toNat=t*H:=qAd _ (by omega) have eH:H.toUSize.toNat=H:=qAd _ (by omega) obtain ⟨w1,w2⟩:=wcpW_spec a 0 (t*H).toUSize H.toUSize (by omega) (by rw [eH]; simp; omega) (by rw [eT,eH]; omega) _ 0 B rfl (by simp) (by omega) (by rw [eT,eH]; omega) have hs:=hOf_size H (wcpW a 0 (t*H).toUSize H.toUSize 0 B) (t+1) (by rw [w1,Nat.succ_mul]; exact hB) apply Array.ext · rw [hs,ha] · intro j j1 j2 rw [← getElem!_pos _ j j1, ← getElem!_pos _ j j2,hOf_get H _ (t+1) j (by omega) (by rw [w1,Nat.succ_mul]; exact hB), if_neg (by omega),w2,eT,eH,Nat.add_sub_cancel] simp only [show (0:USize).toNat=0 from rfl,Nat.add_zero,Nat.zero_add] rw [if_pos ⟨by omega,by omega⟩,show t*H+j-t*H=j by omega] end theorem loopF_eq (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh:Array Word) (Q:GZq) (hQ:Q=gzPrep inW H wih whh bih bhh) (hok:Q.ok=true) (hxs:x.size≤ 4294967295) (hsR:sumsOK (zS (inW+H+1)).size Q.Pr.size (inW+H+1).toUSize (inW+H+1).toUSize ((2*H+7) / 8) 5=true) (hsN:sumsOK (zS (inW+H+1)).size Q.Pn.size (inW+H+1).toUSize (inW+H).toUSize ((H+7) / 8) 5=true) (hcd:cdOK (zS (inW+H+1)).size Q.Wc.size (inW+1).toUSize inW.toUSize H.toUSize H 0=true) : ∀ (n t:Nat) (B:Array Word) (V S Sc:FloatArray), V.size=(zS (inW+H+1)).size→ S.size=(zS (8*((2*H+7) / 8)+8*((H+7) / 8))).size → Sc.size=(zS (2*H)).size→ B.size=(t+n)*H→ B.size+H+4< 2 ^ 32 → loopF sig tanh inW H x wih whh bih bhh Q t n B V S Sc = recW H (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh) t n (hOf H B t, #[]) B | 0,t,B,V,S,Sc,_,_,_,_,_=>by rw [loopF,recW] | n+1,t,B,V,S,Sc,hV,hS,hSc,hB,hl=>by have hBt:t*H+H≤ B.size:=by rw [hB,Nat.add_mul,Nat.add_mul,Nat.one_mul]; omega obtain ⟨V',S',Sc',e1,e2,e3,e⟩:=loopF_step sig tanh inW H x wih whh bih bhh Q hQ hok hxs hsR hsN hcd t n B V S Sc hV hS hSc hBt hl rw [e,recW] have ha:(gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (hOf H B t, #[])).1.size=H:=by rw [gruStep_ofFn,Array.size_ofFn] have hst:gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (hOf H B t, #[]) = (hOf H (wcpW (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (hOf H B t, #[])).1 0 (t*H).toUSize H.toUSize 0 B) (t+1), #[]):=by rw [hOf_wcp H t _ B ha hBt (by omega)] rfl have eT:(t*H).toUSize.toNat=t*H:=qAd _ (by omega) have eH:H.toUSize.toNat=H:=qAd _ (by omega) obtain ⟨w1, -⟩:=wcpW_spec (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t (hOf H B t, #[])).1 0 (t*H).toUSize H.toUSize (by omega) (by rw [eH]; simp; omega) (by rw [eT,eH]; omega) _ 0 B rfl (by simp) (by omega) (by rw [eT,eH]; omega) rw [loopF_eq sig tanh inW H x wih whh bih bhh Q hQ hok hxs hsR hsN hcd n (t+1) _ V' S' Sc' (by rw [e1,hV]) (by rw [e2,hS]) (by rw [e3,hSc]) (by rw [w1,hB]; congr 1; omega) (by rw [w1]; exact hl), ← hst] theorem gruZ_eq (sig tanh:Word→ Word):gruZ sig tanh=gruWith Pinned.dotFn sig tanh:=by funext T inW H x wih whh bih bhh unfold gruZ have e:=(gzGet inW H wih whh bih bhh).2 dsimp only split_ifs with hc · simp only [Bool.and_eq_true,decide_eq_true_eq] at hc obtain ⟨⟨⟨⟨⟨h1,h2⟩,h3⟩,h4⟩,h5⟩,h6⟩:=hc rw [loopF_eq sig tanh inW H x wih whh bih bhh _ e h1 h2 h4 h5 h6 T 0 (Array.replicate (T*H) 0) _ _ _ rfl rfl rfl (by simp) (by simp; omega)] have e0:hOf H (Array.replicate (T*H) 0) 0=Array.replicate H 0:=by unfold hOf; simp rw [e0,show gruWith Pinned.dotFn sig tanh T inW H x wih whh bih bhh = recurWith T H (gruStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh) (Array.replicate H 0, #[]) from rfl, ← recRun_eq T H _ _ (fun t st=>by rw [gruStep_ofFn,Array.size_ofFn])] unfold recRun rw [if_pos (by omega)] · rfl theorem gruXZ_eq:gruXZ=gruWith Pinned.dotFn sigmoidF3 tanhF3:=by funext T inW H x wih whh bih bhh unfold gruXZ split · rename_i hok; rw [gruZ_eq,sigI_eq hok,tanhI_eq hok] · rfl end RnnZ section RnnX @[inline] def fbuild (n:Nat) (f:Nat→ Float):FloatArray := fpush f 0 n (FloatArray.emptyWithCapacity n) mutual 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 rw [fbuild,(fpush_get f 0 n _ j).2 (by rw [h0]; exact Nat.zero_le _) (by rw [h0,Nat.zero_add]; exact hj),h0, Nat.sub_zero,Nat.zero_add] theorem fbuild_size (n:Nat) (f:Nat→ Float):(fbuild n f).size=n:=by rw [fbuild,fpush_size]; exact Nat.zero_add n theorem uor1 (y:UInt32):(0xFFFFFFFF:UInt32) ||| y=0xFFFFFFFF:=by apply UInt32.toNat_inj.mp rw [UInt32.toNat_or] have:=y.toNat_lt show 4294967295 ||| y.toNat=4294967295 have e:(4294967295:Nat)=2 ^ 32-1:=rfl rw [e] apply Nat.eq_of_testBit_eq intro i rw [Nat.testBit_or,Nat.testBit_two_pow_sub_one] by_cases hi:i< 32 · simp [hi] · simp only [hi,decide_false] exact Nat.testBit_lt_two_pow (Nat.lt_of_lt_of_le this (Nat.pow_le_pow_right (by norm_num) (by omega))) theorem uand1 (u:UInt32):u &&& 0xFFFFFFFF=u := UInt32.toNat_inj.mp (by rw [UInt32.toNat_and] show u.toNat &&& (2 ^ 32-1)=_ rw [Nat.and_two_pow_sub_one_eq_mod]; exact Nat.mod_eq_of_lt u.toNat_lt) end theorem fzF (r:UInt32) : r &&& ((if false=true then (0:UInt32) else 0xFFFFFFFF) ||| ((r >>> (31:UInt32))-1))=r:=by simp only [Bool.false_eq_true,ite_false] rw [uor1,uand1] def pkX (N H:Nat) (Wc:Array Word):FloatArray := fbuild ((H+3) / 4*16*N) fun q => dv Wc[(q % 8 % 4*H+min (2*(q / (8*N))+q % 8 / 4) (H-1))*N+q % (8*N) / 8]! structure LXq where ok:Bool P:FloatArray B:FloatArray hv:Word bm:Float Wc:Array Word b:Array Word def lxPrep (inW H:Nat) (wih whh bih bhh:Array Word):LXq := let Wc:=catW inW H (4*H) wih whh bih let b:=Array.ofFn (n:=4*H) fun k=>bhh[k.val]! ⟨D.scanH 2 Wc != 0xFFFFFFFF && D.scanH 1 b != 0xFFFFFFFF && decide (inW+H+1< 1048576) && decide (0< H) && decide ((H+3) / 4*16*(inW+H+1)≤ 4294967295), pkX (inW+H+1) H Wc,fbuild (4*H) (fun k=>dv b[k]!),D.scanH 2 Wc,dv (D.scanH 1 b),Wc,b⟩ abbrev LXc (inW H:Nat) (wih whh bih bhh:Array Word) := {q:LXq // q=lxPrep inW H wih whh bih bhh} local instance lxcSub (inW H:Nat) (wih whh bih bhh:Array Word):Subsingleton (LXc inW H wih whh bih bhh) := ⟨fun a b=>Subtype.ext (a.2.trans b.2.symm)⟩ structure LXE where (nI nH:Nat) (a b c d:Array Word) (g:USize) (p:LXq) (ok:p=lxPrep nI nH a b c d) @[inline] def lxF1 (inW H:Nat) (wih whh bih bhh:Array Word) (g:USize) (e:LXE) : Option (LXc inW H wih whh bih bhh) := if e.g == g then if hn:e.nI=inW∧e.nH=H then if ha:withPtrEq e.a wih (fun _=>e.a == wih) (fun h=>by rw [h]; exact beq_self_eq_true wih) then if hb:withPtrEq e.b whh (fun _=>e.b == whh) (fun h=>by rw [h]; exact beq_self_eq_true whh) then if hc:withPtrEq e.c bih (fun _=>e.c == bih) (fun h=>by rw [h]; exact beq_self_eq_true bih) then if hd:withPtrEq e.d bhh (fun _=>e.d == bhh) (fun h=>by rw [h]; exact beq_self_eq_true bhh) then some ⟨e.p,by rw [← hn.1, ← hn.2, ← eq_of_beq ha, ← eq_of_beq hb, ← eq_of_beq hc, ← eq_of_beq hd] exact e.ok⟩ else none else none else none else none else none else none @[inline] def lxF (inW H:Nat) (wih whh bih bhh:Array Word) (g:USize) (s:Array LXE) : Option (LXc inW H wih whh bih bhh) := if h:0< s.size then match lxF1 inW H wih whh bih bhh g s[0] with | some v=>some v | none=>if h1:1< s.size then lxF1 inW H wih whh bih bhh g s[1] else none else none @[noinline] def lxS:ST.Ref Unit (Array LXE):=(ST.Prim.mkRef #[] (Void.mk ())).val @[inline] def lxGet (inW H:Nat) (wih whh bih bhh:Array Word):LXc inW H wih whh bih bhh := withPtrAddr wih (fun g => let s:=(ST.Prim.Ref.get lxS (Void.mk ())).val match lxF inW H wih whh bih bhh g s with | some v=>v | none => let p:=lxPrep inW H wih whh bih bhh let old:=(ST.Prim.Ref.swap lxS (#[⟨inW,H,wih,whh,bih,bhh,g,p,rfl⟩] ++ (if h:0< s.size then #[s[0]] else #[])) (Void.mk ())).val match lxF inW H wih whh bih bhh g old with | some v=>v | none=>⟨p,rfl⟩) (fun _ _=>Subsingleton.elim _ _) structure XV where xs:FloatArray ix:Array UInt32 c:USize a:Float ok:Bool def cxX (x:Array Word) (xo:USize):Nat→ USize→ FloatArray→ Array UInt32→ Float→ XV | 0,_,xs,ix,a=>⟨xs,ix,0,a,true⟩ | n+1,j,xs,ix,a => let w:=D.rdW x (xo+j) if w &&& 0x7FFFFFFF == 0 then cxX x xo n (j+1) xs ix a else let d:=dv w cxX x xo n (j+1) (xs.push d) (ix.push j.toUInt32) (a+d.abs) def cxH (h:Array Word) (inW:USize):Nat→ USize→ FloatArray→ Array UInt32→ Float→ Bool→ XV | 0,j,xs,ix,a,ok => let xs':=xs.push (dv oneW) ⟨xs',ix.push (inW+j).toUInt32,xs'.usize,a+(dv oneW).abs,ok⟩ | n+1,j,xs,ix,a,ok => let w:=D.rdW h j let d:=dv w cxH h inW n (j+1) (xs.push d) (ix.push (inW+j).toUInt32) (a+d.abs) (ok && good w) @[inline] def xvB (x h:Array Word) (inW H t:Nat):XV := let v:=cxX x (t*inW).toUSize inW 0 (FloatArray.emptyWithCapacity (inW+H+1)) (Array.emptyWithCapacity (inW+H+1)) 0 cxH h inW.toUSize H 0 v.xs v.ix v.a true @[noinline] def gfb (N:Nat) (X:Thunk (Array Word)) (Wc b:Array Word) (k:Nat) (s nf A:Float) (hv:Word):Word := let bv:=dv b[k]! let z:=ziv (s+bv) (nf*(dv hv*A+bv.abs)) if z == 0xFFFFFFFF then D.fin8n N false X.get Wc b 0 k s nf A hv b[k]! N.toUSize else z @[inline] def gfinU (N:Nat) (X:Thunk (Array Word)) (Q:LXq) (lo sp:UInt64) (nf A:Float) (k:USize) (s:Float):Word := let w:=D.fin1 lo sp (s+D.rdB Q.B k) if w == 0xFFFFFFFF then gfb N X Q.Wc Q.b k.toNat s nf A Q.hv else w local instance:Inhabited D.G16:=⟨⟨0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0⟩⟩ def dotsY (Q:LXq) (v:XV) (N:Nat):Nat→ Nat→ Array D.G16→ Array D.G16 | _,0,R=>R | c,fuel+1,R => let p:=(2*c*8*N).toUSize let p':=((2*c+1)*8*N).toUSize if hg:v.c.toNat≤ v.xs.size∧v.c.toNat≤ v.ix.size∧p.toNat+8*N.toUSize.toNat≤ Q.P.size ∧ p'.toNat+8*N.toUSize.toNat≤ Q.P.size∧Q.P.size≤ 4294967295 then dotsY Q v N (c+1) fuel (R.push (D.go16W v.xs Q.P v.ix p p' N.toUSize v.c 0 hg.1 hg.2.1 hg.2.2.1 hg.2.2.2.1 (D.qA9 hg.2.2.2.2) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)) else R @[inline] def unitW (sig tanh:Word→ Word) (N:Nat) (X:Thunk (Array Word)) (cs:Array Word) (Q:LXq) (lo sp:UInt64) (nf A:Float) (Hs u:USize) (si sf sg so:Float):Word × Word := let gi:=gfinU N X Q lo sp nf A u si let gf:=gfinU N X Q lo sp nf A (Hs+u) sf let gg:=gfinU N X Q lo sp nf A (2*Hs+u) sg let go:=gfinU N X Q lo sp nf A (3*Hs+u) so let c':=cellF (sig gf) (sig gi) (D.rdW cs u) (tanh gg) (mulF (sig go) (tanh c'),c') @[inline] def quad (sig tanh:Word→ Word) (N:Nat) (X:Thunk (Array Word)) (cs:Array Word) (Q:LXq) (lo sp:UInt64) (nf A:Float) (Hs:USize) (k:Nat) (r:D.G16):Q8 := let u:=k.toUSize let u1:=(k+1).toUSize let u2:=(k+2).toUSize let u3:=(k+3).toUSize let gi0:=gfinU N X Q lo sp nf A u r.a let gf0:=gfinU N X Q lo sp nf A (Hs+u) r.b let gg0:=gfinU N X Q lo sp nf A (2*Hs+u) r.c let go0:=gfinU N X Q lo sp nf A (3*Hs+u) r.d let gi1:=gfinU N X Q lo sp nf A u1 r.e let gf1:=gfinU N X Q lo sp nf A (Hs+u1) r.f let gg1:=gfinU N X Q lo sp nf A (2*Hs+u1) r.g let go1:=gfinU N X Q lo sp nf A (3*Hs+u1) r.k let gi2:=gfinU N X Q lo sp nf A u2 r.a' let gf2:=gfinU N X Q lo sp nf A (Hs+u2) r.b' let gg2:=gfinU N X Q lo sp nf A (2*Hs+u2) r.c' let go2:=gfinU N X Q lo sp nf A (3*Hs+u2) r.d' let gi3:=gfinU N X Q lo sp nf A u3 r.e' let gf3:=gfinU N X Q lo sp nf A (Hs+u3) r.f' let gg3:=gfinU N X Q lo sp nf A (2*Hs+u3) r.g' let go3:=gfinU N X Q lo sp nf A (3*Hs+u3) r.k' let f0:=sig gf0 let i0:=sig gi0 let t0:=tanh gg0 let f1:=sig gf1 let i1:=sig gi1 let t1:=tanh gg1 let f2:=sig gf2 let i2:=sig gi2 let t2:=tanh gg2 let f3:=sig gf3 let i3:=sig gi3 let t3:=tanh gg3 let c0:=cellF f0 i0 (D.rdW cs u) t0 let c1:=cellF f1 i1 (D.rdW cs u1) t1 let c2:=cellF f2 i2 (D.rdW cs u2) t2 let c3:=cellF f3 i3 (D.rdW cs u3) t3 let o0:=sig go0 let o1:=sig go1 let o2:=sig go2 let o3:=sig go3 let y0:=tanh c0 let y1:=tanh c1 let y2:=tanh c2 let y3:=tanh c3 ⟨mulF o0 y0,mulF o1 y1,mulF o2 y2,mulF o3 y3,c0,c1,c2,c3⟩ def lane (r:D.G16):Nat→ Nat→ Float | 0,0=>r.a | 0,1=>r.b | 0,2=>r.c | 0,3=>r.d | 1,0=>r.e | 1,1=>r.f | 1,2=>r.g | 1,3=>r.k | 2,0=>r.a' | 2,1=>r.b' | 2,2=>r.c' | 2,3=>r.d' | 3,0=>r.e' | 3,1=>r.f' | 3,2=>r.g' | 3,3=>r.k' | _,_=>0 @[specialize] def unitK (sig tanh:Word→ Word) (N:Nat) (X:Thunk (Array Word)) (cs:Array Word) (Q:LXq) (lo sp:UInt64) (nf A:Float) (Hs:USize) (R:Array D.G16) (k:Nat):Word × Word := unitW sig tanh N X cs Q lo sp nf A Hs k.toUSize (lane R[k / 4]! (k % 4) 0) (lane R[k / 4]! (k % 4) 1) (lane R[k / 4]! (k % 4) 2) (lane R[k / 4]! (k % 4) 3) @[inline] def quadK (sig tanh:Word→ Word) (N:Nat) (X:Thunk (Array Word)) (cs:Array Word) (Q:LXq) (lo sp:UInt64) (nf A:Float) (Hs:USize) (R:Array D.G16) (k:Nat):Q8 := if k % 4=0 then quad sig tanh N X cs Q lo sp nf A Hs k R[k / 4]! else let p0:=unitK sig tanh N X cs Q lo sp nf A Hs R k let p1:=unitK sig tanh N X cs Q lo sp nf A Hs R (k+1) let p2:=unitK sig tanh N X cs Q lo sp nf A Hs R (k+2) let p3:=unitK sig tanh N X cs Q lo sp nf A Hs R (k+3) ⟨p0.1,p1.1,p2.1,p3.1,p0.2,p1.2,p2.2,p3.2⟩ @[specialize] def lstmStepX (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh:Array Word) (Q:LXq) (t:Nat) (st:Array Word × Array Word):Array Word × Array Word := if t*inW+inW+H+1≤ 4294967295∧st.1.size≤ 4294967295∧st.2.size≤ 4294967295 then let v:=xvB x st.1 inW H t if v.ok then let nf:=nfOf (inW+H+1) let lo:=D.loOf (nf*(dv Q.hv*v.a+Q.bm)) let R:=dotsY Q v (inW+H+1) 0 ((H+3) / 4) (Array.emptyWithCapacity ((H+3) / 4)) build8 H (quadK sig tanh (inW+H+1) (Thunk.mk fun _=>xhOf inW H x st.1 t) st.2 Q lo (D.spOf lo) nf v.a H.toUSize R) (unitK sig tanh (inW+H+1) (Thunk.mk fun _=>xhOf inW H x st.1 t) st.2 Q lo (D.spOf lo) nf v.a H.toUSize R) 0 H (Array.emptyWithCapacity H) (Array.emptyWithCapacity H) else lstmStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t st else lstmStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh t st def lstmX (T inW H:Nat) (x wih whh bih bhh:Array Word):Array Word := let Q:=(lxGet inW H wih whh bih bhh).1 if tabOK && Q.ok && x.all good && decide (x.size≤ 4294967295) then recRun T H (lstmStepX sigI tanhI inW H x wih whh bih bhh Q) (Array.replicate H 0,Array.replicate H 0) else lstmWith Pinned.dotFn sigmoidF3 tanhF3 T inW H x wih whh bih bhh mutual theorem lkI (ix:Array UInt32) (L:List Nat) (h:ix.toList.map UInt32.toNat=L) (k q:Nat) (hq:L[k]? = some q):(ix[k]! : UInt32).toNat=q:=by rw [← h,List.getElem?_map,Array.getElem?_toList] at hq obtain ⟨i,hi,rfl⟩:=Option.map_eq_some_iff.mp hq obtain ⟨hk,e⟩:=Array.getElem?_eq_some_iff.mp hi rw [getElem!_pos ix k hk,e] theorem lkF (xs:FloatArray) (L:List Nat) (f:Nat→ Float) (h:xs.data.toList=L.map f) (k q:Nat) (hq:L[k]? = some q):xs.data[k]! = f q:=by have e0:(L.map f)[k]? = some (f q):=by rw [List.getElem?_map,hq]; rfl rw [← h,Array.getElem?_toList] at e0 obtain ⟨hk,e⟩:=Array.getElem?_eq_some_iff.mp e0 rw [getElem!_pos xs.data k hk,e] theorem cxX_spec (x:Array Word) (xo inW:USize) (xb:Nat) (hxo:xo.toNat=xb) (hb:xo.toNat+inW.toNat< 2 ^ 32) (hxs:x.size< 2 ^ 32) : ∀ (d:Nat) (j:USize) (xs:FloatArray) (ix:Array UInt32) (a:Float),j.toNat+d=inW.toNat → xs.data.toList=(D.C_keep (fun p=>x[xb+p]!) j.toNat).map (fun p=>dv x[xb+p]!) → ix.toList.map UInt32.toNat=D.C_keep (fun p=>x[xb+p]!) j.toNat → a=(D.C_keep (fun p=>x[xb+p]!) j.toNat).foldl (fun a p=>a+(dv x[xb+p]!).abs) 0 → (cxX x xo d j xs ix a).xs.data.toList = (D.C_keep (fun p=>x[xb+p]!) inW.toNat).map (fun p=>dv x[xb+p]!) ∧ (cxX x xo d j xs ix a).ix.toList.map UInt32.toNat=D.C_keep (fun p=>x[xb+p]!) inW.toNat ∧ (cxX x xo d j xs ix a).a = (D.C_keep (fun p=>x[xb+p]!) inW.toNat).foldl (fun a p=>a+(dv x[xb+p]!).abs) 0:=by intro d induction d with | zero => intro j xs ix a hj e1 e2 e3 rw [Nat.add_zero] at hj; rw [hj] at e1 e2 e3; exact ⟨e1,e2,e3⟩ | succ d ih => intro j xs ix a hj e1 e2 e3 have ht:j.toNat< inW.toNat:=by rw [← hj]; exact Nat.lt_add_of_pos_right (Nat.succ_pos d) have hu:=D.usz j inW (USize.lt_iff_toNat_lt.mpr ht) have ew:D.rdW x (xo+j)=x[xb+j.toNat]! := by rw [D.qAg x _ hxs,D.qAf _ _ (Nat.lt_of_le_of_lt (Nat.add_le_add_left (Nat.le_of_lt ht) _) hb),hxo] have hj':(j+1).toNat+d=inW.toNat:=by rw [hu,Nat.add_right_comm]; exact hj rw [cxX]; dsimp only; rw [ew] by_cases hz:x[xb+j.toNat]! &&& 0x7FFFFFFF=0 · have hk:=D.qDp (fun p=>x[xb+p]!) j.toNat hz rw [if_pos (beq_iff_eq.mpr hz)] exact ih (j+1) xs ix a hj' (by rw [hu,hk]; exact e1) (by rw [hu,hk]; exact e2) (by rw [hu,hk]; exact e3) · have hk:=D.qD5 (fun p=>x[xb+p]!) j.toNat hz have et:(j.toUInt32).toNat=j.toNat:=by rw [USize.toNat_toUInt32]; exact Nat.mod_eq_of_lt (Nat.lt_trans ht (Nat.lt_of_le_of_lt (Nat.le_add_left _ _) hb)) rw [if_neg (fun h=>hz (beq_iff_eq.mp h))] refine ih (j+1) _ _ _ hj' ?_ ?_ ?_ · rw [hu,hk,List.map_append,List.map_cons,List.map_nil, ← e1]; exact Array.toList_push · rw [hu,hk,Array.toList_push,List.map_append,e2,List.map_cons,List.map_nil,et] · rw [hu,hk,List.foldl_append, ← e3]; rfl theorem cxH_spec (h:Array Word) (inW H:USize) (hhs:h.size< 2 ^ 32) (hb:inW.toNat+H.toNat+1< 2 ^ 32) (g:Nat→ Word) (hg : ∀ j,j< H.toNat→ g (inW.toNat+j)=h[j]!) (hg1:g (inW.toNat+H.toNat)=oneW) (Lx:List Nat) : ∀ (d:Nat) (j:USize) (xs:FloatArray) (ix:Array UInt32) (a:Float) (ok:Bool), j.toNat+d=H.toNat → xs.data.toList=(Lx ++ List.range' inW.toNat j.toNat).map (fun p=>dv (g p)) → ix.toList.map UInt32.toNat=Lx ++ List.range' inW.toNat j.toNat → a=(Lx ++ List.range' inW.toNat j.toNat).foldl (fun a p=>a+(dv (g p)).abs) 0 → (ok=true → ∀ j',j'< j.toNat→ good h[j']! = true) → (cxH h inW d j xs ix a ok).xs.data.toList = (Lx ++ List.range' inW.toNat H.toNat ++ [inW.toNat+H.toNat]).map (fun p=>dv (g p)) ∧ (cxH h inW d j xs ix a ok).ix.toList.map UInt32.toNat = Lx ++ List.range' inW.toNat H.toNat ++ [inW.toNat+H.toNat] ∧ (cxH h inW d j xs ix a ok).c=(cxH h inW d j xs ix a ok).xs.usize ∧ (cxH h inW d j xs ix a ok).a = (Lx ++ List.range' inW.toNat H.toNat ++ [inW.toNat+H.toNat]).foldl (fun a p=>a+(dv (g p)).abs) 0 ∧ ((cxH h inW d j xs ix a ok).ok=true → ∀ j',j'< H.toNat→ good h[j']! = true):=by intro d induction d with | zero => intro j xs ix a ok hj e1 e2 e3 e4 rw [Nat.add_zero] at hj rw [hj] at e1 e2 e3 e4 have eih:((inW+j).toUInt32).toNat=inW.toNat+H.toNat:=by have b0:inW.toNat+H.toNat< 2 ^ 32:=Nat.lt_trans (Nat.lt_succ_self _) hb rw [USize.toNat_toUInt32,D.qAf _ _ (by rw [hj]; exact b0),hj]; exact Nat.mod_eq_of_lt b0 rw [cxH] refine ⟨?_, ?_,rfl, ?_,e4⟩ · rw [List.map_append,List.map_cons,List.map_nil,hg1, ← e1]; exact Array.toList_push · rw [Array.toList_push,List.map_append,e2,List.map_cons,List.map_nil,eih] · rw [List.foldl_append, ← e3]; exact congrArg (fun z=>a+(dv z).abs) hg1.symm | succ d ih => intro j xs ix a ok hj e1 e2 e3 e4 have ht:j.toNat< H.toNat:=by rw [← hj]; exact Nat.lt_add_of_pos_right (Nat.succ_pos d) have hu:=D.usz j H (USize.lt_iff_toNat_lt.mpr ht) have eij:((inW+j).toUInt32).toNat=inW.toNat+j.toNat:=by have b0:inW.toNat+j.toNat< 2 ^ 32:=Nat.lt_trans (Nat.add_lt_add_left ht _) (Nat.lt_trans (Nat.lt_succ_self _) hb) rw [USize.toNat_toUInt32,D.qAf _ _ b0]; exact Nat.mod_eq_of_lt b0 have hr:List.range' inW.toNat (j+1).toNat=List.range' inW.toNat j.toNat ++ [inW.toNat+j.toNat]:=by rw [hu,List.range'_concat,Nat.one_mul] have hgj:=hg j.toNat ht have hj':(j+1).toNat+d=H.toNat:=by rw [hu,Nat.add_right_comm]; exact hj rw [cxH,D.qAg h j hhs] refine ih (j+1) _ _ _ _ hj' ?_ ?_ ?_ ?_ · rw [hr, ← List.append_assoc,List.map_append,List.map_cons,List.map_nil,hgj, ← e1]; exact Array.toList_push · rw [hr, ← List.append_assoc,Array.toList_push,List.map_append,e2,List.map_cons,List.map_nil,eij] · rw [hr, ← List.append_assoc,List.foldl_append, ← e3]; exact congrArg (fun z=>a+(dv z).abs) hgj.symm · intro hok j' hj'' rw [Bool.and_eq_true] at hok rw [hu] at hj'' rcases Nat.lt_succ_iff_lt_or_eq.mp hj'' with hjj | hjj · exact e4 hok.1 j' hjj · rw [hjj]; exact hok.2 end mutual theorem xv_fin (v:XV) (L:List Nat) (f:Nat→ Float) (hL:L.length< 2 ^ 32) (b1:v.xs.data.toList=L.map f) (b2:v.ix.toList.map UInt32.toNat=L) (b3:v.c=v.xs.usize) : v.c.toNat=L.length∧v.c.toNat≤ v.xs.size∧v.c.toNat≤ v.ix.size∧v.xs.size< 2 ^ 32 ∧ ∀ k q:Nat,L[k]? = some q→ (v.ix[k]! : UInt32).toNat=q∧v.xs.data[k]! = f q:=by have s1:v.xs.size=L.length:=by show v.xs.data.size=_; rw [← Array.length_toList,b1,List.length_map] have s2:v.ix.size=L.length:=by rw [← Array.length_toList, ← List.length_map (f:=UInt32.toNat),b2] have c0:v.c.toNat=L.length:=by rw [b3, ← s1]; exact qAd _ (by rw [s1]; exact hL) exact ⟨c0,by rw [c0,s1],by rw [c0,s2],by rw [s1]; exact hL, fun k q hq=>⟨lkI _ L b2 k q hq,lkF _ L f b1 k q hq⟩⟩ theorem lxAr (N H:Nat) (hN:N< 1048576) (hP:(H+3) / 4*16*N≤ 4294967295) (hHN:H< N) : 4*H*N< 2 ^ 32∧N< 2 ^ 20∧N< 2 ^ 32∧4*H< 2 ^ 32∧4*H+8< 2 ^ 32∧H< 2 ^ 32:=by have q:H≤ 4*((H+3) / 4) := Nat.le_of_lt_succ (Nat.lt_of_add_lt_add_right (n:=3) (Nat.lt_mul_div_succ (H+3) (by decide:0< 4))) have h4:4*H≤ (H+3) / 4*16:=by rw [show (H+3) / 4*16=4*(4*((H+3) / 4)) by rw [Nat.mul_comm, ← Nat.mul_assoc]] exact Nat.mul_le_mul_left 4 q have hH:H< 1048576:=Nat.lt_trans hHN hN have h8:4*H+8< 2 ^ 32 := Nat.lt_of_le_of_lt (Nat.add_le_add_right (Nat.mul_le_mul_left 4 (Nat.le_of_lt hH)) 8) (by decide) exact ⟨Nat.lt_of_le_of_lt (le_trans (Nat.mul_le_mul_right _ h4) hP) (Nat.lt_succ_self _),hN, Nat.lt_trans hN (by decide),Nat.lt_of_le_of_lt (Nat.le_add_right _ 8) h8,h8,Nat.lt_trans hH (by decide)⟩ theorem blkAr (N H c:Nat) (hc:c< (H+3) / 4) (hP:(H+3) / 4*16*N≤ 4294967295) : (2*c*8*N).toUSize.toNat=2*c*(8*N)∧((2*c+1)*8*N).toUSize.toNat=(2*c+1)*(8*N) ∧ 2*c*(8*N)+8*N≤ (H+3) / 4*16*N∧(2*c+1)*(8*N)+8*N≤ (H+3) / 4*16*N:=by have e3:(H+3) / 4*16*N=(H+3) / 4*2*(8*N):=by rw [Nat.mul_assoc ((H+3) / 4) 16 N,Nat.mul_assoc ((H+3) / 4) 2 (8*N), ← Nat.mul_assoc 2 8 N] have hc2:2*c+1+1≤ (H+3) / 4*2:=by rw [Nat.mul_comm _ 2]; exact Nat.mul_le_mul_left 2 hc have b1:(2*c+1)*(8*N)+8*N≤ (H+3) / 4*16*N:=by rw [e3, ← Nat.succ_mul]; exact Nat.mul_le_mul_right _ hc2 have b0:2*c*(8*N)+8*N≤ (2*c+1)*(8*N)+8*N := Nat.add_le_add_right (Nat.mul_le_mul_right _ (Nat.le_succ _)) _ have l1:(2*c+1)*(8*N)< 2 ^ 32 := Nat.lt_of_le_of_lt (le_trans (Nat.le_add_right _ _) (le_trans b1 hP)) (Nat.lt_succ_self _) have l0:2*c*(8*N)< 2 ^ 32 := Nat.lt_of_le_of_lt (le_trans (Nat.le_add_right _ _) (le_trans (le_trans b0 b1) hP)) (Nat.lt_succ_self _) rw [Nat.mul_assoc (2*c) 8 N,Nat.mul_assoc (2*c+1) 8 N] exact ⟨qAd _ l0,qAd _ l1,le_trans b0 b1,b1⟩ theorem unitAr (H u:Nat) (hu:u< H) (hH:4*H+8< 2 ^ 32) : u< 2 ^ 32∧H+u< 2 ^ 32∧2*H< 2 ^ 32∧3*H< 2 ^ 32∧2*H+u< 2 ^ 32∧3*H+u< 2 ^ 32:=by have h4:4*H< 2 ^ 32:=Nat.lt_of_le_of_lt (Nat.le_add_right _ 8) hH have h3:3*H+u< 2 ^ 32 := Nat.lt_trans (Nat.lt_of_lt_of_le (Nat.add_lt_add_left hu _) (Nat.le_of_eq (Nat.succ_mul 3 H).symm)) h4 have h2:2*H+u< 2 ^ 32 := Nat.lt_of_le_of_lt (Nat.add_le_add_right (Nat.mul_le_mul_right H (by decide:2≤ 3)) u) h3 have h1:H+u< 2 ^ 32 := Nat.lt_of_le_of_lt (Nat.add_le_add_right (by rw [Nat.two_mul]; exact Nat.le_add_right H H) u) h2 exact ⟨Nat.lt_of_le_of_lt (Nat.le_add_left u H) h1,h1,Nat.lt_of_le_of_lt (Nat.le_add_right _ _) h2, Nat.lt_of_le_of_lt (Nat.le_add_right _ _) h3,h2,h3⟩ theorem xvAr (inW H t:Nat) (hb:t*inW+inW+H+1≤ 4294967295) : inW< 2 ^ 32∧H< 2 ^ 32∧t*inW< 2 ^ 32∧t*inW+inW< 2 ^ 32∧inW+H+1< 2 ^ 32:=by have A:t*inW+inW+H+1< 2 ^ 32:=Nat.lt_of_le_of_lt hb (Nat.lt_succ_self _) have B:t*inW+inW< 2 ^ 32 := Nat.lt_of_le_of_lt (Nat.le_trans (Nat.le_add_right _ H) (Nat.le_add_right _ 1)) A have C:inW+H+1< 2 ^ 32 := Nat.lt_of_le_of_lt (Nat.succ_le_succ (Nat.add_le_add_right (Nat.le_add_left inW (t*inW)) H)) A exact ⟨Nat.lt_of_le_of_lt (Nat.le_add_left _ _) B, Nat.lt_of_le_of_lt (Nat.le_trans (Nat.le_add_left H inW) (Nat.le_add_right _ 1)) C, Nat.lt_of_le_of_lt (Nat.le_add_right _ _) B,B,C⟩ theorem div4 (i H:Nat) (hi:i< H):i / 4< 0+(H+3) / 4:=by rw [Nat.zero_add] have h:=Nat.div_le_div_right (c:=4) (Nat.add_le_add_right hi 3) rw [Nat.add_div_right i (by decide:0< 4)] at h exact h theorem lxOk (inW H:Nat) (wih whh bih bhh:Array Word) (hQ:(lxPrep inW H wih whh bih bhh).ok=true) : D.scanH 2 (catW inW H (4*H) wih whh bih)≠ 0xFFFFFFFF ∧ D.scanH 1 (Array.ofFn (n:=4*H) fun k=>bhh[k.val]!)≠ 0xFFFFFFFF ∧ inW+H+1< 1048576∧0< H∧(H+3) / 4*16*(inW+H+1)≤ 4294967295:=by unfold lxPrep at hQ simp only [Bool.and_eq_true,bne_iff_ne,ne_eq,decide_eq_true_eq] at hQ exact ⟨hQ.1.1.1.1,hQ.1.1.1.2,hQ.1.1.2,hQ.1.2,hQ.2⟩ theorem cout_gate (inW H:Nat) (x wih whh bih bhh h:Array Word) (t k:Nat) (hk:k< 4*H) : D.C_out (inW+H+1) false (xhOf inW H x h t) (catW inW H (4*H) wih whh bih) (Array.ofFn (n:=4*H) fun k=>bhh[k.val]!) 0 k = gateWith Pinned.dotFn inW H x wih whh bih bhh h t k:=by unfold D.C_out gateWith rw [Pinned.dotFn_eq_dotOf] simp only [act,Bool.false_eq_true,ite_false,Nat.zero_mul,Nat.zero_add] have n1 : ∀ j, ¬ j< inW+H+1 → ¬ j< inW:=fun j hj h => hj (Nat.lt_of_lt_of_le h (Nat.le_trans (Nat.le_add_right inW H) (Nat.le_add_right _ 1))) have n2 : ∀ j, ¬ j< inW+H+1 → ¬ j< inW+H:=fun j hj h=>hj (Nat.lt_succ_of_lt h) apply dotOf_congr intro j _ constructor · by_cases hj:j< inW+H+1 · rw [if_pos hj]; unfold xhOf; rw [ofFn_get! _ _ _ hj]; rfl · rw [if_neg hj,if_neg (n1 j hj),if_neg (n2 j hj)] · by_cases hj:j< inW+H+1 · rw [if_pos hj,catW_get inW H (4*H) wih whh bih k j hk hj] by_cases h3:j< inW · rw [if_pos h3,if_pos h3] · by_cases h4:j< inW+H · rw [if_neg h3,if_pos h4,if_neg h3,if_pos h4] · rw [if_neg h3,if_neg h4,if_neg h3,if_neg h4,if_pos (Nat.le_antisymm (Nat.le_of_lt_succ hj) (Nat.le_of_not_lt h4))] · rw [if_neg hj,ofFn_get!F _ k hk,if_neg (n1 j hj),if_neg (n2 j hj), if_neg (fun h=>hj (by rw [h]; exact Nat.lt_succ_self _))] end theorem gfb_eq (N:Nat) (X:Array Word) (Wc b:Array Word) (k:Nat) (s nf A:Float) (hv:Word) : gfb N (Thunk.mk fun _=>X) Wc b k s nf A hv=D.fin8 N false X Wc b 0 k s nf A hv b[k]! N.toUSize:=by unfold gfb D.fin8n dsimp only split · rfl · rename_i hz unfold D.fin8; dsimp only rw [if_neg hz,fzF] theorem gate_ok (inW H:Nat) (x wih whh bih bhh h:Array Word) (t:Nat) (hQ:(lxPrep inW H wih whh bih bhh).ok=true) (hgx : ∀ j,j< inW→ good x[t*inW+j]! = true) (hgh : ∀ j,j< H→ good h[j]! = true) (L:List Nat) (hl:L.Nodup) (hl2 : ∀ p ∈ L,p< inW+H+1) (hz : ∀ p,p< inW+H+1→ p ∉ L→ (xhOf inW H x h t)[0*(inW+H+1)+p]! &&& 0x7FFFFFFF=0) (A:Float) (hA:A=L.foldl (fun a p=>a+(dv (xhOf inW H x h t)[0*(inW+H+1)+p]!).abs) 0) (k:Nat) (hk:k< 4*H) (s:Float) (hs:s=L.foldl (fun acc p=>acc+dv (xhOf inW H x h t)[0*(inW+H+1)+p]! * dv (catW inW H (4*H) wih whh bih)[k*(inW+H+1)+p]!) 0) : gfinU (inW+H+1) (Thunk.mk fun _=>xhOf inW H x h t) (lxPrep inW H wih whh bih bhh) (D.loOf (nfOf (inW+H+1)*(dv (lxPrep inW H wih whh bih bhh).hv*A+(lxPrep inW H wih whh bih bhh).bm))) (D.spOf (D.loOf (nfOf (inW+H+1)*(dv (lxPrep inW H wih whh bih bhh).hv*A + (lxPrep inW H wih whh bih bhh).bm)))) (nfOf (inW+H+1)) A k.toUSize s = gateWith Pinned.dotFn inW H x wih whh bih bhh h t k:=by obtain ⟨hv,hb,hN,hH,hP⟩:=lxOk inW H wih whh bih bhh hQ obtain ⟨a1,a2,a3,a4, -, -⟩:=lxAr _ H hN hP (Nat.lt_succ_of_le (Nat.le_add_left H inW)) set N:=inW+H+1 with hNdef set X:=xhOf inW H x h t with hXdef set Wc:=catW inW H (4*H) wih whh bih with hWc set b:=Array.ofFn (n:=4*H) fun k=>bhh[k.val]! with hbdef have sX:X.size=N:=by rw [hXdef]; unfold xhOf; exact Array.size_ofFn have sW:Wc.size=4*H*N:=by rw [hWc]; unfold catW; exact Array.size_ofFn have sb:b.size=4*H:=by rw [hbdef]; exact Array.size_ofFn have hsW:Wc.size< 2 ^ 32:=by rw [sW]; exact a1 have hsb:b.size< 2 ^ 32:=by rw [sb]; exact a4 have Hv:=D.qA8 2 Wc hsW hv have Hb:=D.qA8 1 b hsb hb have G:D.C_G 1 N (4*H) X Wc b:=⟨by rw [sX,Nat.one_mul],sW.symm,sb.symm,Nat.succ_pos _, Nat.mul_pos (by decide) hH,a2,by rw [sX]; exact a3,hsW,hsb,by rw [Nat.one_mul]; exact a4,fun q hq=>by rw [sX] at hq; rw [hXdef]; unfold xhOf; rw [ofFn_get! _ _ _ hq]; unfold gA split_ifs with h1 h2 · exact hgx q h1 · exact hgh (q-inW) (Nat.sub_lt_left_of_lt_add (Nat.le_of_not_lt h1) h2) · exact good_one,Hv.2.2.1,Hb.2.2.1⟩ obtain ⟨gb1,gb2, -, gb4⟩:=id Hb obtain ⟨pb0,pb1,pb2⟩:=D.qCs gb1 gb2 obtain ⟨fbm,Rbm⟩:=D.qAm _ gb1 have hbm : |R (dv b[k]!)| ≤ R (dv (D.scanH 1 b)):=by have gj:=Hb.2.2.1 k (by rw [sb]; exact hk) rw [(D.qAm _ gj).2,Rbm]; exact pb2 _ gj (gb4 k (by rw [sb]; exact hk)) have bb:R (dv (D.scanH 1 b))≤ 2 ^ (290:ℤ):=by rw [Rbm]; exact pb1.trans (by rw [← zpow_natCast]; exact zpow_le_zpow_right₀ one_le_two (by decide)) have key:=D.qDuF G false (i:=0) (j:=k) (by decide) hk Hv.1 Hv.2.1 (fun q hq=>Hv.2.2.2 _ (by rw [sW]; exact D.qCj hk hq)) L hl hl2 hz hs (dv (D.scanH 1 b)) fbm hbm bb _ rfl rw [← cout_gate inW H x wih whh bih bhh h t k hk, ← key, ← hA] have hB:D.rdB (lxPrep inW H wih whh bih bhh).B k.toUSize=dv b[k]! := by have hBs:(lxPrep inW H wih whh bih bhh).B.size=4*H:=fbuild_size _ _ have hku:k.toUSize.toNat=k:=qAd k (Nat.lt_trans hk a4) rw [D.rdBd _ _ (by rw [hku,hBs]; exact hk) (by rw [hBs]; exact a4),hku, ← fget_data] exact fbuild_get _ _ k hk have q1:(lxPrep inW H wih whh bih bhh).hv=D.scanH 2 Wc:=rfl have q2:(lxPrep inW H wih whh bih bhh).bm=dv (D.scanH 1 b):=rfl have q3:(lxPrep inW H wih whh bih bhh).Wc=Wc:=rfl have q4:(lxPrep inW H wih whh bih bhh).b=b:=rfl unfold gfinU rw [hB,q1,q2,q3,q4] dsimp only split · rename_i he rw [qAd k (Nat.lt_trans hk a4)] exact gfb_eq N X Wc b k s _ A _ · rename_i he unfold D.fz; rw [fzF] def rowOf (H β l:Nat):Nat:=l % 4*H+min (2*β+l / 4) (H-1) theorem pk_idx (b N i l:Nat) (hi:i< N) (hl:l< 8) : (b*(8*N)+8*i+l) % 8=l∧(b*(8*N)+8*i+l) / (8*N)=b ∧ (b*(8*N)+8*i+l) % (8*N) / 8=i:=by have h1:8*i+l< 8*N:=Nat.lt_of_lt_of_le (Nat.add_lt_add_left hl _) (Nat.mul_le_mul_left 8 hi) have hN:8*N > 0:=Nat.lt_of_le_of_lt (Nat.zero_le _) h1 refine ⟨?_, ?_, ?_⟩ · rw [show b*(8*N)+8*i+l=8*(b*N+i)+l by rw [Nat.mul_add,Nat.mul_left_comm b 8 N], Nat.mul_add_mod,Nat.mod_eq_of_lt hl] · rw [Nat.add_assoc,Nat.mul_comm b,Nat.mul_add_div hN,Nat.div_eq_of_lt h1,Nat.add_zero] · rw [Nat.add_assoc,Nat.mul_comm b,Nat.mul_add_mod,Nat.mod_eq_of_lt h1,Nat.mul_add_div (by decide), Nat.div_eq_of_lt hl,Nat.add_zero] mutual theorem pkX_data (N H:Nat) (Wc:Array Word) (b i l:Nat) (hb:b< (H+3) / 4*2) (hi:i< N) (hl:l< 8):(pkX N H Wc).data[b*(8*N)+8*i+l]! = dv Wc[rowOf H b l*N+i]! := by obtain ⟨e1,e2,e3⟩:=pk_idx b N i l hi hl have hq:b*(8*N)+8*i+l< (H+3) / 4*16*N:=by have h1:8*i+l< 8*N:=Nat.lt_of_lt_of_le (Nat.add_lt_add_left hl _) (Nat.mul_le_mul_left 8 hi) have h2:b*(8*N)+8*N≤ (H+3) / 4*16*N:=by rw [← Nat.succ_mul,Nat.mul_assoc ((H+3) / 4) 16 N, show 16*N=2*(8*N) from Nat.mul_assoc 2 8 N, ← Nat.mul_assoc ((H+3) / 4) 2 (8*N)] exact Nat.mul_le_mul_right _ hb rw [Nat.add_assoc]; exact Nat.lt_of_lt_of_le (Nat.add_lt_add_left h1 _) h2 rw [← fget_data]; unfold pkX; rw [fbuild_get _ _ _ hq] simp only [e1,e2,e3]; rfl theorem rowOf_lt (H b l:Nat) (hH:0< H) (hl:l< 8):rowOf H b l< 4*H:=by unfold rowOf have m:min (2*b+l / 4) (H-1)< H:=Nat.lt_of_le_of_lt (Nat.min_le_right _ _) (Nat.sub_lt hH (by decide)) have k:l % 4*H+H≤ 4*H:=by rw [← Nat.succ_mul]; exact Nat.mul_le_mul_right H (Nat.mod_lt _ (by decide)) exact Nat.lt_of_lt_of_le (Nat.add_lt_add_left m _) k theorem lane1 (xs:FloatArray) (ix:Array UInt32) (Wc:Array Word) (N:Nat) (w n:USize) (rho:Nat) (hw:w.toNat=rho*N) (hN:N< 2 ^ 32) (hx:n.toNat≤ xs.size) (hi:n.toNat≤ ix.size) (hs:Wc.size< 2 ^ 32) (h0:w.toNat+N.toUSize.toNat≤ Wc.size) (xf:Nat→ Float) (L:List Nat) (hL:L.length=n.toNat) (hLf : ∀ k q:Nat,L[k]? = some q→ q< N∧(ix[k]! : UInt32).toNat=q∧xs.data[k]! = xf q) : D.go1 xs ix Wc w N.toUSize n 0 hx hi hs h0 0 = L.foldl (fun acc q=>acc+xf q*dv Wc[rho*N+q]!) 0:=by have hm:N.toUSize.toNat=N:=qAd N hN refine D.qH6 hx hi hs h0 xf (fun q=>Wc[rho*N+q]!) (fun q hq=>by rw [hw]) L 0 0 (by rw [hL]; simp) (fun k q hq => ?_) obtain ⟨a1,a2,a3⟩:=hLf k q hq refine ⟨by rw [hm]; exact a1, ?_, ?_⟩ · rw [show (0:USize).toNat+k=k from by simp]; exact a2 · rw [show (0:USize).toNat+k=k from by simp]; exact a3 end mutual theorem blk8 (xs:FloatArray) (ix:Array UInt32) (N H:Nat) (Wc:Array Word) (bk:Nat) (n p:USize) (hp:p.toNat=bk*(8*N)) (hbk:bk< (H+3) / 4*2) (hH:0< H) (hN0:0< N) (hN:N< 2 ^ 32) (hsW:Wc.size=4*H*N) (hW32:4*H*N< 2 ^ 32) (hx:n.toNat≤ xs.size) (hi:n.toNat≤ ix.size) (hb:p.toNat+8*N.toUSize.toNat≤ (pkX N H Wc).size) (hs:(pkX N H Wc).size< 2 ^ 32) (xf:Nat→ Float) (L:List Nat) (hL:L.length=n.toNat) (hLf : ∀ k q:Nat,L[k]? = some q→ q< N∧(ix[k]! : UInt32).toNat=q∧xs.data[k]! = xf q) : D.g8of (D.go8W xs (pkX N H Wc) ix p N.toUSize n 0 hx hi hb hs 0 0 0 0 0 0 0 0) = ⟨L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 0*N+q]!) 0, L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 1*N+q]!) 0, L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 2*N+q]!) 0, L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 3*N+q]!) 0, L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 4*N+q]!) 0, L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 5*N+q]!) 0, L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 6*N+q]!) 0, L.foldl (fun acc q=>acc+xf q*dv Wc[rowOf H bk 7*N+q]!) 0⟩:=by have hm:N.toUSize.toNat=N:=qAd N hN have hsW':Wc.size< 2 ^ 32:=by omega have wl : ∀ l,l< 8→ ((rowOf H bk l*N).toUSize).toNat=rowOf H bk l*N:=fun l hl=>by have:=rowOf_lt H bk l hH hl have:rowOf H bk l*N< 4*H*N:=Nat.mul_lt_mul_of_pos_right this hN0 exact qAd _ (by omega) have wb : ∀ l,l< 8→ ((rowOf H bk l*N).toUSize).toNat+N.toUSize.toNat≤ Wc.size:=fun l hl=>by rw [wl l hl,hm,hsW] have:=Nat.mul_le_mul_right N (rowOf_lt H bk l hH hl) rw [Nat.succ_mul] at this; exact this have HB : ∀ i,i< N.toUSize.toNat → ∀ l,l< 8 → (pkX N H Wc).data[p.toNat+8*i+l]! = dv Wc[((rowOf H bk l*N).toUSize).toNat+i]! := by intro i hi l hl rw [hp,wl l hl]; rw [hm] at hi exact pkX_data N H Wc bk i l hbk hi hl rw [D.g8WE xs (pkX N H Wc) ix Wc p _ _ _ _ _ _ _ _ N.toUSize n hx hi hb hs hsW' (wb 0 (by decide)) (wb 1 (by decide)) (wb 2 (by decide)) (wb 3 (by decide)) (wb 4 (by decide)) (wb 5 (by decide)) (wb 6 (by decide)) (wb 7 (by decide)) (fun i hi=>⟨HB i hi 0 (by decide),HB i hi 1 (by decide),HB i hi 2 (by decide),HB i hi 3 (by decide), HB i hi 4 (by decide),HB i hi 5 (by decide),HB i hi 6 (by decide),HB i hi 7 (by decide)⟩) n.toNat 0 0 0 0 0 0 0 0 0 (by simp)] have G:=fun l (hl:l< 8)=>lane1 xs ix Wc N _ n (rowOf H bk l) (wl l hl) hN hx hi hsW' (wb l hl) xf L hL hLf simp only [D.g8of] rw [G 0 (by decide),G 1 (by decide),G 2 (by decide),G 3 (by decide),G 4 (by decide),G 5 (by decide), G 6 (by decide),G 7 (by decide)] theorem quad_eq (sig tanh:Word→ Word) (N:Nat) (X:Thunk (Array Word)) (cs:Array Word) (Q:LXq) (lo sp:UInt64) (nf A:Float) (Hs:USize) (k:Nat) (r:D.G16) : quad sig tanh N X cs Q lo sp nf A Hs k r = ⟨(unitW sig tanh N X cs Q lo sp nf A Hs k.toUSize r.a r.b r.c r.d).1, (unitW sig tanh N X cs Q lo sp nf A Hs (k+1).toUSize r.e r.f r.g r.k).1, (unitW sig tanh N X cs Q lo sp nf A Hs (k+2).toUSize r.a' r.b' r.c' r.d').1, (unitW sig tanh N X cs Q lo sp nf A Hs (k+3).toUSize r.e' r.f' r.g' r.k').1, (unitW sig tanh N X cs Q lo sp nf A Hs k.toUSize r.a r.b r.c r.d).2, (unitW sig tanh N X cs Q lo sp nf A Hs (k+1).toUSize r.e r.f r.g r.k).2, (unitW sig tanh N X cs Q lo sp nf A Hs (k+2).toUSize r.a' r.b' r.c' r.d').2, (unitW sig tanh N X cs Q lo sp nf A Hs (k+3).toUSize r.e' r.f' r.g' r.k').2⟩:=rfl theorem mod4 (k:Nat) (h:k % 4=0):(k+1) % 4=1∧(k+2) % 4=2∧(k+3) % 4=3 ∧ (k+1) / 4=k / 4∧(k+2) / 4=k / 4∧(k+3) / 4=k / 4:=by have e:k=4*(k / 4):=by have:=Nat.div_add_mod k 4; rw [h,Nat.add_zero] at this; exact this.symm have m : ∀ j,j< 4→ (k+j) % 4=j∧(k+j) / 4=k / 4:=fun j hj=>by rw [e,Nat.add_comm,Nat.add_mul_mod_self_left,Nat.add_mul_div_left _ _ (by decide),Nat.div_eq_of_lt hj, Nat.zero_add,Nat.mod_eq_of_lt hj,Nat.mul_div_cancel_left _ (by decide)] exact ⟨rfl,rfl⟩ exact ⟨(m 1 (by decide)).1,(m 2 (by decide)).1,(m 3 (by decide)).1,(m 1 (by decide)).2,(m 2 (by decide)).2, (m 3 (by decide)).2⟩ end mutual theorem quadK_eq (sig tanh:Word→ Word) (N:Nat) (X:Thunk (Array Word)) (cs:Array Word) (Q:LXq) (lo sp:UInt64) (nf A:Float) (Hs:USize) (R:Array D.G16) (k:Nat) : quadK sig tanh N X cs Q lo sp nf A Hs R k = ⟨(unitK sig tanh N X cs Q lo sp nf A Hs R k).1,(unitK sig tanh N X cs Q lo sp nf A Hs R (k+1)).1, (unitK sig tanh N X cs Q lo sp nf A Hs R (k+2)).1,(unitK sig tanh N X cs Q lo sp nf A Hs R (k+3)).1, (unitK sig tanh N X cs Q lo sp nf A Hs R k).2,(unitK sig tanh N X cs Q lo sp nf A Hs R (k+1)).2, (unitK sig tanh N X cs Q lo sp nf A Hs R (k+2)).2,(unitK sig tanh N X cs Q lo sp nf A Hs R (k+3)).2⟩:=by unfold quadK split · rename_i h obtain ⟨m1,m2,m3,d1,d2,d3⟩:=mod4 k h rw [quad_eq]; unfold unitK; rw [m1,m2,m3,d1,d2,d3,h]; rfl · rfl theorem foldl_cg {α β:Type} (f g:α→ β→ α) : ∀ (l:List β) (a:α), (∀ a b,b ∈ l→ f a b=g a b)→ l.foldl f a=l.foldl g a | [],_,_=>rfl | b :: l,a,h=>by simp only [List.foldl_cons] rw [h a b List.mem_cons_self] exact foldl_cg f g l _ (fun a' b' hb=>h a' b' (List.mem_cons_of_mem _ hb)) theorem xh_get (inW H:Nat) (x h:Array Word) (t q:Nat) (hq:q< inW+H+1) : (xhOf inW H x h t)[0*(inW+H+1)+q]! = gA inW H x h t q:=by rw [Nat.zero_mul,Nat.zero_add]; unfold xhOf; exact ofFn_get! _ _ _ hq end theorem xvB_spec (x h:Array Word) (inW H t:Nat) (hb:t*inW+inW+H+1≤ 4294967295) (hxs:x.size< 2 ^ 32) (hhs:h.size< 2 ^ 32) : (xvB x h inW H t).c.toNat = (D.C_keep (fun p=>x[t*inW+p]!) inW ++ List.range' inW H ++ [inW+H]).length ∧ (xvB x h inW H t).c.toNat≤ (xvB x h inW H t).xs.size ∧ (xvB x h inW H t).c.toNat≤ (xvB x h inW H t).ix.size∧(xvB x h inW H t).xs.size< 2 ^ 32 ∧ (∀ k q:Nat,(D.C_keep (fun p=>x[t*inW+p]!) inW ++ List.range' inW H ++ [inW+H])[k]? = some q → ((xvB x h inW H t).ix[k]! : UInt32).toNat=q ∧ (xvB x h inW H t).xs.data[k]! = dv (xhOf inW H x h t)[0*(inW+H+1)+q]!) ∧ (xvB x h inW H t).a=(D.C_keep (fun p=>x[t*inW+p]!) inW ++ List.range' inW H ++ [inW+H]).foldl (fun a q=>a+(dv (xhOf inW H x h t)[0*(inW+H+1)+q]!).abs) 0 ∧ ((xvB x h inW H t).ok=true → ∀ j,j< H→ good h[j]! = true):=by obtain ⟨z1,z2,z3,z4,z5⟩:=xvAr inW H t hb have ui:inW.toUSize.toNat=inW:=qAd inW z1 have uH:H.toUSize.toNat=H:=qAd H z2 have uo:(t*inW).toUSize.toNat=t*inW:=qAd _ z3 have u0:(0:USize).toNat=0:=rfl obtain ⟨a1,a2,a3⟩:=cxX_spec x (t*inW).toUSize inW.toUSize (t*inW) uo (by rw [uo,ui]; exact z4) hxs inW 0 (FloatArray.emptyWithCapacity (inW+H+1)) (Array.emptyWithCapacity (inW+H+1)) 0 (by rw [ui,u0,Nat.zero_add]) rfl rfl rfl rw [ui] at a1 a2 a3 have hKl:(D.C_keep (fun p=>x[t*inW+p]!) inW).length≤ inW:=D.qBj _ _ have hKm : ∀ q ∈ D.C_keep (fun p=>x[t*inW+p]!) inW,q< inW:=(D.qDs _ inW).2.1 have gx : ∀ q,q< inW→ (xhOf inW H x h t)[0*(inW+H+1)+q]! = x[t*inW+q]! := fun q hq=>by rw [xh_get _ _ _ _ _ _ (Nat.lt_succ_of_lt (Nat.lt_of_lt_of_le hq (Nat.le_add_right _ _)))]; unfold gA rw [if_pos hq] unfold xvB dsimp only generalize cxX x (t*inW).toUSize inW 0 (FloatArray.emptyWithCapacity (inW+H+1)) (Array.emptyWithCapacity (inW+H+1)) 0=v at a1 a2 a3 ⊢ obtain ⟨b1,b2,b3,b4,b5⟩:=cxH_spec h inW.toUSize H.toUSize hhs (by rw [ui,uH]; exact z5) (fun q=>(xhOf inW H x h t)[0*(inW+H+1)+q]!) (fun j hj=>by rw [uH] at hj show (xhOf inW H x h t)[0*(inW+H+1)+(inW.toUSize.toNat+j)]! = h[j]! rw [ui,xh_get _ _ _ _ _ _ (Nat.lt_succ_of_lt (Nat.add_lt_add_left hj inW))]; 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]) (by show (xhOf inW H x h t)[0*(inW+H+1)+(inW.toUSize.toNat+H.toUSize.toNat)]! = oneW rw [ui,uH,xh_get _ _ _ _ _ _ (Nat.lt_succ_self _)]; unfold gA rw [if_neg (Nat.not_lt.mpr (Nat.le_add_right _ _)),if_neg (Nat.lt_irrefl _)]) (D.C_keep (fun p=>x[t*inW+p]!) inW) H 0 v.xs v.ix v.a true (by rw [uH,u0,Nat.zero_add]) (by rw [a1,ui,u0,List.range'_zero,List.append_nil] exact List.map_congr_left (fun q hq=>congrArg dv (gx q (hKm q hq)).symm)) (by rw [a2,ui,u0,List.range'_zero,List.append_nil]) (by rw [a3,ui,u0,List.range'_zero,List.append_nil] exact foldl_cg _ _ _ 0 (fun a q hq=>congrArg (fun z=>a+(dv z).abs) (gx q (hKm q hq)).symm)) (fun _ j hj=>absurd hj (Nat.not_lt_zero _)) rw [ui,uH] at b1 b2 b4; rw [uH] at b5 obtain ⟨c1,c2,c3,c4,c5⟩:=xv_fin _ _ _ (by rw [List.length_append,List.length_append,List.length_range',List.length_singleton] exact Nat.lt_of_le_of_lt (Nat.add_le_add_right (Nat.add_le_add_right hKl H) 1) z5) b1 b2 b3 exact ⟨c1,c2,c3,c4,c5,b4,b5⟩ def grpS (H N:Nat) (rs:Nat→ Float) (c:Nat):D.G16 := ⟨rs (rowOf H (2*c) 0),rs (rowOf H (2*c) 1),rs (rowOf H (2*c) 2),rs (rowOf H (2*c) 3), rs (rowOf H (2*c) 4),rs (rowOf H (2*c) 5),rs (rowOf H (2*c) 6),rs (rowOf H (2*c) 7), rs (rowOf H (2*c+1) 0),rs (rowOf H (2*c+1) 1),rs (rowOf H (2*c+1) 2),rs (rowOf H (2*c+1) 3), rs (rowOf H (2*c+1) 4),rs (rowOf H (2*c+1) 5),rs (rowOf H (2*c+1) 6),rs (rowOf H (2*c+1) 7)⟩ mutual theorem grp16 (xs:FloatArray) (ix:Array UInt32) (N H:Nat) (Wc:Array Word) (c:Nat) (n p p':USize) (hp:p.toNat=2*c*(8*N)) (hp':p'.toNat=(2*c+1)*(8*N)) (hc:c< (H+3) / 4) (hH:0< H) (hN0:0< N) (hN:N< 2 ^ 32) (hsW:Wc.size=4*H*N) (hW32:4*H*N< 2 ^ 32) (hx:n.toNat≤ xs.size) (hi:n.toNat≤ ix.size) (hb:p.toNat+8*N.toUSize.toNat≤ (pkX N H Wc).size) (hb':p'.toNat+8*N.toUSize.toNat≤ (pkX N H Wc).size) (hs:(pkX N H Wc).size< 2 ^ 32) (xf:Nat→ Float) (L:List Nat) (hL:L.length=n.toNat) (hLf : ∀ k q:Nat,L[k]? = some q→ q< N∧(ix[k]! : UInt32).toNat=q∧xs.data[k]! = xf q) : D.go16W xs (pkX N H Wc) ix p p' N.toUSize n 0 hx hi hb hb' hs 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = grpS H N (fun rho=>L.foldl (fun acc q=>acc+xf q*dv Wc[rho*N+q]!) 0) c:=by rw [D.g16W,blk8 xs ix N H Wc (2*c) n p hp (by omega) hH hN0 hN hsW hW32 hx hi hb hs xf L hL hLf, blk8 xs ix N H Wc (2*c+1) n p' hp' (by omega) hH hN0 hN hsW hW32 hx hi hb' hs xf L hL hLf] rfl theorem push_get! {α:Type} [Inhabited α] (a:Array α) (v:α) (i:Nat) : (a.push v)[i]! = if i< a.size then a[i]! else if i=a.size then v else default:=by by_cases h1:i< a.size · rw [if_pos h1,getElem!_pos (a.push v) i (by simp; omega),getElem!_pos a i h1,Array.getElem_push_lt] · rw [if_neg h1] by_cases h2:i=a.size · subst h2; rw [if_pos rfl,getElem!_pos (a.push v) _ (by simp),Array.getElem_push_eq] · rw [if_neg h2,getElem!_neg (a.push v) i (by simp; omega)] end mutual theorem dotsY_spec (Q:LXq) (v:XV) (N H:Nat) (rs:Nat→ Float) (hok : ∀ c,c< (H+3) / 4 → ∀ (p p':USize),p.toNat=2*c*(8*N)→ p'.toNat=(2*c+1)*(8*N) → ∀ hg:v.c.toNat≤ v.xs.size∧v.c.toNat≤ v.ix.size∧p.toNat+8*N.toUSize.toNat≤ Q.P.size ∧ p'.toNat+8*N.toUSize.toNat≤ Q.P.size∧Q.P.size≤ 4294967295, D.go16W v.xs Q.P v.ix p p' N.toUSize v.c 0 hg.1 hg.2.1 hg.2.2.1 hg.2.2.2.1 (D.qA9 hg.2.2.2.2) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0=grpS H N rs c) (hcond : ∀ c,c< (H+3) / 4→ v.c.toNat≤ v.xs.size∧v.c.toNat≤ v.ix.size ∧ (2*c*8*N).toUSize.toNat+8*N.toUSize.toNat≤ Q.P.size ∧ ((2*c+1)*8*N).toUSize.toNat+8*N.toUSize.toNat≤ Q.P.size∧Q.P.size≤ 4294967295) (hpn : ∀ c,c< (H+3) / 4→ (2*c*8*N).toUSize.toNat=2*c*(8*N) ∧ ((2*c+1)*8*N).toUSize.toNat=(2*c+1)*(8*N)) : ∀ (fuel c:Nat) (R:Array D.G16),R.size=c→ (∀ c',c'< c→ R[c']! = grpS H N rs c') → c+fuel≤ (H+3) / 4 → ∀ c',c'< c+fuel→ (dotsY Q v N c fuel R)[c']! = grpS H N rs c':=by intro fuel induction fuel with | zero=>intro c R _ HR _ c' hc'; unfold dotsY; exact HR c' hc' | succ fuel ih => intro c R hR HR hcf c' hc' unfold dotsY dsimp only have hcG:c< (H+3) / 4:=Nat.lt_of_lt_of_le (Nat.lt_add_of_pos_right (Nat.succ_pos fuel)) hcf rw [dif_pos (hcond c hcG)] apply ih (c+1) _ (by rw [Array.size_push,hR]) _ (by rw [Nat.add_assoc,Nat.add_comm 1 fuel]; exact hcf) c' (by rw [Nat.add_assoc,Nat.add_comm 1 fuel]; exact hc') intro c'' hc'' rw [push_get!, hR] by_cases h1:c''< c · rw [if_pos h1]; exact HR c'' h1 · have:c''=c:=Nat.le_antisymm (Nat.le_of_lt_succ hc'') (Nat.le_of_not_lt h1) subst this rw [if_neg h1,if_pos rfl] exact hok c'' hcG _ _ (hpn c'' hcG).1 (hpn c'' hcG).2 (hcond c'' hcG) theorem unit_ok (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh h cs:Array Word) (t:Nat) (hQ:(lxPrep inW H wih whh bih bhh).ok=true) (hgx : ∀ j,j< inW→ good x[t*inW+j]! = true) (hgh : ∀ j,j< H→ good h[j]! = true) (hcs:cs.size< 2 ^ 32) (L:List Nat) (hl:L.Nodup) (hl2 : ∀ p ∈ L,p< inW+H+1) (hz : ∀ p,p< inW+H+1→ p ∉ L→ (xhOf inW H x h t)[0*(inW+H+1)+p]! &&& 0x7FFFFFFF=0) (A:Float) (hA:A=L.foldl (fun a p=>a+(dv (xhOf inW H x h t)[0*(inW+H+1)+p]!).abs) 0) (Hs v:USize) (hHs:Hs.toNat=H) (hH:4*H+8< 2 ^ 32) (u:Nat) (hu:u< H) (hv:v.toNat=u) (rs:Nat→ Float) (hrs : ∀ k,rs k=L.foldl (fun acc p=>acc+dv (xhOf inW H x h t)[0*(inW+H+1)+p]! * dv (catW inW H (4*H) wih whh bih)[k*(inW+H+1)+p]!) 0) : unitW sig tanh (inW+H+1) (Thunk.mk fun _=>xhOf inW H x h t) cs (lxPrep inW H wih whh bih bhh) (D.loOf (nfOf (inW+H+1)*(dv (lxPrep inW H wih whh bih bhh).hv*A+(lxPrep inW H wih whh bih bhh).bm))) (D.spOf (D.loOf (nfOf (inW+H+1)*(dv (lxPrep inW H wih whh bih bhh).hv*A + (lxPrep inW H wih whh bih bhh).bm)))) (nfOf (inW+H+1)) A Hs v (rs u) (rs (H+u)) (rs (2*H+u)) (rs (3*H+u)) = (toWord (Model.mul (ofW (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (3*H+u)))) (ofW (tanh (Pinned.dotFn 2 (fun j=>if j=0 then 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 u)) (fun j=>if j=0 then cs[u]! else tanh (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (2*H+u))))))), Pinned.dotFn 2 (fun j=>if j=0 then 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 u)) (fun j=>if j=0 then cs[u]! else tanh (gateWith Pinned.dotFn inW H x wih whh bih bhh h t (2*H+u)))):=by have G:=fun k (hk:k< 4*H)=>gate_ok inW H x wih whh bih bhh h t hQ hgx hgh L hl hl2 hz A hA k hk (rs k) (hrs k) obtain ⟨w0,w1,w2,w3,w4,w5⟩:=unitAr H u hu hH obtain ⟨i1,i2,i3,i4⟩:=stepIdx4 H u hu have e0:v=u.toUSize:=USize.toNat_inj.mp (by rw [hv,qAd u w0]) have e1:Hs+v=(H+u).toUSize := USize.toNat_inj.mp (by rw [D.qAf _ _ (by rw [hHs,hv]; exact w1),hHs,hv,qAd _ w1]) have t2:(2:USize).toNat=2:=D.uk 2 (by decide) have t3:(3:USize).toNat=3:=D.uk 3 (by decide) have m2:(2*Hs).toNat=2*H:=by rw [D.qWm _ _ (by rw [t2,hHs]; exact w2),t2,hHs] have m3:(3*Hs).toNat=3*H:=by rw [D.qWm _ _ (by rw [t3,hHs]; exact w3),t3,hHs] have e2:2*Hs+v=(2*H+u).toUSize := USize.toNat_inj.mp (by rw [D.qAf _ _ (by rw [m2,hv]; exact w4),m2,hv,qAd _ w4]) have e3:3*Hs+v=(3*H+u).toUSize := USize.toNat_inj.mp (by rw [D.qAf _ _ (by rw [m3,hv]; exact w5),m3,hv,qAd _ w5]) unfold unitW dsimp only rw [e1,e2,e3,G (H+u) i1,G (2*H+u) i3,G (3*H+u) i4,D.qAg cs v hcs,hv] rw [e0,G u i2,cellF_eq,mulF_eq] theorem rowOf_eq (H b l u:Nat) (h:2*b+l / 4=u) (hu:u< H):rowOf H b l=l % 4*H+u:=by unfold rowOf; rw [h,Nat.min_eq_left (Nat.le_sub_one_of_lt hu)] theorem lt4 (j:Nat) (h:j< 4):j=0 ∨ j=1 ∨ j=2 ∨ j=3:=by rcases Nat.lt_or_eq_of_le (Nat.le_of_lt_succ h) with h3 | h3 · rcases Nat.lt_or_eq_of_le (Nat.le_of_lt_succ h3) with h2 | h2 · rcases Nat.lt_or_eq_of_le (Nat.le_of_lt_succ h2) with h1 | h1 · exact Or.inl (Nat.lt_one_iff.mp h1) · exact Or.inr (Or.inl h1) · exact Or.inr (Or.inr (Or.inl h2)) · exact Or.inr (Or.inr (Or.inr h3)) end mutual theorem lane_grpS (H N:Nat) (rs:Nat→ Float) (c j:Nat) (hj:j< 4) (hu:4*c+j< H) : lane (grpS H N rs c) j 0=rs (4*c+j)∧lane (grpS H N rs c) j 1=rs (H+(4*c+j)) ∧ lane (grpS H N rs c) j 2=rs (2*H+(4*c+j))∧lane (grpS H N rs c) j 3=rs (3*H+(4*c+j)):=by have t0:2*(2*c)=4*c:=(Nat.mul_assoc 2 2 c).symm have t1:2*(2*c+1)=4*c+2:=by rw [Nat.mul_add,t0] have z : ∀ u,rs (0*H+u)=rs u:=fun u=>by rw [Nat.zero_mul,Nat.zero_add] have o : ∀ u,rs (1*H+u)=rs (H+u):=fun u=>by rw [Nat.one_mul] have e:=fun b l (h:2*b+l / 4=4*c+j)=>congrArg rs (rowOf_eq H b l _ h hu) rcases lt4 j hj with rfl | rfl | rfl | rfl · exact ⟨(e _ 0 (by rw [t0])).trans (z _),(e _ 1 (by rw [t0])).trans (o _), e _ 2 (by rw [t0]),e _ 3 (by rw [t0])⟩ · exact ⟨(e _ 4 (by rw [t0])).trans (z _),(e _ 5 (by rw [t0])).trans (o _), e _ 6 (by rw [t0]),e _ 7 (by rw [t0])⟩ · exact ⟨(e _ 0 (by rw [t1])).trans (z _),(e _ 1 (by rw [t1])).trans (o _), e _ 2 (by rw [t1]),e _ 3 (by rw [t1])⟩ · exact ⟨(e _ 4 (by rw [t1])).trans (z _),(e _ 5 (by rw [t1])).trans (o _), e _ 6 (by rw [t1]),e _ 7 (by rw [t1])⟩ theorem L_facts (x:Array Word) (inW H t:Nat) (h:Array Word) : (D.C_keep (fun p=>x[t*inW+p]!) inW ++ List.range' inW H ++ [inW+H]).Nodup ∧ (∀ p ∈ D.C_keep (fun p=>x[t*inW+p]!) inW ++ List.range' inW H ++ [inW+H],p< inW+H+1) ∧ (∀ p,p< inW+H+1→ p ∉ D.C_keep (fun p=>x[t*inW+p]!) inW ++ List.range' inW H ++ [inW+H] → (xhOf inW H x h t)[0*(inW+H+1)+p]! &&& 0x7FFFFFFF=0):=by obtain ⟨k1,k2,k3⟩:=D.qDs (fun p=>x[t*inW+p]!) inW refine ⟨?_, ?_, ?_⟩ · rw [List.nodup_append,List.nodup_append] refine ⟨⟨k1,List.nodup_range',fun a ha b hb => ?_⟩,List.nodup_singleton _,fun a ha b hb => ?_⟩ · have:=k2 a ha; rw [List.mem_range'_1] at hb; omega · rw [List.mem_singleton] at hb; subst hb rw [List.mem_append] at ha rcases ha with ha | ha · have:=k2 a ha; omega · rw [List.mem_range'_1] at ha; omega · intro p hp rw [List.mem_append,List.mem_append,List.mem_singleton] at hp rcases hp with (hp | hp) | hp · have:=k2 p hp; omega · rw [List.mem_range'_1] at hp; omega · omega · intro p hp hn simp only [List.mem_append,List.mem_singleton,not_or] at hn obtain ⟨⟨n1,n2⟩,n3⟩:=hn have hpi:p< inW:=by by_contra hc; apply n2; rw [List.mem_range'_1]; omega rw [xh_get _ _ _ _ _ _ hp]; unfold gA; rw [if_pos hpi] exact k3 p hpi n1 end theorem lstmStepX_eq (sig tanh:Word→ Word) (inW H:Nat) (x wih whh bih bhh:Array Word) (hQ:(lxPrep inW H wih whh bih bhh).ok=true) (hx:x.all good=true) (hxs:x.size≤ 4294967295) : lstmStepX sig tanh inW H x wih whh bih bhh (lxPrep inW H wih whh bih bhh) = lstmStepWith Pinned.dotFn sig tanh inW H x wih whh bih bhh:=by funext t st unfold lstmStepX split · rename_i hc obtain ⟨hb,hs1,hs2⟩:=hc obtain ⟨v1,v2,v3,v4,v5,v6,v7⟩:=xvB_spec x st.1 inW H t hb (Nat.lt_succ_of_le hxs) (Nat.lt_succ_of_le hs1) dsimp only split · rename_i hok have hgh:=v7 hok obtain ⟨-, -, hN,hH,hP⟩:=lxOk inW H wih whh bih bhh hQ obtain ⟨hl,hl2,hz⟩:=L_facts x inW H t st.1 have hgx : ∀ j,j< inW→ good x[t*inW+j]! = true:=fun j _=>all_good x hx _ set L:=D.C_keep (fun p=>x[t*inW+p]!) inW ++ List.range' inW H ++ [inW+H] with hLdef set N:=inW+H+1 with hNdef obtain ⟨a1, -, a3, -, a5,a6⟩:=lxAr N H hN hP (Nat.lt_succ_of_le (Nat.le_add_left H inW)) set X:=xhOf inW H x st.1 t with hXdef set Wc:=catW inW H (4*H) wih whh bih with hWc set v:=xvB x st.1 inW H t with hvdef set rs:Nat→ Float:=fun k=>L.foldl (fun acc p=>acc+dv X[0*N+p]! * dv Wc[k*N+p]!) 0 with hrs have sW:Wc.size=4*H*N:=by rw [hWc]; unfold catW; exact Array.size_ofFn have sP:(lxPrep inW H wih whh bih bhh).P.size=(H+3) / 4*16*N:=fbuild_size _ _ have hPd:(lxPrep inW H wih whh bih bhh).P=pkX N H Wc:=rfl have hLf : ∀ k q:Nat,L[k]? = some q→ q< N∧(v.ix[k]! : UInt32).toNat=q ∧ v.xs.data[k]! = dv X[0*N+q]! := fun k q hq => ⟨hl2 q (List.mem_of_getElem? hq),(v5 k q hq).1,(v5 k q hq).2⟩ have hpn : ∀ c,c< (H+3) / 4→ (2*c*8*N).toUSize.toNat=2*c*(8*N) ∧ ((2*c+1)*8*N).toUSize.toNat=(2*c+1)*(8*N):=fun c hc => ⟨(blkAr N H c hc hP).1,(blkAr N H c hc hP).2.1⟩ have hNu:N.toUSize.toNat=N:=qAd N a3 have hcond : ∀ c,c< (H+3) / 4→ v.c.toNat≤ v.xs.size∧v.c.toNat≤ v.ix.size ∧ (2*c*8*N).toUSize.toNat+8*N.toUSize.toNat≤ (lxPrep inW H wih whh bih bhh).P.size ∧ ((2*c+1)*8*N).toUSize.toNat+8*N.toUSize.toNat≤ (lxPrep inW H wih whh bih bhh).P.size ∧ (lxPrep inW H wih whh bih bhh).P.size≤ 4294967295:=fun c hc => ⟨v2,v3,by rw [(blkAr N H c hc hP).1,hNu,sP]; exact (blkAr N H c hc hP).2.2.1, by rw [(blkAr N H c hc hP).2.1,hNu,sP]; exact (blkAr N H c hc hP).2.2.2,by rw [sP]; exact hP⟩ have hR:=dotsY_spec (lxPrep inW H wih whh bih bhh) v N H rs (fun c hc p p' hp hp' hg=>by exact grp16 v.xs v.ix N H Wc c v.c p p' hp hp' hc hH (Nat.succ_pos _) a3 sW a1 hg.1 hg.2.1 hg.2.2.1 hg.2.2.2.1 (D.qA9 hg.2.2.2.2) (fun q=>dv X[0*N+q]!) L v1.symm hLf) hcond hpn ((H+3) / 4) 0 (Array.emptyWithCapacity ((H+3) / 4)) rfl (fun c hc=>absurd hc (Nat.not_lt_zero c)) (Nat.le_of_eq (Nat.zero_add _)) have hHu:H.toUSize.toNat=H:=qAd H a6 rw [build8_spec H (quadK sig tanh N _ st.2 _ _ _ _ _ _ _) (unitK sig tanh N _ st.2 _ _ _ _ _ _ _) (fun k _=>quadK_eq sig tanh N _ st.2 _ _ _ _ _ _ _ k) H 0 _ _ (Nat.zero_le _) (Nat.le_add_left _ _) (by rfl) (by rfl)] have hK : ∀ i,i< H→ unitK sig tanh N (Thunk.mk fun _=>X) st.2 (lxPrep inW H wih whh bih bhh) (D.loOf (nfOf N*(dv (lxPrep inW H wih whh bih bhh).hv*v.a+(lxPrep inW H wih whh bih bhh).bm))) (D.spOf (D.loOf (nfOf N*(dv (lxPrep inW H wih whh bih bhh).hv*v.a+(lxPrep inW H wih whh bih bhh).bm)))) (nfOf N) v.a H.toUSize (dotsY (lxPrep inW H wih whh bih bhh) v N 0 ((H+3) / 4) (Array.emptyWithCapacity ((H+3) / 4))) i = (toWord (Model.mul (ofW (sig (gateWith Pinned.dotFn inW H x wih whh bih bhh st.1 t (3*H+i)))) (ofW (tanh (Pinned.dotFn 2 (fun j=>if j=0 then sig (gateWith Pinned.dotFn inW H x wih whh bih bhh st.1 t (H+i)) else sig (gateWith Pinned.dotFn inW H x wih whh bih bhh st.1 t i)) (fun j=>if j=0 then st.2[i]! else tanh (gateWith Pinned.dotFn inW H x wih whh bih bhh st.1 t (2*H+i))))))), Pinned.dotFn 2 (fun j=>if j=0 then sig (gateWith Pinned.dotFn inW H x wih whh bih bhh st.1 t (H+i)) else sig (gateWith Pinned.dotFn inW H x wih whh bih bhh st.1 t i)) (fun j=>if j=0 then st.2[i]! else tanh (gateWith Pinned.dotFn inW H x wih whh bih bhh st.1 t (2*H+i)))) := fun i hi=>by unfold unitK rw [hR (i / 4) (div4 i H hi)] obtain ⟨l0,l1,l2,l3⟩:=lane_grpS H N rs (i / 4) (i % 4) (Nat.mod_lt _ (by decide)) (by rw [Nat.div_add_mod]; exact hi) rw [l0,l1,l2,l3,Nat.div_add_mod] exact unit_ok sig tanh inW H x wih whh bih bhh st.1 st.2 t hQ hgx hgh (Nat.lt_succ_of_le hs2) L hl hl2 hz v.a v6 H.toUSize i.toUSize hHu a5 i hi (qAd i (Nat.lt_trans hi a6)) rs (fun k=>rfl) unfold lstmStepWith dsimp only refine Prod.ext (Array.ext (by rw [Array.size_ofFn,Array.size_ofFn]) fun i hi1 _ => ?_) (Array.ext (by rw [Array.size_ofFn,Array.size_ofFn]) fun i hi1 _ => ?_) · have hiH:i< H:=by rw [Array.size_ofFn] at hi1; exact hi1 rw [Array.getElem_ofFn,Array.getElem_ofFn] dsimp only rw [hK i hiH] dsimp only obtain ⟨i1,i2,i3,i4⟩:=stepIdx4 H i hiH rw [ofFn_get!F _ _ (by assumption),ofFn_get!F _ _ hiH,ofFn_get!F _ _ (by assumption), ofFn_get!F _ _ (by assumption),ofFn_get!F _ _ (by assumption)] · have hiH:i< H:=by rw [Array.size_ofFn] at hi1; exact hi1 rw [Array.getElem_ofFn,Array.getElem_ofFn] dsimp only rw [hK i hiH] dsimp only obtain ⟨i1,i2,i3,i4⟩:=stepIdx4 H i hiH rw [ofFn_get!F _ _ (by assumption),ofFn_get!F _ _ (by assumption),ofFn_get!F _ _ (by assumption)] · rfl · rfl theorem lstmX_eq:lstmX=lstmWith Pinned.dotFn sigmoidF3 tanhF3:=by funext T inW H x wih whh bih bhh unfold lstmX rw [(lxGet inW H wih whh bih bhh).2] dsimp only split · rename_i hc simp only [Bool.and_eq_true] at hc obtain ⟨⟨⟨hok,hQ⟩,hx⟩,hxs⟩:=hc rw [lstmStepX_eq sigI tanhI inW H x wih whh bih bhh hQ hx (by simpa using hxs), recRun_eq T H _ _ (fun t st=>by unfold lstmStepWith; exact Array.size_ofFn),sigI_eq hok,tanhI_eq hok] rfl · rfl end RnnX end RnnFast def kernels:Kernels where core:=specCore dense:=⟨C.linG,gemmSpec⟩ conv:=specConv elem:=specElem norm:=specNorm attn:=specAttn rnn:=⟨RnnFast.lstmX,RnnFast.gruXZ⟩ theorem correct:Obligation kernels:=by refine obligation_of_families kernels rfl ?_ ?_ ?_ ?_ ?_ ?_ · show (⟨C.linG,gemmSpec⟩:DenseKernels)=specDense rw[C.qHb];rfl · exact rfl · exact rfl · exact rfl · exact rfl · show (⟨RnnFast.lstmX,RnnFast.gruXZ⟩:RecurrentKernels)=specRnn rw[RnnFast.lstmX_eq,RnnFast.gruXZ_eq,RnnFast.sigmoidF3_eq,RnnFast.tanhF3_eq,FastAct.sigmoidF_eq,FastAct.tanhF_eq,Pinned.dotFn_eq_dotOf];rfl end Submission