mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-30 00:34:07 +00:00
Compare commits
9 Commits
inferInsta
...
inv_dyadic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6eb9d9ceb | ||
|
|
5021db43ea | ||
|
|
4758a759aa | ||
|
|
91b113532c | ||
|
|
0b41137923 | ||
|
|
24d316eb17 | ||
|
|
b4f2d75ff7 | ||
|
|
4136fc4ea3 | ||
|
|
c2b2a2adbc |
@@ -9,3 +9,4 @@ prelude
|
||||
public import Init.Data.Dyadic.Basic
|
||||
public import Init.Data.Dyadic.Instances
|
||||
public import Init.Data.Dyadic.Round
|
||||
public import Init.Data.Dyadic.Inv
|
||||
|
||||
@@ -75,7 +75,7 @@ theorem trailingZeros_two_mul {i : Int} (h : i ≠ 0) :
|
||||
|
||||
theorem shiftRight_trailingZeros_mod_two {i : Int} (h : i ≠ 0) :
|
||||
(i >>> i.trailingZeros) % 2 = 1 := by
|
||||
rw (occs := .pos [2]) [← Int.emod_add_ediv i 2]
|
||||
rw (occs := .pos [2]) [← Int.emod_add_mul_ediv i 2]
|
||||
rcases i.emod_two_eq with h' | h' <;> rw [h']
|
||||
· rcases Int.dvd_of_emod_eq_zero h' with ⟨a, rfl⟩
|
||||
simp only [ne_eq, Int.mul_eq_zero, Int.reduceEq, false_or] at h
|
||||
@@ -92,7 +92,7 @@ theorem two_pow_trailingZeros_dvd {i : Int} (h : i ≠ 0) :
|
||||
simp only [ne_eq, Int.mul_eq_zero, Int.reduceEq, false_or] at h
|
||||
rw [trailingZeros_two_mul h, Int.pow_succ']
|
||||
exact Int.mul_dvd_mul_left _ (two_pow_trailingZeros_dvd h)
|
||||
· rw (occs := .pos [1]) [← Int.emod_add_ediv i 2, h', Int.add_comm, trailingZeros_two_mul_add_one]
|
||||
· rw (occs := .pos [1]) [← Int.emod_add_mul_ediv i 2, h', Int.add_comm, trailingZeros_two_mul_add_one]
|
||||
exact Int.one_dvd _
|
||||
termination_by i.natAbs
|
||||
|
||||
@@ -415,16 +415,22 @@ theorem precision_ofIntWithPrec_le {i : Int} (h : i ≠ 0) (prec : Int) :
|
||||
| .zero => rfl
|
||||
| .ofOdd _ _ _ => rfl
|
||||
|
||||
end Dyadic
|
||||
|
||||
namespace Rat
|
||||
|
||||
open Dyadic
|
||||
|
||||
/--
|
||||
Convert a rational number `x` to the greatest dyadic number with precision at most `prec`
|
||||
which is less than or equal to `x`.
|
||||
-/
|
||||
def _root_.Rat.toDyadic (x : Rat) (prec : Int) : Dyadic :=
|
||||
def toDyadic (x : Rat) (prec : Int) : Dyadic :=
|
||||
match prec with
|
||||
| (n : Nat) => .ofIntWithPrec ((x.num <<< n) / x.den) prec
|
||||
| -(n + 1 : Nat) => .ofIntWithPrec (x.num / (x.den <<< (n + 1))) prec
|
||||
|
||||
theorem _root_.Rat.toDyadic_mkRat (a : Int) (b : Nat) (prec : Int) :
|
||||
theorem toDyadic_mkRat (a : Int) (b : Nat) (prec : Int) :
|
||||
Rat.toDyadic (mkRat a b) prec =
|
||||
.ofIntWithPrec ((a <<< prec.toNat) / (b <<< (-prec).toNat)) prec := by
|
||||
by_cases hb : b = 0
|
||||
@@ -432,15 +438,96 @@ theorem _root_.Rat.toDyadic_mkRat (a : Int) (b : Nat) (prec : Int) :
|
||||
rcases h : mkRat a b with ⟨n, d, hnz, hr⟩
|
||||
obtain ⟨m, hm, rfl, rfl⟩ := Rat.mkRat_num_den hb h
|
||||
cases prec
|
||||
· simp only [Rat.toDyadic, Int.ofNat_eq_coe, Int.toNat_natCast, Int.toNat_neg_nat,
|
||||
· simp only [Rat.toDyadic, Int.ofNat_eq_coe, Int.toNat_natCast, Int.toNat_neg_natCast,
|
||||
shiftLeft_zero, Int.natCast_mul]
|
||||
rw [Int.mul_comm d, ← Int.ediv_ediv (by simp), ← Int.shiftLeft_mul,
|
||||
Int.mul_ediv_cancel _ (by simpa using hm)]
|
||||
· simp only [Rat.toDyadic, Int.natCast_shiftLeft, Int.negSucc_eq, ← Int.natCast_add_one,
|
||||
Int.toNat_neg_nat, Int.shiftLeft_zero, Int.neg_neg, Int.toNat_natCast, Int.natCast_mul]
|
||||
Int.toNat_neg_natCast, Int.shiftLeft_zero, Int.neg_neg, Int.toNat_natCast, Int.natCast_mul]
|
||||
rw [Int.mul_comm d, ← Int.mul_shiftLeft, ← Int.ediv_ediv (by simp),
|
||||
Int.mul_ediv_cancel _ (by simpa using hm)]
|
||||
|
||||
theorem toDyadic_eq_ofIntWithPrec (x : Rat) (prec : Int) :
|
||||
x.toDyadic prec = .ofIntWithPrec ((x.num <<< prec.toNat) / (x.den <<< (-prec).toNat)) prec := by
|
||||
conv => lhs; rw [← Rat.mkRat_self x]
|
||||
rw [Rat.toDyadic_mkRat]
|
||||
|
||||
/--
|
||||
Converting a rational to a dyadic at a given precision and then back to a rational
|
||||
gives the same result as taking the floor of the rational at precision `2 ^ prec`.
|
||||
-/
|
||||
theorem toRat_toDyadic (x : Rat) (prec : Int) :
|
||||
(x.toDyadic prec).toRat = (x * 2 ^ prec).floor / 2 ^ prec := by
|
||||
rw [Rat.toDyadic_eq_ofIntWithPrec, toRat_ofIntWithPrec_eq_mul_two_pow, Rat.zpow_neg, Rat.div_def]
|
||||
congr 2
|
||||
rw [Rat.floor_def, Int.shiftLeft_eq, Nat.shiftLeft_eq]
|
||||
match prec with
|
||||
| .ofNat prec =>
|
||||
simp only [Int.ofNat_eq_coe, Int.toNat_natCast, Int.toNat_neg_natCast, Nat.pow_zero,
|
||||
Nat.mul_one]
|
||||
have : (2 ^ prec : Rat) = ((2 ^ prec : Nat) : Rat) := by simp
|
||||
rw [Rat.zpow_natCast, this, Rat.mul_def']
|
||||
simp only [Rat.num_mkRat, Rat.den_mkRat]
|
||||
simp only [Rat.natCast_pow, Rat.natCast_ofNat, Rat.num_pow, Rat.num_ofNat, Rat.den_pow,
|
||||
Rat.den_ofNat, Nat.one_pow, Nat.mul_one]
|
||||
split
|
||||
· simp_all
|
||||
· rw [Int.ediv_ediv (Int.ofNat_zero_le _)]
|
||||
congr 1
|
||||
rw [Int.natCast_ediv, Int.mul_ediv_cancel']
|
||||
rw [Int.natCast_dvd_natCast]
|
||||
apply gcd_dvd_left
|
||||
| .negSucc prec =>
|
||||
simp only [Int.toNat_negSucc, Int.pow_zero, Int.mul_one, Int.neg_negSucc, Int.natCast_mul,
|
||||
Int.natCast_pow, Int.cast_ofNat_Int]
|
||||
have : (2 ^ ((prec : Int) + 1)) = ((2 ^ (prec + 1) : Nat) : Rat) := by simp; rfl
|
||||
rw [Int.negSucc_eq, Rat.zpow_neg, this, Rat.mul_def']
|
||||
simp only [Rat.num_mkRat, Rat.den_mkRat]
|
||||
simp only [natCast_pow, natCast_ofNat, den_inv, num_pow, num_ofNat, Int.natAbs_pow,
|
||||
Int.reduceAbs, num_inv, den_pow, den_ofNat, Nat.one_pow, Int.cast_ofNat_Int, Int.mul_one]
|
||||
have : ¬ (2 ^ (prec + 1) : Int) = 0 := NeZero.out
|
||||
simp only [if_neg this]
|
||||
have : (2 ^ (prec + 1) : Int).sign = 1 := by simpa using Int.pow_pos (by decide)
|
||||
simp only [this]
|
||||
have : x.den * 2 ^ (prec + 1) = 0 ↔ x.den = 0 := by
|
||||
rw [Nat.mul_eq_zero]
|
||||
simp_all
|
||||
simp only [this, Int.mul_one]
|
||||
split
|
||||
· simp_all
|
||||
· rw [Int.ediv_ediv (Int.ofNat_zero_le _)]
|
||||
congr 1
|
||||
rw [Int.natCast_ediv, Int.mul_ediv_cancel']
|
||||
· simp
|
||||
· rw [Int.natCast_dvd_natCast]
|
||||
apply gcd_dvd_left
|
||||
|
||||
theorem toRat_toDyadic_le {x : Rat} {prec : Int} : (x.toDyadic prec).toRat ≤ x := by
|
||||
rw [toRat_toDyadic]
|
||||
have : (x * 2 ^ prec).floor ≤ x * 2 ^ prec := Rat.floor_le _
|
||||
apply Rat.le_of_mul_le_mul_right (c := 2 ^ prec)
|
||||
rw [Rat.div_mul_cancel]
|
||||
exact this
|
||||
· apply Rat.ne_of_gt (Rat.zpow_pos (by decide))
|
||||
· exact Rat.zpow_pos (by decide)
|
||||
|
||||
theorem lt_toRat_toDyadic_add {x : Rat} {prec : Int} :
|
||||
x < (x.toDyadic prec + ofIntWithPrec 1 prec).toRat := by
|
||||
rw [toRat_add, toRat_toDyadic, toRat_ofIntWithPrec_eq_mul_two_pow]
|
||||
have := Rat.lt_floor_add_one (x * 2 ^ prec)
|
||||
rw [Rat.zpow_neg, Rat.div_def, ← Rat.add_mul]
|
||||
apply Rat.lt_of_mul_lt_mul_right (c := 2 ^ prec)
|
||||
rw [Rat.mul_assoc, Rat.inv_mul_cancel, Rat.mul_one]
|
||||
exact mod_cast this
|
||||
· apply Rat.ne_of_gt (Rat.zpow_pos (by decide))
|
||||
· exact Rat.zpow_nonneg (by decide)
|
||||
|
||||
-- TODO: `x.toDyadic prec` is the unique dyadic with the given precision satisfying the two inequalities above.
|
||||
|
||||
end Rat
|
||||
|
||||
namespace Dyadic
|
||||
|
||||
/--
|
||||
Rounds a dyadic rational `x` down to the greatest dyadic number with precision at most `prec`
|
||||
which is less than or equal to `x`.
|
||||
@@ -479,10 +566,11 @@ theorem toDyadic_toRat (x : Dyadic) (prec : Int) :
|
||||
rw [this]
|
||||
cases h : k - prec
|
||||
· simp
|
||||
· simp
|
||||
· simp only [Int.neg_negSucc, Int.natCast_add, Int.cast_ofNat_Int, Int.toNat_natCast_add_one,
|
||||
Int.toNat_negSucc, Int.shiftRight_zero]
|
||||
rw [Int.negSucc_eq, Int.eq_neg_comm, Int.neg_sub, eq_comm, Int.sub_eq_iff_eq_add] at h
|
||||
simp only [Int.neg_negSucc, h, ← Int.natCast_add_one, Int.add_comm _ k,
|
||||
Nat.succ_eq_add_one, Int.toNat_natCast, ofIntWithPrec_shiftLeft_add, ofOdd_eq_ofIntWithPrec]
|
||||
simp only [h, ← Int.natCast_add_one, Int.add_comm _ k, ofIntWithPrec_shiftLeft_add,
|
||||
ofOdd_eq_ofIntWithPrec]
|
||||
|
||||
theorem toRat_inj {x y : Dyadic} : x.toRat = y.toRat ↔ x = y := by
|
||||
refine ⟨fun h => ?_, fun h => h ▸ rfl⟩
|
||||
@@ -578,7 +666,7 @@ theorem blt_eq_false_iff : blt x y = false ↔ ble y x = true := by
|
||||
rcases k₁ - k₂ with (_ | _) | _
|
||||
· simp
|
||||
· simp [← Int.negSucc_eq]
|
||||
· simp only [Int.neg_negSucc, succ_eq_add_one, decide_eq_false_iff_not, Int.not_lt,
|
||||
· simp only [Int.neg_negSucc, decide_eq_false_iff_not, Int.not_lt,
|
||||
decide_eq_true_eq]
|
||||
|
||||
theorem ble_iff_toRat : ble x y ↔ x.toRat ≤ y.toRat := by
|
||||
|
||||
80
src/Init/Data/Dyadic/Inv.lean
Normal file
80
src/Init/Data/Dyadic/Inv.lean
Normal file
@@ -0,0 +1,80 @@
|
||||
/-
|
||||
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Kim Morrison
|
||||
-/
|
||||
module
|
||||
prelude
|
||||
import Init.Data.Dyadic.Basic
|
||||
import Init.Data.Dyadic.Round
|
||||
import Init.Grind.Ordered.Ring
|
||||
|
||||
/-!
|
||||
# Inversion for dyadic numbers
|
||||
-/
|
||||
|
||||
namespace Dyadic
|
||||
|
||||
/--
|
||||
Inverts a dyadic number at a given (maximum) precision.
|
||||
Returns the greatest dyadic number with precision at most `prec` which is less than or equal to `1/x`.
|
||||
For `x = 0`, returns `0`.
|
||||
-/
|
||||
def invAtPrec (x : Dyadic) (prec : Int) : Dyadic :=
|
||||
match x with
|
||||
| .zero => .zero
|
||||
| _ => x.toRat.inv.toDyadic prec
|
||||
|
||||
/-- For a positive dyadic `x`, `invAtPrec x prec * x ≤ 1`. -/
|
||||
theorem invAtPrec_mul_le_one {x : Dyadic} (hx : 0 < x) (prec : Int) :
|
||||
invAtPrec x prec * x ≤ 1 := by
|
||||
rw [le_iff_toRat]
|
||||
rw [toRat_mul]
|
||||
rw [show (1 : Dyadic).toRat = (1 : Rat) from rfl]
|
||||
unfold invAtPrec
|
||||
cases x with
|
||||
| zero =>
|
||||
exfalso
|
||||
contradiction
|
||||
| ofOdd n k hn =>
|
||||
simp only
|
||||
have h_le : ((ofOdd n k hn).toRat.inv.toDyadic prec).toRat ≤ (ofOdd n k hn).toRat.inv := Rat.toRat_toDyadic_le
|
||||
have h_pos : 0 ≤ (ofOdd n k hn).toRat := by
|
||||
rw [lt_iff_toRat, toRat_zero] at hx
|
||||
exact Rat.le_of_lt hx
|
||||
calc ((ofOdd n k hn).toRat.inv.toDyadic prec).toRat * (ofOdd n k hn).toRat
|
||||
≤ (ofOdd n k hn).toRat.inv * (ofOdd n k hn).toRat := Rat.mul_le_mul_of_nonneg_right h_le h_pos
|
||||
_ = 1 := by
|
||||
apply Rat.inv_mul_cancel
|
||||
rw [lt_iff_toRat, toRat_zero] at hx
|
||||
exact Rat.ne_of_gt hx
|
||||
|
||||
/-- For a positive dyadic `x`, `1 < (invAtPrec x prec + 2^(-prec)) * x`. -/
|
||||
theorem one_lt_invAtPrec_add_inc_mul {x : Dyadic} (hx : 0 < x) (prec : Int) :
|
||||
1 < (invAtPrec x prec + ofIntWithPrec 1 prec) * x := by
|
||||
rw [lt_iff_toRat]
|
||||
rw [toRat_mul]
|
||||
rw [show (1 : Dyadic).toRat = (1 : Rat) from rfl]
|
||||
unfold invAtPrec
|
||||
cases x with
|
||||
| zero =>
|
||||
exfalso
|
||||
contradiction
|
||||
| ofOdd n k hn =>
|
||||
simp only
|
||||
have h_le : (ofOdd n k hn).toRat.inv < ((ofOdd n k hn).toRat.inv.toDyadic prec + ofIntWithPrec 1 prec).toRat :=
|
||||
Rat.lt_toRat_toDyadic_add
|
||||
have h_pos : 0 < (ofOdd n k hn).toRat := by
|
||||
rwa [lt_iff_toRat, toRat_zero] at hx
|
||||
calc
|
||||
1 = (ofOdd n k hn).toRat.inv * (ofOdd n k hn).toRat := by
|
||||
symm
|
||||
apply Rat.inv_mul_cancel
|
||||
rw [lt_iff_toRat, toRat_zero] at hx
|
||||
exact Rat.ne_of_gt hx
|
||||
_ < ((ofOdd n k hn).toRat.inv.toDyadic prec + ofIntWithPrec 1 prec).toRat * (ofOdd n k hn).toRat :=
|
||||
Rat.mul_lt_mul_of_pos_right h_le h_pos
|
||||
|
||||
-- TODO: `invAtPrec` is the unique dyadic with the given precision satisfying the two inequalities above.
|
||||
|
||||
end Dyadic
|
||||
@@ -97,7 +97,7 @@ theorem ofNat_emod (m n : Nat) : (↑(m % n) : Int) = m % n := natCast_emod m n
|
||||
|
||||
/-! ### mod definitions -/
|
||||
|
||||
theorem emod_add_ediv : ∀ a b : Int, a % b + b * (a / b) = a
|
||||
theorem emod_add_mul_ediv : ∀ a b : Int, a % b + b * (a / b) = a
|
||||
| ofNat _, ofNat _ => congrArg ofNat <| Nat.mod_add_div ..
|
||||
| ofNat m, -[n+1] => by
|
||||
change (m % succ n + -↑(succ n) * -↑(m / succ n) : Int) = m
|
||||
@@ -111,19 +111,35 @@ where
|
||||
← Int.neg_neg (_-_), Int.neg_sub, Int.sub_sub_self, Int.add_right_comm]
|
||||
exact congrArg (fun x => -(ofNat x + 1)) (Nat.mod_add_div ..)
|
||||
|
||||
/-- Variant of `emod_add_ediv` with the multiplication written the other way around. -/
|
||||
theorem emod_add_ediv' (a b : Int) : a % b + a / b * b = a := by
|
||||
rw [Int.mul_comm]; exact emod_add_ediv ..
|
||||
@[deprecated emod_add_mul_ediv (since := "2025-09-01")]
|
||||
def emod_add_ediv := @emod_add_mul_ediv
|
||||
|
||||
theorem ediv_add_emod (a b : Int) : b * (a / b) + a % b = a := by
|
||||
rw [Int.add_comm]; exact emod_add_ediv ..
|
||||
theorem emod_add_ediv_mul (a b : Int) : a % b + a / b * b = a := by
|
||||
rw [Int.mul_comm]; exact emod_add_mul_ediv ..
|
||||
|
||||
/-- Variant of `ediv_add_emod` with the multiplication written the other way around. -/
|
||||
theorem ediv_add_emod' (a b : Int) : a / b * b + a % b = a := by
|
||||
rw [Int.mul_comm]; exact ediv_add_emod ..
|
||||
@[deprecated emod_add_ediv_mul (since := "2025-09-01")]
|
||||
def emod_add_ediv' := @emod_add_ediv_mul
|
||||
|
||||
theorem mul_ediv_add_emod (a b : Int) : b * (a / b) + a % b = a := by
|
||||
rw [Int.add_comm]; exact emod_add_mul_ediv ..
|
||||
|
||||
@[deprecated mul_ediv_add_emod (since := "2025-09-01")]
|
||||
def ediv_add_emod := @mul_ediv_add_emod
|
||||
|
||||
theorem ediv_mul_add_emod (a b : Int) : a / b * b + a % b = a := by
|
||||
rw [Int.mul_comm]; exact mul_ediv_add_emod ..
|
||||
|
||||
@[deprecated ediv_mul_add_emod (since := "2025-09-01")]
|
||||
def ediv_add_emod' := @ediv_mul_add_emod
|
||||
|
||||
theorem emod_def (a b : Int) : a % b = a - b * (a / b) := by
|
||||
rw [← Int.add_sub_cancel (a % b), emod_add_ediv]
|
||||
rw [← Int.add_sub_cancel (a % b), emod_add_mul_ediv]
|
||||
|
||||
theorem mul_ediv_self (a b : Int) : b * (a / b) = a - a % b := by
|
||||
rw [emod_def, Int.sub_sub_self]
|
||||
|
||||
theorem ediv_mul_self (a b : Int) : a / b * b = a - a % b := by
|
||||
rw [Int.mul_comm, emod_def, Int.sub_sub_self]
|
||||
|
||||
/-! ### `/` ediv -/
|
||||
|
||||
@@ -226,7 +242,7 @@ theorem add_mul_emod_self {a b c : Int} : (a + b * c) % c = a % c :=
|
||||
|
||||
@[simp] theorem emod_add_emod (m n k : Int) : (m % n + k) % n = (m + k) % n := by
|
||||
have := (add_mul_emod_self_left (m % n + k) n (m / n)).symm
|
||||
rwa [Int.add_right_comm, emod_add_ediv] at this
|
||||
rwa [Int.add_right_comm, emod_add_mul_ediv] at this
|
||||
|
||||
@[simp] theorem add_emod_emod (m n k : Int) : (m + n % k) % k = (m + n) % k := by
|
||||
rw [Int.add_comm, emod_add_emod, Int.add_comm]
|
||||
@@ -252,7 +268,7 @@ theorem emod_add_cancel_right {m n k : Int} (i) : (m + i) % n = (k + i) % n ↔
|
||||
|
||||
theorem mul_emod (a b n : Int) : (a * b) % n = (a % n) * (b % n) % n := by
|
||||
conv => lhs; rw [
|
||||
← emod_add_ediv a n, ← emod_add_ediv' b n, Int.add_mul, Int.mul_add, Int.mul_add,
|
||||
← emod_add_mul_ediv a n, ← emod_add_ediv_mul b n, Int.add_mul, Int.mul_add, Int.mul_add,
|
||||
Int.mul_assoc, Int.mul_assoc, ← Int.mul_add n _ _, add_mul_emod_self_left,
|
||||
← Int.mul_assoc, add_mul_emod_self_right]
|
||||
|
||||
@@ -261,7 +277,7 @@ theorem mul_emod (a b n : Int) : (a * b) % n = (a % n) * (b % n) % n := by
|
||||
|
||||
@[simp] theorem emod_emod_of_dvd (n : Int) {m k : Int}
|
||||
(h : m ∣ k) : (n % k) % m = n % m := by
|
||||
conv => rhs; rw [← emod_add_ediv n k]
|
||||
conv => rhs; rw [← emod_add_mul_ediv n k]
|
||||
match k, h with
|
||||
| _, ⟨t, rfl⟩ => rw [Int.mul_assoc, add_mul_emod_self_left]
|
||||
|
||||
@@ -275,7 +291,7 @@ theorem sub_emod (a b n : Int) : (a - b) % n = (a % n - b % n) % n := by
|
||||
/-! ### properties of `/` and `%` -/
|
||||
|
||||
theorem mul_ediv_cancel_of_emod_eq_zero {a b : Int} (H : a % b = 0) : b * (a / b) = a := by
|
||||
have := emod_add_ediv a b; rwa [H, Int.zero_add] at this
|
||||
have := emod_add_mul_ediv a b; rwa [H, Int.zero_add] at this
|
||||
|
||||
theorem ediv_mul_cancel_of_emod_eq_zero {a b : Int} (H : a % b = 0) : a / b * b = a := by
|
||||
rw [Int.mul_comm, mul_ediv_cancel_of_emod_eq_zero H]
|
||||
@@ -326,11 +342,11 @@ theorem emod_pos_of_not_dvd {a b : Int} (h : ¬ a ∣ b) : a = 0 ∨ 0 < b % a :
|
||||
theorem mul_ediv_self_le {x k : Int} (h : k ≠ 0) : k * (x / k) ≤ x :=
|
||||
calc k * (x / k)
|
||||
_ ≤ k * (x / k) + x % k := Int.le_add_of_nonneg_right (emod_nonneg x h)
|
||||
_ = x := ediv_add_emod _ _
|
||||
_ = x := mul_ediv_add_emod _ _
|
||||
|
||||
theorem lt_mul_ediv_self_add {x k : Int} (h : 0 < k) : x < k * (x / k) + k :=
|
||||
calc x
|
||||
_ = k * (x / k) + x % k := (ediv_add_emod _ _).symm
|
||||
_ = k * (x / k) + x % k := (mul_ediv_add_emod _ _).symm
|
||||
_ < k * (x / k) + k := Int.add_lt_add_left (emod_lt_of_pos x h) _
|
||||
|
||||
/-! ### bmod -/
|
||||
|
||||
@@ -334,7 +334,7 @@ theorem fdiv_eq_ediv_of_dvd {a b : Int} (h : b ∣ a) : a.fdiv b = a / b := by
|
||||
|
||||
/-! ### mod definitions -/
|
||||
|
||||
theorem tmod_add_tdiv : ∀ a b : Int, tmod a b + b * (a.tdiv b) = a
|
||||
theorem tmod_add_mul_tdiv : ∀ a b : Int, tmod a b + b * (a.tdiv b) = a
|
||||
| ofNat _, ofNat _ => congrArg ofNat (Nat.mod_add_div ..)
|
||||
| ofNat m, -[n+1] => by
|
||||
change (m % succ n + -↑(succ n) * -↑(m / succ n) : Int) = m
|
||||
@@ -351,21 +351,37 @@ theorem tmod_add_tdiv : ∀ a b : Int, tmod a b + b * (a.tdiv b) = a
|
||||
rw [Int.neg_mul, ← Int.neg_add]
|
||||
exact congrArg (-ofNat ·) (Nat.mod_add_div ..)
|
||||
|
||||
theorem tdiv_add_tmod (a b : Int) : b * a.tdiv b + tmod a b = a := by
|
||||
rw [Int.add_comm]; apply tmod_add_tdiv ..
|
||||
@[deprecated tmod_add_mul_tdiv (since := "2025-09-01")]
|
||||
def tmod_add_tdiv := @tmod_add_mul_tdiv
|
||||
|
||||
/-- Variant of `tmod_add_tdiv` with the multiplication written the other way around. -/
|
||||
theorem tmod_add_tdiv' (m k : Int) : tmod m k + m.tdiv k * k = m := by
|
||||
rw [Int.mul_comm]; apply tmod_add_tdiv
|
||||
theorem mul_tdiv_add_tmod (a b : Int) : b * a.tdiv b + tmod a b = a := by
|
||||
rw [Int.add_comm]; apply tmod_add_mul_tdiv ..
|
||||
|
||||
/-- Variant of `tdiv_add_tmod` with the multiplication written the other way around. -/
|
||||
theorem tdiv_add_tmod' (m k : Int) : m.tdiv k * k + tmod m k = m := by
|
||||
rw [Int.mul_comm]; apply tdiv_add_tmod
|
||||
@[deprecated mul_tdiv_add_tmod (since := "2025-09-01")]
|
||||
def tdiv_add_tmod := @mul_tdiv_add_tmod
|
||||
|
||||
theorem tmod_add_tdiv_mul (m k : Int) : tmod m k + m.tdiv k * k = m := by
|
||||
rw [Int.mul_comm]; apply tmod_add_mul_tdiv
|
||||
|
||||
@[deprecated tmod_add_tdiv_mul (since := "2025-09-01")]
|
||||
def tmod_add_tdiv' := @tmod_add_mul_tdiv
|
||||
|
||||
theorem tdiv_mul_add_tmod (m k : Int) : m.tdiv k * k + tmod m k = m := by
|
||||
rw [Int.mul_comm]; apply mul_tdiv_add_tmod
|
||||
|
||||
@[deprecated tdiv_mul_add_tmod (since := "2025-09-01")]
|
||||
def tdiv_add_tmod' := @tdiv_mul_add_tmod
|
||||
|
||||
theorem tmod_def (a b : Int) : tmod a b = a - b * a.tdiv b := by
|
||||
rw [← Int.add_sub_cancel (tmod a b), tmod_add_tdiv]
|
||||
rw [← Int.add_sub_cancel (tmod a b), tmod_add_mul_tdiv]
|
||||
|
||||
theorem fmod_add_fdiv : ∀ a b : Int, a.fmod b + b * a.fdiv b = a
|
||||
theorem mul_tdiv_self (a b : Int) : b * (a.tdiv b) = a - a.tmod b := by
|
||||
rw [tmod_def, Int.sub_sub_self]
|
||||
|
||||
theorem tdiv_mul_self (a b : Int) : a.tdiv b * b = a - a.tmod b := by
|
||||
rw [Int.mul_comm, tmod_def, Int.sub_sub_self]
|
||||
|
||||
theorem fmod_add_mul_fdiv : ∀ a b : Int, a.fmod b + b * a.fdiv b = a
|
||||
| 0, ofNat _ | 0, -[_+1] => congrArg ofNat <| by simp
|
||||
| succ _, ofNat _ => congrArg ofNat <| Nat.mod_add_div ..
|
||||
| succ m, -[n+1] => by
|
||||
@@ -382,19 +398,35 @@ theorem fmod_add_fdiv : ∀ a b : Int, a.fmod b + b * a.fdiv b = a
|
||||
change -(↑(succ m % succ n) : Int) + -↑(succ n * (succ m / succ n)) = -↑(succ m)
|
||||
rw [← Int.neg_add]; exact congrArg (-ofNat ·) <| Nat.mod_add_div ..
|
||||
|
||||
/-- Variant of `fmod_add_fdiv` with the multiplication written the other way around. -/
|
||||
theorem fmod_add_fdiv' (a b : Int) : a.fmod b + (a.fdiv b) * b = a := by
|
||||
rw [Int.mul_comm]; exact fmod_add_fdiv ..
|
||||
@[deprecated fmod_add_mul_fdiv (since := "2025-09-01")]
|
||||
def fmod_add_fdiv := @fmod_add_mul_fdiv
|
||||
|
||||
theorem fdiv_add_fmod (a b : Int) : b * a.fdiv b + a.fmod b = a := by
|
||||
rw [Int.add_comm]; exact fmod_add_fdiv ..
|
||||
theorem fmod_add_fdiv_mul (a b : Int) : a.fmod b + (a.fdiv b) * b = a := by
|
||||
rw [Int.mul_comm]; exact fmod_add_mul_fdiv ..
|
||||
|
||||
/-- Variant of `fdiv_add_fmod` with the multiplication written the other way around. -/
|
||||
theorem fdiv_add_fmod' (a b : Int) : (a.fdiv b) * b + a.fmod b = a := by
|
||||
rw [Int.mul_comm]; exact fdiv_add_fmod ..
|
||||
@[deprecated fmod_add_fdiv_mul (since := "2025-09-01")]
|
||||
def fmod_add_fdiv' := @fmod_add_fdiv_mul
|
||||
|
||||
theorem mul_fdiv_add_fmod (a b : Int) : b * a.fdiv b + a.fmod b = a := by
|
||||
rw [Int.add_comm]; exact fmod_add_mul_fdiv ..
|
||||
|
||||
@[deprecated mul_fdiv_add_fmod (since := "2025-09-01")]
|
||||
def fdiv_add_fmod := @mul_fdiv_add_fmod
|
||||
|
||||
theorem fdiv_mul_add_fmod (a b : Int) : (a.fdiv b) * b + a.fmod b = a := by
|
||||
rw [Int.mul_comm]; exact mul_fdiv_add_fmod ..
|
||||
|
||||
@[deprecated mul_fdiv_add_fmod (since := "2025-09-01")]
|
||||
def fdiv_add_fmod' := @mul_fdiv_add_fmod
|
||||
|
||||
theorem fmod_def (a b : Int) : a.fmod b = a - b * a.fdiv b := by
|
||||
rw [← Int.add_sub_cancel (a.fmod b), fmod_add_fdiv]
|
||||
rw [← Int.add_sub_cancel (a.fmod b), fmod_add_mul_fdiv]
|
||||
|
||||
theorem mul_fdiv_self (a b : Int) : b * (a.fdiv b) = a - a.fmod b := by
|
||||
rw [fmod_def, Int.sub_sub_self]
|
||||
|
||||
theorem fdiv_mul_self (a b : Int) : a.fdiv b * b = a - a.fmod b := by
|
||||
rw [Int.mul_comm, fmod_def, Int.sub_sub_self]
|
||||
|
||||
/-! ### mod equivalences -/
|
||||
|
||||
@@ -773,7 +805,7 @@ protected theorem ediv_emod_unique {a b r q : Int} (h : 0 < b) :
|
||||
a / b = q ∧ a % b = r ↔ r + b * q = a ∧ 0 ≤ r ∧ r < b := by
|
||||
constructor
|
||||
· intro ⟨rfl, rfl⟩
|
||||
exact ⟨emod_add_ediv a b, emod_nonneg _ (Int.ne_of_gt h), emod_lt_of_pos _ h⟩
|
||||
exact ⟨emod_add_mul_ediv a b, emod_nonneg _ (Int.ne_of_gt h), emod_lt_of_pos _ h⟩
|
||||
· intro ⟨rfl, hz, hb⟩
|
||||
constructor
|
||||
· rw [Int.add_mul_ediv_left r q (Int.ne_of_gt h), ediv_eq_zero_of_lt hz hb]
|
||||
@@ -797,7 +829,7 @@ theorem neg_ediv {a b : Int} : (-a) / b = -(a / b) - if b ∣ a then 0 else b.si
|
||||
if hb : b = 0 then
|
||||
simp [hb]
|
||||
else
|
||||
conv => lhs; rw [← ediv_add_emod a b]
|
||||
conv => lhs; rw [← mul_ediv_add_emod a b]
|
||||
rw [Int.neg_add, ← Int.mul_neg, mul_add_ediv_left _ _ hb, Int.add_comm]
|
||||
split <;> rename_i h
|
||||
· rw [emod_eq_zero_of_dvd h]
|
||||
@@ -1087,6 +1119,10 @@ theorem emod_natAbs_of_neg {x : Int} (h : x < 0) {n : Nat} (w : n ≠ 0) :
|
||||
protected theorem ediv_mul_le (a : Int) {b : Int} (H : b ≠ 0) : a / b * b ≤ a :=
|
||||
Int.le_of_sub_nonneg <| by rw [Int.mul_comm, ← emod_def]; apply emod_nonneg _ H
|
||||
|
||||
protected theorem lt_ediv_mul (a : Int) {b : Int} (H : 0 < b) : a - b < a / b * b := by
|
||||
rw [ediv_mul_self, Int.sub_lt_sub_left_iff]
|
||||
exact emod_lt_of_pos a H
|
||||
|
||||
theorem le_of_mul_le_mul_left {a b c : Int} (w : a * b ≤ a * c) (h : 0 < a) : b ≤ c := by
|
||||
have w := Int.sub_nonneg_of_le w
|
||||
rw [← Int.mul_sub] at w
|
||||
@@ -1177,9 +1213,9 @@ theorem ediv_eq_iff_of_pos {k x y : Int} (h : 0 < k) : x / k = y ↔ y * k ≤ x
|
||||
theorem add_ediv_of_pos {a b c : Int} (h : 0 < c) :
|
||||
(a + b) / c = a / c + b / c + if c ≤ a % c + b % c then 1 else 0 := by
|
||||
have h' : c ≠ 0 := by omega
|
||||
conv => lhs; rw [← Int.ediv_add_emod a c]
|
||||
conv => lhs; rw [← Int.mul_ediv_add_emod a c]
|
||||
rw [Int.add_assoc, Int.mul_add_ediv_left _ _ h']
|
||||
conv => lhs; rw [← Int.ediv_add_emod b c]
|
||||
conv => lhs; rw [← Int.mul_ediv_add_emod b c]
|
||||
rw [Int.add_comm (a % c), Int.add_assoc, Int.mul_add_ediv_left _ _ h',
|
||||
← Int.add_assoc, Int.add_comm (b % c)]
|
||||
congr
|
||||
@@ -1210,7 +1246,7 @@ theorem not_dvd_iff_lt_mul_succ (m : Int) (hn : 0 < n) :
|
||||
¬n ∣ m ↔ (∃ k, n * k < m ∧ m < n * (k + 1)) := by
|
||||
refine ⟨fun h ↦ ?_, ?_⟩
|
||||
· rw [dvd_iff_emod_eq_zero, ← Ne] at h
|
||||
rw [← emod_add_ediv m n]
|
||||
rw [← emod_add_mul_ediv m n]
|
||||
refine ⟨m / n, Int.lt_add_of_pos_left _ ?_, ?_⟩
|
||||
· have := emod_nonneg m (Int.ne_of_gt hn)
|
||||
omega
|
||||
@@ -1485,7 +1521,7 @@ theorem sign_tmod (a b : Int) : sign (tmod a b) = if b ∣ a then 0 else sign a
|
||||
-- Analogues of statements about `ediv` and `emod` from `Bootstrap.lean`
|
||||
|
||||
theorem mul_tdiv_cancel_of_tmod_eq_zero {a b : Int} (H : a.tmod b = 0) : b * (a.tdiv b) = a := by
|
||||
have := tmod_add_tdiv a b; rwa [H, Int.zero_add] at this
|
||||
have := tmod_add_mul_tdiv a b; rwa [H, Int.zero_add] at this
|
||||
|
||||
theorem tdiv_mul_cancel_of_tmod_eq_zero {a b : Int} (H : a.tmod b = 0) : a.tdiv b * b = a := by
|
||||
rw [Int.mul_comm, mul_tdiv_cancel_of_tmod_eq_zero H]
|
||||
@@ -2210,7 +2246,7 @@ theorem fmod_add_cancel_right {m n k : Int} (i) : (m + i).fmod n = (k + i).fmod
|
||||
|
||||
theorem mul_fmod (a b n : Int) : (a * b).fmod n = (a.fmod n * b.fmod n).fmod n := by
|
||||
conv => lhs; rw [
|
||||
← fmod_add_fdiv a n, ← fmod_add_fdiv' b n, Int.add_mul, Int.mul_add, Int.mul_add,
|
||||
← fmod_add_mul_fdiv a n, ← fmod_add_fdiv_mul b n, Int.add_mul, Int.mul_add, Int.mul_add,
|
||||
Int.mul_assoc, Int.mul_assoc, ← Int.mul_add n _ _, add_mul_fmod_self_left,
|
||||
← Int.mul_assoc, add_mul_fmod_self_right]
|
||||
|
||||
@@ -2219,7 +2255,7 @@ theorem mul_fmod (a b n : Int) : (a * b).fmod n = (a.fmod n * b.fmod n).fmod n :
|
||||
|
||||
@[simp] theorem fmod_fmod_of_dvd (n : Int) {m k : Int}
|
||||
(h : m ∣ k) : (n.fmod k).fmod m = n.fmod m := by
|
||||
conv => rhs; rw [← fmod_add_fdiv n k]
|
||||
conv => rhs; rw [← fmod_add_mul_fdiv n k]
|
||||
match k, h with
|
||||
| _, ⟨t, rfl⟩ => rw [Int.mul_assoc, add_mul_fmod_self_left]
|
||||
|
||||
@@ -2249,7 +2285,7 @@ theorem fmod_eq_of_lt {a b : Int} (H1 : 0 ≤ a) (H2 : a < b) : a.fmod b = a :=
|
||||
-- Analogues of properties of `ediv` and `emod` from `Bootstrap.lean`
|
||||
|
||||
theorem mul_fdiv_cancel_of_fmod_eq_zero {a b : Int} (H : a.fmod b = 0) : b * (a.fdiv b) = a := by
|
||||
have := fmod_add_fdiv a b; rwa [H, Int.zero_add] at this
|
||||
have := fmod_add_mul_fdiv a b; rwa [H, Int.zero_add] at this
|
||||
|
||||
theorem fdiv_mul_cancel_of_fmod_eq_zero {a b : Int} (H : a.fmod b = 0) : (a.fdiv b) * b= a := by
|
||||
rw [Int.mul_comm, mul_fdiv_cancel_of_fmod_eq_zero H]
|
||||
@@ -2491,9 +2527,9 @@ theorem bdiv_add_bmod (x : Int) (m : Nat) : m * bdiv x m + bmod x m = x := by
|
||||
ite_self]
|
||||
· dsimp only
|
||||
split
|
||||
· exact ediv_add_emod x m
|
||||
· exact mul_ediv_add_emod x m
|
||||
· rw [Int.mul_add, Int.mul_one, Int.add_assoc, Int.add_comm m, Int.sub_add_cancel]
|
||||
exact ediv_add_emod x m
|
||||
exact mul_ediv_add_emod x m
|
||||
|
||||
theorem bmod_add_bdiv (x : Int) (m : Nat) : bmod x m + m * bdiv x m = x := by
|
||||
rw [Int.add_comm]; exact bdiv_add_bmod x m
|
||||
@@ -2750,7 +2786,7 @@ theorem le_bmod {x : Int} {m : Nat} (h : 0 < m) : - (m/2) ≤ Int.bmod x m := by
|
||||
· exact Int.ne_of_gt (natCast_pos.mpr h)
|
||||
· simp [Int.not_lt] at w
|
||||
refine Int.le_trans ?_ (Int.sub_le_sub_right w _)
|
||||
rw [← ediv_add_emod m 2]
|
||||
rw [← mul_ediv_add_emod m 2]
|
||||
generalize (m : Int) / 2 = q
|
||||
generalize h : (m : Int) % 2 = r at *
|
||||
rcases v with rfl | rfl
|
||||
@@ -2911,7 +2947,7 @@ theorem neg_bmod {a : Int} {b : Nat} :
|
||||
simp only [gt_iff_lt, Nat.zero_lt_succ, Nat.mul_pos_iff_of_pos_left, Int.natCast_mul,
|
||||
cast_ofNat_Int, Int.not_lt] at *
|
||||
rw [Int.mul_dvd_mul_iff_left (by omega)]
|
||||
have := ediv_add_emod a (2 * c)
|
||||
have := mul_ediv_add_emod a (2 * c)
|
||||
rw [(by omega : a % (2 * c) = c)] at this
|
||||
rw [← this]
|
||||
apply Int.dvd_add _ (by simp)
|
||||
|
||||
@@ -40,7 +40,7 @@ theorem ofNat_succ (n : Nat) : (succ n : Int) = n + 1 := rfl
|
||||
|
||||
theorem neg_ofNat_zero : -((0 : Nat) : Int) = 0 := rfl
|
||||
theorem neg_ofNat_succ (n : Nat) : -(succ n : Int) = -[n+1] := rfl
|
||||
theorem neg_negSucc (n : Nat) : -(-[n+1]) = succ n := rfl
|
||||
@[simp] theorem neg_negSucc (n : Nat) : -(-[n+1]) = ((n + 1 : Nat) : Int) := rfl
|
||||
|
||||
theorem negOfNat_eq : negOfNat n = -ofNat n := rfl
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ def cmod (a b : Int) : Int :=
|
||||
|
||||
theorem cdiv_add_cmod (a b : Int) : b*(cdiv a b) + cmod a b = a := by
|
||||
unfold cdiv cmod
|
||||
have := Int.ediv_add_emod (-a) b
|
||||
have := Int.mul_ediv_add_emod (-a) b
|
||||
have := congrArg (Neg.neg) this
|
||||
simp at this
|
||||
conv => rhs; rw[← this]
|
||||
@@ -272,7 +272,7 @@ private abbrev div_mul_cancel_of_mod_zero :=
|
||||
theorem cdiv_eq_div_of_divides {a b : Int} (h : a % b = 0) : a/b = cdiv a b := by
|
||||
replace h := div_mul_cancel_of_mod_zero h
|
||||
have hz : a % b = 0 := by
|
||||
have := Int.ediv_add_emod a b
|
||||
have := Int.mul_ediv_add_emod a b
|
||||
conv at this => rhs; rw [← Int.add_zero a]
|
||||
rw [Int.mul_comm, h] at this
|
||||
exact Int.add_left_cancel this
|
||||
@@ -1753,7 +1753,7 @@ theorem cooper_right_split_dvd (ctx : Context) (p₁ p₂ : Poly) (k : Nat) (b :
|
||||
intros; subst b p'; simp; assumption
|
||||
|
||||
private theorem one_emod_eq_one {a : Int} (h : a > 1) : 1 % a = 1 := by
|
||||
have aux₁ := Int.ediv_add_emod 1 a
|
||||
have aux₁ := Int.mul_ediv_add_emod 1 a
|
||||
have : 1 / a = 0 := Int.ediv_eq_zero_of_lt (by decide) h
|
||||
simp [this] at aux₁
|
||||
assumption
|
||||
@@ -1780,7 +1780,7 @@ private theorem ex_of_dvd {α β a b d x : Int}
|
||||
rw [Int.mul_emod, aux₁, Int.one_mul, Int.emod_emod] at this
|
||||
assumption
|
||||
have : x = (x / d)*d + (- α * b) % d := by
|
||||
conv => lhs; rw [← Int.ediv_add_emod x d]
|
||||
conv => lhs; rw [← Int.mul_ediv_add_emod x d]
|
||||
rw [Int.mul_comm, this]
|
||||
exists x / d
|
||||
|
||||
@@ -1863,7 +1863,7 @@ theorem cooper_unsat (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (α β :
|
||||
exact cooper_unsat' h₁ h₂ h₃ h₄ h₅ h₆
|
||||
|
||||
theorem ediv_emod (x y : Int) : -1 * x + y * (x / y) + x % y = 0 := by
|
||||
rw [Int.add_assoc, Int.ediv_add_emod x y, Int.add_comm]
|
||||
rw [Int.add_assoc, Int.mul_ediv_add_emod x y, Int.add_comm]
|
||||
simp
|
||||
rw [Int.add_neg_eq_sub, Int.sub_self]
|
||||
|
||||
|
||||
@@ -701,10 +701,13 @@ theorem toNat_sub_toNat_neg : ∀ n : Int, ↑n.toNat - ↑(-n).toNat = n
|
||||
| (_+1:Nat) => Nat.add_zero _
|
||||
| -[_+1] => Nat.zero_add _
|
||||
|
||||
@[simp] theorem toNat_neg_nat : ∀ n : Nat, (-(n : Int)).toNat = 0
|
||||
@[simp] theorem toNat_neg_natCast : ∀ n : Nat, (-(n : Int)).toNat = 0
|
||||
| 0 => rfl
|
||||
| _+1 => rfl
|
||||
|
||||
@[deprecated toNat_neg_natCast (since := "2025-08-29")]
|
||||
theorem toNat_neg_nat : ∀ n : Nat, (-(n : Int)).toNat = 0 := toNat_neg_natCast
|
||||
|
||||
/-! ### toNat? -/
|
||||
|
||||
theorem mem_toNat? : ∀ {a : Int} {n : Nat}, toNat? a = some n ↔ a = n
|
||||
|
||||
@@ -150,6 +150,9 @@ instance : LE Rat := ⟨fun a b => b.blt a = false⟩
|
||||
instance (a b : Rat) : Decidable (a ≤ b) :=
|
||||
inferInstanceAs (Decidable (_ = false))
|
||||
|
||||
instance : Min Rat := minOfLe
|
||||
instance : Max Rat := maxOfLe
|
||||
|
||||
/-- Multiplication of rational numbers. (This definition is `@[irreducible]` because you don't
|
||||
want to unfold it. Use `Rat.mul_def` instead.) -/
|
||||
@[irreducible] protected def mul (a b : Rat) : Rat :=
|
||||
|
||||
@@ -7,6 +7,7 @@ module
|
||||
prelude
|
||||
|
||||
public import Init.Data.Rat.Basic
|
||||
public import Init.Data.Int.Gcd
|
||||
import Init.Data.Int.Bitwise.Lemmas
|
||||
|
||||
@[expose] public section
|
||||
@@ -41,6 +42,14 @@ theorem normalize_eq {num den} (den_nz) : normalize num den den_nz =
|
||||
reduced := normalize.reduced den_nz rfl } := by
|
||||
simp only [normalize, maybeNormalize_eq, Int.divExact_eq_ediv]
|
||||
|
||||
@[simp]
|
||||
theorem num_normalize {num den} (den_nz) : (normalize num den den_nz).num = num / num.natAbs.gcd den := by
|
||||
simp [normalize_eq]
|
||||
|
||||
@[simp]
|
||||
theorem den_normalize {num den} (den_nz) : (normalize num den den_nz).den = den / num.natAbs.gcd den := by
|
||||
simp [normalize_eq]
|
||||
|
||||
@[simp] theorem normalize_zero (nz) : normalize 0 d nz = 0 := by
|
||||
simp [normalize, Int.natAbs_zero, Nat.div_self (Nat.pos_of_ne_zero nz)]; rfl
|
||||
|
||||
@@ -111,6 +120,14 @@ theorem mkRat_num_den (z : d ≠ 0) (h : mkRat n d = ⟨n', d', z', c⟩) :
|
||||
|
||||
theorem mkRat_def (n d) : mkRat n d = if d0 : d = 0 then 0 else normalize n d d0 := rfl
|
||||
|
||||
theorem num_mkRat (n d) : (mkRat n d).num = if d = 0 then 0 else n / d.gcd n.natAbs := by
|
||||
rw [mkRat_def]
|
||||
split <;> simp [Nat.gcd_comm]
|
||||
|
||||
theorem den_mkRat (n d) : (mkRat n d).den = if d = 0 then 1 else d / d.gcd n.natAbs := by
|
||||
rw [mkRat_def]
|
||||
split <;> simp [Nat.gcd_comm]
|
||||
|
||||
@[simp]
|
||||
theorem mkRat_self (a : Rat) : mkRat a.num a.den = a := by
|
||||
rw [← normalize_eq_mkRat a.den_nz, normalize_self]
|
||||
@@ -199,6 +216,27 @@ theorem divInt_num_den (z : d ≠ 0) (h : n /. d = ⟨n', d', z', c⟩) :
|
||||
rw [← Int.neg_inj, Int.neg_neg] at h₂
|
||||
simp [Int.natCast_mul, h₁, h₂, Int.mul_neg, Int.neg_eq_zero]
|
||||
|
||||
theorem num_divInt (a b : Int) : (a /. b).num = b.sign * a / b.gcd a := by
|
||||
rw [divInt.eq_def]
|
||||
simp only [inline, Nat.succ_eq_add_one]
|
||||
split <;> rename_i d
|
||||
· simp only [num_mkRat, Int.ofNat_eq_coe]
|
||||
split <;> rename_i h
|
||||
· simp_all
|
||||
· rw [Int.sign_natCast_of_ne_zero h, Int.one_mul, Int.gcd]
|
||||
simp
|
||||
· simp [Int.gcd, Nat.gcd_comm]
|
||||
|
||||
theorem den_divInt (a b : Int) : (a /. b).den = if b = 0 then 1 else b.natAbs / b.gcd a := by
|
||||
rw [divInt.eq_def]
|
||||
simp only [inline, Nat.succ_eq_add_one]
|
||||
split <;> rename_i d
|
||||
· simp only [den_mkRat, Int.ofNat_eq_coe, Int.natAbs_cast]
|
||||
split <;> rename_i h
|
||||
· simp_all
|
||||
· simp [if_neg (by omega), Int.gcd]
|
||||
· simp [Int.gcd, Nat.gcd_comm]
|
||||
|
||||
/-- Define a (dependent) function or prove `∀ r : Rat, p r` by dealing with rational
|
||||
numbers of the form `n /. d` with `0 < d` and coprime `n`, `d`. -/
|
||||
@[elab_as_elim]
|
||||
@@ -225,8 +263,11 @@ def numDenCasesOn''.{u} {C : Rat → Sort u} (a : Rat)
|
||||
@[simp] theorem ofInt_num : (ofInt n : Rat).num = n := rfl
|
||||
@[simp] theorem ofInt_den : (ofInt n : Rat).den = 1 := rfl
|
||||
|
||||
@[simp] theorem num_ofNat : (OfNat.ofNat n : Rat).num = OfNat.ofNat n := rfl
|
||||
@[simp] theorem den_ofNat : (OfNat.ofNat n : Rat).den = 1 := rfl
|
||||
@[simp] theorem num_ofNat : (no_index (OfNat.ofNat n : Rat)).num = OfNat.ofNat n := rfl
|
||||
@[simp] theorem den_ofNat : (no_index (OfNat.ofNat n : Rat)).den = 1 := rfl
|
||||
|
||||
@[simp] theorem num_natCast (n : Nat) : (n : Rat).num = n := rfl
|
||||
@[simp] theorem den_natCast (n : Nat) : (n : Rat).den = 1 := rfl
|
||||
|
||||
@[deprecated num_ofNat (since := "2025-08-22")]
|
||||
abbrev ofNat_num := @num_ofNat
|
||||
@@ -426,6 +467,22 @@ theorem inv_def (a : Rat) : a⁻¹ = (a.den : Int) /. a.num := by
|
||||
apply (num_divInt_den _).symm.trans
|
||||
simp [Int.le_antisymm (Int.not_lt.1 h₂) (Int.not_lt.1 h₁)]
|
||||
|
||||
@[simp] theorem num_inv (a : Rat) : (a⁻¹).num = a.num.sign * a.den := by
|
||||
simp only [inv_def]
|
||||
rw [num_divInt]
|
||||
have := a.reduced
|
||||
dsimp [Nat.Coprime] at this
|
||||
simp [Int.gcd, this]
|
||||
|
||||
@[simp] theorem den_inv (a : Rat) : (a⁻¹).den = if a.num = 0 then 1 else a.num.natAbs := by
|
||||
simp only [inv_def]
|
||||
rw [den_divInt]
|
||||
split
|
||||
· rfl
|
||||
· have := a.reduced
|
||||
dsimp [Nat.Coprime] at this
|
||||
simp [Int.gcd, this]
|
||||
|
||||
@[simp] protected theorem inv_zero : (0 : Rat)⁻¹ = 0 := by
|
||||
change Rat.inv 0 = 0; unfold Rat.inv; rfl
|
||||
|
||||
@@ -488,6 +545,9 @@ theorem pow_def (q : Rat) (n : Nat) :
|
||||
q ^ n = ⟨q.num ^ n, q.den ^ n, by simp [q.den_nz],
|
||||
by rw [Int.natAbs_pow]; exact q.reduced.pow _ _⟩ := rfl
|
||||
|
||||
@[simp] theorem num_pow (q : Rat) (n : Nat) : (q ^ n).num = q.num ^ n := rfl
|
||||
@[simp] theorem den_pow (q : Rat) (n : Nat) : (q ^ n).den = q.den ^ n := rfl
|
||||
|
||||
@[simp] protected theorem pow_zero (q : Rat) : q ^ 0 = 1 := rfl
|
||||
|
||||
protected theorem pow_succ (q : Rat) (n : Nat) : q ^ (n + 1) = q ^ n * q := by
|
||||
@@ -700,6 +760,17 @@ protected theorem mul_pos {a b : Rat} (ha : 0 < a) (hb : 0 < b) : 0 < a * b := b
|
||||
refine Rat.lt_of_le_of_ne (Rat.mul_nonneg (Rat.le_of_lt ha) (Rat.le_of_lt hb)) ?_
|
||||
simp [eq_comm, Rat.mul_eq_zero, Rat.ne_of_gt ha, Rat.ne_of_gt hb]
|
||||
|
||||
protected theorem mul_le_mul_of_nonneg_left {a b c : Rat} (ha : a ≤ b) (hc : 0 ≤ c) :
|
||||
c * a ≤ c * b := by
|
||||
rw [Rat.le_iff_sub_nonneg, Rat.sub_eq_add_neg] at ha ⊢
|
||||
rw [← Rat.mul_neg, ← Rat.mul_add]
|
||||
exact Rat.mul_nonneg hc ha
|
||||
|
||||
protected theorem mul_le_mul_of_nonneg_right {a b c : Rat} (ha : a ≤ b) (hc : 0 ≤ c) :
|
||||
a * c ≤ b * c := by
|
||||
rw [Rat.mul_comm _ c, Rat.mul_comm _ c]
|
||||
exact Rat.mul_le_mul_of_nonneg_left ha hc
|
||||
|
||||
protected theorem mul_lt_mul_of_pos_left {a b c : Rat} (ha : a < b) (hc : 0 < c) :
|
||||
c * a < c * b := by
|
||||
rw [Rat.lt_iff_sub_pos, Rat.sub_eq_add_neg] at ha ⊢
|
||||
@@ -935,3 +1006,63 @@ theorem intCast_nonpos {a : Int} :
|
||||
theorem intCast_neg_iff {a : Int} :
|
||||
(a : Rat) < 0 ↔ a < 0 :=
|
||||
Rat.intCast_lt_intCast
|
||||
|
||||
theorem floor_def (a : Rat) : a.floor = a.num / a.den := by
|
||||
rw [Rat.floor]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp]
|
||||
theorem floor_intCast (a : Int) : (a : Rat).floor = a := by
|
||||
simp [floor_def]
|
||||
|
||||
theorem floor_monotone {a b : Rat} (h : a ≤ b) : a.floor ≤ b.floor := by
|
||||
rw [floor_def, floor_def]
|
||||
rw [Rat.le_iff] at h
|
||||
rw [Int.ediv_le_iff_le_mul (by have := a.den_nz; omega),
|
||||
← Int.mul_lt_mul_right (a := b.den) (by have := b.den_nz; omega)]
|
||||
apply Int.lt_of_le_of_lt h
|
||||
conv =>
|
||||
rhs; congr; congr; rfl
|
||||
rw [← Int.one_mul a.den]
|
||||
rw [← Int.add_mul, Int.mul_right_comm,
|
||||
Int.mul_lt_mul_right (a := a.den) (by have := a.den_nz; omega),
|
||||
Int.add_mul, Int.one_mul, ← Int.sub_lt_iff]
|
||||
exact Int.lt_ediv_mul b.num (b := b.den) (by have := b.den_nz; omega)
|
||||
|
||||
theorem floor_le (a : Rat) : (a.floor : Rat) ≤ a := by
|
||||
rw [floor_def, Rat.le_iff, num_intCast, den_intCast, Int.cast_ofNat_Int, Int.mul_one]
|
||||
apply Int.ediv_mul_le _ (by simpa using a.den_nz)
|
||||
|
||||
theorem lt_floor_add_one (a : Rat) : a < ((a.floor + 1 : Int): Rat) := by
|
||||
rw [floor_def, Rat.lt_iff]
|
||||
have : a.num / ↑a.den + 1 = (a.num + ↑a.den) / ↑a.den := by
|
||||
rw [Int.add_ediv_of_dvd_right] <;> simp [a.den_nz]
|
||||
simp [this]
|
||||
simpa using Int.lt_ediv_mul (a.num + a.den) (b := a.den) (by have := a.den_nz; omega)
|
||||
|
||||
theorem le_floor_iff {x : Int} {a : Rat} : x ≤ a.floor ↔ (x : Rat) ≤ a := by
|
||||
constructor
|
||||
· intro h
|
||||
rw [← intCast_le_intCast] at h
|
||||
exact Rat.le_trans h (floor_le a)
|
||||
· intro h
|
||||
simpa using floor_monotone h
|
||||
|
||||
theorem floor_lt_iff {a : Rat} {x : Int} : a.floor < x ↔ a < (x : Rat) := by
|
||||
rw [← Decidable.not_iff_not, Int.not_lt, le_floor_iff, Rat.not_lt]
|
||||
|
||||
theorem ceil_eq_neg_floor_neg (a : Rat) : a.ceil = -((-a).floor) := by
|
||||
rw [Rat.ceil, Rat.floor]
|
||||
simp only [neg_den, neg_num]
|
||||
split
|
||||
· simp
|
||||
· rw [Int.neg_ediv, if_neg, Int.sign_eq_one_of_pos, Int.neg_sub, Int.sub_neg, Int.add_comm]
|
||||
· have := a.den_nz; omega
|
||||
· intro h
|
||||
rw [Int.ofNat_dvd_left] at h
|
||||
exact Nat.not_coprime_of_dvd_of_dvd (by have := a.den_nz; omega) h (Nat.dvd_refl _) a.reduced
|
||||
|
||||
@[simp]
|
||||
theorem ceil_intCast (a : Int) : (a : Rat).ceil = a := rfl
|
||||
|
||||
-- TODO: reproduce the `floor` inequalities above for `ceil`
|
||||
|
||||
@@ -1534,7 +1534,7 @@ theorem diseq0_to_eq {α} [Field α] (a : α) : a ≠ 0 → a*a⁻¹ = 1 := by
|
||||
|
||||
private theorem of_mod_eq_0 {α} [CommRing α] {a : Int} {c : Nat} : Int.cast c = (0 : α) → a % c = 0 → (a : α) = 0 := by
|
||||
intro h h'
|
||||
have := Int.ediv_add_emod a ↑c
|
||||
have := Int.mul_ediv_add_emod a ↑c
|
||||
rw [h', Int.add_zero] at this
|
||||
replace this := congrArg (Int.cast (R := α)) this
|
||||
rw [Ring.intCast_mul] at this
|
||||
|
||||
@@ -124,7 +124,7 @@ theorem ofNat_natAbs (a : Int) : (a.natAbs : Int) = if 0 ≤ a then a else -a :=
|
||||
split <;> rename_i n
|
||||
· simp only [Int.ofNat_eq_coe]
|
||||
rw [if_pos (Int.natCast_nonneg n)]
|
||||
· simp; rfl
|
||||
· simp
|
||||
|
||||
theorem natAbs_dichotomy {a : Int} : 0 ≤ a ∧ a.natAbs = a ∨ a < 0 ∧ a.natAbs = -a := by
|
||||
by_cases h : 0 ≤ a
|
||||
|
||||
Reference in New Issue
Block a user