|
import Mathlib.Algebra.Order.Floor.Div |
|
import Mathlib.Tactic |
|
|
|
namespace ExactDivRem |
|
|
|
/-- |
|
目的: 上側 magic number `M⁺` を定義する。 |
|
定義: `M⁺ := β ⌈/⌉ D`。 |
|
入力/前提: `β D : Nat`。 |
|
出力: 近似商 `⌊M⁺ * x / β⌋` に使う倍率。 |
|
役割: 主定理の右辺に現れる近似商を構成する。 |
|
-/ |
|
def magicUp (β D : Nat) : Nat := |
|
β ⌈/⌉ D |
|
|
|
/-- |
|
目的: 上側近似の余剰 `δ` を定義する。 |
|
定義: `M⁺ := β ⌈/⌉ D` として `δ := M⁺ * D - β`。 |
|
入力/前提: `β D : Nat`。 |
|
出力: `M⁺ * D` が `β` をどれだけ上回るかを表す自然数。 |
|
役割: 主定理の左辺 `xδ < β(D-r)` に現れる誤差項である。 |
|
-/ |
|
def delta (β D : Nat) : Nat := |
|
magicUp β D * D - β |
|
|
|
/-- |
|
目的: 上側 magic number による近似商を定義する。 |
|
定義: `M⁺ := β ⌈/⌉ D` として `⌊M⁺ * x / β⌋`。 |
|
入力/前提: `β D x : Nat`。 |
|
出力: 近似商。 |
|
役割: 主定理の右辺に現れる商である。 |
|
-/ |
|
def approxQuot (β D x : Nat) : Nat := |
|
(magicUp β D * x) / β |
|
|
|
/-- |
|
目的: 真の商と近似商が一致することを表す。 |
|
定義: `x / D = approxQuot β D x`。 |
|
入力/前提: `β D x : Nat`。 |
|
出力: 命題。 |
|
役割: residual 条件と商一致条件を結ぶ中間述語として使う。 |
|
-/ |
|
def Good (β D x : Nat) : Prop := |
|
x / D = approxQuot β D x |
|
|
|
/-- |
|
目的: 上側近似整除法で現れる補助量 `y = qδ + M⁺r` を定義する。 |
|
定義: `q = x / D`, `r = x % D`, `M⁺ = β ⌈/⌉ D`, |
|
`δ = M⁺ * D - β` として `qδ + M⁺r`。 |
|
入力/前提: `β D x : Nat`。 |
|
出力: 商判定・剰余判定の両方で共通に現れる自然数。 |
|
役割: `Mx = qβ + y`, `Dy = xδ + βr` の共通中間項となる。 |
|
-/ |
|
def upperY (β D x : Nat) : Nat := |
|
(x / D) * delta β D + magicUp β D * (x % D) |
|
|
|
/-- |
|
入力/前提: `A D : Nat`, `hD : 0 < D`。 |
|
主張: `A ≤ (A ⌈/⌉ D) * D`。 |
|
内容: 切り上げ除算の基本的な上側評価を、後続で使う乗法順に整える。 |
|
証明: Mathlib の `le_smul_ceilDiv` を、乗法の可換性で書き換える。 |
|
役割: `magicUp β D * D = β + delta β D` と `delta_lt` の基礎補題である。 |
|
-/ |
|
private lemma le_mul_ceilDiv {A D : Nat} (hD : 0 < D) : |
|
A ≤ (A ⌈/⌉ D) * D := by |
|
simpa [Nat.mul_comm] using |
|
(le_smul_ceilDiv (a := D) (b := A) hD) |
|
|
|
/-- |
|
入力/前提: `β D : Nat`, `hD : 0 < D`。 |
|
主張: `magicUp β D * D = β + delta β D`。 |
|
内容: `delta β D` の定義を、後続の代数変形で使う等式に直す。 |
|
証明: `β ≤ magicUp β D * D` から `Nat.add_sub_of_le` で差を戻す。 |
|
役割: `M * D = β + δ` という基本変形として各分解補題で使う。 |
|
-/ |
|
private lemma magicUp_mul_eq_beta_add_delta {β D : Nat} (hD : 0 < D) : |
|
magicUp β D * D = β + delta β D := by |
|
have hle : β ≤ magicUp β D * D := by |
|
simpa [magicUp] using le_mul_ceilDiv (A := β) (D := D) hD |
|
simpa [delta, Nat.add_comm] using (Nat.add_sub_of_le hle).symm |
|
|
|
/-- |
|
入力/前提: `x D q r : Nat`, `hD : 0 < D`, `hqr : x = q * D + r`, |
|
`hr : r < D`。 |
|
主張: `x / D = q`。 |
|
内容: 標準的な商剰余分解から、自然数除算の商が `q` であることを示す。 |
|
証明: `Nat.add_mul_div_right` と `Nat.div_eq_of_lt hr` に帰着する。 |
|
役割: `Good` を residual 条件に変換する補題で使う。 |
|
-/ |
|
private lemma div_of_decompose {x D q r : Nat} |
|
(hD : 0 < D) (hqr : x = q * D + r) (hr : r < D) : |
|
x / D = q := by |
|
rw [hqr] |
|
calc |
|
(q * D + r) / D = (r + q * D) / D := by rw [Nat.add_comm] |
|
_ = r / D + q := Nat.add_mul_div_right r q hD |
|
_ = q := by rw [Nat.div_eq_of_lt hr, zero_add] |
|
|
|
/-- |
|
入力/前提: `β D q r : Nat`, `hD : 0 < D`。 |
|
主張: `magicUp β D * (q * D + r)` を |
|
`(q * delta β D + magicUp β D * r) + q * β` に分解する。 |
|
内容: `M * D = β + δ` を用いて、近似商の分子を `qβ + y` 型に変形する。 |
|
証明: 分配法則、`magicUp_mul_eq_beta_add_delta`、`ring` で正規化する。 |
|
役割: 商一致条件を residual `qδ + Mr` の大小に落とす代数補題である。 |
|
-/ |
|
private lemma approxQuot_numerator_decompose {β D q r : Nat} |
|
(hD : 0 < D) : |
|
magicUp β D * (q * D + r) = |
|
(q * delta β D + magicUp β D * r) + q * β := by |
|
calc |
|
magicUp β D * (q * D + r) = q * (magicUp β D * D) + magicUp β D * r := by |
|
rw [Nat.mul_add] |
|
ring |
|
_ = q * (β + delta β D) + magicUp β D * r := by |
|
rw [magicUp_mul_eq_beta_add_delta (β := β) (D := D) hD] |
|
_ = (q * delta β D + magicUp β D * r) + q * β := by |
|
ring |
|
|
|
/-- |
|
入力/前提: `β D x q r : Nat`, `hβ : 0 < β`, `hD : 0 < D`, |
|
`hqr : x = q * D + r`。 |
|
主張: `approxQuot β D x = q + ((q * delta β D + magicUp β D * r) / β)`。 |
|
内容: 近似商を、真の商候補 `q` と residual の商に分ける。 |
|
証明: 分子分解後、`Nat.add_mul_div_right` で `q * β` を除去する。 |
|
役割: residual が `β` 未満であることと商一致を結ぶ。 |
|
-/ |
|
private lemma approxQuot_of_decompose {β D x q r : Nat} |
|
(hβ : 0 < β) (hD : 0 < D) (hqr : x = q * D + r) : |
|
approxQuot β D x = q + ((q * delta β D + magicUp β D * r) / β) := by |
|
dsimp [approxQuot] |
|
rw [hqr] |
|
rw [approxQuot_numerator_decompose (β := β) (D := D) (q := q) (r := r) hD] |
|
rw [Nat.add_mul_div_right _ _ hβ] |
|
simp [Nat.add_comm] |
|
|
|
/-- |
|
入力/前提: `β D x q r : Nat`, `hβ : 0 < β`, `hD : 0 < D`, |
|
`hqr : x = q * D + r`, `hr : r < D`。 |
|
主張: `Good β D x ↔ q * delta β D + magicUp β D * r < β`。 |
|
内容: 商一致条件を、分子分解で出る residual の一つの不等式に置き換える。 |
|
証明: 真の商と近似商を展開し、`Nat.div_eq_zero_iff` で割り算を消す。 |
|
役割: 商一致の基本判定を与える中間補題である。 |
|
-/ |
|
private lemma good_iff_residual_lt {β D x q r : Nat} |
|
(hβ : 0 < β) (hD : 0 < D) (hqr : x = q * D + r) (hr : r < D) : |
|
Good β D x ↔ q * delta β D + magicUp β D * r < β := by |
|
rw [Good, div_of_decompose hD hqr hr, approxQuot_of_decompose hβ hD hqr] |
|
constructor |
|
· intro h |
|
have hq0 : q + ((q * delta β D + magicUp β D * r) / β) = q + 0 := by |
|
simpa using h.symm |
|
have hdiv : (q * delta β D + magicUp β D * r) / β = 0 := Nat.add_left_cancel hq0 |
|
rcases (Nat.div_eq_zero_iff).1 hdiv with hβ0 | hlt |
|
· exact False.elim (Nat.ne_of_gt hβ hβ0) |
|
· exact hlt |
|
· intro hlt |
|
rw [Nat.div_eq_of_lt hlt, Nat.add_zero] |
|
|
|
/-- |
|
入力/前提: `β D : Nat`, `hD : 0 < D`。 |
|
主張: `delta β D < D`。 |
|
内容: 切り上げ倍率の余剰 `δ = M * D - β` が 1 除数未満であることを示す。 |
|
証明: 下側評価 `β ≤ M * D` と上側評価 `M * D < β + D` を差に移す。 |
|
役割: `xδ < β` から商条件 `xδ < β(D-r)` を導く際の補助境界である。 |
|
-/ |
|
private lemma delta_lt {β D : Nat} (hD : 0 < D) : |
|
delta β D < D := by |
|
have hle : β ≤ magicUp β D * D := by |
|
simpa [magicUp] using le_mul_ceilDiv (A := β) (D := D) hD |
|
have hlt : magicUp β D * D < β + D := by |
|
have hmul : magicUp β D * D ≤ β + D - 1 := by |
|
simpa [magicUp, Nat.mul_comm] using |
|
Nat.div_mul_le_self (β + D - 1) D |
|
have hpred : β + D - 1 < β + D := by omega |
|
exact lt_of_le_of_lt hmul hpred |
|
have hlt' : magicUp β D * D < D + β := by |
|
simpa [Nat.add_comm] using hlt |
|
simpa [delta] using (Nat.sub_lt_iff_lt_add hle).2 hlt' |
|
|
|
/-- |
|
入力/前提: `β D x : Nat`, `hD : 0 < D`。 |
|
主張: `magicUp β D * x = (x / D) * β + upperY β D x`。 |
|
内容: `x = qD + r` と `M * D = β + δ` から、`Mx = qβ + y` を得る。 |
|
証明: `Nat.div_add_mod` による商剰余分解と分子分解補題を使う。 |
|
役割: 近似商と剰余の解析で、`upperY` を `Mx` の β 未満部分として扱う。 |
|
-/ |
|
private lemma upperY_eq {β D x : Nat} (hD : 0 < D) : |
|
magicUp β D * x = (x / D) * β + upperY β D x := by |
|
let q := x / D |
|
let r := x % D |
|
have hqr : x = q * D + r := by |
|
dsimp [q, r] |
|
simpa [Nat.mul_comm, Nat.add_comm, Nat.add_left_comm, Nat.add_assoc] using |
|
(Nat.div_add_mod x D).symm |
|
calc |
|
magicUp β D * x = magicUp β D * (q * D + r) := by rw [hqr] |
|
_ = (q * delta β D + magicUp β D * r) + q * β := by |
|
simpa [q, r] using |
|
approxQuot_numerator_decompose (β := β) (D := D) (q := q) (r := r) hD |
|
_ = q * β + upperY β D x := by |
|
dsimp [upperY, q, r] |
|
ring |
|
|
|
/-- |
|
入力/前提: `β D x : Nat`, `hD : 0 < D`。 |
|
主張: `D * upperY β D x = x * delta β D + β * (x % D)`。 |
|
内容: `upperY = qδ + Mr` を `D` 倍し、`M * D = β + δ` を代入する。 |
|
証明: 商剰余分解、`magicUp_mul_eq_beta_add_delta`、`ring` による正規化で示す。 |
|
役割: `upperY < β` と `xδ < β(D-r)`、剰余復元条件を接続する。 |
|
-/ |
|
private lemma upperY_scaled_eq {β D x : Nat} (hD : 0 < D) : |
|
D * upperY β D x = x * delta β D + β * (x % D) := by |
|
let q := x / D |
|
let r := x % D |
|
have hqr : x = q * D + r := by |
|
dsimp [q, r] |
|
simpa [Nat.mul_comm, Nat.add_comm, Nat.add_left_comm, Nat.add_assoc] using |
|
(Nat.div_add_mod x D).symm |
|
have hMD : magicUp β D * D = β + delta β D := by |
|
exact magicUp_mul_eq_beta_add_delta (β := β) (D := D) hD |
|
have hr : r < D := by |
|
dsimp [r] |
|
exact Nat.mod_lt _ hD |
|
calc |
|
D * upperY β D x = D * (q * delta β D + magicUp β D * r) := by |
|
dsimp [upperY, q, r] |
|
_ = q * D * delta β D + (magicUp β D * D) * r := by ring |
|
_ = q * D * delta β D + (β + delta β D) * r := by rw [hMD] |
|
_ = (q * D + r) * delta β D + β * r := by ring |
|
_ = x * delta β D + β * (x % D) := by |
|
rw [hqr] |
|
have hmod : (q * D + r) % D = r := by |
|
rw [Nat.add_comm, Nat.mul_comm q D, Nat.add_mul_mod_self_left] |
|
exact Nat.mod_eq_of_lt hr |
|
rw [hmod] |
|
|
|
/-- |
|
入力/前提: `β D x : Nat`, `hD : 0 < D`, `hβ : 0 < β`。 |
|
主張: `approxQuot β D x = x / D ↔ upperY β D x < β`。 |
|
内容: `Mx = qβ + upperY` から、近似商の余分な項が 0 である条件に直す。 |
|
証明: `upperY_eq` で分子を展開し、`Nat.div_eq_zero_iff` を使う。 |
|
役割: 主定理の商一致側を共通補助量 `upperY` の不等式へ変換する。 |
|
-/ |
|
private lemma approxQuot_eq_div_iff_upperY_lt {β D x : Nat} |
|
(hD : 0 < D) (hβ : 0 < β) : |
|
approxQuot β D x = x / D ↔ upperY β D x < β := by |
|
have hdiv : approxQuot β D x = x / D + upperY β D x / β := by |
|
calc |
|
approxQuot β D x = (magicUp β D * x) / β := rfl |
|
_ = ((x / D) * β + upperY β D x) / β := by rw [upperY_eq (β := β) (D := D) (x := x) hD] |
|
_ = (upperY β D x + (x / D) * β) / β := by rw [Nat.add_comm] |
|
_ = upperY β D x / β + x / D := Nat.add_mul_div_right (upperY β D x) (x / D) hβ |
|
_ = x / D + upperY β D x / β := by rw [Nat.add_comm] |
|
rw [hdiv] |
|
constructor |
|
· intro hEq |
|
have h0 : x / D + upperY β D x / β = x / D + 0 := by simpa using hEq |
|
have hydiv0 : upperY β D x / β = 0 := Nat.add_left_cancel h0 |
|
rcases (Nat.div_eq_zero_iff).1 hydiv0 with hβ0 | hylt |
|
· exact False.elim (Nat.ne_of_gt hβ hβ0) |
|
· exact hylt |
|
· intro hylt |
|
rw [Nat.div_eq_of_lt hylt, Nat.add_zero] |
|
|
|
/-- |
|
入力/前提: `β D x : Nat`, `hD : 0 < D`。 |
|
主張: `upperY β D x < β ↔ x * delta β D < β * (D - x % D)`。 |
|
内容: `D * upperY = xδ + βr` を使い、商一致条件を元の不等式へ戻す。 |
|
証明: 正の `D` を両辺に掛け、`upperY_scaled_eq` と自然数線形算術で整理する。 |
|
役割: `approxQuot_eq_div_iff_mul_delta_lt` の左辺条件を導く最終変換である。 |
|
-/ |
|
private lemma upperY_lt_iff_mul_delta_lt {β D x : Nat} (hD : 0 < D) : |
|
upperY β D x < β ↔ x * delta β D < β * (D - x % D) := by |
|
calc |
|
upperY β D x < β ↔ D * upperY β D x < D * β := by |
|
exact (Nat.mul_lt_mul_left hD).symm |
|
_ ↔ x * delta β D + β * (x % D) < D * β := by |
|
rw [upperY_scaled_eq (β := β) (D := D) (x := x) hD] |
|
_ ↔ x * delta β D + β * (x % D) < β * D := by rw [Nat.mul_comm D β] |
|
_ ↔ x * delta β D < β * D - β * (x % D) := by |
|
omega |
|
_ ↔ x * delta β D < β * (D - x % D) := by |
|
rw [Nat.mul_sub_left_distrib] |
|
|
|
/-- |
|
目的: `M := β ⌈/⌉ D`, `δ := M * D - β`, `q := x / D`, `r := x % D` |
|
に対し、`xδ < β(D-r)` と `⌊M * x / β⌋ = q` の同値を与える。 |
|
定義: 定理の主張内で `let M := β ⌈/⌉ D` と |
|
`let δ := M * D - β` を展開する。 |
|
入力/前提: `β D x : Nat`, `hD : 0 < D`, `hβ : 0 < β`。 |
|
出力: 両条件の論理同値。 |
|
役割: 上側 Barrett 型 1 段除算の厳密一致判定を、 |
|
`xδ < β(D-r)` の形で直接使えるようにする。 |
|
-/ |
|
theorem approxQuot_eq_div_iff_mul_delta_lt |
|
{β D x : Nat} (hD : 0 < D) (hβ : 0 < β) : |
|
let M := β ⌈/⌉ D |
|
let δ := M * D - β |
|
let q := x / D |
|
let r := x % D |
|
x * δ < β * (D - r) ↔ (M * x) / β = q := by |
|
dsimp |
|
calc |
|
x * delta β D < β * (D - x % D) ↔ upperY β D x < β := |
|
(upperY_lt_iff_mul_delta_lt (β := β) (D := D) (x := x) hD).symm |
|
_ ↔ approxQuot β D x = x / D := |
|
(approxQuot_eq_div_iff_upperY_lt (β := β) (D := D) (x := x) hD hβ).symm |
|
|
|
/-- |
|
目的: 上側 magic number による商と剰余の同時復元条件を示す。 |
|
定義: `M := β ⌈/⌉ D`, `δ := M * D - β`, `q := x / D`, `r := x % D`, |
|
`y := M * x % β` とおく。 |
|
入力/前提: `β D x : Nat`, `hD : 0 < D`, `hβ : 0 < β`。 |
|
主張: `xδ < β` は |
|
`⌊M * x / β⌋ = q ∧ ⌊y * D / β⌋ = r` |
|
と同値である。 |
|
内容: 共通補助量 `upperY = qδ + M⁺r` を使い、 |
|
`M * x = qβ + upperY` と `D * upperY = xδ + βr` を利用する。 |
|
前向きでは `xδ < β` から商一致を得て `M * x % β = upperY` とし、 |
|
`D * upperY` を `β` で割って剰余一致を導く。 |
|
逆向きでは商一致から `upperY < β` と `M * x % β = upperY` を得て、 |
|
剰余一致と `D * upperY = xδ + βr` から `(xδ) / β = 0` を回収する。 |
|
証明: `approxQuot_eq_div_iff_upperY_lt`, |
|
`upperY_lt_iff_mul_delta_lt`, `upperY_eq`, `upperY_scaled_eq` に帰着する。 |
|
役割: 上側 magic number による 1 段 `divmod` の正しさを、 |
|
商と剰余を同時に含む形で参照できる最終定理である。 |
|
-/ |
|
theorem approxDivRem_iff_mul_delta_lt |
|
{β D x : Nat} (hD : 0 < D) (hβ : 0 < β) : |
|
let M := β ⌈/⌉ D |
|
let δ := M * D - β |
|
let q := x / D |
|
let r := x % D |
|
let y := (M * x) % β |
|
x * δ < β ↔ ((M * x) / β = q ∧ ((y * D) / β = r)) := by |
|
dsimp |
|
set M := magicUp β D |
|
set δ := delta β D |
|
set q := x / D |
|
set r := x % D |
|
set y := (M * x) % β |
|
set y0 := upperY β D x |
|
have hr : r < D := by |
|
dsimp [r] |
|
exact Nat.mod_lt _ hD |
|
have hMx0 : M * x = q * β + y0 := by |
|
simpa [M, q, y0] using upperY_eq (β := β) (D := D) (x := x) hD |
|
have hDy0 : D * y0 = x * δ + β * r := by |
|
simpa [δ, r, y0] using upperY_scaled_eq (β := β) (D := D) (x := x) hD |
|
have hquot0 : (M * x) / β = q ↔ y0 < β := by |
|
simpa [M, q, y0] using |
|
approxQuot_eq_div_iff_upperY_lt (β := β) (D := D) (x := x) hD hβ |
|
have hquot : (M * x) / β = q ↔ x * δ < β * (D - r) := by |
|
calc |
|
(M * x) / β = q ↔ y0 < β := hquot0 |
|
_ ↔ x * δ < β * (D - r) := by |
|
simpa [δ, r, y0] using |
|
upperY_lt_iff_mul_delta_lt (β := β) (D := D) (x := x) hD |
|
constructor |
|
· intro hxδ |
|
have hxδ' : x * δ < β * (D - r) := by |
|
have hDr1 : 1 ≤ D - r := by omega |
|
calc |
|
x * δ < β := hxδ |
|
_ ≤ β * (D - r) := by simpa using Nat.mul_le_mul_left β hDr1 |
|
have hqEq : (M * x) / β = q := hquot.mpr hxδ' |
|
have hxδ_delta : x * δ < β := by |
|
simpa [δ, delta, M, magicUp] using hxδ |
|
have hy0_lt : y0 < β := hquot0.mp hqEq |
|
have hy : y = y0 := by |
|
calc |
|
y = (q * β + y0) % β := by |
|
dsimp [y] |
|
rw [hMx0] |
|
_ = (y0 + q * β) % β := by rw [Nat.add_comm] |
|
_ = (y0 + β * q) % β := by rw [Nat.mul_comm q β] |
|
_ = y0 % β := Nat.add_mul_mod_self_left y0 β q |
|
_ = y0 := Nat.mod_eq_of_lt hy0_lt |
|
have hrEq : (y * D) / β = r := by |
|
calc |
|
(y * D) / β = (y0 * D) / β := by rw [hy] |
|
_ = (x * δ + r * β) / β := by |
|
rw [Nat.mul_comm y0 D, hDy0, Nat.mul_comm β r] |
|
_ = (x * δ) / β + r := Nat.add_mul_div_right (x * δ) r hβ |
|
_ = r := by rw [Nat.div_eq_of_lt hxδ_delta, zero_add] |
|
exact ⟨hqEq, hrEq⟩ |
|
· rintro ⟨hqEq, hrEq⟩ |
|
have hy0_lt : y0 < β := hquot0.mp hqEq |
|
have hy : y = y0 := by |
|
calc |
|
y = (q * β + y0) % β := by |
|
dsimp [y] |
|
rw [hMx0] |
|
_ = (y0 + q * β) % β := by rw [Nat.add_comm] |
|
_ = (y0 + β * q) % β := by rw [Nat.mul_comm q β] |
|
_ = y0 % β := Nat.add_mul_mod_self_left y0 β q |
|
_ = y0 := Nat.mod_eq_of_lt hy0_lt |
|
have hdiv_formula : (y * D) / β = r + (x * δ) / β := by |
|
calc |
|
(y * D) / β = (y0 * D) / β := by rw [hy] |
|
_ = (x * δ + r * β) / β := by |
|
rw [Nat.mul_comm y0 D, hDy0, Nat.mul_comm β r] |
|
_ = (x * δ + r * β) / β := by rw [Nat.add_comm] |
|
_ = r + (x * δ) / β := by |
|
rw [Nat.add_mul_div_right (x * δ) r hβ, Nat.add_comm] |
|
have hxδ_div0 : (x * δ) / β = 0 := by |
|
have htmp : r + (x * δ) / β = r + 0 := by |
|
calc |
|
r + (x * δ) / β = (y * D) / β := by symm; exact hdiv_formula |
|
_ = r := hrEq |
|
_ = r + 0 := by simp |
|
exact Nat.add_left_cancel htmp |
|
rcases (Nat.div_eq_zero_iff).1 hxδ_div0 with hβ0 | hxlt |
|
· exact False.elim (Nat.ne_of_gt hβ hβ0) |
|
· exact hxlt |
|
|
|
/-- |
|
入力/前提: `N L D x : Nat`, `hD : 0 < D`, `hDlt : D < 2 ^ N`, |
|
`hδ : ((2 ^ (N + L)) ⌈/⌉ D) * D - 2 ^ (N + L) ≤ 2 ^ L`, |
|
`hx : x < 2 ^ N`。 |
|
主張: `β := 2 ^ (N + L)` と `M := β ⌈/⌉ D` に対し、 |
|
近似商 `(M * x) / β` と剰余復元 `(((M * x) % β) * D) / β` が正しい。 |
|
内容: `δ ≤ 2 ^ L` なら、任意の `N`-bit 入力 `x` で商と剰余を同時に復元できる。 |
|
証明: `xδ ≤ (2 ^ N - 1) * 2 ^ L < 2 ^ (N + L)` を示し、 |
|
`approxDivRem_iff_mul_delta_lt` に渡す。 |
|
役割: `β = 2 ^ (N + L)` の固定基数で使う系であり、剰余式は次の資料の |
|
Theorem 1 と同じ形を与える。 |
|
参照: Daniel Lemire, Owen Kaser, Nathan Kurz, |
|
"Faster Remainder by Direct Computation: Applications to Compilers and |
|
Software Libraries", arXiv:1902.01961, 2019. |
|
URL: https://arxiv.org/abs/1902.01961 |
|
-/ |
|
theorem approxDivRem_pow2_of_delta_le |
|
{N L D x : Nat} (hD : 0 < D) (hDlt : D < 2 ^ N) |
|
(hδ : ((2 ^ (N + L)) ⌈/⌉ D) * D - 2 ^ (N + L) ≤ 2 ^ L) |
|
(hx : x < 2 ^ N) : |
|
let β := 2 ^ (N + L) |
|
let M := β ⌈/⌉ D |
|
let y := (M * x) % β |
|
(M * x) / β = x / D ∧ (y * D) / β = x % D := by |
|
have hNpos : 0 < 2 ^ N := lt_trans hD hDlt |
|
dsimp |
|
have hβ : 0 < 2 ^ (N + L) := Nat.two_pow_pos _ |
|
have hxle : x ≤ 2 ^ N - 1 := by |
|
simpa [Nat.pred_eq_sub_one] using Nat.le_pred_of_lt hx |
|
have hpred : 2 ^ N - 1 < 2 ^ N := by |
|
exact Nat.sub_lt hNpos (by decide) |
|
have hxδ : x * (((2 ^ (N + L)) ⌈/⌉ D) * D - 2 ^ (N + L)) < 2 ^ (N + L) := by |
|
calc |
|
x * (((2 ^ (N + L)) ⌈/⌉ D) * D - 2 ^ (N + L)) ≤ (2 ^ N - 1) * 2 ^ L := by |
|
exact Nat.mul_le_mul hxle hδ |
|
_ < 2 ^ N * 2 ^ L := by |
|
exact Nat.mul_lt_mul_of_pos_right hpred (Nat.two_pow_pos L) |
|
_ = 2 ^ (N + L) := by |
|
rw [Nat.pow_add] |
|
have hmain := |
|
(approxDivRem_iff_mul_delta_lt |
|
(β := 2 ^ (N + L)) (D := D) (x := x) hD hβ).mp hxδ |
|
exact hmain |
|
|
|
end ExactDivRem |