l3lab/ntp-mathlib huggingface dataset:
/--
the map `limᵢ (Gᵢ ⊗ M) → (limᵢ Gᵢ) ⊗ M` induced by the family of maps `Gᵢ ⊗ M → (limᵢ Gᵢ) ⊗ M`
given by `gᵢ ⊗ m ↦ [gᵢ] ⊗ m`.
-/
noncomputable def fromDirectLimit :
    DirectLimit (G · ⊗[R] M) (f ▷ M) →ₗ[R] DirectLimit G f ⊗[R] M :=
  DirectLimit.lift _ _ _ _ (fun _ ↦ (of _ _ _ _ _).rTensor M)
    fun _ _ _ x ↦ by 

Proof state:
R : Type u_1
inst✝⁶ : CommRing R
ι : Type u_2
inst✝⁵ : DecidableEq ι
inst✝⁴ : Preorder ι
G : ι → Type u_3
inst✝³ : (i : ι) → AddCommGroup (G i)
inst✝² : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝¹ : AddCommGroup M
inst✝ : Module R M
x✝² x✝¹ : ι
x✝ : x✝² ≤ x✝¹
x : G x✝² ⊗[R] M
⊢ ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝¹) ((LinearMap.rTensor M (f x✝² x✝¹ x✝)) x) =
    ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝²) x

Next tactic:
refine' x.induction_on _ _ _
/--
the map `limᵢ (Gᵢ ⊗ M) → (limᵢ Gᵢ) ⊗ M` induced by the family of maps `Gᵢ ⊗ M → (limᵢ Gᵢ) ⊗ M`
given by `gᵢ ⊗ m ↦ [gᵢ] ⊗ m`.
-/
noncomputable def fromDirectLimit :
    DirectLimit (G · ⊗[R] M) (f ▷ M) →ₗ[R] DirectLimit G f ⊗[R] M :=
  DirectLimit.lift _ _ _ _ (fun _ ↦ (of _ _ _ _ _).rTensor M)
    fun _ _ _ x ↦ by refine' x.induction_on _ _ _ <;> 

Proof state:
case refine'_1
R : Type u_1
inst✝⁶ : CommRing R
ι : Type u_2
inst✝⁵ : DecidableEq ι
inst✝⁴ : Preorder ι
G : ι → Type u_3
inst✝³ : (i : ι) → AddCommGroup (G i)
inst✝² : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝¹ : AddCommGroup M
inst✝ : Module R M
x✝² x✝¹ : ι
x✝ : x✝² ≤ x✝¹
x : G x✝² ⊗[R] M
⊢ ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝¹) ((LinearMap.rTensor M (f x✝² x✝¹ x✝)) 0) =
    ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝²) 0

Next tactic:
aesop
/--
the map `limᵢ (Gᵢ ⊗ M) → (limᵢ Gᵢ) ⊗ M` induced by the family of maps `Gᵢ ⊗ M → (limᵢ Gᵢ) ⊗ M`
given by `gᵢ ⊗ m ↦ [gᵢ] ⊗ m`.
-/
noncomputable def fromDirectLimit :
    DirectLimit (G · ⊗[R] M) (f ▷ M) →ₗ[R] DirectLimit G f ⊗[R] M :=
  DirectLimit.lift _ _ _ _ (fun _ ↦ (of _ _ _ _ _).rTensor M)
    fun _ _ _ x ↦ by refine' x.induction_on _ _ _ <;> 

Proof state:
case refine'_2
R : Type u_1
inst✝⁶ : CommRing R
ι : Type u_2
inst✝⁵ : DecidableEq ι
inst✝⁴ : Preorder ι
G : ι → Type u_3
inst✝³ : (i : ι) → AddCommGroup (G i)
inst✝² : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝¹ : AddCommGroup M
inst✝ : Module R M
x✝² x✝¹ : ι
x✝ : x✝² ≤ x✝¹
x : G x✝² ⊗[R] M
⊢ ∀ (x : G x✝²) (y : M),
    ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝¹) ((LinearMap.rTensor M (f x✝² x✝¹ x✝)) (x ⊗ₜ[R] y)) =
      ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝²) (x ⊗ₜ[R] y)

Next tactic:
aesop
/--
the map `limᵢ (Gᵢ ⊗ M) → (limᵢ Gᵢ) ⊗ M` induced by the family of maps `Gᵢ ⊗ M → (limᵢ Gᵢ) ⊗ M`
given by `gᵢ ⊗ m ↦ [gᵢ] ⊗ m`.
-/
noncomputable def fromDirectLimit :
    DirectLimit (G · ⊗[R] M) (f ▷ M) →ₗ[R] DirectLimit G f ⊗[R] M :=
  DirectLimit.lift _ _ _ _ (fun _ ↦ (of _ _ _ _ _).rTensor M)
    fun _ _ _ x ↦ by refine' x.induction_on _ _ _ <;> 

Proof state:
case refine'_3
R : Type u_1
inst✝⁶ : CommRing R
ι : Type u_2
inst✝⁵ : DecidableEq ι
inst✝⁴ : Preorder ι
G : ι → Type u_3
inst✝³ : (i : ι) → AddCommGroup (G i)
inst✝² : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝¹ : AddCommGroup M
inst✝ : Module R M
x✝² x✝¹ : ι
x✝ : x✝² ≤ x✝¹
x : G x✝² ⊗[R] M
⊢ ∀ (x y : G x✝² ⊗[R] M),
    ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝¹) ((LinearMap.rTensor M (f x✝² x✝¹ x✝)) x) =
        ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝²) x →
      ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝¹) ((LinearMap.rTensor M (f x✝² x✝¹ x✝)) y) =
          ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝²) y →
        ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝¹) ((LinearMap.rTensor M (f x✝² x✝¹ x✝)) (x + y)) =
          ((fun x => LinearMap.rTensor M (of R ι G f x)) x✝²) (x + y)

Next tactic:
aesop
variable {M} in
@[simp] lemma toDirectLimit_tmul_of
    {i : ι} (g : G i) (m : M) :
    (toDirectLimit f M <| (of _ _ G f i g) ⊗ₜ m) = (of _ _ _ _ i (g ⊗ₜ m)) := by
  

Proof state:
R : Type u_1
inst✝⁶ : CommRing R
ι : Type u_2
inst✝⁵ : DecidableEq ι
inst✝⁴ : Preorder ι
G : ι → Type u_3
inst✝³ : (i : ι) → AddCommGroup (G i)
inst✝² : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝¹ : AddCommGroup M
inst✝ : Module R M
i : ι
g : G i
m : M
⊢ (toDirectLimit f M) ((of R ι G f i) g ⊗ₜ[R] m) =
    (of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) (g ⊗ₜ[R] m)

Next tactic:
rw [toDirectLimit, lift.tmul, lift_of]
variable {M} in
@[simp] lemma toDirectLimit_tmul_of
    {i : ι} (g : G i) (m : M) :
    (toDirectLimit f M <| (of _ _ G f i g) ⊗ₜ m) = (of _ _ _ _ i (g ⊗ₜ m)) := by
  rw [toDirectLimit, lift.tmul, lift_of]
  

Proof state:
R : Type u_1
inst✝⁶ : CommRing R
ι : Type u_2
inst✝⁵ : DecidableEq ι
inst✝⁴ : Preorder ι
G : ι → Type u_3
inst✝³ : (i : ι) → AddCommGroup (G i)
inst✝² : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝¹ : AddCommGroup M
inst✝ : Module R M
i : ι
g : G i
m : M
⊢ ((LinearMap.compr₂ (mk R (G i) M) (of R ι (fun _i => G _i ⊗[R] M) (fun _i _j h => LinearMap.rTensor M (f _i _j h)) i))
        g)
      m =
    (of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) (g ⊗ₜ[R] m)

Next tactic:
rfl
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  

Proof state:
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
⊢ DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (fun x => G x ⊗[R] M) fun i j h => LinearMap.rTensor M (f i j h)

Next tactic:
refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> 

Proof state:
case refine_1
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
⊢ LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M) = LinearMap.id

Next tactic:
cases isEmpty_or_nonempty ι
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> 

Proof state:
case refine_2
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
⊢ LinearMap.comp (fromDirectLimit f M) (toDirectLimit f M) = LinearMap.id

Next tactic:
cases isEmpty_or_nonempty ι
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · 

Proof state:
case refine_1.inl
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : IsEmpty ι
⊢ LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M) = LinearMap.id

Next tactic:
ext
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; 

Proof state:
case refine_1.inl.h
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : IsEmpty ι
x✝ : DirectLimit (fun x => G x ⊗[R] M) fun i j h => LinearMap.rTensor M (f i j h)
⊢ (LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M)) x✝ = LinearMap.id x✝

Next tactic:
apply Subsingleton.elim
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · 

Proof state:
case refine_1.inr
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : Nonempty ι
⊢ LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M) = LinearMap.id

Next tactic:
refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_ <;> 

Proof state:
case refine_1.inr.refine_1
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : Nonempty ι
x : DirectLimit (fun x => G x ⊗[R] M) fun i j h => LinearMap.rTensor M (f i j h)
i : ι
g : G i ⊗[R] M
⊢ (LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M))
      ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) 0) =
    LinearMap.id ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) 0)

Next tactic:
aesop
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_ <;> 

Proof state:
case refine_1.inr.refine_2
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : Nonempty ι
x : DirectLimit (fun x => G x ⊗[R] M) fun i j h => LinearMap.rTensor M (f i j h)
i : ι
g : G i ⊗[R] M
⊢ ∀ (x : G i) (y : M),
    (LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M))
        ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) (x ⊗ₜ[R] y)) =
      LinearMap.id ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) (x ⊗ₜ[R] y))

Next tactic:
aesop
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_ <;> 

Proof state:
case refine_1.inr.refine_3
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : Nonempty ι
x : DirectLimit (fun x => G x ⊗[R] M) fun i j h => LinearMap.rTensor M (f i j h)
i : ι
g : G i ⊗[R] M
⊢ ∀ (x y : G i ⊗[R] M),
    (LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M))
          ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) x) =
        LinearMap.id ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) x) →
      (LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M))
            ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) y) =
          LinearMap.id ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) y) →
        (LinearMap.comp (toDirectLimit f M) (fromDirectLimit f M))
            ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) (x + y)) =
          LinearMap.id ((of R ι (fun x => G x ⊗[R] M) (fun i j h => LinearMap.rTensor M (f i j h)) i) (x + y))

Next tactic:
aesop
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_ <;> aesop
  · 

Proof state:
case refine_2.inl
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : IsEmpty ι
⊢ LinearMap.comp (fromDirectLimit f M) (toDirectLimit f M) = LinearMap.id

Next tactic:
ext
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_ <;> aesop
  · ext; 

Proof state:
case refine_2.inl.h
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : IsEmpty ι
x✝ : DirectLimit G f ⊗[R] M
⊢ (LinearMap.comp (fromDirectLimit f M) (toDirectLimit f M)) x✝ = LinearMap.id x✝

Next tactic:
apply Subsingleton.elim
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_ <;> aesop
  · ext; apply Subsingleton.elim
  · 

Proof state:
case refine_2.inr
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : Nonempty ι
⊢ LinearMap.comp (fromDirectLimit f M) (toDirectLimit f M) = LinearMap.id

Next tactic:
exact ext (FunLike.ext _ _ fun g ↦ FunLike.ext _ _ fun _ ↦ g.induction_on <| by aesop)
/--
`limᵢ (Gᵢ ⊗ M)` and `(limᵢ Gᵢ) ⊗ M` are isomorphic as modules
-/
noncomputable def directLimitLeft :
    DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := by
  refine LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) ?_ ?_
    <;> cases isEmpty_or_nonempty ι
  · ext; apply Subsingleton.elim
  · refine FunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ g.induction_on ?_ ?_ ?_ <;> aesop
  · ext; apply Subsingleton.elim
  · exact ext (FunLike.ext _ _ fun g ↦ FunLike.ext _ _ fun _ ↦ g.induction_on <| by 

Proof state:
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
h✝ : Nonempty ι
g : DirectLimit G f
x✝ : M
⊢ ∀ (i : ι) (x : G i),
    ((LinearMap.compr₂ (mk R (DirectLimit G f) M) (LinearMap.comp (fromDirectLimit f M) (toDirectLimit f M)))
          ((of R ι G f i) x))
        x✝ =
      ((LinearMap.compr₂ (mk R (DirectLimit G f) M) LinearMap.id) ((of R ι G f i) x)) x✝

Next tactic:
aesop
/--
`M ⊗ (limᵢ Gᵢ)` and `limᵢ (M ⊗ Gᵢ)` are isomorphic as modules
-/
noncomputable def directLimitRight :
    M ⊗[R] DirectLimit G f ≃ₗ[R] DirectLimit (M ⊗[R] G ·) (M ◁ f) :=
  TensorProduct.comm _ _ _ ≪≫ₗ directLimitLeft f M ≪≫ₗ
    Module.DirectLimit.congr (fun i ↦ TensorProduct.comm _ _ _)
      (fun i j h ↦ TensorProduct.ext <| FunLike.ext _ _ <| by 

Proof state:
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
i j : ι
h : i ≤ j
⊢ ∀ (x : G i),
    (LinearMap.compr₂ (mk R (G i) M) (↑((fun i => TensorProduct.comm R (G i) M) j) ∘ₗ LinearMap.rTensor M (f i j h)))
        x =
      (LinearMap.compr₂ (mk R (G i) M) (LinearMap.lTensor M (f i j h) ∘ₗ ↑((fun i => TensorProduct.comm R (G i) M) i)))
        x

Next tactic:
aesop
@[simp] lemma directLimitRight_tmul_of {i : ι} (m : M) (g : G i):
    directLimitRight f M (m ⊗ₜ of _ _ _ _ _ g) = of _ _ _ _ i (m ⊗ₜ g) := by
  

Proof state:
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
i : ι
m : M
g : G i
⊢ (directLimitRight f M) (m ⊗ₜ[R] (of R ι (fun i => G i) f i) g) =
    (of R ι (fun x => M ⊗[R] G x) (fun i j h => LinearMap.lTensor M (f i j h)) i) (m ⊗ₜ[R] g)

Next tactic:
simp [directLimitRight, congr_apply_of]
@[simp] lemma directLimitRight_symm_of_tmul {i : ι} (m : M) (g : G i) :
    (directLimitRight f M).symm (of _ _ _ _ _ (m ⊗ₜ g)) = m ⊗ₜ of _ _ _ f _ g := by
  

Proof state:
R : Type u_1
inst✝⁷ : CommRing R
ι : Type u_2
inst✝⁶ : DecidableEq ι
inst✝⁵ : Preorder ι
G : ι → Type u_3
inst✝⁴ : (i : ι) → AddCommGroup (G i)
inst✝³ : (i : ι) → Module R (G i)
f : (i j : ι) → i ≤ j → G i →ₗ[R] G j
M : Type u_4
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsDirected ι fun x x_1 => x ≤ x_1
i : ι
m : M
g : G i
⊢ (LinearEquiv.symm (directLimitRight f M))
      ((of R ι (fun x => M ⊗[R] G x) (fun i j h => LinearMap.lTensor M (f i j h)) i) (m ⊗ₜ[R] g)) =
    m ⊗ₜ[R] (of R ι (fun i => G i) f i) g

Next tactic:
simp [directLimitRight, congr_symm_apply_of]
theorem Commute.expUnitary_add {a b : selfAdjoint A} (h : Commute (a : A) (b : A)) :
    expUnitary (a + b) = expUnitary a * expUnitary b := by
  

Proof state:
A : Type u_1
inst✝⁵ : NormedRing A
inst✝⁴ : NormedAlgebra ℂ A
inst✝³ : StarRing A
inst✝² : ContinuousStar A
inst✝¹ : CompleteSpace A
inst✝ : StarModule ℂ A
a b : ↥(selfAdjoint A)
h : Commute ↑a ↑b
⊢ expUnitary (a + b) = expUnitary a * expUnitary b

Next tactic:
ext
theorem Commute.expUnitary_add {a b : selfAdjoint A} (h : Commute (a : A) (b : A)) :
    expUnitary (a + b) = expUnitary a * expUnitary b := by
  ext
  

Proof state:
case a
A : Type u_1
inst✝⁵ : NormedRing A
inst✝⁴ : NormedAlgebra ℂ A
inst✝³ : StarRing A
inst✝² : ContinuousStar A
inst✝¹ : CompleteSpace A
inst✝ : StarModule ℂ A
a b : ↥(selfAdjoint A)
h : Commute ↑a ↑b
⊢ ↑(expUnitary (a + b)) = ↑(expUnitary a * expUnitary b)

Next tactic:
have hcomm : Commute (I • (a : A)) (I • (b : A)) := by
    unfold Commute SemiconjBy
    simp only [h.eq, Algebra.smul_mul_assoc, Algebra.mul_smul_comm]
theorem Commute.expUnitary_add {a b : selfAdjoint A} (h : Commute (a : A) (b : A)) :
    expUnitary (a + b) = expUnitary a * expUnitary b := by
  ext
  have hcomm : Commute (I • (a : A)) (I • (b : A)) := by
    

Proof state:
A : Type u_1
inst✝⁵ : NormedRing A
inst✝⁴ : NormedAlgebra ℂ A
inst✝³ : StarRing A
inst✝² : ContinuousStar A
inst✝¹ : CompleteSpace A
inst✝ : StarModule ℂ A
a b : ↥(selfAdjoint A)
h : Commute ↑a ↑b
⊢ Commute (I • ↑a) (I • ↑b)

Next tactic:
unfold Commute SemiconjBy
theorem Commute.expUnitary_add {a b : selfAdjoint A} (h : Commute (a : A) (b : A)) :
    expUnitary (a + b) = expUnitary a * expUnitary b := by
  ext
  have hcomm : Commute (I • (a : A)) (I • (b : A)) := by
    unfold Commute SemiconjBy
    

Proof state:
A : Type u_1
inst✝⁵ : NormedRing A
inst✝⁴ : NormedAlgebra ℂ A
inst✝³ : StarRing A
inst✝² : ContinuousStar A
inst✝¹ : CompleteSpace A
inst✝ : StarModule ℂ A
a b : ↥(selfAdjoint A)
h : Commute ↑a ↑b
⊢ I • ↑a * I • ↑b = I • ↑b * I • ↑a

Next tactic:
simp only [h.eq, Algebra.smul_mul_assoc, Algebra.mul_smul_comm]
theorem Commute.expUnitary_add {a b : selfAdjoint A} (h : Commute (a : A) (b : A)) :
    expUnitary (a + b) = expUnitary a * expUnitary b := by
  ext
  have hcomm : Commute (I • (a : A)) (I • (b : A)) := by
    unfold Commute SemiconjBy
    simp only [h.eq, Algebra.smul_mul_assoc, Algebra.mul_smul_comm]
  

Proof state:
case a
A : Type u_1
inst✝⁵ : NormedRing A
inst✝⁴ : NormedAlgebra ℂ A
inst✝³ : StarRing A
inst✝² : ContinuousStar A
inst✝¹ : CompleteSpace A
inst✝ : StarModule ℂ A
a b : ↥(selfAdjoint A)
h : Commute ↑a ↑b
hcomm : Commute (I • ↑a) (I • ↑b)
⊢ ↑(expUnitary (a + b)) = ↑(expUnitary a * expUnitary b)

Next tactic:
simpa only [expUnitary_coe, AddSubgroup.coe_add, smul_add] using exp_add_of_commute hcomm
theorem Commute.expUnitary {a b : selfAdjoint A} (h : Commute (a : A) (b : A)) :
    Commute (expUnitary a) (expUnitary b) :=
  calc
    selfAdjoint.expUnitary a * selfAdjoint.expUnitary b =
        selfAdjoint.expUnitary b * selfAdjoint.expUnitary a := by
      

Proof state:
A : Type u_1
inst✝⁵ : NormedRing A
inst✝⁴ : NormedAlgebra ℂ A
inst✝³ : StarRing A
inst✝² : ContinuousStar A
inst✝¹ : CompleteSpace A
inst✝ : StarModule ℂ A
a b : ↥(selfAdjoint A)
h : Commute ↑a ↑b
⊢ selfAdjoint.expUnitary a * selfAdjoint.expUnitary b = selfAdjoint.expUnitary b * selfAdjoint.expUnitary a

Next tactic:
rw [← h.expUnitary_add, ← h.symm.expUnitary_add, add_comm]
theorem div_div_div_cancel_right (a : G₀) (hc : c ≠ 0) : a / c / (b / c) = a / b := by
  

Proof state:
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝¹ : MonoidWithZero M₀
inst✝ : GroupWithZero G₀
a✝ b c a : G₀
hc : c ≠ 0
⊢ a / c / (b / c) = a / b

Next tactic:
rw [div_div_eq_mul_div, div_mul_cancel _ hc]