LichenFlattenning:
CEDAR
PROGRAM
IMPORTS AbSets, BiRels, IntStuff, LichenDataOps, LichenDataStructure
EXPORTS LichenTransforms, LichenDataOps
=
ExpandVertex:
PUBLIC
PROC [child: CellInstance]
RETURNS [roleToSib: Seq
--role
é sibling: CellInstance--] ~ {
ct: CellType ~ child.type;
parent: CellType ~ child.containingCT;
u: Unorganized ~ ct.asUnorganized;
roles: INT ~ u.containedInstances.Size[].EN;
promote: VarFunction--part of ct b part of parent-- ~ BiRels.CreateHashFn[];
SetPromotion:
PROC [inner, outer: Wire] ~ {
IF inner=NIL OR outer=NIL THEN ERROR;
promote.AddNewAA[inner, outer];
inner ← inner.FirstChildWire[];
outer ← outer.FirstChildWire[];
WHILE inner#
NIL
AND outer#
NIL
DO
SetPromotion[inner, outer];
inner ← inner.NextChildWire[];
outer ← outer.NextChildWire[];
ENDLOOP;
IF inner#NIL OR outer#NIL THEN ERROR;
};
NotePorting:
PROC [p: Port, w: Wire] ~ {
SetPromotion[p.wire, w];
};
MoveCell:
PROC [ra: Sets.Value] ~ {
ci: CellInstance ~ NARROW[ra.VA];
sib: CellInstance ~ Instantiate[ci.type, parent, CrossNames[child.VertexNames, ci.VertexNames]];
GetPromotion:
PROC [vi, uvo: Vertex, port: Port]
RETURNS [vo: Vertex] ~ {
IF (vo ← NARROW[promote.ApplyA[vi].MDA])#NIL THEN RETURN;
WITH vi
SELECT
FROM
wi: Wire => {
uwo: Wire ~ WITH uvo SELECT FROM x: Wire => x, ENDCASE => NIL;
wo: Wire ~ vo ← CreateWire[parent, uwo, IF uwo#NIL THEN [vi.VertexNames.Copy.data.VA] ELSE CrossNames[child.VertexNames, vi.VertexNames]];
promote.AddNewAA[wi, wo];
WITH uvo
SELECT
FROM
x: Intermediary => AddEdge[[x, wo], port];
ENDCASE => NULL;
FOR cwi: Wire ← wi.FirstChildWire, cwi.NextChildWire WHILE cwi # NIL DO [] ← GetPromotion[cwi, wo, NIL] ENDLOOP;
};
ii: Intermediary => {
io: Intermediary ~ vo ← CreateIntermediary[uvo, wireward, parent, port, [vi.VertexNames.Copy.data.VA]];
PromoteIM: PROC [q: Port, wi: Vertex] ~ {[] ← GetPromotion[wi, io, q]};
promote.AddNewAA[ii, io];
EnumerateImmediateConnections[ii, PromoteIM, [FALSE, TRUE]];
};
cii: CellInstance => ERROR;
ENDCASE => ERROR;
IF vo=NIL THEN ERROR;
};
PromoteEdge:
PROC [p: Port, v: Vertex] ~ {
w: Vertex ~ GetPromotion[v, sib, p];
AddEdge[[sib, w], p];
};
roleToSib.AppendA[sib];
EnumerateImmediateConnections[ci, PromoteEdge];
};
roleToSib ← CreateSeq[oneToOne: TRUE];
EnumerateTopConnections[child, NotePorting];
u.containedInstances.Enumerate[MoveCell];
DeleteVertex[child];
roleToSib ← roleToSib.Freeze;
};
CrossNames:
PUBLIC
PROC [outer, inner: Set
--of SteppyName--]
RETURNS [ListData] ~ {
crossed: Set--of SteppyName-- ~ Setify[CreateSteppyNames[]];
Crossit:
PROC [v1: Sets.Value] ~ {
innerName: SteppyName ~ VSn[v1];
glob: BOOL ← FALSE;
Finish:
PROC [v2: Sets.Value] ~ {
outerName: SteppyName ~ VSn[v2];
name: SteppyName ~ SNCat[outerName, innerName];
new: BOOL ~ crossed.AddElt[SnV[name]];
RETURN};
IF innerName.grade.global THEN {[] ← crossed.AddElt[SnV[innerName]]; RETURN};
outer.Enumerate[Finish];
RETURN};
inner.Enumerate[Crossit];
RETURN [[crossed.data.VA]]};
Flatten:
PUBLIC
PROC [root: CellType, expand: ConstFilter
--of CellInstance--] ~ {
action: BOOL ← TRUE;
MaybeExpand:
PROC [ra: Sets.Value] ~ {
ci: CellInstance ~ NARROW[ra.VA];
IF expand.HasMemA[ci]
THEN {
action ← TRUE;
[] ← ExpandVertex[ci];
};
};
u: Unorganized ~ root.asUnorganized;
IF u=NIL THEN ERROR;
WHILE action
DO
action ← FALSE;
u.containedInstances.Enumerate[MaybeExpand];
ENDLOOP;
root ← root;
};