A MONOID is a set M endowed with an operation
which is associative and which admits a neutral element.
If this operation is commutative (that is
(x, y
M) xy = yx) then
(![]() ![]() ![]() ![]() |
(38) |
define Monoid: Category == ExpressionType with { 1: %; *: (%, %) -> %; ^: (%, Integer) -> %; one?: % -> Boolean; times!: (%, %) -> %; default { one?(a:%):Boolean == a = 1; times!(a:%, b:%):% == { a * b; } } } define AbelianMonoid: Category == ExpressionType with { 0: %; +: (%, %) -> %; *: (Integer, %) -> %; add!: (%, %) -> %; zero?: % -> Boolean; default { zero?(x:%):Boolean == x = 0; add!(a:%, b:%):% == { a + b; } } }
A GROUP is a monoid G where every element has a symmetric element. With multiplicative notations this writes
(![]() ![]() ![]() ![]() |
(39) |
(![]() ![]() ![]() ![]() |
(40) |
define Group: Category == Monoid with { /: (%, %) -> %; inv: % -> %; default (x:%) / (y:%):% == x * inv y; } define AbelianGroup: Category == Join(AdditiveType, AbelianMonoid)
A RING (WITH UNITY) is
(![]() ![]() |
(41) |
define Ring: Category == Join(AbelianGroup, ArithmeticType, Monoid) with { characteristic: Z; coerce: Z -> %; .................... random: () -> % default ((x: %) ^ (n: MachineInteger)): % == x^(n::Z); ((n: AldorInteger) * (x: %)): % == n::% * x; random(): % == random()$Z :: %; ((x: %) ^ (n: AldorInteger)): % == binaryExponentiation(x, n)$BinaryPowering(%,Z); }A ring is said commutative if its multiplication is commutative. Rational numbers, univariate polynomials over
Let R be a commutative ring.
The element a R is an associate of the element b
R
if there exists a unit u
R such that
a = b u.
The operation unitNormal below returns
(b, v, u) given a such that
a = b u and
u v = 1.
If this choice is canonical (that is if for every a and a'
such that
a' is associate with a the first field of unitNormal(a)
is equal to that of unitNormal(a')
then canonicalUnitNormal? returns true.
define CommutativeRing: Category == Ring with { canonicalUnitNormal?: Boolean unitNormal: % -> (%, %, %); reciprocal: % -> Partial(%); unit?: % -> Boolean; ................................. cutoff: MachineInteger -> MachineInteger }
AN INTEGRAL DOMAIN is a ring with no zero-divisors, that is a ring where if the product of two elements is zero then at least of them must be zero. Let R be an integral domain. Let a, b, q1, q2 be in R. Assume that we have
a = b q1 = b q2 and b ![]() |
(42) |
define IntegralDomain: Category == CommutativeRing with { exactQuotient: (%, %) -> Partial(%); ...................................... }
A GCD DOMAIN is an integral domain R where an operation
gcd : (R, R) R is defined and satisfies the following properties
define GcdDomain: Category == IntegralDomain with { gcd: (%, %) -> % gcd!: (%, %) -> % gcd: Generator(%) -> % lcm: (%, %) -> % lcm: List(%) -> % gcdquo: (%, %) -> (%, %, %) gcdquo: List(%) -> (%, List(%)) ............................... }
UNIQUE FACTORIZATION DOMAINS. A nonzero nonunit p R is reducible
if there are two nonunits c, d
R such that
p = c d,
otherwise p is irreducible.
Units are neither reducible nor irreducible.
A nonzero nonunit p
R is prime if
for every c, d
R we have
we have
(p | cd ) ![]() |
(43) |
define FactorizationRing: Category == GcdDomain with { ................................................... }
AN EUCLIDEAN DOMAIN is an integral domain R endowed with a function
d : R
{ -
}
such that for all a, b
R with b
0
there exist q, r
R such that
a = bq + r and d (r) < d (b). | (44) |
define EuclideanDomain: Category == GcdDomain with { divide: (%, %) -> (%, %); quo: (%, %) -> %; rem: (%, %) -> %; euclid: (%, %) -> %; euclideanSize: % -> Integer; extendedEuclidean: (%, %) -> (%, %, %); }In the category EuclideanDomain above the operation euclid denotes the gcd computed by the Euclidean algorithm.
A FIELD is a ring (with unity) where every nonzero element is a unit. In libalgebra fields are commutative rings. Then it follows that they are also integral domains, gcd domains and Euclidean domains.
define Field: Category == Join(EuclideanDomain, Group) with { default { canonicalUnitNormal?:Boolean == true; euclideanSize(a:%):Integer == 0; unit?(x:%):Boolean == true; (a:%) quo (b:%):% == a / b; (a:%) rem (b:%):% == 0; gcd(a:%, b:%):% == { zero? a and zero? b => 0; 1 } (a:%)^(n:Integer):% == { import from BinaryPowering(%, Integer); n > 0 => binaryExponentiation(a, n); inv binaryExponentiation(a, -n); }
THE HIERARCHY OF ALGEBRAIC TYPES
FRACTIONCATEGORY.
define FractionCategory(R: IntegralDomain): Category == Join(IntegralDomain, Algebra R) with { if R has CharacteristicZero then CharacteristicZero; if R has FiniteCharacteristic then FiniteCharacteristic; denominator: % -> R; numerator: % -> R; }