2015-01-12 21:28:42 +00:00
|
|
|
|
/-
|
|
|
|
|
Copyright (c) 2014 Floris van Doorn. All rights reserved.
|
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
Authors: Floris van Doorn, Jeremy Avigad
|
|
|
|
|
Subtraction on the natural numbers, as well as min, max, and distance.
|
|
|
|
|
-/
|
2014-11-22 08:15:51 +00:00
|
|
|
|
import .order
|
2015-10-14 19:27:09 +00:00
|
|
|
|
open eq.ops algebra
|
2014-08-20 02:32:44 +00:00
|
|
|
|
|
2014-08-02 01:40:24 +00:00
|
|
|
|
namespace nat
|
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
/- subtraction -/
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_zero (n : ℕ) : n - 0 = n :=
|
2014-11-22 08:15:51 +00:00
|
|
|
|
rfl
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_succ (n m : ℕ) : n - succ m = pred (n - m) :=
|
2014-11-22 08:15:51 +00:00
|
|
|
|
rfl
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem zero_sub (n : ℕ) : 0 - n = 0 :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.induction_on n !sub_zero
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take k : nat,
|
|
|
|
|
assume IH : 0 - k = 0,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
0 - succ k = pred (0 - k) : sub_succ
|
|
|
|
|
... = pred 0 : IH
|
2015-01-07 01:54:15 +00:00
|
|
|
|
... = 0 : pred_zero)
|
2014-08-27 01:47:36 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem succ_sub_succ (n m : ℕ) : succ n - succ m = n - m :=
|
2014-11-30 23:07:09 +00:00
|
|
|
|
succ_sub_succ_eq_sub n m
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem sub_self (n : ℕ) : n - n = 0 :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.induction_on n !sub_zero (take k IH, !succ_sub_succ ⬝ IH)
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem add_sub_add_right (n k m : ℕ) : (n + k) - (m + k) = n - m :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.induction_on k
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(calc
|
2014-12-24 02:14:19 +00:00
|
|
|
|
(n + 0) - (m + 0) = n - (m + 0) : {!add_zero}
|
|
|
|
|
... = n - m : {!add_zero})
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take l : nat,
|
|
|
|
|
assume IH : (n + l) - (m + l) = n - m,
|
|
|
|
|
calc
|
2014-12-23 22:34:16 +00:00
|
|
|
|
(n + succ l) - (m + succ l) = succ (n + l) - (m + succ l) : {!add_succ}
|
|
|
|
|
... = succ (n + l) - succ (m + l) : {!add_succ}
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = (n + l) - (m + l) : !succ_sub_succ
|
2014-08-27 01:47:36 +00:00
|
|
|
|
... = n - m : IH)
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem add_sub_add_left (k n m : ℕ) : (k + n) - (k + m) = n - m :=
|
|
|
|
|
!add.comm ▸ !add.comm ▸ !add_sub_add_right
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem add_sub_cancel (n m : ℕ) : n + m - m = n :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.induction_on m
|
2015-10-07 23:44:47 +00:00
|
|
|
|
(begin rewrite add_zero end)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take k : ℕ,
|
|
|
|
|
assume IH : n + k - k = n,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
n + succ k - succ k = succ (n + k) - succ k : add_succ
|
|
|
|
|
... = n + k - k : succ_sub_succ
|
2014-08-27 01:47:36 +00:00
|
|
|
|
... = n : IH)
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem add_sub_cancel_left (n m : ℕ) : n + m - n = m :=
|
|
|
|
|
!add.comm ▸ !add_sub_cancel
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem sub_sub (n m k : ℕ) : n - m - k = n - (m + k) :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.induction_on k
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
n - m - 0 = n - m : sub_zero
|
|
|
|
|
... = n - (m + 0) : add_zero)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take l : nat,
|
|
|
|
|
assume IH : n - m - l = n - (m + l),
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
n - m - succ l = pred (n - m - l) : !sub_succ
|
|
|
|
|
... = pred (n - (m + l)) : IH
|
|
|
|
|
... = n - succ (m + l) : sub_succ
|
2015-10-07 23:44:47 +00:00
|
|
|
|
... = n - (m + succ l) : by rewrite add_succ)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem succ_sub_sub_succ (n m k : ℕ) : succ n - m - succ k = n - m - k :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
succ n - m - succ k = succ n - (m + succ k) : sub_sub
|
|
|
|
|
... = succ n - succ (m + k) : add_succ
|
|
|
|
|
... = n - (m + k) : succ_sub_succ
|
|
|
|
|
... = n - m - k : sub_sub
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_self_add (n m : ℕ) : n - (n + m) = 0 :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
n - (n + m) = n - n - m : sub_sub
|
|
|
|
|
... = 0 - m : sub_self
|
|
|
|
|
... = 0 : zero_sub
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub.right_comm (m n k : ℕ) : m - n - k = m - k - n :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2014-10-05 19:39:13 +00:00
|
|
|
|
m - n - k = m - (n + k) : !sub_sub
|
2014-10-02 01:39:47 +00:00
|
|
|
|
... = m - (k + n) : {!add.comm}
|
2014-10-05 19:39:13 +00:00
|
|
|
|
... = m - k - n : !sub_sub⁻¹
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem sub_one (n : ℕ) : n - 1 = pred n :=
|
2015-01-12 21:28:42 +00:00
|
|
|
|
rfl
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem succ_sub_one (n : ℕ) : succ n - 1 = n :=
|
2015-01-12 21:28:42 +00:00
|
|
|
|
rfl
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
/- interaction with multiplication -/
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem mul_pred_left (n m : ℕ) : pred n * m = n * m - m :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.induction_on n
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
pred 0 * m = 0 * m : pred_zero
|
|
|
|
|
... = 0 : zero_mul
|
|
|
|
|
... = 0 - m : zero_sub
|
|
|
|
|
... = 0 * m - m : zero_mul)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take k : nat,
|
|
|
|
|
assume IH : pred k * m = k * m - m,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
pred (succ k) * m = k * m : pred_succ
|
|
|
|
|
... = k * m + m - m : add_sub_cancel
|
|
|
|
|
... = succ k * m - m : succ_mul)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem mul_pred_right (n m : ℕ) : n * pred m = n * m - n :=
|
2015-01-12 21:28:42 +00:00
|
|
|
|
calc
|
|
|
|
|
n * pred m = pred m * n : mul.comm
|
|
|
|
|
... = m * n - n : mul_pred_left
|
|
|
|
|
... = n * m - n : mul.comm
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem mul_sub_right_distrib (n m k : ℕ) : (n - m) * k = n * k - m * k :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.induction_on m
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(n - 0) * k = n * k : sub_zero
|
|
|
|
|
... = n * k - 0 : sub_zero
|
|
|
|
|
... = n * k - 0 * k : zero_mul)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take l : nat,
|
|
|
|
|
assume IH : (n - l) * k = n * k - l * k,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(n - succ l) * k = pred (n - l) * k : sub_succ
|
|
|
|
|
... = (n - l) * k - k : mul_pred_left
|
|
|
|
|
... = n * k - l * k - k : IH
|
|
|
|
|
... = n * k - (l * k + k) : sub_sub
|
|
|
|
|
... = n * k - (succ l * k) : succ_mul)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-02-01 14:55:12 +00:00
|
|
|
|
theorem mul_sub_left_distrib (n m k : ℕ) : n * (m - k) = n * m - n * k :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2014-10-02 01:39:47 +00:00
|
|
|
|
n * (m - k) = (m - k) * n : !mul.comm
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = m * n - k * n : !mul_sub_right_distrib
|
2014-10-02 01:39:47 +00:00
|
|
|
|
... = n * m - k * n : {!mul.comm}
|
|
|
|
|
... = n * m - n * k : {!mul.comm}
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-04-14 13:20:06 +00:00
|
|
|
|
theorem mul_self_sub_mul_self_eq (a b : nat) : a * a - b * b = (a + b) * (a - b) :=
|
2015-10-14 19:27:09 +00:00
|
|
|
|
by rewrite [mul_sub_left_distrib, *right_distrib, mul.comm b a, add.comm (a*a) (a*b), add_sub_add_left]
|
2015-04-14 13:20:06 +00:00
|
|
|
|
|
|
|
|
|
theorem succ_mul_succ_eq (a : nat) : succ a * succ a = a*a + a + a + 1 :=
|
|
|
|
|
calc succ a * succ a = (a+1)*(a+1) : by rewrite [add_one]
|
2015-10-14 19:27:09 +00:00
|
|
|
|
... = a*a + a + a + 1 : by rewrite [right_distrib, left_distrib, one_mul, mul_one]
|
2015-04-14 13:20:06 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
/- interaction with inequalities -/
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-08-02 02:29:50 +00:00
|
|
|
|
theorem succ_sub {m n : ℕ} : m ≥ n → succ m - n = succ (m - n) :=
|
|
|
|
|
sub_induction n m
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(take k, assume H : 0 ≤ k, rfl)
|
|
|
|
|
(take k,
|
2014-08-02 02:29:50 +00:00
|
|
|
|
assume H : succ k ≤ 0,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
absurd H !not_succ_le_zero)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take k l,
|
|
|
|
|
assume IH : k ≤ l → succ l - k = succ (l - k),
|
|
|
|
|
take H : succ k ≤ succ l,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
succ (succ l) - succ k = succ l - k : succ_sub_succ
|
2015-01-07 01:44:04 +00:00
|
|
|
|
... = succ (l - k) : IH (le_of_succ_le_succ H)
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = succ (succ l - succ k) : succ_sub_succ)
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_eq_zero_of_le {n m : ℕ} (H : n ≤ m) : n - m = 0 :=
|
|
|
|
|
obtain (k : ℕ) (Hk : n + k = m), from le.elim H, Hk ▸ !sub_self_add
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem add_sub_of_le {n m : ℕ} : n ≤ m → n + (m - n) = m :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
sub_induction n m
|
|
|
|
|
(take k,
|
|
|
|
|
assume H : 0 ≤ k,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
0 + (k - 0) = k - 0 : zero_add
|
|
|
|
|
... = k : sub_zero)
|
2015-01-07 01:44:04 +00:00
|
|
|
|
(take k, assume H : succ k ≤ 0, absurd H !not_succ_le_zero)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take k l,
|
|
|
|
|
assume IH : k ≤ l → k + (l - k) = l,
|
|
|
|
|
take H : succ k ≤ succ l,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
succ k + (succ l - succ k) = succ k + (l - k) : succ_sub_succ
|
2015-04-18 17:50:30 +00:00
|
|
|
|
... = succ (k + (l - k)) : succ_add
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = succ l : IH (le_of_succ_le_succ H))
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem add_sub_of_ge {n m : ℕ} (H : n ≥ m) : n + (m - n) = n :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
n + (m - n) = n + 0 : sub_eq_zero_of_le H
|
|
|
|
|
... = n : add_zero
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_add_cancel {n m : ℕ} : n ≥ m → n - m + m = n :=
|
|
|
|
|
!add.comm ▸ !add_sub_of_le
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_add_of_le {n m : ℕ} : n ≤ m → n - m + m = m :=
|
|
|
|
|
!add.comm ▸ add_sub_of_ge
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub.cases {P : ℕ → Prop} {n m : ℕ} (H1 : n ≤ m → P 0) (H2 : ∀k, m + k = n -> P k)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
: P (n - m) :=
|
2015-01-07 01:44:04 +00:00
|
|
|
|
or.elim !le.total
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(assume H3 : n ≤ m, (sub_eq_zero_of_le H3)⁻¹ ▸ (H1 H3))
|
|
|
|
|
(assume H3 : m ≤ n, H2 (n - m) (add_sub_of_le H3))
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem exists_sub_eq_of_le {n m : ℕ} (H : n ≤ m) : ∃k, m - k = n :=
|
2015-01-07 01:44:04 +00:00
|
|
|
|
obtain (k : ℕ) (Hk : n + k = m), from le.elim H,
|
2014-12-16 03:05:03 +00:00
|
|
|
|
exists.intro k
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(calc
|
2015-10-07 23:44:47 +00:00
|
|
|
|
m - k = n + k - k : by rewrite Hk
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = n : add_sub_cancel)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
|
|
|
|
theorem add_sub_assoc {m k : ℕ} (H : k ≤ m) (n : ℕ) : n + m - k = n + (m - k) :=
|
|
|
|
|
have l1 : k ≤ m → n + m - k = n + (m - k), from
|
|
|
|
|
sub_induction k m
|
|
|
|
|
(take m : ℕ,
|
|
|
|
|
assume H : 0 ≤ m,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
n + m - 0 = n + m : sub_zero
|
|
|
|
|
... = n + (m - 0) : sub_zero)
|
2015-01-07 01:44:04 +00:00
|
|
|
|
(take k : ℕ, assume H : succ k ≤ 0, absurd H !not_succ_le_zero)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take k m,
|
|
|
|
|
assume IH : k ≤ m → n + m - k = n + (m - k),
|
|
|
|
|
take H : succ k ≤ succ m,
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
n + succ m - succ k = succ (n + m) - succ k : add_succ
|
|
|
|
|
... = n + m - k : succ_sub_succ
|
2015-01-07 01:44:04 +00:00
|
|
|
|
... = n + (m - k) : IH (le_of_succ_le_succ H)
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = n + (succ m - succ k) : succ_sub_succ),
|
2014-08-02 02:29:50 +00:00
|
|
|
|
l1 H
|
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem le_of_sub_eq_zero {n m : ℕ} : n - m = 0 → n ≤ m :=
|
|
|
|
|
sub.cases
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(assume H1 : n ≤ m, assume H2 : 0 = 0, H1)
|
|
|
|
|
(take k : ℕ,
|
|
|
|
|
assume H1 : m + k = n,
|
|
|
|
|
assume H2 : k = 0,
|
2014-12-24 02:14:19 +00:00
|
|
|
|
have H3 : n = m, from !add_zero ▸ H2 ▸ H1⁻¹,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
H3 ▸ !le.refl)
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_sub.cases {P : ℕ → ℕ → Prop} {n m : ℕ} (H1 : ∀k, n = m + k -> P k 0)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(H2 : ∀k, m = n + k → P 0 k) : P (n - m) (m - n) :=
|
2015-01-07 01:44:04 +00:00
|
|
|
|
or.elim !le.total
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(assume H3 : n ≤ m,
|
2015-01-26 16:28:13 +00:00
|
|
|
|
(sub_eq_zero_of_le H3)⁻¹ ▸ (H2 (m - n) (add_sub_of_le H3)⁻¹))
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(assume H3 : m ≤ n,
|
2015-01-26 16:28:13 +00:00
|
|
|
|
(sub_eq_zero_of_le H3)⁻¹ ▸ (H1 (n - m) (add_sub_of_le H3)⁻¹))
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_eq_of_add_eq {n m k : ℕ} (H : n + m = k) : k - n = m :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
have H2 : k - n + n = m + n, from
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
k - n + n = k : sub_add_cancel (le.intro H)
|
2014-08-27 01:47:36 +00:00
|
|
|
|
... = n + m : H⁻¹
|
2014-10-02 01:39:47 +00:00
|
|
|
|
... = m + n : !add.comm,
|
2015-10-22 20:09:26 +00:00
|
|
|
|
add.right_cancel H2
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-06-27 08:41:57 +00:00
|
|
|
|
theorem eq_sub_of_add_eq {a b c : ℕ} (H : a + c = b) : a = b - c :=
|
|
|
|
|
(sub_eq_of_add_eq (!add.comm ▸ H))⁻¹
|
|
|
|
|
|
|
|
|
|
theorem sub_eq_of_eq_add {a b c : ℕ} (H : a = c + b) : a - b = c :=
|
|
|
|
|
sub_eq_of_add_eq (!add.comm ▸ H⁻¹)
|
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_le_sub_right {n m : ℕ} (H : n ≤ m) (k : ℕ) : n - k ≤ m - k :=
|
2015-01-07 01:44:04 +00:00
|
|
|
|
obtain (l : ℕ) (Hl : n + l = m), from le.elim H,
|
|
|
|
|
or.elim !le.total
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(assume H2 : n ≤ k, (sub_eq_zero_of_le H2)⁻¹ ▸ !zero_le)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(assume H2 : k ≤ n,
|
|
|
|
|
have H3 : n - k + l = m - k, from
|
|
|
|
|
calc
|
2014-11-22 08:15:51 +00:00
|
|
|
|
n - k + l = l + (n - k) : add.comm
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = l + n - k : add_sub_assoc H2 l
|
|
|
|
|
... = n + l - k : add.comm
|
|
|
|
|
... = m - k : Hl,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
le.intro H3)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_le_sub_left {n m : ℕ} (H : n ≤ m) (k : ℕ) : k - m ≤ k - n :=
|
2015-01-07 01:44:04 +00:00
|
|
|
|
obtain (l : ℕ) (Hl : n + l = m), from le.elim H,
|
2015-01-12 21:28:42 +00:00
|
|
|
|
sub.cases
|
2014-10-05 18:36:39 +00:00
|
|
|
|
(assume H2 : k ≤ m, !zero_le)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take m' : ℕ,
|
|
|
|
|
assume Hm : m + m' = k,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
have H3 : n ≤ k, from le.trans H (le.intro Hm),
|
2014-08-02 02:29:50 +00:00
|
|
|
|
have H4 : m' + l + n = k - n + n, from
|
|
|
|
|
calc
|
2014-11-22 08:15:51 +00:00
|
|
|
|
m' + l + n = n + (m' + l) : add.comm
|
|
|
|
|
... = n + (l + m') : add.comm
|
|
|
|
|
... = n + l + m' : add.assoc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = m + m' : Hl
|
2014-11-22 08:15:51 +00:00
|
|
|
|
... = k : Hm
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = k - n + n : sub_add_cancel H3,
|
2015-10-22 20:09:26 +00:00
|
|
|
|
le.intro (add.right_cancel H4))
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-10-12 03:35:45 +00:00
|
|
|
|
open algebra
|
2015-10-07 23:44:47 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem sub_pos_of_lt {m n : ℕ} (H : m < n) : n - m > 0 :=
|
2015-10-07 23:44:47 +00:00
|
|
|
|
assert H1 : n = n - m + m, from (sub_add_cancel (le_of_lt H))⁻¹,
|
|
|
|
|
have H2 : 0 + m < n - m + m, begin rewrite [zero_add, -H1], exact H end,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
!lt_of_add_lt_add_right H2
|
2014-12-17 18:32:38 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem lt_of_sub_pos {m n : ℕ} (H : n - m > 0) : m < n :=
|
2015-05-25 09:48:07 +00:00
|
|
|
|
lt_of_not_ge
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(take H1 : m ≥ n,
|
|
|
|
|
have H2 : n - m = 0, from sub_eq_zero_of_le H1,
|
|
|
|
|
!lt.irrefl (H2 ▸ H))
|
|
|
|
|
|
|
|
|
|
theorem lt_of_sub_lt_sub_right {n m k : ℕ} (H : n - k < m - k) : n < m :=
|
2015-05-25 09:48:07 +00:00
|
|
|
|
lt_of_not_ge
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(assume H1 : m ≤ n,
|
|
|
|
|
have H2 : m - k ≤ n - k, from sub_le_sub_right H1 _,
|
2015-05-25 09:48:07 +00:00
|
|
|
|
not_le_of_gt H H2)
|
2015-01-12 21:28:42 +00:00
|
|
|
|
|
|
|
|
|
theorem lt_of_sub_lt_sub_left {n m k : ℕ} (H : n - m < n - k) : k < m :=
|
2015-05-25 09:48:07 +00:00
|
|
|
|
lt_of_not_ge
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(assume H1 : m ≤ k,
|
|
|
|
|
have H2 : n - k ≤ n - m, from sub_le_sub_left H1 _,
|
2015-05-25 09:48:07 +00:00
|
|
|
|
not_le_of_gt H H2)
|
2015-01-12 21:28:42 +00:00
|
|
|
|
|
|
|
|
|
theorem sub_lt_sub_add_sub (n m k : ℕ) : n - k ≤ (n - m) + (m - k) :=
|
|
|
|
|
sub.cases
|
|
|
|
|
(assume H : n ≤ m, !zero_add⁻¹ ▸ sub_le_sub_right H k)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take mn : ℕ,
|
|
|
|
|
assume Hmn : m + mn = n,
|
2015-01-12 21:28:42 +00:00
|
|
|
|
sub.cases
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(assume H : m ≤ k,
|
2015-10-07 23:44:47 +00:00
|
|
|
|
have H2 : n - k ≤ n - m, from sub_le_sub_left H n,
|
|
|
|
|
assert H3 : n - k ≤ mn, from sub_eq_of_add_eq Hmn ▸ H2,
|
|
|
|
|
show n - k ≤ mn + 0, begin rewrite add_zero, assumption end)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(take km : ℕ,
|
2014-08-27 01:47:36 +00:00
|
|
|
|
assume Hkm : k + km = m,
|
|
|
|
|
have H : k + (mn + km) = n, from
|
|
|
|
|
calc
|
2014-11-22 08:15:51 +00:00
|
|
|
|
k + (mn + km) = k + (km + mn): add.comm
|
|
|
|
|
... = k + km + mn : add.assoc
|
|
|
|
|
... = m + mn : Hkm
|
|
|
|
|
... = n : Hmn,
|
2015-01-12 21:28:42 +00:00
|
|
|
|
have H2 : n - k = mn + km, from sub_eq_of_add_eq H,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
H2 ▸ !le.refl))
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-02-25 18:32:50 +00:00
|
|
|
|
theorem sub_lt_self {m n : ℕ} (H1 : m > 0) (H2 : n > 0) : m - n < m :=
|
|
|
|
|
calc
|
|
|
|
|
m - n = succ (pred m) - n : succ_pred_of_pos H1
|
|
|
|
|
... = succ (pred m) - succ (pred n) : succ_pred_of_pos H2
|
|
|
|
|
... = pred m - pred n : succ_sub_succ
|
|
|
|
|
... ≤ pred m : sub_le
|
|
|
|
|
... < succ (pred m) : lt_succ_self
|
|
|
|
|
... = m : succ_pred_of_pos H1
|
|
|
|
|
|
|
|
|
|
theorem le_sub_of_add_le {m n k : ℕ} (H : m + k ≤ n) : m ≤ n - k :=
|
|
|
|
|
calc
|
|
|
|
|
m = m + k - k : add_sub_cancel
|
|
|
|
|
... ≤ n - k : sub_le_sub_right H k
|
|
|
|
|
|
|
|
|
|
theorem lt_sub_of_add_lt {m n k : ℕ} (H : m + k < n) (H2 : k ≤ n) : m < n - k :=
|
|
|
|
|
lt_of_succ_le (le_sub_of_add_le (calc
|
|
|
|
|
succ m + k = succ (m + k) : succ_add_eq_succ_add
|
|
|
|
|
... ≤ n : succ_le_of_lt H))
|
|
|
|
|
|
2015-07-26 22:42:39 +00:00
|
|
|
|
theorem sub_lt_of_lt_add {v n m : nat} (h₁ : v < n + m) (h₂ : n ≤ v) : v - n < m :=
|
|
|
|
|
have succ v ≤ n + m, from succ_le_of_lt h₁,
|
|
|
|
|
have succ (v - n) ≤ m, from
|
|
|
|
|
calc succ (v - n) = succ v - n : succ_sub h₂
|
|
|
|
|
... ≤ n + m - n : sub_le_sub_right this n
|
|
|
|
|
... = m : add_sub_cancel_left,
|
|
|
|
|
lt_of_succ_le this
|
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
/- distance -/
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-09 02:47:44 +00:00
|
|
|
|
definition dist [reducible] (n m : ℕ) := (n - m) + (m - n)
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist.comm (n m : ℕ) : dist n m = dist m n :=
|
2014-10-02 01:39:47 +00:00
|
|
|
|
!add.comm
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem dist_self (n : ℕ) : dist n n = 0 :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2014-11-22 08:15:51 +00:00
|
|
|
|
(n - n) + (n - n) = 0 + (n - n) : sub_self
|
|
|
|
|
... = 0 + 0 : sub_self
|
|
|
|
|
... = 0 : rfl
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem eq_of_dist_eq_zero {n m : ℕ} (H : dist n m = 0) : n = m :=
|
2014-12-23 22:34:16 +00:00
|
|
|
|
have H2 : n - m = 0, from eq_zero_of_add_eq_zero_right H,
|
2015-01-12 21:28:42 +00:00
|
|
|
|
have H3 : n ≤ m, from le_of_sub_eq_zero H2,
|
2014-12-23 22:34:16 +00:00
|
|
|
|
have H4 : m - n = 0, from eq_zero_of_add_eq_zero_left H,
|
2015-01-12 21:28:42 +00:00
|
|
|
|
have H5 : m ≤ n, from le_of_sub_eq_zero H4,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
le.antisymm H3 H5
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-08-04 00:49:20 +00:00
|
|
|
|
theorem dist_eq_zero {n m : ℕ} (H : n = m) : dist n m = 0 :=
|
|
|
|
|
by substvars; rewrite [↑dist, *sub_self, add_zero]
|
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_eq_sub_of_le {n m : ℕ} (H : n ≤ m) : dist n m = m - n :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
dist n m = 0 + (m - n) : {sub_eq_zero_of_le H}
|
|
|
|
|
... = m - n : zero_add
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-08-04 00:49:20 +00:00
|
|
|
|
theorem dist_eq_sub_of_lt {n m : ℕ} (H : n < m) : dist n m = m - n :=
|
|
|
|
|
dist_eq_sub_of_le (le_of_lt H)
|
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_eq_sub_of_ge {n m : ℕ} (H : n ≥ m) : dist n m = n - m :=
|
|
|
|
|
!dist.comm ▸ dist_eq_sub_of_le H
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-08-04 00:49:20 +00:00
|
|
|
|
theorem dist_eq_sub_of_gt {n m : ℕ} (H : n > m) : dist n m = n - m :=
|
|
|
|
|
dist_eq_sub_of_ge (le_of_lt H)
|
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem dist_zero_right (n : ℕ) : dist n 0 = n :=
|
2015-01-12 21:28:42 +00:00
|
|
|
|
dist_eq_sub_of_ge !zero_le ⬝ !sub_zero
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem dist_zero_left (n : ℕ) : dist 0 n = n :=
|
2015-01-12 21:28:42 +00:00
|
|
|
|
dist_eq_sub_of_le !zero_le ⬝ !sub_zero
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist.intro {n m k : ℕ} (H : n + m = k) : dist k n = m :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
dist k n = k - n : dist_eq_sub_of_ge (le.intro H)
|
|
|
|
|
... = m : sub_eq_of_add_eq H
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_add_add_right (n k m : ℕ) : dist (n + k) (m + k) = dist n m :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2014-08-27 01:47:36 +00:00
|
|
|
|
dist (n + k) (m + k) = ((n+k) - (m+k)) + ((m+k)-(n+k)) : rfl
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = (n - m) + ((m + k) - (n + k)) : add_sub_add_right
|
|
|
|
|
... = (n - m) + (m - n) : add_sub_add_right
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_add_add_left (k n m : ℕ) : dist (k + n) (k + m) = dist n m :=
|
2015-10-22 18:54:00 +00:00
|
|
|
|
begin rewrite [add.comm k n, add.comm k m]; apply dist_add_add_right end
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_add_eq_of_ge {n m : ℕ} (H : n ≥ m) : dist n m + m = n :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
dist n m + m = n - m + m : {dist_eq_sub_of_ge H}
|
|
|
|
|
... = n : sub_add_cancel H
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-08-02 02:29:50 +00:00
|
|
|
|
theorem dist_eq_intro {n m k l : ℕ} (H : n + m = k + l) : dist n k = dist l m :=
|
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
dist n k = dist (n + m) (k + m) : dist_add_add_right
|
|
|
|
|
... = dist (k + l) (k + m) : H
|
|
|
|
|
... = dist l m : dist_add_add_left
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_sub_eq_dist_add_left {n m : ℕ} (H : n ≥ m) (k : ℕ) :
|
|
|
|
|
dist (n - m) k = dist n (k + m) :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
have H2 : n - m + (k + m) = k + n, from
|
|
|
|
|
calc
|
2014-11-22 08:15:51 +00:00
|
|
|
|
n - m + (k + m) = n - m + (m + k) : add.comm
|
|
|
|
|
... = n - m + m + k : add.assoc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = n + k : sub_add_cancel H
|
2014-11-22 08:15:51 +00:00
|
|
|
|
... = k + n : add.comm,
|
2014-08-02 02:29:50 +00:00
|
|
|
|
dist_eq_intro H2
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_sub_eq_dist_add_right {k m : ℕ} (H : k ≥ m) (n : ℕ) :
|
|
|
|
|
dist n (k - m) = dist (n + m) k :=
|
|
|
|
|
(dist_sub_eq_dist_add_left H n ▸ !dist.comm) ▸ !dist.comm
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist.triangle_inequality (n m k : ℕ) : dist n k ≤ dist n m + dist m k :=
|
2015-07-22 17:13:19 +00:00
|
|
|
|
have (n - m) + (m - k) + ((k - m) + (m - n)) = (n - m) + (m - n) + ((m - k) + (k - m)),
|
2015-10-07 23:44:47 +00:00
|
|
|
|
begin rewrite [add.comm (k - m) (m - n),
|
|
|
|
|
{n - m + _ + _}add.assoc,
|
|
|
|
|
{m - k + _}add.left_comm, -add.assoc] end,
|
2015-07-22 17:13:19 +00:00
|
|
|
|
this ▸ add_le_add !sub_lt_sub_add_sub !sub_lt_sub_add_sub
|
2014-08-02 02:29:50 +00:00
|
|
|
|
|
2015-01-12 21:28:42 +00:00
|
|
|
|
theorem dist_add_add_le_add_dist_dist (n m k l : ℕ) : dist (n + m) (k + l) ≤ dist n k + dist m l :=
|
2015-10-22 18:54:00 +00:00
|
|
|
|
assert H : dist (n + m) (k + m) + dist (k + m) (k + l) = dist n k + dist m l,
|
|
|
|
|
by rewrite [dist_add_add_left, dist_add_add_right],
|
|
|
|
|
by rewrite -H; apply dist.triangle_inequality
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem dist_mul_right (n k m : ℕ) : dist (n * k) (m * k) = dist n m * k :=
|
2015-07-22 17:13:19 +00:00
|
|
|
|
assert ∀ n m, dist n m = n - m + (m - n), from take n m, rfl,
|
2015-10-14 19:27:09 +00:00
|
|
|
|
by rewrite [this, this n m, right_distrib, *mul_sub_right_distrib]
|
2015-07-22 17:13:19 +00:00
|
|
|
|
|
|
|
|
|
theorem dist_mul_left (k n m : ℕ) : dist (k * n) (k * m) = k * dist n m :=
|
2015-10-07 23:44:47 +00:00
|
|
|
|
begin rewrite [mul.comm k n, mul.comm k m, dist_mul_right, mul.comm] end
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2014-10-05 19:39:13 +00:00
|
|
|
|
theorem dist_mul_dist (n m k l : ℕ) : dist n m * dist k l = dist (n * k + m * l) (n * l + m * k) :=
|
2014-08-02 02:29:50 +00:00
|
|
|
|
have aux : ∀k l, k ≥ l → dist n m * dist k l = dist (n * k + m * l) (n * l + m * k), from
|
|
|
|
|
take k l : ℕ,
|
|
|
|
|
assume H : k ≥ l,
|
2015-05-30 12:09:34 +00:00
|
|
|
|
have H2 : m * k ≥ m * l, from !mul_le_mul_left H,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
have H3 : n * l + m * k ≥ m * l, from le.trans H2 !le_add_left,
|
2014-08-02 02:29:50 +00:00
|
|
|
|
calc
|
2015-01-12 21:28:42 +00:00
|
|
|
|
dist n m * dist k l = dist n m * (k - l) : dist_eq_sub_of_ge H
|
|
|
|
|
... = dist (n * (k - l)) (m * (k - l)) : dist_mul_right
|
2015-07-22 17:13:19 +00:00
|
|
|
|
... = dist (n * k - n * l) (m * k - m * l) : by rewrite [*mul_sub_left_distrib]
|
2015-05-30 12:09:34 +00:00
|
|
|
|
... = dist (n * k) (m * k - m * l + n * l) : dist_sub_eq_dist_add_left (!mul_le_mul_left H)
|
2015-01-12 21:28:42 +00:00
|
|
|
|
... = dist (n * k) (n * l + (m * k - m * l)) : add.comm
|
|
|
|
|
... = dist (n * k) (n * l + m * k - m * l) : add_sub_assoc H2 (n * l)
|
|
|
|
|
... = dist (n * k + m * l) (n * l + m * k) : dist_sub_eq_dist_add_right H3 _,
|
2015-01-07 01:44:04 +00:00
|
|
|
|
or.elim !le.total
|
2015-01-12 21:28:42 +00:00
|
|
|
|
(assume H : k ≤ l, !dist.comm ▸ !dist.comm ▸ aux l k H)
|
2014-08-02 02:29:50 +00:00
|
|
|
|
(assume H : l ≤ k, aux k l H)
|
2014-08-02 01:40:24 +00:00
|
|
|
|
|
2015-08-04 00:49:20 +00:00
|
|
|
|
lemma dist_eq_max_sub_min {i j : nat} : dist i j = (max i j) - min i j :=
|
|
|
|
|
or.elim (lt_or_ge i j)
|
|
|
|
|
(suppose i < j, begin rewrite [max_eq_right_of_lt this, min_eq_left_of_lt this, dist_eq_sub_of_lt this] end)
|
|
|
|
|
(suppose i ≥ j, begin rewrite [max_eq_left this , min_eq_right this, dist_eq_sub_of_ge this] end)
|
|
|
|
|
|
|
|
|
|
lemma dist_succ {i j : nat} : dist (succ i) (succ j) = dist i j :=
|
|
|
|
|
by rewrite [↑dist, *succ_sub_succ]
|
|
|
|
|
|
|
|
|
|
lemma dist_le_max {i j : nat} : dist i j ≤ max i j :=
|
|
|
|
|
begin rewrite dist_eq_max_sub_min, apply sub_le end
|
|
|
|
|
|
|
|
|
|
lemma dist_pos_of_ne {i j : nat} : i ≠ j → dist i j > 0 :=
|
|
|
|
|
assume Pne, lt.by_cases
|
|
|
|
|
(suppose i < j, begin rewrite [dist_eq_sub_of_lt this], apply sub_pos_of_lt this end)
|
|
|
|
|
(suppose i = j, by contradiction)
|
|
|
|
|
(suppose i > j, begin rewrite [dist_eq_sub_of_gt this], apply sub_pos_of_lt this end)
|
|
|
|
|
|
2014-08-20 02:32:44 +00:00
|
|
|
|
end nat
|