DIRECTORY Rope, Atom, IO, Convert, MathExpr, MathConstructors, AlgebraClasses, Ints, Reals, BigRats, RatIntervals, Variables, Polynomials, Formulas, FormulaOperators, AlgebraicNumbers, ExtensionFields, SamplePoints, Points, Sequences, CoveringSets, Colors, Cells, Cads; CadsImpl: CEDAR PROGRAM IMPORTS Rope, Atom, IO, Convert, AlgebraClasses, MathConstructors, Cells, Sequences, Variables, Points, Ints, FormulaOperators, Polynomials, BigRats, CoveringSets, Colors EXPORTS Cads = BEGIN OPEN AC: AlgebraClasses, BR: BigRats, RI: RatIntervals, VARS: Variables, AN: AlgebraicNumbers, PTS: Points, POL: Polynomials, AN: AlgebraicNumbers, EF: ExtensionFields, SEQ: Sequences, QFF: Formulas, SP: SamplePoints, CS: CoveringSets, Cells, Cads; SyntaxError: PUBLIC ERROR [reason: ATOM] = CODE; BadElementStructure: PUBLIC ERROR [elementStructure: AC.Structure] = CODE; TypeError: PUBLIC ERROR [message: ATOM _ $Unspecified] = CODE; ClassPrintName: AC.PrintNameProc = { RETURN["Cads"]; }; ClassShortPrintName: AC.PrintNameProc = { RETURN["Cads"]; }; ClassReportOps: AC.ReportOpsProc = { opNames _ CONS["CoveringSetsFromLinearRope", opNames]; refOps _ CONS[NEW[AC.BinaryInPlaceOp _ CSetsFromLinRope ], refOps]; opNames _ CONS["ParentCad", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ ParCad ], refOps]; opNames _ CONS["InducedCad", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ IndCad ], refOps]; opNames _ CONS["OthClusters", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ OthClusters ], refOps]; opNames _ CONS["BasisClusters", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ BasClusters ], refOps]; opNames _ CONS["CadCells", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ Cels ], refOps]; opNames _ CONS["CellsWithSignature", opNames]; refOps _ CONS[NEW[AC.BinaryOp _ CellsWithSig ], refOps]; opNames _ CONS["BasisProjection", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ BasisProj ], refOps]; opNames _ CONS["Contents", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ Conts ], refOps]; opNames _ CONS["Basis", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ Base ], refOps]; opNames _ CONS["InputPolynomials", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ InputPolys ], refOps]; opNames _ CONS["LocalizationFormula", opNames]; refOps _ CONS[NEW[AC.UnaryOp _ LocalizFormula ], refOps]; opNames _ CONS["FromLinearRope", opNames]; refOps _ CONS[NEW[AC.FromRopeOp _ FromRope], refOps]; }; ClassIsElementOf: AC.ElementOfProc = { 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: CadData; outColumn, tail: LIST OF MathExpr.EXPR _ NIL; colLength: CARDINAL; IF in=NIL THEN { out _ MathConstructors.MakeVector[1, LIST[MathConstructors.MakeVariable["NILCAD"]], FALSE]; RETURN; }; inData _ NARROW[in.data]; IF inData=NIL THEN { out _ MathConstructors.MakeVector[1, LIST[MathConstructors.MakeVariable["NILCAD"]], FALSE]; RETURN; }; outColumn _ tail _ LIST[MathConstructors.MakeVariable[ Rope.Concat[Convert.RopeFromCard[inData.dimension], "-Space Cad"] ] ]; tail _ tail.rest _ LIST[inData.inputPolynomials.structure.class.toExpr[inData.inputPolynomials] ]; colLength _ 2; out _ MathConstructors.MakeVector[colLength, outColumn, FALSE]; }; cadOps: CadOps _ NEW[CadOpsRec _ [ localizationFormula: LocalizFormula, inputPolynomials: InputPolys, basis: Base, contents: Conts, basisProjection: BasisProj, cells: Cels, cellsWithSignature: CellsWithSig, basisClusters: BasClusters, otherClusters: OthClusters, inducedCad: IndCad, parentCad: ParCad, coveringSetsFromLinearRope: CSetsFromLinRope ] ]; cadProp: Atom.DottedPair _ NEW[Atom.DottedPairNode_ [$CadStructure, cadOps]]; cadStructureClass: 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[cadProp] ] ]; MakeCadStructure: PUBLIC PROC [] RETURNS [cellStructure: AC.Structure] ~ { RETURN[ NEW[AC.StructureRec _ [ class: cadStructureClass, instanceData: NIL ] ] ]; }; IsCadStructure: PUBLIC PROC [structure: AC.Structure] RETURNS [BOOL] ~ { IF Atom.GetPropFromList[structure.class.propList, $CadStructure] # NIL THEN RETURN[TRUE] ELSE RETURN[FALSE]; }; LocalizationFormula: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.localizationFormula]; } ELSE ERROR; }; InputPolynomials: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.inputPolynomials]; } ELSE ERROR; }; Basis: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.basis]; } ELSE ERROR; }; Contents: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.contents]; } ELSE ERROR; }; BasisProjection: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.basisProjection]; } ELSE ERROR; }; CadCells: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.cells]; } ELSE ERROR; }; CellsWithSignature: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.BinaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.cellsWithSignature]; } ELSE ERROR; }; BasisClusters: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.basisClusters]; } ELSE ERROR; }; InducedCad: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.inducedCad]; } ELSE ERROR; }; ParentCad: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.UnaryOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.parentCad]; } ELSE ERROR; }; CoveringSetsFromLinearRope: PUBLIC PROC [structure: AC.Structure] RETURNS [AC.BinaryInPlaceOp] ~ { IF IsCadStructure[structure] THEN { cadOps: CadOps _ NARROW[ Atom.GetPropFromList[structure.class.propList, $CadStructure] ]; RETURN[cadOps.coveringSetsFromLinearRope]; } ELSE ERROR; }; Read: PUBLIC AC.ReadOp ~ { minPolyRing, inputPolynomialRing, inputPolyRingSeqStructure: AC.Structure; token: Rope.ROPE; dimension: CARDINAL; name: Rope.ROPE _ NIL; inputVariables, projVariables, minPolyVariable, fieldElementVariable: VARS.VariableSeq; projPolynomialRing: AC.Structure; projPolyRingSeqStructure: AC.Structure; inputPolynomials, basis: SEQ.Sequence _ NIL; numBasisElements: CARDINAL _ 0; contents, basisProjection: SEQ.Sequence _ NIL; basisClusters: SEQ.Sequence _ NIL; cells: SEQ.Sequence _ NIL; cellsData: SEQ.SequenceData; basisSignatureStructure: AC.Structure; inducedCad: Cad _ NIL; inducedCadData: CadData; outData: CadData; token _ in.GetID[]; IF NOT Rope.Equal[token, "BEGINCAD"] THEN ERROR; token _ in.GetID[]; IF Rope.Equal[token, "NAME"] THEN { name _ in.GetID[]; token _ in.GetID[]; }; IF NOT Rope.Equal[token, "DIMENSION"] THEN ERROR; dimension _ in.GetCard[]; token _ in.GetID[]; IF NOT Rope.Equal[token, "INPUTVARIABLES"] THEN ERROR; inputVariables _ VARS.ReadVariableSeq[in]; inputPolynomialRing _ POL.MakePolynomialStructure[BR.BigRats, inputVariables]; inputPolyRingSeqStructure _ SEQ.MakeSequenceStructure[inputPolynomialRing]; token _ in.GetID[]; IF NOT Rope.Equal[token, "MINPOLYVARIABLE"] THEN ERROR; minPolyVariable _ VARS.ReadVariableSeq[in]; minPolyRing _ POL.MakePolynomialStructure[BR.BigRats, minPolyVariable]; token _ in.GetID[]; IF NOT Rope.Equal[token, "FIELDELEMENTVARIABLE"] THEN ERROR; fieldElementVariable _ VARS.ReadVariableSeq[in]; IF NOT Rope.Equal[fieldElementVariable[1], minPolyVariable[1] ] THEN ERROR; -- quick fix; the entire use of fieldElementVariable should be removed token _ in.GetID[]; IF NOT Rope.Equal[token, "INPUTPOLYNOMIALS"] THEN ERROR; inputPolynomials _ inputPolyRingSeqStructure.class.read[in, inputPolyRingSeqStructure]; token _ in.GetID[]; IF Rope.Equal[token, "BASIS"] THEN { basisData: SEQ.SequenceData; basis _ inputPolyRingSeqStructure.class.read[in, inputPolyRingSeqStructure]; basisData _ NARROW[basis.data]; numBasisElements _ basisData.lengthPlus1 - 1; basisSignatureStructure _ PTS.MakePointStructure[FormulaOperators.Operators, numBasisElements]; token _ in.GetID[]; }; projVariables _ VARS.RemoveMainVariable[inputVariables]; projPolynomialRing _ POL.MakePolynomialStructure[BR.BigRats, projVariables]; projPolyRingSeqStructure _ SEQ.MakeSequenceStructure[projPolynomialRing]; IF Rope.Equal[token, "CONTENTS"] THEN { contents _ projPolyRingSeqStructure.class.read[in, projPolyRingSeqStructure]; token _ in.GetID[]; }; IF Rope.Equal[token, "PROJECTION"] THEN { basisProjection _ projPolyRingSeqStructure.class.read[in, projPolyRingSeqStructure]; token _ in.GetID[]; }; IF Rope.Equal[token, "CELLS"] THEN { cellStructure: AC.Structure _ Cells.MakeCellStructure[inputPolynomialRing, minPolyRing, numBasisElements]; cellSeqStructure: AC.Structure _ SEQ.MakeSequenceStructure[cellStructure]; cells _ cellSeqStructure.class.read[in, cellSeqStructure]; token _ in.GetID[]; }; IF Rope.Equal[token, "INDUCEDCAD"] THEN { inducedCad _ Read[in, structure]; token _ in.GetID[]; }; IF NOT Rope.Equal[token, "ENDCAD"] THEN ERROR; outData _ NEW[CadDataRec _ [ dimension: dimension, inputPolynomials: inputPolynomials, basis: basis, contents: contents, basisProjection: basisProjection, cells: cells, basisClusters: basisClusters, inducedCad: inducedCad ] ]; out _ NEW[AC.ObjectRec _ [name: name, structure: structure, data: outData] ]; IF inducedCad#NIL THEN { inducedCadData _ NARROW[inducedCad.data]; inducedCadData.parentCad _ out; }; cellsData _ NARROW[cells.data]; FOR i:NAT IN [1..cellsData.lengthPlus1 - 1] DO cellData: Cells.CellData _ NARROW[cellsData[i].data]; cellData.cad _ out; ENDLOOP; RETURN[out]; }; FromRope: PUBLIC AC.FromRopeOp ~ { out _ Read[IO.RIS[in], structure]; }; ToIndexRope: AC.ToRopeOp ~ { out _ Rope.Cat["Cad(", in.name, ")"]; }; ToRope: PUBLIC AC.ToRopeOp ~ { inData: CadData _ NARROW[in.data]; inputPolyRingSeqStructure: AC.Structure _ inData.inputPolynomials.structure; sequenceStructureData: SEQ.SequenceStructureData _ NARROW[inputPolyRingSeqStructure.instanceData]; inputPolynomialRing: AC.Structure _ sequenceStructureData.elementStructure; inputVariables: VARS.VariableSeq _ NARROW[inputPolynomialRing.instanceData, POL.PolynomialRingData].allVariables; out _ "BEGINCAD\n"; IF in.name#NIL THEN out _ Rope.Cat[out, "NAME\n", in.name, "\n"]; out _ Rope.Concat[out, "DIMENSION\n"]; out _ Rope.Cat[out, Convert.RopeFromCard[inData.dimension], "\n"]; out _ Rope.Concat[out, "INPUTVARIABLES\n"]; out _ Rope.Cat[out, VARS.VariableSeqToRope[inputVariables], "\n"]; out _ Rope.Concat[out, "MINPOLYVARIABLE\n"]; out _ Rope.Cat[out, VARS.VariableSeqToRope[inData.minPolyVariable], "\n"]; out _ Rope.Concat[out, "FIELDELEMENTVARIABLE\n"]; out _ Rope.Cat[out, VARS.VariableSeqToRope[inData.minPolyVariable], "\n"]; IF inData.inputPolynomials#NIL THEN { out _ Rope.Concat[out, "INPUTPOLYNOMIALS\n"]; out _ Rope.Cat[out, inData.inputPolynomials.structure.class.toRope[inData.inputPolynomials], "\n"]; }; IF inData.basis#NIL THEN { out _ Rope.Concat[out, "BASIS\n"]; out _ Rope.Cat[out, inData.basis.structure.class.toRope[inData.basis], "\n"]; }; IF inData.contents#NIL THEN { out _ Rope.Concat[out, "CONTENTS\n"]; out _ Rope.Cat[out, inData.contents.structure.class.toRope[inData.contents], "\n"]; }; IF inData.basisProjection#NIL THEN { out _ Rope.Concat[out, "PROJECTION\n"]; out _ Rope.Cat[out, inData.basisProjection.structure.class.toRope[inData.basisProjection], "\n"]; }; IF inData.cells#NIL THEN { out _ Rope.Concat[out, "CELLS\n"]; out _ Rope.Cat[out, inData.cells.structure.class.toRope[inData.cells], "\n"]; }; IF inData.inducedCad#NIL THEN { out _ Rope.Concat[out, "INDUCEDCAD\n"]; out _ Rope.Cat[out, ToRope[inData.inducedCad], "\n"]; }; out _ Rope.Concat[out, "ENDCAD\n"]; }; Write: PUBLIC AC.WriteOp ~ { stream.PutRope[ToRope[in] ] }; LocalizFormula: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.localizationFormula]; }; InputPolys: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.inputPolynomials]; }; Base: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.basis]; }; Conts: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.contents]; }; BasisProj: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.basisProjection]; }; Cels: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.cells]; }; CellsWithSig: PUBLIC AC.BinaryOp ~ { cadData: CadData _ NARROW[firstArg.data]; -- firstArg is cad basisSig: Cells.Signature _ NARROW[secondArg]; inCells: SEQ.Sequence _ cadData.cells; inCellsData: SEQ.SequenceData _ NARROW[inCells.data]; outCellsList, tail: LIST OF Cells.Cell _ NIL; FOR i:NAT IN [1..inCellsData.lengthPlus1 - 1] DO inCellData: Cells.CellData _ NARROW[inCellsData[i].data]; IF inCellData.basisSignature.structure.class.equal[inCellData.basisSignature, basisSig] THEN { IF outCellsList = NIL THEN outCellsList _ tail _ LIST[inCellsData[i] ] ELSE tail _ tail.rest _ LIST[inCellsData[i] ] }; ENDLOOP; RETURN[ SEQ.MakeSeq[outCellsList, inCells.structure] ]; }; BasClusters: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.basisClusters]; }; OthClusters: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.otherClusters]; }; IndCad: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.inducedCad]; }; ParCad: PUBLIC AC.UnaryOp ~ { data: CadData _ NARROW[arg.data]; RETURN[data.parentCad]; }; LookupCell: PUBLIC AC.BinaryOp ~ { cellsData: SEQ.SequenceData _ NARROW[firstArg.data]; cellIndexStructure: AC.Structure _ secondArg.structure; FOR i:NAT IN [1..cellsData.lengthPlus1 - 1] DO cellData: Cells.CellData _ NARROW[cellsData[i].data]; IF cellIndexStructure.class.equal[cellData.index, secondArg] THEN RETURN[cellsData[i] ]; ENDLOOP; RETURN[NIL]; }; ReadCSets: PUBLIC PROC [in: IO.STREAM, cad: Cads.Cad] ~ { cadData: CadData _ NARROW[cad.data]; token: Rope.ROPE _ in.GetID[]; index: PTS.Point; dimension: CARDINAL; cellIndexStructure: AC.Structure; coveringSetStructure: AC.Structure; cells: SEQ.Sequence; cell: Cells.Cell; cellData: Cells.CellData; IF Rope.Equal[token, "BEGINCOVERINGSETS"] THEN token _ in.GetID[]; -- flush if present IF NOT Rope.Equal[token, "DIMENSION"] THEN ERROR; dimension _ in.GetCard[]; IF dimension # cadData.dimension THEN ERROR; cellIndexStructure _ PTS.MakePointStructure[Ints.Ints, dimension]; coveringSetStructure _ CS.MakeCoveringSetStructure[dimension]; cells _ cadData.cells; token _ in.GetID[]; WHILE Rope.Equal[token, "CELLINDEX"] DO index _ cellIndexStructure.class.read[in, cellIndexStructure]; cell _ LookupCell[cells, index]; cellData _ NARROW[cell.data]; token _ in.GetID[]; IF NOT Rope.Equal[token, "BEGINCOVERINGSET"] THEN ERROR; cellData.coveringSet _ coveringSetStructure.class.read[in, coveringSetStructure]; cellData.color _ Colors.FromRope["Black", Colors.Colors]; token _ in.GetID[]; ENDLOOP; IF NOT Rope.Equal[token, "ENDCOVERINGSETS"] THEN ERROR; }; CSetsFromLinRope: PUBLIC AC.BinaryInPlaceOp ~ { inRope: Rope.ROPE _ NARROW[secondArg]; stream: IO.STREAM _ IO.RIS[inRope]; ReadCSets[stream, firstArg]; }; ExtractClusters: PUBLIC PROC [cad: Cad, numComponents: CARDINAL] RETURNS [basisClusters: SEQ.Sequence] ~ {}; END.  CadsImpl.mesa Graphs, GraphOps, Errors Class for Cell Structures ClassPrintName: AC.PrintNameProc = { data: CadStructureData _ NARROW[structure.instanceData]; RETURN[Rope.Cat[ "Cads in ", data.inputPolynomialRing.class.printName[data.inputPolynomialRing], " and ", data.minPolyRing.class.printName[data.minPolyRing] ] ]; }; ClassShortPrintName: AC.PrintNameProc = { data: CadStructureData _ NARROW[structure.instanceData]; RETURN[Rope.Cat[ "Cads(", data.inputPolynomialRing.class.shortPrintName[data.inputPolynomialRing], data.minPolyRing.class.shortPrintName[data.minPolyRing], ")" ] ]; }; Assumes that if item is a cad, then it really belongs to the domain pointed to by its structure field. makeBasisClusters: MakeBasClusters, makeOtherClusters: MakeOthClusters, -- cluster(cad, edgePredicateFormula) -> clusters Cad Structure Constructor MakeCadStructure: PUBLIC PROC [inputPolynomialRing, minPolyRing: AC.Structure] RETURNS [cellStructure: AC.Structure] ~ { cadStructureData: CadStructureData _ NEW[CadStructureDataRec _ [ inputPolynomialRing: inputPolynomialRing, minPolyRing: minPolyRing ] ]; RETURN[ NEW[AC.StructureRec _ [ class: cadStructureClass, instanceData: cadStructureData ] ] ]; }; Extract Cell Operations from Class Record Property Lists Conversion and IO cadGraphClass: PUBLIC Graphs.GraphClass _ Graphs.NewGraphClass[[ EnumerateVertices: CadEnumerateVertices, Destroy: NIL ]]; CadEnumerateVertices: PUBLIC Graphs.EnumerateVerticesProc ~ { cad: Cad _ NARROW[graph.rep]; cadData: CadData _ NARROW[cad.data]; cells: SEQ.Sequence _ cadData.cells; cellsData: SEQ.SequenceData _ NARROW[cells.data]; FOR i:NAT IN [1..cellsData.lengthPlus1 - 1] DO cellData: Cells.CellData _ NARROW[cellsData[i].data]; consume.proc[cellData.abstractVertex, consume.data]; ENDLOOP; }; cadStructureData: CadStructureData _ NARROW[structure.instanceData]; inputPolynomialRing: AC.Structure _ cadStructureData.inputPolynomialRing; minPolyRing: AC.Structure _ cadStructureData.minPolyRing; cellIndexStructure: AC.Structure; cellIndexStructure _ PTS.MakePointStructure[Ints.Ints, dimension]; Should check that minPolyVariable read = minPolyRing.allVariables IF Rope.Equal[token, "CLUSTERS"] THEN [basisClusters, token] _ ReadSignedRegionSeq[in, cellIndexStructure, inputPolynomialRing, minPolyRing, basisSignatureStructure]; inducedCadStructure: AC.Structure _ MakeCadStructure[projPolynomialRing, minPolyRing]; outData.abstractGraph _ NEW [Graphs.GraphPrivate _ [ class: cadGraphClass, rep: out ]]; inStructureData: CadStructureData _ NARROW[in.structure.instanceData]; minPolyVariable: VARS.VariableSeq _ NARROW[inStructureData.minPolyRing.instanceData, POL.PolynomialRingData].allVariables; IF inData.basisClusters#NIL THEN { out _ Rope.Concat[out, "CLUSTERS\n"]; out _ Rope.Cat[out, SignedRegionSeqToRope[inData.basisClusters], "\n"]; }; Operations MakeBasClusters: PUBLIC AC.UnaryOp ~ { User specifies polynomials with respect to which to cluster by (*,*,@,*,*,@) tuples (@ is new FormulaOperators.Op). data: CadData _ NARROW[arg.data]; edgePredicate: GraphOps.EdgePredicate ~ { cell1: Cells.Cell _ NARROW[v.rep]; cell2: Cells.Cell _ NARROW[w.rep]; cell1Data: Cells.CellData _ NARROW[cell1.data]; cell2Data: Cells.CellData _ NARROW[cell2.data]; RETURN[cell1Data.basisSignature.structure.class.equal[cell1Data.basisSignature, cell2Data.basisSignature] ]; }; numComponents: CARDINAL _ GraphOps.DetermineComponents[data.abstractGraph, Undirected, edgePredicate]; numComponents: CARDINAL _ 0; data.basisClusters _ ExtractClusters[arg, numComponents]; }; MakeOthClusters: PUBLIC AC.BinaryOp ~ { User specifies basis polynomials with respect to which to cluster by (*,*,@,*,*,@) tuples (@ is new FormulaOperators.Op). Should be expanded to tuple of such tuples, one for each dimension, then we can specify clustering with respect to selected basis polys in all dimensions. data: CadData _ NARROW[arg.data]; edgePredicate: GraphOps.EdgePredicate ~ { cell1: Cells.Cell _ NARROW[v.rep]; cell2: Cells.Cell _ NARROW[w.rep]; -- For each elt of Op sequence, if * then ignore this basis poly, else if @, then check for equal signs with respect to this basis poly RETURN[ ]; }; numComponents: CARDINAL _ GraphOps.DetermineComponents[data.abstractGraph, Undirected, edgePredicate]; data.basisClusters _ ExtractClusters[arg, numComponents]; }; Adjacencies and Clusters Κ/˜Jšœ ™ J™šΟk ˜ Jšœ˜J˜Icodešœ˜K˜K˜ K˜J˜J˜J˜Jšœ˜J˜ Jšœ ˜ J˜ J˜ J˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜J˜ J™J™ J˜ J˜Jšœ˜Jšœ˜—J˜head2šœ œ˜Jšœ œ•˜«Jšœ˜—J˜Jšœœœœ œœ œœ œœœœL˜ώJ˜head™Jš Οn œœœ œœ˜0Jš žœœœœœ˜JJš ž œœœ œœ˜>—šœ™šžœœ™$Jšœœ™8šœ ™Jšœ ™ JšœC™CJšœ ™ Jšœ2™2Jšœ™—J™—šžœœ˜$Jšœ ˜J˜—šžœœ™)Jšœœ™8šœ ™J™JšœH™HJšœ8™8J™Jšœ™—J™—šžœœ˜)Jšœ ˜J˜—šžœœ˜$Kšœ œ(˜6Kš œ œœœžœ ˜CKšœ œ˜%Kš œ œœœ žœ ˜1Kšœ œ˜&Kš œ œœœ žœ ˜1Kšœ œ˜'Kš œ œœœ ž œ ˜6Kšœ œ˜)Kš œ œœœ ž œ ˜6Kšœ œ˜$Kš œ œœœ žœ ˜/Kšœ œ ˜.Kš œ œœœ ž œ ˜8Kšœ œ˜+Kš œ œœœ ž œ ˜4Kšœ œ˜$Kš œ œœœ žœ ˜0Kšœ œ˜!Kš œ œœœ žœ ˜/Kšœ œ˜,Kš œ œœœ ž œ ˜5Kšœ œ!˜/Kš œ œœœ žœ ˜9Kšœ œ˜*Kšœ œœœ!˜5Jšœ˜—šžœœ˜&Jšœf™fJš œœ;œœœ˜TJšœœ˜Jšœ˜—šžœœ˜,šœ˜Kšœ œœ˜Kšœ˜—Kšœœ˜J˜—šž œœ ˜Jšœ˜Jš œœœ œœ˜-Jšœ œ˜šœœœ˜JšœUœ˜\Kšœ˜K˜—Jšœ œ ˜šœœœ˜JšœUœ˜\Kšœ˜K˜—šœœ˜6KšœF˜F—KšœœK˜bKšœ˜Jšœ9œ˜@Jšœ˜J˜—šœœ˜"Kšœ$˜$Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ!˜!Kšœ˜Kšœ˜Kšœ#™#Kšœ%Οc1™VKšœ˜Kšœ˜Kšœ,˜,K˜K˜—Kšœœ/˜MK˜š œœœœœ˜JJšœ˜Jšœ˜Jšœ$˜$Kšœœ˜0K˜J˜Kšœ˜J˜Jšœ$˜$Jšœ ˜ Jšœ˜Jšœ˜J˜Jšœ ˜ Jšœ˜J˜K˜Kšœœ˜Kšœ œ˜Kšœœ˜K˜Jšœ œ ˜K˜——šœ™K˜š žœœœ$œ œœ™xšœ%œ™@Jšœ)™)Jšœ™Kšœ™—šœœœ™Jšœ™Jšœ™K™—K™—š žœœœœœ˜Jšœœœ˜Jšœ˜Jšœ˜K˜—K˜——šœ8™8š žœœœ œ œœ˜HKšœAœœœœœœœ˜lK˜K˜—š žœœœ œ œœ ˜Sšœœ˜#KšœœB˜ZKšœ˜#K˜—Kšœœ˜ K˜K˜—š žœœœ œ œœ ˜Pšœœ˜#KšœœB˜ZKšœ˜ K˜—Kšœœ˜ K˜K˜—š žœœœ œ œœ ˜Ešœœ˜#KšœœB˜ZKšœ˜K˜—Kšœœ˜ K˜K˜—š žœœœ œ œœ ˜Hšœœ˜#KšœœB˜ZKšœ˜K˜—Kšœœ˜ K˜K˜—š žœœœ œ œœ ˜Ošœœ˜#KšœœB˜ZKšœ˜K˜—Kšœœ˜ K˜K˜—š žœœœ œ œœ ˜Hšœœ˜#KšœœB˜ZKšœ˜K˜—Kšœœ˜ K˜K˜—š žœœœ œ œœ˜Sšœœ˜#KšœœB˜ZKšœ˜"K˜—Kšœœ˜ K˜K˜—š ž œœœ œ œœ ˜Mšœœ˜#KšœœB˜ZKšœ˜K˜—Kšœœ˜ K˜K˜—š ž œœœ œ œœ ˜Jšœœ˜#KšœœB˜ZKšœ˜K˜—Kšœœ˜ K˜K˜—š ž œœœ œ œœ ˜Išœœ˜#KšœœB˜ZKšœ˜K˜—Kšœœ˜ K˜K˜—š žœœœ œ œœ˜bšœœ˜#KšœœB˜ZKšœ$˜*K˜—Kšœœ˜ K˜K˜——šœ™šœœ,™AKšžœ™(Kšžœ™ K™K™—šžœœ!™=Kšœ œ ™Kšœœ ™$Kšœœ™$Kšœ œœ ™1šœœœ ™.Jšœœ™5Jšœ4™4Jšœ™—J™—J˜šžœœœ ˜Kšœ%œ™DJšœœ2™IJšœ œ*™9Kšœ=œ ˜JJšœ œ˜Jšœ œ˜Jšœ œœ˜JšœFœ ˜WJšœœ ˜!Jšœœ ˜'Jšœœ œ˜,Jšœœ˜Jšœœ œ˜.Jšœœ œ˜"Jšœœ œ˜Jšœ œ˜Jšœœ ™!Jšœœ ˜&JšœŸ˜K˜K˜Kšœ˜Kšœœœœ˜0Kšœ˜šœœ˜#Kšœ˜Kšœ˜K˜—Kšœœ œœ˜1Jšœ˜Jšœœ*™BKšœ˜Kšœœ%œœ˜6Idefaultšœœ˜*Nšœœœ˜NKšœœ,˜LKšœ˜Kšœœ&œœ˜7Nšœœ˜+Kšœœœ˜GNšœA™AKšœ˜Kšœœ+œœ˜˜>Nšœ ˜ Nšœ œ ˜Kšœ˜Kšœœ'œœ˜8KšœQ˜QKšœ9˜9Kšœ˜Kšœ˜—Kšœœ&œœ˜7J˜J˜—šžœœœ˜/Jšœ œœ ˜&Kš œœœœœ ˜#Kšœ˜J˜J˜——šž™š žœ œœœœ˜lK˜—J˜—J˜Jšœ˜J˜—…—AjS