l3lab/ntp-mathlib huggingface dataset:
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case none.none.none
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
⊢ liftOrGet f (liftOrGet f none none) none = liftOrGet f none (liftOrGet f none none)

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case none.none.some
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
val✝ : α
⊢ liftOrGet f (liftOrGet f none none) (some val✝) = liftOrGet f none (liftOrGet f none (some val✝))

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case none.some.none
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
val✝ : α
⊢ liftOrGet f (liftOrGet f none (some val✝)) none = liftOrGet f none (liftOrGet f (some val✝) none)

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case none.some.some
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
val✝¹ val✝ : α
⊢ liftOrGet f (liftOrGet f none (some val✝¹)) (some val✝) = liftOrGet f none (liftOrGet f (some val✝¹) (some val✝))

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case some.none.none
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
val✝ : α
⊢ liftOrGet f (liftOrGet f (some val✝) none) none = liftOrGet f (some val✝) (liftOrGet f none none)

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case some.none.some
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
val✝¹ val✝ : α
⊢ liftOrGet f (liftOrGet f (some val✝¹) none) (some val✝) = liftOrGet f (some val✝¹) (liftOrGet f none (some val✝))

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case some.some.none
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
val✝¹ val✝ : α
⊢ liftOrGet f (liftOrGet f (some val✝¹) (some val✝)) none = liftOrGet f (some val✝¹) (liftOrGet f (some val✝) none)

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isAssociative (f : α → α → α) [IsAssociative α f] :
    IsAssociative (Option α) (liftOrGet f) :=
  ⟨fun a b c ↦ by cases a <;> cases b <;> cases c <;> 

Proof state:
case some.some.some
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsAssociative α f
val✝² val✝¹ val✝ : α
⊢ liftOrGet f (liftOrGet f (some val✝²) (some val✝¹)) (some val✝) =
    liftOrGet f (some val✝²) (liftOrGet f (some val✝¹) (some val✝))

Next tactic:
simp [liftOrGet, IsAssociative.assoc]
instance liftOrGet_isIdempotent (f : α → α → α) [IsIdempotent α f] :
    IsIdempotent (Option α) (liftOrGet f) :=
  ⟨fun a ↦ by 

Proof state:
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsIdempotent α f
a : Option α
⊢ liftOrGet f a a = a

Next tactic:
cases a
instance liftOrGet_isIdempotent (f : α → α → α) [IsIdempotent α f] :
    IsIdempotent (Option α) (liftOrGet f) :=
  ⟨fun a ↦ by cases a <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsIdempotent α f
⊢ liftOrGet f none none = none

Next tactic:
simp [liftOrGet, IsIdempotent.idempotent]
instance liftOrGet_isIdempotent (f : α → α → α) [IsIdempotent α f] :
    IsIdempotent (Option α) (liftOrGet f) :=
  ⟨fun a ↦ by cases a <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
f : α → α → α
inst✝ : IsIdempotent α f
val✝ : α
⊢ liftOrGet f (some val✝) (some val✝) = some val✝

Next tactic:
simp [liftOrGet, IsIdempotent.idempotent]
instance liftOrGet_isLeftId (f : α → α → α) : IsLeftId (Option α) (liftOrGet f) none :=
  ⟨fun a ↦ by 

Proof state:
α : Type u_1
β : Type u_2
f : α → α → α
a : Option α
⊢ liftOrGet f none a = a

Next tactic:
cases a
instance liftOrGet_isLeftId (f : α → α → α) : IsLeftId (Option α) (liftOrGet f) none :=
  ⟨fun a ↦ by cases a <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
f : α → α → α
⊢ liftOrGet f none none = none

Next tactic:
simp [liftOrGet]
instance liftOrGet_isLeftId (f : α → α → α) : IsLeftId (Option α) (liftOrGet f) none :=
  ⟨fun a ↦ by cases a <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
f : α → α → α
val✝ : α
⊢ liftOrGet f none (some val✝) = some val✝

Next tactic:
simp [liftOrGet]
instance liftOrGet_isRightId (f : α → α → α) : IsRightId (Option α) (liftOrGet f) none :=
  ⟨fun a ↦ by 

Proof state:
α : Type u_1
β : Type u_2
f : α → α → α
a : Option α
⊢ liftOrGet f a none = a

Next tactic:
cases a
instance liftOrGet_isRightId (f : α → α → α) : IsRightId (Option α) (liftOrGet f) none :=
  ⟨fun a ↦ by cases a <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
f : α → α → α
⊢ liftOrGet f none none = none

Next tactic:
simp [liftOrGet]
instance liftOrGet_isRightId (f : α → α → α) : IsRightId (Option α) (liftOrGet f) none :=
  ⟨fun a ↦ by cases a <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
f : α → α → α
val✝ : α
⊢ liftOrGet f (some val✝) none = some val✝

Next tactic:
simp [liftOrGet]
/-- Given a self-map `f : α → α`,
`invariants f` is the σ-algebra of measurable sets that are invariant under `f`.

A set `s` is `(invariants f)`-measurable
iff it is meaurable w.r.t. the canonical σ-algebra on `α` and `f ⁻¹' s = s`. -/
def invariants [m : MeasurableSpace α] (f : α → α) : MeasurableSpace α :=
  { m ⊓ ⟨fun s ↦ f ⁻¹' s = s, by 

Proof state:
α : Type u_1
m : MeasurableSpace α
f : α → α
⊢ (fun s => f ⁻¹' s = s) ∅

Next tactic:
simp
/-- Given a self-map `f : α → α`,
`invariants f` is the σ-algebra of measurable sets that are invariant under `f`.

A set `s` is `(invariants f)`-measurable
iff it is meaurable w.r.t. the canonical σ-algebra on `α` and `f ⁻¹' s = s`. -/
def invariants [m : MeasurableSpace α] (f : α → α) : MeasurableSpace α :=
  { m ⊓ ⟨fun s ↦ f ⁻¹' s = s, by simp, by 

Proof state:
α : Type u_1
m : MeasurableSpace α
f : α → α
⊢ ∀ (s : Set α), (fun s => f ⁻¹' s = s) s → (fun s => f ⁻¹' s = s) sᶜ

Next tactic:
simp
/-- Given a self-map `f : α → α`,
`invariants f` is the σ-algebra of measurable sets that are invariant under `f`.

A set `s` is `(invariants f)`-measurable
iff it is meaurable w.r.t. the canonical σ-algebra on `α` and `f ⁻¹' s = s`. -/
def invariants [m : MeasurableSpace α] (f : α → α) : MeasurableSpace α :=
  { m ⊓ ⟨fun s ↦ f ⁻¹' s = s, by simp, by simp, fun f hf ↦ by 

Proof state:
α : Type u_1
m : MeasurableSpace α
f✝ : α → α
f : ℕ → Set α
hf : ∀ (i : ℕ), (fun s => f✝ ⁻¹' s = s) (f i)
⊢ (fun s => f✝ ⁻¹' s = s) (⋃ i, f i)

Next tactic:
simp [hf]
theorem inf_le_invariants_comp (f g : α → α) :
    invariants f ⊓ invariants g ≤ invariants (f ∘ g) := fun s hs ↦
  ⟨hs.1.1, by 

Proof state:
α : Type u_1
inst✝ : MeasurableSpace α
f g : α → α
s : Set α
hs : MeasurableSet s
⊢ f ∘ g ⁻¹' s = s

Next tactic:
rw [preimage_comp, hs.1.2, hs.2.2]
theorem le_invariants_iterate (f : α → α) (n : ℕ) :
    invariants f ≤ invariants (f^[n]) := by
  

Proof state:
α : Type u_1
inst✝ : MeasurableSpace α
f : α → α
n : ℕ
⊢ invariants f ≤ invariants f^[n]

Next tactic:
induction n with
  | zero => simp [invariants_le]
  | succ n ihn => exact le_trans (le_inf ihn le_rfl) (inf_le_invariants_comp _ _)
theorem le_invariants_iterate (f : α → α) (n : ℕ) :
    invariants f ≤ invariants (f^[n]) := by
  induction n with
  

Proof state:
case zero
α : Type u_1
inst✝ : MeasurableSpace α
f : α → α
⊢ invariants f ≤ invariants f^[Nat.zero]

Next tactic:
| zero => simp [invariants_le]
theorem le_invariants_iterate (f : α → α) (n : ℕ) :
    invariants f ≤ invariants (f^[n]) := by
  induction n with
  | zero => 

Proof state:
case zero
α : Type u_1
inst✝ : MeasurableSpace α
f : α → α
⊢ invariants f ≤ invariants f^[Nat.zero]

Next tactic:
simp [invariants_le]
theorem le_invariants_iterate (f : α → α) (n : ℕ) :
    invariants f ≤ invariants (f^[n]) := by
  induction n with
  | zero => simp [invariants_le]
  

Proof state:
case succ
α : Type u_1
inst✝ : MeasurableSpace α
f : α → α
n : ℕ
ihn : invariants f ≤ invariants f^[n]
⊢ invariants f ≤ invariants f^[Nat.succ n]

Next tactic:
| succ n ihn => exact le_trans (le_inf ihn le_rfl) (inf_le_invariants_comp _ _)
theorem le_invariants_iterate (f : α → α) (n : ℕ) :
    invariants f ≤ invariants (f^[n]) := by
  induction n with
  | zero => simp [invariants_le]
  | succ n ihn => 

Proof state:
case succ
α : Type u_1
inst✝ : MeasurableSpace α
f : α → α
n : ℕ
ihn : invariants f ≤ invariants f^[n]
⊢ invariants f ≤ invariants f^[Nat.succ n]

Next tactic:
exact le_trans (le_inf ihn le_rfl) (inf_le_invariants_comp _ _)
theorem measurable_invariants_dom {f : α → α} {g : α → β} :
    Measurable[invariants f] g ↔ Measurable g ∧ ∀ s, MeasurableSet s → (g ∘ f) ⁻¹' s = g ⁻¹' s := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
f : α → α
g : α → β
⊢ Measurable g ↔ Measurable g ∧ ∀ (s : Set β), MeasurableSet s → g ∘ f ⁻¹' s = g ⁻¹' s

Next tactic:
simp only [Measurable, ← forall_and]
theorem measurable_invariants_dom {f : α → α} {g : α → β} :
    Measurable[invariants f] g ↔ Measurable g ∧ ∀ s, MeasurableSet s → (g ∘ f) ⁻¹' s = g ⁻¹' s := by
  simp only [Measurable, ← forall_and]; 

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
f : α → α
g : α → β
⊢ (∀ ⦃t : Set β⦄, MeasurableSet t → MeasurableSet (g ⁻¹' t)) ↔
    ∀ (x : Set β), MeasurableSet x → MeasurableSet (g ⁻¹' x) ∧ g ∘ f ⁻¹' x = g ⁻¹' x

Next tactic:
rfl
theorem measurable_invariants_of_semiconj {fa : α → α} {fb : β → β} {g : α → β} (hg : Measurable g)
    (hfg : Semiconj g fa fb) : @Measurable _ _ (invariants fa) (invariants fb) g := fun s hs ↦
  ⟨hg hs.1, by 

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
fa : α → α
fb : β → β
g : α → β
hg : Measurable g
hfg : Semiconj g fa fb
s : Set β
hs : MeasurableSet s
⊢ fa ⁻¹' (g ⁻¹' s) = g ⁻¹' s

Next tactic:
rw [← preimage_comp, hfg.comp_eq, preimage_comp, hs.2]
@[mono]
theorem card_mono : Monotone (@card α) := by 

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
⊢ Monotone card

Next tactic:
apply card_le_of_subset
theorem card_singleton_inter [DecidableEq α] : ({a} ∩ s).card ≤ 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
⊢ card ({a} ∩ s) ≤ 1

Next tactic:
cases' Finset.decidableMem a s with h h
theorem card_singleton_inter [DecidableEq α] : ({a} ∩ s).card ≤ 1 := by
  cases' Finset.decidableMem a s with h h
  · 

Proof state:
case isFalse
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∉ s
⊢ card ({a} ∩ s) ≤ 1

Next tactic:
simp [Finset.singleton_inter_of_not_mem h]
theorem card_singleton_inter [DecidableEq α] : ({a} ∩ s).card ≤ 1 := by
  cases' Finset.decidableMem a s with h h
  · simp [Finset.singleton_inter_of_not_mem h]
  · 

Proof state:
case isTrue
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∈ s
⊢ card ({a} ∩ s) ≤ 1

Next tactic:
simp [Finset.singleton_inter_of_mem h]
@[simp]
theorem card_insert_of_not_mem (h : a ∉ s) : (insert a s).card = s.card + 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∉ s
⊢ card (insert a s) = card s + 1

Next tactic:
rw [← cons_eq_insert _ _ h, card_cons]
theorem card_insert_of_mem (h : a ∈ s) : card (insert a s) = s.card := by 

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∈ s
⊢ card (insert a s) = card s

Next tactic:
rw [insert_eq_of_mem h]
theorem card_insert_le (a : α) (s : Finset α) : card (insert a s) ≤ s.card + 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
a✝ b : α
inst✝ : DecidableEq α
a : α
s : Finset α
⊢ card (insert a s) ≤ card s + 1

Next tactic:
by_cases h : a ∈ s
theorem card_insert_le (a : α) (s : Finset α) : card (insert a s) ≤ s.card + 1 := by
  by_cases h : a ∈ s
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
s✝ t : Finset α
a✝ b : α
inst✝ : DecidableEq α
a : α
s : Finset α
h : a ∈ s
⊢ card (insert a s) ≤ card s + 1

Next tactic:
rw [insert_eq_of_mem h]
theorem card_insert_le (a : α) (s : Finset α) : card (insert a s) ≤ s.card + 1 := by
  by_cases h : a ∈ s
  · rw [insert_eq_of_mem h]
    

Proof state:
case pos
α : Type u_1
β : Type u_2
s✝ t : Finset α
a✝ b : α
inst✝ : DecidableEq α
a : α
s : Finset α
h : a ∈ s
⊢ card s ≤ card s + 1

Next tactic:
exact Nat.le_succ _
theorem card_insert_le (a : α) (s : Finset α) : card (insert a s) ≤ s.card + 1 := by
  by_cases h : a ∈ s
  · rw [insert_eq_of_mem h]
    exact Nat.le_succ _
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
s✝ t : Finset α
a✝ b : α
inst✝ : DecidableEq α
a : α
s : Finset α
h : a ∉ s
⊢ card (insert a s) ≤ card s + 1

Next tactic:
rw [card_insert_of_not_mem h]
/-- If `a ∈ s` is known, see also `Finset.card_insert_of_mem` and `Finset.card_insert_of_not_mem`.
-/
theorem card_insert_eq_ite : card (insert a s) = if a ∈ s then s.card else s.card + 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
⊢ card (insert a s) = if a ∈ s then card s else card s + 1

Next tactic:
by_cases h : a ∈ s
/-- If `a ∈ s` is known, see also `Finset.card_insert_of_mem` and `Finset.card_insert_of_not_mem`.
-/
theorem card_insert_eq_ite : card (insert a s) = if a ∈ s then s.card else s.card + 1 := by
  by_cases h : a ∈ s
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∈ s
⊢ card (insert a s) = if a ∈ s then card s else card s + 1

Next tactic:
rw [card_insert_of_mem h, if_pos h]
/-- If `a ∈ s` is known, see also `Finset.card_insert_of_mem` and `Finset.card_insert_of_not_mem`.
-/
theorem card_insert_eq_ite : card (insert a s) = if a ∈ s then s.card else s.card + 1 := by
  by_cases h : a ∈ s
  · rw [card_insert_of_mem h, if_pos h]
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∉ s
⊢ card (insert a s) = if a ∈ s then card s else card s + 1

Next tactic:
rw [card_insert_of_not_mem h, if_neg h]
@[simp]
theorem card_doubleton (h : a ≠ b) : ({a, b} : Finset α).card = 2 := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ≠ b
⊢ card {a, b} = 2

Next tactic:
rw [card_insert_of_not_mem (not_mem_singleton.2 h), card_singleton]
/-- $\#(s \setminus \{a\}) = \#s - 1$ if $a \in s$.
  This result is casted to any additive group with 1,
  so that we don't have to work with `ℕ`-subtraction. -/
@[simp]
theorem cast_card_erase_of_mem {R} [AddGroupWithOne R] {s : Finset α} (hs : a ∈ s) :
    ((s.erase a).card : R) = s.card - 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
a b : α
inst✝¹ : DecidableEq α
R : Type u_3
inst✝ : AddGroupWithOne R
s : Finset α
hs : a ∈ s
⊢ ↑(card (erase s a)) = ↑(card s) - 1

Next tactic:
rw [card_erase_of_mem hs, Nat.cast_sub, Nat.cast_one]
/-- $\#(s \setminus \{a\}) = \#s - 1$ if $a \in s$.
  This result is casted to any additive group with 1,
  so that we don't have to work with `ℕ`-subtraction. -/
@[simp]
theorem cast_card_erase_of_mem {R} [AddGroupWithOne R] {s : Finset α} (hs : a ∈ s) :
    ((s.erase a).card : R) = s.card - 1 := by
  rw [card_erase_of_mem hs, Nat.cast_sub, Nat.cast_one]
  

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
a b : α
inst✝¹ : DecidableEq α
R : Type u_3
inst✝ : AddGroupWithOne R
s : Finset α
hs : a ∈ s
⊢ 1 ≤ card s

Next tactic:
rw [Nat.add_one_le_iff, Finset.card_pos]
/-- $\#(s \setminus \{a\}) = \#s - 1$ if $a \in s$.
  This result is casted to any additive group with 1,
  so that we don't have to work with `ℕ`-subtraction. -/
@[simp]
theorem cast_card_erase_of_mem {R} [AddGroupWithOne R] {s : Finset α} (hs : a ∈ s) :
    ((s.erase a).card : R) = s.card - 1 := by
  rw [card_erase_of_mem hs, Nat.cast_sub, Nat.cast_one]
  rw [Nat.add_one_le_iff, Finset.card_pos]
  

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
a b : α
inst✝¹ : DecidableEq α
R : Type u_3
inst✝ : AddGroupWithOne R
s : Finset α
hs : a ∈ s
⊢ Finset.Nonempty s

Next tactic:
exact ⟨a, hs⟩
theorem pred_card_le_card_erase : s.card - 1 ≤ (s.erase a).card := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
⊢ card s - 1 ≤ card (erase s a)

Next tactic:
by_cases h : a ∈ s
theorem pred_card_le_card_erase : s.card - 1 ≤ (s.erase a).card := by
  by_cases h : a ∈ s
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∈ s
⊢ card s - 1 ≤ card (erase s a)

Next tactic:
exact (card_erase_of_mem h).ge
theorem pred_card_le_card_erase : s.card - 1 ≤ (s.erase a).card := by
  by_cases h : a ∈ s
  · exact (card_erase_of_mem h).ge
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∉ s
⊢ card s - 1 ≤ card (erase s a)

Next tactic:
rw [erase_eq_of_not_mem h]
theorem pred_card_le_card_erase : s.card - 1 ≤ (s.erase a).card := by
  by_cases h : a ∈ s
  · exact (card_erase_of_mem h).ge
  · rw [erase_eq_of_not_mem h]
    

Proof state:
case neg
α : Type u_1
β : Type u_2
s t : Finset α
a b : α
inst✝ : DecidableEq α
h : a ∉ s
⊢ card s - 1 ≤ card s

Next tactic:
exact Nat.sub_le _ _
@[simp]
theorem length_toList (s : Finset α) : s.toList.length = s.card := by
  

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
f : α → β
n : ℕ
s : Finset α
⊢ List.length (toList s) = card s

Next tactic:
rw [toList, ← Multiset.coe_card, Multiset.coe_toList, card_def]
theorem card_image_le [DecidableEq β] : (s.image f).card ≤ s.card := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
⊢ card (image f s) ≤ card s

Next tactic:
simpa only [card_map] using (s.1.map f).toFinset_card_le
theorem card_image_of_injOn [DecidableEq β] (H : Set.InjOn f s) : (s.image f).card = s.card := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H : Set.InjOn f ↑s
⊢ card (image f s) = card s

Next tactic:
simp only [card, image_val_of_injOn H, card_map]
theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H : card (image f s) = card s
⊢ Set.InjOn f ↑s

Next tactic:
rw [card_def, card_def, image, toFinset] at H
theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by
  rw [card_def, card_def, image, toFinset] at H
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H :
  Multiset.card { val := dedup (Multiset.map f s.val), nodup := (_ : Nodup (dedup (Multiset.map f s.val))) }.val =
    Multiset.card s.val
⊢ Set.InjOn f ↑s

Next tactic:
dsimp only at H
theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by
  rw [card_def, card_def, image, toFinset] at H
  dsimp only at H
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H : Multiset.card (dedup (Multiset.map f s.val)) = Multiset.card s.val
⊢ Set.InjOn f ↑s

Next tactic:
have : (s.1.map f).dedup = s.1.map f := by
    refine Multiset.eq_of_le_of_card_le (Multiset.dedup_le _) ?_
    simp only [H, Multiset.card_map, le_rfl]
theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by
  rw [card_def, card_def, image, toFinset] at H
  dsimp only at H
  have : (s.1.map f).dedup = s.1.map f := by
    

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H : Multiset.card (dedup (Multiset.map f s.val)) = Multiset.card s.val
⊢ dedup (Multiset.map f s.val) = Multiset.map f s.val

Next tactic:
refine Multiset.eq_of_le_of_card_le (Multiset.dedup_le _) ?_
theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by
  rw [card_def, card_def, image, toFinset] at H
  dsimp only at H
  have : (s.1.map f).dedup = s.1.map f := by
    refine Multiset.eq_of_le_of_card_le (Multiset.dedup_le _) ?_
    

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H : Multiset.card (dedup (Multiset.map f s.val)) = Multiset.card s.val
⊢ Multiset.card (Multiset.map f s.val) ≤ Multiset.card (dedup (Multiset.map f s.val))

Next tactic:
simp only [H, Multiset.card_map, le_rfl]
theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by
  rw [card_def, card_def, image, toFinset] at H
  dsimp only at H
  have : (s.1.map f).dedup = s.1.map f := by
    refine Multiset.eq_of_le_of_card_le (Multiset.dedup_le _) ?_
    simp only [H, Multiset.card_map, le_rfl]
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H : Multiset.card (dedup (Multiset.map f s.val)) = Multiset.card s.val
this : dedup (Multiset.map f s.val) = Multiset.map f s.val
⊢ Set.InjOn f ↑s

Next tactic:
rw [Multiset.dedup_eq_self] at this
theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by
  rw [card_def, card_def, image, toFinset] at H
  dsimp only at H
  have : (s.1.map f).dedup = s.1.map f := by
    refine Multiset.eq_of_le_of_card_le (Multiset.dedup_le _) ?_
    simp only [H, Multiset.card_map, le_rfl]
  rw [Multiset.dedup_eq_self] at this
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
inst✝ : DecidableEq β
H : Multiset.card (dedup (Multiset.map f s.val)) = Multiset.card s.val
this : Nodup (Multiset.map f s.val)
⊢ Set.InjOn f ↑s

Next tactic:
exact inj_on_of_nodup_map this
theorem fiber_card_ne_zero_iff_mem_image (s : Finset α) (f : α → β) [DecidableEq β] (y : β) :
    (s.filter fun x => f x = y).card ≠ 0 ↔ y ∈ s.image f := by
  

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
f✝ : α → β
n : ℕ
s : Finset α
f : α → β
inst✝ : DecidableEq β
y : β
⊢ card (filter (fun x => f x = y) s) ≠ 0 ↔ y ∈ image f s

Next tactic:
rw [← pos_iff_ne_zero, card_pos, fiber_nonempty_iff_mem_image]
lemma card_filter_le_iff (s : Finset α) (P : α → Prop) [DecidablePred P] (n : ℕ) :
    (s.filter P).card ≤ n ↔ ∀ s' ⊆ s, n < s'.card → ∃ a ∈ s', ¬ P a :=
  (s.1.card_filter_le_iff P n).trans ⟨fun H s' hs' h ↦ H s'.1 (by 

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
f : α → β
n✝ : ℕ
s : Finset α
P : α → Prop
inst✝ : DecidablePred P
n : ℕ
H : ∀ s' ≤ s.val, n < Multiset.card s' → ∃ a ∈ s', ¬P a
s' : Finset α
hs' : s' ⊆ s
h : n < card s'
⊢ s'.val ≤ s.val

Next tactic:
aesop
@[simp]
theorem card_subtype (p : α → Prop) [DecidablePred p] (s : Finset α) :
    (s.subtype p).card = (s.filter p).card := by 

Proof state:
α : Type u_1
β : Type u_2
s✝ t : Finset α
f : α → β
n : ℕ
p : α → Prop
inst✝ : DecidablePred p
s : Finset α
⊢ card (Finset.subtype p s) = card (filter p s)

Next tactic:
simp [Finset.subtype]
theorem filter_card_eq {p : α → Prop} [DecidablePred p] (h : (s.filter p).card = s.card) (x : α)
    (hx : x ∈ s) : p x := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
f : α → β
n : ℕ
p : α → Prop
inst✝ : DecidablePred p
h : card (filter p s) = card s
x : α
hx : x ∈ s
⊢ p x

Next tactic:
rw [← eq_of_subset_of_card_le (s.filter_subset p) h.ge, mem_filter] at hx