l3lab/ntp-mathlib huggingface dataset:
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
    -- `touch` is injective
    have touch_inj : touch.Injective := fun C D h' => ComponentCompl.pairwise_disjoint.eq
      (Set.not_disjoint_iff.mpr ⟨touch C, (C.exists_adj_boundary_pair Gpc.out h).choose_spec.1,
                                 h'.symm ▸ (D.exists_adj_boundary_pair Gpc.out h).choose_spec.1⟩)
    -- `touch` has finite range
    have : Finite (Set.range touch) := by
      refine @Subtype.finite _ (Set.Finite.to_subtype ?_) _
      apply Set.Finite.ofFinset (K.biUnion (fun v => G.neighborFinset v))
      

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
h : Finset.Nonempty K
touch : ComponentCompl G ↑K → ↑{v | ∃ k ∈ K, Adj G k v} :=
  fun C =>
    let p := (_ : ∃ ck, ck.1 ∈ C ∧ (ck.2 ∈ fun x => x ∈ K.val) ∧ Adj G ck.1 ck.2);
    { val := (Exists.choose p).1, property := (_ : ∃ k ∈ K, Adj G k (Exists.choose p).1) }
touch_inj : Function.Injective touch
⊢ ∀ (x : V), (x ∈ Finset.biUnion K fun v => neighborFinset G v) ↔ x ∈ {v | ∃ k ∈ K, Adj G k v}

Next tactic:
simp only [Finset.mem_biUnion, mem_neighborFinset, Set.mem_setOf_eq, implies_true]
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
    -- `touch` is injective
    have touch_inj : touch.Injective := fun C D h' => ComponentCompl.pairwise_disjoint.eq
      (Set.not_disjoint_iff.mpr ⟨touch C, (C.exists_adj_boundary_pair Gpc.out h).choose_spec.1,
                                 h'.symm ▸ (D.exists_adj_boundary_pair Gpc.out h).choose_spec.1⟩)
    -- `touch` has finite range
    have : Finite (Set.range touch) := by
      refine @Subtype.finite _ (Set.Finite.to_subtype ?_) _
      apply Set.Finite.ofFinset (K.biUnion (fun v => G.neighborFinset v))
      simp only [Finset.mem_biUnion, mem_neighborFinset, Set.mem_setOf_eq, implies_true]
    -- hence `touch` has a finite domain
    

Proof state:
case inr
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
h : Finset.Nonempty K
touch : ComponentCompl G ↑K → ↑{v | ∃ k ∈ K, Adj G k v} :=
  fun C =>
    let p := (_ : ∃ ck, ck.1 ∈ C ∧ (ck.2 ∈ fun x => x ∈ K.val) ∧ Adj G ck.1 ck.2);
    { val := (Exists.choose p).1, property := (_ : ∃ k ∈ K, Adj G k (Exists.choose p).1) }
touch_inj : Function.Injective touch
this : Finite ↑(Set.range touch)
⊢ Finite (ComponentCompl G ↑K)

Next tactic:
apply Finite.of_injective_finite_range touch_inj
theorem end_hom_mk_of_mk {s} (sec : s ∈ G.end) {K L : (Finset V)ᵒᵖ} (h : L ⟶ K) {v : V}
    (vnL : v ∉ L.unop) (hs : s L = G.componentComplMk vnL) :
    s K = G.componentComplMk (Set.not_mem_subset (le_of_op_hom h : _ ⊆ _) vnL) := by
  

Proof state:
V : Type u
G : SimpleGraph V
K✝ L✝ L' M : Set V
s : (j : (Finset V)ᵒᵖ) → (componentComplFunctor G).obj j
sec : s ∈ SimpleGraph.end G
K L : (Finset V)ᵒᵖ
h : L ⟶ K
v : V
vnL : v ∉ L.unop
hs : s L = componentComplMk G vnL
⊢ s K = componentComplMk G (_ : v ∉ fun a => a ∈ K.unop.val)

Next tactic:
rw [← sec h, hs]
theorem end_hom_mk_of_mk {s} (sec : s ∈ G.end) {K L : (Finset V)ᵒᵖ} (h : L ⟶ K) {v : V}
    (vnL : v ∉ L.unop) (hs : s L = G.componentComplMk vnL) :
    s K = G.componentComplMk (Set.not_mem_subset (le_of_op_hom h : _ ⊆ _) vnL) := by
  rw [← sec h, hs]
  

Proof state:
V : Type u
G : SimpleGraph V
K✝ L✝ L' M : Set V
s : (j : (Finset V)ᵒᵖ) → (componentComplFunctor G).obj j
sec : s ∈ SimpleGraph.end G
K L : (Finset V)ᵒᵖ
h : L ⟶ K
v : V
vnL : v ∉ L.unop
hs : s L = componentComplMk G vnL
⊢ (componentComplFunctor G).map h (componentComplMk G vnL) = componentComplMk G (_ : v ∉ fun a => a ∈ K.unop.val)

Next tactic:
apply ComponentCompl.hom_mk _ (le_of_op_hom h : _ ⊆ _)
theorem infinite_iff_in_eventualRange {K : (Finset V)ᵒᵖ} (C : G.componentComplFunctor.obj K) :
    C.supp.Infinite ↔ C ∈ G.componentComplFunctor.eventualRange K := by
  

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : (Finset V)ᵒᵖ
C : (componentComplFunctor G).obj K
⊢ Set.Infinite (ComponentCompl.supp C) ↔ C ∈ Functor.eventualRange (componentComplFunctor G) K

Next tactic:
simp only [C.infinite_iff_in_all_ranges, CategoryTheory.Functor.eventualRange, Set.mem_iInter,
    Set.mem_range, componentComplFunctor_map]
theorem infinite_iff_in_eventualRange {K : (Finset V)ᵒᵖ} (C : G.componentComplFunctor.obj K) :
    C.supp.Infinite ↔ C ∈ G.componentComplFunctor.eventualRange K := by
  simp only [C.infinite_iff_in_all_ranges, CategoryTheory.Functor.eventualRange, Set.mem_iInter,
    Set.mem_range, componentComplFunctor_map]
  

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : (Finset V)ᵒᵖ
C : (componentComplFunctor G).obj K
⊢ (∀ (L : Finset V) (h : K.unop ⊆ L), ∃ D, ComponentCompl.hom h D = C) ↔
    ∀ (i : (Finset V)ᵒᵖ) (i_1 : i ⟶ K), ∃ y, ComponentCompl.hom (_ : K.unop ≤ i.unop) y = C

Next tactic:
exact
    ⟨fun h Lop KL => h Lop.unop (le_of_op_hom KL), fun h L KL =>
      h (Opposite.op L) (opHomOfLE KL)⟩
/-- The binomial `PMF`: the probability of observing exactly `i` “heads” in a sequence of `n`
independent coin tosses, each having probability `p` of coming up “heads”. -/
noncomputable
def binomial (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) :=
  .ofFintype (fun i => p^(i : ℕ) * (1-p)^((Fin.last n - i) : ℕ) * (n.choose i : ℕ)) (by
    

Proof state:
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ (Finset.sum Finset.univ fun a => (fun i => p ^ ↑i * (1 - p) ^ (↑(Fin.last n) - ↑i) * ↑(Nat.choose n ↑i)) a) = 1

Next tactic:
convert (add_pow p (1-p) n).symm
/-- The binomial `PMF`: the probability of observing exactly `i` “heads” in a sequence of `n`
independent coin tosses, each having probability `p` of coming up “heads”. -/
noncomputable
def binomial (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) :=
  .ofFintype (fun i => p^(i : ℕ) * (1-p)^((Fin.last n - i) : ℕ) * (n.choose i : ℕ)) (by
    convert (add_pow p (1-p) n).symm
    · 

Proof state:
case h.e'_2
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ (Finset.sum Finset.univ fun a => (fun i => p ^ ↑i * (1 - p) ^ (↑(Fin.last n) - ↑i) * ↑(Nat.choose n ↑i)) a) =
    Finset.sum (Finset.range (n + 1)) fun m => p ^ m * (1 - p) ^ (n - m) * ↑(Nat.choose n m)

Next tactic:
rw [Finset.sum_fin_eq_sum_range]
/-- The binomial `PMF`: the probability of observing exactly `i` “heads” in a sequence of `n`
independent coin tosses, each having probability `p` of coming up “heads”. -/
noncomputable
def binomial (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) :=
  .ofFintype (fun i => p^(i : ℕ) * (1-p)^((Fin.last n - i) : ℕ) * (n.choose i : ℕ)) (by
    convert (add_pow p (1-p) n).symm
    · rw [Finset.sum_fin_eq_sum_range]
      

Proof state:
case h.e'_2
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ (Finset.sum (Finset.range (n + 1)) fun i =>
      if h : i < n + 1 then
        (fun i => p ^ ↑i * (1 - p) ^ (↑(Fin.last n) - ↑i) * ↑(Nat.choose n ↑i)) { val := i, isLt := h }
      else 0) =
    Finset.sum (Finset.range (n + 1)) fun m => p ^ m * (1 - p) ^ (n - m) * ↑(Nat.choose n m)

Next tactic:
apply Finset.sum_congr rfl
/-- The binomial `PMF`: the probability of observing exactly `i` “heads” in a sequence of `n`
independent coin tosses, each having probability `p` of coming up “heads”. -/
noncomputable
def binomial (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) :=
  .ofFintype (fun i => p^(i : ℕ) * (1-p)^((Fin.last n - i) : ℕ) * (n.choose i : ℕ)) (by
    convert (add_pow p (1-p) n).symm
    · rw [Finset.sum_fin_eq_sum_range]
      apply Finset.sum_congr rfl
      

Proof state:
case h.e'_2
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ ∀ x ∈ Finset.range (n + 1),
    (if h : x < n + 1 then
        (fun i => p ^ ↑i * (1 - p) ^ (↑(Fin.last n) - ↑i) * ↑(Nat.choose n ↑i)) { val := x, isLt := h }
      else 0) =
      p ^ x * (1 - p) ^ (n - x) * ↑(Nat.choose n x)

Next tactic:
intro i hi
/-- The binomial `PMF`: the probability of observing exactly `i` “heads” in a sequence of `n`
independent coin tosses, each having probability `p` of coming up “heads”. -/
noncomputable
def binomial (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) :=
  .ofFintype (fun i => p^(i : ℕ) * (1-p)^((Fin.last n - i) : ℕ) * (n.choose i : ℕ)) (by
    convert (add_pow p (1-p) n).symm
    · rw [Finset.sum_fin_eq_sum_range]
      apply Finset.sum_congr rfl
      intro i hi
      

Proof state:
case h.e'_2
p : ℝ≥0∞
h : p ≤ 1
n i : ℕ
hi : i ∈ Finset.range (n + 1)
⊢ (if h : i < n + 1 then (fun i => p ^ ↑i * (1 - p) ^ (↑(Fin.last n) - ↑i) * ↑(Nat.choose n ↑i)) { val := i, isLt := h }
    else 0) =
    p ^ i * (1 - p) ^ (n - i) * ↑(Nat.choose n i)

Next tactic:
rw [Finset.mem_range] at hi
/-- The binomial `PMF`: the probability of observing exactly `i` “heads” in a sequence of `n`
independent coin tosses, each having probability `p` of coming up “heads”. -/
noncomputable
def binomial (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) :=
  .ofFintype (fun i => p^(i : ℕ) * (1-p)^((Fin.last n - i) : ℕ) * (n.choose i : ℕ)) (by
    convert (add_pow p (1-p) n).symm
    · rw [Finset.sum_fin_eq_sum_range]
      apply Finset.sum_congr rfl
      intro i hi
      rw [Finset.mem_range] at hi
      

Proof state:
case h.e'_2
p : ℝ≥0∞
h : p ≤ 1
n i : ℕ
hi : i < n + 1
⊢ (if h : i < n + 1 then (fun i => p ^ ↑i * (1 - p) ^ (↑(Fin.last n) - ↑i) * ↑(Nat.choose n ↑i)) { val := i, isLt := h }
    else 0) =
    p ^ i * (1 - p) ^ (n - i) * ↑(Nat.choose n i)

Next tactic:
rw [dif_pos hi, Fin.last]
/-- The binomial `PMF`: the probability of observing exactly `i` “heads” in a sequence of `n`
independent coin tosses, each having probability `p` of coming up “heads”. -/
noncomputable
def binomial (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) :=
  .ofFintype (fun i => p^(i : ℕ) * (1-p)^((Fin.last n - i) : ℕ) * (n.choose i : ℕ)) (by
    convert (add_pow p (1-p) n).symm
    · rw [Finset.sum_fin_eq_sum_range]
      apply Finset.sum_congr rfl
      intro i hi
      rw [Finset.mem_range] at hi
      rw [dif_pos hi, Fin.last]
    · 

Proof state:
case h.e'_3
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ 1 = (p + (1 - p)) ^ n

Next tactic:
simp [h]
@[simp]
theorem binomial_apply_zero (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) :
    binomial p h n 0 = (1-p)^n := by
  

Proof state:
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ (binomial p h n) 0 = (1 - p) ^ n

Next tactic:
simp [binomial_apply]
@[simp]
theorem binomial_apply_last (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) :
    binomial p h n (.last n) = p^n := by
  

Proof state:
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ (binomial p h n) (Fin.last n) = p ^ n

Next tactic:
simp [binomial_apply]
theorem binomial_apply_self (p : ℝ≥0∞) (h : p ≤ 1) (n : ℕ) :
    binomial p h n n = p^n := by 

Proof state:
p : ℝ≥0∞
h : p ≤ 1
n : ℕ
⊢ (binomial p h n) ↑n = p ^ n

Next tactic:
simp
/-- The binomial distribution on one coin is the bernoully distribution. -/
theorem binomial_one_eq_bernoulli (p : ℝ≥0∞) (h : p ≤ 1) :
    binomial p h 1 = (bernoulli p h).map (cond · 1 0) := by
  

Proof state:
p : ℝ≥0∞
h : p ≤ 1
⊢ binomial p h 1 = map (fun x => bif x then 1 else 0) (bernoulli p h)

Next tactic:
ext i
/-- The binomial distribution on one coin is the bernoully distribution. -/
theorem binomial_one_eq_bernoulli (p : ℝ≥0∞) (h : p ≤ 1) :
    binomial p h 1 = (bernoulli p h).map (cond · 1 0) := by
  ext i; 

Proof state:
case h
p : ℝ≥0∞
h : p ≤ 1
i : Fin (1 + 1)
⊢ (binomial p h 1) i = (map (fun x => bif x then 1 else 0) (bernoulli p h)) i

Next tactic:
fin_cases i
/-- The binomial distribution on one coin is the bernoully distribution. -/
theorem binomial_one_eq_bernoulli (p : ℝ≥0∞) (h : p ≤ 1) :
    binomial p h 1 = (bernoulli p h).map (cond · 1 0) := by
  ext i; fin_cases i <;> 

Proof state:
case h.head
p : ℝ≥0∞
h : p ≤ 1
⊢ (binomial p h 1) { val := 0, isLt := (_ : 0 < 1 + 1) } =
    (map (fun x => bif x then 1 else 0) (bernoulli p h)) { val := 0, isLt := (_ : 0 < 1 + 1) }

Next tactic:
simp [tsum_bool, binomial_apply]
/-- The binomial distribution on one coin is the bernoully distribution. -/
theorem binomial_one_eq_bernoulli (p : ℝ≥0∞) (h : p ≤ 1) :
    binomial p h 1 = (bernoulli p h).map (cond · 1 0) := by
  ext i; fin_cases i <;> 

Proof state:
case h.tail.head
p : ℝ≥0∞
h : p ≤ 1
⊢ (binomial p h 1) { val := 1, isLt := (_ : (fun a => a < 1 + 1) 1) } =
    (map (fun x => bif x then 1 else 0) (bernoulli p h)) { val := 1, isLt := (_ : (fun a => a < 1 + 1) 1) }

Next tactic:
simp [tsum_bool, binomial_apply]
instance preadditiveNatLinear : Linear ℕ C
    where
  smul_comp X Y Z r f g := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
X Y Z : C
r : ℕ
f : X ⟶ Y
g : Y ⟶ Z
⊢ (r • f) ≫ g = r • f ≫ g

Next tactic:
exact (Preadditive.rightComp X g).map_nsmul f r
instance preadditiveNatLinear : Linear ℕ C
    where
  smul_comp X Y Z r f g := by exact (Preadditive.rightComp X g).map_nsmul f r
  comp_smul X Y Z f r g := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
X Y Z : C
f : X ⟶ Y
r : ℕ
g : Y ⟶ Z
⊢ f ≫ (r • g) = r • f ≫ g

Next tactic:
exact (Preadditive.leftComp Z f).map_nsmul g r
instance preadditiveIntLinear : Linear ℤ C
    where
  smul_comp X Y Z r f g := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
X Y Z : C
r : ℤ
f : X ⟶ Y
g : Y ⟶ Z
⊢ (r • f) ≫ g = r • f ≫ g

Next tactic:
exact (Preadditive.rightComp X g).map_zsmul f r
instance preadditiveIntLinear : Linear ℤ C
    where
  smul_comp X Y Z r f g := by exact (Preadditive.rightComp X g).map_zsmul f r
  comp_smul X Y Z f r g := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
X Y Z : C
f : X ⟶ Y
r : ℤ
g : Y ⟶ Z
⊢ f ≫ (r • g) = r • f ≫ g

Next tactic:
exact (Preadditive.leftComp Z f).map_zsmul g r
instance [Semiring R] [Linear R C] (X : C) : Module R (End X) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X : C
⊢ Module R (End X)

Next tactic:
dsimp [End]
instance [Semiring R] [Linear R C] (X : C) : Module R (End X) := by
  dsimp [End]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X : C
⊢ Module R (X ⟶ X)

Next tactic:
infer_instance
/-- Composition by a fixed left argument as an `R`-linear map. -/
@[simps]
def leftComp {X Y : C} (Z : C) (f : X ⟶ Y) : (Y ⟶ Z) →ₗ[R] X ⟶ Z
    where
  toFun g := f ≫ g
  map_add' := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X Y Z : C
f : X ⟶ Y
⊢ ∀ (x y : Y ⟶ Z), (fun g => f ≫ g) (x + y) = (fun g => f ≫ g) x + (fun g => f ≫ g) y

Next tactic:
simp
/-- Composition by a fixed left argument as an `R`-linear map. -/
@[simps]
def leftComp {X Y : C} (Z : C) (f : X ⟶ Y) : (Y ⟶ Z) →ₗ[R] X ⟶ Z
    where
  toFun g := f ≫ g
  map_add' := by simp
  map_smul' := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X Y Z : C
f : X ⟶ Y
⊢ ∀ (r : R) (x : Y ⟶ Z),
    AddHom.toFun { toFun := fun g => f ≫ g, map_add' := (_ : ∀ (a a_1 : Y ⟶ Z), f ≫ (a + a_1) = f ≫ a + f ≫ a_1) }
        (r • x) =
      (RingHom.id R) r •
        AddHom.toFun { toFun := fun g => f ≫ g, map_add' := (_ : ∀ (a a_1 : Y ⟶ Z), f ≫ (a + a_1) = f ≫ a + f ≫ a_1) } x

Next tactic:
simp
/-- Composition by a fixed right argument as an `R`-linear map. -/
@[simps]
def rightComp (X : C) {Y Z : C} (g : Y ⟶ Z) : (X ⟶ Y) →ₗ[R] X ⟶ Z
    where
  toFun f := f ≫ g
  map_add' := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X Y Z : C
g : Y ⟶ Z
⊢ ∀ (x y : X ⟶ Y), (fun f => f ≫ g) (x + y) = (fun f => f ≫ g) x + (fun f => f ≫ g) y

Next tactic:
simp
/-- Composition by a fixed right argument as an `R`-linear map. -/
@[simps]
def rightComp (X : C) {Y Z : C} (g : Y ⟶ Z) : (X ⟶ Y) →ₗ[R] X ⟶ Z
    where
  toFun f := f ≫ g
  map_add' := by simp
  map_smul' := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X Y Z : C
g : Y ⟶ Z
⊢ ∀ (r : R) (x : X ⟶ Y),
    AddHom.toFun { toFun := fun f => f ≫ g, map_add' := (_ : ∀ (a a_1 : X ⟶ Y), (a + a_1) ≫ g = a ≫ g + a_1 ≫ g) }
        (r • x) =
      (RingHom.id R) r •
        AddHom.toFun { toFun := fun f => f ≫ g, map_add' := (_ : ∀ (a a_1 : X ⟶ Y), (a + a_1) ≫ g = a ≫ g + a_1 ≫ g) } x

Next tactic:
simp
instance {X Y : C} (f : X ⟶ Y) [Epi f] (r : R) [Invertible r] : Epi (r • f) :=
  ⟨fun g g' H => by
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
R : Type w
inst✝³ : Semiring R
inst✝² : Linear R C
X Y : C
f : X ⟶ Y
inst✝¹ : Epi f
r : R
inst✝ : Invertible r
Z✝ : C
g g' : Y ⟶ Z✝
H : (r • f) ≫ g = (r • f) ≫ g'
⊢ g = g'

Next tactic:
rw [smul_comp, smul_comp, ← comp_smul, ← comp_smul, cancel_epi] at H
instance {X Y : C} (f : X ⟶ Y) [Epi f] (r : R) [Invertible r] : Epi (r • f) :=
  ⟨fun g g' H => by
    rw [smul_comp, smul_comp, ← comp_smul, ← comp_smul, cancel_epi] at H
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
R : Type w
inst✝³ : Semiring R
inst✝² : Linear R C
X Y : C
f : X ⟶ Y
inst✝¹ : Epi f
r : R
inst✝ : Invertible r
Z✝ : C
g g' : Y ⟶ Z✝
H : r • g = r • g'
⊢ g = g'

Next tactic:
simpa [smul_smul] using congr_arg (fun f => ⅟ r • f) H
instance {X Y : C} (f : X ⟶ Y) [Mono f] (r : R) [Invertible r] : Mono (r • f) :=
  ⟨fun g g' H => by
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
R : Type w
inst✝³ : Semiring R
inst✝² : Linear R C
X Y : C
f : X ⟶ Y
inst✝¹ : Mono f
r : R
inst✝ : Invertible r
Z✝ : C
g g' : Z✝ ⟶ X
H : g ≫ (r • f) = g' ≫ (r • f)
⊢ g = g'

Next tactic:
rw [comp_smul, comp_smul, ← smul_comp, ← smul_comp, cancel_mono] at H
instance {X Y : C} (f : X ⟶ Y) [Mono f] (r : R) [Invertible r] : Mono (r • f) :=
  ⟨fun g g' H => by
    rw [comp_smul, comp_smul, ← smul_comp, ← smul_comp, cancel_mono] at H
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : Preadditive C
R : Type w
inst✝³ : Semiring R
inst✝² : Linear R C
X Y : C
f : X ⟶ Y
inst✝¹ : Mono f
r : R
inst✝ : Invertible r
Z✝ : C
g g' : Z✝ ⟶ X
H : r • g = r • g'
⊢ g = g'

Next tactic:
simpa [smul_smul] using congr_arg (fun f => ⅟ r • f) H
/-- Given isomorphic objects `X ≅ Y, W ≅ Z` in a `k`-linear category, we have a `k`-linear
isomorphism between `Hom(X, W)` and `Hom(Y, Z).` -/
def homCongr (k : Type*) {C : Type*} [Category C] [Semiring k] [Preadditive C] [Linear k C]
    {X Y W Z : C} (f₁ : X ≅ Y) (f₂ : W ≅ Z) : (X ⟶ W) ≃ₗ[k] Y ⟶ Z :=
  {
    (rightComp k Y f₂.hom).comp
      (leftComp k W
        f₁.symm.hom) with
    invFun := (leftComp k W f₁.hom).comp (rightComp k Y f₂.symm.hom)
    left_inv := fun x => by
      

Proof state:
C✝ : Type u
inst✝⁷ : Category.{v, u} C✝
inst✝⁶ : Preadditive C✝
R : Type w
inst✝⁵ : Semiring R
inst✝⁴ : Linear R C✝
k : Type u_1
C : Type u_2
inst✝³ : Category.{?u.36673, u_2} C
inst✝² : Semiring k
inst✝¹ : Preadditive C
inst✝ : Linear k C
X Y W Z : C
f₁ : X ≅ Y
f₂ : W ≅ Z
src✝ : (X ⟶ W) →ₗ[k] Y ⟶ Z := rightComp k Y f₂.hom ∘ₗ leftComp k W f₁.symm.hom
x : X ⟶ W
⊢ (leftComp k W f₁.hom ∘ₗ rightComp k Y f₂.symm.hom)
      (AddHom.toFun
        { toAddHom := src✝.toAddHom,
            map_smul' :=
              (_ :
                ∀ (r : k) (x : X ⟶ W),
                  AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id k) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
        x) =
    x

Next tactic:
simp only [Iso.symm_hom, LinearMap.toFun_eq_coe, LinearMap.coe_comp, Function.comp_apply,
        leftComp_apply, rightComp_apply, Category.assoc, Iso.hom_inv_id, Category.comp_id,
        Iso.hom_inv_id_assoc]
/-- Given isomorphic objects `X ≅ Y, W ≅ Z` in a `k`-linear category, we have a `k`-linear
isomorphism between `Hom(X, W)` and `Hom(Y, Z).` -/
def homCongr (k : Type*) {C : Type*} [Category C] [Semiring k] [Preadditive C] [Linear k C]
    {X Y W Z : C} (f₁ : X ≅ Y) (f₂ : W ≅ Z) : (X ⟶ W) ≃ₗ[k] Y ⟶ Z :=
  {
    (rightComp k Y f₂.hom).comp
      (leftComp k W
        f₁.symm.hom) with
    invFun := (leftComp k W f₁.hom).comp (rightComp k Y f₂.symm.hom)
    left_inv := fun x => by
      simp only [Iso.symm_hom, LinearMap.toFun_eq_coe, LinearMap.coe_comp, Function.comp_apply,
        leftComp_apply, rightComp_apply, Category.assoc, Iso.hom_inv_id, Category.comp_id,
        Iso.hom_inv_id_assoc]
    right_inv := fun x => by
      

Proof state:
C✝ : Type u
inst✝⁷ : Category.{v, u} C✝
inst✝⁶ : Preadditive C✝
R : Type w
inst✝⁵ : Semiring R
inst✝⁴ : Linear R C✝
k : Type u_1
C : Type u_2
inst✝³ : Category.{?u.36673, u_2} C
inst✝² : Semiring k
inst✝¹ : Preadditive C
inst✝ : Linear k C
X Y W Z : C
f₁ : X ≅ Y
f₂ : W ≅ Z
src✝ : (X ⟶ W) →ₗ[k] Y ⟶ Z := rightComp k Y f₂.hom ∘ₗ leftComp k W f₁.symm.hom
x : Y ⟶ Z
⊢ AddHom.toFun
      { toAddHom := src✝.toAddHom,
          map_smul' :=
            (_ :
              ∀ (r : k) (x : X ⟶ W),
                AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id k) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
      ((leftComp k W f₁.hom ∘ₗ rightComp k Y f₂.symm.hom) x) =
    x

Next tactic:
simp only [Iso.symm_hom, LinearMap.coe_comp, Function.comp_apply, rightComp_apply,
        leftComp_apply, LinearMap.toFun_eq_coe, Iso.inv_hom_id_assoc, Category.assoc,
        Iso.inv_hom_id, Category.comp_id]
@[simp]
lemma units_smul_comp {X Y Z : C} (r : Rˣ) (f : X ⟶ Y) (g : Y ⟶ Z) :
    (r • f) ≫ g = r • f ≫ g := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X Y Z : C
r : Rˣ
f : X ⟶ Y
g : Y ⟶ Z
⊢ (r • f) ≫ g = r • f ≫ g

Next tactic:
apply Linear.smul_comp
@[simp]
lemma comp_units_smul {X Y Z : C} (f : X ⟶ Y) (r : Rˣ) (g : Y ⟶ Z) :
    f ≫ (r • g) = r • f ≫ g := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type w
inst✝¹ : Semiring R
inst✝ : Linear R C
X Y Z : C
f : X ⟶ Y
r : Rˣ
g : Y ⟶ Z
⊢ f ≫ (r • g) = r • f ≫ g

Next tactic:
apply Linear.comp_smul
/-- Composition as a bilinear map. -/
@[simps]
def comp (X Y Z : C) : (X ⟶ Y) →ₗ[S] (Y ⟶ Z) →ₗ[S] X ⟶ Z
    where
  toFun f := leftComp S Z f
  map_add' := by
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
S : Type w
inst✝¹ : CommSemiring S
inst✝ : Linear S C
X Y Z : C
⊢ ∀ (x y : X ⟶ Y), (fun f => leftComp S Z f) (x + y) = (fun f => leftComp S Z f) x + (fun f => leftComp S Z f) y

Next tactic:
intros
/-- Composition as a bilinear map. -/
@[simps]
def comp (X Y Z : C) : (X ⟶ Y) →ₗ[S] (Y ⟶ Z) →ₗ[S] X ⟶ Z
    where
  toFun f := leftComp S Z f
  map_add' := by
    intros
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
S : Type w
inst✝¹ : CommSemiring S
inst✝ : Linear S C
X Y Z : C
x✝ y✝ : X ⟶ Y
⊢ (fun f => leftComp S Z f) (x✝ + y✝) = (fun f => leftComp S Z f) x✝ + (fun f => leftComp S Z f) y✝

Next tactic:
ext