Free abelian groups #
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' := _}