l3lab/ntp-mathlib huggingface dataset:
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_7
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
x✝ : ULift.{?u.2214, u} α
⊢ x✝⁻¹.down = x✝.down⁻¹

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_8
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
x✝ y✝ : ULift.{?u.2214, u} α
⊢ (x✝ / y✝).down = x✝.down / y✝.down

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_9
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
x✝ : ULift.{?u.2214, u} α
n✝ : ℕ
⊢ (n✝ • x✝).down = n✝ • x✝.down

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_10
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
x✝ : ULift.{?u.2214, u} α
n✝ : ℤ
⊢ (n✝ • x✝).down = n✝ • x✝.down

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_11
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
x✝ : ULift.{?u.2214, u} α
n✝ : ℚ
⊢ (n✝ • x✝).down = n✝ • x✝.down

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_12
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
x✝ : ULift.{?u.2214, u} α
n✝ : ℕ
⊢ (x✝ ^ n✝).down = x✝.down ^ n✝

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_13
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
x✝ : ULift.{?u.2214, u} α
n✝ : ℤ
⊢ (x✝ ^ n✝).down = x✝.down ^ n✝

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_14
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
n✝ : ℕ
⊢ (↑n✝).down = ↑n✝

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_15
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
n✝ : ℤ
⊢ (↑n✝).down = ↑n✝

Next tactic:
rfl
instance divisionRing [DivisionRing α] : DivisionRing (ULift α) := by
  refine' down_injective.divisionRing down .. <;> intros <;> 

Proof state:
case refine'_16
α : Type u
x y : ULift.{v, u} α
inst✝ : DivisionRing α
n✝ : ℚ
⊢ (↑n✝).down = ↑n✝

Next tactic:
rfl
theorem updateFinset_singleton {i y} :
    updateFinset x {i} y = Function.update x i (y ⟨i, mem_singleton_self i⟩) := by
  

Proof state:
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : (i_1 : { x // x ∈ {i} }) → π ↑i_1
⊢ updateFinset x {i} y = update x i (y { val := i, property := (_ : i ∈ {i}) })

Next tactic:
congr with j
theorem updateFinset_singleton {i y} :
    updateFinset x {i} y = Function.update x i (y ⟨i, mem_singleton_self i⟩) := by
  congr with j
  

Proof state:
case h
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : (i_1 : { x // x ∈ {i} }) → π ↑i_1
j : ι
⊢ updateFinset x {i} y j = update x i (y { val := i, property := (_ : i ∈ {i}) }) j

Next tactic:
by_cases hj : j = i
theorem updateFinset_singleton {i y} :
    updateFinset x {i} y = Function.update x i (y ⟨i, mem_singleton_self i⟩) := by
  congr with j
  by_cases hj : j = i
  · 

Proof state:
case pos
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : (i_1 : { x // x ∈ {i} }) → π ↑i_1
j : ι
hj : j = i
⊢ updateFinset x {i} y j = update x i (y { val := i, property := (_ : i ∈ {i}) }) j

Next tactic:
cases hj
theorem updateFinset_singleton {i y} :
    updateFinset x {i} y = Function.update x i (y ⟨i, mem_singleton_self i⟩) := by
  congr with j
  by_cases hj : j = i
  · cases hj
    

Proof state:
case pos.refl
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : (i_1 : { x // x ∈ {i} }) → π ↑i_1
⊢ updateFinset x {i} y i = update x i (y { val := i, property := (_ : i ∈ {i}) }) i

Next tactic:
simp only [dif_pos, Finset.mem_singleton, update_same, updateFinset]
theorem updateFinset_singleton {i y} :
    updateFinset x {i} y = Function.update x i (y ⟨i, mem_singleton_self i⟩) := by
  congr with j
  by_cases hj : j = i
  · cases hj
    simp only [dif_pos, Finset.mem_singleton, update_same, updateFinset]
  · 

Proof state:
case neg
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : (i_1 : { x // x ∈ {i} }) → π ↑i_1
j : ι
hj : ¬j = i
⊢ updateFinset x {i} y j = update x i (y { val := i, property := (_ : i ∈ {i}) }) j

Next tactic:
simp [hj, updateFinset]
theorem update_eq_updateFinset {i y} :
    Function.update x i y = updateFinset x {i} (uniqueElim y) := by
  

Proof state:
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : π i
⊢ update x i y = updateFinset x {i} (uniqueElim y)

Next tactic:
congr with j
theorem update_eq_updateFinset {i y} :
    Function.update x i y = updateFinset x {i} (uniqueElim y) := by
  congr with j
  

Proof state:
case h
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : π i
j : ι
⊢ update x i y j = updateFinset x {i} (uniqueElim y) j

Next tactic:
by_cases hj : j = i
theorem update_eq_updateFinset {i y} :
    Function.update x i y = updateFinset x {i} (uniqueElim y) := by
  congr with j
  by_cases hj : j = i
  · 

Proof state:
case pos
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : π i
j : ι
hj : j = i
⊢ update x i y j = updateFinset x {i} (uniqueElim y) j

Next tactic:
cases hj
theorem update_eq_updateFinset {i y} :
    Function.update x i y = updateFinset x {i} (uniqueElim y) := by
  congr with j
  by_cases hj : j = i
  · cases hj
    

Proof state:
case pos.refl
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : π i
⊢ update x i y i = updateFinset x {i} (uniqueElim y) i

Next tactic:
simp only [dif_pos, Finset.mem_singleton, update_same, updateFinset]
theorem update_eq_updateFinset {i y} :
    Function.update x i y = updateFinset x {i} (uniqueElim y) := by
  congr with j
  by_cases hj : j = i
  · cases hj
    simp only [dif_pos, Finset.mem_singleton, update_same, updateFinset]
    

Proof state:
case pos.refl
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : π i
⊢ y = uniqueElim y { val := i, property := (_ : i ∈ {i}) }

Next tactic:
exact uniqueElim_default (α := fun j : ({i} : Finset ι) => π j) y
theorem update_eq_updateFinset {i y} :
    Function.update x i y = updateFinset x {i} (uniqueElim y) := by
  congr with j
  by_cases hj : j = i
  · cases hj
    simp only [dif_pos, Finset.mem_singleton, update_same, updateFinset]
    exact uniqueElim_default (α := fun j : ({i} : Finset ι) => π j) y
  · 

Proof state:
case neg
ι : Type u_1
π : ι → Sort u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
i : ι
y : π i
j : ι
hj : ¬j = i
⊢ update x i y j = updateFinset x {i} (uniqueElim y) j

Next tactic:
simp [hj, updateFinset]
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  

Proof state:
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
⊢ updateFinset (updateFinset x s y) t z = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z))

Next tactic:
set e := Equiv.Finset.union s t hst
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  

Proof state:
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
⊢ updateFinset (updateFinset x s y) t z = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z))

Next tactic:
congr with i
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  

Proof state:
case h
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
⊢ updateFinset (updateFinset x s y) t z i = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z)) i

Next tactic:
by_cases his : i ∈ s
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> 

Proof state:
case pos
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∈ s
⊢ updateFinset (updateFinset x s y) t z i = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z)) i

Next tactic:
by_cases hit : i ∈ t
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> 

Proof state:
case neg
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∉ s
⊢ updateFinset (updateFinset x s y) t z i = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z)) i

Next tactic:
by_cases hit : i ∈ t
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    

Proof state:
case pos
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∈ s
hit : i ∈ t
⊢ updateFinset (updateFinset x s y) t z i = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z)) i

Next tactic:
simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    

Proof state:
case neg
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∈ s
hit : i ∉ t
⊢ updateFinset (updateFinset x s y) t z i = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z)) i

Next tactic:
simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    

Proof state:
case pos
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∉ s
hit : i ∈ t
⊢ updateFinset (updateFinset x s y) t z i = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z)) i

Next tactic:
simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    

Proof state:
case neg
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∉ s
hit : i ∉ t
⊢ updateFinset (updateFinset x s y) t z i = updateFinset x (s ∪ t) ((piFinsetUnion π hst) (y, z)) i

Next tactic:
simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
  · 

Proof state:
case pos
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∈ s
hit : i ∈ t
⊢ z { val := i, property := (_ : i ∈ t) } = (piFinsetUnion π hst) (y, z) { val := i, property := (_ : i ∈ s ∪ t) }

Next tactic:
exfalso
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
  · exfalso; 

Proof state:
case pos.h
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∈ s
hit : i ∈ t
⊢ False

Next tactic:
exact Finset.disjoint_left.mp hst his hit
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
  · exfalso; exact Finset.disjoint_left.mp hst his hit
  · 

Proof state:
case neg
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∈ s
hit : i ∉ t
⊢ y { val := i, property := (_ : i ∈ s) } = (piFinsetUnion π hst) (y, z) { val := i, property := (_ : i ∈ s ∪ t) }

Next tactic:
exact piCongrLeft_sum_inl (fun b : ↥(s ∪ t) => π b) e y z ⟨i, his⟩ |>.symm
theorem updateFinset_updateFinset {s t : Finset ι} (hst : Disjoint s t)
    {y : ∀ i : ↥s, π i} {z : ∀ i : ↥t, π i} :
    updateFinset (updateFinset x s y) t z =
    updateFinset x (s ∪ t) (Equiv.piFinsetUnion π hst ⟨y, z⟩) := by
  set e := Equiv.Finset.union s t hst
  congr with i
  by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;>
    simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, true_or_iff,
      false_or_iff, not_false_iff]
  · exfalso; exact Finset.disjoint_left.mp hst his hit
  · exact piCongrLeft_sum_inl (fun b : ↥(s ∪ t) => π b) e y z ⟨i, his⟩ |>.symm
  · 

Proof state:
case pos
ι : Type u_1
π : ι → Type u_2
x : (i : ι) → π i
inst✝ : DecidableEq ι
s t : Finset ι
hst : Disjoint s t
y : (i : { x // x ∈ s }) → π ↑i
z : (i : { x // x ∈ t }) → π ↑i
e : { x // x ∈ s } ⊕ { x // x ∈ t } ≃ { x // x ∈ s ∪ t } := Finset.union s t hst
i : ι
his : i ∉ s
hit : i ∈ t
⊢ z { val := i, property := (_ : i ∈ t) } = (piFinsetUnion π hst) (y, z) { val := i, property := (_ : i ∈ s ∪ t) }

Next tactic:
exact piCongrLeft_sum_inr (fun b : ↥(s ∪ t) => π b) e y z ⟨i, hit⟩ |>.symm
theorem assoc_flip :
    (𝟙 A.X ⊗ M.act) ≫ M.act = (α_ A.X A.X M.X).inv ≫ (A.mul ⊗ 𝟙 M.X) ≫ M.act := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A : Mon_ C
M : Mod_ A
⊢ (𝟙 A.X ⊗ M.act) ≫ M.act = (α_ A.X A.X M.X).inv ≫ (A.mul ⊗ 𝟙 M.X) ≫ M.act

Next tactic:
simp
@[simp]
theorem id_hom' (M : Mod_ A) : (𝟙 M : M ⟶ M).hom = 𝟙 M.X := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A : Mon_ C
M✝ M : Mod_ A
⊢ (𝟙 M).hom = 𝟙 M.X

Next tactic:
rfl
/-- A morphism of monoid objects induces a "restriction" or "comap" functor
between the categories of module objects.
-/
@[simps]
def comap {A B : Mon_ C} (f : A ⟶ B) : Mod_ B ⥤ Mod_ A where
  obj M :=
    { X := M.X
      act := (f.hom ⊗ 𝟙 M.X) ≫ M.act
      one_act := by
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
⊢ (A.one ⊗ 𝟙 M.X) ≫ (f.hom ⊗ 𝟙 M.X) ≫ M.act = (λ_ M.X).hom

Next tactic:
slice_lhs 1 2 => rw [← comp_tensor_id]
/-- A morphism of monoid objects induces a "restriction" or "comap" functor
between the categories of module objects.
-/
@[simps]
def comap {A B : Mon_ C} (f : A ⟶ B) : Mod_ B ⥤ Mod_ A where
  obj M :=
    { X := M.X
      act := (f.hom ⊗ 𝟙 M.X) ≫ M.act
      one_act := by
        slice_lhs 1 2 => 

Proof state:
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
| (A.one ⊗ 𝟙 M.X) ≫ (f.hom ⊗ 𝟙 M.X)
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
| M.act

Next tactic:
rw [← comp_tensor_id]
/-- A morphism of monoid objects induces a "restriction" or "comap" functor
between the categories of module objects.
-/
@[simps]
def comap {A B : Mon_ C} (f : A ⟶ B) : Mod_ B ⥤ Mod_ A where
  obj M :=
    { X := M.X
      act := (f.hom ⊗ 𝟙 M.X) ≫ M.act
      one_act := by
        slice_lhs 1 2 => rw [← comp_tensor_id]
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
⊢ (A.one ≫ f.hom ⊗ 𝟙 M.X) ≫ M.act = (λ_ M.X).hom

Next tactic:
rw [f.one_hom, one_act]
/-- A morphism of monoid objects induces a "restriction" or "comap" functor
between the categories of module objects.
-/
@[simps]
def comap {A B : Mon_ C} (f : A ⟶ B) : Mod_ B ⥤ Mod_ A where
  obj M :=
    { X := M.X
      act := (f.hom ⊗ 𝟙 M.X) ≫ M.act
      one_act := by
        slice_lhs 1 2 => rw [← comp_tensor_id]
        rw [f.one_hom, one_act]
      assoc := by
        -- oh, for homotopy.io in a widget!
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
⊢ (A.mul ⊗ 𝟙 M.X) ≫ (f.hom ⊗ 𝟙 M.X) ≫ M.act =
    (α_ A.X A.X M.X).hom ≫ (𝟙 A.X ⊗ (f.hom ⊗ 𝟙 M.X) ≫ M.act) ≫ (f.hom ⊗ 𝟙 M.X) ≫ M.act

Next tactic:
slice_rhs 2 3 => rw [id_tensor_comp_tensor_id, ← tensor_id_comp_id_tensor]
/-- A morphism of monoid objects induces a "restriction" or "comap" functor
between the categories of module objects.
-/
@[simps]
def comap {A B : Mon_ C} (f : A ⟶ B) : Mod_ B ⥤ Mod_ A where
  obj M :=
    { X := M.X
      act := (f.hom ⊗ 𝟙 M.X) ≫ M.act
      one_act := by
        slice_lhs 1 2 => rw [← comp_tensor_id]
        rw [f.one_hom, one_act]
      assoc := by
        -- oh, for homotopy.io in a widget!
        slice_rhs 2 3 => 

Proof state:
case a.a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
| (𝟙 A.X ⊗ (f.hom ⊗ 𝟙 M.X) ≫ M.act) ≫ (f.hom ⊗ 𝟙 M.X)
case a.a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
| M.act
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
| (α_ A.X A.X M.X).hom

Next tactic:
rw [id_tensor_comp_tensor_id, ← tensor_id_comp_id_tensor]
/-- A morphism of monoid objects induces a "restriction" or "comap" functor
between the categories of module objects.
-/
@[simps]
def comap {A B : Mon_ C} (f : A ⟶ B) : Mod_ B ⥤ Mod_ A where
  obj M :=
    { X := M.X
      act := (f.hom ⊗ 𝟙 M.X) ≫ M.act
      one_act := by
        slice_lhs 1 2 => rw [← comp_tensor_id]
        rw [f.one_hom, one_act]
      assoc := by
        -- oh, for homotopy.io in a widget!
        slice_rhs 2 3 => rw [id_tensor_comp_tensor_id, ← tensor_id_comp_id_tensor]
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
⊢ (A.mul ⊗ 𝟙 M.X) ≫ (f.hom ⊗ 𝟙 M.X) ≫ M.act =
    (α_ A.X A.X M.X).hom ≫ ((f.hom ⊗ 𝟙 (A.X ⊗ M.X)) ≫ (𝟙 B.X ⊗ (f.hom ⊗ 𝟙 M.X) ≫ M.act)) ≫ M.act

Next tactic:
rw [id_tensor_comp]
/-- A morphism of monoid objects induces a "restriction" or "comap" functor
between the categories of module objects.
-/
@[simps]
def comap {A B : Mon_ C} (f : A ⟶ B) : Mod_ B ⥤ Mod_ A where
  obj M :=
    { X := M.X
      act := (f.hom ⊗ 𝟙 M.X) ≫ M.act
      one_act := by
        slice_lhs 1 2 => rw [← comp_tensor_id]
        rw [f.one_hom, one_act]
      assoc := by
        -- oh, for homotopy.io in a widget!
        slice_rhs 2 3 => rw [id_tensor_comp_tensor_id, ← tensor_id_comp_id_tensor]
        rw [id_tensor_comp]
        

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
A✝ : Mon_ C
M✝ : Mod_ A✝
A B : Mon_ C
f : A ⟶ B
M : Mod_ B
⊢ (A.mul ⊗ 𝟙 M.X) ≫ (f.hom ⊗ 𝟙 M.X) ≫ M.act =
    (α_ A.X A.X M.X).hom ≫ ((f.hom ⊗ 𝟙 (A.X ⊗ M.X)) ≫ (𝟙 B.X ⊗ f.hom ⊗ 𝟙 M.X) ≫ (𝟙 B.X ⊗ M.act)) ≫ M.act

Next tactic:
slice_rhs 4 5 => rw [Mod_.assoc_flip]