Module docstring
{"## Instances
We provide the Fintype instance for the sum of two fintypes.
"}
{"## Instances
We provide the Fintype instance for the sum of two fintypes.
"}
instFintypeSum
      instance
     (α : Type u) (β : Type v) [Fintype α] [Fintype β] : Fintype (α ⊕ β)
        
      Finset.toLeft_eq_univ
      theorem
     : u.toLeft = univ ↔ univ.map .inl ⊆ u
        lemma toLeft_eq_univ : u.toLeft = univ ↔ univ.map .inl ⊆ u := by
  simp [map_inl_subset_iff_subset_toLeft]
        Finset.toRight_eq_empty
      theorem
     : u.toRight = ∅ ↔ u ⊆ univ.map .inl
        lemma toRight_eq_empty : u.toRight = ∅ ↔ u ⊆ univ.map .inl := by simp [subset_map_inl]
        Finset.toRight_eq_univ
      theorem
     : u.toRight = univ ↔ univ.map .inr ⊆ u
        lemma toRight_eq_univ : u.toRight = univ ↔ univ.map .inr ⊆ u := by
  simp [map_inr_subset_iff_subset_toRight]
        Finset.toLeft_eq_empty
      theorem
     : u.toLeft = ∅ ↔ u ⊆ univ.map .inr
        lemma toLeft_eq_empty : u.toLeft = ∅ ↔ u ⊆ univ.map .inr := by simp [subset_map_inr]
        Finset.univ_disjSum_univ
      theorem
     : univ.disjSum univ = (univ : Finset (α ⊕ β))
        
      Finset.toLeft_univ
      theorem
     : (univ : Finset (α ⊕ β)).toLeft = univ
        
      Finset.toRight_univ
      theorem
     : (univ : Finset (α ⊕ β)).toRight = univ
        
      Fintype.card_sum
      theorem
     [Fintype α] [Fintype β] : Fintype.card (α ⊕ β) = Fintype.card α + Fintype.card β
        @[simp]
theorem Fintype.card_sum [Fintype α] [Fintype β] :
    Fintype.card (α ⊕ β) = Fintype.card α + Fintype.card β :=
  card_disjSum _ _
        fintypeOfFintypeNe
      definition
     (a : α) (_ : Fintype { b // b ≠ a }) : Fintype α
        /-- If the subtype of all-but-one elements is a `Fintype` then the type itself is a `Fintype`. -/
def fintypeOfFintypeNe (a : α) (_ : Fintype { b // b ≠ a }) : Fintype α :=
  Fintype.ofBijective (Sum.elim ((↑) : { b // b = a } → α) ((↑) : { b // b ≠ a } → α)) <| by
    classical exact (Equiv.sumCompl (· = a)).bijective
        image_subtype_ne_univ_eq_image_erase
      theorem
     [Fintype α] [DecidableEq β] (k : β) (b : α → β) :
  image (fun i : { a // b a ≠ k } => b ↑i) univ = (image b univ).erase k
        theorem image_subtype_ne_univ_eq_image_erase [Fintype α] [DecidableEq β] (k : β) (b : α → β) :
    image (fun i : { a // b a ≠ k } => b ↑i) univ = (image b univ).erase k := by
  apply subset_antisymm
  · rw [image_subset_iff]
    intro i _
    apply mem_erase_of_ne_of_mem i.2 (mem_image_of_mem _ (mem_univ _))
  · intro i hi
    rw [mem_image]
    rcases mem_image.1 (erase_subset _ _ hi) with ⟨a, _, ha⟩
    subst ha
    exact ⟨⟨a, ne_of_mem_erase hi⟩, mem_univ _, rfl⟩
        image_subtype_univ_ssubset_image_univ
      theorem
     [Fintype α] [DecidableEq β] (k : β) (b : α → β) (hk : k ∈ Finset.image b univ) (p : β → Prop) [DecidablePred p]
  (hp : ¬p k) : image (fun i : { a // p (b a) } => b ↑i) univ ⊂ image b univ
        theorem image_subtype_univ_ssubset_image_univ [Fintype α] [DecidableEq β] (k : β) (b : α → β)
    (hk : k ∈ Finset.image b univ) (p : β → Prop) [DecidablePred p] (hp : ¬p k) :
    imageimage (fun i : { a // p (b a) } => b ↑i) univ ⊂ image b univ := by
  constructor
  · intro x hx
    rcases mem_image.1 hx with ⟨y, _, hy⟩
    exact hy ▸ mem_image_of_mem b (mem_univ (y : α))
  · intro h
    rw [mem_image] at hk
    rcases hk with ⟨k', _, hk'⟩
    subst hk'
    have := h (mem_image_of_mem b (mem_univ k'))
    rw [mem_image] at this
    rcases this with ⟨j, _, hj'⟩
    exact hp (hj' ▸ j.2)
        Finset.exists_equiv_extend_of_card_eq
      theorem
     [Fintype α] [DecidableEq β] {t : Finset β} (hαt : Fintype.card α = #t) {s : Finset α} {f : α → β}
  (hfst : Finset.image f s ⊆ t) (hfs : Set.InjOn f s) : ∃ g : α ≃ t, ∀ i ∈ s, (g i : β) = f i
        /-- Any injection from a finset `s` in a fintype `α` to a finset `t` of the same cardinality as `α`
can be extended to a bijection between `α` and `t`. -/
theorem Finset.exists_equiv_extend_of_card_eq [Fintype α] [DecidableEq β] {t : Finset β}
    (hαt : Fintype.card α = #t) {s : Finset α} {f : α → β} (hfst : Finset.imageFinset.image f s ⊆ t)
    (hfs : Set.InjOn f s) : ∃ g : α ≃ t, ∀ i ∈ s, (g i : β) = f i := by
  classical
    induction' s using Finset.induction with a s has H generalizing f
    · obtain ⟨e⟩ : Nonempty (α ≃ ↥t) := by rwa [← Fintype.card_eq, Fintype.card_coe]
      use e
      simp
    have hfst' : Finset.imageFinset.image f s ⊆ t := (Finset.image_mono _ (s.subset_insert a)).trans hfst
    have hfs' : Set.InjOn f s := hfs.mono (s.subset_insert a)
    obtain ⟨g', hg'⟩ := H hfst' hfs'
    have hfat : f a ∈ t := hfst (mem_image_of_mem _ (s.mem_insert_self a))
    use g'.trans (Equiv.swap (⟨f a, hfat⟩ : t) (g' a))
    simp_rw [mem_insert]
    rintro i (rfl | hi)
    · simp
    rw [Equiv.trans_apply, Equiv.swap_apply_of_ne_of_ne, hg' _ hi]
    · exact
        ne_of_apply_ne Subtype.val
          (ne_of_eq_of_ne (hg' _ hi) <|
            hfs.ne (subset_insert _ _ hi) (mem_insert_self _ _) <| ne_of_mem_of_not_mem hi has)
    · exact g'.injective.ne (ne_of_mem_of_not_mem hi has)
        Set.MapsTo.exists_equiv_extend_of_card_eq
      theorem
     [Fintype α] {t : Finset β} (hαt : Fintype.card α = #t) {s : Set α} {f : α → β} (hfst : s.MapsTo f t)
  (hfs : Set.InjOn f s) : ∃ g : α ≃ t, ∀ i ∈ s, (g i : β) = f i
        /-- Any injection from a set `s` in a fintype `α` to a finset `t` of the same cardinality as `α`
can be extended to a bijection between `α` and `t`. -/
theorem Set.MapsTo.exists_equiv_extend_of_card_eq [Fintype α] {t : Finset β}
    (hαt : Fintype.card α = #t) {s : Set α} {f : α → β} (hfst : s.MapsTo f t)
    (hfs : Set.InjOn f s) : ∃ g : α ≃ t, ∀ i ∈ s, (g i : β) = f i := by
  classical
    let s' : Finset α := s.toFinset
    have hfst' : s'.image f ⊆ t := by simpa [s', ← Finset.coe_subset] using hfst
    have hfs' : Set.InjOn f s' := by simpa [s'] using hfs
    obtain ⟨g, hg⟩ := Finset.exists_equiv_extend_of_card_eq hαt hfst' hfs'
    refine ⟨g, fun i hi => ?_⟩
    apply hg
    simpa [s'] using hi
        Fintype.card_subtype_or
      theorem
     (p q : α → Prop) [Fintype { x // p x }] [Fintype { x // q x }] [Fintype { x // p x ∨ q x }] :
  Fintype.card { x // p x ∨ q x } ≤ Fintype.card { x // p x } + Fintype.card { x // q x }
        theorem Fintype.card_subtype_or (p q : α → Prop) [Fintype { x // p x }] [Fintype { x // q x }]
    [Fintype { x // p x ∨ q x }] :
    Fintype.card { x // p x ∨ q x } ≤ Fintype.card { x // p x } + Fintype.card { x // q x } := by
  classical
    convert Fintype.card_le_of_embedding (subtypeOrLeftEmbedding p q)
    rw [Fintype.card_sum]
        Fintype.card_subtype_or_disjoint
      theorem
     (p q : α → Prop) (h : Disjoint p q) [Fintype { x // p x }] [Fintype { x // q x }] [Fintype { x // p x ∨ q x }] :
  Fintype.card { x // p x ∨ q x } = Fintype.card { x // p x } + Fintype.card { x // q x }
        theorem Fintype.card_subtype_or_disjoint (p q : α → Prop) (h : Disjoint p q) [Fintype { x // p x }]
    [Fintype { x // q x }] [Fintype { x // p x ∨ q x }] :
    Fintype.card { x // p x ∨ q x } = Fintype.card { x // p x } + Fintype.card { x // q x } := by
  classical
    convert Fintype.card_congr (subtypeOrEquiv p q h)
    simp
        infinite_sum
      theorem
     : Infinite (α ⊕ β) ↔ Infinite α ∨ Infinite β
        @[simp]
theorem infinite_sum : InfiniteInfinite (α ⊕ β) ↔ Infinite α ∨ Infinite β := by
  refine ⟨fun H => ?_, fun H => H.elim (@Sum.infinite_of_left α β) (@Sum.infinite_of_right α β)⟩
  contrapose! H; haveI := fintypeOfNotInfinite H.1; haveI := fintypeOfNotInfinite H.2
  exact Infinite.false