/- Copyright (c) 2017 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro ! This file was ported from Lean 3 source module data.fintype.option ! leanprover-community/mathlib commit 509de852e1de55e1efa8eacfa11df0823f26f226 ! Please do not edit these lines, except to modify the commit id ! if you have ported upstream changes. -/ import Mathlib.Data.Fintype.Card import Mathlib.Data.Finset.Option /-! # fintype instances for option -/ open Function open Nat universe u v variable {αα: Type ?u.8616ββ: Type ?u.3533γ :γ: Type ?u.8Type _} open Finset Function instance {Type _: Type (?u.2694+1)α :α: Type ?u.20Type _} [FintypeType _: Type (?u.20+1)α] : Fintype (Optionα: Type ?u.20α) := ⟨Finset.insertNone univ, funα: Type ?u.20a =>a: ?m.272Goals accomplished! 🐙⟩ theorem univ_option (Goals accomplished! 🐙α :α: Type u_1Type _) [FintypeType _: Type (?u.2338+1)α] : (univ : Finset (Optionα: Type ?u.2338α)) = insertNone univ := rfl #align univ_option univ_option @[simp] theorem Fintype.card_option {α: Type ?u.2338α :α: Type ?u.2703Type _} [FintypeType _: Type (?u.2703+1)α] : Fintype.card (Optionα: Type ?u.2703α) = Fintype.cardα: Type ?u.2703α +α: Type ?u.27031 := (1: ?m.2734Finset.card_cons (Finset.card_cons: ∀ {α : Type ?u.2798} {s : Finset α} {a : α} (h : ¬a ∈ s), Finset.card (cons a s h) = Finset.card s + 1Goals accomplished! 🐙)).trans <| congr_arg₂Goals accomplished! 🐙_ (_: ?m.2831 → ?m.2832 → ?m.2833card_mapcard_map: ∀ {α : Type ?u.2847} {β : Type ?u.2848} {s : Finset α} (f : α ↪ β), Finset.card (map f s) = Finset.card s_) rfl #align fintype.card_option_: ?m.2849 ↪ ?m.2850Fintype.card_option /-- If `Option α` is a `Fintype` then so is `α` -/ def fintypeOfOption {Fintype.card_option: ∀ {α : Type u_1} [inst : Fintype α], Fintype.card (Option α) = Fintype.card α + 1α :α: Type ?u.3539Type _} [Fintype (OptionType _: Type (?u.3539+1)α)] : Fintypeα: Type ?u.3539α := ⟨Finset.eraseNone (Fintype.elems (α := Optionα: Type ?u.3539α)), funα: Type ?u.3539x => mem_eraseNone.mpr (Fintype.complete (somex: ?m.3604x))⟩ #align fintype_of_option fintypeOfOption /-- A type is a `Fintype` if its successor (using `Option`) is a `Fintype`. -/ defx: ?m.3604fintypeOfOptionEquiv [Fintypeα] (f :α: Type ?u.3671α ≃ Optionα: Type ?u.3671β) : Fintypeβ: Type ?u.3674β := haveI := Fintype.ofEquivβ: Type ?u.3674_ f fintypeOfOption #align fintype_of_option_equiv fintypeOfOptionEquiv namespace Fintype /-- A recursor principle for finite types, analogous to `Nat.rec`. It effectively says that every `Fintype` is either `Empty` or `Option α`, up to an `Equiv`. -/ def_: Type ?u.3694truncRecEmptyOption {P :Type u →Type u: Type (u+1)SortSort v: Type vv} (of_equiv : ∀ {Sort v: Type vαα: ?m.3797β},β: ?m.3800α ≃α: ?m.3797β → Pβ: ?m.3800α → Pα: ?m.3797β) (β: ?m.3800h_empty : Ph_empty: P PEmptyPEmpty) (PEmpty: Sort ?u.3811h_option : ∀ {h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)α} [Fintypeα: ?m.3815α] [DecidableEqα: ?m.3815α], Pα: ?m.3815α → P (Optionα: ?m.3815α)) (α: ?m.3815α :α: Type uType u) [FintypeType u: Type (u+1)α] [DecidableEqα: Type uα] : Trunc (Pα: Type uα) :=α: Type uGoals accomplished! 🐙α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))Trunc (P α)α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))
h: P (ULift (Fin (card α)))Trunc (P α)α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))Trunc (P α)α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))
h: P (ULift (Fin (card α)))α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))Trunc (P α)α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))
h: P (ULift (Fin (card α)))
e: α ≃ Fin (card α)P αα✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: (n : ℕ) → Trunc (P (ULift (Fin n)))Trunc (P α)Goals accomplished! 🐙where -- porting note: do a manual recursion, instead of `induction` tactic, -- to ensure the result is computable /-- Internal induction hypothesis -/ ind : ∀Goals accomplished! 🐙n :n: ℕℕ, Trunc (P (ULift <| Finℕ: Typen)) |n: ℕNat.zero =>Nat.zero: ℕGoals accomplished! 🐙Goals accomplished! 🐙Goals accomplished! 🐙α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: card PEmpty = card (ULift (Fin 0))α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: card PEmpty = card (ULift (Fin 0))
e: PEmpty ≃ ULift (Fin 0)α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
this: card PEmpty = card (ULift (Fin 0))
e: PEmpty ≃ ULift (Fin 0)
a| Nat.succGoals accomplished! 🐙n =>n: ℕGoals accomplished! 🐙Goals accomplished! 🐙Goals accomplished! 🐙α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
n: ℕ
this: card (Option (ULift (Fin n))) = card (ULift (Fin (succ n)))α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
n: ℕ
this: card (Option (ULift (Fin n))) = card (ULift (Fin (succ n)))
e: Option (ULift (Fin n)) ≃ ULift (Fin (succ n))α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
n: ℕ
this: card (Option (ULift (Fin n))) = card (ULift (Fin (succ n)))
e: Option (ULift (Fin n)) ≃ ULift (Fin (succ n))α✝: Type ?u.3783
β: Type ?u.3786
γ: Type ?u.3789
P: Type u → Sort v
of_equiv: {α β : Type u} → α ≃ β → P α → P β
h_empty: P PEmpty
h_option: {α : Type u} → [inst : Fintype α] → [inst : DecidableEq α] → P α → P (Option α)
α: Type u
inst✝¹: Fintype α
inst✝: DecidableEq α
n: ℕ
this: card (Option (ULift (Fin n))) = card (ULift (Fin (succ n)))
e: Option (ULift (Fin n)) ≃ ULift (Fin (succ n))
ih: P (ULift (Fin n))#align fintype.trunc_rec_empty_option Fintype.truncRecEmptyOption -- Porting note: due to instance inference issues in `SetTheory.Cardinal.Basic` -- I had to explicitly name `h_fintype` in order to access it manually. -- was `[Fintype α]` /-- An induction principle for finite types, analogous to `Nat.rec`. It effectively says that every `Fintype` is either `Empty` or `Option α`, up to an `Equiv`. -/ @[elab_as_elim] theoremGoals accomplished! 🐙induction_empty_option {P : ∀ (α :α: Type uType u) [FintypeType u: Type (u+1)α],α: Type uProp} (of_equiv : ∀ (Prop: Typeαα: ?m.7621β) [Fintypeβ: ?m.7624β] (β: ?m.7624e :e: α ≃ βα ≃α: ?m.7621β), @Pβ: ?m.7624α (@Fintype.ofEquivα: ?m.7621αα: ?m.7621β ‹_›β: ?m.7624e.symm) → @Pe: α ≃ ββ ‹_›) (β: ?m.7624h_empty : Ph_empty: P PEmptyPEmpty) (h_option : ∀ (PEmpty: Sort ?u.7660α) [Fintypeα: ?m.7676α], Pα: ?m.7676α → P (Optionα: ?m.7676α)) (α: ?m.7676α :α: Type uType u) [Type u: Type (u+1)h_fintype : Fintypeh_fintype: Fintype αα] : Pα: Type uα :=α: Type uGoals accomplished! 🐙Goals accomplished! 🐙Goals accomplished! 🐙Goals accomplished! 🐙α✝: Type ?u.7603
β: Type ?u.7606
γ: Type ?u.7609
P: (α : Type u) → [inst : Fintype α] → Prop
of_equiv: ∀ (α β : Type u) [inst : Fintype β] (e : α ≃ β), P α → P β
h_empty: P PEmpty
h_option: ∀ (α : Type u) [inst : Fintype α], P α → P (Option α)
α: Type u
h_fintype: Fintype α
f_empty:= fun i => ?m.7731 i: ∀ (i : Fintype PEmpty), P PEmptyα✝¹: Type ?u.7603
β: Type ?u.7606
γ: Type ?u.7609
P: (α : Type u) → [inst : Fintype α] → Prop
of_equiv: ∀ (α β : Type u) [inst : Fintype β] (e : α ≃ β), P α → P β
h_empty: P PEmpty
h_option: ∀ (α : Type u) [inst : Fintype α], P α → P (Option α)
α✝: Type u
h_fintype: Fintype α✝
f_empty:= fun i => ?m.7731 i: ∀ (i : Fintype PEmpty), P PEmpty
α: Type u
hα: Fintype α
Pα: ∀ (h : Fintype α), P α
hα': Fintype (Option α)P (Option α)α✝: Type ?u.7603
β: Type ?u.7606
γ: Type ?u.7609
P: (α : Type u) → [inst : Fintype α] → Prop
of_equiv: ∀ (α β : Type u) [inst : Fintype β] (e : α ≃ β), P α → P β
h_empty: P PEmpty
h_option: ∀ (α : Type u) [inst : Fintype α], P α → P (Option α)
α: Type u
h_fintype: Fintype α
f_empty:= fun i => ?m.7731 i: ∀ (i : Fintype PEmpty), P PEmptyGoals accomplished! 🐙α✝: Type ?u.7603
β: Type ?u.7606
γ: Type ?u.7609
P: (α : Type u) → [inst : Fintype α] → Prop
of_equiv: ∀ (α β : Type u) [inst : Fintype β] (e : α ≃ β), P α → P β
h_empty: P PEmpty
h_option: ∀ (α : Type u) [inst : Fintype α], P α → P (Option α)
α: Type u
h_fintype: Fintype α
x✝: Trunc (∀ (h : Fintype α), P α)
p: ∀ (h : Fintype α), P α
mkP αα✝: Type ?u.7603
β: Type ?u.7606
γ: Type ?u.7609
P: (α : Type u) → [inst : Fintype α] → Prop
of_equiv: ∀ (α β : Type u) [inst : Fintype β] (e : α ≃ β), P α → P β
h_empty: P PEmpty
h_option: ∀ (α : Type u) [inst : Fintype α], P α → P (Option α)
α: Type u
h_fintype: Fintype α
x✝: Trunc (∀ (h : Fintype α), P α)
p: ∀ (h : Fintype α), P α
mkP αα✝: Type ?u.7603
β: Type ?u.7606
γ: Type ?u.7609
P: (α : Type u) → [inst : Fintype α] → Prop
of_equiv: ∀ (α β : Type u) [inst : Fintype β] (e : α ≃ β), P α → P β
h_empty: P PEmpty
h_option: ∀ (α : Type u) [inst : Fintype α], P α → P (Option α)
α: Type u
h_fintype: Fintype α
x✝: Trunc (∀ (h : Fintype α), P α)
p: ∀ (h : Fintype α), P α
mkP α-- · #align fintype.induction_empty_option Fintype.induction_empty_option end Fintype /-- An induction principle for finite types, analogous to `Nat.rec`. It effectively says that every `Fintype` is either `Empty` or `Option α`, up to an `Equiv`. -/ theoremGoals accomplished! 🐙Finite.induction_empty_option {P :Type u →Type u: Type (u+1)Prop} (of_equiv : ∀ {Prop: Typeαα: ?m.8630β},β: ?m.8633α ≃α: ?m.8630β → Pβ: ?m.8633α → Pα: ?m.8630β) (β: ?m.8633h_empty : Ph_empty: P PEmptyPEmpty) (h_option : ∀ {PEmpty: Sort ?u.8644α} [Fintypeα: ?m.8648α], Pα: ?m.8648α → P (Optionα: ?m.8648α)) (α: ?m.8648α :α: Type uType u) [FiniteType u: Type (u+1)α] : Pα: Type uα :=α: Type uGoals accomplished! 🐙α✝: Type ?u.8616
β: Type ?u.8619
γ: Type ?u.8622
P: Type u → Prop
of_equiv: ∀ {α β : Type u}, α ≃ β → P α → P β
h_empty: P PEmpty
h_option: ∀ {α : Type u} [inst : Fintype α], P α → P (Option α)
α: Type u
inst✝: Finite α
val✝: Fintype α
intro.refine'_1α✝: Type ?u.8616
β: Type ?u.8619
γ: Type ?u.8622
P: Type u → Prop
of_equiv: ∀ {α β : Type u}, α ≃ β → P α → P β
h_empty: P PEmpty
h_option: ∀ {α : Type u} [inst : Fintype α], P α → P (Option α)
α: Type u
inst✝: Finite α
val✝: Fintype α
intro.refine'_2P PEmptyα✝: Type ?u.8616
β: Type ?u.8619
γ: Type ?u.8622
P: Type u → Prop
of_equiv: ∀ {α β : Type u}, α ≃ β → P α → P β
h_empty: P PEmpty
h_option: ∀ {α : Type u} [inst : Fintype α], P α → P (Option α)
α: Type u
inst✝: Finite α
val✝: Fintype α
intro.refine'_3#align finite.induction_empty_option Finite.induction_empty_optionGoals accomplished! 🐙