l3lab/ntp-mathlib huggingface dataset:
/-- create a `FinEnum` instance from an exhaustive list without duplicates -/
def ofNodupList [DecidableEq α] (xs : List α) (h : ∀ x : α, x ∈ xs) (h' : List.Nodup xs) : FinEnum α
    where
  card := xs.length
  equiv :=
    ⟨fun x => ⟨xs.indexOf x, by rw [List.indexOf_lt_length]; apply h⟩, fun ⟨i, h⟩ =>
      xs.nthLe _ h, fun x => by simp, fun ⟨i, h⟩ => by
      

Proof state:
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs : List α
h✝ : ∀ (x : α), x ∈ xs
h' : List.Nodup xs
x✝ : Fin (List.length xs)
i : ℕ
h : i < List.length xs
⊢ (fun x => { val := List.indexOf x xs, isLt := (_ : List.indexOf x xs < List.length xs) })
      ((fun x =>
          match x with
          | { val := i, isLt := h } => List.nthLe xs i h)
        { val := i, isLt := h }) =
    { val := i, isLt := h }

Next tactic:
simp [*]
/-- create a `FinEnum` instance from an exhaustive list; duplicates are removed -/
def ofList [DecidableEq α] (xs : List α) (h : ∀ x : α, x ∈ xs) : FinEnum α :=
  ofNodupList xs.dedup (by 

Proof state:
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs : List α
h : ∀ (x : α), x ∈ xs
⊢ ∀ (x : α), x ∈ List.dedup xs

Next tactic:
simp [*]
@[simp]
theorem mem_toList [FinEnum α] (x : α) : x ∈ toList α := by
  

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
x : α
⊢ x ∈ toList α

Next tactic:
simp [toList]
@[simp]
theorem mem_toList [FinEnum α] (x : α) : x ∈ toList α := by
  simp [toList]; 

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
x : α
⊢ ∃ a, equiv.symm a = x

Next tactic:
exists equiv x
@[simp]
theorem mem_toList [FinEnum α] (x : α) : x ∈ toList α := by
  simp [toList]; exists equiv x; 

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
x : α
⊢ equiv.symm (equiv x) = x

Next tactic:
simp
@[simp]
theorem nodup_toList [FinEnum α] : List.Nodup (toList α) := by
  

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
⊢ List.Nodup (toList α)

Next tactic:
simp [toList]
@[simp]
theorem nodup_toList [FinEnum α] : List.Nodup (toList α) := by
  simp [toList]; 

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
⊢ List.Nodup (List.map (⇑equiv.symm) (List.finRange (card α)))

Next tactic:
apply List.Nodup.map <;> [apply Equiv.injective; apply List.nodup_finRange]
@[simp]
theorem nodup_toList [FinEnum α] : List.Nodup (toList α) := by
  simp [toList]; 

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
⊢ List.Nodup (List.map (⇑equiv.symm) (List.finRange (card α)))

Next tactic:
apply List.Nodup.map
@[simp]
theorem nodup_toList [FinEnum α] : List.Nodup (toList α) := by
  simp [toList]; apply List.Nodup.map <;> [

Proof state:
case hf
α : Type u
β : α → Type v
inst✝ : FinEnum α
⊢ Injective ⇑equiv.symm

Next tactic:
apply Equiv.injective
@[simp]
theorem nodup_toList [FinEnum α] : List.Nodup (toList α) := by
  simp [toList]; apply List.Nodup.map <;> [apply Equiv.injective; 

Proof state:
case a
α : Type u
β : α → Type v
inst✝ : FinEnum α
⊢ List.Nodup (List.finRange (card α))

Next tactic:
apply List.nodup_finRange
/-- create a `FinEnum` instance using a surjection -/
def ofSurjective {β} (f : β → α) [DecidableEq α] [FinEnum β] (h : Surjective f) : FinEnum α :=
  ofList ((toList β).map f) (by 

Proof state:
α : Type u
β✝ : α → Type v
β : Type ?u.7763
f : β → α
inst✝¹ : DecidableEq α
inst✝ : FinEnum β
h : Surjective f
⊢ ∀ (x : α), x ∈ List.map f (toList β)

Next tactic:
intro
/-- create a `FinEnum` instance using a surjection -/
def ofSurjective {β} (f : β → α) [DecidableEq α] [FinEnum β] (h : Surjective f) : FinEnum α :=
  ofList ((toList β).map f) (by intro; 

Proof state:
α : Type u
β✝ : α → Type v
β : Type ?u.7763
f : β → α
inst✝¹ : DecidableEq α
inst✝ : FinEnum β
h : Surjective f
x✝ : α
⊢ x✝ ∈ List.map f (toList β)

Next tactic:
simp
/-- create a `FinEnum` instance using a surjection -/
def ofSurjective {β} (f : β → α) [DecidableEq α] [FinEnum β] (h : Surjective f) : FinEnum α :=
  ofList ((toList β).map f) (by intro; simp; 

Proof state:
α : Type u
β✝ : α → Type v
β : Type ?u.7763
f : β → α
inst✝¹ : DecidableEq α
inst✝ : FinEnum β
h : Surjective f
x✝ : α
⊢ ∃ a, f a = x✝

Next tactic:
exact h _
/-- create a `FinEnum` instance using an injection -/
noncomputable def ofInjective {α β} (f : α → β) [DecidableEq α] [FinEnum β] (h : Injective f) :
    FinEnum α :=
  ofList ((toList β).filterMap (partialInv f))
    (by
      

Proof state:
α✝ : Type u
β✝ : α✝ → Type v
α : Type ?u.9860
β : Type ?u.9944
f : α → β
inst✝¹ : DecidableEq α
inst✝ : FinEnum β
h : Injective f
⊢ ∀ (x : α), x ∈ List.filterMap (partialInv f) (toList β)

Next tactic:
intro x
/-- create a `FinEnum` instance using an injection -/
noncomputable def ofInjective {α β} (f : α → β) [DecidableEq α] [FinEnum β] (h : Injective f) :
    FinEnum α :=
  ofList ((toList β).filterMap (partialInv f))
    (by
      intro x
      

Proof state:
α✝ : Type u
β✝ : α✝ → Type v
α : Type ?u.9860
β : Type ?u.9944
f : α → β
inst✝¹ : DecidableEq α
inst✝ : FinEnum β
h : Injective f
x : α
⊢ x ∈ List.filterMap (partialInv f) (toList β)

Next tactic:
simp only [mem_toList, true_and_iff, List.mem_filterMap]
/-- create a `FinEnum` instance using an injection -/
noncomputable def ofInjective {α β} (f : α → β) [DecidableEq α] [FinEnum β] (h : Injective f) :
    FinEnum α :=
  ofList ((toList β).filterMap (partialInv f))
    (by
      intro x
      simp only [mem_toList, true_and_iff, List.mem_filterMap]
      

Proof state:
α✝ : Type u
β✝ : α✝ → Type v
α : Type ?u.9860
β : Type ?u.9944
f : α → β
inst✝¹ : DecidableEq α
inst✝ : FinEnum β
h : Injective f
x : α
⊢ ∃ a, partialInv f a = some x

Next tactic:
use f x
/-- create a `FinEnum` instance using an injection -/
noncomputable def ofInjective {α β} (f : α → β) [DecidableEq α] [FinEnum β] (h : Injective f) :
    FinEnum α :=
  ofList ((toList β).filterMap (partialInv f))
    (by
      intro x
      simp only [mem_toList, true_and_iff, List.mem_filterMap]
      use f x
      

Proof state:
case h
α✝ : Type u
β✝ : α✝ → Type v
α : Type ?u.9860
β : Type ?u.9944
f : α → β
inst✝¹ : DecidableEq α
inst✝ : FinEnum β
h : Injective f
x : α
⊢ partialInv f (f x) = some x

Next tactic:
simp only [h, Function.partialInv_left]
instance punit : FinEnum PUnit :=
  ofList [PUnit.unit] fun x => by 

Proof state:
α : Type u
β : α → Type v
x : PUnit.{?u.10775 + 1}
⊢ x ∈ [PUnit.unit]

Next tactic:
cases x
instance punit : FinEnum PUnit :=
  ofList [PUnit.unit] fun x => by cases x; 

Proof state:
case unit
α : Type u
β : α → Type v
⊢ PUnit.unit ∈ [PUnit.unit]

Next tactic:
simp
instance prod {β} [FinEnum α] [FinEnum β] : FinEnum (α × β) :=
  ofList (toList α ×ˢ toList β) fun x => by 

Proof state:
α : Type u
β✝ : α → Type v
β : Type ?u.11153
inst✝¹ : FinEnum α
inst✝ : FinEnum β
x : α × β
⊢ x ∈ toList α ×ˢ toList β

Next tactic:
cases x
instance prod {β} [FinEnum α] [FinEnum β] : FinEnum (α × β) :=
  ofList (toList α ×ˢ toList β) fun x => by cases x; 

Proof state:
case mk
α : Type u
β✝ : α → Type v
β : Type ?u.11153
inst✝¹ : FinEnum α
inst✝ : FinEnum β
fst✝ : α
snd✝ : β
⊢ (fst✝, snd✝) ∈ toList α ×ˢ toList β

Next tactic:
simp
instance sum {β} [FinEnum α] [FinEnum β] : FinEnum (Sum α β) :=
  ofList ((toList α).map Sum.inl ++ (toList β).map Sum.inr) fun x => by 

Proof state:
α : Type u
β✝ : α → Type v
β : Type ?u.12973
inst✝¹ : FinEnum α
inst✝ : FinEnum β
x : α ⊕ β
⊢ x ∈ List.map Sum.inl (toList α) ++ List.map Sum.inr (toList β)

Next tactic:
cases x
instance sum {β} [FinEnum α] [FinEnum β] : FinEnum (Sum α β) :=
  ofList ((toList α).map Sum.inl ++ (toList β).map Sum.inr) fun x => by cases x <;> 

Proof state:
case inl
α : Type u
β✝ : α → Type v
β : Type ?u.12973
inst✝¹ : FinEnum α
inst✝ : FinEnum β
val✝ : α
⊢ Sum.inl val✝ ∈ List.map Sum.inl (toList α) ++ List.map Sum.inr (toList β)

Next tactic:
simp
instance sum {β} [FinEnum α] [FinEnum β] : FinEnum (Sum α β) :=
  ofList ((toList α).map Sum.inl ++ (toList β).map Sum.inr) fun x => by cases x <;> 

Proof state:
case inr
α : Type u
β✝ : α → Type v
β : Type ?u.12973
inst✝¹ : FinEnum α
inst✝ : FinEnum β
val✝ : β
⊢ Sum.inr val✝ ∈ List.map Sum.inl (toList α) ++ List.map Sum.inr (toList β)

Next tactic:
simp
instance fin {n} : FinEnum (Fin n) :=
  ofList (List.finRange _) (by 

Proof state:
α : Type u
β : α → Type v
n : ℕ
⊢ ∀ (x : Fin n), x ∈ List.finRange n

Next tactic:
simp
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  

Proof state:
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s : Finset α
xs : List α
⊢ s ∈ enum xs ↔ ∀ x ∈ s, x ∈ xs

Next tactic:
induction' xs with xs_hd generalizing s
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> 

Proof state:
case nil
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s : Finset α
⊢ s ∈ enum [] ↔ ∀ x ∈ s, x ∈ []

Next tactic:
simp [*, Finset.enum]
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> 

Proof state:
case cons
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
⊢ s ∈ enum (xs_hd :: tail✝) ↔ ∀ x ∈ s, x ∈ xs_hd :: tail✝

Next tactic:
simp [*, Finset.enum]
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · 

Proof state:
case nil
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s : Finset α
⊢ s = ∅ ↔ ∀ (x : α), x ∉ s

Next tactic:
simp [Finset.eq_empty_iff_forall_not_mem]
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · 

Proof state:
case cons
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
⊢ (∃ a, (∀ x ∈ a, x ∈ tail✝) ∧ (s = a ∨ s = {xs_hd} ∪ a)) ↔ ∀ x ∈ s, x = xs_hd ∨ x ∈ tail✝

Next tactic:
constructor
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · 

Proof state:
case cons.mp
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
⊢ (∃ a, (∀ x ∈ a, x ∈ tail✝) ∧ (s = a ∨ s = {xs_hd} ∪ a)) → ∀ x ∈ s, x = xs_hd ∨ x ∈ tail✝

Next tactic:
rintro ⟨a, h, h'⟩ x hx
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      

Proof state:
case cons.mp.intro.intro
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
h' : s = a ∨ s = {xs_hd} ∪ a
x : α
hx : x ∈ s
⊢ x = xs_hd ∨ x ∈ tail✝

Next tactic:
cases' h' with _ h' a b
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · 

Proof state:
case cons.mp.intro.intro.inl
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
x : α
hx : x ∈ s
h✝ : s = a
⊢ x = xs_hd ∨ x ∈ tail✝

Next tactic:
right
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        

Proof state:
case cons.mp.intro.intro.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
x : α
hx : x ∈ s
h✝ : s = a
⊢ x ∈ tail✝

Next tactic:
apply h
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        

Proof state:
case cons.mp.intro.intro.inl.h.a
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
x : α
hx : x ∈ s
h✝ : s = a
⊢ x ∈ a

Next tactic:
subst a
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        

Proof state:
case cons.mp.intro.intro.inl.h.a
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
x : α
hx : x ∈ s
h : ∀ x ∈ s, x ∈ tail✝
⊢ x ∈ s

Next tactic:
exact hx
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · 

Proof state:
case cons.mp.intro.intro.inr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
x : α
hx : x ∈ s
h' : s = {xs_hd} ∪ a
⊢ x = xs_hd ∨ x ∈ tail✝

Next tactic:
simp only [h', mem_union, mem_singleton] at hx ⊢
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        

Proof state:
case cons.mp.intro.intro.inr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
x : α
h' : s = {xs_hd} ∪ a
hx : x = xs_hd ∨ x ∈ a
⊢ x = xs_hd ∨ x ∈ tail✝

Next tactic:
cases' hx with hx hx'
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · 

Proof state:
case cons.mp.intro.intro.inr.inl
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
x : α
h' : s = {xs_hd} ∪ a
hx : x = xs_hd
⊢ x = xs_hd ∨ x ∈ tail✝

Next tactic:
exact Or.inl hx
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · 

Proof state:
case cons.mp.intro.intro.inr.inr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s a : Finset α
h : ∀ x ∈ a, x ∈ tail✝
x : α
h' : s = {xs_hd} ∪ a
hx' : x ∈ a
⊢ x = xs_hd ∨ x ∈ tail✝

Next tactic:
exact Or.inr (h _ hx')
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · exact Or.inr (h _ hx')
    · 

Proof state:
case cons.mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
⊢ (∀ x ∈ s, x = xs_hd ∨ x ∈ tail✝) → ∃ a, (∀ x ∈ a, x ∈ tail✝) ∧ (s = a ∨ s = {xs_hd} ∪ a)

Next tactic:
intro h
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · exact Or.inr (h _ hx')
    · intro h
      

Proof state:
case cons.mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
h : ∀ x ∈ s, x = xs_hd ∨ x ∈ tail✝
⊢ ∃ a, (∀ x ∈ a, x ∈ tail✝) ∧ (s = a ∨ s = {xs_hd} ∪ a)

Next tactic:
exists s \ ({xs_hd} : Finset α)
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · exact Or.inr (h _ hx')
    · intro h
      exists s \ ({xs_hd} : Finset α)
      

Proof state:
case cons.mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
h : ∀ x ∈ s, x = xs_hd ∨ x ∈ tail✝
⊢ (∀ x ∈ s \ {xs_hd}, x ∈ tail✝) ∧ (s = s \ {xs_hd} ∨ s = {xs_hd} ∪ s \ {xs_hd})

Next tactic:
simp only [and_imp, mem_sdiff, mem_singleton]
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · exact Or.inr (h _ hx')
    · intro h
      exists s \ ({xs_hd} : Finset α)
      simp only [and_imp, mem_sdiff, mem_singleton]
      

Proof state:
case cons.mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
h : ∀ x ∈ s, x = xs_hd ∨ x ∈ tail✝
⊢ (∀ x ∈ s, ¬x = xs_hd → x ∈ tail✝) ∧ (s = s \ {xs_hd} ∨ s = {xs_hd} ∪ s \ {xs_hd})

Next tactic:
simp only [or_iff_not_imp_left] at h
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · exact Or.inr (h _ hx')
    · intro h
      exists s \ ({xs_hd} : Finset α)
      simp only [and_imp, mem_sdiff, mem_singleton]
      simp only [or_iff_not_imp_left] at h
      

Proof state:
case cons.mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
h : ∀ x ∈ s, ¬x = xs_hd → x ∈ tail✝
⊢ (∀ x ∈ s, ¬x = xs_hd → x ∈ tail✝) ∧ (s = s \ {xs_hd} ∨ s = {xs_hd} ∪ s \ {xs_hd})

Next tactic:
exists h
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · exact Or.inr (h _ hx')
    · intro h
      exists s \ ({xs_hd} : Finset α)
      simp only [and_imp, mem_sdiff, mem_singleton]
      simp only [or_iff_not_imp_left] at h
      exists h
      

Proof state:
case cons.mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
h : ∀ x ∈ s, ¬x = xs_hd → x ∈ tail✝
⊢ s = s \ {xs_hd} ∨ s = {xs_hd} ∪ s \ {xs_hd}

Next tactic:
by_cases h : xs_hd ∈ s
@[simp]
theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) :
    s ∈ Finset.enum xs ↔ ∀ x ∈ s, x ∈ xs := by
  induction' xs with xs_hd generalizing s <;> simp [*, Finset.enum]
  · simp [Finset.eq_empty_iff_forall_not_mem]
  · constructor
    · rintro ⟨a, h, h'⟩ x hx
      cases' h' with _ h' a b
      · right
        apply h
        subst a
        exact hx
      · simp only [h', mem_union, mem_singleton] at hx ⊢
        cases' hx with hx hx'
        · exact Or.inl hx
        · exact Or.inr (h _ hx')
    · intro h
      exists s \ ({xs_hd} : Finset α)
      simp only [and_imp, mem_sdiff, mem_singleton]
      simp only [or_iff_not_imp_left] at h
      exists h
      by_cases h : xs_hd ∈ s
      · 

Proof state:
case pos
α : Type u
β : α → Type v
inst✝ : DecidableEq α
xs_hd : α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
h✝ : ∀ x ∈ s, ¬x = xs_hd → x ∈ tail✝
h : xs_hd ∈ s
⊢ s = s \ {xs_hd} ∨ s = {xs_hd} ∪ s \ {xs_hd}

Next tactic:
have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]