Martin Escardo and Paulo Oliva, April 2024

The free discrete graphic monoid is given by the monoid of lists
without repetitions.

\begin{code}

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

open import MLTT.Spartan
open import UF.FunExt
open import UF.DiscreteAndSeparated

module DiscreteGraphicMonoids.Free
        (fe : Fun-Ext)
       where

open import MLTT.List
            renaming (_∷_ to _•_ ;          -- typed as \bub
                      _++_ to _◦_ ;         -- typed as \buw
                      ++-assoc to ◦-assoc)
open import Naturals.Order
open import Notation.CanonicalMap
open import Notation.Order
open import UF.Base
open import DiscreteGraphicMonoids.Type
open import DiscreteGraphicMonoids.ListsWithoutRepetitions fe
open import DiscreteGraphicMonoids.LWRDGM fe

\end{code}

List⁻ X is the graphic monoid freely generated by X, with
η⁻ : X → List⁻ X as the universal map, or insertion of generators.

That is,

 1. List⁻ X is a graphic monoid.

 2. There is a map η⁻ : X → List⁻ X, such that for any graphic monoid
    M and any function f : X → M, there is a unique monoid
    homomorphism f' : List⁻ → M.

       η⁻
    X ---> List⁻ X
     \       .
      \      .
       \     .
     f  \    . f⁻
         \   .
          \  .
           \ .
            v
            M


The following is an auxiliary module to prove that.

\begin{code}

module free-discrete-graphic-monoid-development
        {𝓤 𝓥 : Universe}
        (M : 𝓥 ̇ )
        {{M-is-discrete' : is-discrete' M}}
        (e : M)
        (_●_ : M  M  M)
        (●-left-unit : (x : M)  e  x  x)
        (●-right-unit : (x : M)  x  e  x)
        (●-assoc : (x y z : M)  x  (y  z)  (x  y)  z)
        (M-is-graphic : (x y : M)  (x  y)  x  x  y)
        (X : 𝓤 ̇ )
        {{X-is-discrete' : is-discrete' X}}
        (f : X  M)
       where

 M-is-discrete : is-discrete M
 M-is-discrete = discrete'-gives-discrete

 f' : List X  M
 f' []       = e
 f' (x  xs) = f x  f' xs

\end{code}

Notice that f' preserves the unit my construction.

\begin{code}

 f'-preserves-mul : (xs ys : List X)  f' (xs  ys)  f' xs  f' ys
 f'-preserves-mul [] ys =
  f' ([]  ys)  =⟨ refl 
  f' ys         =⟨ (●-left-unit (f' ys))⁻¹ 
  e  f' ys     =⟨ refl 
  f' []  f' ys 
 f'-preserves-mul (x  xs) ys =
  f' (x  xs  ys)      =⟨ refl 
  f x  f' (xs  ys)    =⟨ ap (f x ●_) (f'-preserves-mul xs ys) 
  f x  (f' xs  f' ys) =⟨ ●-assoc (f x) (f' xs) (f' ys) 
  (f x  f' xs)  f' ys =⟨ refl 
  f' (x  xs)  f' ys   

 f⁻ : List⁻ X  M
 f⁻ = f'  underlying-list

 f⁻-triangle : f⁻  η⁻  f
 f⁻-triangle x = (f⁻  η⁻) x =⟨ refl 
                 f x  e     =⟨ ●-right-unit (f x) 
                 f x         

 underlying-list-preserves-unit : ι ([]⁻ {𝓤} {X})  []
 underlying-list-preserves-unit = refl

\end{code}

The function ι : List⁻ X → List X doesn't preserve multiplication, as
this would mean that ρ (xs ◦ ys) = xs ◦ ys for any two lists with
ρ xs = xs and ρ ys = ys. However, it's composition f⁻ with f'
does. We need to use the graphic law, as this is not true in general.

\begin{code}

 ϕ : List M  M
 ϕ []       = e
 ϕ (u  us) = u  ϕ us

\end{code}

Notice that ϕ preserves the unit by construction. It also preserves
multiplication, but we don't use this fact, although we record it.

\begin{code}

 ϕ-preserves-mul : (us vs : List M)
                  ϕ (us  vs)  ϕ us  ϕ vs
 ϕ-preserves-mul [] vs =
  ϕ ([]  vs)   =⟨ refl 
  ϕ vs          =⟨ (●-left-unit (ϕ vs))⁻¹ 
  (e  ϕ vs)    =⟨ refl 
  (ϕ []  ϕ vs) 
 ϕ-preserves-mul (x  us) vs =
  ϕ (x  us  vs)   =⟨ refl 
  x  ϕ (us  vs)   =⟨ ap (x ●_) (ϕ-preserves-mul us vs) 
  x  (ϕ us  ϕ vs) =⟨ ●-assoc x (ϕ us) (ϕ vs) 
  (x  ϕ us)  ϕ vs =⟨ refl 
  ϕ (x  us)  ϕ vs 

 ϕ-map-lemma : (xs : List X)  f' xs  ϕ (map f xs)
 ϕ-map-lemma []       = refl
 ϕ-map-lemma (x  xs) = ap (f x ●_) (ϕ-map-lemma xs)

\end{code}

The following is the only, but crucial, place the graphic property of
M is used directly.

\begin{code}

 ϕ-δ-lemma' : (u v : M) (ws : List M)
             u  (v  ϕ (δ u ws))  u  (v  ϕ ws)
 ϕ-δ-lemma' u v []       = refl
 ϕ-δ-lemma' u v (w  ws) = h (M-is-discrete u w)
  where
   h : is-decidable (u  w)
      u  (v  ϕ (δ u (w  ws)))  u  (v  ϕ (w  ws))
   h (inl refl) =
    u  (v  ϕ (δ u (u  ws))) =⟨ ap  -  u  (v  ϕ -)) (δ-same u ws) 
    u  (v  ϕ (δ u ws))       =⟨ ϕ-δ-lemma' u v ws 
    u  (v  ϕ ws)             =⟨ ●-assoc u v (ϕ ws) 
    (u  v)  ϕ ws             =⟨ ap (_● ϕ ws) ((M-is-graphic u v)⁻¹) 
    ((u  v)  u)  ϕ ws       =⟨ (●-assoc (u  v) u (ϕ ws))⁻¹ 
    (u  v)  (u  ϕ ws)       =⟨ (●-assoc u v (u  ϕ ws))⁻¹ 
    u  (v  (u  ϕ ws))       =⟨ refl 
    u  (v  ϕ (u  ws))       
   h (inr ν) =
    u  (v  ϕ (δ u (w  ws))) =⟨ ap  -  u  (v  ϕ -)) (δ-≠ u w ws ν) 
    u  (v  ϕ (w  δ u ws))   =⟨ refl 
    u  (v  (w  ϕ (δ u ws))) =⟨ ap (u ●_) (●-assoc v w (ϕ (δ u ws))) 
    u  ((v  w)  ϕ (δ u ws)) =⟨ ϕ-δ-lemma' u (v  w) ws 
    u  ((v  w)  ϕ ws)       =⟨ ap (u ●_) ((●-assoc v w (ϕ ws))⁻¹) 
    u  (v  (w  ϕ ws))       =⟨ refl 
    u  (v  ϕ (w  ws))       

\end{code}

We need the following particular case of the above lemma.

\begin{code}

 ϕ-δ-lemma : (u : M) (ws : List M)
            u  ϕ (δ u ws)  u  ϕ ws
 ϕ-δ-lemma u ws =
  u  ϕ (δ u ws)       =⟨ ap (u ●_) ((●-left-unit (ϕ (δ u ws)))⁻¹) 
  u  (e  ϕ (δ u ws)) =⟨ ϕ-δ-lemma' u e ws 
  u  (e  ϕ ws)       =⟨ ap (u ●_) (●-left-unit (ϕ ws)) 
  u  ϕ ws             

 ϕ-ρ-lemma : (us vs : List M)
            ρ us  ρ vs
            ϕ us  ϕ vs
 ϕ-ρ-lemma = course-of-values-induction-on-length _ h
  where
   h : (us : List M)
      ((us' : List M)
              length us' < length us
              (vs : List M)  ρ us'  ρ vs  ϕ us'  ϕ vs)
      (vs : List M)  ρ us  ρ vs  ϕ us  ϕ vs
   h [] IH [] e = refl
   h (u  us) IH (v  vs) e =
    ϕ (u  us)     =⟨ refl 
    u  ϕ us       =⟨ (ϕ-δ-lemma u us)⁻¹ 
    u  ϕ (δ u us) =⟨ ap (u ●_) (IH (δ u us) (δ-length u us) (δ v vs) I) 
    u  ϕ (δ v vs) =⟨ ap (_● ϕ (δ v vs)) (equal-heads e) 
    v  ϕ (δ v vs) =⟨ ϕ-δ-lemma v vs 
    v  ϕ vs       =⟨ refl 
    ϕ (v  vs)     
     where
      have-e : u  δ u (ρ us)  v  δ v (ρ vs)
      have-e = e

      I =  ρ (δ u us) =⟨ (δ-ρ-swap u us)⁻¹ 
           δ u (ρ us) =⟨ equal-tails e 
           δ v (ρ vs) =⟨ δ-ρ-swap v vs 
           ρ (δ v vs) 

 ϕ-ρ : (us : List M)  ϕ us  ϕ (ρ us)
 ϕ-ρ us = ϕ-ρ-lemma us (ρ us) ((ρ-idemp us)⁻¹)

 f'-ρ-lemma : (xs : List X)
             f' (ρ xs)  f' xs
 f'-ρ-lemma xs =
  f' (ρ xs)            =⟨ ϕ-map-lemma (ρ xs) 
  ϕ (map f (ρ xs))     =⟨ ϕ-ρ (map f (ρ xs)) 
  ϕ (ρ (map f (ρ xs))) =⟨ ap (ϕ) (ρ-map f xs) 
  ϕ (ρ (map f xs))     =⟨ (ϕ-ρ (map f xs))⁻¹ 
  ϕ (map f xs)         =⟨ (ϕ-map-lemma xs)⁻¹ 
  f' xs                

 f'-ρ-lemma' : (xs ys : List X)
              ρ xs  ρ ys
              f' xs  f' ys
 f'-ρ-lemma' xs ys e =
  f' xs     =⟨ (f'-ρ-lemma xs)⁻¹ 
  f' (ρ xs) =⟨ ap f' e 
  f' (ρ ys) =⟨ f'-ρ-lemma ys 
  f' ys     

 f⁻-preserves-mul : (𝔁𝓼 𝔂𝓼 : List⁻ X)
                   f⁻ (𝔁𝓼 · 𝔂𝓼)  f⁻ 𝔁𝓼  f⁻ 𝔂𝓼
 f⁻-preserves-mul 𝔁𝓼@(xs , a) 𝔂𝓼@(ys , b) =
  f⁻ (𝔁𝓼 · 𝔂𝓼)      =⟨ refl 
  f' (ρ (xs  ys)) =⟨ f'-ρ-lemma (xs  ys) 
  f' (xs  ys)     =⟨ f'-preserves-mul xs ys 
  f' xs  f' ys    =⟨ refl 
  f⁻ 𝔁𝓼  f⁻ 𝔂𝓼      

 f⁻-uniqueness : (h : List⁻ X  M)
                h []⁻  e
                ((xs ys : List⁻ X)  h (xs · ys)  h xs  h ys)
                h  η⁻  f
                h  f⁻
 f⁻-uniqueness h unit-h comp-h triangle-h (xs , a) = I xs a
  where
   I : (xs : List X) (a : ρ xs  xs)
      h (xs , a)  f⁻ (xs , a)
   I [] a =
    h ([] , a) =⟨ ap h (to-List⁻-= refl) 
    h []⁻      =⟨ unit-h 
    e          =⟨ refl 
    f⁻ ([] , a) 
   I (x  xs) a =
    h ((x  xs) , a) =⟨ ap h (·-lemma x xs a) 
    h (η⁻ x · 𝔁𝓼)    =⟨ comp-h (η⁻ x) 𝔁𝓼 
    h (η⁻ x)  h 𝔁𝓼  =⟨ ap₂ _●_ (triangle-h x) (I xs b) 
    f x  f⁻ 𝔁𝓼      =⟨ refl 
    f x  f' xs      =⟨ refl 
    f⁻ ((x  xs) , a) 
     where
      b : ρ xs  xs
      b = ρ-tail x xs a

      𝔁𝓼 : List⁻ X
      𝔁𝓼 = xs , b

\end{code}

We now package the above development as follows, to conclude that, as
claimed, lists without repetitions over a discrete type form the free
discrete graphic monoid.

\begin{code}

module _
        (𝓜 : DGM 𝓥)
        {X : 𝓤 ̇ }
        {{X-is-discrete' : is-discrete' X}}
       where

 open free-discrete-graphic-monoid-development
        𝓜 
       {{discrete-gives-discrete' (discreteness 𝓜)}}
       (unit 𝓜)
       (multiplication 𝓜)
       (left-neutrality 𝓜)
       (right-neutrality 𝓜)
       (associativity 𝓜)
       (graphicality 𝓜)
       X
       {{X-is-discrete'}}

 extension : (X   𝓜 )  List⁻ X   𝓜 
 extension = f⁻

 extension-is-hom : (f : X   𝓜 )
                   is-hom (List⁻-DGM X) 𝓜 (extension f)
 extension-is-hom f = refl , f⁻-preserves-mul f

 triangle : (f : X   𝓜 )
           extension f  η⁻  f
 triangle = f⁻-triangle

 uniqueness : (f : X   𝓜 )
              (g : List⁻ X   𝓜 )
             is-hom (List⁻-DGM X) 𝓜 g
             g  η⁻  f
             extension f  g
 uniqueness f g (g-unit , g-comp) h = ∼-sym (f⁻-uniqueness f g g-unit g-comp h)

\end{code}