RoseDeciders.Mesa
Last Edited by: Spreitzer, July 11, 1985 10:29:49 pm PDT
Last Edited by: Gasbarro, August 16, 1984 4:53:51 pm PDT
Last Edited by: Barth, June 17, 1985 8:15:01 pm PDT
DIRECTORY Asserting, AssertingIO, Atom, Basics, Convert, FS, IO, MessageWindow, Pausers, RedBlackTree, Rope, RoseCreate, RoseTypes, ViewerOps, ViewRec;
RoseDeciders:
CEDAR
PROGRAM
IMPORTS Asserting, AssertingIO, Atom, Convert, FS, IO, MessageWindow, Pausers, RedBlackTree, Rope, RoseCreate, RoseTypes, ViewerOps, ViewRec
EXPORTS RoseCreate =
BEGIN OPEN RoseCreate, RoseTypes;
Name: TYPE = LIST OF ROPE;
LORA: TYPE = LIST OF REF ANY;
ExpandDecisionRef: TYPE = REF ExpandDecision;
decisionProp: ATOM ← Atom.MakeAtom["Spreitzer January 6, 1984 8:33 pm"];
ExpandQuery: TYPE = REF ExpandQueryRep;
ExpandQueryRep:
TYPE =
RECORD [
instanceName, typeName: ROPE ← NIL,
whatToDo: ExpandDecision ← Expand];
expandFirst: PUBLIC ExpandDeciderClosure ← PickInOrder[LIST[Expand, Leaf]];
leafFirst: PUBLIC ExpandDeciderClosure ← PickInOrder[LIST[Leaf, Expand]];
qp: Pausers.Pauser ← NIL;
eq: ExpandQuery ← NEW [ExpandQueryRep ← []];
qerv: ViewRec.RecordViewer;
qv: ViewRec.Viewer ← NIL;
AssertionsFromFile:
PUBLIC
PROC [fileName:
ROPE]
RETURNS [assertions: Assertions] =
BEGIN
from: STREAM ← FS.StreamOpen[fileName];
assertions ← AssertingIO.Read[from];
from.Close[];
END;
LookupCell:
PUBLIC
PROC [path:
LIST
OF
REF
ANY, from: Cell ←
NIL]
RETURNS [cell: Cell] =
BEGIN
sofar: LIST OF ROPE ← NIL;
cell ← from;
WHILE path #
NIL
DO
link:
ROPE ←
WITH path.first
SELECT
FROM
r: ROPE => r,
rt: REF TEXT => Rope.FromRefText[rt],
ENDCASE => ERROR;
next: Cell ← NARROW[(IF cell = NIL THEN roots ELSE cell.components). Lookup[link]];
IF next =
NIL
THEN
{SIGNAL Warning[IO.PutFR["Not found: %g %g %g", IO.refAny[sofar], IO.rope[Convert.RopeFromRope[link]], IO.refAny[path.rest]]]; RETURN [NIL]};
sofar ← CONS[link, sofar];
path ← path.rest;
cell ← next;
ENDLOOP;
END;
LookupNode:
PUBLIC
PROC [path:
LIST
OF
REF
ANY, from: Cell ←
NIL]
RETURNS [node: Node] =
BEGIN
sofar: LIST OF ROPE ← NIL;
cell: Cell ← from;
WHILE path #
NIL
DO
link:
ROPE ←
WITH path.first
SELECT
FROM
r: ROPE => r,
rt: REF TEXT => Rope.FromRefText[rt],
ENDCASE => ERROR;
next: Cell;
IF path.rest = NIL THEN RETURN [LookupCellNode[cell, link]];
next ← NARROW[(IF cell = NIL THEN roots ELSE cell.components). Lookup[link]];
IF next =
NIL
THEN
{SIGNAL Warning[IO.PutFR["Not found: %g %g %g", IO.refAny[sofar], IO.rope[Convert.RopeFromRope[link]], IO.refAny[path.rest]]]; RETURN [NIL]};
sofar ← CONS[link, sofar];
path ← path.rest;
cell ← next;
ENDLOOP;
ERROR;
END;
LookupCellNode:
PUBLIC
PROC [cell: Cell, name:
ROPE]
RETURNS [node: Node] =
BEGIN
index: CARDINAL;
IF (node ← NARROW[cell.internalNodes.Lookup[name]]) # NIL THEN RETURN [node];
IF (index ← GetIndex[cell.type.ports, name]) # notFound THEN RETURN [cell.interfaceNodes[index]];
node ← NIL;
END;
LongNodeName:
PUBLIC
PROC [n: Node, relativeTo: Cell ←
NIL]
RETURNS [name:
ROPE] = {
name ← Rope.Cat[
IF n.cellIn = relativeTo THEN NIL
ELSE IF n.cellIn # NIL THEN LongCellName[n.cellIn, relativeTo].Cat["."]
ELSE "??.",
n.name];
};
LongCellName:
PUBLIC
PROC [c: Cell, relativeTo: Cell ←
NIL]
RETURNS [name:
ROPE] = {
IF c = relativeTo THEN ERROR;
name ← c.name;
FOR c ← c.parent, c.parent
WHILE c # relativeTo
DO
name ← c.name.Cat[".", name]
ENDLOOP};
LongPortName:
PUBLIC
PROC [c:
REF
ANY
--UNION[CellType, Cell]--, pi: PortIndex ← nilPortIndex, epi: EffectivePortIndex ← nilEffectivePortIndex]
RETURNS [name:
ROPE] = {
SELECT
TRUE
FROM
pi # nilPortIndex
AND epi = nilEffectivePortIndex => {
ports: Ports ← NIL;
cName: ROPE ← "??";
WITH c
SELECT
FROM
ct: CellType => {ports ← ct.ports; cName ← ct.name};
cell: Cell => {ports ← cell.type.ports; cName ← LongCellName[cell]};
ENDCASE => ERROR;
name ← cName.Cat[".", ports[pi].name];
};
pi = nilPortIndex
AND epi # nilEffectivePortIndex => {
cell: Cell ← NARROW[c];
name ← LongCellName[cell].Cat[".", cell.realCellStuff.effectivePorts[epi].name];
};
ENDCASE => ERROR;
};
LowestCommonAncestor:
PUBLIC
PROC [c1, c2: Cell]
RETURNS [lca: Cell] = {
tag: REF ANY;
IF c1 = c2 THEN RETURN [c1];
FOR c: Cell ← c1.parent, c.parent
WHILE c #
NIL
DO
IF c = c2 THEN RETURN [c];
ENDLOOP;
FOR c: Cell ← c2.parent, c.parent
WHILE c #
NIL
DO
IF c = c1 THEN RETURN [c];
ENDLOOP;
tag ← NEW [Cell ← c1];
FOR c: Cell ← c1.parent, c.parent
WHILE c #
NIL
DO
c.other ← Asserting.AssertFn1[$LCASearch, tag, c.other];
ENDLOOP;
FOR c: Cell ← c2.parent, c.parent
WHILE c #
NIL
DO
t2: REF ANY ← Asserting.FnVal[$LCASearch, c.other];
IF t2 = tag THEN RETURN [c];
ENDLOOP;
lca ← NIL};
DepthChoices: TYPE = REF DepthChoicesRep;
DepthChoicesRep:
TYPE =
RECORD [
shallow, deep: ExpandDeciderClosure,
boundary: INT];
ByDepth:
PUBLIC
PROC [shallow: ExpandDeciderClosure, boundary:
INT, deep: ExpandDeciderClosure]
RETURNS [edc: ExpandDeciderClosure] = {
edc ←
NEW [ExpandDeciderClosureRep ← [
DecideByDepth,
NEW [DepthChoicesRep ← [shallow, deep, boundary]]
]];
};
DecideByDepth:
PROC [cell: Cell, otherData:
REF
ANY]
RETURNS [ed: ExpandDecision] = {
dc: DepthChoices ← NARROW[otherData];
depth: INT ← Depth[cell];
edc: ExpandDeciderClosure ← IF depth <= dc.boundary THEN dc.shallow ELSE dc.deep;
ed ← edc.Decide[cell: cell, otherData: edc.otherData];
};
Depth:
PROC [cell: Cell]
RETURNS [depth:
INT] = {
depth ← IF cell.parent # NIL THEN (Depth[cell.parent]+1) ELSE 0;
};
PickInOrder:
PUBLIC
PROC [bestFirst:
--earlier=better--ExpandDecisionList]
RETURNS [edc: ExpandDeciderClosure] = {
edc ← NEW [ExpandDeciderClosureRep ← [DecideFromList, bestFirst]];
};
DecideFromList:
PROC [cell: Cell, otherData:
REF
ANY]
RETURNS [ed: ExpandDecision] = {
bestFirst: ExpandDecisionList ← NARROW[otherData];
FOR bestFirst: ExpandDecisionList ←
NARROW[otherData], bestFirst.rest
WHILE bestFirst #
NIL
DO
IF Possible[cell, bestFirst.first] THEN RETURN [bestFirst.first];
ENDLOOP;
ERROR Error[IO.PutFR["No possible expand decision for %g", IO.refAny[LongCellName[cell]]], cell];
};
DecideFromFile:
PUBLIC
PROC [fileName:
ROPE]
RETURNS [dff: ExpandDeciderClosure] =
BEGIN
file: IO.STREAM ← NIL;
top: LORA;
file ← FS.StreamOpen[fileName: fileName];
top ← LIST[NIL, NIL, IO.GetRefAny[file]];
file.Close[];
dff ← NEW [ExpandDeciderClosureRep ← [Decide: DecideByName, otherData: top]];
END;
Ask: ExpandDecider
--PROC [cell: Cell, otherData: REF ANY] RETURNS [ExpandDecision]-- =
BEGIN
first: BOOLEAN ← TRUE;
eq.instanceName ← cell.name;
eq.typeName ← cell.type.name;
IF qv # NIL AND qv.iconic THEN ViewerOps.OpenIcon[qv];
WHILE first OR NOT Possible[cell, eq.whatToDo] DO qp.Pause[]; first ← FALSE ENDLOOP;
RETURN [eq.whatToDo];
END;
DecideByName: ExpandDecider =
BEGIN
Yelp:
PROC [problem:
ROPE]
RETURNS [ExpandDecision] =
TRUSTED
BEGIN
RETURN [Ask[cell, problem]];
END;
decisionsByName: LORA ← NARROW[otherData];
name: Name ← GetName[cell];
descr: LORA ← GetDescr[name, decisionsByName];
decAt: ATOM;
asAny: REF ANY;
IF descr = NIL THEN RETURN [Yelp["no decision given"]];
IF descr.rest =
NIL
THEN
BEGIN
IF Possible[cell, Leaf] THEN RETURN [Leaf];
RETURN [Yelp["cant make it a Leaf"]];
END;
IF NOT ISTYPE[descr.rest.first, ATOM] THEN RETURN [Yelp["decision not an Atom"]];
IF (asAny ← Atom.GetProp[atom: (decAt ← NARROW[descr.rest.first]), prop: decisionProp]) = NIL THEN RETURN [Yelp["atom not a decision"]];
IF (IF asAny = NIL THEN TRUE ELSE NOT ISTYPE[asAny, ExpandDecisionRef]) THEN RETURN [Yelp["atom not a decision"]];
RETURN [NARROW[asAny, ExpandDecisionRef]^];
END;
GetName:
PROC [cell: Cell]
RETURNS [name: Name] =
BEGIN
name ← NIL;
WHILE cell #
NIL
DO
name ← CONS[cell.name, name];
cell ← cell.parent;
ENDLOOP;
END;
GetDescr:
PROC [name: Name, dbn:
LORA]
RETURNS [
LORA] =
BEGIN
Matches:
PROC [name:
ROPE, asAny:
REF
ANY]
RETURNS [
BOOLEAN] =
BEGIN
dbn: LORA;
s2: ROPE;
IF
NOT
ISTYPE[asAny,
LORA]
THEN
TRUSTED
BEGIN
MessageWindow.Append[message: "Ill formed decisions!", clearFirst: TRUE];
RETURN [FALSE];
END;
dbn ← NARROW[asAny];
IF (
IF dbn =
NIL
THEN
TRUE
ELSE (
IF dbn.first =
NIL
THEN
TRUE
ELSE (
NOT
ISTYPE[dbn.first,
ROPE]
AND
NOT
ISTYPE[dbn.first,
ATOM])))
THEN
TRUSTED
BEGIN
MessageWindow.Append[message: "Ill formed decisions!", clearFirst: TRUE];
RETURN [FALSE];
END;
s2 ←
WITH dbn.first
SELECT
FROM
r: ROPE => r,
a: ATOM => Atom.GetPName[a],
ENDCASE => ERROR;
RETURN [Rope.Equal[s1: name, s2: s2, case: FALSE]];
END;
WHILE name #
NIL
DO
tail: LORA;
IF (
IF dbn =
NIL
THEN
TRUE
ELSE dbn.rest =
NIL)
THEN
TRUSTED
BEGIN
MessageWindow.Append[message: "Ill formed decisions!", clearFirst: TRUE];
RETURN [NIL];
END;
FOR tail ← dbn.rest.rest, tail.rest
WHILE tail #
NIL
DO
IF Matches[name.first, tail.first] THEN EXIT;
ENDLOOP;
IF tail =
NIL
THEN
TRUSTED
BEGIN
MessageWindow.Append[message: "No decsion", clearFirst: TRUE];
RETURN [NIL];
END;
name ← name.rest;
dbn ← NARROW[tail.first];
ENDLOOP;
RETURN [dbn];
END;
MakeQueryPauser: ViewRec.OtherStuffProc =
BEGIN
v: ViewRec.Viewer;
[qp, v] ← Pausers.CreatePauser[enabledName: "Answer Query", disabledName: "", viewerInit: [parent: in, border: FALSE], paint: FALSE];
RETURN [LIST[v]];
END;
Setup:
PROC =
BEGIN
Atom.PutProp[atom: $E, prop: decisionProp, val: NEW [ExpandDecision ← Expand]];
Atom.PutProp[atom: $L, prop: decisionProp, val: NEW [ExpandDecision ← Leaf]];
qerv ← ViewRec.ViewRef[
agg: eq,
otherStuff: MakeQueryPauser,
viewerInit: [iconic: TRUE, column: right, name: "ExpandQuery"]];
qv ← qerv.RVQuaViewer[];
END;
ROPEToRef: TYPE = REF ROPEToRefRep;
ROPEToRefRep: TYPE = RECORD [from: ROPE, to: REF ANY];
ROPEToST: TYPE = REF ROPEToSTRep;
ROPEToSTRep: TYPE = RECORD [from: ROPE, to: SymbolTable];
GetROPEToRefKey:
PROC [data:
REF
ANY]
RETURNS [key:
ROPE]
--RedBlackTree.GetKey-- =
{rr: ROPEToRef ← NARROW[data]; key ← rr.from};
CompareROPEToRefs:
PROC [k, data:
REF
ANY]
RETURNS [c: Basics.Comparison]
--RedBlackTree.Compare-- =
BEGIN
s1: ROPE ← NARROW[k];
s2: ROPE ← GetROPEToRefKey[data];
c ← s1.Compare[s2];
END;
GetROPEToSTKey:
PROC [data:
REF
ANY]
RETURNS [key:
ROPE]
--RedBlackTree.GetKey-- =
{rr: ROPEToST ← NARROW[data]; key ← rr.from};
CompareROPEToSTs:
PROC [k, data:
REF
ANY]
RETURNS [c: Basics.Comparison]
--RedBlackTree.Compare-- =
BEGIN
s1: ROPE ← NARROW[k];
s2: ROPE ← GetROPEToSTKey[data];
c ← s1.Compare[s2];
END;
GetOtherss:
PUBLIC
PROC [fileName:
ROPE]
RETURNS [otherss: SymbolTable] = {
in: IO.STREAM ← FS.StreamOpen[fileName];
otherss ← RedBlackTree.Create[GetROPEToSTKey, CompareROPEToSTs];
DO
cellTypeName: ROPE;
cellST: SymbolTable;
cellMap: ROPEToST;
[] ← in.SkipWhitespace[];
IF in.EndOf[] THEN EXIT;
cellTypeName ← in.GetRopeLiteral[];
cellST ← RedBlackTree.Create[GetROPEToRefKey, CompareROPEToRefs];
cellMap ← NEW [ROPEToSTRep ← [cellTypeName, cellST]];
DO
partName: ROPE;
partAssertions: Assertions;
partMap: ROPEToRef;
[] ← in.SkipWhitespace[];
IF in.PeekChar[] = '. THEN {IF in.GetChar[] # '. THEN ERROR; EXIT};
partName ← in.GetRopeLiteral[];
partAssertions ← AssertingIO.Read[in];
partMap ← NEW [ROPEToRefRep ← [partName, partAssertions]];
cellST.Insert[partMap, partMap.from];
ENDLOOP;
otherss.Insert[cellMap, cellMap.from];
ENDLOOP;
in.Close[];
};
GetOthers:
PUBLIC
PROC [otherss: SymbolTable, cellTypeName:
ROPE]
RETURNS [others: SymbolTable] = {
rr: ROPEToST ← NARROW[otherss.Lookup[cellTypeName]];
others ← IF rr # NIL THEN rr.to ELSE NIL;
};
GetOther:
PUBLIC
PROC [others: SymbolTable, partName:
ROPE]
RETURNS [assertions: Assertions] = {
rr: ROPEToRef ← IF others # NIL THEN NARROW[others.Lookup[partName]] ELSE NIL;
assertions ← IF rr # NIL THEN NARROW[rr.to] ELSE NIL
};
Setup[];
END.