Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit f059336

Browse files
committed
fix(algebra/pi_instances): improve definitions of pi.* (#3116)
The new `test/pi_simp.lean` fails with current `master`. Note that this is a workaround, not a proper fix for `tactic.pi_instance`. See also [Zulip chat](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/.60id.60.20in.20pi_instances) Also use `@[to_additive]` to generate additive definitions, add ordered multiplicative monoids, and add `semimodule (Π i, f i) (Π, g i)`.
1 parent 54cc126 commit f059336

File tree

4 files changed

+134
-74
lines changed

4 files changed

+134
-74
lines changed

src/algebra/category/Group/biproducts.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ to the cartesian product of those groups.
5454
def lift (s : cone F) :
5555
s.X ⟶ AddCommGroup.of (Π j, F.obj j) :=
5656
{ to_fun := λ x j, s.π.app j x,
57-
map_zero' := by { ext, dsimp, simp, refl, },
58-
map_add' := λ x y, by { ext, dsimp, simp, refl, }, }
57+
map_zero' := by { ext, simp },
58+
map_add' := λ x y, by { ext, simp }, }
5959

6060
@[simp] lemma lift_apply (s : cone F) (x : s.X) (j : J) : (lift F s) x j = s.π.app j x := rfl
6161

src/algebra/pi_instances.lean

Lines changed: 108 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ open_locale big_operators
1111

1212
/-!
1313
# Pi instances for algebraic structures
14+
15+
## Implementation notes
16+
17+
We don't use `by pi_instance` directly because currently instances generated by this tactic have
18+
slightly wrong definitions (extra `id`s and `group.mul` instead of `has_mul.mul`). These little
19+
bugs prevent Lean from applying a `simp` lemma about `pi.has_one` to `1` coming from `pi.group`.
20+
21+
## TODO
22+
23+
Properly fix `tactic.pi_instance`.
1424
-/
1525

1626
namespace pi
@@ -19,64 +29,99 @@ variable {I : Type u} -- The indexing type
1929
variable {f : I → Type v} -- The family of types already equipped with instances
2030
variables (x y : Π i, f i) (i : I)
2131

22-
instance has_zero [∀ i, has_zero $ f i] : has_zero (Π i : I, f i) := ⟨λ i, 0
23-
@[simp] lemma zero_apply [∀ i, has_zero $ f i] : (0 : Π i, f i) i = 0 := rfl
32+
@[to_additive] instance has_one [∀ i, has_one $ f i] : has_one (Π i : I, f i) := ⟨λ _, 1
33+
@[simp, to_additive] lemma one_apply [∀ i, has_one $ f i] : (1 : Π i, f i) i = 1 := rfl
34+
35+
@[to_additive]
36+
instance has_mul [∀ i, has_mul $ f i] : has_mul (Π i : I, f i) := ⟨λ f g i, f i * g i⟩
37+
@[simp, to_additive] lemma mul_apply [∀ i, has_mul $ f i] : (x * y) i = x i * y i := rfl
38+
39+
@[to_additive] instance has_inv [∀ i, has_inv $ f i] : has_inv (Π i : I, f i) := ⟨λ f i, (f i)⁻¹⟩
40+
@[simp, to_additive] lemma inv_apply [∀ i, has_inv $ f i] : x⁻¹ i = (x i)⁻¹ := rfl
41+
42+
instance has_scalar {α : Type*} [Π i, has_scalar α $ f i] :
43+
has_scalar α (Π i : I, f i) :=
44+
⟨λ s x, λ i, s • (x i)⟩
45+
46+
@[simp] lemma smul_apply {α : Type*} [Π i, has_scalar α $ f i] (s : α) : (s • x) i = s • x i := rfl
47+
48+
instance has_scalar' {g : I → Type*} [Π i, has_scalar (f i) (g i)] :
49+
has_scalar (Π i, f i) (Π i : I, g i) :=
50+
⟨λ s x, λ i, (s i) • (x i)⟩
51+
52+
@[simp]
53+
lemma smul_apply' {g : I → Type*} [∀ i, has_scalar (f i) (g i)] (s : Π i, f i) (x : Π i, g i) :
54+
(s • x) i = s i • x i :=
55+
rfl
56+
57+
@[to_additive add_semigroup]
58+
instance semigroup [∀ i, semigroup $ f i] : semigroup (Π i : I, f i) :=
59+
by refine_struct { mul := (*), .. }; tactic.pi_instance_derive_field
2460

25-
instance has_one [∀ i, has_one $ f i] : has_one (Π i : I, f i) := ⟨λ i, 1
26-
@[simp] lemma one_apply [∀ i, has_one $ f i] : (1 : Π i, f i) i = 1 := rfl
61+
@[to_additive add_comm_semigroup]
62+
instance comm_semigroup [∀ i, comm_semigroup $ f i] : comm_semigroup (Π i : I, f i) :=
63+
by refine_struct { mul := (*), .. }; tactic.pi_instance_derive_field
2764

28-
attribute [to_additive] pi.has_one
29-
attribute [to_additive] pi.one_apply
65+
@[to_additive add_monoid]
66+
instance monoid [∀ i, monoid $ f i] : monoid (Π i : I, f i) :=
67+
by refine_struct { one := (1 : Π i, f i), mul := (*), .. }; tactic.pi_instance_derive_field
3068

31-
instance has_add [∀ i, has_add $ f i] : has_add (Π i : I, f i) := ⟨λ x y, λ i, x i + y i⟩
32-
@[simp] lemma add_apply [∀ i, has_add $ f i] : (x + y) i = x i + y i := rfl
69+
@[to_additive add_comm_monoid]
70+
instance comm_monoid [∀ i, comm_monoid $ f i] : comm_monoid (Π i : I, f i) :=
71+
by refine_struct { one := (1 : Π i, f i), mul := (*), .. }; tactic.pi_instance_derive_field
3372

34-
instance has_mul [∀ i, has_mul $ f i] : has_mul (Π i : I, f i) := ⟨λ x y, λ i, x i * y i⟩
35-
@[simp] lemma mul_apply [∀ i, has_mul $ f i] : (x * y) i = x i * y i := rfl
73+
@[to_additive add_group]
74+
instance group [∀ i, group $ f i] : group (Π i : I, f i) :=
75+
by refine_struct { one := (1 : Π i, f i), mul := (*), inv := has_inv.inv, .. };
76+
tactic.pi_instance_derive_field
3677

37-
attribute [to_additive] pi.has_mul
38-
attribute [to_additive] pi.mul_apply
78+
@[to_additive add_comm_group]
79+
instance comm_group [∀ i, comm_group $ f i] : comm_group (Π i : I, f i) :=
80+
by refine_struct { one := (1 : Π i, f i), mul := (*), inv := has_inv.inv, .. };
81+
tactic.pi_instance_derive_field
3982

40-
instance has_inv [∀ i, has_inv $ f i] : has_inv (Π i : I, f i) := ⟨λ x, λ i, (x i)⁻¹⟩
41-
@[simp] lemma inv_apply [∀ i, has_inv $ f i] : x⁻¹ i = (x i)⁻¹ := rfl
83+
instance mul_zero_class i, mul_zero_class $ f i] : mul_zero_class (Π i : I, f i) :=
84+
by refine_struct { zero := (0 : Π i, f i), mul := (*), .. }; tactic.pi_instance_derive_field
4285

43-
instance has_neg [∀ i, has_neg $ f i] : has_neg (Π i : I, f i) := ⟨λ x, λ i, -(x i)⟩
44-
@[simp] lemma neg_apply [∀ i, has_neg $ f i] : (-x) i = -x i := rfl
86+
instance distrib i, distrib $ f i] : distrib (Π i : I, f i) :=
87+
by refine_struct { add := (+), mul := (*), .. }; tactic.pi_instance_derive_field
4588

46-
attribute [to_additive] pi.has_inv
47-
attribute [to_additive] pi.inv_apply
89+
instance semiring [∀ i, semiring $ f i] : semiring (Π i : I, f i) :=
90+
by refine_struct { zero := (0 : Π i, f i), one := 1, add := (+), mul := (*), .. };
91+
tactic.pi_instance_derive_field
4892

49-
instance has_scalar {α : Type*} [∀ i, has_scalar α $ f i] : has_scalar α (Π i : I, f i) := ⟨λ s x, λ i, s • (x i)⟩
50-
@[simp] lemma smul_apply {α : Type*} [∀ i, has_scalar α $ f i] (s : α) : (s • x) i = s • x i := rfl
93+
instance ring [∀ i, ring $ f i] : ring (Π i : I, f i) :=
94+
by refine_struct { zero := (0 : Π i, f i), one := 1, add := (+), mul := (*),
95+
neg := has_neg.neg, .. }; tactic.pi_instance_derive_field
5196

52-
instance semigroup [∀ i, semigroup $ f i] : semigroup (Π i : I, f i) := by pi_instance
53-
instance comm_semigroup [∀ i, comm_semigroup $ f i] : comm_semigroup (Π i : I, f i) := by pi_instance
54-
instance monoid [∀ i, monoid $ f i] : monoid (Π i : I, f i) := by pi_instance
55-
instance comm_monoid [∀ i, comm_monoid $ f i] : comm_monoid (Π i : I, f i) := by pi_instance
56-
instance group [∀ i, group $ f i] : group (Π i : I, f i) := by pi_instance
57-
instance comm_group [∀ i, comm_group $ f i] : comm_group (Π i : I, f i) := by pi_instance
58-
instance add_semigroup [∀ i, add_semigroup $ f i] : add_semigroup (Π i : I, f i) := by pi_instance
59-
instance add_comm_semigroup [∀ i, add_comm_semigroup $ f i] : add_comm_semigroup (Π i : I, f i) := by pi_instance
60-
instance add_monoid [∀ i, add_monoid $ f i] : add_monoid (Π i : I, f i) := by pi_instance
61-
instance add_comm_monoid [∀ i, add_comm_monoid $ f i] : add_comm_monoid (Π i : I, f i) := by pi_instance
62-
instance add_group [∀ i, add_group $ f i] : add_group (Π i : I, f i) := by pi_instance
63-
instance add_comm_group [∀ i, add_comm_group $ f i] : add_comm_group (Π i : I, f i) := by pi_instance
64-
instance semiring [∀ i, semiring $ f i] : semiring (Π i : I, f i) := by pi_instance
65-
instance ring [∀ i, ring $ f i] : ring (Π i : I, f i) := by pi_instance
66-
instance comm_ring [∀ i, comm_ring $ f i] : comm_ring (Π i : I, f i) := by pi_instance
97+
instance comm_ring [∀ i, comm_ring $ f i] : comm_ring (Π i : I, f i) :=
98+
by refine_struct { zero := (0 : Π i, f i), one := 1, add := (+), mul := (*),
99+
neg := has_neg.neg, .. }; tactic.pi_instance_derive_field
67100

68-
instance mul_action (α) {m : monoid α} [ i, mul_action α $ f i] :
101+
instance mul_action (α) {m : monoid α} [Π i, mul_action α $ f i] :
69102
@mul_action α (Π i : I, f i) m :=
70-
{ smul := λ c f i, c • f i,
103+
{ smul := (•),
71104
mul_smul := λ r s f, funext $ λ i, mul_smul _ _ _,
72105
one_smul := λ f, funext $ λ i, one_smul α _ }
73106

107+
instance mul_action' {g : I → Type*} {m : Π i, monoid (f i)} [Π i, mul_action (f i) (g i)] :
108+
@mul_action (Π i, f i) (Π i : I, g i) (@pi.monoid I f m) :=
109+
{ smul := (•),
110+
mul_smul := λ r s f, funext $ λ i, mul_smul _ _ _,
111+
one_smul := λ f, funext $ λ i, one_smul _ _ }
112+
74113
instance distrib_mul_action (α) {m : monoid α} {n : ∀ i, add_monoid $ f i} [∀ i, distrib_mul_action α $ f i] :
75114
@distrib_mul_action α (Π i : I, f i) m (@pi.add_monoid I f n) :=
76115
{ smul_zero := λ c, funext $ λ i, smul_zero _,
77116
smul_add := λ c f g, funext $ λ i, smul_add _ _ _,
78117
..pi.mul_action _ }
79118

119+
instance distrib_mul_action' {g : I → Type*} {m : Π i, monoid (f i)} {n : Π i, add_monoid $ g i}
120+
[Π i, distrib_mul_action (f i) (g i)] :
121+
@distrib_mul_action (Π i, f i) (Π i : I, g i) (@pi.monoid I f m) (@pi.add_monoid I g n) :=
122+
{ smul_add := by { intros, ext x, apply smul_add },
123+
smul_zero := by { intros, ext x, apply smul_zero } }
124+
80125
variables (I f)
81126

82127
instance semimodule (α) {r : semiring α} {m : ∀ i, add_comm_monoid $ f i} [∀ i, semimodule α $ f i] :
@@ -87,41 +132,35 @@ instance semimodule (α) {r : semiring α} {m : ∀ i, add_comm_monoid $ f i} [
87132

88133
variables {I f}
89134

135+
instance semimodule' {g : I → Type*} {r : Π i, semiring (f i)} {m : Π i, add_comm_monoid (g i)}
136+
[Π i, semimodule (f i) (g i)] :
137+
semimodule (Π i, f i) (Π i, g i) :=
138+
{ add_smul := by { intros, ext1, apply add_smul },
139+
zero_smul := by { intros, ext1, apply zero_smul } }
140+
141+
@[to_additive add_left_cancel_semigroup]
90142
instance left_cancel_semigroup [∀ i, left_cancel_semigroup $ f i] :
91143
left_cancel_semigroup (Π i : I, f i) :=
92-
by pi_instance
93-
94-
instance add_left_cancel_semigroup [∀ i, add_left_cancel_semigroup $ f i] :
95-
add_left_cancel_semigroup (Π i : I, f i) :=
96-
by pi_instance
144+
by refine_struct { mul := (*) }; tactic.pi_instance_derive_field
97145

146+
@[to_additive add_right_cancel_semigroup]
98147
instance right_cancel_semigroup [∀ i, right_cancel_semigroup $ f i] :
99148
right_cancel_semigroup (Π i : I, f i) :=
100-
by pi_instance
101-
102-
instance add_right_cancel_semigroup [∀ i, add_right_cancel_semigroup $ f i] :
103-
add_right_cancel_semigroup (Π i : I, f i) :=
104-
by pi_instance
105-
106-
instance ordered_cancel_comm_monoid [∀ i, ordered_cancel_add_comm_monoid $ f i] :
107-
ordered_cancel_add_comm_monoid (Π i : I, f i) :=
108-
by pi_instance
109-
110-
instance ordered_add_comm_group [∀ i, ordered_add_comm_group $ f i] :
111-
ordered_add_comm_group (Π i : I, f i) :=
112-
{ add_le_add_left := λ x y hxy c i, add_le_add_left (hxy i) _,
113-
..pi.add_comm_group,
149+
by refine_struct { mul := (*) }; tactic.pi_instance_derive_field
150+
151+
@[to_additive ordered_cancel_add_comm_monoid]
152+
instance ordered_cancel_comm_monoid [∀ i, ordered_cancel_comm_monoid $ f i] :
153+
ordered_cancel_comm_monoid (Π i : I, f i) :=
154+
by refine_struct { mul := (*), one := (1 : Π i, f i), le := (≤), lt := (<), .. pi.partial_order };
155+
tactic.pi_instance_derive_field
156+
157+
@[to_additive ordered_add_comm_group]
158+
instance ordered_comm_group [∀ i, ordered_comm_group $ f i] :
159+
ordered_comm_group (Π i : I, f i) :=
160+
{ mul_le_mul_left := λ x y hxy c i, mul_le_mul_left' (hxy i),
161+
..pi.comm_group,
114162
..pi.partial_order }
115163

116-
attribute [to_additive add_semigroup] pi.semigroup
117-
attribute [to_additive add_comm_semigroup] pi.comm_semigroup
118-
attribute [to_additive add_monoid] pi.monoid
119-
attribute [to_additive add_comm_monoid] pi.comm_monoid
120-
attribute [to_additive add_group] pi.group
121-
attribute [to_additive add_comm_group] pi.comm_group
122-
attribute [to_additive add_left_cancel_semigroup] pi.left_cancel_semigroup
123-
attribute [to_additive add_right_cancel_semigroup] pi.right_cancel_semigroup
124-
125164
@[simp] lemma sub_apply [∀ i, add_group $ f i] : (x - y) i = x i - y i := rfl
126165

127166
@[to_additive]
@@ -309,16 +348,14 @@ section
309348
variables {f}
310349
variables [Π i, semiring (f i)]
311350

312-
-- it is somewhat unfortunate that we can't easily use `add_monoid_hom.functions_ext` here
351+
-- we need `apply`+`convert` because Lean fails to unify different `add_monoid` instances
352+
-- on `Π i, f i`
313353
@[ext]
314354
lemma ring_hom.functions_ext [fintype I] (G : Type*) [semiring G] (g h : (Π i, f i) →+* G)
315355
(w : ∀ (i : I) (x : f i), g (single i x) = h (single i x)) : g = h :=
316356
begin
317-
ext k,
318-
rw [←finset.univ_sum_single k, ring_hom.map_sum, ring_hom.map_sum],
319-
apply finset.sum_congr rfl,
320-
intros,
321-
apply w,
357+
apply ring_hom.coe_add_monoid_hom_injective,
358+
convert add_monoid_hom.functions_ext _ _ _ _; assumption
322359
end
323360
end
324361
end

src/topology/metric_space/pi_Lp.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ protected lemma dist {p : ℝ} {hp : 1 ≤ p} {α : ι → Type*}
221221
/-- normed group instance on the product of finitely many normed groups, using the `L^p` norm. -/
222222
instance normed_group [∀i, normed_group (α i)] : normed_group (pi_Lp p hp α) :=
223223
{ norm := λf, (∑ (i : ι), norm (f i) ^ p) ^ (1/p),
224-
dist_eq := λ x y, by { simp [pi_Lp.dist, dist_eq_norm], refl },
224+
dist_eq := λ x y, by { simp [pi_Lp.dist, dist_eq_norm] },
225225
.. pi.add_comm_group }
226226

227227
lemma norm_eq {p : ℝ} {hp : 1 ≤ p} {α : ι → Type*}

test/pi_simp.lean

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/-
2+
Copyright (c) 2020 Yury G. Kudryashov. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Author: Yury G. Kudryashov
5+
-/
6+
import algebra.pi_instances
7+
8+
/-!
9+
Test if `simp` can use a lemma about `pi.has_one` to simplify `1` coming from `pi.group`
10+
-/
11+
12+
variables {I : Type*} {f : Π i : I, Type*}
13+
14+
namespace test
15+
16+
def eval_default [inhabited I] (F : Π i, f i) : f (default I) := F (default I)
17+
18+
@[simp] lemma eval_default_one [inhabited I] [Π i, has_one (f i)] :
19+
eval_default (1 : Π i, f i) = 1 := rfl
20+
21+
example [inhabited I] [Π i, group (f i)] (F : Π i, f i) : eval_default (F⁻¹ * F) = 1 := by simp
22+
23+
end test

0 commit comments

Comments
 (0)