From 53a81b5c68cd85a71f29bdc40f11abc44de8eb3e Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 17:53:11 +0100 Subject: [PATCH 01/35] First pass at new definitions --- .../BigOperators/Group/Finset/Basic.lean | 4 +- Mathlib/Algebra/FiniteSupport/Basic.lean | 2 +- Mathlib/Algebra/Ring/Prod.lean | 4 +- .../Analysis/SpecialFunctions/Pow/Deriv.lean | 6 +- Mathlib/Data/Finset/Prod.lean | 5 +- Mathlib/Data/Int/Cast/Prod.lean | 3 +- Mathlib/Data/Nat/Cast/Prod.lean | 3 +- Mathlib/Data/Prod/Init.lean | 87 +++++++++++++++++++ Mathlib/Data/Set/Prod.lean | 21 ++--- Mathlib/Data/Sum/Init.lean | 61 +++++++++++++ .../Manifold/ContMDiff/Constructions.lean | 16 ++-- Mathlib/Geometry/Manifold/ContMDiffMap.lean | 2 +- Mathlib/MeasureTheory/Function/AEEqFun.lean | 6 +- .../Function/L1Space/Integrable.lean | 2 +- .../AEStronglyMeasurable.lean | 2 +- .../Function/StronglyMeasurable/Basic.lean | 2 +- .../MeasureTheory/Measure/AEMeasurable.lean | 2 +- Mathlib/NumberTheory/Height/Basic.lean | 2 +- Mathlib/Order/Filter/Basic.lean | 2 +- Mathlib/Order/Filter/Prod.lean | 2 +- Mathlib/Order/Hom/Basic.lean | 2 +- Mathlib/Order/Monotone/Defs.lean | 4 +- Mathlib/Order/ScottContinuity.lean | 4 +- Mathlib/Probability/Kernel/Basic.lean | 2 +- .../Kernel/Composition/MeasureCompProd.lean | 6 +- .../Probability/Kernel/Composition/Prod.lean | 2 +- .../Topology/Algebra/ProperAction/Basic.lean | 4 +- Mathlib/Topology/Compactness/Compact.lean | 2 +- Mathlib/Topology/Constructions/SumProd.lean | 6 +- Mathlib/Topology/ContinuousOn.lean | 4 +- Mathlib/Topology/EMetricSpace/Lipschitz.lean | 6 +- Mathlib/Topology/UniformSpace/Basic.lean | 4 +- .../UniformSpace/UniformConvergence.lean | 8 +- MathlibTest/Continuity.lean | 2 +- MathlibTest/fun_prop.lean | 2 +- 35 files changed, 221 insertions(+), 71 deletions(-) create mode 100644 Mathlib/Data/Prod/Init.lean create mode 100644 Mathlib/Data/Sum/Init.lean diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index 28bdc737819ec3..9d2b47e2569bb3 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -283,8 +283,8 @@ end bij @[to_additive (attr := simp)] lemma prod_diag (s : Finset ι) (f : ι × ι → M) : - ∏ i ∈ s.diag, f i = ∏ i ∈ s, f (i, i) := by - simp [diag] + ∏ i ∈ s.diag, f i = ∏ i ∈ s, (f ∘ Prod.diag) i := by + simp [diag, Prod.diag_apply] @[to_additive] theorem prod_image' [DecidableEq ι] {s : Finset κ} {g : κ → ι} (h : κ → M) diff --git a/Mathlib/Algebra/FiniteSupport/Basic.lean b/Mathlib/Algebra/FiniteSupport/Basic.lean index 66b51c3f410ed6..d810f395f483d1 100644 --- a/Mathlib/Algebra/FiniteSupport/Basic.lean +++ b/Mathlib/Algebra/FiniteSupport/Basic.lean @@ -55,7 +55,7 @@ lemma HasFiniteMulSupport.snd {M' : Type*} [One M'] {f : α → M × M'} (hf : H @[to_additive (attr := fun_prop)] lemma HasFiniteMulSupport.prodMk {M' : Type*} [One M'] {f : α → M} {g : α → M'} (hf : HasFiniteMulSupport f) (hg : HasFiniteMulSupport g) : - HasFiniteMulSupport fun a ↦ (f a, g a) := by + HasFiniteMulSupport (Prod.pair f g) := by simp only [HasFiniteMulSupport] at hf hg ⊢ rw [mulSupport_prodMk f g] exact hf.union hg diff --git a/Mathlib/Algebra/Ring/Prod.lean b/Mathlib/Algebra/Ring/Prod.lean index 94357bd286e99c..33289f939e02ab 100644 --- a/Mathlib/Algebra/Ring/Prod.lean +++ b/Mathlib/Algebra/Ring/Prod.lean @@ -132,7 +132,7 @@ variable [NonUnitalNonAssocSemiring T] (f : R →ₙ+* S) (g : R →ₙ+* T) `f.prod g : R →ₙ+* S × T` given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →ₙ+* S) (g : R →ₙ+* T) : R →ₙ+* S × T := { MulHom.prod (f : MulHom R S) (g : MulHom R T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := fun x => (f x, g x) } + toFun := Prod.pair f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := @@ -208,7 +208,7 @@ variable [NonAssocSemiring T] (f : R →+* S) (g : R →+* T) given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →+* S) (g : R →+* T) : R →+* S × T := { MonoidHom.prod (f : R →* S) (g : R →* T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := fun x => (f x, g x) } + toFun := Prod.pair f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean index 9aa96ec2855caf..0f9967c2ea2e97 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean @@ -85,7 +85,7 @@ theorem HasStrictFDerivAt.const_cpow (hf : HasStrictFDerivAt f f' x) (h0 : c ≠ theorem HasFDerivAt.cpow (hf : HasFDerivAt f f' x) (hg : HasFDerivAt g g' x) (h0 : f x ∈ slitPlane) : HasFDerivAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') x := by - convert (@Complex.hasFDerivAt_cpow ((fun x => (f x, g x)) x) h0).comp x (hf.prodMk hg) + convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp x (hf.prodMk hg) theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x ≠ 0) : HasFDerivAt (fun x => c ^ f x) ((c ^ f x * Complex.log c) • f') x := @@ -94,7 +94,7 @@ theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x theorem HasFDerivWithinAt.cpow (hf : HasFDerivWithinAt f f' s x) (hg : HasFDerivWithinAt g g' s x) (h0 : f x ∈ slitPlane) : HasFDerivWithinAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') s x := by - convert (@Complex.hasFDerivAt_cpow ((fun x => (f x, g x)) x) h0).comp_hasFDerivWithinAt x + convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp_hasFDerivWithinAt x (hf.prodMk hg) theorem HasFDerivWithinAt.const_cpow (hf : HasFDerivWithinAt f f' s x) (h0 : c ≠ 0 ∨ f x ≠ 0) : @@ -387,7 +387,7 @@ theorem differentiableAt_rpow_of_ne (p : ℝ × ℝ) (hp : p.1 ≠ 0) : theorem _root_.HasStrictDerivAt.rpow {f g : ℝ → ℝ} {f' g' : ℝ} (hf : HasStrictDerivAt f f' x) (hg : HasStrictDerivAt g g' x) (h : 0 < f x) : HasStrictDerivAt (fun x => f x ^ g x) (f' * g x * f x ^ (g x - 1) + g' * f x ^ g x * Real.log (f x)) x := by - convert (hasStrictFDerivAt_rpow_of_pos ((fun x => (f x, g x)) x) h).comp_hasStrictDerivAt x + convert (hasStrictFDerivAt_rpow_of_pos ((Prod.pair f g) x) h).comp_hasStrictDerivAt x (hf.prodMk hg) using 1 simp [mul_assoc, mul_comm] diff --git a/Mathlib/Data/Finset/Prod.lean b/Mathlib/Data/Finset/Prod.lean index 9161ff8ee434b8..9c6c97b8b5671b 100644 --- a/Mathlib/Data/Finset/Prod.lean +++ b/Mathlib/Data/Finset/Prod.lean @@ -240,8 +240,7 @@ variable (s t : Finset α) /-- Given a finite set `s`, the diagonal, `s.diag` is the set of pairs of the form `(a, a)` for `a ∈ s`. -/ -def diag : Finset (α × α) := - s.map ⟨fun a ↦ (a, a), by simp [Function.Injective]⟩ +def diag : Finset (α × α) := s.map ⟨Prod.diag, Prod.injective_diag⟩ -- TODO: define `Multiset.offDiag`, provide basic API, use it here /-- Given a finite set `s`, the off-diagonal, `s.offDiag` is the set of pairs `(a, b)` with `a ≠ b` @@ -255,7 +254,7 @@ variable {s} {x : α × α} @[simp, grind =] theorem mem_diag : x ∈ s.diag ↔ x.1 ∈ s ∧ x.1 = x.2 := by - aesop (add simp diag) + aesop (add simp [diag, Prod.ext_iff]) @[simp, grind =] theorem mem_offDiag : x ∈ s.offDiag ↔ x.1 ∈ s ∧ x.2 ∈ s ∧ x.1 ≠ x.2 := by diff --git a/Mathlib/Data/Int/Cast/Prod.lean b/Mathlib/Data/Int/Cast/Prod.lean index a3473f657d8617..f92d160a1d13e3 100644 --- a/Mathlib/Data/Int/Cast/Prod.lean +++ b/Mathlib/Data/Int/Cast/Prod.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.Int.Cast.Basic public import Mathlib.Data.Nat.Cast.Prod +public import Mathlib.Data.Prod.Init /-! # The product of two `AddGroupWithOne`s. @@ -21,7 +22,7 @@ variable {α β : Type*} [AddGroupWithOne α] [AddGroupWithOne β] instance : AddGroupWithOne (α × β) := { Prod.instAddMonoidWithOne, Prod.instAddGroup with - intCast := fun n => (n, n) + intCast := Prod.pair IntCast.intCast IntCast.intCast intCast_ofNat := fun _ => by ext <;> simp intCast_negSucc := fun _ => by ext <;> simp } diff --git a/Mathlib/Data/Nat/Cast/Prod.lean b/Mathlib/Data/Nat/Cast/Prod.lean index 8850134e8a6450..78627dbbdbe413 100644 --- a/Mathlib/Data/Nat/Cast/Prod.lean +++ b/Mathlib/Data/Nat/Cast/Prod.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Group.Prod public import Mathlib.Data.Nat.Cast.Defs +public import Mathlib.Data.Prod.Init /-! # The product of two `AddMonoidWithOne`s. @@ -24,7 +25,7 @@ variable [AddMonoidWithOne α] [AddMonoidWithOne β] instance instAddMonoidWithOne : AddMonoidWithOne (α × β) := { Prod.instAddMonoid, @Prod.instOne α β _ _ with - natCast := fun n => (n, n) + natCast := Prod.pair NatCast.natCast NatCast.natCast natCast_zero := congr_arg₂ Prod.mk Nat.cast_zero Nat.cast_zero natCast_succ := fun _ => congr_arg₂ Prod.mk (Nat.cast_succ _) (Nat.cast_succ _) } diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean new file mode 100644 index 00000000000000..f9c35110523ef7 --- /dev/null +++ b/Mathlib/Data/Prod/Init.lean @@ -0,0 +1,87 @@ +/- +Copyright (c) 2026 Wrenna Robson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Wrena Robson +-/ +module + +/-! + +This file should not depend on anything defined in Mathlib (except for notation), so that it can be +upstreamed to Batteries or the Lean standard library easily. + +-/ + +@[expose] public section + +namespace Prod + +universe u₁ u₂ u₃ u₄ u₅ + +variable {α : Type u₁} {β : Type u₂} {γ : Sort u₃} {δ : Type u₄} {ε : Type u₅} + +/-- This is the pairing operation on functions, dual to `Sum.elim`. -/ +@[expose] protected def pair (f : γ → α) (g : γ → β) : γ → α × β := fun a ↦ (f a, g a) + +section + +variable (f : γ → α) (g : γ → β) + +@[grind =] theorem pair_apply (c : γ) : Prod.pair f g c = (f c, g c) := rfl + +@[simp] theorem fst_pair {c} : (Prod.pair f g c).fst = f c := rfl +@[simp] theorem snd_pair {c} : (Prod.pair f g c).snd = g c := rfl + +@[simp] theorem fst_comp_pair : fst ∘ Prod.pair f g = f := rfl +@[simp] theorem snd_comp_pair : snd ∘ Prod.pair f g = g := rfl +@[simp] theorem pair_fst_snd : @Prod.pair α β _ fst snd = id := rfl + +theorem pair_comp {δ} {h : δ → γ} : Prod.pair f g ∘ h = Prod.pair (f ∘ h) (g ∘ h) := rfl + +@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : Prod.pair (fst ∘ f) (snd ∘ f) = f := rfl + +theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.pair f g = Prod.pair f' g' ↔ f = f' ∧ g = g' := by + simp [funext_iff, Prod.ext_iff, forall_and] + +end + +section + +/- We can define `Prod.map` in terms of `Prod.pair`. -/ +theorem map_eq_pair {f : α → β} {g : δ → ε} : Prod.map f g = Prod.pair (f ∘ fst) (g ∘ snd) := rfl + +@[grind _=_] +theorem map_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : + Prod.map f h (Prod.pair g k c) = Prod.pair (f ∘ g) (h ∘ k) c := rfl + +theorem map_comp_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : + Prod.map f h ∘ Prod.pair g k = Prod.pair (f ∘ g) (h ∘ k) := rfl + +end + +/-- The diagonal map into Prod. -/ +@[expose] protected def diag : α → α × α := Prod.pair id id + +section + +variable {a b : α} + +@[grind =] theorem diag_apply : Prod.diag a = (a, a) := rfl + +@[simp, grind =] theorem fst_diag : (Prod.diag a).1 = a := rfl +@[simp, grind =] theorem snd_diag : (Prod.diag a).2 = a := rfl + +@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Prod.diag a) = Prod.pair f g a := rfl + +theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = Prod.pair f g := rfl + +theorem injective_diag : Function.Injective (Prod.diag (α := α)) := fun _ _ => congrArg fst + +theorem exists_diag_apply_iff (p : α × α) : (∃ a, p = Prod.diag a) ↔ p.1 = p.2 := by + simp [Prod.ext_iff, eq_comm] + +@[simp] theorem diag_eq_iff : Prod.diag a = Prod.diag b ↔ a = b := injective_diag.eq_iff + +end + +end Prod diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 161b9cca4c1660..496866096a45f5 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -8,6 +8,7 @@ module public import Mathlib.Data.Set.Image public import Mathlib.Data.SProd public import Mathlib.Data.Sum.Basic +public import Mathlib.Data.Prod.Init /-! # Sets in product and pi types @@ -179,7 +180,7 @@ theorem preimage_prod_map_prod (f : α → β) (g : γ → δ) (s : Set β) (t : rfl theorem mk_preimage_prod (f : γ → α) (g : γ → β) : - (fun x => (f x, g x)) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := + (Prod.pair f g) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := rfl @[simp] @@ -238,7 +239,7 @@ theorem prod_univ_range_eq {m₂ : β → δ} : ext <| by simp [range] theorem range_pair_subset (f : α → β) (g : α → γ) : - (range fun x => (f x, g x)) ⊆ range f ×ˢ range g := by grind + (range Prod.pair f g) ⊆ range f ×ˢ range g := by grind theorem Nonempty.prod : s.Nonempty → t.Nonempty → (s ×ˢ t).Nonempty := fun ⟨x, hx⟩ ⟨y, hy⟩ => ⟨(x, y), ⟨hx, hy⟩⟩ @@ -259,7 +260,7 @@ theorem prod_sub_preimage_iff {W : Set γ} {f : α × β → γ} : s ×ˢ t ⊆ f ⁻¹' W ↔ ∀ a b, a ∈ s → b ∈ t → f (a, b) ∈ W := by simp [subset_def] theorem image_prodMk_subset_prod {f : α → β} {g : α → γ} {s : Set α} : - (fun x => (f x, g x)) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind + (Prod.pair f g) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind theorem image_prodMk_subset_prod_left (hb : b ∈ t) : (fun a => (a, b)) '' s ⊆ s ×ˢ t := by grind @@ -408,7 +409,7 @@ end Prod /-! ### Diagonal In this section we prove some lemmas about the diagonal set `{p | p.1 = p.2}` and the diagonal map -`fun x ↦ (x, x)`. +`Prod.diag`. -/ @@ -428,25 +429,25 @@ theorem preimage_coe_coe_diagonal (s : Set α) : simp [Set.diagonal] @[simp] -theorem range_diag : (range fun x => (x, x)) = diagonal α := by +theorem range_diag : range Prod.diag = diagonal α := by ext ⟨x, y⟩ - simp [diagonal, eq_comm] + simp [Prod.ext_iff] theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, (x, x) ∈ s := by - rw [← range_diag, range_subset_iff] + simp_rw [← range_diag, range_subset_iff, Prod.diag_apply] @[simp] theorem prod_subset_compl_diagonal_iff_disjoint : s ×ˢ t ⊆ (diagonal α)ᶜ ↔ Disjoint s t := prod_subset_iff.trans disjoint_iff_forall_ne.symm @[simp] -theorem diag_preimage_prod (s t : Set α) : (fun x => (x, x)) ⁻¹' s ×ˢ t = s ∩ t := +theorem diag_preimage_prod (s t : Set α) : Prod.diag ⁻¹' s ×ˢ t = s ∩ t := rfl -theorem diag_preimage_prod_self (s : Set α) : (fun x => (x, x)) ⁻¹' s ×ˢ s = s := +theorem diag_preimage_prod_self (s : Set α) : Prod.diag ⁻¹' s ×ˢ s = s := inter_self s -theorem diag_image (s : Set α) : (fun x => (x, x)) '' s = diagonal α ∩ s ×ˢ s := by +theorem diag_image (s : Set α) : Prod.diag '' s = diagonal α ∩ s ×ˢ s := by rw [← range_diag, ← image_preimage_eq_range_inter, diag_preimage_prod_self] theorem diagonal_eq_univ_iff : diagonal α = univ ↔ Subsingleton α := by diff --git a/Mathlib/Data/Sum/Init.lean b/Mathlib/Data/Sum/Init.lean new file mode 100644 index 00000000000000..37245c820e5f4e --- /dev/null +++ b/Mathlib/Data/Sum/Init.lean @@ -0,0 +1,61 @@ +/- +Copyright (c) 2026 Wrenna Robson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Wrena Robson +-/ +module + +/-! + +This file should not depend on anything defined in Mathlib (except for notation), so that it can be +upstreamed to Batteries or the Lean standard library easily. + +-/ + +@[expose] public section + +namespace Sum + +universe u₁ u₂ u₃ u₄ + +variable {α : Type u₁} {β : Type u₂} {γ : Sort u₃} {δ : Type u₄} + +theorem elim_apply_of_isLeft {f : α → γ} {g : β → γ} {x} (h : x.isLeft) : + Sum.elim f g x = f (x.getLeft h) := by grind + +theorem elim_apply_of_isRight {f : α → γ} {g : β → γ} {x} (h : x.isRight) : + Sum.elim f g x = g (x.getRight h) := by grind + +theorem elim_apply {f : α → γ} {g : β → γ} {x} : Sum.elim f g x = + if h : x.isLeft then f (x.getLeft h) else g (x.getRight (by grind)) := by cases x <;> simp + +@[expose] protected def get : α ⊕ α → α := Sum.elim id id + +section + +variable {x y : α ⊕ α} {a : α} + +@[simp, grind =] theorem get_inl : Sum.get (inl a) = a := rfl +@[simp, grind =] theorem get_inr : Sum.get (inr a) = a := rfl + +theorem get_apply_of_isLeft (h : x.isLeft) : + x.get = x.getLeft h := by grind + +theorem get_apply_of_isRight (h : x.isRight) : + x.get = x.getRight h := by grind + +theorem get_apply : Sum.get x = if h : x.isLeft then x.getLeft h else x.getRight (by grind) := by grind + +@[simp, grind =] theorem get_map {f : β → α} {g : δ → α} {y : β ⊕ δ} : + (y.map f g).get = y.elim f g := by cases y <;> rfl + +theorem map_comp_diag {f : β → α} {g : δ → α} : Sum.get ∘ Sum.map f g = Sum.elim f g := + funext fun _ => get_map + +theorem surjective_diag : Function.Surjective (Sum.get (α := α)) := fun a => ⟨Sum.inl a, rfl⟩ + +@[simp, grind =] theorem get_eq_iff : x.get = y.get ↔ x = y ∨ x = y.swap := by grind + +end + +end Sum diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean index fe13581917f544..cc9dcb1dcf2060 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean @@ -55,39 +55,39 @@ section ProdMk theorem ContMDiffWithinAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffWithinAt I I' n f s x) (hg : ContMDiffWithinAt I J' n g s x) : - ContMDiffWithinAt I (I'.prod J') n (fun x => (f x, g x)) s x := by + ContMDiffWithinAt I (I'.prod J') n (Prod.pair f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem ContMDiffWithinAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffWithinAt I 𝓘(𝕜, E') n f s x) (hg : ContMDiffWithinAt I 𝓘(𝕜, F') n g s x) : - ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (fun x => (f x, g x)) s x := by + ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ nonrec theorem ContMDiffAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffAt I I' n f x) - (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (fun x => (f x, g x)) x := + (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (Prod.pair f g) x := hf.prodMk hg nonrec theorem ContMDiffAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffAt I 𝓘(𝕜, E') n f x) (hg : ContMDiffAt I 𝓘(𝕜, F') n g x) : - ContMDiffAt I 𝓘(𝕜, E' × F') n (fun x => (f x, g x)) x := + ContMDiffAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) x := hf.prodMk_space hg theorem ContMDiffOn.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffOn I I' n f s) - (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (fun x => (f x, g x)) s := + (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (Prod.pair f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem ContMDiffOn.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffOn I 𝓘(𝕜, E') n f s) - (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (fun x => (f x, g x)) s := + (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (Prod.pair f g) s := fun x hx => (hf x hx).prodMk_space (hg x hx) nonrec theorem ContMDiff.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiff I I' n f) - (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n fun x => (f x, g x) := fun x => + (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n Prod.pair f g := fun x => (hf x).prodMk (hg x) theorem ContMDiff.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiff I 𝓘(𝕜, E') n f) - (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n fun x => (f x, g x) := fun x => + (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n Prod.pair f g := fun x => (hf x).prodMk_space (hg x) end ProdMk diff --git a/Mathlib/Geometry/Manifold/ContMDiffMap.lean b/Mathlib/Geometry/Manifold/ContMDiffMap.lean index e0fce000c3f725..5ed3ded179099c 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMap.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMap.lean @@ -106,7 +106,7 @@ def snd : C^n⟮I.prod I', M × M'; I', M'⟯ := /-- Given two `C^n` maps `f` and `g`, this is the `C^n` map `x ↦ (f x, g x)`. -/ def prodMk (f : C^n⟮J, N; I, M⟯) (g : C^n⟮J, N; I', M'⟯) : C^n⟮J, N; I.prod I', M × M'⟯ := - ⟨fun x => (f x, g x), f.2.prodMk g.2⟩ + ⟨Prod.pair f g, f.2.prodMk g.2⟩ end ContMDiffMap diff --git a/Mathlib/MeasureTheory/Function/AEEqFun.lean b/Mathlib/MeasureTheory/Function/AEEqFun.lean index 30e7591ffabeb8..6241ed016179f5 100644 --- a/Mathlib/MeasureTheory/Function/AEEqFun.lean +++ b/Mathlib/MeasureTheory/Function/AEEqFun.lean @@ -397,15 +397,15 @@ def pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : α →ₘ[μ] β × γ @[simp] theorem pair_mk_mk (f : α → β) (hf) (g : α → γ) (hg) : - (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (fun x => (f x, g x)) (hf.prodMk hg) := + (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (Prod.pair f g) (hf.prodMk hg) := rfl theorem pair_eq_mk (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g = - mk (fun x => (f x, g x)) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by + mk (Prod.pair f g) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by simp only [← pair_mk_mk, mk_coeFn, f.aestronglyMeasurable, g.aestronglyMeasurable] -theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] fun x => (f x, g x) := by +theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] Prod.pair f g := by rw [pair_eq_mk] apply coeFn_mk diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 77cca407c40a70..5c237bb54bdaf9 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -640,7 +640,7 @@ lemma integrable_of_le_of_le {f g₁ g₂ : α → ℝ} (hf : AEStronglyMeasurab -- TODO: generalising this to enorms requires defining a product instance for enormed monoids first @[fun_prop] theorem Integrable.prodMk {f : α → β} {g : α → γ} (hf : Integrable f μ) (hg : Integrable g μ) : - Integrable (fun x => (f x, g x)) μ := + Integrable (Prod.pair f g) μ := ⟨by fun_prop, (hf.norm.add' hg.norm).mono <| Eventually.of_forall fun x => diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index ac19e8f1167772..88cc6e2a8b4f5a 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -229,7 +229,7 @@ protected theorem snd {f : α → β × γ} (hf : AEStronglyMeasurable[m] f μ) @[fun_prop] protected theorem prodMk {f : α → β} {g : α → γ} (hf : AEStronglyMeasurable[m] f μ) - (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (fun x => (f x, g x)) μ := + (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (Prod.pair f g) μ := ⟨fun x => (hf.mk f x, hg.mk g x), hf.stronglyMeasurable_mk.prodMk hg.stronglyMeasurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 3fb9a2f92a404a..af077ea96e0b55 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -352,7 +352,7 @@ protected theorem snd {m : MeasurableSpace α} [TopologicalSpace β] [Topologica @[fun_prop] protected theorem prodMk {m : MeasurableSpace α} [TopologicalSpace β] [TopologicalSpace γ] {f : α → β} {g : α → γ} (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : - StronglyMeasurable fun x => (f x, g x) := by + StronglyMeasurable Prod.pair f g := by refine ⟨fun n => SimpleFunc.pair (hf.approx n) (hg.approx n), fun x => ?_⟩ rw [nhds_prod_eq] exact Tendsto.prodMk (hf.tendsto_approx x) (hg.tendsto_approx x) diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index caf6b54410060a..834a6479a1d262 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -190,7 +190,7 @@ protected theorem snd {f : α → β × γ} (hf : AEMeasurable f μ) : @[fun_prop] theorem prodMk {f : α → β} {g : α → γ} (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (fun x => (f x, g x)) μ := + AEMeasurable (Prod.pair f g) μ := ⟨fun a => (hf.mk f a, hg.mk g a), hf.measurable_mk.prodMk hg.measurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/NumberTheory/Height/Basic.lean b/Mathlib/NumberTheory/Height/Basic.lean index 5366554e2b265f..bacf7ed94ebcc6 100644 --- a/Mathlib/NumberTheory/Height/Basic.lean +++ b/Mathlib/NumberTheory/Height/Basic.lean @@ -755,7 +755,7 @@ lemma mulHeight_mul_le (x y : ι → K) : mulHeight (x * y) ≤ mulHeight x * mu rcases eq_or_ne y 0 with rfl | hy · simpa using one_le_mulHeight x rw [← mulHeight_fun_mul_eq hx hy, - show x * y = (fun a ↦ x a.1 * y a.2) ∘ fun i ↦ (i, i) by ext1; simp] + show x * y = (fun a ↦ x a.1 * y a.2) ∘ Prod.diag by ext1; simp] exact mulHeight_comp_le .. open Real in diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 4c785e2440a714..a0e486e162de51 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -976,7 +976,7 @@ instance {l : Filter α} : trans := EventuallyEq.trans theorem EventuallyEq.prodMk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') : - (fun x => (f x, g x)) =ᶠ[l] fun x => (f' x, g' x) := + (Prod.pair f g) =ᶠ[l] fun x => (f' x, g' x) := hf.mp <| hg.mono <| by intros diff --git a/Mathlib/Order/Filter/Prod.lean b/Mathlib/Order/Filter/Prod.lean index 7b62056a431787..1bc02e4de462dd 100644 --- a/Mathlib/Order/Filter/Prod.lean +++ b/Mathlib/Order/Filter/Prod.lean @@ -202,7 +202,7 @@ theorem Eventually.diag_of_prod_right {f : Filter α} {g : Filter γ} {p : α × obtain ⟨t, ht, s, hs, hst⟩ := eventually_prod_iff.1 h exact (ht.prod_mk hs.diag_of_prod).mono fun x hx => by simp only [hst hx.1 hx.2] -theorem tendsto_diag : Tendsto (fun i => (i, i)) f (f ×ˢ f) := +theorem tendsto_diag : Tendsto Prod.diag f (f ×ˢ f) := tendsto_iff_eventually.mpr fun _ hpr => hpr.diag_of_prod theorem prod_iInf_left [Nonempty ι] {f : ι → Filter α} {g : Filter β} : diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 203d35fd18e021..5b3e4f752e0845 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -369,7 +369,7 @@ theorem comp_const (γ : Type*) [Preorder γ] (f : α →o β) (c : α) : `OrderHom`. -/ @[simps] protected def prod (f : α →o β) (g : α →o γ) : α →o β × γ := - ⟨fun x => (f x, g x), fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ + ⟨Prod.pair f g, fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ @[mono, to_dual self] theorem prod_mono {f₁ f₂ : α →o β} (hf : f₁ ≤ f₂) {g₁ g₂ : α →o γ} (hg : g₁ ≤ g₂) : diff --git a/Mathlib/Order/Monotone/Defs.lean b/Mathlib/Order/Monotone/Defs.lean index 76e1afbe8215dc..09d1c7520dbb4d 100644 --- a/Mathlib/Order/Monotone/Defs.lean +++ b/Mathlib/Order/Monotone/Defs.lean @@ -507,11 +507,11 @@ theorem monotone_fst : Monotone (@Prod.fst α β) := fun _ _ ↦ And.left theorem monotone_snd : Monotone (@Prod.snd α β) := fun _ _ ↦ And.right theorem monotone_prodMk_iff {f : γ → α} {g : γ → β} : - Monotone (fun x => (f x, g x)) ↔ Monotone f ∧ Monotone g := by + Monotone (Prod.pair f g) ↔ Monotone f ∧ Monotone g := by simp_rw [Monotone, Prod.mk_le_mk, forall_and] theorem Monotone.prodMk {f : γ → α} {g : γ → β} (hf : Monotone f) (hg : Monotone g) : - Monotone (fun x => (f x, g x)) := + Monotone (Prod.pair f g) := monotone_prodMk_iff.2 ⟨hf, hg⟩ theorem Monotone.prodMap (hf : Monotone f) (hg : Monotone g) : Monotone (Prod.map f g) := diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index 0f1b1eebde29ff..01702a3bce853e 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -106,7 +106,7 @@ theorem ScottContinuousOn.image_comp {g : β → γ} @[fun_prop] lemma ScottContinuousOn.prodMk {g : α → γ} (hD : ∀ a b : α, a ≤ b → {a, b} ∈ D) (hf : ScottContinuousOn D f) (hg : ScottContinuousOn D g) : - ScottContinuousOn D fun x => (f x, g x) := fun d hd₁ hd₂ hd₃ a hda => by + ScottContinuousOn D Prod.pair f g := fun d hd₁ hd₂ hd₃ a hda => by rw [IsLUB, IsLeast, upperBounds] constructor · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, @@ -172,7 +172,7 @@ lemma ScottContinuous.comp {g : β → γ} @[fun_prop] lemma ScottContinuous.prodMk {g : α → γ} (hf : ScottContinuous f) (hg : ScottContinuous g) : - ScottContinuous fun x => (f x, g x) := by + ScottContinuous Prod.pair f g := by rw [← scottContinuousOn_univ] at ⊢ hf hg exact ScottContinuousOn.prodMk (by grind) hf hg diff --git a/Mathlib/Probability/Kernel/Basic.lean b/Mathlib/Probability/Kernel/Basic.lean index b1098ee54922a5..e2b62d86cc64eb 100644 --- a/Mathlib/Probability/Kernel/Basic.lean +++ b/Mathlib/Probability/Kernel/Basic.lean @@ -130,7 +130,7 @@ section Copy /-- The deterministic kernel that maps `x : α` to the Dirac measure at `(x, x) : α × α`. -/ noncomputable def copy (α : Type*) [MeasurableSpace α] : Kernel α (α × α) := - Kernel.deterministic (fun x ↦ (x, x)) (measurable_id.prod measurable_id) + Kernel.deterministic Prod.diag (measurable_id.prod measurable_id) instance : IsMarkovKernel (copy α) := by rw [copy]; infer_instance diff --git a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean index cd7d039fbe6cc8..9644d378367039 100644 --- a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean @@ -99,14 +99,14 @@ lemma _root_.ProbabilityTheory.Kernel.compProd_apply_eq_compProd_sectR {γ : Typ ext s hs simp_rw [Kernel.compProd_apply hs, compProd_apply hs, Kernel.sectR_apply] -lemma compProd_id [SFinite μ] : μ ⊗ₘ Kernel.id = μ.map (fun x ↦ (x, x)) := by +lemma compProd_id [SFinite μ] : μ ⊗ₘ Kernel.id = μ.map Prod.diag := by ext s hs rw [compProd_apply hs, map_apply (measurable_id.prod measurable_id) hs] have h_meas a : MeasurableSet (Prod.mk a ⁻¹' s) := measurable_prodMk_left hs simp_rw [Kernel.id_apply, dirac_apply' _ (h_meas _)] calc ∫⁻ a, (Prod.mk a ⁻¹' s).indicator 1 a ∂μ - _ = ∫⁻ a, ((fun x ↦ (x, x)) ⁻¹' s).indicator 1 a ∂μ := rfl - _ = μ ((fun x ↦ (x, x)) ⁻¹' s) := by + _ = ∫⁻ a, (Prod.diag ⁻¹' s).indicator 1 a ∂μ := rfl + _ = μ (Prod.diag ⁻¹' s) := by rw [lintegral_indicator_one] exact (measurable_id.prod measurable_id) hs diff --git a/Mathlib/Probability/Kernel/Composition/Prod.lean b/Mathlib/Probability/Kernel/Composition/Prod.lean index 4c2ca33414e800..9d73c928a09356 100644 --- a/Mathlib/Probability/Kernel/Composition/Prod.lean +++ b/Mathlib/Probability/Kernel/Composition/Prod.lean @@ -216,7 +216,7 @@ lemma swap_prod {κ : Kernel α β} [IsSFiniteKernel κ] {η : Kernel α γ} [Is lemma deterministic_prod_deterministic {f : α → β} {g : α → γ} (hf : Measurable f) (hg : Measurable g) : deterministic f hf ×ₖ deterministic g hg - = deterministic (fun a ↦ (f a, g a)) (hf.prodMk hg) := by + = deterministic (Prod.pair f g) (hf.prodMk hg) := by ext; simp_rw [prod_apply, deterministic_apply, Measure.dirac_prod_dirac] lemma id_prod_eq : @Kernel.id (α × β) inferInstance = diff --git a/Mathlib/Topology/Algebra/ProperAction/Basic.lean b/Mathlib/Topology/Algebra/ProperAction/Basic.lean index fb7302e13d1098..b3071395cc93ae 100644 --- a/Mathlib/Topology/Algebra/ProperAction/Basic.lean +++ b/Mathlib/Topology/Algebra/ProperAction/Basic.lean @@ -139,8 +139,8 @@ theorem t2Space_of_properSMul_of_t1Group [h_proper : ProperSMul G X] [T1Space G] rw [t2_iff_isClosed_diagonal] let g := fun gx : G × X ↦ (gx.1 • gx.2, gx.2) have proper_g : IsProperMap g := (properSMul_iff G X).1 h_proper - have : g ∘ f = fun x ↦ (x, x) := by ext x <;> simp [f, g] - have range_gf : range (g ∘ f) = diagonal X := by simp [this] + have : g ∘ f = Prod.diag := by ext x <;> simp [f, g] + have range_gf : range (g ∘ f) = diagonal X := range_diag rw [← range_gf] exact (proper_g.comp proper_f).isClosed_range diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index cdcc570028e7e6..773472f77e9cd9 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -411,7 +411,7 @@ theorem IsCompact.mem_prod_nhdsSet_of_forall {K : Set Y} {X} {l : Filter X} {s : -- That would seem a bit more natural. theorem IsCompact.nhdsSet_inf_eq_biSup {K : Set X} (hK : IsCompact K) (l : Filter X) : (𝓝ˢ K) ⊓ l = ⨆ x ∈ K, 𝓝 x ⊓ l := by - have : ∀ f : Filter X, f ⊓ l = comap (fun x ↦ (x, x)) (f ×ˢ l) := fun f ↦ by + have : ∀ f : Filter X, f ⊓ l = comap Prod.diag (f ×ˢ l) := fun f ↦ by simpa only [comap_prod] using congrArg₂ (· ⊓ ·) comap_id.symm comap_id.symm simp_rw [this, ← comap_iSup, hK.nhdsSet_prod_eq_biSup] diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index 004b2a64bf8222..fa9fb259541e97 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -61,7 +61,7 @@ variable [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z] [Topolog @[simp] theorem continuous_prodMk {f : X → Y} {g : X → Z} : - (Continuous fun x => (f x, g x)) ↔ Continuous f ∧ Continuous g := + (Continuous Prod.pair f g) ↔ Continuous f ∧ Continuous g := continuous_inf_rng.trans <| continuous_induced_rng.and continuous_induced_rng @[continuity] @@ -138,7 +138,7 @@ theorem Filter.Tendsto.snd_nhds {X} {l : Filter X} {f : X → Y × Z} {p : Y × @[continuity, fun_prop] theorem Continuous.prodMk {f : Z → X} {g : Z → Y} (hf : Continuous f) (hg : Continuous g) : - Continuous fun x => (f x, g x) := + Continuous Prod.pair f g := continuous_prodMk.2 ⟨hf, hg⟩ @[continuity] @@ -345,7 +345,7 @@ theorem Filter.Eventually.curry_nhds {p : X × Y → Prop} {x : X} {y : Y} @[fun_prop] theorem ContinuousAt.prodMk {f : X → Y} {g : X → Z} {x : X} (hf : ContinuousAt f x) - (hg : ContinuousAt g x) : ContinuousAt (fun x => (f x, g x)) x := + (hg : ContinuousAt g x) : ContinuousAt (Prod.pair f g) x := hf.prodMk_nhds hg theorem ContinuousAt.prodMap {f : X → Z} {g : Y → W} {p : X × Y} (hf : ContinuousAt f p.fst) diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index f1a9f9c1334284..bb9a5376b7afa8 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -577,12 +577,12 @@ theorem ContinuousOn.image_closure (hf : ContinuousOn f (closure s)) : theorem ContinuousWithinAt.prodMk {f : α → β} {g : α → γ} {s : Set α} {x : α} (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g s x) : - ContinuousWithinAt (fun x => (f x, g x)) s x := + ContinuousWithinAt (Prod.pair f g) s x := hf.prodMk_nhds hg @[fun_prop] theorem ContinuousOn.prodMk {f : α → β} {g : α → γ} {s : Set α} (hf : ContinuousOn f s) - (hg : ContinuousOn g s) : ContinuousOn (fun x => (f x, g x)) s := fun x hx => + (hg : ContinuousOn g s) : ContinuousOn (Prod.pair f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem continuousOn_fst {s : Set (α × β)} : ContinuousOn Prod.fst s := diff --git a/Mathlib/Topology/EMetricSpace/Lipschitz.lean b/Mathlib/Topology/EMetricSpace/Lipschitz.lean index 8e37ed75fa5d38..a7f7eb75343f2f 100644 --- a/Mathlib/Topology/EMetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/EMetricSpace/Lipschitz.lean @@ -244,7 +244,7 @@ protected theorem prod_snd : LipschitzWith 1 (@Prod.snd α β) := /-- If `f` and `g` are Lipschitz functions, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {f : α → β} {Kf : ℝ≥0} (hf : LipschitzWith Kf f) {g : α → γ} {Kg : ℝ≥0} - (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) fun x => (f x, g x) := by + (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) Prod.pair f g := by intro x y rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf x y) (hg x y) @@ -331,7 +331,7 @@ protected theorem comp {g : β → γ} {t : Set β} {Kg : ℝ≥0} (hg : Lipschi /-- If `f` and `g` are Lipschitz on `s`, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {g : α → γ} {Kf Kg : ℝ≥0} (hf : LipschitzOnWith Kf f s) - (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (fun x => (f x, g x)) s := by + (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (Prod.pair f g) s := by intro _ hx _ hy rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf hx hy) (hg hx hy) @@ -385,7 +385,7 @@ protected lemma comp {f : β → γ} {g : α → β} /-- If `f` and `g` are locally Lipschitz, so is the induced map `f × g` to the product type. -/ protected lemma prodMk {f : α → β} (hf : LocallyLipschitz f) {g : α → γ} (hg : LocallyLipschitz g) : - LocallyLipschitz fun x => (f x, g x) := by + LocallyLipschitz Prod.pair f g := by intro x rcases hf x with ⟨Kf, t₁, h₁t, hfL⟩ rcases hg x with ⟨Kg, t₂, h₂t, hgL⟩ diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index 890f5efd1ed61d..4e49c12ba6a043 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -1073,9 +1073,9 @@ lemma exists_is_open_mem_uniformity_of_forall_mem_eq end Uniform theorem Filter.Tendsto.congr_uniformity {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (fun x => (f x, g x)) l (𝓤 β)) : Tendsto g l (𝓝 b) := + (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto g l (𝓝 b) := Uniform.tendsto_nhds_right.2 <| (Uniform.tendsto_nhds_right.1 hf).uniformity_trans hg theorem Uniform.tendsto_congr {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hfg : Tendsto (fun x => (f x, g x)) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := + (hfg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := ⟨fun h => h.congr_uniformity hfg, fun h => h.congr_uniformity hfg.uniformity_symm⟩ diff --git a/Mathlib/Topology/UniformSpace/UniformConvergence.lean b/Mathlib/Topology/UniformSpace/UniformConvergence.lean index be119d39d3a840..09b6805fca837d 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergence.lean @@ -290,12 +290,12 @@ protected theorem TendstoUniformlyOn.prodMk {ι' β' : Type*} [UniformSpace β'] (h' : TendstoUniformlyOn F' f' p' s) : TendstoUniformlyOn (fun (i : ι × ι') a => (F i.1 a, F' i.2 a)) (fun a => (f a, f' a)) (p ×ˢ p') s := - (congr_arg _ s.inter_self).mp ((h.prodMap h').comp fun a => (a, a)) + (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Prod.diag) theorem TendstoUniformly.prodMk {ι' β' : Type*} [UniformSpace β'] {F' : ι' → α → β'} {f' : α → β'} {p' : Filter ι'} (h : TendstoUniformly F f p) (h' : TendstoUniformly F' f' p') : TendstoUniformly (fun (i : ι × ι') a => (F i.1 a, F' i.2 a)) (fun a => (f a, f' a)) (p ×ˢ p') := - (h.prodMap h').comp fun a => (a, a) + (h.prodMap h').comp Prod.diag /-- Uniform convergence on a filter `p'` to a constant function is equivalent to convergence in `p ×ˢ p'`. -/ @@ -542,12 +542,12 @@ theorem UniformCauchySeqOn.prodMap {ι' α' β' : Type*} [UniformSpace β'] {F' theorem UniformCauchySeqOn.prod {ι' β' : Type*} [UniformSpace β'] {F' : ι' → α → β'} {p' : Filter ι'} (h : UniformCauchySeqOn F p s) (h' : UniformCauchySeqOn F' p' s) : UniformCauchySeqOn (fun (i : ι × ι') a => (F i.fst a, F' i.snd a)) (p ×ˢ p') s := - (congr_arg _ s.inter_self).mp ((h.prodMap h').comp fun a => (a, a)) + (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Prod.diag) theorem UniformCauchySeqOn.prod' {β' : Type*} [UniformSpace β'] {F' : ι → α → β'} (h : UniformCauchySeqOn F p s) (h' : UniformCauchySeqOn F' p s) : UniformCauchySeqOn (fun (i : ι) a => (F i a, F' i a)) p s := fun u hu => - have hh : Tendsto (fun x : ι => (x, x)) p (p ×ˢ p) := tendsto_diag + have hh : Tendsto Prod.diag p (p ×ˢ p) := tendsto_diag (hh.prodMap hh).eventually ((h.prod h') u hu) /-- If a sequence of functions is uniformly Cauchy on a set, then the values at each point form diff --git a/MathlibTest/Continuity.lean b/MathlibTest/Continuity.lean index 9eaa064c713956..1265cdf012cd77 100644 --- a/MathlibTest/Continuity.lean +++ b/MathlibTest/Continuity.lean @@ -51,7 +51,7 @@ example (b : Y) : Continuous (fun _ : X => b) := by continuity example (f : C(X, Y)) (g : C(Y, Z)) : Continuous (g ∘ f) := by continuity -example (f : C(X, Y)) (g : C(X, Z)) : Continuous (fun x => (f x, g x)) := by continuity +example (f : C(X, Y)) (g : C(X, Z)) : Continuous (Prod.pair f g) := by continuity example (f : C(X, Y)) (g : C(W, Z)) : Continuous (Prod.map f g) := by continuity diff --git a/MathlibTest/fun_prop.lean b/MathlibTest/fun_prop.lean index b730948c2830a5..b3b81ad2343da8 100644 --- a/MathlibTest/fun_prop.lean +++ b/MathlibTest/fun_prop.lean @@ -50,7 +50,7 @@ Let's mark the product constructor. -/ attribute [fun_prop] - Measurable.prodMk -- Measurable f → Measurable g → Measurable fun x => (f x, g x) + Measurable.prodMk -- Measurable f → Measurable g → Measurable Prod.pair f g /-! When it comes to product projection, their properties are usually stated in two different ways From 0cbba0c0a90212b33d870cedc5286dd0f44b6ae3 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 17:56:03 +0100 Subject: [PATCH 02/35] Add docstrings --- Mathlib/Data/Prod/Init.lean | 7 +++++++ Mathlib/Data/Sum/Init.lean | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index f9c35110523ef7..ad65f3c93e2feb 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -7,6 +7,13 @@ module /-! +This file defines `Prod.pair f g`, the operation that pairs two functions `f : γ → α` and +`g : γ → β` into a function `γ → α × β`. + +It also defines the special case when `f = g = id`, `Prod.diag`. This is the canonical injection +of a type into its prouduct with itself onto its diagonal. + + This file should not depend on anything defined in Mathlib (except for notation), so that it can be upstreamed to Batteries or the Lean standard library easily. diff --git a/Mathlib/Data/Sum/Init.lean b/Mathlib/Data/Sum/Init.lean index 37245c820e5f4e..7397ef174959d3 100644 --- a/Mathlib/Data/Sum/Init.lean +++ b/Mathlib/Data/Sum/Init.lean @@ -7,6 +7,8 @@ module /-! +This file defines `Sum.get`, the operation that extracts a term of type `α` from `α ⊕ α`. + This file should not depend on anything defined in Mathlib (except for notation), so that it can be upstreamed to Batteries or the Lean standard library easily. @@ -44,7 +46,7 @@ theorem get_apply_of_isLeft (h : x.isLeft) : theorem get_apply_of_isRight (h : x.isRight) : x.get = x.getRight h := by grind -theorem get_apply : Sum.get x = if h : x.isLeft then x.getLeft h else x.getRight (by grind) := by grind +theorem get_apply : Sum.get x = if h : x.isLeft then x.getLeft h else x.getRight (by grind) := by grind @[simp, grind =] theorem get_map {f : β → α} {g : δ → α} {y : β ⊕ δ} : (y.map f g).get = y.elim f g := by cases y <;> rfl From 6920c7b03b3514d0ab801329808a5ecbe6f85870 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 18:06:34 +0100 Subject: [PATCH 03/35] Updated Mathlib.lean --- Mathlib.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib.lean b/Mathlib.lean index 5cfac1df523bc2..fe77d44fb3e16b 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4120,6 +4120,7 @@ public import Mathlib.Data.PSigma.Order public import Mathlib.Data.Part public import Mathlib.Data.Pi.Interval public import Mathlib.Data.Prod.Basic +public import Mathlib.Data.Prod.Init public import Mathlib.Data.Prod.Lex public import Mathlib.Data.Prod.PProd public import Mathlib.Data.Prod.TProd @@ -4245,6 +4246,7 @@ public import Mathlib.Data.String.Defs public import Mathlib.Data.String.Lemmas public import Mathlib.Data.Subtype public import Mathlib.Data.Sum.Basic +public import Mathlib.Data.Sum.Init public import Mathlib.Data.Sum.Interval public import Mathlib.Data.Sum.Lattice public import Mathlib.Data.Sum.Order From b9d9eae9331cfcf94955d4d4951837563d26b62a Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 18:12:08 +0100 Subject: [PATCH 04/35] Fix lint --- Mathlib/Data/Prod/Init.lean | 4 +++- Mathlib/Data/Sum/Init.lean | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index ad65f3c93e2feb..45ae9ac5a64822 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -1,10 +1,12 @@ /- Copyright (c) 2026 Wrenna Robson. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Wrena Robson +Authors: Wrenna Robson -/ module +public import Mathlib.Init + /-! This file defines `Prod.pair f g`, the operation that pairs two functions `f : γ → α` and diff --git a/Mathlib/Data/Sum/Init.lean b/Mathlib/Data/Sum/Init.lean index 7397ef174959d3..15e2b92e47fcf6 100644 --- a/Mathlib/Data/Sum/Init.lean +++ b/Mathlib/Data/Sum/Init.lean @@ -1,10 +1,12 @@ /- Copyright (c) 2026 Wrenna Robson. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Wrena Robson +Authors: Wrenna Robson -/ module +public import Mathlib.Init + /-! This file defines `Sum.get`, the operation that extracts a term of type `α` from `α ⊕ α`. From f3d7a86fd15d6d860cb05e2c9e248f946dbfb8e9 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 18:13:12 +0100 Subject: [PATCH 05/35] Fix lint --- Mathlib/Data/Prod/Init.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index 45ae9ac5a64822..9f7010b7be86cf 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -49,8 +49,8 @@ theorem pair_comp {δ} {h : δ → γ} : Prod.pair f g ∘ h = Prod.pair (f ∘ @[simp] theorem pair_fst_snd_comp {f : γ → α × β} : Prod.pair (fst ∘ f) (snd ∘ f) = f := rfl -theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.pair f g = Prod.pair f' g' ↔ f = f' ∧ g = g' := by - simp [funext_iff, Prod.ext_iff, forall_and] +theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.pair f g = Prod.pair f' g' ↔ + f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] end From db2aa5289132086196fa7df2493f8e9c7621daae Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 18:13:40 +0100 Subject: [PATCH 06/35] Fix lint --- Mathlib/Data/Prod/Init.lean | 3 ++- Mathlib/Data/Sum/Init.lean | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index 9f7010b7be86cf..0c2b8c58ce077f 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -80,7 +80,8 @@ variable {a b : α} @[simp, grind =] theorem fst_diag : (Prod.diag a).1 = a := rfl @[simp, grind =] theorem snd_diag : (Prod.diag a).2 = a := rfl -@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Prod.diag a) = Prod.pair f g a := rfl +@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Prod.diag a) = + Prod.pair f g a := rfl theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = Prod.pair f g := rfl diff --git a/Mathlib/Data/Sum/Init.lean b/Mathlib/Data/Sum/Init.lean index 15e2b92e47fcf6..4d41a122c9e40b 100644 --- a/Mathlib/Data/Sum/Init.lean +++ b/Mathlib/Data/Sum/Init.lean @@ -48,7 +48,8 @@ theorem get_apply_of_isLeft (h : x.isLeft) : theorem get_apply_of_isRight (h : x.isRight) : x.get = x.getRight h := by grind -theorem get_apply : Sum.get x = if h : x.isLeft then x.getLeft h else x.getRight (by grind) := by grind +theorem get_apply : Sum.get x = if h : x.isLeft then x.getLeft h else x.getRight (by grind) := by + grind @[simp, grind =] theorem get_map {f : β → α} {g : δ → α} {y : β ⊕ δ} : (y.map f g).get = y.elim f g := by cases y <;> rfl From f1a6f9b703c5d2f9ab876c45839c54c680c819e7 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 18:45:26 +0100 Subject: [PATCH 07/35] Fix file --- Mathlib/Algebra/FiniteSupport/Basic.lean | 2 +- Mathlib/Algebra/Ring/Prod.lean | 4 +- .../Analysis/SpecialFunctions/Pow/Deriv.lean | 6 +-- Mathlib/Data/Int/Cast/Prod.lean | 2 +- Mathlib/Data/Nat/Cast/Prod.lean | 2 +- Mathlib/Data/Prod/Init.lean | 45 ++++++++++--------- Mathlib/Data/Set/Prod.lean | 6 +-- .../Manifold/ContMDiff/Constructions.lean | 16 +++---- Mathlib/Geometry/Manifold/ContMDiffMap.lean | 2 +- Mathlib/MeasureTheory/Function/AEEqFun.lean | 6 +-- .../Function/L1Space/Integrable.lean | 2 +- .../AEStronglyMeasurable.lean | 2 +- .../Function/StronglyMeasurable/Basic.lean | 2 +- .../MeasureTheory/Measure/AEMeasurable.lean | 2 +- Mathlib/Order/Basic.lean | 23 +++++++++- Mathlib/Order/Filter/Basic.lean | 2 +- Mathlib/Order/Hom/Basic.lean | 2 +- Mathlib/Order/Monotone/Defs.lean | 6 +-- Mathlib/Order/ScottContinuity.lean | 4 +- .../Probability/Kernel/Composition/Prod.lean | 2 +- Mathlib/Topology/Constructions/SumProd.lean | 6 +-- Mathlib/Topology/ContinuousOn.lean | 4 +- Mathlib/Topology/EMetricSpace/Lipschitz.lean | 6 +-- Mathlib/Topology/UniformSpace/Basic.lean | 4 +- MathlibTest/Continuity.lean | 2 +- MathlibTest/fun_prop.lean | 2 +- 26 files changed, 94 insertions(+), 68 deletions(-) diff --git a/Mathlib/Algebra/FiniteSupport/Basic.lean b/Mathlib/Algebra/FiniteSupport/Basic.lean index d810f395f483d1..53fe058883ecbc 100644 --- a/Mathlib/Algebra/FiniteSupport/Basic.lean +++ b/Mathlib/Algebra/FiniteSupport/Basic.lean @@ -55,7 +55,7 @@ lemma HasFiniteMulSupport.snd {M' : Type*} [One M'] {f : α → M × M'} (hf : H @[to_additive (attr := fun_prop)] lemma HasFiniteMulSupport.prodMk {M' : Type*} [One M'] {f : α → M} {g : α → M'} (hf : HasFiniteMulSupport f) (hg : HasFiniteMulSupport g) : - HasFiniteMulSupport (Prod.pair f g) := by + HasFiniteMulSupport (Prod.prodMk f g) := by simp only [HasFiniteMulSupport] at hf hg ⊢ rw [mulSupport_prodMk f g] exact hf.union hg diff --git a/Mathlib/Algebra/Ring/Prod.lean b/Mathlib/Algebra/Ring/Prod.lean index 33289f939e02ab..f2be9ffe9eae2a 100644 --- a/Mathlib/Algebra/Ring/Prod.lean +++ b/Mathlib/Algebra/Ring/Prod.lean @@ -132,7 +132,7 @@ variable [NonUnitalNonAssocSemiring T] (f : R →ₙ+* S) (g : R →ₙ+* T) `f.prod g : R →ₙ+* S × T` given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →ₙ+* S) (g : R →ₙ+* T) : R →ₙ+* S × T := { MulHom.prod (f : MulHom R S) (g : MulHom R T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := Prod.pair f g } + toFun := Prod.prodMk f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := @@ -208,7 +208,7 @@ variable [NonAssocSemiring T] (f : R →+* S) (g : R →+* T) given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →+* S) (g : R →+* T) : R →+* S × T := { MonoidHom.prod (f : R →* S) (g : R →* T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := Prod.pair f g } + toFun := Prod.prodMk f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean index 0f9967c2ea2e97..c007c707438c5c 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean @@ -85,7 +85,7 @@ theorem HasStrictFDerivAt.const_cpow (hf : HasStrictFDerivAt f f' x) (h0 : c ≠ theorem HasFDerivAt.cpow (hf : HasFDerivAt f f' x) (hg : HasFDerivAt g g' x) (h0 : f x ∈ slitPlane) : HasFDerivAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') x := by - convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp x (hf.prodMk hg) + convert (@Complex.hasFDerivAt_cpow ((Prod.prodMk f g) x) h0).comp x (hf.prodMk hg) theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x ≠ 0) : HasFDerivAt (fun x => c ^ f x) ((c ^ f x * Complex.log c) • f') x := @@ -94,7 +94,7 @@ theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x theorem HasFDerivWithinAt.cpow (hf : HasFDerivWithinAt f f' s x) (hg : HasFDerivWithinAt g g' s x) (h0 : f x ∈ slitPlane) : HasFDerivWithinAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') s x := by - convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp_hasFDerivWithinAt x + convert (@Complex.hasFDerivAt_cpow ((Prod.prodMk f g) x) h0).comp_hasFDerivWithinAt x (hf.prodMk hg) theorem HasFDerivWithinAt.const_cpow (hf : HasFDerivWithinAt f f' s x) (h0 : c ≠ 0 ∨ f x ≠ 0) : @@ -387,7 +387,7 @@ theorem differentiableAt_rpow_of_ne (p : ℝ × ℝ) (hp : p.1 ≠ 0) : theorem _root_.HasStrictDerivAt.rpow {f g : ℝ → ℝ} {f' g' : ℝ} (hf : HasStrictDerivAt f f' x) (hg : HasStrictDerivAt g g' x) (h : 0 < f x) : HasStrictDerivAt (fun x => f x ^ g x) (f' * g x * f x ^ (g x - 1) + g' * f x ^ g x * Real.log (f x)) x := by - convert (hasStrictFDerivAt_rpow_of_pos ((Prod.pair f g) x) h).comp_hasStrictDerivAt x + convert (hasStrictFDerivAt_rpow_of_pos ((Prod.prodMk f g) x) h).comp_hasStrictDerivAt x (hf.prodMk hg) using 1 simp [mul_assoc, mul_comm] diff --git a/Mathlib/Data/Int/Cast/Prod.lean b/Mathlib/Data/Int/Cast/Prod.lean index f92d160a1d13e3..6c82f03243934c 100644 --- a/Mathlib/Data/Int/Cast/Prod.lean +++ b/Mathlib/Data/Int/Cast/Prod.lean @@ -22,7 +22,7 @@ variable {α β : Type*} [AddGroupWithOne α] [AddGroupWithOne β] instance : AddGroupWithOne (α × β) := { Prod.instAddMonoidWithOne, Prod.instAddGroup with - intCast := Prod.pair IntCast.intCast IntCast.intCast + intCast := Prod.prodMk IntCast.intCast IntCast.intCast intCast_ofNat := fun _ => by ext <;> simp intCast_negSucc := fun _ => by ext <;> simp } diff --git a/Mathlib/Data/Nat/Cast/Prod.lean b/Mathlib/Data/Nat/Cast/Prod.lean index 78627dbbdbe413..4adb77e3ac7001 100644 --- a/Mathlib/Data/Nat/Cast/Prod.lean +++ b/Mathlib/Data/Nat/Cast/Prod.lean @@ -25,7 +25,7 @@ variable [AddMonoidWithOne α] [AddMonoidWithOne β] instance instAddMonoidWithOne : AddMonoidWithOne (α × β) := { Prod.instAddMonoid, @Prod.instOne α β _ _ with - natCast := Prod.pair NatCast.natCast NatCast.natCast + natCast := Prod.prodMk NatCast.natCast NatCast.natCast natCast_zero := congr_arg₂ Prod.mk Nat.cast_zero Nat.cast_zero natCast_succ := fun _ => congr_arg₂ Prod.mk (Nat.cast_succ _) (Nat.cast_succ _) } diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index 0c2b8c58ce077f..0039c65c61efc2 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -9,7 +9,7 @@ public import Mathlib.Init /-! -This file defines `Prod.pair f g`, the operation that pairs two functions `f : γ → α` and +This file defines `Prod.prodMk f g`, the operation that prodMks two functions `f : γ → α` and `g : γ → β` into a function `γ → α × β`. It also defines the special case when `f = g = id`, `Prod.diag`. This is the canonical injection @@ -30,46 +30,51 @@ universe u₁ u₂ u₃ u₄ u₅ variable {α : Type u₁} {β : Type u₂} {γ : Sort u₃} {δ : Type u₄} {ε : Type u₅} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -@[expose] protected def pair (f : γ → α) (g : γ → β) : γ → α × β := fun a ↦ (f a, g a) +@[expose] protected def prodMk (f : γ → α) (g : γ → β) : γ → α × β := fun a ↦ (f a, g a) section variable (f : γ → α) (g : γ → β) -@[grind =] theorem pair_apply (c : γ) : Prod.pair f g c = (f c, g c) := rfl +@[grind =] theorem prodMk_apply (c : γ) : Prod.prodMk f g c = (f c, g c) := rfl -@[simp] theorem fst_pair {c} : (Prod.pair f g c).fst = f c := rfl -@[simp] theorem snd_pair {c} : (Prod.pair f g c).snd = g c := rfl +@[simp] theorem fst_prodMk {c} : (Prod.prodMk f g c).fst = f c := rfl +@[simp] theorem snd_prodMk {c} : (Prod.prodMk f g c).snd = g c := rfl -@[simp] theorem fst_comp_pair : fst ∘ Prod.pair f g = f := rfl -@[simp] theorem snd_comp_pair : snd ∘ Prod.pair f g = g := rfl -@[simp] theorem pair_fst_snd : @Prod.pair α β _ fst snd = id := rfl +@[simp] theorem fst_comp_prodMk : fst ∘ Prod.prodMk f g = f := rfl +@[simp] theorem snd_comp_prodMk : snd ∘ Prod.prodMk f g = g := rfl +@[simp] theorem prodMk_fst_snd : @Prod.prodMk α β _ fst snd = id := rfl -theorem pair_comp {δ} {h : δ → γ} : Prod.pair f g ∘ h = Prod.pair (f ∘ h) (g ∘ h) := rfl +theorem prodMk_comp {δ} {h : δ → γ} : Prod.prodMk f g ∘ h = Prod.prodMk (f ∘ h) (g ∘ h) := rfl -@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : Prod.pair (fst ∘ f) (snd ∘ f) = f := rfl +@[simp] theorem prodMk_fst_snd_comp {f : γ → α × β} : Prod.prodMk (fst ∘ f) (snd ∘ f) = f := rfl -theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.pair f g = Prod.pair f' g' ↔ +theorem prodMk_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.prodMk f g = Prod.prodMk f' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] +@[grind =] +theorem prodMk_const_const (a : α) (b : β) : + Prod.prodMk (Function.const γ a) (Function.const γ b) = Function.const γ (a, b) := rfl + end section -/- We can define `Prod.map` in terms of `Prod.pair`. -/ -theorem map_eq_pair {f : α → β} {g : δ → ε} : Prod.map f g = Prod.pair (f ∘ fst) (g ∘ snd) := rfl +/- We can define `Prod.map` in terms of `Prod.prodMk`. -/ +theorem map_eq_prodMk {f : α → β} {g : δ → ε} : Prod.map f g = + Prod.prodMk (f ∘ fst) (g ∘ snd) := rfl @[grind _=_] -theorem map_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : - Prod.map f h (Prod.pair g k c) = Prod.pair (f ∘ g) (h ∘ k) c := rfl +theorem map_prodMk {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : + Prod.map f h (Prod.prodMk g k c) = Prod.prodMk (f ∘ g) (h ∘ k) c := rfl -theorem map_comp_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : - Prod.map f h ∘ Prod.pair g k = Prod.pair (f ∘ g) (h ∘ k) := rfl +theorem map_comp_prodMk {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : + Prod.map f h ∘ Prod.prodMk g k = Prod.prodMk (f ∘ g) (h ∘ k) := rfl end /-- The diagonal map into Prod. -/ -@[expose] protected def diag : α → α × α := Prod.pair id id +@[expose] protected def diag : α → α × α := Prod.prodMk id id section @@ -81,9 +86,9 @@ variable {a b : α} @[simp, grind =] theorem snd_diag : (Prod.diag a).2 = a := rfl @[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Prod.diag a) = - Prod.pair f g a := rfl + Prod.prodMk f g a := rfl -theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = Prod.pair f g := rfl +theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = Prod.prodMk f g := rfl theorem injective_diag : Function.Injective (Prod.diag (α := α)) := fun _ _ => congrArg fst diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 496866096a45f5..6543f0eda86817 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -180,7 +180,7 @@ theorem preimage_prod_map_prod (f : α → β) (g : γ → δ) (s : Set β) (t : rfl theorem mk_preimage_prod (f : γ → α) (g : γ → β) : - (Prod.pair f g) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := + (Prod.prodMk f g) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := rfl @[simp] @@ -239,7 +239,7 @@ theorem prod_univ_range_eq {m₂ : β → δ} : ext <| by simp [range] theorem range_pair_subset (f : α → β) (g : α → γ) : - (range Prod.pair f g) ⊆ range f ×ˢ range g := by grind + (range Prod.prodMk f g) ⊆ range f ×ˢ range g := by grind theorem Nonempty.prod : s.Nonempty → t.Nonempty → (s ×ˢ t).Nonempty := fun ⟨x, hx⟩ ⟨y, hy⟩ => ⟨(x, y), ⟨hx, hy⟩⟩ @@ -260,7 +260,7 @@ theorem prod_sub_preimage_iff {W : Set γ} {f : α × β → γ} : s ×ˢ t ⊆ f ⁻¹' W ↔ ∀ a b, a ∈ s → b ∈ t → f (a, b) ∈ W := by simp [subset_def] theorem image_prodMk_subset_prod {f : α → β} {g : α → γ} {s : Set α} : - (Prod.pair f g) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind + (Prod.prodMk f g) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind theorem image_prodMk_subset_prod_left (hb : b ∈ t) : (fun a => (a, b)) '' s ⊆ s ×ˢ t := by grind diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean index cc9dcb1dcf2060..b98174878c08b4 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean @@ -55,39 +55,39 @@ section ProdMk theorem ContMDiffWithinAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffWithinAt I I' n f s x) (hg : ContMDiffWithinAt I J' n g s x) : - ContMDiffWithinAt I (I'.prod J') n (Prod.pair f g) s x := by + ContMDiffWithinAt I (I'.prod J') n (Prod.prodMk f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem ContMDiffWithinAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffWithinAt I 𝓘(𝕜, E') n f s x) (hg : ContMDiffWithinAt I 𝓘(𝕜, F') n g s x) : - ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) s x := by + ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (Prod.prodMk f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ nonrec theorem ContMDiffAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffAt I I' n f x) - (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (Prod.pair f g) x := + (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (Prod.prodMk f g) x := hf.prodMk hg nonrec theorem ContMDiffAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffAt I 𝓘(𝕜, E') n f x) (hg : ContMDiffAt I 𝓘(𝕜, F') n g x) : - ContMDiffAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) x := + ContMDiffAt I 𝓘(𝕜, E' × F') n (Prod.prodMk f g) x := hf.prodMk_space hg theorem ContMDiffOn.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffOn I I' n f s) - (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (Prod.pair f g) s := + (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (Prod.prodMk f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem ContMDiffOn.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffOn I 𝓘(𝕜, E') n f s) - (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (Prod.pair f g) s := + (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (Prod.prodMk f g) s := fun x hx => (hf x hx).prodMk_space (hg x hx) nonrec theorem ContMDiff.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiff I I' n f) - (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n Prod.pair f g := fun x => + (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n Prod.prodMk f g := fun x => (hf x).prodMk (hg x) theorem ContMDiff.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiff I 𝓘(𝕜, E') n f) - (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n Prod.pair f g := fun x => + (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n Prod.prodMk f g := fun x => (hf x).prodMk_space (hg x) end ProdMk diff --git a/Mathlib/Geometry/Manifold/ContMDiffMap.lean b/Mathlib/Geometry/Manifold/ContMDiffMap.lean index 5ed3ded179099c..721eea8c5bdae8 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMap.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMap.lean @@ -106,7 +106,7 @@ def snd : C^n⟮I.prod I', M × M'; I', M'⟯ := /-- Given two `C^n` maps `f` and `g`, this is the `C^n` map `x ↦ (f x, g x)`. -/ def prodMk (f : C^n⟮J, N; I, M⟯) (g : C^n⟮J, N; I', M'⟯) : C^n⟮J, N; I.prod I', M × M'⟯ := - ⟨Prod.pair f g, f.2.prodMk g.2⟩ + ⟨Prod.prodMk f g, f.2.prodMk g.2⟩ end ContMDiffMap diff --git a/Mathlib/MeasureTheory/Function/AEEqFun.lean b/Mathlib/MeasureTheory/Function/AEEqFun.lean index 6241ed016179f5..90cee565b5a0a4 100644 --- a/Mathlib/MeasureTheory/Function/AEEqFun.lean +++ b/Mathlib/MeasureTheory/Function/AEEqFun.lean @@ -397,15 +397,15 @@ def pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : α →ₘ[μ] β × γ @[simp] theorem pair_mk_mk (f : α → β) (hf) (g : α → γ) (hg) : - (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (Prod.pair f g) (hf.prodMk hg) := + (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (Prod.prodMk f g) (hf.prodMk hg) := rfl theorem pair_eq_mk (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g = - mk (Prod.pair f g) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by + mk (Prod.prodMk f g) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by simp only [← pair_mk_mk, mk_coeFn, f.aestronglyMeasurable, g.aestronglyMeasurable] -theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] Prod.pair f g := by +theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] Prod.prodMk f g := by rw [pair_eq_mk] apply coeFn_mk diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 5c237bb54bdaf9..9000172232a3c9 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -640,7 +640,7 @@ lemma integrable_of_le_of_le {f g₁ g₂ : α → ℝ} (hf : AEStronglyMeasurab -- TODO: generalising this to enorms requires defining a product instance for enormed monoids first @[fun_prop] theorem Integrable.prodMk {f : α → β} {g : α → γ} (hf : Integrable f μ) (hg : Integrable g μ) : - Integrable (Prod.pair f g) μ := + Integrable (Prod.prodMk f g) μ := ⟨by fun_prop, (hf.norm.add' hg.norm).mono <| Eventually.of_forall fun x => diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index 88cc6e2a8b4f5a..ffa3977aa488ae 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -229,7 +229,7 @@ protected theorem snd {f : α → β × γ} (hf : AEStronglyMeasurable[m] f μ) @[fun_prop] protected theorem prodMk {f : α → β} {g : α → γ} (hf : AEStronglyMeasurable[m] f μ) - (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (Prod.pair f g) μ := + (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (Prod.prodMk f g) μ := ⟨fun x => (hf.mk f x, hg.mk g x), hf.stronglyMeasurable_mk.prodMk hg.stronglyMeasurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index af077ea96e0b55..672b187b1eccaf 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -352,7 +352,7 @@ protected theorem snd {m : MeasurableSpace α} [TopologicalSpace β] [Topologica @[fun_prop] protected theorem prodMk {m : MeasurableSpace α} [TopologicalSpace β] [TopologicalSpace γ] {f : α → β} {g : α → γ} (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : - StronglyMeasurable Prod.pair f g := by + StronglyMeasurable Prod.prodMk f g := by refine ⟨fun n => SimpleFunc.pair (hf.approx n) (hg.approx n), fun x => ?_⟩ rw [nhds_prod_eq] exact Tendsto.prodMk (hf.tendsto_approx x) (hg.tendsto_approx x) diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index 834a6479a1d262..cd72ead85dbe42 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -190,7 +190,7 @@ protected theorem snd {f : α → β × γ} (hf : AEMeasurable f μ) : @[fun_prop] theorem prodMk {f : α → β} {g : α → γ} (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (Prod.pair f g) μ := + AEMeasurable (Prod.prodMk f g) μ := ⟨fun a => (hf.mk f a, hg.mk g a), hf.measurable_mk.prodMk hg.measurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 009c8e9c49d18f..5319e2362e33fa 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -13,6 +13,7 @@ public import Mathlib.Tactic.Convert public import Mathlib.Tactic.Inhabit public import Mathlib.Tactic.SimpRw public import Mathlib.Tactic.GCongr.Core +public import Mathlib.Data.Prod.Init /-! # Basic definitions about `≤` and `<` @@ -864,7 +865,7 @@ type synonym `α ×ₗ β = α × β`. namespace Prod section LE -variable [LE α] [LE β] {x y : α × β} {a a₁ a₂ : α} {b b₁ b₂ : β} +variable [LE α] [LE β] {x y : α × β} {a a₁ a₂ : α} {b b₁ b₂ : β} {α₂} {β₂} instance : LE (α × β) where le p q := p.1 ≤ q.1 ∧ p.2 ≤ q.2 @@ -884,6 +885,26 @@ lemma GCongr.mk_le_mk (ha : a₁ ≤ a₂) (hb : b₁ ≤ b₂) : (a₁, b₁) @[to_dual (attr := simp) mk_le_swap] lemma swap_le_mk : x.swap ≤ (b, a) ↔ x ≤ (a, b) := and_comm +section +variable {α β₁ β₂ : Type*} [LE β₁] [LE β₂] + +@[simp] +lemma prodMk_le_prodMk_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : + Prod.prodMk u₁ u₂ ≤ Prod.prodMk v₁ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by + simp [Pi.le_def, Prod.le_def, forall_and] + +lemma const_le_prodMk_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : + Function.const _ b ≤ Prod.prodMk v₁ v₂ ↔ + Function.const _ b.1 ≤ v₁ ∧ Function.const _ b.2 ≤ v₂ := + prodMk_const_const b.1 b.2 ▸ prodMk_le_prodMk_iff .. + +lemma prodMk_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : + Prod.prodMk v₁ v₂ ≤ Function.const _ b ↔ + v₁ ≤ Function.const _ b.1 ∧ v₂ ≤ Function.const _ b.2 := + prodMk_const_const b.1 b.2 ▸ prodMk_le_prodMk_iff .. + +end + end LE section Preorder diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index a0e486e162de51..f738233c35cb16 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -976,7 +976,7 @@ instance {l : Filter α} : trans := EventuallyEq.trans theorem EventuallyEq.prodMk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') : - (Prod.pair f g) =ᶠ[l] fun x => (f' x, g' x) := + (Prod.prodMk f g) =ᶠ[l] fun x => (f' x, g' x) := hf.mp <| hg.mono <| by intros diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 5b3e4f752e0845..5a7308dc84b5e5 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -369,7 +369,7 @@ theorem comp_const (γ : Type*) [Preorder γ] (f : α →o β) (c : α) : `OrderHom`. -/ @[simps] protected def prod (f : α →o β) (g : α →o γ) : α →o β × γ := - ⟨Prod.pair f g, fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ + ⟨Prod.prodMk f g, fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ @[mono, to_dual self] theorem prod_mono {f₁ f₂ : α →o β} (hf : f₁ ≤ f₂) {g₁ g₂ : α →o γ} (hg : g₁ ≤ g₂) : diff --git a/Mathlib/Order/Monotone/Defs.lean b/Mathlib/Order/Monotone/Defs.lean index 09d1c7520dbb4d..643afec9e98595 100644 --- a/Mathlib/Order/Monotone/Defs.lean +++ b/Mathlib/Order/Monotone/Defs.lean @@ -507,11 +507,11 @@ theorem monotone_fst : Monotone (@Prod.fst α β) := fun _ _ ↦ And.left theorem monotone_snd : Monotone (@Prod.snd α β) := fun _ _ ↦ And.right theorem monotone_prodMk_iff {f : γ → α} {g : γ → β} : - Monotone (Prod.pair f g) ↔ Monotone f ∧ Monotone g := by - simp_rw [Monotone, Prod.mk_le_mk, forall_and] + Monotone (Prod.prodMk f g) ↔ Monotone f ∧ Monotone g := by + simp [Monotone, Prod.le_def, forall_and] theorem Monotone.prodMk {f : γ → α} {g : γ → β} (hf : Monotone f) (hg : Monotone g) : - Monotone (Prod.pair f g) := + Monotone (Prod.prodMk f g) := monotone_prodMk_iff.2 ⟨hf, hg⟩ theorem Monotone.prodMap (hf : Monotone f) (hg : Monotone g) : Monotone (Prod.map f g) := diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index 01702a3bce853e..0dc0d38cc35e17 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -106,7 +106,7 @@ theorem ScottContinuousOn.image_comp {g : β → γ} @[fun_prop] lemma ScottContinuousOn.prodMk {g : α → γ} (hD : ∀ a b : α, a ≤ b → {a, b} ∈ D) (hf : ScottContinuousOn D f) (hg : ScottContinuousOn D g) : - ScottContinuousOn D Prod.pair f g := fun d hd₁ hd₂ hd₃ a hda => by + ScottContinuousOn D Prod.prodMk f g := fun d hd₁ hd₂ hd₃ a hda => by rw [IsLUB, IsLeast, upperBounds] constructor · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, @@ -172,7 +172,7 @@ lemma ScottContinuous.comp {g : β → γ} @[fun_prop] lemma ScottContinuous.prodMk {g : α → γ} (hf : ScottContinuous f) (hg : ScottContinuous g) : - ScottContinuous Prod.pair f g := by + ScottContinuous Prod.prodMk f g := by rw [← scottContinuousOn_univ] at ⊢ hf hg exact ScottContinuousOn.prodMk (by grind) hf hg diff --git a/Mathlib/Probability/Kernel/Composition/Prod.lean b/Mathlib/Probability/Kernel/Composition/Prod.lean index 9d73c928a09356..ee46c515e5ed07 100644 --- a/Mathlib/Probability/Kernel/Composition/Prod.lean +++ b/Mathlib/Probability/Kernel/Composition/Prod.lean @@ -216,7 +216,7 @@ lemma swap_prod {κ : Kernel α β} [IsSFiniteKernel κ] {η : Kernel α γ} [Is lemma deterministic_prod_deterministic {f : α → β} {g : α → γ} (hf : Measurable f) (hg : Measurable g) : deterministic f hf ×ₖ deterministic g hg - = deterministic (Prod.pair f g) (hf.prodMk hg) := by + = deterministic (Prod.prodMk f g) (hf.prodMk hg) := by ext; simp_rw [prod_apply, deterministic_apply, Measure.dirac_prod_dirac] lemma id_prod_eq : @Kernel.id (α × β) inferInstance = diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index fa9fb259541e97..cf6516152527df 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -61,7 +61,7 @@ variable [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z] [Topolog @[simp] theorem continuous_prodMk {f : X → Y} {g : X → Z} : - (Continuous Prod.pair f g) ↔ Continuous f ∧ Continuous g := + (Continuous Prod.prodMk f g) ↔ Continuous f ∧ Continuous g := continuous_inf_rng.trans <| continuous_induced_rng.and continuous_induced_rng @[continuity] @@ -138,7 +138,7 @@ theorem Filter.Tendsto.snd_nhds {X} {l : Filter X} {f : X → Y × Z} {p : Y × @[continuity, fun_prop] theorem Continuous.prodMk {f : Z → X} {g : Z → Y} (hf : Continuous f) (hg : Continuous g) : - Continuous Prod.pair f g := + Continuous Prod.prodMk f g := continuous_prodMk.2 ⟨hf, hg⟩ @[continuity] @@ -345,7 +345,7 @@ theorem Filter.Eventually.curry_nhds {p : X × Y → Prop} {x : X} {y : Y} @[fun_prop] theorem ContinuousAt.prodMk {f : X → Y} {g : X → Z} {x : X} (hf : ContinuousAt f x) - (hg : ContinuousAt g x) : ContinuousAt (Prod.pair f g) x := + (hg : ContinuousAt g x) : ContinuousAt (Prod.prodMk f g) x := hf.prodMk_nhds hg theorem ContinuousAt.prodMap {f : X → Z} {g : Y → W} {p : X × Y} (hf : ContinuousAt f p.fst) diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index bb9a5376b7afa8..46d2dce9d9a330 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -577,12 +577,12 @@ theorem ContinuousOn.image_closure (hf : ContinuousOn f (closure s)) : theorem ContinuousWithinAt.prodMk {f : α → β} {g : α → γ} {s : Set α} {x : α} (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g s x) : - ContinuousWithinAt (Prod.pair f g) s x := + ContinuousWithinAt (Prod.prodMk f g) s x := hf.prodMk_nhds hg @[fun_prop] theorem ContinuousOn.prodMk {f : α → β} {g : α → γ} {s : Set α} (hf : ContinuousOn f s) - (hg : ContinuousOn g s) : ContinuousOn (Prod.pair f g) s := fun x hx => + (hg : ContinuousOn g s) : ContinuousOn (Prod.prodMk f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem continuousOn_fst {s : Set (α × β)} : ContinuousOn Prod.fst s := diff --git a/Mathlib/Topology/EMetricSpace/Lipschitz.lean b/Mathlib/Topology/EMetricSpace/Lipschitz.lean index a7f7eb75343f2f..ed41ec26a222c9 100644 --- a/Mathlib/Topology/EMetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/EMetricSpace/Lipschitz.lean @@ -244,7 +244,7 @@ protected theorem prod_snd : LipschitzWith 1 (@Prod.snd α β) := /-- If `f` and `g` are Lipschitz functions, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {f : α → β} {Kf : ℝ≥0} (hf : LipschitzWith Kf f) {g : α → γ} {Kg : ℝ≥0} - (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) Prod.pair f g := by + (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) Prod.prodMk f g := by intro x y rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf x y) (hg x y) @@ -331,7 +331,7 @@ protected theorem comp {g : β → γ} {t : Set β} {Kg : ℝ≥0} (hg : Lipschi /-- If `f` and `g` are Lipschitz on `s`, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {g : α → γ} {Kf Kg : ℝ≥0} (hf : LipschitzOnWith Kf f s) - (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (Prod.pair f g) s := by + (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (Prod.prodMk f g) s := by intro _ hx _ hy rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf hx hy) (hg hx hy) @@ -385,7 +385,7 @@ protected lemma comp {f : β → γ} {g : α → β} /-- If `f` and `g` are locally Lipschitz, so is the induced map `f × g` to the product type. -/ protected lemma prodMk {f : α → β} (hf : LocallyLipschitz f) {g : α → γ} (hg : LocallyLipschitz g) : - LocallyLipschitz Prod.pair f g := by + LocallyLipschitz Prod.prodMk f g := by intro x rcases hf x with ⟨Kf, t₁, h₁t, hfL⟩ rcases hg x with ⟨Kg, t₂, h₂t, hgL⟩ diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index 4e49c12ba6a043..5750b48ccdf738 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -1073,9 +1073,9 @@ lemma exists_is_open_mem_uniformity_of_forall_mem_eq end Uniform theorem Filter.Tendsto.congr_uniformity {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto g l (𝓝 b) := + (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (Prod.prodMk f g) l (𝓤 β)) : Tendsto g l (𝓝 b) := Uniform.tendsto_nhds_right.2 <| (Uniform.tendsto_nhds_right.1 hf).uniformity_trans hg theorem Uniform.tendsto_congr {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hfg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := + (hfg : Tendsto (Prod.prodMk f g) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := ⟨fun h => h.congr_uniformity hfg, fun h => h.congr_uniformity hfg.uniformity_symm⟩ diff --git a/MathlibTest/Continuity.lean b/MathlibTest/Continuity.lean index 1265cdf012cd77..f51d9cd6371166 100644 --- a/MathlibTest/Continuity.lean +++ b/MathlibTest/Continuity.lean @@ -51,7 +51,7 @@ example (b : Y) : Continuous (fun _ : X => b) := by continuity example (f : C(X, Y)) (g : C(Y, Z)) : Continuous (g ∘ f) := by continuity -example (f : C(X, Y)) (g : C(X, Z)) : Continuous (Prod.pair f g) := by continuity +example (f : C(X, Y)) (g : C(X, Z)) : Continuous (Prod.prodMk f g) := by continuity example (f : C(X, Y)) (g : C(W, Z)) : Continuous (Prod.map f g) := by continuity diff --git a/MathlibTest/fun_prop.lean b/MathlibTest/fun_prop.lean index b3b81ad2343da8..3be0933dc4e0b3 100644 --- a/MathlibTest/fun_prop.lean +++ b/MathlibTest/fun_prop.lean @@ -50,7 +50,7 @@ Let's mark the product constructor. -/ attribute [fun_prop] - Measurable.prodMk -- Measurable f → Measurable g → Measurable Prod.pair f g + Measurable.prodMk -- Measurable f → Measurable g → Measurable Prod.prodMk f g /-! When it comes to product projection, their properties are usually stated in two different ways From 72061fe520c8a3e210454ec1f08b476b34a44d71 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 18:50:47 +0100 Subject: [PATCH 08/35] Fix file --- Mathlib/Data/Set/Prod.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 6543f0eda86817..666015c2f41a44 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -239,7 +239,7 @@ theorem prod_univ_range_eq {m₂ : β → δ} : ext <| by simp [range] theorem range_pair_subset (f : α → β) (g : α → γ) : - (range Prod.prodMk f g) ⊆ range f ×ˢ range g := by grind + (range (Prod.prodMk f g)) ⊆ range f ×ˢ range g := by grind theorem Nonempty.prod : s.Nonempty → t.Nonempty → (s ×ˢ t).Nonempty := fun ⟨x, hx⟩ ⟨y, hy⟩ => ⟨(x, y), ⟨hx, hy⟩⟩ From 35640a759a390c3107c4948f3ee188c4c603c332 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 23:40:34 +0100 Subject: [PATCH 09/35] Add updates --- Mathlib.lean | 1 + Mathlib/Algebra/FiniteSupport/Basic.lean | 2 +- Mathlib/Algebra/Notation/Pi/Defs.lean | 8 -- Mathlib/Algebra/Ring/Prod.lean | 4 +- Mathlib/Algebra/Star/StarAlgHom.lean | 2 +- .../Analysis/SpecialFunctions/Pow/Deriv.lean | 6 +- Mathlib/Data/Bool/Init.lean | 26 ++++++ Mathlib/Data/Int/Cast/Prod.lean | 2 +- Mathlib/Data/Nat/Cast/Prod.lean | 2 +- Mathlib/Data/Prod/Basic.lean | 10 +++ Mathlib/Data/Prod/Init.lean | 83 +++++++++++------ Mathlib/Data/Set/Prod.lean | 6 +- Mathlib/Data/Sum/Init.lean | 5 ++ .../Manifold/ContMDiff/Constructions.lean | 16 ++-- Mathlib/Geometry/Manifold/ContMDiffMap.lean | 2 +- Mathlib/Logic/Equiv/Prod.lean | 90 ++++++++++--------- Mathlib/Logic/Function/Basic.lean | 2 + Mathlib/MeasureTheory/Function/AEEqFun.lean | 6 +- .../Function/L1Space/Integrable.lean | 2 +- .../AEStronglyMeasurable.lean | 2 +- .../Function/StronglyMeasurable/Basic.lean | 2 +- .../MeasureTheory/Measure/AEMeasurable.lean | 2 +- Mathlib/Order/Basic.lean | 6 +- Mathlib/Order/Filter/Basic.lean | 2 +- Mathlib/Order/Hom/Basic.lean | 2 +- Mathlib/Order/Monotone/Defs.lean | 4 +- Mathlib/Order/ScottContinuity.lean | 4 +- .../Probability/Kernel/Composition/Prod.lean | 2 +- .../Algebra/InfiniteSum/Constructions.lean | 2 +- Mathlib/Topology/Constructions/SumProd.lean | 6 +- Mathlib/Topology/ContinuousOn.lean | 4 +- Mathlib/Topology/EMetricSpace/Lipschitz.lean | 6 +- Mathlib/Topology/UniformSpace/Basic.lean | 4 +- MathlibTest/Continuity.lean | 2 +- MathlibTest/fun_prop.lean | 2 +- 35 files changed, 200 insertions(+), 127 deletions(-) create mode 100644 Mathlib/Data/Bool/Init.lean diff --git a/Mathlib.lean b/Mathlib.lean index fe77d44fb3e16b..344861f24feb29 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3652,6 +3652,7 @@ public import Mathlib.Data.BitVec public import Mathlib.Data.Bool.AllAny public import Mathlib.Data.Bool.Basic public import Mathlib.Data.Bool.Count +public import Mathlib.Data.Bool.Init public import Mathlib.Data.Bool.Set public import Mathlib.Data.Bracket public import Mathlib.Data.Bundle diff --git a/Mathlib/Algebra/FiniteSupport/Basic.lean b/Mathlib/Algebra/FiniteSupport/Basic.lean index 53fe058883ecbc..d810f395f483d1 100644 --- a/Mathlib/Algebra/FiniteSupport/Basic.lean +++ b/Mathlib/Algebra/FiniteSupport/Basic.lean @@ -55,7 +55,7 @@ lemma HasFiniteMulSupport.snd {M' : Type*} [One M'] {f : α → M × M'} (hf : H @[to_additive (attr := fun_prop)] lemma HasFiniteMulSupport.prodMk {M' : Type*} [One M'] {f : α → M} {g : α → M'} (hf : HasFiniteMulSupport f) (hg : HasFiniteMulSupport g) : - HasFiniteMulSupport (Prod.prodMk f g) := by + HasFiniteMulSupport (Prod.pair f g) := by simp only [HasFiniteMulSupport] at hf hg ⊢ rw [mulSupport_prodMk f g] exact hf.union hg diff --git a/Mathlib/Algebra/Notation/Pi/Defs.lean b/Mathlib/Algebra/Notation/Pi/Defs.lean index 56fb6e87726968..68580139f65f3e 100644 --- a/Mathlib/Algebra/Notation/Pi/Defs.lean +++ b/Mathlib/Algebra/Notation/Pi/Defs.lean @@ -26,14 +26,6 @@ variable {ι α β : Type*} {G M R : ι → Type*} namespace Pi --- TODO: Do we really need this definition? If so, where to put it? -/-- The mapping into a product type built from maps into each component. -/ -@[simp] -protected def prod {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : α i × β i := (f i, g i) - -lemma prod_fst_snd : Pi.prod (Prod.fst : α × β → α) (Prod.snd : α × β → β) = id := rfl -lemma prod_snd_fst : Pi.prod (Prod.snd : α × β → β) (Prod.fst : α × β → α) = .swap := rfl - /-! `1`, `0`, `+`, `*`, `+ᵥ`, `•`, `^`, `-`, `⁻¹`, and `/` are defined pointwise. -/ section One diff --git a/Mathlib/Algebra/Ring/Prod.lean b/Mathlib/Algebra/Ring/Prod.lean index f2be9ffe9eae2a..33289f939e02ab 100644 --- a/Mathlib/Algebra/Ring/Prod.lean +++ b/Mathlib/Algebra/Ring/Prod.lean @@ -132,7 +132,7 @@ variable [NonUnitalNonAssocSemiring T] (f : R →ₙ+* S) (g : R →ₙ+* T) `f.prod g : R →ₙ+* S × T` given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →ₙ+* S) (g : R →ₙ+* T) : R →ₙ+* S × T := { MulHom.prod (f : MulHom R S) (g : MulHom R T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := Prod.prodMk f g } + toFun := Prod.pair f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := @@ -208,7 +208,7 @@ variable [NonAssocSemiring T] (f : R →+* S) (g : R →+* T) given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →+* S) (g : R →+* T) : R →+* S × T := { MonoidHom.prod (f : R →* S) (g : R →* T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := Prod.prodMk f g } + toFun := Prod.pair f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := diff --git a/Mathlib/Algebra/Star/StarAlgHom.lean b/Mathlib/Algebra/Star/StarAlgHom.lean index 2ef669e39999ad..0d011f9cdb86b4 100644 --- a/Mathlib/Algebra/Star/StarAlgHom.lean +++ b/Mathlib/Algebra/Star/StarAlgHom.lean @@ -593,7 +593,7 @@ variable {R A B C} /-- The `Pi.prod` of two morphisms is a morphism. -/ @[simps!] def prod (f : A →⋆ₐ[R] B) (g : A →⋆ₐ[R] C) : A →⋆ₐ[R] B × C := - { f.toAlgHom.prod g.toAlgHom with map_star' := fun x => by simp [Prod.star_def, map_star] } + { f.toAlgHom.prod g.toAlgHom with map_star' := by simp [Prod.star_def, map_star, Prod.ext_iff] } theorem coe_prod (f : A →⋆ₐ[R] B) (g : A →⋆ₐ[R] C) : ⇑(f.prod g) = Pi.prod f g := rfl diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean index c007c707438c5c..0f9967c2ea2e97 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean @@ -85,7 +85,7 @@ theorem HasStrictFDerivAt.const_cpow (hf : HasStrictFDerivAt f f' x) (h0 : c ≠ theorem HasFDerivAt.cpow (hf : HasFDerivAt f f' x) (hg : HasFDerivAt g g' x) (h0 : f x ∈ slitPlane) : HasFDerivAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') x := by - convert (@Complex.hasFDerivAt_cpow ((Prod.prodMk f g) x) h0).comp x (hf.prodMk hg) + convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp x (hf.prodMk hg) theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x ≠ 0) : HasFDerivAt (fun x => c ^ f x) ((c ^ f x * Complex.log c) • f') x := @@ -94,7 +94,7 @@ theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x theorem HasFDerivWithinAt.cpow (hf : HasFDerivWithinAt f f' s x) (hg : HasFDerivWithinAt g g' s x) (h0 : f x ∈ slitPlane) : HasFDerivWithinAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') s x := by - convert (@Complex.hasFDerivAt_cpow ((Prod.prodMk f g) x) h0).comp_hasFDerivWithinAt x + convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp_hasFDerivWithinAt x (hf.prodMk hg) theorem HasFDerivWithinAt.const_cpow (hf : HasFDerivWithinAt f f' s x) (h0 : c ≠ 0 ∨ f x ≠ 0) : @@ -387,7 +387,7 @@ theorem differentiableAt_rpow_of_ne (p : ℝ × ℝ) (hp : p.1 ≠ 0) : theorem _root_.HasStrictDerivAt.rpow {f g : ℝ → ℝ} {f' g' : ℝ} (hf : HasStrictDerivAt f f' x) (hg : HasStrictDerivAt g g' x) (h : 0 < f x) : HasStrictDerivAt (fun x => f x ^ g x) (f' * g x * f x ^ (g x - 1) + g' * f x ^ g x * Real.log (f x)) x := by - convert (hasStrictFDerivAt_rpow_of_pos ((Prod.prodMk f g) x) h).comp_hasStrictDerivAt x + convert (hasStrictFDerivAt_rpow_of_pos ((Prod.pair f g) x) h).comp_hasStrictDerivAt x (hf.prodMk hg) using 1 simp [mul_assoc, mul_comm] diff --git a/Mathlib/Data/Bool/Init.lean b/Mathlib/Data/Bool/Init.lean new file mode 100644 index 00000000000000..503874b50e1646 --- /dev/null +++ b/Mathlib/Data/Bool/Init.lean @@ -0,0 +1,26 @@ +/- +Copyright (c) 2026 Wrenna Robson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Wrenna Robson +-/ +module + +public import Mathlib.Init + +/-! + +This file gives theorems about Bool that could be upstreamed. + +This file should not depend on anything defined in Mathlib (except for notation), so that it can be +upstreamed to Batteries or the Lean standard library easily. + +-/ + +@[expose] public section + +namespace Bool + +theorem cond_apply {α β} (f g : α → β) {b : Bool} {a : α} : + (bif b then f else g) a = bif b then f a else g a := by cases b <;> rfl + +end Bool diff --git a/Mathlib/Data/Int/Cast/Prod.lean b/Mathlib/Data/Int/Cast/Prod.lean index 6c82f03243934c..f92d160a1d13e3 100644 --- a/Mathlib/Data/Int/Cast/Prod.lean +++ b/Mathlib/Data/Int/Cast/Prod.lean @@ -22,7 +22,7 @@ variable {α β : Type*} [AddGroupWithOne α] [AddGroupWithOne β] instance : AddGroupWithOne (α × β) := { Prod.instAddMonoidWithOne, Prod.instAddGroup with - intCast := Prod.prodMk IntCast.intCast IntCast.intCast + intCast := Prod.pair IntCast.intCast IntCast.intCast intCast_ofNat := fun _ => by ext <;> simp intCast_negSucc := fun _ => by ext <;> simp } diff --git a/Mathlib/Data/Nat/Cast/Prod.lean b/Mathlib/Data/Nat/Cast/Prod.lean index 4adb77e3ac7001..78627dbbdbe413 100644 --- a/Mathlib/Data/Nat/Cast/Prod.lean +++ b/Mathlib/Data/Nat/Cast/Prod.lean @@ -25,7 +25,7 @@ variable [AddMonoidWithOne α] [AddMonoidWithOne β] instance instAddMonoidWithOne : AddMonoidWithOne (α × β) := { Prod.instAddMonoid, @Prod.instOne α β _ _ with - natCast := Prod.prodMk NatCast.natCast NatCast.natCast + natCast := Prod.pair NatCast.natCast NatCast.natCast natCast_zero := congr_arg₂ Prod.mk Nat.cast_zero Nat.cast_zero natCast_succ := fun _ => congr_arg₂ Prod.mk (Nat.cast_succ _) (Nat.cast_succ _) } diff --git a/Mathlib/Data/Prod/Basic.lean b/Mathlib/Data/Prod/Basic.lean index afaeaafe82632a..1e853d9e9aee6c 100644 --- a/Mathlib/Data/Prod/Basic.lean +++ b/Mathlib/Data/Prod/Basic.lean @@ -9,6 +9,7 @@ public import Lean.PrettyPrinter.Delaborator.Builtins public import Mathlib.Logic.Function.Defs public import Mathlib.Logic.Function.Iterate public import Mathlib.Tactic.Inhabit +public import Mathlib.Data.Prod.Init public import Batteries.Tactic.Trans import Mathlib.Tactic.Attr.Register @@ -22,6 +23,15 @@ It also defines better delaborators for product projections. @[expose] public section +namespace Pi + +variable {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) {c} + +@[simp] theorem fst_dcomp_pair : Prod.fst ∘' Pi.prod f g = f := rfl +@[simp] theorem snd_dcomp_pair : Prod.snd ∘' Pi.prod f g = g := rfl + +end Pi + variable {α : Type*} {β : Type*} {γ : Type*} {δ : Type*} namespace Prod diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index 0039c65c61efc2..f86733eb19a761 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -9,7 +9,7 @@ public import Mathlib.Init /-! -This file defines `Prod.prodMk f g`, the operation that prodMks two functions `f : γ → α` and +This file defines `Prod.pair f g`, the operation that pairs two functions `f : γ → α` and `g : γ → β` into a function `γ → α × β`. It also defines the special case when `f = g = id`, `Prod.diag`. This is the canonical injection @@ -23,58 +23,89 @@ upstreamed to Batteries or the Lean standard library easily. @[expose] public section -namespace Prod +namespace Pi + +/-- The mapping into a product type built from maps into each component. -/ +protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) : ∀ i, α i × β i := + fun i ↦ (f i, g i) + +section + +variable {ι} {α β : ι → Type*} (f f' : ∀ i, α i) (g g' : ∀ i, β i) {c} + +@[grind =] theorem prod_apply : Pi.prod f g c = (f c, g c) := rfl + +@[simp] theorem fst_prod : (Pi.prod f g c).fst = f c := rfl +@[simp] theorem snd_prod : (Pi.prod f g c).snd = g c := rfl + +lemma prod_fst_snd {α β} : Pi.prod (Prod.fst : _ → α) (Prod.snd : _ → β) = id := rfl +lemma prod_snd_fst {α β} : Pi.prod (Prod.snd : _ → β) (Prod.fst : _ → α) = .swap := rfl -universe u₁ u₂ u₃ u₄ u₅ +theorem blahj {ι : Type*} {β γ : ι → Type*} {h : ∀ i, β i × γ i} : + Pi.prod (Prod.fst <| h ·) (Prod.snd <| h ·) = h := rfl -variable {α : Type u₁} {β : Type u₂} {γ : Sort u₃} {δ : Type u₄} {ε : Type u₅} +--(Pi.prod (fun x1 x2 ↦ (x1 x2).fst) (fun x1 x2 ↦ (x1 x2).snd) h) +theorem prod_eq_iff : Pi.prod f g = Pi.prod f' g' ↔ f = f' ∧ g = g' := by + simp [funext_iff, Prod.ext_iff, forall_and] + +end + +end Pi + +namespace Prod + +variable {α β δ ε : Type*} {γ : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -@[expose] protected def prodMk (f : γ → α) (g : γ → β) : γ → α × β := fun a ↦ (f a, g a) +protected def pair (f : γ → α) (g : γ → β) : γ → α × β := Pi.prod f g section variable (f : γ → α) (g : γ → β) -@[grind =] theorem prodMk_apply (c : γ) : Prod.prodMk f g c = (f c, g c) := rfl +@[grind =] theorem pair_apply (c : γ) : Prod.pair f g c = (f c, g c) := rfl -@[simp] theorem fst_prodMk {c} : (Prod.prodMk f g c).fst = f c := rfl -@[simp] theorem snd_prodMk {c} : (Prod.prodMk f g c).snd = g c := rfl +@[simp] theorem fst_pair {c} : (Prod.pair f g c).fst = f c := rfl +@[simp] theorem snd_pair {c} : (Prod.pair f g c).snd = g c := rfl -@[simp] theorem fst_comp_prodMk : fst ∘ Prod.prodMk f g = f := rfl -@[simp] theorem snd_comp_prodMk : snd ∘ Prod.prodMk f g = g := rfl -@[simp] theorem prodMk_fst_snd : @Prod.prodMk α β _ fst snd = id := rfl +@[simp] theorem fst_comp_pair : fst ∘ Prod.pair f g = f := rfl +@[simp] theorem snd_comp_pair : snd ∘ Prod.pair f g = g := rfl +@[simp] theorem pair_fst_snd : @Prod.pair α β _ fst snd = id := rfl -theorem prodMk_comp {δ} {h : δ → γ} : Prod.prodMk f g ∘ h = Prod.prodMk (f ∘ h) (g ∘ h) := rfl +theorem pair_comp {δ} {h : δ → γ} : Prod.pair f g ∘ h = Prod.pair (f ∘ h) (g ∘ h) := rfl -@[simp] theorem prodMk_fst_snd_comp {f : γ → α × β} : Prod.prodMk (fst ∘ f) (snd ∘ f) = f := rfl +@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : Prod.pair (fst ∘ f) (snd ∘ f) = f := rfl -theorem prodMk_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.prodMk f g = Prod.prodMk f' g' ↔ +theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.pair f g = Prod.pair f' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] +theorem injective_uncurry_pair : Function.Injective <| + (Prod.pair (α := α) (β := β) (γ := δ)).uncurry := by + simp [Function.Injective, funext_iff, Prod.ext_iff]; grind + @[grind =] -theorem prodMk_const_const (a : α) (b : β) : - Prod.prodMk (Function.const γ a) (Function.const γ b) = Function.const γ (a, b) := rfl +theorem pair_const_const (a : α) (b : β) : + Prod.pair (Function.const γ a) (Function.const γ b) = Function.const γ (a, b) := rfl end section -/- We can define `Prod.map` in terms of `Prod.prodMk`. -/ -theorem map_eq_prodMk {f : α → β} {g : δ → ε} : Prod.map f g = - Prod.prodMk (f ∘ fst) (g ∘ snd) := rfl +/- We can define `Prod.map` in terms of `Prod.pair`. -/ +theorem map_eq_pair {f : α → β} {g : δ → ε} : Prod.map f g = + Prod.pair (f ∘ fst) (g ∘ snd) := rfl @[grind _=_] -theorem map_prodMk {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : - Prod.map f h (Prod.prodMk g k c) = Prod.prodMk (f ∘ g) (h ∘ k) c := rfl +theorem map_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : + Prod.map f h (Prod.pair g k c) = Prod.pair (f ∘ g) (h ∘ k) c := rfl -theorem map_comp_prodMk {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : - Prod.map f h ∘ Prod.prodMk g k = Prod.prodMk (f ∘ g) (h ∘ k) := rfl +theorem map_comp_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : + Prod.map f h ∘ Prod.pair g k = Prod.pair (f ∘ g) (h ∘ k) := rfl end /-- The diagonal map into Prod. -/ -@[expose] protected def diag : α → α × α := Prod.prodMk id id +@[expose] protected def diag : α → α × α := Prod.pair id id section @@ -86,9 +117,9 @@ variable {a b : α} @[simp, grind =] theorem snd_diag : (Prod.diag a).2 = a := rfl @[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Prod.diag a) = - Prod.prodMk f g a := rfl + Prod.pair f g a := rfl -theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = Prod.prodMk f g := rfl +theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = Prod.pair f g := rfl theorem injective_diag : Function.Injective (Prod.diag (α := α)) := fun _ _ => congrArg fst diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 666015c2f41a44..d1d3f956ee6d52 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -180,7 +180,7 @@ theorem preimage_prod_map_prod (f : α → β) (g : γ → δ) (s : Set β) (t : rfl theorem mk_preimage_prod (f : γ → α) (g : γ → β) : - (Prod.prodMk f g) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := + (Prod.pair f g) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := rfl @[simp] @@ -239,7 +239,7 @@ theorem prod_univ_range_eq {m₂ : β → δ} : ext <| by simp [range] theorem range_pair_subset (f : α → β) (g : α → γ) : - (range (Prod.prodMk f g)) ⊆ range f ×ˢ range g := by grind + (range (Prod.pair f g)) ⊆ range f ×ˢ range g := by grind theorem Nonempty.prod : s.Nonempty → t.Nonempty → (s ×ˢ t).Nonempty := fun ⟨x, hx⟩ ⟨y, hy⟩ => ⟨(x, y), ⟨hx, hy⟩⟩ @@ -260,7 +260,7 @@ theorem prod_sub_preimage_iff {W : Set γ} {f : α × β → γ} : s ×ˢ t ⊆ f ⁻¹' W ↔ ∀ a b, a ∈ s → b ∈ t → f (a, b) ∈ W := by simp [subset_def] theorem image_prodMk_subset_prod {f : α → β} {g : α → γ} {s : Set α} : - (Prod.prodMk f g) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind + (Prod.pair f g) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind theorem image_prodMk_subset_prod_left (hb : b ∈ t) : (fun a => (a, b)) '' s ⊆ s ×ˢ t := by grind diff --git a/Mathlib/Data/Sum/Init.lean b/Mathlib/Data/Sum/Init.lean index 4d41a122c9e40b..a2155b28984d40 100644 --- a/Mathlib/Data/Sum/Init.lean +++ b/Mathlib/Data/Sum/Init.lean @@ -24,6 +24,11 @@ universe u₁ u₂ u₃ u₄ variable {α : Type u₁} {β : Type u₂} {γ : Sort u₃} {δ : Type u₄} +def cases {γ : α ⊕ β → Sort u₃} (f : (a : α) → γ (inl a)) (g : (b : β) → γ (inr b)) + (x : α ⊕ β) : γ x := x.casesOn f g + +theorem elim_eq_cases {f : α → γ} {g : β → γ} : Sum.elim f g = Sum.cases f g := rfl + theorem elim_apply_of_isLeft {f : α → γ} {g : β → γ} {x} (h : x.isLeft) : Sum.elim f g x = f (x.getLeft h) := by grind diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean index b98174878c08b4..cc9dcb1dcf2060 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean @@ -55,39 +55,39 @@ section ProdMk theorem ContMDiffWithinAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffWithinAt I I' n f s x) (hg : ContMDiffWithinAt I J' n g s x) : - ContMDiffWithinAt I (I'.prod J') n (Prod.prodMk f g) s x := by + ContMDiffWithinAt I (I'.prod J') n (Prod.pair f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem ContMDiffWithinAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffWithinAt I 𝓘(𝕜, E') n f s x) (hg : ContMDiffWithinAt I 𝓘(𝕜, F') n g s x) : - ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (Prod.prodMk f g) s x := by + ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ nonrec theorem ContMDiffAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffAt I I' n f x) - (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (Prod.prodMk f g) x := + (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (Prod.pair f g) x := hf.prodMk hg nonrec theorem ContMDiffAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffAt I 𝓘(𝕜, E') n f x) (hg : ContMDiffAt I 𝓘(𝕜, F') n g x) : - ContMDiffAt I 𝓘(𝕜, E' × F') n (Prod.prodMk f g) x := + ContMDiffAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) x := hf.prodMk_space hg theorem ContMDiffOn.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffOn I I' n f s) - (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (Prod.prodMk f g) s := + (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (Prod.pair f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem ContMDiffOn.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffOn I 𝓘(𝕜, E') n f s) - (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (Prod.prodMk f g) s := + (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (Prod.pair f g) s := fun x hx => (hf x hx).prodMk_space (hg x hx) nonrec theorem ContMDiff.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiff I I' n f) - (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n Prod.prodMk f g := fun x => + (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n Prod.pair f g := fun x => (hf x).prodMk (hg x) theorem ContMDiff.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiff I 𝓘(𝕜, E') n f) - (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n Prod.prodMk f g := fun x => + (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n Prod.pair f g := fun x => (hf x).prodMk_space (hg x) end ProdMk diff --git a/Mathlib/Geometry/Manifold/ContMDiffMap.lean b/Mathlib/Geometry/Manifold/ContMDiffMap.lean index 721eea8c5bdae8..5ed3ded179099c 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMap.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMap.lean @@ -106,7 +106,7 @@ def snd : C^n⟮I.prod I', M × M'; I', M'⟯ := /-- Given two `C^n` maps `f` and `g`, this is the `C^n` map `x ↦ (f x, g x)`. -/ def prodMk (f : C^n⟮J, N; I, M⟯) (g : C^n⟮J, N; I', M'⟯) : C^n⟮J, N; I.prod I', M × M'⟯ := - ⟨Prod.prodMk f g, f.2.prodMk g.2⟩ + ⟨Prod.pair f g, f.2.prodMk g.2⟩ end ContMDiffMap diff --git a/Mathlib/Logic/Equiv/Prod.lean b/Mathlib/Logic/Equiv/Prod.lean index b5fceded97edfb..589bd2fe48bc3c 100644 --- a/Mathlib/Logic/Equiv/Prod.lean +++ b/Mathlib/Logic/Equiv/Prod.lean @@ -7,6 +7,9 @@ module public import Mathlib.Logic.Equiv.Defs public import Mathlib.Tactic.Contrapose +public import Mathlib.Data.Prod.Init +public import Mathlib.Data.Sum.Init +public import Mathlib.Data.Bool.Init /-! # Equivalence between product types @@ -338,56 +341,59 @@ section /-- The type of functions to a product `β × γ` is equivalent to the type of pairs of functions `α → β` and `β → γ`. -/ -@[simps] -def arrowProdEquivProdArrow (α : Type*) (β γ : α → Type*) : - ((i : α) → β i × γ i) ≃ ((i : α) → β i) × ((i : α) → γ i) where - toFun := fun f => (fun c => (f c).1, fun c => (f c).2) - invFun := fun p c => (p.1 c, p.2 c) +@[simps! (attr := grind =)] +def arrowProdEquivProdArrow (α β γ : Type*) : (α → β × γ) ≃ (α → β) × (α → γ) where + toFun := Prod.pair (Prod.fst <| · ·) (Prod.snd <| · ·) + invFun := Prod.pair.uncurry + +/-- The type of a pi-type indexed by `i : ι` to products `β i × γ i` is equivalent to product of two +pi-types `∀ i, β i` and `∀ i, γ i`. This is a dependent version of +`Equiv.arrowProdEquivProdArrow`. -/ +@[simps! (attr := grind =)] +def piProdEquivProdPi (α : Type*) (β γ : α → Type*) : + (∀ i, β i × γ i) ≃ (∀ i, β i) × (∀ i, γ i) where + toFun := Prod.pair (Prod.fst <| · ·) (Prod.snd <| · ·) + invFun := Pi.prod.uncurry open Sum +/-- The type of functions on a sum type `α ⊕ β` is equivalent to the type of pairs of functions +on `α` and on `β`. -/ +@[simps! (attr := grind =)] +def sumArrowEquivProdArrow (α β γ : Type*) : (α ⊕ β → γ) ≃ (α → γ) × (β → γ) where + toFun := Prod.pair (· <| inl ·) (· <| inr ·) + invFun := Sum.elim.uncurry + left_inv f := by ext (i | i) <;> rfl + +@[deprecated sumArrowEquivProdArrow_symm_apply (since := "2026-04-03")] +theorem sumArrowEquivProdArrow_symm_apply_inl {α β γ} (f : α → γ) (g : β → γ) (a : α) : + ((sumArrowEquivProdArrow α β γ).symm (f, g)) (inl a) = f a := by + apply sumArrowEquivProdArrow_symm_apply + +@[deprecated sumArrowEquivProdArrow_symm_apply (since := "2026-04-03")] +theorem sumArrowEquivProdArrow_symm_apply_inr {α β γ} (f : α → γ) (g : β → γ) (b : β) : + ((sumArrowEquivProdArrow α β γ).symm (f, g)) (inr b) = g b := by + apply sumArrowEquivProdArrow_symm_apply + /-- The type of dependent functions on a sum type `ι ⊕ ι'` is equivalent to the type of pairs of functions on `ι` and on `ι'`. This is a dependent version of `Equiv.sumArrowEquivProdArrow`. -/ @[simps (attr := grind =)] def sumPiEquivProdPi {ι ι'} (π : ι ⊕ ι' → Type*) : (∀ i, π i) ≃ (∀ i, π (inl i)) × ∀ i', π (inr i') where - toFun f := ⟨fun i => f (inl i), fun i' => f (inr i')⟩ - invFun g := Sum.rec g.1 g.2 + toFun := Prod.pair (· <| inl ·) (· <| inr ·) + invFun := Sum.rec.uncurry left_inv f := by ext (i | i) <;> rfl /-- The equivalence between a product of two dependent functions types and a single dependent function type. Basically a symmetric version of `Equiv.sumPiEquivProdPi`. -/ @[simps! (attr := grind =)] def prodPiEquivSumPi {ι ι'} (π : ι → Type u) (π' : ι' → Type u) : - ((∀ i, π i) × ∀ i', π' i') ≃ ∀ i, Sum.elim π π' i := + ((∀ i, π i) × ∀ i', π' i') ≃ ∀ i : ι ⊕ ι', i.elim π π' := sumPiEquivProdPi (Sum.elim π π') |>.symm -/-- The type of functions on a sum type `α ⊕ β` is equivalent to the type of pairs of functions -on `α` and on `β`. -/ -def sumArrowEquivProdArrow (α β γ : Type*) : (α ⊕ β → γ) ≃ (α → γ) × (β → γ) := - ⟨fun f => (f ∘ inl, f ∘ inr), fun p => Sum.elim p.1 p.2, fun f => by ext ⟨⟩ <;> rfl, fun p => by - cases p - rfl⟩ - -@[simp, grind =] -theorem sumArrowEquivProdArrow_apply_fst {α β γ} (f : α ⊕ β → γ) (a : α) : - (sumArrowEquivProdArrow α β γ f).1 a = f (inl a) := - rfl - -@[simp, grind =] -theorem sumArrowEquivProdArrow_apply_snd {α β γ} (f : α ⊕ β → γ) (b : β) : - (sumArrowEquivProdArrow α β γ f).2 b = f (inr b) := - rfl - -@[simp, grind =] -theorem sumArrowEquivProdArrow_symm_apply_inl {α β γ} (f : α → γ) (g : β → γ) (a : α) : - ((sumArrowEquivProdArrow α β γ).symm (f, g)) (inl a) = f a := - rfl - -@[simp, grind =] -theorem sumArrowEquivProdArrow_symm_apply_inr {α β γ} (f : α → γ) (g : β → γ) (b : β) : - ((sumArrowEquivProdArrow α β γ).symm (f, g)) (inr b) = g b := - rfl +def piProdEquivSumPi (α : Type*) (β γ : α → Type u) : + (∀ i, β i × γ i) ≃ ∀ i : α ⊕ α, i.elim β γ := + (piProdEquivProdPi _ _ _).trans (prodPiEquivSumPi _ _) /-- Type product is right distributive with respect to type sum up to an equivalence. -/ def sumProdDistrib (α β γ) : (α ⊕ β) × γ ≃ α × γ ⊕ β × γ := @@ -423,18 +429,18 @@ def sigmaProdDistrib {ι : Type*} (α : ι → Type*) (β : Type*) : (Σ i, α i /-- The product `Bool × α` is equivalent to `α ⊕ α`. -/ @[simps (attr := grind =)] -def boolProdEquivSum (α) : Bool × α ≃ α ⊕ α where - toFun p := if p.1 then (inr p.2) else (inl p.2) - invFun := Sum.elim (Prod.mk false) (Prod.mk true) - left_inv := by rintro ⟨_ | _, _⟩ <;> rfl - right_inv := by rintro (_ | _) <;> rfl +def boolProdEquivSum (α : Type*) : Bool × α ≃ α ⊕ α where + toFun := (cond · inr inl).uncurry + invFun := Prod.pair Sum.isRight Sum.get + left_inv := by grind + right_inv := by grind /-- The function type `Bool → α` is equivalent to `α × α`. -/ @[simps (attr := grind =)] def boolArrowEquivProd (α : Type*) : (Bool → α) ≃ α × α where - toFun f := (f false, f true) - invFun p b := if b then p.2 else p.1 - left_inv _ := by grind + toFun := Prod.pair (· false) (· true) + invFun := flip (cond · Prod.snd Prod.fst ·) + left_inv _ := by grind [flip] end diff --git a/Mathlib/Logic/Function/Basic.lean b/Mathlib/Logic/Function/Basic.lean index 44534ad0ffc944..06428a1d7597ee 100644 --- a/Mathlib/Logic/Function/Basic.lean +++ b/Mathlib/Logic/Function/Basic.lean @@ -830,6 +830,8 @@ section CurryAndUncurry theorem uncurry_def {α β γ} (f : α → β → γ) : uncurry f = fun p ↦ f p.1 p.2 := rfl +@[simp] theorem uncurry_apply {α β γ} (f : α → β → γ) (p : α × β) : uncurry f p = f p.1 p.2 := rfl + theorem uncurry_injective {α β γ} : Function.Injective (uncurry : (α → β → γ) → _) := LeftInverse.injective curry_uncurry diff --git a/Mathlib/MeasureTheory/Function/AEEqFun.lean b/Mathlib/MeasureTheory/Function/AEEqFun.lean index 90cee565b5a0a4..6241ed016179f5 100644 --- a/Mathlib/MeasureTheory/Function/AEEqFun.lean +++ b/Mathlib/MeasureTheory/Function/AEEqFun.lean @@ -397,15 +397,15 @@ def pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : α →ₘ[μ] β × γ @[simp] theorem pair_mk_mk (f : α → β) (hf) (g : α → γ) (hg) : - (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (Prod.prodMk f g) (hf.prodMk hg) := + (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (Prod.pair f g) (hf.prodMk hg) := rfl theorem pair_eq_mk (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g = - mk (Prod.prodMk f g) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by + mk (Prod.pair f g) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by simp only [← pair_mk_mk, mk_coeFn, f.aestronglyMeasurable, g.aestronglyMeasurable] -theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] Prod.prodMk f g := by +theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] Prod.pair f g := by rw [pair_eq_mk] apply coeFn_mk diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 9000172232a3c9..5c237bb54bdaf9 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -640,7 +640,7 @@ lemma integrable_of_le_of_le {f g₁ g₂ : α → ℝ} (hf : AEStronglyMeasurab -- TODO: generalising this to enorms requires defining a product instance for enormed monoids first @[fun_prop] theorem Integrable.prodMk {f : α → β} {g : α → γ} (hf : Integrable f μ) (hg : Integrable g μ) : - Integrable (Prod.prodMk f g) μ := + Integrable (Prod.pair f g) μ := ⟨by fun_prop, (hf.norm.add' hg.norm).mono <| Eventually.of_forall fun x => diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index ffa3977aa488ae..88cc6e2a8b4f5a 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -229,7 +229,7 @@ protected theorem snd {f : α → β × γ} (hf : AEStronglyMeasurable[m] f μ) @[fun_prop] protected theorem prodMk {f : α → β} {g : α → γ} (hf : AEStronglyMeasurable[m] f μ) - (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (Prod.prodMk f g) μ := + (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (Prod.pair f g) μ := ⟨fun x => (hf.mk f x, hg.mk g x), hf.stronglyMeasurable_mk.prodMk hg.stronglyMeasurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 672b187b1eccaf..af077ea96e0b55 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -352,7 +352,7 @@ protected theorem snd {m : MeasurableSpace α} [TopologicalSpace β] [Topologica @[fun_prop] protected theorem prodMk {m : MeasurableSpace α} [TopologicalSpace β] [TopologicalSpace γ] {f : α → β} {g : α → γ} (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : - StronglyMeasurable Prod.prodMk f g := by + StronglyMeasurable Prod.pair f g := by refine ⟨fun n => SimpleFunc.pair (hf.approx n) (hg.approx n), fun x => ?_⟩ rw [nhds_prod_eq] exact Tendsto.prodMk (hf.tendsto_approx x) (hg.tendsto_approx x) diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index cd72ead85dbe42..834a6479a1d262 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -190,7 +190,7 @@ protected theorem snd {f : α → β × γ} (hf : AEMeasurable f μ) : @[fun_prop] theorem prodMk {f : α → β} {g : α → γ} (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (Prod.prodMk f g) μ := + AEMeasurable (Prod.pair f g) μ := ⟨fun a => (hf.mk f a, hg.mk g a), hf.measurable_mk.prodMk hg.measurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 5319e2362e33fa..94d0c9102406a0 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -890,16 +890,16 @@ variable {α β₁ β₂ : Type*} [LE β₁] [LE β₂] @[simp] lemma prodMk_le_prodMk_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : - Prod.prodMk u₁ u₂ ≤ Prod.prodMk v₁ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by + Prod.pair u₁ u₂ ≤ Prod.pair v₁ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by simp [Pi.le_def, Prod.le_def, forall_and] lemma const_le_prodMk_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - Function.const _ b ≤ Prod.prodMk v₁ v₂ ↔ + Function.const _ b ≤ Prod.pair v₁ v₂ ↔ Function.const _ b.1 ≤ v₁ ∧ Function.const _ b.2 ≤ v₂ := prodMk_const_const b.1 b.2 ▸ prodMk_le_prodMk_iff .. lemma prodMk_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - Prod.prodMk v₁ v₂ ≤ Function.const _ b ↔ + Prod.pair v₁ v₂ ≤ Function.const _ b ↔ v₁ ≤ Function.const _ b.1 ∧ v₂ ≤ Function.const _ b.2 := prodMk_const_const b.1 b.2 ▸ prodMk_le_prodMk_iff .. diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index f738233c35cb16..a0e486e162de51 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -976,7 +976,7 @@ instance {l : Filter α} : trans := EventuallyEq.trans theorem EventuallyEq.prodMk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') : - (Prod.prodMk f g) =ᶠ[l] fun x => (f' x, g' x) := + (Prod.pair f g) =ᶠ[l] fun x => (f' x, g' x) := hf.mp <| hg.mono <| by intros diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 5a7308dc84b5e5..5b3e4f752e0845 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -369,7 +369,7 @@ theorem comp_const (γ : Type*) [Preorder γ] (f : α →o β) (c : α) : `OrderHom`. -/ @[simps] protected def prod (f : α →o β) (g : α →o γ) : α →o β × γ := - ⟨Prod.prodMk f g, fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ + ⟨Prod.pair f g, fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ @[mono, to_dual self] theorem prod_mono {f₁ f₂ : α →o β} (hf : f₁ ≤ f₂) {g₁ g₂ : α →o γ} (hg : g₁ ≤ g₂) : diff --git a/Mathlib/Order/Monotone/Defs.lean b/Mathlib/Order/Monotone/Defs.lean index 643afec9e98595..a7d7c60a76eb3f 100644 --- a/Mathlib/Order/Monotone/Defs.lean +++ b/Mathlib/Order/Monotone/Defs.lean @@ -507,11 +507,11 @@ theorem monotone_fst : Monotone (@Prod.fst α β) := fun _ _ ↦ And.left theorem monotone_snd : Monotone (@Prod.snd α β) := fun _ _ ↦ And.right theorem monotone_prodMk_iff {f : γ → α} {g : γ → β} : - Monotone (Prod.prodMk f g) ↔ Monotone f ∧ Monotone g := by + Monotone (Prod.pair f g) ↔ Monotone f ∧ Monotone g := by simp [Monotone, Prod.le_def, forall_and] theorem Monotone.prodMk {f : γ → α} {g : γ → β} (hf : Monotone f) (hg : Monotone g) : - Monotone (Prod.prodMk f g) := + Monotone (Prod.pair f g) := monotone_prodMk_iff.2 ⟨hf, hg⟩ theorem Monotone.prodMap (hf : Monotone f) (hg : Monotone g) : Monotone (Prod.map f g) := diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index 0dc0d38cc35e17..01702a3bce853e 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -106,7 +106,7 @@ theorem ScottContinuousOn.image_comp {g : β → γ} @[fun_prop] lemma ScottContinuousOn.prodMk {g : α → γ} (hD : ∀ a b : α, a ≤ b → {a, b} ∈ D) (hf : ScottContinuousOn D f) (hg : ScottContinuousOn D g) : - ScottContinuousOn D Prod.prodMk f g := fun d hd₁ hd₂ hd₃ a hda => by + ScottContinuousOn D Prod.pair f g := fun d hd₁ hd₂ hd₃ a hda => by rw [IsLUB, IsLeast, upperBounds] constructor · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, @@ -172,7 +172,7 @@ lemma ScottContinuous.comp {g : β → γ} @[fun_prop] lemma ScottContinuous.prodMk {g : α → γ} (hf : ScottContinuous f) (hg : ScottContinuous g) : - ScottContinuous Prod.prodMk f g := by + ScottContinuous Prod.pair f g := by rw [← scottContinuousOn_univ] at ⊢ hf hg exact ScottContinuousOn.prodMk (by grind) hf hg diff --git a/Mathlib/Probability/Kernel/Composition/Prod.lean b/Mathlib/Probability/Kernel/Composition/Prod.lean index ee46c515e5ed07..9d73c928a09356 100644 --- a/Mathlib/Probability/Kernel/Composition/Prod.lean +++ b/Mathlib/Probability/Kernel/Composition/Prod.lean @@ -216,7 +216,7 @@ lemma swap_prod {κ : Kernel α β} [IsSFiniteKernel κ] {η : Kernel α γ} [Is lemma deterministic_prod_deterministic {f : α → β} {g : α → γ} (hf : Measurable f) (hg : Measurable g) : deterministic f hf ×ₖ deterministic g hg - = deterministic (Prod.prodMk f g) (hf.prodMk hg) := by + = deterministic (Prod.pair f g) (hf.prodMk hg) := by ext; simp_rw [prod_apply, deterministic_apply, Measure.dirac_prod_dirac] lemma id_prod_eq : @Kernel.id (α × β) inferInstance = diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean b/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean index dd08bd9caf1a31..f231558c5ec702 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean @@ -67,7 +67,7 @@ section ProdCodomain variable [CommMonoid α] [TopologicalSpace α] [CommMonoid γ] [TopologicalSpace γ] @[to_additive HasSum.prodMk] -theorem HasProd.prodMk {f : β → α} {g : β → γ} {a : α} {b : γ} (hf : HasProd f a L) +theorem HasProd.pair {f : β → α} {g : β → γ} {a : α} {b : γ} (hf : HasProd f a L) (hg : HasProd g b L) : HasProd (fun x ↦ (⟨f x, g x⟩ : α × γ)) ⟨a, b⟩ L := by simp [HasProd, ← prod_mk_prod, Filter.Tendsto.prodMk_nhds hf hg] diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index cf6516152527df..fa9fb259541e97 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -61,7 +61,7 @@ variable [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z] [Topolog @[simp] theorem continuous_prodMk {f : X → Y} {g : X → Z} : - (Continuous Prod.prodMk f g) ↔ Continuous f ∧ Continuous g := + (Continuous Prod.pair f g) ↔ Continuous f ∧ Continuous g := continuous_inf_rng.trans <| continuous_induced_rng.and continuous_induced_rng @[continuity] @@ -138,7 +138,7 @@ theorem Filter.Tendsto.snd_nhds {X} {l : Filter X} {f : X → Y × Z} {p : Y × @[continuity, fun_prop] theorem Continuous.prodMk {f : Z → X} {g : Z → Y} (hf : Continuous f) (hg : Continuous g) : - Continuous Prod.prodMk f g := + Continuous Prod.pair f g := continuous_prodMk.2 ⟨hf, hg⟩ @[continuity] @@ -345,7 +345,7 @@ theorem Filter.Eventually.curry_nhds {p : X × Y → Prop} {x : X} {y : Y} @[fun_prop] theorem ContinuousAt.prodMk {f : X → Y} {g : X → Z} {x : X} (hf : ContinuousAt f x) - (hg : ContinuousAt g x) : ContinuousAt (Prod.prodMk f g) x := + (hg : ContinuousAt g x) : ContinuousAt (Prod.pair f g) x := hf.prodMk_nhds hg theorem ContinuousAt.prodMap {f : X → Z} {g : Y → W} {p : X × Y} (hf : ContinuousAt f p.fst) diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index 46d2dce9d9a330..bb9a5376b7afa8 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -577,12 +577,12 @@ theorem ContinuousOn.image_closure (hf : ContinuousOn f (closure s)) : theorem ContinuousWithinAt.prodMk {f : α → β} {g : α → γ} {s : Set α} {x : α} (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g s x) : - ContinuousWithinAt (Prod.prodMk f g) s x := + ContinuousWithinAt (Prod.pair f g) s x := hf.prodMk_nhds hg @[fun_prop] theorem ContinuousOn.prodMk {f : α → β} {g : α → γ} {s : Set α} (hf : ContinuousOn f s) - (hg : ContinuousOn g s) : ContinuousOn (Prod.prodMk f g) s := fun x hx => + (hg : ContinuousOn g s) : ContinuousOn (Prod.pair f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem continuousOn_fst {s : Set (α × β)} : ContinuousOn Prod.fst s := diff --git a/Mathlib/Topology/EMetricSpace/Lipschitz.lean b/Mathlib/Topology/EMetricSpace/Lipschitz.lean index ed41ec26a222c9..a7f7eb75343f2f 100644 --- a/Mathlib/Topology/EMetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/EMetricSpace/Lipschitz.lean @@ -244,7 +244,7 @@ protected theorem prod_snd : LipschitzWith 1 (@Prod.snd α β) := /-- If `f` and `g` are Lipschitz functions, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {f : α → β} {Kf : ℝ≥0} (hf : LipschitzWith Kf f) {g : α → γ} {Kg : ℝ≥0} - (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) Prod.prodMk f g := by + (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) Prod.pair f g := by intro x y rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf x y) (hg x y) @@ -331,7 +331,7 @@ protected theorem comp {g : β → γ} {t : Set β} {Kg : ℝ≥0} (hg : Lipschi /-- If `f` and `g` are Lipschitz on `s`, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {g : α → γ} {Kf Kg : ℝ≥0} (hf : LipschitzOnWith Kf f s) - (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (Prod.prodMk f g) s := by + (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (Prod.pair f g) s := by intro _ hx _ hy rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf hx hy) (hg hx hy) @@ -385,7 +385,7 @@ protected lemma comp {f : β → γ} {g : α → β} /-- If `f` and `g` are locally Lipschitz, so is the induced map `f × g` to the product type. -/ protected lemma prodMk {f : α → β} (hf : LocallyLipschitz f) {g : α → γ} (hg : LocallyLipschitz g) : - LocallyLipschitz Prod.prodMk f g := by + LocallyLipschitz Prod.pair f g := by intro x rcases hf x with ⟨Kf, t₁, h₁t, hfL⟩ rcases hg x with ⟨Kg, t₂, h₂t, hgL⟩ diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index 5750b48ccdf738..4e49c12ba6a043 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -1073,9 +1073,9 @@ lemma exists_is_open_mem_uniformity_of_forall_mem_eq end Uniform theorem Filter.Tendsto.congr_uniformity {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (Prod.prodMk f g) l (𝓤 β)) : Tendsto g l (𝓝 b) := + (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto g l (𝓝 b) := Uniform.tendsto_nhds_right.2 <| (Uniform.tendsto_nhds_right.1 hf).uniformity_trans hg theorem Uniform.tendsto_congr {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hfg : Tendsto (Prod.prodMk f g) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := + (hfg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := ⟨fun h => h.congr_uniformity hfg, fun h => h.congr_uniformity hfg.uniformity_symm⟩ diff --git a/MathlibTest/Continuity.lean b/MathlibTest/Continuity.lean index f51d9cd6371166..1265cdf012cd77 100644 --- a/MathlibTest/Continuity.lean +++ b/MathlibTest/Continuity.lean @@ -51,7 +51,7 @@ example (b : Y) : Continuous (fun _ : X => b) := by continuity example (f : C(X, Y)) (g : C(Y, Z)) : Continuous (g ∘ f) := by continuity -example (f : C(X, Y)) (g : C(X, Z)) : Continuous (Prod.prodMk f g) := by continuity +example (f : C(X, Y)) (g : C(X, Z)) : Continuous (Prod.pair f g) := by continuity example (f : C(X, Y)) (g : C(W, Z)) : Continuous (Prod.map f g) := by continuity diff --git a/MathlibTest/fun_prop.lean b/MathlibTest/fun_prop.lean index 3be0933dc4e0b3..b3b81ad2343da8 100644 --- a/MathlibTest/fun_prop.lean +++ b/MathlibTest/fun_prop.lean @@ -50,7 +50,7 @@ Let's mark the product constructor. -/ attribute [fun_prop] - Measurable.prodMk -- Measurable f → Measurable g → Measurable Prod.prodMk f g + Measurable.prodMk -- Measurable f → Measurable g → Measurable Prod.pair f g /-! When it comes to product projection, their properties are usually stated in two different ways From 21c76909e3bbd58776e0316864ef51b77c967d8a Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 23:45:15 +0100 Subject: [PATCH 10/35] Add missing docstring --- Mathlib/Logic/Equiv/Prod.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Logic/Equiv/Prod.lean b/Mathlib/Logic/Equiv/Prod.lean index 589bd2fe48bc3c..9cdcf653405dd8 100644 --- a/Mathlib/Logic/Equiv/Prod.lean +++ b/Mathlib/Logic/Equiv/Prod.lean @@ -391,6 +391,9 @@ def prodPiEquivSumPi {ι ι'} (π : ι → Type u) (π' : ι' → Type u) : ((∀ i, π i) × ∀ i', π' i') ≃ ∀ i : ι ⊕ ι', i.elim π π' := sumPiEquivProdPi (Sum.elim π π') |>.symm + +/-- The equivalence between a pi-type indexed by `i : ι` to products `β i × γ i` +and a pi-type indexed by `α ⊕ α`. -/ def piProdEquivSumPi (α : Type*) (β γ : α → Type u) : (∀ i, β i × γ i) ≃ ∀ i : α ⊕ α, i.elim β γ := (piProdEquivProdPi _ _ _).trans (prodPiEquivSumPi _ _) From 33f7026082c0ff60babc83b7408cce888b4aedf7 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 3 Apr 2026 23:45:31 +0100 Subject: [PATCH 11/35] Remove rogue space --- Mathlib/Logic/Equiv/Prod.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Logic/Equiv/Prod.lean b/Mathlib/Logic/Equiv/Prod.lean index 9cdcf653405dd8..d06f3e068d50f4 100644 --- a/Mathlib/Logic/Equiv/Prod.lean +++ b/Mathlib/Logic/Equiv/Prod.lean @@ -391,7 +391,6 @@ def prodPiEquivSumPi {ι ι'} (π : ι → Type u) (π' : ι' → Type u) : ((∀ i, π i) × ∀ i', π' i') ≃ ∀ i : ι ⊕ ι', i.elim π π' := sumPiEquivProdPi (Sum.elim π π') |>.symm - /-- The equivalence between a pi-type indexed by `i : ι` to products `β i × γ i` and a pi-type indexed by `α ⊕ α`. -/ def piProdEquivSumPi (α : Type*) (β γ : α → Type u) : From c560e7cd72153798367f9d55d0c4f113475f6699 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 00:18:02 +0100 Subject: [PATCH 12/35] Add lemmas --- Mathlib/Data/Prod/Init.lean | 64 +++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index f86733eb19a761..062c097cd459c4 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -38,16 +38,35 @@ variable {ι} {α β : ι → Type*} (f f' : ∀ i, α i) (g g' : ∀ i, β i) { @[simp] theorem fst_prod : (Pi.prod f g c).fst = f c := rfl @[simp] theorem snd_prod : (Pi.prod f g c).snd = g c := rfl -lemma prod_fst_snd {α β} : Pi.prod (Prod.fst : _ → α) (Prod.snd : _ → β) = id := rfl -lemma prod_snd_fst {α β} : Pi.prod (Prod.snd : _ → β) (Prod.fst : _ → α) = .swap := rfl +@[simp] theorem prod_fst_snd {α β} : Pi.prod (Prod.fst : _ → α) (Prod.snd : _ → β) = id := rfl +@[simp] theorem prod_snd_fst {α β} : Pi.prod (Prod.snd : _ → β) (Prod.fst : _ → α) = .swap := rfl -theorem blahj {ι : Type*} {β γ : ι → Type*} {h : ∀ i, β i × γ i} : +theorem prod_fst_snd_comp {h : ∀ i, α i × β i} : Pi.prod (Prod.fst <| h ·) (Prod.snd <| h ·) = h := rfl ---(Pi.prod (fun x1 x2 ↦ (x1 x2).fst) (fun x1 x2 ↦ (x1 x2).snd) h) -theorem prod_eq_iff : Pi.prod f g = Pi.prod f' g' ↔ f = f' ∧ g = g' := by +theorem fst_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.fst <| (Pi.prod f g) ·) = f := rfl +theorem snd_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.snd <| (Pi.prod f g) ·) = g := rfl + +@[simp] +theorem prod_eq_iff {f : ∀ i, α i} {g : ∀ i, β i} : + Pi.prod f g = Pi.prod f' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] + +theorem prod_ext_iff {h h' : ∀ i, α i × β i} : h = h' ↔ + (Prod.fst <| h ·) = (Prod.fst <| h' ·) ∧ (Prod.snd <| h ·) = (Prod.snd <| h' ·) := by simp [funext_iff, Prod.ext_iff, forall_and] +theorem exists_prod_apply_eq (h : ∀ i, α i × β i) : ∃ f g, Pi.prod f g = h := + ⟨(Prod.fst <| h ·), (Prod.snd <| h ·), prod_fst_snd_comp⟩ + +theorem exists_fst_comp (f : ∀ i, α i) (g : ∀ i, β i) : + ∃ h : ∀ i, α i × β i, (Prod.fst <| h ·) = f := ⟨Pi.prod f g, fst_comp_prod⟩ +theorem exists_snd_comp (f : ∀ i, α i) (g : ∀ i, β i) : + ∃ h : ∀ i, α i × β i, (Prod.snd <| h ·) = g := ⟨Pi.prod f g, snd_comp_prod⟩ + +@[grind =] +theorem prod_const_const {γ} {α β} {a : α} {b : β} : + Pi.prod (Function.const γ a) (Function.const γ b) = Function.const γ (a, b) := rfl + end end Pi @@ -65,33 +84,52 @@ variable (f : γ → α) (g : γ → β) @[grind =] theorem pair_apply (c : γ) : Prod.pair f g c = (f c, g c) := rfl +theorem pair_comp {δ} {h : δ → γ} : Prod.pair f g ∘ h = Prod.pair (f ∘ h) (g ∘ h) := rfl + @[simp] theorem fst_pair {c} : (Prod.pair f g c).fst = f c := rfl @[simp] theorem snd_pair {c} : (Prod.pair f g c).snd = g c := rfl -@[simp] theorem fst_comp_pair : fst ∘ Prod.pair f g = f := rfl -@[simp] theorem snd_comp_pair : snd ∘ Prod.pair f g = g := rfl @[simp] theorem pair_fst_snd : @Prod.pair α β _ fst snd = id := rfl - -theorem pair_comp {δ} {h : δ → γ} : Prod.pair f g ∘ h = Prod.pair (f ∘ h) (g ∘ h) := rfl +@[simp] theorem pair_snd_fst : @Prod.pair α β _ snd fst = .swap := rfl @[simp] theorem pair_fst_snd_comp {f : γ → α × β} : Prod.pair (fst ∘ f) (snd ∘ f) = f := rfl +@[simp] theorem fst_comp_pair {f : γ → α} {g : γ → β} : fst ∘ Prod.pair f g = f := rfl +@[simp] theorem snd_comp_pair {f : γ → α} {g : γ → β} : snd ∘ Prod.pair f g = g := rfl + theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.pair f g = Prod.pair f' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem injective_uncurry_pair : Function.Injective <| - (Prod.pair (α := α) (β := β) (γ := δ)).uncurry := by - simp [Function.Injective, funext_iff, Prod.ext_iff]; grind +theorem pair_ext_iff {h h' : γ → α × β} : h = h' ↔ + (Prod.fst ∘ h) = (Prod.fst ∘ h') ∧ (Prod.snd ∘ h) = (Prod.snd ∘ h') := by + simp [funext_iff, Prod.ext_iff, forall_and] + +theorem exists_prod_apply_eq (h : γ → α × β) : ∃ f g, Prod.pair f g = h := + ⟨Prod.fst ∘ h, Prod.snd ∘ h, pair_fst_snd_comp⟩ + +theorem exists_fst_comp (f : γ → α) (g : γ → β) : + ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨Pi.prod f g, fst_comp_pair⟩ +theorem exists_snd_comp (f : γ → α) (g : γ → β) : + ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨Pi.prod f g, snd_comp_pair⟩ + +theorem leftInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.LeftInverse + (Prod.pair (α := α) (β := β) (γ := δ)).uncurry (Prod.pair (fst ∘ ·) (snd ∘ ·)) := fun _ => rfl + +theorem rightInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.RightInverse + (Prod.pair (α := α) (β := β) (γ := δ)).uncurry (Prod.pair (fst ∘ ·) (snd ∘ ·)) := fun _ => rfl @[grind =] theorem pair_const_const (a : α) (b : β) : Prod.pair (Function.const γ a) (Function.const γ b) = Function.const γ (a, b) := rfl +theorem const_prod {γ} {α β} {p : α × β} : + Function.const γ p = Prod.pair (Function.const γ p.1) (Function.const γ p.2) := rfl + end section -/- We can define `Prod.map` in terms of `Prod.pair`. -/ +/- We can define `Prod.map` in terms of `Prod.pair` (TODO: and we should). -/ theorem map_eq_pair {f : α → β} {g : δ → ε} : Prod.map f g = Prod.pair (f ∘ fst) (g ∘ snd) := rfl From 575328ac2b55a781ceb07f13d88ff03fdc76d90e Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 00:20:52 +0100 Subject: [PATCH 13/35] Fix naming error --- Mathlib/Order/Basic.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 94d0c9102406a0..5e9da1c56e2b74 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -889,19 +889,19 @@ section variable {α β₁ β₂ : Type*} [LE β₁] [LE β₂] @[simp] -lemma prodMk_le_prodMk_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : +lemma pair_le_pair_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : Prod.pair u₁ u₂ ≤ Prod.pair v₁ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by simp [Pi.le_def, Prod.le_def, forall_and] -lemma const_le_prodMk_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : +lemma const_le_pair_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : Function.const _ b ≤ Prod.pair v₁ v₂ ↔ Function.const _ b.1 ≤ v₁ ∧ Function.const _ b.2 ≤ v₂ := - prodMk_const_const b.1 b.2 ▸ prodMk_le_prodMk_iff .. + pair_const_const b.1 b.2 ▸ pair_le_pair_iff .. -lemma prodMk_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : +lemma pair_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : Prod.pair v₁ v₂ ≤ Function.const _ b ↔ v₁ ≤ Function.const _ b.1 ∧ v₂ ≤ Function.const _ b.2 := - prodMk_const_const b.1 b.2 ▸ prodMk_le_prodMk_iff .. + pair_const_const b.1 b.2 ▸ pair_le_pair_iff .. end From 4500cc0c761c8d274fba3faf231933bce2bb6135 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 00:47:07 +0100 Subject: [PATCH 14/35] Add notation --- Mathlib/Data/Prod/Init.lean | 98 ++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Data/Prod/Init.lean index 062c097cd459c4..e6989487519984 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Data/Prod/Init.lean @@ -9,7 +9,7 @@ public import Mathlib.Init /-! -This file defines `Prod.pair f g`, the operation that pairs two functions `f : γ → α` and +This file defines `(f △ g)`, the operation that pairs two functions `f : γ → α` and `g : γ → β` into a function `γ → α × β`. It also defines the special case when `f = g = id`, `Prod.diag`. This is the canonical injection @@ -29,43 +29,45 @@ namespace Pi protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) : ∀ i, α i × β i := fun i ↦ (f i, g i) +@[inherit_doc] infixr:65 " △' " => Pi.prod + section variable {ι} {α β : ι → Type*} (f f' : ∀ i, α i) (g g' : ∀ i, β i) {c} -@[grind =] theorem prod_apply : Pi.prod f g c = (f c, g c) := rfl +@[grind =] theorem prod_apply : (f △' g) c = (f c, g c) := rfl -@[simp] theorem fst_prod : (Pi.prod f g c).fst = f c := rfl -@[simp] theorem snd_prod : (Pi.prod f g c).snd = g c := rfl +@[simp] theorem fst_prod : ((f △' g) c).fst = f c := rfl +@[simp] theorem snd_prod : ((f △' g) c).snd = g c := rfl -@[simp] theorem prod_fst_snd {α β} : Pi.prod (Prod.fst : _ → α) (Prod.snd : _ → β) = id := rfl -@[simp] theorem prod_snd_fst {α β} : Pi.prod (Prod.snd : _ → β) (Prod.fst : _ → α) = .swap := rfl +@[simp] theorem prod_fst_snd {α β} : (Prod.fst : _ → α) △' (Prod.snd : _ → β) = id := rfl +@[simp] theorem prod_snd_fst {α β} : (Prod.snd : _ → β) △' (Prod.fst : _ → α) = .swap := rfl theorem prod_fst_snd_comp {h : ∀ i, α i × β i} : - Pi.prod (Prod.fst <| h ·) (Prod.snd <| h ·) = h := rfl + (Prod.fst <| h ·) △' (Prod.snd <| h ·) = h := rfl -theorem fst_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.fst <| (Pi.prod f g) ·) = f := rfl -theorem snd_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.snd <| (Pi.prod f g) ·) = g := rfl +theorem fst_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.fst <| (f △' g) ·) = f := rfl +theorem snd_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.snd <| (f △' g) ·) = g := rfl @[simp] theorem prod_eq_iff {f : ∀ i, α i} {g : ∀ i, β i} : - Pi.prod f g = Pi.prod f' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] + f △' g = f' △' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] theorem prod_ext_iff {h h' : ∀ i, α i × β i} : h = h' ↔ (Prod.fst <| h ·) = (Prod.fst <| h' ·) ∧ (Prod.snd <| h ·) = (Prod.snd <| h' ·) := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem exists_prod_apply_eq (h : ∀ i, α i × β i) : ∃ f g, Pi.prod f g = h := +theorem exists_prod_apply_eq (h : ∀ i, α i × β i) : ∃ f g, (f △' g) = h := ⟨(Prod.fst <| h ·), (Prod.snd <| h ·), prod_fst_snd_comp⟩ theorem exists_fst_comp (f : ∀ i, α i) (g : ∀ i, β i) : - ∃ h : ∀ i, α i × β i, (Prod.fst <| h ·) = f := ⟨Pi.prod f g, fst_comp_prod⟩ + ∃ h : ∀ i, α i × β i, (Prod.fst <| h ·) = f := ⟨(f △' g), fst_comp_prod⟩ theorem exists_snd_comp (f : ∀ i, α i) (g : ∀ i, β i) : - ∃ h : ∀ i, α i × β i, (Prod.snd <| h ·) = g := ⟨Pi.prod f g, snd_comp_prod⟩ + ∃ h : ∀ i, α i × β i, (Prod.snd <| h ·) = g := ⟨(f △' g), snd_comp_prod⟩ @[grind =] theorem prod_const_const {γ} {α β} {a : α} {b : β} : - Pi.prod (Function.const γ a) (Function.const γ b) = Function.const γ (a, b) := rfl + (Function.const γ a) △' (Function.const γ b) = Function.const γ (a, b) := rfl end @@ -76,54 +78,56 @@ namespace Prod variable {α β δ ε : Type*} {γ : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -protected def pair (f : γ → α) (g : γ → β) : γ → α × β := Pi.prod f g +protected def pair (f : γ → α) (g : γ → β) : γ → α × β := (f △' g) + +@[inherit_doc] infixr:65 " △ " => Prod.pair section variable (f : γ → α) (g : γ → β) -@[grind =] theorem pair_apply (c : γ) : Prod.pair f g c = (f c, g c) := rfl +@[grind =] theorem pair_apply (c : γ) : (f △ g) c = (f c, g c) := rfl -theorem pair_comp {δ} {h : δ → γ} : Prod.pair f g ∘ h = Prod.pair (f ∘ h) (g ∘ h) := rfl +theorem pair_comp {δ} {h : δ → γ} : (f △ g) ∘ h = (f ∘ h) △ (g ∘ h) := rfl -@[simp] theorem fst_pair {c} : (Prod.pair f g c).fst = f c := rfl -@[simp] theorem snd_pair {c} : (Prod.pair f g c).snd = g c := rfl +@[simp] theorem fst_pair {c} : ((f △ g) c).fst = f c := rfl +@[simp] theorem snd_pair {c} : ((f △ g) c).snd = g c := rfl -@[simp] theorem pair_fst_snd : @Prod.pair α β _ fst snd = id := rfl -@[simp] theorem pair_snd_fst : @Prod.pair α β _ snd fst = .swap := rfl +@[simp] theorem pair_fst_snd : fst (α := α) △ snd (β := β) = id := rfl +@[simp] theorem pair_snd_fst : snd (β := β) △ fst (α := α) = .swap := rfl -@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : Prod.pair (fst ∘ f) (snd ∘ f) = f := rfl +@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : (fst ∘ f) △ (snd ∘ f) = f := rfl -@[simp] theorem fst_comp_pair {f : γ → α} {g : γ → β} : fst ∘ Prod.pair f g = f := rfl -@[simp] theorem snd_comp_pair {f : γ → α} {g : γ → β} : snd ∘ Prod.pair f g = g := rfl +@[simp] theorem fst_comp_pair {f : γ → α} {g : γ → β} : fst ∘ (f △ g) = f := rfl +@[simp] theorem snd_comp_pair {f : γ → α} {g : γ → β} : snd ∘ (f △ g) = g := rfl -theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : Prod.pair f g = Prod.pair f' g' ↔ +theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : f △ g = f' △ g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] theorem pair_ext_iff {h h' : γ → α × β} : h = h' ↔ - (Prod.fst ∘ h) = (Prod.fst ∘ h') ∧ (Prod.snd ∘ h) = (Prod.snd ∘ h') := by + Prod.fst ∘ h = Prod.fst ∘ h' ∧ Prod.snd ∘ h = (Prod.snd ∘ h') := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem exists_prod_apply_eq (h : γ → α × β) : ∃ f g, Prod.pair f g = h := +theorem exists_prod_apply_eq (h : γ → α × β) : ∃ f g, f △ g = h := ⟨Prod.fst ∘ h, Prod.snd ∘ h, pair_fst_snd_comp⟩ theorem exists_fst_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨Pi.prod f g, fst_comp_pair⟩ + ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨f △ g, fst_comp_pair⟩ theorem exists_snd_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨Pi.prod f g, snd_comp_pair⟩ + ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨f △ g, snd_comp_pair⟩ theorem leftInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.LeftInverse - (Prod.pair (α := α) (β := β) (γ := δ)).uncurry (Prod.pair (fst ∘ ·) (snd ∘ ·)) := fun _ => rfl + (Prod.pair (γ := δ)).uncurry ((fst (α := α) ∘ ·) △ (snd (β := β) ∘ ·)) := fun _ => rfl theorem rightInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.RightInverse - (Prod.pair (α := α) (β := β) (γ := δ)).uncurry (Prod.pair (fst ∘ ·) (snd ∘ ·)) := fun _ => rfl + (Prod.pair (γ := δ)).uncurry ((fst (α := α) ∘ ·) △ (snd (β := β) ∘ ·)) := fun _ => rfl @[grind =] theorem pair_const_const (a : α) (b : β) : - Prod.pair (Function.const γ a) (Function.const γ b) = Function.const γ (a, b) := rfl + (Function.const γ a) △ (Function.const γ b) = Function.const γ (a, b) := rfl theorem const_prod {γ} {α β} {p : α × β} : - Function.const γ p = Prod.pair (Function.const γ p.1) (Function.const γ p.2) := rfl + Function.const γ p = (Function.const γ p.1) △ (Function.const γ p.2) := rfl end @@ -131,40 +135,42 @@ section /- We can define `Prod.map` in terms of `Prod.pair` (TODO: and we should). -/ theorem map_eq_pair {f : α → β} {g : δ → ε} : Prod.map f g = - Prod.pair (f ∘ fst) (g ∘ snd) := rfl + (f ∘ fst) △ (g ∘ snd) := rfl @[grind _=_] theorem map_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : - Prod.map f h (Prod.pair g k c) = Prod.pair (f ∘ g) (h ∘ k) c := rfl + Prod.map f h ((g △ k) c) = ((f ∘ g) △ (h ∘ k)) c := rfl theorem map_comp_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : - Prod.map f h ∘ Prod.pair g k = Prod.pair (f ∘ g) (h ∘ k) := rfl + Prod.map f h ∘ (g △ k) = (f ∘ g) △ (h ∘ k) := rfl end /-- The diagonal map into Prod. -/ -@[expose] protected def diag : α → α × α := Prod.pair id id +@[expose] protected def diag : α → α × α := id △ id + +@[inherit_doc] prefix:max "Δ " => Prod.diag section variable {a b : α} -@[grind =] theorem diag_apply : Prod.diag a = (a, a) := rfl +@[grind =] theorem diag_apply : Δ a = (a, a) := rfl -@[simp, grind =] theorem fst_diag : (Prod.diag a).1 = a := rfl -@[simp, grind =] theorem snd_diag : (Prod.diag a).2 = a := rfl +@[simp, grind =] theorem fst_diag : (Δ a).1 = a := rfl +@[simp, grind =] theorem snd_diag : (Δ a).2 = a := rfl -@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Prod.diag a) = - Prod.pair f g a := rfl +@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Δ a) = + (f △ g) a := rfl -theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = Prod.pair f g := rfl +theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = (f △ g) := rfl -theorem injective_diag : Function.Injective (Prod.diag (α := α)) := fun _ _ => congrArg fst +theorem injective_diag : Function.Injective (α := α) Prod.diag := fun _ _ => congrArg fst -theorem exists_diag_apply_iff (p : α × α) : (∃ a, p = Prod.diag a) ↔ p.1 = p.2 := by +theorem exists_diag_apply_iff (p : α × α) : (∃ a, p = Δ a) ↔ p.1 = p.2 := by simp [Prod.ext_iff, eq_comm] -@[simp] theorem diag_eq_iff : Prod.diag a = Prod.diag b ↔ a = b := injective_diag.eq_iff +@[simp] theorem diag_eq_iff : Δ a = Δ b ↔ a = b := injective_diag.eq_iff end From 4f5fad08d5d45e353202facd8e553a5d1ea27cf8 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 00:52:53 +0100 Subject: [PATCH 15/35] Fix issue --- Mathlib/Logic/Equiv/Basic.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Logic/Equiv/Basic.lean b/Mathlib/Logic/Equiv/Basic.lean index fbc5193ae2dbab..15ee48832a7e6e 100644 --- a/Mathlib/Logic/Equiv/Basic.lean +++ b/Mathlib/Logic/Equiv/Basic.lean @@ -876,12 +876,11 @@ lemma piCongrLeft_apply_eq_cast {P : β → Sort v} {e : α ≃ β} theorem piCongrLeft_sumInl {ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i))) (g : ∀ i, π (e (inr i))) (i : ι) : piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inl i)) = f i := by - grind - + simp theorem piCongrLeft_sumInr {ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i))) (g : ∀ i, π (e (inr i))) (j : ι') : piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inr j)) = g j := by - grind + simp end From 612ad89fee1b23541f82d188d43830c34217201f Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 01:12:42 +0100 Subject: [PATCH 16/35] Move to Function namespace --- Mathlib.lean | 4 +- Mathlib/Algebra/Algebra/NonUnitalHom.lean | 10 +-- Mathlib/Algebra/Algebra/Prod.lean | 4 +- Mathlib/Algebra/FiniteSupport/Basic.lean | 2 +- Mathlib/Algebra/Group/Prod.lean | 8 +-- Mathlib/Algebra/Lie/Prod.lean | 2 +- Mathlib/Algebra/Ring/Prod.lean | 4 +- Mathlib/Algebra/Star/StarAlgHom.lean | 12 ++-- .../Analysis/SpecialFunctions/Pow/Deriv.lean | 6 +- Mathlib/Data/Bool/Init.lean | 26 ------- Mathlib/Data/Int/Cast/Prod.lean | 4 +- Mathlib/Data/Nat/Cast/Prod.lean | 4 +- Mathlib/Data/Prod/Basic.lean | 6 +- Mathlib/Data/Set/Prod.lean | 8 +-- Mathlib/Data/Sum/Init.lean | 71 ------------------- .../Manifold/ContMDiff/Constructions.lean | 16 ++--- Mathlib/Geometry/Manifold/ContMDiffMap.lean | 2 +- Mathlib/LinearAlgebra/Prod.lean | 8 +-- Mathlib/Logic/Equiv/Prod.lean | 18 +++-- .../{Data/Prod => Logic/Function}/Init.lean | 34 ++++----- Mathlib/MeasureTheory/Function/AEEqFun.lean | 6 +- .../Function/L1Space/Integrable.lean | 2 +- .../AEStronglyMeasurable.lean | 2 +- .../Function/StronglyMeasurable/Basic.lean | 2 +- .../MeasureTheory/Measure/AEMeasurable.lean | 2 +- Mathlib/Order/Basic.lean | 12 ++-- Mathlib/Order/Filter/Basic.lean | 2 +- Mathlib/Order/Hom/Basic.lean | 2 +- Mathlib/Order/Monotone/Defs.lean | 4 +- Mathlib/Order/ScottContinuity.lean | 4 +- .../Probability/Kernel/Composition/Prod.lean | 2 +- .../Algebra/InfiniteSum/Constructions.lean | 2 +- Mathlib/Topology/Constructions/SumProd.lean | 6 +- Mathlib/Topology/ContinuousOn.lean | 4 +- Mathlib/Topology/EMetricSpace/Lipschitz.lean | 6 +- Mathlib/Topology/UniformSpace/Basic.lean | 4 +- MathlibTest/Continuity.lean | 2 +- MathlibTest/fun_prop.lean | 2 +- 38 files changed, 108 insertions(+), 207 deletions(-) delete mode 100644 Mathlib/Data/Bool/Init.lean delete mode 100644 Mathlib/Data/Sum/Init.lean rename Mathlib/{Data/Prod => Logic/Function}/Init.lean (83%) diff --git a/Mathlib.lean b/Mathlib.lean index 344861f24feb29..bfbc1842e61770 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3652,7 +3652,6 @@ public import Mathlib.Data.BitVec public import Mathlib.Data.Bool.AllAny public import Mathlib.Data.Bool.Basic public import Mathlib.Data.Bool.Count -public import Mathlib.Data.Bool.Init public import Mathlib.Data.Bool.Set public import Mathlib.Data.Bracket public import Mathlib.Data.Bundle @@ -4121,7 +4120,6 @@ public import Mathlib.Data.PSigma.Order public import Mathlib.Data.Part public import Mathlib.Data.Pi.Interval public import Mathlib.Data.Prod.Basic -public import Mathlib.Data.Prod.Init public import Mathlib.Data.Prod.Lex public import Mathlib.Data.Prod.PProd public import Mathlib.Data.Prod.TProd @@ -4247,7 +4245,6 @@ public import Mathlib.Data.String.Defs public import Mathlib.Data.String.Lemmas public import Mathlib.Data.Subtype public import Mathlib.Data.Sum.Basic -public import Mathlib.Data.Sum.Init public import Mathlib.Data.Sum.Interval public import Mathlib.Data.Sum.Lattice public import Mathlib.Data.Sum.Order @@ -5120,6 +5117,7 @@ public import Mathlib.Logic.Function.Defs public import Mathlib.Logic.Function.DependsOn public import Mathlib.Logic.Function.FiberPartition public import Mathlib.Logic.Function.FromTypes +public import Mathlib.Logic.Function.Init public import Mathlib.Logic.Function.Iterate public import Mathlib.Logic.Function.OfArity public import Mathlib.Logic.Function.ULift diff --git a/Mathlib/Algebra/Algebra/NonUnitalHom.lean b/Mathlib/Algebra/Algebra/NonUnitalHom.lean index d3986be73bd13b..dd399313c609d0 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalHom.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalHom.lean @@ -371,11 +371,11 @@ variable [DistribMulAction R C] /-- The prod of two morphisms is a morphism. -/ @[simps] def prod (f : A →ₙₐ[R] B) (g : A →ₙₐ[R] C) : A →ₙₐ[R] B × C where - toFun := Pi.prod f g - map_zero' := by simp only [Pi.prod, Prod.mk_zero_zero, map_zero] - map_add' x y := by simp only [Pi.prod, Prod.mk_add_mk, map_add] - map_mul' x y := by simp only [Pi.prod, Prod.mk_mul_mk, map_mul] - map_smul' c x := by simp only [Pi.prod, map_smul, MonoidHom.id_apply, Prod.smul_mk] + toFun := Function.prod f g + map_zero' := by simp only [Function.prod, Prod.mk_zero_zero, map_zero] + map_add' x y := by simp only [Function.prod, Prod.mk_add_mk, map_add] + map_mul' x y := by simp only [Function.prod, Prod.mk_mul_mk, map_mul] + map_smul' c x := by simp only [Function.prod, map_smul, MonoidHom.id_apply, Prod.smul_mk] theorem coe_prod (f : A →ₙₐ[R] B) (g : A →ₙₐ[R] C) : ⇑(f.prod g) = Pi.prod f g := rfl diff --git a/Mathlib/Algebra/Algebra/Prod.lean b/Mathlib/Algebra/Algebra/Prod.lean index 46058dff5af82d..66cd3bf80c06aa 100644 --- a/Mathlib/Algebra/Algebra/Prod.lean +++ b/Mathlib/Algebra/Algebra/Prod.lean @@ -77,7 +77,7 @@ theorem snd_apply (a) : snd R A B a = a.2 := rfl variable {R} -/-- The `Pi.prod` of two morphisms is a morphism. -/ +/-- The `Function.prod` of two morphisms is a morphism. -/ @[simps!] def prod (f : A →ₐ[R] B) (g : A →ₐ[R] C) : A →ₐ[R] B × C := { f.toRingHom.prod g.toRingHom with @@ -85,7 +85,7 @@ def prod (f : A →ₐ[R] B) (g : A →ₐ[R] C) : A →ₐ[R] B × C := simp only [toRingHom_eq_coe, RingHom.toFun_eq_coe, RingHom.prod_apply, coe_toRingHom, commutes, Prod.algebraMap_apply] } -theorem coe_prod (f : A →ₐ[R] B) (g : A →ₐ[R] C) : ⇑(f.prod g) = Pi.prod f g := +theorem coe_prod (f : A →ₐ[R] B) (g : A →ₐ[R] C) : ⇑(f.prod g) = Function.prod f g := rfl @[simp] diff --git a/Mathlib/Algebra/FiniteSupport/Basic.lean b/Mathlib/Algebra/FiniteSupport/Basic.lean index d810f395f483d1..79ba79f7524426 100644 --- a/Mathlib/Algebra/FiniteSupport/Basic.lean +++ b/Mathlib/Algebra/FiniteSupport/Basic.lean @@ -55,7 +55,7 @@ lemma HasFiniteMulSupport.snd {M' : Type*} [One M'] {f : α → M × M'} (hf : H @[to_additive (attr := fun_prop)] lemma HasFiniteMulSupport.prodMk {M' : Type*} [One M'] {f : α → M} {g : α → M'} (hf : HasFiniteMulSupport f) (hg : HasFiniteMulSupport g) : - HasFiniteMulSupport (Prod.pair f g) := by + HasFiniteMulSupport (Function.prod f g) := by simp only [HasFiniteMulSupport] at hf hg ⊢ rw [mulSupport_prodMk f g] exact hf.union hg diff --git a/Mathlib/Algebra/Group/Prod.lean b/Mathlib/Algebra/Group/Prod.lean index 7b6de8812c6ba1..2b516ede3c9d4d 100644 --- a/Mathlib/Algebra/Group/Prod.lean +++ b/Mathlib/Algebra/Group/Prod.lean @@ -221,11 +221,11 @@ theorem coe_snd : ⇑(snd M N) = Prod.snd := `f.prod g : AddHom M (N × P)` given by `(f.prod g) x = (f x, g x)` -/] protected def prod (f : M →ₙ* N) (g : M →ₙ* P) : M →ₙ* N × P where - toFun := Pi.prod f g + toFun := Function.prod f g map_mul' x y := Prod.ext (f.map_mul x y) (g.map_mul x y) @[to_additive coe_prod] -theorem coe_prod (f : M →ₙ* N) (g : M →ₙ* P) : ⇑(f.prod g) = Pi.prod f g := +theorem coe_prod (f : M →ₙ* N) (g : M →ₙ* P) : ⇑(f.prod g) = Function.prod f g := rfl @[to_additive (attr := simp) prod_apply] @@ -387,12 +387,12 @@ given by `(f.prod g) x = (f x, g x)`. -/ `f.prod g : M →+ N × P` given by `(f.prod g) x = (f x, g x)` -/] protected def prod (f : M →* N) (g : M →* P) : M →* N × P where - toFun := Pi.prod f g + toFun := Function.prod f g map_one' := Prod.ext f.map_one g.map_one map_mul' x y := Prod.ext (f.map_mul x y) (g.map_mul x y) @[to_additive coe_prod] -theorem coe_prod (f : M →* N) (g : M →* P) : ⇑(f.prod g) = Pi.prod f g := +theorem coe_prod (f : M →* N) (g : M →* P) : ⇑(f.prod g) = Function.prod f g := rfl @[to_additive (attr := simp) prod_apply] diff --git a/Mathlib/Algebra/Lie/Prod.lean b/Mathlib/Algebra/Lie/Prod.lean index be9596c35560c2..b3e21f22fee50d 100644 --- a/Mathlib/Algebra/Lie/Prod.lean +++ b/Mathlib/Algebra/Lie/Prod.lean @@ -99,7 +99,7 @@ def prod (f : L →ₗ⁅R⁆ L₁) (g : L →ₗ⁅R⁆ L₂) : L →ₗ⁅R⁆ toLinearMap := LinearMap.prod f g map_lie' := by simp -theorem coe_prod (f : L →ₗ⁅R⁆ L₁) (g : L →ₗ⁅R⁆ L₂) : ⇑(f.prod g) = Pi.prod f g := +theorem coe_prod (f : L →ₗ⁅R⁆ L₁) (g : L →ₗ⁅R⁆ L₂) : ⇑(f.prod g) = Function.prod f g := rfl @[simp] diff --git a/Mathlib/Algebra/Ring/Prod.lean b/Mathlib/Algebra/Ring/Prod.lean index 33289f939e02ab..bf32efe783fc61 100644 --- a/Mathlib/Algebra/Ring/Prod.lean +++ b/Mathlib/Algebra/Ring/Prod.lean @@ -132,7 +132,7 @@ variable [NonUnitalNonAssocSemiring T] (f : R →ₙ+* S) (g : R →ₙ+* T) `f.prod g : R →ₙ+* S × T` given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →ₙ+* S) (g : R →ₙ+* T) : R →ₙ+* S × T := { MulHom.prod (f : MulHom R S) (g : MulHom R T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := Prod.pair f g } + toFun := Function.prod f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := @@ -208,7 +208,7 @@ variable [NonAssocSemiring T] (f : R →+* S) (g : R →+* T) given by `(f.prod g) x = (f x, g x)` -/ protected def prod (f : R →+* S) (g : R →+* T) : R →+* S × T := { MonoidHom.prod (f : R →* S) (g : R →* T), AddMonoidHom.prod (f : R →+ S) (g : R →+ T) with - toFun := Prod.pair f g } + toFun := Function.prod f g } @[simp] theorem prod_apply (x) : f.prod g x = (f x, g x) := diff --git a/Mathlib/Algebra/Star/StarAlgHom.lean b/Mathlib/Algebra/Star/StarAlgHom.lean index 0d011f9cdb86b4..311ce0599e6097 100644 --- a/Mathlib/Algebra/Star/StarAlgHom.lean +++ b/Mathlib/Algebra/Star/StarAlgHom.lean @@ -485,13 +485,13 @@ def snd : A × B →⋆ₙₐ[R] B := variable {R A B C} -/-- The `Pi.prod` of two morphisms is a morphism. -/ +/-- The `Function.prod` of two morphisms is a morphism. -/ @[simps!] def prod (f : A →⋆ₙₐ[R] B) (g : A →⋆ₙₐ[R] C) : A →⋆ₙₐ[R] B × C := { f.toNonUnitalAlgHom.prod g.toNonUnitalAlgHom with map_star' := fun x => by simp [map_star, Prod.star_def] } -theorem coe_prod (f : A →⋆ₙₐ[R] B) (g : A →⋆ₙₐ[R] C) : ⇑(f.prod g) = Pi.prod f g := +theorem coe_prod (f : A →⋆ₙₐ[R] B) (g : A →⋆ₙₐ[R] C) : ⇑(f.prod g) = Function.prod f g := rfl @[simp] @@ -504,7 +504,7 @@ theorem snd_prod (f : A →⋆ₙₐ[R] B) (g : A →⋆ₙₐ[R] C) : (snd R B @[simp] theorem prod_fst_snd : prod (fst R A B) (snd R A B) = 1 := - DFunLike.coe_injective Pi.prod_fst_snd + DFunLike.coe_injective Function.prod_fst_snd /-- Taking the product of two maps with the same domain is equivalent to taking the product of their codomains. -/ @@ -590,12 +590,12 @@ def snd : A × B →⋆ₐ[R] B := variable {R A B C} -/-- The `Pi.prod` of two morphisms is a morphism. -/ +/-- The `Function.prod` of two morphisms is a morphism. -/ @[simps!] def prod (f : A →⋆ₐ[R] B) (g : A →⋆ₐ[R] C) : A →⋆ₐ[R] B × C := { f.toAlgHom.prod g.toAlgHom with map_star' := by simp [Prod.star_def, map_star, Prod.ext_iff] } -theorem coe_prod (f : A →⋆ₐ[R] B) (g : A →⋆ₐ[R] C) : ⇑(f.prod g) = Pi.prod f g := +theorem coe_prod (f : A →⋆ₐ[R] B) (g : A →⋆ₐ[R] C) : ⇑(f.prod g) = Function.prod f g := rfl @[simp] @@ -608,7 +608,7 @@ theorem snd_prod (f : A →⋆ₐ[R] B) (g : A →⋆ₐ[R] C) : (snd R B C).com @[simp] theorem prod_fst_snd : prod (fst R A B) (snd R A B) = 1 := - DFunLike.coe_injective Pi.prod_fst_snd + DFunLike.coe_injective Function.prod_fst_snd /-- Taking the product of two maps with the same domain is equivalent to taking the product of their codomains. -/ diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean index 0f9967c2ea2e97..06d82e198fdba0 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean @@ -85,7 +85,7 @@ theorem HasStrictFDerivAt.const_cpow (hf : HasStrictFDerivAt f f' x) (h0 : c ≠ theorem HasFDerivAt.cpow (hf : HasFDerivAt f f' x) (hg : HasFDerivAt g g' x) (h0 : f x ∈ slitPlane) : HasFDerivAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') x := by - convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp x (hf.prodMk hg) + convert (@Complex.hasFDerivAt_cpow ((Function.prod f g) x) h0).comp x (hf.prodMk hg) theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x ≠ 0) : HasFDerivAt (fun x => c ^ f x) ((c ^ f x * Complex.log c) • f') x := @@ -94,7 +94,7 @@ theorem HasFDerivAt.const_cpow (hf : HasFDerivAt f f' x) (h0 : c ≠ 0 ∨ f x theorem HasFDerivWithinAt.cpow (hf : HasFDerivWithinAt f f' s x) (hg : HasFDerivWithinAt g g' s x) (h0 : f x ∈ slitPlane) : HasFDerivWithinAt (fun x => f x ^ g x) ((g x * f x ^ (g x - 1)) • f' + (f x ^ g x * Complex.log (f x)) • g') s x := by - convert (@Complex.hasFDerivAt_cpow ((Prod.pair f g) x) h0).comp_hasFDerivWithinAt x + convert (@Complex.hasFDerivAt_cpow ((Function.prod f g) x) h0).comp_hasFDerivWithinAt x (hf.prodMk hg) theorem HasFDerivWithinAt.const_cpow (hf : HasFDerivWithinAt f f' s x) (h0 : c ≠ 0 ∨ f x ≠ 0) : @@ -387,7 +387,7 @@ theorem differentiableAt_rpow_of_ne (p : ℝ × ℝ) (hp : p.1 ≠ 0) : theorem _root_.HasStrictDerivAt.rpow {f g : ℝ → ℝ} {f' g' : ℝ} (hf : HasStrictDerivAt f f' x) (hg : HasStrictDerivAt g g' x) (h : 0 < f x) : HasStrictDerivAt (fun x => f x ^ g x) (f' * g x * f x ^ (g x - 1) + g' * f x ^ g x * Real.log (f x)) x := by - convert (hasStrictFDerivAt_rpow_of_pos ((Prod.pair f g) x) h).comp_hasStrictDerivAt x + convert (hasStrictFDerivAt_rpow_of_pos ((Function.prod f g) x) h).comp_hasStrictDerivAt x (hf.prodMk hg) using 1 simp [mul_assoc, mul_comm] diff --git a/Mathlib/Data/Bool/Init.lean b/Mathlib/Data/Bool/Init.lean deleted file mode 100644 index 503874b50e1646..00000000000000 --- a/Mathlib/Data/Bool/Init.lean +++ /dev/null @@ -1,26 +0,0 @@ -/- -Copyright (c) 2026 Wrenna Robson. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Wrenna Robson --/ -module - -public import Mathlib.Init - -/-! - -This file gives theorems about Bool that could be upstreamed. - -This file should not depend on anything defined in Mathlib (except for notation), so that it can be -upstreamed to Batteries or the Lean standard library easily. - --/ - -@[expose] public section - -namespace Bool - -theorem cond_apply {α β} (f g : α → β) {b : Bool} {a : α} : - (bif b then f else g) a = bif b then f a else g a := by cases b <;> rfl - -end Bool diff --git a/Mathlib/Data/Int/Cast/Prod.lean b/Mathlib/Data/Int/Cast/Prod.lean index f92d160a1d13e3..8b81432b435a79 100644 --- a/Mathlib/Data/Int/Cast/Prod.lean +++ b/Mathlib/Data/Int/Cast/Prod.lean @@ -7,7 +7,7 @@ module public import Mathlib.Data.Int.Cast.Basic public import Mathlib.Data.Nat.Cast.Prod -public import Mathlib.Data.Prod.Init +public import Mathlib.Logic.Function.Init /-! # The product of two `AddGroupWithOne`s. @@ -22,7 +22,7 @@ variable {α β : Type*} [AddGroupWithOne α] [AddGroupWithOne β] instance : AddGroupWithOne (α × β) := { Prod.instAddMonoidWithOne, Prod.instAddGroup with - intCast := Prod.pair IntCast.intCast IntCast.intCast + intCast := Function.prod IntCast.intCast IntCast.intCast intCast_ofNat := fun _ => by ext <;> simp intCast_negSucc := fun _ => by ext <;> simp } diff --git a/Mathlib/Data/Nat/Cast/Prod.lean b/Mathlib/Data/Nat/Cast/Prod.lean index 78627dbbdbe413..07e7ecc774d78c 100644 --- a/Mathlib/Data/Nat/Cast/Prod.lean +++ b/Mathlib/Data/Nat/Cast/Prod.lean @@ -7,7 +7,7 @@ module public import Mathlib.Algebra.Group.Prod public import Mathlib.Data.Nat.Cast.Defs -public import Mathlib.Data.Prod.Init +public import Mathlib.Logic.Function.Init /-! # The product of two `AddMonoidWithOne`s. @@ -25,7 +25,7 @@ variable [AddMonoidWithOne α] [AddMonoidWithOne β] instance instAddMonoidWithOne : AddMonoidWithOne (α × β) := { Prod.instAddMonoid, @Prod.instOne α β _ _ with - natCast := Prod.pair NatCast.natCast NatCast.natCast + natCast := Function.prod NatCast.natCast NatCast.natCast natCast_zero := congr_arg₂ Prod.mk Nat.cast_zero Nat.cast_zero natCast_succ := fun _ => congr_arg₂ Prod.mk (Nat.cast_succ _) (Nat.cast_succ _) } diff --git a/Mathlib/Data/Prod/Basic.lean b/Mathlib/Data/Prod/Basic.lean index 1e853d9e9aee6c..5bca9909711866 100644 --- a/Mathlib/Data/Prod/Basic.lean +++ b/Mathlib/Data/Prod/Basic.lean @@ -9,7 +9,7 @@ public import Lean.PrettyPrinter.Delaborator.Builtins public import Mathlib.Logic.Function.Defs public import Mathlib.Logic.Function.Iterate public import Mathlib.Tactic.Inhabit -public import Mathlib.Data.Prod.Init +public import Mathlib.Logic.Function.Init public import Batteries.Tactic.Trans import Mathlib.Tactic.Attr.Register @@ -27,8 +27,8 @@ namespace Pi variable {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) {c} -@[simp] theorem fst_dcomp_pair : Prod.fst ∘' Pi.prod f g = f := rfl -@[simp] theorem snd_dcomp_pair : Prod.snd ∘' Pi.prod f g = g := rfl +@[simp] theorem fst_dcomp_pair : Prod.fst ∘' (f △' g) = f := rfl +@[simp] theorem snd_dcomp_pair : Prod.snd ∘' (f △' g) = g := rfl end Pi diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index d1d3f956ee6d52..e98c8256deee16 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -8,7 +8,7 @@ module public import Mathlib.Data.Set.Image public import Mathlib.Data.SProd public import Mathlib.Data.Sum.Basic -public import Mathlib.Data.Prod.Init +public import Mathlib.Logic.Function.Init /-! # Sets in product and pi types @@ -180,7 +180,7 @@ theorem preimage_prod_map_prod (f : α → β) (g : γ → δ) (s : Set β) (t : rfl theorem mk_preimage_prod (f : γ → α) (g : γ → β) : - (Prod.pair f g) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := + (Function.prod f g) ⁻¹' s ×ˢ t = f ⁻¹' s ∩ g ⁻¹' t := rfl @[simp] @@ -239,7 +239,7 @@ theorem prod_univ_range_eq {m₂ : β → δ} : ext <| by simp [range] theorem range_pair_subset (f : α → β) (g : α → γ) : - (range (Prod.pair f g)) ⊆ range f ×ˢ range g := by grind + (range (Function.prod f g)) ⊆ range f ×ˢ range g := by grind theorem Nonempty.prod : s.Nonempty → t.Nonempty → (s ×ˢ t).Nonempty := fun ⟨x, hx⟩ ⟨y, hy⟩ => ⟨(x, y), ⟨hx, hy⟩⟩ @@ -260,7 +260,7 @@ theorem prod_sub_preimage_iff {W : Set γ} {f : α × β → γ} : s ×ˢ t ⊆ f ⁻¹' W ↔ ∀ a b, a ∈ s → b ∈ t → f (a, b) ∈ W := by simp [subset_def] theorem image_prodMk_subset_prod {f : α → β} {g : α → γ} {s : Set α} : - (Prod.pair f g) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind + (Function.prod f g) '' s ⊆ (f '' s) ×ˢ (g '' s) := by grind theorem image_prodMk_subset_prod_left (hb : b ∈ t) : (fun a => (a, b)) '' s ⊆ s ×ˢ t := by grind diff --git a/Mathlib/Data/Sum/Init.lean b/Mathlib/Data/Sum/Init.lean deleted file mode 100644 index a2155b28984d40..00000000000000 --- a/Mathlib/Data/Sum/Init.lean +++ /dev/null @@ -1,71 +0,0 @@ -/- -Copyright (c) 2026 Wrenna Robson. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Wrenna Robson --/ -module - -public import Mathlib.Init - -/-! - -This file defines `Sum.get`, the operation that extracts a term of type `α` from `α ⊕ α`. - -This file should not depend on anything defined in Mathlib (except for notation), so that it can be -upstreamed to Batteries or the Lean standard library easily. - --/ - -@[expose] public section - -namespace Sum - -universe u₁ u₂ u₃ u₄ - -variable {α : Type u₁} {β : Type u₂} {γ : Sort u₃} {δ : Type u₄} - -def cases {γ : α ⊕ β → Sort u₃} (f : (a : α) → γ (inl a)) (g : (b : β) → γ (inr b)) - (x : α ⊕ β) : γ x := x.casesOn f g - -theorem elim_eq_cases {f : α → γ} {g : β → γ} : Sum.elim f g = Sum.cases f g := rfl - -theorem elim_apply_of_isLeft {f : α → γ} {g : β → γ} {x} (h : x.isLeft) : - Sum.elim f g x = f (x.getLeft h) := by grind - -theorem elim_apply_of_isRight {f : α → γ} {g : β → γ} {x} (h : x.isRight) : - Sum.elim f g x = g (x.getRight h) := by grind - -theorem elim_apply {f : α → γ} {g : β → γ} {x} : Sum.elim f g x = - if h : x.isLeft then f (x.getLeft h) else g (x.getRight (by grind)) := by cases x <;> simp - -@[expose] protected def get : α ⊕ α → α := Sum.elim id id - -section - -variable {x y : α ⊕ α} {a : α} - -@[simp, grind =] theorem get_inl : Sum.get (inl a) = a := rfl -@[simp, grind =] theorem get_inr : Sum.get (inr a) = a := rfl - -theorem get_apply_of_isLeft (h : x.isLeft) : - x.get = x.getLeft h := by grind - -theorem get_apply_of_isRight (h : x.isRight) : - x.get = x.getRight h := by grind - -theorem get_apply : Sum.get x = if h : x.isLeft then x.getLeft h else x.getRight (by grind) := by - grind - -@[simp, grind =] theorem get_map {f : β → α} {g : δ → α} {y : β ⊕ δ} : - (y.map f g).get = y.elim f g := by cases y <;> rfl - -theorem map_comp_diag {f : β → α} {g : δ → α} : Sum.get ∘ Sum.map f g = Sum.elim f g := - funext fun _ => get_map - -theorem surjective_diag : Function.Surjective (Sum.get (α := α)) := fun a => ⟨Sum.inl a, rfl⟩ - -@[simp, grind =] theorem get_eq_iff : x.get = y.get ↔ x = y ∨ x = y.swap := by grind - -end - -end Sum diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean index cc9dcb1dcf2060..916893a673bdb9 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean @@ -55,39 +55,39 @@ section ProdMk theorem ContMDiffWithinAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffWithinAt I I' n f s x) (hg : ContMDiffWithinAt I J' n g s x) : - ContMDiffWithinAt I (I'.prod J') n (Prod.pair f g) s x := by + ContMDiffWithinAt I (I'.prod J') n (Function.prod f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem ContMDiffWithinAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffWithinAt I 𝓘(𝕜, E') n f s x) (hg : ContMDiffWithinAt I 𝓘(𝕜, F') n g s x) : - ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) s x := by + ContMDiffWithinAt I 𝓘(𝕜, E' × F') n (Function.prod f g) s x := by rw [contMDiffWithinAt_iff] at * exact ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ nonrec theorem ContMDiffAt.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffAt I I' n f x) - (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (Prod.pair f g) x := + (hg : ContMDiffAt I J' n g x) : ContMDiffAt I (I'.prod J') n (Function.prod f g) x := hf.prodMk hg nonrec theorem ContMDiffAt.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffAt I 𝓘(𝕜, E') n f x) (hg : ContMDiffAt I 𝓘(𝕜, F') n g x) : - ContMDiffAt I 𝓘(𝕜, E' × F') n (Prod.pair f g) x := + ContMDiffAt I 𝓘(𝕜, E' × F') n (Function.prod f g) x := hf.prodMk_space hg theorem ContMDiffOn.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiffOn I I' n f s) - (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (Prod.pair f g) s := + (hg : ContMDiffOn I J' n g s) : ContMDiffOn I (I'.prod J') n (Function.prod f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem ContMDiffOn.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiffOn I 𝓘(𝕜, E') n f s) - (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (Prod.pair f g) s := + (hg : ContMDiffOn I 𝓘(𝕜, F') n g s) : ContMDiffOn I 𝓘(𝕜, E' × F') n (Function.prod f g) s := fun x hx => (hf x hx).prodMk_space (hg x hx) nonrec theorem ContMDiff.prodMk {f : M → M'} {g : M → N'} (hf : ContMDiff I I' n f) - (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n Prod.pair f g := fun x => + (hg : ContMDiff I J' n g) : ContMDiff I (I'.prod J') n Function.prod f g := fun x => (hf x).prodMk (hg x) theorem ContMDiff.prodMk_space {f : M → E'} {g : M → F'} (hf : ContMDiff I 𝓘(𝕜, E') n f) - (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n Prod.pair f g := fun x => + (hg : ContMDiff I 𝓘(𝕜, F') n g) : ContMDiff I 𝓘(𝕜, E' × F') n Function.prod f g := fun x => (hf x).prodMk_space (hg x) end ProdMk diff --git a/Mathlib/Geometry/Manifold/ContMDiffMap.lean b/Mathlib/Geometry/Manifold/ContMDiffMap.lean index 5ed3ded179099c..72b84928317824 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMap.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMap.lean @@ -106,7 +106,7 @@ def snd : C^n⟮I.prod I', M × M'; I', M'⟯ := /-- Given two `C^n` maps `f` and `g`, this is the `C^n` map `x ↦ (f x, g x)`. -/ def prodMk (f : C^n⟮J, N; I, M⟯) (g : C^n⟮J, N; I', M'⟯) : C^n⟮J, N; I.prod I', M × M'⟯ := - ⟨Prod.pair f g, f.2.prodMk g.2⟩ + ⟨Function.prod f g, f.2.prodMk g.2⟩ end ContMDiffMap diff --git a/Mathlib/LinearAlgebra/Prod.lean b/Mathlib/LinearAlgebra/Prod.lean index 6416808409864e..69728fde258738 100644 --- a/Mathlib/LinearAlgebra/Prod.lean +++ b/Mathlib/LinearAlgebra/Prod.lean @@ -93,11 +93,11 @@ theorem snd_surjective : Function.Surjective (snd R M M₂) := fun x => ⟨(0, x /-- The prod of two linear maps is a linear map. -/ @[simps] def prod (f : M →ₗ[R] M₂) (g : M →ₗ[R] M₃) : M →ₗ[R] M₂ × M₃ where - toFun := Pi.prod f g - map_add' x y := by simp only [Pi.prod, Prod.mk_add_mk, map_add] - map_smul' c x := by simp only [Pi.prod, Prod.smul_mk, map_smul, RingHom.id_apply] + toFun := Function.prod f g + map_add' x y := by simp only [Pi.prod_apply, Prod.mk_add_mk, map_add] + map_smul' c x := by simp only [Pi.prod_apply, Prod.smul_mk, map_smul, RingHom.id_apply] -theorem coe_prod (f : M →ₗ[R] M₂) (g : M →ₗ[R] M₃) : ⇑(f.prod g) = Pi.prod f g := +theorem coe_prod (f : M →ₗ[R] M₂) (g : M →ₗ[R] M₃) : ⇑(f.prod g) = Function.prod f g := rfl @[simp] diff --git a/Mathlib/Logic/Equiv/Prod.lean b/Mathlib/Logic/Equiv/Prod.lean index d06f3e068d50f4..7b030f20c2cce7 100644 --- a/Mathlib/Logic/Equiv/Prod.lean +++ b/Mathlib/Logic/Equiv/Prod.lean @@ -7,9 +7,7 @@ module public import Mathlib.Logic.Equiv.Defs public import Mathlib.Tactic.Contrapose -public import Mathlib.Data.Prod.Init -public import Mathlib.Data.Sum.Init -public import Mathlib.Data.Bool.Init +public import Mathlib.Logic.Function.Init /-! # Equivalence between product types @@ -343,8 +341,8 @@ section `α → β` and `β → γ`. -/ @[simps! (attr := grind =)] def arrowProdEquivProdArrow (α β γ : Type*) : (α → β × γ) ≃ (α → β) × (α → γ) where - toFun := Prod.pair (Prod.fst <| · ·) (Prod.snd <| · ·) - invFun := Prod.pair.uncurry + toFun := Function.prod (Prod.fst <| · ·) (Prod.snd <| · ·) + invFun := Function.prod.uncurry /-- The type of a pi-type indexed by `i : ι` to products `β i × γ i` is equivalent to product of two pi-types `∀ i, β i` and `∀ i, γ i`. This is a dependent version of @@ -352,7 +350,7 @@ pi-types `∀ i, β i` and `∀ i, γ i`. This is a dependent version of @[simps! (attr := grind =)] def piProdEquivProdPi (α : Type*) (β γ : α → Type*) : (∀ i, β i × γ i) ≃ (∀ i, β i) × (∀ i, γ i) where - toFun := Prod.pair (Prod.fst <| · ·) (Prod.snd <| · ·) + toFun := Function.prod (Prod.fst <| · ·) (Prod.snd <| · ·) invFun := Pi.prod.uncurry open Sum @@ -361,7 +359,7 @@ open Sum on `α` and on `β`. -/ @[simps! (attr := grind =)] def sumArrowEquivProdArrow (α β γ : Type*) : (α ⊕ β → γ) ≃ (α → γ) × (β → γ) where - toFun := Prod.pair (· <| inl ·) (· <| inr ·) + toFun := Function.prod (· <| inl ·) (· <| inr ·) invFun := Sum.elim.uncurry left_inv f := by ext (i | i) <;> rfl @@ -380,7 +378,7 @@ functions on `ι` and on `ι'`. This is a dependent version of `Equiv.sumArrowEq @[simps (attr := grind =)] def sumPiEquivProdPi {ι ι'} (π : ι ⊕ ι' → Type*) : (∀ i, π i) ≃ (∀ i, π (inl i)) × ∀ i', π (inr i') where - toFun := Prod.pair (· <| inl ·) (· <| inr ·) + toFun := Function.prod (· <| inl ·) (· <| inr ·) invFun := Sum.rec.uncurry left_inv f := by ext (i | i) <;> rfl @@ -433,14 +431,14 @@ def sigmaProdDistrib {ι : Type*} (α : ι → Type*) (β : Type*) : (Σ i, α i @[simps (attr := grind =)] def boolProdEquivSum (α : Type*) : Bool × α ≃ α ⊕ α where toFun := (cond · inr inl).uncurry - invFun := Prod.pair Sum.isRight Sum.get + invFun := Function.prod Sum.isRight (Sum.elim id id) left_inv := by grind right_inv := by grind /-- The function type `Bool → α` is equivalent to `α × α`. -/ @[simps (attr := grind =)] def boolArrowEquivProd (α : Type*) : (Bool → α) ≃ α × α where - toFun := Prod.pair (· false) (· true) + toFun := Function.prod (· false) (· true) invFun := flip (cond · Prod.snd Prod.fst ·) left_inv _ := by grind [flip] diff --git a/Mathlib/Data/Prod/Init.lean b/Mathlib/Logic/Function/Init.lean similarity index 83% rename from Mathlib/Data/Prod/Init.lean rename to Mathlib/Logic/Function/Init.lean index e6989487519984..82bded321ff5db 100644 --- a/Mathlib/Data/Prod/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -12,7 +12,7 @@ public import Mathlib.Init This file defines `(f △ g)`, the operation that pairs two functions `f : γ → α` and `g : γ → β` into a function `γ → α × β`. -It also defines the special case when `f = g = id`, `Prod.diag`. This is the canonical injection +It also defines the special case when `f = g = id`, `Function.diag`. This is the canonical injection of a type into its prouduct with itself onto its diagonal. @@ -73,14 +73,14 @@ end end Pi -namespace Prod +namespace Function variable {α β δ ε : Type*} {γ : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ protected def pair (f : γ → α) (g : γ → β) : γ → α × β := (f △' g) -@[inherit_doc] infixr:65 " △ " => Prod.pair +@[inherit_doc] infixr:65 " △ " => Function.pair section @@ -93,13 +93,13 @@ theorem pair_comp {δ} {h : δ → γ} : (f △ g) ∘ h = (f ∘ h) △ (g ∘ @[simp] theorem fst_pair {c} : ((f △ g) c).fst = f c := rfl @[simp] theorem snd_pair {c} : ((f △ g) c).snd = g c := rfl -@[simp] theorem pair_fst_snd : fst (α := α) △ snd (β := β) = id := rfl -@[simp] theorem pair_snd_fst : snd (β := β) △ fst (α := α) = .swap := rfl +@[simp] theorem pair_fst_snd : Prod.fst (α := α) △ Prod.snd (β := β) = id := rfl +@[simp] theorem pair_snd_fst : Prod.snd (β := β) △ Prod.fst (α := α) = .swap := rfl -@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : (fst ∘ f) △ (snd ∘ f) = f := rfl +@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : (Prod.fst ∘ f) △ (Prod.snd ∘ f) = f := rfl -@[simp] theorem fst_comp_pair {f : γ → α} {g : γ → β} : fst ∘ (f △ g) = f := rfl -@[simp] theorem snd_comp_pair {f : γ → α} {g : γ → β} : snd ∘ (f △ g) = g := rfl +@[simp] theorem fst_comp_pair {f : γ → α} {g : γ → β} : Prod.fst ∘ (f △ g) = f := rfl +@[simp] theorem snd_comp_pair {f : γ → α} {g : γ → β} : Prod.snd ∘ (f △ g) = g := rfl theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : f △ g = f' △ g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] @@ -117,10 +117,12 @@ theorem exists_snd_comp (f : γ → α) (g : γ → β) : ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨f △ g, snd_comp_pair⟩ theorem leftInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.LeftInverse - (Prod.pair (γ := δ)).uncurry ((fst (α := α) ∘ ·) △ (snd (β := β) ∘ ·)) := fun _ => rfl + (Function.pair (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := + fun _ => rfl theorem rightInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.RightInverse - (Prod.pair (γ := δ)).uncurry ((fst (α := α) ∘ ·) △ (snd (β := β) ∘ ·)) := fun _ => rfl + (Function.pair (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := + fun _ => rfl @[grind =] theorem pair_const_const (a : α) (b : β) : @@ -133,9 +135,9 @@ end section -/- We can define `Prod.map` in terms of `Prod.pair` (TODO: and we should). -/ +/- We can define `Prod.map` in terms of `Function.pair` (TODO: and we should). -/ theorem map_eq_pair {f : α → β} {g : δ → ε} : Prod.map f g = - (f ∘ fst) △ (g ∘ snd) := rfl + (f ∘ Prod.fst) △ (g ∘ Prod.snd) := rfl @[grind _=_] theorem map_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : @@ -149,7 +151,7 @@ end /-- The diagonal map into Prod. -/ @[expose] protected def diag : α → α × α := id △ id -@[inherit_doc] prefix:max "Δ " => Prod.diag +@[inherit_doc] prefix:max "Δ " => Function.diag section @@ -163,9 +165,9 @@ variable {a b : α} @[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Δ a) = (f △ g) a := rfl -theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Prod.diag = (f △ g) := rfl +theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = (f △ g) := rfl -theorem injective_diag : Function.Injective (α := α) Prod.diag := fun _ _ => congrArg fst +theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst theorem exists_diag_apply_iff (p : α × α) : (∃ a, p = Δ a) ↔ p.1 = p.2 := by simp [Prod.ext_iff, eq_comm] @@ -174,4 +176,4 @@ theorem exists_diag_apply_iff (p : α × α) : (∃ a, p = Δ a) ↔ p.1 = p.2 : end -end Prod +end Function diff --git a/Mathlib/MeasureTheory/Function/AEEqFun.lean b/Mathlib/MeasureTheory/Function/AEEqFun.lean index 6241ed016179f5..0a8f8c8746058f 100644 --- a/Mathlib/MeasureTheory/Function/AEEqFun.lean +++ b/Mathlib/MeasureTheory/Function/AEEqFun.lean @@ -397,15 +397,15 @@ def pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : α →ₘ[μ] β × γ @[simp] theorem pair_mk_mk (f : α → β) (hf) (g : α → γ) (hg) : - (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (Prod.pair f g) (hf.prodMk hg) := + (mk f hf : α →ₘ[μ] β).pair (mk g hg) = mk (Function.prod f g) (hf.prodMk hg) := rfl theorem pair_eq_mk (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g = - mk (Prod.pair f g) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by + mk (Function.prod f g) (f.aestronglyMeasurable.prodMk g.aestronglyMeasurable) := by simp only [← pair_mk_mk, mk_coeFn, f.aestronglyMeasurable, g.aestronglyMeasurable] -theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] Prod.pair f g := by +theorem coeFn_pair (f : α →ₘ[μ] β) (g : α →ₘ[μ] γ) : f.pair g =ᵐ[μ] Function.prod f g := by rw [pair_eq_mk] apply coeFn_mk diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 5c237bb54bdaf9..a8cfac493a6189 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -640,7 +640,7 @@ lemma integrable_of_le_of_le {f g₁ g₂ : α → ℝ} (hf : AEStronglyMeasurab -- TODO: generalising this to enorms requires defining a product instance for enormed monoids first @[fun_prop] theorem Integrable.prodMk {f : α → β} {g : α → γ} (hf : Integrable f μ) (hg : Integrable g μ) : - Integrable (Prod.pair f g) μ := + Integrable (Function.prod f g) μ := ⟨by fun_prop, (hf.norm.add' hg.norm).mono <| Eventually.of_forall fun x => diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index 88cc6e2a8b4f5a..3f375404d6398d 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -229,7 +229,7 @@ protected theorem snd {f : α → β × γ} (hf : AEStronglyMeasurable[m] f μ) @[fun_prop] protected theorem prodMk {f : α → β} {g : α → γ} (hf : AEStronglyMeasurable[m] f μ) - (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (Prod.pair f g) μ := + (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (Function.prod f g) μ := ⟨fun x => (hf.mk f x, hg.mk g x), hf.stronglyMeasurable_mk.prodMk hg.stronglyMeasurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index af077ea96e0b55..adbc34e2567cc6 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -352,7 +352,7 @@ protected theorem snd {m : MeasurableSpace α} [TopologicalSpace β] [Topologica @[fun_prop] protected theorem prodMk {m : MeasurableSpace α} [TopologicalSpace β] [TopologicalSpace γ] {f : α → β} {g : α → γ} (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : - StronglyMeasurable Prod.pair f g := by + StronglyMeasurable Function.prod f g := by refine ⟨fun n => SimpleFunc.pair (hf.approx n) (hg.approx n), fun x => ?_⟩ rw [nhds_prod_eq] exact Tendsto.prodMk (hf.tendsto_approx x) (hg.tendsto_approx x) diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index 834a6479a1d262..6b1c26db1846d7 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -190,7 +190,7 @@ protected theorem snd {f : α → β × γ} (hf : AEMeasurable f μ) : @[fun_prop] theorem prodMk {f : α → β} {g : α → γ} (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (Prod.pair f g) μ := + AEMeasurable (Function.prod f g) μ := ⟨fun a => (hf.mk f a, hg.mk g a), hf.measurable_mk.prodMk hg.measurable_mk, hf.ae_eq_mk.prodMk hg.ae_eq_mk⟩ diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 5e9da1c56e2b74..a86770dae6f898 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -13,7 +13,7 @@ public import Mathlib.Tactic.Convert public import Mathlib.Tactic.Inhabit public import Mathlib.Tactic.SimpRw public import Mathlib.Tactic.GCongr.Core -public import Mathlib.Data.Prod.Init +public import Mathlib.Logic.Function.Init /-! # Basic definitions about `≤` and `<` @@ -890,18 +890,18 @@ variable {α β₁ β₂ : Type*} [LE β₁] [LE β₂] @[simp] lemma pair_le_pair_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : - Prod.pair u₁ u₂ ≤ Prod.pair v₁ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by + Function.prod u₁ u₂ ≤ Function.prod v₁ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by simp [Pi.le_def, Prod.le_def, forall_and] lemma const_le_pair_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - Function.const _ b ≤ Prod.pair v₁ v₂ ↔ + Function.const _ b ≤ Function.prod v₁ v₂ ↔ Function.const _ b.1 ≤ v₁ ∧ Function.const _ b.2 ≤ v₂ := - pair_const_const b.1 b.2 ▸ pair_le_pair_iff .. + prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. lemma pair_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - Prod.pair v₁ v₂ ≤ Function.const _ b ↔ + Function.prod v₁ v₂ ≤ Function.const _ b ↔ v₁ ≤ Function.const _ b.1 ∧ v₂ ≤ Function.const _ b.2 := - pair_const_const b.1 b.2 ▸ pair_le_pair_iff .. + prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. end diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index a0e486e162de51..bdef6eb088e349 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -976,7 +976,7 @@ instance {l : Filter α} : trans := EventuallyEq.trans theorem EventuallyEq.prodMk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') : - (Prod.pair f g) =ᶠ[l] fun x => (f' x, g' x) := + (Function.prod f g) =ᶠ[l] fun x => (f' x, g' x) := hf.mp <| hg.mono <| by intros diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 5b3e4f752e0845..40261b411fb1f8 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -369,7 +369,7 @@ theorem comp_const (γ : Type*) [Preorder γ] (f : α →o β) (c : α) : `OrderHom`. -/ @[simps] protected def prod (f : α →o β) (g : α →o γ) : α →o β × γ := - ⟨Prod.pair f g, fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ + ⟨Function.prod f g, fun _ _ h => ⟨f.mono h, g.mono h⟩⟩ @[mono, to_dual self] theorem prod_mono {f₁ f₂ : α →o β} (hf : f₁ ≤ f₂) {g₁ g₂ : α →o γ} (hg : g₁ ≤ g₂) : diff --git a/Mathlib/Order/Monotone/Defs.lean b/Mathlib/Order/Monotone/Defs.lean index a7d7c60a76eb3f..c052cef6e38ccc 100644 --- a/Mathlib/Order/Monotone/Defs.lean +++ b/Mathlib/Order/Monotone/Defs.lean @@ -507,11 +507,11 @@ theorem monotone_fst : Monotone (@Prod.fst α β) := fun _ _ ↦ And.left theorem monotone_snd : Monotone (@Prod.snd α β) := fun _ _ ↦ And.right theorem monotone_prodMk_iff {f : γ → α} {g : γ → β} : - Monotone (Prod.pair f g) ↔ Monotone f ∧ Monotone g := by + Monotone (Function.prod f g) ↔ Monotone f ∧ Monotone g := by simp [Monotone, Prod.le_def, forall_and] theorem Monotone.prodMk {f : γ → α} {g : γ → β} (hf : Monotone f) (hg : Monotone g) : - Monotone (Prod.pair f g) := + Monotone (Function.prod f g) := monotone_prodMk_iff.2 ⟨hf, hg⟩ theorem Monotone.prodMap (hf : Monotone f) (hg : Monotone g) : Monotone (Prod.map f g) := diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index 01702a3bce853e..cfe993c197eb4f 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -106,7 +106,7 @@ theorem ScottContinuousOn.image_comp {g : β → γ} @[fun_prop] lemma ScottContinuousOn.prodMk {g : α → γ} (hD : ∀ a b : α, a ≤ b → {a, b} ∈ D) (hf : ScottContinuousOn D f) (hg : ScottContinuousOn D g) : - ScottContinuousOn D Prod.pair f g := fun d hd₁ hd₂ hd₃ a hda => by + ScottContinuousOn D Function.prod f g := fun d hd₁ hd₂ hd₃ a hda => by rw [IsLUB, IsLeast, upperBounds] constructor · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, @@ -172,7 +172,7 @@ lemma ScottContinuous.comp {g : β → γ} @[fun_prop] lemma ScottContinuous.prodMk {g : α → γ} (hf : ScottContinuous f) (hg : ScottContinuous g) : - ScottContinuous Prod.pair f g := by + ScottContinuous Function.prod f g := by rw [← scottContinuousOn_univ] at ⊢ hf hg exact ScottContinuousOn.prodMk (by grind) hf hg diff --git a/Mathlib/Probability/Kernel/Composition/Prod.lean b/Mathlib/Probability/Kernel/Composition/Prod.lean index 9d73c928a09356..bc7790fbc4e9e4 100644 --- a/Mathlib/Probability/Kernel/Composition/Prod.lean +++ b/Mathlib/Probability/Kernel/Composition/Prod.lean @@ -216,7 +216,7 @@ lemma swap_prod {κ : Kernel α β} [IsSFiniteKernel κ] {η : Kernel α γ} [Is lemma deterministic_prod_deterministic {f : α → β} {g : α → γ} (hf : Measurable f) (hg : Measurable g) : deterministic f hf ×ₖ deterministic g hg - = deterministic (Prod.pair f g) (hf.prodMk hg) := by + = deterministic (Function.prod f g) (hf.prodMk hg) := by ext; simp_rw [prod_apply, deterministic_apply, Measure.dirac_prod_dirac] lemma id_prod_eq : @Kernel.id (α × β) inferInstance = diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean b/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean index f231558c5ec702..8c8a560405527c 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean @@ -67,7 +67,7 @@ section ProdCodomain variable [CommMonoid α] [TopologicalSpace α] [CommMonoid γ] [TopologicalSpace γ] @[to_additive HasSum.prodMk] -theorem HasProd.pair {f : β → α} {g : β → γ} {a : α} {b : γ} (hf : HasProd f a L) +theorem HasFunction.prod {f : β → α} {g : β → γ} {a : α} {b : γ} (hf : HasProd f a L) (hg : HasProd g b L) : HasProd (fun x ↦ (⟨f x, g x⟩ : α × γ)) ⟨a, b⟩ L := by simp [HasProd, ← prod_mk_prod, Filter.Tendsto.prodMk_nhds hf hg] diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index fa9fb259541e97..978f0388a4aca3 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -61,7 +61,7 @@ variable [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z] [Topolog @[simp] theorem continuous_prodMk {f : X → Y} {g : X → Z} : - (Continuous Prod.pair f g) ↔ Continuous f ∧ Continuous g := + (Continuous Function.prod f g) ↔ Continuous f ∧ Continuous g := continuous_inf_rng.trans <| continuous_induced_rng.and continuous_induced_rng @[continuity] @@ -138,7 +138,7 @@ theorem Filter.Tendsto.snd_nhds {X} {l : Filter X} {f : X → Y × Z} {p : Y × @[continuity, fun_prop] theorem Continuous.prodMk {f : Z → X} {g : Z → Y} (hf : Continuous f) (hg : Continuous g) : - Continuous Prod.pair f g := + Continuous Function.prod f g := continuous_prodMk.2 ⟨hf, hg⟩ @[continuity] @@ -345,7 +345,7 @@ theorem Filter.Eventually.curry_nhds {p : X × Y → Prop} {x : X} {y : Y} @[fun_prop] theorem ContinuousAt.prodMk {f : X → Y} {g : X → Z} {x : X} (hf : ContinuousAt f x) - (hg : ContinuousAt g x) : ContinuousAt (Prod.pair f g) x := + (hg : ContinuousAt g x) : ContinuousAt (Function.prod f g) x := hf.prodMk_nhds hg theorem ContinuousAt.prodMap {f : X → Z} {g : Y → W} {p : X × Y} (hf : ContinuousAt f p.fst) diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index bb9a5376b7afa8..e5edc8e7cce1b2 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -577,12 +577,12 @@ theorem ContinuousOn.image_closure (hf : ContinuousOn f (closure s)) : theorem ContinuousWithinAt.prodMk {f : α → β} {g : α → γ} {s : Set α} {x : α} (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g s x) : - ContinuousWithinAt (Prod.pair f g) s x := + ContinuousWithinAt (Function.prod f g) s x := hf.prodMk_nhds hg @[fun_prop] theorem ContinuousOn.prodMk {f : α → β} {g : α → γ} {s : Set α} (hf : ContinuousOn f s) - (hg : ContinuousOn g s) : ContinuousOn (Prod.pair f g) s := fun x hx => + (hg : ContinuousOn g s) : ContinuousOn (Function.prod f g) s := fun x hx => (hf x hx).prodMk (hg x hx) theorem continuousOn_fst {s : Set (α × β)} : ContinuousOn Prod.fst s := diff --git a/Mathlib/Topology/EMetricSpace/Lipschitz.lean b/Mathlib/Topology/EMetricSpace/Lipschitz.lean index a7f7eb75343f2f..e161593eeb3e4b 100644 --- a/Mathlib/Topology/EMetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/EMetricSpace/Lipschitz.lean @@ -244,7 +244,7 @@ protected theorem prod_snd : LipschitzWith 1 (@Prod.snd α β) := /-- If `f` and `g` are Lipschitz functions, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {f : α → β} {Kf : ℝ≥0} (hf : LipschitzWith Kf f) {g : α → γ} {Kg : ℝ≥0} - (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) Prod.pair f g := by + (hg : LipschitzWith Kg g) : LipschitzWith (max Kf Kg) Function.prod f g := by intro x y rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf x y) (hg x y) @@ -331,7 +331,7 @@ protected theorem comp {g : β → γ} {t : Set β} {Kg : ℝ≥0} (hg : Lipschi /-- If `f` and `g` are Lipschitz on `s`, so is the induced map `f × g` to the product type. -/ protected theorem prodMk {g : α → γ} {Kf Kg : ℝ≥0} (hf : LipschitzOnWith Kf f s) - (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (Prod.pair f g) s := by + (hg : LipschitzOnWith Kg g s) : LipschitzOnWith (max Kf Kg) (Function.prod f g) s := by intro _ hx _ hy rw [ENNReal.coe_mono.map_max, Prod.edist_eq, max_mul] exact max_le_max (hf hx hy) (hg hx hy) @@ -385,7 +385,7 @@ protected lemma comp {f : β → γ} {g : α → β} /-- If `f` and `g` are locally Lipschitz, so is the induced map `f × g` to the product type. -/ protected lemma prodMk {f : α → β} (hf : LocallyLipschitz f) {g : α → γ} (hg : LocallyLipschitz g) : - LocallyLipschitz Prod.pair f g := by + LocallyLipschitz Function.prod f g := by intro x rcases hf x with ⟨Kf, t₁, h₁t, hfL⟩ rcases hg x with ⟨Kg, t₂, h₂t, hgL⟩ diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index 4e49c12ba6a043..b8a3ed7a253362 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -1073,9 +1073,9 @@ lemma exists_is_open_mem_uniformity_of_forall_mem_eq end Uniform theorem Filter.Tendsto.congr_uniformity {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto g l (𝓝 b) := + (hf : Tendsto f l (𝓝 b)) (hg : Tendsto (Function.prod f g) l (𝓤 β)) : Tendsto g l (𝓝 b) := Uniform.tendsto_nhds_right.2 <| (Uniform.tendsto_nhds_right.1 hf).uniformity_trans hg theorem Uniform.tendsto_congr {α β} [UniformSpace β] {f g : α → β} {l : Filter α} {b : β} - (hfg : Tendsto (Prod.pair f g) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := + (hfg : Tendsto (Function.prod f g) l (𝓤 β)) : Tendsto f l (𝓝 b) ↔ Tendsto g l (𝓝 b) := ⟨fun h => h.congr_uniformity hfg, fun h => h.congr_uniformity hfg.uniformity_symm⟩ diff --git a/MathlibTest/Continuity.lean b/MathlibTest/Continuity.lean index 1265cdf012cd77..dba115d41095af 100644 --- a/MathlibTest/Continuity.lean +++ b/MathlibTest/Continuity.lean @@ -51,7 +51,7 @@ example (b : Y) : Continuous (fun _ : X => b) := by continuity example (f : C(X, Y)) (g : C(Y, Z)) : Continuous (g ∘ f) := by continuity -example (f : C(X, Y)) (g : C(X, Z)) : Continuous (Prod.pair f g) := by continuity +example (f : C(X, Y)) (g : C(X, Z)) : Continuous (Function.prod f g) := by continuity example (f : C(X, Y)) (g : C(W, Z)) : Continuous (Prod.map f g) := by continuity diff --git a/MathlibTest/fun_prop.lean b/MathlibTest/fun_prop.lean index b3b81ad2343da8..ea31f74b8ff205 100644 --- a/MathlibTest/fun_prop.lean +++ b/MathlibTest/fun_prop.lean @@ -50,7 +50,7 @@ Let's mark the product constructor. -/ attribute [fun_prop] - Measurable.prodMk -- Measurable f → Measurable g → Measurable Prod.pair f g + Measurable.prodMk -- Measurable f → Measurable g → Measurable Function.prod f g /-! When it comes to product projection, their properties are usually stated in two different ways From 6970ccca82aa3780e9e7a3267b47ee8e9cb044c1 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 01:17:40 +0100 Subject: [PATCH 17/35] Finish name change --- Mathlib/Logic/Function/Init.lean | 52 ++++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 82bded321ff5db..203d26c1c0f8d5 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -78,54 +78,54 @@ namespace Function variable {α β δ ε : Type*} {γ : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -protected def pair (f : γ → α) (g : γ → β) : γ → α × β := (f △' g) +protected def prod (f : γ → α) (g : γ → β) : γ → α × β := (f △' g) -@[inherit_doc] infixr:65 " △ " => Function.pair +@[inherit_doc] infixr:65 " △ " => Function.prod section variable (f : γ → α) (g : γ → β) -@[grind =] theorem pair_apply (c : γ) : (f △ g) c = (f c, g c) := rfl +@[grind =] theorem prod_apply (c : γ) : (f.prod g) c = (f c, g c) := rfl -theorem pair_comp {δ} {h : δ → γ} : (f △ g) ∘ h = (f ∘ h) △ (g ∘ h) := rfl +theorem prod_comp {δ} {h : δ → γ} : (f △ g) ∘ h = (f ∘ h) △ (g ∘ h) := rfl -@[simp] theorem fst_pair {c} : ((f △ g) c).fst = f c := rfl -@[simp] theorem snd_pair {c} : ((f △ g) c).snd = g c := rfl +@[simp] theorem fst_prod {c} : ((f △ g) c).fst = f c := rfl +@[simp] theorem snd_prod {c} : ((f △ g) c).snd = g c := rfl -@[simp] theorem pair_fst_snd : Prod.fst (α := α) △ Prod.snd (β := β) = id := rfl -@[simp] theorem pair_snd_fst : Prod.snd (β := β) △ Prod.fst (α := α) = .swap := rfl +@[simp] theorem prod_fst_snd : Prod.fst (α := α) △ Prod.snd (β := β) = id := rfl +@[simp] theorem prod_snd_fst : Prod.snd (β := β) △ Prod.fst (α := α) = .swap := rfl -@[simp] theorem pair_fst_snd_comp {f : γ → α × β} : (Prod.fst ∘ f) △ (Prod.snd ∘ f) = f := rfl +@[simp] theorem prod_fst_snd_comp {f : γ → α × β} : (Prod.fst ∘ f) △ (Prod.snd ∘ f) = f := rfl -@[simp] theorem fst_comp_pair {f : γ → α} {g : γ → β} : Prod.fst ∘ (f △ g) = f := rfl -@[simp] theorem snd_comp_pair {f : γ → α} {g : γ → β} : Prod.snd ∘ (f △ g) = g := rfl +@[simp] theorem fst_comp_prod {f : γ → α} {g : γ → β} : Prod.fst ∘ (f △ g) = f := rfl +@[simp] theorem snd_comp_prod {f : γ → α} {g : γ → β} : Prod.snd ∘ (f △ g) = g := rfl -theorem pair_eq_iff {f f' : γ → α} {g g' : γ → β} : f △ g = f' △ g' ↔ +theorem prod_eq_iff {f f' : γ → α} {g g' : γ → β} : f △ g = f' △ g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem pair_ext_iff {h h' : γ → α × β} : h = h' ↔ +theorem prod_ext_iff {h h' : γ → α × β} : h = h' ↔ Prod.fst ∘ h = Prod.fst ∘ h' ∧ Prod.snd ∘ h = (Prod.snd ∘ h') := by simp [funext_iff, Prod.ext_iff, forall_and] theorem exists_prod_apply_eq (h : γ → α × β) : ∃ f g, f △ g = h := - ⟨Prod.fst ∘ h, Prod.snd ∘ h, pair_fst_snd_comp⟩ + ⟨Prod.fst ∘ h, Prod.snd ∘ h, prod_fst_snd_comp⟩ theorem exists_fst_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨f △ g, fst_comp_pair⟩ + ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨f △ g, fst_comp_prod⟩ theorem exists_snd_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨f △ g, snd_comp_pair⟩ + ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨f △ g, snd_comp_prod⟩ -theorem leftInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.LeftInverse - (Function.pair (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := +theorem leftInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.LeftInverse + (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := fun _ => rfl -theorem rightInverse_uncurry_pair_pair_fst_comp_snd_comp : Function.RightInverse - (Function.pair (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := +theorem rightInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.RightInverse + (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := fun _ => rfl @[grind =] -theorem pair_const_const (a : α) (b : β) : +theorem prod_const_const (a : α) (b : β) : (Function.const γ a) △ (Function.const γ b) = Function.const γ (a, b) := rfl theorem const_prod {γ} {α β} {p : α × β} : @@ -135,20 +135,20 @@ end section -/- We can define `Prod.map` in terms of `Function.pair` (TODO: and we should). -/ -theorem map_eq_pair {f : α → β} {g : δ → ε} : Prod.map f g = +/- We can define `Prod.map` in terms of `Function.prod` (TODO: and we should). -/ +theorem map_eq_prod {f : α → β} {g : δ → ε} : Prod.map f g = (f ∘ Prod.fst) △ (g ∘ Prod.snd) := rfl @[grind _=_] -theorem map_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : +theorem map_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : Prod.map f h ((g △ k) c) = ((f ∘ g) △ (h ∘ k)) c := rfl -theorem map_comp_pair {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : +theorem map_comp_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : Prod.map f h ∘ (g △ k) = (f ∘ g) △ (h ∘ k) := rfl end -/-- The diagonal map into Prod. -/ +/-- The diagonal map into `Prod`. -/ @[expose] protected def diag : α → α × α := id △ id @[inherit_doc] prefix:max "Δ " => Function.diag From 676f422ddb657b3377a4340f30cc67868f1a976a Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 01:22:49 +0100 Subject: [PATCH 18/35] Add Function.prodMap --- Mathlib/Logic/Function/Init.lean | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 203d26c1c0f8d5..94a95c719d0e86 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -133,11 +133,13 @@ theorem const_prod {γ} {α β} {p : α × β} : end +/-- `Function.prodMap` is `Prod.map` in the `Function` namespace. -/ +def prodMap (f : α → β) (g : δ → ε) := (f ∘ Prod.fst) △ (g ∘ Prod.snd) + section -/- We can define `Prod.map` in terms of `Function.prod` (TODO: and we should). -/ -theorem map_eq_prod {f : α → β} {g : δ → ε} : Prod.map f g = - (f ∘ Prod.fst) △ (g ∘ Prod.snd) := rfl +@[simp, grind =] +theorem prodMap_eq_prod_map {f : α → β} {g : δ → ε} : f.prodMap g = Prod.map f g := rfl @[grind _=_] theorem map_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : @@ -149,7 +151,7 @@ theorem map_comp_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ end /-- The diagonal map into `Prod`. -/ -@[expose] protected def diag : α → α × α := id △ id +protected def diag : α → α × α := id △ id @[inherit_doc] prefix:max "Δ " => Function.diag From f26ee9210464ffb6381f7c27f58fdc11e8a3c71e Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 01:23:57 +0100 Subject: [PATCH 19/35] Reorg section --- Mathlib/Logic/Function/Init.lean | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 94a95c719d0e86..daa45b37e97c45 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -136,8 +136,6 @@ end /-- `Function.prodMap` is `Prod.map` in the `Function` namespace. -/ def prodMap (f : α → β) (g : δ → ε) := (f ∘ Prod.fst) △ (g ∘ Prod.snd) -section - @[simp, grind =] theorem prodMap_eq_prod_map {f : α → β} {g : δ → ε} : f.prodMap g = Prod.map f g := rfl @@ -148,8 +146,6 @@ theorem map_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} theorem map_comp_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : Prod.map f h ∘ (g △ k) = (f ∘ g) △ (h ∘ k) := rfl -end - /-- The diagonal map into `Prod`. -/ protected def diag : α → α × α := id △ id From 139b491c4eccc3a605bb558ab89bc884a9b89f1c Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 01:32:02 +0100 Subject: [PATCH 20/35] Further renames --- Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean | 4 ++-- Mathlib/Data/Finset/Prod.lean | 2 +- Mathlib/Data/Set/Prod.lean | 12 ++++++------ Mathlib/NumberTheory/Height/Basic.lean | 2 +- Mathlib/Order/Filter/Prod.lean | 2 +- Mathlib/Probability/Kernel/Basic.lean | 2 +- .../Kernel/Composition/MeasureCompProd.lean | 6 +++--- Mathlib/Topology/Algebra/ProperAction/Basic.lean | 2 +- Mathlib/Topology/Compactness/Compact.lean | 2 +- .../Topology/UniformSpace/UniformConvergence.lean | 8 ++++---- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index 9d2b47e2569bb3..135b227cef3ad7 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -283,8 +283,8 @@ end bij @[to_additive (attr := simp)] lemma prod_diag (s : Finset ι) (f : ι × ι → M) : - ∏ i ∈ s.diag, f i = ∏ i ∈ s, (f ∘ Prod.diag) i := by - simp [diag, Prod.diag_apply] + ∏ i ∈ s.diag, f i = ∏ i ∈ s, (f ∘ Function.diag) i := by + simp [diag, Function.diag_apply] @[to_additive] theorem prod_image' [DecidableEq ι] {s : Finset κ} {g : κ → ι} (h : κ → M) diff --git a/Mathlib/Data/Finset/Prod.lean b/Mathlib/Data/Finset/Prod.lean index 9c6c97b8b5671b..cfc791755e35ef 100644 --- a/Mathlib/Data/Finset/Prod.lean +++ b/Mathlib/Data/Finset/Prod.lean @@ -240,7 +240,7 @@ variable (s t : Finset α) /-- Given a finite set `s`, the diagonal, `s.diag` is the set of pairs of the form `(a, a)` for `a ∈ s`. -/ -def diag : Finset (α × α) := s.map ⟨Prod.diag, Prod.injective_diag⟩ +def diag : Finset (α × α) := s.map ⟨Function.diag, Prod.injective_diag⟩ -- TODO: define `Multiset.offDiag`, provide basic API, use it here /-- Given a finite set `s`, the off-diagonal, `s.offDiag` is the set of pairs `(a, b)` with `a ≠ b` diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index e98c8256deee16..7c4b3d51375c2f 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -409,7 +409,7 @@ end Prod /-! ### Diagonal In this section we prove some lemmas about the diagonal set `{p | p.1 = p.2}` and the diagonal map -`Prod.diag`. +`Function.diag`. -/ @@ -429,25 +429,25 @@ theorem preimage_coe_coe_diagonal (s : Set α) : simp [Set.diagonal] @[simp] -theorem range_diag : range Prod.diag = diagonal α := by +theorem range_diag : range Function.diag = diagonal α := by ext ⟨x, y⟩ simp [Prod.ext_iff] theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, (x, x) ∈ s := by - simp_rw [← range_diag, range_subset_iff, Prod.diag_apply] + simp_rw [← range_diag, range_subset_iff, Function.diag_apply] @[simp] theorem prod_subset_compl_diagonal_iff_disjoint : s ×ˢ t ⊆ (diagonal α)ᶜ ↔ Disjoint s t := prod_subset_iff.trans disjoint_iff_forall_ne.symm @[simp] -theorem diag_preimage_prod (s t : Set α) : Prod.diag ⁻¹' s ×ˢ t = s ∩ t := +theorem diag_preimage_prod (s t : Set α) : Function.diag ⁻¹' s ×ˢ t = s ∩ t := rfl -theorem diag_preimage_prod_self (s : Set α) : Prod.diag ⁻¹' s ×ˢ s = s := +theorem diag_preimage_prod_self (s : Set α) : Function.diag ⁻¹' s ×ˢ s = s := inter_self s -theorem diag_image (s : Set α) : Prod.diag '' s = diagonal α ∩ s ×ˢ s := by +theorem diag_image (s : Set α) : Function.diag '' s = diagonal α ∩ s ×ˢ s := by rw [← range_diag, ← image_preimage_eq_range_inter, diag_preimage_prod_self] theorem diagonal_eq_univ_iff : diagonal α = univ ↔ Subsingleton α := by diff --git a/Mathlib/NumberTheory/Height/Basic.lean b/Mathlib/NumberTheory/Height/Basic.lean index bacf7ed94ebcc6..5a62146c478ad1 100644 --- a/Mathlib/NumberTheory/Height/Basic.lean +++ b/Mathlib/NumberTheory/Height/Basic.lean @@ -755,7 +755,7 @@ lemma mulHeight_mul_le (x y : ι → K) : mulHeight (x * y) ≤ mulHeight x * mu rcases eq_or_ne y 0 with rfl | hy · simpa using one_le_mulHeight x rw [← mulHeight_fun_mul_eq hx hy, - show x * y = (fun a ↦ x a.1 * y a.2) ∘ Prod.diag by ext1; simp] + show x * y = (fun a ↦ x a.1 * y a.2) ∘ Function.diag by ext1; simp] exact mulHeight_comp_le .. open Real in diff --git a/Mathlib/Order/Filter/Prod.lean b/Mathlib/Order/Filter/Prod.lean index 1bc02e4de462dd..0716d7359400c3 100644 --- a/Mathlib/Order/Filter/Prod.lean +++ b/Mathlib/Order/Filter/Prod.lean @@ -202,7 +202,7 @@ theorem Eventually.diag_of_prod_right {f : Filter α} {g : Filter γ} {p : α × obtain ⟨t, ht, s, hs, hst⟩ := eventually_prod_iff.1 h exact (ht.prod_mk hs.diag_of_prod).mono fun x hx => by simp only [hst hx.1 hx.2] -theorem tendsto_diag : Tendsto Prod.diag f (f ×ˢ f) := +theorem tendsto_diag : Tendsto Function.diag f (f ×ˢ f) := tendsto_iff_eventually.mpr fun _ hpr => hpr.diag_of_prod theorem prod_iInf_left [Nonempty ι] {f : ι → Filter α} {g : Filter β} : diff --git a/Mathlib/Probability/Kernel/Basic.lean b/Mathlib/Probability/Kernel/Basic.lean index e2b62d86cc64eb..dadf20a07be2ac 100644 --- a/Mathlib/Probability/Kernel/Basic.lean +++ b/Mathlib/Probability/Kernel/Basic.lean @@ -130,7 +130,7 @@ section Copy /-- The deterministic kernel that maps `x : α` to the Dirac measure at `(x, x) : α × α`. -/ noncomputable def copy (α : Type*) [MeasurableSpace α] : Kernel α (α × α) := - Kernel.deterministic Prod.diag (measurable_id.prod measurable_id) + Kernel.deterministic Function.diag (measurable_id.prod measurable_id) instance : IsMarkovKernel (copy α) := by rw [copy]; infer_instance diff --git a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean index 9644d378367039..06d950e9c855a1 100644 --- a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean @@ -99,14 +99,14 @@ lemma _root_.ProbabilityTheory.Kernel.compProd_apply_eq_compProd_sectR {γ : Typ ext s hs simp_rw [Kernel.compProd_apply hs, compProd_apply hs, Kernel.sectR_apply] -lemma compProd_id [SFinite μ] : μ ⊗ₘ Kernel.id = μ.map Prod.diag := by +lemma compProd_id [SFinite μ] : μ ⊗ₘ Kernel.id = μ.map Function.diag := by ext s hs rw [compProd_apply hs, map_apply (measurable_id.prod measurable_id) hs] have h_meas a : MeasurableSet (Prod.mk a ⁻¹' s) := measurable_prodMk_left hs simp_rw [Kernel.id_apply, dirac_apply' _ (h_meas _)] calc ∫⁻ a, (Prod.mk a ⁻¹' s).indicator 1 a ∂μ - _ = ∫⁻ a, (Prod.diag ⁻¹' s).indicator 1 a ∂μ := rfl - _ = μ (Prod.diag ⁻¹' s) := by + _ = ∫⁻ a, (Function.diag ⁻¹' s).indicator 1 a ∂μ := rfl + _ = μ (Function.diag ⁻¹' s) := by rw [lintegral_indicator_one] exact (measurable_id.prod measurable_id) hs diff --git a/Mathlib/Topology/Algebra/ProperAction/Basic.lean b/Mathlib/Topology/Algebra/ProperAction/Basic.lean index b3071395cc93ae..2c5f7d6ec0ed4d 100644 --- a/Mathlib/Topology/Algebra/ProperAction/Basic.lean +++ b/Mathlib/Topology/Algebra/ProperAction/Basic.lean @@ -139,7 +139,7 @@ theorem t2Space_of_properSMul_of_t1Group [h_proper : ProperSMul G X] [T1Space G] rw [t2_iff_isClosed_diagonal] let g := fun gx : G × X ↦ (gx.1 • gx.2, gx.2) have proper_g : IsProperMap g := (properSMul_iff G X).1 h_proper - have : g ∘ f = Prod.diag := by ext x <;> simp [f, g] + have : g ∘ f = Function.diag := by ext x <;> simp [f, g] have range_gf : range (g ∘ f) = diagonal X := range_diag rw [← range_gf] exact (proper_g.comp proper_f).isClosed_range diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index 773472f77e9cd9..a32afb2e8668db 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -411,7 +411,7 @@ theorem IsCompact.mem_prod_nhdsSet_of_forall {K : Set Y} {X} {l : Filter X} {s : -- That would seem a bit more natural. theorem IsCompact.nhdsSet_inf_eq_biSup {K : Set X} (hK : IsCompact K) (l : Filter X) : (𝓝ˢ K) ⊓ l = ⨆ x ∈ K, 𝓝 x ⊓ l := by - have : ∀ f : Filter X, f ⊓ l = comap Prod.diag (f ×ˢ l) := fun f ↦ by + have : ∀ f : Filter X, f ⊓ l = comap Function.diag (f ×ˢ l) := fun f ↦ by simpa only [comap_prod] using congrArg₂ (· ⊓ ·) comap_id.symm comap_id.symm simp_rw [this, ← comap_iSup, hK.nhdsSet_prod_eq_biSup] diff --git a/Mathlib/Topology/UniformSpace/UniformConvergence.lean b/Mathlib/Topology/UniformSpace/UniformConvergence.lean index 09b6805fca837d..7e6d93000dd153 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergence.lean @@ -290,12 +290,12 @@ protected theorem TendstoUniformlyOn.prodMk {ι' β' : Type*} [UniformSpace β'] (h' : TendstoUniformlyOn F' f' p' s) : TendstoUniformlyOn (fun (i : ι × ι') a => (F i.1 a, F' i.2 a)) (fun a => (f a, f' a)) (p ×ˢ p') s := - (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Prod.diag) + (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Function.diag) theorem TendstoUniformly.prodMk {ι' β' : Type*} [UniformSpace β'] {F' : ι' → α → β'} {f' : α → β'} {p' : Filter ι'} (h : TendstoUniformly F f p) (h' : TendstoUniformly F' f' p') : TendstoUniformly (fun (i : ι × ι') a => (F i.1 a, F' i.2 a)) (fun a => (f a, f' a)) (p ×ˢ p') := - (h.prodMap h').comp Prod.diag + (h.prodMap h').comp Function.diag /-- Uniform convergence on a filter `p'` to a constant function is equivalent to convergence in `p ×ˢ p'`. -/ @@ -542,12 +542,12 @@ theorem UniformCauchySeqOn.prodMap {ι' α' β' : Type*} [UniformSpace β'] {F' theorem UniformCauchySeqOn.prod {ι' β' : Type*} [UniformSpace β'] {F' : ι' → α → β'} {p' : Filter ι'} (h : UniformCauchySeqOn F p s) (h' : UniformCauchySeqOn F' p' s) : UniformCauchySeqOn (fun (i : ι × ι') a => (F i.fst a, F' i.snd a)) (p ×ˢ p') s := - (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Prod.diag) + (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Function.diag) theorem UniformCauchySeqOn.prod' {β' : Type*} [UniformSpace β'] {F' : ι → α → β'} (h : UniformCauchySeqOn F p s) (h' : UniformCauchySeqOn F' p s) : UniformCauchySeqOn (fun (i : ι) a => (F i a, F' i a)) p s := fun u hu => - have hh : Tendsto Prod.diag p (p ×ˢ p) := tendsto_diag + have hh : Tendsto Function.diag p (p ×ˢ p) := tendsto_diag (hh.prodMap hh).eventually ((h.prod h') u hu) /-- If a sequence of functions is uniformly Cauchy on a set, then the values at each point form From c9a3021be233507a576be1f679a45b80c9aed2ae Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:01:44 +0100 Subject: [PATCH 21/35] Apply fixes --- .../Bicategory/Modification/Lax.lean | 16 ++++---- .../Bicategory/Modification/Oplax.lean | 18 ++++---- Mathlib/CategoryTheory/Subfunctor/Image.lean | 2 +- Mathlib/Data/Finset/Prod.lean | 2 +- Mathlib/Data/Set/Prod.lean | 20 ++++----- Mathlib/Logic/Function/Init.lean | 2 +- Mathlib/Order/Basic.lean | 41 ++++++++++--------- Mathlib/Order/Filter/Basic.lean | 6 +-- Mathlib/Order/ScottContinuity.lean | 6 +-- Mathlib/SetTheory/ZFC/Basic.lean | 2 +- 10 files changed, 55 insertions(+), 60 deletions(-) diff --git a/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean b/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean index a607ea0766471e..a77f413e64eb43 100644 --- a/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean @@ -85,8 +85,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ Δ.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ D.app a end Modification @@ -107,13 +107,13 @@ Note that this is a scoped instance in the `Lax.LaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id η := ⟨Modification.id η⟩ - comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ + comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @[ext] -lemma homCategory.ext {Γ Δ : η ⟶ θ} (h : ∀ a, Γ.as.app a = Δ.as.app a) : Γ = Δ := +lemma homCategory.ext {Γ D : η ⟶ θ} (h : ∀ a, Γ.as.app a = D.as.app a) : Γ = D := Hom.ext <| Modification.ext <| funext h /-- Construct a modification isomorphism between lax natural transformations @@ -171,9 +171,9 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ Δ.app a + app a := Γ.app a ≫ D.app a end Modification @@ -194,13 +194,13 @@ Note that this is a scoped instance in the `Lax.OplaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id η := ⟨Modification.id η⟩ - comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ + comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @[ext] -lemma homCategory.ext {Γ Δ : η ⟶ θ} (h : ∀ a, Γ.as.app a = Δ.as.app a) : Γ = Δ := +lemma homCategory.ext {Γ D : η ⟶ θ} (h : ∀ a, Γ.as.app a = D.as.app a) : Γ = D := Hom.ext <| Modification.ext <| funext h /-- Construct a modification isomorphism between oplax natural transformations diff --git a/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean b/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean index 0d7409d80b3499..29a281e6b73f0d 100644 --- a/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean @@ -112,8 +112,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ Δ.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ D.app a end Modification @@ -134,7 +134,7 @@ Note that this is a scoped instance in the `Oplax.LaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id η := ⟨Modification.id η⟩ - comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ + comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @@ -213,8 +213,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ Δ.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ D.app a end Modification @@ -235,7 +235,7 @@ Note that this a scoped instance in the `Oplax.OplaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id Γ := ⟨Modification.id Γ⟩ - comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ + comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @@ -342,8 +342,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ Δ.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ D.app a end Modification @@ -364,7 +364,7 @@ Note that this a scoped instance in the `Oplax.StrongTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id Γ := ⟨Modification.id Γ⟩ - comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ + comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ diff --git a/Mathlib/CategoryTheory/Subfunctor/Image.lean b/Mathlib/CategoryTheory/Subfunctor/Image.lean index 172820104e78bf..3df07873185c6f 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Image.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Image.lean @@ -125,7 +125,7 @@ variable (G : Subfunctor F) (f : F ⟶ F') def image : Subfunctor F' where obj i := (f.app i) '' (G.obj i) map := by - rintro Δ Δ' φ _ ⟨x, hx, rfl⟩ + rintro D D' φ _ ⟨x, hx, rfl⟩ exact ⟨F.map φ x, G.map φ hx, by apply FunctorToTypes.naturality⟩ lemma image_top : (⊤ : Subfunctor F).image f = range f := by aesop diff --git a/Mathlib/Data/Finset/Prod.lean b/Mathlib/Data/Finset/Prod.lean index cfc791755e35ef..242990101874a6 100644 --- a/Mathlib/Data/Finset/Prod.lean +++ b/Mathlib/Data/Finset/Prod.lean @@ -240,7 +240,7 @@ variable (s t : Finset α) /-- Given a finite set `s`, the diagonal, `s.diag` is the set of pairs of the form `(a, a)` for `a ∈ s`. -/ -def diag : Finset (α × α) := s.map ⟨Function.diag, Prod.injective_diag⟩ +def diag : Finset (α × α) := s.map ⟨Function.diag, Function.injective_diag⟩ -- TODO: define `Multiset.offDiag`, provide basic API, use it here /-- Given a finite set `s`, the off-diagonal, `s.offDiag` is the set of pairs `(a, b)` with `a ≠ b` diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 7c4b3d51375c2f..097f90221ff914 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -417,24 +417,22 @@ section Diagonal variable {α : Type*} {s t : Set α} +@[simp] theorem range_diag : range Function.diag = diagonal α := Set.ext <| by simp + lemma diagonal_nonempty [Nonempty α] : (diagonal α).Nonempty := - Nonempty.elim ‹_› fun x => ⟨_, mem_diagonal x⟩ + range_diag ▸ (range_nonempty Function.diag) instance decidableMemDiagonal [h : DecidableEq α] (x : α × α) : Decidable (x ∈ diagonal α) := h x.1 x.2 -theorem preimage_coe_coe_diagonal (s : Set α) : - Prod.map (fun x : s => (x : α)) (fun x : s => (x : α)) ⁻¹' diagonal α = diagonal s := by - ext ⟨⟨x, hx⟩, ⟨y, hy⟩⟩ - simp [Set.diagonal] +theorem preimage_val_val_diagonal (s : Set α) : + Prod.map Subtype.val Subtype.val ⁻¹' diagonal α = diagonal s := Set.ext <| by simp -@[simp] -theorem range_diag : range Function.diag = diagonal α := by - ext ⟨x, y⟩ - simp [Prod.ext_iff] +@[deprecated (since := "2026-04-04")] +alias preimage_coe_coe_diagonal := preimage_val_val_diagonal -theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, (x, x) ∈ s := by - simp_rw [← range_diag, range_subset_iff, Function.diag_apply] +theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, Δ x ∈ s := by + simp_rw [← range_diag, range_subset_iff] @[simp] theorem prod_subset_compl_diagonal_iff_disjoint : s ×ˢ t ⊆ (diagonal α)ᶜ ↔ Disjoint s t := diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index daa45b37e97c45..23614e3b3a8c2b 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -167,7 +167,7 @@ theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Functio theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst -theorem exists_diag_apply_iff (p : α × α) : (∃ a, p = Δ a) ↔ p.1 = p.2 := by +@[simp] theorem exists_diag_apply_iff (p : α × α) : (∃ a, Δ a = p) ↔ p.1 = p.2 := by simp [Prod.ext_iff, eq_comm] @[simp] theorem diag_eq_iff : Δ a = Δ b ↔ a = b := injective_diag.eq_iff diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index a86770dae6f898..52be25ce5deb99 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -885,26 +885,6 @@ lemma GCongr.mk_le_mk (ha : a₁ ≤ a₂) (hb : b₁ ≤ b₂) : (a₁, b₁) @[to_dual (attr := simp) mk_le_swap] lemma swap_le_mk : x.swap ≤ (b, a) ↔ x ≤ (a, b) := and_comm -section -variable {α β₁ β₂ : Type*} [LE β₁] [LE β₂] - -@[simp] -lemma pair_le_pair_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : - Function.prod u₁ u₂ ≤ Function.prod v₁ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by - simp [Pi.le_def, Prod.le_def, forall_and] - -lemma const_le_pair_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - Function.const _ b ≤ Function.prod v₁ v₂ ↔ - Function.const _ b.1 ≤ v₁ ∧ Function.const _ b.2 ≤ v₂ := - prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. - -lemma pair_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - Function.prod v₁ v₂ ≤ Function.const _ b ↔ - v₁ ≤ Function.const _ b.1 ∧ v₂ ≤ Function.const _ b.2 := - prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. - -end - end LE section Preorder @@ -1138,3 +1118,24 @@ noncomputable instance AsLinearOrder.linearOrder [PartialOrder α] [IsTotal α ( __ := (inferInstance : PartialOrder α) le_total := @total_of α (· ≤ ·) _ toDecidableLE := Classical.decRel _ + +namespace Function + +variable {α β₁ β₂ : Type*} [LE β₁] [LE β₂] + +@[simp] +lemma pair_le_pair_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : + u₁ △ u₂ ≤ v₁ △ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by + simp [Pi.le_def, Prod.le_def, forall_and] + +lemma const_le_pair_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : + Function.const _ b ≤ v₁ △ v₂ ↔ + Function.const _ b.1 ≤ v₁ ∧ Function.const _ b.2 ≤ v₂ := + prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. + +lemma pair_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : + v₁ △ v₂ ≤ Function.const _ b ↔ + v₁ ≤ Function.const _ b.1 ∧ v₂ ≤ Function.const _ b.2 := + prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. + +end Function diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index bdef6eb088e349..7f6392d9017c4b 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -976,11 +976,7 @@ instance {l : Filter α} : trans := EventuallyEq.trans theorem EventuallyEq.prodMk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') : - (Function.prod f g) =ᶠ[l] fun x => (f' x, g' x) := - hf.mp <| - hg.mono <| by - intros - simp only [*] + (Function.prod f g) =ᶠ[l] (f' △ g') := hf.mp <| hg.mono <| by grind /-- See `EventuallyEq.comp_tendsto` in Mathlib.Order.Filter.Tendsto for a similar statement w.r.t. composition on the right. -/ diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index cfe993c197eb4f..9394e2779c34af 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -106,16 +106,16 @@ theorem ScottContinuousOn.image_comp {g : β → γ} @[fun_prop] lemma ScottContinuousOn.prodMk {g : α → γ} (hD : ∀ a b : α, a ≤ b → {a, b} ∈ D) (hf : ScottContinuousOn D f) (hg : ScottContinuousOn D g) : - ScottContinuousOn D Function.prod f g := fun d hd₁ hd₂ hd₃ a hda => by + ScottContinuousOn D (f △ g) := fun d hd₁ hd₂ hd₃ a hda => by rw [IsLUB, IsLeast, upperBounds] constructor · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, - Prod.mk_le_mk] + Function.prod_apply, Prod.mk_le_mk] intro b hb exact ⟨hf.monotone D hD (hda.1 hb), hg.monotone D hD (hda.1 hb)⟩ · intro ⟨p₁, p₂⟩ hp simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, - Prod.mk_le_mk] at hp + Function.prod_apply, Prod.mk_le_mk] at hp ⊢ constructor · rw [isLUB_le_iff (hf hd₁ hd₂ hd₃ hda), upperBounds] simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq] diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index fb336648ffb4d1..27ae1f6dd13c12 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -457,7 +457,7 @@ theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : | ⟨a, c⟩ => by let ⟨b, hb⟩ := αβ a induction ea : A a with | _ γ Γ - induction eb : B b with | _ δ Δ + induction eb : B b with | _ δ D rw [ea, eb] at hb obtain ⟨γδ, δγ⟩ := hb let c : (A a).Type := c From 1d2f67fe17021c31037f6631372cd5d1b99c0ffc Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:12:11 +0100 Subject: [PATCH 22/35] Allow for rewrites --- Mathlib/Algebra/Notation/Support.lean | 2 +- Mathlib/Analysis/Analytic/Constructions.lean | 16 +++++++-------- Mathlib/Analysis/Asymptotics/TVS.lean | 8 ++++---- Mathlib/Analysis/Calculus/ContDiff/Basic.lean | 4 ++-- .../Calculus/ContDiffHolder/Pointwise.lean | 2 +- .../Manifold/ContMDiff/Constructions.lean | 8 ++++---- .../Manifold/MFDeriv/SpecificFunctions.lean | 20 +++++++++---------- Mathlib/Logic/Function/Init.lean | 6 +++++- Mathlib/Order/Filter/EventuallyConst.lean | 2 +- Mathlib/Order/OmegaCompletePartialOrder.lean | 2 +- .../Kernel/Composition/MapComap.lean | 8 ++++---- Mathlib/Tactic/FunProp.lean | 2 +- Mathlib/Topology/UniformSpace/Defs.lean | 6 +++--- .../LocallyUniformConvergence.lean | 4 ++-- Mathlib/Topology/UniformSpace/Separation.lean | 2 +- .../DifferentialGeometry/Notation/Basic.lean | 2 +- 16 files changed, 49 insertions(+), 45 deletions(-) diff --git a/Mathlib/Algebra/Notation/Support.lean b/Mathlib/Algebra/Notation/Support.lean index 976c3d00f51a6e..fdc45efbd56586 100644 --- a/Mathlib/Algebra/Notation/Support.lean +++ b/Mathlib/Algebra/Notation/Support.lean @@ -173,7 +173,7 @@ lemma mulSupport_comp_eq_preimage (g : κ → M) (f : ι → κ) : @[to_additive support_prodMk] lemma mulSupport_prodMk (f : ι → M) (g : ι → N) : - mulSupport (fun x ↦ (f x, g x)) = mulSupport f ∪ mulSupport g := + mulSupport (f △ g) = mulSupport f ∪ mulSupport g := Set.ext fun x ↦ by simp only [mulSupport, not_and_or, mem_union, mem_setOf_eq, Prod.mk_eq_one, Ne] diff --git a/Mathlib/Analysis/Analytic/Constructions.lean b/Mathlib/Analysis/Analytic/Constructions.lean index 8e4a7cb6769404..2ec3e15f5a4c6b 100644 --- a/Mathlib/Analysis/Analytic/Constructions.lean +++ b/Mathlib/Analysis/Analytic/Constructions.lean @@ -290,7 +290,7 @@ lemma FormalMultilinearSeries.radius_prod_eq_min lemma HasFPowerSeriesWithinOnBall.prod {e : E} {f : E → F} {g : E → G} {r s : ℝ≥0∞} {t : Set E} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesWithinOnBall f p t e r) (hg : HasFPowerSeriesWithinOnBall g q t e s) : - HasFPowerSeriesWithinOnBall (fun x ↦ (f x, g x)) (p.prod q) t e (min r s) where + HasFPowerSeriesWithinOnBall (f △ g) (p.prod q) t e (min r s) where r_le := by rw [p.radius_prod_eq_min] exact min_le_min hf.r_le hg.r_le @@ -305,14 +305,14 @@ lemma HasFPowerSeriesWithinOnBall.prod {e : E} {f : E → F} {g : E → G} {r s lemma HasFPowerSeriesOnBall.prod {e : E} {f : E → F} {g : E → G} {r s : ℝ≥0∞} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesOnBall f p e r) (hg : HasFPowerSeriesOnBall g q e s) : - HasFPowerSeriesOnBall (fun x ↦ (f x, g x)) (p.prod q) e (min r s) := by + HasFPowerSeriesOnBall (f △ g) (p.prod q) e (min r s) := by rw [← hasFPowerSeriesWithinOnBall_univ] at hf hg ⊢ exact hf.prod hg lemma HasFPowerSeriesWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set E} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesWithinAt f p s e) (hg : HasFPowerSeriesWithinAt g q s e) : - HasFPowerSeriesWithinAt (fun x ↦ (f x, g x)) (p.prod q) s e := by + HasFPowerSeriesWithinAt (f △ g) (p.prod q) s e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -320,7 +320,7 @@ lemma HasFPowerSeriesWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set lemma HasFPowerSeriesAt.prod {e : E} {f : E → F} {g : E → G} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesAt f p e) (hg : HasFPowerSeriesAt g q e) : - HasFPowerSeriesAt (fun x ↦ (f x, g x)) (p.prod q) e := by + HasFPowerSeriesAt (f △ g) (p.prod q) e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -328,7 +328,7 @@ lemma HasFPowerSeriesAt.prod {e : E} {f : E → F} {g : E → G} /-- The Cartesian product of analytic functions is analytic. -/ lemma AnalyticWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set E} (hf : AnalyticWithinAt 𝕜 f s e) (hg : AnalyticWithinAt 𝕜 g s e) : - AnalyticWithinAt 𝕜 (fun x ↦ (f x, g x)) s e := by + AnalyticWithinAt 𝕜 (f △ g) s e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -337,7 +337,7 @@ lemma AnalyticWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set E} @[fun_prop] lemma AnalyticAt.prod {e : E} {f : E → F} {g : E → G} (hf : AnalyticAt 𝕜 f e) (hg : AnalyticAt 𝕜 g e) : - AnalyticAt 𝕜 (fun x ↦ (f x, g x)) e := by + AnalyticAt 𝕜 (f △ g) e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -345,13 +345,13 @@ lemma AnalyticAt.prod {e : E} {f : E → F} {g : E → G} /-- The Cartesian product of analytic functions within a set is analytic. -/ lemma AnalyticOn.prod {f : E → F} {g : E → G} {s : Set E} (hf : AnalyticOn 𝕜 f s) (hg : AnalyticOn 𝕜 g s) : - AnalyticOn 𝕜 (fun x ↦ (f x, g x)) s := + AnalyticOn 𝕜 (f △ g) s := fun x hx ↦ (hf x hx).prod (hg x hx) /-- The Cartesian product of analytic functions is analytic. -/ lemma AnalyticOnNhd.prod {f : E → F} {g : E → G} {s : Set E} (hf : AnalyticOnNhd 𝕜 f s) (hg : AnalyticOnNhd 𝕜 g s) : - AnalyticOnNhd 𝕜 (fun x ↦ (f x, g x)) s := + AnalyticOnNhd 𝕜 (f △ g) s := fun x hx ↦ (hf x hx).prod (hg x hx) /-- `AnalyticAt.comp` for functions on product spaces -/ diff --git a/Mathlib/Analysis/Asymptotics/TVS.lean b/Mathlib/Analysis/Asymptotics/TVS.lean index 50c5e8a599a193..cca12ef7ffcf73 100644 --- a/Mathlib/Analysis/Asymptotics/TVS.lean +++ b/Mathlib/Analysis/Asymptotics/TVS.lean @@ -464,7 +464,7 @@ lemma IsLittleOTVS.bot : f =o[𝕜; ⊥] g := ⟨fun u hU ↦ ⟨univ, by simp [EventuallyLE]⟩⟩ theorem IsLittleOTVS.prodMk [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} - (hf : f =o[𝕜; l] k) (hg : g =o[𝕜; l] k) : (fun x ↦ (f x, g x)) =o[𝕜; l] k := by + (hf : f =o[𝕜; l] k) (hg : g =o[𝕜; l] k) : (f △ g) =o[𝕜; l] k := by rw [((nhds_basis_balanced 𝕜 E).prod_nhds (nhds_basis_balanced 𝕜 F)).isLittleOTVS_iff (basis_sets _)] rintro ⟨U, V⟩ ⟨⟨hU, hUb⟩, hV, hVb⟩ @@ -484,11 +484,11 @@ protected theorem IsLittleOTVS.snd {f : α → E × F} {g : α → G} (h : f =o[ @[simp] theorem isLittleOTVS_prodMk_left [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} : - (fun x ↦ (f x, g x)) =o[𝕜; l] k ↔ f =o[𝕜; l] k ∧ g =o[𝕜; l] k := + (f △ g) =o[𝕜; l] k ↔ f =o[𝕜; l] k ∧ g =o[𝕜; l] k := ⟨fun h ↦ ⟨h.fst, h.snd⟩, fun h ↦ h.elim .prodMk⟩ theorem IsBigOTVS.prodMk [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} - (hf : f =O[𝕜; l] k) (hg : g =O[𝕜; l] k) : (fun x ↦ (f x, g x)) =O[𝕜; l] k := by + (hf : f =O[𝕜; l] k) (hg : g =O[𝕜; l] k) : (f △ g) =O[𝕜; l] k := by rw [((nhds_basis_balanced 𝕜 E).prod_nhds (nhds_basis_balanced 𝕜 F)).isBigOTVS_iff (basis_sets _)] rintro ⟨U, V⟩ ⟨⟨hU, hUb⟩, hV, hVb⟩ rcases ((hf.eventually_smallSets U hU).and (hg.eventually_smallSets V hV)).exists_mem_of_smallSets @@ -507,7 +507,7 @@ protected theorem IsBigOTVS.snd {f : α → E × F} {g : α → G} (h : f =O[ @[simp] theorem isBigOTVS_prodMk_left [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} : - (fun x ↦ (f x, g x)) =O[𝕜; l] k ↔ f =O[𝕜; l] k ∧ g =O[𝕜; l] k := + (f △ g) =O[𝕜; l] k ↔ f =O[𝕜; l] k ∧ g =O[𝕜; l] k := ⟨fun h ↦ ⟨h.fst, h.snd⟩, fun h ↦ h.elim .prodMk⟩ @[to_fun] diff --git a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean index e0ad3b97537a73..ae2a6cb753b168 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean @@ -588,7 +588,7 @@ theorem ContDiff.prodMk {f : E → F} {g : E → G} (hf : ContDiff 𝕜 n f) (hg theorem iteratedFDerivWithin_prodMk {f : E → F} {g : E → G} (hf : ContDiffWithinAt 𝕜 n f s x) (hg : ContDiffWithinAt 𝕜 n g s x) (hs : UniqueDiffOn 𝕜 s) (ha : x ∈ s) {i : ℕ} (hi : i ≤ n) : - iteratedFDerivWithin 𝕜 i (fun x ↦ (f x, g x)) s x = + iteratedFDerivWithin 𝕜 i (f △ g) s x = (iteratedFDerivWithin 𝕜 i f s x).prod (iteratedFDerivWithin 𝕜 i g s x) := by ext <;> · rw [← ContinuousLinearMap.iteratedFDerivWithin_comp_left _ (hf.prodMk hg) hs ha hi] @@ -596,7 +596,7 @@ theorem iteratedFDerivWithin_prodMk {f : E → F} {g : E → G} (hf : ContDiffWi theorem iteratedFDeriv_prodMk {f : E → F} {g : E → G} (hf : ContDiffAt 𝕜 n f x) (hg : ContDiffAt 𝕜 n g x) {i : ℕ} (hi : i ≤ n) : - iteratedFDeriv 𝕜 i (fun x ↦ (f x, g x)) x = + iteratedFDeriv 𝕜 i (f △ g) x = (iteratedFDeriv 𝕜 i f x).prod (iteratedFDeriv 𝕜 i g x) := by simp only [← iteratedFDerivWithin_univ] exact iteratedFDerivWithin_prodMk hf.contDiffWithinAt hg.contDiffWithinAt uniqueDiffOn_univ diff --git a/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean b/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean index 0a34d6f0757294..4451dbb07b9ec2 100644 --- a/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean +++ b/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean @@ -134,7 +134,7 @@ theorem snd {a : E × F} : ContDiffPointwiseHolderAt k α Prod.snd a := theorem prodMk {g : E → G} (hf : ContDiffPointwiseHolderAt k α f a) (hg : ContDiffPointwiseHolderAt k α g a) : - ContDiffPointwiseHolderAt k α (fun x ↦ (f x, g x)) a where + ContDiffPointwiseHolderAt k α (f △ g) a where contDiffAt := hf.contDiffAt.prodMk hg.contDiffAt isBigO := calc _ =ᶠ[𝓝 a] (fun x ↦ (iteratedFDeriv ℝ k f x - iteratedFDeriv ℝ k f a).prod diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean index 916893a673bdb9..4bbca2049036a4 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean @@ -224,15 +224,15 @@ theorem contMDiff_prod_assoc : theorem ContMDiffWithinAt.comp₂ {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} {t : Set (M' × N')} (ha : ContMDiffWithinAt (I'.prod J') J n h t (f x, g x)) (fa : ContMDiffWithinAt I I' n f s x) (ga : ContMDiffWithinAt I J' n g s x) - (st : MapsTo (fun x ↦ (f x, g x)) s t) : + (st : MapsTo (f △ g) s t) : ContMDiffWithinAt I J n (fun x ↦ h (f x, g x)) s x := - ha.comp (f := fun x ↦ (f x, g x)) _ (fa.prodMk ga) st + ha.comp (f := f △ g) _ (fa.prodMk ga) st /-- `ContMDiffWithinAt.comp₂`, with a separate argument for point equality. -/ theorem ContMDiffWithinAt.comp₂_of_eq {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} {y : M' × N'} {t : Set (M' × N')} (ha : ContMDiffWithinAt (I'.prod J') J n h t y) (fa : ContMDiffWithinAt I I' n f s x) (ga : ContMDiffWithinAt I J' n g s x) - (e : (f x, g x) = y) (st : MapsTo (fun x ↦ (f x, g x)) s t) : + (e : (f x, g x) = y) (st : MapsTo (f △ g) s t) : ContMDiffWithinAt I J n (fun x ↦ h (f x, g x)) s x := by rw [← e] at ha exact ha.comp₂ fa ga st @@ -241,7 +241,7 @@ theorem ContMDiffWithinAt.comp₂_of_eq {h : M' × N' → N} {f : M → M'} {g : theorem ContMDiffAt.comp₂ {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} (ha : ContMDiffAt (I'.prod J') J n h (f x, g x)) (fa : ContMDiffAt I I' n f x) (ga : ContMDiffAt I J' n g x) : ContMDiffAt I J n (fun x ↦ h (f x, g x)) x := - ha.comp (f := fun x ↦ (f x, g x)) _ (fa.prodMk ga) + ha.comp (f := f △ g) _ (fa.prodMk ga) /-- `ContMDiffAt.comp₂`, with a separate argument for point equality. -/ theorem ContMDiffAt.comp₂_of_eq {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} {y : M' × N'} diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 19a57d0c91d8d5..4ce6d886430d41 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -215,7 +215,7 @@ section Prod theorem MDifferentiableWithinAt.prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) : - MDiffAt[s] (fun x ↦ (f x, g x)) x := + MDiffAt[s] (f △ g) x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ /-- If `f` and `g` have derivatives `df` and `dg` within `s` at `x`, respectively, @@ -228,17 +228,17 @@ theorem HasMFDerivWithinAt.prodMk {f : M → M'} {g : M → M''} lemma mfderivWithin_prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) (hs : UniqueMDiffWithinAt I s x) : - mfderiv[s] (fun x ↦ (f x, g x)) x = (mfderiv[s] f x).prod (mfderiv[s] g x) := + mfderiv[s] (f △ g) x = (mfderiv[s] f x).prod (mfderiv[s] g x) := (hf.hasMFDerivWithinAt.prodMk hg.hasMFDerivWithinAt).mfderivWithin hs lemma mfderiv_prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt f x) (hg : MDiffAt g x) : - mfderiv% (fun x ↦ (f x, g x)) x = (mfderiv% f x).prod (mfderiv% g x) := by + mfderiv% (f △ g) x = (mfderiv% f x).prod (mfderiv% g x) := by simp_rw [← mfderivWithin_univ] exact mfderivWithin_prodMk hf.mdifferentiableWithinAt hg.mdifferentiableWithinAt (uniqueMDiffWithinAt_univ I) theorem MDifferentiableAt.prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt f x) (hg : MDiffAt g x) : - MDiffAt (fun x ↦ (f x, g x)) x := + MDiffAt (f △ g) x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ /-- If `f` and `g` have derivatives `df` and `dg` at `x`, respectively, @@ -251,27 +251,27 @@ theorem HasMFDerivAt.prodMk {f : M → M'} {g : M → M''} theorem MDifferentiableWithinAt.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) : - MDifferentiableWithinAt I 𝓘(𝕜, E' × E'') (fun x ↦ (f x, g x)) s x := + MDifferentiableWithinAt I 𝓘(𝕜, E' × E'') (f △ g) s x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem MDifferentiableAt.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiffAt f x) (hg : MDiffAt g x) : - MDifferentiableAt I 𝓘(𝕜, E' × E'') (fun x ↦ (f x, g x)) x := + MDifferentiableAt I 𝓘(𝕜, E' × E'') (f △ g) x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem MDifferentiableOn.prodMk {f : M → M'} {g : M → M''} (hf : MDiff[s] f) (hg : MDiff[s] g) : - MDiff[s] (fun x ↦ (f x, g x)) := fun x hx ↦ (hf x hx).prodMk (hg x hx) + MDiff[s] (f △ g) := fun x hx ↦ (hf x hx).prodMk (hg x hx) theorem MDifferentiable.prodMk {f : M → M'} {g : M → M''} (hf : MDiff f) (hg : MDiff g) : - MDiff fun x ↦ (f x, g x) := fun x ↦ (hf x).prodMk (hg x) + MDiff f △ g := fun x ↦ (hf x).prodMk (hg x) theorem MDifferentiableOn.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiff[s] f) (hg : MDiff[s] g) : - MDifferentiableOn I 𝓘(𝕜, E' × E'') (fun x ↦ (f x, g x)) s := + MDifferentiableOn I 𝓘(𝕜, E' × E'') (f △ g) s := fun x hx ↦ (hf x hx).prodMk_space (hg x hx) theorem MDifferentiable.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiff f) (hg : MDiff g) : - MDifferentiable I 𝓘(𝕜, E' × E'') fun x ↦ (f x, g x) := + MDifferentiable I 𝓘(𝕜, E' × E'') f △ g := fun x ↦ (hf x).prodMk_space (hg x) theorem hasMFDerivAt_fst (x : M × M') : diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 23614e3b3a8c2b..82fa26eb4d1f41 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -163,7 +163,8 @@ variable {a b : α} @[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Δ a) = (f △ g) a := rfl -theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = (f △ g) := rfl +@[simp] theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = (f △ g) := + rfl theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst @@ -172,6 +173,9 @@ theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ @[simp] theorem diag_eq_iff : Δ a = Δ b ↔ a = b := injective_diag.eq_iff +@[simp] theorem prod_diag_diag : Function.diag △ Function.diag (α := α) = + Function.diag ∘ Function.diag := rfl + end end Function diff --git a/Mathlib/Order/Filter/EventuallyConst.lean b/Mathlib/Order/Filter/EventuallyConst.lean index ca8acc5962f950..aa35b482b539bb 100644 --- a/Mathlib/Order/Filter/EventuallyConst.lean +++ b/Mathlib/Order/Filter/EventuallyConst.lean @@ -125,7 +125,7 @@ lemma comp₂ {g : α → γ} (hf : EventuallyConst f l) (op : β → γ → δ) (tendsto_map (f := op.uncurry)).comp (tendsto_map.prodMk tendsto_map) lemma prodMk {g : α → γ} (hf : EventuallyConst f l) (hg : EventuallyConst g l) : - EventuallyConst (fun x ↦ (f x, g x)) l := + EventuallyConst (f △ g) l := hf.comp₂ Prod.mk hg @[to_additive] diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index d7177b87e2b1a0..9d5d3802f9913f 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -448,7 +448,7 @@ theorem ωSup_zip (c₀ : Chain α) (c₁ : Chain β) : ωSup (c₀.zip c₁) = @[fun_prop] lemma ωScottContinuous.prodMk {f : α → β} (hf : ωScottContinuous f) {g : α → γ} (hg : ωScottContinuous g) : - ωScottContinuous fun x ↦ (f x, g x) := + ωScottContinuous f △ g := ScottContinuousOn.prodMk (fun a b hab ↦ ⟨pair a b hab, range_pair a b hab⟩) hf hg @[fun_prop] diff --git a/Mathlib/Probability/Kernel/Composition/MapComap.lean b/Mathlib/Probability/Kernel/Composition/MapComap.lean index d99d07d86f0cb6..4c44d18c8b2d4a 100644 --- a/Mathlib/Probability/Kernel/Composition/MapComap.lean +++ b/Mathlib/Probability/Kernel/Composition/MapComap.lean @@ -450,13 +450,13 @@ instance (priority := 100) isFiniteKernel_of_isFiniteKernel_fst {κ : Kernel α simp lemma fst_map_prod (κ : Kernel α β) {f : β → γ} {g : β → δ} (hg : Measurable g) : - fst (map κ (fun x ↦ (f x, g x))) = map κ f := by + fst (map κ (f △ g)) = map κ f := by by_cases hf : Measurable f · ext x s hs rw [fst_apply' _ _ hs, map_apply' _ (hf.prod hg) _, map_apply' _ hf _ hs] · simp only [Set.preimage, Set.mem_setOf] · exact measurable_fst hs - · have : ¬ Measurable (fun x ↦ (f x, g x)) := by + · have : ¬ Measurable (f △ g) := by contrapose! hf; exact hf.fst simp [map_of_not_measurable _ hf, map_of_not_measurable _ this] @@ -512,13 +512,13 @@ instance (priority := 100) isFiniteKernel_of_isFiniteKernel_snd {κ : Kernel α simp lemma snd_map_prod (κ : Kernel α β) {f : β → γ} {g : β → δ} (hf : Measurable f) : - snd (map κ (fun x ↦ (f x, g x))) = map κ g := by + snd (map κ (f △ g)) = map κ g := by by_cases hg : Measurable g · ext x s hs rw [snd_apply' _ _ hs, map_apply' _ (hf.prod hg), map_apply' _ hg _ hs] · simp only [Set.preimage, Set.mem_setOf] · exact measurable_snd hs - · have : ¬ Measurable (fun x ↦ (f x, g x)) := by + · have : ¬ Measurable (f △ g) := by contrapose! hg; exact hg.snd simp [map_of_not_measurable _ hg, map_of_not_measurable _ this] diff --git a/Mathlib/Tactic/FunProp.lean b/Mathlib/Tactic/FunProp.lean index a3dfd2a7215af4..9c8a86a6169f6e 100644 --- a/Mathlib/Tactic/FunProp.lean +++ b/Mathlib/Tactic/FunProp.lean @@ -214,7 +214,7 @@ There are four types of theorems that are used a bit differently. Continuous (fun x ↦ (f x).snd) := ... @[fun_prop] theorem continuous_prod_mk (f : X → Y) (g : X → Z) (hf : Continuous f) (hg : Continuous g) : - Continuous (fun x ↦ (f x, g x)) := ... + Continuous (f △ g) := ... ``` - Function Theorems: diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index f4adcf7562c83b..02dcd102616f61 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -491,19 +491,19 @@ theorem tendsto_swap_uniformity : Tendsto (@Prod.swap α α) (𝓤 α) (𝓤 α) theorem comp_mem_uniformity_sets {s : SetRel α α} (hs : s ∈ 𝓤 α) : ∃ t ∈ 𝓤 α, t ○ t ⊆ s := (mem_lift'_sets <| monotone_id.relComp monotone_id).mp <| comp_le_uniformity hs -/-- Relation `fun f g ↦ Tendsto (fun x ↦ (f x, g x)) l (𝓤 α)` is transitive. -/ +/-- Relation `fun f g ↦ Tendsto (f △ g) l (𝓤 α)` is transitive. -/ theorem Filter.Tendsto.uniformity_trans {l : Filter β} {f₁ f₂ f₃ : β → α} (h₁₂ : Tendsto (fun x => (f₁ x, f₂ x)) l (𝓤 α)) (h₂₃ : Tendsto (fun x => (f₂ x, f₃ x)) l (𝓤 α)) : Tendsto (fun x => (f₁ x, f₃ x)) l (𝓤 α) := by refine le_trans (le_lift'.2 fun s hs => mem_map.2 ?_) comp_le_uniformity filter_upwards [mem_map.1 (h₁₂ hs), mem_map.1 (h₂₃ hs)] with x hx₁₂ hx₂₃ using ⟨_, hx₁₂, hx₂₃⟩ -/-- Relation `fun f g ↦ Tendsto (fun x ↦ (f x, g x)) l (𝓤 α)` is symmetric. -/ +/-- Relation `fun f g ↦ Tendsto (f △ g) l (𝓤 α)` is symmetric. -/ theorem Filter.Tendsto.uniformity_symm {l : Filter β} {f : β → α × α} (h : Tendsto f l (𝓤 α)) : Tendsto (fun x => ((f x).2, (f x).1)) l (𝓤 α) := tendsto_swap_uniformity.comp h -/-- Relation `fun f g ↦ Tendsto (fun x ↦ (f x, g x)) l (𝓤 α)` is reflexive. -/ +/-- Relation `fun f g ↦ Tendsto (f △ g) l (𝓤 α)` is reflexive. -/ theorem tendsto_diag_uniformity (f : β → α) (l : Filter β) : Tendsto (fun x => (f x, f x)) l (𝓤 α) := fun _s hs => mem_map.2 <| univ_mem' fun _ => refl_mem_uniformity hs diff --git a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean index 2170661fd474fb..051553daf3f1b5 100644 --- a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean @@ -200,7 +200,7 @@ end Comp theorem TendstoLocallyUniformlyOn.prodMk [UniformSpace γ] {G : ι → α → γ} {g : α → γ} (hF : TendstoLocallyUniformlyOn F f p s) (hG : TendstoLocallyUniformlyOn G g p s) : - TendstoLocallyUniformlyOn (fun n x ↦ (F n x, G n x)) (fun x ↦ (f x, g x)) p s := by + TendstoLocallyUniformlyOn (fun n x ↦ (F n x, G n x)) (f △ g) p s := by rw [tendstoLocallyUniformlyOn_iff_forall_tendsto] at * intro x hx rw [uniformity_prod_eq_comap_prod, tendsto_comap_iff] @@ -213,7 +213,7 @@ theorem TendstoLocallyUniformlyOn.piProd [UniformSpace γ] {G : ι → α → γ theorem TendstoLocallyUniformly.prodMk [UniformSpace γ] {G : ι → α → γ} {g : α → γ} (hF : TendstoLocallyUniformly F f p) (hG : TendstoLocallyUniformly G g p) : - TendstoLocallyUniformly (fun n x ↦ (F n x, G n x)) (fun x ↦ (f x, g x)) p := by + TendstoLocallyUniformly (fun n x ↦ (F n x, G n x)) (f △ g) p := by rw [← tendstoLocallyUniformlyOn_univ] at * exact hF.prodMk hG diff --git a/Mathlib/Topology/UniformSpace/Separation.lean b/Mathlib/Topology/UniformSpace/Separation.lean index f98785563d78df..d440ca9978aba5 100644 --- a/Mathlib/Topology/UniformSpace/Separation.lean +++ b/Mathlib/Topology/UniformSpace/Separation.lean @@ -207,7 +207,7 @@ theorem eq_of_clusterPt_uniformity [T0Space α] {x y : α} (h : ClusterPt (x, y) theorem Filter.Tendsto.inseparable_iff_uniformity {β} {l : Filter β} [NeBot l] {f g : β → α} {a b : α} (ha : Tendsto f l (𝓝 a)) (hb : Tendsto g l (𝓝 b)) : - Inseparable a b ↔ Tendsto (fun x ↦ (f x, g x)) l (𝓤 α) := by + Inseparable a b ↔ Tendsto (f △ g) l (𝓤 α) := by refine ⟨fun h ↦ (ha.prodMk_nhds hb).mono_right h.nhds_le_uniformity, fun h ↦ ?_⟩ rw [inseparable_iff_clusterPt_uniformity] exact (ClusterPt.of_le_nhds (ha.prodMk_nhds hb)).mono h diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 2976d90b7c9fc8..147ab71b959e14 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -1067,7 +1067,7 @@ section product /-- info: MDifferentiable I (I'.prod I') fun x ↦ Prod.mk (f x) (g x) : Prop -/ #guard_msgs in -#check MDiff (fun x ↦ (f x, g x)) +#check MDiff (f △ g) /-- info: MDifferentiable (I.prod (modelWithCornersSelf 𝕜 E)) I' k : Prop -/ #guard_msgs in From 9773b26b770441643583fcca6b70d641faf7391c Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:16:44 +0100 Subject: [PATCH 23/35] Fix --- Mathlib/Algebra/Notation/Support.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Notation/Support.lean b/Mathlib/Algebra/Notation/Support.lean index fdc45efbd56586..0ac45ce5c76c60 100644 --- a/Mathlib/Algebra/Notation/Support.lean +++ b/Mathlib/Algebra/Notation/Support.lean @@ -174,13 +174,12 @@ lemma mulSupport_comp_eq_preimage (g : κ → M) (f : ι → κ) : @[to_additive support_prodMk] lemma mulSupport_prodMk (f : ι → M) (g : ι → N) : mulSupport (f △ g) = mulSupport f ∪ mulSupport g := - Set.ext fun x ↦ by - simp only [mulSupport, not_and_or, mem_union, mem_setOf_eq, Prod.mk_eq_one, Ne] + Set.ext fun x ↦ by simp [mulSupport, Prod.ext_iff, imp_iff_not_or] @[to_additive support_prodMk'] lemma mulSupport_prodMk' (f : ι → M × N) : - mulSupport f = (mulSupport fun x ↦ (f x).1) ∪ mulSupport fun x ↦ (f x).2 := by - simp only [← mulSupport_prodMk] + mulSupport f = (mulSupport (Prod.fst ∘ f)) ∪ mulSupport (Prod.snd ∘ f) := by + simp [← mulSupport_prodMk] @[to_additive] lemma mulSupport_along_fiber_subset (f : ι × κ → M) (i : ι) : From 56051da63cc7736fdff5e3d955183562beb628bc Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:20:46 +0100 Subject: [PATCH 24/35] Adjust variable name --- .../SimplexCategory/Basic.lean | 42 +++++++++---------- .../Bicategory/Modification/Pseudo.lean | 6 +-- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 4d974b7baba490..19d05839539d93 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -204,7 +204,7 @@ lemma diag_subinterval_eq {n} (j l : ℕ) (hjl : j + l ≤ n) : ext (i : Fin 2) match i with | 0 | 1 => simp <;> lia -instance (Δ : SimplexCategory) : Subsingleton (Δ ⟶ ⦋0⦌) where +instance (D : SimplexCategory) : Subsingleton (D ⟶ ⦋0⦌) where allEq f g := by ext : 3; apply Subsingleton.elim (α := Fin 1) theorem hom_zero_zero (f : ⦋0⦌ ⟶ ⦋0⦌) : f = 𝟙 _ := by @@ -538,7 +538,7 @@ def skeletalFunctor : SimplexCategory ⥤ NonemptyFinLinOrd where obj a := NonemptyFinLinOrd.of (Fin (a.len + 1)) map f := NonemptyFinLinOrd.ofHom f.toOrderHom -theorem skeletalFunctor.coe_map {Δ₁ Δ₂ : SimplexCategory} (f : Δ₁ ⟶ Δ₂) : +theorem skeletalFunctor.coe_map {D₁ D₂ : SimplexCategory} (f : D₁ ⟶ D₂) : ↑(skeletalFunctor.map f).hom.hom = f.toOrderHom := rfl @@ -737,9 +737,9 @@ theorem eq_id_of_isIso {x : SimplexCategory} (f : x ⟶ x) [IsIso f] : f = 𝟙 congr_arg (fun φ : _ ≅ _ => φ.hom) (iso_eq_iso_refl (asIso f)) set_option backward.isDefEq.respectTransparency false in -theorem eq_σ_comp_of_not_injective' {n : ℕ} {Δ' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ Δ') +theorem eq_σ_comp_of_not_injective' {n : ℕ} {D' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ D') (i : Fin (n + 1)) (hi : θ.toOrderHom (Fin.castSucc i) = θ.toOrderHom i.succ) : - ∃ θ' : ⦋n⦌ ⟶ Δ', θ = σ i ≫ θ' := by + ∃ θ' : ⦋n⦌ ⟶ D', θ = σ i ≫ θ' := by use δ i.succ ≫ θ ext x : 3 simp only [len_mk, σ, mkHom, comp_toOrderHom, Hom.toOrderHom_mk, OrderHom.comp_coe, @@ -769,9 +769,9 @@ theorem eq_σ_comp_of_not_injective' {n : ℕ} {Δ' : SimplexCategory} (θ : ⦋ lia set_option backward.isDefEq.respectTransparency false in -theorem eq_σ_comp_of_not_injective {n : ℕ} {Δ' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ Δ') +theorem eq_σ_comp_of_not_injective {n : ℕ} {D' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ D') (hθ : ¬Function.Injective θ.toOrderHom) : - ∃ (i : Fin (n + 1)) (θ' : ⦋n⦌ ⟶ Δ'), θ = σ i ≫ θ' := by + ∃ (i : Fin (n + 1)) (θ' : ⦋n⦌ ⟶ D'), θ = σ i ≫ θ' := by simp only [Function.Injective, exists_prop, not_forall] at hθ -- as θ is not injective, there exists `x simp [hj] -theorem eq_comp_δ_of_not_surjective {n : ℕ} {Δ : SimplexCategory} (θ : Δ ⟶ ⦋n + 1⦌) +theorem eq_comp_δ_of_not_surjective {n : ℕ} {D : SimplexCategory} (θ : D ⟶ ⦋n + 1⦌) (hθ : ¬Function.Surjective θ.toOrderHom) : - ∃ (i : Fin (n + 2)) (θ' : Δ ⟶ ⦋n⦌), θ = θ' ≫ δ i := by + ∃ (i : Fin (n + 2)) (θ' : D ⟶ ⦋n⦌), θ = θ' ≫ δ i := by obtain ⟨i, hi⟩ := not_forall.mp hθ use i exact eq_comp_δ_of_not_surjective' θ i (not_exists.mp hi) @@ -836,8 +836,8 @@ theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i haveI := CategoryTheory.mono_of_mono θ' (δ i) rw [h, eq_id_of_mono θ', Category.id_comp] -theorem len_lt_of_mono {Δ' Δ : SimplexCategory} (i : Δ' ⟶ Δ) [Mono i] (hi' : Δ ≠ Δ') : - Δ'.len < Δ.len := by +theorem len_lt_of_mono {D' D : SimplexCategory} (i : D' ⟶ D) [Mono i] (hi' : D ≠ D') : + D'.len < D.len := by grind [→ len_le_of_mono, SimplexCategory.ext] noncomputable instance : SplitEpiCategory SimplexCategory := @@ -850,24 +850,24 @@ instance : HasStrongEpiMonoFactorisations SimplexCategory := instance : HasStrongEpiImages SimplexCategory := Limits.hasStrongEpiImages_of_hasStrongEpiMonoFactorisations -instance (Δ Δ' : SimplexCategory) (θ : Δ ⟶ Δ') : Epi (factorThruImage θ) := +instance (D D' : SimplexCategory) (θ : D ⟶ D') : Epi (factorThruImage θ) := StrongEpi.epi -theorem image_eq {Δ Δ' Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ Δ'} [Epi e] {i : Δ' ⟶ Δ''} - [Mono i] (fac : e ≫ i = φ) : image φ = Δ' := by +theorem image_eq {D D' D'' : SimplexCategory} {φ : D ⟶ D''} {e : D ⟶ D'} [Epi e] {i : D' ⟶ D''} + [Mono i] (fac : e ≫ i = φ) : image φ = D' := by haveI := strongEpi_of_epi e let e := image.isoStrongEpiMono e i fac ext exact le_antisymm (len_le_of_epi e.hom) (len_le_of_mono e.hom) -theorem image_ι_eq {Δ Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ image φ} [Epi e] - {i : image φ ⟶ Δ''} [Mono i] (fac : e ≫ i = φ) : image.ι φ = i := by +theorem image_ι_eq {D D'' : SimplexCategory} {φ : D ⟶ D''} {e : D ⟶ image φ} [Epi e] + {i : image φ ⟶ D''} [Mono i] (fac : e ≫ i = φ) : image.ι φ = i := by haveI := strongEpi_of_epi e rw [← image.isoStrongEpiMono_hom_comp_ι e i fac, SimplexCategory.eq_id_of_isIso (image.isoStrongEpiMono e i fac).hom, Category.id_comp] -theorem factorThruImage_eq {Δ Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ image φ} [Epi e] - {i : image φ ⟶ Δ''} [Mono i] (fac : e ≫ i = φ) : factorThruImage φ = e := by +theorem factorThruImage_eq {D D'' : SimplexCategory} {φ : D ⟶ D''} {e : D ⟶ image φ} [Epi e] + {i : image φ ⟶ D''} [Mono i] (fac : e ≫ i = φ) : factorThruImage φ = e := by rw [← cancel_mono i, fac, ← image_ι_eq fac, image.fac] end EpiMono @@ -882,8 +882,8 @@ def toCat : SimplexCategory ⥤ Cat.{0} := theorem toCat.obj_eq_Fin (n : ℕ) : toCat.obj ⦋n⦌ = Fin (n + 1) := rfl -instance uniqueHomToZero {Δ : SimplexCategory} : Unique (Δ ⟶ ⦋0⦌) where - default := Δ.const _ 0 +instance uniqueHomToZero {D : SimplexCategory} : Unique (D ⟶ ⦋0⦌) where + default := D.const _ 0 uniq := eq_const_to_zero /-- The object `⦋0⦌` is terminal in `SimplexCategory`. -/ diff --git a/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean b/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean index fe16ab520f6ac3..000368d4b5f933 100644 --- a/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean +++ b/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean @@ -119,8 +119,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ Δ.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ D.app a end Modification @@ -140,7 +140,7 @@ Note that this a scoped instance in the `Pseudofunctor.StrongTrans` namespace. - scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id Γ := ⟨Modification.id Γ⟩ - comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ + comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ From 6290791aaa599947d45a6a771492ed09c6c1cdf2 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:31:49 +0100 Subject: [PATCH 25/35] Change notation --- Mathlib/Logic/Function/Init.lean | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 82fa26eb4d1f41..37f837bfc373ea 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -149,18 +149,18 @@ theorem map_comp_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ /-- The diagonal map into `Prod`. -/ protected def diag : α → α × α := id △ id -@[inherit_doc] prefix:max "Δ " => Function.diag +@[inherit_doc] prefix:max "⇗" => Function.diag section variable {a b : α} -@[grind =] theorem diag_apply : Δ a = (a, a) := rfl +@[grind =] theorem diag_apply : ⇗a = (a, a) := rfl -@[simp, grind =] theorem fst_diag : (Δ a).1 = a := rfl -@[simp, grind =] theorem snd_diag : (Δ a).2 = a := rfl +@[simp, grind =] theorem fst_diag : (⇗a).1 = a := rfl +@[simp, grind =] theorem snd_diag : (⇗a).2 = a := rfl -@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (Δ a) = +@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (⇗a) = (f △ g) a := rfl @[simp] theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = (f △ g) := @@ -168,10 +168,10 @@ variable {a b : α} theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst -@[simp] theorem exists_diag_apply_iff (p : α × α) : (∃ a, Δ a = p) ↔ p.1 = p.2 := by +@[simp] theorem exists_diag_apply_iff (p : α × α) : (∃ a, ⇗a = p) ↔ p.1 = p.2 := by simp [Prod.ext_iff, eq_comm] -@[simp] theorem diag_eq_iff : Δ a = Δ b ↔ a = b := injective_diag.eq_iff +@[simp] theorem diag_eq_iff : ⇗a = ⇗b ↔ a = b := injective_diag.eq_iff @[simp] theorem prod_diag_diag : Function.diag △ Function.diag (α := α) = Function.diag ∘ Function.diag := rfl From 6b27fab4c807489b787ae0f387b2686d340867dc Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:34:34 +0100 Subject: [PATCH 26/35] =?UTF-8?q?Revert=20=CE=94=E2=86=92D=20substitutions?= =?UTF-8?q?=20in=20files=20with=20no=20other=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../SimplexCategory/Basic.lean | 42 +++++++++---------- .../Bicategory/Modification/Lax.lean | 16 +++---- .../Bicategory/Modification/Oplax.lean | 18 ++++---- .../Bicategory/Modification/Pseudo.lean | 6 +-- Mathlib/CategoryTheory/Subfunctor/Image.lean | 2 +- Mathlib/SetTheory/ZFC/Basic.lean | 2 +- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 19d05839539d93..4d974b7baba490 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -204,7 +204,7 @@ lemma diag_subinterval_eq {n} (j l : ℕ) (hjl : j + l ≤ n) : ext (i : Fin 2) match i with | 0 | 1 => simp <;> lia -instance (D : SimplexCategory) : Subsingleton (D ⟶ ⦋0⦌) where +instance (Δ : SimplexCategory) : Subsingleton (Δ ⟶ ⦋0⦌) where allEq f g := by ext : 3; apply Subsingleton.elim (α := Fin 1) theorem hom_zero_zero (f : ⦋0⦌ ⟶ ⦋0⦌) : f = 𝟙 _ := by @@ -538,7 +538,7 @@ def skeletalFunctor : SimplexCategory ⥤ NonemptyFinLinOrd where obj a := NonemptyFinLinOrd.of (Fin (a.len + 1)) map f := NonemptyFinLinOrd.ofHom f.toOrderHom -theorem skeletalFunctor.coe_map {D₁ D₂ : SimplexCategory} (f : D₁ ⟶ D₂) : +theorem skeletalFunctor.coe_map {Δ₁ Δ₂ : SimplexCategory} (f : Δ₁ ⟶ Δ₂) : ↑(skeletalFunctor.map f).hom.hom = f.toOrderHom := rfl @@ -737,9 +737,9 @@ theorem eq_id_of_isIso {x : SimplexCategory} (f : x ⟶ x) [IsIso f] : f = 𝟙 congr_arg (fun φ : _ ≅ _ => φ.hom) (iso_eq_iso_refl (asIso f)) set_option backward.isDefEq.respectTransparency false in -theorem eq_σ_comp_of_not_injective' {n : ℕ} {D' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ D') +theorem eq_σ_comp_of_not_injective' {n : ℕ} {Δ' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ Δ') (i : Fin (n + 1)) (hi : θ.toOrderHom (Fin.castSucc i) = θ.toOrderHom i.succ) : - ∃ θ' : ⦋n⦌ ⟶ D', θ = σ i ≫ θ' := by + ∃ θ' : ⦋n⦌ ⟶ Δ', θ = σ i ≫ θ' := by use δ i.succ ≫ θ ext x : 3 simp only [len_mk, σ, mkHom, comp_toOrderHom, Hom.toOrderHom_mk, OrderHom.comp_coe, @@ -769,9 +769,9 @@ theorem eq_σ_comp_of_not_injective' {n : ℕ} {D' : SimplexCategory} (θ : ⦋n lia set_option backward.isDefEq.respectTransparency false in -theorem eq_σ_comp_of_not_injective {n : ℕ} {D' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ D') +theorem eq_σ_comp_of_not_injective {n : ℕ} {Δ' : SimplexCategory} (θ : ⦋n + 1⦌ ⟶ Δ') (hθ : ¬Function.Injective θ.toOrderHom) : - ∃ (i : Fin (n + 1)) (θ' : ⦋n⦌ ⟶ D'), θ = σ i ≫ θ' := by + ∃ (i : Fin (n + 1)) (θ' : ⦋n⦌ ⟶ Δ'), θ = σ i ≫ θ' := by simp only [Function.Injective, exists_prop, not_forall] at hθ -- as θ is not injective, there exists `x simp [hj] -theorem eq_comp_δ_of_not_surjective {n : ℕ} {D : SimplexCategory} (θ : D ⟶ ⦋n + 1⦌) +theorem eq_comp_δ_of_not_surjective {n : ℕ} {Δ : SimplexCategory} (θ : Δ ⟶ ⦋n + 1⦌) (hθ : ¬Function.Surjective θ.toOrderHom) : - ∃ (i : Fin (n + 2)) (θ' : D ⟶ ⦋n⦌), θ = θ' ≫ δ i := by + ∃ (i : Fin (n + 2)) (θ' : Δ ⟶ ⦋n⦌), θ = θ' ≫ δ i := by obtain ⟨i, hi⟩ := not_forall.mp hθ use i exact eq_comp_δ_of_not_surjective' θ i (not_exists.mp hi) @@ -836,8 +836,8 @@ theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i haveI := CategoryTheory.mono_of_mono θ' (δ i) rw [h, eq_id_of_mono θ', Category.id_comp] -theorem len_lt_of_mono {D' D : SimplexCategory} (i : D' ⟶ D) [Mono i] (hi' : D ≠ D') : - D'.len < D.len := by +theorem len_lt_of_mono {Δ' Δ : SimplexCategory} (i : Δ' ⟶ Δ) [Mono i] (hi' : Δ ≠ Δ') : + Δ'.len < Δ.len := by grind [→ len_le_of_mono, SimplexCategory.ext] noncomputable instance : SplitEpiCategory SimplexCategory := @@ -850,24 +850,24 @@ instance : HasStrongEpiMonoFactorisations SimplexCategory := instance : HasStrongEpiImages SimplexCategory := Limits.hasStrongEpiImages_of_hasStrongEpiMonoFactorisations -instance (D D' : SimplexCategory) (θ : D ⟶ D') : Epi (factorThruImage θ) := +instance (Δ Δ' : SimplexCategory) (θ : Δ ⟶ Δ') : Epi (factorThruImage θ) := StrongEpi.epi -theorem image_eq {D D' D'' : SimplexCategory} {φ : D ⟶ D''} {e : D ⟶ D'} [Epi e] {i : D' ⟶ D''} - [Mono i] (fac : e ≫ i = φ) : image φ = D' := by +theorem image_eq {Δ Δ' Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ Δ'} [Epi e] {i : Δ' ⟶ Δ''} + [Mono i] (fac : e ≫ i = φ) : image φ = Δ' := by haveI := strongEpi_of_epi e let e := image.isoStrongEpiMono e i fac ext exact le_antisymm (len_le_of_epi e.hom) (len_le_of_mono e.hom) -theorem image_ι_eq {D D'' : SimplexCategory} {φ : D ⟶ D''} {e : D ⟶ image φ} [Epi e] - {i : image φ ⟶ D''} [Mono i] (fac : e ≫ i = φ) : image.ι φ = i := by +theorem image_ι_eq {Δ Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ image φ} [Epi e] + {i : image φ ⟶ Δ''} [Mono i] (fac : e ≫ i = φ) : image.ι φ = i := by haveI := strongEpi_of_epi e rw [← image.isoStrongEpiMono_hom_comp_ι e i fac, SimplexCategory.eq_id_of_isIso (image.isoStrongEpiMono e i fac).hom, Category.id_comp] -theorem factorThruImage_eq {D D'' : SimplexCategory} {φ : D ⟶ D''} {e : D ⟶ image φ} [Epi e] - {i : image φ ⟶ D''} [Mono i] (fac : e ≫ i = φ) : factorThruImage φ = e := by +theorem factorThruImage_eq {Δ Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ image φ} [Epi e] + {i : image φ ⟶ Δ''} [Mono i] (fac : e ≫ i = φ) : factorThruImage φ = e := by rw [← cancel_mono i, fac, ← image_ι_eq fac, image.fac] end EpiMono @@ -882,8 +882,8 @@ def toCat : SimplexCategory ⥤ Cat.{0} := theorem toCat.obj_eq_Fin (n : ℕ) : toCat.obj ⦋n⦌ = Fin (n + 1) := rfl -instance uniqueHomToZero {D : SimplexCategory} : Unique (D ⟶ ⦋0⦌) where - default := D.const _ 0 +instance uniqueHomToZero {Δ : SimplexCategory} : Unique (Δ ⟶ ⦋0⦌) where + default := Δ.const _ 0 uniq := eq_const_to_zero /-- The object `⦋0⦌` is terminal in `SimplexCategory`. -/ diff --git a/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean b/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean index a77f413e64eb43..a607ea0766471e 100644 --- a/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Modification/Lax.lean @@ -85,8 +85,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ D.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ Δ.app a end Modification @@ -107,13 +107,13 @@ Note that this is a scoped instance in the `Lax.LaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id η := ⟨Modification.id η⟩ - comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ + comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @[ext] -lemma homCategory.ext {Γ D : η ⟶ θ} (h : ∀ a, Γ.as.app a = D.as.app a) : Γ = D := +lemma homCategory.ext {Γ Δ : η ⟶ θ} (h : ∀ a, Γ.as.app a = Δ.as.app a) : Γ = Δ := Hom.ext <| Modification.ext <| funext h /-- Construct a modification isomorphism between lax natural transformations @@ -171,9 +171,9 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ D.app a + app a := Γ.app a ≫ Δ.app a end Modification @@ -194,13 +194,13 @@ Note that this is a scoped instance in the `Lax.OplaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id η := ⟨Modification.id η⟩ - comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ + comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @[ext] -lemma homCategory.ext {Γ D : η ⟶ θ} (h : ∀ a, Γ.as.app a = D.as.app a) : Γ = D := +lemma homCategory.ext {Γ Δ : η ⟶ θ} (h : ∀ a, Γ.as.app a = Δ.as.app a) : Γ = Δ := Hom.ext <| Modification.ext <| funext h /-- Construct a modification isomorphism between oplax natural transformations diff --git a/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean b/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean index 29a281e6b73f0d..0d7409d80b3499 100644 --- a/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Modification/Oplax.lean @@ -112,8 +112,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ D.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ Δ.app a end Modification @@ -134,7 +134,7 @@ Note that this is a scoped instance in the `Oplax.LaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id η := ⟨Modification.id η⟩ - comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ + comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @@ -213,8 +213,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ D.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ Δ.app a end Modification @@ -235,7 +235,7 @@ Note that this a scoped instance in the `Oplax.OplaxTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id Γ := ⟨Modification.id Γ⟩ - comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ + comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ @@ -342,8 +342,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ D.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ Δ.app a end Modification @@ -364,7 +364,7 @@ Note that this a scoped instance in the `Oplax.StrongTrans` namespace. -/ scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id Γ := ⟨Modification.id Γ⟩ - comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ + comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ diff --git a/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean b/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean index 000368d4b5f933..fe16ab520f6ac3 100644 --- a/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean +++ b/Mathlib/CategoryTheory/Bicategory/Modification/Pseudo.lean @@ -119,8 +119,8 @@ instance : Inhabited (Modification η η) := /-- Vertical composition of modifications. -/ @[simps] -def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (D : Modification θ ι) : Modification η ι where - app a := Γ.app a ≫ D.app a +def vcomp {ι : F ⟶ G} (Γ : Modification η θ) (Δ : Modification θ ι) : Modification η ι where + app a := Γ.app a ≫ Δ.app a end Modification @@ -140,7 +140,7 @@ Note that this a scoped instance in the `Pseudofunctor.StrongTrans` namespace. - scoped instance homCategory : Category (F ⟶ G) where Hom := Hom id Γ := ⟨Modification.id Γ⟩ - comp Γ D := ⟨Modification.vcomp Γ.as D.as⟩ + comp Γ Δ := ⟨Modification.vcomp Γ.as Δ.as⟩ instance : Inhabited (η ⟶ η) := ⟨𝟙 η⟩ diff --git a/Mathlib/CategoryTheory/Subfunctor/Image.lean b/Mathlib/CategoryTheory/Subfunctor/Image.lean index 3df07873185c6f..172820104e78bf 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Image.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Image.lean @@ -125,7 +125,7 @@ variable (G : Subfunctor F) (f : F ⟶ F') def image : Subfunctor F' where obj i := (f.app i) '' (G.obj i) map := by - rintro D D' φ _ ⟨x, hx, rfl⟩ + rintro Δ Δ' φ _ ⟨x, hx, rfl⟩ exact ⟨F.map φ x, G.map φ hx, by apply FunctorToTypes.naturality⟩ lemma image_top : (⊤ : Subfunctor F).image f = range f := by aesop diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index 27ae1f6dd13c12..fb336648ffb4d1 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -457,7 +457,7 @@ theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : | ⟨a, c⟩ => by let ⟨b, hb⟩ := αβ a induction ea : A a with | _ γ Γ - induction eb : B b with | _ δ D + induction eb : B b with | _ δ Δ rw [ea, eb] at hb obtain ⟨γδ, δγ⟩ := hb let c : (A a).Type := c From 92444162fee1a6d48963c852be6c07fddb67defa Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:36:06 +0100 Subject: [PATCH 27/35] Fix notation --- Mathlib/Data/Set/Prod.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 097f90221ff914..cd0c9633302a87 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -431,7 +431,7 @@ theorem preimage_val_val_diagonal (s : Set α) : @[deprecated (since := "2026-04-04")] alias preimage_coe_coe_diagonal := preimage_val_val_diagonal -theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, Δ x ∈ s := by +theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, ⇗x ∈ s := by simp_rw [← range_diag, range_subset_iff] @[simp] From 81c0460a30b4dfb7daf087401c0ea998464409cb Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:39:29 +0100 Subject: [PATCH 28/35] Change notation --- Mathlib/Algebra/Notation/Support.lean | 2 +- Mathlib/Analysis/Analytic/Constructions.lean | 16 ++-- Mathlib/Analysis/Asymptotics/TVS.lean | 8 +- Mathlib/Analysis/Calculus/ContDiff/Basic.lean | 4 +- .../Calculus/ContDiffHolder/Pointwise.lean | 2 +- .../CategoryTheory/Bicategory/Extension.lean | 14 ++-- .../CategoryTheory/Bicategory/Kan/HasKan.lean | 2 +- .../Combinatorics/Enumerative/Catalan.lean | 2 +- .../Combinatorics/Enumerative/DyckWord.lean | 4 +- Mathlib/Data/Prod/Basic.lean | 4 +- Mathlib/Data/Tree/Basic.lean | 10 +-- .../Manifold/ContMDiff/Constructions.lean | 8 +- .../Manifold/MFDeriv/SpecificFunctions.lean | 20 ++--- Mathlib/Logic/Function/Init.lean | 80 +++++++++---------- Mathlib/Order/Basic.lean | 6 +- Mathlib/Order/Filter/Basic.lean | 2 +- Mathlib/Order/Filter/EventuallyConst.lean | 2 +- Mathlib/Order/OmegaCompletePartialOrder.lean | 2 +- Mathlib/Order/ScottContinuity.lean | 2 +- .../Kernel/Composition/MapComap.lean | 8 +- Mathlib/Tactic/FunProp.lean | 2 +- Mathlib/Topology/UniformSpace/Defs.lean | 6 +- .../LocallyUniformConvergence.lean | 4 +- Mathlib/Topology/UniformSpace/Separation.lean | 2 +- .../DifferentialGeometry/Notation/Basic.lean | 2 +- 25 files changed, 107 insertions(+), 107 deletions(-) diff --git a/Mathlib/Algebra/Notation/Support.lean b/Mathlib/Algebra/Notation/Support.lean index 0ac45ce5c76c60..8c1e3eaa1e17d6 100644 --- a/Mathlib/Algebra/Notation/Support.lean +++ b/Mathlib/Algebra/Notation/Support.lean @@ -173,7 +173,7 @@ lemma mulSupport_comp_eq_preimage (g : κ → M) (f : ι → κ) : @[to_additive support_prodMk] lemma mulSupport_prodMk (f : ι → M) (g : ι → N) : - mulSupport (f △ g) = mulSupport f ∪ mulSupport g := + mulSupport (f ⇊ g) = mulSupport f ∪ mulSupport g := Set.ext fun x ↦ by simp [mulSupport, Prod.ext_iff, imp_iff_not_or] @[to_additive support_prodMk'] diff --git a/Mathlib/Analysis/Analytic/Constructions.lean b/Mathlib/Analysis/Analytic/Constructions.lean index 2ec3e15f5a4c6b..68bf87c40ed249 100644 --- a/Mathlib/Analysis/Analytic/Constructions.lean +++ b/Mathlib/Analysis/Analytic/Constructions.lean @@ -290,7 +290,7 @@ lemma FormalMultilinearSeries.radius_prod_eq_min lemma HasFPowerSeriesWithinOnBall.prod {e : E} {f : E → F} {g : E → G} {r s : ℝ≥0∞} {t : Set E} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesWithinOnBall f p t e r) (hg : HasFPowerSeriesWithinOnBall g q t e s) : - HasFPowerSeriesWithinOnBall (f △ g) (p.prod q) t e (min r s) where + HasFPowerSeriesWithinOnBall (f ⇊ g) (p.prod q) t e (min r s) where r_le := by rw [p.radius_prod_eq_min] exact min_le_min hf.r_le hg.r_le @@ -305,14 +305,14 @@ lemma HasFPowerSeriesWithinOnBall.prod {e : E} {f : E → F} {g : E → G} {r s lemma HasFPowerSeriesOnBall.prod {e : E} {f : E → F} {g : E → G} {r s : ℝ≥0∞} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesOnBall f p e r) (hg : HasFPowerSeriesOnBall g q e s) : - HasFPowerSeriesOnBall (f △ g) (p.prod q) e (min r s) := by + HasFPowerSeriesOnBall (f ⇊ g) (p.prod q) e (min r s) := by rw [← hasFPowerSeriesWithinOnBall_univ] at hf hg ⊢ exact hf.prod hg lemma HasFPowerSeriesWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set E} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesWithinAt f p s e) (hg : HasFPowerSeriesWithinAt g q s e) : - HasFPowerSeriesWithinAt (f △ g) (p.prod q) s e := by + HasFPowerSeriesWithinAt (f ⇊ g) (p.prod q) s e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -320,7 +320,7 @@ lemma HasFPowerSeriesWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set lemma HasFPowerSeriesAt.prod {e : E} {f : E → F} {g : E → G} {p : FormalMultilinearSeries 𝕜 E F} {q : FormalMultilinearSeries 𝕜 E G} (hf : HasFPowerSeriesAt f p e) (hg : HasFPowerSeriesAt g q e) : - HasFPowerSeriesAt (f △ g) (p.prod q) e := by + HasFPowerSeriesAt (f ⇊ g) (p.prod q) e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -328,7 +328,7 @@ lemma HasFPowerSeriesAt.prod {e : E} {f : E → F} {g : E → G} /-- The Cartesian product of analytic functions is analytic. -/ lemma AnalyticWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set E} (hf : AnalyticWithinAt 𝕜 f s e) (hg : AnalyticWithinAt 𝕜 g s e) : - AnalyticWithinAt 𝕜 (f △ g) s e := by + AnalyticWithinAt 𝕜 (f ⇊ g) s e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -337,7 +337,7 @@ lemma AnalyticWithinAt.prod {e : E} {f : E → F} {g : E → G} {s : Set E} @[fun_prop] lemma AnalyticAt.prod {e : E} {f : E → F} {g : E → G} (hf : AnalyticAt 𝕜 f e) (hg : AnalyticAt 𝕜 g e) : - AnalyticAt 𝕜 (f △ g) e := by + AnalyticAt 𝕜 (f ⇊ g) e := by rcases hf with ⟨_, hf⟩ rcases hg with ⟨_, hg⟩ exact ⟨_, hf.prod hg⟩ @@ -345,13 +345,13 @@ lemma AnalyticAt.prod {e : E} {f : E → F} {g : E → G} /-- The Cartesian product of analytic functions within a set is analytic. -/ lemma AnalyticOn.prod {f : E → F} {g : E → G} {s : Set E} (hf : AnalyticOn 𝕜 f s) (hg : AnalyticOn 𝕜 g s) : - AnalyticOn 𝕜 (f △ g) s := + AnalyticOn 𝕜 (f ⇊ g) s := fun x hx ↦ (hf x hx).prod (hg x hx) /-- The Cartesian product of analytic functions is analytic. -/ lemma AnalyticOnNhd.prod {f : E → F} {g : E → G} {s : Set E} (hf : AnalyticOnNhd 𝕜 f s) (hg : AnalyticOnNhd 𝕜 g s) : - AnalyticOnNhd 𝕜 (f △ g) s := + AnalyticOnNhd 𝕜 (f ⇊ g) s := fun x hx ↦ (hf x hx).prod (hg x hx) /-- `AnalyticAt.comp` for functions on product spaces -/ diff --git a/Mathlib/Analysis/Asymptotics/TVS.lean b/Mathlib/Analysis/Asymptotics/TVS.lean index cca12ef7ffcf73..79ef727ffdc35e 100644 --- a/Mathlib/Analysis/Asymptotics/TVS.lean +++ b/Mathlib/Analysis/Asymptotics/TVS.lean @@ -464,7 +464,7 @@ lemma IsLittleOTVS.bot : f =o[𝕜; ⊥] g := ⟨fun u hU ↦ ⟨univ, by simp [EventuallyLE]⟩⟩ theorem IsLittleOTVS.prodMk [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} - (hf : f =o[𝕜; l] k) (hg : g =o[𝕜; l] k) : (f △ g) =o[𝕜; l] k := by + (hf : f =o[𝕜; l] k) (hg : g =o[𝕜; l] k) : (f ⇊ g) =o[𝕜; l] k := by rw [((nhds_basis_balanced 𝕜 E).prod_nhds (nhds_basis_balanced 𝕜 F)).isLittleOTVS_iff (basis_sets _)] rintro ⟨U, V⟩ ⟨⟨hU, hUb⟩, hV, hVb⟩ @@ -484,11 +484,11 @@ protected theorem IsLittleOTVS.snd {f : α → E × F} {g : α → G} (h : f =o[ @[simp] theorem isLittleOTVS_prodMk_left [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} : - (f △ g) =o[𝕜; l] k ↔ f =o[𝕜; l] k ∧ g =o[𝕜; l] k := + (f ⇊ g) =o[𝕜; l] k ↔ f =o[𝕜; l] k ∧ g =o[𝕜; l] k := ⟨fun h ↦ ⟨h.fst, h.snd⟩, fun h ↦ h.elim .prodMk⟩ theorem IsBigOTVS.prodMk [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} - (hf : f =O[𝕜; l] k) (hg : g =O[𝕜; l] k) : (f △ g) =O[𝕜; l] k := by + (hf : f =O[𝕜; l] k) (hg : g =O[𝕜; l] k) : (f ⇊ g) =O[𝕜; l] k := by rw [((nhds_basis_balanced 𝕜 E).prod_nhds (nhds_basis_balanced 𝕜 F)).isBigOTVS_iff (basis_sets _)] rintro ⟨U, V⟩ ⟨⟨hU, hUb⟩, hV, hVb⟩ rcases ((hf.eventually_smallSets U hU).and (hg.eventually_smallSets V hV)).exists_mem_of_smallSets @@ -507,7 +507,7 @@ protected theorem IsBigOTVS.snd {f : α → E × F} {g : α → G} (h : f =O[ @[simp] theorem isBigOTVS_prodMk_left [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] {k : α → G} : - (f △ g) =O[𝕜; l] k ↔ f =O[𝕜; l] k ∧ g =O[𝕜; l] k := + (f ⇊ g) =O[𝕜; l] k ↔ f =O[𝕜; l] k ∧ g =O[𝕜; l] k := ⟨fun h ↦ ⟨h.fst, h.snd⟩, fun h ↦ h.elim .prodMk⟩ @[to_fun] diff --git a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean index ae2a6cb753b168..3a54ae4ceeea09 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean @@ -588,7 +588,7 @@ theorem ContDiff.prodMk {f : E → F} {g : E → G} (hf : ContDiff 𝕜 n f) (hg theorem iteratedFDerivWithin_prodMk {f : E → F} {g : E → G} (hf : ContDiffWithinAt 𝕜 n f s x) (hg : ContDiffWithinAt 𝕜 n g s x) (hs : UniqueDiffOn 𝕜 s) (ha : x ∈ s) {i : ℕ} (hi : i ≤ n) : - iteratedFDerivWithin 𝕜 i (f △ g) s x = + iteratedFDerivWithin 𝕜 i (f ⇊ g) s x = (iteratedFDerivWithin 𝕜 i f s x).prod (iteratedFDerivWithin 𝕜 i g s x) := by ext <;> · rw [← ContinuousLinearMap.iteratedFDerivWithin_comp_left _ (hf.prodMk hg) hs ha hi] @@ -596,7 +596,7 @@ theorem iteratedFDerivWithin_prodMk {f : E → F} {g : E → G} (hf : ContDiffWi theorem iteratedFDeriv_prodMk {f : E → F} {g : E → G} (hf : ContDiffAt 𝕜 n f x) (hg : ContDiffAt 𝕜 n g x) {i : ℕ} (hi : i ≤ n) : - iteratedFDeriv 𝕜 i (f △ g) x = + iteratedFDeriv 𝕜 i (f ⇊ g) x = (iteratedFDeriv 𝕜 i f x).prod (iteratedFDeriv 𝕜 i g x) := by simp only [← iteratedFDerivWithin_univ] exact iteratedFDerivWithin_prodMk hf.contDiffWithinAt hg.contDiffWithinAt uniqueDiffOn_univ diff --git a/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean b/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean index 4451dbb07b9ec2..0844dfb7611b8f 100644 --- a/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean +++ b/Mathlib/Analysis/Calculus/ContDiffHolder/Pointwise.lean @@ -134,7 +134,7 @@ theorem snd {a : E × F} : ContDiffPointwiseHolderAt k α Prod.snd a := theorem prodMk {g : E → G} (hf : ContDiffPointwiseHolderAt k α f a) (hg : ContDiffPointwiseHolderAt k α g a) : - ContDiffPointwiseHolderAt k α (f △ g) a where + ContDiffPointwiseHolderAt k α (f ⇊ g) a where contDiffAt := hf.contDiffAt.prodMk hg.contDiffAt isBigO := calc _ =ᶠ[𝓝 a] (fun x ↦ (iteratedFDeriv ℝ k f x - iteratedFDeriv ℝ k f a).prod diff --git a/Mathlib/CategoryTheory/Bicategory/Extension.lean b/Mathlib/CategoryTheory/Bicategory/Extension.lean index 544da9e4986eb0..4b639b3d102f0d 100644 --- a/Mathlib/CategoryTheory/Bicategory/Extension.lean +++ b/Mathlib/CategoryTheory/Bicategory/Extension.lean @@ -43,8 +43,8 @@ variable {B : Type u} [Bicategory.{w, v} B] {a b c : B} /-- Triangle diagrams for (left) extensions. ``` b - △ \ - | \ extension △ + ⇊ \ + | \ extension ⇊ f | \ | unit | ◿ a - - - ▷ c @@ -92,8 +92,8 @@ def ofCompId (t : LeftExtension f (g ≫ 𝟙 c)) : LeftExtension f g := /-- Whisker a 1-morphism to an extension. ``` b - △ \ - | \ extension △ + ⇊ \ + | \ extension ⇊ f | \ | unit | ◿ a - - - ▷ c - - - ▷ x @@ -164,7 +164,7 @@ end LeftExtension ``` b ◹ | - lift / | △ + lift / | ⇊ / | f | unit / ▽ c - - - ▷ a @@ -213,7 +213,7 @@ def ofIdComp (t : LeftLift f (𝟙 c ≫ g)) : LeftLift f g := ``` b ◹ | - lift / | △ + lift / | ⇊ / | f | unit / ▽ x - - - ▷ c - - - ▷ a @@ -285,7 +285,7 @@ end LeftLift /-- Triangle diagrams for (right) extensions. ``` b - △ \ + ⇊ \ | \ extension | counit f | \ ▽ | ◿ diff --git a/Mathlib/CategoryTheory/Bicategory/Kan/HasKan.lean b/Mathlib/CategoryTheory/Bicategory/Kan/HasKan.lean index b1ddc68a75543a..5c8b3b8f52fc9b 100644 --- a/Mathlib/CategoryTheory/Bicategory/Kan/HasKan.lean +++ b/Mathlib/CategoryTheory/Bicategory/Kan/HasKan.lean @@ -73,7 +73,7 @@ def lan (f : a ⟶ b) (g : a ⟶ c) [HasLeftKanExtension f g] : b ⟶ c := /-- `f⁺ g` is the left Kan extension of `g` along `f`. ``` b - △ \ + ⇊ \ | \ f⁺ g f | \ | ◿ diff --git a/Mathlib/Combinatorics/Enumerative/Catalan.lean b/Mathlib/Combinatorics/Enumerative/Catalan.lean index 034c6700f6b596..16fa94194a84d0 100644 --- a/Mathlib/Combinatorics/Enumerative/Catalan.lean +++ b/Mathlib/Combinatorics/Enumerative/Catalan.lean @@ -142,7 +142,7 @@ namespace Tree /-- Given two finsets, find all trees that can be formed with left child in `a` and right child in `b` -/ abbrev pairwiseNode (a b : Finset (Tree Unit)) : Finset (Tree Unit) := - (a ×ˢ b).map ⟨fun x => x.1 △ x.2, fun ⟨x₁, x₂⟩ ⟨y₁, y₂⟩ => fun h => by simpa using h⟩ + (a ×ˢ b).map ⟨fun x => x.1 ⇊ x.2, fun ⟨x₁, x₂⟩ ⟨y₁, y₂⟩ => fun h => by simpa using h⟩ /-- A Finset of all trees with `n` nodes. See `mem_treesOfNodesEq` -/ def treesOfNumNodesEq : ℕ → Finset (Tree Unit) diff --git a/Mathlib/Combinatorics/Enumerative/DyckWord.lean b/Mathlib/Combinatorics/Enumerative/DyckWord.lean index 7e5508cbd0a109..2509617288ac0b 100644 --- a/Mathlib/Combinatorics/Enumerative/DyckWord.lean +++ b/Mathlib/Combinatorics/Enumerative/DyckWord.lean @@ -484,10 +484,10 @@ open Tree `f(0) = nil`. For a nonzero word find the `D` that matches the initial `U`, which has index `p.firstReturn`, then let `x` be everything strictly between said `U` and `D`, and `y` be everything strictly after said `D`. `p = x.nest + y` with `x, y` (possibly empty) -Dyck words. `f(p) = f(x) △ f(y)`, where △ (defined in `Mathlib/Data/Tree/Basic.lean`) joins two +Dyck words. `f(p) = f(x) ⇊ f(y)`, where ⇊ (defined in `Mathlib/Data/Tree/Basic.lean`) joins two subtrees to a new root node. -/ def toTree (p : DyckWord) : Tree Unit := - if p = 0 then nil else p.insidePart.toTree △ p.outsidePart.toTree + if p = 0 then nil else p.insidePart.toTree ⇊ p.outsidePart.toTree termination_by p.semilength decreasing_by exacts [semilength_insidePart_lt ‹_›, semilength_outsidePart_lt ‹_›] diff --git a/Mathlib/Data/Prod/Basic.lean b/Mathlib/Data/Prod/Basic.lean index 5bca9909711866..3ec15c2ec4af6b 100644 --- a/Mathlib/Data/Prod/Basic.lean +++ b/Mathlib/Data/Prod/Basic.lean @@ -27,8 +27,8 @@ namespace Pi variable {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) {c} -@[simp] theorem fst_dcomp_pair : Prod.fst ∘' (f △' g) = f := rfl -@[simp] theorem snd_dcomp_pair : Prod.snd ∘' (f △' g) = g := rfl +@[simp] theorem fst_dcomp_pair : Prod.fst ∘' (f ⇊' g) = f := rfl +@[simp] theorem snd_dcomp_pair : Prod.snd ∘' (f ⇊' g) = g := rfl end Pi diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index 512aa33acab367..3ba189c3343c89 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -16,7 +16,7 @@ See also `Lean.Data.RBTree` for red-black trees - this version allows more opera to be defined and is better suited for in-kernel computation. We also specialize for `Tree Unit`, which is a binary tree without any -additional data. We provide the notation `a △ b` for making a `Tree Unit` with children +additional data. We provide the notation `a ⇊ b` for making a `Tree Unit` with children `a` and `b`. ## References @@ -120,16 +120,16 @@ def right : Tree α → Tree α | node _ _l r => r /-- A node with `Unit` data -/ -scoped infixr:65 " △ " => Tree.node () +scoped infixr:65 " ⇊ " => Tree.node () /-- Induction principle for `Tree Unit`s -/ @[elab_as_elim] def unitRecOn {motive : Tree Unit → Sort*} (t : Tree Unit) (base : motive nil) - (ind : ∀ x y, motive x → motive y → motive (x △ y)) : motive t := + (ind : ∀ x y, motive x → motive y → motive (x ⇊ y)) : motive t := t.recOn base fun _u ↦ ind -theorem left_node_right_eq_self : ∀ {x : Tree Unit} (_hx : x ≠ nil), x.left △ x.right = x +theorem left_node_right_eq_self : ∀ {x : Tree Unit} (_hx : x ≠ nil), x.left ⇊ x.right = x | nil, h => by trivial - | node _ _ _, _ => rfl -- Porting note: `a △ b` no longer works in pattern matching + | node _ _ _, _ => rfl -- Porting note: `a ⇊ b` no longer works in pattern matching end Tree diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean index 4bbca2049036a4..6a50d3b928651b 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Constructions.lean @@ -224,15 +224,15 @@ theorem contMDiff_prod_assoc : theorem ContMDiffWithinAt.comp₂ {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} {t : Set (M' × N')} (ha : ContMDiffWithinAt (I'.prod J') J n h t (f x, g x)) (fa : ContMDiffWithinAt I I' n f s x) (ga : ContMDiffWithinAt I J' n g s x) - (st : MapsTo (f △ g) s t) : + (st : MapsTo (f ⇊ g) s t) : ContMDiffWithinAt I J n (fun x ↦ h (f x, g x)) s x := - ha.comp (f := f △ g) _ (fa.prodMk ga) st + ha.comp (f := f ⇊ g) _ (fa.prodMk ga) st /-- `ContMDiffWithinAt.comp₂`, with a separate argument for point equality. -/ theorem ContMDiffWithinAt.comp₂_of_eq {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} {y : M' × N'} {t : Set (M' × N')} (ha : ContMDiffWithinAt (I'.prod J') J n h t y) (fa : ContMDiffWithinAt I I' n f s x) (ga : ContMDiffWithinAt I J' n g s x) - (e : (f x, g x) = y) (st : MapsTo (f △ g) s t) : + (e : (f x, g x) = y) (st : MapsTo (f ⇊ g) s t) : ContMDiffWithinAt I J n (fun x ↦ h (f x, g x)) s x := by rw [← e] at ha exact ha.comp₂ fa ga st @@ -241,7 +241,7 @@ theorem ContMDiffWithinAt.comp₂_of_eq {h : M' × N' → N} {f : M → M'} {g : theorem ContMDiffAt.comp₂ {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} (ha : ContMDiffAt (I'.prod J') J n h (f x, g x)) (fa : ContMDiffAt I I' n f x) (ga : ContMDiffAt I J' n g x) : ContMDiffAt I J n (fun x ↦ h (f x, g x)) x := - ha.comp (f := f △ g) _ (fa.prodMk ga) + ha.comp (f := f ⇊ g) _ (fa.prodMk ga) /-- `ContMDiffAt.comp₂`, with a separate argument for point equality. -/ theorem ContMDiffAt.comp₂_of_eq {h : M' × N' → N} {f : M → M'} {g : M → N'} {x : M} {y : M' × N'} diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 4ce6d886430d41..6f7939142d1ca2 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -215,7 +215,7 @@ section Prod theorem MDifferentiableWithinAt.prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) : - MDiffAt[s] (f △ g) x := + MDiffAt[s] (f ⇊ g) x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ /-- If `f` and `g` have derivatives `df` and `dg` within `s` at `x`, respectively, @@ -228,17 +228,17 @@ theorem HasMFDerivWithinAt.prodMk {f : M → M'} {g : M → M''} lemma mfderivWithin_prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) (hs : UniqueMDiffWithinAt I s x) : - mfderiv[s] (f △ g) x = (mfderiv[s] f x).prod (mfderiv[s] g x) := + mfderiv[s] (f ⇊ g) x = (mfderiv[s] f x).prod (mfderiv[s] g x) := (hf.hasMFDerivWithinAt.prodMk hg.hasMFDerivWithinAt).mfderivWithin hs lemma mfderiv_prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt f x) (hg : MDiffAt g x) : - mfderiv% (f △ g) x = (mfderiv% f x).prod (mfderiv% g x) := by + mfderiv% (f ⇊ g) x = (mfderiv% f x).prod (mfderiv% g x) := by simp_rw [← mfderivWithin_univ] exact mfderivWithin_prodMk hf.mdifferentiableWithinAt hg.mdifferentiableWithinAt (uniqueMDiffWithinAt_univ I) theorem MDifferentiableAt.prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt f x) (hg : MDiffAt g x) : - MDiffAt (f △ g) x := + MDiffAt (f ⇊ g) x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ /-- If `f` and `g` have derivatives `df` and `dg` at `x`, respectively, @@ -251,27 +251,27 @@ theorem HasMFDerivAt.prodMk {f : M → M'} {g : M → M''} theorem MDifferentiableWithinAt.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) : - MDifferentiableWithinAt I 𝓘(𝕜, E' × E'') (f △ g) s x := + MDifferentiableWithinAt I 𝓘(𝕜, E' × E'') (f ⇊ g) s x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem MDifferentiableAt.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiffAt f x) (hg : MDiffAt g x) : - MDifferentiableAt I 𝓘(𝕜, E' × E'') (f △ g) x := + MDifferentiableAt I 𝓘(𝕜, E' × E'') (f ⇊ g) x := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ theorem MDifferentiableOn.prodMk {f : M → M'} {g : M → M''} (hf : MDiff[s] f) (hg : MDiff[s] g) : - MDiff[s] (f △ g) := fun x hx ↦ (hf x hx).prodMk (hg x hx) + MDiff[s] (f ⇊ g) := fun x hx ↦ (hf x hx).prodMk (hg x hx) theorem MDifferentiable.prodMk {f : M → M'} {g : M → M''} (hf : MDiff f) (hg : MDiff g) : - MDiff f △ g := fun x ↦ (hf x).prodMk (hg x) + MDiff f ⇊ g := fun x ↦ (hf x).prodMk (hg x) theorem MDifferentiableOn.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiff[s] f) (hg : MDiff[s] g) : - MDifferentiableOn I 𝓘(𝕜, E' × E'') (f △ g) s := + MDifferentiableOn I 𝓘(𝕜, E' × E'') (f ⇊ g) s := fun x hx ↦ (hf x hx).prodMk_space (hg x hx) theorem MDifferentiable.prodMk_space {f : M → E'} {g : M → E''} (hf : MDiff f) (hg : MDiff g) : - MDifferentiable I 𝓘(𝕜, E' × E'') f △ g := + MDifferentiable I 𝓘(𝕜, E' × E'') f ⇊ g := fun x ↦ (hf x).prodMk_space (hg x) theorem hasMFDerivAt_fst (x : M × M') : diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 37f837bfc373ea..0a4c52a4802f51 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -9,7 +9,7 @@ public import Mathlib.Init /-! -This file defines `(f △ g)`, the operation that pairs two functions `f : γ → α` and +This file defines `(f ⇊ g)`, the operation that pairs two functions `f : γ → α` and `g : γ → β` into a function `γ → α × β`. It also defines the special case when `f = g = id`, `Function.diag`. This is the canonical injection @@ -29,45 +29,45 @@ namespace Pi protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) : ∀ i, α i × β i := fun i ↦ (f i, g i) -@[inherit_doc] infixr:65 " △' " => Pi.prod +@[inherit_doc] infixr:65 " ⇊' " => Pi.prod section variable {ι} {α β : ι → Type*} (f f' : ∀ i, α i) (g g' : ∀ i, β i) {c} -@[grind =] theorem prod_apply : (f △' g) c = (f c, g c) := rfl +@[grind =] theorem prod_apply : (f ⇊' g) c = (f c, g c) := rfl -@[simp] theorem fst_prod : ((f △' g) c).fst = f c := rfl -@[simp] theorem snd_prod : ((f △' g) c).snd = g c := rfl +@[simp] theorem fst_prod : ((f ⇊' g) c).fst = f c := rfl +@[simp] theorem snd_prod : ((f ⇊' g) c).snd = g c := rfl -@[simp] theorem prod_fst_snd {α β} : (Prod.fst : _ → α) △' (Prod.snd : _ → β) = id := rfl -@[simp] theorem prod_snd_fst {α β} : (Prod.snd : _ → β) △' (Prod.fst : _ → α) = .swap := rfl +@[simp] theorem prod_fst_snd {α β} : (Prod.fst : _ → α) ⇊' (Prod.snd : _ → β) = id := rfl +@[simp] theorem prod_snd_fst {α β} : (Prod.snd : _ → β) ⇊' (Prod.fst : _ → α) = .swap := rfl theorem prod_fst_snd_comp {h : ∀ i, α i × β i} : - (Prod.fst <| h ·) △' (Prod.snd <| h ·) = h := rfl + (Prod.fst <| h ·) ⇊' (Prod.snd <| h ·) = h := rfl -theorem fst_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.fst <| (f △' g) ·) = f := rfl -theorem snd_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.snd <| (f △' g) ·) = g := rfl +theorem fst_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.fst <| (f ⇊' g) ·) = f := rfl +theorem snd_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.snd <| (f ⇊' g) ·) = g := rfl @[simp] theorem prod_eq_iff {f : ∀ i, α i} {g : ∀ i, β i} : - f △' g = f' △' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] + f ⇊' g = f' ⇊' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] theorem prod_ext_iff {h h' : ∀ i, α i × β i} : h = h' ↔ (Prod.fst <| h ·) = (Prod.fst <| h' ·) ∧ (Prod.snd <| h ·) = (Prod.snd <| h' ·) := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem exists_prod_apply_eq (h : ∀ i, α i × β i) : ∃ f g, (f △' g) = h := +theorem exists_prod_apply_eq (h : ∀ i, α i × β i) : ∃ f g, (f ⇊' g) = h := ⟨(Prod.fst <| h ·), (Prod.snd <| h ·), prod_fst_snd_comp⟩ theorem exists_fst_comp (f : ∀ i, α i) (g : ∀ i, β i) : - ∃ h : ∀ i, α i × β i, (Prod.fst <| h ·) = f := ⟨(f △' g), fst_comp_prod⟩ + ∃ h : ∀ i, α i × β i, (Prod.fst <| h ·) = f := ⟨(f ⇊' g), fst_comp_prod⟩ theorem exists_snd_comp (f : ∀ i, α i) (g : ∀ i, β i) : - ∃ h : ∀ i, α i × β i, (Prod.snd <| h ·) = g := ⟨(f △' g), snd_comp_prod⟩ + ∃ h : ∀ i, α i × β i, (Prod.snd <| h ·) = g := ⟨(f ⇊' g), snd_comp_prod⟩ @[grind =] theorem prod_const_const {γ} {α β} {a : α} {b : β} : - (Function.const γ a) △' (Function.const γ b) = Function.const γ (a, b) := rfl + (Function.const γ a) ⇊' (Function.const γ b) = Function.const γ (a, b) := rfl end @@ -78,9 +78,9 @@ namespace Function variable {α β δ ε : Type*} {γ : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -protected def prod (f : γ → α) (g : γ → β) : γ → α × β := (f △' g) +protected def prod (f : γ → α) (g : γ → β) : γ → α × β := (f ⇊' g) -@[inherit_doc] infixr:65 " △ " => Function.prod +@[inherit_doc] infixr:65 " ⇊ " => Function.prod section @@ -88,66 +88,66 @@ variable (f : γ → α) (g : γ → β) @[grind =] theorem prod_apply (c : γ) : (f.prod g) c = (f c, g c) := rfl -theorem prod_comp {δ} {h : δ → γ} : (f △ g) ∘ h = (f ∘ h) △ (g ∘ h) := rfl +theorem prod_comp {δ} {h : δ → γ} : (f ⇊ g) ∘ h = (f ∘ h) ⇊ (g ∘ h) := rfl -@[simp] theorem fst_prod {c} : ((f △ g) c).fst = f c := rfl -@[simp] theorem snd_prod {c} : ((f △ g) c).snd = g c := rfl +@[simp] theorem fst_prod {c} : ((f ⇊ g) c).fst = f c := rfl +@[simp] theorem snd_prod {c} : ((f ⇊ g) c).snd = g c := rfl -@[simp] theorem prod_fst_snd : Prod.fst (α := α) △ Prod.snd (β := β) = id := rfl -@[simp] theorem prod_snd_fst : Prod.snd (β := β) △ Prod.fst (α := α) = .swap := rfl +@[simp] theorem prod_fst_snd : Prod.fst (α := α) ⇊ Prod.snd (β := β) = id := rfl +@[simp] theorem prod_snd_fst : Prod.snd (β := β) ⇊ Prod.fst (α := α) = .swap := rfl -@[simp] theorem prod_fst_snd_comp {f : γ → α × β} : (Prod.fst ∘ f) △ (Prod.snd ∘ f) = f := rfl +@[simp] theorem prod_fst_snd_comp {f : γ → α × β} : (Prod.fst ∘ f) ⇊ (Prod.snd ∘ f) = f := rfl -@[simp] theorem fst_comp_prod {f : γ → α} {g : γ → β} : Prod.fst ∘ (f △ g) = f := rfl -@[simp] theorem snd_comp_prod {f : γ → α} {g : γ → β} : Prod.snd ∘ (f △ g) = g := rfl +@[simp] theorem fst_comp_prod {f : γ → α} {g : γ → β} : Prod.fst ∘ (f ⇊ g) = f := rfl +@[simp] theorem snd_comp_prod {f : γ → α} {g : γ → β} : Prod.snd ∘ (f ⇊ g) = g := rfl -theorem prod_eq_iff {f f' : γ → α} {g g' : γ → β} : f △ g = f' △ g' ↔ +theorem prod_eq_iff {f f' : γ → α} {g g' : γ → β} : f ⇊ g = f' ⇊ g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] theorem prod_ext_iff {h h' : γ → α × β} : h = h' ↔ Prod.fst ∘ h = Prod.fst ∘ h' ∧ Prod.snd ∘ h = (Prod.snd ∘ h') := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem exists_prod_apply_eq (h : γ → α × β) : ∃ f g, f △ g = h := +theorem exists_prod_apply_eq (h : γ → α × β) : ∃ f g, f ⇊ g = h := ⟨Prod.fst ∘ h, Prod.snd ∘ h, prod_fst_snd_comp⟩ theorem exists_fst_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨f △ g, fst_comp_prod⟩ + ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨f ⇊ g, fst_comp_prod⟩ theorem exists_snd_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨f △ g, snd_comp_prod⟩ + ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨f ⇊ g, snd_comp_prod⟩ theorem leftInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.LeftInverse - (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := + (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := fun _ => rfl theorem rightInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.RightInverse - (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) △ (Prod.snd (β := β) ∘ ·)) := + (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := fun _ => rfl @[grind =] theorem prod_const_const (a : α) (b : β) : - (Function.const γ a) △ (Function.const γ b) = Function.const γ (a, b) := rfl + (Function.const γ a) ⇊ (Function.const γ b) = Function.const γ (a, b) := rfl theorem const_prod {γ} {α β} {p : α × β} : - Function.const γ p = (Function.const γ p.1) △ (Function.const γ p.2) := rfl + Function.const γ p = (Function.const γ p.1) ⇊ (Function.const γ p.2) := rfl end /-- `Function.prodMap` is `Prod.map` in the `Function` namespace. -/ -def prodMap (f : α → β) (g : δ → ε) := (f ∘ Prod.fst) △ (g ∘ Prod.snd) +def prodMap (f : α → β) (g : δ → ε) := (f ∘ Prod.fst) ⇊ (g ∘ Prod.snd) @[simp, grind =] theorem prodMap_eq_prod_map {f : α → β} {g : δ → ε} : f.prodMap g = Prod.map f g := rfl @[grind _=_] theorem map_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : - Prod.map f h ((g △ k) c) = ((f ∘ g) △ (h ∘ k)) c := rfl + Prod.map f h ((g ⇊ k) c) = ((f ∘ g) ⇊ (h ∘ k)) c := rfl theorem map_comp_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : - Prod.map f h ∘ (g △ k) = (f ∘ g) △ (h ∘ k) := rfl + Prod.map f h ∘ (g ⇊ k) = (f ∘ g) ⇊ (h ∘ k) := rfl /-- The diagonal map into `Prod`. -/ -protected def diag : α → α × α := id △ id +protected def diag : α → α × α := id ⇊ id @[inherit_doc] prefix:max "⇗" => Function.diag @@ -161,9 +161,9 @@ variable {a b : α} @[simp, grind =] theorem snd_diag : (⇗a).2 = a := rfl @[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (⇗a) = - (f △ g) a := rfl + (f ⇊ g) a := rfl -@[simp] theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = (f △ g) := +@[simp] theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = (f ⇊ g) := rfl theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst @@ -173,7 +173,7 @@ theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ @[simp] theorem diag_eq_iff : ⇗a = ⇗b ↔ a = b := injective_diag.eq_iff -@[simp] theorem prod_diag_diag : Function.diag △ Function.diag (α := α) = +@[simp] theorem prod_diag_diag : Function.diag ⇊ Function.diag (α := α) = Function.diag ∘ Function.diag := rfl end diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 52be25ce5deb99..1f09ab333bd8ff 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -1125,16 +1125,16 @@ variable {α β₁ β₂ : Type*} [LE β₁] [LE β₂] @[simp] lemma pair_le_pair_iff {u₁ v₁ : α → β₁} {u₂ v₂ : α → β₂} : - u₁ △ u₂ ≤ v₁ △ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by + u₁ ⇊ u₂ ≤ v₁ ⇊ v₂ ↔ u₁ ≤ v₁ ∧ u₂ ≤ v₂ := by simp [Pi.le_def, Prod.le_def, forall_and] lemma const_le_pair_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - Function.const _ b ≤ v₁ △ v₂ ↔ + Function.const _ b ≤ v₁ ⇊ v₂ ↔ Function.const _ b.1 ≤ v₁ ∧ Function.const _ b.2 ≤ v₂ := prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. lemma pair_le_const_iff {b : β₁ × β₂} {v₁ : α → β₁} {v₂ : α → β₂} : - v₁ △ v₂ ≤ Function.const _ b ↔ + v₁ ⇊ v₂ ≤ Function.const _ b ↔ v₁ ≤ Function.const _ b.1 ∧ v₂ ≤ Function.const _ b.2 := prod_const_const b.1 b.2 ▸ pair_le_pair_iff .. diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 7f6392d9017c4b..7caafdaaa0a114 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -976,7 +976,7 @@ instance {l : Filter α} : trans := EventuallyEq.trans theorem EventuallyEq.prodMk {l} {f f' : α → β} (hf : f =ᶠ[l] f') {g g' : α → γ} (hg : g =ᶠ[l] g') : - (Function.prod f g) =ᶠ[l] (f' △ g') := hf.mp <| hg.mono <| by grind + (Function.prod f g) =ᶠ[l] (f' ⇊ g') := hf.mp <| hg.mono <| by grind /-- See `EventuallyEq.comp_tendsto` in Mathlib.Order.Filter.Tendsto for a similar statement w.r.t. composition on the right. -/ diff --git a/Mathlib/Order/Filter/EventuallyConst.lean b/Mathlib/Order/Filter/EventuallyConst.lean index aa35b482b539bb..0e6b612d4b3eff 100644 --- a/Mathlib/Order/Filter/EventuallyConst.lean +++ b/Mathlib/Order/Filter/EventuallyConst.lean @@ -125,7 +125,7 @@ lemma comp₂ {g : α → γ} (hf : EventuallyConst f l) (op : β → γ → δ) (tendsto_map (f := op.uncurry)).comp (tendsto_map.prodMk tendsto_map) lemma prodMk {g : α → γ} (hf : EventuallyConst f l) (hg : EventuallyConst g l) : - EventuallyConst (f △ g) l := + EventuallyConst (f ⇊ g) l := hf.comp₂ Prod.mk hg @[to_additive] diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index 9d5d3802f9913f..61f2892ac28fe7 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -448,7 +448,7 @@ theorem ωSup_zip (c₀ : Chain α) (c₁ : Chain β) : ωSup (c₀.zip c₁) = @[fun_prop] lemma ωScottContinuous.prodMk {f : α → β} (hf : ωScottContinuous f) {g : α → γ} (hg : ωScottContinuous g) : - ωScottContinuous f △ g := + ωScottContinuous f ⇊ g := ScottContinuousOn.prodMk (fun a b hab ↦ ⟨pair a b hab, range_pair a b hab⟩) hf hg @[fun_prop] diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index 9394e2779c34af..1dfd5284a61be1 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -106,7 +106,7 @@ theorem ScottContinuousOn.image_comp {g : β → γ} @[fun_prop] lemma ScottContinuousOn.prodMk {g : α → γ} (hD : ∀ a b : α, a ≤ b → {a, b} ∈ D) (hf : ScottContinuousOn D f) (hg : ScottContinuousOn D g) : - ScottContinuousOn D (f △ g) := fun d hd₁ hd₂ hd₃ a hda => by + ScottContinuousOn D (f ⇊ g) := fun d hd₁ hd₂ hd₃ a hda => by rw [IsLUB, IsLeast, upperBounds] constructor · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, diff --git a/Mathlib/Probability/Kernel/Composition/MapComap.lean b/Mathlib/Probability/Kernel/Composition/MapComap.lean index 4c44d18c8b2d4a..56aeb13bc3f54a 100644 --- a/Mathlib/Probability/Kernel/Composition/MapComap.lean +++ b/Mathlib/Probability/Kernel/Composition/MapComap.lean @@ -450,13 +450,13 @@ instance (priority := 100) isFiniteKernel_of_isFiniteKernel_fst {κ : Kernel α simp lemma fst_map_prod (κ : Kernel α β) {f : β → γ} {g : β → δ} (hg : Measurable g) : - fst (map κ (f △ g)) = map κ f := by + fst (map κ (f ⇊ g)) = map κ f := by by_cases hf : Measurable f · ext x s hs rw [fst_apply' _ _ hs, map_apply' _ (hf.prod hg) _, map_apply' _ hf _ hs] · simp only [Set.preimage, Set.mem_setOf] · exact measurable_fst hs - · have : ¬ Measurable (f △ g) := by + · have : ¬ Measurable (f ⇊ g) := by contrapose! hf; exact hf.fst simp [map_of_not_measurable _ hf, map_of_not_measurable _ this] @@ -512,13 +512,13 @@ instance (priority := 100) isFiniteKernel_of_isFiniteKernel_snd {κ : Kernel α simp lemma snd_map_prod (κ : Kernel α β) {f : β → γ} {g : β → δ} (hf : Measurable f) : - snd (map κ (f △ g)) = map κ g := by + snd (map κ (f ⇊ g)) = map κ g := by by_cases hg : Measurable g · ext x s hs rw [snd_apply' _ _ hs, map_apply' _ (hf.prod hg), map_apply' _ hg _ hs] · simp only [Set.preimage, Set.mem_setOf] · exact measurable_snd hs - · have : ¬ Measurable (f △ g) := by + · have : ¬ Measurable (f ⇊ g) := by contrapose! hg; exact hg.snd simp [map_of_not_measurable _ hg, map_of_not_measurable _ this] diff --git a/Mathlib/Tactic/FunProp.lean b/Mathlib/Tactic/FunProp.lean index 9c8a86a6169f6e..3c955ac5b077b9 100644 --- a/Mathlib/Tactic/FunProp.lean +++ b/Mathlib/Tactic/FunProp.lean @@ -214,7 +214,7 @@ There are four types of theorems that are used a bit differently. Continuous (fun x ↦ (f x).snd) := ... @[fun_prop] theorem continuous_prod_mk (f : X → Y) (g : X → Z) (hf : Continuous f) (hg : Continuous g) : - Continuous (f △ g) := ... + Continuous (f ⇊ g) := ... ``` - Function Theorems: diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index 02dcd102616f61..c0ed3cafeff002 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -491,19 +491,19 @@ theorem tendsto_swap_uniformity : Tendsto (@Prod.swap α α) (𝓤 α) (𝓤 α) theorem comp_mem_uniformity_sets {s : SetRel α α} (hs : s ∈ 𝓤 α) : ∃ t ∈ 𝓤 α, t ○ t ⊆ s := (mem_lift'_sets <| monotone_id.relComp monotone_id).mp <| comp_le_uniformity hs -/-- Relation `fun f g ↦ Tendsto (f △ g) l (𝓤 α)` is transitive. -/ +/-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is transitive. -/ theorem Filter.Tendsto.uniformity_trans {l : Filter β} {f₁ f₂ f₃ : β → α} (h₁₂ : Tendsto (fun x => (f₁ x, f₂ x)) l (𝓤 α)) (h₂₃ : Tendsto (fun x => (f₂ x, f₃ x)) l (𝓤 α)) : Tendsto (fun x => (f₁ x, f₃ x)) l (𝓤 α) := by refine le_trans (le_lift'.2 fun s hs => mem_map.2 ?_) comp_le_uniformity filter_upwards [mem_map.1 (h₁₂ hs), mem_map.1 (h₂₃ hs)] with x hx₁₂ hx₂₃ using ⟨_, hx₁₂, hx₂₃⟩ -/-- Relation `fun f g ↦ Tendsto (f △ g) l (𝓤 α)` is symmetric. -/ +/-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is symmetric. -/ theorem Filter.Tendsto.uniformity_symm {l : Filter β} {f : β → α × α} (h : Tendsto f l (𝓤 α)) : Tendsto (fun x => ((f x).2, (f x).1)) l (𝓤 α) := tendsto_swap_uniformity.comp h -/-- Relation `fun f g ↦ Tendsto (f △ g) l (𝓤 α)` is reflexive. -/ +/-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is reflexive. -/ theorem tendsto_diag_uniformity (f : β → α) (l : Filter β) : Tendsto (fun x => (f x, f x)) l (𝓤 α) := fun _s hs => mem_map.2 <| univ_mem' fun _ => refl_mem_uniformity hs diff --git a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean index 051553daf3f1b5..02422a7037b04d 100644 --- a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean @@ -200,7 +200,7 @@ end Comp theorem TendstoLocallyUniformlyOn.prodMk [UniformSpace γ] {G : ι → α → γ} {g : α → γ} (hF : TendstoLocallyUniformlyOn F f p s) (hG : TendstoLocallyUniformlyOn G g p s) : - TendstoLocallyUniformlyOn (fun n x ↦ (F n x, G n x)) (f △ g) p s := by + TendstoLocallyUniformlyOn (fun n x ↦ (F n x, G n x)) (f ⇊ g) p s := by rw [tendstoLocallyUniformlyOn_iff_forall_tendsto] at * intro x hx rw [uniformity_prod_eq_comap_prod, tendsto_comap_iff] @@ -213,7 +213,7 @@ theorem TendstoLocallyUniformlyOn.piProd [UniformSpace γ] {G : ι → α → γ theorem TendstoLocallyUniformly.prodMk [UniformSpace γ] {G : ι → α → γ} {g : α → γ} (hF : TendstoLocallyUniformly F f p) (hG : TendstoLocallyUniformly G g p) : - TendstoLocallyUniformly (fun n x ↦ (F n x, G n x)) (f △ g) p := by + TendstoLocallyUniformly (fun n x ↦ (F n x, G n x)) (f ⇊ g) p := by rw [← tendstoLocallyUniformlyOn_univ] at * exact hF.prodMk hG diff --git a/Mathlib/Topology/UniformSpace/Separation.lean b/Mathlib/Topology/UniformSpace/Separation.lean index d440ca9978aba5..0f5e601585dad6 100644 --- a/Mathlib/Topology/UniformSpace/Separation.lean +++ b/Mathlib/Topology/UniformSpace/Separation.lean @@ -207,7 +207,7 @@ theorem eq_of_clusterPt_uniformity [T0Space α] {x y : α} (h : ClusterPt (x, y) theorem Filter.Tendsto.inseparable_iff_uniformity {β} {l : Filter β} [NeBot l] {f g : β → α} {a b : α} (ha : Tendsto f l (𝓝 a)) (hb : Tendsto g l (𝓝 b)) : - Inseparable a b ↔ Tendsto (f △ g) l (𝓤 α) := by + Inseparable a b ↔ Tendsto (f ⇊ g) l (𝓤 α) := by refine ⟨fun h ↦ (ha.prodMk_nhds hb).mono_right h.nhds_le_uniformity, fun h ↦ ?_⟩ rw [inseparable_iff_clusterPt_uniformity] exact (ClusterPt.of_le_nhds (ha.prodMk_nhds hb)).mono h diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 147ab71b959e14..9efbd036b6a4f9 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -1067,7 +1067,7 @@ section product /-- info: MDifferentiable I (I'.prod I') fun x ↦ Prod.mk (f x) (g x) : Prop -/ #guard_msgs in -#check MDiff (f △ g) +#check MDiff (f ⇊ g) /-- info: MDifferentiable (I.prod (modelWithCornersSelf 𝕜 E)) I' k : Prop -/ #guard_msgs in From dc67eb8985fe707c5fb3f05acd054296bb3213c8 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:39:40 +0100 Subject: [PATCH 29/35] Change notation --- Mathlib/CategoryTheory/Bicategory/Extension.lean | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/CategoryTheory/Bicategory/Extension.lean b/Mathlib/CategoryTheory/Bicategory/Extension.lean index 4b639b3d102f0d..544da9e4986eb0 100644 --- a/Mathlib/CategoryTheory/Bicategory/Extension.lean +++ b/Mathlib/CategoryTheory/Bicategory/Extension.lean @@ -43,8 +43,8 @@ variable {B : Type u} [Bicategory.{w, v} B] {a b c : B} /-- Triangle diagrams for (left) extensions. ``` b - ⇊ \ - | \ extension ⇊ + △ \ + | \ extension △ f | \ | unit | ◿ a - - - ▷ c @@ -92,8 +92,8 @@ def ofCompId (t : LeftExtension f (g ≫ 𝟙 c)) : LeftExtension f g := /-- Whisker a 1-morphism to an extension. ``` b - ⇊ \ - | \ extension ⇊ + △ \ + | \ extension △ f | \ | unit | ◿ a - - - ▷ c - - - ▷ x @@ -164,7 +164,7 @@ end LeftExtension ``` b ◹ | - lift / | ⇊ + lift / | △ / | f | unit / ▽ c - - - ▷ a @@ -213,7 +213,7 @@ def ofIdComp (t : LeftLift f (𝟙 c ≫ g)) : LeftLift f g := ``` b ◹ | - lift / | ⇊ + lift / | △ / | f | unit / ▽ x - - - ▷ c - - - ▷ a @@ -285,7 +285,7 @@ end LeftLift /-- Triangle diagrams for (right) extensions. ``` b - ⇊ \ + △ \ | \ extension | counit f | \ ▽ | ◿ From 63cb876759452ba9445e7fe134e7d39231a332fd Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 02:58:59 +0100 Subject: [PATCH 30/35] Changes --- Mathlib/Data/Tree/Basic.lean | 2 +- Mathlib/Logic/Function/Init.lean | 8 ++-- Mathlib/MeasureTheory/Measure/Prod.lean | 12 ++--- .../Probability/Independence/Conditional.lean | 4 +- .../Kernel/Composition/MeasureComp.lean | 2 +- Mathlib/Probability/Kernel/CondDistrib.lean | 44 +++++++++---------- .../Topology/Algebra/IsUniformGroup/Defs.lean | 2 +- Mathlib/Topology/ClopenBox.lean | 2 +- Mathlib/Topology/UniformSpace/Defs.lean | 12 ++--- 9 files changed, 43 insertions(+), 45 deletions(-) diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index 3ba189c3343c89..c5b44227e7769b 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -120,7 +120,7 @@ def right : Tree α → Tree α | node _ _l r => r /-- A node with `Unit` data -/ -scoped infixr:65 " ⇊ " => Tree.node () +scoped infixr:65 " △ " => Tree.node () /-- Induction principle for `Tree Unit`s -/ @[elab_as_elim] diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 0a4c52a4802f51..45beb4a19f2b03 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -78,7 +78,7 @@ namespace Function variable {α β δ ε : Type*} {γ : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -protected def prod (f : γ → α) (g : γ → β) : γ → α × β := (f ⇊' g) +protected def prod (f : γ → α) (g : γ → β) : γ → α × β := f ⇊' g @[inherit_doc] infixr:65 " ⇊ " => Function.prod @@ -160,11 +160,9 @@ variable {a b : α} @[simp, grind =] theorem fst_diag : (⇗a).1 = a := rfl @[simp, grind =] theorem snd_diag : (⇗a).2 = a := rfl -@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g (⇗a) = - (f ⇊ g) a := rfl +@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g ⇗a = (f ⇊ g) a := rfl -@[simp] theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = (f ⇊ g) := - rfl +@[simp] theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = f ⇊ g := rfl theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst diff --git a/Mathlib/MeasureTheory/Measure/Prod.lean b/Mathlib/MeasureTheory/Measure/Prod.lean index 487fe7fd620c50..a231d7cf5fe2e3 100644 --- a/Mathlib/MeasureTheory/Measure/Prod.lean +++ b/Mathlib/MeasureTheory/Measure/Prod.lean @@ -1115,19 +1115,19 @@ lemma fst_prod [IsProbabilityMeasure ν] : (μ.prod ν).fst = μ := by rw [fst_apply hs, ← prod_univ, prod_prod, measure_univ, mul_one] theorem fst_map_prodMk₀ {X : α → β} {Y : α → γ} {μ : Measure α} - (hY : AEMeasurable Y μ) : (μ.map fun a => (X a, Y a)).fst = μ.map X := by + (hY : AEMeasurable Y μ) : (μ.map (X ⇊ Y)).fst = μ.map X := by by_cases hX : AEMeasurable X μ · ext1 s hs rw [Measure.fst_apply hs, Measure.map_apply_of_aemeasurable (hX.prodMk hY) (measurable_fst hs), Measure.map_apply_of_aemeasurable hX hs, ← prod_univ, mk_preimage_prod, preimage_univ, inter_univ] - · have : ¬AEMeasurable (fun x ↦ (X x, Y x)) μ := by + · have : ¬AEMeasurable (X ⇊ Y) μ := by contrapose! hX exact measurable_fst.comp_aemeasurable hX simp [map_of_not_aemeasurable, hX, this] theorem fst_map_prodMk {X : α → β} {Y : α → γ} {μ : Measure α} - (hY : Measurable Y) : (μ.map fun a => (X a, Y a)).fst = μ.map X := + (hY : Measurable Y) : (μ.map (X ⇊ Y)).fst = μ.map X := fst_map_prodMk₀ hY.aemeasurable @[simp] @@ -1177,19 +1177,19 @@ lemma snd_prod [IsProbabilityMeasure μ] : (μ.prod ν).snd = ν := by rw [snd_apply hs, ← univ_prod, prod_prod, measure_univ, one_mul] theorem snd_map_prodMk₀ {X : α → β} {Y : α → γ} {μ : Measure α} (hX : AEMeasurable X μ) : - (μ.map fun a => (X a, Y a)).snd = μ.map Y := by + (μ.map (X ⇊ Y)).snd = μ.map Y := by by_cases hY : AEMeasurable Y μ · ext1 s hs rw [Measure.snd_apply hs, Measure.map_apply_of_aemeasurable (hX.prodMk hY) (measurable_snd hs), Measure.map_apply_of_aemeasurable hY hs, ← univ_prod, mk_preimage_prod, preimage_univ, univ_inter] - · have : ¬AEMeasurable (fun x ↦ (X x, Y x)) μ := by + · have : ¬AEMeasurable (X ⇊ Y) μ := by contrapose! hY exact measurable_snd.comp_aemeasurable hY simp [map_of_not_aemeasurable, hY, this] theorem snd_map_prodMk {X : α → β} {Y : α → γ} {μ : Measure α} (hX : Measurable X) : - (μ.map fun a => (X a, Y a)).snd = μ.map Y := + (μ.map (X ⇊ Y)).snd = μ.map Y := snd_map_prodMk₀ hX.aemeasurable @[simp] diff --git a/Mathlib/Probability/Independence/Conditional.lean b/Mathlib/Probability/Independence/Conditional.lean index 73824a2ca4f765..e3e76d0a4a4218 100644 --- a/Mathlib/Probability/Independence/Conditional.lean +++ b/Mathlib/Probability/Independence/Conditional.lean @@ -876,7 +876,7 @@ theorem condIndepFun_iff_condDistrib_prod_ae_eq_prodMkRight Measure.compProd_eq_comp_prod] let e : γ × β' × β ≃ᵐ (γ × β') × β := MeasurableEquiv.prodAssoc.symm have h_eq : ((Kernel.id ×ₖ condDistrib g k μ) ×ₖ condDistrib f k μ) ∘ₘ μ.map k = - (Kernel.id ×ₖ (condDistrib f k μ).prodMkRight _) ∘ₘ μ.map (fun a ↦ (k a, g a)) := by + (Kernel.id ×ₖ (condDistrib f k μ).prodMkRight _) ∘ₘ μ.map (k ⇊ g) := by calc ((Kernel.id ×ₖ condDistrib g k μ) ×ₖ condDistrib f k μ) ∘ₘ μ.map k _ = (Kernel.id ×ₖ (condDistrib f k μ).prodMkRight _) ∘ₘ (μ.map k ⊗ₘ condDistrib g k μ) := by rw [Measure.compProd_eq_comp_prod, Measure.comp_assoc] @@ -885,7 +885,7 @@ theorem condIndepFun_iff_condDistrib_prod_ae_eq_prodMkRight (condDistrib f k μ) Kernel.id measurable_id rw [← Kernel.id] at h simpa using h.symm - _ = (Kernel.id ×ₖ (condDistrib f k μ).prodMkRight _) ∘ₘ μ.map (fun a ↦ (k a, g a)) := by + _ = (Kernel.id ×ₖ (condDistrib f k μ).prodMkRight _) ∘ₘ μ.map (k ⇊ g) := by rw [compProd_map_condDistrib hg.aemeasurable] rw [← h_eq] have h1 : μ.map (fun x ↦ ((k x, g x), f x)) = (μ.map (fun a ↦ (k a, g a, f a))).map e := by diff --git a/Mathlib/Probability/Kernel/Composition/MeasureComp.lean b/Mathlib/Probability/Kernel/Composition/MeasureComp.lean index 81bf2b2cfb4af6..be06725c69dcc6 100644 --- a/Mathlib/Probability/Kernel/Composition/MeasureComp.lean +++ b/Mathlib/Probability/Kernel/Composition/MeasureComp.lean @@ -94,7 +94,7 @@ lemma discard_comp (μ : Measure α) : Kernel.discard α ∘ₘ μ = μ .univ ext s hs; simp [Measure.bind_apply hs (Kernel.aemeasurable _), mul_comm] lemma copy_comp_map {f : α → β} (hf : AEMeasurable f μ) : - Kernel.copy β ∘ₘ (μ.map f) = μ.map (fun a ↦ (f a, f a)) := by + Kernel.copy β ∘ₘ (μ.map f) = μ.map (Function.diag ∘ f) := by rw [Kernel.copy, deterministic_comp_eq_map, AEMeasurable.map_map_of_aemeasurable (by fun_prop) hf] rfl diff --git a/Mathlib/Probability/Kernel/CondDistrib.lean b/Mathlib/Probability/Kernel/CondDistrib.lean index 3a8c1ba8d3f380..93663a650f9076 100644 --- a/Mathlib/Probability/Kernel/CondDistrib.lean +++ b/Mathlib/Probability/Kernel/CondDistrib.lean @@ -63,7 +63,7 @@ the conditional expectation `μ⟦Y ⁻¹' s | mβ.comap X⟧ a`. It also satisf for all integrable functions `f`. -/ noncomputable irreducible_def condDistrib {_ : MeasurableSpace α} [MeasurableSpace β] (Y : α → Ω) (X : α → β) (μ : Measure α) [IsFiniteMeasure μ] : Kernel β Ω := - (μ.map fun a => (X a, Y a)).condKernel + (μ.map (X ⇊ Y)).condKernel instance [MeasurableSpace β] : IsMarkovKernel (condDistrib Y X μ) := by rw [condDistrib]; infer_instance @@ -71,10 +71,10 @@ instance [MeasurableSpace β] : IsMarkovKernel (condDistrib Y X μ) := by variable {mβ : MeasurableSpace β} {s : Set Ω} {t : Set β} {f : β × Ω → F} /-- If the singleton `{x}` has non-zero mass for `μ.map X`, then for all `s : Set Ω`, -`condDistrib Y X μ x s = (μ.map X {x})⁻¹ * μ.map (fun a => (X a, Y a)) ({x} ×ˢ s)` . -/ +`condDistrib Y X μ x s = (μ.map X {x})⁻¹ * μ.map ((X ⇊ Y)) ({x} ×ˢ s)` . -/ lemma condDistrib_apply_of_ne_zero [MeasurableSingletonClass β] (hY : Measurable Y) (x : β) (hX : μ.map X {x} ≠ 0) (s : Set Ω) : - condDistrib Y X μ x s = (μ.map X {x})⁻¹ * μ.map (fun a => (X a, Y a)) ({x} ×ˢ s) := by + condDistrib Y X μ x s = (μ.map X {x})⁻¹ * μ.map ((X ⇊ Y)) ({x} ×ˢ s) := by rw [condDistrib, Measure.condKernel_apply_of_ne_zero _ s] · rw [Measure.fst_map_prodMk hY] · rwa [Measure.fst_map_prodMk hY] @@ -109,10 +109,10 @@ theorem measurable_condDistrib (hs : MeasurableSet s) : (Kernel.measurable_coe _ hs).comp (Measurable.of_comap_le le_rfl) theorem _root_.MeasureTheory.AEStronglyMeasurable.ae_integrable_condDistrib_map_iff - (hY : AEMeasurable Y μ) (hf : AEStronglyMeasurable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf : AEStronglyMeasurable f (μ.map (X ⇊ Y))) : (∀ᵐ a ∂μ.map X, Integrable (fun ω => f (a, ω)) (condDistrib Y X μ a)) ∧ Integrable (fun a => ∫ ω, ‖f (a, ω)‖ ∂condDistrib Y X μ a) (μ.map X) ↔ - Integrable f (μ.map fun a => (X a, Y a)) := by + Integrable f (μ.map (X ⇊ Y)) := by rw [condDistrib, ← hf.ae_integrable_condKernel_iff, Measure.fst_map_prodMk₀ hY] variable [NormedSpace ℝ F] @@ -122,12 +122,12 @@ theorem _root_.MeasureTheory.StronglyMeasurable.integral_condDistrib (hf : Stron rw [condDistrib]; exact hf.integral_kernel_prod_right' theorem _root_.MeasureTheory.AEStronglyMeasurable.integral_condDistrib_map - (hY : AEMeasurable Y μ) (hf : AEStronglyMeasurable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf : AEStronglyMeasurable f (μ.map (X ⇊ Y))) : AEStronglyMeasurable (fun x => ∫ y, f (x, y) ∂condDistrib Y X μ x) (μ.map X) := by rw [← Measure.fst_map_prodMk₀ hY, condDistrib]; exact hf.integral_condKernel theorem _root_.MeasureTheory.AEStronglyMeasurable.integral_condDistrib (hX : AEMeasurable X μ) - (hY : AEMeasurable Y μ) (hf : AEStronglyMeasurable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf : AEStronglyMeasurable f (μ.map (X ⇊ Y))) : AEStronglyMeasurable (fun a => ∫ y, f (X a, y) ∂condDistrib Y X μ (X a)) μ := (hf.integral_condDistrib_map hY).comp_aemeasurable hX @@ -136,7 +136,7 @@ theorem stronglyMeasurable_integral_condDistrib (hf : StronglyMeasurable f) : (hf.integral_condDistrib).comp_measurable <| Measurable.of_comap_le le_rfl theorem aestronglyMeasurable_integral_condDistrib (hX : AEMeasurable X μ) (hY : AEMeasurable Y μ) - (hf : AEStronglyMeasurable f (μ.map fun a => (X a, Y a))) : + (hf : AEStronglyMeasurable f (μ.map (X ⇊ Y))) : AEStronglyMeasurable[mβ.comap X] (fun a => ∫ y, f (X a, y) ∂condDistrib Y X μ (X a)) μ := (hf.integral_condDistrib_map hY).comp_ae_measurable' hX @@ -148,7 +148,7 @@ theorem condDistrib_ae_eq_of_measure_eq_compProd_of_measurable (hX : Measurable X) (hY : Measurable Y) {κ : Kernel β Ω} [IsFiniteKernel κ] (hκ : μ.map (fun x => (X x, Y x)) = μ.map X ⊗ₘ κ) : condDistrib Y X μ =ᵐ[μ.map X] κ := by - have heq : μ.map X = (μ.map (fun x ↦ (X x, Y x))).fst := by + have heq : μ.map X = (μ.map (X ⇊ Y)).fst := by ext s hs rw [Measure.map_apply hX hs, Measure.fst_apply hs, Measure.map_apply] exacts [rfl, Measurable.prod hX hY, measurable_fst hs] @@ -187,7 +187,7 @@ lemma condDistrib_comp {Ω' : Type*} {mΩ' : MeasurableSpace Ω'} [StandardBorel swap; · simp [Measure.map_of_not_aemeasurable hX, Filter.EventuallyEq] refine condDistrib_ae_eq_of_measure_eq_compProd X (by fun_prop) ?_ calc μ.map (fun x ↦ (X x, (f ∘ Y) x)) - _ = (μ.map (fun x ↦ (X x, Y x))).map (Prod.map id f) := by + _ = (μ.map (X ⇊ Y)).map (Prod.map id f) := by rw [AEMeasurable.map_map_of_aemeasurable (by fun_prop) (by fun_prop)] simp [Function.comp_def] _ = (μ.map X ⊗ₘ condDistrib Y X μ).map (Prod.map id f) := by rw [compProd_map_condDistrib hY] @@ -259,45 +259,45 @@ theorem integrable_toReal_condDistrib (hX : AEMeasurable X μ) (hs : MeasurableS _ < ∞ := measure_lt_top _ _ theorem _root_.MeasureTheory.Integrable.condDistrib_ae_map - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : ∀ᵐ b ∂μ.map X, Integrable (fun ω => f (b, ω)) (condDistrib Y X μ b) := by rw [condDistrib, ← Measure.fst_map_prodMk₀ (X := X) hY]; exact hf_int.condKernel_ae theorem _root_.MeasureTheory.Integrable.condDistrib_ae (hX : AEMeasurable X μ) - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : ∀ᵐ a ∂μ, Integrable (fun ω => f (X a, ω)) (condDistrib Y X μ (X a)) := ae_of_ae_map hX (hf_int.condDistrib_ae_map hY) theorem _root_.MeasureTheory.Integrable.integral_norm_condDistrib_map - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : Integrable (fun x => ∫ y, ‖f (x, y)‖ ∂condDistrib Y X μ x) (μ.map X) := by rw [condDistrib, ← Measure.fst_map_prodMk₀ (X := X) hY]; exact hf_int.integral_norm_condKernel theorem _root_.MeasureTheory.Integrable.integral_norm_condDistrib (hX : AEMeasurable X μ) - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : Integrable (fun a => ∫ y, ‖f (X a, y)‖ ∂condDistrib Y X μ (X a)) μ := (hf_int.integral_norm_condDistrib_map hY).comp_aemeasurable hX variable [NormedSpace ℝ F] theorem _root_.MeasureTheory.Integrable.norm_integral_condDistrib_map - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : Integrable (fun x => ‖∫ y, f (x, y) ∂condDistrib Y X μ x‖) (μ.map X) := by rw [condDistrib, ← Measure.fst_map_prodMk₀ (X := X) hY]; exact hf_int.norm_integral_condKernel theorem _root_.MeasureTheory.Integrable.norm_integral_condDistrib (hX : AEMeasurable X μ) - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : Integrable (fun a => ‖∫ y, f (X a, y) ∂condDistrib Y X μ (X a)‖) μ := (hf_int.norm_integral_condDistrib_map hY).comp_aemeasurable hX theorem _root_.MeasureTheory.Integrable.integral_condDistrib_map - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : Integrable (fun x => ∫ y, f (x, y) ∂condDistrib Y X μ x) (μ.map X) := (integrable_norm_iff (hf_int.1.integral_condDistrib_map hY)).mp (hf_int.norm_integral_condDistrib_map hY) theorem _root_.MeasureTheory.Integrable.integral_condDistrib (hX : AEMeasurable X μ) - (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hY : AEMeasurable Y μ) (hf_int : Integrable f (μ.map (X ⇊ Y))) : Integrable (fun a => ∫ y, f (X a, y) ∂condDistrib Y X μ (X a)) μ := (hf_int.integral_condDistrib_map hY).comp_aemeasurable hX @@ -336,7 +336,7 @@ theorem condDistrib_ae_eq_condExp (hX : Measurable X) (hY : Measurable Y) (hs : to the integral of `y ↦ f(X, y)` against the `condDistrib` kernel. -/ theorem condExp_prod_ae_eq_integral_condDistrib' [NormedSpace ℝ F] [CompleteSpace F] (hX : Measurable X) (hY : AEMeasurable Y μ) - (hf_int : Integrable f (μ.map fun a => (X a, Y a))) : + (hf_int : Integrable f (μ.map (X ⇊ Y))) : μ[fun a => f (X a, Y a) | mβ.comap X] =ᵐ[μ] fun a => ∫ y, f (X a, y) ∂condDistrib Y X μ (X a) := by have hf_int' : Integrable (fun a => f (X a, Y a)) μ := @@ -361,10 +361,10 @@ theorem condExp_prod_ae_eq_integral_condDistrib' [NormedSpace ℝ F] [CompleteSp to the integral of `y ↦ f(X, y)` against the `condDistrib` kernel. -/ theorem condExp_prod_ae_eq_integral_condDistrib₀ [NormedSpace ℝ F] [CompleteSpace F] (hX : Measurable X) (hY : AEMeasurable Y μ) - (hf : AEStronglyMeasurable f (μ.map fun a => (X a, Y a))) + (hf : AEStronglyMeasurable f (μ.map (X ⇊ Y))) (hf_int : Integrable (fun a => f (X a, Y a)) μ) : μ[fun a => f (X a, Y a) | mβ.comap X] =ᵐ[μ] fun a => ∫ y, f (X a, y) ∂condDistrib Y X μ (X a) := - have hf_int' : Integrable f (μ.map fun a => (X a, Y a)) := by + have hf_int' : Integrable f (μ.map (X ⇊ Y)) := by rwa [integrable_map_measure hf (hX.aemeasurable.prodMk hY)] condExp_prod_ae_eq_integral_condDistrib' hX hY hf_int' @@ -374,7 +374,7 @@ theorem condExp_prod_ae_eq_integral_condDistrib [NormedSpace ℝ F] [CompleteSpa (hX : Measurable X) (hY : AEMeasurable Y μ) (hf : StronglyMeasurable f) (hf_int : Integrable (fun a => f (X a, Y a)) μ) : μ[fun a => f (X a, Y a) | mβ.comap X] =ᵐ[μ] fun a => ∫ y, f (X a, y) ∂condDistrib Y X μ (X a) := - have hf_int' : Integrable f (μ.map fun a => (X a, Y a)) := by + have hf_int' : Integrable f (μ.map (X ⇊ Y)) := by rwa [integrable_map_measure hf.aestronglyMeasurable (hX.aemeasurable.prodMk hY)] condExp_prod_ae_eq_integral_condDistrib' hX hY hf_int' diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean index 9767b1bebd2cc1..94cffc50abf862 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean @@ -523,7 +523,7 @@ theorem uniformContinuous_of_tendsto_one {hom : Type*} [UniformSpace β] [Group [FunLike hom α β] [MonoidHomClass hom α β] {f : hom} (h : Tendsto f (𝓝 1) (𝓝 1)) : UniformContinuous f := by have : - ((fun x : β × β => x.2 / x.1) ∘ fun x : α × α => (f x.1, f x.2)) = fun x : α × α => + ((fun x : β × β => x.2 / x.1) ∘ Prod.map.uncurry ⇗f) = fun x : α × α => f (x.2 / x.1) := by ext; simp only [Function.comp_apply, map_div] rw [UniformContinuous, uniformity_eq_comap_nhds_one α, uniformity_eq_comap_nhds_one β, tendsto_comap_iff, this] diff --git a/Mathlib/Topology/ClopenBox.lean b/Mathlib/Topology/ClopenBox.lean index a191acd6ea765d..e22a88e7d7965c 100644 --- a/Mathlib/Topology/ClopenBox.lean +++ b/Mathlib/Topology/ClopenBox.lean @@ -61,7 +61,7 @@ theorem exists_finset_eq_sup_prod (W : Clopens (X × Y)) : rcases W.2.1.isCompact.elim_nhds_subcover (fun x ↦ U x ×ˢ V x) (fun x hx ↦ (U x ×ˢ V x).2.isOpen.mem_nhds ⟨hxU x hx, hxV x hx⟩) with ⟨I, hIW, hWI⟩ classical - use I.image fun x ↦ (U x, V x) + use I.image U ⇊ V rw [Finset.sup_image] refine le_antisymm (fun x hx ↦ ?_) (Finset.sup_le fun x hx ↦ ?_) · rcases Set.mem_iUnion₂.1 (hWI hx) with ⟨i, hi, hxi⟩ diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index c0ed3cafeff002..3fd8a7584bf559 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -493,19 +493,19 @@ theorem comp_mem_uniformity_sets {s : SetRel α α} (hs : s ∈ 𝓤 α) : ∃ t /-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is transitive. -/ theorem Filter.Tendsto.uniformity_trans {l : Filter β} {f₁ f₂ f₃ : β → α} - (h₁₂ : Tendsto (fun x => (f₁ x, f₂ x)) l (𝓤 α)) - (h₂₃ : Tendsto (fun x => (f₂ x, f₃ x)) l (𝓤 α)) : Tendsto (fun x => (f₁ x, f₃ x)) l (𝓤 α) := by + (h₁₂ : Tendsto (f₁ ⇊ f₂) l (𝓤 α)) + (h₂₃ : Tendsto (f₂ ⇊ f₃) l (𝓤 α)) : Tendsto (f₁ ⇊ f₃) l (𝓤 α) := by refine le_trans (le_lift'.2 fun s hs => mem_map.2 ?_) comp_le_uniformity filter_upwards [mem_map.1 (h₁₂ hs), mem_map.1 (h₂₃ hs)] with x hx₁₂ hx₂₃ using ⟨_, hx₁₂, hx₂₃⟩ /-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is symmetric. -/ theorem Filter.Tendsto.uniformity_symm {l : Filter β} {f : β → α × α} (h : Tendsto f l (𝓤 α)) : - Tendsto (fun x => ((f x).2, (f x).1)) l (𝓤 α) := + Tendsto (Prod.swap ∘ Function.diag ∘ f) l (𝓤 α) := tendsto_swap_uniformity.comp h /-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is reflexive. -/ theorem tendsto_diag_uniformity (f : β → α) (l : Filter β) : - Tendsto (fun x => (f x, f x)) l (𝓤 α) := fun _s hs => + Tendsto (Function.diag ∘ f) l (𝓤 α) := fun _s hs => mem_map.2 <| univ_mem' fun _ => refl_mem_uniformity hs theorem tendsto_const_uniformity {a : α} {f : Filter β} : Tendsto (fun _ => (a, a)) f (𝓤 α) := @@ -805,7 +805,7 @@ variable [UniformSpace β] as `(x, y)` tends to the diagonal. In other words, if `x` is sufficiently close to `y`, then `f x` is close to `f y` no matter where `x` and `y` are located in `α`. -/ def UniformContinuous (f : α → β) := - Tendsto (fun x : α × α => (f x.1, f x.2)) (𝓤 α) (𝓤 β) + Tendsto (Prod.map.uncurry ⇗f) (𝓤 α) (𝓤 β) /-- Notation for uniform continuity with respect to non-standard `UniformSpace` instances. -/ scoped[Uniformity] notation "UniformContinuous[" u₁ ", " u₂ "]" => @UniformContinuous _ _ u₁ u₂ @@ -815,7 +815,7 @@ the diagonal as `(x, y)` tends to the diagonal while remaining in `s ×ˢ s`. In other words, if `x` is sufficiently close to `y`, then `f x` is close to `f y` no matter where `x` and `y` are located in `s`. -/ def UniformContinuousOn (f : α → β) (s : Set α) : Prop := - Tendsto (fun x : α × α => (f x.1, f x.2)) (𝓤 α ⊓ 𝓟 (s ×ˢ s)) (𝓤 β) + Tendsto (Prod.map.uncurry ⇗f) (𝓤 α ⊓ 𝓟 (s ×ˢ s)) (𝓤 β) theorem uniformContinuous_def {f : α → β} : UniformContinuous f ↔ ∀ r ∈ 𝓤 β, { x : α × α | (f x.1, f x.2) ∈ r } ∈ 𝓤 α := From d156b2ce7ae117ce4c824bc7107db81156133cb1 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 03:07:58 +0100 Subject: [PATCH 31/35] Add fun_prop lemma --- Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean | 2 +- Mathlib/Order/ScottContinuity.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index a691c2a635bb27..3876b545a47161 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -406,7 +406,7 @@ theorem Measurable.prod {f : α → β × γ} (hf₁ : Measurable fun a => (f a) @[fun_prop] theorem Measurable.prodMk {β γ} {_ : MeasurableSpace β} {_ : MeasurableSpace γ} {f : α → β} - {g : α → γ} (hf : Measurable f) (hg : Measurable g) : Measurable fun a : α => (f a, g a) := + {g : α → γ} (hf : Measurable f) (hg : Measurable g) : Measurable (f ⇊ g) := Measurable.prod hf hg @[fun_prop] diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index 1dfd5284a61be1..d730c9758c7f17 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -172,7 +172,7 @@ lemma ScottContinuous.comp {g : β → γ} @[fun_prop] lemma ScottContinuous.prodMk {g : α → γ} (hf : ScottContinuous f) (hg : ScottContinuous g) : - ScottContinuous Function.prod f g := by + ScottContinuous (f ⇊ g) := by rw [← scottContinuousOn_univ] at ⊢ hf hg exact ScottContinuousOn.prodMk (by grind) hf hg From 4a4a43f6bc5b20e136b674eea0e1376d02c306b1 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 15:54:18 +0100 Subject: [PATCH 32/35] Updates --- Mathlib/Algebra/Order/Antidiag/Pi.lean | 5 +- Mathlib/Data/Set/Image.lean | 11 ++ Mathlib/Data/Set/Lattice/Image.lean | 18 +-- Mathlib/Data/Set/NAry.lean | 51 ++++--- Mathlib/Data/Set/Operations.lean | 7 +- Mathlib/Data/Set/Prod.lean | 15 +- Mathlib/Data/Tree/Basic.lean | 6 +- Mathlib/Logic/Equiv/Prod.lean | 24 ++-- Mathlib/Logic/Function/Init.lean | 60 ++++---- Mathlib/Order/CompleteLattice/Basic.lean | 5 +- Mathlib/Order/Filter/Prod.lean | 19 +-- Mathlib/Order/Hom/Basic.lean | 2 +- Mathlib/Order/OmegaCompletePartialOrder.lean | 2 +- Mathlib/Topology/Constructions/SumProd.lean | 137 ++++++++++--------- Mathlib/Topology/UniformSpace/Defs.lean | 14 +- 15 files changed, 196 insertions(+), 180 deletions(-) diff --git a/Mathlib/Algebra/Order/Antidiag/Pi.lean b/Mathlib/Algebra/Order/Antidiag/Pi.lean index 7f601cde03e8fe..65f3e2ae7590c3 100644 --- a/Mathlib/Algebra/Order/Antidiag/Pi.lean +++ b/Mathlib/Algebra/Order/Antidiag/Pi.lean @@ -149,10 +149,7 @@ lemma piAntidiag_empty (n : μ) : piAntidiag (∅ : Finset ι) n = if n = 0 then lemma finsetCongr_piAntidiag_eq_antidiag (n : μ) : Equiv.finsetCongr (Equiv.boolArrowEquivProd _) (piAntidiag univ n) = antidiagonal n := by - ext ⟨x₁, x₂⟩ - simp_rw [Equiv.finsetCongr_apply, mem_map, Equiv.toEmbedding, Function.Embedding.coeFn_mk, - ← Equiv.eq_symm_apply] - simp [add_comm] + simp [Finset.ext_iff, flip, add_comm] end AddCommMonoid diff --git a/Mathlib/Data/Set/Image.lean b/Mathlib/Data/Set/Image.lean index 8dba5bf16dd163..9bd84d9d2df842 100644 --- a/Mathlib/Data/Set/Image.lean +++ b/Mathlib/Data/Set/Image.lean @@ -140,6 +140,9 @@ theorem preimage_comp {s : Set γ} : g ∘ f ⁻¹' s = f ⁻¹' (g ⁻¹' s) := theorem preimage_comp_eq : preimage (g ∘ f) = preimage f ∘ preimage g := rfl +theorem preimage_prod {f : α → β} {g : α → γ} {s : Set (β × γ)} : + (f ⇊ g) ⁻¹' s = {x | (f x, g x) ∈ s} := rfl + theorem preimage_iterate_eq {f : α → α} {n : ℕ} : Set.preimage f^[n] = (Set.preimage f)^[n] := by induction n with | zero => simp @@ -219,6 +222,14 @@ theorem image_comp (f : β → γ) (g : α → β) (a : Set α) : f ∘ g '' a = theorem image_comp_eq {g : β → γ} : image (g ∘ f) = image g ∘ image f := by grind +theorem image_prodMap {δ} (f : α → β) (g : γ → δ) (s : Set (α × γ)) : + (Prod.map f g) '' s = {q | ∃ a b, (a, b) ∈ s ∧ f a = q.1 ∧ g b = q.2} := by + simp [Set.ext_iff, Prod.ext_iff] + +theorem image_prod (f : α → β) (g : α → γ) (s : Set α) : (f ⇊ g) '' s = + {x | ∃ y ∈ s, f y = x.1 ∧ g y = x.2} := by + simp [Set.ext_iff, Prod.ext_iff] + /-- A variant of `image_comp`, useful for rewriting -/ @[grind =] theorem image_image (g : β → γ) (f : α → β) (s : Set α) : g '' (f '' s) = (fun x => g (f x)) '' s := diff --git a/Mathlib/Data/Set/Lattice/Image.lean b/Mathlib/Data/Set/Lattice/Image.lean index ed904b54db22b2..d06019924b9321 100644 --- a/Mathlib/Data/Set/Lattice/Image.lean +++ b/Mathlib/Data/Set/Lattice/Image.lean @@ -515,15 +515,15 @@ theorem iUnion_image_left : ⋃ a ∈ s, f a '' t = image2 f s t := by simp only [image2_eq_iUnion, image_eq_iUnion] theorem iUnion_image_right : ⋃ b ∈ t, (f · b) '' s = image2 f s t := by - rw [image2_swap, iUnion_image_left] + rw [iUnion_image_left, image2_swap f s t] theorem image2_iUnion_left (s : ι → Set α) (t : Set β) : image2 f (⋃ i, s i) t = ⋃ i, image2 f (s i) t := by - simp only [← image_prod, iUnion_prod_const, image_iUnion] + simp only [← image_uncurry_prod, iUnion_prod_const, image_iUnion] theorem image2_iUnion_right (s : Set α) (t : ι → Set β) : image2 f s (⋃ i, t i) = ⋃ i, image2 f s (t i) := by - simp only [← image_prod, prod_iUnion, image_iUnion] + simp only [← image_uncurry_prod, prod_iUnion, image_iUnion] theorem image2_sUnion_left (S : Set (Set α)) (t : Set β) : image2 f (⋃₀ S) t = ⋃ s ∈ S, image2 f s t := by @@ -598,23 +598,19 @@ theorem seq_singleton {s : Set (α → β)} {a : α} : Set.seq s {a} = (fun f : image2_singleton_right theorem seq_seq {s : Set (β → γ)} {t : Set (α → β)} {u : Set α} : - seq s (seq t u) = seq (seq ((· ∘ ·) '' s) t) u := by - simp only [seq_eq_image2, image2_image_left] - exact .symm <| image2_assoc fun _ _ _ ↦ rfl + seq s (seq t u) = seq (seq ((· ∘ ·) '' s) t) u := by ext; aesop theorem image_seq {f : β → γ} {s : Set (α → β)} {t : Set α} : - f '' seq s t = seq ((f ∘ ·) '' s) t := by - simp only [seq, image_image2, image2_image_left, comp_apply] + f '' seq s t = seq ((f ∘ ·) '' s) t := by ext; aesop -theorem prod_eq_seq {s : Set α} {t : Set β} : s ×ˢ t = (Prod.mk '' s).seq t := by - rw [seq_eq_image2, image2_image_left, image2_mk_eq_prod] +theorem prod_eq_seq {s : Set α} {t : Set β} : s ×ˢ t = (Prod.mk '' s).seq t := by ext; aesop theorem prod_image_seq_comm (s : Set α) (t : Set β) : (Prod.mk '' s).seq t = seq ((fun b a => (a, b)) '' t) s := by rw [← prod_eq_seq, ← image_swap_prod, prod_eq_seq, image_seq, ← image_comp]; rfl theorem image2_eq_seq (f : α → β → γ) (s : Set α) (t : Set β) : image2 f s t = seq (f '' s) t := by - rw [seq_eq_image2, image2_image_left] + ext; aesop end Seq diff --git a/Mathlib/Data/Set/NAry.lean b/Mathlib/Data/Set/NAry.lean index 46fe4f361a25b2..e50f7a5e649dea 100644 --- a/Mathlib/Data/Set/NAry.lean +++ b/Mathlib/Data/Set/NAry.lean @@ -69,30 +69,28 @@ theorem image2_subset_iff_right : image2 f s t ⊆ u ↔ ∀ b ∈ t, (fun a => variable (f) -@[simp] -lemma image_prod : (fun x : α × β ↦ f x.1 x.2) '' s ×ˢ t = image2 f s t := - ext fun _ ↦ by simp [and_assoc] - @[simp] lemma image_uncurry_prod (s : Set α) (t : Set β) : uncurry f '' s ×ˢ t = image2 f s t := - image_prod _ + ext fun _ ↦ by simp [and_assoc] @[simp] lemma image2_mk_eq_prod : image2 Prod.mk s t = s ×ˢ t := ext <| by simp @[simp] lemma image2_curry (f : α × β → γ) (s : Set α) (t : Set β) : - image2 (fun a b ↦ f (a, b)) s t = f '' s ×ˢ t := by - simp [← image_uncurry_prod, uncurry] + image2 f.curry s t = f '' s ×ˢ t := by simp [← image_uncurry_prod] -theorem image2_swap (s : Set α) (t : Set β) : image2 f s t = image2 (fun a b => f b a) t s := by - grind +theorem image2_flip (s : Set α) (t : Set β) : image2 (flip f) t s = image2 f s t := by + grind [flip] + +theorem image2_swap (s : Set α) (t : Set β) : image2 f s t = image2 (fun b x ↦ f x b) t s := + (image2_flip f s t).symm variable {f} theorem image2_union_left : image2 f (s ∪ s') t = image2 f s t ∪ image2 f s' t := by - simp_rw [← image_prod, union_prod, image_union] + simp_rw [← image_uncurry_prod, union_prod, image_union] theorem image2_union_right : image2 f s (t ∪ t') = image2 f s t ∪ image2 f s t' := by - rw [← image2_swap, image2_union_left, image2_swap f, image2_swap f] + rw [← image2_flip, image2_union_left, image2_flip f, image2_flip f] lemma image2_inter_left (hf : Injective2 f) : image2 f (s ∩ s') t = image2 f s t ∩ image2 f s' t := by @@ -130,7 +128,7 @@ theorem image2_eq_empty_iff : image2 f s t = ∅ ↔ s = ∅ ∨ t = ∅ := by theorem Subsingleton.image2 (hs : s.Subsingleton) (ht : t.Subsingleton) (f : α → β → γ) : (image2 f s t).Subsingleton := by - rw [← image_prod] + rw [← image_uncurry_prod] apply (hs.prod ht).image theorem image2_inter_subset_left : image2 f (s ∩ s') t ⊆ image2 f s t ∩ image2 f s' t := @@ -176,16 +174,16 @@ theorem image2_congr' (h : ∀ a b, f a b = f' a b) : image2 f s t = image2 f' s image2_congr fun a _ b _ => h a b theorem image_image2 (f : α → β → γ) (g : γ → δ) : - g '' image2 f s t = image2 (fun a b => g (f a b)) s t := by - simp only [← image_prod, image_image] + g '' image2 f s t = g ∘ uncurry f '' s ×ˢ t := by + simp only [← image_uncurry_prod, image_comp] theorem image2_image_left (f : γ → β → δ) (g : α → γ) : - image2 f (g '' s) t = image2 (fun a b => f (g a) b) s t := by - ext; simp - + image2 f (g '' s) t = uncurry f ∘ Prod.map g id '' s ×ˢ t := by + ext; aesop +--fun a b => f (g a) b theorem image2_image_right (f : α → γ → δ) (g : β → γ) : - image2 f s (g '' t) = image2 (fun a b => f a (g b)) s t := by - ext; simp + image2 f s (g '' t) = uncurry f ∘ Prod.map id g '' s ×ˢ t := by + ext; aesop @[simp] theorem image2_left (h : t.Nonempty) : image2 (fun x _ => x) s t = s := by @@ -196,8 +194,8 @@ theorem image2_right (h : s.Nonempty) : image2 (fun _ y => y) s t = t := by simp [nonempty_def.mp h, Set.ext_iff] lemma image2_range (f : α' → β' → γ) (g : α → α') (h : β → β') : - image2 f (range g) (range h) = range fun x : α × β ↦ f (g x.1) (h x.2) := by - simp_rw [← image_univ, image2_image_left, image2_image_right, ← image_prod, univ_prod_univ] + image2 f (range g) (range h) = range (f.uncurry ∘ Prod.map g h) := by + ext; aesop theorem image2_assoc {f : δ → γ → ε} {g : α → β → δ} {f' : α → ε' → ε} {g' : β → γ → ε'} (h_assoc : ∀ a b c, f (g a b) c = f' a (g' b c)) : @@ -205,18 +203,18 @@ theorem image2_assoc {f : δ → γ → ε} {g : α → β → δ} {f' : α → eq_of_forall_subset_iff fun _ ↦ by simp only [image2_subset_iff, forall_mem_image2, h_assoc] theorem image2_comm {g : β → α → γ} (h_comm : ∀ a b, f a b = g b a) : image2 f s t = image2 g t s := - (image2_swap _ _ _).trans <| by simp_rw [h_comm] + (image2_flip _ _ _).trans <| by simp_rw [h_comm] theorem image2_left_comm {f : α → δ → ε} {g : β → γ → δ} {f' : α → γ → δ'} {g' : β → δ' → ε} (h_left_comm : ∀ a b c, f a (g b c) = g' b (f' a c)) : image2 f s (image2 g t u) = image2 g' t (image2 f' s u) := by - rw [image2_swap f', image2_swap f] + rw [← image2_flip f', ← image2_flip f] exact image2_assoc fun _ _ _ => h_left_comm _ _ _ theorem image2_right_comm {f : δ → γ → ε} {g : α → β → δ} {f' : α → γ → δ'} {g' : δ' → β → ε} (h_right_comm : ∀ a b c, f (g a b) c = g' (f' a c) b) : image2 f (image2 g s t) u = image2 g' (image2 f' s u) t := by - rw [image2_swap g, image2_swap g'] + rw [← image2_flip g, ← image2_flip g'] exact image2_assoc fun _ _ _ => h_right_comm _ _ _ theorem image2_image2_image2_comm {f : ε → ζ → ν} {g : α → β → ε} {h : γ → δ → ζ} {f' : ε' → ζ' → ν} @@ -227,8 +225,7 @@ theorem image2_image2_image2_comm {f : ε → ζ → ν} {g : α → β → ε} theorem image_image2_distrib {g : γ → δ} {f' : α' → β' → δ} {g₁ : α → α'} {g₂ : β → β'} (h_distrib : ∀ a b, g (f a b) = f' (g₁ a) (g₂ b)) : - (image2 f s t).image g = image2 f' (s.image g₁) (t.image g₂) := by - simp_rw [image_image2, image2_image_left, image2_image_right, h_distrib] + (image2 f s t).image g = image2 f' (s.image g₁) (t.image g₂) := by aesop /-- Symmetric statement to `Set.image2_image_left_comm`. -/ theorem image_image2_distrib_left {g : γ → δ} {f' : α' → β → δ} {g' : α → α'} @@ -269,7 +266,7 @@ theorem image2_distrib_subset_right {f : δ → γ → ε} {g : α → β → δ theorem image_image2_antidistrib {g : γ → δ} {f' : β' → α' → δ} {g₁ : β → β'} {g₂ : α → α'} (h_antidistrib : ∀ a b, g (f a b) = f' (g₁ b) (g₂ a)) : (image2 f s t).image g = image2 f' (t.image g₁) (s.image g₂) := by - rw [image2_swap f] + rw [← image2_flip f] exact image_image2_distrib fun _ _ => h_antidistrib _ _ /-- Symmetric statement to `Set.image2_image_left_anticomm`. -/ diff --git a/Mathlib/Data/Set/Operations.lean b/Mathlib/Data/Set/Operations.lean index f855341e8c662b..024a306cbb4709 100644 --- a/Mathlib/Data/Set/Operations.lean +++ b/Mathlib/Data/Set/Operations.lean @@ -11,6 +11,7 @@ public import Mathlib.Data.SProd public import Mathlib.Data.Subtype public import Mathlib.Order.Notation public import Mathlib.Tactic.Push.Attr +public import Mathlib.Logic.Function.Init import Mathlib.Tactic.Attr.Register import Aesop.BuiltinRules @@ -225,11 +226,11 @@ theorem prodMk_mem_set_prod_eq : ((a, b) ∈ s ×ˢ t) = (a ∈ s ∧ b ∈ t) : theorem mk_mem_prod (ha : a ∈ s) (hb : b ∈ t) : (a, b) ∈ s ×ˢ t := ⟨ha, hb⟩ theorem prod_image_left (f : α → γ) (s : Set α) (t : Set β) : - (f '' s) ×ˢ t = (fun x ↦ (f x.1, x.2)) '' s ×ˢ t := by + (f '' s) ×ˢ t = Prod.map f id '' s ×ˢ t := by aesop theorem prod_image_right (f : α → γ) (s : Set α) (t : Set β) : - t ×ˢ (f '' s) = (fun x ↦ (x.1, f x.2)) '' t ×ˢ s := by + t ×ˢ (f '' s) = Prod.map id f '' t ×ˢ s := by aesop end Prod @@ -294,7 +295,7 @@ def InjOn (f : α → β) (s : Set α) : Prop := ∀ ⦃x₁ : α⦄, x₁ ∈ s → ∀ ⦃x₂ : α⦄, x₂ ∈ s → f x₁ = f x₂ → x₁ = x₂ /-- The graph of a function `f : α → β` on a set `s`. -/ -def graphOn (f : α → β) (s : Set α) : Set (α × β) := (fun x ↦ (x, f x)) '' s +def graphOn (f : α → β) (s : Set α) : Set (α × β) := (id ⇊ f) '' s /-- `f` is surjective from `s` to `t` if `t` is contained in the image of `s`. -/ def SurjOn (f : α → β) (s : Set α) (t : Set β) : Prop := t ⊆ f '' s diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index cd0c9633302a87..57dcf0e9ba1848 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -926,7 +926,8 @@ variable {α β γ δ : Type*} {s : Set α} {f : α → β} section graphOn variable {x : α × β} -@[simp] lemma mem_graphOn : x ∈ s.graphOn f ↔ x.1 ∈ s ∧ f x.1 = x.2 := by aesop (add simp graphOn) +@[simp] lemma mem_graphOn : x ∈ s.graphOn f ↔ x.1 ∈ s ∧ f x.1 = x.2 := by + simp [graphOn, Prod.ext_iff] @[simp] lemma graphOn_empty (f : α → β) : graphOn f ∅ = ∅ := image_empty _ @[simp] lemma graphOn_eq_empty : graphOn f s = ∅ ↔ s = ∅ := image_eq_empty @@ -956,8 +957,12 @@ lemma image_fst_graphOn (f : α → β) (s : Set α) : Prod.fst '' graphOn f s = lemma fst_injOn_graph : (s.graphOn f).InjOn Prod.fst := by aesop (add simp InjOn) lemma graphOn_comp (s : Set α) (f : α → β) (g : β → γ) : - s.graphOn (g ∘ f) = (fun x ↦ (x.1, g x.2)) '' s.graphOn f := by - simpa using image_comp (fun x ↦ (x.1, g x.2)) (fun x ↦ (x, f x)) _ + s.graphOn (g ∘ f) = Prod.map id g '' s.graphOn f := by + simpa using image_comp (Prod.map id g) (id ⇊ f) _ + +lemma graphOn_prod (s : Set α) (f : α → β) (g : α → γ) : + s.graphOn (f ⇊ g) = {x | x.1 ∈ s ∧ f x.1 = x.2.1 ∧ g x.1 = x.2.2} := by + simp [graphOn, Set.ext_iff, Prod.ext_iff] lemma graphOn_univ_eq_range : univ.graphOn f = range fun x ↦ (x, f x) := image_univ @@ -966,11 +971,11 @@ lemma graphOn_univ_eq_range : univ.graphOn f = range fun x ↦ (x, f x) := image lemma graphOn_prod_graphOn (s : Set α) (t : Set β) (f : α → γ) (g : β → δ) : s.graphOn f ×ˢ t.graphOn g = Equiv.prodProdProdComm .. ⁻¹' (s ×ˢ t).graphOn (Prod.map f g) := by - aesop + simp [Set.ext_iff, Prod.ext_iff, and_and_and_comm] lemma graphOn_prod_prodMap (s : Set α) (t : Set β) (f : α → γ) (g : β → δ) : (s ×ˢ t).graphOn (Prod.map f g) = Equiv.prodProdProdComm .. ⁻¹' s.graphOn f ×ˢ t.graphOn g := by - aesop + simp [Set.ext_iff, Prod.ext_iff, and_and_and_comm] end graphOn diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index c5b44227e7769b..6b9031712231c5 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -125,11 +125,11 @@ scoped infixr:65 " △ " => Tree.node () /-- Induction principle for `Tree Unit`s -/ @[elab_as_elim] def unitRecOn {motive : Tree Unit → Sort*} (t : Tree Unit) (base : motive nil) - (ind : ∀ x y, motive x → motive y → motive (x ⇊ y)) : motive t := + (ind : ∀ x y, motive x → motive y → motive (x △ y)) : motive t := t.recOn base fun _u ↦ ind -theorem left_node_right_eq_self : ∀ {x : Tree Unit} (_hx : x ≠ nil), x.left ⇊ x.right = x +theorem left_node_right_eq_self : ∀ {x : Tree Unit} (_hx : x ≠ nil), x.left △ x.right = x | nil, h => by trivial - | node _ _ _, _ => rfl -- Porting note: `a ⇊ b` no longer works in pattern matching + | node _ _ _, _ => rfl -- Porting note: `a △ b` no longer works in pattern matching end Tree diff --git a/Mathlib/Logic/Equiv/Prod.lean b/Mathlib/Logic/Equiv/Prod.lean index 7b030f20c2cce7..2bce1b4ed2a14e 100644 --- a/Mathlib/Logic/Equiv/Prod.lean +++ b/Mathlib/Logic/Equiv/Prod.lean @@ -97,17 +97,19 @@ theorem prodComm_apply {α β} (x : α × β) : prodComm α β x = x.swap := theorem prodComm_symm (α β) : (prodComm α β).symm = prodComm β α := rfl +open Prod in /-- Type product is associative up to an equivalence. -/ @[simps (attr := grind =)] -def prodAssoc (α β γ) : (α × β) × γ ≃ α × β × γ := - ⟨fun p => (p.1.1, p.1.2, p.2), fun p => ((p.1, p.2.1), p.2.2), fun ⟨⟨_, _⟩, _⟩ => rfl, - fun ⟨_, ⟨_, _⟩⟩ => rfl⟩ +def prodAssoc (α β γ) : (α × β) × γ ≃ α × β × γ where + toFun := (fst ∘ fst) ⇊ ((snd ∘ fst) ⇊ snd) + invFun := (fst ⇊ (fst ∘ snd)) ⇊ (snd ∘ snd) +open Prod in /-- Four-way commutativity of `prod`. The name matches `mul_mul_mul_comm`. -/ @[simps (attr := grind =) apply] def prodProdProdComm (α β γ δ) : (α × β) × γ × δ ≃ (α × γ) × β × δ where - toFun abcd := ((abcd.1.1, abcd.2.1), (abcd.1.2, abcd.2.2)) - invFun acbd := ((acbd.1.1, acbd.2.1), (acbd.1.2, acbd.2.2)) + toFun := ((fst ∘ fst) ⇊ (fst ∘ snd)) ⇊ ((snd ∘ fst) ⇊ (snd ∘ snd)) + invFun := ((fst ∘ fst) ⇊ (fst ∘ snd)) ⇊ ((snd ∘ fst) ⇊ (snd ∘ snd)) @[simp, grind =] theorem prodProdProdComm_symm (α β γ δ) : @@ -118,17 +120,15 @@ theorem prodProdProdComm_symm (α β γ δ) : @[simps (attr := grind =) -fullyApplied] def curry (α β γ) : (α × β → γ) ≃ (α → β → γ) where toFun := Function.curry - invFun := uncurry - left_inv := uncurry_curry - right_inv := curry_uncurry + invFun := Function.uncurry section /-- `PUnit` is a right identity for type product up to an equivalence. -/ @[simps (attr := grind =)] def prodPUnit (α) : α × PUnit ≃ α where - toFun := fun p => p.1 - invFun := fun a => (a, PUnit.unit) + toFun := Prod.fst + invFun := id ⇊ Function.const α () /-- `PUnit` is a left identity for type product up to an equivalence. -/ @[simps! (attr := grind =)] @@ -140,7 +140,7 @@ def punitProd (α) : PUnit × α ≃ α := /-- `PUnit` is a right identity for dependent type product up to an equivalence. -/ @[simps (attr := grind =)] def sigmaPUnit (α) : (_ : α) × PUnit ≃ α where - toFun := fun p => p.1 + toFun := Sigma.fst invFun := fun a => ⟨a, PUnit.unit⟩ /-- Any `Unique` type is a right identity for type product up to equivalence. -/ @@ -439,7 +439,7 @@ def boolProdEquivSum (α : Type*) : Bool × α ≃ α ⊕ α where @[simps (attr := grind =)] def boolArrowEquivProd (α : Type*) : (Bool → α) ≃ α × α where toFun := Function.prod (· false) (· true) - invFun := flip (cond · Prod.snd Prod.fst ·) + invFun := flip (cond · Prod.snd Prod.fst ·) left_inv _ := by grind [flip] end diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 45beb4a19f2b03..2ed8ac82916f7c 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -9,8 +9,8 @@ public import Mathlib.Init /-! -This file defines `(f ⇊ g)`, the operation that pairs two functions `f : γ → α` and -`g : γ → β` into a function `γ → α × β`. +This file defines `(f ⇊ g)`, the operation that pairs two functions `f : ι → α` and +`g : ι → β` into a function `ι → α × β`. It also defines the special case when `f = g = id`, `Function.diag`. This is the canonical injection of a type into its prouduct with itself onto its diagonal. @@ -66,8 +66,8 @@ theorem exists_snd_comp (f : ∀ i, α i) (g : ∀ i, β i) : ∃ h : ∀ i, α i × β i, (Prod.snd <| h ·) = g := ⟨(f ⇊' g), snd_comp_prod⟩ @[grind =] -theorem prod_const_const {γ} {α β} {a : α} {b : β} : - (Function.const γ a) ⇊' (Function.const γ b) = Function.const γ (a, b) := rfl +theorem prod_const_const {ι} {α β} {a : α} {b : β} : + (Function.const ι a) ⇊' (Function.const ι b) = Function.const ι (a, b) := rfl end @@ -75,20 +75,20 @@ end Pi namespace Function -variable {α β δ ε : Type*} {γ : Sort*} +variable {α β γ δ : Type*} {ι : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -protected def prod (f : γ → α) (g : γ → β) : γ → α × β := f ⇊' g +protected def prod (f : ι → α) (g : ι → β) : ι → α × β := f ⇊' g @[inherit_doc] infixr:65 " ⇊ " => Function.prod section -variable (f : γ → α) (g : γ → β) +variable (f : ι → α) (g : ι → β) -@[grind =] theorem prod_apply (c : γ) : (f.prod g) c = (f c, g c) := rfl +@[grind =] theorem prod_apply (c : ι) : (f.prod g) c = (f c, g c) := rfl -theorem prod_comp {δ} {h : δ → γ} : (f ⇊ g) ∘ h = (f ∘ h) ⇊ (g ∘ h) := rfl +theorem prod_comp {γ} {h : γ → ι} : (f ⇊ g) ∘ h = (f ∘ h) ⇊ (g ∘ h) := rfl @[simp] theorem fst_prod {c} : ((f ⇊ g) c).fst = f c := rfl @[simp] theorem snd_prod {c} : ((f ⇊ g) c).snd = g c := rfl @@ -96,54 +96,54 @@ theorem prod_comp {δ} {h : δ → γ} : (f ⇊ g) ∘ h = (f ∘ h) ⇊ (g ∘ @[simp] theorem prod_fst_snd : Prod.fst (α := α) ⇊ Prod.snd (β := β) = id := rfl @[simp] theorem prod_snd_fst : Prod.snd (β := β) ⇊ Prod.fst (α := α) = .swap := rfl -@[simp] theorem prod_fst_snd_comp {f : γ → α × β} : (Prod.fst ∘ f) ⇊ (Prod.snd ∘ f) = f := rfl +@[simp] theorem prod_fst_snd_comp {f : ι → α × β} : (Prod.fst ∘ f) ⇊ (Prod.snd ∘ f) = f := rfl -@[simp] theorem fst_comp_prod {f : γ → α} {g : γ → β} : Prod.fst ∘ (f ⇊ g) = f := rfl -@[simp] theorem snd_comp_prod {f : γ → α} {g : γ → β} : Prod.snd ∘ (f ⇊ g) = g := rfl +@[simp] theorem fst_comp_prod {f : ι → α} {g : ι → β} : Prod.fst ∘ (f ⇊ g) = f := rfl +@[simp] theorem snd_comp_prod {f : ι → α} {g : ι → β} : Prod.snd ∘ (f ⇊ g) = g := rfl -theorem prod_eq_iff {f f' : γ → α} {g g' : γ → β} : f ⇊ g = f' ⇊ g' ↔ +theorem prod_eq_iff {f f' : ι → α} {g g' : ι → β} : f ⇊ g = f' ⇊ g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem prod_ext_iff {h h' : γ → α × β} : h = h' ↔ +theorem prod_ext_iff {h h' : ι → α × β} : h = h' ↔ Prod.fst ∘ h = Prod.fst ∘ h' ∧ Prod.snd ∘ h = (Prod.snd ∘ h') := by simp [funext_iff, Prod.ext_iff, forall_and] -theorem exists_prod_apply_eq (h : γ → α × β) : ∃ f g, f ⇊ g = h := +theorem exists_prod_apply_eq (h : ι → α × β) : ∃ f g, f ⇊ g = h := ⟨Prod.fst ∘ h, Prod.snd ∘ h, prod_fst_snd_comp⟩ -theorem exists_fst_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.fst ∘ h = f := ⟨f ⇊ g, fst_comp_prod⟩ -theorem exists_snd_comp (f : γ → α) (g : γ → β) : - ∃ h : γ → α × β, Prod.snd ∘ h = g := ⟨f ⇊ g, snd_comp_prod⟩ +theorem exists_fst_comp (f : ι → α) (g : ι → β) : + ∃ h : ι → α × β, Prod.fst ∘ h = f := ⟨f ⇊ g, fst_comp_prod⟩ +theorem exists_snd_comp (f : ι → α) (g : ι → β) : + ∃ h : ι → α × β, Prod.snd ∘ h = g := ⟨f ⇊ g, snd_comp_prod⟩ theorem leftInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.LeftInverse - (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := + (Function.prod (ι := γ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := fun _ => rfl theorem rightInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.RightInverse - (Function.prod (γ := δ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := + (Function.prod (ι := γ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := fun _ => rfl @[grind =] theorem prod_const_const (a : α) (b : β) : - (Function.const γ a) ⇊ (Function.const γ b) = Function.const γ (a, b) := rfl + (Function.const ι a) ⇊ (Function.const ι b) = Function.const ι (a, b) := rfl -theorem const_prod {γ} {α β} {p : α × β} : - Function.const γ p = (Function.const γ p.1) ⇊ (Function.const γ p.2) := rfl +theorem const_prod {ι} {α β} {p : α × β} : + Function.const ι p = (Function.const ι p.1) ⇊ (Function.const ι p.2) := rfl end /-- `Function.prodMap` is `Prod.map` in the `Function` namespace. -/ -def prodMap (f : α → β) (g : δ → ε) := (f ∘ Prod.fst) ⇊ (g ∘ Prod.snd) +def prodMap (f : α → β) (g : γ → δ) := (f ∘ Prod.fst) ⇊ (g ∘ Prod.snd) @[simp, grind =] -theorem prodMap_eq_prod_map {f : α → β} {g : δ → ε} : f.prodMap g = Prod.map f g := rfl +theorem prodMap_eq_prod_map {f : α → β} {g : γ → δ} : f.prodMap g = Prod.map f g := rfl @[grind _=_] -theorem map_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} {c} : +theorem map_prod {f : α → β} {g : ι → α} {h : γ → δ} {k : ι → γ} {c} : Prod.map f h ((g ⇊ k) c) = ((f ∘ g) ⇊ (h ∘ k)) c := rfl -theorem map_comp_prod {f : α → β} {g : γ → α} {h : δ → ε} {k : γ → δ} : +theorem map_comp_prod {f : α → β} {g : ι → α} {h : γ → δ} {k : ι → γ} : Prod.map f h ∘ (g ⇊ k) = (f ∘ g) ⇊ (h ∘ k) := rfl /-- The diagonal map into `Prod`. -/ @@ -160,9 +160,9 @@ variable {a b : α} @[simp, grind =] theorem fst_diag : (⇗a).1 = a := rfl @[simp, grind =] theorem snd_diag : (⇗a).2 = a := rfl -@[simp, grind =] theorem map_diag {f : α → β} {g : α → δ} : Prod.map f g ⇗a = (f ⇊ g) a := rfl +@[simp, grind =] theorem map_diag {f : α → β} {g : α → γ} : Prod.map f g ⇗a = (f ⇊ g) a := rfl -@[simp] theorem map_comp_diag {f : α → β} {g : α → δ} : Prod.map f g ∘ Function.diag = f ⇊ g := rfl +@[simp] theorem map_comp_diag {f : α → β} {g : α → γ} : Prod.map f g ∘ Function.diag = f ⇊ g := rfl theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst diff --git a/Mathlib/Order/CompleteLattice/Basic.lean b/Mathlib/Order/CompleteLattice/Basic.lean index 2dc62513a3fddb..dc5474812fd98b 100644 --- a/Mathlib/Order/CompleteLattice/Basic.lean +++ b/Mathlib/Order/CompleteLattice/Basic.lean @@ -776,7 +776,7 @@ theorem biSup_prod' {f : β → γ → α} {s : Set β} {t : Set γ} : @[to_dual] theorem iSup_image2 {γ δ} (f : β → γ → δ) (s : Set β) (t : Set γ) (g : δ → α) : ⨆ d ∈ image2 f s t, g d = ⨆ b ∈ s, ⨆ c ∈ t, g (f b c) := by - rw [← image_prod, iSup_image, biSup_prod] + simp_rw [← image_uncurry_prod, iSup_image, biSup_prod, uncurry_apply] @[to_dual] theorem iSup_sum {f : β ⊕ γ → α} : ⨆ x, f x = (⨆ i, f (Sum.inl i)) ⊔ ⨆ j, f (Sum.inr j) := @@ -807,7 +807,8 @@ theorem iSup_ne_bot_subtype (f : ι → α) : ⨆ i : { i // f i ≠ ⊥ }, f i @[to_dual] theorem sSup_image2 {f : β → γ → α} {s : Set β} {t : Set γ} : - sSup (image2 f s t) = ⨆ (a ∈ s) (b ∈ t), f a b := by rw [← image_prod, sSup_image, biSup_prod] + sSup (image2 f s t) = ⨆ (a ∈ s) (b ∈ t), f a b := by + simp_rw [← image_uncurry_prod, sSup_image, biSup_prod, uncurry_apply] end diff --git a/Mathlib/Order/Filter/Prod.lean b/Mathlib/Order/Filter/Prod.lean index 0716d7359400c3..dbd4bd3fa38d5d 100644 --- a/Mathlib/Order/Filter/Prod.lean +++ b/Mathlib/Order/Filter/Prod.lean @@ -136,12 +136,12 @@ theorem Tendsto.snd {h : Filter γ} {m : α → β × γ} (H : Tendsto m f (g × Tendsto (fun a ↦ (m a).2) f h := tendsto_snd.comp H -theorem Tendsto.prodMk {h : Filter γ} {m₁ : α → β} {m₂ : α → γ} - (h₁ : Tendsto m₁ f g) (h₂ : Tendsto m₂ f h) : Tendsto (fun x => (m₁ x, m₂ x)) f (g ×ˢ h) := +theorem Tendsto.prod {h : Filter γ} {m₁ : α → β} {m₂ : α → γ} + (h₁ : Tendsto m₁ f g) (h₂ : Tendsto m₂ f h) : Tendsto (m₁ ⇊ m₂) f (g ×ˢ h) := tendsto_inf.2 ⟨tendsto_comap_iff.2 h₁, tendsto_comap_iff.2 h₂⟩ theorem tendsto_prod_swap : Tendsto (Prod.swap : α × β → β × α) (f ×ˢ g) (g ×ˢ f) := - tendsto_snd.prodMk tendsto_fst + tendsto_snd.prod tendsto_fst theorem Eventually.prod_inl {la : Filter α} {p : α → Prop} (h : ∀ᶠ x in la, p x) (lb : Filter β) : ∀ᶠ x in la ×ˢ lb, p (x : α × β).1 := @@ -293,13 +293,16 @@ lemma Eventually.trans_prod {h : Filter γ} theorem prod_assoc (f : Filter α) (g : Filter β) (h : Filter γ) : map (Equiv.prodAssoc α β γ) ((f ×ˢ g) ×ˢ h) = f ×ˢ (g ×ˢ h) := by - simp_rw [← comap_equiv_symm, prod_eq_inf, comap_inf, comap_comap, inf_assoc, - Function.comp_def, Equiv.prodAssoc_symm_apply] + unfold Equiv.prodAssoc + simp only [prod_eq_inf, comap_inf, comap_comap, inf_assoc, map_inf (Equiv.injective _), + ← comap_equiv_symm, comap_comap, Equiv.coe_fn_symm_mk, Function.comp_assoc, + Function.fst_comp_prod, Function.snd_comp_prod] theorem prod_assoc_symm (f : Filter α) (g : Filter β) (h : Filter γ) : map (Equiv.prodAssoc α β γ).symm (f ×ˢ (g ×ˢ h)) = (f ×ˢ g) ×ˢ h := by - simp_rw [map_equiv_symm, prod_eq_inf, comap_inf, comap_comap, inf_assoc, - Function.comp_def, Equiv.prodAssoc_apply] + unfold Equiv.prodAssoc + simp only [map_equiv_symm, Equiv.coe_fn_mk, prod_eq_inf, comap_inf, comap_comap, inf_assoc, + Function.comp_assoc, Function.fst_comp_prod, Function.snd_comp_prod] theorem tendsto_prodAssoc {h : Filter γ} : Tendsto (Equiv.prodAssoc α β γ) ((f ×ˢ g) ×ˢ h) (f ×ˢ (g ×ˢ h)) := @@ -328,7 +331,7 @@ theorem prod_map_map_eq.{u, v, w, x} {α₁ : Type u} {α₂ : Type v} {β₁ : let ⟨s₁, hs₁, s₂, hs₂, h⟩ := mem_prod_iff.mp hs mem_of_superset (prod_mem_prod (image_mem_map hs₁) (image_mem_map hs₂)) <| by rwa [prod_image_image_eq, image_subset_iff]) - ((tendsto_map.comp tendsto_fst).prodMk (tendsto_map.comp tendsto_snd)) + ((tendsto_map.comp tendsto_fst).prod (tendsto_map.comp tendsto_snd)) theorem prod_map_map_eq' {α₁ : Type*} {α₂ : Type*} {β₁ : Type*} {β₂ : Type*} (f : α₁ → α₂) (g : β₁ → β₂) (F : Filter α₁) (G : Filter β₁) : diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 40261b411fb1f8..85eee786978f53 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -894,7 +894,7 @@ def prodComm : α × β ≃o β × α where def prodAssoc (α β γ : Type*) [LE α] [LE β] [LE γ] : (α × β) × γ ≃o α × (β × γ) where toEquiv := .prodAssoc α β γ - map_rel_iff' := @fun ⟨⟨_, _⟩, _⟩ ⟨⟨_, _⟩, _⟩ ↦ by simp [Equiv.prodAssoc, and_assoc] + map_rel_iff' := @fun ⟨⟨_, _⟩, _⟩ ⟨⟨_, _⟩, _⟩ ↦ by simp [and_assoc, Prod.le_def] @[simp] theorem coe_prodComm : ⇑(prodComm : α × β ≃o β × α) = Prod.swap := diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index 61f2892ac28fe7..71efd85366fd64 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -448,7 +448,7 @@ theorem ωSup_zip (c₀ : Chain α) (c₁ : Chain β) : ωSup (c₀.zip c₁) = @[fun_prop] lemma ωScottContinuous.prodMk {f : α → β} (hf : ωScottContinuous f) {g : α → γ} (hg : ωScottContinuous g) : - ωScottContinuous f ⇊ g := + ωScottContinuous (f ⇊ g) := ScottContinuousOn.prodMk (fun a b hab ↦ ⟨pair a b hab, range_pair a b hab⟩) hf hg @[fun_prop] diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index 978f0388a4aca3..aa3a339749c7cf 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -60,93 +60,96 @@ variable [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z] [Topolog [TopologicalSpace ε] [TopologicalSpace ζ] @[simp] -theorem continuous_prodMk {f : X → Y} {g : X → Z} : - (Continuous Function.prod f g) ↔ Continuous f ∧ Continuous g := +theorem continuous_prod {f : X → Y} {g : X → Z} : + (Continuous (f ⇊ g)) ↔ Continuous f ∧ Continuous g := continuous_inf_rng.trans <| continuous_induced_rng.and continuous_induced_rng +@[continuity, fun_prop] +theorem Continuous.prod {f : Z → X} {g : Z → Y} (hf : Continuous f) (hg : Continuous g) : + Continuous (f ⇊ g) := continuous_prod.2 ⟨hf, hg⟩ + +@[continuity, fun_prop] +theorem Continuous.fst_of_prod {f : Z → X} {g : Z → Y} (hfg : Continuous (f ⇊ g)) : + Continuous f := (continuous_prod.1 hfg).1 + +@[continuity, fun_prop] +theorem Continuous.snd_of_prod {f : Z → X} {g : Z → Y} (hfg : Continuous (f ⇊ g)) : + Continuous g := (continuous_prod.1 hfg).2 + +@[continuity, fun_prop] +theorem continuous_fst : Continuous (@Prod.fst X Y) := continuous_id.fst_of_prod + +@[continuity, fun_prop] +theorem continuous_snd : Continuous (@Prod.snd X Y) := continuous_id.snd_of_prod + +@[continuity, fun_prop] +theorem Continuous.prodMk : + Continuous (Prod.mk.uncurry (α := X) (β := Y)) := continuous_fst.prod continuous_snd + @[continuity] -theorem continuous_fst : Continuous (@Prod.fst X Y) := - (continuous_prodMk.1 continuous_id).1 +theorem Continuous.prod_right (x : X) : Continuous (Prod.mk (β := Y) x) := + Continuous.prodMk.comp (continuous_const.prod continuous_id) + +@[continuity] +theorem Continuous.prod_left (y : Y) : Continuous (Prod.mk (α := X) · y) := + Continuous.prodMk.comp (continuous_id.prod continuous_const) /-- Postcomposing `f` with `Prod.fst` is continuous -/ @[fun_prop] -theorem Continuous.fst {f : X → Y × Z} (hf : Continuous f) : Continuous fun x : X => (f x).1 := - continuous_fst.comp hf +theorem Continuous.fst {f : X → Y × Z} (hf : Continuous f) : Continuous (Prod.fst ∘ f) := by + fun_prop /-- Precomposing `f` with `Prod.fst` is continuous -/ -theorem Continuous.fst' {f : X → Z} (hf : Continuous f) : Continuous fun x : X × Y => f x.fst := - hf.comp continuous_fst +theorem Continuous.fst' {f : X → Z} (hf : Continuous f) : Continuous (f ∘ Prod.fst (β := Y)) := by + fun_prop -theorem continuousAt_fst {p : X × Y} : ContinuousAt Prod.fst p := - continuous_fst.continuousAt +theorem continuousAt_fst {p : X × Y} : ContinuousAt Prod.fst p := by fun_prop /-- Postcomposing `f` with `Prod.fst` is continuous at `x` -/ @[fun_prop] theorem ContinuousAt.fst {f : X → Y × Z} {x : X} (hf : ContinuousAt f x) : - ContinuousAt (fun x : X => (f x).1) x := - continuousAt_fst.comp hf + ContinuousAt (Prod.fst ∘ f) x := by fun_prop /-- Precomposing `f` with `Prod.fst` is continuous at `(x, y)` -/ theorem ContinuousAt.fst' {f : X → Z} {x : X} {y : Y} (hf : ContinuousAt f x) : - ContinuousAt (fun x : X × Y => f x.fst) (x, y) := - ContinuousAt.comp hf continuousAt_fst + ContinuousAt (f ∘ Prod.fst) (x, y) := by fun_prop /-- Precomposing `f` with `Prod.fst` is continuous at `x : X × Y` -/ theorem ContinuousAt.fst'' {f : X → Z} {x : X × Y} (hf : ContinuousAt f x.fst) : - ContinuousAt (fun x : X × Y => f x.fst) x := - hf.comp continuousAt_fst + ContinuousAt (f ∘ Prod.fst) x := by fun_prop theorem Filter.Tendsto.fst_nhds {X} {l : Filter X} {f : X → Y × Z} {p : Y × Z} - (h : Tendsto f l (𝓝 p)) : Tendsto (fun a ↦ (f a).1) l (𝓝 <| p.1) := + (h : Tendsto f l (𝓝 p)) : Tendsto (Prod.fst ∘ f) l (𝓝 <| p.1) := continuousAt_fst.tendsto.comp h -@[continuity] -theorem continuous_snd : Continuous (@Prod.snd X Y) := - (continuous_prodMk.1 continuous_id).2 - /-- Postcomposing `f` with `Prod.snd` is continuous -/ @[fun_prop] -theorem Continuous.snd {f : X → Y × Z} (hf : Continuous f) : Continuous fun x : X => (f x).2 := - continuous_snd.comp hf +theorem Continuous.snd {f : X → Y × Z} (hf : Continuous f) : Continuous (Prod.snd ∘ f) := by + fun_prop /-- Precomposing `f` with `Prod.snd` is continuous -/ -theorem Continuous.snd' {f : Y → Z} (hf : Continuous f) : Continuous fun x : X × Y => f x.snd := - hf.comp continuous_snd +theorem Continuous.snd' {f : Y → Z} (hf : Continuous f) : Continuous (f ∘ Prod.snd (α := X)) := by + fun_prop -theorem continuousAt_snd {p : X × Y} : ContinuousAt Prod.snd p := - continuous_snd.continuousAt +theorem continuousAt_snd {p : X × Y} : ContinuousAt Prod.snd p := by fun_prop /-- Postcomposing `f` with `Prod.snd` is continuous at `x` -/ @[fun_prop] theorem ContinuousAt.snd {f : X → Y × Z} {x : X} (hf : ContinuousAt f x) : - ContinuousAt (fun x : X => (f x).2) x := - continuousAt_snd.comp hf + ContinuousAt (Prod.snd ∘ f) x := by fun_prop /-- Precomposing `f` with `Prod.snd` is continuous at `(x, y)` -/ theorem ContinuousAt.snd' {f : Y → Z} {x : X} {y : Y} (hf : ContinuousAt f y) : - ContinuousAt (fun x : X × Y => f x.snd) (x, y) := - ContinuousAt.comp hf continuousAt_snd + ContinuousAt (f ∘ Prod.snd) (x, y) := by fun_prop /-- Precomposing `f` with `Prod.snd` is continuous at `x : X × Y` -/ theorem ContinuousAt.snd'' {f : Y → Z} {x : X × Y} (hf : ContinuousAt f x.snd) : - ContinuousAt (fun x : X × Y => f x.snd) x := - hf.comp continuousAt_snd + ContinuousAt (f ∘ Prod.snd) x := by fun_prop theorem Filter.Tendsto.snd_nhds {X} {l : Filter X} {f : X → Y × Z} {p : Y × Z} - (h : Tendsto f l (𝓝 p)) : Tendsto (fun a ↦ (f a).2) l (𝓝 <| p.2) := + (h : Tendsto f l (𝓝 p)) : Tendsto (Prod.snd ∘ f) l (𝓝 <| p.2) := continuousAt_snd.tendsto.comp h -@[continuity, fun_prop] -theorem Continuous.prodMk {f : Z → X} {g : Z → Y} (hf : Continuous f) (hg : Continuous g) : - Continuous Function.prod f g := - continuous_prodMk.2 ⟨hf, hg⟩ - -@[continuity] -theorem Continuous.prodMk_right (x : X) : Continuous fun y : Y => (x, y) := by fun_prop - -@[continuity] -theorem Continuous.prodMk_left (y : Y) : Continuous fun x : X => (x, y) := by fun_prop - /-- If `f x y` is continuous in `x` for all `y ∈ s`, then the set of `x` such that `f x` maps `s` to `t` is closed. -/ lemma IsClosed.setOf_mapsTo {α : Type*} {f : X → α → Z} {s : Set α} {t : Set Z} (ht : IsClosed t) @@ -155,22 +158,22 @@ lemma IsClosed.setOf_mapsTo {α : Type*} {f : X → α → Z} {s : Set α} {t : theorem Continuous.comp₂ {g : X × Y → Z} (hg : Continuous g) {e : W → X} (he : Continuous e) {f : W → Y} (hf : Continuous f) : Continuous fun w => g (e w, f w) := - hg.comp <| he.prodMk hf + hg.comp <| he.prod hf theorem Continuous.comp₃ {g : X × Y × Z → ε} (hg : Continuous g) {e : W → X} (he : Continuous e) {f : W → Y} (hf : Continuous f) {k : W → Z} (hk : Continuous k) : Continuous fun w => g (e w, f w, k w) := - hg.comp₂ he <| hf.prodMk hk + hg.comp₂ he <| hf.prod hk theorem Continuous.comp₄ {g : X × Y × Z × ζ → ε} (hg : Continuous g) {e : W → X} (he : Continuous e) {f : W → Y} (hf : Continuous f) {k : W → Z} (hk : Continuous k) {l : W → ζ} (hl : Continuous l) : Continuous fun w => g (e w, f w, k w, l w) := - hg.comp₃ he hf <| hk.prodMk hl + hg.comp₃ he hf <| hk.prod hl @[continuity, fun_prop] theorem Continuous.prodMap {f : Z → X} {g : W → Y} (hf : Continuous f) (hg : Continuous g) : Continuous (Prod.map f g) := - hf.fst'.prodMk hg.snd' + hf.fst'.prod hg.snd' /-- A version of `continuous_inf_dom_left` for binary functions -/ theorem continuous_inf_dom_left₂ {X Y Z} {f : X → Y → Z} {ta1 ta2 : TopologicalSpace X} @@ -212,13 +215,13 @@ theorem Filter.Eventually.prod_inr_nhds {p : Y → Prop} {y : Y} (h : ∀ᶠ x i ∀ᶠ x in 𝓝 (x, y), p (x : X × Y).2 := continuousAt_snd h -theorem Filter.Eventually.prodMk_nhds {px : X → Prop} {x} (hx : ∀ᶠ x in 𝓝 x, px x) {py : Y → Prop} +theorem Filter.Eventually.prod_nhds {px : X → Prop} {x} (hx : ∀ᶠ x in 𝓝 x, px x) {py : Y → Prop} {y} (hy : ∀ᶠ y in 𝓝 y, py y) : ∀ᶠ p in 𝓝 (x, y), px (p : X × Y).1 ∧ py p.2 := (hx.prod_inl_nhds y).and (hy.prod_inr_nhds x) @[fun_prop] theorem continuous_swap : Continuous (Prod.swap : X × Y → Y × X) := - continuous_snd.prodMk continuous_fst + continuous_snd.prod continuous_fst lemma isClosedMap_swap : IsClosedMap (Prod.swap : X × Y → Y × X) := fun s hs ↦ by rw [image_swap_eq_preimage_swap] @@ -226,11 +229,11 @@ lemma isClosedMap_swap : IsClosedMap (Prod.swap : X × Y → Y × X) := fun s hs theorem Continuous.uncurry_left {f : X → Y → Z} (x : X) (h : Continuous (uncurry f)) : Continuous (f x) := - h.comp (.prodMk_right _) + h.comp (.prod_right _) theorem Continuous.uncurry_right {f : X → Y → Z} (y : Y) (h : Continuous (uncurry f)) : Continuous fun a => f a y := - h.comp (.prodMk_left _) + h.comp (.prod_left _) theorem continuous_curry {g : X × Y → Z} (x : X) (h : Continuous g) : Continuous (curry g x) := Continuous.uncurry_left x h @@ -307,7 +310,7 @@ theorem isOpen_setOf_disjoint_nhds_nhds : IsOpen { p : X × X | Disjoint (𝓝 p exact mem_nhds_prod_iff'.mpr ⟨U, V, hU.2, hU.1, hV.2, hV.1, fun ⟨x', y'⟩ ⟨hx', hy'⟩ => disjoint_of_disjoint_of_mem hd (hU.2.mem_nhds hx') (hV.2.mem_nhds hy')⟩ -theorem Filter.Eventually.prod_nhds {p : X → Prop} {q : Y → Prop} {x : X} {y : Y} +theorem Filter.Eventually.prodMk_nhds {p : X → Prop} {q : Y → Prop} {x : X} {y : Y} (hx : ∀ᶠ x in 𝓝 x, p x) (hy : ∀ᶠ y in 𝓝 y, q y) : ∀ᶠ z : X × Y in 𝓝 (x, y), p z.1 ∧ q z.2 := prod_mem_nhds hx hy @@ -326,11 +329,11 @@ theorem Filter.EventuallyLE.prodMap_nhds {α β : Type*} [LE α] [LE β] {f₁ f theorem nhds_swap (x : X) (y : Y) : 𝓝 (x, y) = (𝓝 (y, x)).map Prod.swap := by rw [nhds_prod_eq, Filter.prod_comm, nhds_prod_eq] -theorem Filter.Tendsto.prodMk_nhds {γ} {x : X} {y : Y} {f : Filter γ} {mx : γ → X} {my : γ → Y} +theorem Filter.Tendsto.prod_nhds {γ} {x : X} {y : Y} {f : Filter γ} {mx : γ → X} {my : γ → Y} (hx : Tendsto mx f (𝓝 x)) (hy : Tendsto my f (𝓝 y)) : Tendsto (fun c => (mx c, my c)) f (𝓝 (x, y)) := by rw [nhds_prod_eq] - exact hx.prodMk hy + exact hx.prod hy theorem Filter.Tendsto.prodMap_nhds {x : X} {y : Y} {z : Z} {w : W} {f : X → Y} {g : Z → W} (hf : Tendsto f (𝓝 x) (𝓝 y)) (hg : Tendsto g (𝓝 z) (𝓝 w)) : @@ -344,13 +347,13 @@ theorem Filter.Eventually.curry_nhds {p : X × Y → Prop} {x : X} {y : Y} exact h.curry @[fun_prop] -theorem ContinuousAt.prodMk {f : X → Y} {g : X → Z} {x : X} (hf : ContinuousAt f x) +theorem ContinuousAt.prod {f : X → Y} {g : X → Z} {x : X} (hf : ContinuousAt f x) (hg : ContinuousAt g x) : ContinuousAt (Function.prod f g) x := - hf.prodMk_nhds hg + hf.prod_nhds hg theorem ContinuousAt.prodMap {f : X → Z} {g : Y → W} {p : X × Y} (hf : ContinuousAt f p.fst) (hg : ContinuousAt g p.snd) : ContinuousAt (Prod.map f g) p := - hf.fst''.prodMk hg.snd'' + hf.fst''.prod hg.snd'' /-- A version of `ContinuousAt.prodMap` that avoids `Prod.fst`/`Prod.snd` by assuming that the point is `(x, y)`. -/ @@ -361,7 +364,7 @@ theorem ContinuousAt.prodMap' {f : X → Z} {g : Y → W} {x : X} {y : Y} (hf : theorem ContinuousAt.comp₂ {f : Y × Z → W} {g : X → Y} {h : X → Z} {x : X} (hf : ContinuousAt f (g x, h x)) (hg : ContinuousAt g x) (hh : ContinuousAt h x) : ContinuousAt (fun x ↦ f (g x, h x)) x := - ContinuousAt.comp hf (hg.prodMk hh) + ContinuousAt.comp hf (hg.prod hh) theorem ContinuousAt.comp₂_of_eq {f : Y × Z → W} {g : X → Y} {h : X → Z} {x : X} {y : Y × Z} (hf : ContinuousAt f y) (hg : ContinuousAt g x) (hh : ContinuousAt h x) (e : (g x, h x) = y) : @@ -372,13 +375,13 @@ theorem ContinuousAt.comp₂_of_eq {f : Y × Z → W} {g : X → Y} {h : X → Z /-- Continuous functions on products are continuous in their first argument -/ theorem Continuous.curry_left {f : X × Y → Z} (hf : Continuous f) {y : Y} : Continuous fun x ↦ f (x, y) := - hf.comp (.prodMk_left _) + hf.comp (.prod_left _) alias Continuous.along_fst := Continuous.curry_left /-- Continuous functions on products are continuous in their second argument -/ theorem Continuous.curry_right {f : X × Y → Z} (hf : Continuous f) {x : X} : Continuous fun y ↦ f (x, y) := - hf.comp (.prodMk_right _) + hf.comp (.prod_right _) alias Continuous.along_snd := Continuous.curry_right -- todo: prove a version of `generateFrom_union` with `image2 (∩) s t` in the LHS and use it here @@ -572,10 +575,10 @@ lemma Topology.isInducing_prod_const {y : Y} {f : X → Z} : Function.comp_def, induced_const, inf_top_eq] lemma isInducing_prodMkLeft (y : Y) : IsInducing (fun x : X ↦ (x, y)) := - .of_comp (.prodMk_left y) continuous_fst .id + .of_comp (.prod_left y) continuous_fst .id lemma isInducing_prodMkRight (x : X) : IsInducing (Prod.mk x : Y → X × Y) := - .of_comp (.prodMk_right x) continuous_snd .id + .of_comp (.prod_right x) continuous_snd .id lemma Topology.IsEmbedding.prodMap {f : X → Y} {g : Z → W} (hf : IsEmbedding f) (hg : IsEmbedding g) : IsEmbedding (Prod.map f g) where @@ -594,13 +597,13 @@ protected lemma Topology.IsOpenEmbedding.prodMap {f : X → Y} {g : Z → W} (hf .of_isEmbedding_isOpenMap (hf.1.prodMap hg.1) (hf.isOpenMap.prodMap hg.isOpenMap) lemma isEmbedding_graph {f : X → Y} (hf : Continuous f) : IsEmbedding fun x => (x, f x) := - .of_comp (continuous_id.prodMk hf) continuous_fst .id + .of_comp (continuous_id.prod hf) continuous_fst .id lemma isEmbedding_prodMkLeft (y : Y) : IsEmbedding (fun x : X ↦ (x, y)) := - .of_comp (.prodMk_left y) continuous_fst .id + .of_comp (.prod_left y) continuous_fst .id lemma isEmbedding_prodMkRight (x : X) : IsEmbedding (Prod.mk x : Y → X × Y) := - .of_comp (.prodMk_right x) continuous_snd .id + .of_comp (.prod_right x) continuous_snd .id theorem IsOpenQuotientMap.prodMap {f : X → Y} {g : Z → W} (hf : IsOpenQuotientMap f) (hg : IsOpenQuotientMap g) : IsOpenQuotientMap (Prod.map f g) := diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index 3fd8a7584bf559..8ca5185671be67 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -500,7 +500,7 @@ theorem Filter.Tendsto.uniformity_trans {l : Filter β} {f₁ f₂ f₃ : β → /-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is symmetric. -/ theorem Filter.Tendsto.uniformity_symm {l : Filter β} {f : β → α × α} (h : Tendsto f l (𝓤 α)) : - Tendsto (Prod.swap ∘ Function.diag ∘ f) l (𝓤 α) := + Tendsto (Prod.swap ∘ f) l (𝓤 α) := tendsto_swap_uniformity.comp h /-- Relation `fun f g ↦ Tendsto (f ⇊ g) l (𝓤 α)` is reflexive. -/ @@ -831,9 +831,9 @@ theorem uniformContinuousOn_univ {f : α → β} : theorem uniformContinuous_of_const {c : α → β} (h : ∀ a b, c a = c b) : UniformContinuous c := - have : (fun x : α × α => (c x.fst, c x.snd)) ⁻¹' SetRel.id = univ := - eq_univ_iff_forall.2 fun ⟨a, b⟩ => h a b - le_trans (map_le_iff_le_comap.2 <| by simp [comap_principal, this]) refl_le_uniformity + have H : Prod.map.uncurry ⇗c ⁻¹' SetRel.id = univ := eq_univ_iff_forall.2 (by simpa using h) + (le_principal_iff.mpr <| mem_map.mpr <| Set.mem_of_eq_of_mem H Filter.univ_mem).trans + refl_le_uniformity theorem uniformContinuous_id : UniformContinuous (@id α) := tendsto_id @@ -856,7 +856,8 @@ theorem Filter.HasBasis.uniformContinuous_iff {ι'} {p : ι → Prop} {s : ι → SetRel α α} (ha : (𝓤 α).HasBasis p s) {q : ι' → Prop} {t : ι' → Set (β × β)} (hb : (𝓤 β).HasBasis q t) {f : α → β} : UniformContinuous f ↔ ∀ i, q i → ∃ j, p j ∧ ∀ x y, (x, y) ∈ s j → (f x, f y) ∈ t i := - (ha.tendsto_iff hb).trans <| by simp only [Prod.forall] + (ha.tendsto_iff hb).trans <| by simp only [Function.uncurry_apply, Function.fst_diag, + Function.snd_diag, Prod.forall, Prod.map_apply] theorem Filter.HasBasis.uniformContinuousOn_iff {ι'} {p : ι → Prop} {s : ι → SetRel α α} (ha : (𝓤 α).HasBasis p s) {q : ι' → Prop} {t : ι' → Set (β × β)} @@ -864,7 +865,8 @@ theorem Filter.HasBasis.uniformContinuousOn_iff {ι'} {p : ι → Prop} UniformContinuousOn f S ↔ ∀ i, q i → ∃ j, p j ∧ ∀ x, x ∈ S → ∀ y, y ∈ S → (x, y) ∈ s j → (f x, f y) ∈ t i := ((ha.inf_principal (S ×ˢ S)).tendsto_iff hb).trans <| by - simp_rw [Prod.forall, Set.inter_comm (s _), forall_mem_comm, mem_inter_iff, mem_prod, and_imp] + simp_rw [Set.inter_comm (s _), mem_inter_iff, mem_prod, Function.uncurry_apply, + Function.fst_diag, Function.snd_diag, and_imp, Prod.forall, Prod.map_apply, forall_mem_comm] /-- A map `f : α → β` between uniform spaces is called *uniform inducing* if the uniformity filter on `α` is the pullback of the uniformity filter on `β` under `Prod.map f f`. If `α` is a separated From 965ff01debe3ce2619bb950e35015a90d736c93c Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 16:13:59 +0100 Subject: [PATCH 33/35] Small tweak --- Mathlib/Logic/Function/Init.lean | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean index 2ed8ac82916f7c..b10bfb4442d606 100644 --- a/Mathlib/Logic/Function/Init.lean +++ b/Mathlib/Logic/Function/Init.lean @@ -26,8 +26,8 @@ upstreamed to Batteries or the Lean standard library easily. namespace Pi /-- The mapping into a product type built from maps into each component. -/ -protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) : ∀ i, α i × β i := - fun i ↦ (f i, g i) +protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : α i × β i := + Prod.mk (f i) (g i) @[inherit_doc] infixr:65 " ⇊' " => Pi.prod @@ -78,7 +78,7 @@ namespace Function variable {α β γ δ : Type*} {ι : Sort*} /-- This is the pairing operation on functions, dual to `Sum.elim`. -/ -protected def prod (f : ι → α) (g : ι → β) : ι → α × β := f ⇊' g +protected def prod : (ι → α) → (ι → β) → ι → α × β := (· ⇊' ·) @[inherit_doc] infixr:65 " ⇊ " => Function.prod @@ -176,4 +176,5 @@ theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ end + end Function From 1720cfdbe3d9bc246707ced88c1fea2f630c9f31 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 16:15:37 +0100 Subject: [PATCH 34/35] Simply add the new functions --- Mathlib.lean | 1 + Mathlib/Logic/Function/Init.lean | 180 +++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 Mathlib/Logic/Function/Init.lean diff --git a/Mathlib.lean b/Mathlib.lean index 896c561fa97d3c..ed5cd718e178b1 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5117,6 +5117,7 @@ public import Mathlib.Logic.Function.Defs public import Mathlib.Logic.Function.DependsOn public import Mathlib.Logic.Function.FiberPartition public import Mathlib.Logic.Function.FromTypes +public import Mathlib.Logic.Function.Init public import Mathlib.Logic.Function.Iterate public import Mathlib.Logic.Function.OfArity public import Mathlib.Logic.Function.ULift diff --git a/Mathlib/Logic/Function/Init.lean b/Mathlib/Logic/Function/Init.lean new file mode 100644 index 00000000000000..b10bfb4442d606 --- /dev/null +++ b/Mathlib/Logic/Function/Init.lean @@ -0,0 +1,180 @@ +/- +Copyright (c) 2026 Wrenna Robson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Wrenna Robson +-/ +module + +public import Mathlib.Init + +/-! + +This file defines `(f ⇊ g)`, the operation that pairs two functions `f : ι → α` and +`g : ι → β` into a function `ι → α × β`. + +It also defines the special case when `f = g = id`, `Function.diag`. This is the canonical injection +of a type into its prouduct with itself onto its diagonal. + + +This file should not depend on anything defined in Mathlib (except for notation), so that it can be +upstreamed to Batteries or the Lean standard library easily. + +-/ + +@[expose] public section + +namespace Pi + +/-- The mapping into a product type built from maps into each component. -/ +protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : α i × β i := + Prod.mk (f i) (g i) + +@[inherit_doc] infixr:65 " ⇊' " => Pi.prod + +section + +variable {ι} {α β : ι → Type*} (f f' : ∀ i, α i) (g g' : ∀ i, β i) {c} + +@[grind =] theorem prod_apply : (f ⇊' g) c = (f c, g c) := rfl + +@[simp] theorem fst_prod : ((f ⇊' g) c).fst = f c := rfl +@[simp] theorem snd_prod : ((f ⇊' g) c).snd = g c := rfl + +@[simp] theorem prod_fst_snd {α β} : (Prod.fst : _ → α) ⇊' (Prod.snd : _ → β) = id := rfl +@[simp] theorem prod_snd_fst {α β} : (Prod.snd : _ → β) ⇊' (Prod.fst : _ → α) = .swap := rfl + +theorem prod_fst_snd_comp {h : ∀ i, α i × β i} : + (Prod.fst <| h ·) ⇊' (Prod.snd <| h ·) = h := rfl + +theorem fst_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.fst <| (f ⇊' g) ·) = f := rfl +theorem snd_comp_prod {f : ∀ i, α i} {g : ∀ i, β i} : (Prod.snd <| (f ⇊' g) ·) = g := rfl + +@[simp] +theorem prod_eq_iff {f : ∀ i, α i} {g : ∀ i, β i} : + f ⇊' g = f' ⇊' g' ↔ f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] + +theorem prod_ext_iff {h h' : ∀ i, α i × β i} : h = h' ↔ + (Prod.fst <| h ·) = (Prod.fst <| h' ·) ∧ (Prod.snd <| h ·) = (Prod.snd <| h' ·) := by + simp [funext_iff, Prod.ext_iff, forall_and] + +theorem exists_prod_apply_eq (h : ∀ i, α i × β i) : ∃ f g, (f ⇊' g) = h := + ⟨(Prod.fst <| h ·), (Prod.snd <| h ·), prod_fst_snd_comp⟩ + +theorem exists_fst_comp (f : ∀ i, α i) (g : ∀ i, β i) : + ∃ h : ∀ i, α i × β i, (Prod.fst <| h ·) = f := ⟨(f ⇊' g), fst_comp_prod⟩ +theorem exists_snd_comp (f : ∀ i, α i) (g : ∀ i, β i) : + ∃ h : ∀ i, α i × β i, (Prod.snd <| h ·) = g := ⟨(f ⇊' g), snd_comp_prod⟩ + +@[grind =] +theorem prod_const_const {ι} {α β} {a : α} {b : β} : + (Function.const ι a) ⇊' (Function.const ι b) = Function.const ι (a, b) := rfl + +end + +end Pi + +namespace Function + +variable {α β γ δ : Type*} {ι : Sort*} + +/-- This is the pairing operation on functions, dual to `Sum.elim`. -/ +protected def prod : (ι → α) → (ι → β) → ι → α × β := (· ⇊' ·) + +@[inherit_doc] infixr:65 " ⇊ " => Function.prod + +section + +variable (f : ι → α) (g : ι → β) + +@[grind =] theorem prod_apply (c : ι) : (f.prod g) c = (f c, g c) := rfl + +theorem prod_comp {γ} {h : γ → ι} : (f ⇊ g) ∘ h = (f ∘ h) ⇊ (g ∘ h) := rfl + +@[simp] theorem fst_prod {c} : ((f ⇊ g) c).fst = f c := rfl +@[simp] theorem snd_prod {c} : ((f ⇊ g) c).snd = g c := rfl + +@[simp] theorem prod_fst_snd : Prod.fst (α := α) ⇊ Prod.snd (β := β) = id := rfl +@[simp] theorem prod_snd_fst : Prod.snd (β := β) ⇊ Prod.fst (α := α) = .swap := rfl + +@[simp] theorem prod_fst_snd_comp {f : ι → α × β} : (Prod.fst ∘ f) ⇊ (Prod.snd ∘ f) = f := rfl + +@[simp] theorem fst_comp_prod {f : ι → α} {g : ι → β} : Prod.fst ∘ (f ⇊ g) = f := rfl +@[simp] theorem snd_comp_prod {f : ι → α} {g : ι → β} : Prod.snd ∘ (f ⇊ g) = g := rfl + +theorem prod_eq_iff {f f' : ι → α} {g g' : ι → β} : f ⇊ g = f' ⇊ g' ↔ + f = f' ∧ g = g' := by simp [funext_iff, Prod.ext_iff, forall_and] + +theorem prod_ext_iff {h h' : ι → α × β} : h = h' ↔ + Prod.fst ∘ h = Prod.fst ∘ h' ∧ Prod.snd ∘ h = (Prod.snd ∘ h') := by + simp [funext_iff, Prod.ext_iff, forall_and] + +theorem exists_prod_apply_eq (h : ι → α × β) : ∃ f g, f ⇊ g = h := + ⟨Prod.fst ∘ h, Prod.snd ∘ h, prod_fst_snd_comp⟩ + +theorem exists_fst_comp (f : ι → α) (g : ι → β) : + ∃ h : ι → α × β, Prod.fst ∘ h = f := ⟨f ⇊ g, fst_comp_prod⟩ +theorem exists_snd_comp (f : ι → α) (g : ι → β) : + ∃ h : ι → α × β, Prod.snd ∘ h = g := ⟨f ⇊ g, snd_comp_prod⟩ + +theorem leftInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.LeftInverse + (Function.prod (ι := γ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := + fun _ => rfl + +theorem rightInverse_uncurry_prod_prod_fst_comp_snd_comp : Function.RightInverse + (Function.prod (ι := γ)).uncurry ((Prod.fst (α := α) ∘ ·) ⇊ (Prod.snd (β := β) ∘ ·)) := + fun _ => rfl + +@[grind =] +theorem prod_const_const (a : α) (b : β) : + (Function.const ι a) ⇊ (Function.const ι b) = Function.const ι (a, b) := rfl + +theorem const_prod {ι} {α β} {p : α × β} : + Function.const ι p = (Function.const ι p.1) ⇊ (Function.const ι p.2) := rfl + +end + +/-- `Function.prodMap` is `Prod.map` in the `Function` namespace. -/ +def prodMap (f : α → β) (g : γ → δ) := (f ∘ Prod.fst) ⇊ (g ∘ Prod.snd) + +@[simp, grind =] +theorem prodMap_eq_prod_map {f : α → β} {g : γ → δ} : f.prodMap g = Prod.map f g := rfl + +@[grind _=_] +theorem map_prod {f : α → β} {g : ι → α} {h : γ → δ} {k : ι → γ} {c} : + Prod.map f h ((g ⇊ k) c) = ((f ∘ g) ⇊ (h ∘ k)) c := rfl + +theorem map_comp_prod {f : α → β} {g : ι → α} {h : γ → δ} {k : ι → γ} : + Prod.map f h ∘ (g ⇊ k) = (f ∘ g) ⇊ (h ∘ k) := rfl + +/-- The diagonal map into `Prod`. -/ +protected def diag : α → α × α := id ⇊ id + +@[inherit_doc] prefix:max "⇗" => Function.diag + +section + +variable {a b : α} + +@[grind =] theorem diag_apply : ⇗a = (a, a) := rfl + +@[simp, grind =] theorem fst_diag : (⇗a).1 = a := rfl +@[simp, grind =] theorem snd_diag : (⇗a).2 = a := rfl + +@[simp, grind =] theorem map_diag {f : α → β} {g : α → γ} : Prod.map f g ⇗a = (f ⇊ g) a := rfl + +@[simp] theorem map_comp_diag {f : α → β} {g : α → γ} : Prod.map f g ∘ Function.diag = f ⇊ g := rfl + +theorem injective_diag : Function.Injective (α := α) Function.diag := fun _ _ => congrArg Prod.fst + +@[simp] theorem exists_diag_apply_iff (p : α × α) : (∃ a, ⇗a = p) ↔ p.1 = p.2 := by + simp [Prod.ext_iff, eq_comm] + +@[simp] theorem diag_eq_iff : ⇗a = ⇗b ↔ a = b := injective_diag.eq_iff + +@[simp] theorem prod_diag_diag : Function.diag ⇊ Function.diag (α := α) = + Function.diag ∘ Function.diag := rfl + +end + + +end Function From 81d11ca2a12fa1a5a5281b3d452605be2cd6fc6a Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 4 Apr 2026 16:17:18 +0100 Subject: [PATCH 35/35] Remove old Pi.prod --- Mathlib/Algebra/Notation/Pi/Defs.lean | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Mathlib/Algebra/Notation/Pi/Defs.lean b/Mathlib/Algebra/Notation/Pi/Defs.lean index 56fb6e87726968..68580139f65f3e 100644 --- a/Mathlib/Algebra/Notation/Pi/Defs.lean +++ b/Mathlib/Algebra/Notation/Pi/Defs.lean @@ -26,14 +26,6 @@ variable {ι α β : Type*} {G M R : ι → Type*} namespace Pi --- TODO: Do we really need this definition? If so, where to put it? -/-- The mapping into a product type built from maps into each component. -/ -@[simp] -protected def prod {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : α i × β i := (f i, g i) - -lemma prod_fst_snd : Pi.prod (Prod.fst : α × β → α) (Prod.snd : α × β → β) = id := rfl -lemma prod_snd_fst : Pi.prod (Prod.snd : α × β → β) (Prod.fst : α × β → α) = .swap := rfl - /-! `1`, `0`, `+`, `*`, `+ᵥ`, `•`, `^`, `-`, `⁻¹`, and `/` are defined pointwise. -/ section One