DIRECTORY AbSets, BiRels, IntStuff, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenNavigation, Rope, SetBasics, StructuredStreams, UnparserBuffer, ViewerIO; LichenData4Impl: CEDAR PROGRAM IMPORTS AbSets, BiRels, IntStuff, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenNavigation, SetBasics = BEGIN OPEN LichenArrayStuff, LichenDataOps, LichenDataStructure, Sets:AbSets, Ints:IntStuff, SS:StructuredStreams, UB:UnparserBuffer; Set: TYPE ~ LichenDataStructure.Set; Function: TYPE ~ LichenDataStructure.Function; OneToOne: TYPE ~ LichenDataStructure.OneToOne; Seq: TYPE ~ LichenDataStructure.Seq; Thing: TYPE ~ REF ANY --actually UNION [Port, Wire]--; Wirism: TYPE ~ REF ANY --actually UNION [Vertex, DumbWire]--; refPerms: Sets.Space ~ BiRels.CreateBiRelSpace[ALL[SetBasics.ints]]; ReOrderDesign: PROC [d: Design] ~ { desiredPerm: BiRel--Wirism X REF Permutation-- ~ BiRels.CreateHashReln[[SetBasics.refs, refPerms]]; portDesires: Function--Port _ REF Permutation-- ~ BiRels.CreateHashFn[invable: FALSE]; delayedVerts: Set--of Vertex-- ~ Sets.CreateHashSet[]; delayedPorts: Set--of Port-- ~ Sets.CreateHashSet[]; arrayWireArray: Function--DumbWire _ Array-- ~ BiRels.CreateHashFn[invable: FALSE]; StartCellType: PROC [val: REF ANY] ~ { ct: CellType ~ NARROW[val]; WorkOnPort: PROC [port: Port] RETURNS [doKids, moreSibs: BOOL _ TRUE] ~ { IF port.FirstChildPort[]=NIL THEN RETURN; {desire: Permutation ~ DesiredPerm[port, LichenNavigation.portToChildren, LichenNavigation.bestPortShortName]; IF desire.IsIDSubset[] THEN RETURN; {refDesire: REF ANY ~ desire.Refify; delay: BOOL _ FALSE; CheckInstance: PROC [ci: CellInstance] ~ { v: Vertex ~ FindCellConnection[ci, port]; allMe: BOOL ~ AllForPort[v, port]; IF NOT allMe THEN delay _ TRUE; RETURN}; CheckArray: PROC [act: CellType] ~ { a: Array ~ act.asArray; CheckOtherPort: PROC [other: Port] ~ {IF other#port THEN delay _ TRUE}; EnumerateConnectedEltPorts[a, port, CheckOtherPort, TRUE]; RETURN}; DelayInstance: PROC [ci: CellInstance] ~ { v: Vertex ~ FindCellConnection[ci, port]; [] _ delayedVerts.AddA[v]; [] _ desiredPerm.AddAA[v, refDesire]; RETURN}; DelayArray: PROC [act: CellType] ~ { a: Array ~ act.asArray; DelayArrayWire: PROC [dw: DumbWire] ~ { [] _ arrayWireArray.AddAA[dw, a]; [] _ desiredPerm.AddAA[dw, refDesire]; RETURN}; EnumerateDumbWiresForPort[a, port, DelayArrayWire]; RETURN}; ct.EnumerateInstances[CheckInstance, TRUE]; ct.EnumerateArrays[CheckArray]; IF delay THEN { ct.EnumerateInstances[DelayInstance, TRUE]; ct.EnumerateArrays[DelayArray]; IF NOT delayedPorts.AddA[port] THEN ERROR; portDesires.AddNewAA[port, refDesire]} ELSE PermutePort[port, desire, TRUE]; RETURN}}}; WorkOnWire: PROC [wire: Wire] RETURNS [doKids, moreSibs: BOOL _ TRUE] ~ { IF wire.FirstChildWire[]=NIL THEN RETURN; {desire: Permutation ~ DesiredPerm[wire, LichenNavigation.wireToChildren, LichenNavigation.bestVertexShortName]; IF desire.IsIDSubset[] THEN RETURN; {refDesire: REF ANY ~ desire.Refify; delay: BOOL ~ NOT AllForPort[wire, find]; IF delay THEN { [] _ delayedVerts.AddA[wire]; [] _ desiredPerm.AddAA[wire, refDesire]; } ELSE PermuteWire[wire, desire]; RETURN}}}; [] _ EnumeratePort[ct.port, WorkOnPort]; IF ct.asUnorganized#NIL THEN [] _ ct.asUnorganized.internalWire.EnumerateWire[WorkOnWire]; RETURN}; DoDelayedPort: PROC [val: REF ANY] ~ { port: Port ~ NARROW[val]; ct: CellType ~ PortCCT[port]; allSame: BOOL _ TRUE; desire: Permutation ~ BiRels.DeRef[portDesires.ApplyA[port].MA]; CheckInstance: PROC [ci: CellInstance] ~ { v: Vertex ~ FindCellConnection[ci, port]; perms: Set ~ desiredPerm.MappingA[v]; size: INT ~ perms.Size[Ints.two].EN; IF size=0 THEN ERROR; IF size>1 THEN allSame _ FALSE; RETURN}; CheckArray: PROC [act: CellType] ~ { a: Array ~ act.asArray; CheckArrayWire: PROC [dw: DumbWire] ~ { perms: Set ~ desiredPerm.MappingA[dw]; size: INT ~ perms.Size[Ints.two].EN; IF size=0 THEN ERROR; IF size>1 THEN allSame _ FALSE; RETURN}; EnumerateDumbWiresForPort[a, port, CheckArrayWire]; RETURN}; ct.EnumerateInstances[CheckInstance, TRUE]; ct.EnumerateArrays[CheckArray]; IF allSame THEN PermutePort[port, desire, FALSE] ELSE Log["Port %g not permuted", LIST[port]]; RETURN}; DoDelayedWire: PROC [val: REF ANY] ~ { wire: Wire ~ NARROW[val]; ct: CellType ~ wire.containingCT; perms: Set ~ desiredPerm.MappingA[wire]; size: INT ~ perms.Size[Ints.two].EN; IF size=0 THEN ERROR; IF size>1 THEN { Log["%g perms desired for wire %g", LIST[NEW [INT _ size], wire]]; RETURN}; {desire: Permutation ~ BiRels.DeRef[perms.TheElt.VA]; PermuteWire[wire, desire]; RETURN}}; d.cellTypes.EnumA[StartCellType]; delayedPorts.EnumA[DoDelayedPort]; delayedVerts.EnumA[DoDelayedWire]; RETURN}; find: Port ~ NEW [PortPrivate]; AllForPort: PROC [v: Vertex, port: Port] RETURNS [allSame: BOOL _ TRUE] ~ { CheckEdge: PROC [p: Port, w: Vertex, e: Edge] ~ { IF p=NIL OR p=find THEN ERROR; IF port=find THEN port _ p ELSE IF p#port THEN allSame _ FALSE; RETURN}; v.EnumerateImmediateEdges[CheckEdge, [cellward: TRUE, wireward: FALSE]]; IF NOT allSame THEN RETURN; WITH v SELECT FROM ci: CellInstance => IF port#find AND port#ci.type.port THEN RETURN [FALSE]; im: Intermediary => IF port#find AND port#im.port THEN RETURN [FALSE]; w: Wire => IF w.containingWire#NIL THEN { goal: Port; IF port=find THEN goal _ find ELSE IF port=NIL THEN goal _ NIL ELSE WITH port.parent SELECT FROM ct: CellType => ERROR--shouldn't happen--; parent: Port => { wi: INT ~ w.containingWire.WireIndex[w]; pi: INT ~ port.PortIndex[]; IF wi=pi THEN goal _ parent ELSE goal _ NIL}; ENDCASE => ERROR; IF NOT AllForPort[w.containingWire, goal] THEN RETURN [FALSE]; }; ENDCASE => ERROR; RETURN}; DesiredPerm: PROC [parent: Thing, ToChildren: OneToOne--Thing f Seq of children--, ToName: Function--Thing _ SteppyName--] RETURNS [perm: Permutation] ~ { children: Seq--of child Things-- ~ BiRels.DeRef[ToChildren.ApplyA[parent].MA].CreateSimpleCopy; names: Seq--of SteppyName-- ~ children.Compose[right: ToName, restricts: [TRUE, FALSE]]; perm _ BiRels.GradeUp[names, alphaSteppyNameOrder]; RETURN}; alphaSteppyNameOrder: SetBasics.Order ~ SetBasics.CreateLORASpace[NIL, LIST[nameStepSpace]].SpaceOrder[]; PermutePort: PROC [port: Port, perm: Permutation, doConnections: BOOL] ~ { oldKids: Seq ~ BiRels.DeRef[LichenNavigation.portToChildren.ApplyA[port].MA] .CreateSimpleCopy; n: INT ~ oldKids.Size.EN; prev: Port _ NIL; index: INT _ 0; FixElt: PROC [pair: BiRels.Pair] ~ { newIndex: INT ~ pair[left].VI; oldIndex: INT ~ pair[right].VI; kid: Port ~ NARROW[oldKids.ApplyI[oldIndex].MA]; IF index#newIndex THEN ERROR; kid.prev _ prev; IF prev#NIL THEN prev.next _ kid ELSE port.firstChild _ kid; prev _ kid; index _ index+1; RETURN}; FixInstance: PROC [ci: CellInstance] ~ { v: Vertex ~ FindCellConnection[ci, port]; PermuteVertex[v, perm]; }; perm.Enumerate[FixElt]; IF index#n THEN ERROR; prev.next _ NIL; port.lastChild _ prev; IF doConnections THEN port.PortCCT.EnumerateInstances[FixInstance, TRUE]; RETURN}; PermuteWire: PROC [wire: Wire, perm: Permutation] ~ { oldKids: Seq ~ BiRels.DeRef[LichenNavigation.wireToChildren.ApplyA[wire].MA] .CreateSimpleCopy; n: INT ~ oldKids.Size.EN; prev: Wire _ NIL; index: INT _ 0; FixElt: PROC [pair: BiRels.Pair] ~ { newIndex: INT ~ pair[left].VI; oldIndex: INT ~ pair[right].VI; kid: Wire ~ NARROW[oldKids.ApplyI[oldIndex].MA]; IF index#newIndex THEN ERROR; kid.prev _ prev; IF prev#NIL THEN prev.next _ kid ELSE wire.firstChild _ kid; prev _ kid; index _ index+1; RETURN}; perm.Enumerate[FixElt]; IF index#n THEN ERROR; prev.next _ NIL; wire.lastChild _ prev; RETURN}; PermuteVertex: PROC [v: Vertex, perm: Permutation] ~ { WITH v SELECT FROM w: Wire => {PermuteWire[w, perm]; RETURN}; im: Intermediary => NULL; ci: CellInstance => NULL; ENDCASE => ERROR; {old: Seq--of old Edge-- ~ BiRels.CreateSimple[oneToOne: TRUE, dense: TRUE]; NoteOldEdge: PROC [p: Port, w: Vertex, e: Edge] ~ { IF e.sides[cellward].v#v THEN ERROR; old.AppendA[e]; RETURN}; v.EnumerateImmediateEdges[NoteOldEdge, [cellward: FALSE, wireward: TRUE], forward]; {n: INT ~ old.Size.EN; oldFirstWireward: Edge ~ NARROW[old.First[].it[right].VA]; lastCellward: Edge ~ oldFirstWireward.sides[cellward].prev; prev: Edge _ lastCellward; prevSide: GraphDirection _ wireward; index: INT _ 0; FixElt: PROC [pair: BiRels.Pair] ~ { newIndex: INT ~ pair[left].VI; oldIndex: INT ~ pair[right].VI; e: Edge ~ NARROW[old.ApplyI[oldIndex].MA]; IF index#newIndex THEN ERROR; e.sides[cellward].prev _ prev; IF prev#NIL THEN prev.sides[prevSide].next _ e ELSE IF v.firstEdge.sides[cellward].v#v THEN ERROR ELSE v.firstEdge _ e; prev _ e; prevSide _ cellward; index _ index+1; RETURN}; IF lastCellward#NIL AND lastCellward.sides[wireward].v#v THEN ERROR; perm.Enumerate[FixElt]; IF index#n OR n=0 THEN ERROR; prev.sides[cellward].next _ NIL; v.lastEdge _ prev; RETURN}}}; END. \LichenData4Impl.Mesa Last tweaked by Mike Spreitzer on January 7, 1988 5:20:47 pm PST Κ –˜™Icodešœ@™@—J˜KšΟk œ ˜©K˜šΡbnxœœ˜Kšœl˜sKšœ˜—K˜Kš œœ7ΟnœŸœ œœ˜…K˜Kšœœ˜$Kšœ œ ˜.Kšœ œ ˜.Kšœœ˜$K˜Kš œœœœΟcœ˜6Kš œœœœ %œ˜=K˜Kšœ/œ˜DK˜šŸ œœ˜#Kšœ  Πcm œ5˜cKšœ ‘ œ œ˜VKšœ  œ˜6Kšœ  œ˜4Kšœ  ‘ œ œ˜SšŸ œœœœ˜&Kšœœ˜š Ÿ œœœœœ˜IKšœœœœ˜)Kšœn˜nKšœœœ˜#Kšœ œœ˜$Kšœœœ˜šŸ œœ˜*Kšœ)˜)Kšœœ˜"Kšœœœ œ˜Kšœ˜—šŸ œœ˜$K˜Kš Ÿœœœ œ œ˜GKšœ4œ˜:Kšœ˜—šŸ œœ˜*Kšœ)˜)Kšœ˜Kšœ%˜%Kšœ˜—šŸ œœ˜$K˜šŸœœ˜'Kšœ!˜!Kšœ&˜&Kšœ˜—Kšœ3˜3Kšœ˜—Kšœ%œ˜+Kšœ˜šœœ˜Kšœ%œ˜+Kšœ˜Kšœœœœ˜*Kšœ&˜&—Kšœœ˜%Kšœ˜ —š Ÿ œœœœœ˜IKšœœœœ˜)Kšœp˜pKšœœœ˜#Kšœ œœ˜$Kšœœœ˜)šœœ˜Kšœ˜Kšœ(˜(Kšœ˜—Kšœ˜Kšœ˜ —Kšœ(˜(Kšœœœ>˜ZKšœ˜—šŸ œœœœ˜&Kšœ œ˜K˜Kšœ œœ˜Kšœ<œ˜@šŸ œœ˜*Kšœ)˜)Kšœ%˜%Kšœœœ˜$Kšœœœ˜Kšœœ œ˜Kšœ˜—šŸ œœ˜$K˜šŸœœ˜'Kšœ&˜&Kšœœœ˜$Kšœœœ˜Kšœœ œ˜Kšœ˜—Kšœ3˜3Kšœ˜—Kšœ%œ˜+Kšœ˜šœ˜ Kšœœ˜%Kšœœ˜-—Kšœ˜—šŸ œœœœ˜&Kšœ œ˜K˜!Kšœ(˜(Kšœœœ˜$Kšœœœ˜šœœ˜Kšœ$œœœ˜BKšœ˜—Kšœ1œ˜5Kšœ˜Kšœ˜ —K˜!Kšœ"˜"Kšœ"˜"Kšœ˜—K˜Kšœ œ˜K˜š Ÿ œœœ œœ˜KšŸ œœ"˜1Kš œœœœœ˜Kš œ œ œœœ œ˜?Kšœ˜—Kšœ0œ œ˜HKšœœ œœ˜šœœ˜Kš œœ œœœœ˜KKš œœ œœœœ˜Fšœ œœœ˜)K˜ Kšœ œ ˜Kš œœœœ˜ šœœ œ˜!Kšœ œ˜*˜Kšœœ!˜(Kšœœ˜Kšœœœœ˜-—Kšœœ˜—Kš œœ$œœœ˜>K˜—Kšœœ˜—Kšœ˜—K˜šŸ œœŸ œ  ‘ œŸœ  ‘  œœ˜šKšœ  œ*œ˜_Kšœ  œ/œœ˜XKšœ3˜3Kšœ˜KšœBœœ˜i—K˜šŸ œœ0œ˜JKšœIœ˜_Kšœœœ˜Kšœ œ˜Kšœœ˜šŸœœ˜$Kšœ œœ˜Kšœ œœ˜Kšœ œœ˜0Kšœœœ˜K˜Kšœœœœ˜