open import Data.Fin hiding (_<_)
open import Data.Fin.Properties
open import Data.Nat
open import Data.Nat.Properties
open import Relation.Binary.Definitions
open import Relation.Binary.PropositionalEquality hiding ([_])
open ≡-Reasoning
open import Function
open import Data.Sum
module Eser.Fin where
finMaxOrSmaller
: {n : ℕ}
→ (x : Fin $ ℕ.suc n)
→ x ≡ fromℕ n ⊎ x Data.Fin.< fromℕ n
finMaxOrSmaller {n} x =
let x≤n : x Data.Fin.≤ fromℕ n
x≤n = ≤fromℕ x
in
let H : toℕ x ≡ toℕ (fromℕ n) ⊎ x Data.Fin.< fromℕ n
H = Data.Sum.swap $ m≤n⇒m<n∨m≡n x≤n
in
Data.Sum.map₁ toℕ-injective H
fin≤TFMax
: {n : ℕ}
→ (x : Fin $ ℕ.suc n)
→ toℕ x Data.Nat.≤ toℕ (fromℕ n)
fin≤TFMax {n} x = subst (λ y → toℕ x Data.Nat.≤ y)
(sym $ toℕ-fromℕ n)
(s≤s⁻¹ $ toℕ<n x)
toℕ-suc
: {c : ℕ}
→ (n : Fin c)
→ toℕ (Fin.suc n) ≡ ℕ.suc (toℕ n)
toℕ-suc {c} n = toℕ-↑ʳ 1 n
lower-s≤s
: {c k : ℕ}
→ (n : Fin c)
→ (h : toℕ n Data.Nat.< k)
→ Fin.suc (lower n h) ≡ lower (Fin.suc n) (s≤s h)
lower-s≤s {suc c} zero (s≤s z≤n) = refl
lower-s≤s {suc c} (suc n) (s≤s h) = refl
toℕ-lower
: {c k : ℕ}
→ (n : Fin c)
→ (h : toℕ n Data.Nat.< k)
→ toℕ (lower n h) ≡ toℕ n
toℕ-lower {suc c} {suc k'} zero (s≤s z≤n) = refl
toℕ-lower {c@(suc c')} {k@(suc k')} (suc n) h@(s≤s h') =
let TLn≡Tn : toℕ (lower n h') ≡ toℕ n
TLn≡Tn = toℕ-lower {c'} {k'} n h'
in
let STLn≡STn : suc (toℕ (lower n h')) ≡ suc (toℕ n)
STLn≡STn = cong suc TLn≡Tn
in
let STn≡STn : suc (toℕ n) ≡ toℕ (Fin.suc n)
STn≡STn = toℕ-suc n
in
let STLn≡TSLn : suc (toℕ (lower n h')) ≡ toℕ (Fin.suc (lower n h'))
STLn≡TSLn = toℕ-suc (lower n h')
in
let TSLn≡TLSn : toℕ (Fin.suc (lower n h')) ≡ toℕ (lower (suc n) h)
TSLn≡TLSn = cong toℕ (lower-s≤s n h')
in
sym(
begin
toℕ (suc n)
≡⟨ toℕ-suc n ⟩
suc (toℕ n)
≡⟨ sym STLn≡STn ⟩
suc (toℕ (lower n h'))
≡⟨ STLn≡TSLn ⟩
toℕ (Fin.suc (lower n h'))
≡⟨ TSLn≡TLSn ⟩
toℕ (lower (suc n) h)
∎)
_F+_ = Data.Fin._+_
_ℕ+_ = Data.Nat._+_
toℕ-suc-+
: {c : ℕ}
→ (x y : Fin (ℕ.suc c))
→ toℕ (Fin.suc (x F+ y)) ≡ toℕ ( Fin.suc x F+ y)
toℕ-suc-+ {c} x y = refl
toℕ-+-comm
: {c k : ℕ}
→ (x : Fin c)
→ (y : Fin k)
→ toℕ (x F+ y) ≡ toℕ x ℕ+ toℕ y
toℕ-+-comm {c} zero zero = refl
toℕ-+-comm {c} zero (suc y) = refl
toℕ-+-comm {ℕ.suc c} (suc x) y =
sym (
begin
toℕ (suc x) ℕ+ toℕ y
≡⟨ refl ⟩
ℕ.suc (toℕ x ℕ+ toℕ y)
≡⟨ cong ℕ.suc (sym (toℕ-+-comm x y)) ⟩
ℕ.suc (toℕ (x F+ y))
≡⟨ refl ⟩
toℕ (suc x F+ y)
∎
)
cast-suc-comm
: {c k : ℕ}
→ (x : Fin (ℕ.suc c))
→ (y : Fin k)
→ (z : toℕ x ℕ+ k ≡ ℕ.suc c)
→ (Sz : toℕ (Fin.suc x) ℕ+ k ≡ ℕ.suc (ℕ.suc c))
→ Fin.suc (cast z (x F+ y)) ≡ cast Sz (Fin.suc x F+ y)
cast-suc-comm x y z Sz =
let lemma : toℕ( Fin.suc (cast z (x F+ y))) ≡ toℕ( cast Sz (Fin.suc x F+ y))
lemma = begin
toℕ( Fin.suc (cast z (x F+ y)))
≡⟨ refl ⟩
ℕ.suc (toℕ( cast z (x F+ y)))
≡⟨ cong ℕ.suc (toℕ-cast z (x F+ y)) ⟩
ℕ.suc (toℕ( x F+ y ))
≡⟨ cong ℕ.suc (toℕ-+-comm x y) ⟩
ℕ.suc (toℕ x ℕ+ toℕ y)
≡⟨ refl ⟩
ℕ.suc (toℕ x) ℕ+ toℕ y
≡⟨ refl ⟩
toℕ (Fin.suc x) ℕ+ toℕ y
≡⟨ sym (toℕ-+-comm (Fin.suc x) y) ⟩
toℕ (Fin.suc x F+ y)
≡⟨ sym (toℕ-cast Sz (Fin.suc x F+ y)) ⟩
toℕ( cast Sz (Fin.suc x F+ y))
∎
in
toℕ-injective lemma
minus-suc : (m n : ℕ) → m Data.Nat.≤ n → ℕ.suc n ∸ m ≡ ℕ.suc (n ∸ m)
minus-suc m n z≤n = refl
minus-suc (ℕ.suc m) (ℕ.suc n) (s≤s m≤n) = minus-suc m n m≤n
castabilityTheorem
: (c : ℕ)
→ (n : Fin (ℕ.suc c))
→ toℕ n ℕ+ (ℕ.suc (c ∸ toℕ n)) ≡ ℕ.suc c
castabilityTheorem c n =
let meh : toℕ n Data.Nat.≤ ℕ.suc c
meh = Data.Fin.Properties.toℕ≤n n
in
let lemma : toℕ n Data.Nat.+ (ℕ.suc c ∸ toℕ n) ≡ ℕ.suc c
lemma = Data.Nat.Properties.m+[n∸m]≡n meh
in
let Tn≤Sc : toℕ n Data.Nat.≤ c
Tn≤Sc = s≤s⁻¹ (toℕ<n n)
in
let H : ℕ.suc c ∸ toℕ n ≡ ℕ.suc (c ∸ toℕ n)
H = (minus-suc (toℕ n) c Tn≤Sc)
in
trans (cong (λ x → toℕ n Data.Nat.+ x) (sym H)) lemma
addFinZeroCasted
: (c x : ℕ)
→ (i : Fin (ℕ.suc c))
→ (z : toℕ i ℕ+ ℕ.suc x ≡ ℕ.suc c)
→ i ≡ cast z (i F+ (Fin.zero {x}))
addFinZeroCasted c x Fin.zero refl = refl
addFinZeroCasted (ℕ.suc c) (x) (Fin.suc i) z =
let z1 : toℕ i ℕ+ (ℕ.suc (x)) ≡ ℕ.suc c
z1 = Data.Nat.Properties.suc-injective z
in
let H₁ : i ≡ cast z1 (i F+ (Fin.zero {x}))
H₁ = addFinZeroCasted c (x) i z1
in
let H₂ : Fin.suc i ≡ Fin.suc (cast z1 (i F+ Fin.zero))
H₂ = cong Fin.suc H₁
in
let H₃ : Fin.suc i ≡ (cast z (Fin.suc i F+ Fin.zero))
H₃ = trans H₂ (cast-suc-comm i Fin.zero z1 z)
in
H₃
addFinZeroCastedCanonical
: (c : ℕ)
→ (i : Fin (ℕ.suc c))
→ i ≡ cast (castabilityTheorem c i) (i F+ (Fin.zero {c ∸ toℕ i}))
addFinZeroCastedCanonical c Fin.zero = refl
addFinZeroCastedCanonical (ℕ.suc c) (Fin.suc i) =
let z1 : toℕ i ℕ+ ℕ.suc (c ∸ toℕ i) ≡ ℕ.suc c
z1 = castabilityTheorem c i
in
let z = castabilityTheorem (ℕ.suc c) (Fin.suc i)
in
let H₁ : i ≡ cast z1 (i F+ Fin.zero)
H₁ = addFinZeroCastedCanonical c i
in
let H₂ : Fin.suc i ≡ Fin.suc (cast z1 (i F+ Fin.zero))
H₂ = cong Fin.suc H₁
in
let H₃ : Fin.suc i ≡ (cast z (Fin.suc i F+ Fin.zero))
H₃ = trans H₂ (cast-suc-comm i Fin.zero z1 z)
in
H₃