@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Yury Kudryashov
5
5
-/
6
6
import Mathlib.Algebra.FreeMonoid.Basic
7
- import Mathlib.Algebra.Group.TypeTags.Hom
7
+ import Mathlib.Algebra.Group.TypeTags.Basic
8
8
9
9
/-!
10
10
# `List.count` as a bundled homomorphism
@@ -13,73 +13,76 @@ In this file we define `FreeMonoid.countP`, `FreeMonoid.count`, `FreeAddMonoid.c
13
13
`FreeAddMonoid.count`. These are `List.countP` and `List.count` bundled as multiplicative and
14
14
additive homomorphisms from `FreeMonoid` and `FreeAddMonoid`.
15
15
16
- We do not use `to_additive` because it can't map `Multiplicative ℕ` to `ℕ`.
16
+ We do not use `to_additive` too much because it can't map `Multiplicative ℕ` to `ℕ`.
17
+ -/
17
18
18
- ## TODO
19
+ variable {α : Type *} (p : α → Prop ) [DecidablePred p]
19
20
20
- There is lots of defeq abuse here of `FreeAddMonoid α = List α`, e.g. in statements like
21
- ```
22
- theorem countP_apply (l : FreeAddMonoid α) : countP p l = List.countP p l := rfl
23
- ```
24
- This needs cleaning up.
21
+ namespace FreeMonoid
22
+ /-- `List.countP` lifted to free monoids-/
23
+ @[to_additive "`List.countP` lifted to free additive monoids"]
24
+ def countP' (l : FreeMonoid α) : ℕ := l.toList.countP p
25
25
26
- -/
26
+ @[to_additive]
27
+ lemma countP'_one : (1 : FreeMonoid α).countP' p = 0 := rfl
27
28
28
- variable {α : Type *} (p : α → Prop ) [DecidablePred p]
29
+ @[to_additive]
30
+ lemma countP'_mul (l₁ l₂ : FreeMonoid α) : (l₁ * l₂).countP' p = l₁.countP' p + l₂.countP' p := by
31
+ dsimp [countP']
32
+ simp only [List.countP_append]
29
33
30
- namespace FreeAddMonoid
34
+ /-- `List.countP` as a bundled multiplicative monoid homomorphism. -/
35
+ def countP : FreeMonoid α →* Multiplicative ℕ where
36
+ toFun := .ofAdd ∘ FreeMonoid.countP' p
37
+ map_one' := by
38
+ simp [countP'_one p]
39
+ map_mul' x y := by
40
+ simp [countP'_mul p]
31
41
32
- /-- `List.countP` as a bundled additive monoid homomorphism. -/
33
- def countP : FreeAddMonoid α →+ ℕ where
34
- toFun := List.countP p
35
- map_zero' := List.countP_nil _
36
- map_add' := List.countP_append _
42
+ theorem countP_apply (l : FreeMonoid α) : l.countP p = .ofAdd (l.toList.countP p) := rfl
37
43
38
- theorem countP_of (x : α) : countP p (of x) = if p x = true then 1 else 0 := by
39
- change List.countP p [x] = _
40
- simp [List.countP_cons]
44
+ lemma countP_of (x : α) : (of x).countP p =
45
+ if p x then Multiplicative.ofAdd 1 else Multiplicative.ofAdd 0 := by
46
+ rw [countP_apply, toList_of, List.countP_singleton, apply_ite (Multiplicative.ofAdd)]
47
+ simp only [decide_eq_true_eq]
41
48
42
- theorem countP_apply (l : FreeAddMonoid α) : countP p l = List.countP p l := rfl
43
49
44
50
/-- `List.count` as a bundled additive monoid homomorphism. -/
45
- -- Porting note: was (x = ·)
46
- def count [DecidableEq α] (x : α) : FreeAddMonoid α →+ ℕ := countP (· = x)
47
-
48
- theorem count_of [DecidableEq α] (x y : α) : count x (of y) = (Pi.single x 1 : α → ℕ) y := by
49
- change List.count x [y] = _
50
- simp [Pi.single, Function.update, List.count_cons]
51
+ def count [DecidableEq α] (x : α) : FreeMonoid α →* Multiplicative ℕ := countP (· = x)
51
52
52
- theorem count_apply [DecidableEq α] (x : α) (l : FreeAddMonoid α) : count x l = List.count x l :=
53
- rfl
53
+ theorem count_apply [DecidableEq α] (x : α) (l : FreeAddMonoid α) :
54
+ count x l = Multiplicative.ofAdd (l.toList.count x) := rfl
54
55
55
- end FreeAddMonoid
56
+ theorem count_of [DecidableEq α] (x y : α) :
57
+ count x (of y) = Pi.mulSingle (f := fun _ => Multiplicative ℕ) x (Multiplicative.ofAdd 1 ) y :=
58
+ by simp only [count, eq_comm, countP_of, ofAdd_zero, Pi.mulSingle_apply]
56
59
57
- namespace FreeMonoid
60
+ end FreeMonoid
58
61
59
- /-- `List.countP` as a bundled multiplicative monoid homomorphism. -/
60
- def countP : FreeMonoid α →* Multiplicative ℕ :=
61
- AddMonoidHom.toMultiplicative (FreeAddMonoid.countP p)
62
+ namespace FreeAddMonoid
62
63
63
- theorem countP_of' (x : α) :
64
- countP p (of x) = if p x then Multiplicative.ofAdd 1 else Multiplicative.ofAdd 0 := by
65
- erw [FreeAddMonoid.countP_of]
66
- simp only [eq_iff_iff, iff_true, ofAdd_zero]; rfl
64
+ /-- `List.countP` as a bundled additive monoid homomorphism. -/
65
+ def countP : FreeAddMonoid α →+ ℕ where
66
+ toFun := FreeAddMonoid.countP' p
67
+ map_zero' := countP'_zero p
68
+ map_add' := countP'_add p
67
69
68
- theorem countP_of (x : α) : countP p (of x) = if p x then Multiplicative.ofAdd 1 else 1 := by
69
- rw [countP_of', ofAdd_zero]
70
+ theorem countP_apply (l : FreeAddMonoid α) : l.countP p = l.toList.countP p := rfl
70
71
71
- -- `rfl` is not transitive
72
- theorem countP_apply (l : FreeAddMonoid α) : countP p l = Multiplicative.ofAdd ( List.countP p l) :=
73
- rfl
72
+ theorem countP_of (x : α) : countP p (of x) = if p x then 1 else 0 := by
73
+ rw [countP_apply, toList_of, List.countP_singleton]
74
+ simp only [decide_eq_true_eq]
74
75
75
76
/-- `List.count` as a bundled additive monoid homomorphism. -/
76
- def count [DecidableEq α] (x : α) : FreeMonoid α →* Multiplicative ℕ := countP (· = x)
77
+ -- Porting note: was (x = ·)
78
+ def count [DecidableEq α] (x : α) : FreeAddMonoid α →+ ℕ := countP (· = x)
77
79
78
- theorem count_apply [DecidableEq α] (x : α) (l : FreeAddMonoid α) :
79
- count x l = Multiplicative.ofAdd (List.count x l) := rfl
80
+ lemma count_of [DecidableEq α] (x y : α) : count x (of y) = (Pi.single x 1 : α → ℕ) y := by
81
+ dsimp [count]
82
+ rw [countP_of]
83
+ simp [Pi.single, Function.update]
80
84
81
- theorem count_of [DecidableEq α] (x y : α) :
82
- count x (of y) = @Pi.mulSingle α (fun _ => Multiplicative ℕ) _ _ x (Multiplicative.ofAdd 1 ) y :=
83
- by simp [count, countP_of, Pi.mulSingle_apply, eq_comm, Bool.beq_eq_decide_eq]
85
+ theorem count_apply [DecidableEq α] (x : α) (l : FreeAddMonoid α) : l.count x = l.toList.count x :=
86
+ rfl
84
87
85
- end FreeMonoid
88
+ end FreeAddMonoid
0 commit comments