-- File: IPCB.mesa
-- Last Edited by: CSChow, February 2, 1985 2:31:10 am PST
--Note: IPCB = ChannelBoundary
--This is an abstration of all the intersection information of a channel. It records all the (Channel)
-- intersections, and neighboring components. These interface is separated from CTG to make
-- CTG independent of it.
--This can be considered part of the 'underground world' so the code are quite sensitive
-- to changes.
DIRECTORY
IP;
IPCB: CEDAR DEFINITIONS = BEGIN
Ref: TYPE = REF Rep;
Rep: TYPE = IP.ChBoundaryRep;
IntersectionNode: TYPE = REF IntersectionNodeRep;
IntersectionNodeRep: TYPE = IP.IntersectionNodeRep;
Intersection: TYPE = REF IP.IntersectionRep;
Channel: TYPE = REF IP.ChannelRep;
Component: TYPE = REF IP.ComponentRep;
IntersectionType: TYPE = IP.IntersectionType;
PIntersectionType: TYPE = [0..1];
NIntersectionType: TYPE = [-1..0];
Cross, TEnd: IntersectionType = 0;
TNeg, LNeg: IntersectionType = -1;
TPos, LPos: IntersectionType = 1;
Side: TYPE = IP.PolarityTypes;
EachINodeAction: TYPE = PROC [iNd: IntersectionNode] RETURNS [quit: BOOLFALSE];
EachIntersectionAction: TYPE = PROC[i: Intersection] RETURNS[quit: BOOLFALSE];
EachComponentAction: TYPE = PROC[co: Component] RETURNS[quit: BOOLFALSE];
EachChSegAction: TYPE = PROC [r: Ref, negIntNd, posIntNd: IntersectionNode] RETURNS [quit: BOOLFALSE];
--Client should only access IPCB with the operations given below --
SideEmpty: ERROR;
NotFound: ERROR;
Create: PROC[owner: Channel] RETURNS[r: Ref];
Destroy: PROC[r: Ref];
CheckSelf: PROC[r: Ref];
GetOwner: PROC[r: Ref] RETURNS [Channel] = INLINE {RETURN [r.owner]};
End: PROC[r: Ref, which: Side] RETURNS[Intersection];
NthINode: PROC [r: Ref, which: Side, n: INT] RETURNS[IntersectionNode];
NthIntersection: PROC[r: Ref, which: Side, n: INT] RETURNS[Intersection];
NthComponent: PROC [r: Ref, which: Side, n: INT] RETURNS[Component];
NoIntersection: PROC[r: Ref, which: Side] RETURNS[BOOL];
NoComponent: PROC[r: Ref, which: Side] RETURNS[BOOL];
ComponentOn: PROC[r: Ref, comp: Component, which: Side] RETURNS[BOOL];
EndCh: PROC[r: Ref, ch: Channel] RETURNS [BOOL] = INLINE{RETURN [r.negEnd.intersection.ch = ch OR r.posEnd.intersection.ch = ch]}; --EndCh--
GetChNbr: PROC[r:Ref, ch: Channel, whichNbr, hint: Side] RETURNS [Channel];
SetBoundary: PROC[r: Ref, negEnd, posEnd: Intersection, negSide, posSide: LIST OF Intersection];
InsertCoBetween: PROC[r: Ref, co: Component, negBnd, posBnd: Channel, which: Side];
InsertCoAt: PROC[r: Ref, co: Component, whichSide, whichEnd: Side];
Components: PROC[r: Ref, which: Side, p: EachComponentAction] RETURNS[BOOL];
Intersections: PROC[r: Ref, which: Side, p: EachIntersectionAction] RETURNS[BOOL];
IntersectionNodes: PROC[r: Ref, p: EachINodeAction, which: Side] ;
AllIntersectionNodes: PROC [r: Ref, p: PROC [iNd: IntersectionNode]];
AllInteriorIntersections: PROC [r: Ref] RETURNS[LIST OF IntersectionNode];
ChannelSegments: PROC[r: Ref, p: EachChSegAction] RETURNS[BOOL];
enumerate each segment between two channels on r
--######Used mainly by EditOpsImpl######--
GetINode: PROC[r: Ref, ch: Channel, hint: Side] RETURNS [IntersectionNode];
IntersectsCh: PROC[r: Ref, ch: Channel] RETURNS [BOOL];
ArmOn: PROC[r: Ref, ch: Channel, which: Side] RETURNS [BOOL];
SideAddl: PROC [r: Ref, iNd: IntersectionNode, which: Side] RETURNS [IntersectionNode];
SideAddh: PROC [r: Ref, iNd: IntersectionNode, which: Side] RETURNS [IntersectionNode];
SideInsert: PROC[r:Ref, iNd: IntersectionNode, negBnd, posBnd: Channel, which: Side] RETURNS [IntersectionNode];
SetEnd: PROC [r: Ref, iNd: IntersectionNode, whichEnd: Side] RETURNS [IntersectionNode];
GetEnd: PROC [r: Ref, whichEnd: Side] RETURNS [IntersectionNode] = INLINE {
RETURN [(SELECT whichEnd FROM neg => r.negEnd, pos => r.posEnd, ENDCASE => ERROR)]};--GetEnd--
SideRemovel: PROC [r: Ref, which: Side] RETURNS [iNd: IntersectionNode]; --! Raise SideEmpty error--
SideRemoveh: PROC [r: Ref, which: Side] RETURNS [iNd: IntersectionNode]; --! Raise SideEmpty error--
SideRem: PROC[r: Ref, ch: Channel, which: Side, repCo: Component] RETURNS [iNd: IntersectionNode]; --! Raise NotFound --
SideRem2: PROC[r: Ref, iNd: IntersectionNode, repCo: Component] RETURNS [IntersectionNode]; --! Raise NotFound --
Fragment: PROC [r: Ref, co1, co2: Component, negCh, posCh: Channel];
Merge: PROC [negR, posR: Ref, owner: Channel];
XingCount: PROC[r: Ref, ch: Channel, which: Side] RETURNS [INT];
--returns 'Crossing count' of ch with respect to owner of r
InCount: PROC[r: Ref, ch: Channel, which: Side] RETURNS [INT];
--returns 'intersection count' of ch with respect to owner of r
SetUpDuals: PROC [iNd: IntersectionNode, hint: Side] ;
SideGet: PROC [r: Ref, which: Side] RETURNS [Hd, Tl: LIST OF IntersectionNode];
SideSetComp: PROC [r: Ref, comp: Component, which: Side];
SideGetComp: PROC [r: Ref, which: Side] RETURNS [Component];
SetINodeComps: PROC [iNd: IntersectionNode, negComp, posComp: Component] = INLINE{ iNd.negComp ← negComp; iNd.posComp ← posComp};
SetINodeComp: PROC[iNd: IntersectionNode, comp: Component, which: Side] = INLINE {
SELECT which FROM
neg => iNd.negComp ← comp;
pos => iNd.posComp ← comp;
ENDCASE => ERROR}; --SetINodeComp--
INodeDual: PROC[iNd: IntersectionNode] RETURNS [IntersectionNode] = INLINE {RETURN [iNd.dual]}; --INodeDual--
SetINodeDual: PROC[iNd, iNdDual: IntersectionNode] = INLINE{iNd.dual ← iNdDual}; --SetINodeDual--
DestroyINode: PROC[iNd: IntersectionNode] = INLINE {iNd.dual ← NIL}; --DestroyINode--
ItoINode: PROC [i: Intersection, o: Channel] RETURNS [IntersectionNode];
SideOpenHole1: PROC[mainR, sideR: Ref, negBnd, posBnd: Channel, sideToOp: Side];
SideOpenHole2: PROC[mainR, sideR: Ref, negBnd, posBnd: Channel, sideToOp: Side];
SideCloseHole1: PROC[mainR, sideR: Ref, negBnd, posBnd: Channel, sideToCl: Side];
SideCloseHole2: PROC[mainR, sideR: Ref, negBnd, posBnd: Channel, sideToCl: Side];
END.