diff --git a/src/Init/Data/Fin/Lemmas.lean b/src/Init/Data/Fin/Lemmas.lean index 1a0f5b9113..928c02e4fe 100644 --- a/src/Init/Data/Fin/Lemmas.lean +++ b/src/Init/Data/Fin/Lemmas.lean @@ -208,7 +208,6 @@ theorem val_add_one {n : Nat} (i : Fin (n + 1)) : | .inl h => cases Fin.eq_of_val_eq h; simp | .inr h => simpa [Fin.ne_of_lt h] using val_add_one_of_lt h -unseal Nat.modCore in @[simp] theorem val_two {n : Nat} : (2 : Fin (n + 3)).val = 2 := rfl theorem add_one_pos (i : Fin (n + 1)) (h : i < Fin.last n) : (0 : Fin (n + 1)) < i + 1 := by @@ -243,7 +242,6 @@ theorem succ_ne_zero {n} : ∀ k : Fin n, Fin.succ k ≠ 0 @[simp] theorem succ_zero_eq_one : Fin.succ (0 : Fin (n + 1)) = 1 := rfl -unseal Nat.modCore in /-- Version of `succ_one_eq_two` to be used by `dsimp` -/ @[simp] theorem succ_one_eq_two : Fin.succ (1 : Fin (n + 2)) = 2 := rfl @@ -395,7 +393,6 @@ theorem castSucc_lt_last (a : Fin n) : castSucc a < last n := a.is_lt @[simp] theorem castSucc_zero : castSucc (0 : Fin (n + 1)) = 0 := rfl -unseal Nat.modCore in @[simp] theorem castSucc_one {n : Nat} : castSucc (1 : Fin (n + 2)) = 1 := rfl /-- `castSucc i` is positive when `i` is positive -/ diff --git a/src/Init/Data/Nat/Div.lean b/src/Init/Data/Nat/Div.lean index ae531772cb..7cbff46be5 100644 --- a/src/Init/Data/Nat/Div.lean +++ b/src/Init/Data/Nat/Div.lean @@ -82,28 +82,34 @@ decreasing_by apply div_rec_lemma; assumption @[extern "lean_nat_mod"] protected def mod : @& Nat → @& Nat → Nat - /- These four cases are not needed mathematically, they are just special cases of the - general case. However, it makes `0 % n = 0` etc. true definitionally rather than just - propositionally. + /- + Nat.modCore is defined by well-founded recursion and thus irreducible. Nevertheless it is + desireable if trivial `Nat.mod` calculations, namely + * `Nat.mod 0 m` for all `m` + * `Nat.mod n (m+n)` for concrete literals `n` + reduce definitionally. This property is desirable for `Fin n` literals, as it means `(ofNat 0 : Fin n).val = 0` by - definition. This was true in lean3 and it simplified things for mathlib if it remains true. -/ + definition. + -/ | 0, _ => 0 - | 1, 0 => 0 - | 1, 1 => 0 - | 1, (_+2) => 1 - | x@(_ + 2), y => Nat.modCore x y + | n@(_ + 1), m => + if m ≤ n -- NB: if n < m does not reduce as well as `m ≤ n`! + then Nat.modCore n m + else n instance instMod : Mod Nat := ⟨Nat.mod⟩ -protected theorem modCore_eq_mod (x y : Nat) : Nat.modCore x y = x % y := by - match x, y with - | 0, y => +protected theorem modCore_eq_mod (n m : Nat) : Nat.modCore n m = n % m := by + show Nat.modCore n m = Nat.mod n m + match n, m with + | 0, _ => rw [Nat.modCore] exact if_neg fun ⟨hlt, hle⟩ => Nat.lt_irrefl _ (Nat.lt_of_lt_of_le hlt hle) - | 1, 0 => rw [Nat.modCore]; rfl - | 1, 1 => rw [Nat.modCore, Nat.modCore]; rfl - | 1, (_+2) => rw [Nat.modCore]; rfl - | (_ + 2), _ => rfl + | (_ + 1), _ => + rw [Nat.mod]; dsimp + refine iteInduction (fun _ => rfl) (fun h => ?false) -- cannot use `split` this early yet + rw [Nat.modCore] + exact if_neg fun ⟨_hlt, hle⟩ => h hle theorem mod_eq (x y : Nat) : x % y = if 0 < y ∧ y ≤ x then (x - y) % y else x := by rw [←Nat.modCore_eq_mod, ←Nat.modCore_eq_mod, Nat.modCore]