l3lab/ntp-mathlib huggingface dataset:
/-- A zero morphism `0 : X ⟶ Y` is an isomorphism if and only if
`X` and `Y` are isomorphic to the zero object.
-/
def isIsoZeroEquivIsoZero (X Y : C) : IsIso (0 : X ⟶ Y) ≃ (X ≅ 0) × (Y ≅ 0) := by
  -- This is lame, because `Prod` can't cope with `Prop`, so we can't use `Equiv.prodCongr`.
  refine' (isIsoZeroEquiv X Y).trans _
  symm
  fconstructor
  · rintro ⟨eX, eY⟩
    fconstructor
    exact (idZeroEquivIsoZero X).symm eX
    exact (idZeroEquivIsoZero Y).symm eY
  · 

Proof state:
case invFun
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
⊢ 𝟙 X = 0 ∧ 𝟙 Y = 0 → (X ≅ 0) × (Y ≅ 0)

Next tactic:
rintro ⟨hX, hY⟩
/-- A zero morphism `0 : X ⟶ Y` is an isomorphism if and only if
`X` and `Y` are isomorphic to the zero object.
-/
def isIsoZeroEquivIsoZero (X Y : C) : IsIso (0 : X ⟶ Y) ≃ (X ≅ 0) × (Y ≅ 0) := by
  -- This is lame, because `Prod` can't cope with `Prop`, so we can't use `Equiv.prodCongr`.
  refine' (isIsoZeroEquiv X Y).trans _
  symm
  fconstructor
  · rintro ⟨eX, eY⟩
    fconstructor
    exact (idZeroEquivIsoZero X).symm eX
    exact (idZeroEquivIsoZero Y).symm eY
  · rintro ⟨hX, hY⟩
    

Proof state:
case invFun.intro
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
hX : 𝟙 X = 0
hY : 𝟙 Y = 0
⊢ (X ≅ 0) × (Y ≅ 0)

Next tactic:
fconstructor
/-- A zero morphism `0 : X ⟶ Y` is an isomorphism if and only if
`X` and `Y` are isomorphic to the zero object.
-/
def isIsoZeroEquivIsoZero (X Y : C) : IsIso (0 : X ⟶ Y) ≃ (X ≅ 0) × (Y ≅ 0) := by
  -- This is lame, because `Prod` can't cope with `Prop`, so we can't use `Equiv.prodCongr`.
  refine' (isIsoZeroEquiv X Y).trans _
  symm
  fconstructor
  · rintro ⟨eX, eY⟩
    fconstructor
    exact (idZeroEquivIsoZero X).symm eX
    exact (idZeroEquivIsoZero Y).symm eY
  · rintro ⟨hX, hY⟩
    fconstructor
    

Proof state:
case invFun.intro.fst
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
hX : 𝟙 X = 0
hY : 𝟙 Y = 0
⊢ X ≅ 0
case invFun.intro.snd
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
hX : 𝟙 X = 0
hY : 𝟙 Y = 0
⊢ Y ≅ 0

Next tactic:
exact (idZeroEquivIsoZero X) hX
/-- A zero morphism `0 : X ⟶ Y` is an isomorphism if and only if
`X` and `Y` are isomorphic to the zero object.
-/
def isIsoZeroEquivIsoZero (X Y : C) : IsIso (0 : X ⟶ Y) ≃ (X ≅ 0) × (Y ≅ 0) := by
  -- This is lame, because `Prod` can't cope with `Prop`, so we can't use `Equiv.prodCongr`.
  refine' (isIsoZeroEquiv X Y).trans _
  symm
  fconstructor
  · rintro ⟨eX, eY⟩
    fconstructor
    exact (idZeroEquivIsoZero X).symm eX
    exact (idZeroEquivIsoZero Y).symm eY
  · rintro ⟨hX, hY⟩
    fconstructor
    exact (idZeroEquivIsoZero X) hX
    

Proof state:
case invFun.intro.snd
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
hX : 𝟙 X = 0
hY : 𝟙 Y = 0
⊢ Y ≅ 0

Next tactic:
exact (idZeroEquivIsoZero Y) hY
/-- A zero morphism `0 : X ⟶ Y` is an isomorphism if and only if
`X` and `Y` are isomorphic to the zero object.
-/
def isIsoZeroEquivIsoZero (X Y : C) : IsIso (0 : X ⟶ Y) ≃ (X ≅ 0) × (Y ≅ 0) := by
  -- This is lame, because `Prod` can't cope with `Prop`, so we can't use `Equiv.prodCongr`.
  refine' (isIsoZeroEquiv X Y).trans _
  symm
  fconstructor
  · rintro ⟨eX, eY⟩
    fconstructor
    exact (idZeroEquivIsoZero X).symm eX
    exact (idZeroEquivIsoZero Y).symm eY
  · rintro ⟨hX, hY⟩
    fconstructor
    exact (idZeroEquivIsoZero X) hX
    exact (idZeroEquivIsoZero Y) hY
  · 

Proof state:
case left_inv
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
⊢ Function.LeftInverse (fun a => And.casesOn a fun hX hY => ((idZeroEquivIsoZero X) hX, (idZeroEquivIsoZero Y) hY))
    (_ : (X ≅ 0) × (Y ≅ 0) → 𝟙 X = 0 ∧ 𝟙 Y = 0)

Next tactic:
aesop_cat
/-- A zero morphism `0 : X ⟶ Y` is an isomorphism if and only if
`X` and `Y` are isomorphic to the zero object.
-/
def isIsoZeroEquivIsoZero (X Y : C) : IsIso (0 : X ⟶ Y) ≃ (X ≅ 0) × (Y ≅ 0) := by
  -- This is lame, because `Prod` can't cope with `Prop`, so we can't use `Equiv.prodCongr`.
  refine' (isIsoZeroEquiv X Y).trans _
  symm
  fconstructor
  · rintro ⟨eX, eY⟩
    fconstructor
    exact (idZeroEquivIsoZero X).symm eX
    exact (idZeroEquivIsoZero Y).symm eY
  · rintro ⟨hX, hY⟩
    fconstructor
    exact (idZeroEquivIsoZero X) hX
    exact (idZeroEquivIsoZero Y) hY
  · aesop_cat
  · 

Proof state:
case right_inv
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
⊢ Function.RightInverse (fun a => And.casesOn a fun hX hY => ((idZeroEquivIsoZero X) hX, (idZeroEquivIsoZero Y) hY))
    (_ : (X ≅ 0) × (Y ≅ 0) → 𝟙 X = 0 ∧ 𝟙 Y = 0)

Next tactic:
aesop_cat
theorem isIso_of_source_target_iso_zero {X Y : C} (f : X ⟶ Y) (i : X ≅ 0) (j : Y ≅ 0) :
    IsIso f := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
f : X ⟶ Y
i : X ≅ 0
j : Y ≅ 0
⊢ IsIso f

Next tactic:
rw [zero_of_source_iso_zero f i]
theorem isIso_of_source_target_iso_zero {X Y : C} (f : X ⟶ Y) (i : X ≅ 0) (j : Y ≅ 0) :
    IsIso f := by
  rw [zero_of_source_iso_zero f i]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
X Y : C
f : X ⟶ Y
i : X ≅ 0
j : Y ≅ 0
⊢ IsIso 0

Next tactic:
exact (isIsoZeroEquivIsoZero _ _).invFun ⟨i, j⟩
/-- If there are zero morphisms, any initial object is a zero object. -/
theorem hasZeroObject_of_hasInitial_object [HasZeroMorphisms C] [HasInitial C] :
    HasZeroObject C := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasInitial C
⊢ HasZeroObject C

Next tactic:
refine' ⟨⟨⊥_ C, fun X => ⟨⟨⟨0⟩, by aesop_cat⟩⟩, fun X => ⟨⟨⟨0⟩, fun f => _⟩⟩⟩⟩
/-- If there are zero morphisms, any initial object is a zero object. -/
theorem hasZeroObject_of_hasInitial_object [HasZeroMorphisms C] [HasInitial C] :
    HasZeroObject C := by
  refine' ⟨⟨⊥_ C, fun X => ⟨⟨⟨0⟩, by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasInitial C
X : C
⊢ ∀ (a : ⊥_ C ⟶ X), a = default

Next tactic:
aesop_cat
/-- If there are zero morphisms, any initial object is a zero object. -/
theorem hasZeroObject_of_hasInitial_object [HasZeroMorphisms C] [HasInitial C] :
    HasZeroObject C := by
  refine' ⟨⟨⊥_ C, fun X => ⟨⟨⟨0⟩, by aesop_cat⟩⟩, fun X => ⟨⟨⟨0⟩, fun f => _⟩⟩⟩⟩
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasInitial C
X : C
f : X ⟶ ⊥_ C
⊢ f = default

Next tactic:
calc
    f = f ≫ 𝟙 _ := (Category.comp_id _).symm
    _ = f ≫ 0 := by congr!
    _ = 0 := HasZeroMorphisms.comp_zero _ _
/-- If there are zero morphisms, any initial object is a zero object. -/
theorem hasZeroObject_of_hasInitial_object [HasZeroMorphisms C] [HasInitial C] :
    HasZeroObject C := by
  refine' ⟨⟨⊥_ C, fun X => ⟨⟨⟨0⟩, by aesop_cat⟩⟩, fun X => ⟨⟨⟨0⟩, fun f => _⟩⟩⟩⟩
  calc
    f = f ≫ 𝟙 _ := (Category.comp_id _).symm
    _ = f ≫ 0 := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasInitial C
X : C
f : X ⟶ ⊥_ C
⊢ f ≫ 𝟙 (⊥_ C) = f ≫ 0

Next tactic:
congr!
/-- If there are zero morphisms, any terminal object is a zero object. -/
theorem hasZeroObject_of_hasTerminal_object [HasZeroMorphisms C] [HasTerminal C] :
    HasZeroObject C := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasTerminal C
⊢ HasZeroObject C

Next tactic:
refine' ⟨⟨⊤_ C, fun X => ⟨⟨⟨0⟩, fun f => _⟩⟩, fun X => ⟨⟨⟨0⟩, by aesop_cat⟩⟩⟩⟩
/-- If there are zero morphisms, any terminal object is a zero object. -/
theorem hasZeroObject_of_hasTerminal_object [HasZeroMorphisms C] [HasTerminal C] :
    HasZeroObject C := by
  refine' ⟨⟨⊤_ C, fun X => ⟨⟨⟨0⟩, fun f => _⟩⟩, fun X => ⟨⟨⟨0⟩, by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasTerminal C
X : C
⊢ ∀ (a : X ⟶ ⊤_ C), a = default

Next tactic:
aesop_cat
/-- If there are zero morphisms, any terminal object is a zero object. -/
theorem hasZeroObject_of_hasTerminal_object [HasZeroMorphisms C] [HasTerminal C] :
    HasZeroObject C := by
  refine' ⟨⟨⊤_ C, fun X => ⟨⟨⟨0⟩, fun f => _⟩⟩, fun X => ⟨⟨⟨0⟩, by aesop_cat⟩⟩⟩⟩
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasTerminal C
X : C
f : ⊤_ C ⟶ X
⊢ f = default

Next tactic:
calc
    f = 𝟙 _ ≫ f := (Category.id_comp _).symm
    _ = 0 ≫ f := by congr!
    _ = 0 := zero_comp
/-- If there are zero morphisms, any terminal object is a zero object. -/
theorem hasZeroObject_of_hasTerminal_object [HasZeroMorphisms C] [HasTerminal C] :
    HasZeroObject C := by
  refine' ⟨⟨⊤_ C, fun X => ⟨⟨⟨0⟩, fun f => _⟩⟩, fun X => ⟨⟨⟨0⟩, by aesop_cat⟩⟩⟩⟩
  calc
    f = 𝟙 _ ≫ f := (Category.id_comp _).symm
    _ = 0 ≫ f := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
inst✝ : HasTerminal C
X : C
f : ⊤_ C ⟶ X
⊢ 𝟙 (⊤_ C) ≫ f = 0 ≫ f

Next tactic:
congr!
theorem image_ι_comp_eq_zero {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} [HasImage f]
    [Epi (factorThruImage f)] (h : f ≫ g = 0) : image.ι f ≫ g = 0 :=
  zero_of_epi_comp (factorThruImage f) <| by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
inst✝² : HasZeroMorphisms C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : HasImage f
inst✝ : Epi (factorThruImage f)
h : f ≫ g = 0
⊢ factorThruImage f ≫ image.ι f ≫ g = 0

Next tactic:
simp [h]
theorem comp_factorThruImage_eq_zero {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z} [HasImage g]
    (h : f ≫ g = 0) : f ≫ factorThruImage g = 0 :=
  zero_of_comp_mono (image.ι g) <| by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasZeroMorphisms C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝ : HasImage g
h : f ≫ g = 0
⊢ (f ≫ factorThruImage g) ≫ image.ι g = 0

Next tactic:
simp [h]
@[simp]
theorem image.ι_zero {X Y : C} [HasImage (0 : X ⟶ Y)] : image.ι (0 : X ⟶ Y) = 0 := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
inst✝² : HasZeroMorphisms C
inst✝¹ : HasZeroObject C
X Y : C
inst✝ : HasImage 0
⊢ ι 0 = 0

Next tactic:
rw [← image.lift_fac (monoFactorisationZero X Y)]
@[simp]
theorem image.ι_zero {X Y : C} [HasImage (0 : X ⟶ Y)] : image.ι (0 : X ⟶ Y) = 0 := by
  rw [← image.lift_fac (monoFactorisationZero X Y)]
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
inst✝² : HasZeroMorphisms C
inst✝¹ : HasZeroObject C
X Y : C
inst✝ : HasImage 0
⊢ lift (monoFactorisationZero X Y) ≫ (monoFactorisationZero X Y).m = 0

Next tactic:
simp
/-- If we know `f = 0`,
it requires a little work to conclude `image.ι f = 0`,
because `f = g` only implies `image f ≅ image g`.
-/
@[simp]
theorem image.ι_zero' [HasEqualizers C] {X Y : C} {f : X ⟶ Y} (h : f = 0) [HasImage f] :
    image.ι f = 0 := by
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
inst✝³ : HasZeroMorphisms C
inst✝² : HasZeroObject C
inst✝¹ : HasEqualizers C
X Y : C
f : X ⟶ Y
h : f = 0
inst✝ : HasImage f
⊢ ι f = 0

Next tactic:
rw [image.eq_fac h]
/-- If we know `f = 0`,
it requires a little work to conclude `image.ι f = 0`,
because `f = g` only implies `image f ≅ image g`.
-/
@[simp]
theorem image.ι_zero' [HasEqualizers C] {X Y : C} {f : X ⟶ Y} (h : f = 0) [HasImage f] :
    image.ι f = 0 := by
  rw [image.eq_fac h]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
inst✝³ : HasZeroMorphisms C
inst✝² : HasZeroObject C
inst✝¹ : HasEqualizers C
X Y : C
f : X ⟶ Y
h : f = 0
inst✝ : HasImage f
⊢ (eqToIso h).hom ≫ ι 0 = 0

Next tactic:
simp
protected theorem Periodic.comp [Add α] (h : Periodic f c) (g : β → γ) : Periodic (g ∘ f) c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g✝ : α → β
c c₁ c₂ x : α
inst✝ : Add α
h : Periodic f c
g : β → γ
⊢ Periodic (g ∘ f) c

Next tactic:
simp_all
theorem Periodic.comp_addHom [Add α] [Add γ] (h : Periodic f c) (g : AddHom γ α) (g_inv : α → γ)
    (hg : RightInverse g_inv g) : Periodic (f ∘ g) (g_inv c) := fun x => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g✝ : α → β
c c₁ c₂ x✝ : α
inst✝¹ : Add α
inst✝ : Add γ
h : Periodic f c
g : AddHom γ α
g_inv : α → γ
hg : RightInverse g_inv ⇑g
x : γ
⊢ (f ∘ ⇑g) (x + g_inv c) = (f ∘ ⇑g) x

Next tactic:
simp only [hg c, h (g x), map_add, comp_apply]
@[to_additive]
protected theorem Periodic.mul [Add α] [Mul β] (hf : Periodic f c) (hg : Periodic g c) :
    Periodic (f * g) c := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : Mul β
hf : Periodic f c
hg : Periodic g c
⊢ Periodic (f * g) c

Next tactic:
simp_all
@[to_additive]
protected theorem Periodic.div [Add α] [Div β] (hf : Periodic f c) (hg : Periodic g c) :
    Periodic (f / g) c := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : Div β
hf : Periodic f c
hg : Periodic g c
⊢ Periodic (f / g) c

Next tactic:
simp_all
@[to_additive]
theorem _root_.List.periodic_prod [Add α] [Monoid β] (l : List (α → β))
    (hl : ∀ f ∈ l, Periodic f c) : Periodic l.prod c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : Monoid β
l : List (α → β)
hl : ∀ f ∈ l, Periodic f c
⊢ Periodic (List.prod l) c

Next tactic:
induction' l with g l ih hl
@[to_additive]
theorem _root_.List.periodic_prod [Add α] [Monoid β] (l : List (α → β))
    (hl : ∀ f ∈ l, Periodic f c) : Periodic l.prod c := by
  induction' l with g l ih hl
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : Monoid β
hl : ∀ f ∈ [], Periodic f c
⊢ Periodic (List.prod []) c

Next tactic:
simp
@[to_additive]
theorem _root_.List.periodic_prod [Add α] [Monoid β] (l : List (α → β))
    (hl : ∀ f ∈ l, Periodic f c) : Periodic l.prod c := by
  induction' l with g l ih hl
  · simp
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
f g✝ : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : Monoid β
g : α → β
l : List (α → β)
ih : (∀ f ∈ l, Periodic f c) → Periodic (List.prod l) c
hl : ∀ f ∈ g :: l, Periodic f c
⊢ Periodic (List.prod (g :: l)) c

Next tactic:
rw [List.forall_mem_cons] at hl
@[to_additive]
theorem _root_.List.periodic_prod [Add α] [Monoid β] (l : List (α → β))
    (hl : ∀ f ∈ l, Periodic f c) : Periodic l.prod c := by
  induction' l with g l ih hl
  · simp
  · rw [List.forall_mem_cons] at hl
    

Proof state:
case cons
α : Type u_1
β : Type u_2
γ : Type u_3
f g✝ : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : Monoid β
g : α → β
l : List (α → β)
ih : (∀ f ∈ l, Periodic f c) → Periodic (List.prod l) c
hl : Periodic g c ∧ ∀ x ∈ l, Periodic x c
⊢ Periodic (List.prod (g :: l)) c

Next tactic:
simpa only [List.prod_cons] using hl.1.mul (ih hl.2)
@[to_additive]
theorem _root_.Finset.periodic_prod [Add α] [CommMonoid β] {ι : Type*} {f : ι → α → β}
    (s : Finset ι) (hs : ∀ i ∈ s, Periodic (f i) c) : Periodic (∏ i in s, f i) c :=
  s.prod_to_list f ▸ (s.toList.map f).periodic_prod (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ g : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : CommMonoid β
ι : Type u_4
f : ι → α → β
s : Finset ι
hs : ∀ i ∈ s, Periodic (f i) c
⊢ ∀ f_1 ∈ List.map f (Finset.toList s), Periodic f_1 c

Next tactic:
simpa [-Periodic]
@[to_additive]
protected theorem Periodic.smul [Add α] [SMul γ β] (h : Periodic f c) (a : γ) :
    Periodic (a • f) c := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝¹ : Add α
inst✝ : SMul γ β
h : Periodic f c
a : γ
⊢ Periodic (a • f) c

Next tactic:
simp_all
protected theorem Periodic.const_smul [AddMonoid α] [Group γ] [DistribMulAction γ α]
    (h : Periodic f c) (a : γ) : Periodic (fun x => f (a • x)) (a⁻¹ • c) := fun x => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝² : AddMonoid α
inst✝¹ : Group γ
inst✝ : DistribMulAction γ α
h : Periodic f c
a : γ
x : α
⊢ (fun x => f (a • x)) (x + a⁻¹ • c) = (fun x => f (a • x)) x

Next tactic:
simpa only [smul_add, smul_inv_smul] using h (a • x)
protected theorem Periodic.const_smul₀ [AddCommMonoid α] [DivisionSemiring γ] [Module γ α]
    (h : Periodic f c) (a : γ) : Periodic (fun x => f (a • x)) (a⁻¹ • c) := fun x => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝² : AddCommMonoid α
inst✝¹ : DivisionSemiring γ
inst✝ : Module γ α
h : Periodic f c
a : γ
x : α
⊢ (fun x => f (a • x)) (x + a⁻¹ • c) = (fun x => f (a • x)) x

Next tactic:
by_cases ha : a = 0
protected theorem Periodic.const_smul₀ [AddCommMonoid α] [DivisionSemiring γ] [Module γ α]
    (h : Periodic f c) (a : γ) : Periodic (fun x => f (a • x)) (a⁻¹ • c) := fun x => by
  by_cases ha : a = 0
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝² : AddCommMonoid α
inst✝¹ : DivisionSemiring γ
inst✝ : Module γ α
h : Periodic f c
a : γ
x : α
ha : a = 0
⊢ (fun x => f (a • x)) (x + a⁻¹ • c) = (fun x => f (a • x)) x

Next tactic:
simp only [ha, zero_smul]
protected theorem Periodic.const_smul₀ [AddCommMonoid α] [DivisionSemiring γ] [Module γ α]
    (h : Periodic f c) (a : γ) : Periodic (fun x => f (a • x)) (a⁻¹ • c) := fun x => by
  by_cases ha : a = 0
  · simp only [ha, zero_smul]
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝² : AddCommMonoid α
inst✝¹ : DivisionSemiring γ
inst✝ : Module γ α
h : Periodic f c
a : γ
x : α
ha : ¬a = 0
⊢ (fun x => f (a • x)) (x + a⁻¹ • c) = (fun x => f (a • x)) x

Next tactic:
simpa only [smul_add, smul_inv_smul₀ ha] using h (a • x)
theorem Periodic.const_inv_smul [AddMonoid α] [Group γ] [DistribMulAction γ α] (h : Periodic f c)
    (a : γ) : Periodic (fun x => f (a⁻¹ • x)) (a • c) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝² : AddMonoid α
inst✝¹ : Group γ
inst✝ : DistribMulAction γ α
h : Periodic f c
a : γ
⊢ Periodic (fun x => f (a⁻¹ • x)) (a • c)

Next tactic:
simpa only [inv_inv] using h.const_smul a⁻¹
theorem Periodic.const_inv_smul₀ [AddCommMonoid α] [DivisionSemiring γ] [Module γ α]
    (h : Periodic f c) (a : γ) : Periodic (fun x => f (a⁻¹ • x)) (a • c) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝² : AddCommMonoid α
inst✝¹ : DivisionSemiring γ
inst✝ : Module γ α
h : Periodic f c
a : γ
⊢ Periodic (fun x => f (a⁻¹ • x)) (a • c)

Next tactic:
simpa only [inv_inv] using h.const_smul₀ a⁻¹
theorem Periodic.mul_const' [DivisionSemiring α] (h : Periodic f c) (a : α) :
    Periodic (fun x => f (x * a)) (c / a) := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : DivisionSemiring α
h : Periodic f c
a : α
⊢ Periodic (fun x => f (x * a)) (c / a)

Next tactic:
simpa only [div_eq_mul_inv] using h.mul_const a
theorem Periodic.div_const [DivisionSemiring α] (h : Periodic f c) (a : α) :
    Periodic (fun x => f (x / a)) (c * a) := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : DivisionSemiring α
h : Periodic f c
a : α
⊢ Periodic (fun x => f (x / a)) (c * a)

Next tactic:
simpa only [div_eq_mul_inv] using h.mul_const_inv a
theorem Periodic.add_period [AddSemigroup α] (h1 : Periodic f c₁) (h2 : Periodic f c₂) :
    Periodic f (c₁ + c₂) := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : AddSemigroup α
h1 : Periodic f c₁
h2 : Periodic f c₂
⊢ Periodic f (c₁ + c₂)

Next tactic:
simp_all [← add_assoc]
theorem Periodic.sub_eq [AddGroup α] (h : Periodic f c) (x : α) : f (x - c) = f x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝ : AddGroup α
h : Periodic f c
x : α
⊢ f (x - c) = f x

Next tactic:
simpa only [sub_add_cancel] using (h (x - c)).symm
theorem Periodic.sub_eq' [AddCommGroup α] (h : Periodic f c) : f (c - x) = f (-x) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : AddCommGroup α
h : Periodic f c
⊢ f (c - x) = f (-x)

Next tactic:
simpa only [sub_eq_neg_add] using h (-x)
protected theorem Periodic.neg [AddGroup α] (h : Periodic f c) : Periodic f (-c) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : AddGroup α
h : Periodic f c
⊢ Periodic f (-c)

Next tactic:
simpa only [sub_eq_add_neg, Periodic] using h.sub_eq
theorem Periodic.sub_period [AddGroup α] (h1 : Periodic f c₁) (h2 : Periodic f c₂) :
    Periodic f (c₁ - c₂) := fun x => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝ : AddGroup α
h1 : Periodic f c₁
h2 : Periodic f c₂
x : α
⊢ f (x + (c₁ - c₂)) = f x

Next tactic:
rw [sub_eq_add_neg, ← add_assoc, h2.neg, h1]
theorem Periodic.const_add [AddSemigroup α] (h : Periodic f c) (a : α) :
    Periodic (fun x => f (a + x)) c := fun x => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝ : AddSemigroup α
h : Periodic f c
a x : α
⊢ (fun x => f (a + x)) (x + c) = (fun x => f (a + x)) x

Next tactic:
simpa [add_assoc] using h (a + x)
theorem Periodic.add_const [AddCommSemigroup α] (h : Periodic f c) (a : α) :
    Periodic (fun x => f (x + a)) c := fun x => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝ : AddCommSemigroup α
h : Periodic f c
a x : α
⊢ (fun x => f (x + a)) (x + c) = (fun x => f (x + a)) x

Next tactic:
simpa only [add_right_comm] using h (x + a)
theorem Periodic.const_sub [AddCommGroup α] (h : Periodic f c) (a : α) :
    Periodic (fun x => f (a - x)) c := fun x => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x✝ : α
inst✝ : AddCommGroup α
h : Periodic f c
a x : α
⊢ (fun x => f (a - x)) (x + c) = (fun x => f (a - x)) x

Next tactic:
simp only [← sub_sub, h.sub_eq]
theorem Periodic.sub_const [AddCommGroup α] (h : Periodic f c) (a : α) :
    Periodic (fun x => f (x - a)) c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : AddCommGroup α
h : Periodic f c
a : α
⊢ Periodic (fun x => f (x - a)) c

Next tactic:
simpa only [sub_eq_add_neg] using h.add_const (-a)
theorem Periodic.nsmul [AddMonoid α] (h : Periodic f c) (n : ℕ) : Periodic f (n • c) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : AddMonoid α
h : Periodic f c
n : ℕ
⊢ Periodic f (n • c)

Next tactic:
induction n
theorem Periodic.nsmul [AddMonoid α] (h : Periodic f c) (n : ℕ) : Periodic f (n • c) := by
  induction n <;> 

Proof state:
case zero
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : AddMonoid α
h : Periodic f c
⊢ Periodic f (Nat.zero • c)

Next tactic:
simp_all [Nat.succ_eq_add_one, add_nsmul, ← add_assoc, zero_nsmul]
theorem Periodic.nsmul [AddMonoid α] (h : Periodic f c) (n : ℕ) : Periodic f (n • c) := by
  induction n <;> 

Proof state:
case succ
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : AddMonoid α
h : Periodic f c
n✝ : ℕ
n_ih✝ : Periodic f (n✝ • c)
⊢ Periodic f (Nat.succ n✝ • c)

Next tactic:
simp_all [Nat.succ_eq_add_one, add_nsmul, ← add_assoc, zero_nsmul]
theorem Periodic.nat_mul [Semiring α] (h : Periodic f c) (n : ℕ) : Periodic f (n * c) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f g : α → β
c c₁ c₂ x : α
inst✝ : Semiring α
h : Periodic f c
n : ℕ
⊢ Periodic f (↑n * c)

Next tactic:
simpa only [nsmul_eq_mul] using h.nsmul n