l3lab/ntp-mathlib huggingface dataset:
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
⊢ { i // i ∈ insert x t } ≃ Option { i // i ∈ t }

Next tactic:
refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · 

Proof state:
case refine'_1
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
⊢ LeftInverse
    (fun y =>
      Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
        { val := ↑z, property := (_ : ↑z ∈ insert x t) })
    fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) }

Next tactic:
intro y
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    

Proof state:
case refine'_1
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
y : { i // i ∈ insert x t }
⊢ (fun y =>
        Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
          { val := ↑z, property := (_ : ↑z ∈ insert x t) })
      ((fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) }) y) =
    y

Next tactic:
by_cases h : ↑y = x
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h✝ : x ∉ t
y : { i // i ∈ insert x t }
h : ↑y = x
⊢ (fun y =>
        Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
          { val := ↑z, property := (_ : ↑z ∈ insert x t) })
      ((fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) }) y) =
    y

Next tactic:
simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h✝ : x ∉ t
y : { i // i ∈ insert x t }
h : ¬↑y = x
⊢ (fun y =>
        Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
          { val := ↑z, property := (_ : ↑z ∈ insert x t) })
      ((fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) }) y) =
    y

Next tactic:
simp only [h, Option.elim, dif_neg, not_false_iff, Subtype.coe_eta, Subtype.coe_mk]
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
    · simp only [h, Option.elim, dif_neg, not_false_iff, Subtype.coe_eta, Subtype.coe_mk]
  · 

Proof state:
case refine'_2
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
⊢ Function.RightInverse
    (fun y =>
      Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
        { val := ↑z, property := (_ : ↑z ∈ insert x t) })
    fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) }

Next tactic:
rintro (_ | y)
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
    · simp only [h, Option.elim, dif_neg, not_false_iff, Subtype.coe_eta, Subtype.coe_mk]
  · rintro (_ | y)
    · 

Proof state:
case refine'_2.none
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
⊢ (fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) })
      ((fun y =>
          Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
            { val := ↑z, property := (_ : ↑z ∈ insert x t) })
        none) =
    none

Next tactic:
simp only [Option.elim, dif_pos]
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
    · simp only [h, Option.elim, dif_neg, not_false_iff, Subtype.coe_eta, Subtype.coe_mk]
  · rintro (_ | y)
    · simp only [Option.elim, dif_pos]
    · 

Proof state:
case refine'_2.some
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
y : { i // i ∈ t }
⊢ (fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) })
      ((fun y =>
          Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
            { val := ↑z, property := (_ : ↑z ∈ insert x t) })
        (some y)) =
    some y

Next tactic:
have : ↑y ≠ x := by
        rintro ⟨⟩
        exact h y.2
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
    · simp only [h, Option.elim, dif_neg, not_false_iff, Subtype.coe_eta, Subtype.coe_mk]
  · rintro (_ | y)
    · simp only [Option.elim, dif_pos]
    · have : ↑y ≠ x := by
        

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
y : { i // i ∈ t }
⊢ ↑y ≠ x

Next tactic:
rintro ⟨⟩
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
    · simp only [h, Option.elim, dif_neg, not_false_iff, Subtype.coe_eta, Subtype.coe_mk]
  · rintro (_ | y)
    · simp only [Option.elim, dif_pos]
    · have : ↑y ≠ x := by
        rintro ⟨⟩
        

Proof state:
case refl
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
y : { i // i ∈ t }
h : ↑y ∉ t
⊢ False

Next tactic:
exact h y.2
/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtypeInsertEquivOption {t : Finset α} {x : α} (h : x ∉ t) :
    { i // i ∈ insert x t } ≃ Option { i // i ∈ t } := by
  refine'
    { toFun := fun y => if h : ↑y = x then none else some ⟨y, (mem_insert.mp y.2).resolve_left h⟩
      invFun := fun y => (y.elim ⟨x, mem_insert_self _ _⟩) fun z => ⟨z, mem_insert_of_mem z.2⟩.. }
  · intro y
    by_cases h : ↑y = x
    · simp only [Subtype.ext_iff, h, Option.elim, dif_pos, Subtype.coe_mk]
    · simp only [h, Option.elim, dif_neg, not_false_iff, Subtype.coe_eta, Subtype.coe_mk]
  · rintro (_ | y)
    · simp only [Option.elim, dif_pos]
    · have : ↑y ≠ x := by
        rintro ⟨⟩
        exact h y.2
      

Proof state:
case refine'_2.some
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t✝ u v : Finset α
a b : α
t : Finset α
x : α
h : x ∉ t
y : { i // i ∈ t }
this : ↑y ≠ x
⊢ (fun y => if h : ↑y = x then none else some { val := ↑y, property := (_ : ↑y ∈ t) })
      ((fun y =>
          Option.elim y { val := x, property := (_ : x ∈ insert x t) } fun z =>
            { val := ↑z, property := (_ : ↑z ∈ insert x t) })
        (some y)) =
    some y

Next tactic:
simp only [this, Option.elim, Subtype.eta, dif_neg, not_false_iff, Subtype.coe_mk]
@[simp]
theorem disjoint_insert_left : Disjoint (insert a s) t ↔ a ∉ t ∧ Disjoint s t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t u v : Finset α
a b : α
⊢ _root_.Disjoint (insert a s) t ↔ a ∉ t ∧ _root_.Disjoint s t

Next tactic:
simp only [disjoint_left, mem_insert, or_imp, forall_and, forall_eq]
@[simp]
theorem disjoint_insert_right : Disjoint s (insert a t) ↔ a ∉ s ∧ Disjoint s t :=
  disjoint_comm.trans <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s t u v : Finset α
a b : α
⊢ _root_.Disjoint (insert a t) s ↔ a ∉ s ∧ _root_.Disjoint s t

Next tactic:
rw [disjoint_insert_left, _root_.disjoint_comm]
@[simp]
theorem disjUnion_eq_union (s t h) : @disjUnion α s t h = s ∪ t :=
  ext fun a => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u v : Finset α
a✝ b : α
s t : Finset α
h : _root_.Disjoint s t
a : α
⊢ a ∈ disjUnion s t h ↔ a ∈ s ∪ t

Next tactic:
simp
theorem not_mem_union : a ∉ s ∪ t ↔ a ∉ s ∧ a ∉ t := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
⊢ a ∉ s ∪ t ↔ a ∉ s ∧ a ∉ t

Next tactic:
rw [mem_union, not_or]
theorem union_left_comm (s t u : Finset α) : s ∪ (t ∪ u) = t ∪ (s ∪ u) :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u✝ v : Finset α
a b : α
s t u : Finset α
x✝ : α
⊢ x✝ ∈ s ∪ (t ∪ u) ↔ x✝ ∈ t ∪ (s ∪ u)

Next tactic:
simp only [mem_union, or_left_comm]
theorem union_right_comm (s t u : Finset α) : s ∪ t ∪ u = s ∪ u ∪ t :=
  ext fun x => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u✝ v : Finset α
a b : α
s t u : Finset α
x : α
⊢ x ∈ s ∪ t ∪ u ↔ x ∈ s ∪ u ∪ t

Next tactic:
simp only [mem_union, or_assoc, @or_comm (x ∈ t)]
@[simp]
theorem union_empty (s : Finset α) : s ∪ ∅ = s :=
  ext fun x => mem_union.trans <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
s : Finset α
x : α
⊢ x ∈ s ∨ x ∈ ∅ ↔ x ∈ s

Next tactic:
simp
@[simp]
theorem empty_union (s : Finset α) : ∅ ∪ s = s :=
  ext fun x => mem_union.trans <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
s : Finset α
x : α
⊢ x ∈ ∅ ∨ x ∈ s ↔ x ∈ s

Next tactic:
simp
@[simp]
theorem insert_union (a : α) (s t : Finset α) : insert a s ∪ t = insert a (s ∪ t) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u v : Finset α
a✝ b a : α
s t : Finset α
⊢ insert a s ∪ t = insert a (s ∪ t)

Next tactic:
simp only [insert_eq, union_assoc]
@[simp]
theorem union_insert (a : α) (s t : Finset α) : s ∪ insert a t = insert a (s ∪ t) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u v : Finset α
a✝ b a : α
s t : Finset α
⊢ s ∪ insert a t = insert a (s ∪ t)

Next tactic:
simp only [insert_eq, union_left_comm]
theorem insert_union_distrib (a : α) (s t : Finset α) :
    insert a (s ∪ t) = insert a s ∪ insert a t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u v : Finset α
a✝ b a : α
s t : Finset α
⊢ insert a (s ∪ t) = insert a s ∪ insert a t

Next tactic:
simp only [insert_union, union_insert, insert_idem]
@[simp] lemma left_eq_union : s = s ∪ t ↔ t ⊆ s := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
⊢ s = s ∪ t ↔ t ⊆ s

Next tactic:
rw [eq_comm, union_eq_left]
@[simp] lemma right_eq_union : s = t ∪ s ↔ t ⊆ s := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
⊢ s = t ∪ s ↔ t ⊆ s

Next tactic:
rw [eq_comm, union_eq_right]
@[simp]
theorem disjoint_union_left : Disjoint (s ∪ t) u ↔ Disjoint s u ∧ Disjoint t u := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
⊢ _root_.Disjoint (s ∪ t) u ↔ _root_.Disjoint s u ∧ _root_.Disjoint t u

Next tactic:
simp only [disjoint_left, mem_union, or_imp, forall_and]
@[simp]
theorem disjoint_union_right : Disjoint s (t ∪ u) ↔ Disjoint s t ∧ Disjoint s u := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
⊢ _root_.Disjoint s (t ∪ u) ↔ _root_.Disjoint s t ∧ _root_.Disjoint s u

Next tactic:
simp only [disjoint_right, mem_union, or_imp, forall_and]
/-- To prove a relation on pairs of `Finset X`, it suffices to show that it is
  * symmetric,
  * it holds when one of the `Finset`s is empty,
  * it holds for pairs of singletons,
  * if it holds for `[a, c]` and for `[b, c]`, then it holds for `[a ∪ b, c]`.
-/
theorem induction_on_union (P : Finset α → Finset α → Prop) (symm : ∀ {a b}, P a b → P b a)
    (empty_right : ∀ {a}, P a ∅) (singletons : ∀ {a b}, P {a} {b})
    (union_of : ∀ {a b c}, P a c → P b c → P (a ∪ b) c) : ∀ a b, P a b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s s₁ s₂ t t₁ t₂ u v : Finset α
a b : α
P : Finset α → Finset α → Prop
symm : ∀ {a b : Finset α}, P a b → P b a
empty_right : ∀ {a : Finset α}, P a ∅
singletons : ∀ {a b : α}, P {a} {b}
union_of : ∀ {a b c : Finset α}, P a c → P b c → P (a ∪ b) c
⊢ ∀ (a b : Finset α), P a b

Next tactic:
intro a b
/-- To prove a relation on pairs of `Finset X`, it suffices to show that it is
  * symmetric,
  * it holds when one of the `Finset`s is empty,
  * it holds for pairs of singletons,
  * if it holds for `[a, c]` and for `[b, c]`, then it holds for `[a ∪ b, c]`.
-/
theorem induction_on_union (P : Finset α → Finset α → Prop) (symm : ∀ {a b}, P a b → P b a)
    (empty_right : ∀ {a}, P a ∅) (singletons : ∀ {a b}, P {a} {b})
    (union_of : ∀ {a b c}, P a c → P b c → P (a ∪ b) c) : ∀ a b, P a b := by
  intro a b
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s s₁ s₂ t t₁ t₂ u v : Finset α
a✝ b✝ : α
P : Finset α → Finset α → Prop
symm : ∀ {a b : Finset α}, P a b → P b a
empty_right : ∀ {a : Finset α}, P a ∅
singletons : ∀ {a b : α}, P {a} {b}
union_of : ∀ {a b c : Finset α}, P a c → P b c → P (a ∪ b) c
a b : Finset α
⊢ P a b

Next tactic:
refine' Finset.induction_on b empty_right fun x s _xs hi => symm _
/-- To prove a relation on pairs of `Finset X`, it suffices to show that it is
  * symmetric,
  * it holds when one of the `Finset`s is empty,
  * it holds for pairs of singletons,
  * if it holds for `[a, c]` and for `[b, c]`, then it holds for `[a ∪ b, c]`.
-/
theorem induction_on_union (P : Finset α → Finset α → Prop) (symm : ∀ {a b}, P a b → P b a)
    (empty_right : ∀ {a}, P a ∅) (singletons : ∀ {a b}, P {a} {b})
    (union_of : ∀ {a b c}, P a c → P b c → P (a ∪ b) c) : ∀ a b, P a b := by
  intro a b
  refine' Finset.induction_on b empty_right fun x s _xs hi => symm _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t t₁ t₂ u v : Finset α
a✝ b✝ : α
P : Finset α → Finset α → Prop
symm : ∀ {a b : Finset α}, P a b → P b a
empty_right : ∀ {a : Finset α}, P a ∅
singletons : ∀ {a b : α}, P {a} {b}
union_of : ∀ {a b c : Finset α}, P a c → P b c → P (a ∪ b) c
a b : Finset α
x : α
s : Finset α
_xs : x ∉ s
hi : P a s
⊢ P (insert x s) a

Next tactic:
rw [Finset.insert_eq]
/-- To prove a relation on pairs of `Finset X`, it suffices to show that it is
  * symmetric,
  * it holds when one of the `Finset`s is empty,
  * it holds for pairs of singletons,
  * if it holds for `[a, c]` and for `[b, c]`, then it holds for `[a ∪ b, c]`.
-/
theorem induction_on_union (P : Finset α → Finset α → Prop) (symm : ∀ {a b}, P a b → P b a)
    (empty_right : ∀ {a}, P a ∅) (singletons : ∀ {a b}, P {a} {b})
    (union_of : ∀ {a b c}, P a c → P b c → P (a ∪ b) c) : ∀ a b, P a b := by
  intro a b
  refine' Finset.induction_on b empty_right fun x s _xs hi => symm _
  rw [Finset.insert_eq]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t t₁ t₂ u v : Finset α
a✝ b✝ : α
P : Finset α → Finset α → Prop
symm : ∀ {a b : Finset α}, P a b → P b a
empty_right : ∀ {a : Finset α}, P a ∅
singletons : ∀ {a b : α}, P {a} {b}
union_of : ∀ {a b c : Finset α}, P a c → P b c → P (a ∪ b) c
a b : Finset α
x : α
s : Finset α
_xs : x ∉ s
hi : P a s
⊢ P ({x} ∪ s) a

Next tactic:
apply union_of _ (symm hi)
/-- To prove a relation on pairs of `Finset X`, it suffices to show that it is
  * symmetric,
  * it holds when one of the `Finset`s is empty,
  * it holds for pairs of singletons,
  * if it holds for `[a, c]` and for `[b, c]`, then it holds for `[a ∪ b, c]`.
-/
theorem induction_on_union (P : Finset α → Finset α → Prop) (symm : ∀ {a b}, P a b → P b a)
    (empty_right : ∀ {a}, P a ∅) (singletons : ∀ {a b}, P {a} {b})
    (union_of : ∀ {a b c}, P a c → P b c → P (a ∪ b) c) : ∀ a b, P a b := by
  intro a b
  refine' Finset.induction_on b empty_right fun x s _xs hi => symm _
  rw [Finset.insert_eq]
  apply union_of _ (symm hi)
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t t₁ t₂ u v : Finset α
a✝ b✝ : α
P : Finset α → Finset α → Prop
symm : ∀ {a b : Finset α}, P a b → P b a
empty_right : ∀ {a : Finset α}, P a ∅
singletons : ∀ {a b : α}, P {a} {b}
union_of : ∀ {a b c : Finset α}, P a c → P b c → P (a ∪ b) c
a b : Finset α
x : α
s : Finset α
_xs : x ∉ s
hi : P a s
⊢ P {x} a

Next tactic:
refine' Finset.induction_on a empty_right fun a t _ta hi => symm _
/-- To prove a relation on pairs of `Finset X`, it suffices to show that it is
  * symmetric,
  * it holds when one of the `Finset`s is empty,
  * it holds for pairs of singletons,
  * if it holds for `[a, c]` and for `[b, c]`, then it holds for `[a ∪ b, c]`.
-/
theorem induction_on_union (P : Finset α → Finset α → Prop) (symm : ∀ {a b}, P a b → P b a)
    (empty_right : ∀ {a}, P a ∅) (singletons : ∀ {a b}, P {a} {b})
    (union_of : ∀ {a b c}, P a c → P b c → P (a ∪ b) c) : ∀ a b, P a b := by
  intro a b
  refine' Finset.induction_on b empty_right fun x s _xs hi => symm _
  rw [Finset.insert_eq]
  apply union_of _ (symm hi)
  refine' Finset.induction_on a empty_right fun a t _ta hi => symm _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u v : Finset α
a✝¹ b✝ : α
P : Finset α → Finset α → Prop
symm : ∀ {a b : Finset α}, P a b → P b a
empty_right : ∀ {a : Finset α}, P a ∅
singletons : ∀ {a b : α}, P {a} {b}
union_of : ∀ {a b c : Finset α}, P a c → P b c → P (a ∪ b) c
a✝ b : Finset α
x : α
s : Finset α
_xs : x ∉ s
hi✝ : P a✝ s
a : α
t : Finset α
_ta : a ∉ t
hi : P {x} t
⊢ P (insert a t) {x}

Next tactic:
rw [Finset.insert_eq]
/-- To prove a relation on pairs of `Finset X`, it suffices to show that it is
  * symmetric,
  * it holds when one of the `Finset`s is empty,
  * it holds for pairs of singletons,
  * if it holds for `[a, c]` and for `[b, c]`, then it holds for `[a ∪ b, c]`.
-/
theorem induction_on_union (P : Finset α → Finset α → Prop) (symm : ∀ {a b}, P a b → P b a)
    (empty_right : ∀ {a}, P a ∅) (singletons : ∀ {a b}, P {a} {b})
    (union_of : ∀ {a b c}, P a c → P b c → P (a ∪ b) c) : ∀ a b, P a b := by
  intro a b
  refine' Finset.induction_on b empty_right fun x s _xs hi => symm _
  rw [Finset.insert_eq]
  apply union_of _ (symm hi)
  refine' Finset.induction_on a empty_right fun a t _ta hi => symm _
  rw [Finset.insert_eq]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α
s✝ s₁ s₂ t✝ t₁ t₂ u v : Finset α
a✝¹ b✝ : α
P : Finset α → Finset α → Prop
symm : ∀ {a b : Finset α}, P a b → P b a
empty_right : ∀ {a : Finset α}, P a ∅
singletons : ∀ {a b : α}, P {a} {b}
union_of : ∀ {a b c : Finset α}, P a c → P b c → P (a ∪ b) c
a✝ b : Finset α
x : α
s : Finset α
_xs : x ∉ s
hi✝ : P a✝ s
a : α
t : Finset α
_ta : a ∉ t
hi : P {x} t
⊢ P ({a} ∪ t) {x}

Next tactic:
exact union_of singletons (symm hi)
theorem _root_.Directed.exists_mem_subset_of_finset_subset_biUnion {α ι : Type*} [hn : Nonempty ι]
    {f : ι → Set α} (h : Directed (· ⊆ ·) f) {s : Finset α} (hs : (s : Set α) ⊆ ⋃ i, f i) :
    ∃ i, (s : Set α) ⊆ f i := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α✝
s✝ s₁ s₂ t t₁ t₂ u v : Finset α✝
a b : α✝
α : Type u_4
ι : Type u_5
hn : Nonempty ι
f : ι → Set α
h : Directed (fun x x_1 => x ⊆ x_1) f
s : Finset α
hs : ↑s ⊆ ⋃ i, f i
⊢ ∃ i, ↑s ⊆ f i

Next tactic:
classical
    revert hs
    refine' s.induction_on _ _
    · refine' fun _ => ⟨hn.some, _⟩
      simp only [coe_empty, Set.empty_subset]
    · intro b t _hbt htc hbtc
      obtain ⟨i : ι, hti : (t : Set α) ⊆ f i⟩ := htc (Set.Subset.trans (t.subset_insert b) hbtc)
      obtain ⟨j, hbj⟩ : ∃ j, b ∈ f j := by simpa [Set.mem_iUnion₂] using hbtc (t.mem_insert_self b)
      rcases h j i with ⟨k, hk, hk'⟩
      use k
      rw [coe_insert, Set.insert_subset_iff]
      exact ⟨hk hbj, _root_.trans hti hk'⟩
theorem _root_.Directed.exists_mem_subset_of_finset_subset_biUnion {α ι : Type*} [hn : Nonempty ι]
    {f : ι → Set α} (h : Directed (· ⊆ ·) f) {s : Finset α} (hs : (s : Set α) ⊆ ⋃ i, f i) :
    ∃ i, (s : Set α) ⊆ f i := by
  classical
    

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : DecidableEq α✝
s✝ s₁ s₂ t t₁ t₂ u v : Finset α✝
a b : α✝
α : Type u_4
ι : Type u_5
hn : Nonempty ι
f : ι → Set α
h : Directed (fun x x_1 => x ⊆ x_1) f
s : Finset α
hs : ↑s ⊆ ⋃ i, f i
⊢ ∃ i, ↑s ⊆ f i

Next tactic:
revert hs