l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem powersetCard_self (s : Finset α) : powersetCard s.card s = {s} := by
  ext
  rw [mem_powersetCard, mem_singleton]
  constructor
  · exact fun ⟨hs, hc⟩ => eq_of_subset_of_card_le hs hc.ge
  · rintro rfl
    

Proof state:
case a.mpr
α : Type u_1
s t a✝ : Finset α
⊢ a✝ ⊆ a✝ ∧ card a✝ = card a✝

Next tactic:
simp
theorem powerset_card_disjiUnion (s : Finset α) :
    Finset.powerset s =
      (range (s.card + 1)).disjiUnion (fun i => powersetCard i s)
        (s.pairwise_disjoint_powersetCard.set_pairwise _) := by
  

Proof state:
α : Type u_1
s✝ t s : Finset α
⊢ powerset s =
    disjiUnion (range (card s + 1)) (fun i => powersetCard i s)
      (_ : Set.Pairwise ↑(range (card s + 1)) fun i j => _root_.Disjoint (powersetCard i s) (powersetCard j s))

Next tactic:
refine' ext fun a => ⟨fun ha => _, fun ha => _⟩
theorem powerset_card_disjiUnion (s : Finset α) :
    Finset.powerset s =
      (range (s.card + 1)).disjiUnion (fun i => powersetCard i s)
        (s.pairwise_disjoint_powersetCard.set_pairwise _) := by
  refine' ext fun a => ⟨fun ha => _, fun ha => _⟩
  · 

Proof state:
case refine'_1
α : Type u_1
s✝ t s a : Finset α
ha : a ∈ powerset s
⊢ a ∈
    disjiUnion (range (card s + 1)) (fun i => powersetCard i s)
      (_ : Set.Pairwise ↑(range (card s + 1)) fun i j => _root_.Disjoint (powersetCard i s) (powersetCard j s))

Next tactic:
rw [mem_disjiUnion]
theorem powerset_card_disjiUnion (s : Finset α) :
    Finset.powerset s =
      (range (s.card + 1)).disjiUnion (fun i => powersetCard i s)
        (s.pairwise_disjoint_powersetCard.set_pairwise _) := by
  refine' ext fun a => ⟨fun ha => _, fun ha => _⟩
  · rw [mem_disjiUnion]
    

Proof state:
case refine'_1
α : Type u_1
s✝ t s a : Finset α
ha : a ∈ powerset s
⊢ ∃ a_1 ∈ range (card s + 1), a ∈ powersetCard a_1 s

Next tactic:
exact
      ⟨a.card, mem_range.mpr (Nat.lt_succ_of_le (card_le_of_subset (mem_powerset.mp ha))),
        mem_powersetCard.mpr ⟨mem_powerset.mp ha, rfl⟩⟩
theorem powerset_card_disjiUnion (s : Finset α) :
    Finset.powerset s =
      (range (s.card + 1)).disjiUnion (fun i => powersetCard i s)
        (s.pairwise_disjoint_powersetCard.set_pairwise _) := by
  refine' ext fun a => ⟨fun ha => _, fun ha => _⟩
  · rw [mem_disjiUnion]
    exact
      ⟨a.card, mem_range.mpr (Nat.lt_succ_of_le (card_le_of_subset (mem_powerset.mp ha))),
        mem_powersetCard.mpr ⟨mem_powerset.mp ha, rfl⟩⟩
  · 

Proof state:
case refine'_2
α : Type u_1
s✝ t s a : Finset α
ha :
  a ∈
    disjiUnion (range (card s + 1)) (fun i => powersetCard i s)
      (_ : Set.Pairwise ↑(range (card s + 1)) fun i j => _root_.Disjoint (powersetCard i s) (powersetCard j s))
⊢ a ∈ powerset s

Next tactic:
rcases mem_disjiUnion.mp ha with ⟨i, _hi, ha⟩
theorem powerset_card_disjiUnion (s : Finset α) :
    Finset.powerset s =
      (range (s.card + 1)).disjiUnion (fun i => powersetCard i s)
        (s.pairwise_disjoint_powersetCard.set_pairwise _) := by
  refine' ext fun a => ⟨fun ha => _, fun ha => _⟩
  · rw [mem_disjiUnion]
    exact
      ⟨a.card, mem_range.mpr (Nat.lt_succ_of_le (card_le_of_subset (mem_powerset.mp ha))),
        mem_powersetCard.mpr ⟨mem_powerset.mp ha, rfl⟩⟩
  · rcases mem_disjiUnion.mp ha with ⟨i, _hi, ha⟩
    

Proof state:
case refine'_2.intro.intro
α : Type u_1
s✝ t s a : Finset α
ha✝ :
  a ∈
    disjiUnion (range (card s + 1)) (fun i => powersetCard i s)
      (_ : Set.Pairwise ↑(range (card s + 1)) fun i j => _root_.Disjoint (powersetCard i s) (powersetCard j s))
i : ℕ
_hi : i ∈ range (card s + 1)
ha : a ∈ powersetCard i s
⊢ a ∈ powerset s

Next tactic:
exact mem_powerset.mpr (mem_powersetCard.mp ha).1
theorem powerset_card_biUnion [DecidableEq (Finset α)] (s : Finset α) :
    Finset.powerset s = (range (s.card + 1)).biUnion fun i => powersetCard i s := by
  

Proof state:
α : Type u_1
s✝ t : Finset α
inst✝ : DecidableEq (Finset α)
s : Finset α
⊢ powerset s = Finset.biUnion (range (card s + 1)) fun i => powersetCard i s

Next tactic:
simpa only [disjiUnion_eq_biUnion] using powerset_card_disjiUnion s
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  

Proof state:
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
⊢ sup (powersetCard (Nat.succ n) u) id = u

Next tactic:
apply le_antisymm
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · 

Proof state:
case a
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
⊢ sup (powersetCard (Nat.succ n) u) id ≤ u

Next tactic:
simp_rw [Finset.sup_le_iff, mem_powersetCard]
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    

Proof state:
case a
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
⊢ ∀ (b : Finset α), b ⊆ u ∧ card b = Nat.succ n → id b ≤ u

Next tactic:
rintro x ⟨h, -⟩
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    

Proof state:
case a.intro
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
x : Finset α
h : x ⊆ u
⊢ id x ≤ u

Next tactic:
exact h
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    exact h
  · 

Proof state:
case a
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
⊢ u ≤ sup (powersetCard (Nat.succ n) u) id

Next tactic:
rw [sup_eq_biUnion, le_iff_subset, subset_iff]
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    exact h
  · rw [sup_eq_biUnion, le_iff_subset, subset_iff]
    

Proof state:
case a
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
⊢ ∀ ⦃x : α⦄, x ∈ u → x ∈ Finset.biUnion (powersetCard (Nat.succ n) u) id

Next tactic:
intro x hx
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    exact h
  · rw [sup_eq_biUnion, le_iff_subset, subset_iff]
    intro x hx
    

Proof state:
case a
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
x : α
hx : x ∈ u
⊢ x ∈ Finset.biUnion (powersetCard (Nat.succ n) u) id

Next tactic:
simp only [mem_biUnion, exists_prop, id.def]
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    exact h
  · rw [sup_eq_biUnion, le_iff_subset, subset_iff]
    intro x hx
    simp only [mem_biUnion, exists_prop, id.def]
    

Proof state:
case a
α : Type u_1
s t : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
x : α
hx : x ∈ u
⊢ ∃ a ∈ powersetCard (Nat.succ n) u, x ∈ a

Next tactic:
obtain ⟨t, ht⟩ : ∃ t, t ∈ powersetCard n (u.erase x) := powersetCard_nonempty
      (le_trans (Nat.le_sub_one_of_lt hn) pred_card_le_card_erase)
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    exact h
  · rw [sup_eq_biUnion, le_iff_subset, subset_iff]
    intro x hx
    simp only [mem_biUnion, exists_prop, id.def]
    obtain ⟨t, ht⟩ : ∃ t, t ∈ powersetCard n (u.erase x) := powersetCard_nonempty
      (le_trans (Nat.le_sub_one_of_lt hn) pred_card_le_card_erase)
    · 

Proof state:
case a.intro
α : Type u_1
s t✝ : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
x : α
hx : x ∈ u
t : Finset α
ht : t ∈ powersetCard n (erase u x)
⊢ ∃ a ∈ powersetCard (Nat.succ n) u, x ∈ a

Next tactic:
refine' ⟨insert x t, _, mem_insert_self _ _⟩
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    exact h
  · rw [sup_eq_biUnion, le_iff_subset, subset_iff]
    intro x hx
    simp only [mem_biUnion, exists_prop, id.def]
    obtain ⟨t, ht⟩ : ∃ t, t ∈ powersetCard n (u.erase x) := powersetCard_nonempty
      (le_trans (Nat.le_sub_one_of_lt hn) pred_card_le_card_erase)
    · refine' ⟨insert x t, _, mem_insert_self _ _⟩
      

Proof state:
case a.intro
α : Type u_1
s t✝ : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
x : α
hx : x ∈ u
t : Finset α
ht : t ∈ powersetCard n (erase u x)
⊢ insert x t ∈ powersetCard (Nat.succ n) u

Next tactic:
rw [← insert_erase hx, powersetCard_succ_insert (not_mem_erase _ _)]
theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u.card) :
    (powersetCard n.succ u).sup id = u := by
  apply le_antisymm
  · simp_rw [Finset.sup_le_iff, mem_powersetCard]
    rintro x ⟨h, -⟩
    exact h
  · rw [sup_eq_biUnion, le_iff_subset, subset_iff]
    intro x hx
    simp only [mem_biUnion, exists_prop, id.def]
    obtain ⟨t, ht⟩ : ∃ t, t ∈ powersetCard n (u.erase x) := powersetCard_nonempty
      (le_trans (Nat.le_sub_one_of_lt hn) pred_card_le_card_erase)
    · refine' ⟨insert x t, _, mem_insert_self _ _⟩
      rw [← insert_erase hx, powersetCard_succ_insert (not_mem_erase _ _)]
      

Proof state:
case a.intro
α : Type u_1
s t✝ : Finset α
inst✝ : DecidableEq α
u : Finset α
n : ℕ
hn : n < card u
x : α
hx : x ∈ u
t : Finset α
ht : t ∈ powersetCard n (erase u x)
⊢ insert x t ∈ powersetCard (Nat.succ n) (erase u x) ∪ image (insert x) (powersetCard n (erase u x))

Next tactic:
exact mem_union_right _ (mem_image_of_mem _ ht)
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    

Proof state:
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
⊢ t ∈ powersetCard n (map f s) ↔ t ∈ map (mapEmbedding f).toEmbedding (powersetCard n s)

Next tactic:
simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    

Proof state:
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
⊢ t ⊆ map f s ∧ card t = n ↔ ∃ a, (a ⊆ s ∧ card a = n) ∧ (mapEmbedding f).toEmbedding a = t

Next tactic:
constructor
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · 

Proof state:
case mp
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
⊢ t ⊆ map f s ∧ card t = n → ∃ a, (a ⊆ s ∧ card a = n) ∧ (mapEmbedding f).toEmbedding a = t

Next tactic:
classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      refine' ⟨_, _, this⟩
      rw [← card_map f, this, h.2]; simp
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      

Proof state:
case mp
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
⊢ t ⊆ map f s ∧ card t = n → ∃ a, (a ⊆ s ∧ card a = n) ∧ (mapEmbedding f).toEmbedding a = t

Next tactic:
intro h
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      

Proof state:
case mp
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
h : t ⊆ map f s ∧ card t = n
⊢ ∃ a, (a ⊆ s ∧ card a = n) ∧ (mapEmbedding f).toEmbedding a = t

Next tactic:
have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        

Proof state:
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
h : t ⊆ map f s ∧ card t = n
⊢ map f (filter (fun x => f x ∈ t) s) = t

Next tactic:
ext x
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        

Proof state:
case a
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
h : t ⊆ map f s ∧ card t = n
x : β
⊢ x ∈ map f (filter (fun x => f x ∈ t) s) ↔ x ∈ t

Next tactic:
simp only [mem_map, mem_filter, decide_eq_true_eq]
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        

Proof state:
case a
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
h : t ⊆ map f s ∧ card t = n
x : β
⊢ (∃ a, (a ∈ s ∧ f a ∈ t) ∧ f a = x) ↔ x ∈ t

Next tactic:
exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      

Proof state:
case mp
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
h : t ⊆ map f s ∧ card t = n
this : map f (filter (fun x => f x ∈ t) s) = t
⊢ ∃ a, (a ⊆ s ∧ card a = n) ∧ (mapEmbedding f).toEmbedding a = t

Next tactic:
refine' ⟨_, _, this⟩
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      refine' ⟨_, _, this⟩
      

Proof state:
case mp
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
h : t ⊆ map f s ∧ card t = n
this : map f (filter (fun x => f x ∈ t) s) = t
⊢ filter (fun x => f x ∈ t) s ⊆ s ∧ card (filter (fun x => f x ∈ t) s) = n

Next tactic:
rw [← card_map f, this, h.2]
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      refine' ⟨_, _, this⟩
      rw [← card_map f, this, h.2]; 

Proof state:
case mp
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
h : t ⊆ map f s ∧ card t = n
this : map f (filter (fun x => f x ∈ t) s) = t
⊢ filter (fun x => f x ∈ t) s ⊆ s ∧ n = n

Next tactic:
simp
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      refine' ⟨_, _, this⟩
      rw [← card_map f, this, h.2]; simp
    · 

Proof state:
case mpr
α : Type u_1
s✝ t✝ : Finset α
β : Type u_2
f : α ↪ β
n : ℕ
s : Finset α
t : Finset β
⊢ (∃ a, (a ⊆ s ∧ card a = n) ∧ (mapEmbedding f).toEmbedding a = t) → t ⊆ map f s ∧ card t = n

Next tactic:
rintro ⟨a, ⟨has, rfl⟩, rfl⟩
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      refine' ⟨_, _, this⟩
      rw [← card_map f, this, h.2]; simp
    · rintro ⟨a, ⟨has, rfl⟩, rfl⟩
      

Proof state:
case mpr.intro.intro.intro
α : Type u_1
s✝ t : Finset α
β : Type u_2
f : α ↪ β
s a : Finset α
has : a ⊆ s
⊢ (mapEmbedding f).toEmbedding a ⊆ map f s ∧ card ((mapEmbedding f).toEmbedding a) = card a

Next tactic:
dsimp [RelEmbedding.coe_toEmbedding]
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      refine' ⟨_, _, this⟩
      rw [← card_map f, this, h.2]; simp
    · rintro ⟨a, ⟨has, rfl⟩, rfl⟩
      dsimp [RelEmbedding.coe_toEmbedding]
      --Porting note: Why is `rw` required here and not `simp`?
      

Proof state:
case mpr.intro.intro.intro
α : Type u_1
s✝ t : Finset α
β : Type u_2
f : α ↪ β
s a : Finset α
has : a ⊆ s
⊢ (mapEmbedding f) a ⊆ map f s ∧ card ((mapEmbedding f) a) = card a

Next tactic:
rw [mapEmbedding_apply]
theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding :=
  ext <| fun t => by
    simp only [card_map, mem_powersetCard, le_eq_subset, gt_iff_lt, mem_map, mapEmbedding_apply]
    constructor
    · classical
      intro h
      have : map f (filter (fun x => (f x ∈ t)) s) = t := by
        ext x
        simp only [mem_map, mem_filter, decide_eq_true_eq]
        exact ⟨fun ⟨_y, ⟨_hy₁, hy₂⟩, hy₃⟩ => hy₃ ▸ hy₂,
          fun hx => let ⟨y, hy⟩ := mem_map.1 (h.1 hx); ⟨y, ⟨hy.1, hy.2 ▸ hx⟩, hy.2⟩⟩
      refine' ⟨_, _, this⟩
      rw [← card_map f, this, h.2]; simp
    · rintro ⟨a, ⟨has, rfl⟩, rfl⟩
      dsimp [RelEmbedding.coe_toEmbedding]
      --Porting note: Why is `rw` required here and not `simp`?
      rw [mapEmbedding_apply]
      

Proof state:
case mpr.intro.intro.intro
α : Type u_1
s✝ t : Finset α
β : Type u_2
f : α ↪ β
s a : Finset α
has : a ⊆ s
⊢ map f a ⊆ map f s ∧ card (map f a) = card a

Next tactic:
simp [has]
@[simp]
theorem prod_edist_eq_card (f g : WithLp 0 (α × β)) :
    edist f g =
      (if edist f.fst g.fst = 0 then 0 else 1) + (if edist f.snd g.snd = 0 then 0 else 1) := by
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : EDist α
inst✝ : EDist β
x y : WithLp p (α × β)
x' : α × β
f g : WithLp 0 (α × β)
⊢ edist f g = (if edist f.1 g.1 = 0 then 0 else 1) + if edist f.2 g.2 = 0 then 0 else 1

Next tactic:
convert if_pos rfl
theorem prod_edist_eq_sup (f g : WithLp ∞ (α × β)) :
    edist f g = edist f.fst g.fst ⊔ edist f.snd g.snd := by
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : EDist α
inst✝ : EDist β
x y : WithLp p (α × β)
x' : α × β
f g : WithLp ⊤ (α × β)
⊢ edist f g = edist f.1 g.1 ⊔ edist f.2 g.2

Next tactic:
dsimp [edist]
theorem prod_edist_eq_sup (f g : WithLp ∞ (α × β)) :
    edist f g = edist f.fst g.fst ⊔ edist f.snd g.snd := by
  dsimp [edist]
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : EDist α
inst✝ : EDist β
x y : WithLp p (α × β)
x' : α × β
f g : WithLp ⊤ (α × β)
⊢ (if ⊤ = 0 then (if edist f.1 g.1 = 0 then 0 else 1) + if edist f.2 g.2 = 0 then 0 else 1
    else if ⊤ = ⊤ then max (edist f.1 g.1) (edist f.2 g.2) else (edist f.1 g.1 ^ 0 + edist f.2 g.2 ^ 0) ^ (1 / 0)) =
    max (edist f.1 g.1) (edist f.2 g.2)

Next tactic:
exact if_neg ENNReal.top_ne_zero
/-- The distance from one point to itself is always zero.

This holds independent of `p` and does not require `[Fact (1 ≤ p)]`. We keep it separate
from `WithLp.instProdPseudoEMetricSpace` so it can be used also for `p < 1`. -/
theorem prod_edist_self (f : WithLp p (α × β)) : edist f f = 0 := by
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
f : WithLp p (α × β)
⊢ edist f f = 0

Next tactic:
rcases p.trichotomy with (rfl | rfl | h)