# 2020-01-17 `FinVec` ``` module FinVec where open import Data.Product open import Data.Nat using ( ℕ ; zero ; suc ; _<_ ; z≤n ; s≤s ) open import Function using ( _∘_ ) open import Relation.Binary.PropositionalEquality using ( _≡_ ; refl ; cong ) ``` ## Prototypical Finite Types: `Fin` The type `Fin n` can be seen as an inductive implementation of the set of all natural numbers less than `n`. Informally: Fin 0 = {} Fin 1 = { 0 } Fin 2 = { 0 , 1 } ``` data Fin : ℕ → Set where zero : {n : ℕ} → Fin (suc n) suc : {n : ℕ} → Fin n → Fin (suc n) ``` suc (zero : Fin 1) : Fin 2 ``` toℕ : {n : ℕ} → Fin n → ℕ toℕ zero = 0 toℕ (suc i) = suc (toℕ i) ``` For each `n`, the function `toℕ {n}` is injective: ``` suc-injective : {m n : ℕ} → ℕ.suc m ≡ suc n → m ≡ n suc-injective = {!!} toℕ-injective : {n : ℕ} {i j : Fin n} → toℕ i ≡ toℕ j → i ≡ j toℕ-injective = {!!} ``` But since `toℕ {n}` is not surjective, we cannot define a full inverse: fromℕ : {n : ℕ} → (m : ℕ) → Fin n -- cannot be injective because of pigeon-hole toℕ-fromℕ : {n : ℕ} (m : ℕ) → toℕ (fromℕ m) ≡ m -- cannot be made to hold Since the range of the function `toℕ {n}` contains exactly the natural numbers that are smaller than `n`, the restriction to these makes it possible to define an inverse function for `toℕ {n}`: ``` fromℕ : {n : ℕ} → (m : ℕ) → m < n → Fin n fromℕ = {!!} ``` If we defined this correctly, we can now show the inverse properties: ``` toℕ-bound : {n : ℕ} (i : Fin n) → toℕ i < n toℕ-bound = {!!} fromℕ-toℕ : {n : ℕ} (i : Fin n) → fromℕ (toℕ i) {!!} ≡ i fromℕ-toℕ = {!!} toℕ-fromℕ : {n : ℕ} (m : ℕ) (m