Type of functions with finite support #
For any type α and a type M with zero, we define the type finsupp α M (notation: α →₀ M)
of finitely supported functions from α to M, i.e. the functions which are zero everywhere
on α except on a finite set.
Functions with finite support are used (at least) in the following parts of the library:
-
monoid_algebra R Mandadd_monoid_algebra R Mare defined asM →₀ R; -
polynomials and multivariate polynomials are defined as
add_monoid_algebras, hence they usefinsuppunder the hood; -
the linear combination of a family of vectors
v iwith coefficientsf i(as used, e.g., to define linearly independent familylinear_independent) is defined as a mapfinsupp.total : (ι → M) → (ι →₀ R) →ₗ[R] M.
Some other constructions are naturally equivalent to α →₀ M with some α and M but are defined
in a different way in the library:
multiset α ≃+ α →₀ ℕ;free_abelian_group α ≃+ α →₀ ℤ.
Most of the theory assumes that the range is a commutative additive monoid. This gives us the big
sum operator as a powerful way to construct finsupp elements.
Many constructions based on α →₀ M use semireducible type tags to avoid reusing unwanted type
instances. E.g., monoid_algebra, add_monoid_algebra, and types based on these two have
non-pointwise multiplication.
Notations #
This file adds α →₀ M as a global notation for finsupp α M. We also use the following convention
for Type* variables in this file
-
α,β,γ: types with no additional structure that appear as the first argument tofinsuppsomewhere in the statement; -
ι: an auxiliary index type; -
M,M',N,P: types withhas_zeroor(add_)(comm_)monoidstructure;Mis also used for a (semi)module over a (semi)ring. -
G,H: groups (commutative or not, multiplicative or additive); -
R,S: (semi)rings.
TODO #
-
This file is currently ~2K lines long, so possibly it should be splitted into smaller chunks;
-
Add the list of definitions and important lemmas to the module docstring.
Implementation notes #
This file is a noncomputable theory and uses classical logic throughout.
Notation #
This file defines α →₀ β as notation for finsupp α β.
Equations
- finsupp.has_coe_to_fun = {coe := finsupp.to_fun _inst_1}
Equations
- finsupp.has_zero = {zero := {support := ∅, to_fun := 0, mem_support_to_fun := _}}
Equations
- finsupp.inhabited = {default := 0}
Given fintype α, equiv_fun_on_fintype is the equiv between α →₀ β and α → β.
(All functions on a finite type are finitely supported.)
Equations
- finsupp.equiv_fun_on_fintype = {to_fun := λ (f : α →₀ M) (a : α), ⇑f a, inv_fun := λ (f : α → M), {support := finset.filter (λ (a : α), f a ≠ 0) finset.univ, to_fun := f, mem_support_to_fun := _}, left_inv := _, right_inv := _}
Declarations about single #
single a b is the finitely supported function which has
value b at a and zero otherwise.
finsupp.single a b is injective in b. For the statement that it is injective in a, see
finsupp.single_left_injective
finsupp.single a b is injective in a. For the statement that it is injective in b, see
finsupp.single_injective
Declarations about update #
Replace the value of a α →₀ M at a given point a : α by a given value b : M.
If b = 0, this amounts to removing a from the finsupp.support.
Otherwise, if a was not in the finsupp.support, it is added to it.
This is the finitely-supported version of function.update.
Declarations about on_finset #
on_finset s f hf is the finsupp function representing f restricted to the finset s.
The function needs to be 0 outside of s. Use this when the set needs to be filtered anyways,
otherwise a better set representation is often available.
Equations
- finsupp.on_finset s f hf = {support := finset.filter (λ (a : α), f a ≠ 0) s, to_fun := f, mem_support_to_fun := _}
The natural finsupp induced by the function f given that it has finite support.
Equations
- finsupp.of_support_finite f hf = {support := hf.to_finset, to_fun := f, mem_support_to_fun := _}
Equations
- finsupp.can_lift = {coe := coe_fn finsupp.has_coe_to_fun, cond := λ (f : α → M), (function.support f).finite, prf := _}
Declarations about map_range #
The composition of f : M → N and g : α →₀ M is
map_range f hf g : α →₀ N, well-defined when f 0 = 0.
This preserves the structure on f, and exists in various bundled forms for when f is itself
bundled:
finsupp.map_range.equivfinsupp.map_range.zero_homfinsupp.map_range.add_monoid_homfinsupp.map_range.add_equivfinsupp.map_range.linear_mapfinsupp.map_range.linear_equiv
Equations
- finsupp.map_range f hf g = finsupp.on_finset g.support (f ∘ ⇑g) _
Declarations about emb_domain #
Given f : α ↪ β and v : α →₀ M, emb_domain f v : β →₀ M
is the finitely supported function whose value at f a : β is v a.
For a b : β outside the range of f, it is zero.
Equations
- finsupp.emb_domain f v = {support := finset.map f v.support, to_fun := λ (a₂ : β), dite (a₂ ∈ finset.map f v.support) (λ (h : a₂ ∈ finset.map f v.support), ⇑v (finset.choose (λ (a₁ : α), ⇑f a₁ = a₂) v.support _)) (λ (h : a₂ ∉ finset.map f v.support), 0), mem_support_to_fun := _}
Declarations about zip_with #
zip_with f hf g₁ g₂ is the finitely supported function satisfying
zip_with f hf g₁ g₂ a = f (g₁ a) (g₂ a), and it is well-defined when f 0 0 = 0.
Equations
- finsupp.zip_with f hf g₁ g₂ = finsupp.on_finset (g₁.support ∪ g₂.support) (λ (a : α), f (⇑g₁ a) (⇑g₂ a)) _
Declarations about erase #
erase a f is the finitely supported function equal to f except at a where it is equal to
0.
Declarations about sum and prod #
In most of this section, the domain β is assumed to be an add_monoid.
prod f g is the product of g a (f a) over the support of f.
sum f g is the sum of g a (f a) over the support of f.
A restatement of prod_ite_eq with the equality test reversed.
A restatement of sum_ite_eq with the equality test reversed.
If g maps a second argument of 0 to 1, then multiplying it over the
result of on_finset is the same as multiplying it over the original
finset.
If g maps a second argument of 0 to 0, summing it over the
result of on_finset is the same as summing it over the original
finset.
Taking a product over f : α →₀ M is the same as multiplying the value on a single element
y ∈ f.support by the product over erase y f.
Taking a sum over over f : α →₀ M is the same as adding the value on a
single element y ∈ f.support to the sum over erase y f.
Generalization of finsupp.mul_prod_erase: if g maps a second argument of 0 to 1,
then its product over f : α →₀ M is the same as multiplying the value on any element
y : α by the product over erase y f.
Generalization of finsupp.add_sum_erase: if g maps a second argument of 0
to 0, then its sum over f : α →₀ M is the same as adding the value on any element
y : α to the sum over erase y f.
Additive monoid structure on α →₀ M #
Equations
- finsupp.has_add = {add := finsupp.zip_with has_add.add finsupp.has_add._proof_1}
Equations
- finsupp.add_zero_class = {zero := 0, add := has_add.add finsupp.has_add, zero_add := _, add_zero := _}
finsupp.single as an add_monoid_hom.
See finsupp.lsingle for the stronger version as a linear map.
Equations
- finsupp.single_add_hom a = {to_fun := finsupp.single a, map_zero' := _, map_add' := _}
Evaluation of a function f : α →₀ M at a point as an additive monoid homomorphism.
See finsupp.lapply for the stronger version as a linear map.
finsupp.erase as an add_monoid_hom.
Equations
- finsupp.erase_add_hom a = {to_fun := finsupp.erase a, map_zero' := _, map_add' := _}
If two additive homomorphisms from α →₀ M are equal on each single a b, then
they are equal.
If two additive homomorphisms from α →₀ M are equal on each single a b, then
they are equal.
We formulate this using equality of add_monoid_homs 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).
Bundle emb_domain f as an additive map from α →₀ M to β →₀ M.
Equations
- finsupp.emb_domain.add_monoid_hom f = {to_fun := λ (v : α →₀ M), finsupp.emb_domain f v, map_zero' := _, map_add' := _}
Equations
- finsupp.add_monoid = {add := has_add.add finsupp.has_add, add_assoc := _, zero := 0, zero_add := _, add_zero := _, nsmul := λ (n : ℕ) (v : α →₀ M), finsupp.map_range (has_scalar.smul n) _ v, nsmul_zero' := _, nsmul_succ' := _}
Equations
- finsupp.add_comm_monoid = {add := add_monoid.add finsupp.add_monoid, add_assoc := _, zero := add_monoid.zero finsupp.add_monoid, zero_add := _, add_zero := _, nsmul := add_monoid.nsmul finsupp.add_monoid, nsmul_zero' := _, nsmul_succ' := _, add_comm := _}
Equations
- finsupp.has_sub = {sub := finsupp.zip_with has_sub.sub finsupp.has_sub._proof_1}
Equations
- finsupp.add_group = {add := add_monoid.add finsupp.add_monoid, add_assoc := _, zero := add_monoid.zero finsupp.add_monoid, zero_add := _, add_zero := _, nsmul := add_monoid.nsmul finsupp.add_monoid, nsmul_zero' := _, nsmul_succ' := _, neg := finsupp.map_range has_neg.neg neg_zero, sub := has_sub.sub finsupp.has_sub, sub_eq_add_neg := _, zsmul := λ (n : ℤ) (v : α →₀ G), finsupp.map_range (has_scalar.smul n) _ v, zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _}
Equations
- finsupp.add_comm_group = {add := add_group.add finsupp.add_group, add_assoc := _, zero := add_group.zero finsupp.add_group, zero_add := _, add_zero := _, nsmul := add_group.nsmul finsupp.add_group, nsmul_zero' := _, nsmul_succ' := _, neg := add_group.neg finsupp.add_group, sub := add_group.sub finsupp.add_group, sub_eq_add_neg := _, zsmul := add_group.zsmul finsupp.add_group, zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _, add_comm := _}
The canonical isomorphism between families of additive monoid homomorphisms α → (M →+ N)
and monoid homomorphisms (α →₀ M) →+ N.
For disjoint f1 and f2, and function g, the product of the products of g
over f1 and f2 equals the product of g over f1 + f2
finsupp.map_range as an equiv.
Equations
- finsupp.map_range.equiv f hf hf' = {to_fun := finsupp.map_range ⇑f hf, inv_fun := finsupp.map_range ⇑(f.symm) hf', left_inv := _, right_inv := _}
Composition with a fixed zero-preserving homomorphism is itself an zero-preserving homomorphism on functions.
Equations
- finsupp.map_range.zero_hom f = {to_fun := finsupp.map_range ⇑f _, map_zero' := _}
Composition with a fixed additive homomorphism is itself an additive homomorphism on functions.
Equations
- finsupp.map_range.add_monoid_hom f = {to_fun := finsupp.map_range ⇑f _, map_zero' := _, map_add' := _}
finsupp.map_range.add_monoid_hom as an equiv.
Equations
- finsupp.map_range.add_equiv f = {to_fun := finsupp.map_range ⇑f _, inv_fun := finsupp.map_range ⇑(f.symm) _, left_inv := _, right_inv := _, map_add' := _}
Declarations about map_domain #
Given f : α → β and v : α →₀ M, map_domain f v : β →₀ M
is the finitely supported function whose value at a : β is the sum
of v x over all x such that f x = a.
Equations
- finsupp.map_domain f v = v.sum (λ (a : α), finsupp.single (f a))
finsupp.map_domain is an add_monoid_hom.
Equations
- finsupp.map_domain.add_monoid_hom f = {to_fun := finsupp.map_domain f, map_zero' := _, map_add' := _}
A version of sum_map_domain_index that takes a bundled add_monoid_hom,
rather than separate linearity hypotheses.
When g preserves addition, map_range and map_domain commute.
Declarations about comap_domain #
Given f : α → β, l : β →₀ M and a proof hf that f is injective on
the preimage of l.support, comap_domain f l hf is the finitely supported function
from α to M given by composing l with f.
Equations
- finsupp.comap_domain f l hf = {support := l.support.preimage f hf, to_fun := λ (a : α), ⇑l (f a), mem_support_to_fun := _}
Declarations about equiv_congr_left #
Given f : α ≃ β, we can map l : α →₀ M to equiv_map_domain f l : β →₀ M (computably)
by mapping the support forwards and the function backwards.
Equations
- finsupp.equiv_map_domain f l = {support := finset.map f.to_embedding l.support, to_fun := λ (a : β), ⇑l (⇑(f.symm) a), mem_support_to_fun := _}
Given f : α ≃ β, the finitely supported function spaces are also in bijection:
(α →₀ M) ≃ (β →₀ M).
This is the finitely-supported version of equiv.Pi_congr_left.
Equations
- finsupp.equiv_congr_left f = {to_fun := finsupp.equiv_map_domain f, inv_fun := finsupp.equiv_map_domain f.symm, left_inv := _, right_inv := _}
Declarations about filter #
filter p f is the function which is f a if p a is true and 0 otherwise.
Equations
- finsupp.filter p f = {support := finset.filter (λ (a : α), p a) f.support, to_fun := λ (a : α), ite (p a) (⇑f a) 0, mem_support_to_fun := _}
Declarations about frange #
frange f is the image of f on the support of f.
Equations
- f.frange = finset.image ⇑f f.support
Declarations about subtype_domain #
subtype_domain p f is the restriction of the finitely supported function
f to the subtype p.
Equations
- finsupp.subtype_domain p f = {support := finset.subtype p f.support, to_fun := ⇑f ∘ coe, mem_support_to_fun := _}
subtype_domain but as an add_monoid_hom.
Equations
- finsupp.subtype_domain_add_monoid_hom = {to_fun := finsupp.subtype_domain p, map_zero' := _, map_add' := _}
finsupp.filter as an add_monoid_hom.
Equations
- finsupp.filter_add_hom p = {to_fun := finsupp.filter p, map_zero' := _, map_add' := _}
Given f : α →₀ ℕ, f.to_multiset is the multiset with multiplicities given by the values of
f on the elements of α. We define this function as an add_equiv.
Declarations about curry and uncurry #
Given a finitely supported function f from a product type α × β to γ,
curry f is the "curried" finitely supported function from α to the type of
finitely supported functions from β to γ.
Equations
- f.curry = f.sum (λ (p : α × β) (c : M), finsupp.single p.fst (finsupp.single p.snd c))
Given a finitely supported function f from α to the type of
finitely supported functions from β to M,
uncurry f is the "uncurried" finitely supported function from α × β to M.
finsupp_prod_equiv defines the equiv between ((α × β) →₀ M) and (α →₀ (β →₀ M)) given by
currying and uncurrying.
Equations
- finsupp.finsupp_prod_equiv = {to_fun := finsupp.curry _inst_1, inv_fun := finsupp.uncurry _inst_1, left_inv := _, right_inv := _}
finsupp.sum_elim f g maps inl x to f x and inr y to g y.
The equivalence between (α ⊕ β) →₀ γ and (α →₀ γ) × (β →₀ γ).
This is the finsupp version of equiv.sum_arrow_equiv_prod_arrow.
The additive equivalence between (α ⊕ β) →₀ M and (α →₀ M) × (β →₀ M).
This is the finsupp version of equiv.sum_arrow_equiv_prod_arrow.
Equations
Scalar multiplication by a group element g, given by precomposition with the action of g⁻¹ on the domain.
Equations
- finsupp.comap_has_scalar = {smul := λ (g : G) (f : α →₀ M), finsupp.comap_domain (λ (a : α), g⁻¹ • a) f _}
Scalar multiplication by a group element, given by precomposition with the action of g⁻¹ on the domain, is multiplicative in g.
Equations
- finsupp.comap_mul_action = {to_has_scalar := finsupp.comap_has_scalar _inst_3, one_smul := _, mul_smul := _}
Scalar multiplication by a group element, given by precomposition with the action of g⁻¹ on the domain, is additive in the second argument.
Equations
- finsupp.comap_distrib_mul_action = {to_mul_action := finsupp.comap_mul_action _inst_3, smul_add := _, smul_zero := _}
Scalar multiplication by a group element on finitely supported functions on a group, given by precomposition with the action of g⁻¹.
Equations
- finsupp.has_scalar = {smul := λ (a : R) (v : α →₀ M), finsupp.map_range (has_scalar.smul a) _ v}
Throughout this section, some monoid and semiring arguments are specified with {} instead of
[]. See note [implicit instance arguments].
Equations
- finsupp.distrib_mul_action α M = {to_mul_action := {to_has_scalar := {smul := has_scalar.smul finsupp.has_scalar}, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}
Equations
- finsupp.module α M = {to_distrib_mul_action := {to_mul_action := {to_has_scalar := {smul := has_scalar.smul finsupp.has_scalar}, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
A version of finsupp.sum_smul_index' for bundled additive maps.
finsupp.single as a distrib_mul_action_hom.
See also finsupp.lsingle for the version as a linear map.
Equations
- finsupp.distrib_mul_action_hom.single a = {to_fun := (finsupp.single_add_hom a).to_fun, map_smul' := _, map_zero' := _, map_add' := _}
The finsupp version of pi.unique.
Equations
- finsupp.unique_of_right = {to_inhabited := {default := default (α →₀ R) finsupp.inhabited}, uniq := _}
The finsupp version of pi.unique_of_is_empty.
Equations
- finsupp.unique_of_left = {to_inhabited := {default := default (α →₀ R) finsupp.inhabited}, uniq := _}
Given an add_comm_monoid M and s : set α, restrict_support_equiv s M is the equiv
between the subtype of finitely supported functions with support contained in s and
the type of finitely supported functions from s.
Equations
- finsupp.restrict_support_equiv s M = {to_fun := λ (f : {f // ↑(f.support) ⊆ s}), finsupp.subtype_domain (λ (x : α), x ∈ s) f.val, inv_fun := λ (f : ↥s →₀ M), ⟨finsupp.map_domain subtype.val f, _⟩, left_inv := _, right_inv := _}
Given add_comm_monoid M and e : α ≃ β, dom_congr e is the corresponding equiv between
α →₀ M and β →₀ M.
This is finsupp.equiv_congr_left as an add_equiv.
Equations
- finsupp.dom_congr e = {to_fun := finsupp.equiv_map_domain e, inv_fun := finsupp.equiv_map_domain e.symm, left_inv := _, right_inv := _, map_add' := _}
Declarations about sigma types #
Given l, a finitely supported function from the sigma type Σ (i : ι), αs i to M and
an index element i : ι, split l i is the ith component of l,
a finitely supported function from as i to M.
This is the finsupp version of sigma.curry.
Equations
- l.split i = finsupp.comap_domain (sigma.mk i) l _
Given l, a finitely supported function from the sigma type Σ (i : ι), αs i to β,
split_support l is the finset of indices in ι that appear in the support of l.
Equations
Given l, a finitely supported function from the sigma type Σ i, αs i to β and
an ι-indexed family g of functions from (αs i →₀ β) to γ, split_comp defines a
finitely supported function from the index type ι to γ given by composing g i with
split l i.
Equations
- l.split_comp g hg = {support := l.split_support, to_fun := λ (i : ι), g i (l.split i), mem_support_to_fun := _}
On a fintype η, finsupp.split is an equivalence between (Σ (j : η), ιs j) →₀ α
and Π j, (ιs j →₀ α).
This is the finsupp version of equiv.Pi_curry.
Equations
- finsupp.sigma_finsupp_equiv_pi_finsupp = {to_fun := finsupp.split _inst_3, inv_fun := λ (f : Π (j : η), ιs j →₀ α), finsupp.on_finset (finset.univ.sigma (λ (j : η), (f j).support)) (λ (ji : Σ (j : η), ιs j), ⇑(f ji.fst) ji.snd) _, left_inv := _, right_inv := _}
On a fintype η, finsupp.split is an additive equivalence between
(Σ (j : η), ιs j) →₀ α and Π j, (ιs j →₀ α).
This is the add_equiv version of finsupp.sigma_finsupp_equiv_pi_finsupp.
Equations
Given a multiset s, s.to_finsupp returns the finitely supported function on ℕ given by
the multiplicities of the elements of s.
Equations
Equations
- finsupp.partial_order = {le := preorder.le finsupp.preorder, lt := preorder.lt finsupp.preorder, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _}
Equations
- finsupp.ordered_add_comm_monoid = {add := add_comm_monoid.add finsupp.add_comm_monoid, add_assoc := _, zero := add_comm_monoid.zero finsupp.add_comm_monoid, zero_add := _, add_zero := _, nsmul := add_comm_monoid.nsmul finsupp.add_comm_monoid, nsmul_zero' := _, nsmul_succ' := _, add_comm := _, le := partial_order.le finsupp.partial_order, lt := partial_order.lt finsupp.partial_order, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, add_le_add_left := _}
Equations
- finsupp.ordered_cancel_add_comm_monoid = {add := add_comm_monoid.add finsupp.add_comm_monoid, add_assoc := _, add_left_cancel := _, zero := add_comm_monoid.zero finsupp.add_comm_monoid, zero_add := _, add_zero := _, nsmul := add_comm_monoid.nsmul finsupp.add_comm_monoid, nsmul_zero' := _, nsmul_succ' := _, add_comm := _, le := partial_order.le finsupp.partial_order, lt := partial_order.lt finsupp.partial_order, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, add_le_add_left := _, le_of_add_le_add_left := _}
Equations
- finsupp.decidable_le = λ (f g : α →₀ M), decidable_of_iff (∀ (s : α), s ∈ f.support → ⇑f s ≤ ⇑g s) _
finsupp.to_multiset as an order isomorphism.
Equations
The order on σ →₀ ℕ is well-founded.
Declarations about subtraction on finsupp with codomain a canonically_ordered_add_monoid.
Some of these lemmas are used to develop the partial derivative on mv_polynomial.
Equations
- finsupp.order_bot = {bot := 0, bot_le := _}
This is called tsub for truncated subtraction, to distinguish it with subtraction in an
additive group.
Equations
- finsupp.tsub = {sub := finsupp.zip_with (λ (m n : M), m - n) finsupp.tsub._proof_1}
Equations
- finsupp.canonically_ordered_add_monoid = {add := ordered_add_comm_monoid.add finsupp.ordered_add_comm_monoid, add_assoc := _, zero := ordered_add_comm_monoid.zero finsupp.ordered_add_comm_monoid, zero_add := _, add_zero := _, nsmul := ordered_add_comm_monoid.nsmul finsupp.ordered_add_comm_monoid, nsmul_zero' := _, nsmul_succ' := _, add_comm := _, le := ordered_add_comm_monoid.le finsupp.ordered_add_comm_monoid, lt := ordered_add_comm_monoid.lt finsupp.ordered_add_comm_monoid, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, add_le_add_left := _, bot := order_bot.bot finsupp.order_bot, bot_le := _, le_iff_exists_add := _}
Equations
Some lemmas specifically about ℕ.