l3lab/ntp-mathlib huggingface dataset:
theorem continuous_of_scottContinuous {α β} [OmegaCompletePartialOrder α]
    [OmegaCompletePartialOrder β] (f : Scott α → Scott β)
    (hf : OmegaCompletePartialOrder.Continuous' f) : Continuous f := by
  rw [continuous_def]
  intro s hs
  change Continuous' (s ∘ f)
  cases' hs with hs hs'
  cases' hf with hf hf'
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : OmegaCompletePartialOrder α
inst✝ : OmegaCompletePartialOrder β
f : Scott α → Scott β
s : Set (Scott β)
hs : Monotone fun x => x ∈ s
hs' : OmegaCompletePartialOrder.Continuous { toFun := fun x => x ∈ s, monotone' := hs }
hf : Monotone f
hf' : OmegaCompletePartialOrder.Continuous { toFun := f, monotone' := hf }
⊢ Continuous' (s ∘ f)

Next tactic:
apply Continuous.of_bundled
theorem continuous_of_scottContinuous {α β} [OmegaCompletePartialOrder α]
    [OmegaCompletePartialOrder β] (f : Scott α → Scott β)
    (hf : OmegaCompletePartialOrder.Continuous' f) : Continuous f := by
  rw [continuous_def]
  intro s hs
  change Continuous' (s ∘ f)
  cases' hs with hs hs'
  cases' hf with hf hf'
  apply Continuous.of_bundled
  

Proof state:
case intro.intro.hf'
α : Type u_1
β : Type u_2
inst✝¹ : OmegaCompletePartialOrder α
inst✝ : OmegaCompletePartialOrder β
f : Scott α → Scott β
s : Set (Scott β)
hs : Monotone fun x => x ∈ s
hs' : OmegaCompletePartialOrder.Continuous { toFun := fun x => x ∈ s, monotone' := hs }
hf : Monotone f
hf' : OmegaCompletePartialOrder.Continuous { toFun := f, monotone' := hf }
⊢ OmegaCompletePartialOrder.Continuous { toFun := s ∘ f, monotone' := ?intro.intro.hf }
case intro.intro.hf
α : Type u_1
β : Type u_2
inst✝¹ : OmegaCompletePartialOrder α
inst✝ : OmegaCompletePartialOrder β
f : Scott α → Scott β
s : Set (Scott β)
hs : Monotone fun x => x ∈ s
hs' : OmegaCompletePartialOrder.Continuous { toFun := fun x => x ∈ s, monotone' := hs }
hf : Monotone f
hf' : OmegaCompletePartialOrder.Continuous { toFun := f, monotone' := hf }
⊢ Monotone (s ∘ f)

Next tactic:
apply continuous_comp _ _ hf' hs'
instance (priority := 100) ModularFormClass.modularForm :
    ModularFormClass (ModularForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
f g : ModularForm Γ k
h : (fun f => f.toFun) f = (fun f => f.toFun) g
⊢ f = g

Next tactic:
cases f
instance (priority := 100) ModularFormClass.modularForm :
    ModularFormClass (ModularForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by cases f; 

Proof state:
case mk
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
g : ModularForm Γ k
toSlashInvariantForm✝ : SlashInvariantForm Γ k
holo'✝ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝
bdd_at_infty'✝ : ∀ (A : SL(2, ℤ)), IsBoundedAtImInfty (⇑toSlashInvariantForm✝ ∣[k] A)
h :
  (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, bdd_at_infty' := bdd_at_infty'✝ } =
    (fun f => f.toFun) g
⊢ { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, bdd_at_infty' := bdd_at_infty'✝ } = g

Next tactic:
cases g
instance (priority := 100) ModularFormClass.modularForm :
    ModularFormClass (ModularForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by cases f; cases g; 

Proof state:
case mk.mk
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
toSlashInvariantForm✝¹ : SlashInvariantForm Γ k
holo'✝¹ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝¹
bdd_at_infty'✝¹ : ∀ (A : SL(2, ℤ)), IsBoundedAtImInfty (⇑toSlashInvariantForm✝¹ ∣[k] A)
toSlashInvariantForm✝ : SlashInvariantForm Γ k
holo'✝ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝
bdd_at_infty'✝ : ∀ (A : SL(2, ℤ)), IsBoundedAtImInfty (⇑toSlashInvariantForm✝ ∣[k] A)
h :
  (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝¹, holo' := holo'✝¹, bdd_at_infty' := bdd_at_infty'✝¹ } =
    (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, bdd_at_infty' := bdd_at_infty'✝ }
⊢ { toSlashInvariantForm := toSlashInvariantForm✝¹, holo' := holo'✝¹, bdd_at_infty' := bdd_at_infty'✝¹ } =
    { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, bdd_at_infty' := bdd_at_infty'✝ }

Next tactic:
congr
instance (priority := 100) ModularFormClass.modularForm :
    ModularFormClass (ModularForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by cases f; cases g; congr; 

Proof state:
case mk.mk.e_toSlashInvariantForm
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
toSlashInvariantForm✝¹ : SlashInvariantForm Γ k
holo'✝¹ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝¹
bdd_at_infty'✝¹ : ∀ (A : SL(2, ℤ)), IsBoundedAtImInfty (⇑toSlashInvariantForm✝¹ ∣[k] A)
toSlashInvariantForm✝ : SlashInvariantForm Γ k
holo'✝ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝
bdd_at_infty'✝ : ∀ (A : SL(2, ℤ)), IsBoundedAtImInfty (⇑toSlashInvariantForm✝ ∣[k] A)
h :
  (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝¹, holo' := holo'✝¹, bdd_at_infty' := bdd_at_infty'✝¹ } =
    (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, bdd_at_infty' := bdd_at_infty'✝ }
⊢ toSlashInvariantForm✝¹ = toSlashInvariantForm✝

Next tactic:
exact FunLike.ext' h
instance (priority := 100) CuspFormClass.cuspForm : CuspFormClass (CuspForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
f g : CuspForm Γ k
h : (fun f => f.toFun) f = (fun f => f.toFun) g
⊢ f = g

Next tactic:
cases f
instance (priority := 100) CuspFormClass.cuspForm : CuspFormClass (CuspForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by cases f; 

Proof state:
case mk
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
g : CuspForm Γ k
toSlashInvariantForm✝ : SlashInvariantForm Γ k
holo'✝ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝
zero_at_infty'✝ : ∀ (A : SL(2, ℤ)), IsZeroAtImInfty (⇑toSlashInvariantForm✝ ∣[k] A)
h :
  (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, zero_at_infty' := zero_at_infty'✝ } =
    (fun f => f.toFun) g
⊢ { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, zero_at_infty' := zero_at_infty'✝ } = g

Next tactic:
cases g
instance (priority := 100) CuspFormClass.cuspForm : CuspFormClass (CuspForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by cases f; cases g; 

Proof state:
case mk.mk
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
toSlashInvariantForm✝¹ : SlashInvariantForm Γ k
holo'✝¹ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝¹
zero_at_infty'✝¹ : ∀ (A : SL(2, ℤ)), IsZeroAtImInfty (⇑toSlashInvariantForm✝¹ ∣[k] A)
toSlashInvariantForm✝ : SlashInvariantForm Γ k
holo'✝ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝
zero_at_infty'✝ : ∀ (A : SL(2, ℤ)), IsZeroAtImInfty (⇑toSlashInvariantForm✝ ∣[k] A)
h :
  (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝¹, holo' := holo'✝¹, zero_at_infty' := zero_at_infty'✝¹ } =
    (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, zero_at_infty' := zero_at_infty'✝ }
⊢ { toSlashInvariantForm := toSlashInvariantForm✝¹, holo' := holo'✝¹, zero_at_infty' := zero_at_infty'✝¹ } =
    { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, zero_at_infty' := zero_at_infty'✝ }

Next tactic:
congr
instance (priority := 100) CuspFormClass.cuspForm : CuspFormClass (CuspForm Γ k) Γ k where
  coe f := f.toFun
  coe_injective' f g h := by cases f; cases g; congr; 

Proof state:
case mk.mk.e_toSlashInvariantForm
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
toSlashInvariantForm✝¹ : SlashInvariantForm Γ k
holo'✝¹ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝¹
zero_at_infty'✝¹ : ∀ (A : SL(2, ℤ)), IsZeroAtImInfty (⇑toSlashInvariantForm✝¹ ∣[k] A)
toSlashInvariantForm✝ : SlashInvariantForm Γ k
holo'✝ : MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑toSlashInvariantForm✝
zero_at_infty'✝ : ∀ (A : SL(2, ℤ)), IsZeroAtImInfty (⇑toSlashInvariantForm✝ ∣[k] A)
h :
  (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝¹, holo' := holo'✝¹, zero_at_infty' := zero_at_infty'✝¹ } =
    (fun f => f.toFun)
      { toSlashInvariantForm := toSlashInvariantForm✝, holo' := holo'✝, zero_at_infty' := zero_at_infty'✝ }
⊢ toSlashInvariantForm✝¹ = toSlashInvariantForm✝

Next tactic:
exact FunLike.ext' h
instance add : Add (ModularForm Γ k) :=
  ⟨fun f g =>
    { toSlashInvariantForm := f + g
      holo' := f.holo'.add g.holo'
      bdd_at_infty' := fun A => by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
f g : ModularForm Γ k
A : SL(2, ℤ)
⊢ IsBoundedAtImInfty
    (⇑({ toFun := ⇑f, slash_action_eq' := (_ : ∀ (γ : ↥Γ), ⇑f ∣[k] γ = ⇑f) } +
          { toFun := ⇑g, slash_action_eq' := (_ : ∀ (γ : ↥Γ), ⇑g ∣[k] γ = ⇑g) }) ∣[k]
      A)

Next tactic:
simpa using (f.bdd_at_infty' A).add (g.bdd_at_infty' A)
instance instZero : Zero (ModularForm Γ k) :=
  ⟨ { toSlashInvariantForm := 0
      holo' := fun _ => mdifferentiableAt_const 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ)
      bdd_at_infty' := fun A => by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
A : SL(2, ℤ)
⊢ IsBoundedAtImInfty (⇑0 ∣[k] A)

Next tactic:
simpa using zero_form_isBoundedAtImInfty
instance instSMul : SMul α (ModularForm Γ k) :=
  ⟨fun c f =>
    { toSlashInvariantForm := c • f.1
      holo' := by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
α : Type u_2
inst✝¹ : SMul α ℂ
inst✝ : IsScalarTower α ℂ ℂ
c : α
f : ModularForm Γ k
⊢ MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑(c • f.toSlashInvariantForm)

Next tactic:
simpa using f.holo'.const_smul (c • (1 : ℂ))
instance instSMul : SMul α (ModularForm Γ k) :=
  ⟨fun c f =>
    { toSlashInvariantForm := c • f.1
      holo' := by simpa using f.holo'.const_smul (c • (1 : ℂ))
      bdd_at_infty' := fun A => by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
α : Type u_2
inst✝¹ : SMul α ℂ
inst✝ : IsScalarTower α ℂ ℂ
c : α
f : ModularForm Γ k
A : SL(2, ℤ)
⊢ IsBoundedAtImInfty (⇑(c • f.toSlashInvariantForm) ∣[k] A)

Next tactic:
simpa using (f.bdd_at_infty' A).const_smul_left (c • (1 : ℂ))
instance instNeg : Neg (ModularForm Γ k) :=
  ⟨fun f =>
    { toSlashInvariantForm := -f.1
      holo' := f.holo'.neg
      bdd_at_infty' := fun A => by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
f : ModularForm Γ k
A : SL(2, ℤ)
⊢ IsBoundedAtImInfty (⇑(-f.toSlashInvariantForm) ∣[k] A)

Next tactic:
simpa using (f.bdd_at_infty' A).neg
/-- The modular form of weight `k_1 + k_2` given by the product of two modular forms of weights
`k_1` and `k_2`. -/
def mul {k_1 k_2 : ℤ} {Γ : Subgroup SL(2, ℤ)} (f : ModularForm Γ k_1) (g : ModularForm Γ k_2) :
    ModularForm Γ (k_1 + k_2) where
  toSlashInvariantForm := f.1.mul g.1
  holo' := f.holo'.mul g.holo'
  bdd_at_infty' A := by
    -- porting note: was `by simpa using ...`
    -- `mul_slash_SL2` is no longer a `simp` and `simpa only [mul_slash_SL2] using ...` failed
    

Proof state:
F : Type u_1
Γ✝ : Subgroup SL(2, ℤ)
k k_1 k_2 : ℤ
Γ : Subgroup SL(2, ℤ)
f : ModularForm Γ k_1
g : ModularForm Γ k_2
A : SL(2, ℤ)
⊢ IsBoundedAtImInfty (⇑(SlashInvariantForm.mul f.toSlashInvariantForm g.toSlashInvariantForm) ∣[k_1 + k_2] A)

Next tactic:
rw [SlashInvariantForm.coe_mul, mul_slash_SL2]
/-- The modular form of weight `k_1 + k_2` given by the product of two modular forms of weights
`k_1` and `k_2`. -/
def mul {k_1 k_2 : ℤ} {Γ : Subgroup SL(2, ℤ)} (f : ModularForm Γ k_1) (g : ModularForm Γ k_2) :
    ModularForm Γ (k_1 + k_2) where
  toSlashInvariantForm := f.1.mul g.1
  holo' := f.holo'.mul g.holo'
  bdd_at_infty' A := by
    -- porting note: was `by simpa using ...`
    -- `mul_slash_SL2` is no longer a `simp` and `simpa only [mul_slash_SL2] using ...` failed
    rw [SlashInvariantForm.coe_mul, mul_slash_SL2]
    

Proof state:
F : Type u_1
Γ✝ : Subgroup SL(2, ℤ)
k k_1 k_2 : ℤ
Γ : Subgroup SL(2, ℤ)
f : ModularForm Γ k_1
g : ModularForm Γ k_2
A : SL(2, ℤ)
⊢ IsBoundedAtImInfty (⇑f.toSlashInvariantForm ∣[k_1] A * ⇑g.toSlashInvariantForm ∣[k_2] A)

Next tactic:
exact (f.bdd_at_infty' A).mul (g.bdd_at_infty' A)
instance : One (ModularForm Γ 0) :=
  ⟨ { toSlashInvariantForm := 1
      holo' := fun x => mdifferentiableAt_const 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ)
      bdd_at_infty' := fun A => by
        

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
A : SL(2, ℤ)
⊢ IsBoundedAtImInfty (⇑1 ∣[0] A)

Next tactic:
simpa only [SlashInvariantForm.one_coe_eq_one,
          ModularForm.is_invariant_one] using atImInfty.const_boundedAtFilter (1 : ℂ)
instance hasAdd : Add (CuspForm Γ k) :=
  ⟨fun f g =>
    { toSlashInvariantForm := f + g
      holo' := f.holo'.add g.holo'
      zero_at_infty' := fun A => by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
f g : CuspForm Γ k
A : SL(2, ℤ)
⊢ IsZeroAtImInfty
    (⇑({ toFun := ⇑f, slash_action_eq' := (_ : ∀ (γ : ↥Γ), ⇑f ∣[k] γ = ⇑f) } +
          { toFun := ⇑g, slash_action_eq' := (_ : ∀ (γ : ↥Γ), ⇑g ∣[k] γ = ⇑g) }) ∣[k]
      A)

Next tactic:
simpa using (f.zero_at_infty' A).add (g.zero_at_infty' A)
instance instZero : Zero (CuspForm Γ k) :=
  ⟨ { toSlashInvariantForm := 0
      holo' := fun _ => mdifferentiableAt_const 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ)
      zero_at_infty' := by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
⊢ ∀ (A : SL(2, ℤ)), IsZeroAtImInfty (⇑0 ∣[k] A)

Next tactic:
simpa using Filter.zero_zeroAtFilter _
instance instSMul : SMul α (CuspForm Γ k) :=
  ⟨fun c f =>
    { toSlashInvariantForm := c • f.1
      holo' := by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
α : Type u_2
inst✝¹ : SMul α ℂ
inst✝ : IsScalarTower α ℂ ℂ
c : α
f : CuspForm Γ k
⊢ MDifferentiable 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) ⇑(c • f.toSlashInvariantForm)

Next tactic:
simpa using f.holo'.const_smul (c • (1 : ℂ))
instance instSMul : SMul α (CuspForm Γ k) :=
  ⟨fun c f =>
    { toSlashInvariantForm := c • f.1
      holo' := by simpa using f.holo'.const_smul (c • (1 : ℂ))
      zero_at_infty' := fun A => by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
α : Type u_2
inst✝¹ : SMul α ℂ
inst✝ : IsScalarTower α ℂ ℂ
c : α
f : CuspForm Γ k
A : SL(2, ℤ)
⊢ IsZeroAtImInfty (⇑(c • f.toSlashInvariantForm) ∣[k] A)

Next tactic:
simpa using (f.zero_at_infty' A).smul (c • (1 : ℂ))
instance instNeg : Neg (CuspForm Γ k) :=
  ⟨fun f =>
    { toSlashInvariantForm := -f.1
      holo' := f.holo'.neg
      zero_at_infty' := fun A => by 

Proof state:
F : Type u_1
Γ : Subgroup SL(2, ℤ)
k : ℤ
f : CuspForm Γ k
A : SL(2, ℤ)
⊢ IsZeroAtImInfty (⇑(-f.toSlashInvariantForm) ∣[k] A)

Next tactic:
simpa using (f.zero_at_infty' A).neg
theorem card_derangements_fin_add_two (n : ℕ) :
    card (derangements (Fin (n + 2))) =
      (n + 1) * card (derangements (Fin n)) + (n + 1) * card (derangements (Fin (n + 1))) := by
  -- get some basic results about the size of fin (n+1) plus or minus an element
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
⊢ card ↑(derangements (Fin (n + 2))) =
    (n + 1) * card ↑(derangements (Fin n)) + (n + 1) * card ↑(derangements (Fin (n + 1)))

Next tactic:
have h1 : ∀ a : Fin (n + 1), card ({a}ᶜ : Set (Fin (n + 1))) = card (Fin n) := by
    intro a
    simp only [Fintype.card_fin, Finset.card_fin, Fintype.card_ofFinset, Finset.filter_ne' _ a,
      Set.mem_compl_singleton_iff, Finset.card_erase_of_mem (Finset.mem_univ a),
      add_tsub_cancel_right]
theorem card_derangements_fin_add_two (n : ℕ) :
    card (derangements (Fin (n + 2))) =
      (n + 1) * card (derangements (Fin n)) + (n + 1) * card (derangements (Fin (n + 1))) := by
  -- get some basic results about the size of fin (n+1) plus or minus an element
  have h1 : ∀ a : Fin (n + 1), card ({a}ᶜ : Set (Fin (n + 1))) = card (Fin n) := by
    

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
⊢ ∀ (a : Fin (n + 1)), card ↑{a}ᶜ = card (Fin n)

Next tactic:
intro a
theorem card_derangements_fin_add_two (n : ℕ) :
    card (derangements (Fin (n + 2))) =
      (n + 1) * card (derangements (Fin n)) + (n + 1) * card (derangements (Fin (n + 1))) := by
  -- get some basic results about the size of fin (n+1) plus or minus an element
  have h1 : ∀ a : Fin (n + 1), card ({a}ᶜ : Set (Fin (n + 1))) = card (Fin n) := by
    intro a
    

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
a : Fin (n + 1)
⊢ card ↑{a}ᶜ = card (Fin n)

Next tactic:
simp only [Fintype.card_fin, Finset.card_fin, Fintype.card_ofFinset, Finset.filter_ne' _ a,
      Set.mem_compl_singleton_iff, Finset.card_erase_of_mem (Finset.mem_univ a),
      add_tsub_cancel_right]
theorem card_derangements_fin_add_two (n : ℕ) :
    card (derangements (Fin (n + 2))) =
      (n + 1) * card (derangements (Fin n)) + (n + 1) * card (derangements (Fin (n + 1))) := by
  -- get some basic results about the size of fin (n+1) plus or minus an element
  have h1 : ∀ a : Fin (n + 1), card ({a}ᶜ : Set (Fin (n + 1))) = card (Fin n) := by
    intro a
    simp only [Fintype.card_fin, Finset.card_fin, Fintype.card_ofFinset, Finset.filter_ne' _ a,
      Set.mem_compl_singleton_iff, Finset.card_erase_of_mem (Finset.mem_univ a),
      add_tsub_cancel_right]
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
h1 : ∀ (a : Fin (n + 1)), card ↑{a}ᶜ = card (Fin n)
⊢ card ↑(derangements (Fin (n + 2))) =
    (n + 1) * card ↑(derangements (Fin n)) + (n + 1) * card ↑(derangements (Fin (n + 1)))

Next tactic:
have h2 : card (Fin (n + 2)) = card (Option (Fin (n + 1))) := by simp only [card_fin, card_option]
theorem card_derangements_fin_add_two (n : ℕ) :
    card (derangements (Fin (n + 2))) =
      (n + 1) * card (derangements (Fin n)) + (n + 1) * card (derangements (Fin (n + 1))) := by
  -- get some basic results about the size of fin (n+1) plus or minus an element
  have h1 : ∀ a : Fin (n + 1), card ({a}ᶜ : Set (Fin (n + 1))) = card (Fin n) := by
    intro a
    simp only [Fintype.card_fin, Finset.card_fin, Fintype.card_ofFinset, Finset.filter_ne' _ a,
      Set.mem_compl_singleton_iff, Finset.card_erase_of_mem (Finset.mem_univ a),
      add_tsub_cancel_right]
  have h2 : card (Fin (n + 2)) = card (Option (Fin (n + 1))) := by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
h1 : ∀ (a : Fin (n + 1)), card ↑{a}ᶜ = card (Fin n)
⊢ card (Fin (n + 2)) = card (Option (Fin (n + 1)))

Next tactic:
simp only [card_fin, card_option]
theorem card_derangements_fin_add_two (n : ℕ) :
    card (derangements (Fin (n + 2))) =
      (n + 1) * card (derangements (Fin n)) + (n + 1) * card (derangements (Fin (n + 1))) := by
  -- get some basic results about the size of fin (n+1) plus or minus an element
  have h1 : ∀ a : Fin (n + 1), card ({a}ᶜ : Set (Fin (n + 1))) = card (Fin n) := by
    intro a
    simp only [Fintype.card_fin, Finset.card_fin, Fintype.card_ofFinset, Finset.filter_ne' _ a,
      Set.mem_compl_singleton_iff, Finset.card_erase_of_mem (Finset.mem_univ a),
      add_tsub_cancel_right]
  have h2 : card (Fin (n + 2)) = card (Option (Fin (n + 1))) := by simp only [card_fin, card_option]
  -- rewrite the LHS and substitute in our fintype-level equivalence
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
h1 : ∀ (a : Fin (n + 1)), card ↑{a}ᶜ = card (Fin n)
h2 : card (Fin (n + 2)) = card (Option (Fin (n + 1)))
⊢ card ↑(derangements (Fin (n + 2))) =
    (n + 1) * card ↑(derangements (Fin n)) + (n + 1) * card ↑(derangements (Fin (n + 1)))

Next tactic:
simp only [card_derangements_invariant h2,
    card_congr
      (@derangementsRecursionEquiv (Fin (n + 1))
        _),-- push the cardinality through the Σ and ⊕ so that we can use `card_n`
    card_sigma,
    card_sum, card_derangements_invariant (h1 _), Finset.sum_const, nsmul_eq_mul, Finset.card_fin,
    mul_add, Nat.cast_id]
theorem numDerangements_succ (n : ℕ) :
    (numDerangements (n + 1) : ℤ) = (n + 1) * (numDerangements n : ℤ) - (-1) ^ n := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
⊢ ↑(numDerangements (n + 1)) = (↑n + 1) * ↑(numDerangements n) - (-1) ^ n

Next tactic:
induction' n with n hn
theorem numDerangements_succ (n : ℕ) :
    (numDerangements (n + 1) : ℤ) = (n + 1) * (numDerangements n : ℤ) - (-1) ^ n := by
  induction' n with n hn
  · 

Proof state:
case zero
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
⊢ ↑(numDerangements (Nat.zero + 1)) = (↑Nat.zero + 1) * ↑(numDerangements Nat.zero) - (-1) ^ Nat.zero

Next tactic:
rfl
theorem numDerangements_succ (n : ℕ) :
    (numDerangements (n + 1) : ℤ) = (n + 1) * (numDerangements n : ℤ) - (-1) ^ n := by
  induction' n with n hn
  · rfl
  · 

Proof state:
case succ
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
hn : ↑(numDerangements (n + 1)) = (↑n + 1) * ↑(numDerangements n) - (-1) ^ n
⊢ ↑(numDerangements (Nat.succ n + 1)) = (↑(Nat.succ n) + 1) * ↑(numDerangements (Nat.succ n)) - (-1) ^ Nat.succ n

Next tactic:
simp only [numDerangements_add_two, hn, pow_succ, Int.ofNat_mul, Int.ofNat_add, Int.ofNat_succ]
theorem numDerangements_succ (n : ℕ) :
    (numDerangements (n + 1) : ℤ) = (n + 1) * (numDerangements n : ℤ) - (-1) ^ n := by
  induction' n with n hn
  · rfl
  · simp only [numDerangements_add_two, hn, pow_succ, Int.ofNat_mul, Int.ofNat_add, Int.ofNat_succ]
    

Proof state:
case succ
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
hn : ↑(numDerangements (n + 1)) = (↑n + 1) * ↑(numDerangements n) - (-1) ^ n
⊢ (↑n + 1) * (↑(numDerangements n) + ((↑n + 1) * ↑(numDerangements n) - (-1) ^ n)) =
    (↑n + 1 + 1) * ((↑n + 1) * ↑(numDerangements n) - (-1) ^ n) - -1 * (-1) ^ n

Next tactic:
ring
theorem card_derangements_fin_eq_numDerangements {n : ℕ} :
    card (derangements (Fin n)) = numDerangements n := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
⊢ card ↑(derangements (Fin n)) = numDerangements n

Next tactic:
induction' n using Nat.strong_induction_on with n hyp
theorem card_derangements_fin_eq_numDerangements {n : ℕ} :
    card (derangements (Fin n)) = numDerangements n := by
  induction' n using Nat.strong_induction_on with n hyp
  

Proof state:
case h
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
n : ℕ
hyp : ∀ m < n, card ↑(derangements (Fin m)) = numDerangements m
⊢ card ↑(derangements (Fin n)) = numDerangements n

Next tactic:
rcases n with _ | _ | n
theorem card_derangements_fin_eq_numDerangements {n : ℕ} :
    card (derangements (Fin n)) = numDerangements n := by
  induction' n using Nat.strong_induction_on with n hyp
  rcases n with _ | _ | n
  -- porting note: the two `convert_to` weren't necessary before.
  · 

Proof state:
case h.zero
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
hyp : ∀ m < Nat.zero, card ↑(derangements (Fin m)) = numDerangements m
⊢ card ↑(derangements (Fin Nat.zero)) = numDerangements Nat.zero

Next tactic:
convert_to card ↑{ f : Perm (Fin 0) | ∀ (x : Fin 0), f x ≠ x } = _ using 2
theorem card_derangements_fin_eq_numDerangements {n : ℕ} :
    card (derangements (Fin n)) = numDerangements n := by
  induction' n using Nat.strong_induction_on with n hyp
  rcases n with _ | _ | n
  -- porting note: the two `convert_to` weren't necessary before.
  · convert_to card ↑{ f : Perm (Fin 0) | ∀ (x : Fin 0), f x ≠ x } = _ using 2; 

Proof state:
case h.zero.convert_2
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
hyp : ∀ m < Nat.zero, card ↑(derangements (Fin m)) = numDerangements m
⊢ card ↑{f | ∀ (x : Fin 0), f x ≠ x} = numDerangements Nat.zero

Next tactic:
rfl
theorem card_derangements_fin_eq_numDerangements {n : ℕ} :
    card (derangements (Fin n)) = numDerangements n := by
  induction' n using Nat.strong_induction_on with n hyp
  rcases n with _ | _ | n
  -- porting note: the two `convert_to` weren't necessary before.
  · convert_to card ↑{ f : Perm (Fin 0) | ∀ (x : Fin 0), f x ≠ x } = _ using 2; rfl
  · 

Proof state:
case h.succ.zero
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
hyp : ∀ m < Nat.succ Nat.zero, card ↑(derangements (Fin m)) = numDerangements m
⊢ card ↑(derangements (Fin (Nat.succ Nat.zero))) = numDerangements (Nat.succ Nat.zero)

Next tactic:
convert_to card ↑{ f : Perm (Fin 1) | ∀ (x : Fin 1), f x ≠ x } = _ using 2