@@ -3053,6 +3053,12 @@ theorem getLsbD_extractAndExtendPopulate_add {x : BitVec w} (hk : k < w):
30533053 simp [← extractLsb'_extractAndExtendPopulate_eq (w := w) (len := w) (i := pos) (x := x)]
30543054 omega
30553055
3056+ theorem getLsbD_extractAndExtendPopulate_add' {x : BitVec w} (hk : k < v) :
3057+ (x.extractAndExtendPopulate v).getLsbD (pos * v + k) = ((x.extractLsb' pos 1 ).zeroExtend v).getLsbD k := by
3058+ simp [← extractLsb'_extractAndExtendPopulate_eq (w := w) (len := v) (i := pos) (x := x)]
3059+ intros
3060+ omega
3061+
30563062theorem getLsbD_extractAndExtend_of_le_of_lt (w idx currIdx : Nat) (hw : 0 < w) (x : BitVec w)
30573063 (_hcurr : currIdx < w)
30583064 (hlt : idx < w * (currIdx + 1 )) (hle : w * currIdx ≤ idx) :
@@ -3093,14 +3099,108 @@ theorem getLsbD_extractAndExtend_of_le_of_lt (w idx currIdx : Nat) (hw : 0 < w)
30933099 omega
30943100
30953101
3096- theorem th3 :
3097- (extractAndExtendPopulate w (setWidth n x)).addRecAux n 0 #w = (extractAndExtendPopulate w x).addRecAux n 0 #w := by
3098- have : extractAndExtendPopulate w (setWidth n x) = (extractAndExtendPopulate w x).setWidth (n * w) := by
3099- generalize hgen : extractAndExtendPopulate w x = gen
3102+ theorem getLsbD_extractAndExtend {x : BitVec w} (hv : 0 < v):
3103+ (BitVec.extractAndExtendPopulate v x).getLsbD k =
3104+ let idx := k % v
3105+ let pos := (k - idx) / v
3106+ ((x.extractLsb' pos 1 ).zeroExtend v).getLsbD idx := by
3107+ rw [← getLsbD_extractAndExtendPopulate_add' (by exact mod_lt k hv)]
3108+ congr
3109+ have := Nat.mod_def (m := k) (k := v)
3110+ have : (k - k % v) % v = 0 := by
3111+ rw [Nat.mod_def (m := k) (k := v)]
3112+ have : k - (k - v * (k / v)) = (v * (k / v)) := by
3113+ refine Nat.sub_sub_self ?_
3114+ rw [Nat.mul_comm]
3115+ exact div_mul_le_self k v
3116+ rw [this ]
3117+ rw [Nat.mul_comm]
3118+ exact mul_mod_left (k / v) v
3119+ rw [Nat.div_mul_cancel (by omega)]
3120+ omega
31003121
3101- sorry
3122+ theorem extractAndExtendPopulate_setWidth {x : BitVec w} (hv : 0 < v) :
3123+ (extractAndExtendPopulate v (setWidth m x)) =
3124+ setWidth (m * v) ((extractAndExtendPopulate v x)) := by
3125+ ext k hk
3126+ rw [← getLsbD_eq_getElem]
3127+ rw [← getLsbD_eq_getElem]
3128+ rw [getLsbD_extractAndExtend (x := (setWidth m x)) (v := v) (k := k) (by omega)]
3129+ simp
3130+ rw [getLsbD_extractAndExtend (x := x) (v := v) (k := k) (by omega)]
3131+ simp
3132+ have := mod_lt (y := v) (x := k) hv
3133+ simp [this ]
3134+ by_cases hmod0 : k % v = 0
3135+ · simp [hmod0]
3136+ have : (k / v < m) = (k < m * v) := by
3137+ simp
3138+ constructor
3139+ · intro hc
3140+ omega
3141+ · intro hc
3142+ exact (div_lt_iff_lt_mul hv).mpr hk
3143+ simp [this ]
3144+ · simp [hmod0]
31023145
3103- sorry
3146+ theorem addRecAux_setWidth_extractAndExtend {x : BitVec w} (hn : n ≤ w) (hv : 0 < v) (hm : n ≤ m):
3147+ (setWidth (m * v) (extractAndExtendPopulate v x)).addRecAux n 0 #v =
3148+ (extractAndExtendPopulate v x).addRecAux n 0 #v := by
3149+ induction n generalizing m v
3150+ · case zero => simp
3151+ · case succ n ihn =>
3152+ simp
3153+ rw [← addRecAux_zero_add]
3154+ conv =>
3155+ rhs
3156+ rw [← addRecAux_zero_add]
3157+ rw [ihn (by omega) (by omega) (by omega)]
3158+ simp
3159+ rw [extractLsb'_extractAndExtendPopulate_eq ]
3160+ rw [← extractAndExtendPopulate_setWidth (by omega)]
3161+ rw [extractLsb'_extractAndExtendPopulate_eq]
3162+ ext k hk
3163+ simp
3164+ by_cases hk0 : k = 0
3165+ · simp [hk0]
3166+ intros
3167+ omega
3168+ · simp [hk0]
3169+
3170+ theorem th3 {x : BitVec w} (h : n ≤ w) (hw : 1 < w) (hv : v < w) (hn : n ≤ m):
3171+ (extractAndExtendPopulate v (setWidth m x)).addRecAux n 0 #v = (extractAndExtendPopulate v x).addRecAux n 0 #v := by
3172+ induction n generalizing v m
3173+ · case _ =>
3174+ simp
3175+ · case _ n' ihn' =>
3176+ simp
3177+ rw [← addRecAux_zero_add]
3178+ conv =>
3179+ rhs
3180+ rw [← addRecAux_zero_add]
3181+ by_cases hn' : n' ≤ w
3182+ · rw [ihn' hn' (by omega) (by omega)]
3183+ simp
3184+ ext k hk
3185+ rw [extractLsb'_extractAndExtendPopulate_eq]
3186+ rw [extractLsb'_extractAndExtendPopulate_eq]
3187+ simp
3188+ by_cases hk0 : k = 0
3189+ · simp [hk0]
3190+ omega
3191+ · simp [hk0]
3192+ · have : n' = w + 1 := by omega
3193+ subst this
3194+ congr 1
3195+ · rw [extractAndExtendPopulate_setWidth (by omega)]
3196+ rw [addRecAux_setWidth_extractAndExtend (by omega) (by omega) (by omega)]
3197+ · rw [extractLsb'_extractAndExtendPopulate_eq]
3198+ rw [extractLsb'_extractAndExtendPopulate_eq]
3199+ simp
3200+ ext k hk
3201+ by_cases hk0 : k = 0
3202+ · simp [hk0]
3203+ · simp [hk0]
31043204
31053205theorem addRecAux_extractAndExtendPopulate_setWidth_eq {x : BitVec (w + 1 )} (h : n ≤ w) :
31063206 (extractAndExtendPopulate w (setWidth w x)).addRecAux n 0 #w =
@@ -3129,7 +3229,7 @@ theorem addRecAux_extractAndExtendPopulate_setWidth_eq {x : BitVec (w + 1)} (h :
31293229 have hext2 := extractLsb'_extractAndExtendPopulate_eq (w := w + 1 ) (len := w) (i := w) (x := x)
31303230 have hext1 := extractLsb'_extractAndExtendPopulate_eq (w := w) (len := w) (i := w) (x := (x.setWidth w))
31313231 congr 1
3132- · rw [th3]
3232+ · rw [th3 ( by omega) ( by omega) ( by omega) ( by omega) ]
31333233 · rw [hext1, hext2]
31343234 ext k hk
31353235 simp
@@ -3170,6 +3270,8 @@ theorem addRecAux_extractAndExtendPopulateAux_le_of_le {x : BitVec w} (hn : n
31703270 · have := Nat.lt_two_pow_self (n := w + 1 + 1 )
31713271 omega
31723272
3273+
3274+
31733275theorem addRecAux_extractAndExtendPopulateAux_le_of_le_of_lt {x : BitVec (w + 1 )} (hn : n ≤ w) :
31743276 ((extractAndExtendPopulate w x).addRecAux n 0 #w).toNat ≤ n := by
31753277 induction n
@@ -3197,51 +3299,73 @@ theorem addRecAux_extractAndExtendPopulateAux_le_of_le_of_lt {x : BitVec (w + 1)
31973299 have := Nat.lt_two_pow_self (n := w)
31983300 omega
31993301
3200- theorem thm4 {x : BitVec (w' + 1 + 1 ) } (hn : n ≤ w') :
3201- (extractAndExtendPopulate v (setWidth (w' + 1 ) x)) .addRecAux n 0 #v =
3202- (extractAndExtendPopulate v x).addRecAux n 0 #v := by
3203- induction n generalizing v
3204- · case zero =>
3302+ theorem addRecAux_extractAndExtendPopulateAux_le_of_le' {x : BitVec w } (h : n < 2 ^ v) :
3303+ (( extractAndExtendPopulate v x) .addRecAux n 0 #v).toNat ≤ n := by
3304+ induction n
3305+ · simp
3306+ · case _ n ihn =>
32053307 simp
3308+ rw [← addRecAux_zero_add]
3309+ simp only [toNat_add, -extractLsb'_toNat, add_mod_mod]
3310+ have : (extractLsb' (n * v) v (extractAndExtendPopulate v x)).toNat ≤ 1 := by
3311+ rw [extractLsb'_extractAndExtendPopulate_eq]
3312+ simp
3313+ rw [Nat.mod_eq_of_lt]
3314+ · omega
3315+ · omega
3316+ rw [Nat.mod_eq_of_lt]
3317+ · omega
3318+ · omega
3319+
3320+ theorem toNat_addRecAux_extractAndExtendPopulate {x : BitVec w} (hn : n ≤ w) (hv : v < w) (hv : 0 < v) (h : w < 2 ^ v) :
3321+ ((extractAndExtendPopulate v x).addRecAux n 0 #v).toNat =
3322+ ((extractAndExtendPopulate (v + 1 ) x).addRecAux n 0 #(v + 1 )).toNat := by
3323+ induction n
3324+ · case zero => simp
32063325 · case succ n ihn =>
32073326 simp
3208- rw [←addRecAux_zero_add]
3327+ rw [← addRecAux_zero_add]
3328+ have := addRecAux_extractAndExtendPopulateAux_le_of_le (x := x) (n := n) (by omega)
3329+ have := Nat.pow_lt_pow_of_lt (a := 2 ) (n := 1 ) (m := v + 1 ) (by omega) (by omega)
3330+ have : (zeroExtend (v + 1 ) (extractLsb' n 1 x)).toNat ≤ 1 := by
3331+ simp
3332+ have := Nat.mod_lt (y := 2 ) (x := x.toNat >>> n)
3333+ rw [Nat.mod_eq_of_lt]
3334+ <;> omega
3335+ have : n + 1 < 2 ^ (v + 1 ) := by
3336+ omega
32093337 conv =>
32103338 rhs
3211- rw [←addRecAux_zero_add]
3212- by_cases hle : n ≤ w'
3213- · rw [ihn hle]
3214- simp [extractLsb'_extractAndExtendPopulate_eq]
3215- ext k hk
3216- by_cases hk : k = 0
3217- · simp [hk]
3339+ rw [← addRecAux_zero_add]
3340+ simp only [toNat_add, ihn (by omega), -extractLsb'_toNat, add_mod_mod]
3341+ rw [extractLsb'_extractAndExtendPopulate_eq]
3342+ rw [extractLsb'_extractAndExtendPopulate_eq]
3343+ rcases v with _|v
3344+ · omega
3345+ · have h1 := addRecAux_extractAndExtendPopulateAux_le_of_le' (x := x) (n := n) (v := v + 1 + 1 ) (by omega)
3346+ have := addRecAux_extractAndExtendPopulateAux_le_of_le (x := x) (n := n) (by omega)
3347+ have := Nat.pow_lt_pow_of_lt (a := 2 ) (n := 1 ) (m := v + 1 + 1 ) (by omega) (by omega)
3348+ have : (zeroExtend (v + 1 ) (extractLsb' n 1 x)).toNat ≤ 1 := by
3349+ simp
3350+ have := Nat.mod_lt (y := 2 ) (x := x.toNat >>> n)
3351+ rw [Nat.mod_eq_of_lt]
3352+ <;> omega
3353+ have : n + 1 < 2 ^ (v + 1 ) := by
32183354 omega
3219- · simp [hk]
3220- · have : n = w' + 1 := by omega
3221- subst this
3222- rw [←addRecAux_zero_add]
3223- conv =>
3224- rhs
3225- rw [←addRecAux_zero_add]
3226- induction v
3227- · case _ =>
3355+ rw [Nat.mod_eq_of_lt]
3356+ · rw [Nat.mod_eq_of_lt]
3357+ · simp
3358+ rw [Nat.mod_eq_of_lt (b := 2 ^ (v + 1 ))]
3359+ · rw [Nat.mod_eq_of_lt (b := 2 ^ (v + 1 + 1 ))]
3360+ omega
3361+ · omega
3362+ · omega
3363+ · have : ((extractAndExtendPopulate (v + 1 + 1 ) x).addRecAux n 0 #(v + 1 + 1 )).toNat +
3364+ (zeroExtend (v + 1 ) (extractLsb' n 1 x)).toNat ≤ n + 1 := by omega
32283365 omega
3229- · case _ v' ihv' =>
3230- congr 1
3231- ·
3232-
32333366
32343367
3235- sorry
3236- · ext k hk
3237- simp
3238- omega
3239-
3240- theorem thm5 {x : BitVec (w' + 1 + 1 )} (hn : n ≤ w') :
3241- ((extractAndExtendPopulate (w' + 1 ) x).addRecAux n 0 #(w' + 1 )).toNat =
3242- ((extractAndExtendPopulate (w' + 1 + 1 ) x).addRecAux n 0 #(w' + 1 + 1 )).toNat := by sorry
3243-
3244- theorem thm1 {x : BitVec (w' + 1 )} (hn : n ≤ w') :
3368+ theorem setWidth_addRecAux_estractAndExtendPopuate_of_le {x : BitVec (w' + 1 )} (hn : n ≤ w') :
32453369 setWidth (w' + 1 ) ((extractAndExtendPopulate w' (setWidth w' x)).addRecAux n 0 #w') =
32463370 (extractAndExtendPopulate (w' + 1 ) x).addRecAux n 0 #(w' + 1 ) := by
32473371 induction n generalizing w'
@@ -3366,7 +3490,8 @@ theorem thm1 {x : BitVec (w' + 1)} (hn : n ≤ w') :
33663490 · rw [Nat.mod_eq_of_lt]
33673491 · rw [Nat.add_assoc]
33683492 congr 1
3369- · simp [thm4, thm5]
3493+ · rw [th3 (by omega) (by omega) (by omega) (by omega)]
3494+ rw [toNat_addRecAux_extractAndExtendPopulate (by omega) (by omega) (by omega) (by omega)]
33703495 · rw [heq14Nat, heq23Nat, Nat.add_comm]
33713496 · omega
33723497 · omega
@@ -3378,7 +3503,6 @@ theorem thm1 {x : BitVec (w' + 1)} (hn : n ≤ w') :
33783503 <;> omega
33793504 · omega
33803505
3381-
33823506theorem cpop_eq_recursive_addition {x : BitVec w} :
33833507 let arg := extractAndExtendPopulate w x
33843508 x.cpop = arg.addRecAux w 0 #w := by
@@ -3409,8 +3533,7 @@ theorem cpop_eq_recursive_addition {x : BitVec w} :
34093533 rw [this ]
34103534 rw [ihw']
34113535 congr 1
3412- ·
3413- rw [thm1 (by omega), addRecAux_extractAndExtendPopulate_setWidth_eq (by omega)]
3536+ · rw [setWidth_addRecAux_estractAndExtendPopuate_of_le (by omega)]
34143537 · rw [hext]
34153538 simp
34163539 have : x[w'].toNat ≤ 1 := by cases x[w'] <;> simp
0 commit comments