import ContractExact namespace Submission open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats local notation"¡"=>Nat.mod_eq_of_lt local notation"¢"=>UInt64.toNat_inj.mp local notation"£"=>USize.lt_iff_toNat_lt local notation"¤"=>UInt64.toNat_add local notation"¥"=>Bool.false_eq_true local notation"§"=>UInt64.toNat_sub_of_le local notation"©"=>Nat.shiftRight_eq_div_pow local notation"®"=>Nat.shiftLeft_eq local notation"¶"=>Nat.mul_le_mul_right local notation"¿"=>UInt64.le_iff_toNat_le local notation"˂"=>Nat.pow_le_pow_right local notation"˃"=>UInt64.lt_iff_toNat_lt local notation"˄"=>Nat.two_pow_pos local notation"˅"=>UInt32.toNat_inj.mp local notation"˒"=>UInt64.toNat_shiftLeft local notation"˓"=>UInt64.le_iff_toNat_le.mp local notation"˔"=>UInt64.toNat_shiftRight local notation"˕"=>Nat.and_two_pow_sub_one_eq_mod local notation"˖"=>USize.le_size local notation"⠁"=>Array.ofFn local notation"˞"=>Nat.pos_of_ne_zero local notation"˟"=>Nat.add_mul_mod_self_right local notation"˥"=>Nat.zero_add local notation"˦"=>Nat.add_mul_div_right local notation"˧"=>Nat.le_mul_of_pos_right local notation"˨"=>UInt64.toNat_lt_size local notation"˩"=>USize.lt_iff_toNat_lt.mp local notation"˪"=>Nat.pow_add local notation"˫"=>Nat.div_eq_of_lt local notation"˭"=>Nat.div_div_eq_div_mul local notation"˯"=>Bool.and_eq_true local notation"˰"=>UInt64.toNat_sub local notation"˱"=>Nat.mul_comm local notation"˲"=>UInt32.toNat_shiftRight local notation"˳"=>Nat.mul_pos local notation"˴"=>Nat.mul_lt_mul_of_pos_right local notation"˵"=>Nat.mod_lt local notation"˶"=>Nat.div_lt_of_lt_mul local notation"˷"=>Bool.xor local notation"˸"=>Nat.le_mul_of_pos_left local notation"˹"=>Nat.add_comm local notation"˺"=>Nat.mul_assoc local notation"˻"=>Nat.log2_self_le local notation"˼"=>Nat.le_add_right local notation"˽"=>List.range'_succ local notation"⠌"=>Nat.mul_lt_mul_of_lt_of_le local notation"˿"=>Nat.mul_eq_zero.mp local notation"͵"=>Nat.lt_of_le_of_ne local notation"҂"=>Nat.lt_of_le_of_lt local notation"՚"=>Nat.eq_zero_or_pos local notation"՛"=>List.range local notation"՜"=>UInt64.toNat_toUInt32 local notation"՝"=>UInt32.toNat_toUInt64 local notation"՞"=>UInt64.toNat_zero local notation"՟"=>UInt32.toNat_lt_size local notation"։"=>Int.add_emod local notation"֍"=>USize.size local notation"֎"=>Nat.lt_log2_self local notation"֏"=>Nat.div_add_mod' local notation"׀"=>Nat.add_mul local notation"׃"=>UInt32.ofNat local notation"⠍"=>UInt32.le_iff_toNat_le local notation"׳"=>Nat.mul_zero local notation"״"=>Bool.or_eq_true local notation"؆"=>Bool.eq_iff_iff local notation"؇"=>Array.replicate local notation"⠎"=>Nat.le_div_iff_mul_le local notation"⠏"=>Nat.div_lt_iff_lt_mul local notation"⠃"=>UInt64.le_iff_toNat_le.mpr local notation"؋"=>Nat.one_mul local notation"⠄"=>UInt32.toNat_inj local notation"؍"=>Nat.zero_mul local notation"؎"=>Nat.log2_eq_iff local notation"؏"=>Nat.lt_succ_iff.mp local notation"؛"=>Nat.lt_or_eq_of_le local notation"⠅"=>UInt32.lt_iff_toNat_lt local notation"⠆"=>Nat.pos_iff_ne_zero.mp local notation"؟"=>Nat.cast_sub local notation"⠇"=>USize.toNat_sub_of_le local notation"٫"=>UInt64.toNat_mul local notation"٬"=>UInt64.toNat_inj local notation"٭"=>UInt32.toNat_and local notation"۔"=>List.ext_getElem local notation"⠈"=>UInt32.toNat_toUSize local notation"۩"=>Int.negSucc local notation"۽"=>USize.toNat_one local notation"۾"=>Nat.toUInt64_eq local notation"܀"=>Nat.div_add_mod local notation"܁"=>List.foldl_cons local notation"⠉"=>UInt64.toNat_ofNat' local notation"⠊"=>Nat.div_mul_le_self local notation"܄"=>UInt64.toNat local notation"܅"=>Nat.add_zero local notation"⠂"=>USize.toNat_inj.mp local notation"܇"=>Nat.mul_le_mul local notation"⠋"=>Nat.lt_of_lt_of_le local notation:max x:max "˗"=>UInt64.toNat (x :) local notation:max x:max "܆"=>USize.toNat (x :) local notation:max x:max "؊"=>UInt32.toNat (x :) local notation:max x:max "،"=>Nat.log2 (x :) local notation:max x:max "؝"=>Nat.toUSize (x :) local notation:max x:max "؞"=>Fin.val (x :) local notation:max x:max "٪"=>Array.size (x :) local notation:max x:max "۞"=>ExactRuntime.ConvShape.stride (x :) local notation:max x:max "܂"=>UInt64.toNat_lt (x :) local notation:max x:max "܃"=>Array.toList (x :) local notation:max x:max "܈"=>FloatLib.Floats.Formats.BinaryInterchange.FloatFormat.fracWidth (x :) local notation:max x:max "˾"=>Nat.toUInt64 (x :) local notation:max x:max "׆"=>UInt32.toUInt64 (x :) local notation:max x:max "؈"=>Int.toNat (x :) local notation:max x:max "؉"=>UInt64.toUInt32 (x :) local notation"܉"=>by omega local notation"܊"=>by norm_num local notation"܋"=>by simp local notation"܌"=>by decide local notation"܍"=>by positivity local notation"߶"=>by simp;omega local notation"߷"=>by grind local notation"߸"=>by ring local notation"߹"=>by simp_all local notation"߾"=>0x80000000 local notation"߿"=>0x100000000 local notation"─"=>0x7FFFFFFF local notation"━"=>ite_true local notation"│"=>ite_false local notation"┃"=>decide_eq_true_eq local notation"┄"=>zpow_natCast local notation"┅"=>toDyadic_ofUInt32 local notation"┆"=>Model.roundDyadicGeneral_eq_roundDyadic local notation"┇"=>decodeD_toRat local notation"┈"=>decide_eq_true_iff local notation"┉"=>finishWord_scale local notation"┊"=>mantOf_lt_24 local notation"┋"=>isFinite_ofUInt32 local notation"┌"=>decodeD_negative local notation"┍"=>getElem!_pos local notation"┎"=>Model.NativeBinary32.mkBits local notation"┏"=>FloatFormat.toModel local notation"┐"=>FloatLib.Numerics.roundQuotientEven local notation"┑"=>Model.roundDyadicGeneral local notation"┒"=>finishWord local notation"┓"=>rationalWord local notation"└"=>windowAt local notation"┕"=>ConvShape local notation"┖"=>Float.Model.totalExponent local notation"┗"=>Fmt.minSubnormalExponent local notation"┘"=>FloatLib.Numerics.roundShiftRightEven local notation"┙"=>Model.addDyadic local notation"┚"=>sqrtLower local notation"┛"=>Model.toReal local notation"├"=>sqrtAccuracy local notation"┝"=>decodeD local notation"┞"=>UInt64 local notation"┟"=>UInt32 local notation"┠"=>Array local notation"┡"=>USize local notation"┢"=>Word local notation"┣"=>Bool structure Acc where pos:┠ Nat neg:┠ Nat special:┣ negZero:┣ def Acc.empty:Acc:=⟨Array.replicate 18 0,Array.replicate 18 0,false,true⟩ def Acc.total (acc:Acc):Int:=(limbVal acc.pos.toList:Int)-limbVal acc.neg.toList @[inline] def Acc.add (acc:Acc) (m idx:Nat) (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⟩ @[inline] def Acc.markSpecial (acc:Acc):Acc := match acc with | ⟨pos,ng,_,nz⟩=>⟨pos,ng,true,nz⟩ lemma Acc.add_spec (acc:Acc) (m idx:Nat) (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 h0:m=0 . simp[Acc.add,Acc.total,h0,hp,hn] . cases neg . refine⟨by simp[Acc.add,h0,addLimbs64_size,hp],by simp[Acc.add,h0,hn],by simp[Acc.add,h0],by simp[Acc.add,h0],?_⟩ simp only[Acc.add,h0,│,¥,addLimbs64_eq _ _ _ hm,Acc.total];rw[addLimbs_val _ _ _ ܉];push_cast;ring . refine⟨by simp[Acc.add,h0,hp],by simp[Acc.add,h0,addLimbs64_size,hn],by simp[Acc.add,h0],by simp[Acc.add,h0],?_⟩ simp only[Acc.add,h0,│,━,addLimbs64_eq _ _ _ hm,Acc.total];rw[addLimbs_val _ _ _ ܉];push_cast;ring lemma Acc.total_empty:Acc.empty.total=0:=܌ section open FloatLib.Numerics lemma ZbF (s:┣) (m:Nat) (e:Int) (j:Nat) (h:j+25<=m،):Model.roundDyadic Fmt ⟨s,shiftRightJam m j,e+j⟩=Model.roundDyadic Fmt ⟨s,m,e⟩:=by have h7:m≠0:=by rintro rfl;simp at h have h9:2^m،<=m:=˻ h7;have hm:2^(j+1)<=m:=le_trans (˂ ܊ ܉) h9 have h0:(shiftRightJam m j)،=m،-j:=log2_shiftRightJam m j hm;have hc:shiftRightJam m j≠0:=shiftRightJam_ne_zero m j (le_trans (˂ ܊ ܉) hm) rw[<- ┆,<- ┆];unfold Model.roundDyadicGeneral;simp only[beq_iff_eq,│,h0];have hd:((m،-j:Nat):Int)+(e+j)=(m،:Int)+e:=܉ have h8:Fmt܈=23:=rfl;have h6:┗ = -149:=rfl;have h5:Fmt.minNormalExponent = -126:=rfl;rw[h8,h6,h5];split_ifs with h1 h2 h3 h4<;>try omega . rfl . congr 1;obtain⟨a,ha⟩:∃ a:Nat,e - -149=۩ a:=⟨(-(e+149)-1)؈,by omega⟩ have hb:e+j - -149=۩ (a-j):=܉ rw[ha,hb];dsimp only;rw[show a-j+1=(a+1)-j by omega] exact roundShiftRightEven_shiftRightJam m j (a+1) ܉ . congr 1;rw[show m،-j-23=(m،-23)-j by omega];exact roundShiftRightEven_shiftRightJam m j _ ܉ def Yg (a:┠ Nat) (i:Nat):Nat -> Nat | 0=>0 | k+1=>a[i]! + 2^32*Yg a (i+1) k lemma Zv (a:┠ Nat) (i k m:Nat):Yg a i (k+m)=Yg a i k+2^(32*k)*Yg a (i+k) m:=by induction k generalizing i with | zero=>simp[Yg] | succ k ih=>rw[show k+1+m=(k+m)+1 by omega,Yg,Yg,ih,show i+1+k=i+(k+1) by omega];ring lemma ZbG (a b:┠ Nat) (i j k:Nat) (h:∀ t,t a[i+t]! = b[j+t]!):Yg a i k=Yg b j k:=by induction k generalizing i j with | zero=>rfl | succ k ih=>rw[Yg,Yg,ih (i+1) (j+1) (λ t ht=>by rw[show i+1+t=i+(t+1) by omega,show j+1+t=j+(t+1) by omega];exact h (t+1) ܉),show a[i]! = b[j]! from by simpa using h 0 ܉] lemma Zw (a:┠ Nat) (i k:Nat):Yg a i k=0↔∀ t,t a[i+t]! = 0:=by induction k generalizing i with | zero=>simp[Yg] | succ k ih => rw[Yg,Nat.add_eq_zero_iff,Nat.mul_eq_zero,ih (i+1)];have hp:(2:ℕ)^32≠0:=܋ constructor . rintro ⟨h0,h1 | h1⟩ t ht . exact absurd h1 hp . rcases t with _ | t . simpa using h0 . rw[show i+(t+1)=i+1+t by omega];exact h1 t ܉ . intro h;refine⟨by simpa using h 0 ܉,Or.inr λ t ht=>?_⟩ rw[show i+1+t=i+(t+1) by omega];exact h (t+1) ܉ lemma ZbH (a:┠ Nat) (i k:Nat) (h:∀ t,t a[i+t]! < 2^32):Yg a i k<2^(32*k):=by induction k generalizing i with | zero=>simp[Yg] | succ k ih => have h0:=h 0 ܉;have h1:=ih (i+1) (λ t ht=>by rw[show i+1+t=i+(t+1) by omega];exact h (t+1) ܉) simp at h0;rw[Yg,show 32*(k+1)=32+32*k by ring,pow_add];linarith lemma K5 (a:┠ Nat) (t:Nat) (h:a٪<=t):a[t]! = 0:=߹ lemma ZbI (a:┠ Nat) (i k:Nat) (h:a٪<=i+k):Yg a i k=limbVal (a܃.drop i):=by induction k generalizing i with | zero=>simp[Yg,List.drop_of_length_le (by simpa using h:a.toList.length<=i),limbVal] | succ k ih => rw[Yg,ih (i+1) ܉];by_cases hi:i a[t]! = 0) (h1:∀ t,lo+n<=t -> a[t]! = 0) : limbVal a܃=2^(32*lo)*Yg a lo n:=by rw[<- List.drop_zero (l:=a܃),<- ZbI a 0 (lo+(n+a٪)) ܉,Zv,Zv] rw[(Zw a 0 lo).2 (λ t ht=>by simpa using h0 t ht),(Zw a (0+lo+n) a٪).2 (λ t _=>h1 _ ܉)] simp def YP (a b:┠ Nat) (i ca cb br:Nat) (out:┠ Nat) : Nat -> ┠ Nat × Nat × Nat × Nat | 0=>(out,ca,cb,br) | k+1 => let ta:=a[i]! + ca let tb:=b[i]! + cb let t:=ta%4294967296+4294967296-tb%4294967296-br YP a b (i+1) (ta/4294967296) (tb/4294967296) (1-t/4294967296) (out.push (t%4294967296)) k lemma K4 (a b:┠ Nat) (i ca cb br:Nat) (out:┠ Nat) (k:Nat) (ha:br<=1) (h0:∀ t,t out[t]! < 2^32) : let r:=YP a b i ca cb br out k r.1.size=out٪+k/\(∀ t,t r.1[t]! < 2^32) /\ (Yg r.1 0 r.1.size:Int)+2^(32*(out٪+k))*(r.2.1-r.2.2.1-r.2.2.2:Int)=Yg out 0 out٪+2^(32*out٪)*((Yg a i k:Int)-Yg b i k+ca-cb-br):=by induction k generalizing i ca cb br out with | zero=>exact⟨by simp[YP],by simpa [YP] using h0,by simp[YP,Yg]⟩ | succ k ih => simp only[YP];set ta:=a[i]! + ca;set tb:=b[i]! + cb;set t:=ta%4294967296+4294967296-tb%4294967296-br;have hd:t%4294967296<2^32:=܉ have h5:∀ s,s < (out.push (t%4294967296))٪ -> (out.push (t%4294967296))[s]! < 2^32:=by intro s hs;simp only[Array.size_push]at hs;rcases ؛ (؏ hs) with hs | rfl . rw[┍ _ s ߶,Array.getElem_push_lt hs,<- ┍ out s hs];exact h0 s hs . rw[┍ _ _ ܋,Array.getElem_push_eq];exact hd obtain⟨h1,h2,h3⟩:=ih (i+1) (ta/4294967296) (tb/4294967296) (1-t/4294967296) (out.push (t%4294967296)) ܉ h5 refine⟨by simp[h1];omega,h2,?_⟩;have h4:Yg (out.push (t%4294967296)) 0 (out٪+1)=Yg out 0 out٪+2^(32*out٪)*(t%4294967296):=by rw[Zv,ZbG _ out 0 0 out٪ (λ s hs=>by rw[┍ _ _ ߶,Array.getElem_push_lt ܉,<- ┍ out _ ܉])] simp only[Yg,˥,׳,܅];rw[┍ _ _ ܋,Array.getElem_push_eq] simp only[Array.size_push]at h3 ⊢;rw[show out٪+(k+1)=out٪+1+k by omega];rw[h3,h4,Yg,Yg];have h6:((t%4294967296:Nat):Int)+4294967296*((ta/4294967296:Nat)-(tb/4294967296:Nat)-(1-t/4294967296:Nat))=(a[i]! : Int)-b[i]! + ca-cb-br:=܉ simp only[Nat.cast_add,Nat.cast_mul,Nat.cast_pow,Nat.cast_ofNat];linear_combination (2:Int)^(32*out٪)*h6 def YW (r:┠ Nat):Nat -> Option Nat | 0=>none | k+1=>if r[k]! != 0 then some k else YW r k def YX (r:┠ Nat):Nat -> ┣ | 0=>false | k+1=>r[k]! != 0||YX r k lemma ZbK (r:┠ Nat) (k:Nat) (h:YW r k=none):∀ t,t r[t]! = 0:=by induction k with | zero=>intro t ht;omega | succ k ih => simp only[YW]at h;split at h . cases h . rename_i hk;intro t ht;rcases ؛ (؏ ht) with ht | rfl . exact ih h t ht . simpa using hk lemma K3 (r:┠ Nat) (k h:Nat) (hh:YW r k=some h):h t r[t]! = 0:=by induction k with | zero=>simp[YW]at hh | succ k ih => simp only[YW]at hh;split at hh . rename_i hk;cases hh;exact⟨by omega,by simpa using hk,λ t h1 h2=>by omega⟩ . rename_i hk;obtain⟨a,b,c⟩:=ih hh;refine⟨by omega,b,λ t h1 h2=>?_⟩;rcases ؛ (؏ h2) with h2 | rfl . exact c t h1 h2 . simpa using hk lemma K2 (r:┠ Nat) (k:Nat):YX r k=false↔∀ t,t r[t]! = 0:=by induction k with | zero=>simp[YX] | succ k ih => simp only[YX,Bool.or_eq_false_iff,bne_eq_false_iff_eq,ih];constructor . rintro ⟨h0,h1⟩ t ht;rcases ؛ (؏ ht) with ht | rfl . exact h1 t ht . exact h0 . intro h;exact⟨h k ܉,λ t ht=>h t ܉⟩ lemma ZbL (r:┠ Nat) (k:Nat):YX r k=(Yg r 0 k != 0):=by have hz:=Zw r 0 k;simp at hz;cases h:YX r k . rw[hz.2 ((K2 r k).1 h)];rfl . have:Yg r 0 k≠0:=λ h0=>by have:=(K2 r k).2 (hz.1 h0);simp_all simp[this] lemma ZbM (low x y h:Nat) (h6:low<2^(32*h)):shiftRightJam (low+2^(32*h)*(x+2^32*y)) (32*h+2)=if x%4 != 0||low != 0 then (y*1073741824+x/4)|||1 else y*1073741824+x/4:=by have h5:2^(32*h+2)=4*2^(32*h):=߷ have hs:x%4<4:=˵ x ܊ have hA:low+2^(32*h)*(x%4)<4*2^(32*h):=by nlinarith have h3:low+2^(32*h)*(x+2^32*y)=(low+2^(32*h)*(x%4))+4*2^(32*h)*(y*1073741824+x/4):=by have h4:=Nat.mod_add_div x 4;conv_lhs=>rw[<- h4] ring have hz:low+2^(32*h)*(x%4)=0↔¬(x%4≠0\/low≠0):=by constructor . intro h0;have h1:=Nat.eq_zero_of_add_eq_zero h0;rcases ˿ h1.2 with h2 | h2<;>omega . intro h0;simp at h0;simp[h0.1,h0.2] unfold shiftRightJam;dsimp only;rw[h5,h3,Nat.add_mul_div_left _ _ ܉,˫ hA,˥,Nat.add_mul_mod_self_left,¡ hA] by_cases hc:x%4≠0\/low≠0 . have:¬ (low+2^(32*h)*(x%4)=0):=λ h0=>hz.mp h0 hc;have hb:(x%4 != 0||low != 0)=true:=߷ simp only[beq_iff_eq,this,│,hb,━] . have:low+2^(32*h)*(x%4)=0:=hz.mpr hc;have hb:(x%4 != 0||low != 0)=false:=߷ simp only[beq_iff_eq,this,━,hb];rfl def Yas (neg:┣) (r:┠ Nat) (e:Int) (negZero:┣):┟ := match YW r r.size with | none=>finishWord 0 e negZero | some 0=>finishWord (if neg then -(r[0]! : Int) else r[0]!) e negZero | some (h+1) => let x:=r[h]! let v:=r[h+1]! * 1073741824+x/4 let m:=if x%4 != 0||YX r h then v|||1 else v toWord (Model.roundDyadic Fmt ⟨neg,m,e+((32*h+2:Nat):Int)⟩) lemma ZbN (neg:┣) (R:Nat) (e:Int) (negZero:┣) (hR:R≠0):┒ (if neg then -(R:Int) else R) e negZero=toWord (Model.roundDyadic Fmt ⟨neg,R,e⟩):=by have h0:(0:Int)simp[finishWord,ofIntDyadic,hR,not_lt.mpr h0.le,˞ hR] lemma K1 (neg:┣) (r:┠ Nat) (e:Int) (negZero:┣) (hr:∀ t,t r[t]! < 2^32) : Yas neg r e negZero=┒ (if neg then -(Yg r 0 r٪:Int) else Yg r 0 r٪) e negZero:=by unfold Yas;split . rename_i h7;rw[(Zw r 0 r٪).2 (λ t ht=>by simpa using ZbK r _ h7 t ht)];simp . rename_i h0;obtain⟨h1,h2,h3⟩:=K3 r _ 0 h0;rw[show r٪=1+(r٪-1) by omega,Zv,(Zw r (0+1) (r٪-1)).2 (λ t ht=>h3 _ ܉ ܉)] simp[Yg] . rename_i h h0;obtain⟨h1,h2,h3⟩:=K3 r _ (h+1) h0;have hR:Yg r 0 r٪=Yg r 0 h+2^(32*h)*(r[h]! + 2^32*r[h+1]!):=by rw[show r٪=h+(2+(r٪-h-2)) by omega,Zv,Zv,(Zw r (0+h+2) _).2 (λ t ht=>h3 _ ܉ ܉)] simp[Yg] have h5:Yg r 0 h<2^(32*h):=ZbH r 0 h (λ t ht=>hr _ ܉);have h4:Yg r 0 r٪≠0:=by rw[hR];have:0<2^(32*h)*(r[h]! + 2^32*r[h+1]!):=by have:=˞ h2;positivity omega have h6:32*h+2+25<=(Yg r 0 r٪)،:=by rw[Nat.le_log2 h4,hR];have:1<=r[h+1]! := ˞ h2;calc 2^(32*h+2+25)<=2^(32*h)*2^32:=by rw[<- pow_add];exact ˂ ܊ ܉ _<=2^(32*h)*(r[h]! + 2^32*r[h+1]!):=by gcongr;linarith _<=_:=܉ rw[ZbN neg _ e negZero h4,<- ZbF neg _ e _ h6,hR,ZbM _ _ _ h h5,ZbL] def Yab (pos neg:┠ Nat):Nat -> Nat | 0=>0 | k+1=>if pos[k]! != 0||neg[k]! != 0 then k+1 else Yab pos neg k lemma ZbO (pos neg:┠ Nat) (k:Nat):∀ t,Yab pos neg k<=t -> t pos[t]! = 0/\neg[t]! = 0:=by induction k with | zero=>intro t _ ht;omega | succ k ih => intro t h1 h2;simp only[Yab]at h1;split at h1 . omega . rename_i hk;rcases ؛ (؏ h2) with h2 | rfl . exact ih t h1 h2 . simpa [״,bne_iff_ne,not_or] using hk def YaL (pos neg:┠ Nat) (e:Int) (negZero:┣):┟ := let lo:=lowLimb pos neg pos.size 0 let n:=Yab pos neg (max pos.size neg.size)+1-lo let e':=e+((32*lo:Nat):Int) let d:=YP pos neg lo 0 0 0 (Array.emptyWithCapacity n) n if d.2.1=0/\d.2.2.1=0/\d.2.2.2=0 then Yas false d.1 e' negZero else let d':=YP neg pos lo 0 0 0 (Array.emptyWithCapacity n) n if d'.2.1=0/\d'.2.2.1=0/\d'.2.2.2=0 then Yas true d'.1 e' negZero else finishLimbs pos neg e negZero lemma N0 (pos neg:┠ Nat) (e:Int) (negZero:┣):YaL pos neg e negZero=┒ ((limbVal pos܃:Int)-limbVal neg܃) e negZero:=by unfold YaL;dsimp only;set lo:=lowLimb pos neg pos٪ 0;set n:=Yab pos neg (max pos٪ neg٪)+1-lo;have h3:=lowLimb_zero pos neg pos٪ 0;have h4:=ZbO pos neg (max pos٪ neg٪);have h5 (a:┠ Nat) (ha:a=pos\/a=neg):limbVal a܃=2^(32*lo)*Yg a lo n:=by apply ZbJ a lo n . intro t ht;rcases ha with rfl | rfl . exact(h3 t ܉ ht).1 . exact(h3 t ܉ ht).2 . intro t ht;by_cases h6:t < max pos٪ neg٪ . rcases ha with rfl | rfl . exact(h4 t ܉ h6).1 . exact(h4 t ܉ h6).2 . rcases ha with rfl | rfl<;>exact K5 _ t ܉ have hP:=h5 pos (Or.inl rfl);have hN:=h5 neg (Or.inr rfl);rw[show(Array.emptyWithCapacity n:┠ Nat)=#[] from rfl];have hd:=K4 pos neg lo 0 0 0 #[] n ܉ ܋;have h7:=K4 neg pos lo 0 0 0 #[] n ܉ ܋;have h9:Yg (#[]:┠ Nat) 0 0=0:=rfl;simp only[List.size_toArray,List.length_nil,׳,pow_zero,one_mul,h9,Nat.cast_zero,zero_add]at hd h7 obtain⟨-,hb,hv⟩:=hd;obtain⟨-,h8,h0⟩:=h7;split_ifs with h1 h2 . rw[K1 false _ _ _ hb,┉,hP,hN];simp;congr 1;rw[h1.1,h1.2.1,h1.2.2]at hv;linear_combination (2:Int)^(32*lo)*hv . rw[K1 true _ _ _ h8,┉,hP,hN];simp;congr 1;rw[h2.1,h2.2.1,h2.2.2]at h0;linear_combination (-(2:Int)^(32*lo))*h0 . exact finishLimbs_eq pos neg e negZero end @[inline] def Yy (acc:Acc) (wa wb:┟):Acc := if expOf wa=255\/expOf wb=255 then acc.markSpecial else acc.add (mantOf wa*mantOf wb) (idxOf wa+idxOf wb) (Bool.xor (signOf wa) (signOf wb)) @[specialize] def Yw (fa fb:Nat -> ┟) (pos neg:┠ Nat) (sp nz:┣) (index:Nat):Nat -> Acc | 0=>⟨pos,neg,sp,nz⟩ | count+1 => match Yy ⟨pos,neg,sp,nz⟩ (fa index) (fb index) with | ⟨p,n,s,z⟩=>Yw fa fb p n s z (index+1) count @[inline] def Yn (n:Nat) (fa fb:Nat -> ┟):┟ := let acc:=Yw fa fb (Array.replicate 18 0) (Array.replicate 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 YaL acc.pos acc.neg (-298) (n≠0&&acc.negZero) lemma Zn (wa wb:┟):(if ˷ (signOf wa) (signOf wb) then -((mantOf wa*mantOf wb:Nat):Int) else ((mantOf wa*mantOf wb:Nat):Int))=sv wa*sv wb:=by unfold sv;cases signOf wa<;>cases signOf wb<;>simp lemma ZbP (fa fb:Nat -> ┟) (pos neg:┠ Nat) (nz:┣) (index count:Nat):(Yw 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[Yw];have hs:(Yy ⟨pos,neg,true,nz⟩ (fa index) (fb index)).special=true:=by unfold Yy Acc.markSpecial Acc.add;split_ifs<;>rfl generalize Yy ⟨pos,neg,true,nz⟩ (fa index) (fb index)=r at hs ⊢;obtain⟨p,q,s,z⟩:=r;subst hs;exact ih .. lemma M9 (fa fb:Nat -> ┟) (A B:┠ ┟) (n:Nat) (hA:∀ k,k A[k]! = fa k) (hB:∀ k,k B[k]! = fb k) (acc:Acc) (index remaining:Nat) (h:index+remaining<=n) (hp:acc.pos.size=18) (hn:acc.neg.size=18) (h0:(Yw fa fb acc.pos acc.neg acc.special acc.negZero index remaining).special =false) : acc.special=false /\ (∀ k,index<=k -> k < index+remaining -> expOf A[k]! ≠ 255/\expOf B[k]! ≠ 255) /\ (Yw fa fb acc.pos acc.neg acc.special acc.negZero index remaining).total=acc.total+dsum A B index remaining /\ (Yw 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[Yw,dsum,dallNZ] | succ count ih => obtain⟨p,q,s,z⟩:=acc;have ha:=hA index ܉;have hb:=hB index ܉;by_cases he:expOf (fa index)=255\/expOf (fb index)=255 . exfalso;rw[Yw]at h0;have hs:(Yy ⟨p,q,s,z⟩ (fa index) (fb index)).special=true:=by simp[Yy,he,Acc.markSpecial] generalize Yy ⟨p,q,s,z⟩ (fa index) (fb index)=r at hs h0;obtain⟨p',q',s',z'⟩:=r;subst hs;rw[ZbP]at h0;exact Bool.noConfusion h0 . have h6:=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)) (˷ (signOf (fa index)) (signOf (fb index))) hp hn (mul_mant_lt _ _) (by have:=idxOf_le _ h6.1;have:=idxOf_le _ h6.2;omega) have h7:Yy ⟨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)) (˷ (signOf (fa index)) (signOf (fb index))):=by simp[Yy,he] rw[Yw,h7]at h0 ⊢;obtain⟨hs,h8,hD,hz⟩:=ih _ (index+1) ܉ h1 h2 h0;refine⟨by rw[<- h3,hs],?_,?_,?_⟩ . intro k k1 k2;rcases Nat.lt_or_ge k (index+1) with hk | hk . have:k=index:=܉ subst this;rw[ha,hb];exact h6 . exact h8 k hk ܉ . rw[hD,h5,dsum,ha,hb,Zn];ring . rw[hz,h4,dallNZ,ha,hb];simp[Bool.and_assoc] lemma Ze (n:Nat) (f:Nat -> ┟) (k:Nat) (hk:kf i؞)[k]! = f k:=߹ lemma Z5 (n:Nat) (fa fb:Nat -> ┟):Yn n fa fb=dotSpec (Array.ofFn (n:=n) λ i=>fa i) (Array.ofFn (n:=n) λ i=>fb i):=by unfold Yn;set A:=Array.ofFn (n:=n) λ i=>fa i with hA;set B:=Array.ofFn (n:=n) λ i=>fb i with hB;set acc:=Yw fa fb (؇ 18 0) (؇ 18 0) false true 0 n with hj;by_cases hh:acc.special=true . simp[hh] . have h9:acc.special=false:=߷ obtain⟨-,h3,hD,hz⟩:=M9 fa fb A B n (Ze n fa) (Ze n fb) Acc.empty 0 n ܉ (by simp[Acc.empty]) (by simp[Acc.empty]) h9 have hD:acc.total=dsum A B 0 n:=by have:=hD;simp only[Acc.total_empty,Int.zero_add]at this;exact this have hz:acc.negZero=dallNZ A B 0 n:=by have:=hz;exact this simp only[h9,¥,│];rw[N0,show((limbVal acc.pos.toList:Int)-limbVal acc.neg.toList)=acc.total from rfl] have hc:A.size=n:=by simp[hA] have ha:B.size=n:=by simp[hB] set L:=A.map (Model.ofUInt32 (fmt:=Fmt)) with hL set R:=B.map (Model.ofUInt32 (fmt:=Fmt)) with hR have h0:L.size=R.size:=߷ have hd:L.size=n:=߷ have h5:∀ k (hk:ka[i؞]!)=a:=by subst h;apply Array.ext ܋;intro i h1 h2;rw[Array.getElem_ofFn,┍ a i h2] lemma ZbQ (n:Nat) (c:┟):(Array.ofFn (n:=n) λ _=>c)=؇ n c:=by apply Array.ext ܋;simp def YaM (a b:┠ ┟):┟ := if a.size=b.size then Yn a.size (λ i=>a[i]!) (λ i=>b[i]!) else dotSpec a b def YaN (x:┠ ┟):┟:=Yn x.size (λ i=>x[i]!) (λ _=>oneW) lemma ZbR (a b:┠ ┟):YaM a b=dotSpec a b:=by unfold YaM;split . rename_i h;rw[Z5,Z6 a _ rfl,Z6 b _ h] . rfl lemma ZbS (x:┠ ┟):YaN x=sumSpec x:=by rw[YaN,Z5,Z6 x _ rfl,ZbQ,sumSpec] lemma Zi:Yn=dotOf:=funext λ n=>funext λ fa=>funext λ fb=>Z5 n fa fb lemma M8 (w:┢):toWord (ofW w)=w:=by apply ˅;simp only[toWord,ofW,Model.toNatBits,ofUInt32_bits];exact ¡ w.toBitVec.isLt lemma M7 (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',¡ h];exact Model.ofNatBits_toNatBits z @[inline] def Yz (w:┢):Int := if signOf w then -((mantOf w<<simp[®] lemma Zx (w:┢):(┝ w).toReal=(Yz w:ℝ)*2^(-149:Int):=by rw[<- FloatLib.Numerics.Dyadic.cast_toRat,┇,ZbT];push_cast;rw[zpow_sub₀ two_ne_zero,┄];ring lemma ZH (w:┟):(expOf w)؊=w؊/2^23%256:=by simp only[expOf,٭,˲,©];exact ˕ _ 8 lemma ZR (w:┟):(fracOf w)؊=w؊%2^23:=by exact ˕ _ 23 @[inline] def Yac (w:┢):Int:=let m:Int:=(w.toNat%2147483648:Nat);if signOf w then -m else m def mg (n:Nat):Nat:=if n/2^23%256=0 then n%2^23 else (2^23+n%2^23)*2^(n/2^23%256-1) lemma G4 (w:┢):mantOf w<<simp lemma ZS (a b:Nat) (h:a%2^31nlinarith [Nat.one_le_two_pow (n:=A-1)] lemma ZbU (a b:┢):compare (Yac a) (Yac b)=compare (Yz a) (Yz b):=by have e:∀ a b:Nat,a%2^31=b%2^31 -> mg a=mg b:=λ a b h=>by unfold mg;rw[show a/2^23%256=b/2^23%256 by omega,show a%2^23=b%2^23 by omega] have:=ZS a؊ b؊;have:=ZS b؊ a؊;have:=e a؊ b؊;have:=ZS 0 b؊;have:=e b؊ 0;have:mg 0=0:=rfl;unfold Yac Yz;rw[G4,G4];simp only[compare,compareOfLessAndEq];split_ifs<;>first|rfl|omega lemma ZbV (a:┢) (ha:expOf a≠255):ofW a=(if Model.isZero (ofW a)&&Model.isZero (ofW a) then Model.zero Fmt (Model.signBit (ofW a)&&Model.signBit (ofW a)) else ofW a):=by simp only[Bool.and_self];split . rename_i hz;obtain⟨h1,h2⟩:=(Model.isZero_iff_fields_of_isFinite (by simp[ofW,┋,ha])).1 hz conv_lhs=>rw[<- Model.ofFields_signBit_expField_fracField (ofW a),h1,h2] cases Model.signBit (ofW a)<;>decide . rfl @[inline] def YQ (a b:┢):┢ := if expOf a=255\/expOf b=255 then toWord (Model.maximum (ofW a) (ofW b)) else match compare (Yac a) (Yac b) with | .lt=>b | .gt=>a | .eq=>if a=b then a else toWord (if Model.isZero (ofW a)&&Model.isZero (ofW b) then Model.zero Fmt (Model.signBit (ofW a)&&Model.signBit (ofW b)) else ofW a) lemma X9 (a b:┢):Model.cmpDyadic (┝ a) (┝ b)=compare (Yz a) (Yz b):=by have hs:(0:ℝ)<2^(-149:Int):=zpow_pos two_pos _;cases h:compare (Yz a) (Yz b) . rw[Model.cmpDyadic_lt_iff,Zx,Zx];exact mul_lt_mul_of_pos_right (by exact_mod_cast compare_lt_iff_lt.mp h) hs . rw[Model.cmpDyadic_eq_iff,Zx,Zx,compare_eq_iff_eq.mp h] . rw[Model.cmpDyadic_gt_iff,Zx,Zx];exact mul_lt_mul_of_pos_right (by exact_mod_cast compare_gt_iff_gt.mp h) hs lemma X8 (a b:┢):ofW (YQ a b)=Model.maximum (ofW a) (ofW b):=by unfold YQ;split . exact M7 _ . rename_i hs;rw[ZbU];have ha:=┅ a (λ h=>hs (Or.inl h));have hb:=┅ b (λ h=>hs (Or.inr h));have h0:=Model.isNaN_eq_false_of_toDyadic?_some ha;have h1:=Model.isNaN_eq_false_of_toDyadic?_some hb;have hc:Model.compare (ofW a) (ofW b)=some _:=Model.compare_eq_some_cmpDyadic_of_toDyadic? _ _ ha hb;rw[X9]at hc;have h2:Model.chooseNaN2 (ofW a) (ofW b)=none:=(Model.chooseNaN2_eq_none_iff _ _).2 ⟨h0,h1⟩;unfold Model.maximum;rw[Model.withNaNSelection_of_none _ _ h2];rw[Model.compareNonNaN_eq_of_compare_eq_some _ _ _ _ hc];cases compare (Yz a) (Yz b)<;>simp only[M7,apply_ite ofW];by_cases h:a=b . subst h;rw[if_pos rfl];exact ZbV a (λ h=>hs (Or.inl h)) . rw[if_neg h] def Yad (c h w k:Nat) (inp:┠ ┢):┠ ┢ := Array.ofFn (n:=c*(h/k*(w/k))) λ q => let ch:=q.val/(h/k*(w/k)) let y:=q.val/(w/k)%(h/k) let x:=q.val%(w/k) (List.range (k*k)).foldl (λ acc t=>YQ acc (poolAt h w k inp ch y x t)) (poolAt h w k inp ch y x 0) lemma X7 (p:Nat -> ┢) (l:List Nat) (acc:┢):l.foldl (λ m t=>Model.maximum m (ofW (p t))) (ofW acc)=ofW (l.foldl (λ a t=>YQ a (p t)) acc):=by induction l generalizing acc with | nil=>rfl | cons t l ih=>simp only[܁,<- X8,ih] lemma M6:Yad=maxpoolSpec:=by funext c h w k inp;simp only[Yad,maxpoolSpec,X7,M8] def kernels0:Kernels where core:=⟨YaN,YaM⟩ dense:=⟨linearWith Yn,gemmWith Yn⟩ conv:=⟨conv2dWith Yn,depthwiseWith Yn⟩ elem:=⟨avgpoolWith Yn,Yad,addReluSpec,scaleShiftSpec⟩ norm:=⟨rmsnormWith Yn,layernormWith Yn⟩ lemma X6:Obligation kernels0:=by simp only[Obligation,kernels0,specKernels,specCore,specDense,specConv,specElem,specNorm,linearSpec,gemmSpec,conv2dSpec,depthwiseSpec,avgpoolSpec,rmsnormSpec,layernormSpec,M6,Zi,funext ZbS,funext λ a=>funext (ZbR a)] def Yo (fa fb:Nat -> ┟) (i:Nat):Nat -> Int | 0=>0 | r+1=>sv (fa i)*sv (fb i)*2^(idxOf (fa i)+idxOf (fb i))+Yo fa fb (i+1) r def Yq (fa fb:Nat -> ┟) (i:Nat):Nat -> ┣ | 0=>true | r+1=>(decide (mantOf (fa i)*mantOf (fb i)=0)&&Bool.xor (signOf (fa i)) (signOf (fb i))) && Yq fa fb (i+1) r lemma Zb0 (n:Nat) (fa fb:Nat -> ┟) (i r:Nat) (h:i+r<=n):dsum (Array.ofFn (n:=n) λ k=>fa k؞) (Array.ofFn (n:=n) λ k=>fb k؞) i r=Yo fa fb i r:=by induction r generalizing i with | zero=>rfl | succ r ih=>rw[dsum,Yo,Ze n fa i ܉,Ze n fb i ܉,ih (i+1) ܉] lemma Zb1 (n:Nat) (fa fb:Nat -> ┟) (i r:Nat) (h:i+r<=n):dallNZ (Array.ofFn (n:=n) λ k=>fa k؞) (Array.ofFn (n:=n) λ k=>fb k؞) i r=Yq fa fb i r:=by induction r generalizing i with | zero=>rfl | succ r ih=>rw[dallNZ,Yq,Ze n fa i ܉,Ze n fb i ܉,ih (i+1) ܉] lemma Zb2 (fa fb:Nat -> ┟) (pos neg:┠ Nat) (nz:┣) (index remaining:Nat) (h0:∀ k,index<=k -> k < index+remaining -> expOf (fa k)≠255/\expOf (fb k)≠255) : (Yw fa fb pos neg false nz index remaining).special=false:=by induction remaining generalizing pos neg nz index with | zero=>rfl | succ count ih => rw[Yw];have hf:=h0 index le_rfl ܉;have hs:(Yy ⟨pos,neg,false,nz⟩ (fa index) (fb index)).special=false:=by have hc:¬(expOf (fa index)=255\/expOf (fb index)=255):=by rintro (h | h) . exact hf.1 h . exact hf.2 h unfold Yy;unfold Acc.add;split_ifs<;>rfl generalize Yy ⟨pos,neg,false,nz⟩ (fa index) (fb index)=r at hs ⊢;obtain⟨p,q,s,z⟩:=r;subst hs;exact ih _ _ _ _ (λ k h1 h2=>h0 k ܉ ܉) lemma Zy (n:Nat) (fa fb:Nat -> ┟) (h1:∀ k,k expOf (fa k)≠255/\expOf (fb k)≠255) : dotOf n fa fb=┒ (Yo fa fb 0 n) (-298) (decide (n≠0)&&Yq fa fb 0 n):=by rw[<- Zi];unfold Yn;set A:=Array.ofFn (n:=n) λ i=>fa i؞ with hA;set B:=Array.ofFn (n:=n) λ i=>fb i؞ with hB;set acc:=Yw fa fb (؇ 18 0) (؇ 18 0) false true 0 n with h5;have h0:acc.special=false:=Zb2 fa fb _ _ true 0 n (λ k _ h2=>h1 k ܉) obtain⟨-,-,hD,hz⟩:=M9 fa fb A B n (Ze n fa) (Ze n fb) Acc.empty 0 n ܉ (by simp[Acc.empty]) (by simp[Acc.empty]) h0 have h4:acc.total=Yo fa fb 0 n:=by have:=hD;simp only[Acc.total_empty,Int.zero_add]at this;rw[<- Zb0 n fa fb 0 n ܉];exact this have h3:acc.negZero=Yq fa fb 0 n:=by have:=hz;rw[<- Zb1 n fa fb 0 n ܉];exact this simp only[h0,¥,│];rw[N0,show((limbVal acc.pos.toList:Int)-limbVal acc.neg.toList)=acc.total from rfl,h4,h3] def YC (w2 w1 w0:┞):Int := ((w2.toNat*2^128+w1.toNat*2^64+w0.toNat:Nat):Int) - (if w2.toNat<2^63 then 0 else 2^192) def Ym (w:┞):Int:=(w.toNat:Int)-(if w.toNat<2^63 then 0 else 2^64) lemma Zb3 (s:┣) (E F:Nat) (hE:E<256) (hF:F<2^23):(Model.ofFields Fmt s E F).toNatBits=(if s then 2^31 else 0)+E*2^23+F:=by rw[Model.ofFields_eq_ofFieldsImpl];simp only[Model.ofFieldsImpl,Model.mkBitsImpl,Model.ofBits,Model.toNatBits,BitVec.toNat_ofNatLT];have h1:E&&&Fmt.expAllOnesNat=E:=Nat.and_two_pow_sub_one_of_lt_two_pow (n:=8) hE;have h2:F&&&Fmt.fracMaskNat=F:=Nat.and_two_pow_sub_one_of_lt_two_pow (n:=23) hF;rw[h1,h2,show E.shiftLeft Fmt܈=E<<<23 from rfl,Nat.or_assoc,<- Nat.shiftLeft_add_eq_or_of_lt hF] have hb:E<<<23+F<2^31:=܉ cases s . simp[®] . simp only[━];rw[show Nat.shiftLeft 1 (Fmt.expWidth+Fmt܈)=1<<<31 from rfl,<- Nat.shiftLeft_add_eq_or_of_lt hb];simp;omega @[inline] def Yv (neg:┣) (E F:┟):┟:=(if neg then (0x80000000:┟) else 0)+(E<<<23)+F lemma ZT (neg:┣) (E F:┟) (hE:E؊<256) (hF:F؊<2^23):Yv neg E F=toWord (Model.ofFields Fmt neg E؊ F؊):=by unfold toWord;rw[Zb3 neg _ _ hE hF];apply UInt32.toNat_inj.mp;unfold Yv;cases neg<;>simp<;>omega lemma M5 (neg:┣):Yv neg 255 0=toWord (Model.nativeOverflow Fmt neg):=by rw[Model.nativeOverflow_eq_signedInf_of_isIEEE Fmt ܌];cases neg<;>decide lemma Zb4 (neg:┣):Yv neg 0 0=toWord (Model.zero Fmt neg):=by cases neg<;>decide @[inline] def YH (x r d:┞):┞:=if x>>>(r+d) != 0 then r+d else r @[inline] def Yj (x:┞):┞ := YH x (YH x (YH x (YH x (YH x (YH x 0 32) 16) 8) 4) 2) 1 lemma Zz (x r d:┞) (D:Nat) (hD:d˗=D) (hd:1<=D) (hr:r˗+2*D<=64) (h1:2^r˗<=x˗) (h2:x˗<2^(r˗+2*D)) : (YH x r d)˗+D<=64/\2^(YH x r d)˗<=x˗ /\ x˗<2^((YH x r d)˗+D):=by subst hD;have h3:(r+d)˗=r˗+d˗:=by rw[¤];omega have hs:(x>>>(r+d))˗=x˗/2^(r˗+d˗):=by rw[˔,h3,¡ ܉,©] unfold YH;by_cases hc:x>>>(r+d) != 0 . simp only[hc,━,h3];have:x˗/2^(r˗+d˗)≠0:=by intro h;apply(bne_iff_ne.mp hc);apply ¢;rw[hs,h];rfl refine⟨by omega,?_,by rw[show r˗+d˗+d˗=r˗+2*d˗ by omega];exact h2⟩;exact(⠎ (˄ _)).mp (Nat.one_le_iff_ne_zero.mpr this) |>.trans' ܋ . simp only[hc,│,¥];have h0:x>>>(r+d)=0:=߷ have:x˗/2^(r˗+d˗)=0:=by rw[<- hs,h0];rfl refine⟨by omega,h1,?_⟩ exact(Nat.div_eq_zero_iff_lt (˄ _)).mp this lemma Zj (x:┞) (hx:x≠0):(Yj x)˗=x˗،:=by have h0:1<=x˗:=Nat.one_le_iff_ne_zero.mpr λ h=>hx (¢ (by simpa using h));have h1:=x܂;obtain⟨a1,b1,c1⟩:=Zz x 0 32 32 rfl ܌ ܌ (by simpa using h0) (by simpa using h1);obtain⟨a2,b2,c2⟩:=Zz x _ 16 16 rfl ܌ ܉ b1 (by simpa using c1);obtain⟨a3,b3,c3⟩:=Zz x _ 8 8 rfl ܌ ܉ b2 (by simpa using c2);obtain⟨a4,b4,c4⟩:=Zz x _ 4 4 rfl ܌ ܉ b3 (by simpa using c3);obtain⟨a5,b5,c5⟩:=Zz x _ 2 2 rfl ܌ ܉ b4 (by simpa using c4);obtain⟨a6,b6,c6⟩:=Zz x _ 1 1 rfl ܌ ܉ b5 (by simpa using c5);exact((؎ ܉).mpr ⟨b6,c6⟩).symm @[inline] def Ybm (m:┞) (e:Int):┞ := match e+149 with | .ofNat k=>m<<FloatLib.Numerics.FixedWord.roundShiftRightEven m (k+1) @[inline] def YaO (neg:┣) (m:┞) (e:Int):┟ := let fr:=Ybm m e if fr==0 then Yv neg 0 0 else if (0x800000:┞)<=fr then Yv neg 1 0 else Yv neg 0 fr.toUInt32 lemma Zb5 (neg:┣) (m:┞) (e:Int) (hm:m˗≠0) (h:(m˗،:Int)+e < -126) : YaO neg m e=toWord (Model.packRoundedSubnormal Fmt neg (Model.zero Fmt neg) (match e-┗ with | Int.ofNat shift=>m˗<<┘ m˗ (shift+1))):=by have h2:m˗<2^(m˗،+1):=֎;rw[show e-Fmt.minSubnormalExponent=e+149 by rw[show Fmt.minSubnormalExponent = -149 from rfl];omega];unfold YaO Ybm;generalize hs:e+149=s;suffices H:∀ (fr:┞) (F:Nat),fr˗=F -> F<=2^23 -> (if fr==0 then Yv neg 0 0 else if (0x800000:┞)<=fr then Yv neg 1 0 else Yv neg 0 fr؉)=toWord (Model.packRoundedSubnormal Fmt neg (Model.zero Fmt neg) F) by cases s with | ofNat k => have hk:(k:Int)=e+149:=߷ have hb:m˗*2^k<2^23:=by calc m˗*2^k<2^(m˗،+1)*2^k:=˴ h2 (˄ k) _=2^(m˗،+1+k):=by rw[<- ˪] _<=2^23:=˂ ܊ ܉ apply H _ (m˗<< have hk:۩ k=e+149:=by rw[hs] apply H _ _ (FloatLib.Numerics.FixedWord.roundShiftRightEven_toNat m (k+1));have hq:m˗/2^(k+1)<2^23:=by rw[⠏ (˄ _)];calc m˗<2^(m˗،+1):=h2 _<=2^(23+(k+1)):=˂ ܊ (by rw[Int.negSucc_eq]at hk;omega) _=2^23*2^(k+1):=by rw[˪] have:=FloatLib.Numerics.roundShiftRightEven_le_succ m˗ (k+1);omega intro fr F hF h5;subst hF;unfold Model.packRoundedSubnormal;by_cases h0:fr=0 . subst h0;exact Zb4 neg have h4:(fr˗==0)=false:=by simpa using λ h=>h0 (¢ (by simpa using h)) simp only[show(fr==0)=false by simpa using h0,h4,¥,│];by_cases h1:fr˗>=2^23 . have:(0x800000:┞)<=fr:=by rw[¿];simpa using h1 simp only[this,━,show fr˗>=Model.pow2 Fmt܈ from h1] exact ZT neg 1 0 ܌ ܌ . have:¬ (0x800000:┞)<=fr:=by rw[¿];simpa using h1 simp only[this,│,show ¬ fr˗>=Model.pow2 Fmt܈ from h1] have hc:fr؉؊=fr˗:=by rw[՜];omega rw[ZT neg 0 _ ܌ (by rw[hc];omega),hc];rfl @[inline] def YK (m L:┞):┞ := if 23<=L then FloatLib.Numerics.FixedWord.roundShiftRightEven m (L-23).toNat else m<<<(23-L) @[inline] def Yae (neg:┣) (m L:┞) (t:Int):┟ := let rm:=YK m L if rm==0x1000000 then (if t+1>127 then Yv neg 255 0 else Yv neg (t+128).toNat.toUInt32 0) else Yv neg (t+127).toNat.toUInt32 (rm.toUInt32-0x800000) lemma Z7 (m:┞) (hm:m≠0):(YK m (Yj m))˗=(if Fmt܈<=m˗، then ┘ m˗ (m˗،-Fmt܈) else m˗<<<(Fmt܈-m˗،)) /\ 2^23<=(YK m (Yj m))˗/\(YK m (Yj m))˗<=2^24:=by have h3:m˗≠0:=λ h=>hm (¢ (by simpa using h));have hL:=Zj m hm;have h0:2^m˗،<=m˗:=˻ h3;have h1:m˗<2^(m˗،+1):=֎;rw[show Fmt܈=23 from rfl];unfold YK;generalize Yj m=L at hL ⊢;generalize hN:m˗،=N at * by_cases h:23<=N . have hu:(23:┞)<=L:=by rw[¿,hL];simp;omega have hs:(L-23)˗=N-23:=߹ simp only[hu,━,h,hs,FloatLib.Numerics.FixedWord.roundShiftRightEven_toNat];have h4:2^23<=m˗/2^(N-23):=by rw[⠎ (˄ _),<- ˪,show 23+(N-23)=N by omega] exact h0 have h6:m˗/2^(N-23)<2^24:=by rw[⠏ (˄ _),<- ˪,show 24+(N-23)=N+1 by omega];exact h1 have:=FloatLib.Numerics.div_two_pow_le_roundShiftRightEven m˗ (N-23);have:=FloatLib.Numerics.roundShiftRightEven_le_succ m˗ (N-23);refine⟨trivial,by omega,by omega⟩ . have hu:¬ (23:┞)<=L:=by rw[¿,hL];simp;omega have hs:(23-L)˗=23-N:=by rw[§ _ _ (by rw[¿,hL];simp;omega),hL];rfl simp only[hu,│,h];have h2:2^23<=m˗*2^(23-N):=by calc 2^23=2^N*2^(23-N):=by rw[<- ˪];congr 1;omega _<=m˗*2^(23-N):=¶ _ h0 have h5:m˗*2^(23-N)<2^24:=by calc m˗*2^(23-N)<2^(N+1)*2^(23-N):=˴ h1 (˄ _) _=2^24:=by rw[<- ˪];congr 1;omega have he:(m<<<(23-L))˗=m˗*2^(23-N):=by rw[˒,hs,¡ (show 23-N<64 by omega),®];exact ¡ ܉ rw[he,®];exact⟨rfl,h2,by omega⟩ lemma B2 (n:Nat) (h:n<2^32):n.toUInt32؊=n:=by rw[Nat.toUInt32_eq,UInt32.toNat_ofNat',¡ h] lemma Zb6 (neg:┣) (m:┞) (e:Int) (hm:m≠0) (h1:¬ ((m˗،:Int)+e>127)) (h2:¬ ((m˗،:Int)+e < -126)) : Yae neg m (Yj m) ((m˗،:Int)+e)=toWord (Model.packRoundedNormal Fmt neg (Model.nativeOverflow Fmt neg) (↑m˗،+e) (if Fmt܈<=m˗، then ┘ m˗ (m˗،-Fmt܈) else m˗<<<(Fmt܈-m˗،))):=by obtain⟨hr,h5,h4⟩:=Z7 m hm;rw[<- hr];unfold Yae Model.packRoundedNormal;generalize YK m (Yj m)=rm at h5 h4 ⊢;generalize (m˗،:Int)+e=t at h1 h2 ⊢;simp only[Model.pow2_eq_two_pow,show Fmt܈=23 from rfl,show Fmt.maxNormalExponent=127 from rfl,show Fmt.exponentBias=127 from rfl,show Fmt.maxFiniteExpField=254 from rfl,show Fmt.maxFiniteFracField=8388607 from rfl,Nat.reducePow,Nat.reduceAdd,Int.ofNat_eq_natCast,Nat.cast_ofNat] by_cases hc:rm˗=16777216 . have h0:(rm==0x1000000)=true:=by rw[beq_iff_eq];apply ¢;rw[hc];rfl simp only[h0,━,hc,BEq.rfl,Nat.reduceSub];by_cases ho:t+1>127 . simp only[ho,━];exact M5 neg . simp only[ho,│];have hE:((t+128)؈.toUInt32)؊=(t+1+127)؈:=by rw[B2 (t+128)؈ ܉];omega have h3:((t+1+127)؈>254||((t+1+127)؈==254&&decide (0>8388607)))=false:=߷ simp only[h3,¥,│];rw[ZT neg _ 0 (by rw[hE];omega) ܌,hE];rfl . have h0:(rm==0x1000000)=false:=by rw[beq_eq_false_iff_ne];intro h;apply hc;rw[h];rfl have h6:(rm˗==16777216)=false:=߷ simp only[h0,h6,¥,│,show ¬ t>127 by omega] have hE:=B2 (t+127)؈ ܉ have hF:(rm؉-0x800000)؊=rm˗-8388608:=by rw[UInt32.toNat_sub_of_le _ _ (by rw[⠍,՜];simp;omega),՜];simp;omega have h3:((t+127)؈>254||((t+127)؈==254&&decide (rm˗-8388608>8388607)))=false:=߷ simp only[h3,¥,│];rw[ZT neg _ _ (by rw[hE];omega) (by rw[hF];omega),hE,hF] @[inline] def YA (neg:┣) (m:┞) (e:Int):┟ := let L:=Yj m let t:Int:=(L.toNat:Int)+e if t>127 then Yv neg 255 0 else if t < -126 then YaO neg m e else Yae neg m L t lemma ZU (neg:┣) (m:┞) (e:Int) (hm:m≠0):YA neg m e=toWord (┑ Fmt ⟨neg,m˗,e⟩):=by have h0:m˗≠0:=λ h=>hm (¢ (by simpa using h));have hL:=Zj m hm;unfold YA Model.roundDyadicGeneral;simp only[show(m˗==0)=false by simpa using h0,¥,│,hL,show Fmt.maxNormalExponent=127 from rfl,show Fmt.minNormalExponent = -126 from rfl] by_cases h1:(m˗،:Int)+e>127 . simp only[h1,━];exact M5 neg . simp only[h1,│];by_cases h2:(m˗،:Int)+e < -126 . simp only[h2,━];exact Zb5 neg m e h0 h2 . simp only[h2,│];exact Zb6 neg m e hm h1 h2 @[noinline] def Ybn (neg:┣) (m:┞) (e:Int):┟:=YA neg m e @[noinline] def Yat (neg:┣) (m:┞) (e:Int) (L c:┞):┟ := YA neg m (e+((L.toNat+c.toNat:Nat):Int)) @[inline] def YY (n:┞):┞ := let q:=n>>>40 q+(((n&&&0xFFFFFFFFFF)+0x7FFFFFFFFF+(q&&&1))>>>40) lemma Zb7 (n:┞):(YY n)˗=┘ n˗ 40:=by rw[FloatLib.Numerics.roundShiftRightEven_eq_guard_sticky _ _ ܌];have hn:=n܂;have h1:(n>>>40)˗=n˗/2^40:=by rw[˔,©];rfl have h2:(n&&&0xFFFFFFFFFF)˗=n˗%2^40:=by rw[UInt64.toNat_and,show(0xFFFFFFFFFF:┞)˗=2^40-1 from rfl,˕] have h3:((n>>>40)&&&1)˗=n˗/2^40%2:=߹ have g1:n˗/2^(40-1)%2=n˗%2^40/2^39:=by rw[show(2:Nat)^40=2^39*2 by norm_num,Nat.mod_mul_right_div_self] have g2:n˗%2^(40-1)=n˗%2^40%2^39:=by rw[show(2:Nat)^40=2^39*2 by norm_num,Nat.mod_mul_right_mod] have hR:=˵ n˗ (show 0<2^40 by decide);have hQ:n˗/2^40<2^24:=by rw[⠏ ܌];exact hn unfold YY;simp only[¤,˔,h1,h2,h3,Nat.testBit_eq_decide_div_mod_eq,g1,g2];clear h1 h2 h3 g1 g2;generalize n˗%2^40=R at *;simp only[UInt64.reduceToNat,Nat.reduceMod,Nat.reducePow,©]at *;split . rename_i h;simp at h;omega . rename_i h;simp at h;omega lemma Z8 (neg:┣) (E F:┟) (h:E؊*2^23+F؊<2^31):(Yv neg E F)؊=(if neg then 2^31 else 0)+E؊*2^23+F؊:=by unfold Yv;cases neg<;>simp<;>omega @[inline] def YZ (neg:┣) (u n:┞):┟ := (if neg then (0x80000000:┟) else 0)+((u<<<23)+YY n).toUInt32 lemma Zb8 (neg:┣) (u n:┞) (hu:u˗<=253) (hq:(YY n)˗<=2^24):(YZ neg u n)؊=(if neg then 2^31 else 0)+u˗*2^23+(YY n)˗:=by have hs:(u<<<23)˗=u˗*2^23:=by rw[˒];simp;omega unfold YZ;cases neg<;>simp<;>omega lemma M4 (neg:┣) (m:┞) (e:Int) (u:┞) (hm:m≠0) (hu:(u˗:Int)=(m˗،:Int)+e+126) (h2:u˗<=253) : YZ neg u (m<<<(63-Yj m))=YA neg m e:=by have h5:m˗≠0:=λ h=>hm (¢ (by simpa using h));have hL:=Zj m hm;obtain⟨hr,h4,h7⟩:=Z7 m hm;have hN:m˗،<64:=(Nat.log2_lt h5).mpr m܂;have h1:m˗<2^(m˗،+1):=֎;have hq:(YY (m<<<(63-Yj m)))˗=(YK m (Yj m))˗:=by rw[Zb7,hr];have hs:(63-Yj m)˗=63-m˗،:=by rw[§ _ _ (by rw[¿,hL];simp;omega -splitDisjunctions),hL];rfl have h3:(m<<<(63-Yj m))˗=m˗*2^(63-m˗،):=by rw[˒,hs,¡ (show 63-m˗،<64 by omega),®];apply ¡ calc m˗*2^(63-m˗،)<2^(m˗،+1)*2^(63-m˗،):=˴ h1 (˄ _) _=2^64:=by rw[<- ˪,show m˗،+1+(63-m˗،)=64 by omega] rw[h3,show Fmt܈=23 from rfl];split . rw[show(40:Nat)=(m˗،-23)+(63-m˗،) by omega,FloatLib.Numerics.roundShiftRightEven_mul_two_pow] . rw[FloatLib.Numerics.roundShiftRightEven_mul_two_pow_of_le _ _ _ ܉,®,show 63-m˗،-40=23-m˗، by omega] have h6:(YY (m<<<(63-Yj m)))˗<=2^24:=܉ rw[show YA neg m e=Yae neg m (Yj m) ((m˗،:Int)+e) by unfold YA;simp only[hL,show ¬ ((m˗،:Int)+e>127) by omega -splitDisjunctions,show ¬ ((m˗،:Int)+e < -126) by omega -splitDisjunctions,│]] apply ˅;rw[Zb8 neg u _ h2 h6,hq];unfold Yae;generalize YK m (Yj m)=rm at hq h4 h7 ⊢;generalize (m˗،:Int)+e=t at hu ⊢;by_cases hc:rm˗=16777216 . have h0:(rm==0x1000000)=true:=by rw[beq_iff_eq];apply ¢;rw[hc];rfl simp only[h0,━];by_cases ho:t+1>127 . simp only[ho,━];rw[Z8 neg 255 0 ܌];simp;omega . simp only[ho,│];have hE:=B2 (t+128)؈ ܉ rw[Z8 neg _ 0 (by rw[hE];simp;omega),hE];simp;omega . have h0:(rm==0x1000000)=false:=by rw[beq_eq_false_iff_ne];intro h;apply hc;rw[h];rfl simp only[h0,¥,│];have hE:=B2 (t+127)؈ ܉ have hF:(rm؉-0x800000)؊=rm˗-8388608:=by rw[UInt32.toNat_sub_of_le _ _ (by rw[⠍,՜];simp;omega -splitDisjunctions),՜];simp;omega rw[Z8 neg _ _ (by rw[hE,hF];omega),hE,hF];omega lemma M3 (neg:┣) (n:┞) (E:Int) (u:┞) (hn:2^63<=n˗) (hu:(u˗:Int)=E+189) (h3:u˗<=253) : YZ neg u n=YA neg n E:=by have h2:n˗≠0:=⠆ (lt_of_lt_of_le (˄ 63) hn);have h1:n≠0:=λ h=>h2 (by rw[h];rfl);have h0:n˗،=63:=(؎ h2).mpr ⟨hn,n܂⟩;have hL:Yj n=63:=¢ (by rw[Zj n h1,h0];rfl);have:=M4 neg n E u h1 (by rw[h0];push_cast;omega) h3;rw[hL,show n<<<(63-63:┞)=n from ¢ (by rw[˒];simp only[UInt64.reduceSub,Nat.zero_mod,Nat.shiftLeft_zero];exact ¡ n܂)]at this exact this lemma Zb9 (e:Int) (c:┞) (hc:c˗<2^62) (h:(Int64.ofInt e).toInt=e) (hu:((Int64.ofInt e).toUInt64+c)˗<=253) : (((Int64.ofInt e).toUInt64+c)˗:Int)=e+c˗:=by have h1:=Int64.toInt_lt (Int64.ofInt e);have h2:=Int64.le_toInt (Int64.ofInt e);have hx:((Int64.ofInt e).toUInt64˗:Int)=e%2^64:=by simp;exact Int.toNat_of_nonneg (Int.emod_nonneg _ ܌) rw[¤]at hu ⊢;omega def Y0 (e:Int) (ok:┣) (B:┞):Prop := ∀ c:┞,c.toNat<2^62 -> ok=true -> (B+c).toNat<=253 -> ((B+c).toNat:Int)=e+c.toNat lemma M2 (e:Int):Y0 e ((Int64.ofInt e).toInt==e) (Int64.ofInt e).toUInt64:=λ c hc h0 hu=>Zb9 e c hc (beq_iff_eq.mp h0) hu @[inline] def Yau (neg:┣) (m:┞) (e:Int) (ok:┣) (b:┞):┟ := let L:=Yj m let u:=b+L+126 if ok&&u<=253 then YZ neg u (m<<<(63-L)) else Ybn neg m e lemma M1 (neg:┣) (m:┞) (e:Int) (ok:┣) (B:┞) (hm:m≠0) (hr:Y0 e ok B):Yau neg m e ok B=YA neg m e:=by have h3:m˗≠0:=λ h=>hm (¢ (by simpa using h));have hL:=Zj m hm;have hN:m˗،<64:=(Nat.log2_lt h3).mpr m܂;unfold Yau Ybn;dsimp only;split . rename_i h;simp at h;obtain⟨h1,h2⟩:=h;have hc:(Yj m+126)˗=m˗،+126:=by rw[¤,hL];simp;omega rw[UInt64.add_assoc]at h2 ⊢;have h0:(B+(Yj m+126))˗<=253:=by have:=˓ h2;simpa using this have hw:=hr _ (by rw[hc];omega) h1 h0;exact M4 neg m e _ hm (by rw[hw];push_cast;omega) h0 . rfl @[inline] def YaP (w:┞) (e:Int) (negZero ok:┣) (B:┞):┟ := if w=0 then (if negZero then 0x80000000 else 0) else let neg:=w>>>63 != 0 Yau neg (if neg then 0-w else w) e ok B lemma H7 (w:┞) (e:Int) (negZero ok:┣) (B:┞) (hr:Y0 e ok B):YaP w e negZero ok B=┒ (Ym w) e negZero:=by unfold YaP finishWord;by_cases hw:w=0 . subst hw;simp[Ym] . have h7:w˗≠0:=λ h=>hw (¢ (by simpa using h)) have h6:=w܂;obtain⟨h5,h3,hS⟩:(w>>>63 != 0)=decide (Ym w<0) /\ (if (w>>>63 != 0)=true then 0-w else w)˗=(Ym w).natAbs/\Ym w≠0:=by by_cases h:w˗<2^63 . have hv:Ym w=(w˗:Int):=by unfold Ym;omega have h0:(w>>>63 != 0)=false:=by simp;apply ¢;simp;omega rw[hv,h0];simp only[¥,│,Int.natAbs_natCast];refine⟨by simp,trivial,by omega⟩ . have hv:Ym w=(w˗:Int)-2^64:=by unfold Ym;simp only[h,│] have h1:(w>>>63 != 0)=true:=by simp;intro e;have:=congrArg ܄ e;simp at this;omega have h4:(0-w)˗=2^64-w˗:=by rw[˰];simp;omega rw[hv,h1];simp only[━,h4];refine⟨by simp;omega,by omega,by omega⟩ simp only[hw,│,hS];rw[<- ┆];have hm:(if (w>>>63 != 0)=true then 0-w else w)≠0:=߷ rw[M1 _ _ _ _ _ hm hr,ZU _ _ _ hm,h3,h5];rfl def YaQ (w:┞) (e:Int) (negZero:┣):┟ := YaP w e negZero ((Int64.ofInt e).toInt==e) (Int64.ofInt e).toUInt64 lemma D9 (w:┞) (e:Int) (negZero:┣):YaQ w e negZero=┒ (Ym w) e negZero := H7 w e negZero _ _ (M2 e) lemma U5 (V s:Nat) (h:s+25<=V،):(FloatLib.Numerics.shiftRightJam V s)،=V،-s:=by have hV:V≠0:=by intro h0;subst h0;simp at h have h4:2^V،<=V:=˻ hV;have h5:V<2^(V،+1):=֎;have h1:2^(V،-s)<=V/2^s:=by rw[⠎ (˄ _),<- ˪,show V،-s+s=V، by omega];exact h4 have h3:V/2^s<2^(V،-s+1):=by rw[⠏ (˄ _),<- ˪,show V،-s+1+s=V،+1 by omega];exact h5 unfold FloatLib.Numerics.shiftRightJam;simp only;split . exact(؎ ܉).mpr ⟨h1,h3⟩ . rw[FloatLib.Numerics.or_one_eq];split . rename_i _ h6;apply(؎ ܉).mpr omega . exact(؎ ܉).mpr ⟨h1,h3⟩ lemma M0 (neg:┣) (V s:Nat) (e:Int) (h:s+25<=V،):┑ Fmt ⟨neg,FloatLib.Numerics.shiftRightJam V s,e+s⟩=┑ Fmt ⟨neg,V,e⟩:=by have hV:V≠0:=by intro h0;subst h0;simp at h have h1:2^s<=V:=le_trans (˂ ܊ ܉) (˻ hV) have hx:FloatLib.Numerics.shiftRightJam V s≠0:=FloatLib.Numerics.shiftRightJam_ne_zero V s h1;have hl:=U5 V s h;unfold Model.roundDyadicGeneral;simp only[show(FloatLib.Numerics.shiftRightJam V s==0)=false by simpa using hx,show(V==0)=false by simpa using hV,¥,│,hl] have ht:((V،-s:Nat):Int)+(e+s)=V،+e:=܉ rw[ht];split . rfl . split . rename_i _ h2;have h3:┗ = -149:=rfl;have h6:(V،:Int)+e < -126:=lt_of_lt_of_eq h2 rfl;obtain⟨a,ha⟩:∃ a:Nat,e-┗=۩ a/\s+2<=a+1:=by refine⟨(-(e+149)-1)؈,?_,by omega⟩;omega have hb:e+(s:Int)-┗=۩ (a-s):=܉ rw[ha.1,hb];simp only;rw[show a-s+1=a+1-s by omega,FloatLib.Numerics.roundShiftRightEven_shiftRightJam V s (a+1) ha.2] . rename_i _ h2;have h5:Fmt܈<=V،-s:=by rw[show Fmt܈=23 from rfl];omega have h4:Fmt܈<=V،:=܉ simp only[h5,h4,━];rw[show Fmt܈=23 from rfl,show V،-s-23=V،-23-s by omega,FloatLib.Numerics.roundShiftRightEven_shiftRightJam V s (V،-23) ܉] lemma Z9 (hi lo Lw:┞) (L:Nat) (h2:Lw˗=L) (hL:L<=63) (h4:hi˗<2^(L+1)):((hi<<<(63-Lw))|||((lo>>>Lw)>>>1))˗=(hi˗*2^64+lo˗)/2^(L+1) /\ ((lo<<<(63-Lw)) != 0)=decide ((hi˗*2^64+lo˗)%2^(L+1)≠0):=by have hs:(63-Lw)˗=63-L:=by rw[§ _ _ (by rw[¿,h2];simp;omega),h2];rfl have hp:(2:Nat)^64=2^(63-L)*2^(L+1):=by rw[<- ˪];congr 1;omega have hA:(hi<<<(63-Lw))˗=hi˗*2^(63-L):=by rw[˒,hs,¡ (show 63-L<64 by omega),®] apply ¡;calc hi˗*2^(63-L)<2^(L+1)*2^(63-L):=˴ h4 (˄ _) _=2^64:=by rw[<- ˪];congr 1;omega have hB:((lo>>>Lw)>>>1)˗=lo˗/2^(L+1):=by rw[˔,˔,h2,¡ (show L<64 by omega)];simp only[UInt64.reduceToNat,Nat.reduceMod,©,˭,<- Nat.pow_succ] have h7:lo˗/2^(L+1)<2^(63-L):=by rw[⠏ (˄ _),<- hp];exact lo܂ have h3:(hi˗*2^64+lo˗)/2^(L+1)=hi˗*2^(63-L)+lo˗/2^(L+1):=by rw[hp,<- ˺,˹,˦ _ _ (˄ _),˹] have h6:(hi˗*2^64+lo˗)%2^(L+1)=lo˗%2^(L+1):=by rw[hp,<- ˺,˹,˟] refine⟨?_,?_⟩ . rw[UInt64.toNat_or,hA,hB,h3,<- ®,<- Nat.shiftLeft_add_eq_or_of_lt h7] . rw[h6];have hC:(lo<<<(63-Lw))˗=lo˗%2^(L+1)*2^(63-L):=by rw[˒,hs,¡ (show 63-L<64 by omega),®,hp,˱ (2^(63-L)),Nat.mul_mod_mul_right] have h5:0<2^(63-L):=˄ _;by_cases h0:lo˗%2^(L+1)=0 . have:lo<<<(63-Lw)=0:=¢ (by rw[hC,h0,՞];simp);simp[this,h0] . have:lo<<<(63-Lw)≠0:=λ e=>by have h1:=congrArg ܄ e;rw[hC,՞]at h1;rcases ˿ h1 with h | h . exact h0 h . exact absurd h (⠆ h5) simp[this,h0] @[inline] def Yav (w0:┞):┞ := ~~~w0+1 @[inline] def Yaw (w1 w0:┞):┞ := ~~~w1+(if w0==0 then 1 else 0) @[inline] def Yax (w2 w1 w0:┞):┞ := ~~~w2+(if w1==0&&w0==0 then 1 else 0) lemma U4 (w2 w1 w0:┞) (h:w2˗*2^128+w1˗*2^64+w0˗≠0):(Yax w2 w1 w0)˗*2^128+(Yaw w1 w0)˗*2^64+(Yav w0)˗=2^192-(w2˗*2^128+w1˗*2^64+w0˗):=by have a2:=w2܂;have a1:=w1܂;have a0:=w0܂;unfold Yax Yaw Yav;by_cases z0:w0=0 . have z0':w0˗=0:=߹ by_cases z1:w1=0 . have z1':w1˗=0:=߷ simp only[z0,z1,Bool.and_self,━,UInt64.toNat_not]at *;simp at *;omega . have z1b:(w1==0)=false:=߷ have z1':w1˗≠0:=λ h=>z1 (¢ (by rw[h];rfl)) simp only[z0,z1b,beq_self_eq_true,Bool.false_and,¥,│,━,¤,UInt64.toNat_not]at *;simp at *;omega . have z0b:(w0==0)=false:=߷ have z0':w0˗≠0:=λ h=>z0 (¢ (by rw[h];rfl)) simp only[z0b,Bool.and_false,¥,│,¤,UInt64.toNat_not]at *;simp at *;omega @[inline] def Yaf (neg:┣) (m2 m1 m0:┞) (e:Int):┟ := let L:=Yj m2 let x:=(m2<<<(63-L))|||((m1>>>L)>>>1) let st:=(m1<<<(63-L)) != 0||m0 != 0 YA neg (if st then x|||1 else x) (e+((L.toNat+65:Nat):Int)) @[inline] def Yag (neg:┣) (m1 m0:┞) (e:Int):┟ := let L:=Yj m1 let x:=(m1<<<(63-L))|||((m0>>>L)>>>1) let st:=(m0<<<(63-L)) != 0 YA neg (if st then x|||1 else x) (e+((L.toNat+1:Nat):Int)) @[inline] def Yay (neg:┣) (m2 m1 m0:┞) (e:Int):┟ := if m2 != 0 then Yaf neg m2 m1 m0 e else if m1 != 0 then Yag neg m1 m0 e else YA neg m0 e lemma L9 (x:┞) (st:┣) (Q R:Nat) (hx:x˗=Q) (h0:st=decide (R≠0)) (hQ:2<=Q):(if st then x|||1 else x)˗=(if R==0 then Q else Q|||1):=by subst hx h0;by_cases hR:R=0 . simp[hR] . simp[hR] lemma QF (m:┞) (h:m≠0):m˗،<=63/\m˗<2^(m˗،+1)/\2^m˗،<=m˗:=by have h5:m˗≠0:=λ h'=>h (¢ (by rw[h'];rfl)) exact⟨by have:=(Nat.log2_lt h5).mpr m܂;omega,֎,˻ h5⟩ lemma QH (m r K:Nat) (h4:2^K<=m):2<=(m*2^64+r)/2^(K+1):=by rw[⠎ (˄ _)];calc 2*2^(K+1)=2^K*2^2:=by rw[<- ˪,<- Nat.pow_succ'] _<=m*2^64:=܇ h4 (˂ ܊ ܊) _<=_:=˼ _ _ lemma QL (m:┞) (s r:Nat) (h:m≠0) (hr:r<2^s):(m˗*2^s+r)،=s+m˗،:=by have h5:m˗≠0:=λ h'=>h (¢ (by rw[h'];rfl)) have h6:=@Nat.lt_log2_self m˗;apply(؎ (Nat.ne_of_gt (⠋ (˳ (˞ h5) (˄ s)) (˼ _ _)))).mpr;constructor . rw[˪,˱];exact(¶ _ (˻ h5)).trans (˼ _ _) . calc m˗*2^s+r < (m˗+1)*2^s:=by rw[׀,؋];omega _<=2^(m˗،+1)*2^s:=¶ _ h6 _=2^(s+m˗،+1):=by rw[<- ˪];ring_nf lemma QN (x:┞) (st:┣) (Q R:Nat) (hj:(if st then x|||1 else x)˗=(if R==0 then Q else Q|||1)) (hQ:2<=Q):(if st then x|||1 else x)≠0:=by intro h;have h3:=congrArg ܄ h;rw[hj,՞]at h3;split at h3 . omega . rw[FloatLib.Numerics.or_one_eq]at h3;split at h3<;>omega lemma U3 (neg:┣) (m1 m0:┞) (e:Int) (h1:m1≠0):Yag neg m1 m0 e=toWord (┑ Fmt ⟨neg,m1˗*2^64+m0˗,e⟩):=by have a1:=m1܂;have a0:=m0܂;unfold Yag;have hK:=Zj m1 h1;obtain⟨h8,h6,h4⟩:=QF m1 h1;generalize h0:m1˗،=K at hK h8 h6 h4;obtain⟨hx,h2⟩:=Z9 m1 m0 (Yj m1) K hK h8 h6;generalize Yj m1=L at hK hx h2 ⊢;have hQ:=QH _ m0˗ K h4;have hj:=L9 _ _ _ _ hx h2 hQ;rw[ZU _ _ _ (QN _ _ _ _ hj hQ),hj,hK];have h9:=QL m1 64 _ h1 a0;rw[h0]at h9;have:=M0 neg (m1˗*2^64+m0˗) (K+1) e ܉;unfold FloatLib.Numerics.shiftRightJam at this;rw[this] lemma U2 (neg:┣) (m2 m1 m0:┞) (e:Int) (h2:m2≠0):Yaf neg m2 m1 m0 e=toWord (┑ Fmt ⟨neg,m2˗*2^128+m1˗*2^64+m0˗,e⟩):=by have a1:=m1܂;have a0:=m0܂;unfold Yaf;have h0:m2˗≠0:=λ h=>h2 (¢ (by rw[h];rfl));have hM:m2˗*2^128+m1˗*2^64+m0˗≠0:=by have hp:0 < m2˗*2^128:=˳ (˞ h0) (˄ _);rw[Nat.add_assoc];exact Nat.ne_of_gt (⠋ hp (˼ _ _)) have hK:=Zj m2 h2;obtain⟨hd,h5,h8⟩:=QF m2 h2;generalize h4:m2˗،=K at hK hd h5 h8;obtain⟨hx,h1⟩:=Z9 m2 m1 (Yj m2) K hK hd h5;generalize Yj m2=L at hK hx h1 ⊢;obtain⟨A,hA⟩:∃ A,m2˗*2^64+m1˗=A:=⟨_,rfl⟩;rw[hA]at hx h1;have hb:A=A/2^(K+1)*2^(K+1)+A%2^(K+1):=(֏ A _).symm;have hg:A%2^(K+1)<2^(K+1):=˵ _ (˄ _);have h6:(2:Nat)^(K+65)=2^(K+1)*2^64:=߷ have h7:m2˗*2^128+m1˗*2^64+m0˗=(A%2^(K+1)*2^64+m0˗)+A/2^(K+1)*2^(K+65):=by have:m2˗*2^128+m1˗*2^64=A*2^64:=by rw[<- hA];ring rw[this,h6];conv_lhs=>rw[hb] ring have h9:A%2^(K+1)*2^64+m0˗<2^(K+65):=by rw[h6];calc A%2^(K+1)*2^64+m0˗h (¢ (by rw[h'];rfl));simp[h,this] rw[hf];by_cases hz:A%2^(K+1)=0<;>by_cases hh:m0˗=0<;>simp have ha:=QH _ m1˗ K h8;rw[hA]at ha;rw[<- hQ]at hx ha;have hj:=L9 _ _ _ _ hx hc ha;rw[ZU _ _ _ (QN _ _ _ _ hj ha),hj,hK];have hi:=QL m2 128 (m1˗*2^64+m0˗) h2 (by clear * - a0 a1;omega);rw[<- Nat.add_assoc,h4]at hi have:=M0 neg (m2˗*2^128+m1˗*2^64+m0˗) (K+65) e ܉;unfold FloatLib.Numerics.shiftRightJam at this;rw[this] lemma L8 (neg:┣) (m2 m1 m0:┞) (e:Int) (hM:m2˗*2^128+m1˗*2^64+m0˗≠0) : Yay neg m2 m1 m0 e=toWord (┑ Fmt ⟨neg,m2˗*2^128+m1˗*2^64+m0˗,e⟩):=by unfold Yay;by_cases h2:m2=0 . subst h2;simp only[│,՞,؍,˥]at hM ⊢;by_cases h1:m1=0 . subst h1;simp at hM ⊢;exact ZU neg m0 e (λ h=>hM (by rw[h];rfl)) . simp only[show(m1 != 0)=true by simpa using h1,━];exact U3 neg m1 m0 e h1 . simp only[show(m2 != 0)=true by simpa using h2,━];exact U2 neg m2 m1 m0 e h2 lemma ZaP (hi lo Lw:┞) (L:Nat) (h0:Lw˗=L) (hL:L<=63) (h1:hi˗<2^(L+1)) (h2:2^L<=hi˗) (st:┣) : 2^63<=(if st then ((hi<<<(63-Lw))|||((lo>>>Lw)>>>1))|||1 else (hi<<<(63-Lw))|||((lo>>>Lw)>>>1))˗:=by obtain⟨hx,-⟩:=Z9 hi lo Lw L h0 hL h1;have hQ:2^63<=(hi˗*2^64+lo˗)/2^(L+1):=by rw[⠎ (˄ _)];calc 2^63*2^(L+1)=2^L*2^64:=by rw[<- ˪,<- ˪,show 63+(L+1)=L+64 by omega] _<=hi˗*2^64:=¶ _ h2 _<=_:=˼ _ _ cases st . simp only[¥,│];rw[hx];exact hQ . simp only[━];rw[UInt64.toNat_or,hx,show(1:┞)˗=1 from rfl,FloatLib.Numerics.or_one_eq];split<;>omega @[inline] def YaR (neg:┣) (m1 m0:┞) (e:Int) (ok:┣) (b:┞):┟ := let L:=Yj m1 let x:=(m1<<<(63-L))|||((m0>>>L)>>>1) let st:=(m0<<<(63-L)) != 0 let x':=if st then x|||1 else x let u:=b+L+190 if ok&&u<=253 then YZ neg u x' else Yat neg x' e L 1 lemma G7 (hi lo:┞) (h:hi≠0):(Yj hi)˗=hi˗،/\hi˗،<=63/\∀ st:┣,2^63<=(if st then ((hi<<<(63-Yj hi))|||((lo>>>Yj hi)>>>1))|||1 else (hi<<<(63-Yj hi))|||((lo>>>Yj hi)>>>1))˗:=by have h2:hi˗≠0:=λ e=>h (¢ (by rw[e];rfl)) have h5:hi˗،<=63:=by have:=(Nat.log2_lt h2).mpr hi܂;omega exact⟨Zj hi h,h5,ZaP hi lo (Yj hi) _ (Zj hi h) h5 ֎ (˻ h2)⟩ lemma U1 (neg:┣) (m1 m0:┞) (e:Int) (ok:┣) (B:┞) (h1:m1≠0) (hr:Y0 e ok B):YaR neg m1 m0 e ok B=Yag neg m1 m0 e:=by obtain⟨hK,h5,hn⟩:=G7 m1 m0 h1;generalize m1˗،=K at hK h5;unfold YaR Yag Yat;dsimp only;generalize Yj m1=L at hK hn ⊢;split . rename_i h;simp at h;obtain⟨ha,hb⟩:=h;have hc:(L+190)˗=K+190:=by rw[¤,hK];simp;omega rw[UInt64.add_assoc]at hb ⊢;have h3:(B+(L+190))˗<=253:=by have:=˓ hb;simpa using this have hw:=hr _ (by rw[hc];omega) ha h3;exact M3 neg _ _ _ (hn _) (by rw[hw];push_cast;omega) h3 . rfl @[inline] def YaS (neg:┣) (m2 m1 m0:┞) (e:Int) (ok:┣) (b:┞):┟ := let L:=Yj m2 let x:=(m2<<<(63-L))|||((m1>>>L)>>>1) let st:=(m1<<<(63-L)) != 0||m0 != 0 let x':=if st then x|||1 else x let u:=b+L+254 if ok&&u<=253 then YZ neg u x' else Yat neg x' e L 65 lemma U0 (neg:┣) (m2 m1 m0:┞) (e:Int) (ok:┣) (B:┞) (h2:m2≠0) (hr:Y0 e ok B):YaS neg m2 m1 m0 e ok B=Yaf neg m2 m1 m0 e:=by obtain⟨hK,h5,hn⟩:=G7 m2 m1 h2;generalize m2˗،=K at hK h5;unfold YaS Yaf Yat;dsimp only;generalize Yj m2=L at hK hn ⊢;split . rename_i h;simp at h;obtain⟨ha,hb⟩:=h;have hc:(L+254)˗=K+254:=by rw[¤,hK];simp;omega rw[UInt64.add_assoc]at hb ⊢;have h3:(B+(L+254))˗<=253:=by have:=˓ hb;simpa using this have hw:=hr _ (by rw[hc];omega) ha h3;exact M3 neg _ _ _ (hn _) (by rw[hw];push_cast;omega) h3 . rfl @[inline] def Yaz (neg:┣) (m2 m1 m0:┞) (e:Int) (ok:┣) (b:┞):┟ := if m2 != 0 then YaS neg m2 m1 m0 e ok b else if m1 != 0 then YaR neg m1 m0 e ok b else Yau neg m0 e ok b lemma L7 (neg:┣) (m2 m1 m0:┞) (e:Int) (ok:┣) (B:┞) (hM:m2˗*2^128+m1˗*2^64+m0˗≠0) (hr:Y0 e ok B) : Yaz neg m2 m1 m0 e ok B=Yay neg m2 m1 m0 e:=by unfold Yaz Yay;by_cases h2:m2=0 . subst h2;by_cases h1:m1=0 . subst h1;exact M1 neg m0 e ok B (λ h=>hM (by rw[h];rfl)) hr . simp only[show(m1 != 0)=true by simpa using h1,━];exact U1 neg m1 m0 e ok B h1 hr . simp only[show(m2 != 0)=true by simpa using h2,━];exact U0 neg m2 m1 m0 e ok B h2 hr @[inline] def YaT (w2 w1 w0:┞) (e:Int) (negZero ok:┣) (B:┞):┟ := if w2=0/\w1=0/\w0=0 then (if negZero then 0x80000000 else 0) else if w2>>>63 != 0 then Yaz true (Yax w2 w1 w0) (Yaw w1 w0) (Yav w0) e ok B else Yaz false w2 w1 w0 e ok B lemma H6 (w2 w1 w0:┞) (e:Int) (negZero ok:┣) (B:┞) (hr:Y0 e ok B):YaT w2 w1 w0 e negZero ok B=┒ (YC w2 w1 w0) e negZero:=by have a2:=w2܂;have a1:=w1܂;have a0:=w0܂;have hV:w2˗*2^128+w1˗*2^64+w0˗<2^192:=by have:w1˗*2^64+w0˗<2^128:=by calc w1˗*2^64+w0˗>>63 != 0)=false:=by simp;apply ¢;simp;omega have hS:YC w2 w1 w0≠0:=܉ simp only[h0,¥,│,hS];rw[<- ┆,L7 false w2 w1 w0 e _ _ (by rw[hN];exact h2) hr,L8 false w2 w1 w0 e (by rw[hN];exact h2),hN] unfold ofIntDyadic;rw[hv,Int.natAbs_natCast,decide_eq_false (Int.not_lt.mpr (Int.natCast_nonneg N))] . have hv:YC w2 w1 w0=(N:Int)-2^192:=by unfold YC;rw[hN];simp only[hn,│] have h1:(w2>>>63 != 0)=true:=by simp;intro e;have:=congrArg ܄ e;simp at this;omega have h6:(N:Int)-2^192 = -((2^192-N:Nat):Int):=܉ have hS:YC w2 w1 w0≠0:=܉ have h3:=U4 w2 w1 w0 (by rw[hN];exact h2);rw[hN]at h3;have hM:(Yax w2 w1 w0)˗*2^128+(Yaw w1 w0)˗*2^64+(Yav w0)˗≠0:=܉ simp only[h1,━,hS,│];rw[<- ┆,L7 true _ _ _ e _ _ hM hr,L8 true _ _ _ e hM,h3];unfold ofIntDyadic;rw[hv,h6,Int.natAbs_neg,Int.natAbs_natCast,decide_eq_true (Int.neg_neg_of_pos (Int.natCast_pos.mpr (Nat.sub_pos_of_lt hV)))] def Ybo (w2 w1 w0:┞) (e:Int) (negZero:┣):┟ := YaT w2 w1 w0 e negZero ((Int64.ofInt e).toInt==e) (Int64.ofInt e).toUInt64 lemma T9 (w2 w1 w0:┞) (e:Int) (negZero:┣):Ybo w2 w1 w0 e negZero=┒ (YC w2 w1 w0) e negZero := H6 w2 w1 w0 e negZero _ _ (M2 e) @[inline] def Yf (w:┟):┞ := if expOf w=0 then (fracOf w).toUInt64 else (fracOf w).toUInt64+0x800000 @[inline] def Yd (w:┟):┞ := if expOf w=0 then 0 else (expOf w).toUInt64-1 lemma Zk (w:┟):(Yf w)˗=mantOf w:=by have:=fracOf_toNat_lt w;unfold Yf mantOf;split_ifs . simp . simp only[¤];show((fracOf w)؊+8388608)%2^64=2^23+(fracOf w)؊;omega lemma Zf (w:┟):(Yd w)˗=idxOf w:=by unfold Yd idxOf;split_ifs with h . rfl . have h1:1<=(expOf w)؊:=by rcases ՚ (expOf w)؊ with h0 | h0 . exact absurd (˅ (by simpa using h0)) h . exact h0 rw[§ _ _ (by rw[¿];simp;omega)];simp lemma Zc (a b:┡) (h:a܆+b܆<֍):(a+b)܆=a܆+b܆:=by exact ¡ h lemma A4 (A:┠ ┢) (base n k:┡) (hA:base܆+n܆<=A.size) (hs:base܆+n܆<֍) (h:k>>1)>>>(63-r))˗=m˗/2^(64-r˗):=by rw[˔,˔,T8 r h0,©,©,¡ (show 63-r˗<64 by omega),show(1:┞)˗%64=1 from rfl,˭,<- ˪] congr 2;omega lemma L3 (m r:Nat) (hr:r<64):m*2^r%2^64+m/2^(64-r)*2^64=m*2^r:=by have h:m*2^r/2^64=m/2^(64-r):=by rw[show(2:Nat)^64=2^r*2^(64-r) by rw[<- ˪];congr 1;omega,<- ˭,Nat.mul_div_cancel _ (˄ r)] rw[<- h];exact Nat.mod_add_div' _ _ lemma T7 (m s:┞) (h0:s˗<64):((m>>>1)>>>(63-(s&&&63)))˗*2^64+(m<<<(s&&&63))˗ =m˗*2^s˗:=by have hr:(s&&&63)˗=s˗:=by rw[L6];exact ¡ h0 rw[L5 _ _ ܉,L4 _ _ ܉,hr] have Zh:=L3 m˗ s˗ h0;omega lemma T6 (m s:┞) (h1:64<=s˗) (h2:s˗<128):((m>>>1)>>>(63-(s&&&63)))˗*2^128+(m<<<(s&&&63))˗*2^64 =m˗*2^s˗:=by have hr:(s&&&63)˗=s˗-64:=by rw[L6];omega rw[L5 _ _ ܉,L4 _ _ ܉,hr] have Zh:=L3 m˗ (s˗-64) ܉ have hp:m˗*2^s˗=m˗*2^(s˗-64)*2^64:=by rw[˺,<- ˪];congr 2;omega omega lemma T5 (m s:┞) (hs:s˗<128):(if s<64 then (0:┞) else (m>>>1)>>>(63-(s&&&63)))˗*2^128 + (if s<64 then (m>>>1)>>>(63-(s&&&63)) else m<<<(s&&&63))˗*2^64 + (if s<64 then m<<<(s&&&63) else 0)˗=m˗*2^s˗:=by by_cases h:s<64 . rw[if_pos h,if_pos h,if_pos h,՞,؍,˥];exact T7 m s (UInt64.lt_iff_toNat_lt.mp h) . rw[if_neg h,if_neg h,if_neg h,՞,܅];exact T6 m s (by have:=UInt64.lt_iff_toNat_lt.not.mp h;simp at this;omega) hs lemma D8 (y ng:┞) (h:ng˗<=1):(y^^^(0-ng))˗=if ng˗=1 then 2^64-1-y˗ else y˗:=by rcases Nat.le_one_iff_eq_zero_or_eq_one.mp h with h0 | h1 . have:ng=0:=¢ (by simpa using h0);subst this;simp . have:ng=1:=¢ (by simpa using h1) subst this;show(y.toBitVec^^^BitVec.allOnes 64).toNat=_;rw[BitVec.xor_allOnes,BitVec.toNat_not];simp lemma ZJ (a b:┞):(a+b)˗=(a˗+b˗)%2^64 /\ (if a+brcases Nat.lt_or_ge kb˗ 1 with h2 | h2 . rw[show ka˗=0 by omega,show kb˗=0 by omega];rfl . rw[show ka˗=0 by omega,Nat.zero_or];omega . rw[show kb˗=0 by omega,Nat.or_zero];omega . omega -splitDisjunctions rw[¤,¤,h8,h7,h6,h3,h0,h5,h4];omega lemma T3 (w2 w1 w0 c:┞):(w2+(if w1+(if w0+comega lemma H4 (t0 t1 t2:┞):((t0|||t1|||t2)==0)=decide (t2˗*2^128+t1˗*2^64+t0˗=0):=by have h0:t0=0↔t0˗=0:=by rw[<- ٬];simp have h1:t1=0↔t1˗=0:=by rw[<- ٬];simp have h2:t2=0↔t2˗=0:=by rw[<- ٬];simp rw[؆,beq_iff_eq,┈,UInt64.or_eq_zero_iff,UInt64.or_eq_zero_iff,h0,h1,h2];omega lemma C5 (a b:┟):((a^^^b)>>>31)׆˗=if ˷ (signOf a) (signOf b) then 1 else 0:=by have ha:a؊<2^32:=՟ a;have hb:b؊<2^32:=՟ b;have h0:signOf a=decide (a؊/2^31=1):=by unfold signOf;have h1:(a؊&&&2^31)%2^31=0:=by rw[Nat.and_mod_two_pow,Nat.mod_self,Nat.and_zero] have h2:(a؊&&&2^31)/2^31=a؊/2^31%2:=by rw[Nat.and_div_two_pow,Nat.div_self (˄ 31),Nat.and_one_is_mod] have h3:(a&&&߾)؊=a؊&&&2^31:=܋ have h4:(a&&&߾ != 0)=decide ((a&&&߾)؊≠0):=by rw[؆,bne_iff_ne,┈,ne_eq,ne_eq,<- ⠄];simp rw[h4,h3,؆,┈,┈];omega have h5:signOf b=decide (b؊/2^31=1):=by unfold signOf;have h1:(b؊&&&2^31)%2^31=0:=by rw[Nat.and_mod_two_pow,Nat.mod_self,Nat.and_zero] have h2:(b؊&&&2^31)/2^31=b؊/2^31%2:=by rw[Nat.and_div_two_pow,Nat.div_self (˄ 31),Nat.and_one_is_mod] have h3:(b&&&߾)؊=b؊&&&2^31:=܋ have h4:(b&&&߾ != 0)=decide ((b&&&߾)؊≠0):=by rw[؆,bne_iff_ne,┈,ne_eq,ne_eq,<- ⠄];simp rw[h4,h3,؆,┈,┈];omega rw[՝,˲,UInt32.toNat_xor,show(31:┟)؊%32=31 from rfl,Nat.shiftRight_xor_distrib,©,©,h0,h5] have:a؊/2^31<=1:=܉ have:b؊/2^31<=1:=܉ rcases Nat.le_one_iff_eq_zero_or_eq_one.mp ‹a.toNat/2^31<=1› with h | h<;>rcases Nat.le_one_iff_eq_zero_or_eq_one.mp ‹b.toNat/2^31<=1› with h' | h' <;> rw[h,h']<;>decide @[inline] def YL {β:Type} (lo:┞) (a b:┟) (w2 w1 w0 c:┞) (kont:┞ -> ┞ -> ┞ -> ┞ -> β):β := let m:=Yf a*Yf b let s:=Yd a+Yd b-lo let rr:=s&&&63 let x0:=m<<>>1)>>>(63-rr) let lowq:=s<64 let y0:=if lowq then x0 else 0 let y1:=if lowq then x1 else x0 let y2:=if lowq then 0 else x1 let ng:=((a^^^b)>>>31).toUInt64 let mk:┞:=0-ng let s0:=w0+(y0^^^mk) let k0:┞:=if s0>>1)>>>(63-(s&&&63)))˗*2^128 + (if s<64 then (m>>>1)>>>(63-(s&&&63)) else m<<<(s&&&63))˗*2^64 + (if s<64 then m<<<(s&&&63) else 0)˗=0:=by have h0:m=0:=¢ (by simpa using hm);subst h0;split_ifs<;>simp<;>rfl lemma Zg (w:┟):idxOf w<=254:=by have:=expOf_toNat_lt w;unfold idxOf;split_ifs<;>omega lemma ZK (a b:┟):mantOf a*mantOf b<2^48:=calc mantOf a*mantOf b<2^24*2^24:=Nat.mul_lt_mul'' (┊ a) (┊ b) lemma B3 (a b:┢):(Yf a*Yf b)˗=mantOf a*mantOf b:=by rw[٫,Zk,Zk];exact ¡ (by have:=ZK a b;omega) lemma C1 (a b:┢):(Yd a+Yd b)˗=idxOf a+idxOf b:=by have:=Zg a;have:=Zg b;rw[¤,Zf,Zf,¡ ܉] lemma G5 (a b:┢):Yf a*Yf b=0↔mantOf a*mantOf b=0:=by rw[<- B3,<- ٬];rfl lemma G8 (w:┢):(Yf w==0)=decide (mantOf w=0):=by rw[؆,beq_iff_eq,┈,<- Zk,<- ٬];rfl lemma Zr {β:Type} (lo:┞) (a b:┟) (w2 w1 w0 c:┞) (kont:┞ -> ┞ -> ┞ -> ┞ -> β) (hc:c˗+1<2^64) (hw:mantOf a*mantOf b≠0 -> lo˗<=idxOf a+idxOf b/\idxOf a+idxOf b>>31)׆=ng at h3 ⊢ . rw[¤];have:ng˗<=1:=by rw[h3];split_ifs<;>omega -splitDisjunctions omega -splitDisjunctions · have hY:(if s<64 then (0:┞) else (m>>>1)>>>(63-(s&&&63)))˗*2^128+(if s<64 then (m>>>1)>>>(63-(s&&&63)) else m<<<(s&&&63))˗*2^64 + (if s<64 then m<<<(s&&&63) else 0)˗=mantOf a*mantOf b*2^(idxOf a+idxOf b-lo˗):=by by_cases h0:mantOf a*mantOf b=0 . rw[h0,؍];exact T2 m s (by rw[h4,h0]) . obtain⟨h1,h2⟩:=hw h0;have h7:s˗=idxOf a+idxOf b-lo˗:=by rw[<- hs,§ _ _ (by rw[¿,¤,Zf,Zf];have:=Zg a;have:=Zg b;omega -splitDisjunctions), ¤,Zf,Zf] have:=Zg a;have:=Zg b;rw[¡ (by omega -splitDisjunctions)] rw[<- h4,<- h7];exact T5 m s ܉ generalize (if s<64 then (0:┞) else (m>>>1)>>>(63-(s&&&63)))=y2 at hY ⊢;generalize (if s<64 then (m>>>1)>>>(63-(s&&&63)) else m<<<(s&&&63))=y1 at hY ⊢;generalize (if s<64 then m<<<(s&&&63) else 0)=y0 at hY ⊢;have h5:ng˗<=1:=߷ have z2:=D8 y2 ng h5;have z1:=D8 y1 ng h5;have z0:=D8 y0 ng h5;have hd:y2˗<2^64:=˨ y2;have ha:y1˗<2^64:=˨ y1;have hf:y0˗<2^64:=˨ y0;unfold Yx;rw[T4,¤,Nat.mod_eq_of_lt (a:=c˗+ng˗) (by omega -splitDisjunctions),<- Zn] generalize hP:mantOf a*mantOf b*2^(idxOf a+idxOf b-lo˗)=P at hY;have h6:(if ˷ (signOf a) (signOf b) then -((mantOf a*mantOf b:Nat):Int) else ((mantOf a*mantOf b:Nat):Int))*2^(idxOf a+idxOf b-lo˗) = if ˷ (signOf a) (signOf b) then -(P:Int) else (P:Int):=by rw[<- hP];split_ifs<;>push_cast<;>ring rw[h6];split_ifs at h3 z2 z1 z0 ⊢ with hx h9<;>omega @[inline] def YD (w2 w1 w0 c:┞) (e:Int):┞ := let t0:=w0+c let k0:┞:=if t0>>23).toNat def YM (a:┟):Nat:=((a&&&0x7FFFFFFF)>>>23).toNat lemma T1 (a:┟):(a&&&─)؊=(expOf a)؊*2^23+(fracOf a)؊:=by simp only[٭,expOf,fracOf,˲];rw[show(─:┟)؊=2^31-1 from rfl,show(0xFF:┟)؊=2^8-1 from rfl,show(0x7FFFFF:┟)؊=2^23-1 from rfl,show(23:┟)؊%32=23 from rfl,˕,˕,˕,©] omega lemma Zb (a:┟):YR a<=511/\YM a<=255/\(YM a<255 -> expOf a≠255) /\ (mantOf a≠0 -> YR a<=idxOf a+1/\idxOf a+1<=max (YM a) 1):=by have hv:=T1 a;have hE:=expOf_toNat_lt a;have hF:=fracOf_toNat_lt a;have h3:YR a=if (a&&&─)؊=0 then 511 else ((a&&&─)؊-1)/2^23:=by unfold YR;rw[˲,UInt32.toNat_sub,show(23:┟)؊%32=23 from rfl,©,show(1:┟)؊=1 from rfl] split_ifs with h0<;>omega have h4:YM a=(expOf a)؊:=by unfold YM;rw[˲,show(23:┟)؊%32=23 from rfl,©,hv] omega have h1:expOf a=0↔(expOf a)؊=0:=by rw[<- ⠄];simp have h2:expOf a=255↔(expOf a)؊=255:=by rw[<- ⠄];simp unfold mantOf idxOf;rw[h3,h4];refine⟨by split_ifs<;>omega,by omega -splitDisjunctions,λ h he=>by rw[h2]at he;omega -splitDisjunctions,λ hm=>?_⟩;by_cases h0:expOf a=0 . rw[if_pos h0]at hm ⊢;rw[h1]at h0;split_ifs<;>omega . rw[if_neg h0]at hm ⊢;rw[h1]at h0;split_ifs<;>omega def Yah (A:┠ ┢) (base n:┡) (hA:base.toNat+n.toNat<=A.size) (hs:base.toNat+n.toNat>>23 let kh:=v>>>23 Yah A base n hA hs (if kl t L<=YR A[base܆+t]! /\ YM A[base܆+t]! <= H:=by generalize hd:n܆-k܆=d;induction d generalizing k lo hi with | zero => have h0:¬ kby omega⟩ rw[UInt32.toNat_add,UInt32.toNat_shiftLeft,show(16:┟)؊%32=16 from rfl,®] omega | succ d ih => have h0:k>>23)؊=YR w:=rfl;have hg:((w&&&─)>>>23)؊=YM w:=rfl;obtain⟨k1,k2,-,-⟩:=Zb w;obtain⟨L,H,h1,h2,h3,h5,h6,h4⟩:=ih (if ((w&&&─)-1)>>>23>>23 else lo) (if hi < (w&&&─)>>>23 then (w&&&─)>>>23 else hi) (k+1) ܉ (by split_ifs<;>omega) (by split_ifs<;>omega) ܉ have hh:(if ((w&&&─)-1)>>>23>>23 else lo)؊<=lo؊/\(if ((w&&&─)-1)>>>23>>23 else lo)؊<=YR w:=by split_ifs with hc . rw[⠅]at hc;omega . rw[⠅]at hc;omega have hj:hi؊<=(if hi < (w&&&─)>>>23 then (w&&&─)>>>23 else hi)؊/\YM w<=(if hi < (w&&&─)>>>23 then (w&&&─)>>>23 else hi)؊:=by split_ifs with hc . rw[⠅]at hc;omega . rw[⠅]at hc;omega refine⟨L,H,h1,h2,h3,by omega,by omega,λ t hb h9=>?_⟩;rcases Nat.lt_or_ge t (k܆+1) with ht | ht . have h8:t=k܆:=܉ subst h8;rw[hw];omega . exact h4 t ܉ h9 def YS (X W:┠ ┢) (xa wa n:┡) (hX:xa.toNat+n.toNat<=X.size) (hW:wa.toNat+n.toNat<=W.size) (hx:xa.toNat+n.toNatYS X W xa wa n hX hW hx hw lo e bw v2 v1 v0 c' (k+1) else YL lo oneW bw w2 w1 w0 c λ v2 v1 v0 c'=>YD v2 v1 v0 c' e termination_by n.toNat-k.toNat decreasing_by exact ZI n k h def YB (X W:┠ ┢) (xa wa lo k:Nat):Nat -> Int | 0=>0 | r+1=>sv X[xa+k]! * sv W[wa+k]! * 2^(idxOf X[xa+k]! + idxOf W[wa+k]! - lo) + YB X W xa wa lo (k+1) r lemma ZL (a b:┟) (lo:Nat) (h:mantOf a*mantOf b≠0 -> lo<=idxOf a+idxOf b/\idxOf a+idxOf b<=lo+122) : -(2^170:Int)<=sv a*sv b*2^(idxOf a+idxOf b-lo) /\ sv a*sv b*2^(idxOf a+idxOf b-lo)<=2^170:=by rw[<- Zn];have hM:=ZK a b;by_cases h0:mantOf a*mantOf b=0 . rw[h0];split_ifs<;>simp . obtain⟨h1,h2⟩:=h h0;have hp:2^(idxOf a+idxOf b-lo)<=2^122:=˂ ܊ ܉;have hP:mantOf a*mantOf b*2^(idxOf a+idxOf b-lo)<=2^170:=calc mantOf a*mantOf b*2^(idxOf a+idxOf b-lo)<=2^48*2^122:=܇ ܉ hp _=2^170:=܊ have Zh:((mantOf a*mantOf b:Nat):Int)*2^(idxOf a+idxOf b-lo)=((mantOf a*mantOf b*2^(idxOf a+idxOf b-lo):Nat):Int):=by push_cast;ring split_ifs . rw[neg_mul,Zh];omega . rw[Zh];omega lemma ZW (fa fb:Nat -> ┟):∀ r k,Yo fa fb k (r+1)=Yo fa fb k r+sv (fa (k+r))*sv (fb (k+r))*2^(idxOf (fa (k+r))+idxOf (fb (k+r))):=by intro r;induction r with | zero=>intro k;simp[Yo] | succ r ih=>intro k;rw[Yo,ih (k+1),Yo,show k+1+r=k+(r+1) by omega];ring lemma ZA (a b:┟) (lo:Nat) (h:mantOf a*mantOf b≠0 -> lo<=idxOf a+idxOf b):sv a*sv b*2^(idxOf a+idxOf b)=2^lo*(sv a*sv b*2^(idxOf a+idxOf b-lo)):=by by_cases h0:mantOf a*mantOf b=0 . have:sv a*sv b=0:=by rw[<- Zn,h0];split_ifs<;>simp rw[this];ring rw[show idxOf a+idxOf b=lo+(idxOf a+idxOf b-lo) by omega,pow_add];rw[show lo+(idxOf a+idxOf b-lo)-lo=idxOf a+idxOf b-lo by omega];ring @[inline] def Yc (A:┠ ┢) (inW i:Nat):┟ := if h:i*inW+inW<=A.size/\i*inW+inW<=4294967295 then Yah A (i*inW).toUSize inW.toUSize (by rw [Za _ ܉,Za _ ܉];exact h.1) (by rw [Za _ ܉,Za _ ܉];have:=USize.le_size;omega) 511 0 0 else 0x01FF00FF @[inline] def Yk (k:┟):┞:=(if k=0 then 0 else k-1).toUInt64 @[inline] def Yp (bx bv bw:┟):┞ := let lo0:=Yk (bx>>>16)+Yk (bv>>>16) let xb:=Yd oneW+Yd bw if !(Yf bw==0)&&xbif t < inW then X[i*inW+t]! else oneW) (λ t=>if t < inW then W[j*inW+t]! else b[j]!) @[inline] def YL6 {β:Type} (lo:┞) (a b:┟) (w2 w1 w0 c:┞) (kont:┞ -> ┞ -> ┞ -> ┞ -> β):β := let m:=Yf a*Yf b let s:=Yd a+Yd b-lo let rr:=s&&&63 let y0:=m<<>>1)>>>(63-rr) let ng:=((a^^^b)>>>31).toUInt64 let mk:┞:=0-ng let s0:=w0+(y0^^^mk) let k0:┞:=if s0 ┞ -> ┞ -> ┞ -> β) (h:mantOf a*mantOf b=0\/(lo˗<=idxOf a+idxOf b/\idxOf a+idxOf b<=lo˗+63)) : YL6 lo a b w2 w1 w0 c kont=YL lo a b w2 w1 w0 c kont:=by unfold YL6 YL;by_cases hs:Yd a+Yd b-lo<64 · simp only[hs,━,UInt64.zero_xor] · have hm:Yf a*Yf b=0:=by rcases h with h|⟨h1,h2⟩ · rcases ˿ h with h|h · have:Yf a=0:=¢ (by rw[Zk,h];rfl) rw[this];simp · have:Yf b=0:=¢ (by rw[Zk,h];rfl) rw[this];simp · exfalso;apply hs;have fa:=Zf a;have fb:=Zf b;have ia:=Zg a;have ib:=Zg b;rw[˃,§ _ _ (⠃ (by rw[¤,fa,fb];norm_num;omega)),¤,fa,fb] norm_num;omega simp only[hs,│,hm,UInt64.zero_shiftLeft,UInt64.zero_shiftRight,UInt64.zero_xor] def YS6 (X W:┠ ┢) (xa wa n:┡) (hX:xa.toNat+n.toNat<=X.size) (hW:wa.toNat+n.toNat<=W.size) (hx:xa.toNat+n.toNatYS6 X W xa wa n hX hW hx hw lo e bw v2 v1 v0 c' (k+1) else YL lo oneW bw w2 w1 w0 c λ v2 v1 v0 c'=>YD v2 v1 v0 c' e termination_by n.toNat-k.toNat decreasing_by exact ZI n k h lemma E7 (X W:┠ ┢) (xa wa n:┡) (hX:xa܆+n܆<=X.size) (hW:wa܆+n܆<=W.size) (hx:xa܆+n܆<֍) (hw:wa܆+n܆<֍) (lo:┞) (e:Int) (bw:┟) (h5:∀ t,t mantOf X[xa܆+t]! * mantOf W[wa܆+t]! ≠ 0 -> lo˗<=idxOf X[xa܆+t]! + idxOf W[wa܆+t]! /\ idxOf X[xa܆+t]! + idxOf W[wa܆+t]! <= lo˗+63) : ∀ (d:Nat) (k:┡) (w2 w1 w0 c:┞),n܆-k܆=d -> YS6 X W xa wa n hX hW hx hw lo e bw w2 w1 w0 c k=YS X W xa wa n hX hW hx hw lo e bw w2 w1 w0 c k:=by intro d;induction d with | zero=> intro k w2 w1 w0 c hd;have h0:¬ k intro k w2 w1 w0 c hd;have h0:k122 then Yai X W b inW i j else let r:=if hi-lo<=63 then YS6 X W (i*inW).toUSize (j*inW).toUSize inW.toUSize (by rw [Za _ ܉,Za _ ܉];exact h.1) (by rw [Za _ ܉,Za _ ܉];exact h.2.1) (by rw [Za _ ܉,Za _ ܉];have:=USize.le_size;omega) (by rw [Za _ ܉,Za _ ܉];have:=USize.le_size;omega) lo ((lo.toNat:Int)-298) bw 0 0 0 0 0 else YS X W (i*inW).toUSize (j*inW).toUSize inW.toUSize (by rw [Za _ ܉,Za _ ܉];exact h.1) (by rw [Za _ ܉,Za _ ܉];exact h.2.1) (by rw [Za _ ܉,Za _ ܉];have:=USize.le_size;omega) (by rw [Za _ ܉,Za _ ܉];have:=USize.le_size;omega) lo ((lo.toNat:Int)-298) bw 0 0 0 0 0 if r<0x100000000 then r.toUInt32 else Yai X W b inW i j else Yai X W b inW i j @[specialize] def Yaj (hw:Nat) (f:Nat -> Nat -> ┢) (ch j:Nat) (acc:┠ ┢):┠ ┢ := if j Nat -> ┢) (ch:Nat) (acc:┠ ┢):┠ ┢ := if ch Nat -> ┢):┠ ┢:=Yak c hw f 0 (Array.mkEmpty (c*hw)) lemma H3 (hw:Nat) (f:Nat -> Nat -> ┢) (ch:Nat):∀ k j (acc:┠ ┢),hw-j=k -> (Yaj hw f ch j acc)܃=acc܃++(List.range' j (hw-j)).map (f ch):=by intro k;induction k with | zero=>intro j acc h;unfold Yaj;rw[if_neg ܉];simp[h] | succ k ih=> intro j acc h;unfold Yaj;rw[if_pos ܉,ih (j+1) _ ܉,show hw-j=(hw-(j+1))+1 by omega,˽];simp lemma S7 (c hw:Nat) (f:Nat -> Nat -> ┢):∀ k ch (acc:┠ ┢),c-ch=k -> (Yak c hw f ch acc)܃=acc܃++(List.range' (ch*hw) ((c-ch)*hw)).map (λ i=>f (i/hw) (i%hw)):=by intro k;induction k with | zero=>intro ch acc h;unfold Yak;rw[if_neg ܉];simp[h] | succ k ih=> intro ch acc h;unfold Yak;rw[if_pos ܉,ih (ch+1) _ ܉,H3 hw f ch _ 0 _ rfl,show(c-ch)*hw=hw+(c-(ch+1))*hw by rw[show c-ch=(c-(ch+1))+1 by omega,׀,؋,˹],<- List.range'_append,List.map_append,Nat.succ_mul] simp only[List.append_assoc,Nat.sub_zero];congr 2 . rw[show List.range' (ch*hw) hw=(List.range' 0 hw).map (ch*hw+·) by rw[List.map_add_range'];simp,List.map_map];apply List.map_congr_left;intro j hj;rw[List.mem_range'_1]at hj;simp only[Function.comp_def,˹ (ch*hw) j,˦ _ _ (show 0 Nat -> ┢):YT c hw f=Array.ofFn (n:=N) λ i=>f (i؞/hw) (i؞%hw):=by subst hN;apply Array.ext';rw[YT,S7 c hw f _ 0 _ rfl];apply ۔<;>simp @[specialize] def Yaq (n:Nat) (f:Nat -> ┢) (i:Nat) (acc:┠ ┢):┠ ┢ := if i ┢):┠ ┢:=Yaq n f 0 (Array.mkEmpty n) @[inline] def YaJ (w:┢) (m:┞):┞ := (Yf w<<<(Yd w-m))*((1:┞)-(2:┞)*(w>>>31).toUInt64) @[inline] def Y4 (w:┢) (m:┞):┟:=(YaJ w m+0x80000000).toUInt32 @[inline] def QhiS (hi lo q:┞):┞ := hi+((0:┞)-(q>>>63))+(if lo+q>>16) @[specialize] def QY6G (n:┡) (f:(k:┡) -> k ┞) (B0:┞) (bw:┟) (hi lo:┞) (k:┡):┞ := if h:k>>63)) hi lo 0 λ v2 v1 v0 c' => YD v2 v1 v0 c' ((B0.toNat:Int)-298) termination_by n.toNat-k.toNat decreasing_by exact ZI n k h @[inline] def QPb (x:┟) (m:┞) (s:┣):Nat := let M:=Yf x<<<(Yd x-m) (if signOf x != s then 4611686018427387904-M else 4611686018427387904+M).toNat @[specialize] def QPD (n:Nat) (f:Nat -> ┟) (m:┞) (t:Nat) (P:┠ Nat):┠ Nat := if t ┟) (t:Nat) (I:┠ ┟):┠ ┟ := if t>>31).toUSize)܆=2*k܆+(w>>>31)؊/\(w>>>31)؊<2:=by have e:(w>>>31)؊<2:=by rw[˲];have:=w.toNat_lt;simp;omega have:=˖;refine⟨?_,e⟩;rw[Zc _ _ (by rw[Zc _ _ ܉,⠈];omega),Zc _ _ ܉,⠈];omega @[inline] def QPS (inW:Nat) (BX BV:┠ ┟):┣ := 16<=inW&&BX.all (λ bx=>bx&&&0xFFFF != 255)&&BV.all (λ bv=>bv&&&0xFFFF != 255) && (BX.foldl (λ (m:┞) (bx:┟)=>max m (QYF bx)) 0).toNat+(BV.foldl (λ (m:┞) (bv:┟)=>max m (QYF bv)) 0).toNat<=14 lemma O7 (u:┟) (n:Nat) (h:n<1048576):(min u (n-1).toUInt32)؊<=n-1 /\ (u؊<=n-1 -> min u (n-1).toUInt32=u):=by have e:(n-1).toUInt32؊=n-1:=߶ rw[UInt32.min_def];split<;>rename_i c<;>rw[⠍,e]at c . exact⟨c,λ _=>rfl⟩ . exact⟨by omega,λ h2=>absurd h2 c⟩ @[inline] def QPa (X:┠ ┢) (P:┠ Nat) (I:┠ ┟) (W b:┠ ┢) (inW i j:Nat) (bx bv:┟):┢ := let xm:=Yk (bx>>>16) let wm:=Yk (bv>>>16) let bw:=b[j]! let xb:=Yd oneW+Yd bw if h:P.size=2*(if I.size=0 then inW else I.size)/\I.size<=inW/\i*inW+inW<=X.size/\j*inW+inW<=W.size/\i*inW+inW<=4294967295 /\ j*inW+inW<=4294967295/\inW<1048576/\(bx&&&0xFFFF)≠255/\(bv&&&0xFFFF)≠255 /\ xm<=Yk (bx&&&0xFFFF)/\wm<=Yk (bv&&&0xFFFF)/\(QYF bx).toNat+(QYF bv).toNat<=14 /\ expOf bw≠255/\(Yf bw=0\/(xm+wm<=xb/\xb-(xm+wm)<80))/\1<=wm then let wa:=(j*inW).toUSize let iw:=(inW-1).toUInt32 let r:=if c:I.size=0 then QY6G inW.toUSize (λ k hk=> let w:=W.uget (wa+k) (by have:=USize.lt_iff_toNat_lt.mp hk;rw [Za _ ܉] at this;simp only [wa];rw [Zc _ _ (by rw [Za _ ܉];have:=USize.le_size;omega),Za _ ܉];omega) ((P.uget (k+k+(w>>>31).toUSize) (by have:=USize.lt_iff_toNat_lt.mp hk;rw [Za _ ܉] at this;have:=B6 k w ܉;rw [if_pos c] at h;omega)).toUInt64-4611686018427387904)*(Yf w<<<((expOf w).toUInt64-(wm+1)))) (xm+wm) bw 0 0 0 else QY6G I.size.toUSize (λ k hk=> let u:=I.uget k (by have:=USize.lt_iff_toNat_lt.mp hk;rw [Za _ ܉] at this;omega) let w:=W.uget (wa+(min u iw).toUSize) (by have:=USize.lt_iff_toNat_lt.mp hk;rw [Za _ ܉] at this;have:=(O7 u inW ܉).1;simp only [wa,iw] at *;rw [Zc _ _ (by rw [Za _ ܉,UInt32.toNat_toUSize];have:=USize.le_size;omega),Za _ ܉,UInt32.toNat_toUSize];omega) ((P.uget (k+k+(w>>>31).toUSize) (by have:=USize.lt_iff_toNat_lt.mp hk;rw [Za _ ܉] at this;have:=B6 k w ܉;rw [if_neg c] at h;omega)).toUInt64-4611686018427387904)*(Yf w<<<((expOf w).toUInt64-(wm+1)))) (xm+wm) bw 0 0 0 if r<0x100000000 then r.toUInt32 else Yai X W b inW i j else YaU X W b inW i j bx bv def YaV (rows inW outW:Nat) (relu:┣) (X W b:┠ ┢):┠ ┢ := let BX:┠ ┟:=Array.ofFn (n:=rows) λ i=>Yc X inW i.val let BV:┠ ┟:=Array.ofFn (n:=outW) λ j=>Yc W inW j.val let P:┠ (┠ Nat × ┠ ┟):=if QPS inW BX BV then Array.ofFn (n:=rows) λ i=> let I:=QPI inW (λ t=>X[i.val*inW+t]!) 0 (Array.emptyWithCapacity inW) if 0X[i.val*inW+(I[m]!).toNat]!) (Yk (BX[i.val]! >>> 16)) 0 (Array.emptyWithCapacity (2*I.size)),I) else (QPD inW (λ t=>X[i.val*inW+t]!) (Yk (BX[i.val]! >>> 16)) 0 (Array.emptyWithCapacity (2*inW)),#[]) else Array.replicate rows (#[],#[]) YT rows outW λ i j=>act relu (QPa X P[i]!.1 P[i]!.2 W b inW i j BX[i]! BV[j]!) lemma Zq (k:┟):(Yk k)˗=k؊-1:=by unfold Yk;split_ifs with h . subst h;rfl . rw[՝,UInt32.toNat_sub_of_le _ _ (by rw[⠍];have:k؊≠0:=λ h0=>h (˅ (by simpa using h0));show 1<=k؊;omega)] rfl lemma G6 (x y:┟):(Yk x+Yk y)˗=x؊-1+(y؊-1):=by rw[¤,Zq,Zq];have:x؊<2^32:=՟ _;have:y؊<2^32:=՟ _;exact ¡ ܉ lemma ZM (bw:┟):(Yd oneW+Yd bw)˗=idxOf oneW+idxOf bw:=by rw[¤,Zf,Zf];have:=Zg oneW;have:=Zg bw;exact ¡ ܉ lemma D7 (bx bv bw:┟):(Yp bx bv bw)˗<=((bx>>>16)؊-1)+((bv>>>16)؊-1) /\ (mantOf bw≠0 -> (Yp bx bv bw)˗<=idxOf oneW+idxOf bw):=by have h1:=G6 (bx>>>16) (bv>>>16);have h2:=ZM bw;have hm:=G8 bw;unfold Yp;dsimp only;rw[hm];split_ifs with hc . simp only[˯,Bool.not_eq_true',decide_eq_false_iff_not,┃,˃]at hc;omega . simp only[˯,Bool.not_eq_true',decide_eq_false_iff_not,┃,˃,not_and,not_lt]at hc;constructor . omega . intro hb;have:=hc hb;omega lemma D6 (bx bv bw:┟):((bx&&&0xFFFF)؊-1)+((bv&&&0xFFFF)؊-1)<=(Yu bx bv bw)˗ /\ (mantOf bw≠0 -> idxOf oneW+idxOf bw<=(Yu bx bv bw)˗):=by have h1:=G6 (bx&&&0xFFFF) (bv&&&0xFFFF);have h2:=ZM bw;have hm:=G8 bw;unfold Yu;dsimp only;rw[hm];split_ifs with hc . simp only[˯,Bool.not_eq_true',decide_eq_false_iff_not,┃,˃]at hc;omega . simp only[˯,Bool.not_eq_true',decide_eq_false_iff_not,┃,˃,not_and,not_lt]at hc;constructor . omega . intro hb;have:=hc hb;omega lemma Zo (bx:┟) (L H:Nat) (h:bx؊=L*2^16+H) (hH:H<2^16):(bx>>>16)؊=L/\(bx&&&0xFFFF)؊=H:=by constructor . rw[˲,show(16:┟)؊%32=16 from rfl,©,h];omega . rw[٭,show(0xFFFF:┟)؊=2^16-1 from rfl,˕,h];omega lemma B5 (X W b:┠ ┢) (inW i j:Nat):Yai X W b inW 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 Yai;rw[Zi] lemma Zp (A:┠ ┢) (inW i:Nat) (h1:i*inW+inW<=A.size) (h2:i*inW+inW<=4294967295) : ∃ L H:Nat,(Yc A inW i)؊=L*2^16+H/\L<=511/\H<=255 /\ ∀ t,t < inW -> L<=YR A[i*inW+t]! /\ YM A[i*inW+t]! <= H:=by have h0:(i*inW)؝܆=i*inW:=Za _ ܉;have h3:inW؝܆=inW:=Za _ ܉;unfold Yc;rw[dif_pos ⟨h1,by omega⟩];obtain⟨L,H,e,hL,hH,-,-,h4⟩:=T0 A (i*inW)؝ inW؝ (by rw[h0,h3];exact h1) (by rw[h0,h3];have:=˖;omega) 511 0 0 ܋ ܌ ܌ refine⟨L,H,e,hL,hH,λ t ht=>?_⟩;have:=h4 t ܋ (by rw[h3];exact ht);rwa[h0]at this lemma A2 (S:Int) (lo:┞) (c:┣) (FB D:┢) (hf:S=0 -> FB=D) (hb:D=┒ (S*2^lo˗) (-298) c) : (if (if S=0 then 4294967296 else (┒ S ((lo˗:Int)-298) false)׆)<4294967296 then (if S=0 then 4294967296 else (┒ S ((lo˗:Int)-298) false)׆)؉ else FB)=D:=by by_cases h4:S=0 . rw[if_pos h4,if_neg ܌,hf h4] . rw[if_neg h4];have ha:(┒ S ((lo˗:Int)-298) false)׆<4294967296:=by rw[˃];simpa using ՟ (┒ S ((lo˗:Int)-298) false) rw[if_pos ha,hb,<- ┉];have e1:(┒ S ((lo˗:Int)-298) false)׆؉=┒ S ((lo˗:Int)-298) false:=by apply ˅;simp rw[e1];unfold finishWord;rw[if_neg h4,if_neg h4,show(-298:Int)+(lo˗:Int)=(lo˗:Int)-298 by ring] lemma C2 (u p:┞) (c4:¬u122):p˗<=u˗/\u˗-p˗<=122:=by rw[˃]at c4;have d4:p˗<=u˗:=܉ rw[gt_iff_lt,˃,§ _ _ (⠃ d4)]at c5;exact⟨d4,Nat.not_lt.mp c5⟩ lemma E2 {L r i:Nat} (h1:L<=r) (h2:r<=i+1):L-1<=i:=܉ lemma E1 {m H i:Nat} (h1:m<=H) (h2:i+1<=max m 1):i<=H-1:=܉ lemma ZQ {p u a b c d B:Nat} {x w:┢} (wl:p<=(a-1)+(b-1)) (wh:(c-1)+(d-1)<=u) (d5:u-p<=B) (r1:a<=YR x/\YM x<=c) (r2:b<=YR w/\YM w<=d) (hm:mantOf x*mantOf w≠0):p<=idxOf x+idxOf w/\idxOf x+idxOf w<=p+B:= have k1:=(Zb x).2.2.2 (left_ne_zero_of_mul hm);have k2:=(Zb w).2.2.2 (right_ne_zero_of_mul hm);⟨wl.trans (Nat.add_le_add (E2 r1.1 k1.1) (E2 r2.1 k2.1)),(Nat.add_le_add (E1 r1.2 k1.2) (E1 r2.2 k2.2)).trans (wh.trans (Nat.sub_le_iff_le_add'.mp d5))⟩ lemma L0 (x y:FloatLib.Numerics.Dyadic) (h:(┙ x y).significand=0) : (┙ x y).negative=(x.negative&&y.negative):=by unfold Model.addDyadic FloatLib.Numerics.Dyadic.add FloatLib.Numerics.Dyadic.addFields at h ⊢;dsimp only at h ⊢;split_ifs at h ⊢<;>simp_all lemma K9 (d:FloatLib.Numerics.Dyadic) (h:d.significand=0):Model.roundDyadic Fmt d=Model.zero Fmt d.negative:=by rw[Model.roundDyadic_eq_roundDyadicImpl];unfold Model.roundDyadicImpl;rw[if_pos ܌];unfold Model.ieeeRoundDyadicImpl;rw[if_pos (by simp[h])];cases d.negative<;>rfl lemma ZN (k:Nat):(2:ℚ)^((k:ℤ)-149)=2^k*2^(-149:ℤ):=by rw[sub_eq_add_neg,zpow_add₀ two_ne_zero,┄] lemma D5:(2:ℚ)^(-149:ℤ)*2^(-149:ℤ)=2^(-298:ℤ):=by rw[<- zpow_add₀ two_ne_zero];norm_num lemma W7 (a b:┢) (ha:expOf a≠255) (hb:expOf b≠255):toWord (Model.add (ofW a) (ofW b))=┒ (sv a*2^idxOf a+sv b*2^idxOf b) (-149) (signOf a&&signOf b):=by rw[Model.Proof.add_eq_spec];simp only[Model.Spec.add,ofW,┅ a ha,┅ b hb];have h0:(┙ (┝ a) (┝ b)).toRat=((sv a*2^idxOf a+sv b*2^idxOf b:Int):ℚ)*2^(-149:ℤ):=by rw[Model.addDyadic,FloatLib.Numerics.Dyadic.add_toRat,┇,┇,ZN,ZN];push_cast;ring by_cases hS:sv a*2^idxOf a+sv b*2^idxOf b=0 . have hz:(┙ (┝ a) (┝ b)).significand=0:=߹ rw[K9 _ hz,L0 _ _ hz,┌,┌,hS,finishWord_zero] . exact(finishWord_of_ne _ _ _ _ hS h0).symm lemma K8 (x y z:┢) (hx:expOf x≠255) (hy:expOf y≠255) (hz:expOf z≠255):toWord (Model.fma (ofW x) (ofW y) (ofW z))=┒ (sv x*sv y*2^(idxOf x+idxOf y)+sv z*2^(idxOf z+149)) (-298) (˷ (signOf x) (signOf y)&&signOf z):=by rw[Model.Proof.fma_eq_spec];have h2:=┅ x hx;have h1:=┅ y hy;have h0:=┅ z hz;have h5:Model.chooseNaN3 (Model.ofUInt32 x:Model Fmt) (Model.ofUInt32 y) (Model.ofUInt32 z)=none := (Model.chooseNaN3_eq_none_iff _ _ _).2 ⟨Model.isNaN_eq_false_of_toDyadic?_some h2,Model.isNaN_eq_false_of_toDyadic?_some h1,Model.isNaN_eq_false_of_toDyadic?_some h0⟩ simp only[Model.Spec.fma,ofW,h5,Model.isInf_eq_false_of_toDyadic?_some h2,Model.isInf_eq_false_of_toDyadic?_some h1,Model.isInf_eq_false_of_toDyadic?_some h0, Bool.or_false,¥,│,h2,h1,h0] set P:FloatLib.Numerics.Dyadic := { negative:=˷ (┝ x).negative (┝ y).negative significand:=(┝ x).significand*(┝ y).significand exponent:=(┝ x).exponent+(┝ y).exponent } with hP have h6:(┙ P (┝ z)).toRat=((sv x*sv y*2^(idxOf x+idxOf y)+sv z*2^(idxOf z+149):Int):ℚ)*2^(-298:ℤ):=by have hm:=FloatLib.Numerics.Dyadic.mul_toRat (┝ x) (┝ y);simp only[FloatLib.Numerics.Dyadic.mul,FloatLib.Numerics.Dyadic.mulFields]at hm;rw[Model.addDyadic,FloatLib.Numerics.Dyadic.add_toRat,hP,hm,┇,┇,┇,ZN,ZN,ZN,<- D5] have h4:(2:ℚ)^(idxOf z+149)*2^(-298:ℤ)=2^idxOf z*2^(-149:ℤ):=by rw[pow_add,<- D5,mul_assoc] norm_num push_cast;rw[<- D5]at h4;linear_combination (sv z:ℚ)*h4 by_cases hS:sv x*sv y*2^(idxOf x+idxOf y)+sv z*2^(idxOf z+149)=0 . have h3:(┙ P (┝ z)).significand=0:=߹ rw[K9 _ h3,L0 _ _ h3,hP];rw[┌,┌,┌,hS,finishWord_zero] . exact(finishWord_of_ne _ _ _ _ hS h6).symm lemma K7 (j:Nat) (hj:j<=6):expOf (natW (2^j))≠255/\signOf (natW (2^j))=false /\ mantOf (natW (2^j))=2^23/\idxOf (natW (2^j))=126+j:=by interval_cases j<;>decide lemma D4 (w:┟):signOf w=decide (2^31<=w؊):=by have h0:=w.toNat_lt_size;have h:(w&&&߾)؊=2^31*(w؊/2^31%2):=by rw[٭,show(߾:┟)؊=2^31 from rfl,Nat.and_two_pow,Nat.testBit_eq_decide_div_mod_eq] have hq:w؊/2^31%2<2:=˵ _ ܊;generalize w؊/2^31%2=q at hq ⊢;interval_cases q<;>rfl unfold signOf;rw[؆];simp;rw[<- UInt32.toNat_inj,h,show(0:┟)؊=0 from rfl];simp only[UInt32.size]at h0;omega lemma W6 (s:┢) (j:Nat) (hj:j<=6) (hn:j < (expOf s)؊):(expOf (s-(׃ j<<<23)))؊=(expOf s)؊-j /\ fracOf (s-(׃ j<<<23))=fracOf s /\ signOf (s-(׃ j<<<23))=signOf s:=by rw[ZH]at hn;have ht:(׃ j<<<23)؊=j*2^23:=by rw[UInt32.toNat_shiftLeft,UInt32.toNat_ofNat',®,show(23:┟)؊%32=23 from rfl,¡ (by omega:j<2^32)] exact ¡ ܉ have h0:׃ j<<<23<=s:=by rw[⠍,ht];omega have hr:(s-(׃ j<<<23))؊=s؊-j*2^23:=߹ refine⟨?_,?_,?_⟩ . rw[ZH,ZH,hr];omega . apply ˅;rw[ZR,ZR,hr];omega . rw[D4,D4,hr];simp;omega lemma ZX (w:┢) (hw:expOf w≠255):┛ (ofW w)=(sv w:ℝ)*2^((idxOf w:ℤ)-149):=by rw[Model.toReal_eq];simp only[ofW,┅ w hw];rw[<- FloatLib.Numerics.Dyadic.cast_toRat,┇];push_cast;rfl lemma W5 (s y:┢) (j:Nat) (hj:j<=6) (hs:expOf s≠255) (hn:j < (expOf s)؊) (h0:expOf y≠255) (hl:signOf y=false) (h9:mantOf y=2^23) (hi:idxOf y=126+j) : toWord (Model.div (ofW s) (ofW y))=s-(׃ j<<<23):=by have hh:sv y=2^23:=by unfold sv;rw[hl,h9];rfl have hm:Model.isZero (ofW y)=false:=by rw[ofW,Model.isZero_eq_beq_zero_of_toDyadic?_some (┅ y h0),decodeD_sig_zero,h9];decide obtain⟨he,hf,ho⟩:=W6 s j hj hn;set r:=s-(׃ j<<<23) with hr;have hu:=expOf_toNat_lt s;have h5:expOf r≠255:=by intro h;have h2:=congrArg UInt32.toNat h;simp at h2;have hv:(expOf s)؊≠255:=λ h'=>hs (˅ (by simpa using h'));omega have h3:expOf r≠0:=by intro h;have h2:=congrArg UInt32.toNat h;simp at h2;omega have h6:expOf s≠0:=by intro h;rw[h]at hn;simp at hn have hp:sv r=sv s:=by unfold sv mantOf;rw[ho,hf,if_neg h3,if_neg h6] have ht:(idxOf r:ℤ)=(idxOf s:ℤ)-j:=by unfold idxOf;rw[if_neg h3,if_neg h6,he];omega have h1:Model.isFinite (ofW s)=true:=by simp[ofW,┋,hs] have hc:Model.isFinite (ofW y)=true:=by simp[ofW,┋,h0] have h8:Model.isFinite (ofW r)=true:=by simp[ofW,┋,h5] have ha:Model.isZero (ofW y)=false:=hm;have h7:┛ (ofW y)=2^j:=by rw[ZX _ h0,hh,hi];push_cast;rw[show((126:ℤ)+j-149)=(j:ℤ)+(-23) by ring,zpow_add₀ two_ne_zero,┄] field_simp;norm_num have hg:┛ (ofW r)=┛ (ofW s)/2^j:=by rw[ZX _ h5,ZX _ hs,hp,ht,show((idxOf s:ℤ)-j-149)=((idxOf s:ℤ)-149) + -(j:ℤ) by ring,zpow_add₀ two_ne_zero,zpow_neg,┄] field_simp have hb : |┛ (ofW s)/┛ (ofW y)| <= ┛ (Model.posMaxFinite Fmt):=by rw[h7,abs_div,abs_of_pos (by positivity:(0:ℝ)<2^j)] calc |┛ (ofW s)| / 2^j <= |┛ (ofW s)| := div_le_self (abs_nonneg _) (one_le_pow₀ ܊) _<=_:=Model.abs_toReal_le_posMaxFinite_of_isIEEE_of_isFinite _ ܌ h1 have hd:Model.isFinite (Model.div (ofW s) (ofW y))=true:=Model.isFinite_div_of_abs_div_le_posMaxFinite _ _ ܌ h1 hc ha hb have h4:=Model.toReal_div_eq_roundAt _ _ ܌ h1 hc ha hd;rw[h7,<- hg,Model.roundAt_toReal_eq _ h8]at h4;have hq:┛ (Model.div (ofW s) (ofW y))≠0:=by rw[h4,ZX _ h5];apply mul_ne_zero _ (zpow_ne_zero _ two_ne_zero);have:sv r≠0:=by unfold sv mantOf;split<;>omega exact_mod_cast this have hk:=Model.eq_of_toReal_eq_of_nonzero hd h8 h4 hq;rw[hk,M8] lemma W4 (s:┢) (j:Nat) (hj:j<=6) (hs:expOf s≠255) (hn:j < (expOf s)؊) : toWord (Model.div (ofW s) (ofW (natW (2^j))))=s-(׃ j<<<23):=by obtain⟨h1,h2,h3,h4⟩:=K7 j hj;exact W5 s _ j hj hs hn h1 h2 h3 h4 lemma W3 (s y:┢) (h2:expOf s=0) (h3:fracOf s=0) (h9:expOf y≠255) (ha:signOf y=false) (h6:mantOf y≠0) : toWord (Model.div (ofW s) (ofW y))=s:=by have hs:expOf s≠255:=߷ rw[Model.Proof.div_eq_spec];simp only[Model.Spec.div,ofW,┅ s hs,┅ _ h9];have h7:┝ s=⟨signOf s,0,0⟩:=by simp[decodeD,h2,h3] have h8:((┝ y).significand==0)=false:=by rw[decodeD_sig_zero];simp[h6] rw[h7,h8,┌,ha];have h5:=s.toNat_lt_size;simp only[UInt32.size]at h5;have he:=ZH s;have hf:=ZR s;rw[h2]at he;rw[h3]at hf;simp at he hf;have h1:=D4 s;cases h4:signOf s . rw[h4]at h1;have:s؊<2^31:=by simpa using h1.symm have h0:s=0:=˅ ߶ rw[h0];rfl . rw[h4]at h1;have:2^31<=s؊:=by simpa using h1.symm have h0:s=߾:=˅ ߶ rw[h0];rfl lemma W1 (s:┢) (j:Nat) (hj:j<=6) (h0:expOf s=0) (h4:fracOf s=0) : toWord (Model.div (ofW s) (ofW (natW (2^j))))=s:=by obtain⟨h1,h2,h3,-⟩:=K7 j hj;exact W3 s _ h0 h4 h1 h2 (by rw[h3];norm_num) @[inline] def Yl (w:┢):┞ := if expOf w=0 then (fracOf w).toUInt64 else (fracOf w).toUInt64+0x800000 lemma Zs (w:┢):(Yl w)˗=mantOf w:=by have hf:=fracOf_toNat_lt w;unfold Yl mantOf;split . simp . rw[¤,՝,show(0x800000:┞)˗=2^23 from rfl,¡ ܉] omega lemma W0 (m:┞) (neg:┣) (hm:m˗<2^63):Ym (if neg then 0-m else m)=if neg then -(m˗:Int) else (m˗:Int):=by cases neg . simp only[¥,│,Ym];rw[if_pos hm];simp . simp only[━,Ym];rw[˰,show(0:┞)˗=0 from rfl];by_cases h0:m˗=0 . rw[h0];norm_num . have h1:(2^64-m˗+0)%2^64=2^64-m˗:=܉ omega lemma K6 (x y:┞) (h1 : -2^63<=Ym x+Ym y) (h2:Ym x+Ym y<2^63):Ym (x+y)=Ym x+Ym y:=by unfold Ym at h1 h2 ⊢;rw[¤];split_ifs at h1 h2 ⊢<;>omega lemma V9 (m:┞) (d:Nat) (hd:d<64) (h:m˗*2^d<2^64):(m<<simp[h] lemma ZY (m:┞) (d:Nat) (neg:┣) (hd:d<64) (h:m˗*2^d<2^62) : Ym (if neg then 0-(m<<simp[Nat.cast_mul,Nat.cast_pow] lemma D3 (w:┢):(if signOf w then -((Yl w)˗:Int) else ((Yl w)˗:Int))=sv w:=by rw[Zs];rfl lemma ZO:sv oneW=2^23/\idxOf oneW=126:=܌ lemma N9 (a b:┢) (e:Nat) (h:mantOf a*mantOf b≠0 -> e<128) : -2^175constructor<;>linarith lemma V7 (S e:Int) (n1 n2:┣) (h:S≠0):┒ S e n1=┒ S e n2:=by simp[finishWord,h] lemma V6 (m1 m2 p q:┞):(m1≠0 -> (if m1=0 then q else if m2=0 then p else if p<=q then p else q)<=p) /\ (m2≠0 -> (if m1=0 then q else if m2=0 then p else if p<=q then p else q)<=q):=߷ @[inline] def Yal (a b c d:┢) (nz:┣) (slow:Unit -> ┢):┢ := let p:=Yd a+Yd b let q:=Yd c+Yd d let m1:=Yf a*Yf b let m2:=Yf c*Yf d let lo:=if m1=0 then q else if m2=0 then p else if p<=q then p else q if (m1=0\/p-lo<128)/\(m2=0\/q-lo<128) then YL lo a b 0 0 0 0 λ w2 w1 w0 k => YL lo c d w2 w1 w0 k λ v2 v1 v0 k' => let r:=YD v2 v1 v0 k' ((lo.toNat:Int)-298) if r=0x100000000 then (if nz then 0x80000000 else 0) else r.toUInt32 else slow () lemma G9 (a b:┢) (lo:┞) (hp:(Yd a+Yd b)˗=idxOf a+idxOf b) (z:Yf a*Yf b=0↔mantOf a*mantOf b=0) (L:Yf a*Yf b≠0 -> lo<=Yd a+Yd b) (h6:Yf a*Yf b=0\/Yd a+Yd b-lo<128) : mantOf a*mantOf b≠0 -> lo˗<=idxOf a+idxOf b/\idxOf a+idxOf bh0 (z.mp h);have h3:=L hm;have h1:Yd a+Yd b-lo<128:=h6.resolve_left hm rw[¿,hp]at h3;rw[˃,§ _ _ (L hm),hp]at h1;simp at h1;omega lemma N8 (a b c d:┢) (nz:┣) (slow:Unit -> ┢) (h9:slow ()=┒ (sv a*sv b*2^(idxOf a+idxOf b)+sv c*sv d*2^(idxOf c+idxOf d)) (-298) nz) : Yal a b c d nz slow=┒ (sv a*sv b*2^(idxOf a+idxOf b)+sv c*sv d*2^(idxOf c+idxOf d)) (-298) nz:=by unfold Yal;dsimp only;have ia:=Zg a;have ib:=Zg b;have ic:=Zg c;have id:=Zg d;have hp:=C1 a b have hq:=C1 c d have hc:=B3 a b have hd:=B3 c d have z1:=G5 a b have z2:=G5 c d obtain⟨L1,L2⟩:=V6 (Yf a*Yf b) (Yf c*Yf d) (Yd a+Yd b) (Yd c+Yd d) generalize hg:(if Yf a*Yf b=0 then Yd c+Yd d else if Yf c*Yf d=0 then Yd a+Yd b else if Yd a+Yd b<=Yd c+Yd d then Yd a+Yd b else Yd c+Yd d)=lo at L1 L2 ⊢ split . rename_i h6;have F1:=G9 a b lo hp z1 L1 h6.1;have F2:=G9 c d lo hq z2 L2 h6.2 obtain⟨w2,w1,w0,k,e1,hk,hv⟩:=Zr lo a b 0 0 0 0 (λ w2 w1 w0 k=>YL lo c d w2 w1 w0 k λ v2 v1 v0 k'=>let r:=YD v2 v1 v0 k' ((lo˗:Int)-298);if r=߿ then (if nz then (߾:┟) else 0) else r؉) ܋ F1 rw[e1];obtain⟨v2,v1,v0,k',e2,hf,h8⟩:=Zr lo c d w2 w1 w0 k (λ v2 v1 v0 k'=>let r:=YD v2 v1 v0 k' ((lo˗:Int)-298);if r=߿ then (if nz then (߾:┟) else 0) else r؉) (by simp at hk;omega) F2 rw[e2];have h5:=N9 a b (idxOf a+idxOf b-lo˗) (λ h0=>by omega) have h4:=N9 c d (idxOf c+idxOf d-lo˗) (λ h0=>by omega) have ha:Yx 0 0 0=0:=rfl;rw[ha,show(0:┞)˗=0 from rfl]at hv;have hb:((Yx v2 v1 v0+k'˗:Nat):Int)%2^192=(sv a*sv b*2^(idxOf a+idxOf b-lo˗)+sv c*sv d*2^(idxOf c+idxOf d-lo˗))%2^192:=by rw[h8];rw[։,hv,<- ։];simp rw[ZV v2 v1 v0 k' _ _ (by linarith [h5.1,h4.1]) (by linarith [h5.2,h4.2]) hb];have hS:sv a*sv b*2^(idxOf a+idxOf b)+sv c*sv d*2^(idxOf c+idxOf d)=(sv a*sv b*2^(idxOf a+idxOf b-lo˗)+sv c*sv d*2^(idxOf c+idxOf d-lo˗))*2^lo˗:=by have e1:=ZC (sv a*sv b) (idxOf a+idxOf b) lo˗ (by by_cases h0:mantOf a*mantOf b=0 . left;rw[<- Zn,h0];simp . right;exact(F1 h0).1) have e2:=ZC (sv c*sv d) (idxOf c+idxOf d) lo˗ (by by_cases h0:mantOf c*mantOf d=0 . left;rw[<- Zn,h0];simp . right;exact(F2 h0).1) rw[e1,e2];ring by_cases hz:sv a*sv b*2^(idxOf a+idxOf b-lo˗)+sv c*sv d*2^(idxOf c+idxOf d-lo˗)=0 . rw[if_pos hz,if_pos rfl,hS,hz,zero_mul];cases nz<;>rfl . rw[if_neg hz];have h7:(┒ (sv a*sv b*2^(idxOf a+idxOf b-lo˗)+sv c*sv d*2^(idxOf c+idxOf d-lo˗)) ((lo˗:Int)-298) false)׆ ≠߿:=by intro h;have h2:=congrArg ܄ h;have:=՟ (┒ (sv a*sv b*2^(idxOf a+idxOf b-lo˗)+sv c*sv d*2^(idxOf c+idxOf d-lo˗)) ((lo˗:Int)-298) false) simp only[UInt32.size]at this;simp at h2;omega rw[if_neg h7,UInt32.toUInt32_toUInt64,hS,show((lo˗:Int)-298) = -298+(lo˗:Int) by ring,┉] apply V7;intro h;apply hz;have he:(2:Int)^lo˗≠0:=pow_ne_zero _ two_ne_zero;exact(mul_eq_zero.mp h).resolve_right he . exact h9 @[inline] def Y1 (ma mb:┞) (ia ib:Nat):Nat := if ma=0 then ib else if mb=0 then ia else min ia ib lemma N7 (ma mb:┞) (ia ib:Nat):(ma=0\/Y1 ma mb ia ib<=ia)/\(mb=0\/Y1 ma mb ia ib<=ib):=by unfold Y1;refine⟨?_,?_⟩<;>split_ifs<;>first | (left;assumption) | (right;omega) @[inline] def YaW (sa:┣) (ma:┞) (ia:Nat) (sb:┣) (mb:┞) (ib:Nat) (sh:Int) (nz:┣) (slow:Unit -> ┢):┢ := let k:=Y1 ma mb ia ib let da:=ia-k let db:=ib-k if da<=38/\db<=38 then let ta:=ma<< ┢) (h5:ma˗<2^24) (h0:mb˗<2^24) (h6:slow ()=┒ ((if sa then -(ma˗:Int) else ma˗)*2^ia+(if sb then -(mb˗:Int) else mb˗)*2^ib) sh nz) : YaW sa ma ia sb mb ib sh nz slow=┒ ((if sa then -(ma˗:Int) else ma˗)*2^ia+(if sb then -(mb˗:Int) else mb˗)*2^ib) sh nz:=by have Zc8:∀ (m:┞) (d:Nat),m˗<2^24 -> d<=38 -> m˗*2^d<2^62:=λ m d h hd=>calc m˗*2^d<2^24*2^38:=⠌ h (˂ ܊ hd) ܍ _=2^62:=܊ unfold YaW;dsimp only;split . rename_i hd;obtain⟨h8,h7⟩:=N7 ma mb ia ib;set k:=Y1 ma mb ia ib;have g1:=Zc8 ma _ h5 hd.1;have g2:=Zc8 mb _ h0 hd.2;have hA:=ZY ma (ia-k) sa (by omega -splitDisjunctions) g1 have hB:=ZY mb (ib-k) sb (by omega -splitDisjunctions) g2 rw[D9,K6 _ _ ?_ ?_,hA,hB] . rw[show((k:Int)+sh)=sh+(k:Int) by ring,┉];have e1:=ZC (if sa then -(ma˗:Int) else ma˗) ia k (by rcases h8 with h | h . left;subst h;simp . right;exact h) have e2:=ZC (if sb then -(mb˗:Int) else mb˗) ib k (by rcases h7 with h | h . left;subst h;simp . right;exact h) rw[e1,e2];ring all_goals rw[hA,hB];have h1:(ma˗*2^(ia-k):Int)<2^62:=by exact_mod_cast g1 have h2:(mb˗*2^(ib-k):Int)<2^62:=by exact_mod_cast g2 have h3:(0:Int)<=ma˗*2^(ia-k):=܋ have h4:(0:Int)<=mb˗*2^(ib-k):=܋ cases sa<;>cases sb<;>simp<;>linarith . exact h6 @[inline] def YaX (a b:┢):┢ := if expOf a=255\/expOf b=255 then toWord (Model.add (ofW a) (ofW b)) else YaW (signOf a) (Yl a) (idxOf a) (signOf b) (Yl b) (idxOf b) (-149) (signOf a&&signOf b) (λ _=>Yal a oneW b oneW (signOf a&&signOf b) (λ _=>toWord (Model.add (ofW a) (ofW b)))) lemma V4 (a b:┢):YaX a b=toWord (Model.add (ofW a) (ofW b)):=by unfold YaX;split . rfl . rename_i h;have ha:expOf a≠255:=λ h'=>h (Or.inl h');have hb:expOf b≠255:=λ h'=>h (Or.inr h');have hS:=W7 a b ha hb;have h2:toWord (Model.add (ofW a) (ofW b))=┒ (sv a*sv oneW*2^(idxOf a+idxOf oneW)+sv b*sv oneW*2^(idxOf b+idxOf oneW)) (-298) (signOf a&&signOf b):=by rw[hS,ZO.1,ZO.2,show(-149:Int) = -298+((149:Nat):Int) by norm_num,┉] congr 1;ring have hT:Yal a oneW b oneW (signOf a&&signOf b) (λ _=>toWord (Model.add (ofW a) (ofW b)))=toWord (Model.add (ofW a) (ofW b)):=by rw[N8 _ _ _ _ _ _ h2,h2] rw[<- D3 a,<- D3 b]at hS;rw[V5 _ _ _ _ _ _ _ _ _ (by rw[Zs];exact ┊ a) (by rw[Zs];exact ┊ b) (by rw[hT];exact hS),hS] @[inline] def YaY (x y z:┢):┢ := if expOf x=255\/expOf y=255\/expOf z=255 then toWord (Model.fma (ofW x) (ofW y) (ofW z)) else let mp:=Yl x*Yl y let mz:=Yl z let p:=idxOf x+idxOf y let q:=idxOf z+149 let k:=Y1 mp mz p q let dp:=p-k let dq:=q-k if dp<=14/\dq<=38 then let neg:=Bool.xor (signOf x) (signOf y) let tp:=mp<<toWord (Model.fma (ofW x) (ofW y) (ofW z))) lemma V3 (x y z:┢):YaY x y z=toWord (Model.fma (ofW x) (ofW y) (ofW z)):=by unfold YaY;split . rfl . rename_i h;have hx:expOf x≠255:=λ h'=>h (Or.inl h');have hy:expOf y≠255:=λ h'=>h (Or.inr (Or.inl h'));have hz:expOf z≠255:=λ h'=>h (Or.inr (Or.inr h'));dsimp only;split . rename_i hd;rw[K8 x y z hx hy hz];have hm:(Yl x*Yl y)˗=mantOf x*mantOf y:=by rw[٫,Zs,Zs];exact ¡ (mul_mant_lt x y) have h8:(Yl x*Yl y)˗<2^48:=by rw[hm];calc mantOf x*mantOf y<2^24*2^24:=Nat.mul_lt_mul'' (┊ x) (┊ y) _=2^48:=܊ have h4:(Yl z)˗<2^24:=by rw[Zs];exact ┊ z obtain⟨h9,h5⟩:=N7 (Yl x*Yl y) (Yl z) (idxOf x+idxOf y) (idxOf z+149);set k:=Y1 (Yl x*Yl y) (Yl z) (idxOf x+idxOf y) (idxOf z+149);set mp:=Yl x*Yl y;have bP:mp˗*2^(idxOf x+idxOf y-k)<2^62:=calc mp˗*2^(idxOf x+idxOf y-k)<2^48*2^14:=⠌ h8 (˂ ܊ hd.1) ܍ _=2^62:=܊ have bQ:(Yl z)˗*2^(idxOf z+149-k)<2^62:=calc (Yl z)˗*2^(idxOf z+149-k)<2^24*2^38:=⠌ h4 (˂ ܊ hd.2) ܍ _=2^62:=܊ have hA:=ZY mp (idxOf x+idxOf y-k) (˷ (signOf x) (signOf y)) ܉ bP have hB:=ZY (Yl z) (idxOf z+149-k) (signOf z) ܉ bQ;have hP:(if ˷ (signOf x) (signOf y) then -(mp˗:Int) else (mp˗:Int))=sv x*sv y:=by rw[hm,Zn] have hZ:(if signOf z then -((Yl z)˗:Int) else ((Yl z)˗:Int))=sv z:=D3 z;rw[hP]at hA;rw[hZ]at hB;have c1:(0:Int)<=mp˗*2^(idxOf x+idxOf y-k):=܋ have c2:(0:Int)<=(Yl z)˗*2^(idxOf z+149-k):=܋ have h1:(sv x*sv y)*2^(idxOf x+idxOf y-k)=(if ˷ (signOf x) (signOf y) then -(mp˗:Int) else (mp˗:Int))*2^(idxOf x+idxOf y-k):=by rw[hP] have h3:sv z*2^(idxOf z+149-k)=(if signOf z then -((Yl z)˗:Int) else ((Yl z)˗:Int))*2^(idxOf z+149-k):=by rw[hZ] have h7 : -2^63<=sv x*sv y*2^(idxOf x+idxOf y-k)+sv z*2^(idxOf z+149-k):=by rw[h1,h3];cases ˷ (signOf x) (signOf y)<;>cases signOf z<;>simp<;>linarith have h6:sv x*sv y*2^(idxOf x+idxOf y-k)+sv z*2^(idxOf z+149-k)<2^63:=by rw[h1,h3];cases ˷ (signOf x) (signOf y)<;>cases signOf z<;>simp<;>linarith rw[D9,K6 _ _ (by rw[hA,hB];exact h7) (by rw[hA,hB];exact h6),hA,hB,show((k:Int)-298) = -298+(k:Int) by ring,┉] have e1:=ZC (sv x*sv y) (idxOf x+idxOf y) k (by rcases h9 with h0 | h0 . left;have:mantOf x*mantOf y=0:=by rw[<- hm,h0];rfl rw[<- Zn,this];simp . right;exact h0) have e2:=ZC (sv z) (idxOf z+149) k (by rcases h5 with h0 | h0 . left;have:mantOf z=0:=by rw[<- Zs];simp[h0] exact V8 z this . right;exact h0) rw[e1,e2];ring . have hF:=K8 x y z hx hy hz;have h2:toWord (Model.fma (ofW x) (ofW y) (ofW z))=┒ (sv x*sv y*2^(idxOf x+idxOf y)+sv z*sv oneW*2^(idxOf z+idxOf oneW)) (-298) (˷ (signOf x) (signOf y)&&signOf z):=by rw[hF,ZO.1,ZO.2];ring rw[N8 _ _ _ _ _ _ h2,h2] @[inline] def YaA (j:Nat) (s:┢):┢ := if expOf s≠255/\j < (expOf s).toNat then s-(UInt32.ofNat j<<<23) else if expOf s=0/\fracOf s=0 then s else toWord (Model.div (ofW s) (ofW (natW (2^j)))) lemma N6 (j:Nat) (hj:j<=6) (s:┢):YaA j s=toWord (Model.div (ofW s) (ofW (natW (2^j)))):=by unfold YaA;split . rename_i h;exact(W4 s j hj h.1 h.2).symm . split . rename_i h2;exact(W1 s j hj h2.1 h2.2).symm . rfl @[inline] def YaB (kk:Nat) (s:┢):┢ := if kk=4 then YaA 2 s else if kk=64 then YaA 6 s else toWord (Model.div (ofW s) (ofW (natW kk))) lemma N5 (kk:Nat) (s:┢):YaB kk s=toWord (Model.div (ofW s) (ofW (natW kk))):=by unfold YaB;split . rename_i h;subst h;exact N6 2 ܊ s . split . rename_i h;subst h;exact N6 6 ܊ s . rfl def YaZ (c h w k:Nat) (inp:┠ ┢):┠ ┢ := Array.ofFn (n:=c*(h/k*(w/k))) λ q => let ch:=q.val/(h/k*(w/k)) let y:=q.val/(w/k)%(h/k) let x:=q.val%(w/k) YaB (k*k) (Yn (k*k) (poolAt h w k inp ch y x) (λ _=>oneW)) lemma V2:YaZ=avgpoolSpec:=by funext c h w k inp;simp only[YaZ,avgpoolSpec,avgpoolWith,N5,Zi] @[specialize] def YE (n:┡) (fx fw:(t:┡) -> t ┢) (lo:┞) (e:Int) (bx bw:┟) (w2 w1 w0 c:┞) (k:┡):┞ := if h:k YE n fx fw lo e bx bw v2 v1 v0 c' (k+1) else YL lo bx bw w2 w1 w0 c λ v2 v1 v0 c'=>YD v2 v1 v0 c' e termination_by n.toNat-k.toNat decreasing_by exact ZI n k h def Yr (fa fb:Nat -> ┢) (lo k:Nat):Nat -> Int | 0=>0 | r+1=>sv (fa k)*sv (fb k)*2^(idxOf (fa k)+idxOf (fb k)-lo)+Yr fa fb lo (k+1) r lemma E0 (n:┡) (fx fw:(t:┡) -> t ┢) (Yi fwN:Nat -> ┢) (h9:∀ t h,fx t h=Yi t܆) (he:∀ t h,fw t h=fwN t܆) (lo:┞) (e:Int) (bx bw:┟) (hn:n܆<2^32) (hb:mantOf bx*mantOf bw≠0 -> lo˗<=idxOf bx+idxOf bw/\idxOf bx+idxOf bw k܆<=n܆ -> c˗<=k܆ -> (∀ t,k܆<=t -> t mantOf (Yi t)*mantOf (fwN t)≠0 -> lo˗<=idxOf (Yi t)+idxOf (fwN t)/\idxOf (Yi t)+idxOf (fwN t) ((Yx w2 w1 w0+c˗:Nat):Int)%2^192=S0%2^192 -> S=S0+Yr Yi fwN lo˗ k܆ (n܆-k܆)+sv bx*sv bw*2^(idxOf bx+idxOf bw-lo˗) -> -2^191<=S -> S<2^191 -> YE n fx fw lo e bx bw w2 w1 w0 c k=if S=0 then ߿ else (┒ S e false)׆:=by intro d;induction d with | zero => intro k w2 w1 w0 c S0 S hd hk hc h5 hv hS h6 h7;have h0:¬ kYD v2 v1 v0 c' e) ܉ hb rw[h3];apply ZV v2 v1 v0 c' e S h6 h7;rw[h4,hS,show n܆-k܆=0 by omega,Yr];omega | succ d ih => intro k w2 w1 w0 c S0 S hd hk hc h5 hv hS h6 h7;have h0:kYE n fx fw lo e bx bw v2 v1 v0 c' (k+1)) ܉ (h5 k܆ (le_refl _) ܉) rw[h3];refine ih (k+1) v2 v1 v0 c' (S0+sv (Yi k܆)*sv (fwN k܆)*2^(idxOf (Yi k܆)+idxOf (fwN k܆)-lo˗)) S ܉ ܉ ܉ (λ t h1 h2=>h5 t ܉ h2) ?_ ?_ h6 h7 . rw[h4];omega . rw[hS,show n܆-k܆=(n܆-(k+1)܆)+1 by omega,Yr,h8];ring lemma B4 (fa fb:Nat -> ┢) (lo:Nat):∀ (r k:Nat),(∀ t,k<=t -> t mantOf (fa t)*mantOf (fb t)≠0 -> lo<=idxOf (fa t)+idxOf (fb t)/\idxOf (fa t)+idxOf (fb t)<=lo+122) -> -((r:Int)*2^170)<=Yr fa fb lo k r/\Yr fa fb lo k r<=(r:Int)*2^170:=by intro r;induction r with | zero=>intro k _;simp[Yr] | succ r ih=>intro k h;obtain⟨a1,a2⟩:=ZL (fa k) (fb k) lo (h k (le_refl _) ܉);obtain⟨b1,b2⟩:=ih (k+1) (λ t h1 h2=>h t ܉ ܉);rw[Yr];push_cast;constructor<;>linarith lemma N4 (fa fb:Nat -> ┢) (K lo:Nat) (bx bw:┟):∀ r k,k+r<=K -> (∀ t,k<=t -> t mantOf (fa t)*mantOf (fb t)≠0 -> lo<=idxOf (fa t)+idxOf (fb t)) -> Yo (λ t=>if tif tintro k _ _;simp[Yo,Yr] | succ r ih=>intro k hk h;rw[Yo,Yr,ih (k+1) ܉ (λ t h1 h2=>h t ܉ ܉)];simp only[show k t ┢) (Yi fwN:Nat -> ┢) (hd:∀ t h,fx t h=Yi t܆) (hh:∀ t h,fw t h=fwN t܆) (bw:┟) (lo:┞) (hK:K<1048576) (h9:∀ t,t expOf (Yi t)≠255) (hc:∀ t,t expOf (fwN t)≠255) (hf:expOf bw≠255) (h5:∀ t,t mantOf (Yi t)*mantOf (fwN t)≠0 -> lo˗<=idxOf (Yi t)+idxOf (fwN t)/\idxOf (Yi t)+idxOf (fwN t)<=lo˗+122) (h1:mantOf oneW*mantOf bw≠0 -> lo˗<=idxOf oneW+idxOf bw/\idxOf oneW+idxOf bw<=lo˗+122) (FB:┢) (hi:FB=dotOf (K+1) (λ t=>if tif tif tif th5 t ܉ h3);have hm:=ZL oneW bw lo˗ h1;generalize h7:Yr Yi fwN lo˗ 0 K+sv oneW*sv bw*2^(idxOf oneW+idxOf bw-lo˗)=Srel have hg : -2^191<=Srel:=܉ have hj:Srel<2^191:=܉ have ha:=E0 K؝ fx fw Yi fwN hd hh lo ((lo˗:Int)-298) oneW bw ܉ (λ h=>⟨(h1 h).1,by have:=(h1 h).2;omega⟩) K 0 0 0 0 0 0 Srel (by simp[h6]) ܋ ܋ (λ t _ h2 h3=>by have:=h5 t ܉ h3;exact⟨this.1,by omega⟩) (by simp[Yx]) (by rw[<- h7,h6];simp) hg hj rw[ha];have hb:∀ k,k expOf ((λ t=>if tif tif tif tif tif t(h5 t ܉ h3).1)] simp;rw[ZA oneW bw lo˗ (λ h=>(h1 h).1),<- h7];ring exact A2 _ _ _ _ _ (λ _=>hi) he lemma O8 (X W:┠ ┢) (xa wa lo:Nat):∀ r k,YB X W xa wa lo k r=Yr (λ t=>X[xa+t]!) (λ t=>W[wa+t]!) lo k r:=by intro r;induction r with | zero=>intro k;rfl | succ r ih=>intro k;rw[YB,Yr,ih] lemma O6 (X W:┠ ┢) (xa wa n:┡) (hX:xa܆+n܆<=X.size) (hW:wa܆+n܆<=W.size) (hx:xa܆+n܆<֍) (hw:wa܆+n܆<֍) (lo:┞) (e:Int) (bw:┟):∀ d (k:┡) (w2 w1 w0 c:┞),n܆-k܆=d -> YS X W xa wa n hX hW hx hw lo e bw w2 w1 w0 c k=YE n (λ t h=>X.uget (xa+t) (A4 X xa n t hX hx h)) (λ t h=>W.uget (wa+t) (A4 W wa n t hW hw h)) lo e oneW bw w2 w1 w0 c k:=by intro d;induction d with | zero=>intro k w2 w1 w0 c hd;have h0:¬ kintro k w2 w1 w0 c hd;have h0:k lo˗<=idxOf oneW+idxOf bw/\idxOf oneW+idxOf bw k܆<=n܆ -> c˗<=k܆ -> (∀ t,k܆<=t -> t mantOf X[xa܆+t]! * mantOf W[wa܆+t]! ≠ 0 -> lo˗<=idxOf X[xa܆+t]! + idxOf W[wa܆+t]! /\ idxOf X[xa܆+t]! + idxOf W[wa܆+t]! < lo˗+128) -> ((Yx w2 w1 w0+c˗:Nat):Int)%2^192=S0%2^192 -> S=S0+YB X W xa܆ wa܆ lo˗ k܆ (n܆-k܆)+sv oneW*sv bw*2^(idxOf oneW+idxOf bw-lo˗) -> -2^191<=S -> S<2^191 -> YS X W xa wa n hX hW hx hw lo e bw w2 w1 w0 c k=if S=0 then ߿ else (┒ S e false)׆:=by intro d k w2 w1 w0 c S0 S hd hk hc h5 hv hS h6 h7;rw[O6 X W xa wa n hX hW hx hw lo e bw _ k w2 w1 w0 c rfl];exact E0 n _ _ (λ t=>X[xa܆+t]!) (λ t=>W[wa܆+t]!) (λ t h=>A3 X xa t _ (by have:=˩ h;omega)) (λ t h=>A3 W wa t _ (by have:=˩ h;omega)) lo e oneW bw hn h9 d k w2 w1 w0 c S0 S hd hk hc h5 hv (by rw[hS,O8]) h6 h7 lemma S8 (X W:┠ ┢) (xa wa lo:Nat):∀ (r k:Nat),(∀ t,k<=t -> t mantOf X[xa+t]! * mantOf W[wa+t]! ≠ 0 -> lo<=idxOf X[xa+t]! + idxOf W[wa+t]! /\ idxOf X[xa+t]! + idxOf W[wa+t]! <= lo+122) -> -((r:Int)*2^170)<=YB X W xa wa lo k r/\YB X W xa wa lo k r<=(r:Int)*2^170:=λ r k h=>O8 X W xa wa lo r k ▸ B4 _ _ lo r k h lemma H9 (X W:┠ ┢) (inW i j:Nat) (bw:┟) (lo:┞) (p1:(i*inW)؝܆+inW؝܆<=X.size) (p2:(j*inW)؝܆+inW؝܆<=W.size) (p3:(i*inW)؝܆+inW؝܆<֍) (p4:(j*inW)؝܆+inW؝܆<֍) (h8:(i*inW)؝܆=i*inW) (h6:(j*inW)؝܆=j*inW) (h7:inW؝܆=inW) (hn:inW<1048576) (hb:∀ t,t < inW -> expOf X[i*inW+t]! ≠ 255) (he:∀ t,t < inW -> expOf W[j*inW+t]! ≠ 255) (hg:expOf bw≠255) (h5:∀ t,t < inW -> mantOf X[i*inW+t]! * mantOf W[j*inW+t]! ≠ 0 -> lo˗<=idxOf X[i*inW+t]! + idxOf W[j*inW+t]! /\ idxOf X[i*inW+t]! + idxOf W[j*inW+t]! <= lo˗+122) (h1:mantOf oneW*mantOf bw≠0 -> lo˗<=idxOf oneW+idxOf bw/\idxOf oneW+idxOf bw<=lo˗+122) (FB:┢) (hi:FB=dotOf (inW+1) (λ t=>if t < inW then X[i*inW+t]! else oneW) (λ t=>if t < inW then W[j*inW+t]! else bw)) : (if YS X W (i*inW)؝ (j*inW)؝ inW؝ p1 p2 p3 p4 lo ((lo˗:Int)-298) bw 0 0 0 0 0<߿ then (YS X W (i*inW)؝ (j*inW)؝ inW؝ p1 p2 p3 p4 lo ((lo˗:Int)-298) bw 0 0 0 0 0)؉ else FB) = dotOf (inW+1) (λ t=>if t < inW then X[i*inW+t]! else oneW) (λ t=>if t < inW then W[j*inW+t]! else bw):=by rw[O6 X W _ _ _ p1 p2 p3 p4 lo _ bw _ 0 0 0 0 0 rfl];exact H8 inW _ _ (λ t=>X[i*inW+t]!) (λ t=>W[j*inW+t]!) (λ t h=>by rw[A3 X _ t _ (by have:=˩ h;omega),h8]) (λ t h=>by rw[A3 W _ t _ (by have:=˩ h;omega),h6]) bw lo hn hb he hg h5 h1 FB hi lemma W9 (X W b:┠ ┢) (inW i j:Nat):YaU X W b inW i j (Yc X inW i) (Yc W inW 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 YaU;split . rename_i hg;obtain⟨hk,ha,hi,hf,hd⟩:=hg;have hh:(i*inW)؝܆=i*inW:=Za _ (by omega -splitDisjunctions);have hb:(j*inW)؝܆=j*inW:=Za _ (by omega -splitDisjunctions);have he:inW؝܆=inW:=Za _ (by omega -splitDisjunctions);obtain⟨Lx,Hx,h5,hl,hp,h1⟩:=Zp X inW i hk hi;obtain⟨Lv,Hv,h4,hq,ho,h8⟩:=Zp W inW j ha hf;generalize Yc X inW i=bx at h5 ⊢;generalize Yc W inW j=bv at h4 ⊢;obtain⟨hj,h3⟩:=Zo bx Lx Hx h5 (by omega -splitDisjunctions);obtain⟨h9,h7⟩:=Zo bv Lv Hv h4 (by omega -splitDisjunctions);obtain⟨wl1,wl2⟩:=D7 bx bv b[j]!;obtain⟨wh1,wh2⟩:=D6 bx bv b[j]!;rw[hj,h9]at wl1;rw[h3,h7]at wh1;dsimp only;split . exact B5 X W b inW i j . rename_i hc;simp only[״,┃,not_or]at hc;obtain⟨⟨⟨⟨c1,c2⟩,c3⟩,c4⟩,c5⟩:=id hc;have d1:Hx≠255:=λ h=>c1 (˅ (by rw[h3,h];rfl));have d2:Hv≠255:=λ h=>c2 (˅ (by rw[h7,h];rfl));obtain⟨d4,d5⟩:=C2 _ _ c4 c5 by_cases h63:Yu bx bv b[j]! - Yp bx bv b[j]! <= 63;on_goal 1 => rw[if_pos h63];have d6:(Yu bx bv b[j]!)˗-(Yp bx bv b[j]!)˗<=63:=by rw[¿,§ _ _ (⠃ d4)]at h63;exact h63 rw[E7 X W (i*inW)؝ (j*inW)؝ inW؝ _ _ _ _ (Yp bx bv b[j]!) _ b[j]! (λ t ht hm=>by rw[hh,hb]at hm ⊢;rw[he]at ht;exact ZQ wl1 wh1 d6 (h1 t ht) (h8 t ht) hm) inW؝܆ 0 0 0 0 0 ܋] on_goal 2=>rw[if_neg h63] all_goals apply H9 X W inW i j b[j]! (Yp bx bv b[j]!) _ _ _ _ hh hb he hd . intro t ht;exact(Zb X[i*inW+t]!).2.2.1 (҂ (h1 t ht).2 (͵ hp d1)) . intro t ht;exact(Zb W[j*inW+t]!).2.2.1 (҂ (h8 t ht).2 (͵ ho d2)) . exact c3 . intro t ht hm;exact ZQ wl1 wh1 d5 (h1 t ht) (h8 t ht) hm . intro hm;have h0:mantOf b[j]! ≠ 0:=λ h=>hm (by rw[h,׳]);exact⟨wl2 h0,(wh2 h0).trans (Nat.sub_le_iff_le_add'.mp d5)⟩ . exact B5 X W b inW i j . exact B5 X W b inW i j @[inline] def Yb (s:ConvShape):Nat:=s.h+2*s.pad @[inline] def Ya (s:ConvShape):Nat:=s.w+2*s.pad @[inline] def YI (s:ConvShape) (inp:┠ ┢) (idx:Nat):┢ := let c:=idx/(Yb s*Ya s) let yy:=idx/Ya s%Yb s let xx:=idx%Ya s if yy=s.h\/xx-s.pad>=s.w then 0 else inp[(c*s.h+(yy-s.pad))*s.w+(xx-s.pad)]! @[inline] def Ys (s:ConvShape) (t:Nat):Nat := t/(s.kh*s.kw)*(Yb s*Ya s)+t/s.kw%s.kh*Ya s+t%s.kw lemma N3 (c yy xx A B:Nat) (h1:yy pbn+(off[t]!)؊if tif tif tif t pbn+(off[t]!).toNat122 then Yam s inp wts b k o cw y x else let r:=YE k.toUSize (λ t ht=>P.uget (pbn.toUSize+(off.uget t (by rw [hoff];rw [USize.lt_iff_toNat_lt,Za _ ܉] at ht;exact ht)).toUSize) (by have:=N1 P off k pbn hoff hPs hix t ht ܉ (by rw [hoff];rw [USize.lt_iff_toNat_lt,Za _ ܉] at ht;exact ht) rw [this.1];exact this.2)) (λ t ht=>wts.uget ((o*k).toUSize+t) (by have:=Z0 wts o k h t ht rw [this.1];exact this.2)) lo ((lo.toNat:Int)-298) oneW bw 0 0 0 0 0 if r<0x100000000 then r.toUInt32 else Yam s inp wts b k o cw y x else Yam s inp wts b k o cw y x lemma J8 (s:┕) (inp P:┠ ┢) (off:┠ ┟) (wts b:┠ ┢) (k o cw y x pbn:Nat) (hd:off٪=k) (hk:k<1048576) (h5:P.size<4294967296) (h0:∀ t,t pbn+(off[t]!)؊ P[pbn+(off[t]!)؊]! = └ s inp y x (cw+t)) : YaC s inp P off wts b k o cw y x pbn (Yc P P.size 0) (Yc wts k o) hd hk h5 h0 = dotOf (k+1) (λ t=>if tif tc1 (˅ (by rw[h6,h];rfl));have d2:Hv≠255:=λ h=>c2 (˅ (by rw[ha,h];rfl));obtain⟨d4,d5⟩:=C2 _ _ c4 c5 have he:∀ t,t └ s inp y x (cw+t)=P[0*P.size+(pbn+(off[t]!)؊)]! :=λ t ht=>by rw[؍,˥];exact(hl t ht).symm apply H8 k _ _ (λ t=>└ s inp y x (cw+t)) (λ t=>wts[o*k+t]!) _ _ b[o]! (Yp bx bv b[o]!) hk . intro t ht;rw[he t ht];exact(Zb _).2.2.1 (҂ (h3 _ (h0 t ht)).2 (͵ hq d1)) . intro t ht;exact(Zb _).2.2.1 (҂ (hb t ht).2 (͵ hp d2)) . exact c3 . intro t ht hm;rw[he t ht]at hm ⊢;exact ZQ wl1 wh1 d5 (h3 _ (h0 t ht)) (hb t ht) hm . intro hm;have h2:mantOf b[o]! ≠ 0:=λ h=>hm (by rw[h,׳]);exact⟨wl2 h2,(wh2 h2).trans (Nat.sub_le_iff_le_add'.mp d5)⟩ . exact D2 s inp wts b k o cw y x . intro t ht;have hi:k؝܆=k:=Za _ ܉ have hh:t܆(Ys s t؞).toUInt32)[t]!)؊=Ys s t:=߹ def Ya0 (s:ConvShape) (relu:┣) (inp wts b:┠ ┢):┠ ┢ := if hg:s.kh<=Yb s/\s.kw<=Ya s/\s.cin*(Yb s*Ya s)<=4294967295 /\ s.cin*s.kh*s.kw<1048576 then let P:┠ ┢:=Array.ofFn (n:=s.cin*(Yb s*Ya s)) λ i=>YI s inp i.val let off:┠ ┟:=Array.ofFn (n:=s.cin*s.kh*s.kw) λ t=>(Ys s t.val).toUInt32 let bp:=Yc P P.size 0 let BW:┠ ┟:=Array.ofFn (n:=s.cout) λ o=>Yc wts (s.cin*s.kh*s.kw) o.val Array.ofFn (n:=s.cout*(s.ho*s.wo)) λ q => act relu (YaC s inp P off wts b (s.cin*s.kh*s.kw) (q.val/(s.ho*s.wo)) 0 (q.val/s.wo%s.ho) (q.val%s.wo) (q.val/s.wo%s.ho*s.stride*Ya s+q.val%s.wo*s.stride) bp BW[q.val/(s.ho*s.wo)]! (by simp [off]) hg.2.2.2 (by simp [P];have:=hg.2.2.1;omega) (λ t ht=>by obtain ⟨hy,hx,-⟩:=Zt s.cout s.ho s.wo q.val q.isLt obtain ⟨w1,-⟩:=D1 s inp hg.1 hg.2.1 _ _ t hy hx ht simp only [P,off,Array.size_ofFn] rw [ZD s _ t ht ܉] exact w1)) else conv2dWith Yn s relu inp wts b lemma V0:Ya0=conv2dSpec:=by funext s relu inp wts b;unfold Ya0 conv2dSpec;split . rename_i hg;dsimp only;congr 1;funext q;obtain⟨hy,hx,ho⟩:=Zt s.cout s.ho s.wo q؞ q.isLt;rw[Ze s.cout (λ o=>Yc wts (s.cin*s.kh*s.kw) o) _ ho];congr 1;refine(J8 s inp _ _ wts b _ _ 0 _ _ _ _ _ _ _ ?_).trans ?_ . intro t ht;obtain⟨w1,w2⟩:=D1 s inp hg.1 hg.2.1 _ _ t hy hx ht;rw[ZD s _ t ht ܉,˥,Ze _ (λ i=>YI s inp i) _ w1] exact w2 . simp . simp only[Zi] def dwF (s:ConvShape) (relu:┣) (inp wts b:┠ ┢):┠ ┢ := if hg:s.kh<=Yb s/\s.kw<=Ya s/\s.cin*(Yb s*Ya s)<=4294967295 /\ s.kh*s.kw<1048576 then let P:┠ ┢:=Array.ofFn (n:=s.cin*(Yb s*Ya s)) λ i=>YI s inp i.val let off:┠ ┟:=Array.ofFn (n:=s.kh*s.kw) λ t=>(Ys s t.val).toUInt32 let bp:=Yc P P.size 0 let BW:┠ ┟:=Array.ofFn (n:=s.cin) λ c=>Yc wts (s.kh*s.kw) c.val Array.ofFn (n:=s.cin*(s.ho*s.wo)) λ q => act relu (YaC s inp P off wts b (s.kh*s.kw) (q.val/(s.ho*s.wo)) (q.val/(s.ho*s.wo)*(s.kh*s.kw)) (q.val/s.wo%s.ho) (q.val%s.wo) (q.val/(s.ho*s.wo)*(Yb s*Ya s) + (q.val/s.wo%s.ho*s.stride*Ya s+q.val%s.wo*s.stride)) bp BW[q.val/(s.ho*s.wo)]! (by simp [off]) hg.2.2.2 (by simp [P];have:=hg.2.2.1;omega) (λ t ht=>by obtain ⟨hy,hx,hc⟩:=Zt s.cin s.ho s.wo q.val q.isLt obtain ⟨w1,-⟩:=ZZ s inp _ t _ _ hg.1 hg.2.1 hc ht hy hx simp only [P,off,Array.size_ofFn] rw [ZD s _ t ht ܉] exact w1)) else depthwiseWith Yn s relu inp wts b lemma U9:dwF=depthwiseSpec:=by funext s relu inp wts b;unfold dwF depthwiseSpec;split . rename_i hg;dsimp only;congr 1;funext q;obtain⟨hy,hx,hc⟩:=Zt s.cin s.ho s.wo q؞ q.isLt;rw[Ze s.cin (λ c=>Yc wts (s.kh*s.kw) c) _ hc];congr 1;refine(J8 s inp _ _ wts b _ _ _ _ _ _ _ _ _ _ ?_).trans rfl;intro t ht;obtain⟨w1,w2⟩:=ZZ s inp _ t _ _ hg.1 hg.2.1 hc ht hy hx;rw[ZD s _ t ht ܉,Ze _ (λ i=>YI s inp i) _ w1];exact w2 . simp only[Zi] lemma U8 (fa fb:Nat -> ┢) (lo:Nat):∀ r k,(∀ t,k<=t -> t mantOf (fa t)*mantOf (fb t)≠0 -> lo<=idxOf (fa t)+idxOf (fb t)) -> Yo fa fb k r=2^lo*Yr fa fb lo k r:=by intro r;induction r with | zero=>intro k _;simp[Yo,Yr] | succ r ih => intro k h;rw[Yo,Yr,ih (k+1) (λ t h1 h2=>h t ܉ ܉),ZA _ _ lo (h k (le_refl _) ܉)] ring lemma U7 (K:Nat) (fx fw:(t:┡) -> t ┢) (Yi fwN:Nat -> ┢) (ha:∀ t h,fx t h=Yi t܆) (he:∀ t h,fw t h=fwN t܆) (lo:┞) (hK:K<1048576) (h7:∀ t,t expOf (Yi t)≠255) (h9:∀ t,t expOf (fwN t)≠255) (h1:∀ t,t mantOf (Yi t)*mantOf (fwN t)≠0 -> lo˗<=idxOf (Yi t)+idxOf (fwN t)/\idxOf (Yi t)+idxOf (fwN t)<=lo˗+122) (FB:┢) (hf:FB=dotOf K Yi fwN) : (if YE K؝ fx fw lo ((lo˗:Int)-298) 0 0 0 0 0 0 0<߿ then (YE K؝ fx fw lo ((lo˗:Int)-298) 0 0 0 0 0 0 0)؉ else FB) = dotOf K Yi fwN:=by have h4:K؝܆=K:=Za _ ܉ have hh:=B4 Yi fwN lo˗ K 0 (λ t _ h2 h3=>h1 t ܉ h3) have hc:sv (0:┟)=0:=܌ generalize h5:Yr Yi fwN lo˗ 0 K=Srel;have hd : -2^191<=Srel:=܉ have hg:Srel<2^191:=܉ have h8:=E0 K؝ fx fw Yi fwN ha he lo ((lo˗:Int)-298) 0 0 ܉ (λ h=>absurd (by decide:mantOf (0:┟)*mantOf 0=0) h) K 0 0 0 0 0 0 Srel (by simp[h4]) ܋ ܋ (λ t _ h2 h3=>by have:=h1 t ܉ h3;exact⟨this.1,by omega⟩) (by simp[Yx]) (by rw[<- h5,h4,hc];simp) hd hg rw[h8];have hb:dotOf K Yi fwN=┒ (Srel*2^lo˗) (-298) (decide (K≠0)&&Yq Yi fwN 0 K):=by rw[Zy K Yi fwN (λ t ht=>⟨h7 t ht,h9 t ht⟩)];rw[U8 Yi fwN lo˗ K 0 (λ t _ h2 h3=>(h1 t ܉ h3).1),<- h5];ring exact A2 _ _ _ _ _ (λ _=>hf) hb lemma J7 (B:┠ ┢) (k n bk j:Nat) (h:(bk+k)*n<=B.size/\jA[r*k+t]!) (λ t=>B[(bk+t)*n+j]!) lemma D0 (A B:┠ ┢) (k n r bk j:Nat):Yan A B k n r bk j=dotOf k (λ t=>A[r*k+t]!) (λ t=>B[(bk+t)*n+j]!):=by unfold Yan;rw[Zi] @[inline] def Ya2 (A B:┠ ┢) (k n r bk j:Nat) (ba bb:┟) (hk:k<1048576) : ┢ := if h:r*k+k<=A.size/\r*k+k<=4294967295/\((bk+k)*n<=B.size/\j122 then Yan A B k n r bk j else let r':=YE k.toUSize (λ t ht=>A.uget ((r*k).toUSize+t) (by have:=Z0 A r k ⟨h.1,h.2.1⟩ t ht rw [this.1];exact this.2)) (λ t ht=>B.uget ((bk*n+j).toUSize+t*n.toUSize) (by have:=J7 B k n bk j h.2.2 hk t ht rw [this.1];exact this.2)) lo ((lo.toNat:Int)-298) 0 0 0 0 0 0 0 if r'<0x100000000 then r'.toUInt32 else Yan A B k n r bk j else Yan A B k n r bk j lemma U6 (A B:┠ ┢) (k n r bk j:Nat) (hk:k<1048576):Ya2 A B k n r bk j (Yc A k r) (Yc B B.size 0) hk=dotOf k (λ t=>A[r*k+t]!) (λ t=>B[(bk+t)*n+j]!):=by unfold Ya2;split . rename_i hg;obtain⟨Lx,Hx,h6,hd,hh,h0⟩:=Zp A k r hg.1 hg.2.1;obtain⟨Lv,Hv,h4,hi,hf,h9⟩:=Zp B B.size 0 ܉ ܉;generalize Yc A k r=bx at h6 ⊢;generalize Yc B B.size 0=bv at h4 ⊢;obtain⟨hb,h3⟩:=Zo bx Lx Hx h6 ܉;obtain⟨ha,h8⟩:=Zo bv Lv Hv h4 ܉;obtain⟨wl1,-⟩:=D7 bx bv 0;obtain⟨wh1,-⟩:=D6 bx bv 0;dsimp only;split . exact D0 A B k n r bk j . rename_i hc;simp only[״,┃,not_or]at hc;obtain⟨⟨⟨c1,c2⟩,c4⟩,c5⟩:=id hc;have d1:Hx≠255:=λ h=>c1 (˅ (by rw[h3,h];rfl));have d2:Hv≠255:=λ h=>c2 (˅ (by rw[h8,h];rfl));obtain⟨d4,d5⟩:=C2 _ _ c4 c5 rw[h3,h8]at wh1;rw[hb,ha]at wl1;have h5:∀ t,t (bk+t)*n+j B[(bk+t)*n+j]! = B[0*B.size+((bk+t)*n+j)]! := by simp apply U7 k _ _ (λ t=>A[r*k+t]!) (λ t=>B[(bk+t)*n+j]!) _ _ (Yp bx bv 0) hk . intro t ht;exact(Zb _).2.2.1 (҂ (h0 t ht).2 (͵ hh d1)) . intro t ht;rw[h2 t ht];exact(Zb _).2.2.1 (҂ (h9 _ (h5 t ht)).2 (͵ hf d2)) . intro t ht hm;rw[h2 t ht]at hm ⊢;exact ZQ wl1 wh1 d5 (h0 t ht) (h9 _ (h5 t ht)) hm . exact D0 A B k n r bk j . intro t ht;obtain⟨e1,e2⟩:=Z0 A r k ⟨hg.1,hg.2.1⟩ t ht;show A[((r*k)؝+t)܆]=_;rw[<- ┍ A _ (by rw[e1];exact e2)];simp only[e1] . intro t ht;obtain⟨e1,e2⟩:=J7 B k n bk j hg.2.2 hk t ht;show B[((bk*n+j)؝+t*n؝)܆]=_;rw[<- ┍ B _ (by rw[e1];exact e2)];simp only[e1] . exact D0 A B k n r bk j def Ya3 (batch m k n:Nat) (A B:┠ ┢):┠ ┢ := if hk:k<1048576 then let bb:=Yc B B.size 0 let BA:┠ ┟:=Array.ofFn (n:=batch*m) λ r=>Yc A k r.val YT (batch*m) n λ r j=>Ya2 A B k n r (r/m*k) j BA[r]! bb hk else gemmWith Yn batch m k n A B lemma X5:Ya3=gemmSpec:=by funext batch m k n A B;unfold Ya3 gemmSpec;split . rename_i hk;rw[ZB _ _ _ (˺ _ _ _)];congr 1;funext q;have g1:∀ v:Nat,v/n=v/(m*n)*m+v/n%m:=by intro v;rw[˱ m n,<- ˭];exact(֏ _ _).symm have g2:∀ v:Nat,v/n/m=v/(m*n):=by intro v;rw[˭,˱ n m] rw[g2 q؞];conv_lhs=>rw[g1 q؞] obtain⟨hi,hj,hb⟩:=Zt batch m n q؞ q.isLt;have hr:q؞/(m*n)*m+q؞/n%mYc A k r) _ hr];exact U6 A B k n _ _ _ hk . simp only[Zi] section open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Numerics open Model open RationalBinary (floorLog2 scaleByPowerOfTwo scaleByPowerOfTwo_snd_ne_zero) open FloatLib.Numerics (binaryRadix Radix.toReal) lemma bz (e:Int):bpow e=(2:ℝ)^e:=by simp[bpow,FloatLib.Floats.Formats.Flocq.bpow,binaryRadix,Radix.toReal] lemma cW (w:┟):toWord (NativeBinary32.ofUInt32 w)=w:=by simp only[toWord,NativeBinary32.ofUInt32,toNatBits,ofBits];exact UInt32.ofNat_toNat lemma cU {a b:Int} {v:ℝ} (h1:bpow a<=v) (h2:v roundQuotientEven (scaleByPowerOfTwo n d x).1 (scaleByPowerOfTwo n d x).2= roundQuotientEven (scaleByPowerOfTwo n' d' x').1 (scaleByPowerOfTwo n' d' x').2:=λ x x' h=>by apply roundQuotientEven_eq_of_rat_eq _ _ _ _ (scaleByPowerOfTwo_snd_ne_zero _ _ _ hd) (scaleByPowerOfTwo_snd_ne_zero _ _ _ h0);rw[scaleByPowerOfTwo_real,scaleByPowerOfTwo_real];rwa[mul_assoc,<- bpow_add,mul_assoc,<- bpow_add,add_sub_cancel,add_sub_cancel]at h rw[roundRatScaled_false_eq_of_isIEEE f n d e hf hn hd,roundRatScaled_false_eq_of_isIEEE f n' d' e' hf h5 h0];simp only[];rw[hQ _ (e'+Int.ofNat (FloatFormat.subnormalAlignExp f)) (by rw[hv];ring_nf),hQ _ (Int.ofNat f܈-floorLog2 n' d') (by rw[hv,show Int.ofNat f܈-floorLog2 n d-e=Int.ofNat f܈-floorLog2 n' d'-e' by omega]),hT] lemma J6 (Q:ℚ) (s:┣) (N D:Nat) (E:Int) (hD:0 0simp_all obtain rfl:Q=0:=by simp[hQ] simp[roundRatScaled_num_zero _ _ _ _ hD.ne'];rfl have hv:(0:ℚ)simp[neg_div] have h0:Q.num.natAbs≠0:=by simpa using (show Q≠0 by rw[hQ];cases s<;>simp[hv.ne']) have hR:(0:ℝ)push_cast<;>simp[abs_of_pos hR] rw[show decide (Q<0)=s by rw[hQ];cases s<;>simp[hv,not_lt.mpr hv.le]];cases s . exact cV _ hf _ _ _ _ _ _ h0 Q.den_nz hN hD.ne' h1 . rw[roundRatScaled_true_eq_neg_false _ _ _ _ hf Q.den_nz,roundRatScaled_true_eq_neg_false _ _ _ _ hf hD.ne',cV _ hf _ _ _ _ _ _ h0 Q.den_nz hN hD.ne' h1] lemma X4 (q u D r:Nat) (hu:2<=u) (he:u%2=0) (hr:0.trans (by push_cast;ring) . rw[bpow_natCast];push_cast;rw[pow_succ];linarith . rw[show((q،+1:ℕ):ℤ)+1=((q،+2:ℕ):ℤ) by push_cast;ring,bpow_natCast];push_cast;rw[show q،+2=(q،+1)+1 by ring,pow_succ];linarith lemma X3 (s:┣) (N D:Nat) (E:Int) (hD:0simp[hA,hF]<;>omega . have:¬ ((q،:ℤ)+Esimp[hF]<;>omega end section open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats FloatLib.Floats.Formats.Flocq open Float.Model.UnpackedFloat open FloatLib.Numerics (binaryRadix Radix.toReal) lemma X2 (q:ℚ) (num den:Nat) (e:Int) (hq:0(x:ℝ)) h8;push_cast at this;rw[this,h4] rw[hv,Real.sqrt_mul (by exact_mod_cast hq.le),Real.sqrt_sq ܍];simp only[bpow,binaryRadix,Radix.toReal] push_cast;rw[mul_assoc,<- zpow_add₀ (by norm_num:(2:ℝ)≠0)];simp rw[h5]at he hs;have ha:(nearestEven (scaledMantissa binaryRadix (Model.fexpOf Fmt) (Real.sqrt (q:ℝ))))؈ = (shiftToTargetExponent (┏ Fmt) (┚ num den) e (├ num den)).1.roundedMantissa:=by rw[hs,<- hn];simp have h3:(shiftToTargetExponent (┏ Fmt) (┚ num den) e (├ num den)).2=(┏ Fmt).targetExponent (┖ (┚ num den) e):=by rw[Model.shiftToTargetExponent_eq_of_le_targetExponent Fmt _ e _ h2] simp only[sqrtMathWord,h6,│,he,ha];rw[Model.roundWithAccuracy_eq_finishRoundedMantissa];rw[h3] end @[inline] def Y2 (x:┠ ┢) (base n:Nat):Nat := (List.range n).foldl (λ b j => let w:=x[base+j]! if mantOf w=0 then b else min b (idxOf w)) 255 @[inline] def Y6 (x:┠ ┢) (base n b0:Nat):┠ Nat := (List.range n).foldl (λ a j => let w:=x[base+j]! addLimbs64 a (mantOf w*mantOf w).toUInt64 (2*(idxOf w-b0))) (Array.replicate 18 0) @[inline] def Y7 (x:┠ ┢) (base n b0:Nat):┠ Nat × ┠ Nat := (List.range n).foldl (λ pq j => let w:=x[base+j]! if signOf w then (pq.1,addLimbs64 pq.2 (mantOf w).toUInt64 (idxOf w-b0)) else (addLimbs64 pq.1 (mantOf w).toUInt64 (idxOf w-b0),pq.2)) (Array.replicate 18 0,Array.replicate 18 0) @[inline] def sqA (num den root:Nat):Nat:= if num=root*root*den then 0 else if 4*num ┢):┢ := let t:Int:=(47-(num0.log2:Int)+m.log2+1)/2 let num:=if 0<=t then num0<<<(2*t.toNat) else num0 let den:=if 0<=t then m else m<<<(2*(-t).toNat) let root:=sqrtLower num den if 8388608<=root then sqW num den root (h-t) else fallback () @[inline] def YF (b0 ie:Nat):Nat:=min (2*b0) (ie+149)/2*2 @[inline] def YaE (x:┠ ┢) (n:Nat) (eps:┢) (r:Nat):┢ := let b0:=Y2 x (r*n) n let c:=YF b0 (idxOf eps) YaD (limbValA (Y6 x (r*n) n b0)<<<(2*b0-c) + (n*mantOf eps)<<<(idxOf eps+149-c)) n (((c:Int)-298)/2) λ _=>sqrtRational (rowVariance n x r 0+rationalWord eps) @[inline] def Y8 (x:┠ ┢) (n:Nat) (eps:┢) (r:Nat):Nat × Int × ┢ := let b0:=Y2 x (r*n) n let pq:=Y7 x (r*n) n b0 let S1:Int:=(limbValA pq.1:Int)-limbValA pq.2 let T:Int:=(n:Int)*limbValA (Y6 x (r*n) n b0)-S1*S1 let c:=YF b0 (idxOf eps) (b0,S1,YaD (T.toNat<<<(2*b0-c)+(n*n*mantOf eps)<<<(idxOf eps+149-c)) (n*n) (((c:Int)-298)/2) λ _ => sqrtRational (rowVariance n x r (rowMean n x r)+rationalWord eps)) section open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats open Float.Model.UnpackedFloat lemma iB (w:┢):idxOf w<=254:=by have:=expOf_toNat_lt w;unfold idxOf;split_ifs<;>omega lemma lS (m k:Nat -> Nat) (hm:∀ j,m j<2^64) (hk:∀ j,k j/32+1<18) (l:List Nat) (a:┠ Nat) (ha:a٪=18) : (l.foldl (λ a j=>addLimbs64 a (m j)˾ (k j)) a)٪=18 /\ limbVal (l.foldl (λ a j=>addLimbs64 a (m j)˾ (k j)) a)܃=limbVal a܃+(l.map λ j=>m j*2^k j).sum:=by induction l generalizing a with | nil=>simp[ha] | cons j l ih=>simp;obtain⟨h1,h2⟩:=ih (addLimbs64 a (m j)˾ (k j)) (by rw[addLimbs64_size];exact ha);refine⟨h1,?_⟩;rw[h2,addLimbs64_eq _ _ _ (hm j),addLimbs_val _ _ _ (by rw[ha];exact hk j)];ring lemma lP (x:┠ ┢) (base b0:Nat) (f:┠ Nat × ┠ Nat -> Nat -> ┠ Nat × ┠ Nat) (hf:∀ pq j,f pq j=if signOf x[base+j]! then (pq.1,addLimbs64 pq.2 (mantOf x[base+j]!)˾ (idxOf x[base+j]! - b0)) else (addLimbs64 pq.1 (mantOf x[base+j]!)˾ (idxOf x[base+j]! - b0),pq.2)) (l:List Nat):∀ p q,p٪=18 -> q٪=18 -> (l.foldl f (p,q)).1.size=18 /\ (l.foldl f (p,q)).2.size=18/\((limbVal (l.foldl f (p,q)).1.toList:Int) - limbVal (l.foldl f (p,q)).2.toList)=(limbVal p܃:Int)-limbVal q܃+(l.map λ j=>sv x[base+j]! * 2^(idxOf x[base+j]! - b0)).sum:=by induction l with | nil=>intro p q hp hq;simp[hp,hq] | cons j l ih => intro p q hp hq;simp only[܁,List.map_cons,List.sum_cons,hf];have hm:=┊ x[base+j]!;have hi:=iB x[base+j]!;by_cases hs:signOf x[base+j]! = true . simp only[hs,━];obtain⟨h1,h2,h3⟩:=ih p (addLimbs64 q (mantOf x[base+j]!)˾ (idxOf x[base+j]! - b0)) hp (by rw[addLimbs64_size];exact hq) refine⟨h1,h2,?_⟩;rw[h3,addLimbs64_eq _ _ _ ܉,addLimbs_val _ _ _ (by rw[hq];omega)];simp only[sv,hs,━];push_cast;ring . simp only[hs,¥,│];obtain⟨h1,h2,h3⟩:=ih (addLimbs64 p (mantOf x[base+j]!)˾ (idxOf x[base+j]! - b0)) q (by rw[addLimbs64_size];exact hp) hq refine⟨h1,h2,?_⟩;rw[h3,addLimbs64_eq _ _ _ ܉,addLimbs_val _ _ _ (by rw[hp];omega)];simp only[sv,hs,¥,│];push_cast;ring lemma fS (f:Nat -> ℚ) (l:List Nat) (a:ℚ):l.foldl (λ t j=>t+f j) a=a+(l.map f).sum:=by induction l generalizing a with | nil=>simp | cons j l ih=>simp[܁,ih,add_assoc] lemma A0 (num den:Nat):├ num den=Float.Model.UnpackedFloat.accuracyOfFraction (sqA num den (┚ num den)) 4:=by unfold sqrtAccuracy sqA;dsimp only;simp only[sq];split_ifs<;>rfl lemma G2 (N d:Nat):N/d<=┐ N d /\ ┐ N d<=N/d+1:=by unfold FloatLib.Numerics.roundQuotientEven;dsimp only;split_ifs<;>omega lemma F8:Fmt܈=23/\Model.pow2 Fmt܈=8388608/\Model.pow2 (Fmt܈+1)=16777216/\FloatFormat.ieeeMinNormalExponent Fmt = -126/\ Int.ofNat (FloatFormat.ieeeMaxNormalExponent Fmt)=127/\Int.ofNat Fmt.bias=127:=܌ lemma QW (E F:Nat):toWord (Model.NativeBinary32.ofUInt32 (┎ false E F))=┎ false E F:=by simp only[toWord,Model.NativeBinary32.ofUInt32,Model.toNatBits,Model.ofBits];exact UInt32.ofNat_toNat lemma F7 (r:Nat) (k:Int) (h1:8388608<=r) (h2:r<16777216) (hk:-126<=k) (hk2:k<=127) : toWord (Model.ofModel Fmt (Model.finishRoundedMantissa (┏ Fmt) .positive (r,k-23)))=┎ false (k+127)؈ (r-8388608):=by obtain⟨hf,hp,hp1,hmin,hmax,hb⟩:=F8;have e1:=Model.finishRoundedMantissa_normalized Fmt .positive r k (by rw[hp];exact h1) (by rw[hp1];exact h2) (by rw[hmin];exact hk) rw[show(k-23:Int)=k-(Fmt܈:Int) by rw[hf];rfl,e1] have e2:=Model.ofModel_finite_normalized_eq_ofFields Fmt false r k (by rw[hp];exact h1) (by rw[hp1];exact h2) (by rw[hmin];exact hk) (by rw[hmax];exact hk2) erw [e2];have e4:=QW (k+127)؈ (r-8388608);rw[Model.NativeBinary32.ofUInt32_mkBits]at e4;exact e4 lemma F9 (k:Int) (hk:-126<=k) (hk2:k+1<=127) : toWord (Model.ofModel Fmt (Model.finishRoundedMantissa (┏ Fmt) .positive (16777216,k-23)))=┎ false (k+1+127)؈ 0:=by obtain⟨hf,hp,hp1,hmin,hmax,hb⟩:=F8;have e1:=Model.finishRoundedMantissa_normalized_carry Fmt .positive k (by rw[hmin];exact hk) rw[show(k-23:Int)=k-(Fmt܈:Int) by rw[hf];rfl,show(16777216:Nat)=Model.pow2 (Fmt܈+1) from hp1.symm,e1] have e2:=Model.ofModel_finite_normalized_eq_ofFields Fmt false (Model.pow2 Fmt܈) (k+1) le_rfl (by rw[hp,hp1];decide) (by rw[hmin];omega) (by rw[hmax];exact hk2) erw [e2];have e4:=QW (k+1+127)؈ 0;rw[Model.NativeBinary32.ofUInt32_mkBits]at e4;exact e4 theorem A1 (num den:Nat) (e:Int):sqW num den (┚ num den) e=toWord (Model.ofModel Fmt (Float.Model.UnpackedFloat.roundWithAccuracy (┏ Fmt) .positive (┚ num den) e (├ num den))):=by have hA:=A0 num den;unfold sqW;generalize ┚ num den=root at hA ⊢;have hmb:(┏ Fmt).mantissaBits=24:=܌ have hme:(┏ Fmt).minExponent = -149:=܌ by_cases hs:root<16777216;on_goal 1=>simp only[hs,━,Nat.cast_zero,add_zero] on_goal 2=>simp only[hs,│,Nat.cast_one] all_goals split;on_goal 2=>rfl rename_i hc;obtain⟨h23,h25,hd,hx1,hx2⟩:=hc;have hlt:sqA num den root<4:=by unfold sqA;split_ifs<;>omega generalize sqA num den root=a at hA hlt ⊢;rw[hA];have key:=Model.roundWithAccuracy_quotient_eq_finishRoundedMantissa (┏ Fmt) .positive (4*root+a) 4 e ܊ rw[show(4*root+a)/4=root by omega,show(4*root+a)%4=a by omega]at key have hne:root≠0:=܉ · have hl1:=(Nat.le_log2 hne).mpr (show 2^23<=root by omega) have hl2:=(Nat.log2_lt hne).mpr (show root<2^24 by omega) have hsh:((┏ Fmt).targetExponent (┖ root e) - e)؈=0:=by simp only[Float.Model.Format.targetExponent,Float.Model.totalExponent,hmb,hme];omega rw[key];dsimp only;rw[hsh];simp only[pow_zero,mul_one,Nat.cast_zero,add_zero];obtain⟨b1,b2⟩:=G2 (4*root+a) 4;generalize ┐ (4*root+a) 4=r at b1 b2 ⊢;split · rename_i hr;subst hr;rw[show e=(e+23)-23 by ring,F9 (e+23) ܉ ܉];congr 2;omega · rw[show e=(e+23)-23 by ring,F7 r (e+23) ܉ ܉ ܉ ܉];congr 2;omega · have hl1:=(Nat.le_log2 hne).mpr (show 2^24<=root by omega) have hl2:=(Nat.log2_lt hne).mpr (show root<2^25 by omega) have hsh:((┏ Fmt).targetExponent (┖ root e) - e)؈=1:=by simp only[Float.Model.Format.targetExponent,Float.Model.totalExponent,hmb,hme];omega rw[key];dsimp only;rw[hsh];simp only[pow_one,Nat.cast_one];obtain⟨b1,b2⟩:=G2 (4*root+a) (4*2);generalize ┐ (4*root+a) (4*2)=r at b1 b2 ⊢;split · rename_i hr;subst hr;rw[show e+1=(e+24)-23 by ring,F9 (e+24) ܉ ܉];congr 2;omega · rw[show e+1=(e+24)-23 by ring,F7 r (e+24) ܉ ܉ ܉ ܉];congr 2;omega lemma J4 (num0 m:Nat) (h:Int) (q:ℚ) (hq:0sqrtRational q)=sqrtRational q:=by unfold YaD;simp only[A1];generalize (47-((num0،:Nat):Int)+(m،:Nat)+1)/2=t;have e:∀ k:Nat,(2:ℚ)^(2*k)=4^(k:ℤ):=λ k=>by rw[pow_mul,┄];norm_num by_cases h0:0<=t<;>simp only[h0,━,│]<;>split_ifs with hr<;>try rfl all_goals refine X2 q _ _ _ hq (by first | exact hm | (rw[®];exact ˳ hm ܍)) ?_ (by rw[show(2:Nat)^23=8388608 by norm_num];exact hr) all_goals rw[<- hv,show -(h-t)=t-h by ring,zpow_sub₀ ܊];simp only[®] all_goals push_cast;rw[e,Int.toNat_of_nonneg ܉];field_simp [zpow_neg] all_goals rw[mul_assoc,<- zpow_add₀ ܊];simp lemma X1 (w:┢):(sv w:ℚ)^2=(mantOf w:ℚ)^2:=by unfold sv;split_ifs<;>push_cast<;>ring lemma J3 (eps:┢) (he:0<┓ eps):┓ eps=(mantOf eps:ℚ)*2^((idxOf eps:ℤ)-149):=by have h:=he;simp only[rationalWord,┇]at h ⊢;unfold sv at h ⊢;split_ifs at h ⊢ with hs . have:(0:ℚ)<=2^((idxOf eps:ℤ)-149):=܍ push_cast at h;nlinarith [show(0:ℚ)<=mantOf eps by positivity] . push_cast;ring lemma J2 (x:┠ ┢) (n r b0:Nat) (h1:∀ j b0<=idxOf x[r*n+j]!) : (limbValA (Y6 x (r*n) n b0):ℚ)*2^((2*b0:ℤ)-298)=((՛ n).map λ j=>(┓ x[r*n+j]!)^2).sum:=by unfold Y6;rw[limbValA_eq,(lS (λ j=>mantOf x[r*n+j]! * mantOf x[r*n+j]!) (λ j=>2*(idxOf x[r*n+j]! - b0)) (λ j=>by have:=┊ x[r*n+j]!;nlinarith) (λ j=>by have:=iB x[r*n+j]!;omega) _ _ ܋).2] have h0:limbVal (؇ 18 0)܃=0:=܌ rw[h0,zero_add,Nat.cast_list_sum,List.map_map,<- List.sum_map_mul_right];congr 1;apply List.map_congr_left;intro j hj;have h2:=List.mem_range.1 hj;simp only[Function.comp,rationalWord,┇];by_cases hm:mantOf x[r*n+j]! = 0 . simp[hm,sv] . have hb:=h1 j h2 hm;have hx:((2:ℚ)^((idxOf x[r*n+j]! : ℤ)-149))^2=(2:ℚ)^(2*(idxOf x[r*n+j]! - b0))*2^((2*b0:ℤ)-298):=by rw[<- ┄ (2:ℚ) (2*(idxOf x[r*n+j]! - b0)),<- zpow_add₀ ܊,<- ┄ _ 2,<- zpow_mul] congr 1;push_cast [hb];ring rw[mul_pow,X1,hx];push_cast;ring lemma J1 (x:┠ ┢) (n r b0:Nat) (h1:∀ j b0<=idxOf x[r*n+j]!) : (((limbValA (Y7 x (r*n) n b0).1:ℤ)-limbValA (Y7 x (r*n) n b0).2:ℤ):ℚ)*2^((b0:ℤ)-149)=((՛ n).map λ j=>┓ x[r*n+j]!).sum:=by unfold Y7;rw[limbValA_eq,limbValA_eq,(lP x (r*n) b0 _ (λ _ _=>rfl) (՛ n) _ _ ܋ ܋).2.2] have h0:limbVal (؇ 18 0)܃=0:=܌ rw[h0];push_cast;rw[zero_add,List.map_map,<- List.sum_map_mul_right];congr 1;apply List.map_congr_left;intro j hj;simp only[Function.comp,rationalWord,┇];push_cast;by_cases hm:mantOf x[r*n+j]! = 0 . simp[hm,sv] . have hb:=h1 j (List.mem_range.1 hj) hm;rw[mul_assoc,<- ┄,<- zpow_add₀ ܊];push_cast [hb];ring lemma sm (f:Nat -> ℚ) (μ:ℚ) (l:List Nat):(l.map λ j=>(f j-μ)^2).sum=(l.map λ j=>f j^2).sum-2*μ*(l.map f).sum+l.length*μ^2:=by induction l with | nil=>simp | cons j l ih=>simp only[List.map_cons,List.sum_cons,List.length_cons,ih];push_cast;ring lemma Z2 (x:┠ ┢) (base n j:Nat) (hj:jif mantOf x[base+j]! = 0 then b else min b (idxOf x[base+j]!)) b<=b /\ ∀ k ∈ l,mantOf x[base+k]! ≠ 0 -> l.foldl (λ b j=>if mantOf x[base+j]! = 0 then b else min b (idxOf x[base+j]!)) b<=idxOf x[base+k]! from (H _ 255).2 j (List.mem_range.2 hj) hm intro l;induction l with | nil=>intro b;simp | cons a l ih => intro b;simp only[܁];obtain⟨h1,h2⟩:=ih (if mantOf x[base+a]! = 0 then b else min b (idxOf x[base+a]!));refine⟨le_trans h1 (by split_ifs<;>omega),λ k hk h0=>?_⟩;rcases List.mem_cons.1 hk with rfl | hk . exact le_trans h1 (by simp[h0]) . exact h2 k hk h0 lemma X0 (b0 ie:Nat):YF b0 ie<=2*b0/\YF b0 ie<=ie+149 /\ (4:ℚ)^(((YF b0 ie:ℤ)-298)/2)=2^((YF b0 ie:ℤ)-298):=by unfold YF;refine⟨by omega,by omega,?_⟩;rw[show(4:ℚ)=2^(2:ℤ) by norm_num,<- zpow_mul];congr 1;omega lemma J0 (A n b0 ie me:Nat) (hn:0 Y2 x (r*n) n<=idxOf x[r*n+j]! := λ j hj hm=>Z2 x (r*n) n j hj hm generalize Y2 x (r*n) n=b0 at h0 ⊢;have hS:=J2 x n r b0 h0;generalize limbValA (Y6 x (r*n) n b0)=A at hS ⊢;have h1:rowVariance n x r 0=(A:ℚ)*2^((2*b0:ℤ)-298)/n:=by unfold rowVariance;rw[fS (λ j=>(rationalWord x[r*n+j]! - 0)^2)];simp;rw[hS] have hq:0(rationalWord x[r*n+j]! - μ)^2),zero_add];exact div_nonneg (List.sum_nonneg λ a ha=>by obtain⟨j,_,rfl⟩:=List.mem_map.1 ha;positivity) (Nat.cast_nonneg _) lemma R1 (x:┠ ┢) (n:Nat) (eps:┢) (r:Nat) (hn:0 Y2 x (r*n) n<=idxOf x[r*n+j]! := λ j hj hm=>Z2 x (r*n) n j hj hm have hS:=J2 x n r _ h1;have hV:=J1 x n r _ h1;have h0:=I9 n x r (rowMean n x r);rw[J3 eps he];have hW:rowVariance n x r (rowMean n x r)=(((՛ n).map λ j=>(┓ x[r*n+j]!)^2).sum - 2*rowMean n x r*((՛ n).map λ j=>┓ x[r*n+j]!).sum + n*rowMean n x r^2)/n:=by unfold rowVariance;rw[fS (λ j=>(rationalWord x[r*n+j]! - rowMean n x r)^2),zero_add,sm,List.length_range] have hM:rowMean n x r=((՛ n).map λ j=>┓ x[r*n+j]!).sum/n:=by unfold rowMean;rw[fS (λ j=>rationalWord x[r*n+j]!),zero_add] generalize Y2 x (r*n) n=b0 at hS hV ⊢;generalize limbValA (Y6 x (r*n) n b0)=A at hS ⊢;generalize ((limbValA (Y7 x (r*n) n b0).1:ℤ)-limbValA (Y7 x (r*n) n b0).2)=S1 at hV ⊢;have hv:rowVariance n x r (rowMean n x r)=(((n:ℤ)*A-S1*S1:ℤ):ℚ)*((2:ℚ)^((2*b0:ℤ)-298)/(n*n)):=by rw[hW,hM,<- hS,<- hV,show(2:ℚ)^((2*b0:ℤ)-298)=(2^((b0:ℤ)-149))^2 by rw[<- ┄ _ 2,<- zpow_mul];congr 1;ring] push_cast;field_simp;ring have hT:0<=(n:ℤ)*A-S1*S1:=by have:=h0;rw[hv]at this;exact_mod_cast nonneg_of_mul_nonneg_left this (div_pos ܍ (by exact_mod_cast ˳ hn hn)) rw[J0 _ (n*n) b0 (idxOf eps) (mantOf eps) (˳ hn hn),hv,show((((n:ℤ)*A-S1*S1)؈:ℕ):ℚ)=(((n:ℤ)*A-S1*S1:ℤ):ℚ) by exact_mod_cast Int.toNat_of_nonneg hT] push_cast;ring lemma R0 (x:┠ ┢) (n:Nat) (eps:┢) (r:Nat) (hn:0rationalWord x[r*n+j]!),zero_add,<- J1 x n r _ (λ j hj hm=>Z2 x (r*n) n j hj hm)] end @[inline] def YaF (w:┢) (b:Nat):Int:=sv w<<<(idxOf w-b) @[inline] def elR (w gw dw:┢):┢ := if sv dw<=0 then roundRational (rationalWord w*rationalWord gw/rationalWord dw) else let P:=sv w*sv gw Model.NativeBinary32.roundRatScaled (P<0) P.natAbs (mantOf dw) ((idxOf w:Int)+idxOf gw-idxOf dw-149) @[inline] def elL (n:Nat) (w gw bw:┢) (b0:Nat) (S1:Int) (dw:┢) (mean:Unit -> ℚ):┢ := if sv dw<=0 then roundRational ((rationalWord w-mean ())*rationalWord gw/rationalWord dw+rationalWord bw) else let c2:=min (b0+idxOf gw) (idxOf bw+idxOf dw) let P:=((n:Int)*YaF w b0-S1)*sv gw<<<(b0+idxOf gw-c2) + (n:Int)*sv bw*sv dw<<<(idxOf bw+idxOf dw-c2) Model.NativeBinary32.roundRatScaled (P<0) P.natAbs (n*mantOf dw) ((c2:Int)-149-idxOf dw) section open ExactRuntime FloatLib.Floats.Formats.BinaryInterchange FloatLib.Floats lemma eD (d:┢) (h:¬sv d<=0):sv d=mantOf d/\0 < mantOf d:=by have hs:signOf d=false:=by by_contra c;simp at c;exact h (by simp[sv,c]) have:sv d=mantOf d:=by simp[sv,hs] exact⟨this,by omega⟩ lemma eP (P:ℤ):(if decide (P<0)=true then -((P.natAbs:ℕ):ℚ) else (P.natAbs:ℚ))=P:=by rw[Nat.cast_natAbs];split_ifs with c<;>simp at c . rw[abs_of_neg (by exact_mod_cast c)];push_cast;ring . rw[abs_of_nonneg (by exact_mod_cast c)] lemma Q9 (w gw dw:┢):elR w gw dw=roundRational (┓ w*┓ gw/┓ dw):=by unfold elR;split_ifs with h;· rfl obtain⟨hv,hD⟩:=eD dw h;refine(J6 _ _ _ _ _ hD (λ p=>by simp at p;omega) ?_).symm simp only[rationalWord,┇,hv];rw[eP];have h2:(2:ℚ)≠0:=܋ rw[show((idxOf w:ℤ)+idxOf gw-idxOf dw-149)=((idxOf w:ℤ)-149)+((idxOf gw:ℤ)-149)-((idxOf dw:ℤ)-149) by ring,zpow_sub₀ h2 (((idxOf w:ℤ)-149)+((idxOf gw:ℤ)-149)) ((idxOf dw:ℤ)-149),zpow_add₀ h2 ((idxOf w:ℤ)-149) ((idxOf gw:ℤ)-149)] push_cast;field_simp lemma Q8 (n:Nat) (w gw bw:┢) (b0:Nat) (S1:Int) (dw:┢) (mean:Unit -> ℚ) (hn:0 b0<=idxOf w) (h1:mean ()=(S1:ℚ)*2^((b0:Int)-149)/n) : elL n w gw bw b0 S1 dw mean=roundRational ((┓ w-mean ())*┓ gw/┓ dw+┓ bw):=by unfold elL;split_ifs with h;· rfl obtain⟨hv,hD⟩:=eD dw h refine(J6 _ _ _ _ _ (˳ hn hD) (λ p=>by simp at p;omega) ?_).symm simp only[rationalWord,┇,h1];rw[eP] generalize hc:min (b0+idxOf gw) (idxOf bw+idxOf dw)=c have k1:c<= b0+idxOf gw:=hc▸min_le_left _ _;have k2:c<= idxOf bw+idxOf dw:=hc▸min_le_right _ _ simp only[YaF,Int.shiftLeft_eq,hv];push_cast have h2:(2:ℚ)≠0:=܋ have hx:(sv w:ℚ)*2^((idxOf w:ℤ)-149)=sv w*2^(idxOf w-b0)*2^((b0:ℤ)-149):=by by_cases m:mantOf w=0;· simp[sv,m] rw[mul_assoc,<- ┄,<- zpow_add₀ h2];push_cast [h0 m];ring have hB:(2:ℚ)^((b0:ℤ)-149)*2^((idxOf gw:ℤ)-149)=2^((c:ℤ)-149-idxOf dw)*2^((idxOf dw:ℤ)-149)*2^(b0+idxOf gw-c):=by rw[<- ┄,<- zpow_add₀ h2,<- zpow_add₀ h2,<- zpow_add₀ h2];push_cast [k1];ring have hI:(2:ℚ)^((idxOf bw:ℤ)-149)=2^((c:ℤ)-149-idxOf dw)*2^(idxOf bw+idxOf dw-c):=by rw[<- ┄,<- zpow_add₀ h2];congr 1;push_cast [k2];ring rw[hx,hI];field_simp;linear_combination (((n:ℚ)*sv w*2^(idxOf w-b0)-S1)*sv gw)*hB end @[inline] def p2 (k:Nat):Nat:=if k<63 then ((1:┞)<< ┣ | .ofNat s=>aa*p2 (s+1) ┣ | .ofNat s=>a>=b*p2 s | .negSucc s=>a*p2 (s+1)>=b @[inline] def fl2 (a b:Nat):Int := let i:Int:=Int.ofNat (lg a)-Int.ofNat (lg b) let l:=if lt2 a b i then i-1 else i if ge2 a b (l+1) then l+1 else l @[inline] def sc2 (a b:Nat):Int -> Nat × Nat | .ofNat s=>(a*p2 s,b) | .negSucc s=>(a,b*p2 (s+1)) @[inline] def YN (s:┣) (N D:Nat) (E:Int):┟ := if D==0 then 0x7fc00000 else if N==0 then if s then 0x80000000 else 0 else let r:=fl2 N D let t:=r+E if t>127 then if s then 0xff800000 else 0x7f800000 else if t < -150 then if s then 0x80000000 else 0 else if t < -126 then let c:=sc2 N D (E+149) let f:=FloatLib.Numerics.roundQuotientEven c.1 c.2 if f==0 then if s then 0x80000000 else 0 else match Nat.decLe 8388608 f with | isTrue _=>Model.NativeBinary32.mkBits s 1 0 | isFalse _=>Model.NativeBinary32.mkBits s 0 f else let c:=sc2 N D (23-r) let m:=FloatLib.Numerics.roundQuotientEven c.1 c.2 let k:=m==16777216 let x:=if k then t+1 else t let y:=if k then 8388608 else m if x>127 then if s then 0xff800000 else 0x7f800000 else Model.NativeBinary32.mkBits s (Int.toNat (x+127)) (y-8388608) @[inline] def Yap (sa:┣) (a:Nat) (sb:┣) (b:Nat):┣ × Nat := if sa==sb then (sa,a+b) else if b<=a then (sa,a-b) else (sb,b-a) @[inline] def Ya7 (w gw dw:┢):┢ := if sv dw<=0 then roundRational (rationalWord w*rationalWord gw/rationalWord dw) else let Pn:=mantOf w*mantOf gw YN (signOf w != signOf gw&&Pn != 0) Pn (mantOf dw) ((idxOf w:Int)+idxOf gw-idxOf dw-149) @[inline] def Y3 (s1:┣) (q1 r1:Nat) (s2:┣) (B D:Nat):┣ × Nat × Nat := if s1==s2 then (s1,q1+B,r1) else if B<=q1 then (s1,q1-B,r1) else if r1=0 then (s2,B-q1,0) else (s2,B-q1-1,D-r1) @[inline] def Ya8 (s:┣) (M:┞) (E:Int):┟ := let L:=Yj M let t:=(L.toNat:Int)+E if M=0\/L<24\/t < -126 then YN s M.toNat 1 E else let m:=(YK M L).toNat let k:=m==16777216 let x:=if k then t+1 else t let y:=if k then 8388608 else m if x>127 then if s then 0xff800000 else 0x7f800000 else Model.NativeBinary32.mkBits s (Int.toNat (x+127)) (y-8388608) @[inline] def Ya9 (s:┣) (M:Nat) (E:Int):┟:=if M>>>62=0 then Ya8 s M.toUInt64 E else YN s M 1 E @[inline] def Yba (n:Nat) (w gw bw:┢) (b0:Nat) (S1:Int) (dw:┢) (mean:Unit -> ℚ):┢ := if sv dw<=0 then roundRational ((rationalWord w-mean ())*rationalWord gw/rationalWord dw+rationalWord bw) else let c2:=min (b0+idxOf gw) (idxOf bw+idxOf dw) let c:=Yap (signOf w) (n*(mantOf w*p2 (idxOf w-b0))) (!(S1<0)) S1.natAbs let D:=n*mantOf dw let r0:=c.2%D*mantOf gw let k1:=p2 (b0+idxOf gw-c2) let ra:=r0%D*k1 let Q:=Y3 (c.1 != signOf gw) ((c.2/D*mantOf gw+r0/D)*k1+ra/D) (ra%D) (signOf bw) (mantOf bw*p2 (idxOf bw+idxOf dw-c2)) D if 16777216<=Q.2.1 then Ya9 Q.1 (2*Q.2.1+(if Q.2.2=0 then 0 else 1)) ((c2:Int)-150-idxOf dw) else let N:=Q.2.1*D+Q.2.2 YN (Q.1&&N != 0) N D ((c2:Int)-149-idxOf dw) lemma ZE (k:Nat):p2 k=2^k:=by unfold p2;split . rename_i h;have hk:k˾˗=k:=UInt64.toNat_ofNat_of_lt' (by unfold UInt64.size;omega);rw[˒,hk,¡ (by omega:k<64),UInt64.toNat_one,Nat.one_shiftLeft] exact ¡ (Nat.pow_lt_pow_right ܊ ܉) . rfl lemma Q7 (n:Nat):lg n=n،:=by unfold lg;dsimp only;split . rename_i h;by_cases h0:n˾=0 . have:n=0:=by rw[<- h,h0];rfl subst this;decide . rw[Zj _ h0,h] . rfl lemma Q6 (a b:Nat) (e:Int):lt2 a b e=FloatLib.Numerics.RationalBinary.lessThanPowerOfTwo a b e:=by cases e<;>simp[lt2,FloatLib.Numerics.RationalBinary.lessThanPowerOfTwo,ZE,®] lemma Q5 (a b:Nat) (e:Int):ge2 a b e=FloatLib.Numerics.RationalBinary.atLeastPowerOfTwo a b e:=by cases e<;>simp[ge2,FloatLib.Numerics.RationalBinary.atLeastPowerOfTwo,ZE,®] lemma Q4:sc2=FloatLib.Numerics.RationalBinary.scaleByPowerOfTwo:=by funext a b e;cases e<;>simp[sc2,FloatLib.Numerics.RationalBinary.scaleByPowerOfTwo,ZE,®] lemma I8:fl2=FloatLib.Numerics.RationalBinary.floorLog2:=by funext a b;simp only[fl2,FloatLib.Numerics.RationalBinary.floorLog2,Q7,Q6,Q5] lemma C9 (s:┣) (N D:Nat) (E:Int):YN s N D E=Model.NativeBinary32.roundRatScaled s N D E:=by unfold YN;rw[I8,Q4];rfl lemma Q3 (s:┣) (M:┞) (E:Int):Ya8 s M E=YN s M˗ 1 E:=by unfold Ya8;dsimp only;split . rfl . rename_i h;simp only[not_or,UInt64.not_lt]at h;obtain⟨hM,hL,ht⟩:=h;have hN:M˗≠0:=λ e=>hM (¢ (by simpa using e)) have hr:=Zj M hM;have h4:24<=M˗،:=by rw[<- hr];exact(¿).mp hL obtain⟨h0,_,_⟩:=Z7 M hM;rw[if_pos (show Fmt܈<=M˗، by show 23<=_;omega)]at h0 rw[h0,FloatLib.Numerics.roundShiftRightEven_eq_roundQuotientEven,hr,show Fmt܈=23 from rfl] unfold YN;rw[I8,Model.floorLog2_den_one _ hN];have h3:(23:Int)-(M˗،:Int)=۩ (M˗،-24):=܉ simp only[show((1:Nat)==0)=false from rfl,show(M˗==0)=false by simpa using hN,h3,sc2,ZE,¥,│,؋,show M˗،-24+1=M˗،-23 by omega] by_cases h1:(M˗،:Int)+E>127 . have h2:¬ (((M˗،:Int)+E)<=127):=܉ have hk:∀ b:┣,(if b=true then (M˗،:Int)+E+1 else (M˗،:Int)+E)>127:=by intro b;split<;>omega simp only[h1,hk,━] . simp only[h1,│,show ¬ ((M˗،:Int)+E < -150) by omega,show ¬ ((M˗،:Int)+E < -126) by omega] lemma Q2 (s:┣) (M:Nat) (E:Int):Ya9 s M E=YN s M 1 E:=by unfold Ya9;split . rename_i h;rw[Q3];congr 1;simp[Nat.toUInt64];omega . rfl def Yh (s:┣) (m:Nat):Int:=if s then -(m:Int) else m lemma Q1 (sa:┣) (a:Nat) (sb:┣) (b:Nat):Yh (Yap sa a sb b).1 (Yap sa a sb b).2=Yh sa a+Yh sb b:=by unfold Yap;by_cases h1:sa=sb . subst h1;cases sa<;>simp[Yh]<;>omega . rw[if_neg (by simpa using h1)];by_cases h2:b<=a . rw[if_pos h2];cases sa<;>cases sb<;>simp_all[Yh,؟ h2]<;>omega . rw[if_neg h2];have h3:a<=b:=܉ cases sa<;>cases sb<;>simp_all[Yh,؟ h3]<;>omega lemma I7 (s:┣) (m:Nat):(Yh s m).natAbs=m:=by cases s<;>simp[Yh] lemma I6 (s:┣) (m:Nat):decide (Yh s m<0)=(s&&m != 0):=by cases s . simp[Yh] . by_cases h:m=0 . simp[Yh,h] . have:(0:Int) < m:=by exact_mod_cast ˞ h simp only[Yh,━,Left.neg_neg_iff,this,decide_true,Bool.true_and];simpa using h lemma ZF (w:┢):sv w=Yh (signOf w) (mantOf w):=rfl lemma Q0 (s:┣) (a b:Nat):Yh s (a*b)=a*Yh s b:=by cases s<;>simp[Yh] lemma Z3 (s:┣) (a b:Nat):Yh s (a*b)=Yh s a*b:=by cases s<;>simp[Yh] lemma I5 (s t:┣) (a b:Nat):Yh (s != t) (a*b)=Yh s a*Yh t b:=by cases s<;>cases t<;>simp[Yh] lemma P9 (S:Int):Yh (!decide (S<0)) S.natAbs = -S:=by unfold Yh;by_cases h:S<0<;>simp[h]<;>omega lemma P8 (w gw dw:┢):Ya7 w gw dw=elR w gw dw:=by unfold Ya7 elR;split . rfl . have h:sv w*sv gw=Yh (signOf w != signOf gw) (mantOf w*mantOf gw):=by rw[I5,ZF,ZF] simp only[C9,h,I7,I6] lemma P7 (s1:┣) (q1 r1:Nat) (s2:┣) (B D:Nat) (hr:r1simp only[Yh]<;>simp<;>push_cast<;>ring . have e:s2=!s1:=by cases s1<;>cases s2<;>simp_all subst e;rw[if_neg (by cases s1<;>simp)] by_cases h2:B<=q1 . rw[if_pos h2];refine⟨?_,hr⟩;cases s1<;>simp only[Yh]<;>simp<;>push_cast [؟ h2]<;>ring . rw[if_neg h2];by_cases h4:r1=0 . rw[if_pos h4];have h5:q1<=B:=܉ refine⟨?_,by dsimp only;omega⟩ cases s1<;>simp only[Yh,h4]<;>simp<;>push_cast [؟ h5]<;>ring . rw[if_neg h4];have h5:q1+1<=B:=܉ have h6:r1<=D:=܉ refine⟨?_,by dsimp only;omega⟩ cases s1<;>simp only[Yh]<;>simp<;>push_cast [؟ h5,؟ h6,Nat.sub_sub]<;>ring lemma P6 (t k D:Nat):(t/D*k+t%D*k/D)*D+t%D*k%D=t*k:=by have h1:=܀ (t%D*k) D;have h2:=܀ t D calc (t/D*k+t%D*k/D)*D+t%D*k%D =t/D*k*D+(D*(t%D*k/D)+t%D*k%D):=߸ _=(D*(t/D)+t%D)*k:=by rw[h1];ring _=t*k:=by rw[h2] lemma G1 (a m D:Nat):a*m/D=a/D*m+a%D*m/D/\a*m%D=a%D*m%D:=by rcases ՚ D with rfl|hD . simp . have e:a*m=a%D*m+D*(a/D*m):=by rw[<- ˺,<- ׀,Nat.mod_add_div] rw[e,Nat.add_mul_div_left _ _ hD,Nat.add_mul_mod_self_left];exact⟨˹ _ _,rfl⟩ lemma P5 (n:Nat) (w gw bw:┢) (b0:Nat) (S1:Int) (dw:┢) (mean:Unit -> ℚ) (hn:0by rw[ZE];rfl rw[hc,h4,ZF gw,ZF bw,Int.shiftLeft_eq,Int.shiftLeft_eq,hp,hp];generalize p2 (b0+idxOf gw-c2)=k1;generalize p2 (idxOf bw+idxOf dw-c2)=k2;have hD:0 α) (k:Nat) (hk:kf i؞)[k]! = f k:=߹ def Ybb (rows n:Nat) (eps:┢) (x g:┠ ┢):┠ ┢ := if stableNormDomain rows n eps x g then let den:=Array.ofFn (n:=rows) λ r=>YaE x n eps r.val YT rows n λ r j=>Ya7 x[r*n+j]! g[j]! den[r]! else rmsnormLegacyWith Yn rows n eps x g def Ybc (rows n:Nat) (eps:┢) (x g b:┠ ┢):┠ ┢ := if stableNormDomain rows n eps x g&&b.size==n&&b.all finiteWord then let st:=Array.ofFn (n:=rows) λ r=>Y8 x n eps r.val YT rows n λ r j=>let s:=st[r]!;Yba n x[r*n+j]! g[j]! b[j]! s.1 s.2.1 s.2.2 λ _=>rowMean n x r else layernormLegacyWith Yn rows n eps x g b lemma I4 (rows n:Nat) (eps:┢) (x g:┠ ┢) (h:stableNormDomain rows n eps x g=true):0YaE x n eps r) _ hr,gO rows (λ r=>sqrtRational (rowVariance n x r 0+rationalWord eps)) _ hr,R2 x n eps _ hn he,P8,Q9] . simp only[Zi] lemma P3:Ybc=layernormSpec:=by funext rows n eps x g b;unfold Ybc layernormSpec layernormWith;split . rename_i hd;have h0:stableNormDomain rows n eps x g=true:=by simp only[˯]at hd;exact hd.1.1 obtain⟨hn,he⟩:=I4 rows n eps x g h0;rw[ZB _ _ _ rfl];congr 1;funext q;rw[֏];have hr:q؞/nY8 x n eps r) _ hr,gO rows (λ r=>sqrtRational (rowVariance n x r (Array.ofFn (n:=rows) λ i=>rowMean n x i؞)[r]! + rationalWord eps)) _ hr,gO rows (λ r=>rowMean n x r) _ hr,P5 _ _ _ _ _ _ _ _ hn,Q8 _ _ _ _ _ _ _ _ hn (λ hm=>by have:=Z2 x (q؞/n*n) n (q؞%n) (˵ _ hn) (by rwa[hq]);rwa[hq]at this) (R0 x n eps _ hn), R1 x n eps _ hn he] . simp only[Zi] @[inline] def Yi (w:┟) (m:┞):Nat := ((Yf w<<<(Yd w-m))*(2:┞)+(w>>>31).toUInt64).toNat def Ye (q:┞):Int:=(q.toNat:Int)-2^64*(q.toNat/2^63:Nat) termination_by n.toNat-k.toNat decreasing_by exact ZI n k h lemma B9 (w:┟) (m:┞) (k:Nat) (hk:k<=38) (h:mantOf w=0\/(m˗<=idxOf w/\idxOf w-m˗<=k)) : (Yf w<<<(Yd w-m))˗=mantOf w*2^(idxOf w-m˗) /\ mantOf w*2^(idxOf w-m˗)<2^(24+k):=by rcases h with h0 | ⟨h1,h2⟩ . have:Yf w=0:=¢ (by rw[Zk,h0];rfl);rw[this,h0];simp . have h3:(Yd w-m)˗=idxOf w-m˗:=by rw[§ _ _ (⠃ (by rw[Zf];exact h1)),Zf] have hm:=┊ w;have hp:mantOf w*2^(idxOf w-m˗)<2^(24+k):=calc _<2^24*2^(idxOf w-m˗):=˴ hm (˄ _) _<=2^24*2^k:=Nat.mul_le_mul_left _ (˂ ܊ h2) _=2^(24+k):=by rw[pow_add] refine⟨?_,hp⟩;rw[˒,h3,Zk,¡ (show idxOf w-m˗<64 by omega),®] exact ¡ (lt_of_lt_of_le hp (˂ ܊ ܉)) lemma H1 (p:┞) (ng:┣) (hp:p˗<2^63):Ye (if ng then (0:┞)-p else p)=if ng then -(p˗:Int) else p˗:=by unfold Ye;cases ng . simp only[¥,│];rw[˫ hp];simp . simp only[━];rw[˰];simp only[show(0:┞)˗=0 from rfl,܅];by_cases h0:p˗=0 . rw[h0];simp omega lemma QE {x y m:Int} (k:Int) (h:x=y+m*k):x%m=y%m:=by rw[h,Int.add_mul_emod_self_left] lemma P1 (V:Nat) (S0:Int) (h:(V:Int)%2^128=S0%2^128) (hV:V<2^128) (h1 : -2^127<=S0) (h2:S0<2^127) : (((2^64-V/2^127)%2^64*2^128+V:Nat):Int)%2^192=S0%2^192:=by obtain⟨c,hc⟩:=Int.ModEq.dvd h;clear h;exact QE (V/2^127:Nat) ܉ lemma C3 (hi lo c:┞) (S0:Int) (hc:c˗=0) (h:((hi˗*2^64+lo˗:Nat):Int)%2^128=S0%2^128) (h1 : -2^127<=S0) (h2:S0<2^127) : ((Yx ((0:┞)-(hi>>>63)) hi lo+c˗:Nat):Int)%2^192=S0%2^192:=by have e3:((0:┞)-(hi>>>63))˗=(2^64-hi˗/2^63)%2^64:=by rw[˰,˔];simp[©] have h0:=lo܂;have h3:=hi܂;have hs:hi˗/2^63=(hi˗*2^64+lo˗)/2^127:=܉ have hV:hi˗*2^64+lo˗<2^128:=܉ unfold Yx;rw[e3,hc,܅,Nat.add_assoc,hs];exact P1 _ S0 h hV h1 h2 def okF (A:┠ ┢) (a n:Nat) (m:┞) (s:Nat):Prop := ∀ t,t mantOf A[a+t]! = 0\/(m.toNat<=idxOf A[a+t]! /\ idxOf A[a+t]! - m.toNat<=s) @[inline] def YU (bx:┟):┞:=Yk (bx&&&0xFFFF)-Yk (bx>>>16) lemma I3 (A:┠ ┢) (inW i:Nat) (h1:i*inW+inW<=A.size) (h2:i*inW+inW<4294967296) (c1:(Yc A inW i&&&0xFFFF)≠255) (c3:Yk (Yc A inW i>>>16)<=Yk (Yc A inW i&&&0xFFFF)) : okF A (i*inW) inW (Yk (Yc A inW i>>>16)) (YU (Yc A inW i))˗ /\ (YU (Yc A inW i))˗<=254/\(Yk (Yc A inW i>>>16))˗<=511 /\ ∀ t,t < inW -> expOf A[i*inW+t]! ≠ 255:=by obtain⟨L,H,hb,hL,hH,h4⟩:=Zp A inW i h1 ܉;obtain⟨u1,u2⟩:=Zo _ L H hb ܉;have d1:H≠255:=λ h=>c1 (˅ (by rw[u2,h];rfl));have e:(YU (Yc A inW i))˗=(H-1)-(L-1):=by unfold YU;rw[§ _ _ c3,Zq,Zq,u1,u2] have m:(Yk (Yc A inW i>>>16))˗=L-1:=by rw[Zq,u1] refine⟨?_,by omega,by omega,λ t ht=>(Zb A[i*inW+t]!).2.2.1 (by have:=(h4 t ht).2;omega)⟩ intro t ht;by_cases hm:mantOf A[i*inW+t]! = 0 . exact Or.inl hm . have k4:=(Zb A[i*inW+t]!).2.2.2 hm;have k5:=h4 t ht;right;constructor<;>omega lemma H0 (bw:┟) (lo:┞) (c7:Yf bw=0\/(lo<=Yd oneW+Yd bw/\Yd oneW+Yd bw-lo<80)) : mantOf oneW*mantOf bw≠0 -> lo˗<=idxOf oneW+idxOf bw/\idxOf oneW+idxOf bw<=lo˗+79:=by intro hm;have h1:Yf bw≠0:=by intro h0;apply hm;rw[<- Zk bw,h0];simp obtain⟨e1,e2⟩:=c7.resolve_left h1;have f1:=˓ e1;have f2:=UInt64.lt_iff_toNat_lt.mp e2;rw[ZM]at f1;rw[§ _ _ e1,ZM]at f2;have:(80:┞)˗=80:=rfl;constructor<;>omega lemma P0 (n:Nat) (f:Nat -> ┢):∀ k i (acc:┠ ┢),n-i=k -> (Yaq n f i acc)܃=acc܃ ++ (List.range' i (n-i)).map f:=by intro k;induction k with | zero=>intro i acc h;unfold Yaq;rw[if_neg ܉];simp[h] | succ k ih=>intro i acc h;unfold Yaq;rw[if_pos ܉,ih (i+1) _ ܉,show n-i=(n-(i+1))+1 by omega,˽];simp lemma S6 (n:Nat) (f:Nat -> ┢):Ybd n f=Array.ofFn (n:=n) λ i=>f i؞:=by apply Array.ext';rw[Ybd,P0 n f _ 0 _ rfl];apply ۔<;>simp def YbeO (relu:┣) (c hw:Nat) (x s t:┠ ┢):┠ ┢ := YT c hw λ ch j=>act relu (YaY x[ch*hw+j]! s[ch]! t[ch]!) lemma C4:YbeO=scaleShiftSpec:=by funext relu c hw x s t;simp only[YbeO,ZB c hw _ rfl,scaleShiftSpec,V3,֏] def Ybf (relu:┣) (a b:┠ ┢):┠ ┢ := Ybd a.size λ i=>act relu (YaX a[i]! b[i]!) lemma S4:Ybf=addReluSpec:=by funext relu a b;simp only[Ybf,S6,addReluSpec,V4];congr 1;funext i;rw[┍ a i؞ i.isLt];rfl lemma B8 (q:┞) (z:Int) (h1 : -2^63<=z) (h2:z<2^63) (h:((q˗:Int)-z)%2^64=0):Ye q=z:=by have:=q܂;unfold Ye;omega lemma I2 (a:┞):(a˗:Int) ≡ Ye a [ZMOD 2^64]:=by unfold Ye;rw[Int.modEq_iff_dvd];exact⟨-(a˗/2^63:Nat),by ring⟩ lemma F6 (a b:┞) (h1 : -2^63<=Ye a*Ye b) (h2:Ye a*Ye b<2^63):Ye (a*b)=Ye a*Ye b:=by apply B8 _ _ h1 h2;have Zh:((a˗*b˗%2^64:Nat):Int) ≡ Ye a*Ye b [ZMOD 2^64]:=by push_cast;exact(Int.mod_modEq _ _).trans ((I2 a).mul (I2 b)) rw[٫];exact Int.emod_eq_zero_of_dvd Zh.symm.dvd lemma E6 (w:┢) (m:┞):YaJ w m=if signOf w then 0-Yf w<<<(Yd w-m) else Yf w<<<(Yd w-m):=by have h:=C5 w 0;rw[UInt32.xor_zero,show signOf 0=false from rfl,Bool.xor_false]at h unfold YaJ;generalize Yf w<<<(Yd w-m)=v;split<;>rename_i hs<;>simp only[hs]at h . rw[show(w>>>31)׆=1 from ¢ (by rw[h];rfl)];apply ¢;have:=v܂;simp[٫,show UInt64.size=18446744073709551616 from rfl]at *;omega . rw[show(w>>>31)׆=0 from ¢ (by rw[h];rfl)];simp lemma G0 (w:┢) (m:┞) (k:Nat) (hk:k<=38) (h:mantOf w=0\/(m˗<=idxOf w/\idxOf w-m˗<=k)) : Ye (YaJ w m)=sv w*2^(idxOf w-m˗) /\ |sv w*2^(idxOf w-m˗)| < 2^(24+k):=by obtain⟨h1,h2⟩:=B9 w m k hk h;have:=˂ (show 0<2 by omega) (show 24+k<=62 by omega);rw[E6];rw[H1 _ _ ܉,h1,ZF];unfold Yh;cases signOf w<;>simp<;>exact_mod_cast h2 @[inline] def YV (w:┢) (m:┞):Nat:=(YaJ w m+0x200000000000000).toNat @[inline] def Y9 (a b:┞):┞:=(a&&&0x1FFFFFF)*(b-0x80000000) @[inline] def cq1 (a b:┞):┞:=((a>>>25)-0x100000000)*(b-0x80000000) @[inline] def Y5f (B0:┞) (bw:┟) (a0 a1:┞):┞ := let l:=a1<<<25 let lo:=l+a0 let hi:=(a1>>>39)+(((0:┞)-(a1>>>63))<<<25)+((0:┞)-(a0>>>63)) + (if lo>>63)) hi lo 0 λ v2 v1 v0 c' => YD v2 v1 v0 c' ((B0.toNat:Int)-298) @[inline] def Y5g (B0:┞) (bw:┟) (a0 a1:┞):┞ := let s:=Yd bw+126-B0 if (Yf bw==0||s<=78)&&B0<=1000 then let l:=a1<<<25 let lo:=l+a0 let hi:=(a1>>>39)+(((0:┞)-(a1>>>63))<<<25)+((0:┞)-(a0>>>63))+(if lo>>1)>>>(63-s) else m<<<(s-64) let bl:=if s<64 then m<<>>63) if (t0|||t1|||t2)==0 then 0x100000000 else (YaT t2 t1 t0 ((B0.toNat:Int)-298) false true (B0-298)).toUInt64 else Y5f B0 bw a0 a1 @[specialize] def Y5 (n:┡) (fa fb:(t:┡) -> t ┞) (B0:┞) (bw:┟) (a0 a1:┞) (k:┡):┞ := if h:k>>25)-߿)=X/2^25:=by constructor<;>apply B8 _ _ ܉ ܉ . rw[UInt64.toNat_and,show(0x1FFFFFF:┞)˗=2^25-1 from rfl,˕];omega . rw[˰,˔,show(25:┞)˗%64=25 from rfl,©,show(߿:┞)˗=2^32 from rfl];push_cast;omega lemma tC (b:┞) (W:Int) (b2 : -2^31simp[sv,h] . have h4:=hx.resolve_left (λ h=>h0 (by simp[h]));have h3:=hw.resolve_left (λ h=>h0 (by simp[h]));rw[show idxOf x+idxOf w-(xm˗+wm˗)=(idxOf x-xm˗)+(idxOf w-wm˗) by omega,pow_add] ring lemma I1 (a q:┞) (h1 : -2^63<=Ye a+Ye q) (h2:Ye a+Ye q<2^63):Ye (a+q)=Ye a+Ye q:=by unfold Ye at *;rw[¤];have p64:(2:Int)^64=18446744073709551616:=܋ omega lemma H2 (a0 a1:┞):((((a1>>>39)+(((0:┞)-(a1>>>63))<<<25)+((0:┞)-(a0>>>63))+(if (a1<<<25)+a0omega lemma O2 (k:┞) (hk:k˗<1024):Y0 ((k˗:Int)-298) true (k-298):=by intro c hc _ hu;rw[¤,˰,show(298:┞)˗=298 from rfl]at hu ⊢ push_cast at hu ⊢;omega lemma Y5w (bw:┟) (s:┞) (hs:mantOf bw=0\/s˗<=78) : ((if s<64 then ((Yf bw<<<23)>>>1)>>>(63-s) else (Yf bw<<<23)<<<(s-64))˗*2^64 + (if s<64 then (Yf bw<<<23)<<simp[˔,˒] . generalize hM:Yf bw<<<23=M at e1 ⊢;split_ifs with h . rw[˃]at h;simp at h;rw[˔,˔,˒,§ _ _ (by rw[¿];simp;omega),e1] simp only[show(1:┞)˗=1 from rfl,show(63:┞)˗=63 from rfl,©,®,¡ (show 63-s˗<64 by omega),¡ (show s˗<64 by omega),˭,<- pow_add] rw[show 1+(63-s˗)=64-s˗ by omega] have hp:2^64=2^(64-s˗)*2^s˗:=by rw[<- pow_add,show 64-s˗+s˗=64 by omega] rw[hp,Nat.mul_mod_mul_right,<- ˺,<- ׀,֏] . rw[˃]at h;simp at h;rw[˒,§ _ _ (by rw[¿];simp;omega),e1] rw[show(64:┞)˗=64 from rfl,®,¡ (show s˗-64<64 by omega),՞,܅] have hb:mantOf bw*2^23*2^(s˗-64)<2^64:=by calc mantOf bw*2^23*2^(s˗-64)<2^24*2^23*2^14:=⠌ (˴ hm ܍) (˂ ܉ ܉) ܍ _<2^64:=܊ rw[¡ hb,˺,<- pow_add,show s˗-64+64=s˗ by omega] lemma O1 (hi lo bh bl:┞):((((hi+bh+(if lo+blomega lemma YCn (t2 t1 t0:┞) (h:t2˗*2^128+t1˗*2^64+t0˗=0):YC t2 t1 t0=0:=by have:=t2܂;unfold YC;rw[h];split_ifs<;>omega lemma E9 (B0:┞) (bw:┟) (a0 a1:┞) (S:Int) (hu:mantOf oneW*mantOf bw≠0 -> B0˗<=idxOf oneW+idxOf bw) (hA1 : -2^89>>1)>>>(63-s) else (Yf bw<<<23)<<<(s-64))=bh at hBB ⊢;generalize (if s<64 then (Yf bw<<<23)<<push_cast<;>ring have hb2:bh˗*2^64+bl˗<=2^125:=by rw[hBB];rcases hsm with h|⟨h1,h2,h3⟩ . simp[h] . have:=┊ bw;calc mantOf bw*2^23*2^s˗<=2^24*2^23*2^78:=܇ (¶ _ (le_of_lt this)) (˂ ܉ h1) _=2^125:=܊ have hacc:=H2 a0 a1;generalize (a1>>>39)+(((0:┞)-(a1>>>63))<<<25)+((0:┞)-(a0>>>63))+(if (a1<<<25)+a0omega have hSb2:S<2^127:=by rw[hS,hbias];split_ifs<;>omega have h3:=C3 t1 t0 0 S rfl ht hSb1 hSb2;generalize (0:┞)-(t1>>>63)=t2 at h3 ⊢;unfold Yx at h3;have t2l:=t2܂;have t1l:=t1܂;have t0l:=t0܂;have hY:YC t2 t1 t0=S:=H5 t2 t1 t0 S ܉ ܉ (by push_cast at h3 ⊢;omega) rw[H4];by_cases hS0:S=0 . have:=YCz t2 t1 t0 (by rw[hY,hS0]) rw[if_pos (decide_eq_true this),if_pos hS0] . have:t2˗*2^128+t1˗*2^64+t0˗≠0:=λ h0=>hS0 (by rw[<- hY];exact YCn t2 t1 t0 h0) rw[if_neg (by simpa using this),if_neg hS0,H6 _ _ _ _ _ _ _ (O2 B0 ܉),hY] lemma S3 (K:Nat) (fa fb:(t:┡) -> t ┞) (xN wN:Nat -> ┢) (xm wm:┞) (sx sw:Nat) (hs:sx+sw<=31) (h6:sw<=6) (hK:K<=256) (hg:∀ t h,fa t h=(YV (xN t܆) xm)˾) (hi:∀ t h,fb t h=(Y4 (wN t܆) wm)׆) (h8:∀ t,t mantOf (xN t)=0\/(xm˗<=idxOf (xN t)/\idxOf (xN t)-xm˗<=sx)) (h9:∀ t,t mantOf (wN t)=0\/(wm˗<=idxOf (wN t)/\idxOf (wN t)-wm˗<=sw)) (hB:(xm+wm)˗=xm˗+wm˗) (bw:┟) (ho:∀ t,t expOf (xN t)≠255) (hp:∀ t,t expOf (wN t)≠255) (hr:expOf bw≠255) (h5:mantOf oneW*mantOf bw≠0 -> (xm+wm)˗<=idxOf oneW+idxOf bw/\idxOf oneW+idxOf bw<=(xm+wm)˗+122) : (if Y5 K؝ fa fb (xm+wm) bw 0 0 0<߿ then (Y5 K؝ fa fb (xm+wm) bw 0 0 0)؉ else if Yq (λ t=>if tif tif tif t (xm+wm)˗<=idxOf oneW+idxOf bw/\idxOf oneW+idxOf bw < (xm+wm)˗+128 := λ h=>⟨(h5 h).1,by have:=(h5 h).2;omega⟩ have A:∀ (d:Nat) (k:┡) (a0 a1:┞) (S:Int),K-k܆=d -> k܆<=K -> -((k܆:Int)*2^55)<=Ye a0 -> Ye a0<=k܆*2^55 -> -((k܆:Int)*2^55)<=Ye a1 -> Ye a1<=k܆*2^55 -> S=Ye a0+2^25*Ye a1+Yr xN wN (xm+wm)˗ k܆ (K-k܆)+sv oneW*sv bw*2^(idxOf oneW+idxOf bw-(xm+wm)˗) -> -2^191<=S -> S<2^191 -> Y5 K؝ fa fb (xm+wm) bw a0 a1 k=if S=0 then ߿ else (┒ S (((xm+wm)˗:Int)-298) false)׆:=by intro d induction d with | zero => intro k a0 a1 S hd hk l0 u0 l1 u1 hS h4 h1;rw[Y5,dif_neg (by rw[£,hc];omega)] by_cases hf5:((Yf bw==0||Yd bw+126-(xm+wm)<=78)&&(xm+wm)<=1000)=true . have q55:(2:Int)^55=36028797018963968:=܊ have q89:(2:Int)^89=618970019642690137449562112:=܊ exact E9 _ _ _ _ S (λ h=>(hu h).1) (by rw[q89];rw[q55]at l0 u0 l1 u1;linarith) (by rw[q89];rw[q55]at l0 u0 l1 u1;linarith) (by rw[hS,show K-k܆=0 by omega,Yr];ring) hf5 unfold Y5g;rw[if_neg hf5];unfold Y5f;obtain⟨v2,v1,v0,c',hj,-,hl⟩:=Zr (xm+wm) oneW bw _ _ ((a1<<<25)+a0) 0 (λ v2 v1 v0 c'=>YD v2 v1 v0 c' (((xm+wm)˗:Int)-298)) ܋ hu rw[hj] apply ZV v2 v1 v0 c' _ S h4 h1 have p55:(2:Int)^55=36028797018963968:=܊ have p127:(2:Int)^127=170141183460469231731687303715884105728:=܊ have hn:=C3 _ ((a1<<<25)+a0) 0 (Ye a0+2^25*Ye a1) rfl (H2 a0 a1) (by rw[p127];rw[p55]at l0 u0 l1 u1;linarith) (by rw[p127];rw[p55]at l0 u0 l1 u1;linarith) rw[hl,։,hn,<- ։,hS,show K-k܆=0 by omega,Yr];ring_nf | succ d ih => intro k a0 a1 S hd hk l0 u0 l1 u1 hS h4 h1 have hf:k mantOf (xN t)*mantOf (wN t)≠0 -> (xm+wm)˗<=idxOf (xN t)+idxOf (wN t) /\ idxOf (xN t)+idxOf (wN t)<=(xm+wm)˗+122:=by intro t ht hm;have u:=(h8 t ht).resolve_left (λ h=>hm (by rw[h,؍]));have v:=(h9 t ht).resolve_left (λ h=>hm (by rw[h,׳]));constructor<;>omega have hv:=B4 xN wN (xm+wm)˗ K 0 (λ t _ h2 h3=>he t ܉ h3);have hx:=ZL oneW bw (xm+wm)˗ h5;generalize hS:Yr xN wN (xm+wm)˗ 0 K+sv oneW*sv bw*2^(idxOf oneW+idxOf bw-(xm+wm)˗)=S have h4 : -2^191<=S:=by rw[<- hS];omega have h1:S<2^191:=by rw[<- hS];omega have hq:dotOf (K+1) (λ t=>if tif tif tif tby by_cases h:tsimp[h,ho,hp,hr]<;>decide)];congr 1;rw[ZW,N4 xN wN K (xm+wm)˗ oneW bw K 0 ܉ (λ t _ h2 h3=>(he t ܉ h3).1)] simp only[˥,Nat.lt_irrefl,if_false];rw[ZA oneW bw (xm+wm)˗ (λ h=>(h5 h).1),<- hS];ring rw[A K 0 0 0 S ܋ ܋ (by simp[Ye]) (by simp[Ye]) (by simp[Ye]) (by simp[Ye]) (by rw[<- hS];simp[Ye]) h4 h1];exact A2 _ _ _ _ _ (λ h=>by rw[hq,h];simp[finishWord]) hq lemma u1 (n:┡) (h:¬n=0):(n-1)܆h (⠂ (by rw[e];rfl));rw[⠇ _ _ (USize.le_iff_toNat_le.mpr ߶)];simp;omega @[specialize] def YO {α:Type} (B C:┡) (f:┡ -> ┡ -> ┡ -> α) (n:┡) (a b c:┡) (acc:┠ α):┠ α := if h:n=0 then acc else let acc:=acc.push (f a b c) if c+1 ┡ -> ┡ -> α) (hB:0 b܆ c܆ i+n<4294967296 -> (YO B C f n؝ a b c acc)܃=acc܃ ++ (List.range' i n).map (λ j=>f (j/(B܆*C܆))؝ (j/C܆%B܆)؝ (j%C܆)؝):=by intro n;induction n with | zero=>intro i a b c acc _ _ _ _;unfold YO;rw[dif_pos (⠂ ܋)];simp | succ n ih => intro i a b c acc hi hb hc hn;have hs:=˖;obtain⟨d1,d2,d3⟩:=N3 a܆ b܆ c܆ B܆ C܆ hb hc;rw[hi]at d1 d2 d3;have h3:a܆<=a܆*(B܆*C܆):=˧ _ (˳ hB hC);have h1:b܆<=b܆*C܆:=˧ _ hC;have u:∀ (x:┡) (y:Nat),y=x܆ -> y<4294967296 -> y؝=x := λ x y h hy=>⠂ (by rw[Za _ hy,h]) have hf:f (i/(B܆*C܆))؝ (i/C܆%B܆)؝ (i%C܆)؝=f a b c:=by rw[u a _ d1 ܉,u b _ d2 ܉,u c _ d3 ܉] have p1:∀ x:┡,x܆<=i -> (x+1)܆=x܆+1:=λ x h=>by rw[Zc _ _ (by simp only[۽];omega),۽] have c1:=p1 c ܉;have b1:=p1 b ܉;have a1:=p1 a ܉;have z:(0:┡)܆=0:=rfl;have e1:(n+1)؝܆=n+1:=Za _ ܉;unfold YO;rw[dif_neg (λ e=>by rw[e]at e1;simp at e1),show(n+1)؝-1=n؝ from USize.toNat_inj.mp (by rw[⠇ _ _ (USize.le_iff_toNat_le.mpr (by rw[e1];simp)),e1,Za _ ܉];simp)] rw[˽,List.map_cons,hf];split . rename_i h;rw[£,c1]at h;rw[ih (i+1) a b (c+1) _ (by rw[c1];omega) hb (by rw[c1];omega) ܉];simp . rename_i h;rw[£,c1]at h;have h0:C܆=c܆+1:=܉ split . rename_i h';rw[£,b1]at h';rw[ih (i+1) a (b+1) 0 _ (by rw[b1,z,׀,؋];omega) (by rw[b1];omega) (by rw[z];omega) ܉] simp . rename_i h';rw[£,b1]at h';have h2:B܆*C܆=b܆*C܆+c܆+1:=by rw[show B܆=b܆+1 by omega,׀,h0];omega rw[ih (i+1) (a+1) 0 0 _ (by rw[a1,z,׀,؋];omega) (by rw[z];omega) (by rw[z];omega) ܉] simp lemma C6 {α:Type} (B C:┡) (f:┡ -> ┡ -> ┡ -> α) (hB:0f (q؞/(B܆*C܆))؝ (q؞/C܆%B܆)؝ (q؞%C܆)؝:=by apply Array.ext';rw[S2 B C f hB hC N 0 0 0 0 _ ܋ ߶ ߶ ܉];apply ۔<;>simp @[inline] def YG (bv bw:┟) (xm:┞):┞ := if bv>>>16==511 then Yd oneW+Yd bw-xm else Yk (bv>>>16) @[inline] def Ybg (bv bw bp:┟) (k:Nat) (xm:┞):┣ := let xb:=Yd oneW+Yd bw k<256&&(bp&&&0xFFFF) != 255&&(bv&&&0xFFFF) != 255&&xm<=Yk (bp>>>16) && Yk (bp>>>16)<=Yk (bp&&&0xFFFF)&&Yk (bp&&&0xFFFF)-xm<=31 && (if bv>>>16==511 then xm<=xb else Yk (bv>>>16)<=Yk (bv&&&0xFFFF)&&YU bv<=6 && Yk (bp&&&0xFFFF)-xm+YU bv<=31)&&expOf bw != 255 && (Yf bw==0||(xm+YG bv bw xm<=xb&&xb-(xm+YG bv bw xm)<80)) @[inline] def Ybh (bp:┟) (BW:┠ ┟) (b:┠ ┢):┞ := (Array.range BW.size).foldl (λ (m:┞) (o:Nat) => let wm:=Yk ((BW[o]! : ┟)>>>16) let xb:=Yd oneW+Yd b[o]! if (BW[o]! : ┟)>>>16 != 511&&Yf b[o]! != 0&&xb < m+wm then xb-wm else m) (Yk (bp>>>16)) @[inline] def Ybs (s:ConvShape) (inp:┠ ┢) (c yy xx:Nat):┢ := if yy=s.h\/xx-s.pad>=s.w then 0 else inp[(c*s.h+(yy-s.pad))*s.w+(xx-s.pad)]! @[inline] def YbsU (pd h w:┡) (inp:┠ ┢) (c yy xx:┡):┢ := if yy=h || xx - pd>=w then 0 else let j:=(c*h+(yy - pd))*w+(xx - pd) if hj:j.toNat < inp.size then inp.uget j hj else 0 @[inline] def Ybi (s:ConvShape) (inp:┠ ┢) (xm:┞):┠ Nat := let pd:=s.pad.toUSize let h:=s.h.toUSize let w:=s.w.toUSize YO (Yb s).toUSize (Ya s).toUSize (λ c yy xx=>YV (YbsU pd h w inp c yy xx) xm) (s.cin*(Yb s*Ya s)).toUSize 0 0 0 (Array.mkEmpty (s.cin*(Yb s*Ya s))) lemma C7 (s:┕) (inp:┠ ┢) (c yy xx:Nat) (hc:crename_i d . rw[if_pos (by simpa using d)] . rw[if_neg (by simpa using d)];simp only[״,┃,not_or,Nat.not_le]at d have m1:c*s.h+(yy-s.pad) < (c+1)*s.h:=by rw[Nat.succ_mul];omega have m2:(c*s.h+(yy-s.pad))*s.w+(xx-s.pad) < (c+1)*s.h*s.w:=calc _ < (c*s.h+(yy-s.pad))*s.w+s.w:=܉ _=(c*s.h+(yy-s.pad)+1)*s.w:=by rw[Nat.succ_mul] _<=_:=¶ _ m1 have m0:c*s.h<=(c*s.h+(yy-s.pad))*s.w:=Nat.le_trans (˼ _ _) (˧ _ ܉) have M:∀ x,x<4294967296 -> x%2^System.Platform.numBits=x:=λ x h=>¡ (⠋ h L) have m3:(c+1)*s.h<=(c+1)*s.h*s.w:=˧ _ ܉ have j:((c؝*s.h.toUSize+(yy؝-s.pad.toUSize))*s.w.toUSize+(xx؝-s.pad.toUSize))܆=(c*s.h+(yy-s.pad))*s.w+(xx-s.pad):=by simp only[USize.toNat_add,USize.toNat_mul,Za c ܉,qh,qw,s1,s2] rw[M (c*s.h) ܉,M (c*s.h+(yy-s.pad)) ܉,M ((c*s.h+(yy-s.pad))*s.w) ܉,M _ ܉] split<;>rename_i hj . rw[<- j,┍ inp _ hj];rfl . rw[j]at hj;rw[getElem!_neg inp _ hj];rfl lemma I0 (s:┕) (inp:┠ ┢) (xm:┞) (h0:0YV (YI s inp i؞) xm:=by have a0:0by simp[h]at h0);have b0:0by simp[h]at h0);have a1:Yb s<=Yb s*Ya s:=˧ _ b0;have b1:Ya s<=Yb s*Ya s:=˸ _ a0;have hp:(Yb s)؝܆=Yb s:=Za _ ܉;have hw:(Ya s)؝܆=Ya s:=Za _ ܉;unfold Ybi;dsimp only;rw[C6 _ _ _ (by rw[hp];omega) (by rw[hw];omega) _ _ h1];refine congrArg _ (funext λ i=>?_);rw[hp,hw] exact congrArg (YV · xm) ((C7 s inp _ _ _ (˶ (lt_of_lt_of_eq i.isLt (˱ _ _))) (˵ _ a0) (˵ _ b0) h1).trans rfl) lemma uk {t:┡} {k:Nat} (ht:t ┣ | 0=>true | r+1 => (let p:=if iif t < k then └ s inp y x (cw+t) else oneW) (λ t=>if t < k then wts[o*k+t]! else b[o]!) i r:=by intro r; induction r <;> intro i <;> simp only[zW,Yq, *] @[inline] def Ybj (s:ConvShape) (inp:┠ ┢) (P2:┠ Nat) (off:┠ ┟) (wts:┠ ┢) (W2:┠ ┟) (b:┠ ┢) (k o cw y x:Nat) (pb wa:┡) (B0:┞) (hk:k<1048576) (hoff:off.size=k) (hix:∀ t,t pb.toNat+(off[t]!).toNat wa.toNat+t(P2.uget (pb+(off.uget t (by rw [hoff];exact uk ht hk)).toUSize) (F5 _ _ _ (by rw [ox];exact hix _ (uk ht hk)))).toUInt64) (λ t ht=>(W2.uget (wa+t) (F5 _ _ _ (hW _ (uk ht hk)))).toUInt64) B0 b[o]! 0 0 0 if v<0x100000000 then v.toUInt32 else if zW s inp wts b k o cw y x 0 (k+1) then 0x80000000 else 0 lemma B7 {α:Type} [Inhabited α] (A:┠ α) (i:┡) (h:i܆ pb܆+(off[t]!)؊ wa܆+t P2[pb܆+(off[t]!)؊]! = YV (└ s inp y x (cw+t)) xm) (h9:∀ t,t W2[wa܆+t]! = Y4 wts[o*k+t]! (YG (Yc wts k o) b[o]! xm)) (h7:inp٪<4294967296) (h3:o*k+k<=wts٪/\wts٪<4294967296) (B0:┞) (h8:B0=xm+YG (Yc wts k o) b[o]! xm) : Ybj s inp P2 off wts W2 b k o cw y x pb wa B0 hk ha h2 hW = dotOf (k+1) (λ t=>if tif t>>16))˗:=by unfold YU;rw[§ _ _ c5] set wm:=YG (Yc wts k o) b[o]! xm with h5;have Zh:∃ sw,sw<=6/\(Yk (bp&&&0xFFFF))˗-xm˗+sw<=31 /\ (∀ t,t mantOf wts[o*k+t]! = 0\/(wm˗<=idxOf wts[o*k+t]! /\ idxOf wts[o*k+t]! - wm˗<=sw))/\(∀ t,t expOf wts[o*k+t]! ≠ 255) /\ (xm+wm)˗=xm˗+wm˗:=by by_cases hz:Yc wts k o>>>16=511 . simp only[hz,if_true,┃]at cD;obtain⟨L,H,hb,-,hH,h4⟩:=Zp wts k o h3.1 ܉;obtain⟨u1,u2⟩:=Zo _ L H hb ܉;rw[hz]at u1;have he:H≠255:=λ h=>c3 (˅ (by rw[u2,h];rfl));have hd:=ZM b[o]!;have:=Zg b[o]!;have:=(ZO).2;have z:∀ t,t mantOf wts[o*k+t]! = 0/\expOf wts[o*k+t]! ≠ 255:=λ t ht=>by obtain⟨k1,k2⟩:=h4 t ht;obtain⟨-,-,k3,k4⟩:=Zb wts[o*k+t]!;exact⟨by by_contra hm;have:=(k4 hm).1;simp at u1;omega,k3 ܉⟩ refine⟨0,by omega,by omega,λ t ht=>Or.inl (z t ht).1,λ t ht=>(z t ht).2,?_⟩;simp only[h5,YG,hz,beq_self_eq_true,if_true];rw[¤,§ _ _ cD];omega . simp only[hz,if_false,˯,┃]at cD;obtain⟨⟨d1,d2⟩,d3⟩:=cD;obtain⟨wf,ws,wm5,wfin⟩:=I3 wts k o h3.1 ܉ c3 d1 have e3:=˓ d2;have e4:=˓ d3;rw[¤,§ _ _ (UInt64.le_trans c4 c5)]at e4;simp only[show(31:┞)˗=31 from rfl,show(6:┞)˗=6 from rfl]at e3 e4 have ew:wm=Yk (Yc wts k o>>>16):=by simp[h5,YG,hz] rw[ew];exact⟨_,e3,by omega,wf,wfin,by rw[¤];omega⟩ obtain⟨sw,k6,ks,wf,wfin,hB⟩:=Zh;refine S3 k _ _ (λ t=>└ s inp y x (cw+t)) (λ t=>wts[o*k+t]!) xm _ ((Yk (bp&&&0xFFFF))˗-xm˗) sw ܉ k6 ܉ ?_ ?_ (λ t _=>?_) wf hB b[o]! (λ t _=>?_) wfin c9 (λ h=>⟨(h6 h).1,by have:=(h6 h).2;omega⟩) rotate_left 2 . rcases K0 s inp y x (cw+t) with h | ⟨j,hj,h⟩<;>rw[h] . exact Or.inl rfl . rcases xf j hj with h' | h'<;>simp only[˥]at h' . exact Or.inl h' . right;omega . rcases K0 s inp y x (cw+t) with h | ⟨j,hj,h⟩<;>rw[h] . decide . exact xfin j hj . intro t ht;have h0:=uk ht hk;have h1:=h2 _ h0;rw[B7 P2 _ _ _ (by rw[Zc _ _ (by rw[ox];have:=˖;omega),ox]),hP _ h0] . intro t ht;have h0:=uk ht hk;have h1:=hW _ h0;rw[B7 W2 _ _ _ (Zc _ _ (by have:=˖;omega)),h9 _ h0] lemma Z4 {a:┡} {n:Nat} (h:aomega);rw[e4,e5]at u;cases dw . simp only[¥,if_false,˥]at h ⊢;rw[USize.zero_add,u] . simp only[if_true]at h ⊢;rw[Zc _ _ (by rw[um _ _ (by rw[e6];omega),u,e6];have:=˖;omega),um _ _ (by rw[e6];omega),u,e6] lemma J9 (dw:┣) (s:┕) (inp:┠ ┢) (k o y x t:Nat) (hk:k=if dw then s.kh*s.kw else s.cin*s.kh*s.kw) (h1:s.kh<=Yb s) (h2:s.kw<=Ya s) (ho:dw -> oY4 wts[t.val]! (YG BW[t.val/k]! b[t.val/k]! xm) else let ku:=k.toUSize YO 1 ku (λ o _ j => let i:=o*ku+j Y4 (if h:i.toNatY4 wts[t؞]! (YG BW[t؞/k]! b[t؞/k]! xm):=by unfold YW2;split · rfl · rename_i hk0;have hku:k؝܆=k:=Za k hk2;rw[C6 1 k؝ _ ܋ (by rw[hku];omega) wts٪ _ hs] refine congrArg _ (funext λ q=>?_) have hq:=q.isLt;simp only[hku,۽,؋];have hd:(q؞/k)؝܆=q؞/k:=Za _ (by have:=Nat.div_le_self q؞ k;omega) have hm:(q؞%k)؝܆=q؞%k:=Za _ (by have:=Nat.mod_le q؞ k;omega) have e1:q؞/k*k+q؞%k=q؞:=by rw[˱];exact ܀ q؞ k have hi:((q؞/k)؝*k؝+(q؞%k)؝)܆=q؞:=by rw[USize.toNat_add,USize.toNat_mul,hd,hku,hm,¡ (lt_of_lt_of_le (show q؞/k*k<4294967296 by omega) ˖),¡ (lt_of_lt_of_le (show q؞/k*k+q؞%k<4294967296 by omega) ˖),e1] congr 1 · exact A5 wts _ q؞ hi 0 rfl · congr 1 · exact A5 BW _ (q؞/k) hd 0 rfl · exact A5 b _ (q؞/k) hd 0 rfl @[inline] def cdQ (dw:┣) (s:ConvShape) (relu:┣) (inp wts b:┠ ┢) (k C:Nat) (hk:k=if dw then s.kh*s.kw else s.cin*s.kh*s.kw) (hC:C=if dw then s.cin else s.cout) : ┠ ┢ := let off:┠ ┟:=Array.ofFn (n:=k) λ t=>(Ys s t.val).toUInt32 let bp:=Yc inp inp.size 0 let BW:┠ ┟:=Array.ofFn (n:=C) λ o=>Yc wts k o.val let xm:=Ybh bp BW b if hg:s.kh<=Yb s/\s.kw<=Ya s/\0Ybg BW[o]! b[o]! bp k xm) then let P2:=Ybi s inp xm let W2:┠ ┟:=YW2 wts BW b xm k have hP2:P2.size=s.cin*(Yb s*Ya s):=by simp only [P2];rw [I0 s inp xm hg.2.2.1 ܉ ܉,Array.size_ofFn] have a:=C0 s C hg.2.2.1 let B0s:┠ ┞:=Array.ofFn (n:=C) λ o=>xm+YG BW[o.val]! b[o.val]! xm let hw:=(Yb s*Ya s).toUSize let st:=s.stride.toUSize let wp:=(Ya s).toUSize let ku:=k.toUSize YO s.ho.toUSize s.wo.toUSize (λ o y x => if h:oby obtain ⟨w1,-⟩:=J9 dw s inp k o.toNat y.toNat x.toNat t hk hg.1 hg.2.1 (by intro d;subst d hC;simpa using Z4 h.1 ܉) (Z4 h.2.1 ܉) (Z4 h.2.2 ܉) ht rw [G3 dw s o y x hg.2.2.1 ܉ ܉,hP2,ZD s _ t ht ܉];omega) (λ t ht=>by have:=Nat.mul_le_mul_right k (show o.toNat+1<=C from Z4 h.1 ܉) rw [Nat.add_mul,Nat.one_mul] at this rw [um _ _ (by rw [Za _ ܉];omega),Za _ ܉] simp only [W2,A6 wts BW b xm k ܉ ܉,Array.size_ofFn];omega)) else 0) (C*(s.ho*s.wo)).toUSize 0 0 0 (Array.mkEmpty (C*(s.ho*s.wo))) else if dw then dwF s relu inp wts b else Ya0 s relu inp wts b lemma R7 (dw:┣) (s:┕) (relu:┣) (inp wts b:┠ ┢) (k C:Nat) (hk:k=if dw then s.kh*s.kw else s.cin*s.kh*s.kw) (hC:C=if dw then s.cin else s.cout) : (if dw then depthwiseSpec else conv2dSpec) s relu inp wts b=Array.ofFn (n:=C*(s.ho*s.wo)) λ q=>act relu (dotOf (k+1) (λ t=>if tif tsimp[depthwiseSpec,depthwiseWith,conv2dSpec,conv2dWith] lemma C8 (dw:┣) (s:┕) (relu:┣) (inp wts b:┠ ┢) (k C:Nat) (hk:k=if dw then s.kh*s.kw else s.cin*s.kh*s.kw) (hC:C=if dw then s.cin else s.cout) : cdQ dw s relu inp wts b k C hk hC=(if dw then depthwiseSpec else conv2dSpec) s relu inp wts b:=by unfold cdQ;dsimp only;split . rename_i hg;obtain⟨g1,g2,g3,g4,g5,g6,g7⟩:=hg;obtain⟨a1,a2,a3,a4⟩:=C0 s C g3;have ho:s.ho.toUSize.toNat=s.ho:=Za _ ܉;have hw:s.wo.toUSize.toNat=s.wo:=Za _ ܉;rw[C6 _ _ _ (by rw[ho];exact(ZG s).1) (by rw[hw];exact(ZG s).2) _ _ ܉,R7 dw s relu inp wts b k C hk hC] congr 1;funext q;obtain⟨hy,hx,hq⟩:=Zt C s.ho s.wo q؞ q.isLt;have e1:(q؞/(s.ho*s.wo))؝܆=q؞/(s.ho*s.wo):=Za _ (by have:=Nat.div_le_self q؞ (s.ho*s.wo);have:=q.isLt;omega) have e2:(q؞/s.wo%s.ho)؝܆=q؞/s.wo%s.ho:=Za _ ܉;have e3:(q؞%s.wo)؝܆=q؞%s.wo:=Za _ ܉;have ek:k؝܆=k:=Za _ ܉;have hc:q؞/(s.ho*s.wo)*k+k<=wts٪:=by have:=¶ k (show q؞/(s.ho*s.wo)+1<=C by omega);rw[׀,؋]at this;omega simp only[ho,hw];rw[dif_pos ⟨by rw[£,e1,Za _ ܉];exact hq,by rw[£,e2,ho];exact hy,by rw[£,e3,hw];exact hx⟩] simp only[e1,e2,e3];congr 1;refine R8 s inp _ _ wts _ b _ _ _ _ _ _ _ (Ybh (Yc inp inp٪ 0) (Array.ofFn (n:=C) λ o=>Yc wts k o؞) b) _ _ _ _ ?_ ?_ ?_ ܉ ⟨hc,by omega⟩ _ ?_ . have:=Array.all_eq_true.mp g7 (q؞/(s.ho*s.wo)) ߶;simpa [gO C (λ o=>Yc wts k o) _ hq] using this . intro t ht;obtain⟨w1,w2⟩:=J9 dw s inp k (q؞/(s.ho*s.wo)) _ _ t hk g1 g2 (by intro d;subst d hC;simpa using hq) hy hx ht rw[G3 dw s _ _ _ g3 ܉ (by rw[e1,e2,e3];omega),e1,e2,e3,ZD s _ t ht ܉,I0 s inp _ g3 ܉ ܉,gO _ (λ i=>YV (YI s inp i) _) _ w1,w2] . intro t ht;rw[um _ _ (by rw[e1,ek];omega),e1,ek,A6 _ _ _ _ _ ܉ ܉,gO _ (λ t=>Y4 wts[t]! (YG (Array.ofFn (n:=C) λ o=>Yc wts k o؞)[t/k]! b[t/k]! (Ybh (Yc inp inp٪ 0) (Array.ofFn (n:=C) λ o=>Yc wts k o؞) b))) _ ܉, show(q؞/(s.ho*s.wo)*k+t)/k=q؞/(s.ho*s.wo) by rw[˹,˦ _ _ ܉,˫ ht,˥], gO C (λ o=>Yc wts k o) _ hq] . rw[gO C (λ o=>_+YG (Array.ofFn (n:=C) λ o=>Yc wts k o؞)[o]! b[o]! _) _ hq,gO C (λ o=>Yc wts k o) _ hq] . subst hk hC;cases dw . exact V0 ▸ rfl . exact U9 ▸ rfl def Ybp (s:ConvShape) (relu:┣) (inp wts b:┠ ┢):┠ ┢ := cdQ false s relu inp wts b _ _ rfl rfl def dwQ (s:ConvShape) (relu:┣) (inp wts b:┠ ┢):┠ ┢ := cdQ true s relu inp wts b _ _ rfl rfl lemma R6:Ybp=conv2dSpec:=funext λ s=>funext λ r=>funext λ i=>funext λ w=>funext λ b=>C8 false s r i w b _ _ rfl rfl lemma R5:dwQ=depthwiseSpec:=funext λ s=>funext λ r=>funext λ i=>funext λ w=>funext λ b=>C8 true s r i w b _ _ rfl rfl lemma dz (n:Nat) (F:Nat -> ┢) (hn:0 expOf (F t)≠255) : dotOf (n+1) (λ t=>if tif toneW):=by have cg:∀ r k,k+r<=n -> Yo (λ t=>if tif toneW) k r /\ Yq (λ t=>if tif toneW) k r:=by intro r;induction r with | zero=>intro k _;exact⟨rfl,rfl⟩ | succ r ih=>intro k h;obtain⟨a,b⟩:=ih (k+1) ܉;simp only[Yo,Yq,a,b,if_pos (show k ┢) r k,Yq f g k (r+1)=(Yq f g k r && (decide (mantOf (f (k+r))*mantOf (g (k+r))=0)&&˷ (signOf (f (k+r))) (signOf (g (k+r))))):=by intro f g r;induction r with | zero=>intro k;simp[Yq] | succ r ih => intro k;conv_lhs=>rw[Yq,ih (k+1)] conv_rhs=>rw[Yq] rw[show k+1+r=k+(r+1) by omega];simp only[Bool.and_assoc] rw[Zy (n+1) _ _ (λ t _=>by by_cases h:tsimp[h,hf]<;>decide),Zy n _ _ (λ t ht=>⟨hf t ht,by decide⟩),ZW,sn,(cg n 0 ܉).1,(cg n 0 ܉).2] have z1:sv (߾:┟)=0:=܌ have z2:((decide (mantOf oneW*mantOf (߾:┟)=0)) && ˷ (signOf oneW) (signOf (߾:┟)))=true:=܌ simp only[˥,Nat.lt_irrefl,if_false,z1,mul_zero,zero_mul,add_zero,z2,Bool.and_true,show(n+1≠0)=True from eq_true ܉,show(n≠0)=True from eq_true ܉] lemma wp (c h w k ch y x t:Nat) (inp:┠ ┢) (hy:yg5 (˅ (by rw[u2,e];rfl));omega) . rw[getElem!_neg inp j hj];decide have ho:ConvShape.ho ⟨c,h,w,c,k,k,k,0⟩=h/k:=by show(h-k)/k+1=h/k;conv_rhs=>rw[show h=(h-k)+k by omega];rw[Nat.add_div_right _ hk] have hw:ConvShape.wo ⟨c,h,w,c,k,k,k,0⟩=w/k:=by show(w-k)/k+1=w/k;conv_rhs=>rw[show w=(w-k)+k by omega];rw[Nat.add_div_right _ hk] rw[C8,if_pos rfl];unfold depthwiseSpec depthwiseWith avgpoolSpec avgpoolWith;apply Array.ext . simp[ho,hw] . intro i h1 h2;simp only[Array.getElem_map,Array.getElem_ofFn,ho,hw];have hq:ih0 _)] unfold act;simp;congr 1<;>funext t<;>split . rename_i ht;exact wp c h w k _ _ _ t inp hy hx ht . rfl . rename_i ht;rw[┍ _ _ ߶];simp . rw[┍ _ _ ߶];simp . rw[V2] def Ybl (c h w k:Nat) (inp:┠ ┢):┠ ┢ := if k=2 then YT (c*(h/2)) (w/2) λ cy x=> let p:=poolAt h w 2 inp (cy/(h/2)) (cy%(h/2)) x YQ (YQ (YQ (YQ (p 0) (p 0)) (p 1)) (p 2)) (p 3) else Yad c h w k inp lemma R3:Ybl=maxpoolSpec:=by rw[<- M6];funext c h w k inp;unfold Ybl;split . subst_vars;rw[ZB _ _ (c*(h/2*(w/2))) (˺ _ _ _)];congr 1;have e1:∀ v:Nat,v/(w/2)/(h/2)=v/(h/2*(w/2)):=λ v=>by rw[˭,˱] simp only[e1,show ՛ (2*2)=[0,1,2,3] from rfl,܁,List.foldl_nil] . rfl @[noinline] def YaYs (x y z:┢):┢:=YaY x y z @[inline] def Ysx (x y z:┢) (my iy mz iq:┞):┢ := if expOf x != 255 then let mp:=Yl x*my let p:=Yd x+iy let k:=if mp==0 then iq else if mz==0 then p else if p<=iq then p else iq let dp:=if k<=p then p-k else 0 let dq:=if k<=iq then iq-k else 0 if dp<=14 && dq<=38 then let neg:=Bool.xor (signOf x) (signOf y) let tp:=mp<<omega generalize hD:(if K<=P then P-K else 0)=D;generalize hE:(if K<=Q then Q-K else 0)=E;have eD:D˗=P˗-K˗:=by rw[<- hD];exact O0 P K have eE:E˗=Q˗-K˗:=by rw[<- hE];exact O0 Q K by_cases hc:(D<=14 && E<=38)=true . rw[if_pos hc];simp only[˯,┃]at hc;have c1:D˗<=14:=by have:=˓ hc.1;simpa using this have c2:E˗<=38:=by have:=˓ hc.2;simpa using this unfold YaY;rw[if_neg (show ¬(expOf x=255\/expOf y=255\/expOf z=255) by rintro (h|h|h)<;>contradiction)] dsimp only;rw[<- ek,<- ep,<- eq,if_pos (And.intro (show P˗-K˗<=14 by omega) (show Q˗-K˗<=38 by omega))] have sD:(P˗-K˗)˾=D:=¢ (by rw[۾,⠉,eD];omega) have sE:(Q˗-K˗)˾=E:=¢ (by rw[۾,⠉,eE];omega) rw[sD,sE,D9,H7 _ _ _ _ _ (O2 K ܉)] . rw[if_neg hc];rfl def Ysj (relu:┣) (x:┠ ┢) (n:┡) (hn:n.toNat<=x.size) (y z:┢) (my iy mz iq:┞) (j:┡) (acc:┠ ┢):┠ ┢ := if h:j (Ysj relu x n hn y z (Yl y) (Yd y) (Yl z) (Yd z+149) j acc)܃=acc܃++(List.range' j܆ (n܆-j܆)).map (λ i=>act relu (YaY x[i]! y z)):=by intro m;induction m with | zero=>intro j acc h;unfold Ysj;rw[dif_neg (by rw[£];omega)];simp[h] | succ m ih=> intro j acc h;unfold Ysj;have hj:jact relu (YaY x[ch*hw+j]! s[ch]! t[ch]!)) ch 0 acc) else acc termination_by c-ch lemma E4 (relu:┣) (c hw:Nat) (x s t:┠ ┢) (hx:c*hw<=x٪) (hc:c*hw<=4294967295) : ∀ m ch (acc:┠ ┢),c-ch=m -> Ysk relu c hw x s t hx hc ch acc=Yak c hw (λ ch j=>act relu (YaY x[ch*hw+j]! s[ch]! t[ch]!)) ch acc:=by intro m;induction m with | zero=>intro ch acc h;unfold Ysk Yak;rw[dif_neg ܉,if_neg ܉] | succ m ih=> intro ch acc h;unfold Ysk Yak;rw[dif_pos (show ch>>63))˗*2^64+q˗:Nat):Int)%2^128=Ye q%2^128:=by have e3:((0:┞)-(q>>>63))˗=(2^64-q˗/2^63)%2^64:=by rw[˰,˔];simp[©] have:=q܂;unfold Ye;rw[e3];exact QE (q˗/2^63:Nat) ܉ lemma O4 (w:┟):((w>>>31)׆)˗=if signOf w then 1 else 0:=by have h:=C5 w 0;rwa[UInt32.xor_zero,show signOf 0=false from rfl,Bool.xor_false]at h lemma A9 (x w:┟) (xm wm:┞) (xs ws:Nat) (hs:xs+ws<=14) (hx:mantOf x=0\/(xm˗<=idxOf x/\idxOf x-xm˗<=xs)) (hw:mantOf w=0\/(wm˗<=idxOf w/\idxOf w-wm˗<=ws)) (h1:1<=wm) : Ye (((QPb x xm (signOf w))˾-4611686018427387904)*(Yf w<<<((expOf w)׆-(wm+1)))) = sv x*sv w*2^(idxOf x+idxOf w-(xm˗+wm˗)) /\ -2^62grind rw[hq,show(signOf x != signOf w)=˷ (signOf x) (signOf w) by cases signOf x<;>cases signOf w<;>rfl];generalize M*D=p at hP ⊢;have h5:=H1 p (˷ (signOf x) (signOf w)) (by rw[hP.1];omega);have Zk:(if ˷ (signOf x) (signOf w) then -(p˗:Int) else p˗) = sv x*sv w*2^(idxOf x+idxOf w-(xm˗+wm˗)):=by rw[hP.1,<- Zn];by_cases h0:mantOf x*mantOf w=0 . have:mantOf x*2^(idxOf x-xm˗)*(mantOf w*2^(idxOf w-wm˗))=0:=by rcases ˿ h0 with h | h<;>simp[h] rw[this,h0];simp . have hx0:mantOf x≠0:=λ h=>h0 (by simp[h]);have hw0:mantOf w≠0:=λ h=>h0 (by simp[h]);have hx1:=hx.resolve_left hx0;have hw1:=hw.resolve_left hw0;have e:idxOf x+idxOf w-(xm˗+wm˗) = (idxOf x-xm˗)+(idxOf w-wm˗):=܉ rw[e,pow_add];split_ifs<;>push_cast<;>ring have hp2:(p˗:Int)<2^62:=by have:=hP.2;rw[<- hP.1]at this;exact_mod_cast this refine⟨h5.trans Zk,?_,?_⟩<;>rw[<- Zk]<;>split_ifs<;>omega lemma A8 (X W:┠ ┢) (xa wa:Nat) (n:┡) (f:(k:┡) -> k ┞) (B0:┞) (bw:┟) (hn:n܆<=1048576) (hq:∀ t h,Ye (f t h)=sv X[xa+t܆]!*sv W[wa+t܆]!*2^(idxOf X[xa+t܆]!+idxOf W[wa+t܆]!-B0˗) /\ -2^62<=Ye (f t h) /\ Ye (f t h)<=2^62) (hu:mantOf oneW*mantOf bw≠0 -> B0˗<=idxOf oneW+idxOf bw/\idxOf oneW+idxOf bw<=B0˗+122) : ∀ (d:Nat) (k:┡) (hi lo:┞) (S0 S:Int),n܆-k܆=d -> k܆<=n܆ -> ((hi˗*2^64+lo˗:Nat):Int)%2^128=S0%2^128 -> -((k܆:Int)*2^62)<=S0 -> S0<=k܆*2^62 -> S=S0+YB X W xa wa B0˗ k܆ (n܆-k܆)+sv oneW*sv bw*2^(idxOf oneW+idxOf bw-B0˗) -> -2^191<=S -> S<2^191 -> QY6G n f B0 bw hi lo k=if S=0 then ߿ else (┒ S ((B0˗:Int)-298) false)׆:=by have p62:(2:Int)^62=4611686018427387904:=܊ have p127:(2:Int)^127=170141183460469231731687303715884105728:=܊ intro d;induction d with | zero=> intro k hi lo S0 S hd hk h1 l0 u0 hS a1 a2;rw[QY6G,dif_neg (by rw[£];omega)] obtain⟨v2,v1,v0,c',hj,-,hl⟩:=Zr B0 oneW bw _ hi lo 0 (λ v2 v1 v0 c'=>YD v2 v1 v0 c' ((B0˗:Int)-298)) ܋ (λ h=>⟨(hu h).1,by have:=(hu h).2;omega⟩) rw[hj];apply ZV v2 v1 v0 c' _ S a1 a2;have hk2:(k܆:Int)<=1048576:=܉ have hn2:=C3 hi lo 0 S0 rfl h1 (by rw[p127];rw[p62]at l0 u0;nlinarith) (by rw[p127];rw[p62]at l0 u0;nlinarith) rw[hl,։,hn2,<- ։,hS,show n܆-k܆=0 by omega,YB];ring_nf | succ d ih=> intro k hi lo S0 S hd hk h1 l0 u0 hS a1 a2;have hf:k>>16)<=Yk (Yc A inW i&&&0xFFFF)) (fx:(QYF (Yc A inW i))˗<=c) : ∀ t,t < inW -> (mantOf A[i*inW+t]! = 0\/((Yk (Yc A inW i>>>16))˗<=idxOf A[i*inW+t]!/\idxOf A[i*inW+t]!-(Yk (Yc A inW i>>>16))˗<=c)) /\ expOf A[i*inW+t]!≠255:=by obtain⟨L,H,h5,-,hH,hr⟩:=Zp A inW i h1 h2;obtain⟨hj,h3⟩:=Zo _ L H h5 ܉ have kx:=Zq (Yc A inW i>>>16);have kx2:=Zq (Yc A inW i&&&0xFFFF);rw[hj]at kx;rw[h3]at kx2;unfold QYF at fx;rw[§ _ _ q10,kx,kx2]at fx;have g8:H≠255:=λ c=>q8 (˅ (by rw[h3,c];rfl)) intro t ht;obtain⟨-,-,k3,ka⟩:=Zb A[i*inW+t]!;have:=hr t ht;refine⟨?_,k3 (҂ this.2 (͵ hH g8))⟩;by_cases hm:mantOf A[i*inW+t]! = 0 . exact Or.inl hm . have k5:=ka hm;right;rw[kx];exact⟨E2 this.1 k5.1,(Nat.sub_le_sub_right (E1 this.2 k5.2) _).trans fx⟩ lemma O3 (X W b:┠ ┢) (inW i j cx cw:Nat) (bx bv:┟) (X' W':┠ ┢) (xa wa:Nat) (n:┡) (f:(k:┡) -> k ┞) (q3:i*inW+inW<=X.size) (q4:j*inW+inW<=W.size) (q5:i*inW+inW<=4294967295) (q6:j*inW+inW<=4294967295) (q7:inW<1048576) (hc:cx+cw<=122) (hn:n܆<=1048576) (hY:YB X' W' xa wa ((Yk (bx>>>16))+(Yk (bv>>>16)))˗ 0 n܆=YB X W (i*inW) (j*inW) ((Yk (bx>>>16))+(Yk (bv>>>16)))˗ 0 inW) (rx:∀ t,t < inW -> (mantOf X[i*inW+t]! = 0\/((Yk (bx>>>16))˗<=idxOf X[i*inW+t]!/\idxOf X[i*inW+t]!-(Yk (bx>>>16))˗<=cx)) /\ expOf X[i*inW+t]!≠255) (rv:∀ t,t < inW -> (mantOf W[j*inW+t]! = 0\/((Yk (bv>>>16))˗<=idxOf W[j*inW+t]!/\idxOf W[j*inW+t]!-(Yk (bv>>>16))˗<=cw)) /\ expOf W[j*inW+t]!≠255) (q14:expOf b[j]!≠255) (q15:Yf b[j]! = 0\/(Yk (bx>>>16)+Yk (bv>>>16)<=Yd oneW+Yd b[j]!/\Yd oneW+Yd b[j]!-(Yk (bx>>>16)+Yk (bv>>>16))<80)) (hq:∀ t h,Ye (f t h)=sv X'[xa+t܆]!*sv W'[wa+t܆]!*2^(idxOf X'[xa+t܆]!+idxOf W'[wa+t܆]!-((Yk (bx>>>16))˗+(Yk (bv>>>16))˗)) /\ -2^62<=Ye (f t h) /\ Ye (f t h)<=2^62) : (if QY6G n f (Yk (bx>>>16)+Yk (bv>>>16)) b[j]! 0 0 0<߿ then (QY6G n f (Yk (bx>>>16)+Yk (bv>>>16)) b[j]! 0 0 0)؉ else Yai X W b inW 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 have hh:(i*inW)؝܆=i*inW:=Za _ ܉ have hb:(j*inW)؝܆=j*inW:=Za _ ܉ have he:inW؝܆=inW:=Za _ ܉ have hB:((Yk (bx>>>16))+(Yk (bv>>>16)))˗=(Yk (bx>>>16))˗+(Yk (bv>>>16))˗:=by rw[¤];exact ¡ (by rw[Zq,Zq];have:=(bx>>>16).toNat_lt;have:=(bv>>>16).toNat_lt;omega) have hu:=H0 b[j]! _ q15;have h5':∀ t,t < inW -> mantOf X[i*inW+t]! * mantOf W[j*inW+t]! ≠ 0 -> ((Yk (bx>>>16))+(Yk (bv>>>16)))˗<=idxOf X[i*inW+t]! + idxOf W[j*inW+t]! /\ idxOf X[i*inW+t]! + idxOf W[j*inW+t]! <= ((Yk (bx>>>16))+(Yk (bv>>>16)))˗+122:=by intro t ht hm;have u:=(rx t ht).1.resolve_left (λ c=>hm (by rw[c,؍]));have v:=(rv t ht).1.resolve_left (λ c=>hm (by rw[c,׳]));rw[hB];constructor<;>omega have hl:=S8 X W (i*inW) (j*inW) _ inW 0 (λ t _ h2 h3=>h5' t ܉ h3) have hm:=ZL oneW b[j]! _ (λ c=>⟨(hu c).1,by have:=(hu c).2;omega⟩) generalize hS:YB X W (i*inW) (j*inW) ((Yk (bx>>>16))+(Yk (bv>>>16)))˗ 0 inW+sv oneW*sv b[j]!*(2:Int)^(idxOf oneW+idxOf b[j]!-((Yk (bx>>>16))+(Yk (bv>>>16)))˗)=S at hl hm;have s1 : -2^191<=S:=܉ have s2:S<2^191:=܉ rw[A8 X' W' xa wa n f _ b[j]! hn (λ t h=>by rw[hB];exact hq t h) (λ c=>⟨(hu c).1,by have:=(hu c).2;omega⟩) n܆ 0 0 0 0 S ܋ ܋ ܋ ܋ ܋ (by rw[<- hS,<- hY];simp) s1 s2,<- S9 X W (i*inW)؝ (j*inW)؝ inW؝ (by rw[hh,he];omega) (by rw[hb,he];omega) (by rw[hh,he];have:=˖;omega) (by rw[hb,he];have:=˖;omega) _ _ b[j]! ܉ (λ c=>⟨(hu c).1,by have:=(hu c).2;omega⟩) inW 0 0 0 0 0 0 S (by simp[he]) ܋ ܋ (λ t _ h2 h3=>by rw[hh,hb]at h3 ⊢;have:=h5' t ܉ h3;exact⟨this.1,by omega⟩) (by simp[Yx]) (by rw[<- hS,hh,hb,he];simp) s1 s2] exact H9 X W inW i j b[j]! _ _ _ _ _ hh hb he q7 (λ t ht=>(rx t ht).2) (λ t ht=>(rv t ht).2) q14 h5' (λ c=>⟨(hu c).1,by have:=(hu c).2;omega⟩) _ (B5 X W b inW i j) lemma F4 (n:Nat) (f:Nat -> ┟) (m:┞):∀ k t (P:┠ Nat),n-t=k -> (QPD n f m t P)܃=P܃ ++ (List.range' (2*t) (2*(n-t))).map λ u=>QPb (f (u/2)) m (u%2=1):=by intro k;induction k with | zero=>intro t P h;unfold QPD;rw[if_neg ܉];simp[h] | succ k ih=>intro t P h;unfold QPD;rw[if_pos ܉];dsimp only;rw[ih (t+1) _ ܉,show 2*(n-t)=2*(n-(t+1))+1+1 by omega,˽,˽];simp[show 2*t/2=t by omega,show(2*t+1)/2=t by omega,show 2*(t+1)=2*t+1+1 by omega,show(2*t+1)%2=1 by omega] lemma B1 (n c:Nat) (f:Nat -> ┟) (m:┞):QPD n f m 0 (Array.emptyWithCapacity c)=Array.ofFn (n:=2*n) λ u=>QPb (f (u؞/2)) m (u؞%2=1):=by apply Array.ext';rw[F4 n f m _ 0 _ rfl];apply ۔<;>simp lemma F3 (n:Nat) (f:Nat -> ┟):∀ k t (I:┠ ┟),n-t=k -> (QPI n f t I)܃=I܃ ++ ((List.range' t (n-t)).filter λ u=>Yf (f u)≠0).map (·.toUInt32):=by intro k;induction k with | zero=>intro t I h;unfold QPI;rw[if_neg ܉];simp[h] | succ k ih=>intro t I h;unfold QPI;rw[if_pos ܉,ih (t+1) _ ܉,show n-t=(n-(t+1))+1 by omega,˽];split<;>simp[*] lemma O5 (X W:┠ ┢) (a b lo:Nat):∀ r k,YB X W a b lo k r=((List.range' k r).map λ u=>sv X[a+u]!*sv W[b+u]!*2^(idxOf X[a+u]!+idxOf W[b+u]!-lo)).sum:=by intro r;induction r with | zero=>intro k;rfl | succ r ih=>intro k;rw[YB,ih,˽];simp lemma QFL (L:List Nat) (p:Nat -> Prop) [DecidablePred p] (g:Nat -> Int) (h:∀ x ∈ L,¬p x -> g x=0):((L.filter p).map g).sum=(L.map g).sum:=by induction L with | nil=>rfl | cons x L ih=>simp only[List.filter_cons,List.map_cons,List.sum_cons];split<;>simp_all lemma F0 (X:┠ ┢) (P:┠ Nat) (I:┠ ┟) (W b:┠ ┢) (inW i j:Nat) (H:(I.size=0 -> ∀ t,t<2*inW -> P.size=2*inW -> P[t]! = QPb X[i*inW+t/2]! (Yk (Yc X inW i>>>16)) (t%2=1)) /\ (I.size≠0 -> I܃=((՛ inW).filter λ t=>Yf X[i*inW+t]! ≠ 0).map (·.toUInt32) /\ ∀ u,u<2*I.size -> P.size=2*I.size -> P[u]! = QPb X[i*inW+(I[u/2]!)؊]! (Yk (Yc X inW i>>>16)) (u%2=1))) : QPa X P I W b inW i j (Yc X inW i) (Yc W inW 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 QPa;dsimp only;by_cases c:I.size=0<;>simp only[c,↓reduceDIte,↓reduceIte]<;>split<;>(try exact W9 X W b inW i j)<;>rename_i h <;> obtain⟨q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q14,q15,q16⟩:=h<;>have rx:=A7 X inW i _ q3 q5 q8 q10 le_rfl<;>have rv:=A7 W inW j _ q4 q6 q9 q11 le_rfl <;> have U:∀ {α:Type} [Inhabited α] (A:┠ α) (k:┡) h,A.uget k h=A[k܆]!:=λ A k h=>by rw[┍ A k܆ h];rfl . have hP:=H.1 c;exact O3 X W b inW i j _ _ _ _ X W _ _ _ _ q3 q4 q5 q6 q7 ܉ (by rw[Za _ ܉];omega) (by rw[Za _ ܉]) rx rv q14 q15 (λ t h=>by have ht:=˩ h;rw[Za _ ܉]at ht have e:((j*inW)؝+t)܆=j*inW+t܆:=by rw[Zc _ _ (by rw[Za _ ܉];have:=˖;omega),Za _ ܉] simp only[U,e];have r2:=(rv _ ht).1;generalize W[j*inW+t܆]! = w at r2 ⊢;obtain⟨e1,e2⟩:=B6 t w ܉;have hs:=O4 w;simp only[՝]at hs rw[e1,hP _ ܉ q1,show(2*t܆+(w>>>31)؊)/2=t܆ by omega,show decide ((2*t܆+(w>>>31)؊)%2=1)=signOf w by rcases Bool.eq_false_or_eq_true (signOf w) with c|c<;>rw[c]at hs ⊢<;>simp only[↓reduceIte,¥,┃,decide_eq_false_iff_not]at hs ⊢<;>omega] have:=A9 _ _ _ _ _ _ q12 (rx _ ht).1 r2 q16;rw[this.1];exact⟨rfl,this.2.1.le,this.2.2.le⟩) . obtain⟨hI,hP⟩:=H.2 c;have hm:∀ m,m (I[m]!)؊ < inW:=λ m h=>by have e:I܃[m]'߶ ∈ ((՛ inW).filter λ t=>Yf X[i*inW+t]! ≠ 0).map (·.toUInt32):=hI ▸ List.getElem_mem _ rw[┍ I m h];simp only[List.mem_map,List.mem_filter,List.mem_range,Array.getElem_toList]at e;obtain⟨u,⟨hu,-⟩,e⟩:=e;rw[<- e];simp;omega have V:∀ (g:┟ -> ┢) m,m (I.map g)[0+m]! = g I[m]!:=λ g m h=>by rw[˥,┍ _ m ߶,┍ I m h];simp have hL:=congrArg List.length hI;simp only[Array.length_toList,List.length_map]at hL;exact O3 X W b inW i j _ _ _ _ (I.map λ v=>X[i*inW+v؊]!) (I.map λ v=>W[j*inW+v؊]!) 0 0 _ _ q3 q4 q5 q6 q7 ܉ (by rw[Za _ ܉];omega) (by rw[Za _ ܉,O5,O5,<- List.range_eq_range',<- List.range_eq_range',<- QFL (՛ inW) (λ t=>Yf X[i*inW+t]! ≠ 0) _ (λ u _ h=>by simp only[not_not]at h;have:mantOf X[i*inW+u]! = 0:=by rw[<- Zk,h];rfl simp[sv,this])] congr 1;apply ۔ (by simp[hL]);intro m h1 h2;simp only[List.length_map,List.length_range]at h1 have e:=List.getElem_of_eq hI ߶;simp only[Array.getElem_toList,List.getElem_map]at e have f:=List.getElem_mem (l:=(՛ inW).filter λ t=>Yf X[i*inW+t]! ≠ 0) (by rw[<- hL];exact h1);simp only[List.mem_filter,List.mem_range]at f have k:(I[m]'h1)؊=((՛ inW).filter λ t=>Yf X[i*inW+t]! ≠ 0)[m]'(by rw[<- hL];exact h1):=by rw[e];generalize ((՛ inW).filter λ t=>Yf X[i*inW+t]! ≠ 0)[m]'(by rw[<- hL];exact h1)=u at f ⊢;simp;omega simp only[List.getElem_map,List.getElem_range,V _ _ h1,┍ I m h1,k]) rx rv q14 q15 (λ t h=>by have ht:=˩ h;rw[Za _ ܉]at ht;have ei:=hm _ ht rw[V _ _ ht,V _ _ ht];have e:((j*inW)؝+(I[t܆]!).toUSize)܆=j*inW+(I[t܆]!)؊:=by rw[Zc _ _ (by rw[Za _ ܉,⠈];have:=˖;omega),Za _ ܉,⠈] simp only[U];rw[(O7 _ inW ܉).2 ܉,e];have r2:=(rv _ ei).1;generalize W[j*inW+(I[t܆]!)؊]! = w at r2 ⊢ obtain⟨e1,e2⟩:=B6 t w ܉;have hs:=O4 w;simp only[՝]at hs rw[e1,hP _ ܉ q1,show(2*t܆+(w>>>31)؊)/2=t܆ by omega,show decide ((2*t܆+(w>>>31)؊)%2=1)=signOf w by rcases Bool.eq_false_or_eq_true (signOf w) with c|c<;>rw[c]at hs ⊢<;>simp only[↓reduceIte,¥,┃,decide_eq_false_iff_not]at hs ⊢<;>omega] have:=A9 _ _ _ _ _ _ q12 (rx _ ei).1 r2 q16;rw[this.1];exact⟨rfl,this.2.1.le,this.2.2.le⟩) lemma W8:YaV=linearSpec:=by funext rows inW outW relu X W b;unfold YaV linearSpec linearWith;dsimp only;rw[ZB _ _ _ rfl]<;>congr 1<;>funext q<;>have hq:=q.isLt<;>have h0:0 have hi:q؞/outWhave hj:q؞%outW rw[Ze rows (λ i=>Yc X inW i) _ hi,Ze outW (λ j=>Yc W inW j) _ hj] rw[F0];split . rw[┍ _ (q؞/outW) ߶];simp only[Array.getElem_ofFn];split . rename_i hc;simp only[˯,┃]at hc;refine⟨λ c=>absurd c (by dsimp only;omega),λ _=>⟨?_,λ u hu hs=>?_⟩⟩ . rw[F3 _ _ _ 0 _ rfl];simp[<- List.range_eq_range'] . rw[B1,┍ _ u (by rw[Array.size_ofFn];omega)];simp[Ze rows _ _ hi] . exact⟨λ _ t ht hs=>by rw[B1,┍ _ t ߶];simp[Ze rows _ _ hi],λ c=>absurd rfl c⟩ . rw[┍ _ _ ߶];simp;intro t ht hs;omega def kernels:Kernels where core:=kernels0.core dense:=⟨YaV,Ya3⟩ conv:=⟨Ybp,dwQ⟩ elem:=⟨Ybk,Ybl,Ybf,Ybe⟩ norm:=⟨Ybb,Ybc⟩ theorem correct:Obligation kernels:=by have h:kernels0=specKernels:=X6;simp only[Obligation,kernels,h,specKernels,specDense,specConv,specElem,specNorm,W8,X5,R6,R5,R4,S4,S5, R3,P4,P3] end Submission