l3lab/ntp-mathlib huggingface dataset:
/-- Pointwise `Finset.Icc` bundled as a `DFinsupp`. -/
def rangeIcc (f g : Π₀ i, α i) : Π₀ i, Finset (α i) where
  toFun i := Icc (f i) (g i)
  support' := f.support'.bind fun fs => g.support'.map fun gs =>
    ⟨ fs.1 + gs.1,
      fun i => or_iff_not_imp_left.2 fun h => by
        have hf : f i = 0 := (fs.prop i).resolve_left
            (Multiset.not_mem_mono (Multiset.Le.subset <| Multiset.le_add_right _ _) h)
        have hg : g i = 0 := (gs.prop i).resolve_left
            (Multiset.not_mem_mono (Multiset.Le.subset <| Multiset.le_add_left _ _) h)
        -- porting note: was rw, but was rewriting under lambda, so changed to simp_rw
        simp_rw [hf, hg]
        

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → Zero (α i)
inst✝¹ : (i : ι) → PartialOrder (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f✝ g✝ : Π₀ (i : ι), α i
i✝ : ι
a : α i✝
f g : Π₀ (i : ι), α i
fs : { s // ∀ (i : ι), i ∈ s ∨ toFun f i = 0 }
gs : { s // ∀ (i : ι), i ∈ s ∨ toFun g i = 0 }
i : ι
h : i ∉ ↑fs + ↑gs
hf : f i = 0
hg : g i = 0
⊢ Icc 0 0 = 0

Next tactic:
exact Icc_self _
theorem support_rangeIcc_subset [DecidableEq ι] [∀ i, DecidableEq (α i)] :
    (f.rangeIcc g).support ⊆ f.support ∪ g.support := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : (i : ι) → Zero (α i)
inst✝³ : (i : ι) → PartialOrder (α i)
inst✝² : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
i : ι
a : α i
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
⊢ support (rangeIcc f g) ⊆ support f ∪ support g

Next tactic:
refine' fun x hx => _
theorem support_rangeIcc_subset [DecidableEq ι] [∀ i, DecidableEq (α i)] :
    (f.rangeIcc g).support ⊆ f.support ∪ g.support := by
  refine' fun x hx => _
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : (i : ι) → Zero (α i)
inst✝³ : (i : ι) → PartialOrder (α i)
inst✝² : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
i : ι
a : α i
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
x : ι
hx : x ∈ support (rangeIcc f g)
⊢ x ∈ support f ∪ support g

Next tactic:
by_contra h
theorem support_rangeIcc_subset [DecidableEq ι] [∀ i, DecidableEq (α i)] :
    (f.rangeIcc g).support ⊆ f.support ∪ g.support := by
  refine' fun x hx => _
  by_contra h
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : (i : ι) → Zero (α i)
inst✝³ : (i : ι) → PartialOrder (α i)
inst✝² : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
i : ι
a : α i
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
x : ι
hx : x ∈ support (rangeIcc f g)
h : x ∉ support f ∪ support g
⊢ False

Next tactic:
refine' not_mem_support_iff.2 _ hx
theorem support_rangeIcc_subset [DecidableEq ι] [∀ i, DecidableEq (α i)] :
    (f.rangeIcc g).support ⊆ f.support ∪ g.support := by
  refine' fun x hx => _
  by_contra h
  refine' not_mem_support_iff.2 _ hx
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : (i : ι) → Zero (α i)
inst✝³ : (i : ι) → PartialOrder (α i)
inst✝² : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
i : ι
a : α i
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
x : ι
hx : x ∈ support (rangeIcc f g)
h : x ∉ support f ∪ support g
⊢ (rangeIcc f g) x = 0

Next tactic:
rw [rangeIcc_apply, not_mem_support_iff.1 (not_mem_mono (subset_union_left _ _) h),
    not_mem_support_iff.1 (not_mem_mono (subset_union_right _ _) h)]
theorem support_rangeIcc_subset [DecidableEq ι] [∀ i, DecidableEq (α i)] :
    (f.rangeIcc g).support ⊆ f.support ∪ g.support := by
  refine' fun x hx => _
  by_contra h
  refine' not_mem_support_iff.2 _ hx
  rw [rangeIcc_apply, not_mem_support_iff.1 (not_mem_mono (subset_union_left _ _) h),
    not_mem_support_iff.1 (not_mem_mono (subset_union_right _ _) h)]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : (i : ι) → Zero (α i)
inst✝³ : (i : ι) → PartialOrder (α i)
inst✝² : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
i : ι
a : α i
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
x : ι
hx : x ∈ support (rangeIcc f g)
h : x ∉ support f ∪ support g
⊢ Icc 0 0 = 0

Next tactic:
exact Icc_self _
@[simp]
theorem card_pi (f : Π₀ i, Finset (α i)) : f.pi.card = f.prod fun i => (f i).card := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → Zero (α i)
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
f : Π₀ (i : ι), Finset (α i)
⊢ card (pi f) = prod f fun i => ↑(card (f i))

Next tactic:
rw [pi, card_dfinsupp]
@[simp]
theorem card_pi (f : Π₀ i, Finset (α i)) : f.pi.card = f.prod fun i => (f i).card := by
  rw [pi, card_dfinsupp]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → Zero (α i)
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
f : Π₀ (i : ι), Finset (α i)
⊢ ∏ i in support f, card (f i) = prod f fun i => ↑(card (f i))

Next tactic:
exact Finset.prod_congr rfl fun i _ => by simp only [Pi.nat_apply, Nat.cast_id]
@[simp]
theorem card_pi (f : Π₀ i, Finset (α i)) : f.pi.card = f.prod fun i => (f i).card := by
  rw [pi, card_dfinsupp]
  exact Finset.prod_congr rfl fun i _ => by 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → Zero (α i)
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (α i)
f : Π₀ (i : ι), Finset (α i)
i : ι
x✝ : i ∈ support f
⊢ card (f i) = (fun i => ↑(card (f i))) i (f i)

Next tactic:
simp only [Pi.nat_apply, Nat.cast_id]
instance : LocallyFiniteOrder (Π₀ i, α i) :=
  LocallyFiniteOrder.ofIcc (Π₀ i, α i)
    (fun f g => (f.support ∪ g.support).dfinsupp <| f.rangeIcc g)
    (fun f g x => by
      

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → PartialOrder (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g x : Π₀ (i : ι), α i
⊢ x ∈ (fun f g => dfinsupp (support f ∪ support g) ⇑(rangeIcc f g)) f g ↔ f ≤ x ∧ x ≤ g

Next tactic:
refine' (mem_dfinsupp_iff_of_support_subset <| support_rangeIcc_subset).trans _
instance : LocallyFiniteOrder (Π₀ i, α i) :=
  LocallyFiniteOrder.ofIcc (Π₀ i, α i)
    (fun f g => (f.support ∪ g.support).dfinsupp <| f.rangeIcc g)
    (fun f g x => by
      refine' (mem_dfinsupp_iff_of_support_subset <| support_rangeIcc_subset).trans _
      

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → PartialOrder (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g x : Π₀ (i : ι), α i
⊢ (∀ (i : ι), x i ∈ (rangeIcc f g) i) ↔ f ≤ x ∧ x ≤ g

Next tactic:
simp_rw [mem_rangeIcc_apply_iff, forall_and]
instance : LocallyFiniteOrder (Π₀ i, α i) :=
  LocallyFiniteOrder.ofIcc (Π₀ i, α i)
    (fun f g => (f.support ∪ g.support).dfinsupp <| f.rangeIcc g)
    (fun f g x => by
      refine' (mem_dfinsupp_iff_of_support_subset <| support_rangeIcc_subset).trans _
      simp_rw [mem_rangeIcc_apply_iff, forall_and]
      

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → PartialOrder (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g x : Π₀ (i : ι), α i
⊢ ((∀ (x_1 : ι), f x_1 ≤ x x_1) ∧ ∀ (x_1 : ι), x x_1 ≤ g x_1) ↔ f ≤ x ∧ x ≤ g

Next tactic:
rfl
theorem card_Ico : (Ico f g).card = (∏ i in f.support ∪ g.support, (Icc (f i) (g i)).card) - 1 := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → PartialOrder (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
⊢ card (Ico f g) = ∏ i in support f ∪ support g, card (Icc (f i) (g i)) - 1

Next tactic:
rw [card_Ico_eq_card_Icc_sub_one, card_Icc]
theorem card_Ioc : (Ioc f g).card = (∏ i in f.support ∪ g.support, (Icc (f i) (g i)).card) - 1 := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → PartialOrder (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
⊢ card (Ioc f g) = ∏ i in support f ∪ support g, card (Icc (f i) (g i)) - 1

Next tactic:
rw [card_Ioc_eq_card_Icc_sub_one, card_Icc]
theorem card_Ioo : (Ioo f g).card = (∏ i in f.support ∪ g.support, (Icc (f i) (g i)).card) - 2 := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → PartialOrder (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
⊢ card (Ioo f g) = ∏ i in support f ∪ support g, card (Icc (f i) (g i)) - 2

Next tactic:
rw [card_Ioo_eq_card_Icc_sub_two, card_Icc]
theorem card_uIcc : (uIcc f g).card = ∏ i in f.support ∪ g.support, (uIcc (f i) (g i)).card := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → Lattice (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
⊢ card (uIcc f g) = ∏ i in support f ∪ support g, card (uIcc (f i) (g i))

Next tactic:
rw [← support_inf_union_support_sup]
theorem card_uIcc : (uIcc f g).card = ∏ i in f.support ∪ g.support, (uIcc (f i) (g i)).card := by
  rw [← support_inf_union_support_sup]; 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝⁴ : DecidableEq ι
inst✝³ : (i : ι) → DecidableEq (α i)
inst✝² : (i : ι) → Lattice (α i)
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f g : Π₀ (i : ι), α i
⊢ card (uIcc f g) = ∏ i in support (f ⊓ g) ∪ support (f ⊔ g), card (uIcc (f i) (g i))

Next tactic:
exact card_Icc _ _
theorem card_Iic : (Iic f).card = ∏ i in f.support, (Iic (f i)).card := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝³ : DecidableEq ι
inst✝² : (i : ι) → DecidableEq (α i)
inst✝¹ : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f : Π₀ (i : ι), α i
⊢ card (Iic f) = ∏ i in support f, card (Iic (f i))

Next tactic:
simp_rw [Iic_eq_Icc, card_Icc, DFinsupp.bot_eq_zero, support_zero, empty_union, zero_apply,
    bot_eq_zero]
theorem card_Iio : (Iio f).card = (∏ i in f.support, (Iic (f i)).card) - 1 := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝³ : DecidableEq ι
inst✝² : (i : ι) → DecidableEq (α i)
inst✝¹ : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝ : (i : ι) → LocallyFiniteOrder (α i)
f : Π₀ (i : ι), α i
⊢ card (Iio f) = ∏ i in support f, card (Iic (f i)) - 1

Next tactic:
rw [card_Iio_eq_card_Iic_sub_one, card_Iic]
instance [Finite α] [Finite β] : Finite (α × β) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Finite α
inst✝ : Finite β
⊢ Finite (α × β)

Next tactic:
haveI := Fintype.ofFinite α
instance [Finite α] [Finite β] : Finite (α × β) := by
  haveI := Fintype.ofFinite α
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Finite α
inst✝ : Finite β
this : Fintype α
⊢ Finite (α × β)

Next tactic:
haveI := Fintype.ofFinite β
instance [Finite α] [Finite β] : Finite (α × β) := by
  haveI := Fintype.ofFinite α
  haveI := Fintype.ofFinite β
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Finite α
inst✝ : Finite β
this✝ : Fintype α
this : Fintype β
⊢ Finite (α × β)

Next tactic:
infer_instance
instance [Finite α] [Finite β] : Finite (Sum α β) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Finite α
inst✝ : Finite β
⊢ Finite (α ⊕ β)

Next tactic:
haveI := Fintype.ofFinite α
instance [Finite α] [Finite β] : Finite (Sum α β) := by
  haveI := Fintype.ofFinite α
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Finite α
inst✝ : Finite β
this : Fintype α
⊢ Finite (α ⊕ β)

Next tactic:
haveI := Fintype.ofFinite β
instance [Finite α] [Finite β] : Finite (Sum α β) := by
  haveI := Fintype.ofFinite α
  haveI := Fintype.ofFinite β
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : Finite α
inst✝ : Finite β
this✝ : Fintype α
this : Fintype β
⊢ Finite (α ⊕ β)

Next tactic:
infer_instance
instance {β : α → Type*} [Finite α] [∀ a, Finite (β a)] : Finite (Σa, β a) := by
  

Proof state:
α : Type u_1
β✝ : Type u_2
γ : Type u_3
β : α → Type u_4
inst✝¹ : Finite α
inst✝ : ∀ (a : α), Finite (β a)
⊢ Finite ((a : α) × β a)

Next tactic:
letI := Fintype.ofFinite α
instance {β : α → Type*} [Finite α] [∀ a, Finite (β a)] : Finite (Σa, β a) := by
  letI := Fintype.ofFinite α
  

Proof state:
α : Type u_1
β✝ : Type u_2
γ : Type u_3
β : α → Type u_4
inst✝¹ : Finite α
inst✝ : ∀ (a : α), Finite (β a)
this : Fintype α := Fintype.ofFinite α
⊢ Finite ((a : α) × β a)

Next tactic:
letI := fun a => Fintype.ofFinite (β a)
instance {β : α → Type*} [Finite α] [∀ a, Finite (β a)] : Finite (Σa, β a) := by
  letI := Fintype.ofFinite α
  letI := fun a => Fintype.ofFinite (β a)
  

Proof state:
α : Type u_1
β✝ : Type u_2
γ : Type u_3
β : α → Type u_4
inst✝¹ : Finite α
inst✝ : ∀ (a : α), Finite (β a)
this✝ : Fintype α := Fintype.ofFinite α
this : (a : α) → Fintype (β a) := fun a => Fintype.ofFinite (β a)
⊢ Finite ((a : α) × β a)

Next tactic:
infer_instance
instance [Finite α] : Finite (Set α) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Finite α
⊢ Finite (Set α)

Next tactic:
cases nonempty_fintype α
instance [Finite α] : Finite (Set α) := by
  cases nonempty_fintype α
  

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Finite α
val✝ : Fintype α
⊢ Finite (Set α)

Next tactic:
infer_instance
instance Pi.finite {α : Sort*} {β : α → Sort*} [Finite α] [∀ a, Finite (β a)] :
    Finite (∀ a, β a) := by
  

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : α → Sort u_5
inst✝¹ : Finite α
inst✝ : ∀ (a : α), Finite (β a)
⊢ Finite ((a : α) → β a)

Next tactic:
haveI := Fintype.ofFinite (PLift α)
instance Pi.finite {α : Sort*} {β : α → Sort*} [Finite α] [∀ a, Finite (β a)] :
    Finite (∀ a, β a) := by
  haveI := Fintype.ofFinite (PLift α)
  

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : α → Sort u_5
inst✝¹ : Finite α
inst✝ : ∀ (a : α), Finite (β a)
this : Fintype (PLift α)
⊢ Finite ((a : α) → β a)

Next tactic:
haveI := fun a => Fintype.ofFinite (PLift (β a))
instance Pi.finite {α : Sort*} {β : α → Sort*} [Finite α] [∀ a, Finite (β a)] :
    Finite (∀ a, β a) := by
  haveI := Fintype.ofFinite (PLift α)
  haveI := fun a => Fintype.ofFinite (PLift (β a))
  

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : α → Sort u_5
inst✝¹ : Finite α
inst✝ : ∀ (a : α), Finite (β a)
this✝ : Fintype (PLift α)
this : (a : α) → Fintype (PLift (β a))
⊢ Finite ((a : α) → β a)

Next tactic:
exact
    Finite.of_equiv (∀ a : PLift α, PLift (β (Equiv.plift a)))
      (Equiv.piCongr Equiv.plift fun _ => Equiv.plift)
instance Vector.finite {α : Type*} [Finite α] {n : ℕ} : Finite (Vector α n) := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
α : Type u_4
inst✝ : Finite α
n : ℕ
⊢ Finite (Vector α n)

Next tactic:
haveI := Fintype.ofFinite α
instance Vector.finite {α : Type*} [Finite α] {n : ℕ} : Finite (Vector α n) := by
  haveI := Fintype.ofFinite α
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
α : Type u_4
inst✝ : Finite α
n : ℕ
this : Fintype α
⊢ Finite (Vector α n)

Next tactic:
infer_instance
instance Function.Embedding.finite {α β : Sort*} [Finite β] : Finite (α ↪ β) := by
  

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : Sort u_5
inst✝ : Finite β
⊢ Finite (α ↪ β)

Next tactic:
cases' isEmpty_or_nonempty (α ↪ β) with _ h
instance Function.Embedding.finite {α β : Sort*} [Finite β] : Finite (α ↪ β) := by
  cases' isEmpty_or_nonempty (α ↪ β) with _ h
  · -- Porting note: infer_instance fails because it applies `Finite.of_fintype` and produces a
    -- "stuck at solving universe constraint" error.
    

Proof state:
case inl
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : Sort u_5
inst✝ : Finite β
h✝ : IsEmpty (α ↪ β)
⊢ Finite (α ↪ β)

Next tactic:
apply Finite.of_subsingleton
instance Function.Embedding.finite {α β : Sort*} [Finite β] : Finite (α ↪ β) := by
  cases' isEmpty_or_nonempty (α ↪ β) with _ h
  · -- Porting note: infer_instance fails because it applies `Finite.of_fintype` and produces a
    -- "stuck at solving universe constraint" error.
    apply Finite.of_subsingleton

  · 

Proof state:
case inr
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : Sort u_5
inst✝ : Finite β
h : Nonempty (α ↪ β)
⊢ Finite (α ↪ β)

Next tactic:
refine' h.elim fun f => _
instance Function.Embedding.finite {α β : Sort*} [Finite β] : Finite (α ↪ β) := by
  cases' isEmpty_or_nonempty (α ↪ β) with _ h
  · -- Porting note: infer_instance fails because it applies `Finite.of_fintype` and produces a
    -- "stuck at solving universe constraint" error.
    apply Finite.of_subsingleton

  · refine' h.elim fun f => _
    

Proof state:
case inr
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : Sort u_5
inst✝ : Finite β
h : Nonempty (α ↪ β)
f : α ↪ β
⊢ Finite (α ↪ β)

Next tactic:
haveI : Finite α := Finite.of_injective _ f.injective
instance Function.Embedding.finite {α β : Sort*} [Finite β] : Finite (α ↪ β) := by
  cases' isEmpty_or_nonempty (α ↪ β) with _ h
  · -- Porting note: infer_instance fails because it applies `Finite.of_fintype` and produces a
    -- "stuck at solving universe constraint" error.
    apply Finite.of_subsingleton

  · refine' h.elim fun f => _
    haveI : Finite α := Finite.of_injective _ f.injective
    

Proof state:
case inr
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : Sort u_5
inst✝ : Finite β
h : Nonempty (α ↪ β)
f : α ↪ β
this : Finite α
⊢ Finite (α ↪ β)

Next tactic:
exact Finite.of_injective _ FunLike.coe_injective
instance Equiv.finite_right {α β : Sort*} [Finite β] : Finite (α ≃ β) :=
  Finite.of_injective Equiv.toEmbedding fun e₁ e₂ h => Equiv.ext <| by
    

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Sort u_4
β : Sort u_5
inst✝ : Finite β
e₁ e₂ : α ≃ β
h : Equiv.toEmbedding e₁ = Equiv.toEmbedding e₂
⊢ ∀ (x : α), e₁ x = e₂ x

Next tactic:
convert FunLike.congr_fun h using 0
instance [Finite α] {n : ℕ} : Finite (Sym α n) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Finite α
n : ℕ
⊢ Finite (Sym α n)

Next tactic:
haveI := Fintype.ofFinite α
instance [Finite α] {n : ℕ} : Finite (Sym α n) := by
  haveI := Fintype.ofFinite α
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : Finite α
n : ℕ
this : Fintype α
⊢ Finite (Sym α n)

Next tactic:
infer_instance
@[simp] lemma discrim_neg [Ring R] (a b c : R) : discrim (-a) (-b) (-c) = discrim a b c := by
  

Proof state:
R : Type u_1
inst✝ : Ring R
a b c : R
⊢ discrim (-a) (-b) (-c) = discrim a b c

Next tactic:
simp [discrim]
lemma discrim_eq_sq_of_quadratic_eq_zero {x : R} (h : a * x * x + b * x + c = 0) :
    discrim a b c = (2 * a * x + b) ^ 2 := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
a b c x : R
h : a * x * x + b * x + c = 0
⊢ discrim a b c = (2 * a * x + b) ^ 2

Next tactic:
rw [discrim]
lemma discrim_eq_sq_of_quadratic_eq_zero {x : R} (h : a * x * x + b * x + c = 0) :
    discrim a b c = (2 * a * x + b) ^ 2 := by
  rw [discrim]
  

Proof state:
R : Type u_1
inst✝ : CommRing R
a b c x : R
h : a * x * x + b * x + c = 0
⊢ b ^ 2 - 4 * a * c = (2 * a * x + b) ^ 2

Next tactic:
linear_combination -4 * a * h
/-- A quadratic has roots if and only if its discriminant equals some square.
-/
theorem quadratic_eq_zero_iff_discrim_eq_sq [NeZero (2 : R)] [NoZeroDivisors R]
    (ha : a ≠ 0) (x : R) :
    a * x * x + b * x + c = 0 ↔ discrim a b c = (2 * a * x + b) ^ 2 := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
a b c : R
inst✝¹ : NeZero 2
inst✝ : NoZeroDivisors R
ha : a ≠ 0
x : R
⊢ a * x * x + b * x + c = 0 ↔ discrim a b c = (2 * a * x + b) ^ 2

Next tactic:
refine ⟨discrim_eq_sq_of_quadratic_eq_zero, fun h ↦ ?_⟩
/-- A quadratic has roots if and only if its discriminant equals some square.
-/
theorem quadratic_eq_zero_iff_discrim_eq_sq [NeZero (2 : R)] [NoZeroDivisors R]
    (ha : a ≠ 0) (x : R) :
    a * x * x + b * x + c = 0 ↔ discrim a b c = (2 * a * x + b) ^ 2 := by
  refine ⟨discrim_eq_sq_of_quadratic_eq_zero, fun h ↦ ?_⟩
  

Proof state:
R : Type u_1
inst✝² : CommRing R
a b c : R
inst✝¹ : NeZero 2
inst✝ : NoZeroDivisors R
ha : a ≠ 0
x : R
h : discrim a b c = (2 * a * x + b) ^ 2
⊢ a * x * x + b * x + c = 0

Next tactic:
rw [discrim] at h
/-- A quadratic has roots if and only if its discriminant equals some square.
-/
theorem quadratic_eq_zero_iff_discrim_eq_sq [NeZero (2 : R)] [NoZeroDivisors R]
    (ha : a ≠ 0) (x : R) :
    a * x * x + b * x + c = 0 ↔ discrim a b c = (2 * a * x + b) ^ 2 := by
  refine ⟨discrim_eq_sq_of_quadratic_eq_zero, fun h ↦ ?_⟩
  rw [discrim] at h
  

Proof state:
R : Type u_1
inst✝² : CommRing R
a b c : R
inst✝¹ : NeZero 2
inst✝ : NoZeroDivisors R
ha : a ≠ 0
x : R
h : b ^ 2 - 4 * a * c = (2 * a * x + b) ^ 2
⊢ a * x * x + b * x + c = 0

Next tactic:
have ha : 2 * 2 * a ≠ 0 := mul_ne_zero (mul_ne_zero (NeZero.ne _) (NeZero.ne _)) ha
/-- A quadratic has roots if and only if its discriminant equals some square.
-/
theorem quadratic_eq_zero_iff_discrim_eq_sq [NeZero (2 : R)] [NoZeroDivisors R]
    (ha : a ≠ 0) (x : R) :
    a * x * x + b * x + c = 0 ↔ discrim a b c = (2 * a * x + b) ^ 2 := by
  refine ⟨discrim_eq_sq_of_quadratic_eq_zero, fun h ↦ ?_⟩
  rw [discrim] at h
  have ha : 2 * 2 * a ≠ 0 := mul_ne_zero (mul_ne_zero (NeZero.ne _) (NeZero.ne _)) ha
  

Proof state:
R : Type u_1
inst✝² : CommRing R
a b c : R
inst✝¹ : NeZero 2
inst✝ : NoZeroDivisors R
ha✝ : a ≠ 0
x : R
h : b ^ 2 - 4 * a * c = (2 * a * x + b) ^ 2
ha : 2 * 2 * a ≠ 0
⊢ a * x * x + b * x + c = 0

Next tactic:
apply mul_left_cancel₀ ha
/-- A quadratic has roots if and only if its discriminant equals some square.
-/
theorem quadratic_eq_zero_iff_discrim_eq_sq [NeZero (2 : R)] [NoZeroDivisors R]
    (ha : a ≠ 0) (x : R) :
    a * x * x + b * x + c = 0 ↔ discrim a b c = (2 * a * x + b) ^ 2 := by
  refine ⟨discrim_eq_sq_of_quadratic_eq_zero, fun h ↦ ?_⟩
  rw [discrim] at h
  have ha : 2 * 2 * a ≠ 0 := mul_ne_zero (mul_ne_zero (NeZero.ne _) (NeZero.ne _)) ha
  apply mul_left_cancel₀ ha
  

Proof state:
R : Type u_1
inst✝² : CommRing R
a b c : R
inst✝¹ : NeZero 2
inst✝ : NoZeroDivisors R
ha✝ : a ≠ 0
x : R
h : b ^ 2 - 4 * a * c = (2 * a * x + b) ^ 2
ha : 2 * 2 * a ≠ 0
⊢ 2 * 2 * a * (a * x * x + b * x + c) = 2 * 2 * a * 0

Next tactic:
linear_combination -h
/-- Roots of a quadratic equation. -/
theorem quadratic_eq_zero_iff (ha : a ≠ 0) {s : K} (h : discrim a b c = s * s) (x : K) :
    a * x * x + b * x + c = 0 ↔ x = (-b + s) / (2 * a) ∨ x = (-b - s) / (2 * a) := by
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NeZero 2
a b c x✝ : K
ha : a ≠ 0
s : K
h : discrim a b c = s * s
x : K
⊢ a * x * x + b * x + c = 0 ↔ x = (-b + s) / (2 * a) ∨ x = (-b - s) / (2 * a)

Next tactic:
rw [quadratic_eq_zero_iff_discrim_eq_sq ha, h, sq, mul_self_eq_mul_self_iff]
/-- Roots of a quadratic equation. -/
theorem quadratic_eq_zero_iff (ha : a ≠ 0) {s : K} (h : discrim a b c = s * s) (x : K) :
    a * x * x + b * x + c = 0 ↔ x = (-b + s) / (2 * a) ∨ x = (-b - s) / (2 * a) := by
  rw [quadratic_eq_zero_iff_discrim_eq_sq ha, h, sq, mul_self_eq_mul_self_iff]
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NeZero 2
a b c x✝ : K
ha : a ≠ 0
s : K
h : discrim a b c = s * s
x : K
⊢ s = 2 * a * x + b ∨ s = -(2 * a * x + b) ↔ x = (-b + s) / (2 * a) ∨ x = (-b - s) / (2 * a)

Next tactic:
field_simp
/-- Roots of a quadratic equation. -/
theorem quadratic_eq_zero_iff (ha : a ≠ 0) {s : K} (h : discrim a b c = s * s) (x : K) :
    a * x * x + b * x + c = 0 ↔ x = (-b + s) / (2 * a) ∨ x = (-b - s) / (2 * a) := by
  rw [quadratic_eq_zero_iff_discrim_eq_sq ha, h, sq, mul_self_eq_mul_self_iff]
  field_simp
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NeZero 2
a b c x✝ : K
ha : a ≠ 0
s : K
h : discrim a b c = s * s
x : K
⊢ s = 2 * a * x + b ∨ s = -b + -(2 * a * x) ↔ x * (2 * a) = -b + s ∨ x * (2 * a) = -b - s

Next tactic:
apply or_congr
/-- Roots of a quadratic equation. -/
theorem quadratic_eq_zero_iff (ha : a ≠ 0) {s : K} (h : discrim a b c = s * s) (x : K) :
    a * x * x + b * x + c = 0 ↔ x = (-b + s) / (2 * a) ∨ x = (-b - s) / (2 * a) := by
  rw [quadratic_eq_zero_iff_discrim_eq_sq ha, h, sq, mul_self_eq_mul_self_iff]
  field_simp
  apply or_congr
  · 

Proof state:
case h₁
K : Type u_1
inst✝¹ : Field K
inst✝ : NeZero 2
a b c x✝ : K
ha : a ≠ 0
s : K
h : discrim a b c = s * s
x : K
⊢ s = 2 * a * x + b ↔ x * (2 * a) = -b + s

Next tactic:
constructor