{-# OPTIONS --safe #-} module Data.Fin.Properties where open import Prelude open import Data.Pushout open import Relation.Binary private variable n : ℕ import Data.Nat.Order as ℕ infix 4 _<ᵇ_ _<_ _≮ᵇ_ _≮_ _≤ᵇ_ _≤_ _<ᵇ_ : Fin n → Fin n → Bool n <ᵇ m = FinToℕ n .fst ℕ.<ᵇ FinToℕ m .fst _<_ : Fin n → Fin n → Type n < m = T (n <ᵇ m) _≮ᵇ_ : Fin n → Fin n → Bool n ≮ᵇ m = ! (n <ᵇ m) _≮_ : Fin n → Fin n → Type n ≮ m = T (n ≮ᵇ m) _≤ᵇ_ : Fin n → Fin n → Bool n ≤ᵇ m = FinToℕ n .fst ℕ.≤ᵇ FinToℕ m .fst _≤_ : Fin n → Fin n → Type n ≤ m = T (n ≤ᵇ m) suc-injective : (x y : Fin n) → suc x ≡ suc y → x ≡ y suc-injective x y = cong {A = Fin _} λ { zero → x ; (suc z) → z } foldFin : ∀ {n} → A → (Fin n → A → A) → A foldFin {n = zero} e f = e foldFin {n = suc n} e f = f zero (foldFin e (λ x a → f (suc x) a)) import Data.Nat.Properties as ℕ zero≢suc : {x : Fin n} → zero ≢ suc x zero≢suc = ℕ.zero≢suc ∘ cong (fst ∘ FinToℕ) suc≢zero : {x : Fin n} → suc x ≢ zero suc≢zero = ℕ.suc≢zero ∘ cong (fst ∘ FinToℕ) private variable m : ℕ open import Isomorphism.Properties Fin⊥ : Fin 0 ⇔ ⊥ Fin⊥ .fun () Fin⊥ .inv () Fin⊥ .rightInv () Fin⊥ .leftInv () isPropFin1 : isProp (Fin 1) isPropFin1 zero zero = refl Finsuc : Fin (suc n) ⇔ (⊤ ⊎ Fin n) Finsuc .fun zero = inl tt Finsuc .fun (suc n) = inr n Finsuc .inv (inl x) = zero Finsuc .inv (inr x) = suc x Finsuc .rightInv (inl x) = refl Finsuc .rightInv (inr x) = refl Finsuc .leftInv zero = refl Finsuc .leftInv (suc x) = refl fin-+ : (Fin n ⊎ Fin m) ⇔ Fin (n ℕ.+ m) fin-+ {n = zero} {m = m} = cong-⇔ (_⊎ Fin m) Fin⊥ ⟨ trans-⇔ ⟩ ⊎-idˡ fin-+ {n = suc n} {m = m} = cong-⇔ (_⊎ Fin m) Finsuc ⟨ trans-⇔ ⟩ ⊎-assoc ⟨ trans-⇔ ⟩ cong-⇔ (⊤ ⊎_) fin-+ ⟨ trans-⇔ ⟩ sym-⇔ Finsuc fin-× : (Fin n × Fin m) ⇔ Fin (n ℕ.* m) fin-× {n = zero } {m = m} = cong-⇔ (_× Fin m) Fin⊥ ⟨ trans-⇔ ⟩ ×-annˡ ⟨ trans-⇔ ⟩ sym-⇔ Fin⊥ fin-× {n = suc n} {m = m} = cong-⇔ (_× Fin m) Finsuc ⟨ trans-⇔ ⟩ swap-× ⟨ trans-⇔ ⟩ ×-distrib-⊎ ⟨ trans-⇔ ⟩ cong-⇔ (_⊎ (Fin m × Fin n)) (swap-× ⟨ trans-⇔ ⟩ ×-idˡ) ⟨ trans-⇔ ⟩ cong-⇔ (Fin m ⊎_) swap-× ⟨ trans-⇔ ⟩ cong-⇔ (Fin m ⊎_) (fin-× {n = n} {m = m}) ⟨ trans-⇔ ⟩ fin-+ {n = m} {m = n ℕ.* m}