--File: IPPlaceKitImpl.mesa
Last Edited by: CSChow, January 25, 1985 12:43:58 pm PST
DIRECTORY
OrderedRefArray,
IP,
IPCB,
IPCoTab,
IPCTG,
IPTop,
IPTopOps,
IPBasicOps,
IPTopOpRecs,
IPPlaceKit;
IPPlaceKitImpl: CEDAR PROGRAM
IMPORTS OrderedRefArray, IP, IPBasicOps, IPCoTab, IPCTG, IPCB, IPTopOps
EXPORTS IPPlaceKit = BEGIN OPEN IPPlaceKit;
-- Operation to execute a trial
Execute: PUBLIC PROC[top: IPTop.Ref, trial: REF] ={
WITH trial SELECT FROM
gr: REF GrowRec => [] ← IPTopOps.Grow[top, gr.co, gr.chToSplit, gr.negBnd, gr.posBnd, TRUE];
com: IPTopOpRecs.RComposite => IPTopOps.Redo[top, com];
ENDCASE => ERROR IP.Error[callingError, "Execute doesnt know about this type"]
}; --Execute
--Trials Generating Primitives: :
CreateChEnumData: PUBLIC PROC[refCh: IPCTG.Channel] RETURNS [ChEnumData] ={
RETURN [NEW[ChEnumDataRep ← [IPCB.End[refCh.boundary, neg].ch, IPCB.End[refCh.boundary, pos].ch, refCh.boundary.negSideHd, refCh.boundary.posSideHd]]]};--CreateChEnumData
GetChSucc: PUBLIC PROC[data: ChEnumData, getXOnce: BOOLTRUE] RETURNS [IPCTG.Channel] ={
countXOnce: BOOLTRUE;
chSucc: IPCTG.Channel ← data.nextCh;
negSide: LIST OF REF IP.IntersectionNodeRep ← data.negSidePtr;
posSide: LIST OF REF IP.IntersectionNodeRep ← data.posSidePtr;
IF negSide = NIL OR posSide = NIL
THEN {
--(0) chSucc = NIL
IF chSucc = NIL THEN RETURN [NIL];
--(1) negSide # NIL
IF negSide # NIL THEN {data.nextCh ← negSide.first.intersection.ch; data.negSidePtr ← data.negSidePtr.rest};
--(2) posSide # NIL
IF posSide # NIL THEN {data.nextCh ←posSide.first.intersection.ch; data.posSidePtr ← data.posSidePtr.rest};
--(3) Both NILs
IF negSide = NIL AND posSide = NIL THEN {
IF chSucc = data.finalCh
THEN data.nextCh ← NIL
ELSE data.nextCh ← data.finalCh;};
}
ELSE {
negCh: IPCTG.Channel ← negSide.first.intersection.ch;
posCh: IPCTG.Channel ← posSide.first.intersection.ch;
IF IPCTG.GetCoord[negCh] > IPCTG.GetCoord[posCh]
THEN {data.nextCh ← posCh; data.posSidePtr ← data.posSidePtr.rest}
ELSE {data.nextCh ← negCh; data.negSidePtr ← data.negSidePtr.rest};
IF getXOnce AND negCh = posCh THEN data.posSidePtr ← data.posSidePtr.rest;
-- negCh = posCh => IPCTG.GetCoord[negCh] = IPCTG.GetCoord[posCh]
-- => data.negSidePtr has been incremented.
-- So if getXOnce then need to increment data.posSidePtr
}; --endIF
RETURN [chSucc];
};--GetChSucc
AllChGrowSites: PUBLIC PROC[refCh: IPCTG.Channel, action: EachChGrowSiteAction] ={
negBnd: ChEnumData ← CreateChEnumData[refCh];
posBnd: ChEnumData ← CreateChEnumData[refCh];
negCh, posCh: IPCTG.Channel;
DO
negCh ← GetChSucc[negBnd, TRUE];
IF negCh = NIL THEN EXIT;
posBnd^ ← negBnd^;
DO
next, quit: BOOL;
posCh ← GetChSucc[posBnd, TRUE];
IF posCh = NIL THEN EXIT;
[next, quit] ← action[negCh, posCh];
IF quit THEN RETURN;
IF next THEN EXIT;
ENDLOOP;
ENDLOOP;
}; --AllChGrowSites
ChGrowSites: PUBLIC PROC[refCh: IPCTG.Channel, whichSide: IP.PolarityTypes, action: EachChGrowSiteAction]= {
filterSites: EachChGrowSiteAction ={
IF ~IPCTG.ArmOn[refCh, negBnd, whichSide] OR ~IPCTG.ArmOn[refCh, posBnd, whichSide]
THEN RETURN;
[next, quit] ← action[negBnd, posBnd]
}; --filterSites
AllChGrowSites[refCh, filterSites]
}; --ChGrowSites
AllTopGrow1Sites: PUBLIC PROC[top: IPTop.Ref, action: EachTopGrow1SiteAction] ={
eachComp: IPCoTab.EachComponentAction = {
FOR corner: IPCoTab.CornerTypes IN [sw..nw] UNTIL quit DO
IF CoCornerFree[co, corner] THEN quit ← action[co, corner]
ENDLOOP;
}; --eachComp
IPCoTab.Components[top.coTab, eachComp]
}; --AllTopGrow1Sites
SideComponents: PUBLIC PROC[refCh: IPCTG.Channel, which: IPCTG.Side, action: IPCoTab.EachComponentAction] ={
filteredAction: IPCTG.EachComponentAction ={
IF co # NIL THEN RETURN [action[co]]}; --filteredAction
[] ← IPCTG.Components[refCh, which, filteredAction]
}; --SideComponents
SideChannels: PUBLIC PROC[refCh: IPCTG.Channel, which: IPCTG.Side, action: IPCTG.EachChannelAction] ={
intersectionAction: IPCTG.EachIntersectionAction ={
RETURN [action[i.ch]]
}; --intersectionAction
[] ← IPCTG.Intersections[refCh, which, intersectionAction]
}; --SideChannels
-- Useful routines
NonActiveComps: PUBLIC PROC [top: IPTop.Ref, action: IPCoTab.EachComponentAction] ={
nonActiveComps: IPCoTab.EachComponentAction ={
IF IPCoTab.CoActive[co]
THEN NULL
ELSE RETURN [action[co]]
}; --nonActiveComps
IPCoTab.AllComponents[top.coTab, nonActiveComps];
}; --NonActiveComps
CountComps: PUBLIC PROC[comps: Components] RETURNS [count: NAT ← 0] ={
UNTIL comps = NIL DO
count ← count.SUCC;
comps ← comps.rest;
ENDLOOP
}; --CountComps
CopyCompsHead: PUBLIC PROC[comps: Components, head: NAT] RETURNS [compHd, compRest: Components] ={
IF head = 0 OR comps = NIL
THEN RETURN [NIL, comps]
ELSE {
compTl: Components ← LIST[comps.first];
compHd ← compTl;
DO
head ← head.PRED;
comps ← comps.rest;
IF comps = NIL OR head = 0 THEN {compRest ← comps; EXIT};
compTl.rest ← LIST[comps.first];
compTl ← compTl.rest
ENDLOOP;
};
}; --CopyCompsHead
GetComponents: PUBLIC PROC[remTrack: LIST OF REF] RETURNS [comps: Components ← NIL] ={
getCo: PROC[step: REF] ={
WITH step SELECT FROM
s1: IPTopOpRecs.FRShrink1 => comps ← CONS[s1.co, comps];
rc: IPTopOpRecs.FRRemoveCo => comps ← CONS[rc.co, comps];
cm: IPTopOpRecs.RComposite => getCo[cm.first];
ENDCASE =>
ERROR IP.Error[callingError, "GetComponents doesn't know about this type"];
}; --getCo
UNTIL remTrack = NIL DO
getCo[remTrack.first];
remTrack ← remTrack.rest
ENDLOOP;
}; --GetComponents
GetComponentArea: PUBLIC PROC[comp: IPCoTab.Component, minusUsedCorners, minusFreeCorners: BOOLTRUE] RETURNS [area: INT] ={
xDim, yDim: INT;
--(1) Compute area of outline
[xDim, yDim] ← IPCoTab.GetDim[comp];
area ← (xDim * yDim);
--(2) Subtract area of corners
FOR corner: IP.CornerTypes IN [sw..nw] DO
cornerChs: IPCoTab.CornerChannels ← IPCoTab.GetCornerChs[comp, corner];
cornerSp: IPCoTab.CornerSpace ← IPCoTab.GetCornerSp[comp, corner];
areaDecr: INT;
IF cornerSp = NIL
THEN areaDecr ← 0
ELSE {
[xDim, yDim] ← cornerSp^;
areaDecr ← (xDim * yDim);
};
IF cornerChs = NIL
THEN {
IF minusFreeCorners THEN area ← (area - areaDecr)
}
ELSE {
IF minusUsedCorners THEN area ← (area - areaDecr)
}
ENDLOOP;
}; --GetComponentArea
CoCornerFree: PUBLIC PROC[co: IPCoTab.Component, corner: IPCoTab.CornerTypes] RETURNS [BOOL] ={
RETURN [IPCoTab.GetCornerSp[co, corner] # NIL AND (IPCoTab.GetCornerChs[co, corner] = NIL OR ~IPCoTab.CoActive[co])]
}; --CoCornerBitible
ComputeZType: PUBLIC PROC[corner: IPCoTab.CornerTypes, refChType: IPCTG.ChType] RETURNS [IP.PolarityTypes] ={
SELECT refChType FROM
hor => RETURN [IF corner = sw OR corner = ne THEN pos ELSE neg];
ver => RETURN [IF corner = sw OR corner = ne THEN neg ELSE pos];
ENDCASE => ERROR;
}; --ComputeZType
--High level routines
CompactComp0: PUBLIC PROC[
top: IPTop.Ref,
comp: IPCoTab.Component,
direction: IPCTG.ChType,
placeEval: PlaceEvaluator, -- Simply use as an eval function no prunning
results: OrderedRefArray.Ref,
resultsAfter: NAT,
keepInitTrack: BOOLTRUE, --Provided for convenience
formZOk: BOOLTRUE -- This means okay to formz during compaction
] ={
directnFlipped: IPCTG.ChType ← IPBasicOps.OTFlip[direction];
addTrack: PROC ={
value: INT ← placeEval[top, NIL].value;
OrderedRefArray.Insert[results, IPTopOps.GetTrack[top, resultsAfter], value]
}; --addTrack
biteCorner: PROC[corner: IPCoTab.CornerTypes] ={
IF IPCoTab.GetCornerSp[comp, corner] # NIL THEN {
refCh: IPCTG.Channel ← IPCoTab.GetPrinCh[comp, IPBasicOps.CTResolveFor[corner, directnFlipped]];
chSide: IPCTG.Side ← IPBasicOps.CTDirectnFor[corner, direction];
tToLAction: IPCTG.EachChannelAction ={
[] ← IPTopOps.TtoL[top, comp, ch, IPBasicOps.CTDirectnFor[corner, directnFlipped], TRUE];
addTrack[];
IF corner # nw THEN biteCorner[corner.SUCC];
[] ← IPTopOps.Undo1[top];
};--tToLAction
fZAction: IPCoTab.EachComponentAction ={
cornerDiag: IPCoTab.CornerTypes ← IPBasicOps.CTDiag[corner];
IF IPTopOps.FormZChk[top, co, comp, ComputeZType[corner, directnFlipped]]
THEN {
[] ← IPTopOps.FormZ[top, co, comp, ComputeZType[corner, directnFlipped], TRUE];
addTrack[];
IF corner # nw THEN biteCorner[corner.SUCC];
[] ← IPTopOps.Undo1[top];
};
}; --fZAction
SideChannels[refCh, chSide, tToLAction];
IF formZOk THEN SideComponents[refCh, chSide, fZAction];
}; --endIf
IF corner # nw THEN biteCorner[corner.SUCC];
};--biteCorner
IF keepInitTrack THEN addTrack[];
biteCorner[sw];
}; --CompactComp0
CompactComp1: PUBLIC PROC[
top: IPTop.Ref,
comp: IPCoTab.Component,
direction: IPCTG.ChType,
placeEval: PlaceEvaluator, -- Simply use as an eval function no prunning
results: OrderedRefArray.Ref, -- improvement added here
resultsAfter: NAT,
keepInitTrack: BOOLTRUE --Provided for convenience
] ={
eachNeighborAction: IPCoTab.EachComponentAction = {
CompactComp0[top, comp, direction, placeEval, results, resultsAfter, FALSE, FALSE]
}; --eachNeighborAction
--(1) Apply compaction to comp
CompactComp0[top, comp, direction, placeEval, results, resultsAfter, keepInitTrack, TRUE];
SELECT direction FROM
hor => {
SideComponents[IPCoTab.GetPrinCh[comp, west], neg, eachNeighborAction];
SideComponents[IPCoTab.GetPrinCh[comp, east], pos, eachNeighborAction];
direction ← IPBasicOps.OTFlip[direction];
SideComponents[IPCoTab.GetPrinCh[comp, south], neg, eachNeighborAction];
SideComponents[IPCoTab.GetPrinCh[comp, north], pos, eachNeighborAction];
};
ver => {
SideComponents[IPCoTab.GetPrinCh[comp, south], neg, eachNeighborAction];
SideComponents[IPCoTab.GetPrinCh[comp, north], pos, eachNeighborAction];
direction ← IPBasicOps.OTFlip[direction];
SideComponents[IPCoTab.GetPrinCh[comp, west], neg, eachNeighborAction];
SideComponents[IPCoTab.GetPrinCh[comp, east], pos, eachNeighborAction];
};
ENDCASE => ERROR;
}; --CompactComp1
FTPerturbTop: PUBLIC PROC[ --FT = FlipT
top: IPTop.Ref,
placeEval: PlaceEvaluator, -- Simply use as an eval function no prunning
depth: NAT,
results: OrderedRefArray.Ref,
resultsAfter: NAT,
keepInitTrack: BOOLTRUE --Provided for convenience
] ={
whichEnd: IP.PolarityTypes;
eachTrialAction: EachChGrowSiteAction ={
-- Perhaps should do prunning, but how??
IF IPTopOps.FlipTChk[top, negBnd, posBnd, whichEnd] THEN {
[] ← IPTopOps.FlipT[top, negBnd, posBnd, whichEnd, TRUE];
FTPerturbTop[top, placeEval, depth.PRED, results, resultsAfter, TRUE];
[] ← IPTopOps.Undo1[top]
};
IF IPTopOps.FlipTChk[top, posBnd, negBnd, whichEnd] THEN {
[] ← IPTopOps.FlipT[top, posBnd, negBnd, whichEnd, TRUE];
FTPerturbTop[top, placeEval, depth.PRED, results, resultsAfter, TRUE];
[] ← IPTopOps.Undo1[top]
};
}; --eachTrackAction
eachChAction: IPCTG.EachChannelAction = {
whichEnd ← neg; -- info used above
ChGrowSites[ch, neg, eachTrialAction];
whichEnd ← pos; -- info used above
ChGrowSites[ch, pos, eachTrialAction];
}; --eachChAction
IF keepInitTrack THEN OrderedRefArray.Insert[results, IPTopOps.GetTrack[top, resultsAfter], placeEval[top, NIL].value];
IF depth > 0 THEN [] ← IPCTG.Channels[top.ctg, eachChAction]
};--FTPerturbTop
END.