# 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*) [AddCommGroup A]

• FreeAbelianGroup α : 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 : FreeAbelianGroup α →+ A : the group homomorphism induced by the map f : α → A.

• map (f : α → β) : FreeAbelianGroup α →+ FreeAbelianGroup β : functoriality of FreeAbelianGroup.

• instance [Monoid α] : Semigroup (FreeAbelianGroup α)

• instance [CommMonoid α] : CommRing (FreeAbelianGroup α)

It has been suggested that we would be better off refactoring this file and using Finsupp instead.

## Implementation issues #

The definition is def FreeAbelianGroup : Type u := Additive <| Abelianization <| FreeGroup α.

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 FreeAbelianGroup.map (f : α → β) is defined to be the AddGroup homomorphism FreeAbelianGroup α →+ FreeAbelianGroup β (with α and β now allowed to be in different universes), so (map f).map_add etc can be used to prove that FreeAbelianGroup.map preserves addition. The functions map_id, map_id_apply, map_comp, map_comp_apply and map_of_apply are about FreeAbelianGroup.map. def FreeAbelianGroup (α : Type u) : The free abelian group on a type. Equations Instances For Equations • = Additive.addCommGroup Equations • = { default := 0 } Equations • = id inferInstance def FreeAbelianGroup.of {α : Type u} (x : α) : The canonical map from α to FreeAbelianGroup α. Equations • = Abelianization.of () Instances For def FreeAbelianGroup.lift {α : Type u} {β : Type v} [] : (αβ) () The map FreeAbelianGroup α →+ A induced by a map of types α → A. Equations • FreeAbelianGroup.lift = FreeGroup.lift.trans (Abelianization.lift.trans MonoidHom.toAdditive) Instances For @[simp] theorem FreeAbelianGroup.lift.of {α : Type u} {β : Type v} [] (f : αβ) (x : α) : (FreeAbelianGroup.lift f) = f x theorem FreeAbelianGroup.lift.unique {α : Type u} {β : Type v} [] (f : αβ) (g : ) (hg : ∀ (x : α), g = f x) {x : } : g x = (FreeAbelianGroup.lift f) x theorem FreeAbelianGroup.lift.ext {α : Type u} {β : Type v} [] (g : ) (h : ) (H : ∀ (x : α), g = h ) : g = h See note [partially-applied ext lemmas]. theorem FreeAbelianGroup.lift.map_hom {α : Type u_1} {β : Type u_2} {γ : Type u_3} [] [] (a : ) (f : αβ) (g : β →+ γ) : g ((FreeAbelianGroup.lift f) a) = (FreeAbelianGroup.lift (g f)) a theorem FreeAbelianGroup.of_injective {α : Type u} : Function.Injective FreeAbelianGroup.of theorem FreeAbelianGroup.induction_on {α : Type u} {C : } (z : ) (C0 : C 0) (C1 : ∀ (x : α), C ) (Cn : ∀ (x : α), C C ) (Cp : ∀ (x y : ), C xC yC (x + y)) : C z theorem FreeAbelianGroup.lift.add' {α : Type u_1} {β : Type u_2} [] (a : ) (f : αβ) (g : αβ) : (FreeAbelianGroup.lift (f + g)) a = (FreeAbelianGroup.lift f) a + (FreeAbelianGroup.lift g) a @[simp] theorem FreeAbelianGroup.liftAddGroupHom_apply {α : Type u_1} (β : Type u_2) [] (a : ) (f : αβ) : = (FreeAbelianGroup.lift f) a def FreeAbelianGroup.liftAddGroupHom {α : Type u_1} (β : Type u_2) [] (a : ) : (αβ) →+ β If g : FreeAbelianGroup X and A is an abelian group then liftAddGroupHom 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 FreeAbelianGroup X → A at g. Equations Instances For theorem FreeAbelianGroup.lift_neg' {α : Type u} {β : Type u_1} [] (f : αβ) : FreeAbelianGroup.lift (-f) = -FreeAbelianGroup.lift f theorem FreeAbelianGroup.induction_on' {α : Type u} {C : } (z : ) (C0 : C 0) (C1 : ∀ (x : α), C (pure x)) (Cn : ∀ (x : α), C (pure x)C (-pure x)) (Cp : ∀ (x y : ), C xC yC (x + y)) : C z @[simp] theorem FreeAbelianGroup.map_pure {α : Type u} {β : Type u} (f : αβ) (x : α) : f <$> pure x = pure (f x)
@[simp]
theorem FreeAbelianGroup.map_zero {α : Type u} {β : Type u} (f : αβ) :
f <$> 0 = 0 @[simp] theorem FreeAbelianGroup.map_add {α : Type u} {β : Type u} (f : αβ) (x : ) (y : ) : f <$> (x + y) = f <$> x + f <$> y
@[simp]
theorem FreeAbelianGroup.map_neg {α : Type u} {β : Type u} (f : αβ) (x : ) :
f <$> (-x) = -f <$> x
@[simp]
theorem FreeAbelianGroup.map_sub {α : Type u} {β : Type u} (f : αβ) (x : ) (y : ) :
f <$> (x - y) = f <$> x - f <$> y @[simp] theorem FreeAbelianGroup.map_of {α : Type u} {β : Type u} (f : αβ) (y : α) : theorem FreeAbelianGroup.pure_bind {α : Type u} {β : Type u} (f : α) (x : α) : pure x >>= f = f x @[simp] theorem FreeAbelianGroup.zero_bind {α : Type u} {β : Type u} (f : α) : 0 >>= f = 0 @[simp] theorem FreeAbelianGroup.add_bind {α : Type u} {β : Type u} (f : α) (x : ) (y : ) : x + y >>= f = (x >>= f) + (y >>= f) @[simp] theorem FreeAbelianGroup.neg_bind {α : Type u} {β : Type u} (f : α) (x : ) : -x >>= f = -(x >>= f) @[simp] theorem FreeAbelianGroup.sub_bind {α : Type u} {β : Type u} (f : α) (x : ) (y : ) : x - y >>= f = (x >>= f) - (y >>= f) @[simp] theorem FreeAbelianGroup.pure_seq {α : Type u} {β : Type u} (f : αβ) (x : ) : (Seq.seq (pure f) fun (x_1 : Unit) => x) = f <$> x
@[simp]
theorem FreeAbelianGroup.zero_seq {α : Type u} {β : Type u} (x : ) :
(Seq.seq 0 fun (x_1 : Unit) => x) = 0
@[simp]
theorem FreeAbelianGroup.add_seq {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) (g : FreeAbelianGroup (αβ)) (x : ) :
(Seq.seq (f + g) fun (x_1 : Unit) => x) = (Seq.seq f fun (x_1 : Unit) => x) + Seq.seq g fun (x_1 : Unit) => x
@[simp]
theorem FreeAbelianGroup.neg_seq {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) (x : ) :
(Seq.seq (-f) fun (x_1 : Unit) => x) = -Seq.seq f fun (x_1 : Unit) => x
@[simp]
theorem FreeAbelianGroup.sub_seq {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) (g : FreeAbelianGroup (αβ)) (x : ) :
(Seq.seq (f - g) fun (x_1 : Unit) => x) = (Seq.seq f fun (x_1 : Unit) => x) - Seq.seq g fun (x_1 : Unit) => x
def FreeAbelianGroup.seqAddGroupHom {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) :

If f : FreeAbelianGroup (α → β), then f <*> is an additive morphism FreeAbelianGroup α →+ FreeAbelianGroup β.

Equations
Instances For
@[simp]
theorem FreeAbelianGroup.seq_zero {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) :
(Seq.seq f fun (x : Unit) => 0) = 0
@[simp]
theorem FreeAbelianGroup.seq_add {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) (x : ) (y : ) :
(Seq.seq f fun (x_1 : Unit) => x + y) = (Seq.seq f fun (x_1 : Unit) => x) + Seq.seq f fun (x : Unit) => y
@[simp]
theorem FreeAbelianGroup.seq_neg {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) (x : ) :
(Seq.seq f fun (x_1 : Unit) => -x) = -Seq.seq f fun (x_1 : Unit) => x
@[simp]
theorem FreeAbelianGroup.seq_sub {α : Type u} {β : Type u} (f : FreeAbelianGroup (αβ)) (x : ) (y : ) :
(Seq.seq f fun (x_1 : Unit) => x - y) = (Seq.seq f fun (x_1 : Unit) => x) - Seq.seq f fun (x : Unit) => y
def FreeAbelianGroup.map {α : Type u} {β : Type v} (f : αβ) :

The additive group homomorphism FreeAbelianGroup α →+ FreeAbelianGroup β induced from a map α → β.

Equations
• = FreeAbelianGroup.lift (FreeAbelianGroup.of f)
Instances For
theorem FreeAbelianGroup.lift_comp {α : Type u_1} {β : Type u_2} {γ : Type u_3} [] (f : αβ) (g : βγ) (x : ) :
(FreeAbelianGroup.lift (g f)) x = (FreeAbelianGroup.lift g) ( x)
theorem FreeAbelianGroup.map_id_apply {α : Type u} (x : ) :
() x = x
theorem FreeAbelianGroup.map_comp {α : Type u} {β : Type v} {γ : Type w} {f : αβ} {g : βγ} :
theorem FreeAbelianGroup.map_comp_apply {α : Type u} {β : Type v} {γ : Type w} {f : αβ} {g : βγ} (x : ) :
(FreeAbelianGroup.map (g f)) x = ( x)
@[simp]
theorem FreeAbelianGroup.map_of_apply {α : Type u} {β : Type v} {f : αβ} (a : α) :
instance FreeAbelianGroup.mul (α : Type u) [Mul α] :
Equations
• = { mul := fun (x : ) => (FreeAbelianGroup.lift fun (x₂ : α) => (FreeAbelianGroup.lift fun (x₁ : α) => FreeAbelianGroup.of (x₁ * x₂)) x) }
theorem FreeAbelianGroup.mul_def {α : Type u} [Mul α] (x : ) (y : ) :
x * y = (FreeAbelianGroup.lift fun (x₂ : α) => (FreeAbelianGroup.lift fun (x₁ : α) => FreeAbelianGroup.of (x₁ * x₂)) x) y
@[simp]
theorem FreeAbelianGroup.of_mul_of {α : Type u} [Mul α] (x : α) (y : α) :
theorem FreeAbelianGroup.of_mul {α : Type u} [Mul α] (x : α) (y : α) :
instance FreeAbelianGroup.distrib {α : Type u} [Mul α] :
Equations
• FreeAbelianGroup.distrib = let __src := ; let __src_1 := ;
Equations
• FreeAbelianGroup.nonUnitalNonAssocRing = let __src := FreeAbelianGroup.distrib; let __src_1 := ;
instance FreeAbelianGroup.one (α : Type u) [One α] :
Equations
• = { one := }
instance FreeAbelianGroup.nonUnitalRing (α : Type u) [] :
Equations
• = let __src := FreeAbelianGroup.nonUnitalNonAssocRing;
instance FreeAbelianGroup.ring (α : Type u) [] :
Equations
• = let __src := ; let __src_1 := ; Ring.mk SubNegMonoid.zsmul

FreeAbelianGroup.of is a MonoidHom when α is a Monoid.

Equations
• FreeAbelianGroup.ofMulHom = { toFun := FreeAbelianGroup.of, map_one' := , map_mul' := }
Instances For
@[simp]
theorem FreeAbelianGroup.ofMulHom_coe {α : Type u} [] :
FreeAbelianGroup.ofMulHom = FreeAbelianGroup.of
def FreeAbelianGroup.liftMonoid {α : Type u} {R : Type u_1} [] [Ring R] :
(α →* R) ()

If f preserves multiplication, then so does lift f.

Equations
• One or more equations did not get rendered due to their size.
Instances For
@[simp]
theorem FreeAbelianGroup.liftMonoid_coe_addMonoidHom {α : Type u} {R : Type u_1} [] [Ring R] (f : α →* R) :
(FreeAbelianGroup.liftMonoid f) = FreeAbelianGroup.lift f
@[simp]
theorem FreeAbelianGroup.liftMonoid_coe {α : Type u} {R : Type u_1} [] [Ring R] (f : α →* R) :
(FreeAbelianGroup.liftMonoid f) = (FreeAbelianGroup.lift f)
@[simp]
theorem FreeAbelianGroup.liftMonoid_symm_coe {α : Type u} {R : Type u_1} [] [Ring R] (f : ) :
(FreeAbelianGroup.liftMonoid.symm f) = FreeAbelianGroup.lift.symm f
theorem FreeAbelianGroup.one_def {α : Type u} [] :
theorem FreeAbelianGroup.of_one {α : Type u} [] :
Equations
• = let __src := ;

The free abelian group on a type with one term is isomorphic to ℤ.

Equations
• = { toFun := (FreeAbelianGroup.lift fun (x : T) => 1), invFun := fun (n : ) => n FreeAbelianGroup.of default, left_inv := , right_inv := , map_add' := }
Instances For
def FreeAbelianGroup.equivOfEquiv {α : Type u_1} {β : Type u_2} (f : α β) :

Isomorphic types have isomorphic free abelian groups.

Equations
• = { toFun := (), invFun := (FreeAbelianGroup.map f.symm), left_inv := , right_inv := , map_add' := }
Instances For