Martin Escardo, July 2026.

The free egroup on a setoid, in pure MLTT.

EGroups.FreeOnType constructs the free egroup on a *type* A of
generators (with the identity type as the equality of
generators). Here we construct the free egroup on a *setoid* ๐”ธ, which
is the correct free-forgetful adjunction: the underlying-setoid
functor egroups โ†’ Setoids has a left adjoint.

The construction reuses the word-level free-group construction on the
underlying type โˆฃ ๐”ธ โˆฃ, imported from Groups.Free, but coarsens its
equivalence relation _โˆฟ_ so as to additionally identify generators
that are related in ๐”ธ. Explicitly, the equivalence relation _โ‰_ on
words is generated by _โˆฟ_ (cancellation of formal inverses) together
with the pointwise, letter-by-letter relation _โ‰‹_ coming from ๐”ธ.

For simplicity we take the equivalence relation of ๐”ธ to live in the
same universe as its carrier.

TODO. Generalize this, if it is worth for any particular application.

\begin{code}

{-# OPTIONS --safe --without-K #-}

module EGroups.FreeOnSetoid where

open import MLTT.Spartan
open import MLTT.List renaming (_โˆท_ to _โ€ข_ ; _++_ to _โ—ฆ_ ; ++-assoc to โ—ฆ-assoc)

open import Groups.Free using (module free-group-construction)
open import EGroups.Setoid
open import EGroups.Type
open import EGroups.MediatingMap

module _ (๐”ธ : Setoid ๐“ค ๐“ค) where

 open free-group-construction โˆฃ ๐”ธ โˆฃ

\end{code}

The pointwise, letter-by-letter relation on words: two words are
_โ‰‹_-related when they have the same length, the same polarities, and
_โ‰ˆโŸฆ ๐”ธ โŸง_-related generators.

\begin{code}

 _โ‰‹_ : FA โ†’ FA โ†’ ๐“ค ฬ‡
 []            โ‰‹ []            = ๐Ÿ™
 []            โ‰‹ (_ โ€ข _)       = ๐Ÿ˜
 (_ โ€ข _)       โ‰‹ []            = ๐Ÿ˜
 ((n , a) โ€ข s) โ‰‹ ((m , b) โ€ข t) = (n ๏ผ m) ร— (a โ‰ˆโŸฆ ๐”ธ โŸง b) ร— (s โ‰‹ t)

 โ‰‹-refl : (s : FA) โ†’ s โ‰‹ s
 โ‰‹-refl []            = โ‹†
 โ‰‹-refl ((n , a) โ€ข s) = refl , setoid-refl ๐”ธ a , โ‰‹-refl s

 โ‰‹-sym : (s t : FA) โ†’ s โ‰‹ t โ†’ t โ‰‹ s
 โ‰‹-sym []            []            _           = โ‹†
 โ‰‹-sym []            (x โ€ข t)       ()
 โ‰‹-sym (x โ€ข s)       []            ()
 โ‰‹-sym ((n , a) โ€ข s) ((m , b) โ€ข t) (p , q , r) =
  (p โปยน) , setoid-sym ๐”ธ a b q , โ‰‹-sym s t r

 โ‰‹-trans : (s t u : FA) โ†’ s โ‰‹ t โ†’ t โ‰‹ u โ†’ s โ‰‹ u
 โ‰‹-trans []            []            []            _           _             = โ‹†
 โ‰‹-trans []            []            (x โ€ข u)       _           ()
 โ‰‹-trans []            (x โ€ข t)       u             ()          _
 โ‰‹-trans (x โ€ข s)       []            u             ()          _
 โ‰‹-trans ((n , a) โ€ข s) ((m , b) โ€ข t) []            _           ()
 โ‰‹-trans ((n , a) โ€ข s) ((m , b) โ€ข t) ((k , c) โ€ข u) (p , q , r) (p' , q' , r') =
  (p โˆ™ p') , setoid-trans ๐”ธ a b c q q' , โ‰‹-trans s t u r r'

 โ‰‹-โ—ฆ : (s s' t t' : FA) โ†’ s โ‰‹ s' โ†’ t โ‰‹ t' โ†’ (s โ—ฆ t) โ‰‹ (s' โ—ฆ t')
 โ‰‹-โ—ฆ []            []            t t' _           e = e
 โ‰‹-โ—ฆ []            (x โ€ข s')      t t' ()          e
 โ‰‹-โ—ฆ (x โ€ข s)       []            t t' ()          e
 โ‰‹-โ—ฆ ((n , a) โ€ข s) ((m , b) โ€ข s') t t' (p , q , r) e =
  p , q , โ‰‹-โ—ฆ s s' t t' r e

 ฮท-โ‰‹ : {a b : โˆฃ ๐”ธ โˆฃ} โ†’ a โ‰ˆโŸฆ ๐”ธ โŸง b โ†’ ฮท a โ‰‹ ฮท b
 ฮท-โ‰‹ q = refl , q , โ‹†

\end{code}

The equivalence relation _โ‰_ on words, generated by _โˆฟ_ and _โ‰‹_.

\begin{code}

 data _โ‰_ : FA โ†’ FA โ†’ ๐“ค ฬ‡ where
  โˆฟ-gives-โ‰ : {s t : FA} โ†’ s โˆฟ t โ†’ s โ‰ t
  โ‰‹-gives-โ‰ : {s t : FA} โ†’ s โ‰‹ t โ†’ s โ‰ t
  โ‰-trans   : {s t u : FA} โ†’ s โ‰ t โ†’ t โ‰ u โ†’ s โ‰ u

 infix 0 _โ‰_

 โ‰-refl : (s : FA) โ†’ s โ‰ s
 โ‰-refl s = โˆฟ-gives-โ‰ (srt-reflexive _โ–ท_ s)

 โ‰-sym : (s t : FA) โ†’ s โ‰ t โ†’ t โ‰ s
 โ‰-sym s t (โˆฟ-gives-โ‰ p) = โˆฟ-gives-โ‰ (srt-symmetric _โ–ท_ s t p)
 โ‰-sym s t (โ‰‹-gives-โ‰ p) = โ‰‹-gives-โ‰ (โ‰‹-sym s t p)
 โ‰-sym s t (โ‰-trans p q) = โ‰-trans (โ‰-sym _ t q) (โ‰-sym s _ p)

 ๏ผ-gives-โ‰ : {s t : FA} โ†’ s ๏ผ t โ†’ s โ‰ t
 ๏ผ-gives-โ‰ {s} refl = โ‰-refl s

 โ—ฆ-left-โ‰ : (s s' t : FA) โ†’ s โ‰ s' โ†’ s โ—ฆ t โ‰ s' โ—ฆ t
 โ—ฆ-left-โ‰ s s' t (โˆฟ-gives-โ‰ p) = โˆฟ-gives-โ‰ (โ—ฆ-cong-โˆฟ p (srt-reflexive _โ–ท_ t))
 โ—ฆ-left-โ‰ s s' t (โ‰‹-gives-โ‰ p) = โ‰‹-gives-โ‰ (โ‰‹-โ—ฆ s s' t t p (โ‰‹-refl t))
 โ—ฆ-left-โ‰ s s' t (โ‰-trans {s} {u} {s'} p q) =
  โ‰-trans (โ—ฆ-left-โ‰ s u t p) (โ—ฆ-left-โ‰ u s' t q)

 โ—ฆ-right-โ‰ : (s t t' : FA) โ†’ t โ‰ t' โ†’ s โ—ฆ t โ‰ s โ—ฆ t'
 โ—ฆ-right-โ‰ s t t' (โˆฟ-gives-โ‰ p) = โˆฟ-gives-โ‰ (โ—ฆ-cong-โˆฟ (srt-reflexive _โ–ท_ s) p)
 โ—ฆ-right-โ‰ s t t' (โ‰‹-gives-โ‰ p) = โ‰‹-gives-โ‰ (โ‰‹-โ—ฆ s s t t' (โ‰‹-refl s) p)
 โ—ฆ-right-โ‰ s t t' (โ‰-trans {t} {u} {t'} p q) =
  โ‰-trans (โ—ฆ-right-โ‰ s t u p) (โ—ฆ-right-โ‰ s u t' q)

 โ—ฆ-cong-โ‰ : {s s' t t' : FA} โ†’ s โ‰ s' โ†’ t โ‰ t' โ†’ s โ—ฆ t โ‰ s' โ—ฆ t'
 โ—ฆ-cong-โ‰ {s} {s'} {t} {t'} d e =
  โ‰-trans (โ—ฆ-left-โ‰ s s' t d) (โ—ฆ-right-โ‰ s' t t' e)

\end{code}

The free egroup on the setoid ๐”ธ: words with the operation of concatenation,
the empty word as unit, and finv as inverse, all up to _โ‰_.

\begin{code}

 free-egroup-setoid : EGroup ๐“ค ๐“ค
 free-egroup-setoid =
    (FA , _โ‰_ , (โ‰-refl , โ‰-sym , (ฮป x y z โ†’ โ‰-trans {x} {y} {z})))
  , _โ—ฆ_
  , ( โ—ฆ-cong-โ‰
    , (ฮป s t u โ†’ ๏ผ-gives-โ‰ (โ—ฆ-assoc s t u))
    , ( []
      , (ฮป s โ†’ โ‰-refl s)
      , (ฮป s โ†’ ๏ผ-gives-โ‰ (([]-right-neutral s) โปยน))
      , (ฮป s โ†’ finv s , โˆฟ-gives-โ‰ (finv-left-โˆฟ s) , โˆฟ-gives-โ‰ (finv-right-โˆฟ s)) ) )

\end{code}

The universal property. Given a target egroup ๐“– and a setoid map
f : ๐”ธ โ†’ underlying-setoid ๐“–, the extension is the mediating map h of
EGroups.MediatingMap, which respects _โ‰_ because f respects the relation of ๐”ธ.

\begin{code}

 module universal-property
          (๐“– : EGroup ๐“ฅ ๐“ฆ)
          (f : โˆฃ ๐”ธ โˆฃ โ†’ โŸจ ๐“– โŸฉ)
          (f-resp : is-setoid-map ๐”ธ (underlying-setoid ๐“–) f)
        where

  open E-group-theory ๐“–
  open โ‰ˆ-reasoning (underlying-relation ๐“–) (E-refl ๐“–) (E-trans ๐“–)
  open free-group-mediating-map โˆฃ ๐”ธ โˆฃ โŸจ ๐“– โŸฉ (underlying-relation ๐“–)
        (E-refl ๐“–) (E-sym ๐“–) (E-trans ๐“–)
        (E-multiplication ๐“–) (E-is-congruence ๐“–) (E-assoc ๐“–)
        (E-unit ๐“–) (E-unit-left ๐“–) (E-unit-right ๐“–)
        (E-inv ๐“–) (E-inv-left ๐“–) (E-inv-right ๐“–)
        f

  h-resp-โ‰‹ : (s t : FA) โ†’ s โ‰‹ t โ†’ h s โ‰ˆโŸจ ๐“– โŸฉ h t
  h-resp-โ‰‹ []            []            _           = E-refl ๐“– (h [])
  h-resp-โ‰‹ []            (x โ€ข t)       ()
  h-resp-โ‰‹ (x โ€ข s)       []            ()
  h-resp-โ‰‹ ((โ‚€ , a) โ€ข s) ((โ‚€ , b) โ€ข t) (refl , q , r) =
   E-is-congruence ๐“– (f-resp q) (h-resp-โ‰‹ s t r)
  h-resp-โ‰‹ ((โ‚ , a) โ€ข s) ((โ‚ , b) โ€ข t) (refl , q , r) =
   E-is-congruence ๐“– (โ‰ˆ-inv-cong (f a) (f b) (f-resp q)) (h-resp-โ‰‹ s t r)
  h-resp-โ‰‹ ((โ‚€ , a) โ€ข s) ((โ‚ , b) โ€ข t) (() , q , r)
  h-resp-โ‰‹ ((โ‚ , a) โ€ข s) ((โ‚€ , b) โ€ข t) (() , q , r)

  h-resp-โ‰ : (s t : FA) โ†’ s โ‰ t โ†’ h s โ‰ˆโŸจ ๐“– โŸฉ h t
  h-resp-โ‰ s t (โˆฟ-gives-โ‰ p)             = h-identifies-โˆฟ-related-points p
  h-resp-โ‰ s t (โ‰‹-gives-โ‰ p)             = h-resp-โ‰‹ s t p
  h-resp-โ‰ s t (โ‰-trans {s} {u} {t} p q) =
   E-trans ๐“– (h s) (h u) (h t) (h-resp-โ‰ s u p) (h-resp-โ‰ u t q)

  free-map : โŸจ free-egroup-setoid โŸฉ โ†’ โŸจ ๐“– โŸฉ
  free-map = h

  free-map-is-hom : is-hom free-egroup-setoid ๐“– free-map
  free-map-is-hom = (ฮป {x} {y} โ†’ h-resp-โ‰ x y)
                  , (ฮป {x} {y} โ†’ h-is-hom x y)

  free-map-triangle : (a : โˆฃ ๐”ธ โˆฃ) โ†’ free-map (ฮท a) โ‰ˆโŸจ ๐“– โŸฉ f a
  free-map-triangle a = E-unit-right ๐“– (f a)

  free-map-is-unique : (g : โŸจ free-egroup-setoid โŸฉ โ†’ โŸจ ๐“– โŸฉ)
                     โ†’ is-hom free-egroup-setoid ๐“– g
                     โ†’ ((a : โˆฃ ๐”ธ โˆฃ) โ†’ g (ฮท a) โ‰ˆโŸจ ๐“– โŸฉ f a)
                     โ†’ (s : โŸจ free-egroup-setoid โŸฉ) โ†’ g s โ‰ˆโŸจ ๐“– โŸฉ free-map s
  free-map-is-unique g g-hom@(_ , g-mult) g-tri = u
   where
    g-pu : g [] โ‰ˆโŸจ ๐“– โŸฉ E-unit ๐“–
    g-pu = homs-preserve-unit free-egroup-setoid ๐“– g g-hom

    g-pi : (w : FA) โ†’ g (finv w) โ‰ˆโŸจ ๐“– โŸฉ E-inv ๐“– (g w)
    g-pi w = homs-preserve-inv free-egroup-setoid ๐“– g g-hom w

    u : (s : FA) โ†’ g s โ‰ˆโŸจ ๐“– โŸฉ free-map s
    u [] = g-pu
    u ((โ‚€ , a) โ€ข s) =
     g (ฮท a โ—ฆ s)            โ‰ˆ[ g-mult {ฮท a} {s} ]
     g (ฮท a) ยทโŸจ ๐“– โŸฉ g s     โ‰ˆ[ E-is-congruence ๐“– (g-tri a) (u s) ]
     f a ยทโŸจ ๐“– โŸฉ h s         โ‰ˆโˆŽ
    u ((โ‚ , a) โ€ข s) =
     g (finv (ฮท a) โ—ฆ s)          โ‰ˆ[ g-mult {finv (ฮท a)} {s} ]
     g (finv (ฮท a)) ยทโŸจ ๐“– โŸฉ g s   โ‰ˆ[ E-is-congruence ๐“– lemma (u s) ]
     E-inv ๐“– (f a) ยทโŸจ ๐“– โŸฉ h s    โ‰ˆโˆŽ
      where
       lemma : g (finv (ฮท a)) โ‰ˆโŸจ ๐“– โŸฉ E-inv ๐“– (f a)
       lemma = g (finv (ฮท a))    โ‰ˆ[ g-pi (ฮท a) ]
               E-inv ๐“– (g (ฮท a)) โ‰ˆ[ โ‰ˆ-inv-cong (g (ฮท a)) (f a) (g-tri a) ]
               E-inv ๐“– (f a)     โ‰ˆโˆŽ

\end{code}

As an immediate corollary, two homomorphisms out of the free egroup
that both extend f agree up to the equivalence relation.

\begin{code}

  free-map-is-uniqueโ‚‚ : (gโ‚€ gโ‚ : โŸจ free-egroup-setoid โŸฉ โ†’ โŸจ ๐“– โŸฉ)
                      โ†’ is-hom free-egroup-setoid ๐“– gโ‚€
                      โ†’ is-hom free-egroup-setoid ๐“– gโ‚
                      โ†’ ((a : โˆฃ ๐”ธ โˆฃ) โ†’ gโ‚€ (ฮท a) โ‰ˆโŸจ ๐“– โŸฉ f a)
                      โ†’ ((a : โˆฃ ๐”ธ โˆฃ) โ†’ gโ‚ (ฮท a) โ‰ˆโŸจ ๐“– โŸฉ f a)
                      โ†’ (s : โŸจ free-egroup-setoid โŸฉ) โ†’ gโ‚€ s โ‰ˆโŸจ ๐“– โŸฉ gโ‚ s
  free-map-is-uniqueโ‚‚ gโ‚€ gโ‚ iโ‚€ iโ‚ tโ‚€ tโ‚ s =
   E-trans ๐“– (gโ‚€ s) (free-map s) (gโ‚ s)
    (free-map-is-unique gโ‚€ iโ‚€ tโ‚€ s)
    (E-sym ๐“– (gโ‚ s) (free-map s) (free-map-is-unique gโ‚ iโ‚ tโ‚ s))

\end{code}

The universal property as an adjunction: restriction along ฮท and
extension are mutually inverse setoid maps between the hom-setoid out of
the free egroup and the setoid of setoid maps from ๐”ธ into the underlying
setoid of the target. This is the free-forgetful adjunction between
setoids and EGroups.

\begin{code}

 free-adjunction-setoid : (๐“– : EGroup ๐“ฅ ๐“ฆ)
                        โ†’ hom-setoid free-egroup-setoid ๐“–
                        โ‰…หข setoid-map-setoid ๐”ธ (underlying-setoid ๐“–)
 free-adjunction-setoid ๐“– = record
                              { to        = to
                              ; from      = from
                              ; to-resp   = ฮป {x} {y} โ†’ to-resp {x} {y}
                              ; from-resp = ฮป {x} {y} โ†’ from-resp {x} {y}
                              ; to-from   = ฮต
                              ; from-to   = ฮธ
                              }
  where
   open universal-property ๐“–

   S = hom-setoid free-egroup-setoid ๐“–
   T = setoid-map-setoid ๐”ธ (underlying-setoid ๐“–)

   to : โˆฃ S โˆฃ โ†’ โˆฃ T โˆฃ
   to (g , g-resp , _) = (ฮป a โ†’ g (ฮท a)) ,
                         (ฮป {a} {b} q โ†’ g-resp (โ‰‹-gives-โ‰ (ฮท-โ‰‹ q)))

   from : โˆฃ T โˆฃ โ†’ โˆฃ S โˆฃ
   from (f , f-resp) = free-map f f-resp , free-map-is-hom f f-resp

   to-resp : is-setoid-map S T to
   to-resp p a = p (ฮท a)

   from-resp : is-setoid-map T S from
   from-resp {f , f-resp} {f' , f'-resp} p s =
    free-map-is-unique f' f'-resp (free-map f f-resp) (free-map-is-hom f f-resp)
     (ฮป a โ†’ E-trans ๐“– (free-map f f-resp (ฮท a)) (f a) (f' a)
             (free-map-triangle f f-resp a) (p a)) s

   ฮต : (๐•— : โˆฃ T โˆฃ) โ†’ to (from ๐•—) โ‰ˆโŸฆ T โŸง ๐•—
   ฮต (f , f-resp) a = free-map-triangle f f-resp a

   ฮธ : (u : โˆฃ S โˆฃ) โ†’ from (to u) โ‰ˆโŸฆ S โŸง u
   ฮธ u@(g , g-hom) s =
    let (tf , tf-resp) = to u
    in E-sym ๐“– (g s) (free-map tf tf-resp s)
        (free-map-is-unique tf tf-resp g g-hom (ฮป a โ†’ E-refl ๐“– (g (ฮท a))) s)

\end{code}