l3lab/ntp-mathlib huggingface dataset:
theorem comp_inj' {p₁ p₂ : Path a b} {q₁ q₂ : Path b c} (h : p₁.length = p₂.length) :
    p₁.comp q₁ = p₂.comp q₂ ↔ p₁ = p₂ ∧ q₁ = q₂ :=
  ⟨fun h_eq => (comp_inj <| Nat.add_left_cancel <| by simpa [h] using congr_arg length h_eq).1 h_eq,
   by 

Proof state:
V : Type u
inst✝ : Quiver V
a b c d : V
p₁ p₂ : Path a b
q₁ q₂ : Path b c
h : length p₁ = length p₂
⊢ p₁ = p₂ ∧ q₁ = q₂ → comp p₁ q₁ = comp p₂ q₂

Next tactic:
rintro ⟨rfl, rfl⟩
theorem comp_inj' {p₁ p₂ : Path a b} {q₁ q₂ : Path b c} (h : p₁.length = p₂.length) :
    p₁.comp q₁ = p₂.comp q₂ ↔ p₁ = p₂ ∧ q₁ = q₂ :=
  ⟨fun h_eq => (comp_inj <| Nat.add_left_cancel <| by simpa [h] using congr_arg length h_eq).1 h_eq,
   by rintro ⟨rfl, rfl⟩; 

Proof state:
case intro
V : Type u
inst✝ : Quiver V
a b c d : V
p₁ : Path a b
q₁ : Path b c
h : length p₁ = length p₁
⊢ comp p₁ q₁ = comp p₁ q₁

Next tactic:
rfl
/-- `Quiver.Path.toList` is a contravariant functor. The inversion comes from `Quiver.Path` and
`List` having different preferred directions for adding elements. -/
@[simp]
theorem toList_comp (p : Path a b) : ∀ {c} (q : Path b c), (p.comp q).toList = q.toList ++ p.toList
  | _, nil => by 

Proof state:
V : Type u
inst✝ : Quiver V
a b c d : V
p : Path a b
⊢ toList (comp p nil) = toList nil ++ toList p

Next tactic:
simp
/-- `Quiver.Path.toList` is a contravariant functor. The inversion comes from `Quiver.Path` and
`List` having different preferred directions for adding elements. -/
@[simp]
theorem toList_comp (p : Path a b) : ∀ {c} (q : Path b c), (p.comp q).toList = q.toList ++ p.toList
  | _, nil => by simp
  | _, @cons _ _ _ d _ q _ => by 

Proof state:
V : Type u
inst✝ : Quiver V
a b c d✝ : V
p : Path a b
x✝ d : V
q : Path b d
a✝ : d ⟶ x✝
⊢ toList (comp p (cons q a✝)) = toList (cons q a✝) ++ toList p

Next tactic:
simp [toList_comp]
theorem toList_injective (a : V) : ∀ b, Injective (toList : Path a b → List V)
  | _, nil, nil, _ => rfl
  | _, nil, @cons _ _ _ c _ p f, h => by 

Proof state:
V : Type u
inst✝¹ : Quiver V
a✝ b c✝ d : V
inst✝ : ∀ (a b : V), Subsingleton (a ⟶ b)
a c : V
p : Path a c
f : c ⟶ a
h : toList nil = toList (cons p f)
⊢ nil = cons p f

Next tactic:
cases h
theorem toList_injective (a : V) : ∀ b, Injective (toList : Path a b → List V)
  | _, nil, nil, _ => rfl
  | _, nil, @cons _ _ _ c _ p f, h => by cases h
  | _, @cons _ _ _ c _ p f, nil, h => by 

Proof state:
V : Type u
inst✝¹ : Quiver V
a✝ b c✝ d : V
inst✝ : ∀ (a b : V), Subsingleton (a ⟶ b)
a c : V
p : Path a c
f : c ⟶ a
h : toList (cons p f) = toList nil
⊢ cons p f = nil

Next tactic:
cases h
theorem toList_injective (a : V) : ∀ b, Injective (toList : Path a b → List V)
  | _, nil, nil, _ => rfl
  | _, nil, @cons _ _ _ c _ p f, h => by cases h
  | _, @cons _ _ _ c _ p f, nil, h => by cases h
  | _, @cons _ _ _ c _ p f, @cons _ _ _ t _ C D, h => by
    

Proof state:
V : Type u
inst✝¹ : Quiver V
a✝ b c✝ d : V
inst✝ : ∀ (a b : V), Subsingleton (a ⟶ b)
a x✝ c : V
p : Path a c
f : c ⟶ x✝
t : V
C : Path a t
D : t ⟶ x✝
h : toList (cons p f) = toList (cons C D)
⊢ cons p f = cons C D

Next tactic:
simp only [toList, List.cons.injEq] at h
theorem toList_injective (a : V) : ∀ b, Injective (toList : Path a b → List V)
  | _, nil, nil, _ => rfl
  | _, nil, @cons _ _ _ c _ p f, h => by cases h
  | _, @cons _ _ _ c _ p f, nil, h => by cases h
  | _, @cons _ _ _ c _ p f, @cons _ _ _ t _ C D, h => by
    simp only [toList, List.cons.injEq] at h
    

Proof state:
V : Type u
inst✝¹ : Quiver V
a✝ b c✝ d : V
inst✝ : ∀ (a b : V), Subsingleton (a ⟶ b)
a x✝ c : V
p : Path a c
f : c ⟶ x✝
t : V
C : Path a t
D : t ⟶ x✝
h : c = t ∧ toList p = toList C
⊢ cons p f = cons C D

Next tactic:
obtain ⟨rfl, hAC⟩ := h
theorem toList_injective (a : V) : ∀ b, Injective (toList : Path a b → List V)
  | _, nil, nil, _ => rfl
  | _, nil, @cons _ _ _ c _ p f, h => by cases h
  | _, @cons _ _ _ c _ p f, nil, h => by cases h
  | _, @cons _ _ _ c _ p f, @cons _ _ _ t _ C D, h => by
    simp only [toList, List.cons.injEq] at h
    obtain ⟨rfl, hAC⟩ := h
    

Proof state:
case intro
V : Type u
inst✝¹ : Quiver V
a✝ b c✝ d : V
inst✝ : ∀ (a b : V), Subsingleton (a ⟶ b)
a x✝ c : V
p : Path a c
f : c ⟶ x✝
C : Path a c
D : c ⟶ x✝
hAC : toList p = toList C
⊢ cons p f = cons C D

Next tactic:
simp [toList_injective _ _ hAC, eq_iff_true_of_subsingleton]
@[simp]
theorem mapPath_comp {a b : V} (p : Path a b) :
    ∀ {c : V} (q : Path b c), F.mapPath (p.comp q) = (F.mapPath p).comp (F.mapPath q)
  | _, Path.nil => rfl
  | c, Path.cons q e => by 

Proof state:
V : Type u₁
inst✝¹ : Quiver V
W : Type u₂
inst✝ : Quiver W
F : V ⥤q W
a b : V
p : Path a b
c b✝ : V
q : Path b b✝
e : b✝ ⟶ c
⊢ mapPath F (Path.comp p (Path.cons q e)) = Path.comp (mapPath F p) (mapPath F (Path.cons q e))

Next tactic:
dsimp
@[simp]
theorem mapPath_comp {a b : V} (p : Path a b) :
    ∀ {c : V} (q : Path b c), F.mapPath (p.comp q) = (F.mapPath p).comp (F.mapPath q)
  | _, Path.nil => rfl
  | c, Path.cons q e => by dsimp; 

Proof state:
V : Type u₁
inst✝¹ : Quiver V
W : Type u₂
inst✝ : Quiver W
F : V ⥤q W
a b : V
p : Path a b
c b✝ : V
q : Path b b✝
e : b✝ ⟶ c
⊢ Path.cons (mapPath F (Path.comp p q)) (F.map e) = Path.cons (Path.comp (mapPath F p) (mapPath F q)) (F.map e)

Next tactic:
rw [mapPath_comp p q]
@[simp]
theorem sigma_nonempty : (s.sigma t).Nonempty ↔ ∃ i ∈ s, (t i).Nonempty := by 

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
⊢ Finset.Nonempty (Finset.sigma s t) ↔ ∃ i ∈ s, Finset.Nonempty (t i)

Next tactic:
simp [Finset.Nonempty]
@[simp]
theorem sigma_eq_empty : s.sigma t = ∅ ↔ ∀ i ∈ s, t i = ∅ := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
⊢ Finset.sigma s t = ∅ ↔ ∀ i ∈ s, t i = ∅

Next tactic:
simp only [← not_nonempty_iff_eq_empty, sigma_nonempty, not_exists, not_and]
theorem pairwiseDisjoint_map_sigmaMk :
    (s : Set ι).PairwiseDisjoint fun i => (t i).map (Embedding.sigmaMk i) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
⊢ Set.PairwiseDisjoint ↑s fun i => map (Embedding.sigmaMk i) (t i)

Next tactic:
intro i _ j _ hij
theorem pairwiseDisjoint_map_sigmaMk :
    (s : Set ι).PairwiseDisjoint fun i => (t i).map (Embedding.sigmaMk i) := by
  intro i _ j _ hij
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
⊢ (_root_.Disjoint on fun i => map (Embedding.sigmaMk i) (t i)) i j

Next tactic:
rw [Function.onFun, disjoint_left]
theorem pairwiseDisjoint_map_sigmaMk :
    (s : Set ι).PairwiseDisjoint fun i => (t i).map (Embedding.sigmaMk i) := by
  intro i _ j _ hij
  rw [Function.onFun, disjoint_left]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
⊢ ∀ ⦃a : (x : ι) × α x⦄, a ∈ map (Embedding.sigmaMk i) (t i) → a ∉ map (Embedding.sigmaMk j) (t j)

Next tactic:
simp_rw [mem_map, Function.Embedding.sigmaMk_apply]
theorem pairwiseDisjoint_map_sigmaMk :
    (s : Set ι).PairwiseDisjoint fun i => (t i).map (Embedding.sigmaMk i) := by
  intro i _ j _ hij
  rw [Function.onFun, disjoint_left]
  simp_rw [mem_map, Function.Embedding.sigmaMk_apply]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
⊢ ∀ ⦃a : (x : ι) × α x⦄, (∃ a_1 ∈ t i, { fst := i, snd := a_1 } = a) → ¬∃ a_2 ∈ t j, { fst := j, snd := a_2 } = a

Next tactic:
rintro _ ⟨y, _, rfl⟩ ⟨z, _, hz'⟩
theorem pairwiseDisjoint_map_sigmaMk :
    (s : Set ι).PairwiseDisjoint fun i => (t i).map (Embedding.sigmaMk i) := by
  intro i _ j _ hij
  rw [Function.onFun, disjoint_left]
  simp_rw [mem_map, Function.Embedding.sigmaMk_apply]
  rintro _ ⟨y, _, rfl⟩ ⟨z, _, hz'⟩
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
y : α i
left✝¹ : y ∈ t i
z : α j
left✝ : z ∈ t j
hz' : { fst := j, snd := z } = { fst := i, snd := y }
⊢ False

Next tactic:
exact hij (congr_arg Sigma.fst hz'.symm)
theorem sigma_eq_biUnion [DecidableEq (Σi, α i)] (s : Finset ι) (t : ∀ i, Finset (α i)) :
    s.sigma t = s.biUnion fun i => (t i).map <| Embedding.sigmaMk i := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s✝ s₁ s₂ : Finset ι
t✝ t₁ t₂ : (i : ι) → Finset (α i)
inst✝ : DecidableEq ((i : ι) × α i)
s : Finset ι
t : (i : ι) → Finset (α i)
⊢ Finset.sigma s t = Finset.biUnion s fun i => map (Embedding.sigmaMk i) (t i)

Next tactic:
ext ⟨x, y⟩
theorem sigma_eq_biUnion [DecidableEq (Σi, α i)] (s : Finset ι) (t : ∀ i, Finset (α i)) :
    s.sigma t = s.biUnion fun i => (t i).map <| Embedding.sigmaMk i := by
  ext ⟨x, y⟩
  

Proof state:
case a.mk
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s✝ s₁ s₂ : Finset ι
t✝ t₁ t₂ : (i : ι) → Finset (α i)
inst✝ : DecidableEq ((i : ι) × α i)
s : Finset ι
t : (i : ι) → Finset (α i)
x : ι
y : α x
⊢ { fst := x, snd := y } ∈ Finset.sigma s t ↔
    { fst := x, snd := y } ∈ Finset.biUnion s fun i => map (Embedding.sigmaMk i) (t i)

Next tactic:
simp [and_left_comm]
theorem sup_sigma [SemilatticeSup β] [OrderBot β] :
    (s.sigma t).sup f = s.sup fun i => (t i).sup fun b => f ⟨i, b⟩ := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
f : (i : ι) × α i → β
inst✝¹ : SemilatticeSup β
inst✝ : OrderBot β
⊢ sup (Finset.sigma s t) f = sup s fun i => sup (t i) fun b => f { fst := i, snd := b }

Next tactic:
simp only [le_antisymm_iff, Finset.sup_le_iff, mem_sigma, and_imp, Sigma.forall]
theorem sup_sigma [SemilatticeSup β] [OrderBot β] :
    (s.sigma t).sup f = s.sup fun i => (t i).sup fun b => f ⟨i, b⟩ := by
  simp only [le_antisymm_iff, Finset.sup_le_iff, mem_sigma, and_imp, Sigma.forall]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
f : (i : ι) × α i → β
inst✝¹ : SemilatticeSup β
inst✝ : OrderBot β
⊢ (∀ (a : ι) (b : α a),
      a ∈ s → b ∈ t a → f { fst := a, snd := b } ≤ sup s fun i => sup (t i) fun b => f { fst := i, snd := b }) ∧
    ∀ b ∈ s, ∀ b_1 ∈ t b, f { fst := b, snd := b_1 } ≤ sup (Finset.sigma s t) f

Next tactic:
exact
    ⟨fun i a hi ha => (le_sup hi).trans' <| le_sup (f := fun a => f ⟨i, a⟩) ha, fun i hi a ha =>
      le_sup <| mem_sigma.2 ⟨hi, ha⟩⟩
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : Sigma α
b : Sigma β
x : Sigma γ
⊢ x ∈ sigmaLift f a b ↔ ∃ (ha : a.fst = x.fst) (hb : b.fst = x.fst), x.snd ∈ f (ha ▸ a.snd) (hb ▸ b.snd)

Next tactic:
obtain ⟨⟨i, a⟩, j, b⟩ := a, b
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  

Proof state:
case mk.mk
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := j, snd := b } ↔
    ∃ (ha : { fst := i, snd := a }.fst = x.fst) (hb : { fst := j, snd := b }.fst = x.fst),
      x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)

Next tactic:
obtain rfl | h := Decidable.eq_or_ne i j
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · 

Proof state:
case mk.mk.inl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := i, snd := b } ↔
    ∃ (ha : { fst := i, snd := a }.fst = x.fst) (hb : { fst := i, snd := b }.fst = x.fst),
      x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := i, snd := b }.snd)

Next tactic:
constructor
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · 

Proof state:
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := i, snd := b } →
    ∃ (ha : { fst := i, snd := a }.fst = x.fst) (hb : { fst := i, snd := b }.fst = x.fst),
      x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := i, snd := b }.snd)

Next tactic:
simp_rw [sigmaLift]
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      

Proof state:
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ (x ∈ if h : True then map (Embedding.sigmaMk i) (f a b) else ∅) →
    ∃ (h : i = x.fst) (h_1 : i = x.fst),
      x.snd ∈ f ((_ : { fst := i, snd := a }.fst = x.fst) ▸ a) ((_ : { fst := i, snd := b }.fst = x.fst) ▸ b)

Next tactic:
simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      

Proof state:
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ ∀ x_1 ∈ f a b,
    { fst := i, snd := x_1 } = x →
      ∃ (h : i = x.fst) (h_1 : i = x.fst),
        x.snd ∈ f ((_ : { fst := i, snd := a }.fst = x.fst) ▸ a) ((_ : { fst := i, snd := b }.fst = x.fst) ▸ b)

Next tactic:
rintro x hx rfl
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      

Proof state:
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
i : ι
a : α i
b : β i
x : γ i
hx : x ∈ f a b
⊢ ∃ (h : i = { fst := i, snd := x }.fst) (h_1 : i = { fst := i, snd := x }.fst),
    { fst := i, snd := x }.snd ∈
      f ((_ : { fst := i, snd := a }.fst = { fst := i, snd := x }.fst) ▸ a)
        ((_ : { fst := i, snd := b }.fst = { fst := i, snd := x }.fst) ▸ b)

Next tactic:
exact ⟨rfl, rfl, hx⟩
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      exact ⟨rfl, rfl, hx⟩
    · 

Proof state:
case mk.mk.inl.mpr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ (∃ (ha : { fst := i, snd := a }.fst = x.fst) (hb : { fst := i, snd := b }.fst = x.fst),
      x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := i, snd := b }.snd)) →
    x ∈ sigmaLift f { fst := i, snd := a } { fst := i, snd := b }

Next tactic:
rintro ⟨⟨⟩, ⟨⟩, hx⟩
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      exact ⟨rfl, rfl, hx⟩
    · rintro ⟨⟨⟩, ⟨⟩, hx⟩
      

Proof state:
case mk.mk.inl.mpr.intro.refl.intro.refl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
a : α x.1
b : β x.1
hx :
  x.snd ∈
    f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
      ((_ : { fst := x.1, snd := b }.fst = { fst := x.1, snd := b }.fst) ▸ { fst := x.1, snd := b }.snd)
⊢ x ∈ sigmaLift f { fst := x.1, snd := a } { fst := x.1, snd := b }

Next tactic:
rw [sigmaLift, dif_pos rfl, mem_map]
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      exact ⟨rfl, rfl, hx⟩
    · rintro ⟨⟨⟩, ⟨⟩, hx⟩
      rw [sigmaLift, dif_pos rfl, mem_map]
      

Proof state:
case mk.mk.inl.mpr.intro.refl.intro.refl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
a : α x.1
b : β x.1
hx :
  x.snd ∈
    f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
      ((_ : { fst := x.1, snd := b }.fst = { fst := x.1, snd := b }.fst) ▸ { fst := x.1, snd := b }.snd)
⊢ ∃
    a_1 ∈
      f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
        { fst := x.1, snd := b }.snd,
    (Embedding.sigmaMk { fst := x.1, snd := b }.fst) a_1 = x

Next tactic:
exact ⟨_, hx, by simp [Sigma.ext_iff]⟩
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      exact ⟨rfl, rfl, hx⟩
    · rintro ⟨⟨⟩, ⟨⟩, hx⟩
      rw [sigmaLift, dif_pos rfl, mem_map]
      exact ⟨_, hx, by 

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
a : α x.1
b : β x.1
hx :
  x.snd ∈
    f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
      ((_ : { fst := x.1, snd := b }.fst = { fst := x.1, snd := b }.fst) ▸ { fst := x.1, snd := b }.snd)
⊢ (Embedding.sigmaMk { fst := x.1, snd := b }.fst) x.snd = x

Next tactic:
simp [Sigma.ext_iff]
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      exact ⟨rfl, rfl, hx⟩
    · rintro ⟨⟨⟩, ⟨⟩, hx⟩
      rw [sigmaLift, dif_pos rfl, mem_map]
      exact ⟨_, hx, by simp [Sigma.ext_iff]⟩
  · 

Proof state:
case mk.mk.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
h : i ≠ j
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := j, snd := b } ↔
    ∃ (ha : { fst := i, snd := a }.fst = x.fst) (hb : { fst := j, snd := b }.fst = x.fst),
      x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)

Next tactic:
rw [sigmaLift, dif_neg h]
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      exact ⟨rfl, rfl, hx⟩
    · rintro ⟨⟨⟩, ⟨⟩, hx⟩
      rw [sigmaLift, dif_pos rfl, mem_map]
      exact ⟨_, hx, by simp [Sigma.ext_iff]⟩
  · rw [sigmaLift, dif_neg h]
    

Proof state:
case mk.mk.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
h : i ≠ j
⊢ x ∈ ∅ ↔
    ∃ (ha : { fst := i, snd := a }.fst = x.fst) (hb : { fst := j, snd := b }.fst = x.fst),
      x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)

Next tactic:
refine' iff_of_false (not_mem_empty _) _
theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Sigma α) (b : Sigma β)
    (x : Sigma γ) :
    x ∈ sigmaLift f a b ↔ ∃ (ha : a.1 = x.1) (hb : b.1 = x.1), x.2 ∈ f (ha ▸ a.2) (hb ▸ b.2) := by
  obtain ⟨⟨i, a⟩, j, b⟩ := a, b
  obtain rfl | h := Decidable.eq_or_ne i j
  · constructor
    · simp_rw [sigmaLift]
      simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index,
        and_imp]
      rintro x hx rfl
      exact ⟨rfl, rfl, hx⟩
    · rintro ⟨⟨⟩, ⟨⟩, hx⟩
      rw [sigmaLift, dif_pos rfl, mem_map]
      exact ⟨_, hx, by simp [Sigma.ext_iff]⟩
  · rw [sigmaLift, dif_neg h]
    refine' iff_of_false (not_mem_empty _) _
    

Proof state:
case mk.mk.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
h : i ≠ j
⊢ ¬∃ (ha : { fst := i, snd := a }.fst = x.fst) (hb : { fst := j, snd := b }.fst = x.fst),
      x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)

Next tactic:
rintro ⟨⟨⟩, ⟨⟩, _⟩