feat(library/data/nat/pairing): add "elegant" pairing/unpairing function
This commit is contained in:
parent
2eb7538c96
commit
11dbcda9d2
1 changed files with 50 additions and 0 deletions
50
library/data/nat/pairing.lean
Normal file
50
library/data/nat/pairing.lean
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/-
|
||||||
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
|
Module: data.nat.pairing
|
||||||
|
Authors: Leonardo de Moura
|
||||||
|
|
||||||
|
Elegant pairing function.
|
||||||
|
-/
|
||||||
|
import data.nat.sqrt data.nat.div
|
||||||
|
open prod decidable
|
||||||
|
|
||||||
|
namespace nat
|
||||||
|
definition mkpair (a b : nat) : nat :=
|
||||||
|
if a < b then b*b + a else a*a + a + b
|
||||||
|
|
||||||
|
definition unpair (n : nat) : nat × nat :=
|
||||||
|
let s := sqrt n in
|
||||||
|
if n - s*s < s then (n - s*s, s) else (s, n - s*s - s)
|
||||||
|
|
||||||
|
theorem mkpair_unpair (n : nat) : mkpair (pr1 (unpair n)) (pr2 (unpair n)) = n :=
|
||||||
|
let s := sqrt n in
|
||||||
|
by_cases
|
||||||
|
(λ h₁ : n - s*s < s,
|
||||||
|
begin
|
||||||
|
esimp [unpair],
|
||||||
|
rewrite [if_pos h₁],
|
||||||
|
esimp [mkpair],
|
||||||
|
rewrite [if_pos h₁, add_sub_of_le (sqrt_lower n)]
|
||||||
|
end)
|
||||||
|
(λ h₂ : ¬ n - s*s < s,
|
||||||
|
have g₁ : s ≤ n - s*s, from le_of_not_lt h₂,
|
||||||
|
assert g₂ : s + s*s ≤ n - s*s + s*s, from add_le_add_right g₁ (s*s),
|
||||||
|
assert g₃ : s*s + s ≤ n, by rewrite [sub_add_cancel (sqrt_lower n) at g₂, add.comm at g₂]; exact g₂,
|
||||||
|
have l₁ : n ≤ s*s + s + s, from sqrt_upper n,
|
||||||
|
have l₂ : n - s*s ≤ s + s, from calc
|
||||||
|
n - s*s ≤ (s*s + s + s) - s*s : sub_le_sub_right l₁ (s*s)
|
||||||
|
... = (s*s + (s+s)) - s*s : by rewrite add.assoc
|
||||||
|
... = s + s : by rewrite add_sub_cancel_left,
|
||||||
|
have l₃ : n - s*s - s ≤ s, from calc
|
||||||
|
n - s*s - s ≤ (s + s) - s : sub_le_sub_right l₂ s
|
||||||
|
... = s : by rewrite add_sub_cancel_left,
|
||||||
|
assert l₄ : ¬ s < n - s*s - s, from not_lt_of_le l₃,
|
||||||
|
begin
|
||||||
|
esimp [unpair],
|
||||||
|
rewrite [if_neg h₂], esimp,
|
||||||
|
esimp [mkpair],
|
||||||
|
rewrite [if_neg l₄, sub_sub, add_sub_of_le g₃],
|
||||||
|
end)
|
||||||
|
end nat
|
Loading…
Add table
Reference in a new issue