Theorem: Finset.card_eq_of_bijective
File: Mathlib/Data/Finset/Card.lean

tactic: calc
  s.card = ((range n).attach.image fun i => f i.1 (mem_range.1 i.2)).card := by rw [this]
  _      = (range n).attach.card := ?_
  _      = (range n).card := card_attach
  _      = n := card_range n
state_before: α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
⊢ s.card = n
state_after: α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
⊢ (image (fun i => f ↑i ⋯) (range n).attach).card = (range n).attach.card

tactic: apply card_image_of_injective
state_before: α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
⊢ (image (fun i => f ↑i ⋯) (range n).attach).card = (range n).attach.card
state_after: case H
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
⊢ Injective fun i => f ↑i ⋯

tactic: intro ⟨i, hi⟩ ⟨j, hj⟩ eq
state_before: case H
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
⊢ Injective fun i => f ↑i ⋯
state_after: case H
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
i : ℕ
hi : i ∈ range n
j : ℕ
hj : j ∈ range n
eq : (fun i => f ↑i ⋯) ⟨i, hi⟩ = (fun i => f ↑i ⋯) ⟨j, hj⟩
⊢ ⟨i, hi⟩ = ⟨j, hj⟩

tactic: exact Subtype.eq <| f_inj i j (mem_range.1 hi) (mem_range.1 hj) eq
state_before: case H
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
i : ℕ
hi : i ∈ range n
j : ℕ
hj : j ∈ range n
eq : (fun i => f ↑i ⋯) ⟨i, hi⟩ = (fun i => f ↑i ⋯) ⟨j, hj⟩
⊢ ⟨i, hi⟩ = ⟨j, hj⟩
state_after: no goals

tactic: ext a
state_before: α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
⊢ s = image (fun i => f ↑i ⋯) (range n).attach
state_after: case a
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ a ∈ s ↔ a ∈ image (fun i => f ↑i ⋯) (range n).attach

tactic: suffices _ : a ∈ s ↔ ∃ (i : _) (hi : i ∈ range n), f i (mem_range.1 hi) = a by
  simpa only [mem_image, mem_attach, true_and_iff, Subtype.exists]
state_before: case a
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ a ∈ s ↔ a ∈ image (fun i => f ↑i ⋯) (range n).attach
state_after: case a
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ a ∈ s ↔ ∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a

tactic: constructor
state_before: case a
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ a ∈ s ↔ ∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a
state_after: case a.mp
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ a ∈ s → ∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a

case a.mpr
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ (∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a) → a ∈ s

tactic: simpa only [mem_image, mem_attach, true_and_iff, Subtype.exists]
state_before: α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
x✝ : a ∈ s ↔ ∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a
⊢ a ∈ s ↔ a ∈ image (fun i => f ↑i ⋯) (range n).attach
state_after: no goals

tactic: intro ha
state_before: case a.mp
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ a ∈ s → ∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a
state_after: case a.mp
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
ha : a ∈ s
⊢ ∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a

tactic: obtain ⟨i, hi, rfl⟩ := hf a ha
state_before: case a.mp
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
ha : a ∈ s
⊢ ∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a
state_after: case a.mp.intro.intro
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
i : ℕ
hi : i < n
ha : f i hi ∈ s
⊢ ∃ i_1, ∃ (hi_1 : i_1 ∈ range n), f i_1 ⋯ = f i hi

tactic: use i, mem_range.2 hi
state_before: case a.mp.intro.intro
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
i : ℕ
hi : i < n
ha : f i hi ∈ s
⊢ ∃ i_1, ∃ (hi_1 : i_1 ∈ range n), f i_1 ⋯ = f i hi
state_after: no goals

tactic: rintro ⟨i, hi, rfl⟩
state_before: case a.mpr
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
a : α
⊢ (∃ i, ∃ (hi : i ∈ range n), f i ⋯ = a) → a ∈ s
state_after: case a.mpr.intro.intro
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
i : ℕ
hi : i ∈ range n
⊢ f i ⋯ ∈ s

tactic: apply hf'
state_before: case a.mpr.intro.intro
α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
i : ℕ
hi : i ∈ range n
⊢ f i ⋯ ∈ s
state_after: no goals

tactic: rw [this]
state_before: α : Type u_1
β : Type u_2
R : Type u_3
s t u : Finset α
f✝ : α → β
n : ℕ
f : (i : ℕ) → i < n → α
hf : ∀ a ∈ s, ∃ i, ∃ (h : i < n), f i h = a
hf' : ∀ (i : ℕ) (h : i < n), f i h ∈ s
f_inj : ∀ (i j : ℕ) (hi : i < n) (hj : j < n), f i hi = f j hj → i = j
this : s = image (fun i => f ↑i ⋯) (range n).attach
⊢ s.card = (image (fun i => f ↑i ⋯) (range n).attach).card
state_after: no goals