module Data.Fin.Properties where
Finite sets - propertiesπ
Orderingπ
As noted in Data.Fin.Base
, weβve set up
the ordering on Fin
so that we can re-use all the proofs
about the ordering on Nat
.
However, there are still quite a few interesting things one can say
about skip
and squish
. In particular, we can
prove the simplicial identities, which characterize the
interactions between these two functions.
These lemmas might seem somewhat arbitrary and complicated, which is
true! However, they are enough to describe all the possible interactions
of skip
and squish
, which in turn are the
building blocks for every monotone function between Fin
, so itβs not that
surprising that they would be a bit of a mess!
skip-comm : β {n} (i j : Fin (suc n)) β i β€ j β β x β skip (weaken i) (skip j x) β‘ skip (fsuc j) (skip i x) skip-comm fzero j le x = refl skip-comm (fsuc i) (fsuc j) le fzero = refl skip-comm (fsuc i) (fsuc j) (Nat.sβ€s le) (fsuc x) = ap fsuc (skip-comm i j le x) drop-comm : β {n} (i j : Fin n) β i β€ j β β x β squish j (squish (weaken i) x) β‘ squish i (squish (fsuc j) x) drop-comm fzero fzero le fzero = refl drop-comm fzero fzero le (fsuc x) = refl drop-comm fzero (fsuc j) le fzero = refl drop-comm fzero (fsuc j) le (fsuc x) = refl drop-comm (fsuc i) (fsuc j) le fzero = refl drop-comm (fsuc i) (fsuc j) (Nat.sβ€s le) (fsuc x) = ap fsuc (drop-comm i j le x) squish-skip-comm : β {n} (i : Fin (suc n)) (j : Fin n) β i < fsuc j β β x β squish (fsuc j) (skip (weaken i) x) β‘ skip i (squish j x) squish-skip-comm fzero j (Nat.sβ€s p) x = refl squish-skip-comm (fsuc i) (fsuc j) (Nat.sβ€s p) fzero = refl squish-skip-comm (fsuc i) (fsuc j) (Nat.sβ€s p) (fsuc x) = ap fsuc (squish-skip-comm i j p x) squish-skip : β {n} (i j : Fin n) β i β‘ j β β x β squish j (skip (weaken j) x) β‘ x squish-skip fzero fzero p x = refl squish-skip fzero (fsuc j) p x = absurd (fzeroβ fsuc p) squish-skip (fsuc i) fzero p x = refl squish-skip (fsuc i) (fsuc j) p fzero = refl squish-skip (fsuc i) (fsuc j) p (fsuc x) = ap fsuc (squish-skip i j (fsuc-inj p) x) squish-skip-fsuc : β {n} (i : Fin (suc n)) (j : Fin n) β i β‘ fsuc j β β x β squish j (skip i x) β‘ x squish-skip-fsuc fzero fzero p x = refl squish-skip-fsuc fzero (fsuc j) p x = absurd (fzeroβ fsuc p) squish-skip-fsuc (fsuc i) fzero p fzero = refl squish-skip-fsuc (fsuc fzero) fzero p (fsuc x) = refl squish-skip-fsuc (fsuc (fsuc i)) fzero p (fsuc x) = absurd (fzeroβ fsuc (fsuc-inj (sym p))) squish-skip-fsuc (fsuc i) (fsuc j) p fzero = refl squish-skip-fsuc (fsuc i) (fsuc j) p (fsuc x) = ap fsuc (squish-skip-fsuc i j (fsuc-inj p) x) Fin-peel : β {l k} β Fin (suc l) β Fin (suc k) β Fin l β Fin k Fin-peel {l} {k} slβsk = (IsoβEquiv (lβk , (iso kβl bβaβb aβbβa))) where skβsl : Fin (suc k) β Fin (suc l) skβsl = slβsk eβ»ΒΉ module slβsk = Equiv slβsk module skβsl = Equiv skβsl lβk : Fin l β Fin k lβk x with inspect (slβsk.to (fsuc x)) ... | fsuc y , _ = y ... | fzero , p with inspect (slβsk.to fzero) ... | fsuc y , _ = y ... | fzero , q = absurd (fzeroβ fsuc (slβsk.injectiveβ q p)) kβl : Fin k β Fin l kβl x with inspect (skβsl.to (fsuc x)) ... | fsuc x , _ = x ... | fzero , p with inspect (skβsl.to fzero) ... | fsuc y , _ = y ... | fzero , q = absurd (fzeroβ fsuc (skβsl.injectiveβ q p)) absurd-path : β {β} {A : Type β} {y : A} .{x : β₯} β absurd x β‘ y absurd-path {x = ()} aβbβa : β a β kβl (lβk a) β‘ a aβbβa a with inspect (slβsk.to (fsuc a)) aβbβa a | fsuc x , p' with inspect (skβsl.to (fsuc x)) aβbβa a | fsuc x , p' | fsuc y , q' = fsuc-inj ( sym q' β ap (skβsl.to) (sym p') β slβsk.Ξ· _) aβbβa a | fsuc x , p' | fzero , q' = absurd contra where r = slβsk.injectiveβ p' (slβsk.Ξ΅ (fsuc x)) contra = fzeroβ fsuc (sym (r β q')) aβbβa a | fzero , p' with inspect (slβsk.to fzero) aβbβa a | fzero , p' | fsuc x , q' with inspect (skβsl.to (fsuc x)) aβbβa a | fzero , p' | fsuc x , q' | fsuc y , r' = absurd do fzeroβ fsuc (sym (sym r' β ap skβsl.to (sym q') β slβsk.Ξ· fzero)) aβbβa a | fzero , p' | fsuc x , q' | fzero , r' with inspect (skβsl.to fzero) aβbβa a | fzero , p' | fsuc x , q' | fzero , r' | fsuc z , s = fsuc-inj $ sym s β ap skβsl.to (sym p') β slβsk.Ξ· (fsuc a) aβbβa a | fzero , p' | fsuc x , q' | fzero , r' | fzero , s = absurd-path aβbβa a | fzero , p' | fzero , q' = absurd (fzeroβ fsuc $ slβsk.injectiveβ q' p') bβaβb : β b β lβk (kβl b) β‘ b bβaβb b with inspect (skβsl.to (fsuc b)) bβaβb b | fsuc x , p' with inspect (slβsk.to (fsuc x)) bβaβb b | fsuc x , p' | fsuc y , q' = fsuc-inj $ sym q' β ap (slβsk.to) (sym p') β skβsl.Ξ· _ bβaβb b | fsuc x , p' | fzero , q' = absurd contra where r = skβsl.injectiveβ p' (skβsl.Ξ΅ (fsuc x)) contra = fzeroβ fsuc (sym (r β q')) bβaβb b | fzero , p' with inspect (skβsl.to fzero) bβaβb b | fzero , p' | fsuc x , q' with inspect (slβsk.to (fsuc x)) bβaβb b | fzero , p' | fsuc x , q' | fsuc y , r' = absurd (fzeroβ fsuc $ sym (sym r' β ap (slβsk.to) (sym q') β skβsl.Ξ· _)) bβaβb b | fzero , p' | fsuc x , q' | fzero , r' with inspect (slβsk.to fzero) bβaβb a | fzero , p' | fsuc x , q' | fzero , r' | fsuc z , s = fsuc-inj $ sym s β ap (slβsk.to) (sym p') β skβsl.Ξ· (fsuc a) bβaβb a | fzero , p' | fsuc x , q' | fzero , r' | fzero , s = absurd-path bβaβb b | fzero , p' | fzero , q' = absurd (fzeroβ fsuc $ skβsl.injectiveβ q' p') Fin-injective : β {l k} β Fin l β Fin k β l β‘ k Fin-injective {zero} {zero} lβk = refl Fin-injective {zero} {suc k} lβk with equivβinverse (lβk .snd) fzero ... | () Fin-injective {suc l} {zero} lβk with lβk .fst fzero ... | () Fin-injective {suc l} {suc k} slβsk = ap suc $ Fin-injective (Fin-peel slβsk) to-from-β< : β {n} (x : β< n) β to-β< {n = n} (from-β< x) β‘ x to-from-β< {n = suc n} x = Ξ£-prop-path! (to-from-β {n = suc n} x) where to-from-β : β {n} x β to-nat {n = n} (from-β< x) β‘ x .fst to-from-β {n = suc n} (zero , p) = refl to-from-β {n = suc n} (suc x , Nat.sβ€s p) = ap suc (to-from-β {n = n} (x , p)) from-to-β< : β {n} (x : Fin n) β from-β< (to-β< x) β‘ x from-to-β< fzero = refl from-to-β< (fsuc x) = ap fsuc (from-to-β< x) Finββ< : β {n} β Fin n β β< n Finββ< {n} = to-β< , is-isoβis-equiv (iso from-β< (to-from-β< {n}) from-to-β<) avoid-injective : β {n} (i : Fin (suc n)) {j k : Fin (suc n)} {iβ j : i β j} {iβ k : i β k} β avoid i j iβ j β‘ avoid i k iβ k β j β‘ k avoid-injective fzero {fzero} {k} {iβ j} p = absurd (iβ j refl) avoid-injective fzero {fsuc j} {fzero} {iβ k = iβ k} p = absurd (iβ k refl) avoid-injective {suc n} fzero {fsuc j} {fsuc k} p = ap fsuc p avoid-injective {suc n} (fsuc i) {fzero} {fzero} p = refl avoid-injective {suc n} (fsuc i) {fzero} {fsuc k} p = absurd (fzeroβ fsuc p) avoid-injective {suc n} (fsuc i) {fsuc j} {fzero} p = absurd (fzeroβ fsuc (sym p)) avoid-injective {suc n} (fsuc i) {fsuc j} {fsuc k} p = ap fsuc (avoid-injective {n} i {j} {k} (fsuc-inj p)) skip-injective : β {n} (i : Fin (suc n)) (j k : Fin n) β skip i j β‘ skip i k β j β‘ k skip-injective fzero j k p = fsuc-inj p skip-injective (fsuc i) fzero fzero p = refl skip-injective (fsuc i) fzero (fsuc k) p = absurd (fzeroβ fsuc p) skip-injective (fsuc i) (fsuc j) fzero p = absurd (fzeroβ fsuc (sym p)) skip-injective (fsuc i) (fsuc j) (fsuc k) p = ap fsuc (skip-injective i j k (fsuc-inj p)) skip-skips : β {n} (i : Fin (suc n)) (j : Fin n) β skip i j β i skip-skips fzero j p = fzeroβ fsuc (sym p) skip-skips (fsuc i) fzero p = fzeroβ fsuc p skip-skips (fsuc i) (fsuc j) p = skip-skips i j (fsuc-inj p) avoid-skip : β {n} (i : Fin (suc n)) (j : Fin n) {neq : i β skip i j} β avoid i (skip i j) neq β‘ j avoid-skip fzero fzero = refl avoid-skip fzero (fsuc j) = refl avoid-skip (fsuc i) fzero = refl avoid-skip (fsuc i) (fsuc j) = ap fsuc (avoid-skip i j) skip-avoid : β {n} (i : Fin (suc n)) (j : Fin (suc n)) {iβ j : i β j} β skip i (avoid i j iβ j) β‘ j skip-avoid fzero fzero {iβ j} = absurd (iβ j refl) skip-avoid {suc n} fzero (fsuc j) = refl skip-avoid {suc n} (fsuc i) fzero = refl skip-avoid {suc n} (fsuc i) (fsuc j) = ap fsuc (skip-avoid i j)
Iterated products and sumsπ
We can break down and over finite sets as iterated products and sums, respectively.
Fin-suc-Ξ : β {β} {n} {A : Fin (suc n) β Type β} β (β x β A x) β (A fzero Γ (β x β A (fsuc x))) Fin-suc-Ξ = IsoβEquiv Ξ» where .fst f β f fzero , (Ξ» x β f (fsuc x)) .snd .is-iso.inv (z , s) β fin-cons z s .snd .is-iso.rinv x β refl .snd .is-iso.linv k i fzero β k fzero .snd .is-iso.linv k i (fsuc n) β k (fsuc n) Fin-suc-Ξ£ : β {β} {n} {A : Fin (suc n) β Type β} β Ξ£ (Fin (suc n)) A β (A fzero β Ξ£ (Fin n) (A β fsuc)) Fin-suc-Ξ£ = IsoβEquiv Ξ» where .fst (fzero , a) β inl a .fst (fsuc x , a) β inr (x , a) .snd .is-iso.inv (inl a) β fzero , a .snd .is-iso.inv (inr (x , a)) β fsuc x , a .snd .is-iso.rinv (inl _) β refl .snd .is-iso.rinv (inr _) β refl .snd .is-iso.linv (fzero , a) β refl .snd .is-iso.linv (fsuc x , a) β refl
Finite choiceπ
An important fact about the (standard) finite sets in
constructive mathematics is that they always support choice,
which we phrase below as a βsearchβ operator: if
is any Monoidal
functor on types, then
it commutes with products. Since
over
are
iterated
products, we have that
commutes with
Fin-Monoidal : β {β} n {A : Fin n β Type β} {M} (let module M = Effect M) β β¦ Monoidal M β¦ β (β x β M.β (A x)) β M.β (β x β A x) Fin-Monoidal zero _ = invmap (Ξ» _ ()) _ munit Fin-Monoidal (suc n) k = Fin-suc-Ξ eβ»ΒΉ <β> (k 0 <,> Fin-Monoidal n (k β fsuc))
In particular, instantiating
with the propositional
truncation (which is an Idiom
and hence Monoidal
), we get a version of
the axiom of
choice for finite sets.
finite-choice : β {β} n {A : Fin n β Type β} β (β x β β₯ A x β₯) β β₯ (β x β A x) β₯ finite-choice n = Fin-Monoidal n
An immediate consequence is that surjections into a finite set (thus, between finite sets) merely split:
finite-surjection-split : β {β} {n} {B : Type β} β (f : B β Fin n) β is-surjective f β β₯ (β x β fibre f x) β₯ finite-surjection-split f = finite-choice _
Dually, we have that any Alternative
functor
commutes with
on finite sets, since those are iterated sums.
Fin-Alternative : β {β} n {A : Fin n β Type β} {M} (let module M = Effect M) β β¦ Alternative M β¦ β (β x β M.β (A x)) β M.β (Ξ£ (Fin n) A) Fin-Alternative zero _ = invmap (Ξ» ()) (Ξ» ()) empty Fin-Alternative (suc n) k = Fin-suc-Ξ£ eβ»ΒΉ <β> (k 0 <+> Fin-Alternative n (k β fsuc))
As a consequence, instantiating
with Dec
, we get that finite sets
are exhaustible and omniscient, which
means that any family of decidable types indexed by a finite sets yields
decidable
and
respectively.
instance Dec-Fin-β : β {n β} {A : Fin n β Type β} β β¦ β {x} β Dec (A x) β¦ β Dec (β x β A x) Dec-Fin-β {n} β¦ d β¦ = Fin-Monoidal n (Ξ» _ β d) Dec-Fin-Ξ£ : β {n β} {A : Fin n β Type β} β β¦ β {x} β Dec (A x) β¦ β Dec (Ξ£ (Fin n) A) Dec-Fin-Ξ£ {n} β¦ d β¦ = Fin-Alternative n Ξ» _ β d
Fin-omniscience : β {n β} (P : Fin n β Type β) β¦ _ : β {x} β Dec (P x) β¦ β (Ξ£[ j β Fin n ] P j Γ β k β P k β j β€ k) β (β x β Β¬ P x) Fin-omniscience {zero} P = inr Ξ» () Fin-omniscience {suc n} P with holds? (P 0) ... | yes here = inl (0 , here , Ξ» _ _ β 0β€x) ... | no Β¬here with Fin-omniscience (P β fsuc) ... | inl (ix , pix , least) = inl (fsuc ix , pix , fin-cons (Ξ» here β absurd (Β¬here here)) Ξ» i pi β Nat.sβ€s (least i pi)) ... | inr nowhere = inr (fin-cons Β¬here nowhere)
Fin-omniscience-neg : β {n β} (P : Fin n β Type β) β¦ _ : β {x} β Dec (P x) β¦ β (β x β P x) β (Ξ£[ j β Fin n ] Β¬ P j Γ β k β Β¬ P k β j β€ k) Fin-omniscience-neg P with Fin-omniscience (Β¬_ β P) ... | inr p = inl Ξ» i β decβdne (p i) ... | inl (j , Β¬pj , least) = inr (j , Β¬pj , least) Fin-find : β {n β} {P : Fin n β Type β} β¦ _ : β {x} β Dec (P x) β¦ β Β¬ (β x β P x) β Ξ£[ x β Fin n ] Β¬ P x Γ β y β Β¬ P y β x β€ y Fin-find {P = P} Β¬p with Fin-omniscience-neg P ... | inl p = absurd (Β¬p p) ... | inr p = p
Injections and surjectionsπ
The standard finite sets are Dedekind-finite, which means that every injection is a bijection. We prove this by a straightforward but annoying induction on
Fin-injectionβequiv : β {n} (f : Fin n β Fin n) β injective f β is-equiv f Fin-injectionβequiv {zero} f inj .is-eqv () Fin-injectionβequiv {suc n} f inj .is-eqv i with f 0 β‘? i ... | yes p = contr (0 , p) Ξ» (j , p') β Ξ£-prop-path! (inj (p β sym p')) ... | no Β¬p = contr (fsuc (rec .centre .fst) , avoid-injective (f 0) (rec .centre .snd)) Ξ» where (fzero , p) β absurd (Β¬p p) (fsuc j , p) β Ξ£-prop-path! (ap (fsuc β fst) (rec .paths (j , apβ (avoid (f 0)) p prop!))) where rec = Fin-injectionβequiv {n} (Ξ» x β avoid (f 0) (f (fsuc x)) (fzeroβ fsuc β inj)) (Ξ» p β fsuc-inj (inj (avoid-injective (f 0) p))) .is-eqv (avoid (f 0) i Β¬p)
Since every surjection between finite sets splits, any surjection has an injective right inverse, which is thus a bijection; by general properties of equivalences, this implies that is also a bijection.
Fin-surjectionβequiv : β {n} (f : Fin n β Fin n) β is-surjective f β is-equiv f Fin-surjectionβequiv f surj = case finite-surjection-split f surj of Ξ» split β left-inverseβequiv (snd β split) (Fin-injectionβequiv (fst β split) (right-inverseβinjective f (snd β split)))
Vector operationsπ
avoid-insert : β {n} {β} {A : Type β} β (Ο : Fin n β A) β (i : Fin (suc n)) (a : A) β (j : Fin (suc n)) β (iβ j : i β j) β (Ο [ i β a ]) j β‘ Ο (avoid i j iβ j) avoid-insert {n = n} Ο fzero a fzero iβ j = absurd (iβ j refl) avoid-insert {n = suc n} Ο fzero a (fsuc j) iβ j = refl avoid-insert {n = suc n} Ο (fsuc i) a fzero iβ j = refl avoid-insert {n = suc n} Ο (fsuc i) a (fsuc j) iβ j = avoid-insert (Ο β fsuc) i a j (iβ j β ap fsuc) insert-lookup : β {n} {β} {A : Type β} β (Ο : Fin n β A) β (i : Fin (suc n)) (a : A) β (Ο [ i β a ]) i β‘ a insert-lookup {n = n} Ο fzero a = refl insert-lookup {n = suc n} Ο (fsuc i) a = insert-lookup (Ο β fsuc) i a delete-insert : β {n} {β} {A : Type β} β (Ο : Fin n β A) β (i : Fin (suc n)) (a : A) β β j β delete (Ο [ i β a ]) i j β‘ Ο j delete-insert Ο fzero a j = refl delete-insert Ο (fsuc i) a fzero = refl delete-insert Ο (fsuc i) a (fsuc j) = delete-insert (Ο β fsuc) i a j insert-delete : β {n} {β} {A : Type β} β (Ο : Fin (suc n) β A) β (i : Fin (suc n)) (a : A) β Ο i β‘ a β β j β ((delete Ο i) [ i β a ]) j β‘ Ο j insert-delete {n = n} Ο fzero a p fzero = sym p insert-delete {n = n} Ο fzero a p (fsuc j) = refl insert-delete {n = suc n} Ο (fsuc i) a p fzero = refl insert-delete {n = suc n} Ο (fsuc i) a p (fsuc j) = insert-delete (Ο β fsuc) i a p j