module Data.Fin.Base where
Finite setsπ
The type is the type with exactly elements. We define it as a record type, packaging a natural number with a proof that
record Fin (n : Nat) : Type where
constructor fin
field
: Nat
lower : Irr (lower Nat.< n) β¦ bounded β¦
While the type
is a homotopy proposition, we
would like to enforce that constructions on
definitionally do not depend on the given proof. Therefore, we
have wrapped it in Irr
.
In dependent type theory, itβs common to instead define the finite
sets as an inductive family indexed over Nat
. However, in cubical type theory,
there is a good reason to avoid inductive families: they have subst
as an additional constructor,
including along constant paths. This makes the normal form of
any expression involving substitution in an indexed family, even if the
thing being transported is a constructor form, very bad.
Instead, we would like the subst
operation on Fin
to definitionally
commute with the constructors, and (if possible) to definitionally
preserve the underlying numeric value. Defining Fin
as an indexed type with an irrelevant
proof field achieves exactly this:
private
: β {m n} β m β‘ n β Fin m β Fin n
cast (fin n β¦ i β¦) = record
cast p { lower = n
; bounded = subst (n Nat.<_) p <$> i
}
_ : β {m n} {p : m β‘ n} {x : Fin m} β subst Fin p x β‘ cast p x
_ = refl
open Data.Irr using (make-irr) public
open Fin using (lower) public
pattern fzero = fin zero
We can still prove that the definition above is equivalent
to an inductive family. In particular, itβs generated by the
βconstructorsβ fzero
and fsuc
.
_ : β {n} β Fin (suc n)
_ = fzero
: β {n} β Fin n β Fin (suc n)
fsuc (fin n β¦ x β¦) = fin (suc n) β¦ Nat.sβ€s <$> x β¦ fsuc
: β (n : Nat) β Fin (suc n)
from-nat = fzero
from-nat zero (suc n) = fsuc (from-nat n)
from-nat
module _ {m n : Nat} (p : m β‘ n) (x : Fin m) where
_ : subst (Fin β suc) p (fsuc x) β‘ fsuc (subst Fin p x)
_ = refl
_ : subst (Fin β suc) p fzero β‘ fzero
_ = refl
Viewing elements of a finite setπ
Agda has good support, through the with
abstraction,
to pretend that a type is inductively generated. We therefore expose a
type Fin-view
which allows us to
discriminate on whether an element of
is fzero
or fsuc
.
data Fin-view : {n : Nat} β Fin n β Type where
: β {n} β Fin-view {suc n} fzero
zero : β {n} (i : Fin n) β Fin-view {suc n} (fsuc i) suc
Of course, this family has a section, expressing that any finite number is generated by one of the two βconstructorsβ.
: β {n} (i : Fin n) β Fin-view i
fin-view {suc n} fzero = zero
fin-view {suc n} (fin (suc i) β¦ b β¦) = suc (fin i β¦ Nat.β€-peel <$> b β¦)
fin-view
{zero} (fin _ β¦ forget i β¦) = absurd (Nat.Β¬sucβ€0 i) fin-view
As a first application, we can prove that Fin 0
is
empty:
: Fin 0 β β₯
Fin-absurd with fin-view i
Fin-absurd i ... | ()
We can also define an elimination principle for the family which applies the view at βevery levelβ.
Fin-elim: β {β} (P : β {n} β Fin n β Type β)
β (β {n} β P {suc n} fzero)
β (β {i} (j : Fin i) β P j β P (fsuc j))
β β {n} (i : Fin n) β P i
with fin-view i
Fin-elim P pfzero pfsuc i ... | zero = pfzero
... | suc i = pfsuc i (Fin-elim P pfzero pfsuc i)
: β {n} {x y : Fin n} β x .lower β‘ y .lower β x β‘ y
fin-ap = apβ (Ξ» x y β fin x β¦ y β¦) p (to-pathp refl) fin-ap p
Next, we move on to one of the most useful functions for Fin
: strength
. This allows
us to (possibly) strengthen the upper bound on some
Fin n
.
: β {n} β Fin (suc n) β Fin (suc n) β Fin n
strengthen {n = zero} k with fin-view k
strengthen ... | vzero = inl fzero
{n = suc n} k with fin-view k
strengthen ... | zero = inr fzero
... | suc i = β-map fsuc fsuc (strengthen i)
On the other hand, weaken
does
the opposite: it relaxes the upper bound on some Fin n
,
allowing us to regard it as a Fin (suc n)
.
: β {n} β Fin n β Fin (suc n)
weaken with fin-view n
weaken n ... | zero = fzero
... | suc i = fsuc (weaken i)
We can also relax the upper bounds if m β€ n
.
: β {m n} β m Nat.β€ n β Fin m β Fin n
inject (fin n β¦ b β¦) = fin n β¦ (Ξ» e β Nat.β€-trans e p) <$> b β¦ inject p
Discretenessπ
Since the finite set of size is a subset of the natural numbers, which have decidable equality, it follows that also has decidable equality.
instance
: β {n} β Discrete (Fin n)
Discrete-Fin {x = x} {y} with x .lower β‘? y .lower
Discrete-Fin ... | yes p = yes (fin-ap p)
... | no Β¬p = no Ξ» p β Β¬p (ap lower p)
In particular, Hedbergβs theorem shows that is a set.
opaque: β {n} β is-set (Fin n)
Fin-is-set = Discreteβis-set Discrete-Fin
Fin-is-set
instance
: β {n k} β H-Level (Fin n) (2 + k)
H-Level-Fin = basic-instance 2 Fin-is-set H-Level-Fin
However, we can also mimic parts of the proof that Nat
itself is discrete, and obtain useful
combinators for reasoning with finite sets. For example, the zero
element in
is never equal to a successor:
: β {n k p} β Β¬ Path (Fin (suc n)) fzero (fin (suc k) β¦ p β¦)
fzeroβ fsuc = Nat.zeroβ suc (ap lower p) fzeroβ fsuc p
: β {n k p} β Β¬ Path (Fin (suc n)) (fin (suc k) β¦ p β¦) fzero
fsucβ fzero = Nat.sucβ zero (ap lower p) fsucβ fzero p
Moreover, since we can implement a βpredecessorβ operation, we get
that fsuc
is an injection.
: β {n} {i j : Fin n} β fsuc i β‘ fsuc j β i β‘ j
fsuc-inj {n = suc n} p = ap pred p where
fsuc-inj : Fin (suc (suc n)) β Fin (suc n)
pred with fin-view n
pred n ... | zero = fzero
... | suc i = i
instance
: β {n} β Number (Fin n)
Number-Fin {n} .Number.Constraint k = k Nat.< n
Number-Fin {n} .Number.fromNat k β¦ e β¦ = fin k β¦ forget e β¦
Number-Fin
open import Data.Nat.Base using (0β€x ; sβ€s') public
: β {β} {n} {P : Fin (suc n) β Type β} β P 0 β (β x β P (fsuc x)) β β x β P x
Fin-cases with fin-view n
Fin-cases p0 ps n ... | zero = p0
... | suc i = ps i
: β {β} {n} {P : Fin (suc n) β Type β} β P 0 β (β x β P (fsuc x)) β β x β P x
fin-cons = Fin-cases fin-cons
Orderingπ
Keeping with the view that Fin
represents the type of bounded natural numbers, we can re-use the
ordering on Nat
to induce an
ordering on Fin
. This means that
any lemmas about the ordering on natural numbers apply immediately to
the ordering on standard finite sets.
_β€_ : β {n} β Fin n β Fin n β Type
= i .lower Nat.β€ j .lower
i β€ j infix 7 _β€_
_<_ : β {n} β Fin n β Fin n β Type
= i .lower Nat.< j .lower
i < j infix 7 _<_
Next, we define a pair of functions squish
and skip
, which are the building blocks for
all monotone functions between Fin
. squish i
takes a
j : Fin (suc n)
to a Fin n
by mapping both
i
and i+1
to i
. Its counterpart
skip i
takes some j : Fin n
to a
Fin (suc n)
by skipping over i
instead.
: β {n} β Fin n β Fin (suc n) β Fin n
squish with fin-view n | fin-view k
squish n k ... | zero | zero = fzero
... | zero | suc j = j
... | suc i | zero = fzero
... | suc i | suc j = fsuc (squish i j)
: β {n} β Fin (suc n) β Fin n β Fin (suc n)
skip with fin-view n
skip n k ... | zero = fsuc k
... | suc i with fin-view k
... | zero = fzero
... | suc j = fsuc (skip i j)
Arithmeticπ
: β {m n} β Fin (m + n) β Fin m β Fin n
split-+ {m = zero} i = inr i
split-+ {m = suc m} k with fin-view k
split-+ ... | zero = inl fzero
... | suc i = β-map fsuc id (split-+ i)
: β {n} (i j : Fin (suc n)) β i β j β Fin n
avoid {n = n} i j iβ j with fin-view i | fin-view j
avoid ... | zero | zero = absurd (iβ j refl)
... | zero | suc j = j
{n = suc n} _ _ iβ j | suc i | zero = fzero
avoid {n = suc n} _ _ iβ j | suc i | suc j = fsuc (avoid i j (iβ j β ap fsuc))
avoid
: β {n} (m : Nat) β Fin n β Fin (m + n)
fshift = i
fshift zero i (suc m) i = fsuc (fshift m i)
fshift
: β {n} β Fin n β Fin n
opposite {n = n} i with fin-view i
opposite {n = suc n} _ | zero = from-nat n
opposite {n = suc n} _ | suc i = weaken (opposite i) opposite
Vector operationsπ
_[_β_]
: β {β} {A : Type β} {n}
β (Fin n β A) β Fin (suc n) β A
β Fin (suc n) β A
_[_β_] {n = n} p i a j with fin-view i | fin-view j
_[_β_] {n = n} Ο fzero a fzero | zero | zero = a
_[_β_] {n = n} Ο fzero a .(fsuc j) | zero | suc j = Ο j
_[_β_] {n = suc n} Ο .(fsuc i) a .fzero | suc i | zero = Ο fzero
_[_β_] {n = suc n} Ο .(fsuc i) a .(fsuc j) | suc i | suc j = ((Ο β fsuc) [ i β a ]) j
delete: β {β} {A : Type β} {n}
β (Fin (suc n) β A) β Fin (suc n)
β Fin n β A
= Ο (skip i j) delete Ο i j