lean4-htt/library/init/data/nat/div.lean
Leonardo de Moura 1ad1080f11 refactor(library): keep only basic nat theorems
All theorems are proved without using the tactic framework.
Thus, we can define `fin/uint32/uint64` types and their operations
before we define the tactic framework.
2018-04-11 16:47:54 -07:00

96 lines
3.6 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import init.wf init.data.nat.basic
namespace nat
private def div_rec_lemma {x y : nat} : 0 < y ∧ y ≤ x → x - y < x :=
λ h, and.rec (λ ypos ylex, sub_lt (nat.lt_of_lt_of_le ypos ylex) ypos) h
private def div.F (x : nat) (f : Π x₁, x₁ < x → nat → nat) (y : nat) : nat :=
if h : 0 < y ∧ y ≤ x then f (x - y) (div_rec_lemma h) y + 1 else zero
protected def div := well_founded.fix lt_wf div.F
instance : has_div nat :=
⟨nat.div⟩
private lemma div_def_aux (x y : nat) : x / y = if h : 0 < y ∧ y ≤ x then (x - y) / y + 1 else 0 :=
congr_fun (well_founded.fix_eq lt_wf div.F x) y
lemma div_def (x y : nat) : x / y = if 0 < y ∧ y ≤ x then (x - y) / y + 1 else 0 :=
dif_eq_if (0 < y ∧ y ≤ x) ((x - y) / y + 1) 0 ▸ div_def_aux x y
private lemma {u} div.induction.F
(C : nat → nat → Sort u)
(h₁ : ∀ x y, 0 < y ∧ y ≤ x → C (x - y) y → C x y)
(h₂ : ∀ x y, ¬(0 < y ∧ y ≤ x) → C x y)
(x : nat) (f : ∀ (x₁ : nat), x₁ < x → ∀ (y : nat), C x₁ y) (y : nat) : C x y :=
if h : 0 < y ∧ y ≤ x then h₁ x y h (f (x - y) (div_rec_lemma h) y) else h₂ x y h
@[elab_as_eliminator]
lemma {u} div.induction_on
{C : nat → nat → Sort u}
(x y : nat)
(h₁ : ∀ x y, 0 < y ∧ y ≤ x → C (x - y) y → C x y)
(h₂ : ∀ x y, ¬(0 < y ∧ y ≤ x) → C x y)
: C x y :=
well_founded.fix nat.lt_wf (div.induction.F C h₁ h₂) x y
private def mod.F (x : nat) (f : Π x₁, x₁ < x → nat → nat) (y : nat) : nat :=
if h : 0 < y ∧ y ≤ x then f (x - y) (div_rec_lemma h) y else x
protected def mod := well_founded.fix lt_wf mod.F
instance : has_mod nat :=
⟨nat.mod⟩
private lemma mod_def_aux (x y : nat) : x % y = if h : 0 < y ∧ y ≤ x then (x - y) % y else x :=
congr_fun (well_founded.fix_eq lt_wf mod.F x) y
lemma mod_def (x y : nat) : x % y = if 0 < y ∧ y ≤ x then (x - y) % y else x :=
dif_eq_if (0 < y ∧ y ≤ x) ((x - y) % y) x ▸ mod_def_aux x y
@[elab_as_eliminator]
lemma {u} mod.induction_on
{C : nat → nat → Sort u}
(x y : nat)
(h₁ : ∀ x y, 0 < y ∧ y ≤ x → C (x - y) y → C x y)
(h₂ : ∀ x y, ¬(0 < y ∧ y ≤ x) → C x y)
: C x y :=
div.induction_on x y h₁ h₂
lemma mod_zero (a : nat) : a % 0 = a :=
suffices (if 0 < 0 ∧ 0 ≤ a then (a - 0) % 0 else a) = a, from (mod_def a 0).symm ▸ this,
have h : ¬ (0 < 0 ∧ 0 ≤ a), from λ ⟨h₁, _⟩, absurd h₁ (nat.lt_irrefl _),
if_neg h
lemma mod_eq_of_lt {a b : nat} (h : a < b) : a % b = a :=
suffices (if 0 < b ∧ b ≤ a then (a - b) % b else a) = a, from (mod_def a b).symm ▸ this,
have h' : ¬(0 < b ∧ b ≤ a), from λ ⟨_, h₁⟩, absurd h₁ (nat.not_le_of_gt h),
if_neg h'
lemma mod_eq_sub_mod {a b : nat} (h : a ≥ b) : a % b = (a - b) % b :=
or.elim (eq_zero_or_pos b)
(λ h₁, h₁.symm ▸ (nat.sub_zero a).symm ▸ rfl)
(λ h₁, (mod_def a b).symm ▸ if_pos ⟨h₁, h⟩)
lemma mod_lt (x : nat) {y : nat} : y > 0 → x % y < y :=
mod.induction_on x y
(λ x y ⟨_, h₁⟩ h₂ h₃,
have ih : (x - y) % y < y, from h₂ h₃,
have heq : x % y = (x - y) % y, from mod_eq_sub_mod h₁,
heq.symm ▸ ih)
(λ x y h₁ h₂,
have h₁ : ¬ 0 < y ¬ y ≤ x, from iff.mp (decidable.not_and_iff_or_not _ _) h₁,
or.elim h₁
(λ h₁, absurd h₂ h₁)
(λ h₁,
have hgt : y > x, from gt_of_not_le h₁,
have heq : x % y = x, from mod_eq_of_lt hgt,
heq.symm ▸ hgt))
end nat