LichenDataImpl1B.Mesa
Last tweaked by Mike Spreitzer on August 2, 1988 4:23:13 pm PDT
DIRECTORY AbSets, AMBridge, BasicTime, BiRelImplementor, BiRels, Convert, FS, Interpreter, InterpreterOps, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, List, ProcessProps, Rope, RopeHash, SetBasics, SymTab;
LichenDataImpl1B:
CEDAR
PROGRAM
IMPORTS AbSets, AMBridge, BiRelImplementor, BiRels, Convert, FS, InterpreterOps, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, List, ProcessProps, Rope, RopeHash, SetBasics, SymTab
EXPORTS LichenDataStructure
=
BEGIN OPEN IB:LichenIntBasics, IB, LichenDataStructure, LichenDataOps, Sets:AbSets;
nyet: PUBLIC ERROR ~ CODE;
Warning: PUBLIC SIGNAL [msg: ROPE, v1, v2, v3, v4, v5: REF ANY ← NIL] ~ CODE;
Error: PUBLIC ERROR [msg: ROPE, v1, v2, v3, v4, v5: REF ANY ← NIL] ~ CODE;
PartClassName:
PUBLIC
ARRAY PartClass
OF
ROPE ← [
p: "port",
w: "wire",
i: "cell instance"];
anyROPE: PUBLIC ROPE ~ R["any rope"];
anyInt: PUBLIC REF INT ~ NEW [INT ← INT.LAST-1];
DimName: ARRAY Dim2 OF ROPE = [X: "X", Y: "Y"];
genBland: NameGenerator =
NEW [NameGeneratorPrivate ← [
GenerateBlandName,
NEW [NameCountsPrivate ← []]
]];
NameCounts: TYPE = REF NameCountsPrivate;
NameCountsPrivate:
TYPE =
RECORD [
d, cellType, port, vertex: INT ← 0
];
genSymbol: NameGenerator =
NEW [NameGeneratorPrivate ← [
GenerateSymbolName,
NEW [TVNameGeneratorPrivate ← [
nc: NEW [NameCountsPrivate ← []],
symbols: LIST[SymTab.Create[]]
]]
]];
TVNameGenerator: TYPE = REF TVNameGeneratorPrivate;
TVNameGeneratorPrivate:
TYPE =
RECORD [
nc: NameCounts,
symbols: Interpreter.SymbolsList
];
defaultNameGen: NameGenerator ~ genSymbol;
nameStepSpace:
PUBLIC SetBasics.Space ~
NEW [SetBasics.SpacePrivate ← [
Contains: StepContains,
Equal: StepEqual,
AHash: StepHash,
ACompare: StepCompare,
Print: StepPrint,
name: "name steps"
]];
steplistSpace:
PUBLIC SetBasics.Space ~
NEW [SetBasics.SpacePrivate ← [
Contains: SteppyNamesContains,
Equal: SteplistEqual,
AHash: SteppyNamesHash,
ACompare: SteplistCompare,
Print: SteppyNamesPrint,
name: "steplists"
]];
steppyNameSpace:
PUBLIC SetBasics.Space ~
NEW [SetBasics.SpacePrivate ← [
Contains: SteppyNamesContains,
Equal: SteppyNamesEqual,
AHash: SteppyNamesHash,
ACompare: SteppyNamesCompare,
Print: SteppyNamesPrint,
name: "steppy names"
]];
emptyRopeSet: PUBLIC Set ~ Sets.CreateEmptySet[SetBasics.ropes[TRUE]];
emptySteppySet: PUBLIC Set ~ Sets.CreateEmptySet[steppyNameSpace];
gends: PUBLIC Set ~ Sets.CreateFilter[[TestGrade, steppyNameSpace, $gend], constant];
longNames: PUBLIC Set ~ Sets.CreateFilter[[TestGrade, steppyNameSpace, $long], constant];
nonGlobals: PUBLIC Set ~ Sets.CreateFilter[[TestGrade, steppyNameSpace, $nonGlobal], constant];
powerNames: PUBLIC Set ~ Sets.CreateFilter[[TestGrade, steppyNameSpace, $power], constant];
lastRope: PUBLIC BiRel ~ BiRels.FnFromProc[Apply: ApplyLastRope, spaces: [steppyNameSpace, SetBasics.ropes[TRUE]], constant: TRUE];
vddRopes: PUBLIC Set ~ Sets.RopesMatching[["vdd*", FALSE, star]];
gndRopes: PUBLIC Set ~ Sets.RopesMatching[["gnd*", FALSE, star]];
vddNames: PUBLIC Set ~ lastRope.Image[vddRopes, rightToLeft];
gndNames: PUBLIC Set ~ lastRope.Image[gndRopes, rightToLeft];
endOfQ: PUBLIC Vertex ~ NEW [VertexPrivate[i]];
IntRefArray: TYPE ~ ARRAY [0 .. 64] OF REF INT;
intRefs: REF IntRefArray ~ NEW [IntRefArray ← ALL[NIL]];
matchingClass: BiRels.BiRelClass ~ BiRelImplementor.CreateClass[[HasPair: MatchingHasPair, Spaces: BothSNSpace, mutability: constant]];
overlapClass: BiRels.BiRelClass ~ BiRelImplementor.CreateClass[[HasPair: OverlapHasPair, Spaces: BothSNSpace, mutability: constant]];
matching: PUBLIC BiRel ~ [matchingClass, NIL];
difoverlap: PUBLIC BiRel ~ [overlapClass, NIL];
Describe:
PUBLIC
PROC [d: Design, subject:
REF
ANY, relativeTo:
REF
ANY ←
NIL, nameGen: NameGenerator ←
NIL]
RETURNS [name:
ROPE] = {
name ← UnparseRootedSteppyName[SteppyDescribe[d, subject, relativeTo, nameGen]];
RETURN};
SteppyDescribe:
PUBLIC
PROC [d: Design, subject:
REF
ANY, relativeTo:
REF
ANY ←
NIL, nameGen: NameGenerator ←
NIL]
RETURNS [RootedSteppyName] = {
IF nameGen = NIL THEN nameGen ← defaultNameGen;
IF subject = relativeTo
THEN
RETURN [[noName,
FALSE]]
ELSE
WITH subject
SELECT
FROM
sd: Design => {
short: ROPE ← NARROW[sd.names.AnElt[].MDA];
IF short=
NIL
THEN {
short ← nameGen.GenerateName[nameGen.data, subject];
IF NOT sd.names.AddA[short] THEN ERROR};
RETURN [[OSn[short], FALSE]]};
ct: CellType => {
mv: Sets.MaybeValue ~ ct.d.ctName.Lookup[goal: AV[ct], side: left, order: Sets.alleq];
short: ROPE;
IF mv.found
THEN short ←
NARROW[mv.it.
VA]
ELSE {
short ← nameGen.GenerateName[nameGen.data, subject];
d.ctName.AddNewAA[ct, short]};
IF NOT d.cellTypes.HasMemA[ct] THEN ERROR;
RETURN RSNCat[SteppyDescribe[d, d, relativeTo, nameGen], OSn[short]]};
v: Vertex => {
cct: CellType ~ d.VCct[v];
WITH relativeTo
SELECT
FROM
aw: Wire => {w: Wire ~
NARROW[v];
IF NOT PWIsAncestor[d, aw, w] THEN ERROR;
{msn: MaybeSteppyName ~ ScanRelativeNames[cct, w, aw, w, AcceptAnySteppyName];
IF msn.found THEN RETURN [[msn.it, FALSE]];
RETURN [[SteppyDescribe[d, subject, cct, nameGen].name, Zork[]]]}};
ENDCASE => NULL;
{mv: Sets.MaybeValue ~ cct.fullName[v.class].Lookup[goal: AV[v], side: left];
tail: SteppyName;
IF mv.found THEN tail ← VSn[mv.it] ELSE KnowVertexName[cct, v, tail ← OSn[nameGen.GenerateName[nameGen.data, subject]], FALSE];
RETURN RSNCat[SteppyDescribe[d, cct, relativeTo, nameGen], tail]}};
port: Port => {
cct: CellType ~ d.PCct[port];
WITH relativeTo
SELECT
FROM
ap: Port => {
IF NOT PWIsAncestor[d, ap, port] THEN ERROR;
{msn: MaybeSteppyName ~ ScanRelativeNames[cct, p, ap, port, AcceptAnySteppyName];
IF msn.found THEN RETURN [[msn.it, FALSE]];
RETURN [[SteppyDescribe[d, subject, cct, nameGen].name, Zork[]]]}};
ENDCASE => NULL;
{mv: Sets.MaybeValue ~ cct.fullName[p].Lookup[goal: AV[port], side: left];
tail: SteppyName;
IF mv.found THEN tail ← VSn[mv.it] ELSE KnowPortName[cct, port, tail ← OSn[nameGen.GenerateName[nameGen.data, subject]], FALSE];
RETURN RSNCat[SteppyDescribe[d, cct, relativeTo, nameGen], tail]}};
ENDCASE => ERROR;
};
Zork:
PROC
RETURNS [
BOOL]
~ {IF sigz THEN Hard[]; hards ← hards + 1; RETURN [TRUE]};
sigz: BOOL ← TRUE;
Hard: SIGNAL ~ CODE;
hards: INT ← 0;
GenerateBlandName:
PROC [data, subject:
REF
ANY]
RETURNS [name:
ROPE] = {
nc: NameCounts = NARROW[data];
name ← GenByCount[nc, "#", subject];
};
GenByCount:
PROC [nc: NameCounts, sep:
ROPE, subject:
REF
ANY]
RETURNS [name:
ROPE] = {
n: INT ← 0;
WITH subject
SELECT
FROM
d: Design => {n ← nc.d ← nc.d + 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.Cat[sep, Convert.RopeFromInt[n]];
};
GenerateSymbolName:
PROC [data, subject:
REF
ANY]
RETURNS [name:
ROPE] = {
tvng: TVNameGenerator ~ NARROW[data];
evalHead: InterpreterOps.EvalHead ~ NARROW[List.Assoc[$EvalHead, ProcessProps.GetPropList[]]];
syms: Interpreter.SymbolsList ~ IF evalHead#NIL AND evalHead.specials#NIL THEN evalHead.specials ELSE tvng.symbols;
name ← Rope.Concat[IF syms=tvng.symbols THEN "&&" ELSE "&", 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],
symbolsList: syms]};
RETURN};
SteppyNameGradeCompare:
PUBLIC
PROC [g1, g2: SteppyNameGrade]
RETURNS [SetBasics.TotalComparison] ~ {
IF g1 = g2 THEN RETURN [equal];
RETURN [
SELECT
TRUE
FROM
g1.global<g2.global => greater,
g1.global>g2.global => less,
g1.gend<g2.gend => less,
g1.gend>g2.gend => greater,
g1.power<g2.power => greater,
g1.power>g2.power => less,
g1.nonsubs<g2.nonsubs => less,
g1.nonsubs>g2.nonsubs => greater,
g1.subs<g2.subs => less,
g1.subs>g2.subs => greater,
ENDCASE => ERROR--they were equal!--];
};
NameStepListCompare:
PUBLIC
PROC [l1, l2: NameStepList]
RETURNS [c: SetBasics.TotalComparison] ~ {
WHILE l1#l2
DO
IF l1=NIL THEN RETURN [less];
IF l2=NIL THEN RETURN [greater];
WITH l1.first
SELECT
FROM
x1:
REF
INT =>
WITH l2.first
SELECT
FROM
x2: REF INT => IF (c ← SetBasics.CompareIntI[x1^, x2^]) # equal THEN RETURN;
x2: ROPE => RETURN [greater];
ENDCASE => ERROR;
x1:
ROPE =>
WITH l2.first
SELECT
FROM
x2:
ROPE => {
s1: BOOL ~ x1.Equal["gnd", FALSE] OR x1.Equal["vdd", FALSE];
s2: BOOL ~ x2.Equal["gnd", FALSE] OR x2.Equal["vdd", FALSE];
IF s1#s2 THEN RETURN [IF s1 THEN less ELSE greater];
IF (c ← SetBasics.Unbasicify[x1.Compare[x2, FALSE]]) # equal THEN RETURN;
IF (c ← SetBasics.Unbasicify[x1.Compare[x2, TRUE]]) # equal THEN RETURN};
x2: REF INT => RETURN [less];
ENDCASE => ERROR;
ENDCASE => ERROR;
l1 ← l1.rest;
l2 ← l2.rest;
ENDLOOP;
RETURN [equal]};
NameStepListEqual:
PUBLIC
PROC [l1, l2: NameStepList, clip1, clip2: NameStepList ←
NIL]
RETURNS [
BOOL] ~ {
WHILE l1#clip1
AND l2#clip2
DO
WITH l1.first
SELECT
FROM
x:
ROPE =>
WITH l2.first
SELECT
FROM
y: ROPE => IF NOT x.Equal[y] THEN RETURN [FALSE];
y: REF INT => RETURN [FALSE];
ENDCASE => ERROR;
x:
REF
INT =>
WITH l2.first
SELECT
FROM
y: ROPE => RETURN [FALSE];
y: REF INT => IF x^#y^ THEN RETURN [FALSE];
ENDCASE => ERROR;
ENDCASE => ERROR;
l1 ← l1.rest;
l2 ← l2.rest;
ENDLOOP;
RETURN [(l1=clip1) = (l2=clip2)]};
StepContains:
PROC [data:
REF
ANY, v: Sets.Value]
RETURNS [
BOOL] ~ {
RETURN [
WITH v.ra
SELECT
FROM
y: ROPE => TRUE,
y: REF INT => TRUE,
ENDCASE => FALSE]};
StepEqual:
PROC [data:
REF
ANY, v1, v2: Sets.Value]
RETURNS [
BOOL] ~ {
WITH v1.
VA
SELECT
FROM
x:
REF
INT =>
WITH v2.
VA
SELECT
FROM
y: REF INT => RETURN [x^ = y^];
y: ROPE => RETURN [FALSE];
ENDCASE => ERROR;
x:
ROPE =>
WITH v2.
VA
SELECT
FROM
y: REF INT => RETURN [FALSE];
y: ROPE => RETURN [x.Equal[y]];
ENDCASE => ERROR;
ENDCASE => ERROR;
};
StepHash:
PROC [data:
REF
ANY, v: Sets.Value]
RETURNS [
CARDINAL] ~ {
WITH v.
VA
SELECT
FROM
x: REF INT => RETURN SetBasics.HashIntI[x^];
x: ROPE => RETURN [RopeHash.FromRope[rope: x]];
ENDCASE => ERROR;
};
StepCompare:
PROC [data:
REF
ANY, v1, v2: Sets.Value]
RETURNS [SetBasics.TotalComparison] ~ {
WITH v1.
VA
SELECT
FROM
x:
REF
INT =>
WITH v2.
VA
SELECT
FROM
y: REF INT => RETURN [SetBasics.CompareIntI[x^, y^]];
y: ROPE => RETURN [less];
ENDCASE => ERROR;
x:
ROPE =>
WITH v2.
VA
SELECT
FROM
y: REF INT => RETURN [greater];
y: ROPE => RETURN [SetBasics.Unbasicify[x.Compare[y]]];
ENDCASE => ERROR;
ENDCASE => ERROR;
};
StepPrint:
PROC [data:
REF
ANY, v: Sets.Value, to:
IO.
STREAM, depth, length:
INT, verbose:
BOOL] ~ {
WITH v.
VA
SELECT
FROM
x: ROPE => to.PutRope[x];
x: REF INT => to.Put[[integer[x^]]];
ENDCASE => ERROR;
RETURN};
SteppyNamesContains:
PROC [data:
REF
ANY, v: Sets.Value]
RETURNS [
BOOL] ~ {
RETURN [
WITH v.ra
SELECT
FROM
x: NameStepList => TRUE,
ENDCASE => FALSE]};
SteplistEqual:
PROC [data:
REF
ANY, v1, v2: Sets.Value]
RETURNS [
BOOL] ~ {
RETURN [SteplistCompare[data, v1, v2]=equal]};
SteppyNamesEqual:
PROC [data:
REF
ANY, v1, v2: Sets.Value]
RETURNS [
BOOL] ~ {
RETURN [SteppyNamesCompare[data, v1, v2]=equal]};
SteppyNamesHash:
PROC [data:
REF
ANY, v: Sets.Value]
RETURNS [hash:
CARDINAL ← 0] ~ {
n: SteppyName ← VSn[v];
FOR steps: NameStepList ← n.steps, steps.rest
WHILE steps#
NIL
DO
hash ← hash + (
WITH steps.first
SELECT
FROM
x: ROPE => RopeHash.FromRope[x],
x: REF INT => SetBasics.HashIntI[x^],
ENDCASE => ERROR);
ENDLOOP;
RETURN};
SteplistCompare:
PROC [data:
REF
ANY, v1, v2: Sets.Value]
RETURNS [c: SetBasics.TotalComparison] ~ {
n1: SteppyName ~ VSn[v1];
n2: SteppyName ~ VSn[v2];
c ← NameStepListCompare[n1.steps, n2.steps];
RETURN};
SteppyNamesCompare:
PROC [data:
REF
ANY, v1, v2: Sets.Value]
RETURNS [c: SetBasics.TotalComparison] ~ {
n1: SteppyName ~ VSn[v1];
n2: SteppyName ~ VSn[v2];
IF (c ← SteppyNameGradeCompare[n1.grade, n2.grade])#equal THEN RETURN;
c ← NameStepListCompare[n1.steps, n2.steps];
RETURN};
SteppyNamesPrint:
PROC [data:
REF
ANY, v: Sets.Value, to:
IO.
STREAM, depth, length:
INT, verbose:
BOOL] ~ {
name: SteppyName ~ VSn[v];
to.PutRope[UnparseSteppyName[name]];
RETURN};
TestGrade:
PROC [val: Sets.Value, data:
REF
ANY ←
NIL]
RETURNS [
BOOL] ~ {
sn: SteppyName ~ VSn[val];
SELECT data
FROM
$gend => RETURN [sn.grade.gend];
$nonGlobal => RETURN [NOT sn.grade.global];
$long => RETURN [sn.grade.gend OR sn.grade.nonsubs>1];
$power => RETURN [sn.grade.power];
ENDCASE => ERROR};
ApplyLastRope:
PROC [data:
REF
ANY, v: Sets.Value]
RETURNS [mv: Sets.MaybeValue] ~ {
sn: SteppyName ~ VSn[v];
IF sn.grade.nonsubs = 0 THEN RETURN [Sets.noMaybe];
{lr: ROPE ~ LastRope[sn];
RETURN [[TRUE, AV[lr]]]}};
LastRope:
PUBLIC
PROC [sn: SteppyName]
RETURNS [
ROPE] ~ {
subj: ROPE ← NIL;
FOR nsl: NameStepList ← sn.steps, nsl.rest
WHILE nsl#
NIL
DO
WITH nsl.first
SELECT
FROM
x: ROPE => subj ← x;
x: REF INT => NULL;
ENDCASE => ERROR;
ENDLOOP;
RETURN [subj]};
PreTails:
PUBLIC
PROC [tail: SteppyName]
RETURNS [Set
--of SteppyName--] ~ {
RETURN Sets.CreateFilter[[TestTail, steppyNameSpace, NEW [SteppyName ← tail]], constant];
};
TestTail:
PROC [val: Sets.Value, data:
REF
ANY ←
NIL]
RETURNS [
BOOL] ~ {
pre: SteppyName ~ VSn[val];
tail: SteppyName ~ NARROW[data, REF SteppyName]^;
IF tail.grade.subs>pre.grade.subs OR tail.grade.nonsubs>pre.grade.nonsubs THEN RETURN [FALSE];
{preSteps: NameStepList ← pre.steps;
tailSteps: NameStepList ← tail.steps;
THROUGH [0 .. (pre.grade.subs+pre.grade.nonsubs) - (tail.grade.subs+tail.grade.nonsubs) ) DO preSteps ← preSteps.rest ENDLOOP;
WHILE tailSteps#
NIL
DO
IF NOT nameStepSpace.SEqual[AV[tailSteps.first], AV[preSteps.first]] THEN RETURN [FALSE];
tailSteps ← tailSteps.rest;
preSteps ← preSteps.rest;
ENDLOOP;
IF preSteps#NIL THEN ERROR;
RETURN [TRUE]}};
CopyTill:
PUBLIC
PROC [first, afterlast:
LORA]
RETURNS [new: TList ← []] ~ {
FOR cur:
LORA ← first, cur.rest
WHILE cur#afterlast
DO
this: LORA ~ LIST[cur.first];
IF new.tail=NIL THEN new.head ← this ELSE new.tail.rest ← this;
new.tail ← this;
ENDLOOP;
RETURN};
LTl:
PUBLIC
PROC [head:
LORA]
RETURNS [TList] ~ {
IF head=NIL THEN RETURN [[NIL, NIL]];
{tail: LORA ← head;
FOR tail ← tail, tail.rest WHILE tail.rest#NIL DO NULL ENDLOOP;
RETURN [[head, tail]]}};
NewInt:
PUBLIC
PROC [i:
INT]
RETURNS [
REF
INT] ~ {
IF i IN [0 .. 64] THEN RETURN [intRefs[i]];
RETURN [NEW [INT ← i]]};
AIName:
PUBLIC
PROC [a: Array, ai: Int2]
RETURNS [SteppyName] ~ {
IF a.size2[X]=1
THEN
IF a.size2[Y]=1
THEN RETURN [noName]
ELSE RETURN OSn[NewInt[ai[Y]]]
ELSE
IF a.size2[Y]=1
THEN RETURN OSn[NewInt[ai[X]]]
ELSE RETURN LSn[LIST[NewInt[ai[X]], NewInt[ai[Y]]]]};
ExtendName:
PUBLIC
PROC [fileName, defaultExtension:
ROPE]
RETURNS [fullFName:
ROPE, cp:
FS.ComponentPositions] ~ {
[fullFName, cp, ] ← FS.ExpandName[fileName];
IF defaultExtension.Length[]>0
AND cp.ext.start = cp.base.start+cp.base.length
THEN {
fileName ←
FS.ConstructFName[[
server: fullFName.Substr[cp.server.start, cp.server.length],
dir: fullFName.Substr[cp.dir.start, cp.dir.length],
subDirs: fullFName.Substr[cp.subDirs.start, cp.subDirs.length],
base: fullFName.Substr[cp.base.start, cp.base.length],
ext: defaultExtension,
ver: fullFName.Substr[cp.ver.start, cp.ver.length]
]];
[fullFName, cp, ] ← FS.ExpandName[fileName];
RETURN};
RETURN};
MatchingHasPair:
PROC [br: BiRel, pair: BiRels.Pair]
RETURNS [
BOOL] ~ {
pat: SteppyNamePattern ← VSn[pair[left]];
subj: SteppyName ← VSn[pair[right]];
IF pat.grade.subs # subj.grade.subs OR pat.grade.nonsubs # subj.grade.nonsubs THEN RETURN [FALSE];
WHILE pat.steps#
NIL
DO
WITH pat.steps.first
SELECT
FROM
x:
ROPE =>
WITH subj.steps.first
SELECT
FROM
y: ROPE => IF x#anyROPE AND NOT x.Equal[y] THEN RETURN [FALSE];
ENDCASE => RETURN [FALSE];
x:
REF
INT =>
WITH subj.steps.first
SELECT
FROM
y: REF INT => IF x#anyInt AND x^#y^ THEN RETURN [FALSE];
ENDCASE => RETURN [FALSE];
ENDCASE => ERROR;
pat.steps ← pat.steps.rest;
subj.steps ← subj.steps.rest;
ENDLOOP;
RETURN [TRUE]};
BothSNSpace:
PROC [br: BiRel]
RETURNS [BiRels.SpacePair]
~ {RETURN [ALL[steppyNameSpace]]};
OverlapHasPair:
PROC [br: BiRel, pair: BiRels.Pair]
RETURNS [
BOOL] ~ {
pat1: SteppyNamePattern ← VSn[pair[left]];
pat2: SteppyNamePattern ← VSn[pair[right]];
dif: BOOL ← FALSE;
IF pat1.grade.subs # pat2.grade.subs OR pat1.grade.nonsubs # pat2.grade.nonsubs THEN RETURN [FALSE];
WHILE pat1.steps#
NIL
DO
WITH pat1.steps.first
SELECT
FROM
x:
ROPE =>
WITH pat2.steps.first
SELECT
FROM
y:
ROPE =>
IF x=anyROPE OR y=anyROPE THEN dif ← dif OR x#y
ELSE IF NOT x.Equal[y] THEN RETURN [FALSE];
ENDCASE => RETURN [FALSE];
x:
REF
INT =>
WITH pat2.steps.first
SELECT
FROM
y:
REF
INT =>
IF x=anyInt OR y=anyInt THEN dif ← dif OR x#y
ELSE IF x^#y^ THEN RETURN [FALSE];
ENDCASE => RETURN [FALSE];
ENDCASE => ERROR;
pat1.steps ← pat1.steps.rest;
pat2.steps ← pat2.steps.rest;
ENDLOOP;
RETURN [dif]};
PWRoot:
PUBLIC
PROC [d: Design, x:
PW]
RETURNS [
PW] ~ {
DO
mv: Sets.MaybeValue ~ d.parent.ApplyA[x];
IF NOT mv.found THEN RETURN [x];
x ← mv.it.VA;
ENDLOOP;
};
CiCtr:
PUBLIC PROC [ci: CellInstance, ict: CellType]
RETURNS [Int2]
~ {RETURN TransOffPos[VXfm[ict.d.ciXfm.ApplyA[ci].Val], ci.offset, Range2Mid[ict.bbox]]};
Start:
PROC ~ {
FOR i: INT IN [0 .. 64] DO intRefs[i] ← NEW [INT ← i] ENDLOOP;
RETURN};
Start[];
END.