AlgebraicNumbersImpl:
CEDAR
PROGRAM
IMPORTS Rope, IO, RatIntervals, BigRats
EXPORTS AlgebraicNumbers =
Errors
BadGroundField: PUBLIC ERROR [groundStructure: AC.Structure] = CODE;
SyntaxError: PUBLIC ERROR [kind: ATOM ← $Unspecified] = CODE;
Constructors
MakeAlgebraicNumber:
PUBLIC
PROC [minPolyRing:
AC.Structure, minimalPolynomial:
POL.Polynomial, real:
BOOL ←
FALSE, isolatingInterval:
RI.RatInterval ←
NIL]
RETURNS [AlgebraicNumber] ~ {
data: POL.PolynomialRingData ← NARROW[minPolyRing.instanceData];
groundStructure: AC.Structure ← data.coeffRing;
IF groundStructure.class.category#field AND groundStructure.class.category#divisionAlgebra THEN ERROR BadGroundField[groundStructure];
IF
NOT real
THEN {
IF groundStructure.class.algebraicallyClosedField THEN ERROR;
RETURN[
NEW[AlgebraicNumberRec ← [
minPolyRing: minPolyRing,
minimalPolynomial: minimalPolynomial
]] ]
}
ELSE {
IF NOT groundStructure.class.realField THEN ERROR;
IF groundStructure.class.realClosedField THEN ERROR;
IF isolatingInterval = NIL THEN ERROR;
RETURN[
NEW[AlgebraicNumberRec ← [
minPolyRing: minPolyRing,
minimalPolynomial: minimalPolynomial,
real: TRUE,
isolatingInterval: isolatingInterval
]] ]
};
};
IO
ReadAlgebraicNumber:
PUBLIC
PROC [in:
IO.
STREAM, minPolyRing:
AC.Structure, real:
BOOL ←
FALSE]
RETURNS [out: AlgebraicNumber] ~ {
minimalPolynomial: POL.Polynomial ← NARROW[minPolyRing.class.read[in, minPolyRing] ]; -- should check monic, irreducible
data: POL.PolynomialRingData ← NARROW[minPolyRing.instanceData];
groundStructure: AC.Structure ← data.coeffRing;
puncChar: CHAR;
IF groundStructure # BR.BigRats THEN ERROR BadGroundField[groundStructure];
IF
NOT real
THEN {
IF groundStructure.class.algebraicallyClosedField THEN ERROR;
RETURN[
NEW[AlgebraicNumberRec ← [
minPolyRing: minPolyRing,
minimalPolynomial: minimalPolynomial
]] ]
}
ELSE {
isolatingInterval: RI.RatInterval;
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
IF puncChar # ', THEN SyntaxError[$CommaExpected];
[]← in.SkipWhitespace[];
isolatingInterval ← RI.ReadRatInterval[in];
RETURN[
NEW[AlgebraicNumberRec ← [
minPolyRing: minPolyRing,
minimalPolynomial: minimalPolynomial,
real: TRUE,
isolatingInterval: isolatingInterval
]] ]
};
};
ReadRealAlgebraicNumber: PUBLIC PROC [in: IO.STREAM, minPolyRing: AC.Structure] RETURNS [out: AlgebraicNumber] ~ {
conjugatesDefinition: AlgebraicNumber ← ReadAlgebraicNumber[in, minPolyRing];
isolatingInterval: RI.RatInterval ← RI.ReadRatInterval[in];
out ← NEW[RealAlgebraicNumberRec ← [conjugatesDefinition: conjugatesDefinition, isolatingInterval: isolatingInterval] ]; -- groundField must be real
};
AlgebraicNumberFromRope:
PUBLIC
PROC [in: Rope.
ROPE, minPolyRing:
AC.Structure, real:
BOOL ←
FALSE]
RETURNS [out: AlgebraicNumber] = {
out ← ReadAlgebraicNumber[IO.RIS[in], minPolyRing, real];
};
AlgebraicNumberToRope:
PUBLIC
PROC [in: AlgebraicNumber]
RETURNS [out: Rope.
ROPE] ~ {
out ← Rope.Concat[in.minPolyRing.class.toRope[in.minimalPolynomial], ", \n"];
IF in.real THEN out ← Rope.Concat[out, RI.RatIntervalToRope[in.isolatingInterval] ];
};
WriteAlgebraicNumber:
PUBLIC
PROC [in: AlgebraicNumber, out:
IO.
STREAM] = {
out.PutRope[ AlgebraicNumberToRope[in] ]
};