{-# OPTIONS --without-K --rewriting #-} open import lib.Basics open import lib.NType2 open import lib.types.Nat open import lib.types.Subtype module lib.types.Fin where Fin : ℕ → Type₀ Fin n = Σ ℕ (_< n) instance Fin-reader : ∀ {n} → FromNat (Fin n) FromNat.in-range (Fin-reader {n}) m = m < n FromNat.read (Fin-reader {n}) m ⦃ m<n ⦄ = m , m<n Fin-S : ∀ {n} → Fin n → Fin (S n) Fin-S (n , lt) = n , ltSR lt Fin-S^ : ∀ {n} → (m : ℕ) → Fin n → Fin (m + n) Fin-S^ O <n = <n Fin-S^ (S m) <n = Fin-S (Fin-S^ m <n) Fin-S^' : ∀ {n} → (m : ℕ) → Fin n → Fin (ℕ-S^' m n) Fin-S^' O <n = <n Fin-S^' (S m) <n = Fin-S^' m (Fin-S <n) Fin-to-≠ : ∀ {n} (<n : Fin n) → fst <n ≠ n Fin-to-≠ <n = <-to-≠ (snd <n) Fin-prop : ℕ → SubtypeProp ℕ lzero Fin-prop n = ((_< n) , λ _ → <-is-prop) abstract Fin-is-set : {n : ℕ} → is-set (Fin n) Fin-is-set {n} = Subtype-level (Fin-prop n) Fin-has-dec-eq : {n : ℕ} → has-dec-eq (Fin n) Fin-has-dec-eq {n} = Subtype-has-dec-eq (Fin-prop n) ℕ-has-dec-eq private Fin-pred=-type : {n : ℕ} → Fin n → Fin n → Type₀ Fin-pred=-type (_ , ltSR _) (_ , ltS) = ⊤ Fin-pred=-type (_ , ltS) (_ , ltSR _) = ⊤ Fin-pred=-type (m , ltS) (n , ltS) = m == n :> ℕ Fin-pred=-type {S n} (m , ltSR m<n) (o , ltSR o<n) = (m , m<n) == (o , o<n) :> Fin n Fin-pred= : {n : ℕ} {x y : Fin n} → x == y → Fin-pred=-type x y Fin-pred= {x = (_ , ltS)} idp = idp Fin-pred= {x = (_ , ltSR _)} idp = idp abstract ltSR≠ltS : ∀ {m} (<m : Fin m) → Fin-S <m ≠ (m , ltS) ltSR≠ltS <m = Fin-to-≠ <m ∘ ap fst ltS≠ltSR : ∀ {m} (<m : Fin m) → (m , ltS) ≠ Fin-S <m ltS≠ltSR <m = Fin-to-≠ <m ∘ ! ∘ ap fst abstract Fin-S-is-inj : ∀ {n} → is-inj (Fin-S {n = n}) Fin-S-is-inj _ _ = Fin-pred= Fin-S-≠ : ∀ {n} {<n₀ <n₁ : Fin n} (p : <n₀ ≠ <n₁) → Fin-S <n₀ ≠ Fin-S <n₁ Fin-S-≠ {<n₀ = <n₀} {<n₁} p = p ∘ Fin-S-is-inj <n₀ <n₁ Fin-S^-≠ : ∀ {n} m {<n₀ <n₁ : Fin n} (p : <n₀ ≠ <n₁) → Fin-S^ m <n₀ ≠ Fin-S^ m <n₁ Fin-S^-≠ O p = p Fin-S^-≠ (S n) p = Fin-S-≠ (Fin-S^-≠ n p) Fin-S^'-≠ : ∀ {n} m {<n₀ <n₁ : Fin n} (p : <n₀ ≠ <n₁) → Fin-S^' m <n₀ ≠ Fin-S^' m <n₁ Fin-S^'-≠ O p = p Fin-S^'-≠ (S n) p = Fin-S^'-≠ n (Fin-S-≠ p) Fin-equiv-Empty : Fin 0 ≃ Empty Fin-equiv-Empty = equiv to from to-from from-to where to : Fin 0 → Empty to (_ , ()) from : Empty → Fin 0 from () abstract to-from : ∀ x → to (from x) == x to-from () from-to : ∀ x → from (to x) == x from-to (_ , ()) Fin-equiv-Coprod : {n : ℕ} → Fin (S n) ≃ Fin n ⊔ Unit Fin-equiv-Coprod {n} = equiv to from to-from from-to where to : Fin (S n) → Fin n ⊔ Unit to (m , ltS) = inr unit to (m , ltSR lt) = inl (m , lt) from : Fin n ⊔ Unit → Fin (S n) from (inr _) = n , ltS from (inl fin) = Fin-S fin abstract to-from : ∀ x → to (from x) == x to-from (inr _) = idp to-from (inl _) = idp from-to : ∀ x → from (to x) == x from-to (_ , ltS) = idp from-to (_ , ltSR _) = idp