|
| 1 | +/- |
| 2 | +Copyright (c) 2019 Simon Hudon. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Simon Hudon, Yury Kudryashov |
| 5 | +-/ |
| 6 | +import algebra.group.hom data.equiv.algebra data.list.basic |
| 7 | + |
| 8 | +/-! |
| 9 | +# Free monoid over a given alphabet |
| 10 | +
|
| 11 | +## Main definitions |
| 12 | +
|
| 13 | +* `free_monoid α`: free monoid over alphabet `α`; defined as a synonym for `list α` |
| 14 | + with multiplication given by `(++)`. |
| 15 | +* `free_monoid.of`: embedding `α → free_monoid α` sending each element `x` to `[x]`; |
| 16 | +* `free_monoid.lift α M`: natural equivalence between `α → M` and `free_monoid α →* M`; |
| 17 | + for technical reasons `α` and `M` are explicit arguments; |
| 18 | +* `free_monoid.map`: embedding of `α → β` into `free_monoid α →* free_monoid β` given by `list.map`. |
| 19 | +-/ |
| 20 | + |
| 21 | +variables {α : Type*} {β : Type*} {γ : Type*} {M : Type*} [monoid M] |
| 22 | + |
| 23 | +/-- Free monoid over a given alphabet. -/ |
| 24 | +@[to_additive free_add_monoid "Free nonabelian additive monoid over a given alphabet"] |
| 25 | +def free_monoid (α) := list α |
| 26 | + |
| 27 | +namespace free_monoid |
| 28 | + |
| 29 | +@[to_additive] |
| 30 | +instance {α} : monoid (free_monoid α) := |
| 31 | +{ one := [], |
| 32 | + mul := λ x y, (x ++ y : list α), |
| 33 | + mul_one := by intros; apply list.append_nil, |
| 34 | + one_mul := by intros; refl, |
| 35 | + mul_assoc := by intros; apply list.append_assoc } |
| 36 | + |
| 37 | +@[to_additive] |
| 38 | +instance {α} : inhabited (free_monoid α) := ⟨1⟩ |
| 39 | + |
| 40 | +@[to_additive] |
| 41 | +lemma one_def {α} : (1 : free_monoid α) = [] := rfl |
| 42 | + |
| 43 | +@[to_additive] |
| 44 | +lemma mul_def {α} (xs ys : list α) : (xs * ys : free_monoid α) = (xs ++ ys : list α) := |
| 45 | +rfl |
| 46 | + |
| 47 | +/-- Embeds an element of `α` into `free_monoid α` as a singleton list. -/ |
| 48 | +@[to_additive "Embeds an element of `α` into `free_add_monoid α` as a singleton list." ] |
| 49 | +def of (x : α) : free_monoid α := [x] |
| 50 | + |
| 51 | +@[to_additive] |
| 52 | +lemma of_mul_eq_cons (x : α) (l : free_monoid α) : of x * l = x :: l := rfl |
| 53 | + |
| 54 | +@[to_additive] |
| 55 | +lemma hom_eq ⦃f g : free_monoid α →* M⦄ (h : ∀ x, f (of x) = g (of x)) : |
| 56 | + f = g := |
| 57 | +begin |
| 58 | + ext l, |
| 59 | + induction l with a l ihl, |
| 60 | + { exact f.map_one.trans g.map_one.symm }, |
| 61 | + { rw [← of_mul_eq_cons, f.map_mul, h, ihl, ← g.map_mul] } |
| 62 | +end |
| 63 | + |
| 64 | +section |
| 65 | +-- TODO[Lean 4] : make these arguments implicit |
| 66 | +variables (α M) |
| 67 | + |
| 68 | +/-- Equivalence between maps `α → M` and monoid homomorphisms `free_monoid α →* M`. -/ |
| 69 | +@[to_additive "Equivalence between maps `α → A` and additive monoid homomorphisms |
| 70 | +`free_add_monoid α →+ A`."] |
| 71 | +def lift : (α → M) ≃ (free_monoid α →* M) := |
| 72 | +{ to_fun := λ f, ⟨λ l, (l.map f).prod, rfl, |
| 73 | + λ l₁ l₂, by simp only [mul_def, list.map_append, list.prod_append]⟩, |
| 74 | + inv_fun := λ f x, f (of x), |
| 75 | + left_inv := λ f, funext $ λ x, one_mul (f x), |
| 76 | + right_inv := λ f, hom_eq $ λ x, one_mul (f (of x)) } |
| 77 | +end |
| 78 | + |
| 79 | +lemma lift_eval_of (f : α → M) (x : α) : lift α M f (of x) = f x := |
| 80 | +congr_fun ((lift α M).symm_apply_apply f) x |
| 81 | + |
| 82 | +lemma lift_restrict (f : free_monoid α →* M) : lift α M (f ∘ of) = f := |
| 83 | +(lift α M).apply_symm_apply f |
| 84 | + |
| 85 | +/-- The unique monoid homomorphism `free_monoid α →* free_monoid β` that sends |
| 86 | +each `of x` to `of (f x)`. -/ |
| 87 | +@[to_additive "The unique additive monoid homomorphism `free_add_monoid α →+ free_add_monoid β` |
| 88 | +that sends each `of x` to `of (f x)`."] |
| 89 | +def map (f : α → β) : free_monoid α →* free_monoid β := |
| 90 | +{ to_fun := list.map f, |
| 91 | + map_one' := rfl, |
| 92 | + map_mul' := λ l₁ l₂, list.map_append _ _ _ } |
| 93 | + |
| 94 | +@[simp, to_additive] lemma map_of (f : α → β) (x : α) : map f (of x) = of (f x) := rfl |
| 95 | + |
| 96 | +@[to_additive] |
| 97 | +lemma lift_of_comp_eq_map (f : α → β) : |
| 98 | + lift α (free_monoid β) (λ x, of (f x)) = map f := |
| 99 | +hom_eq $ λ x, rfl |
| 100 | + |
| 101 | +@[to_additive] |
| 102 | +lemma map_comp (g : β → γ) (f : α → β) : map (g ∘ f) = (map g).comp (map f) := |
| 103 | +hom_eq $ λ x, rfl |
| 104 | + |
| 105 | +end free_monoid |
0 commit comments