l3lab/ntp-mathlib huggingface dataset:
@[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
      · have : {xs_hd} ⊆ s := by
          

Proof state:
α : 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
⊢ {xs_hd} ⊆ s

Next tactic:
simp only [HasSubset.Subset, *, forall_eq, 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]
      simp only [or_iff_not_imp_left] at h
      exists h
      by_cases h : xs_hd ∈ s
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        

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
this : {xs_hd} ⊆ s
⊢ s = s \ {xs_hd} ∨ s = {xs_hd} ∪ s \ {xs_hd}

Next tactic:
simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
@[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
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
      · 

Proof state:
case neg
α : 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:
left
@[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
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
      · left
        

Proof state:
case neg.h
α : 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}

Next tactic:
symm
@[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
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
      · left
        symm
        

Proof state:
case neg.h
α : 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 \ {xs_hd} = s

Next tactic:
simp only [sdiff_eq_self]
@[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
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
      · left
        symm
        simp only [sdiff_eq_self]
        

Proof state:
case neg.h
α : 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 ∩ {xs_hd} ⊆ ∅

Next tactic:
intro 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
        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
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
      · left
        symm
        simp only [sdiff_eq_self]
        intro a
        

Proof state:
case neg.h
α : 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
a : α
⊢ a ∈ s ∩ {xs_hd} → a ∈ ∅

Next tactic:
simp only [and_imp, mem_inter, 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]
      simp only [or_iff_not_imp_left] at h
      exists h
      by_cases h : xs_hd ∈ s
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
      · left
        symm
        simp only [sdiff_eq_self]
        intro a
        simp only [and_imp, mem_inter, mem_singleton]
        

Proof state:
case neg.h
α : 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
a : α
⊢ a ∈ s → a = xs_hd → a ∈ ∅

Next tactic:
rintro h₀ rfl
@[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
      · have : {xs_hd} ⊆ s := by
          simp only [HasSubset.Subset, *, forall_eq, mem_singleton]
        simp only [union_sdiff_of_subset this, or_true_iff, Finset.union_sdiff_of_subset,
          eq_self_iff_true]
      · left
        symm
        simp only [sdiff_eq_self]
        intro a
        simp only [and_imp, mem_inter, mem_singleton]
        rintro h₀ rfl
        

Proof state:
case neg.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
tail✝ : List α
tail_ih✝ : ∀ (s : Finset α), s ∈ enum tail✝ ↔ ∀ x ∈ s, x ∈ tail✝
s : Finset α
a : α
h₀ : a ∈ s
h✝ : ∀ x ∈ s, ¬x = a → x ∈ tail✝
h : a ∉ s
⊢ a ∈ ∅

Next tactic:
exact (h h₀).elim
instance Finset.finEnum [FinEnum α] : FinEnum (Finset α) :=
  ofList (Finset.enum (toList α)) (by 

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
⊢ ∀ (x : Finset α), x ∈ enum (toList α)

Next tactic:
intro
instance Finset.finEnum [FinEnum α] : FinEnum (Finset α) :=
  ofList (Finset.enum (toList α)) (by intro; 

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

Next tactic:
simp
instance Subtype.finEnum [FinEnum α] (p : α → Prop) [DecidablePred p] : FinEnum { x // p x } :=
  ofList ((toList α).filterMap fun x => if h : p x then some ⟨_, h⟩ else none)
    (by 

Proof state:
α : Type u
β : α → Type v
inst✝¹ : FinEnum α
p : α → Prop
inst✝ : DecidablePred p
⊢ ∀ (x : { x // p x }),
    x ∈ List.filterMap (fun x => if h : p x then some { val := x, property := h } else none) (toList α)

Next tactic:
rintro ⟨x, h⟩
instance Subtype.finEnum [FinEnum α] (p : α → Prop) [DecidablePred p] : FinEnum { x // p x } :=
  ofList ((toList α).filterMap fun x => if h : p x then some ⟨_, h⟩ else none)
    (by rintro ⟨x, h⟩; 

Proof state:
case mk
α : Type u
β : α → Type v
inst✝¹ : FinEnum α
p : α → Prop
inst✝ : DecidablePred p
x : α
h : p x
⊢ { val := x, property := h } ∈
    List.filterMap (fun x => if h : p x then some { val := x, property := h } else none) (toList α)

Next tactic:
simp
instance Subtype.finEnum [FinEnum α] (p : α → Prop) [DecidablePred p] : FinEnum { x // p x } :=
  ofList ((toList α).filterMap fun x => if h : p x then some ⟨_, h⟩ else none)
    (by rintro ⟨x, h⟩; simp; 

Proof state:
case mk
α : Type u
β : α → Type v
inst✝¹ : FinEnum α
p : α → Prop
inst✝ : DecidablePred p
x : α
h : p x
⊢ ∃ a, (if h : p a then some { val := a, property := h } else none) = some { val := x, property := h }

Next tactic:
exists x
instance Subtype.finEnum [FinEnum α] (p : α → Prop) [DecidablePred p] : FinEnum { x // p x } :=
  ofList ((toList α).filterMap fun x => if h : p x then some ⟨_, h⟩ else none)
    (by rintro ⟨x, h⟩; simp; exists x; 

Proof state:
case mk
α : Type u
β : α → Type v
inst✝¹ : FinEnum α
p : α → Prop
inst✝ : DecidablePred p
x : α
h : p x
⊢ (if h : p x then some { val := x, property := h } else none) = some { val := x, property := h }

Next tactic:
simp [*]
instance (β : α → Type v) [FinEnum α] [∀ a, FinEnum (β a)] : FinEnum (Sigma β) :=
  ofList ((toList α).bind fun a => (toList (β a)).map <| Sigma.mk a)
    (by 

Proof state:
α : Type u
β✝ β : α → Type v
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
⊢ ∀ (x : Sigma β), x ∈ List.bind (toList α) fun a => List.map (Sigma.mk a) (toList (β a))

Next tactic:
intro x
instance (β : α → Type v) [FinEnum α] [∀ a, FinEnum (β a)] : FinEnum (Sigma β) :=
  ofList ((toList α).bind fun a => (toList (β a)).map <| Sigma.mk a)
    (by intro x; 

Proof state:
α : Type u
β✝ β : α → Type v
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
x : Sigma β
⊢ x ∈ List.bind (toList α) fun a => List.map (Sigma.mk a) (toList (β a))

Next tactic:
cases x
instance (β : α → Type v) [FinEnum α] [∀ a, FinEnum (β a)] : FinEnum (Sigma β) :=
  ofList ((toList α).bind fun a => (toList (β a)).map <| Sigma.mk a)
    (by intro x; cases x; 

Proof state:
case mk
α : Type u
β✝ β : α → Type v
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
fst✝ : α
snd✝ : β fst✝
⊢ { fst := fst✝, snd := snd✝ } ∈ List.bind (toList α) fun a => List.map (Sigma.mk a) (toList (β a))

Next tactic:
simp
instance PSigma.finEnumPropLeft {α : Prop} {β : α → Type v} [∀ a, FinEnum (β a)] [Decidable α] :
    FinEnum (Σ'a, β a) :=
  if h : α then ofList ((toList (β h)).map <| PSigma.mk h) fun ⟨a, Ba⟩ => by 

Proof state:
α✝ : Type u
β✝ : α✝ → Type v
α : Prop
β : α → Type v
inst✝¹ : (a : α) → FinEnum (β a)
inst✝ : Decidable α
h : α
x✝ : (a : α) ×' β a
a : α
Ba : β a
⊢ { fst := a, snd := Ba } ∈ List.map (PSigma.mk h) (toList (β h))

Next tactic:
simp
instance PSigma.finEnumPropProp {α : Prop} {β : α → Prop} [Decidable α] [∀ a, Decidable (β a)] :
    FinEnum (Σ'a, β a) :=
  if h : ∃ a, β a then ofList [⟨h.fst, h.snd⟩] (by 

Proof state:
α✝ : Type u
β✝ : α✝ → Type v
α : Prop
β : α → Prop
inst✝¹ : Decidable α
inst✝ : (a : α) → Decidable (β a)
h : ∃ (a : α), β a
⊢ ∀ (x : (a : α) ×' β a), x ∈ [{ fst := (_ : α), snd := (_ : β (_ : α)) }]

Next tactic:
rintro ⟨⟩
instance PSigma.finEnumPropProp {α : Prop} {β : α → Prop} [Decidable α] [∀ a, Decidable (β a)] :
    FinEnum (Σ'a, β a) :=
  if h : ∃ a, β a then ofList [⟨h.fst, h.snd⟩] (by rintro ⟨⟩; 

Proof state:
case mk
α✝ : Type u
β✝ : α✝ → Type v
α : Prop
β : α → Prop
inst✝¹ : Decidable α
inst✝ : (a : α) → Decidable (β a)
h : ∃ (a : α), β a
fst✝ : α
snd✝ : β fst✝
⊢ { fst := fst✝, snd := snd✝ } ∈ [{ fst := (_ : α), snd := (_ : β (_ : α)) }]

Next tactic:
simp
instance (priority := 100) [FinEnum α] : Fintype α where
  elems := univ.map (equiv).symm.toEmbedding
  complete := by 

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
⊢ ∀ (x : α), x ∈ map (Equiv.toEmbedding equiv.symm) univ

Next tactic:
intros
instance (priority := 100) [FinEnum α] : Fintype α where
  elems := univ.map (equiv).symm.toEmbedding
  complete := by intros; 

Proof state:
α : Type u
β : α → Type v
inst✝ : FinEnum α
x✝ : α
⊢ x✝ ∈ map (Equiv.toEmbedding equiv.symm) univ

Next tactic:
simp
/-- For `Pi.cons x xs y f` create a function where every `i ∈ xs` is mapped to `f i` and
`x` is mapped to `y`  -/
def Pi.cons [DecidableEq α] (x : α) (xs : List α) (y : β x) (f : ∀ a, a ∈ xs → β a) :
    ∀ a, a ∈ (x :: xs : List α) → β a
  | b, h => if h' : b = x then cast (by 

Proof state:
α : Type u
β : α → Type v
inst✝ : DecidableEq α
x : α
xs : List α
y : β x
f : (a : α) → a ∈ xs → β a
b : α
h : b ∈ x :: xs
h' : b = x
⊢ β x = β b

Next tactic:
rw [h']
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  

Proof state:
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs : List α
f : (a : α) → a ∈ xs → β a
⊢ f ∈ pi xs fun x => toList (β x)

Next tactic:
induction' xs with xs_hd xs_tl xs_ih
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> 

Proof state:
case nil
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
f : (a : α) → a ∈ [] → β a
⊢ f ∈ pi [] fun x => toList (β x)

Next tactic:
simp [pi, -List.map_eq_map, monad_norm, functor_norm]
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> 

Proof state:
case cons
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ f ∈ pi (xs_hd :: xs_tl) fun x => toList (β x)

Next tactic:
simp [pi, -List.map_eq_map, monad_norm, functor_norm]
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · 

Proof state:
case nil
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
f : (a : α) → a ∈ [] → β a
⊢ f = fun x h => (_ : False).elim

Next tactic:
ext a ⟨⟩
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · 

Proof state:
case cons
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ ∃ a, (∃ a_1, a = Pi.cons xs_hd xs_tl a_1) ∧ ∃ a_1 ∈ pi xs_tl fun x => toList (β x), f = a a_1

Next tactic:
exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    

Proof state:
case cons
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ (∃ a, Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) = Pi.cons xs_hd xs_tl a) ∧
    ∃ a ∈ pi xs_tl fun x => toList (β x), f = Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) a

Next tactic:
constructor
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    

Proof state:
case cons.left
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ ∃ a, Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) = Pi.cons xs_hd xs_tl a
case cons.right
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ ∃ a ∈ pi xs_tl fun x => toList (β x), f = Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) a

Next tactic:
exact ⟨_, rfl⟩
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    

Proof state:
case cons.right
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ ∃ a ∈ pi xs_tl fun x => toList (β x), f = Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) a

Next tactic:
exists Pi.tail f
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    

Proof state:
case cons.right
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ (Pi.tail f ∈ pi xs_tl fun x => toList (β x)) ∧
    f = Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) (Pi.tail f)

Next tactic:
constructor
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    constructor
    · 

Proof state:
case cons.right.left
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ Pi.tail f ∈ pi xs_tl fun x => toList (β x)

Next tactic:
apply xs_ih