refactor: let Nat.mod reduce more (#4145)
this refined upon #4098 and makes `Nat.mod` reduce on even more literals. The key observation that I missed earlier is that `if m ≤ n` reduces better than `if n < m`. Also see discussion at https://github.com/leanprover-community/mathlib4/pull/12853#discussion_r1597798308
This commit is contained in:
parent
d833f82fe8
commit
842280321b
2 changed files with 21 additions and 18 deletions
|
|
@ -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 -/
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue