CellsImpl:
CEDAR
PROGRAM
IMPORTS Rope, Atom, IO, Convert, Imager, ImagerPath, AlgebraClasses, MathConstructors, FormulaOperators, Ints, Points, Formulas, SamplePoints, CoveringSets, Colors
EXPORTS Cells =
Class for Cell Structures
ClassPrintName:
AC.PrintNameProc = {
data: CellStructureData ← NARROW[structure.instanceData];
basisSigStructData: PTS.PointStructureData ← NARROW[data.basisSignatureStructure.instanceData];
numBasisElements: CARDINAL ← basisSigStructData.dimension;
out: Rope.
ROPE ← Rope.Cat[
"Cells over ",
data.inputPolynomialRing.class.printName[data.inputPolynomialRing],
" and ",
data.minPolyRing.class.printName[data.minPolyRing]
];
RETURN[Rope.Cat[out,
" with ",
Convert.RopeFromCard[numBasisElements],
" basis elements"
] ];
};
ClassShortPrintName:
AC.PrintNameProc = {
data: CellStructureData ← NARROW[structure.instanceData];
basisSigStructData: PTS.PointStructureData ← NARROW[data.basisSignatureStructure.instanceData];
numBasisElements: CARDINAL ← basisSigStructData.dimension;
out: Rope.
ROPE ← Rope.Cat[
"Cells(",
data.inputPolynomialRing.class.shortPrintName[data.inputPolynomialRing],
" , ",
data.minPolyRing.class.shortPrintName[data.minPolyRing],
" , "];
RETURN[Rope.Cat[out,
Convert.RopeFromCard[numBasisElements],
")"
] ];
};
ClassReportOps:
AC.ReportOpsProc = {
opNames ← CONS["Display2D", opNames];
refOps ← CONS[NEW[AC.Display2DOp ← Disp2D ], refOps];
opNames ← CONS["BoundingBox", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← BoundBox ], refOps];
opNames ← CONS["SetColor", opNames];
refOps ← CONS[NEW[AC.BinaryInPlaceOp ← SetCol ], refOps];
opNames ← CONS["Color", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← Col ], refOps];
opNames ← CONS["CoveringSet", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← CoverSet ], refOps];
opNames ← CONS["DefiningFormula", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← DefiningForm ], refOps];
opNames ← CONS["SamplePoint", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← SamplePt ], refOps];
opNames ← CONS["BasisSignature", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← BasisSig ], refOps];
opNames ← CONS["AdjacentCells", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← AdjCells ], refOps];
opNames ← CONS["Cad", opNames];
refOps ← CONS[NEW[AC.UnaryOp ← GetCad ], refOps];
opNames ← CONS["FromLinearRope", opNames];
refOps ← CONS[NEW[AC.FromRopeOp ← FromRope], refOps];
};
ClassIsElementOf:
AC.ElementOfProc = {
Assumes that if item is a cell, then it really belongs to the structure pointed to by its structure field.
IF NOT structure.class.structureEqual[structure, item.structure] THEN RETURN[FALSE];
RETURN[ TRUE ]
};
ClassLegalFirstChar:
AC.LegalFirstCharOp = {
SELECT char
FROM
'[ , '(=> RETURN[TRUE];
ENDCASE;
RETURN[FALSE];
};
ClassToExpr: AC.ToExprOp = {
inData: CellData;
outColumn, tail: LIST OF MathExpr.EXPR ← NIL;
colLength: CARDINAL;
IF in=NIL THEN {
out ← MathConstructors.MakeVector[1, LIST[MathConstructors.MakeVariable["NILCELL"]], FALSE];
RETURN;
};
inData ← NARROW[in.data];
IF inData=NIL THEN {
out ← MathConstructors.MakeVector[1, LIST[MathConstructors.MakeVariable["NILCELL"]], FALSE];
RETURN;
};
outColumn ← tail ← LIST[MathConstructors.MakeVariable["BEGINCELL"] ];
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["INDEX"] ];
tail ← tail.rest ← LIST[inData.index.structure.class.toExpr[inData.index] ];
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["SAMPLEPOINT"] ];
IF inData.samplePoint # NIL THEN
tail ← tail.rest ← LIST[inData.samplePoint.structure.class.toExpr[inData.samplePoint] ]
ELSE
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["NILSAMPLEPOINT"] ];
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["DEFININGFORMULA"] ];
IF inData.definingFormula # NIL THEN
tail ← tail.rest ← LIST[inData.definingFormula.structure.class.toExpr[inData.definingFormula] ]
ELSE
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["NILDEFININGFORMULA"] ];
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["BEGINCOVERINGSET"] ];
IF inData.coveringSet # NIL THEN
tail ← tail.rest ← LIST[inData.coveringSet.structure.class.toExpr[inData.coveringSet] ]
ELSE
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["NILCOVERINGSET"] ];
tail ← tail.rest ← LIST[MathConstructors.MakeVariable["ENDCELL"] ];
colLength ← 10;
out ← MathConstructors.MakeVector[colLength, outColumn, FALSE];
};
ClassToExpr:
AC.ToExprOp = {
inData: CellData;
outColumn, tail: LIST OF MathExpr.EXPR ← NIL;
colLength: CARDINAL ← 1;
IF in=
NIL
THEN {
out ← MathConstructors.MakeVector[colLength, LIST[MathConstructors.MakeVariable["NILCELL"]], FALSE];
RETURN;
};
inData ← NARROW[in.data];
IF inData=
NIL
THEN {
out ← MathConstructors.MakeVector[colLength, LIST[MathConstructors.MakeVariable["NILCELL"]], FALSE];
RETURN;
};
outColumn ← tail
← LIST[MathConstructors.MakeVariable[
Rope.Concat[Convert.RopeFromCard[inData.dimension], "-Cell"] ] ];
tail ← tail.rest ← LIST[inData.index.structure.class.toExpr[inData.index] ];
colLength ← 2;
out ← MathConstructors.MakeVector[colLength, outColumn, FALSE];
};
cellOps: CellOps ←
NEW[CellOpsRec ← [
cad: GetCad,
adjacentCells: AdjCells,
basisSignature: BasisSig,
samplePoint: SamplePt,
definingFormula: DefiningForm,
coveringSet: CoverSet,
color: Col,
setColor: SetCol,
boundingBox: BoundBox,
display2D: Disp2D
] ];
cellProp: Atom.DottedPair ← NEW[Atom.DottedPairNode← [$CellStructure, cellOps]];
cellStructureClass:
PUBLIC
AC.StructureClass ←
NEW[
AC.StructureClassRec ← [
category: set,
printName: ClassPrintName,
shortPrintName: ClassShortPrintName,
structureEqual: AC.defaultStructureEqualityTest,
reportOps: ClassReportOps,
isElementOf: ClassIsElementOf,
legalFirstChar: ClassLegalFirstChar,
read: Read,
fromRope: FromRope,
toRope: ToRope,
toIndexRope: ToIndexRope,
write: Write,
toExpr: ClassToExpr,
integralDomain: FALSE,
gcdDomain: FALSE,
euclideanDomain: FALSE,
propList: LIST[cellProp]
] ];
Conversion and IO
cadVertexClass: PUBLIC Graphs.VertexClass ← Graphs.NewVertexClass[[
Expand: CellExpand
]];
CellExpand: PUBLIC Graphs.ExpandProc ~ {
cell: Cell ← NARROW[vertex.rep];
cellData: CellData ← NARROW[cell.data];
adjacencies: SEQ.Sequence ← cellData.adjacentCells;
adjacenciesData: SEQ.SequenceData ← NARROW[adjacencies.data];
FOR i:NAT IN [1..adjacenciesData.lengthPlus1 - 1] DO
otherCellData: CellData ← NARROW[adjacenciesData[i].data];
otherVertex ← otherCellData.abstractVertex;
edge: Graphs.Edge ← Graphs.AddEdge[vertex, otherVertex, Undirected, NIL, NIL];
edge: Graphs.Edge ← [
direction: Undirected,
label: NIL,
otherSide: cellData.abstractVertex
];
Consume.proc[edge, Consume.data];
ENDLOOP;
};
Read:
PUBLIC
AC.ReadOp ~ {
cellStructureData: CellStructureData ← NARROW[structure.instanceData];
inputPolynomialRing: AC.Structure ← cellStructureData.inputPolynomialRing;
minPolyRing: AC.Structure ← cellStructureData.minPolyRing;
basisSignatureStructure: AC.Structure ← cellStructureData.basisSignatureStructure;
polyRingData: POL.PolynomialRingData ← NARROW[inputPolynomialRing.instanceData];
ambientSpaceDimension: CARDINAL ← polyRingData.allVariables.lengthPlus1 - 1;
cellIndexStructure: AC.Structure ← PTS.MakePointStructure[Ints.Ints, ambientSpaceDimension];
formulaAlgebra: AC.Structure ← QFF.MakeFormulaAlgebra[inputPolynomialRing];
samplePointStructure: AC.Structure ← SP.MakeSamplePointStructure[inputPolynomialRing, minPolyRing];
coveringSetStructure: AC.Structure ← CS.MakeCoveringSetStructure[ambientSpaceDimension];
outData: CellData;
token: Rope.ROPE;
index: CellIndex;
basisSignature: Signature;
samplePoint: SP.SamplePoint ← NIL;
samplePointData: SP.SamplePointData;
definingFormula: QFF.Formula ← NIL;
coveringSet: CS.CoveringSet ← NIL;
token ← in.GetID[];
IF NOT Rope.Equal[token, "BEGINCELL"] THEN ERROR;
token ← in.GetID[];
IF NOT Rope.Equal[token, "INDEX"] THEN ERROR;
index ← cellIndexStructure.class.read[in, cellIndexStructure];
token ← in.GetID[];
IF Rope.Equal[token, "BASISSIGNATURE"]
THEN {
basisSignature ← basisSignatureStructure.class.read[in, basisSignatureStructure];
token ← in.GetID[];
};
IF Rope.Equal[token, "SAMPLEPOINT"]
THEN
{
samplePoint ← samplePointStructure.class.read[in, samplePointStructure];
token ← in.GetID[];
};
IF Rope.Equal[token, "DEFININGFORMULA"]
THEN {
definingFormula ← formulaAlgebra.class.read[in, formulaAlgebra];
token ← in.GetID[];
};
IF Rope.Equal[token, "BEGINCOVERINGSET"]
THEN {
coveringSet ← coveringSetStructure.class.read[in, coveringSetStructure];
token ← in.GetID[];
};
IF NOT Rope.Equal[token, "ENDCELL"] THEN ERROR;
outData ←
NEW[CellDataRec ← [
index: index,
basisSignature: basisSignature,
samplePoint: samplePoint,
definingFormula: definingFormula,
coveringSet: coveringSet
]];
out ← NEW[AC.ObjectRec ← [structure: structure, data: outData] ];
outData.dimension ← CellDim[out];
samplePointData ← NARROW[samplePoint.data];
samplePointData.cell ← out; -- need to do the same for covering set
outData.abstractVertex ← NEW [Graphs.VertexPrivate ← [
class: cadVertexClass,
rep: out
]];
RETURN[out];
};
FromRope:
PUBLIC
AC.FromRopeOp ~ {
out ← Read[IO.RIS[in], structure];
};
ToIndexRope:
AC.ToRopeOp ~ {
inData: CellData ← NARROW[in.data];
out ← inData.index.structure.class.toRope[inData.index];
};
ToRope:
PUBLIC
AC.ToRopeOp ~ {
inData: CellData ← NARROW[in.data];
out ← "";
out ← "BEGINCELL\n";
out ← Rope.Concat[out, "INDEX\n"];
out ← Rope.Cat[out, inData.index.structure.class.toRope[inData.index], "\n"];
IF inData.basisSignature#
NIL
THEN {
out ← Rope.Concat[out, "BASISSIGNATURE\n"];
out ← Rope.Cat[out, inData.basisSignature.structure.class.toRope[inData.basisSignature], "\n"];
};
IF inData.samplePoint#
NIL
THEN {
out ← Rope.Concat[out, "SAMPLEPOINT\n"];
out ← Rope.Concat[out, inData.samplePoint.structure.class.toRope[inData.samplePoint]];
};
IF inData.definingFormula#
NIL
THEN {
out ← Rope.Concat[out, "DEFININGFORMULA\n"];
out ← Rope.Cat[out, inData.definingFormula.structure.class.toRope[inData.definingFormula], "\n"];
};
IF inData.coveringSet#
NIL
THEN {
out ← Rope.Concat[out, "BEGINCOVERINGSET\n"];
out ← Rope.Cat[out, inData.coveringSet.structure.class.toRope[inData.coveringSet], "\n"];
};
out ← Rope.Concat[out, "ENDCELL\n"];
};
Write:
PUBLIC
AC.WriteOp ~ {
stream.PutRope[ToRope[in] ]
};
Operations
SetCad:
PUBLIC
PROC [cell, cad:
AC.Object] ~ {
data: CellData ← NARROW[cell.data];
data.cad ← cad;
};
GetCad:
PUBLIC
AC.UnaryOp ~ {
data: CellData ← NARROW[arg.data];
RETURN[data.cad];
};
CellDim:
PUBLIC
AC.ElementRankOp ~ {
data: CellData ← NARROW[arg.data];
inData: PTS.PointData ← NARROW[data.index.data];
dimension: CARDINAL ← 0;
FOR i:
NAT
IN [1..inData.dimensionPlus1 - 1]
DO
coodData: Ints.IntData ← NARROW[inData[i].data];
dimension ← dimension + coodData^ MOD 2;
ENDLOOP;
RETURN[dimension];
};
AdjCells:
PUBLIC
AC.UnaryOp ~ {
data: CellData ← NARROW[arg.data];
RETURN[data.adjacentCells];
};
BasisSig:
PUBLIC
AC.UnaryOp ~ {
data: CellData ← NARROW[arg.data];
RETURN[data.basisSignature];
};
SamplePt:
PUBLIC
AC.UnaryOp ~ {
data: CellData ← NARROW[arg.data];
RETURN[data.samplePoint];
};
DefiningForm:
PUBLIC
AC.UnaryOp ~ {
data: CellData ← NARROW[arg.data];
RETURN[data.definingFormula];
};
CoverSet:
PUBLIC
AC.UnaryOp ~ {
data: CellData ← NARROW[arg.data];
RETURN[data.coveringSet];
};
Col:
PUBLIC
AC.UnaryOp ~ {
data: CellData ← NARROW[arg.data];
RETURN[data.color];
};
SetCol:
PUBLIC
AC.BinaryInPlaceOp ~ {
data: CellData ← NARROW[firstArg.data];
rope: Rope.ROPE ← NARROW[secondArg];
data.color ← Colors.FromRope[rope, Colors.Colors];
};
BoundBox:
PUBLIC
AC.UnaryOp ~ {
cellData: CellData ← NARROW[arg.data];
coveringSetData: CS.CoveringSetData;
IF cellData.coveringSet = NIL THEN RETURN[NIL];
coveringSetData ← NARROW[cellData.coveringSet.data];
RETURN[coveringSetData.boundingBox];
};
Disp2D:
PUBLIC
AC.Display2DOp ~ {
cellData: CellData ← NARROW[object.data];
dimension: CARDINAL ← cellData.dimension;
IF cellData.coveringSet = NIL THEN RETURN;
SELECT dimension
FROM
0 => Display0Cell[object, context, dotWidth];
1 => Display1Cell[object, context, segmentWidth];
ENDCASE;
};
ImagerVecFromRealPoint:
PROC [point:
PTS.Point]
RETURNS [v: Imager.
VEC] ~ {
x: Reals.Real ← NARROW[point.data, PTS.PointData][1];
y: Reals.Real ← NARROW[point.data, PTS.PointData][2];
xData: Reals.RealData ← NARROW[x.data];
yData: Reals.RealData ← NARROW[y.data];
RETURN[ [xData^ , yData^] ];
};
Display0Cell:
PROC [cell: Cell, context: Imager.Context, dotWidth:
REAL] ~ {
cellData: CellData ← NARROW[cell.data];
coveringSetData: CS.CoveringSetData ← NARROW[cellData.coveringSet.data];
dataPointsData: SEQ.SequenceData ← NARROW[coveringSetData.dataPoints.data];
column: SEQ.Sequence ← dataPointsData[1];
columnData: SEQ.SequenceData ← NARROW[column.data];
vec: Imager.VEC;
IF columnData.lengthPlus1 = 1 THEN RETURN;
vec ← ImagerVecFromRealPoint[columnData[1] ];
Imager.SetStrokeWidth[context, dotWidth];
Imager.MaskStrokeTrajectory[context, ImagerPath.MoveTo[vec] ];
};
Display1Cell:
PROC [cell: Cell, context: Imager.Context, segmentWidth:
REAL] ~ {
cellData: CellData ← NARROW[cell.data];
coveringSetData: CS.CoveringSetData ← NARROW[cellData.coveringSet.data];
dataPointsData: SEQ.SequenceData ← NARROW[coveringSetData.dataPoints.data];
column: SEQ.Sequence ← dataPointsData[1];
columnData: SEQ.SequenceData ← NARROW[column.data];
vec: Imager.VEC;
trajectory: Imager.Trajectory;
IF columnData.lengthPlus1 = 1 THEN RETURN;
vec ← ImagerVecFromRealPoint[columnData[1] ];
trajectory ← ImagerPath.MoveTo[vec];
Imager.SetStrokeWidth[context, segmentWidth];
FOR j:
NAT
IN [1..columnData.lengthPlus1-1]
DO
vec ← ImagerVecFromRealPoint[columnData[j] ];
trajectory ← trajectory.LineTo[vec];
ENDLOOP;
Imager.MaskStrokeTrajectory[context, trajectory];
};