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;
}