LichenData2Impl.Mesa
Mike Spreitzer January 15, 1987 2:18:17 pm PST
DIRECTORY AMBridge, Asserting, Basics, Convert, GList, HashTable, InterpreterOps, IntHashTable, IO, LichenDataStructure, LichenDataOps, LichenSetTheory, Rope, StructuredStreams, SymTab, TiogaAccess, UnparserBuffer, ViewerIO;
LichenData2Impl:
CEDAR
PROGRAM
IMPORTS AMBridge, Asserting, Convert, InterpreterOps, IO, LichenDataStructure, LichenSetTheory, Rope, StructuredStreams, TiogaAccess, UnparserBuffer
EXPORTS LichenDataStructure
=
BEGIN OPEN LichenSetTheory, LichenDataStructure, SS:StructuredStreams, UB:UnparserBuffer;
nyet: PUBLIC ERROR = CODE;
Warning: PUBLIC SIGNAL [msg: ROPE ← NIL, v1, v2, v3, v4, v5: REF ANY ← NIL] = CODE;
Error: PUBLIC ERROR [msg: ROPE, v1, v2, v3, v4, v5: REF ANY ← NIL] = CODE;
nameReln: PUBLIC ATOM ← $LichenName;
partsByNameKey: PUBLIC ATOM ← $LichenNameToPart;
DimName: ARRAY Dim OF ROPE = [Foo: "Foo", Bar: "Bar"];
EndName: ARRAY End OF ROPE = [low: "low", high: "high"];
step: ROPE = ".";
Describe:
PUBLIC
PROC [subject:
REF
ANY, relativeTo:
REF
ANY ←
NIL, nameGen: NameGenerator ←
NIL]
RETURNS [name:
ROPE] = {
GetShort:
PROC [oldAssns: Assertions]
RETURNS [newAssns: Assertions, name:
ROPE] = {
name ← NARROW[Asserting.FnVal[nameReln, newAssns ← oldAssns]];
IF name =
NIL
THEN {
name ← nameGen.GenerateName[nameGen.data, subject];
newAssns ← Asserting.Assert[nameReln, LIST[name], newAssns];
};
};
IF nameGen = NIL THEN nameGen ← defaultNameGen;
IF subject = relativeTo
THEN name ←
NIL
ELSE
WITH subject
SELECT
FROM
d: Design => {
short: ROPE;
[d.other, short] ← GetShort[d.other];
name ← short;
};
ct: CellType => {
short: ROPE;
[ct.otherPublic, short] ← GetShort[ct.otherPublic];
name ← IF ct.designs.HasMember[relativeTo] OR ct.designs.Size[]=0 THEN short ELSE Describe[GetADesign[ct], relativeTo, nameGen].Cat[step, short];
};
v: Vertex => {
short: ROPE;
parent: REF ANY;
[v.other, short] ← GetShort[v.other];
WITH v
SELECT
FROM
ci: CellInstance => parent ← v.containingCT;
im: Intermediary => parent ← ImParent[im];
w: Wire => parent ← WireContainer[w];
ENDCASE => ERROR;
name ← IF relativeTo = parent OR parent = NIL THEN short ELSE Describe[parent, relativeTo, nameGen].Cat[step, short];
};
port: Port => {
short: ROPE;
parent: REF ANY = port.parent;
[port.other, short] ← GetShort[port.other];
name ← IF relativeTo = parent OR parent = NIL THEN short ELSE Describe[parent, relativeTo, nameGen].Cat[step, short];
};
ENDCASE => ERROR;
};
GetADesign:
PROC [ct: CellType]
RETURNS [d: Design] = {
See: PROC [ra: REF ANY] = {d ← NARROW[ra]};
IF ct.designs.Size[] = 0 THEN RETURN [NIL];
ct.designs.Enumerate[See];
};
WireContainer:
PROC [w: Wire]
RETURNS [container:
REF
ANY] = {
container ←
SELECT w.containingWire
FROM
NIL => w.containingCT,
ENDCASE => w.containingWire;
};
defaultNameGen: NameGenerator =
NEW [NameGeneratorPrivate ← [
GenerateBlandName,
NEW [NameCountsPrivate ← []]
]];
NameCounts: TYPE = REF NameCountsPrivate;
NameCountsPrivate:
TYPE =
RECORD [
design, cellType, port, vertex: INT ← 0
];
GenerateBlandName:
PROC [data, subject:
REF
ANY]
RETURNS [name:
ROPE] = {
nc: NameCounts = NARROW[data];
name ← GenByCount[nc, subject];
};
TVNameGenerator: TYPE = REF TVNameGeneratorPrivate;
TVNameGeneratorPrivate:
TYPE =
RECORD [
nc: NameCounts,
symTab: SymTab.Ref
];
MakeTVNameGen:
PROC [symTab: SymTab.Ref]
RETURNS [ng: NameGenerator] = {
ng ←
NEW [NameGeneratorPrivate ← [
GenerateTVName,
NEW [TVNameGeneratorPrivate ← [
nc: NEW [NameCountsPrivate ← []],
symTab: symTab
]]
]];
};
GenerateTVName:
PROC [data, subject:
REF
ANY]
RETURNS [name:
ROPE] = {
tvng: TVNameGenerator = NARROW[data];
name ← Rope.Concat["&", GenByCount[tvng.nc, subject]];
TRUSTED {InterpreterOps.RegisterTV[
name: name,
tv: AMBridge.TVForReferent[
WITH subject
SELECT
FROM
d: Design => NEW [Design ← d],
ct: CellType => NEW [CellType ← ct],
p: Port => NEW [Port ← p],
v: Vertex => NEW [Vertex ← v],
ENDCASE => ERROR],
symTab: tvng.symTab]};
};
GenByCount:
PROC [nc: NameCounts, subject:
REF
ANY]
RETURNS [name:
ROPE] = {
n: INT ← 0;
WITH subject
SELECT
FROM
d: Design => {n ← nc.design ← nc.design + 1; name ← "D"};
ct: CellType => {n ← nc.cellType ← nc.cellType + 1; name ← "CT"};
p: Port => {n ← nc.port ← nc.port + 1; name ← "P"};
v: Vertex => {n ← nc.vertex ← nc.vertex + 1; name ← "V"};
ENDCASE => ERROR;
name ← name.Concat[Convert.RopeFromInt[n]];
};
PrintObject:
PROC [to:
IO.
STREAM, united:
BOOL,
PrintIt:
PROC] = {
SS.Bp[to, IF united THEN united ELSE lookLeft, printStep];
SS.Begin[to];
PrintIt[!UNWIND => SS.End[to]];
SS.End[to];
};
printStep: INT ← 2;
printWidth: INT ← 65;
PrintDesignOnFile:
PROC [design: Design, nameGen: NameGenerator ←
NIL, fileName:
ROPE ←
NIL] = {
taw: TiogaAccess.Writer = TiogaAccess.Create[];
realFileName: ROPE = IF fileName # NIL THEN fileName ELSE Rope.Cat[NARROW[Asserting.FnVal[nameReln, design.other]], ".design"];
ss: IO.STREAM = SS.Create[UB.NewInittedHandle[[output: [access[taw, printStep]], margin: printWidth]]];
PrintDesign[ss, design, nameGen];
TiogaAccess.WriteFile[taw, realFileName];
ss.Close[];
};
PrintDesign:
PROC [to:
IO.
STREAM, design: Design, nameGen: NameGenerator ←
NIL] = {
Filter: PROC [CellType] RETURNS [BOOL] = {RETURN [TRUE]};
PrintDesignSubset[to, design, nameGen, Filter];
};
PrintDesignSubset:
PROC [to:
IO.
STREAM, design: Design, nameGen: NameGenerator, Filter:
PROC [CellType]
RETURNS [
BOOL]] = {
CTPrint:
PROC [ra:
REF
ANY] = {
ct: CellType = NARROW[ra];
Inner: PROC = {PrintCellType[to, ct, nameGen]};
IF Filter[ct] THEN PrintObject[to, TRUE, Inner];
};
IF NOT SS.IsAnSS[to] THEN to ← SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]];
to.PutF["%g: Design {", [rope[Describe[design, NIL, nameGen]]]];
design.cellTypes.Enumerate[CTPrint];
to.PutF["}"];
};
PrintCellType:
PROC [to:
IO.
STREAM, ct: CellType, nameGen: NameGenerator ←
NIL] = {
Main:
PROC = {
to.PutF["%g: CellType[", [rope[Describe[ct, GetADesign[ct], nameGen]]]];
PrintObject[to, TRUE, PortPrint];
IF ct.asUnorganized #
NIL
THEN {
to.PutRope[", "]; PrintObject[to, TRUE, IWPrint];
to.PutRope[", "]; PrintObject[to, TRUE, CIPrint];
};
IF ct.asArray #
NIL
THEN {
to.PutRope[", "]; PrintObject[to, TRUE, AyPrint];
};
to.PutRope["]"];
};
PortPrint:
PROC = {
to.PutF["port: "];
PrintPort[to, ct.port, nameGen];
};
IWPrint:
PROC = {
to.PutF["internal wire: "];
PrintWire[to, ct.asUnorganized.internalWire, nameGen];
};
CIPrint:
PROC = {
to.PutF["contained instances: "];
PrintInstances[to, ct.asUnorganized.containedInstances, ct.asUnorganized.mirror, nameGen];
};
AyPrint:
PROC = {
to.PutRope["asArray: "];
PrintArray[to, ct, nameGen]
};
IF NOT SS.IsAnSS[to] THEN to ← SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]];
--PrintObject[to, TRUE, Main]--Main[];
};
portLimit: NAT ← 69;
PrintPort:
PROC [to:
IO.
STREAM, port: Port, nameGen: NameGenerator] = {
first: BOOL ← TRUE;
i: INT ← 0;
to.PutRope[Describe[port, port.parent, nameGen]];
IF port.FirstChildPort[] = NIL THEN RETURN;
to.PutRope["["];
FOR subPort: Port ← port.FirstChildPort[], subPort.NextChildPort[]
WHILE subPort #
NIL
DO
PortPrint: PROC = {PrintPort[to, subPort, nameGen]};
PrintElipsis: PROC = {to.PutRope["..."]};
IF i < portLimit
OR subPort.NextChildPort[] =
NIL
THEN {
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, PortPrint]
}
ELSE
IF i = portLimit
THEN {
to.PutRope[", "];
PrintObject[to, FALSE, PrintElipsis]
};
i ← i + 1;
ENDLOOP;
to.PutRope["]"];
};
PrintWire:
PROC [to:
IO.
STREAM, wire: Wire, nameGen: NameGenerator] = {
first: BOOL ← TRUE;
to.PutRope[Describe[wire, WireContainer[wire], nameGen]];
IF wire.FirstChildWire[] = NIL THEN RETURN;
to.PutRope["["];
FOR subWire: Wire ← wire.FirstChildWire[], subWire.NextChildWire[]
WHILE subWire #
NIL
DO
WirePrint: PROC = {PrintWire[to, subWire, nameGen]};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, WirePrint];
ENDLOOP;
to.PutRope["]"];
};
PrintInstances:
PROC [to:
IO.
STREAM, set: Set
--OF CellInstance--, mirror: CellInstance, nameGen: NameGenerator] = {
first: BOOL ← TRUE;
PrintIt:
PROC [ra:
REF
ANY] = {
ci: CellInstance = NARROW[ra];
IPrint: PROC = {PrintInstance[to, ci, nameGen]};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, TRUE, IPrint];
};
to.PutRope["["];
set.Enumerate[PrintIt];
PrintIt[mirror];
to.PutRope["]"];
};
PrintInstance:
PROC [to:
IO.
STREAM, ci: CellInstance, nameGen: NameGenerator] = {
PrintConnections:
PROC [v: Vertex] = {
first: BOOL ← TRUE;
PrintConnection:
PROC [port: Port, w: Vertex] = {
CPrint:
PROC = {
to.PutF["%g: ", [rope[Describe[port, port.parent, nameGen]]]];
WITH w
SELECT
FROM
im: Intermediary => {
PrintConnections[im];
};
wire: Wire => {
to.PutRope[Describe[wire, WireContainer[wire], nameGen]];
};
ci: CellInstance => ERROR;
ENDCASE => ERROR;
};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, CPrint];
};
to.PutRope["["];
EnumerateImmediateConnections[v, PrintConnection, [cellward: FALSE, wireward: TRUE]];
to.PutRope["]"];
};
to.PutF["%g: %g", [rope[Describe[ci, ci.containingCT, nameGen]]], [rope[Describe[ci.type, GetADesign[ci.type], nameGen]]] ];
PrintConnections[ci];
};
PrintArray:
PROC [to:
IO.
STREAM, ct: CellType, nameGen: NameGenerator] = {
a: Array = ct.asArray;
groupName: Mapper = CreateHashMapper[];
nGroups: NAT ← 0;
JPPrint:
PROC = {
to.PutF["joints period = [%g, %g]", [integer[a.jointsPeriod[Foo]]], [integer[a.jointsPeriod[Bar]]]]};
GMPrint:
PROC = {
to.PutF["groupingMiddles = [%g, %g]", [rope[FmtGP[a.groupingParmses[Foo]]]], [rope[FmtGP[a.groupingParmses[Bar]]]]];
};
AWPrint:
PROC = {
to.PutRope["wires = ["];
PrintArrayWires[to, a, groupName, nameGen];
to.PutRope["]"];
};
to.PutF["{%g BY %g OF %g, ",
[integer[a.size[Foo]]], [integer[a.size[Bar]]],
[rope[Describe[a.eltType, GetADesign[ct], nameGen]]]
];
PrintObject[to, FALSE, JPPrint];
to.PutRope[", "];
PrintObject[to, FALSE, GMPrint];
FOR gi
f:
NAT
IN [0 .. a.groupingParmses[Foo].sum)
DO
FOR gi
b:
NAT
IN [0 .. a.groupingParmses[Bar].sum)
DO
gi: NAT = a.groupingParmses[Bar].sum * gif + gib;
gs: Groupings = NARROW[a.groupingses[gi]];
PrintGroups:
PROC = {
first: BOOL ← TRUE;
PrintGroup:
PROC [ra:
REF
ANY] = {
g: Group = NARROW[ra];
name: ROPE = IO.PutFR["G%g", [integer[nGroups ← nGroups+1]]];
GPrint:
PROC = {
to.PutF["%g: ", [rope[name]]];
PrintGroupContents[to, a, g, nameGen];
};
IF groupName.SetMapping[g, name].hadMapping THEN ERROR;
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, GPrint];
};
to.PutF["groups[%g, %g] = [", [integer[gif]], [integer[gib]]];
gs.groups.Enumerate[PrintGroup];
to.PutRope["]"];
};
to.PutRope[", "];
PrintObject[to, TRUE, PrintGroups];
ENDLOOP ENDLOOP;
FOR d: Dim
IN Dim
DO
PrintJoints:
PROC = {
first: BOOL ← TRUE;
to.PutF["joints[%g] = [", [rope[DimName[d]]]];
FOR
f
f:
NAT
IN [0 .. a.jointsPeriod[Foo])
DO
FOR
f
b:
NAT
IN [0 .. a.jointsPeriod[Bar])
DO
phase: Nat2 = [ff, fb];
JPrint:
PROC = {
to.PutF["[%g,%g]: ", [integer[ff]], [integer[fb]]];
PrintJoint[to, ct, d, phase, GetArrayJoint[a, d, phase], nameGen, groupName];
};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, TRUE, JPrint];
ENDLOOP;
ENDLOOP;
to.PutRope["]"];
};
to.PutRope[", "];
PrintObject[to, TRUE, PrintJoints];
ENDLOOP;
to.PutRope[", "];
PrintObject[to, TRUE, AWPrint];
to.PutRope["}"];
};
PrintArrayWires:
PROC [to:
IO.
STREAM, a: Array, groupName: Mapper, nameGen: NameGenerator] ~ {
first: BOOL ← TRUE;
PrintPerAW:
PROC [ra:
REF
ANY] ~ {
aw: ArrayWire ~ NARROW[ra];
AWPrint:
PROC ~ {
first: BOOL ← TRUE;
PerElt:
PROC [ra:
REF
ANY] ~ {
elt: ArrayWireElement ~ NARROW[ra];
EltPrint: PROC ~ {to.PutF["[%g:%g]%g", [integer[elt.ai[Foo]]], [integer[elt.ai[Bar]]], [rope[NARROW[groupName.Map[elt.group]]]]]};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, EltPrint];
};
to.PutRope["{"];
aw.elts.Enumerate[PerElt];
to.PutRope["}"];
};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, AWPrint];
};
a.wires.Enumerate[PrintPerAW];
};
PrintGroupContents:
PROC [to:
IO.
STREAM, a: Array, g: Group, nameGen: NameGenerator] = {
first: BOOL ← TRUE;
to.PutRope["{"];
FOR pl: PortList ← g.ports, pl.rest
WHILE pl #
NIL
DO
p: Port = pl.first;
name: ROPE = Describe[p, a.eltType.port, nameGen];
IF first THEN first ← FALSE ELSE to.PutRope[", "];
SS.Bp[to, lookLeft, printStep];
to.PutRope[name];
ENDLOOP;
to.PutRope["}"];
};
PrintJoint:
PROC [to:
IO.
STREAM, act: CellType, d: Dim, phase: Nat2, j: Joint, nameGen: NameGenerator, groupName: Mapper] = {
GPFPrint:
PROC = {
to.PutF["grouping middles = [%g, %g]", [rope[FmtGP[j.groupingParmses[Foo]]]], [rope[FmtGP[j.groupingParmses[Bar]]]]]};
to.PutRope["{"];
PrintObject[to, FALSE, GPFPrint];
FOR jgi
f:
NAT
IN [0 .. j.groupingParmses[Foo].sum)
DO
FOR jgi
b:
NAT
IN [0 .. j.groupingParmses[Bar].sum)
DO
jgi2: Nat2 = [jgif, jgib];
jgi: NAT = j.groupingParmses[Bar].sum * jgif + jgib;
ties: Set = NARROW[j.ties[jgi]];
GIPrint:
PROC = {
first: BOOL ← TRUE;
PerTie:
PROC [ra:
REF
ANY] = {
tie: Tie = NARROW[ra];
TPrint: PROC = {PrintTie[to, act, d, phase, j, jgi2, tie, nameGen, groupName]};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, TPrint];
};
to.PutF["@[%g, %g] {", [integer[jgif]], [integer[jgib]]];
[] ← ties.Enumerate[PerTie];
to.PutRope["}"];
};
to.PutRope[", "];
PrintObject[to, TRUE, GIPrint];
ENDLOOP ENDLOOP;
to.PutRope["}"];
};
printIncompleteness: BOOL ← TRUE;
PrintTie:
PROC [to:
IO.
STREAM, act: CellType, d: Dim, phase: Nat2, j: Joint, jgi2: Nat2, tie: Tie, nameGen: NameGenerator, groupName: Mapper] = {
Bitch:
PROC = {
CPrint:
PROC = {
to.PutRope[" "];
PrintCliques[to, act, d, phase, j, jgi2, tie, nameGen];
};
to.PutF["(%g/%g incomplete", [integer[tie.completion.nIncomplete]], [integer[tie.completion.length]]];
IF printIncompleteness THEN CPrint[];
to.PutRope[")"];
};
FmtGrp:
PROC [g: Group]
RETURNS [name:
ROPE] = {
IF g = NIL THEN RETURN ["?nil?"];
name ← NARROW[groupName.Map[g]];
IF name = NIL THEN name ← "??"};
to.PutF["%g—%g", [rope[FmtGrp[tie.groups[low]]]], [rope[FmtGrp[tie.groups[high]]]]];
IF tie.completion # NIL THEN Bitch[];
};
FmtGP:
PROC [gp: GroupingParms]
RETURNS [asRope:
ROPE] = {
asRope ← IO.PutFR["[%g..%g]", [integer[gp.middle.min]], [integer[gp.middle.maxPlusOne-1]]]};
PrintCliques:
PROC [to:
IO.
STREAM, act: CellType, d: Dim, phase: Nat2, j: Joint, jgi2: Nat2, tie: Tie, nameGen: NameGenerator] = {
a: Array = act.asArray;
jSize: Nat2 = Nat2Tweak[a.size, d, -1];
jiir: Range2 = Jgi2ToLair[a, phase, j, jgi2].jiir;
jif0, jif1: NAT ← 0;
RowSame:
PROC [f0, f1:
NAT]
RETURNS [same:
BOOL] = {
clai00f: NAT = jSize[Bar] * f0;
clai00b: NAT = jiir[Bar].min * a.jointsPeriod[Bar] + phase[Bar];
FOR side: End
IN End
DO
g: Group = tie.groups[side];
IF g #
NIL
THEN {
FOR ports: PortList ← g.ports, ports.rest
WHILE ports #
NIL
DO
port: Port = ports.first;
rpd: RoledPortData = FetchRPD[a, d, [side, port]];
clai0: NAT ← clai00f + clai00b;
clai1: NAT ← jSize[Bar] * f1 + clai00b;
IF rpd = NIL THEN ERROR;
FOR ji
b:
INT
IN [jiir[Bar].min .. jiir[Bar].maxPlusOne)
DO
IF GetRoot[a, d, rpd, clai0] # GetRoot[a, d, rpd, clai1] THEN RETURN [FALSE];
clai0 ← clai0 + a.jointsPeriod[Bar];
clai1 ← clai1 + a.jointsPeriod[Bar];
ENDLOOP;
ENDLOOP;
};
ENDLOOP;
same ← TRUE;
};
to.PutRope["["];
FOR ji
f0 ← jiir[Foo].min, ji
f1
WHILE ji
f0 < jiir[Foo].maxPlusOne
DO
f0: NAT = jif0 * a.jointsPeriod[Foo] + phase[Foo];
f1: NAT ← f0 + a.jointsPeriod[Foo];
RPrint:
PROC = {
to.PutRope[FmtRange[[jif0, jif1]]];
to.PutRope[": "];
PrintRowCliques[to, act, d, phase, j, jiir, tie, f0, nameGen];
};
FOR ji
f1 ← ji
f0+1, ji
f1+1
UNTIL ji
f1 = jiir[Foo].maxPlusOne
OR
NOT RowSame[f0, f1]
DO
f1 ← f1 + a.jointsPeriod[Foo];
ENDLOOP;
IF jif0 > jiir[Foo].min THEN to.PutRope[", "];
PrintObject[to, FALSE, RPrint];
ENDLOOP;
to.PutRope["]"];
};
PrintRowCliques:
PROC [to:
IO.
STREAM, act: CellType, d: Dim, phase: Nat2, j: Joint, jiir: Range2, tie: Tie, f:
NAT, nameGen: NameGenerator] = {
a: Array = act.asArray;
jSize: Nat2 = Nat2Tweak[a.size, d, -1];
claiBase: NAT = jSize[Bar] * f;
ColSame:
PROC [b0, b1:
NAT]
RETURNS [same:
BOOL] = {
FOR side: End
IN End
DO
g: Group = tie.groups[side];
IF g #
NIL
THEN {
FOR ports: PortList ← g.ports, ports.rest
WHILE ports #
NIL
DO
port: Port = ports.first;
rpd: RoledPortData = FetchRPD[a, d, [side, port]];
IF GetRoot[a, d, rpd, claiBase+b0] # GetRoot[a, d, rpd, claiBase+b1] THEN RETURN [FALSE];
ENDLOOP;
};
ENDLOOP;
same ← TRUE;
};
jib0, jib1: NAT ← 0;
to.PutRope["("];
FOR ji
b0 ← jiir[Bar].min, ji
b1
WHILE ji
b0 < jiir[Bar].maxPlusOne
DO
b0: NAT = jib0 * a.jointsPeriod[Bar] + phase[Bar];
b1: NAT ← b0 + a.jointsPeriod[Bar];
CPrint:
PROC = {
to.PutRope[FmtRange[[jib0, jib1]]];
to.PutRope[": "];
PrintColCliques[to, act, d, j, tie, [f, b0], nameGen];
};
FOR ji
b1 ← ji
b0+1, ji
b1+1
UNTIL ji
b1 = jiir[Bar].maxPlusOne
OR
NOT ColSame[b0, b1]
DO
b1 ← b1 + a.jointsPeriod[Foo];
ENDLOOP;
IF jib0 > jiir[Bar].min THEN to.PutRope[", "];
PrintObject[to, FALSE, CPrint];
ENDLOOP;
to.PutRope[")"];
};
cliques: RefTable--root rpd b member rpd list-- = CreateRefTable[];
PrintColCliques:
PROC [to:
IO.
STREAM, act: CellType, d: Dim, j: Joint, tie: Tie, lai: Nat2, nameGen: NameGenerator] = {
a: Array = act.asArray;
jSize: Nat2 = Nat2Tweak[a.size, d, -1];
clai: NAT = jSize[Bar] * lai[Foo] + lai[Bar];
to.PutRope["{"];
cliques.Erase[];
FOR side: End
IN End
DO
g: Group = tie.groups[side];
IF g #
NIL
THEN {
FOR ports: PortList ← g.ports, ports.rest
WHILE ports #
NIL
DO
port: Port = ports.first;
rpd: RoledPortData = FetchRPD[a, d, [side, port]];
rootIndex: NAT = GetRoot[a, d, rpd, clai];
root: RoledPortData = NARROW[a.roles[d].refs[rootIndex]];
members: RoledPortDataList ← NARROW[cliques.Fetch[root].value];
members ← CONS[rpd, members];
[] ← cliques.Store[root, members];
ENDLOOP;
};
ENDLOOP;
{first: BOOL ← TRUE;
PrintClique:
PROC [key, value:
REF
ANY]
RETURNS [quit:
BOOL ←
FALSE]
--HashTable.EachPairAction-- = {
members: RoledPortDataList = NARROW[value];
CPrint:
PROC = {
first: BOOL ← TRUE;
to.PutRope["("];
FOR rpds: RoledPortDataList ← members, rpds.rest
WHILE rpds #
NIL
DO
rpd: RoledPortData = rpds.first;
IF first THEN first ← FALSE ELSE to.PutRope[", "];
SS.Bp[to, width, printStep];
to.PutRope[FmtRPD[a, rpd, nameGen]];
ENDLOOP;
to.PutRope[")"];
};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, CPrint];
};
[] ← cliques.Pairs[PrintClique];
to.PutRope["}"];
}};
FmtRPD:
PROC [a: Array, rpd: RoledPortData, nameGen: NameGenerator]
RETURNS [asRope:
ROPE] = {
asRope ← EndName[rpd.side].Cat["/", Describe[rpd.port, a.eltType.port, nameGen]];
};
FmtRange:
PROC [r: Range]
RETURNS [asRope:
ROPE] = {
asRope ← Convert.RopeFromInt[r.min];
IF r.min+1 # r.maxPlusOne THEN asRope ← asRope.Cat["~", Convert.RopeFromInt[r.maxPlusOne-1]];
};
PrintArrays:
PROC [to:
IO.
STREAM, design: Design, nameGen: NameGenerator ←
NIL] = {
Filter:
PROC [ct: CellType]
RETURNS [pass:
BOOL] = {
pass ← ct.asArray # NIL;
};
PrintDesignSubset[to, design, nameGen, Filter];
};
PrintIncompletes:
PROC [to:
IO.
STREAM, design: Design, nameGen: NameGenerator ←
NIL] = {
PrintDesignSubset[to, design, nameGen, IsIncompleteArray];
};
END.