Skip to content

Commit 58f3e39

Browse files
committed
refactor(Limits/Preserves/Finite): review API (#21890)
- Discard unneeded `Subsingleton` instances. Probably, these instances were added when the typeclasses were in `Type*`. - Require a proof for `Fin _` in the definition, then prove an instance for `J : Type u`. - Assume `Finite _` instead of `Fintype _` here and there. - Drop some no longer needed `Nonempty` wrappers.
1 parent e26b4ff commit 58f3e39

File tree

19 files changed

+123
-153
lines changed

19 files changed

+123
-153
lines changed

Mathlib/CategoryTheory/Closed/Ideal.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ lemma preservesBinaryProducts_of_exponentialIdeal :
302302
/--
303303
If a reflective subcategory is an exponential ideal, then the reflector preserves finite products.
304304
-/
305-
lemma preservesFiniteProducts_of_exponentialIdeal (J : Type) [Fintype J] :
305+
lemma preservesFiniteProducts_of_exponentialIdeal (J : Type) [Finite J] :
306306
PreservesLimitsOfShape (Discrete J) (reflector i) := by
307307
letI := preservesBinaryProducts_of_exponentialIdeal i
308308
letI : PreservesLimitsOfShape _ (reflector i) := leftAdjoint_preservesTerminal_of_reflective.{0} i

Mathlib/CategoryTheory/Galois/Action.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ instance : Functor.ReflectsIsomorphisms (functorToAction F) where
6969
isIso_of_reflects_iso f F
7070

7171
noncomputable instance : PreservesFiniteCoproducts (functorToAction F) :=
72-
fun J _ ↦ Action.preservesColimitsOfShape_of_preserves (functorToAction F)
73-
(inferInstanceAs <| PreservesColimitsOfShape (Discrete J) F)⟩
72+
fun _ ↦ Action.preservesColimitsOfShape_of_preserves (functorToAction F)
73+
(inferInstanceAs <| PreservesColimitsOfShape (Discrete _) F)⟩
7474

7575
noncomputable instance : PreservesFiniteProducts (functorToAction F) :=
76-
fun J _ ↦ Action.preservesLimitsOfShape_of_preserves (functorToAction F)
77-
(inferInstanceAs <| PreservesLimitsOfShape (Discrete J) F)⟩
76+
fun _ ↦ Action.preservesLimitsOfShape_of_preserves (functorToAction F)
77+
(inferInstanceAs <| PreservesLimitsOfShape (Discrete _) F)⟩
7878

7979
noncomputable instance (G : Type*) [Group G] [Finite G] :
8080
PreservesColimitsOfShape (SingleObj G) (functorToAction F) :=

Mathlib/CategoryTheory/Galois/Examples.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ instance : PreGaloisCategory (Action FintypeCat (MonCat.of G)) where
8989

9090
/-- The forgetful functor from finite `G`-sets to sets is a `FiberFunctor`. -/
9191
noncomputable instance : FiberFunctor (Action.forget FintypeCat (MonCat.of G)) where
92-
preservesFiniteCoproducts := ⟨fun _ _ ↦ inferInstance⟩
92+
preservesFiniteCoproducts := ⟨fun _ ↦ inferInstance⟩
9393
preservesQuotientsByFiniteGroups _ _ _ := inferInstance
9494
reflectsIsos := ⟨fun f (_ : IsIso f.hom) => inferInstance⟩
9595

Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,11 @@ lemma preservesShape_fin_of_preserves_binary_and_terminal (n : ℕ) :
156156
apply preservesLimit_of_iso_diagram F that
157157

158158
/-- If `F` preserves the terminal object and binary products then it preserves finite products. -/
159-
lemma preservesFiniteProducts_of_preserves_binary_and_terminal (J : Type*) [Fintype J] :
160-
PreservesLimitsOfShape (Discrete J) F := by
161-
classical
162-
let e := Fintype.equivFin J
163-
haveI := preservesShape_fin_of_preserves_binary_and_terminal F (Fintype.card J)
164-
apply preservesLimitsOfShape_of_equiv (Discrete.equivalence e).symm
159+
lemma preservesFiniteProducts_of_preserves_binary_and_terminal (J : Type*) [Finite J] :
160+
PreservesLimitsOfShape (Discrete J) F :=
161+
let ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J
162+
have := preservesShape_fin_of_preserves_binary_and_terminal F n
163+
preservesLimitsOfShape_of_equiv (Discrete.equivalence e).symm _
165164

166165
end Preserves
167166

@@ -287,12 +286,11 @@ lemma preservesShape_fin_of_preserves_binary_and_initial (n : ℕ) :
287286
apply preservesColimit_of_iso_diagram F that
288287

289288
/-- If `F` preserves the initial object and binary coproducts then it preserves finite products. -/
290-
lemma preservesFiniteCoproductsOfPreservesBinaryAndInitial (J : Type*) [Fintype J] :
291-
PreservesColimitsOfShape (Discrete J) F := by
292-
classical
293-
let e := Fintype.equivFin J
294-
haveI := preservesShape_fin_of_preserves_binary_and_initial F (Fintype.card J)
295-
apply preservesColimitsOfShape_of_equiv (Discrete.equivalence e).symm
289+
lemma preservesFiniteCoproductsOfPreservesBinaryAndInitial (J : Type*) [Finite J] :
290+
PreservesColimitsOfShape (Discrete J) F :=
291+
let ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J
292+
have := preservesShape_fin_of_preserves_binary_and_initial F n
293+
preservesColimitsOfShape_of_equiv (Discrete.equivalence e).symm _
296294

297295
end Preserves
298296

Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,9 @@ lemma preservesFiniteLimits_of_preservesEqualizers_and_finiteProducts [HasEquali
204204
[HasFiniteProducts C] (G : C ⥤ D) [PreservesLimitsOfShape WalkingParallelPair G]
205205
[PreservesFiniteProducts G] : PreservesFiniteLimits G where
206206
preservesFiniteLimits := by
207-
intro J sJ fJ
208-
haveI : Fintype J := inferInstance
209-
haveI : Fintype ((p : J × J) × (p.fst ⟶ p.snd)) := inferInstance
210-
apply @preservesLimit_of_preservesEqualizers_and_product _ _ _ sJ _ _ ?_ ?_ _ G _ ?_ ?_
211-
· apply hasLimitsOfShape_discrete _ _
212-
· apply hasLimitsOfShape_discrete _
213-
· apply PreservesFiniteProducts.preserves _
214-
· apply PreservesFiniteProducts.preserves _
207+
intros
208+
apply preservesLimit_of_preservesEqualizers_and_product
209+
215210

216211
/-- If G preserves equalizers and products, it preserves all limits. -/
217212
lemma preservesLimits_of_preservesEqualizers_and_products [HasEqualizers C]
@@ -292,7 +287,7 @@ lemma preservesFiniteLimits_of_preservesTerminal_and_pullbacks [HasTerminal C]
292287
preservesEqualizers_of_preservesPullbacks_and_binaryProducts G
293288
apply
294289
@preservesFiniteLimits_of_preservesEqualizers_and_finiteProducts _ _ _ _ _ _ G _ ?_
295-
apply PreservesFiniteProducts.mk
290+
refine ⟨fun n ↦ ?_⟩
296291
apply preservesFiniteProducts_of_preserves_binary_and_terminal G
297292

298293
attribute [local instance] preservesFiniteLimits_of_preservesTerminal_and_pullbacks in
@@ -493,13 +488,7 @@ lemma preservesFiniteColimits_of_preservesCoequalizers_and_finiteCoproducts
493488
[PreservesFiniteCoproducts G] : PreservesFiniteColimits G where
494489
preservesFiniteColimits := by
495490
intro J sJ fJ
496-
haveI : Fintype J := inferInstance
497-
haveI : Fintype ((p : J × J) × (p.fst ⟶ p.snd)) := inferInstance
498-
apply @preservesColimit_of_preservesCoequalizers_and_coproduct _ _ _ sJ _ _ ?_ ?_ _ G _ ?_ ?_
499-
· apply hasColimitsOfShape_discrete _ _
500-
· apply hasColimitsOfShape_discrete _
501-
· apply PreservesFiniteCoproducts.preserves _
502-
· apply PreservesFiniteCoproducts.preserves _
491+
apply preservesColimit_of_preservesCoequalizers_and_coproduct
503492

504493
/-- If G preserves coequalizers and coproducts, it preserves all colimits. -/
505494
lemma preservesColimits_of_preservesCoequalizers_and_coproducts [HasCoequalizers C]
@@ -580,7 +569,7 @@ lemma preservesFiniteColimits_of_preservesInitial_and_pushouts [HasInitial C]
580569
(preservesCoequalizers_of_preservesPushouts_and_binaryCoproducts G)
581570
refine
582571
@preservesFiniteColimits_of_preservesCoequalizers_and_finiteCoproducts _ _ _ _ _ _ G _ ?_
583-
apply PreservesFiniteCoproducts.mk
572+
refine ⟨fun _ ↦ ?_⟩
584573
apply preservesFiniteCoproductsOfPreservesBinaryAndInitial G
585574

586575
attribute [local instance] preservesFiniteColimits_of_preservesInitial_and_pushouts in

Mathlib/CategoryTheory/Limits/Preserves/Finite.lean

Lines changed: 48 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ class PreservesFiniteLimits (F : C ⥤ D) : Prop where
4343

4444
attribute [instance] PreservesFiniteLimits.preservesFiniteLimits
4545

46-
instance (F : C ⥤ D) : Subsingleton (PreservesFiniteLimits F) :=
47-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
48-
4946
/-- Preserving finite limits also implies preserving limits over finite shapes in higher universes,
5047
though through a noncomputable instance. -/
5148
instance (priority := 100) preservesLimitsOfShapeOfPreservesFiniteLimits (F : C ⥤ D)
@@ -93,29 +90,25 @@ lemma preservesFiniteLimits_of_natIso {F G : C ⥤ D} (h : F ≅ G) [PreservesFi
9390

9491
/- Porting note: adding this class because quantified classes don't behave well
9592
https://github.com/leanprover-community/mathlib4/pull/2764 -/
96-
/-- A functor `F` preserves finite products if it preserves all from `Discrete J`
97-
for `Fintype J` -/
93+
/-- A functor `F` preserves finite products if it preserves all from `Discrete J` for `Finite J`.
94+
We require this for `J = Fin n` in the definition,
95+
then generalize to `J : Type u` in the instance. -/
9896
class PreservesFiniteProducts (F : C ⥤ D) : Prop where
99-
preserves : ∀ (J : Type) [Fintype J], PreservesLimitsOfShape (Discrete J) F
100-
101-
attribute [instance] PreservesFiniteProducts.preserves
102-
103-
instance (F : C ⥤ D) : Subsingleton (PreservesFiniteProducts F) :=
104-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
97+
preserves : ∀ n, PreservesLimitsOfShape (Discrete (Fin n)) F
10598

10699
instance (priority := 100) (F : C ⥤ D) (J : Type u) [Finite J]
107100
[PreservesFiniteProducts F] : PreservesLimitsOfShape (Discrete J) F := by
108-
apply Nonempty.some
109101
obtain ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J
110-
exact ⟨preservesLimitsOfShape_of_equiv (Discrete.equivalence e.symm) F⟩
102+
have := PreservesFiniteProducts.preserves (F := F) n
103+
exact preservesLimitsOfShape_of_equiv (Discrete.equivalence e.symm) F
111104

112105
instance comp_preservesFiniteProducts (F : C ⥤ D) (G : D ⥤ E)
113106
[PreservesFiniteProducts F] [PreservesFiniteProducts G] :
114107
PreservesFiniteProducts (F ⋙ G) where
115-
preserves _ _ := inferInstance
108+
preserves _ := inferInstance
116109

117110
instance (F : C ⥤ D) [PreservesFiniteLimits F] : PreservesFiniteProducts F where
118-
preserves _ _ := inferInstance
111+
preserves _ := inferInstance
119112

120113
/--
121114
A functor is said to reflect finite limits, if it reflects all limits of shape `J`,
@@ -127,20 +120,20 @@ class ReflectsFiniteLimits (F : C ⥤ D) : Prop where
127120

128121
attribute [instance] ReflectsFiniteLimits.reflects
129122

130-
instance (F : C ⥤ D) : Subsingleton (ReflectsFiniteLimits F) :=
131-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
132-
133123
/- Similarly to preserving finite products, quantified classes don't behave well. -/
134124
/--
135-
A functor `F` preserves finite products if it reflects limits of shape `Discrete J` for finite `J`
125+
A functor `F` preserves finite products if it reflects limits of shape `Discrete J` for finite `J`.
126+
We require this for `J = Fin n` in the definition,
127+
then generalize to `J : Type u` in the instance.
136128
-/
137129
class ReflectsFiniteProducts (F : C ⥤ D) : Prop where
138-
reflects : ∀ (J : Type) [Fintype J], ReflectsLimitsOfShape (Discrete J) F
130+
reflects : ∀ n, ReflectsLimitsOfShape (Discrete (Fin n)) F
139131

140-
attribute [instance] ReflectsFiniteProducts.reflects
141-
142-
instance (F : C ⥤ D) : Subsingleton (ReflectsFiniteProducts F) :=
143-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
132+
instance (priority := 100) (F : C ⥤ D) [ReflectsFiniteProducts F] (J : Type u) [Finite J] :
133+
ReflectsLimitsOfShape (Discrete J) F :=
134+
let ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J
135+
have := ReflectsFiniteProducts.reflects (F := F) n
136+
reflectsLimitsOfShape_of_equiv (Discrete.equivalence e.symm) _
144137

145138
-- This is a dangerous instance as it has unbound universe variables.
146139
/-- If we reflect limits of some arbitrary size, then we reflect all finite limits. -/
@@ -174,7 +167,7 @@ finite products.
174167
-/
175168
lemma preservesFiniteProducts_of_reflects_of_preserves (F : C ⥤ D) (G : D ⥤ E)
176169
[PreservesFiniteProducts (F ⋙ G)] [ReflectsFiniteProducts G] : PreservesFiniteProducts F where
177-
preserves _ _ := preservesLimitsOfShape_of_reflects_of_preserves F G
170+
preserves _ := preservesLimitsOfShape_of_reflects_of_preserves F G
178171

179172
instance reflectsFiniteLimits_of_reflectsIsomorphisms (F : C ⥤ D)
180173
[F.ReflectsIsomorphisms] [HasFiniteLimits C] [PreservesFiniteLimits F] :
@@ -184,15 +177,15 @@ instance reflectsFiniteLimits_of_reflectsIsomorphisms (F : C ⥤ D)
184177
instance reflectsFiniteProducts_of_reflectsIsomorphisms (F : C ⥤ D)
185178
[F.ReflectsIsomorphisms] [HasFiniteProducts C] [PreservesFiniteProducts F] :
186179
ReflectsFiniteProducts F where
187-
reflects _ _ := reflectsLimitsOfShape_of_reflectsIsomorphisms
180+
reflects _ := reflectsLimitsOfShape_of_reflectsIsomorphisms
188181

189182
instance comp_reflectsFiniteProducts (F : C ⥤ D) (G : D ⥤ E)
190183
[ReflectsFiniteProducts F] [ReflectsFiniteProducts G] :
191184
ReflectsFiniteProducts (F ⋙ G) where
192-
reflects _ _ := inferInstance
185+
reflects _ := inferInstance
193186

194187
instance (F : C ⥤ D) [ReflectsFiniteLimits F] : ReflectsFiniteProducts F where
195-
reflects _ _ := inferInstance
188+
reflects _ := inferInstance
196189

197190
/-- A functor is said to preserve finite colimits, if it preserves all colimits of
198191
shape `J`, where `J : Type` is a finite category.
@@ -204,9 +197,6 @@ class PreservesFiniteColimits (F : C ⥤ D) : Prop where
204197

205198
attribute [instance] PreservesFiniteColimits.preservesFiniteColimits
206199

207-
instance (F : C ⥤ D) : Subsingleton (PreservesFiniteColimits F) :=
208-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
209-
210200
/--
211201
Preserving finite colimits also implies preserving colimits over finite shapes in higher
212202
universes.
@@ -257,44 +247,36 @@ lemma preservesFiniteColimits_of_natIso {F G : C ⥤ D} (h : F ≅ G) [Preserves
257247

258248
/- Porting note: adding this class because quantified classes don't behave well
259249
https://github.com/leanprover-community/mathlib4/pull/2764 -/
260-
/-- A functor `F` preserves finite products if it preserves all from `Discrete J`
261-
for `Fintype J` -/
250+
/-- A functor `F` preserves finite products if it preserves all from `Discrete J` for `Fintype J`.
251+
We require this for `J = Fin n` in the definition,
252+
then generalize to `J : Type u` in the instance. -/
262253
class PreservesFiniteCoproducts (F : C ⥤ D) : Prop where
263-
/-- preservation of colimits indexed by `Discrete J` when `[Fintype J]` -/
264-
preserves : ∀ (J : Type) [Fintype J], PreservesColimitsOfShape (Discrete J) F
265-
266-
attribute [instance] PreservesFiniteCoproducts.preserves
267-
268-
instance (F : C ⥤ D) : Subsingleton (PreservesFiniteCoproducts F) :=
269-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
254+
/-- preservation of colimits indexed by `Discrete (Fin n)`. -/
255+
preserves : ∀ n, PreservesColimitsOfShape (Discrete (Fin n)) F
270256

271257
instance (priority := 100) (F : C ⥤ D) (J : Type u) [Finite J]
272-
[PreservesFiniteCoproducts F] : PreservesColimitsOfShape (Discrete J) F := by
273-
apply Nonempty.some
274-
obtain ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J
275-
exact ⟨preservesColimitsOfShape_of_equiv (Discrete.equivalence e.symm) F
258+
[PreservesFiniteCoproducts F] : PreservesColimitsOfShape (Discrete J) F :=
259+
let ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J
260+
have := PreservesFiniteCoproducts.preserves (F := F) n
261+
preservesColimitsOfShape_of_equiv (Discrete.equivalence e.symm) F
276262

277263
instance comp_preservesFiniteCoproducts (F : C ⥤ D) (G : D ⥤ E)
278264
[PreservesFiniteCoproducts F] [PreservesFiniteCoproducts G] :
279265
PreservesFiniteCoproducts (F ⋙ G) where
280-
preserves _ _ := inferInstance
266+
preserves _ := inferInstance
281267

282268
instance (F : C ⥤ D) [PreservesFiniteColimits F] : PreservesFiniteCoproducts F where
283-
preserves _ _ := inferInstance
269+
preserves _ := inferInstance
284270

285271
/--
286272
A functor is said to reflect finite colimits, if it reflects all colimits of shape `J`,
287273
where `J : Type` is a finite category.
288274
-/
289275
class ReflectsFiniteColimits (F : C ⥤ D) : Prop where
290-
reflects : ∀ (J : Type) [SmallCategory J] [FinCategory J], ReflectsColimitsOfShape J F := by
291-
infer_instance
276+
[reflects : ∀ (J : Type) [SmallCategory J] [FinCategory J], ReflectsColimitsOfShape J F]
292277

293278
attribute [instance] ReflectsFiniteColimits.reflects
294279

295-
instance (F : C ⥤ D) : Subsingleton (ReflectsFiniteColimits F) :=
296-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
297-
298280
-- This is a dangerous instance as it has unbound universe variables.
299281
/-- If we reflect colimits of some arbitrary size, then we reflect all finite colimits. -/
300282
lemma ReflectsColimitsOfSize.reflectsFiniteColimits
@@ -315,16 +297,20 @@ instance (priority := 120) (F : C ⥤ D)
315297

316298
/- Similarly to preserving finite coproducts, quantified classes don't behave well. -/
317299
/--
318-
A functor `F` preserves finite coproducts if it reflects colimits of shape `Discrete J` for
319-
finite `J`
300+
A functor `F` preserves finite coproducts if it reflects colimits of shape `Discrete J`
301+
for finite `J`.
302+
303+
We require this for `J = Fin n` in the definition,
304+
then generalize to `J : Type u` in the instance.
320305
-/
321306
class ReflectsFiniteCoproducts (F : C ⥤ D) : Prop where
322-
reflects : ∀ (J : Type) [Fintype J], ReflectsColimitsOfShape (Discrete J) F
323-
324-
attribute [instance] ReflectsFiniteCoproducts.reflects
307+
reflects : ∀ n, ReflectsColimitsOfShape (Discrete (Fin n)) F
325308

326-
instance (F : C ⥤ D) : Subsingleton (ReflectsFiniteCoproducts F) :=
327-
fun ⟨a⟩ ⟨b⟩ => by congr⟩
309+
instance (priority := 100) (F : C ⥤ D) [ReflectsFiniteCoproducts F] (J : Type u) [Finite J] :
310+
ReflectsColimitsOfShape (Discrete J) F :=
311+
let ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J
312+
have := ReflectsFiniteCoproducts.reflects (F := F) n
313+
reflectsColimitsOfShape_of_equiv (Discrete.equivalence e.symm) _
328314

329315
/--
330316
If `F ⋙ G` preserves finite colimits and `G` reflects finite colimits, then `F` preserves finite
@@ -341,7 +327,7 @@ finite coproducts.
341327
lemma preservesFiniteCoproducts_of_reflects_of_preserves (F : C ⥤ D) (G : D ⥤ E)
342328
[PreservesFiniteCoproducts (F ⋙ G)] [ReflectsFiniteCoproducts G] :
343329
PreservesFiniteCoproducts F where
344-
preserves _ _ := preservesColimitsOfShape_of_reflects_of_preserves F G
330+
preserves _ := preservesColimitsOfShape_of_reflects_of_preserves F G
345331

346332
instance reflectsFiniteColimitsOfReflectsIsomorphisms (F : C ⥤ D)
347333
[F.ReflectsIsomorphisms] [HasFiniteColimits C] [PreservesFiniteColimits F] :
@@ -351,14 +337,14 @@ instance reflectsFiniteColimitsOfReflectsIsomorphisms (F : C ⥤ D)
351337
instance reflectsFiniteCoproductsOfReflectsIsomorphisms (F : C ⥤ D)
352338
[F.ReflectsIsomorphisms] [HasFiniteCoproducts C] [PreservesFiniteCoproducts F] :
353339
ReflectsFiniteCoproducts F where
354-
reflects _ _ := reflectsColimitsOfShape_of_reflectsIsomorphisms
340+
reflects _ := reflectsColimitsOfShape_of_reflectsIsomorphisms
355341

356342
instance comp_reflectsFiniteCoproducts (F : C ⥤ D) (G : D ⥤ E)
357343
[ReflectsFiniteCoproducts F] [ReflectsFiniteCoproducts G] :
358344
ReflectsFiniteCoproducts (F ⋙ G) where
359-
reflects _ _ := inferInstance
345+
reflects _ := inferInstance
360346

361347
instance (F : C ⥤ D) [ReflectsFiniteColimits F] : ReflectsFiniteCoproducts F where
362-
reflects _ _ := inferInstance
348+
reflects _ := inferInstance
363349

364350
end CategoryTheory.Limits

0 commit comments

Comments
 (0)