LichenDataImplArrays1.Mesa
Last tweaked by Mike Spreitzer on May 9, 1988 1:34:16 pm PDT
DIRECTORY AbSets, Basics, BasicTime, BiRels, IO, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, Rope, SetBasics;
LichenDataImplArrays1: CEDAR PROGRAM
IMPORTS AbSets, BiRels, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, Rope, SetBasics
EXPORTS LichenArrayPrivate, LichenDataStructure, LichenDataOps
=
BEGIN OPEN IB:LichenIntBasics, IB, LichenDataStructure, LichenDataOps, LichenArrayPrivate, Sets:AbSets;
CreateArray: PUBLIC PROC [d: Design, eltType: CellType, size, basePeriod: Int2, names: Set--of ROPE--] RETURNS [act: CellType] ~ {
aName: ROPE ~ NARROW[names.AnElt[].MA];
act ← CreateCellType[d, array, names];
{svSpace: Sets.Space ~ NEW [SetBasics.SpacePrivate ← [
Contains: SVContains,
Equal: SVEqual,
AHash: SVHash,
ACompare: SVCompare,
Print: SVPrint,
name: Rope.Cat["stat verts of ", aName],
data: act]];
paiSpace: Sets.Space ~ NEW [SetBasics.SpacePrivate ← [
Contains: PAIContains,
Equal: PAIEqual,
AHash: PAIHash,
ACompare: PAICompare,
Print: PAIPrint,
name: Rope.Cat["pais of ", aName],
data: act]];
edgeSpace: Sets.Space ~ NEW [SetBasics.SpacePrivate ← [
Contains: SEContains,
Equal: SEEqual,
AHash: SEHash,
ACompare: SECompare,
Print: SEPrint,
name: Rope.Cat["stat edges of ", aName],
data: act]];
a: Array ~ NEW [ArrayPrivate ← [
size2: size,
size: Area[size],
basePeriod: basePeriod,
statrep: NEW [StatRepPrivate ← [
edgeSpace: edgeSpace, paiSpace: paiSpace, svSpace: svSpace,
edges: Sets.CreateHashSet[edgeSpace],
portEdge: [
FALSE: BiRels.CreateHashReln[spaces: [d.eSpace, edgeSpace], functional: [FALSE, TRUE]],
TRUE: BiRels.CreateHashReln[spaces: [d.eSpace, edgeSpace], functional: [FALSE, TRUE]]
],
apToPAI: BiRels.CreateHashFn[[d.eSpace, paiSpace]]
]]
]];
act.asArray ← a;
d.arrayElt.AddNewAA[act, eltType];
RETURN}};
SVContains: PUBLIC PROC [data: REF ANY, v: Sets.Value] RETURNS [BOOL] ~ {
WITH v.ra SELECT FROM
port: Port => RETURN [TRUE];
ENDCASE => RETURN [FALSE]};
SVHash: PROC [data: REF ANY, v: Sets.Value] RETURNS [CARDINAL] ~ {
act: CellType ~ NARROW[data];
sv: StatVertex ~ VSv[v];
RETURN [act.d.eSpace.SHash[AV[sv.port]] + Int2Hash[sv.phase]]};
SVEqual: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [BOOL] ~ {
RETURN [SVCompare[data, v1, v2]=equal]};
SVCompare: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [c: SetBasics.TotalComparison] ~ {
act: CellType ~ NARROW[data];
sv1: StatVertex ~ VSv[v1];
sv2: StatVertex ~ VSv[v2];
IF (c ← act.d.eSpace.SCompare[AV[sv1.port], AV[sv2.port]]) # equal THEN RETURN;
c ← Int2Compare[sv1.phase, sv2.phase];
RETURN};
SVPrint: PROC [data: REF ANY, v: Sets.Value, to: IO.STREAM, depth, length: INT, verbose: BOOL] ~ {
act: CellType ~ NARROW[data];
sv: StatVertex ~ VSv[v];
act.d.eSpace.SPrint[AV[sv.port], to, depth, length, verbose];
PrintQual[to, "~", act.asArray.basePeriod, sv.phase];
RETURN};
PAIContains: PROC [data: REF ANY, v: Sets.Value] RETURNS [BOOL] ~ {
WITH v.ra SELECT FROM
port: Port => RETURN [TRUE];
ENDCASE => RETURN [FALSE]};
PAIHash: PROC [data: REF ANY, v: Sets.Value] RETURNS [CARDINAL] ~ {
act: CellType ~ NARROW[data];
pai: PortAtIndex ~ VPai[v];
RETURN [act.d.eSpace.SHash[AV[pai.port]] + Int2Hash[pai.ai]]};
PAIEqual: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [BOOL] ~ {
RETURN [PAICompare[data, v1, v2]=equal]};
PAICompare: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [c: SetBasics.TotalComparison] ~ {
act: CellType ~ NARROW[data];
pai1: PortAtIndex ~ VPai[v1];
pai2: PortAtIndex ~ VPai[v2];
IF (c ← act.d.eSpace.SCompare[AV[pai1.port], AV[pai2.port]]) # equal THEN RETURN;
c ← Int2Compare[pai1.ai, pai2.ai];
RETURN};
PAIPrint: PROC [data: REF ANY, v: Sets.Value, to: IO.STREAM, depth, length: INT, verbose: BOOL] ~ {
act: CellType ~ NARROW[data];
pai: PortAtIndex ~ VPai[v];
act.d.eSpace.SPrint[AV[pai.port], to, depth, length, verbose];
PrintQual[to, "@", act.asArray.size2, pai.ai];
RETURN};
SEContains: PROC [data: REF ANY, v: Sets.Value] RETURNS [BOOL] ~ {
IF v.i#0 THEN RETURN [FALSE];
WITH v.ra SELECT FROM
se: StatEdge => RETURN [TRUE];
ENDCASE => RETURN [FALSE]};
SEHash: PROC [data: REF ANY, v: Sets.Value] RETURNS [CARDINAL] ~ {
act: CellType ~ NARROW[data];
se: StatEdge ~ NARROW[v.VA];
RETURN [Int2Hash[se.d] + act.asArray.statrep.svSpace.SHash[SvV[se.vs[FALSE]]] + act.asArray.statrep.svSpace.SHash[SvV[se.vs[TRUE]]]*19]};
SEEqual: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [BOOL] ~ {
RETURN [SECompare[data, v1, v2]=equal]};
SECompare: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [c: SetBasics.TotalComparison] ~ {
act: CellType ~ NARROW[data];
se1: StatEdge ~ NARROW[v1.VA];
se2: StatEdge ~ NARROW[v2.VA];
IF (c ← act.asArray.statrep.svSpace.SCompare[SvV[se1.vs[FALSE]], SvV[se2.vs[FALSE]]]) # equal THEN RETURN;
IF (c ← act.asArray.statrep.svSpace.SCompare[SvV[se1.vs[TRUE]], SvV[se2.vs[TRUE]]]) # equal THEN RETURN;
c ← Int2Compare[se1.d, se2.d];
RETURN};
SEPrint: PROC [data: REF ANY, v: Sets.Value, to: IO.STREAM, depth, length: INT, verbose: BOOL] ~ {
act: CellType ~ NARROW[data];
se: StatEdge ~ NARROW[v.VA];
act.asArray.statrep.svSpace.SPrint[SvV[se.vs[FALSE]], to, depth-1, length, verbose];
to.PutRope[" -> "];
act.asArray.statrep.svSpace.SPrint[SvV[se.vs[TRUE]], to, depth-1, length, verbose];
PrintQual[to, " by ", act.asArray.size2, se.d];
RETURN};
DWContains: PUBLIC PROC [data: REF ANY, v: Sets.Value] RETURNS [BOOL] ~ {
IF v.i#0 THEN RETURN [FALSE];
WITH v.ra SELECT FROM
dw: DumbWire => RETURN [TRUE];
ENDCASE => RETURN [FALSE];
};
DWPrint: PUBLIC PROC [data: REF ANY, v: Sets.Value, to: IO.STREAM, depth, length: INT, verbose: BOOL] ~ {
act: CellType ~ NARROW[data];
dw: DumbWire ~ NARROW[v.VA];
pai: PortAtIndex ~ SomePAI[act, dw];
IF pai.port#NIL THEN {
to.PutRope["{"];
act.d.eSpace.SPrint[AV[pai.port], to, depth, length, verbose];
PrintQual[to, "@", act.asArray.size2, pai.ai];
to.PutRope["}"]}
ELSE to.PutF["%bB", [cardinal[LOOPHOLE[dw]]]];
RETURN};
SomePAI: PUBLIC PROC [act: CellType, dw: DumbWire] RETURNS [PortAtIndex] ~ {
mpc: BiRels.MaybePair ~ dw.eps.APair[];
IF mpc.found THEN {
ep: Port ~ NARROW[mpc.it[left].VA];
cai: CompositeArrayIndex ~ mpc.it[right].VI;
ai: Int2 ~ act.asArray.DecomposeAI[cai];
RETURN [[ep, ai]]}
ELSE RETURN [[NIL, [0, 0]]]};
PrintQual: PROC [to: IO.STREAM, intro: ROPE, size2, qual: Int2] ~ {
IF size2[X]=1
THEN IF size2[Y]=1
THEN NULL
ELSE to.PutF["%g%g", [rope[intro]], [integer[qual[Y]]]]
ELSE IF size2[Y]=1
THEN to.PutF["%g%g", [rope[intro]], [integer[qual[X]]]]
ELSE to.PutF["%g<%g,%g>", [rope[intro]], [integer[qual[X]]], [integer[qual[Y]]]];
};
END.