Free abelian groups #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
The free abelian group on a type α
, defined as the abelianisation of
the free group on α
.
The free abelian group on α
can be abstractly defined as the left adjoint of the
forgetful functor from abelian groups to types. Alternatively, one could define
it as the functions α → ℤ
which send all but finitely many (a : α)
to 0
,
under pointwise addition. In this file, it is defined as the abelianisation
of the free group on α
. All the constructions and theorems required to show
the adjointness of the construction and the forgetful functor are proved in this
file, but the category-theoretic adjunction statement is in
algebra.category.Group.adjunctions
.
Main definitions #
Here we use the following variables: (α β : Type*) (A : Type*) [add_comm_group A]
-
free_abelian_group α
: the free abelian group on a typeα
. As an abelian group it isα →₀ ℤ
, the functions fromα
toℤ
such that all but finitely many elements get mapped to zero, however this is not how it is implemented. -
lift f : free_abelian_group α →+ A
: the group homomorphism induced by the mapf : α → A
. -
map (f : α → β) : free_abelian_group α →+ free_abelian_group β
: functoriality offree_abelian_group
-
instance [monoid α] : semigroup (free_abelian_group α)
-
instance [comm_monoid α] : comm_ring (free_abelian_group α)
It has been suggested that we would be better off refactoring this file
and using finsupp
instead.
Implementation issues #
The definition is def free_abelian_group : Type u := additive $ abelianization $ free_group α
Chris Hughes has suggested that this all be rewritten in terms of finsupp
.
Johan Commelin has written all the API relating the definition to finsupp
in the lean-liquid repo.
The lemmas map_pure
, map_of
, map_zero
, map_add
, map_neg
and map_sub
are proved about the functor.map
<$>
construction, and need α
and β
to
be in the same universe. But
free_abelian_group.map (f : α → β)
is defined to be the add_group
homomorphism free_abelian_group α →+ free_abelian_group β
(with α
and β
now
allowed to be in different universes), so (map f).map_add
etc can be used to prove that free_abelian_group.map
preserves addition. The
functions map_id
, map_id_apply
, map_comp
, map_comp_apply
and map_of_apply
are about free_abelian_group.map
.
The free abelian group on a type.
Equations
Instances for free_abelian_group
- free_abelian_group.add_comm_group
- free_abelian_group.inhabited
- free_abelian_group.monad
- free_abelian_group.is_lawful_monad
- free_abelian_group.is_comm_applicative
- free_abelian_group.has_mul
- free_abelian_group.distrib
- free_abelian_group.non_unital_non_assoc_ring
- free_abelian_group.has_one
- free_abelian_group.non_unital_ring
- free_abelian_group.ring
- free_abelian_group.comm_ring
- free_abelian_group.pempty_unique
Equations
- free_abelian_group.inhabited α = {default := 0}
The canonical map from α to free_abelian_group α
Equations
The map free_abelian_group α →+ A
induced by a map of types α → A
.
If g : free_abelian_group X
and A
is an abelian group then lift_add_group_hom g
is the additive group homomorphism sending a function X → A
to the term of type A
corresponding to the evaluation of the induced map free_abelian_group X → A
at g
.
Equations
- free_abelian_group.lift_add_group_hom β a = add_monoid_hom.mk' (λ (f : α → β), ⇑(⇑free_abelian_group.lift f) a) _
Equations
If f : free_abelian_group (α → β)
, then f <*>
is an additive morphism
free_abelian_group α →+ free_abelian_group β
.
Equations
The additive group homomorphism free_abelian_group α →+ free_abelian_group β
induced from a
map α → β
Equations
Equations
- free_abelian_group.has_mul α = {mul := λ (x : free_abelian_group α), ⇑(⇑free_abelian_group.lift (λ (x₂ : α), ⇑(⇑free_abelian_group.lift (λ (x₁ : α), free_abelian_group.of (x₁ * x₂))) x))}
Equations
- free_abelian_group.distrib = {mul := has_mul.mul (free_abelian_group.has_mul α), add := has_add.add (add_zero_class.to_has_add (free_abelian_group α)), left_distrib := _, right_distrib := _}
Equations
- free_abelian_group.non_unital_non_assoc_ring = {add := distrib.add free_abelian_group.distrib, add_assoc := _, zero := add_comm_group.zero (free_abelian_group.add_comm_group α), zero_add := _, add_zero := _, nsmul := add_comm_group.nsmul (free_abelian_group.add_comm_group α), nsmul_zero' := _, nsmul_succ' := _, neg := add_comm_group.neg (free_abelian_group.add_comm_group α), sub := add_comm_group.sub (free_abelian_group.add_comm_group α), sub_eq_add_neg := _, zsmul := add_comm_group.zsmul (free_abelian_group.add_comm_group α), zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _, add_comm := _, mul := distrib.mul free_abelian_group.distrib, left_distrib := _, right_distrib := _, zero_mul := _, mul_zero := _}
Equations
Equations
- free_abelian_group.non_unital_ring α = {add := non_unital_non_assoc_ring.add free_abelian_group.non_unital_non_assoc_ring, add_assoc := _, zero := non_unital_non_assoc_ring.zero free_abelian_group.non_unital_non_assoc_ring, zero_add := _, add_zero := _, nsmul := non_unital_non_assoc_ring.nsmul free_abelian_group.non_unital_non_assoc_ring, nsmul_zero' := _, nsmul_succ' := _, neg := non_unital_non_assoc_ring.neg free_abelian_group.non_unital_non_assoc_ring, sub := non_unital_non_assoc_ring.sub free_abelian_group.non_unital_non_assoc_ring, sub_eq_add_neg := _, zsmul := non_unital_non_assoc_ring.zsmul free_abelian_group.non_unital_non_assoc_ring, zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _, add_comm := _, mul := has_mul.mul (free_abelian_group.has_mul α), left_distrib := _, right_distrib := _, zero_mul := _, mul_zero := _, mul_assoc := _}
Equations
- free_abelian_group.ring α = {add := non_unital_ring.add (free_abelian_group.non_unital_ring α), add_assoc := _, zero := non_unital_ring.zero (free_abelian_group.non_unital_ring α), zero_add := _, add_zero := _, nsmul := non_unital_ring.nsmul (free_abelian_group.non_unital_ring α), nsmul_zero' := _, nsmul_succ' := _, neg := non_unital_ring.neg (free_abelian_group.non_unital_ring α), sub := non_unital_ring.sub (free_abelian_group.non_unital_ring α), sub_eq_add_neg := _, zsmul := non_unital_ring.zsmul (free_abelian_group.non_unital_ring α), zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _, add_comm := _, int_cast := add_comm_group_with_one.int_cast._default (add_comm_group_with_one.nat_cast._default 1 non_unital_ring.add _ non_unital_ring.zero _ _ non_unital_ring.nsmul _ _) non_unital_ring.add _ non_unital_ring.zero _ _ non_unital_ring.nsmul _ _ 1 _ _ non_unital_ring.neg non_unital_ring.sub _ non_unital_ring.zsmul _ _ _ _, nat_cast := add_comm_group_with_one.nat_cast._default 1 non_unital_ring.add _ non_unital_ring.zero _ _ non_unital_ring.nsmul _ _, one := 1, nat_cast_zero := _, nat_cast_succ := _, int_cast_of_nat := _, int_cast_neg_succ_of_nat := _, mul := has_mul.mul (free_abelian_group.has_mul α), mul_assoc := _, one_mul := _, mul_one := _, npow := monoid.npow._default 1 has_mul.mul _ _, npow_zero' := _, npow_succ' := _, left_distrib := _, right_distrib := _}
free_abelian_group.of
is a monoid_hom
when α
is a monoid
.
Equations
- free_abelian_group.of_mul_hom = {to_fun := free_abelian_group.of α, map_one' := _, map_mul' := _}
If f
preserves multiplication, then so does lift f
.
Equations
- free_abelian_group.comm_ring α = {add := ring.add (free_abelian_group.ring α), add_assoc := _, zero := ring.zero (free_abelian_group.ring α), zero_add := _, add_zero := _, nsmul := ring.nsmul (free_abelian_group.ring α), nsmul_zero' := _, nsmul_succ' := _, neg := ring.neg (free_abelian_group.ring α), sub := ring.sub (free_abelian_group.ring α), sub_eq_add_neg := _, zsmul := ring.zsmul (free_abelian_group.ring α), zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _, add_comm := _, int_cast := ring.int_cast (free_abelian_group.ring α), nat_cast := ring.nat_cast (free_abelian_group.ring α), one := ring.one (free_abelian_group.ring α), nat_cast_zero := _, nat_cast_succ := _, int_cast_of_nat := _, int_cast_neg_succ_of_nat := _, mul := ring.mul (free_abelian_group.ring α), mul_assoc := _, one_mul := _, mul_one := _, npow := ring.npow (free_abelian_group.ring α), npow_zero' := _, npow_succ' := _, left_distrib := _, right_distrib := _, mul_comm := _}
Equations
- free_abelian_group.pempty_unique = {to_inhabited := {default := 0}, uniq := free_abelian_group.pempty_unique._proof_1}
The free abelian group on a type with one term is isomorphic to ℤ
.
Equations
- free_abelian_group.punit_equiv T = {to_fun := ⇑(⇑free_abelian_group.lift (λ (_x : T), 1)), inv_fun := λ (n : ℤ), n • free_abelian_group.of inhabited.default, left_inv := _, right_inv := _, map_add' := _}
Isomorphic types have isomorphic free abelian groups.
Equations
- free_abelian_group.equiv_of_equiv f = {to_fun := ⇑(free_abelian_group.map ⇑f), inv_fun := ⇑(free_abelian_group.map ⇑(f.symm)), left_inv := _, right_inv := _, map_add' := _}