Free modules #
We construct the free module over a ring R
generated by a set X
. It is assumed that both R
and X
have decidable equality.
This is to obtain decidable equality for the elements of the module, which we do (FreeModule.decEq
).
We choose our definition to allow both such computations and to prove results.
The definition is as a quotient of Formal Sums (FormalSum
),
which are simply lists of pairs (a,x)
where a
is a coefficient in R
and x
is a term in X
.
We associate to such a formal sum a coordinate function X → R
(FormalSum.coords
).
We see that having the same coordinate functions gives an equivalence relation on the formal sums.
The free module (FreeModule
) is then defined as the corresponding quotient of such formal sums.
We also give an alternative description via moves, which is more convenient for universal properties.
Formal sums #
A formal sum represents an R
-linear combination of finitely many elements of X
.
This is implemented as a list R × X
, which associates to each element X
of the list a coefficient from R
.
Coordinate functions and Supports #
- We define coordinate functions X → R for formal sums.
- We define (weak) support, relate non-zero coordinates.
- We prove decidable equality on a list (easy fact).
Coordinate functions #
The definition of coordinate functions is in two steps. We first define the coordinate for a pair (a,x)
, and then define the coordinate function for a formal sum by summing over such terms.
Coordinates for a formal sum with one term.
Homomorphism property for coordinates for a formal sum with one term.
Associativity of scalar multiplication coordinates for a formal sum with one term.
Coordinates for a formal sum with one term with scalar 0
.
The coordinates for a formal sum.
Equations
- FormalSum.coords [] x = 0
- FormalSum.coords (h :: t) x = monomCoeff R X x h + FormalSum.coords t x
Support of a formal sum #
We next define the support of a formal sum and prove the property that coordinates vanish outside the support.
Support contains elements x : X
where the coordinate is not 0
.
Equality of coordinates on a list #
We define equality of coordinates on a list and prove that it is decidable and implied by equality of formal sums.
The condition of being equal on all elements is a given list
Equations
- equalOnList [] f g = (true = true)
- equalOnList (h :: t) f g = (f h = g h ∧ equalOnList t f g)
Equal functions are equal on arbitrary supports.
Functions equal on support l
are equal on each x ∈ l
.
Decidability of equality on list.
Quotient Free Module #
- We define relation by having equal coordinates
- We show this is an equivalence relation and define the quotient
Relation by equal coordinates.
Equations
- eqlCoords R X s₁ s₂ = (FormalSum.coords s₁ = FormalSum.coords s₂)
Relation by equal coordinates is reflexive.
Relation by equal coordinates is an equivalence relation.
Setoid based on equal coordinates.
Equations
- formalSumSetoid R X = { r := eqlCoords R X, iseqv := (_ : Equivalence (eqlCoords R X)) }
Equations
- One or more equations did not get rendered due to their size.
Decidable equality on quotient free modules #
We show that the free module F[X]
has decidable equality. This has two steps:
- show decidable equality for images of formal sums.
- lift to quotient (by relating to formal sums).
We also show that the coordinate functions are defined on the quotient.
Decidable equality for quotient elements in the free module
Equations
- One or more equations did not get rendered due to their size.
Lift to quotient #
Boolean equality on support.
Equations
- FreeModule.beqOnSupport l f g = List.all l fun x => decide (f x = g x)
Equality on support from boolean equality.
Boolean equality on support gives equal quotients.
Boolean equality for the quotient via lifting
Equations
- One or more equations did not get rendered due to their size.
Boolean equality for the quotient is equality.
Boolean inequality for the quotient is inequality.
Decidable equality for the free module.
Equations
- FreeModule.decEq x₁ x₂ = match p : FreeModule.beq_quot x₁ x₂ with | true => isTrue (_ : x₁ = x₂) | false => isFalse (_ : ¬x₁ = x₂)
Induced coordinates on the quotient. #
Coordinates are well defined on the quotient.
coordinates for the quotient
Equations
- FreeModule.coordinates x₀ = Quotient.lift (fun s => FormalSum.coords s x₀) (_ : ∀ (a b : FormalSum R X), a ≈ b → FormalSum.coords a x₀ = FormalSum.coords b x₀)
Module structure #
We define the module structure on the quotient of the free module by the equivalence relation.
- We define scalar multiplication and addition on formal sums.
- We show that we have induced operations on the quotient.
- We show that the induced operations give a module structure on the quotient.
Scalar multiplication: on formal sums and on the quotient. #
Scalar multiplication on formal sums.
Equations
- FormalSum.scmul x [] = []
- FormalSum.scmul x (h :: t) = match h with | (a₀, x₀) => (x * a₀, x₀) :: FormalSum.scmul x t
Coordinates after scalar multiplication.
Addition: on formal sums and on the quotient. #
Coordinates add when appending.
Properties of operations on formal sums. #
Associativity for scalar multiplication for formal sums.
Distributivity for the module operations.
Module properties for the free module. #
The zero element of the free module.
Equations
- FreeModule.zero = Quotient.mk (formalSumSetoid R X) []
Multiplication by 0 : R
.
The module is an additive commutative group, mainly proved as a check
Equivalent definition of the relation via moves #
For conceptual results such as the universal property (needed for the group ring structure) it is useful to define the relation on the free module in terms of moves. We do this, and show that this is the same as the relation defined by equality of coordinates.
- We define elementary moves on formal sums
- We show coordinates equal if and only if related by elementary moves
- Hence can define map on Free Module when invariant under elementary moves
- zeroCoeff: ∀ {R X : Type} [inst : Ring R] [inst_1 : DecidableEq R] [inst_2 : DecidableEq X] (tail : FormalSum R X) (x : X) (a : R), a = 0 → ElementaryMove R X ((a, x) :: tail) tail
- addCoeffs: ∀ {R X : Type} [inst : Ring R] [inst_1 : DecidableEq R] [inst_2 : DecidableEq X] (a b : R) (x : X) (tail : FormalSum R X), ElementaryMove R X ((a, x) :: (b, x) :: tail) ((a + b, x) :: tail)
- cons: ∀ {R X : Type} [inst : Ring R] [inst_1 : DecidableEq R] [inst_2 : DecidableEq X] (a : R) (x : X) (s₁ s₂ : FormalSum R X), ElementaryMove R X s₁ s₂ → ElementaryMove R X ((a, x) :: s₁) ((a, x) :: s₂)
- swap: ∀ {R X : Type} [inst : Ring R] [inst_1 : DecidableEq R] [inst_2 : DecidableEq X] (a₁ a₂ : R) (x₁ x₂ : X) (tail : FormalSum R X), ElementaryMove R X ((a₁, x₁) :: (a₂, x₂) :: tail) ((a₂, x₂) :: (a₁, x₁) :: tail)
Elementary moves for formal sums.
Instances For
Equations
- FreeModuleAux R X = Quot (ElementaryMove R X)
Image in the quotient (i.e., actual, not formal, sum).
Equations
- FormalSum.sum s = Quot.mk (ElementaryMove R X) s
Equivalence by having the same image.
Equations
- s₁ ≃ s₂ = (FormalSum.sum s₁ = FormalSum.sum s₂)
Equations
- FormalSum.«term_≃_» = Lean.ParserDescr.trailingNode `FormalSum.term_≃_ 65 66 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ≃ ") (Lean.ParserDescr.cat `term 66))
Invariance of coordinates under elementary moves #
Coordinates are invariant under moves.
Coordinates on the quotients.
Equations
- FreeModuleAux.coeff x₀ = Quot.lift (fun s => FormalSum.coords s x₀) (_ : ∀ (s₁ s₂ : FormalSum R X), ElementaryMove R X s₁ s₂ → FormalSum.coords s₁ x₀ = FormalSum.coords s₂ x₀)
Commutative diagram for coordinates.
Coordinates well-defined under the equivalence generated by moves.
Equal coordinates implies related by elementary moves. #
Cons respects equivalence.
If a coordinate x
for a formal sum s
is non-zero, s
is related by moves to a formal sum with first term x
with coefficient its coordinates, and the rest shorter than s
.
If all coordinates are zero, then moves relate to the empty sum.
If coordinates are equal, the sums are related by moves.
Functions invariant under moves pass to the quotient. #
Lifting functions to the move induced quotient.
Basic Repr
#
An instance of Repr
on Free Modules, mainly for debugging (fairly crude). This is implemented by constructing a norm ball containing all the non-zero coordinates, and then making a list of non-zero coordinates
Equations
- maxNormSuccOnSupp norm crds [] = 0
- maxNormSuccOnSupp norm crds (h :: t) = if crds h ≠ 0 then max (norm h + 1) (maxNormSuccOnSupp norm crds t) else maxNormSuccOnSupp norm crds t
Equations
- FormalSum.normSucc norm s = maxNormSuccOnSupp norm (FormalSum.coords s) (FormalSum.support s)
Equations
- natCube = { norm := id, cube := fun n => List.reverse (List.range n) }
Equations
- intCube = { norm := Int.natAbs, cube := fun n => List.map Int.ofNat (List.reverse (List.range n)) ++ List.map Int.negSucc (List.range (n - 1)) }
Equations
- One or more equations did not get rendered due to their size.
Equations
- FreeModule.coeffList x = List.filterMap (fun x₀ => let a := FreeModule.coordinates x₀ x; if a = 0 then none else some (a, x₀)) (NormCube.cube (FreeModule.normBound x))
Equations
- basicRepr = { reprPrec := fun x x_1 => Std.Format.text (reprStr (FreeModule.coeffList x)) }