module Homotopy.Space.Rose where

Roses🔗

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  base

The 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

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.unit

In 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ˡ x

To 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.
    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
    }