Classes for Point Structures
ClassPrintName:
AC.PrintNameProc = {
data: PointStructureData ← NARROW[structure.instanceData];
RETURN[Rope.Cat[
"Points of dimension ",
Convert.RopeFromCard[data.dimension],
" over ",
data.coordinateStructure.class.printName[data.coordinateStructure]
] ];
};
ClassShortPrintName:
AC.PrintNameProc = {
data: PointStructureData ← NARROW[structure.instanceData];
RETURN[Rope.Cat[
"P",
Convert.RopeFromCard[data.dimension],
"(",
data.coordinateStructure.class.shortPrintName[data.coordinateStructure],
")"
] ];
};
ClassReportOps:
AC.ReportOpsProc = {
class: AC.StructureClass ← structure.class;
opNames ←
CONS["MainCoordinate", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← MainCood ], refOps];
opNames ←
CONS["RemoveMainCoordinate", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← RemoveMainCood ], refOps];
IF class.equal #
NIL
THEN { opNames ←
CONS["Equal", opNames];
refOps ← CONS[NEW[AC.EqualityOp ← Equal], refOps] };
IF class.multiply #
NIL
THEN { opNames ←
CONS["Multiply", opNames];
refOps ← CONS[NEW[AC.BinaryOp ← Multiply], refOps] };
IF class.subtract #
NIL
THEN { opNames ←
CONS["Subtract", opNames];
refOps ← CONS[NEW[AC.BinaryOp ← Subtract], refOps] };
IF class.negate #
NIL
THEN { opNames ←
CONS["Negate", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← Negate], refOps] };
IF class.add #
NIL
THEN { opNames ←
CONS["Add", opNames];
refOps ← CONS[NEW[AC.BinaryOp ← Add], refOps] };
opNames ←
CONS["FromLinearRope", opNames];
refOps ← CONS[NEW[AC.FromRopeOp ← FromRope], refOps];
};
ClassCharacteristic:
AC.StructureRankOp = {
data: PointStructureData ← NARROW[structure.instanceData];
RETURN[ data.coordinateStructure.class.characteristic[data.coordinateStructure] ]
};
ClassIsElementOf:
AC.ElementOfProc = {
Assumes that if item is a point, then it really belongs to the domain pointed to by its structure field.
IF NOT structure.class.structureEqual[structure, item.structure] THEN RETURN[FALSE];
RETURN[ TRUE ]
};
ClassDimension:
AC.StructureRankOp = {
data: PointStructureData ← NARROW[structure.instanceData];
RETURN[data.dimension]
};
ClassLegalFirstChar:
AC.LegalFirstCharOp = {
SELECT char
FROM
'[ , '(=> RETURN[TRUE];
ENDCASE;
RETURN[FALSE];
};
ClassToExpr:
AC.ToExprOp = {
data: PointStructureData;
inData: PointData;
outRow: LIST OF MathExpr.EXPR ← NIL;
IF in=NIL OR in.data=NIL THEN RETURN[MathConstructors.MakeVariable["NilPoint"]];
inData ← NARROW[in.data];
data ← NARROW[in.structure.instanceData];
FOR j:
NAT
DECREASING
IN [1..data.dimension]
DO
outRow ← CONS[data.coordinateStructure.class.toExpr[inData[j] ], outRow];
ENDLOOP;
out ← MathConstructors.MakeVector[data.dimension, outRow, TRUE];
};
ClassZero:
AC.NullaryOp = {
structureData: PointStructureData ← NARROW[structure.instanceData];
coordinateStructure: AC.Structure ← structureData.coordinateStructure;
RETURN[ ImbedSc[coordinateStructure.class.zero[coordinateStructure], structure] ]
};
ClassOne:
AC.NullaryOp = {
structureData: PointStructureData ← NARROW[structure.instanceData];
coordinateStructure: AC.Structure ← structureData.coordinateStructure;
RETURN[ ImbedSc[coordinateStructure.class.one[coordinateStructure], structure] ]
};
pointStructureOps: PointOps ←
NEW[PointOpsRec ← [
removeMainCoordinate: RemoveMainCood,
mainCoordinate: MainCood,
imbedScalar: ImbedSc,
makePoint: MakePt
] ];
pointProp: Atom.DottedPair ← NEW[Atom.DottedPairNode← [$PointStructure, pointStructureOps]];
pointsOverSetClass:
PUBLIC
AC.StructureClass ←
NEW[
AC.StructureClassRec ← [
category: set,
printName: ClassPrintName,
shortPrintName: ClassShortPrintName,
structureEqual: AC.defaultStructureEqualityTest,
isElementOf: ClassIsElementOf,
legalFirstChar: ClassLegalFirstChar,
read: Read,
fromRope: FromRope,
toRope: ToRope, toIndexRope: ToIndexRope,
write: Write,
toExpr: ClassToExpr,
equal: Equal,
integralDomain: FALSE,
gcdDomain: FALSE,
euclideanDomain: FALSE,
propList: LIST[pointProp]
] ];
pointsOverAbelianGroupClass:
PUBLIC
AC.StructureClass ←
NEW[
AC.StructureClassRec ← [
category: group,
printName: ClassPrintName,
shortPrintName: ClassShortPrintName,
structureEqual: AC.defaultStructureEqualityTest,
isElementOf: ClassIsElementOf,
legalFirstChar: ClassLegalFirstChar,
read: Read,
fromRope: FromRope,
toRope: ToRope,
toIndexRope: ToIndexRope,
write: Write,
toExpr: ClassToExpr,
add: Add,
negate: Negate,
subtract: Subtract,
zero: ClassZero,
multiply: ClassMultiply,
commutative: FALSE,
one: ClassOne,
equal: Equal,
integralDomain: FALSE,
gcdDomain: FALSE,
euclideanDomain: FALSE,
propList: LIST[pointProp]
] ];
pointsOverRingClass:
PUBLIC
AC.StructureClass ←
NEW[
AC.StructureClassRec ← [
category: ring,
printName: ClassPrintName,
shortPrintName: ClassShortPrintName,
structureEqual: AC.defaultStructureEqualityTest,
characteristic: ClassCharacteristic,
isElementOf: ClassIsElementOf,
legalFirstChar: ClassLegalFirstChar,
read: Read,
fromRope: FromRope,
toRope: ToRope,
toIndexRope: ToIndexRope,
write: Write,
toExpr: ClassToExpr,
add: Add,
negate: Negate,
subtract: Subtract,
zero: ClassZero,
multiply: Multiply,
commutative: FALSE, -- commutative: FALSE may be bogus
one: ClassOne,
equal: Equal,
integralDomain: FALSE,
gcdDomain: FALSE,
euclideanDomain: FALSE,
propList: LIST[pointProp]
] ];
Point Constructors
ImbedScalar:
PUBLIC AC.UnaryImbedOp ~ {
structureData: PointStructureData ← NARROW[structure.instanceData];
coordinateStructure: AC.Structure ← structureData.coordinateStructure;
outData: PointData ← NEW[PointDataRec[structureData.dimension] ];
IF NOT in.structure.class.structureEqual[in.structure, coordinateStructure] THEN ERROR TypeError[];
FOR i: NAT IN [1..structureData.dimension] DO outData[i] ← in; ENDLOOP;
out ← NEW[AC.ObjectRec ← [structure: structure, data: outData] ];
};
MakePoint:
PUBLIC AC.ListImbedOp ~ {
structureData: PointStructureData ← NARROW[structure.instanceData];
coordinateStructure: AC.Structure ← structureData.coordinateStructure;
length: NAT ← 0;
ptr: LIST OF AC.Object ← data;
outData: PointData;
WHILE ptr#NIL DO length ← length + 1; ptr ← ptr.rest ENDLOOP;
IF length # structureData.dimension THEN ERROR;
outData ← NEW[PointDataRec[length] ];
FOR i:
NAT
IN [1..length]
DO
outData[i] ← data.first;
data ← data.rest;
ENDLOOP;
out ← NEW[AC.ObjectRec ← [structure: structure, data: outData] ];
};
Conversion and IO
Read:
PUBLIC
AC.ReadOp ~ {
structureData: PointStructureData ← NARROW[structure.instanceData];
dimension: NAT ← structureData.dimension;
outData: PointData ← NEW[PointDataRec[dimension] ];
coordinateStructure: AC.Structure ← structureData.coordinateStructure;
puncChar: CHAR;
out ← NEW[AC.ObjectRec ← [structure: structure, data: outData] ];
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
IF puncChar # '( AND puncChar # '[ THEN ERROR;
[]← in.SkipWhitespace[];
FOR i:
NAT
IN [1 .. dimension]
DO
outData[i] ← coordinateStructure.class.read[in, coordinateStructure];
IF i < dimension
THEN {
[]← in.SkipWhitespace[];
IF in.PeekChar[]=', THEN [] ← in.GetChar[]; -- flush comma if present
};
ENDLOOP;
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
IF puncChar # ') AND puncChar # '] THEN ERROR;
[]← in.SkipWhitespace[];
};
FromRope:
PUBLIC
AC.FromRopeOp ~ {
out ← Read[IO.RIS[in], structure];
};
ToRope:
PUBLIC
AC.ToRopeOp ~ {
pointStructureData: PointStructureData ← NARROW[in.structure.instanceData];
coordinateStructure: AC.Structure ← pointStructureData.coordinateStructure;
inData: PointData ← NARROW[in.data];
out ← "( ";
FOR i:
NAT
IN [1..inData.dimensionPlus1)
DO
out ← Rope.Concat[ out, coordinateStructure.class.toRope[inData[i] ] ];
IF i < inData.dimensionPlus1-1 THEN out ← Rope.Concat[out,", "];
ENDLOOP;
out ← Rope.Concat[ out, " )" ];
};
ToIndexRope:
PUBLIC
AC.ToRopeOp ~ {
out ← "Point";
};
Write:
PUBLIC AC.WriteOp ~ {
stream.PutRope[ ToRope[in] ]
};
Point Structure Operations
IsPointStructure:
PUBLIC
AC.StructurePredicate ~ {
IF Atom.GetPropFromList[structure.class.propList, $PointStructure] # NIL THEN RETURN[TRUE] ELSE RETURN[FALSE];
};
RemoveMainCood:
PUBLIC
AC.UnaryOp ~ {
pointStructureData: PointStructureData ← NARROW[arg.structure.instanceData];
dimension: NAT ← pointStructureData.dimension;
coordinateStructure: AC.Structure ← pointStructureData.coordinateStructure;
PData: PointData ← NARROW[arg.data];
QData: PointData ← NEW[PointDataRec[dimension-1] ];
FOR i:NAT IN [1..dimension - 1] DO QData[i] ← PData[i] ENDLOOP;
RETURN[
NEW[
AC.ObjectRec ← [
structure: MakePointStructure[coordinateStructure, dimension-1],
data: QData
] ] ];
};
MainCood:
PUBLIC
AC.UnaryOp ~ {
pointStructureData: PointStructureData ← NARROW[arg.structure.instanceData];
dimension: NAT ← pointStructureData.dimension;
PData: PointData ← NARROW[arg.data];
RETURN[ PData[dimension] ];
};
Arithmetic
Add:
PUBLIC
AC.BinaryOp ~ {
pointStructureData: PointStructureData ← NARROW[firstArg.structure.instanceData];
dimension: NAT ← pointStructureData.dimension;
coordinateStructure: AC.Structure ← pointStructureData.coordinateStructure;
firstData: PointData ← NARROW[firstArg.data];
secondData: PointData ← NARROW[secondArg.data];
resultData: PointData ← NEW[PointDataRec[dimension] ];
FOR i:
NAT
IN [1..dimension]
DO
resultData[i] ← coordinateStructure.class.add[firstData[i], secondData[i] ];
ENDLOOP;
RETURN[
NEW[
AC.ObjectRec ← [
structure: firstArg.structure,
data: resultData
] ] ];
};
Negate:
PUBLIC
AC.UnaryOp ~ {
pointStructureData: PointStructureData ← NARROW[arg.structure.instanceData];
dimension: NAT ← pointStructureData.dimension;
coordinateStructure: AC.Structure ← pointStructureData.coordinateStructure;
data: PointData ← NARROW[arg.data];
resultData: PointData ← NEW[PointDataRec[dimension] ];
FOR i:
NAT
IN [1..dimension]
DO
resultData[i] ← coordinateStructure.class.negate[data[i] ];
ENDLOOP;
RETURN[
NEW[
AC.ObjectRec ← [
structure: arg.structure,
data: resultData
] ] ];
};
Subtract:
PUBLIC
AC.BinaryOp ~ {
pointStructureData: PointStructureData ← NARROW[firstArg.structure.instanceData];
dimension: NAT ← pointStructureData.dimension;
coordinateStructure: AC.Structure ← pointStructureData.coordinateStructure;
firstData: PointData ← NARROW[firstArg.data];
secondData: PointData ← NARROW[secondArg.data];
resultData: PointData ← NEW[PointDataRec[dimension] ];
FOR i:
NAT
IN [1..dimension]
DO
resultData[i] ← coordinateStructure.class.subtract[firstData[i], secondData[i] ];
ENDLOOP;
RETURN[
NEW[
AC.ObjectRec ← [
structure: firstArg.structure,
data: resultData
] ] ];
};
Multiply:
PUBLIC
AC.BinaryOp ~ {
pointStructureData: PointStructureData ← NARROW[firstArg.structure.instanceData];
dimension: NAT ← pointStructureData.dimension;
coordinateStructure: AC.Structure ← pointStructureData.coordinateStructure;
firstData: PointData ← NARROW[firstArg.data];
secondData: PointData ← NARROW[secondArg.data];
resultData: PointData ← NEW[PointDataRec[dimension] ];
FOR i:
NAT
IN [1..dimension]
DO
resultData[i] ← coordinateStructure.class.multiply[firstData[i], secondData[i] ];
ENDLOOP;
RETURN[
NEW[
AC.ObjectRec ← [
structure: firstArg.structure,
data: resultData
] ] ];
};
Start Code
pointsOverSetClass ← AC.MakeClass["PointsOverSetClass", NIL, NIL];
pointsOverAbelianGroupClass ← AC.MakeClass["PointsOverAbelianGroupClass", NIL, NIL];
pointsOverRingClass ← AC.MakeClass["PointsOverRingClass", NIL, NIL];