Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(Data/Finsupp): split off extensionality from Defs.lean #19092

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Mathlib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2476,6 +2476,7 @@ import Mathlib.Data.Finsupp.Basic
import Mathlib.Data.Finsupp.BigOperators
import Mathlib.Data.Finsupp.Defs
import Mathlib.Data.Finsupp.Encodable
import Mathlib.Data.Finsupp.Ext
import Mathlib.Data.Finsupp.Fin
import Mathlib.Data.Finsupp.Fintype
import Mathlib.Data.Finsupp.Indicator
Expand Down
1 change: 1 addition & 0 deletions Mathlib/Algebra/BigOperators/Finsupp.lean
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Mathlib.Algebra.BigOperators.Pi
import Mathlib.Algebra.BigOperators.Ring
import Mathlib.Algebra.BigOperators.Fin
import Mathlib.Algebra.Group.Submonoid.BigOperators
import Mathlib.Data.Finsupp.Ext
import Mathlib.Data.Finsupp.Fin
import Mathlib.Data.Finsupp.Indicator

Expand Down
47 changes: 1 addition & 46 deletions Mathlib/Data/Finsupp/Defs.lean
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes Hölzl, Kim Morrison
-/
import Mathlib.Algebra.Group.Indicator
import Mathlib.Algebra.Group.Submonoid.Basic
import Mathlib.Data.Finset.Max
import Mathlib.Data.Set.Finite.Basic
import Mathlib.Algebra.Group.TypeTags.Hom

/-!
# Type of functions with finite support
Expand Down Expand Up @@ -81,6 +79,7 @@ This file is a `noncomputable theory` and uses classical logic throughout.

-/

assert_not_exists Submonoid

noncomputable section

Expand Down Expand Up @@ -1130,50 +1129,6 @@ theorem induction_on_min₂ (f : α →₀ M) (h0 : p 0)

end LinearOrder

@[simp]
theorem add_closure_setOf_eq_single :
AddSubmonoid.closure { f : α →₀ M | ∃ a b, f = single a b } = ⊤ :=
top_unique fun x _hx =>
Finsupp.induction x (AddSubmonoid.zero_mem _) fun a b _f _ha _hb hf =>
AddSubmonoid.add_mem _ (AddSubmonoid.subset_closure <| ⟨a, b, rfl⟩) hf

/-- If two additive homomorphisms from `α →₀ M` are equal on each `single a b`,
then they are equal. -/
theorem addHom_ext [AddZeroClass N] ⦃f g : (α →₀ M) →+ N⦄
(H : ∀ x y, f (single x y) = g (single x y)) : f = g := by
refine AddMonoidHom.eq_of_eqOn_denseM add_closure_setOf_eq_single ?_
rintro _ ⟨x, y, rfl⟩
apply H

/-- If two additive homomorphisms from `α →₀ M` are equal on each `single a b`,
then they are equal.

We formulate this using equality of `AddMonoidHom`s so that `ext` tactic can apply a type-specific
extensionality lemma after this one. E.g., if the fiber `M` is `ℕ` or `ℤ`, then it suffices to
verify `f (single a 1) = g (single a 1)`. -/
@[ext high]
theorem addHom_ext' [AddZeroClass N] ⦃f g : (α →₀ M) →+ N⦄
(H : ∀ x, f.comp (singleAddHom x) = g.comp (singleAddHom x)) : f = g :=
addHom_ext fun x => DFunLike.congr_fun (H x)

theorem mulHom_ext [MulOneClass N] ⦃f g : Multiplicative (α →₀ M) →* N⦄
(H : ∀ x y, f (Multiplicative.ofAdd <| single x y) = g (Multiplicative.ofAdd <| single x y)) :
f = g :=
MonoidHom.ext <|
DFunLike.congr_fun <| by
have := @addHom_ext α M (Additive N) _ _
(MonoidHom.toAdditive'' f) (MonoidHom.toAdditive'' g) H
ext
rw [DFunLike.ext_iff] at this
apply this

@[ext]
theorem mulHom_ext' [MulOneClass N] {f g : Multiplicative (α →₀ M) →* N}
(H : ∀ x, f.comp (AddMonoidHom.toMultiplicative (singleAddHom x)) =
g.comp (AddMonoidHom.toMultiplicative (singleAddHom x))) :
f = g :=
mulHom_ext fun x => DFunLike.congr_fun (H x)

theorem mapRange_add [AddZeroClass N] {f : M → N} {hf : f 0 = 0}
(hf' : ∀ x y, f (x + y) = f x + f y) (v₁ v₂ : α →₀ M) :
mapRange f hf (v₁ + v₂) = mapRange f hf v₁ + mapRange f hf v₂ :=
Expand Down
72 changes: 72 additions & 0 deletions Mathlib/Data/Finsupp/Ext.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/-
Copyright (c) 2017 Johannes Hölzl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes Hölzl, Kim Morrison
-/
import Mathlib.Algebra.Group.Submonoid.Basic
import Mathlib.Algebra.Group.TypeTags.Hom
import Mathlib.Data.Finsupp.Defs

/-!
# Extensionality for maps on `Finsupp`

This file contains some extensionality principles for maps on `Finsupp`.
These have been moved to their own file to avoid depending on submonoids when defining `Finsupp`.

## Main results

* `Finsupp.add_closure_setOf_eq_single`: `Finsupp` is generated by all the `single`s
* `Finsupp.addHom_ext`: additive homomorphisms that are equal on each `single` are equal everywhere
-/

variable {α M N : Type*}

namespace Finsupp

variable [AddZeroClass M]

@[simp]
theorem add_closure_setOf_eq_single :
AddSubmonoid.closure { f : α →₀ M | ∃ a b, f = single a b } = ⊤ :=
top_unique fun x _hx =>
Finsupp.induction x (AddSubmonoid.zero_mem _) fun a b _f _ha _hb hf =>
AddSubmonoid.add_mem _ (AddSubmonoid.subset_closure <| ⟨a, b, rfl⟩) hf

/-- If two additive homomorphisms from `α →₀ M` are equal on each `single a b`,
then they are equal. -/
theorem addHom_ext [AddZeroClass N] ⦃f g : (α →₀ M) →+ N⦄
(H : ∀ x y, f (single x y) = g (single x y)) : f = g := by
refine AddMonoidHom.eq_of_eqOn_denseM add_closure_setOf_eq_single ?_
rintro _ ⟨x, y, rfl⟩
apply H

/-- If two additive homomorphisms from `α →₀ M` are equal on each `single a b`,
then they are equal.

We formulate this using equality of `AddMonoidHom`s so that `ext` tactic can apply a type-specific
extensionality lemma after this one. E.g., if the fiber `M` is `ℕ` or `ℤ`, then it suffices to
verify `f (single a 1) = g (single a 1)`. -/
@[ext high]
theorem addHom_ext' [AddZeroClass N] ⦃f g : (α →₀ M) →+ N⦄
(H : ∀ x, f.comp (singleAddHom x) = g.comp (singleAddHom x)) : f = g :=
addHom_ext fun x => DFunLike.congr_fun (H x)

theorem mulHom_ext [MulOneClass N] ⦃f g : Multiplicative (α →₀ M) →* N⦄
(H : ∀ x y, f (Multiplicative.ofAdd <| single x y) = g (Multiplicative.ofAdd <| single x y)) :
f = g :=
MonoidHom.ext <|
DFunLike.congr_fun <| by
have := @addHom_ext α M (Additive N) _ _
(MonoidHom.toAdditive'' f) (MonoidHom.toAdditive'' g) H
ext
rw [DFunLike.ext_iff] at this
apply this

@[ext]
theorem mulHom_ext' [MulOneClass N] {f g : Multiplicative (α →₀ M) →* N}
(H : ∀ x, f.comp (AddMonoidHom.toMultiplicative (singleAddHom x)) =
g.comp (AddMonoidHom.toMultiplicative (singleAddHom x))) :
f = g :=
mulHom_ext fun x => DFunLike.congr_fun (H x)

end Finsupp