module Homotopy.Space.Rose whereRoses🔗
The rose with
petals
is the space described by the higher inductive type containing a single
point base and
distinct path constructors from base to base. For example, the following picture
illustrates the rose with 3 petals.
More generally, we can allow the arity to be given by an arbitrary type but for the computation of the fundamental group below, we restrict ourselves to roses with a discrete number of petals.
data Rose {ℓ} (A : Type ℓ) : Type ℓ where
base : Rose A
loop : A → base ≡ baseThe loop space of a rose🔗
When looking at the picture above, it’s easy to imagine some properties of the fundamental group of the rose with 3 petals: we can go around the space and end up back at the endpoint by taking any of the petals, and once we’re back at the basepoint, we can then walk along a different petal; and walking along different petals generates different paths.
One can imagine that a general loop on base is thus described by the list of
petals we have taken, subject to the relation that walking backwards and
then forwards along the same petal does not contribute anything to the
list. This is a combinatorial description of the free group on a discrete type, and
indeed the purpose of this section is to show that
module _ {ℓ} (A : Type ℓ) ⦃ _ : Discrete A ⦄ where
open W A
open C Free-group renaming (Cayley to rot)
module F = Group-on (Free-group .snd)The proof follows exactly the same outline as the computation of the
fundamental group of the circle: we define a type family Cover over the rose on
petals, sending the base point to the type underlying the group
and the path generated by
to the identification
generated by Cayley’s theorem. Transport along this
type family converts loops in Rose
to elements of the free group.
Cover : Rose A → Type ℓ
Cover base = ⌞ Free-group ⌟
Cover (loop x i) = ua (rot (inl x ∷ [] , one _)) i
encode : ∀ x → base ≡ x → Cover x
encode x = J (λ x p → Cover x) F.unitIn the other direction, we define by case analysis a mapping from letters to loops, and extend this to words by recursion; the letter is sent to the loop and the letter is thus sent to
loopˡ : Letter → base ≡ base
loopˡ (inl x) = loop x
loopˡ (inr x) = sym (loop x)
loopʷ : Word → base ≡ base
loopʷ [] = refl
loopʷ (x ∷ xs) = loopʷ xs ∙ loopˡ xTo write a decoding function, we have to show that this function sends the action of a letter on a word to the composition of the paths generated by and this is a simple case bash.
loop-act : (x : Letter) (w : Word) → loopʷ (act x w) ≡ loopʷ w ∙ loopˡ x
loop-act x [] = refl
loop-act x (y ∷ w) with x ≡? opp y
... | no ¬p = refl
... | yes p with x | y
... | inl a | inl b = absurd (inl≠inr p)
... | inr a | inr b = absurd (inr≠inl p)
... | inl a | inr b = sym $
(loopʷ w ∙ sym (loop b)) ∙ loop a ≡⟨ ∙-pullr (ap₂ _∙_ refl (ap loop (inl-inj p)) ∙ ∙-invl _) ⟩
loopʷ w ∙ refl ≡⟨ ∙-idr _ ⟩
loopʷ w ∎
... | inr a | inl b = sym $ ∙-pullr (ap₂ _∙_ (ap loop (inr-inj (sym p))) refl ∙ ∙-invr _) ∙ ∙-idr _This lemma extends to the coherence case of a decoding function exactly as in the case for the circle, i.e. by filling the dotted square face in the diagram
decode : ∀ x → Cover x → base ≡ x
decode base (w , _) = loopʷ w
decode (loop x i) w j = hcomp (∂ i ∨ ∂ j) λ where
k (k = i0) → loopʷ (unglue w .fst) j
k (i = i0) → ∙→square (loop-act (inl x) (w .fst)) (~ k) j
k (i = i1) → loopʷ (w .fst) j
k (j = i0) → base
k (j = i1) → loop x (i ∨ ~ k)To show that these functions are inverses at the base point, we do
some more case analysis— in one direction, this “case analysis” is path
induction, which immediately shows that decoding is inverse to encoding;
in the other, we show that transport along Cover takes composition of paths to the
corresponding operations on the group
encode-decode : ∀ x (p : base ≡ x) → decode x (encode x p) ≡ p
encode-decode x = J (λ x p → decode x (encode x p) ≡ p) refl
private
ε : base ≡ base → ⌞ Free-group ⌟ → ⌞ Free-group ⌟
ε p = subst Cover p
Really, the proof is just a case bash: we start by showing that ε takes loopˡ at
to the action of the letter
on an arbitrary word; this is by cases both on the letter and the head
of the word (if any); but it is nonrecursive.
This is then extended to entire words by recursion.
ε takes loopˡ at
to the action of the letter
on an arbitrary word; this is by cases both on the letter and the head
of the word (if any); but it is nonrecursive. encode-loopˡ
: (w : Word) (r : Reduced w) (x : Letter)
→ ε (loopˡ x) (w , r) .fst ≡ act x w
encode-loopˡ [] r (inl x) = ap (λ e → inl {B = A} e ∷ []) (transport-refl _)
encode-loopˡ [] r (inr x) = refl
encode-loopˡ (y ∷ w) r (inl x) with inl x ≡? opp y
... | yes a = transport-refl w
... | no ¬a = λ i →
inl (transp (λ _ → A) i x)
∷ transp (λ _ → A ⊎ A) i y
∷ transp (λ _ → List (A ⊎ A)) i w
encode-loopˡ (y ∷ w) r (inr x) with inr x ≡? opp y
... | yes a rewrite ≡?-yes' (a ∙ ap opp (sym (transport-refl y))) =
transport-refl _
... | no ¬a rewrite ≡?-no λ p → ¬a (p ∙ ap opp (transport-refl y)) = λ i →
inr x ∷ transp (λ i → A ⊎ A) i y ∷ transp (λ i → List (A ⊎ A)) i w
encode-loopʷ : (w : Word) (r : Reduced w) (w' : ⌞ Free-group ⌟) → ε (loopʷ w) w' .fst ≡ mul w (w' .fst)
encode-loopʷ [] r w' = transport-refl (w' .fst)
encode-loopʷ (x ∷ w) r w' =
ε (loopʷ w ∙ loopˡ x) w' .fst ≡⟨ ap fst (subst-∙ Cover (loopʷ w) (loopˡ x) w') ⟩
ε (loopˡ x) ⌜ ε (loopʷ w) w' ⌝ .fst ≡⟨ ap! (Σ-prop-path! (encode-loopʷ w (uncons-reduced r) w')) ⟩
ε (loopˡ x) (mul w (w' .fst) , mul-reduced w (w' .snd)) .fst ≡⟨ encode-loopˡ (mul w (w' .fst)) (mul-reduced w (w' .snd)) x ⟩
act x (mul w (w' .fst)) ∎As a consequence, the encoding of the word is precisely the product which is of course just this shows that encoding is inverse to decoding.
ΩBouquet : (base ≡ base) ≃ ⌞ Free-group ⌟
ΩBouquet .fst = encode base
ΩBouquet .snd = is-iso→is-equiv record
{ from = decode base
; rinv = λ x → Σ-prop-path! $
encode base (loopʷ (x .fst)) .fst ≡⟨ encode-loopʷ (x .fst) (x .snd) F.unit ⟩
(x F.⋆ F.unit) .fst ≡⟨ ap fst (F.idr {_ , x .snd}) ⟩
x .fst ∎
; linv = encode-decode base
}