l3lab/ntp-mathlib huggingface dataset:
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    cases n
    · simp [Perm.swap]
    simp only [powersetCardAux_cons, map_append, List.map_map]
    rw [← append_assoc, ← append_assoc,
      (by funext s; 

Proof state:
case h
α : Type u_1
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux (Nat.succ n✝) l₁ ~ powersetCardAux (Nat.succ n✝) l₂
s : Multiset α
⊢ (cons b ∘ cons a) s = (cons a ∘ cons b) s

Next tactic:
simp [cons_swap]
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    cases n
    · simp [Perm.swap]
    simp only [powersetCardAux_cons, map_append, List.map_map]
    rw [← append_assoc, ← append_assoc,
      (by funext s; simp [cons_swap] : cons b ∘ cons a = cons a ∘ cons b)]
    

Proof state:
case succ.swap.a.succ
α : Type u_1
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux (Nat.succ n✝) l₁ ~ powersetCardAux (Nat.succ n✝) l₂
⊢ List.map (cons a) (powersetCardAux (Nat.succ n✝) l) ++ List.map (cons b) (powersetCardAux (n✝ + 1) l) ++
      List.map (cons a ∘ cons b) (powersetCardAux n✝ l) ~
    List.map (cons b) (powersetCardAux (Nat.succ n✝) l) ++ List.map (cons a) (powersetCardAux (n✝ + 1) l) ++
      List.map (cons a ∘ cons b) (powersetCardAux n✝ l)

Next tactic:
exact perm_append_comm.append_right _
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    cases n
    · simp [Perm.swap]
    simp only [powersetCardAux_cons, map_append, List.map_map]
    rw [← append_assoc, ← append_assoc,
      (by funext s; simp [cons_swap] : cons b ∘ cons a = cons a ∘ cons b)]
    exact perm_append_comm.append_right _
  · 

Proof state:
case succ.trans
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁✝ l₂✝ l₁ l₂ l₃ : List α
a✝¹ : l₁ ~ l₂
a✝ : l₂ ~ l₃
IH₁ : powersetCardAux (Nat.succ n) l₁ ~ powersetCardAux (Nat.succ n) l₂
IH₂ : powersetCardAux (Nat.succ n) l₂ ~ powersetCardAux (Nat.succ n) l₃
⊢ powersetCardAux (Nat.succ n) l₁ ~ powersetCardAux (Nat.succ n) l₃

Next tactic:
exact IH₁.trans IH₂
@[simp]
theorem powersetCard_zero_left (s : Multiset α) : powersetCard 0 s = {0} :=
  Quotient.inductionOn s fun l => by 

Proof state:
α : Type u_1
s : Multiset α
l : List α
⊢ powersetCard 0 ⟦l⟧ = {0}

Next tactic:
simp [powersetCard_coe']
@[simp]
theorem powersetCard_cons (n : ℕ) (a : α) (s) :
    powersetCard (n + 1) (a ::ₘ s) = powersetCard (n + 1) s + map (cons a) (powersetCard n s) :=
  Quotient.inductionOn s fun l => by 

Proof state:
α : Type u_1
n : ℕ
a : α
s : Multiset α
l : List α
⊢ powersetCard (n + 1) (a ::ₘ ⟦l⟧) = powersetCard (n + 1) ⟦l⟧ + map (cons a) (powersetCard n ⟦l⟧)

Next tactic:
simp [powersetCard_coe']
theorem powersetCard_one (s : Multiset α) : powersetCard 1 s = s.map singleton :=
  Quotient.inductionOn s fun l ↦ by
    

Proof state:
α : Type u_1
s : Multiset α
l : List α
⊢ powersetCard 1 ⟦l⟧ = map singleton ⟦l⟧

Next tactic:
simp [powersetCard_coe, sublistsLen_one, map_reverse, Function.comp]
@[simp]
theorem mem_powersetCard {n : ℕ} {s t : Multiset α} : s ∈ powersetCard n t ↔ s ≤ t ∧ card s = n :=
  Quotient.inductionOn t fun l => by 

Proof state:
α : Type u_1
n : ℕ
s t : Multiset α
l : List α
⊢ s ∈ powersetCard n ⟦l⟧ ↔ s ≤ ⟦l⟧ ∧ card s = n

Next tactic:
simp [powersetCard_coe']
@[simp]
theorem card_powersetCard (n : ℕ) (s : Multiset α) :
    card (powersetCard n s) = Nat.choose (card s) n :=
  Quotient.inductionOn s <| by 

Proof state:
α : Type u_1
n : ℕ
s : Multiset α
⊢ ∀ (a : List α), card (powersetCard n ⟦a⟧) = Nat.choose (card ⟦a⟧) n

Next tactic:
simp [powersetCard_coe]
theorem powersetCard_le_powerset (n : ℕ) (s : Multiset α) : powersetCard n s ≤ powerset s :=
  Quotient.inductionOn s fun l => by
    

Proof state:
α : Type u_1
n : ℕ
s : Multiset α
l : List α
⊢ powersetCard n ⟦l⟧ ≤ powerset ⟦l⟧

Next tactic:
simp only [quot_mk_to_coe, powersetCard_coe, powerset_coe', coe_le]
theorem powersetCard_le_powerset (n : ℕ) (s : Multiset α) : powersetCard n s ≤ powerset s :=
  Quotient.inductionOn s fun l => by
    simp only [quot_mk_to_coe, powersetCard_coe, powerset_coe', coe_le]
    

Proof state:
α : Type u_1
n : ℕ
s : Multiset α
l : List α
⊢ List.map ofList (sublistsLen n l) <+~ List.map ofList (sublists' l)

Next tactic:
exact ((sublistsLen_sublist_sublists' _ _).map _).subperm
theorem powersetCard_mono (n : ℕ) {s t : Multiset α} (h : s ≤ t) :
    powersetCard n s ≤ powersetCard n t :=
  leInductionOn h fun {l₁ l₂} h => by
    

Proof state:
α : Type u_1
n : ℕ
s t : Multiset α
h✝ : s ≤ t
l₁ l₂ : List α
h : l₁ <+ l₂
⊢ powersetCard n ↑l₁ ≤ powersetCard n ↑l₂

Next tactic:
simp only [powersetCard_coe, coe_le]
theorem powersetCard_mono (n : ℕ) {s t : Multiset α} (h : s ≤ t) :
    powersetCard n s ≤ powersetCard n t :=
  leInductionOn h fun {l₁ l₂} h => by
    simp only [powersetCard_coe, coe_le]
    

Proof state:
α : Type u_1
n : ℕ
s t : Multiset α
h✝ : s ≤ t
l₁ l₂ : List α
h : l₁ <+ l₂
⊢ List.map ofList (sublistsLen n l₁) <+~ List.map ofList (sublistsLen n l₂)

Next tactic:
exact ((sublistsLen_sublist_of_sublist _ h).map _).subperm
theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (map f) := by
  

Proof state:
α : Type u_1
β : Type u_2
f : α → β
n : ℕ
s : Multiset α
⊢ powersetCard n (map f s) = map (map f) (powersetCard n s)

Next tactic:
induction' s using Multiset.induction with t s ih generalizing n
theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (map f) := by
  induction' s using Multiset.induction with t s ih generalizing n
  · 

Proof state:
case empty
α : Type u_1
β : Type u_2
f : α → β
n : ℕ
⊢ powersetCard n (map f 0) = map (map f) (powersetCard n 0)

Next tactic:
cases n
theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (map f) := by
  induction' s using Multiset.induction with t s ih generalizing n
  · cases n <;> 

Proof state:
case empty.zero
α : Type u_1
β : Type u_2
f : α → β
⊢ powersetCard Nat.zero (map f 0) = map (map f) (powersetCard Nat.zero 0)

Next tactic:
simp [powersetCard_zero_left, powersetCard_zero_right]
theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (map f) := by
  induction' s using Multiset.induction with t s ih generalizing n
  · cases n <;> 

Proof state:
case empty.succ
α : Type u_1
β : Type u_2
f : α → β
n✝ : ℕ
⊢ powersetCard (Nat.succ n✝) (map f 0) = map (map f) (powersetCard (Nat.succ n✝) 0)

Next tactic:
simp [powersetCard_zero_left, powersetCard_zero_right]
theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (map f) := by
  induction' s using Multiset.induction with t s ih generalizing n
  · cases n <;> simp [powersetCard_zero_left, powersetCard_zero_right]
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
f : α → β
t : α
s : Multiset α
ih : ∀ (n : ℕ), powersetCard n (map f s) = map (map f) (powersetCard n s)
n : ℕ
⊢ powersetCard n (map f (t ::ₘ s)) = map (map f) (powersetCard n (t ::ₘ s))

Next tactic:
cases n
theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (map f) := by
  induction' s using Multiset.induction with t s ih generalizing n
  · cases n <;> simp [powersetCard_zero_left, powersetCard_zero_right]
  · cases n <;> 

Proof state:
case cons.zero
α : Type u_1
β : Type u_2
f : α → β
t : α
s : Multiset α
ih : ∀ (n : ℕ), powersetCard n (map f s) = map (map f) (powersetCard n s)
⊢ powersetCard Nat.zero (map f (t ::ₘ s)) = map (map f) (powersetCard Nat.zero (t ::ₘ s))

Next tactic:
simp [ih, map_comp_cons]
theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) :
    powersetCard n (s.map f) = (powersetCard n s).map (map f) := by
  induction' s using Multiset.induction with t s ih generalizing n
  · cases n <;> simp [powersetCard_zero_left, powersetCard_zero_right]
  · cases n <;> 

Proof state:
case cons.succ
α : Type u_1
β : Type u_2
f : α → β
t : α
s : Multiset α
ih : ∀ (n : ℕ), powersetCard n (map f s) = map (map f) (powersetCard n s)
n✝ : ℕ
⊢ powersetCard (Nat.succ n✝) (map f (t ::ₘ s)) = map (map f) (powersetCard (Nat.succ n✝) (t ::ₘ s))

Next tactic:
simp [ih, map_comp_cons]
theorem bind_powerset_len {α : Type*} (S : Multiset α) :
    (bind (Multiset.range (card S + 1)) fun k => S.powersetCard k) = S.powerset := by
  

Proof state:
α✝ : Type u_1
α : Type u_2
S : Multiset α
⊢ (bind (range (card S + 1)) fun k => powersetCard k S) = powerset S

Next tactic:
induction S using Quotient.inductionOn
theorem bind_powerset_len {α : Type*} (S : Multiset α) :
    (bind (Multiset.range (card S + 1)) fun k => S.powersetCard k) = S.powerset := by
  induction S using Quotient.inductionOn
  

Proof state:
case h
α✝ : Type u_1
α : Type u_2
a✝ : List α
⊢ (bind (range (card ⟦a✝⟧ + 1)) fun k => powersetCard k ⟦a✝⟧) = powerset ⟦a✝⟧

Next tactic:
simp_rw [quot_mk_to_coe, powerset_coe', powersetCard_coe, ← coe_range, coe_bind, ← List.bind_map,
    coe_card]
theorem bind_powerset_len {α : Type*} (S : Multiset α) :
    (bind (Multiset.range (card S + 1)) fun k => S.powersetCard k) = S.powerset := by
  induction S using Quotient.inductionOn
  simp_rw [quot_mk_to_coe, powerset_coe', powersetCard_coe, ← coe_range, coe_bind, ← List.bind_map,
    coe_card]
  

Proof state:
case h
α✝ : Type u_1
α : Type u_2
a✝ : List α
⊢ ↑(List.map ofList (List.bind (List.range (length a✝ + 1)) fun a => sublistsLen a a✝)) =
    ↑(List.map ofList (sublists' a✝))

Next tactic:
exact coe_eq_coe.mpr ((List.range_bind_sublistsLen_perm _).map _)
@[simp]
theorem nodup_powerset {s : Multiset α} : Nodup (powerset s) ↔ Nodup s :=
  ⟨fun h => (nodup_of_le (map_single_le_powerset _) h).of_map _,
    Quotient.inductionOn s fun l h => by
      

Proof state:
α : Type u_1
s : Multiset α
l : List α
h : Nodup ⟦l⟧
⊢ Nodup (powerset ⟦l⟧)

Next tactic:
simp only [quot_mk_to_coe, powerset_coe', coe_nodup]
@[simp]
theorem nodup_powerset {s : Multiset α} : Nodup (powerset s) ↔ Nodup s :=
  ⟨fun h => (nodup_of_le (map_single_le_powerset _) h).of_map _,
    Quotient.inductionOn s fun l h => by
      simp only [quot_mk_to_coe, powerset_coe', coe_nodup]
      

Proof state:
α : Type u_1
s : Multiset α
l : List α
h : Nodup ⟦l⟧
⊢ List.Nodup (List.map ofList (sublists' l))

Next tactic:
refine' (nodup_sublists'.2 h).map_on _
@[simp]
theorem nodup_powerset {s : Multiset α} : Nodup (powerset s) ↔ Nodup s :=
  ⟨fun h => (nodup_of_le (map_single_le_powerset _) h).of_map _,
    Quotient.inductionOn s fun l h => by
      simp only [quot_mk_to_coe, powerset_coe', coe_nodup]
      refine' (nodup_sublists'.2 h).map_on _
      

Proof state:
α : Type u_1
s : Multiset α
l : List α
h : Nodup ⟦l⟧
⊢ ∀ x ∈ sublists' l, ∀ y ∈ sublists' l, ↑x = ↑y → x = y

Next tactic:
exact fun x sx y sy e =>
        (h.perm_iff_eq_of_sublist (mem_sublists'.1 sx) (mem_sublists'.1 sy)).1 (Quotient.exact e)
@[simp] lemma length_append : ∀ (as bs : String), (as ++ bs).length = as.length + bs.length
  | ⟨as⟩, ⟨bs⟩ => by
    

Proof state:
as bs : List Char
⊢ length ({ data := as } ++ { data := bs }) = length { data := as } + length { data := bs }

Next tactic:
rw [congr_append]
@[simp] lemma length_append : ∀ (as bs : String), (as ++ bs).length = as.length + bs.length
  | ⟨as⟩, ⟨bs⟩ => by
    rw [congr_append]
    

Proof state:
as bs : List Char
⊢ length { data := { data := as }.data ++ { data := bs }.data } = length { data := as } + length { data := bs }

Next tactic:
simp only [String.length]
@[simp] lemma length_append : ∀ (as bs : String), (as ++ bs).length = as.length + bs.length
  | ⟨as⟩, ⟨bs⟩ => by
    rw [congr_append]
    simp only [String.length]
    

Proof state:
as bs : List Char
⊢ List.length (as ++ bs) = List.length as + List.length bs

Next tactic:
exact List.length_append as bs
@[simp] lemma length_replicate (n : ℕ) (c : Char) : (replicate n c).length = n := by
  

Proof state:
n : ℕ
c : Char
⊢ length (replicate n c) = n

Next tactic:
simp only [String.length, String.replicate, List.length_replicate]
lemma length_eq_list_length (l : List Char) : (String.mk l).length = l.length := by
  

Proof state:
l : List Char
⊢ length { data := l } = List.length l

Next tactic:
simp only [String.length]
/-- The length of the String returned by `String.leftpad n a c` is equal
  to the larger of `n` and `s.length` -/
@[simp] lemma leftpad_length (n : ℕ) (c : Char) :
    ∀ (s : String), (leftpad n c s).length = max n s.length
  | ⟨s⟩ => by 

Proof state:
n : ℕ
c : Char
s : List Char
⊢ length (leftpad n c { data := s }) = max n (length { data := s })

Next tactic:
simp only [leftpad, String.length, List.leftpad_length]
lemma leftpad_prefix (n : ℕ) (c : Char) : ∀ s, IsPrefix (replicate (n - length s) c) (leftpad n c s)
  | ⟨l⟩ => by 

Proof state:
n : ℕ
c : Char
l : List Char
⊢ IsPrefix (replicate (n - length { data := l }) c) (leftpad n c { data := l })

Next tactic:
simp only [IsPrefix, replicate, leftpad, String.length, List.leftpad_prefix]
lemma leftpad_suffix (n : ℕ) (c : Char) : ∀ s, IsSuffix s (leftpad n c s)
  | ⟨l⟩ => by 

Proof state:
n : ℕ
c : Char
l : List Char
⊢ IsSuffix { data := l } (leftpad n c { data := l })

Next tactic:
simp only [IsSuffix, replicate, leftpad, String.length, List.leftpad_suffix]
instance toContinuousMapClass : ContinuousMapClass C(α, β) α β where
  coe := ContinuousMap.toFun
  coe_injective' f g h := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
f g : C(α, β)
h : f.toFun = g.toFun
⊢ f = g

Next tactic:
cases f
instance toContinuousMapClass : ContinuousMapClass C(α, β) α β where
  coe := ContinuousMap.toFun
  coe_injective' f g h := by cases f; 

Proof state:
case mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
g : C(α, β)
toFun✝ : α → β
continuous_toFun✝ : Continuous toFun✝
h : (mk toFun✝).toFun = g.toFun
⊢ mk toFun✝ = g

Next tactic:
cases g
instance toContinuousMapClass : ContinuousMapClass C(α, β) α β where
  coe := ContinuousMap.toFun
  coe_injective' f g h := by cases f; cases g; 

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
toFun✝¹ : α → β
continuous_toFun✝¹ : Continuous toFun✝¹
toFun✝ : α → β
continuous_toFun✝ : Continuous toFun✝
h : (mk toFun✝¹).toFun = (mk toFun✝).toFun
⊢ mk toFun✝¹ = mk toFun✝

Next tactic:
congr
theorem coe_injective : @Function.Injective C(α, β) (α → β) (↑) := fun f g h => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
f✝ g✝ f g : C(α, β)
h : ⇑f = ⇑g
⊢ f = g

Next tactic:
cases f
theorem coe_injective : @Function.Injective C(α, β) (α → β) (↑) := fun f g h => by
  cases f; 

Proof state:
case mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
f g✝ g : C(α, β)
toFun✝ : α → β
continuous_toFun✝ : Continuous toFun✝
h : ⇑(mk toFun✝) = ⇑g
⊢ mk toFun✝ = g

Next tactic:
cases g
theorem coe_injective : @Function.Injective C(α, β) (α → β) (↑) := fun f g h => by
  cases f; cases g; 

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
f g : C(α, β)
toFun✝¹ : α → β
continuous_toFun✝¹ : Continuous toFun✝¹
toFun✝ : α → β
continuous_toFun✝ : Continuous toFun✝
h : ⇑(mk toFun✝¹) = ⇑(mk toFun✝)
⊢ mk toFun✝¹ = mk toFun✝

Next tactic:
congr
/--
The continuous functions from `α` to `β` are the same as the plain functions when `α` is discrete.
-/
@[simps]
def equivFnOfDiscrete [DiscreteTopology α] : C(α, β) ≃ (α → β) :=
  ⟨fun f => f,
    fun f => ⟨f, continuous_of_discreteTopology⟩,
    fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : TopologicalSpace δ
f g : C(α, β)
inst✝ : DiscreteTopology α
x✝ : C(α, β)
⊢ (fun f => mk f) ((fun f => ⇑f) x✝) = x✝

Next tactic:
ext
/--
The continuous functions from `α` to `β` are the same as the plain functions when `α` is discrete.
-/
@[simps]
def equivFnOfDiscrete [DiscreteTopology α] : C(α, β) ≃ (α → β) :=
  ⟨fun f => f,
    fun f => ⟨f, continuous_of_discreteTopology⟩,
    fun _ => by ext; 

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : TopologicalSpace δ
f g : C(α, β)
inst✝ : DiscreteTopology α
x✝ : C(α, β)
a✝ : α
⊢ ((fun f => mk f) ((fun f => ⇑f) x✝)) a✝ = x✝ a✝

Next tactic:
rfl
/--
The continuous functions from `α` to `β` are the same as the plain functions when `α` is discrete.
-/
@[simps]
def equivFnOfDiscrete [DiscreteTopology α] : C(α, β) ≃ (α → β) :=
  ⟨fun f => f,
    fun f => ⟨f, continuous_of_discreteTopology⟩,
    fun _ => by ext; rfl,
    fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : TopologicalSpace δ
f g : C(α, β)
inst✝ : DiscreteTopology α
x✝ : α → β
⊢ (fun f => ⇑f) ((fun f => mk f) x✝) = x✝

Next tactic:
ext
/--
The continuous functions from `α` to `β` are the same as the plain functions when `α` is discrete.
-/
@[simps]
def equivFnOfDiscrete [DiscreteTopology α] : C(α, β) ≃ (α → β) :=
  ⟨fun f => f,
    fun f => ⟨f, continuous_of_discreteTopology⟩,
    fun _ => by ext; rfl,
    fun _ => by ext; 

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁴ : TopologicalSpace α
inst✝³ : TopologicalSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : TopologicalSpace δ
f g : C(α, β)
inst✝ : DiscreteTopology α
x✝¹ : α → β
x✝ : α
⊢ (fun f => ⇑f) ((fun f => mk f) x✝¹) x✝ = x✝¹ x✝

Next tactic:
rfl
@[simp]
theorem cancel_left {f : C(β, γ)} {g₁ g₂ : C(α, β)} (hf : Injective f) :
    f.comp g₁ = f.comp g₂ ↔ g₁ = g₂ :=
  ⟨fun h => ext fun a => hf <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : TopologicalSpace β
inst✝¹ : TopologicalSpace γ
inst✝ : TopologicalSpace δ
f✝ g : C(α, β)
f : C(β, γ)
g₁ g₂ : C(α, β)
hf : Injective ⇑f
h : comp f g₁ = comp f g₂
a : α
⊢ f (g₁ a) = f (g₂ a)

Next tactic:
rw [← comp_apply, h, comp_apply]
variable (A X) in
/--
Giving a continuous map out of a disjoint union is the same as giving a continuous map out of
each term. This is a version of `Equiv.piCurry` for continuous maps.
-/
@[simps]
def sigmaEquiv : (∀ i, C(X i, A)) ≃ C((Σ i, X i), A) where
  toFun := sigma
  invFun f i := f.comp (sigmaMk i)
  left_inv := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
f g : C(α, β)
I : Type u_5
A : Type u_6
X : I → Type u_7
inst✝¹ : TopologicalSpace A
inst✝ : (i : I) → TopologicalSpace (X i)
⊢ LeftInverse (fun f i => comp f (sigmaMk i)) sigma

Next tactic:
intro
variable (A X) in
/--
Giving a continuous map out of a disjoint union is the same as giving a continuous map out of
each term. This is a version of `Equiv.piCurry` for continuous maps.
-/
@[simps]
def sigmaEquiv : (∀ i, C(X i, A)) ≃ C((Σ i, X i), A) where
  toFun := sigma
  invFun f i := f.comp (sigmaMk i)
  left_inv := by intro; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
f g : C(α, β)
I : Type u_5
A : Type u_6
X : I → Type u_7
inst✝¹ : TopologicalSpace A
inst✝ : (i : I) → TopologicalSpace (X i)
x✝ : (i : I) → C(X i, A)
⊢ (fun f i => comp f (sigmaMk i)) (sigma x✝) = x✝

Next tactic:
ext
variable (A X) in
/--
Giving a continuous map out of a disjoint union is the same as giving a continuous map out of
each term. This is a version of `Equiv.piCurry` for continuous maps.
-/
@[simps]
def sigmaEquiv : (∀ i, C(X i, A)) ≃ C((Σ i, X i), A) where
  toFun := sigma
  invFun f i := f.comp (sigmaMk i)
  left_inv := by intro; ext; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
f g : C(α, β)
I : Type u_5
A : Type u_6
X : I → Type u_7
inst✝¹ : TopologicalSpace A
inst✝ : (i : I) → TopologicalSpace (X i)
x✝¹ : (i : I) → C(X i, A)
x✝ : I
a✝ : X x✝
⊢ ((fun f i => comp f (sigmaMk i)) (sigma x✝¹) x✝) a✝ = (x✝¹ x✝) a✝

Next tactic:
simp
variable (A X) in
/--
Giving a continuous map out of a disjoint union is the same as giving a continuous map out of
each term. This is a version of `Equiv.piCurry` for continuous maps.
-/
@[simps]
def sigmaEquiv : (∀ i, C(X i, A)) ≃ C((Σ i, X i), A) where
  toFun := sigma
  invFun f i := f.comp (sigmaMk i)
  left_inv := by intro; ext; simp
  right_inv := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
f g : C(α, β)
I : Type u_5
A : Type u_6
X : I → Type u_7
inst✝¹ : TopologicalSpace A
inst✝ : (i : I) → TopologicalSpace (X i)
⊢ Function.RightInverse (fun f i => comp f (sigmaMk i)) sigma

Next tactic:
intro
variable (A X) in
/--
Giving a continuous map out of a disjoint union is the same as giving a continuous map out of
each term. This is a version of `Equiv.piCurry` for continuous maps.
-/
@[simps]
def sigmaEquiv : (∀ i, C(X i, A)) ≃ C((Σ i, X i), A) where
  toFun := sigma
  invFun f i := f.comp (sigmaMk i)
  left_inv := by intro; ext; simp
  right_inv := by intro; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
f g : C(α, β)
I : Type u_5
A : Type u_6
X : I → Type u_7
inst✝¹ : TopologicalSpace A
inst✝ : (i : I) → TopologicalSpace (X i)
x✝ : C((i : I) × X i, A)
⊢ sigma ((fun f i => comp f (sigmaMk i)) x✝) = x✝

Next tactic:
ext
variable (A X) in
/--
Giving a continuous map out of a disjoint union is the same as giving a continuous map out of
each term. This is a version of `Equiv.piCurry` for continuous maps.
-/
@[simps]
def sigmaEquiv : (∀ i, C(X i, A)) ≃ C((Σ i, X i), A) where
  toFun := sigma
  invFun f i := f.comp (sigmaMk i)
  left_inv := by intro; ext; simp
  right_inv := by intro; ext; 

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝⁵ : TopologicalSpace α
inst✝⁴ : TopologicalSpace β
inst✝³ : TopologicalSpace γ
inst✝² : TopologicalSpace δ
f g : C(α, β)
I : Type u_5
A : Type u_6
X : I → Type u_7
inst✝¹ : TopologicalSpace A
inst✝ : (i : I) → TopologicalSpace (X i)
x✝ : C((i : I) × X i, A)
a✝ : (i : I) × X i
⊢ (sigma ((fun f i => comp f (sigmaMk i)) x✝)) a✝ = x✝ a✝

Next tactic:
simp