MathDBImpl.mesa
Carl Waldspurger, August 22, 1986 3:29:18 pm PDT
Math Object "DataBase" Operations
DIRECTORY
Basics,
Rope,
Convert,
List USING [AList, Assoc, PutAssoc],
MathExpr USING [AtomClass, CompoundClass, MatrixClass],
MathDB;
MathDBImpl: CEDAR PROGRAM
IMPORTS List, Convert
EXPORTS MathDB ~
BEGIN
Abbreviations from Imported Interfaces
AtomClass: TYPE ~ MathExpr.AtomClass;
CompoundClass: TYPE ~ MathExpr.CompoundClass;
MatrixClass: TYPE ~ MathExpr.MatrixClass;
ROPE: TYPE ~ Rope.ROPE;
AList: TYPE ~ List.AList;
Private (Name, Class) ALists for Expression Classes, by Expr Type
GlobalAtomClasses: List.AList ← NIL;
GlobalCompoundClasses: List.AList ← NIL;
GlobalMatrixClasses: List.AList ← NIL;
Public Lists of Expression Class Names, by Expr Type
AtomClassNames: PUBLIC LIST OF ATOMNIL;
CompoundClassNames: PUBLIC LIST OF ATOMNIL;
MatrixClassNames: PUBLIC LIST OF ATOMNIL;
Operations on Public Lists of Expression Class Names, by Expr Type
ResetAtomClasses: PUBLIC PROC[] ~ {
effects: Resets (i.e. destroys) the global AtomClass DataBase
GlobalAtomClasses ← NIL;
AtomClassNames ← NIL;
};
ResetCompoundClasses: PUBLIC PROC[] ~ {
effects: Resets (i.e. destroys) the global CompoundClass DataBase
GlobalCompoundClasses ← NIL;
CompoundClassNames ← NIL;
};
ResetMatrixClasses: PUBLIC PROC[] ~ {
effects: Resets (i.e. destroys) the global MatrixClass DataBase
GlobalMatrixClasses ← NIL;
MatrixClassNames ← NIL;
};
InstallAtomClass: PUBLIC PROC[class: AtomClass] ~ {
effects: Installs class in global AtomClass DataBase
add atom class to database - not very efficient, but does the job
GlobalAtomClasses ← List.PutAssoc[key: class.name, val: class, aList: GlobalAtomClasses];
add atom class name to index
AtomClassNames ← CONS[class.name, AtomClassNames];
};
InstallCompoundClass: PUBLIC PROC[class: CompoundClass] ~ {
effects: Installs class in global CompoundClass DataBase
add compound class to database - not very efficient, but does the job
GlobalCompoundClasses ← List.PutAssoc[key: class.name, val: class, aList: GlobalCompoundClasses];
add compound class name to index
CompoundClassNames ← CONS[class.name, CompoundClassNames];
};
InstallMatrixClass: PUBLIC PROC[class: MatrixClass] ~ {
effects: Installs class in global MatrixClass DataBase
add matrix class to database
GlobalMatrixClasses ← List.PutAssoc[key: class.name, val: class, aList: GlobalMatrixClasses];
add matrix class name to index
MatrixClassNames ← CONS[class.name, MatrixClassNames];
};
LookupAtomClass: PUBLIC PROC[name: ATOM] RETURNS[AtomClass] ~ {
effects: Returns the AtomClass object associated with name.
SIGNALS notFound if no association exists
atomClass: AtomClass ← NARROW[List.Assoc[key: name, aList: GlobalAtomClasses]];
IF atomClass = NIL THEN ERROR notFound;
RETURN[atomClass];
};
LookupCompoundClass: PUBLIC PROC[name: ATOM] RETURNS[CompoundClass] ~ {
effects: Returns the CompoundClass object associated with name.
SIGNALS notFound if no association exists
compoundClass: CompoundClass ← NARROW[List.Assoc[key: name, aList: GlobalCompoundClasses]];
IF compoundClass = NIL THEN ERROR notFound;
RETURN[compoundClass];
};
LookupMatrixClass: PUBLIC PROC[name: ATOM] RETURNS[MatrixClass] ~ {
effects: Returns the MatrixClass object associated with name.
SIGNALS notFound if no association exists
matrixClass: MatrixClass ← NARROW[List.Assoc[key: name, aList: GlobalMatrixClasses]];
IF matrixClass = NIL THEN ERROR notFound;
RETURN[matrixClass];
};
KillAtomClass: PUBLIC PROC[name: ATOM] ~{
GlobalAtomClasses ← KillAssoc[name, GlobalAtomClasses]
};
KillCompoundClass: PUBLIC PROC[name: ATOM] ~{
GlobalCompoundClasses ← KillAssoc[name, GlobalCompoundClasses]
};
KillMatrixClass: PUBLIC PROC[name: ATOM] ~{
GlobalMatrixClasses ← KillAssoc[name, GlobalMatrixClasses]
};
DescriptionFromName: PUBLIC PROC[className: ATOM] RETURNS[ROPE]~ {
effects: lookup the class in the entire (Atom, Compound, and Matrix) Expression Class database, and return its description. Signals error if not found.
a: AtomClass;
c: CompoundClass;
m: MatrixClass;
a ← LookupAtomClass[className ! notFound => CONTINUE];
IF a#NIL THEN RETURN[Convert.RopeFromAtom[from: className, quote: FALSE] ];
c ← LookupCompoundClass[className ! notFound => CONTINUE];
IF c#NIL THEN RETURN[c.description];
m ← LookupMatrixClass[className ! notFound => CONTINUE];
IF m#NIL THEN RETURN[Convert.RopeFromAtom[from: className, quote: FALSE] ];
ERROR notFound;
};
DescriptionsFromNames: PUBLIC PROC [in: LIST OF ATOM] RETURNS[LIST OF ROPE] ~ {
effects: lookup the class of each element in the entire (Atom, Compound, and Matrix) Expression Class database, and return its description. Signals error if some class not found not found.
out, out2: LIST OF ROPE;
IF in = NIL THEN RETURN[NIL];
out ← out2 ← LIST[DescriptionFromName[in.first] ];
FOR l: LIST OF ATOM ← in.rest, l.rest UNTIL l=NIL DO
out2 ← out2.rest ← LIST[DescriptionFromName[l.first] ];
ENDLOOP;
RETURN[out];
};
Public Lists of Operator Names (Operators assumed to be CompoundExprs)
GlobalOperatorTable: List.AList ← NIL;
Operations on Public Lists of Operator Names
ResetOperatorTable: PUBLIC PROC[] ~ {
GlobalOperatorTableNIL;
};
AddOperator: PUBLIC PROC[class: CompoundClass, familyName: ATOM] ~ {
effects: Installs an operator name in the public list
family: LIST OF REFNARROW[List.Assoc[key: familyName, aList: GlobalOperatorTable]];
IF family=NIL THEN {
GlobalOperatorTable ← List.PutAssoc[key: familyName, val: LIST[class.name], aList: GlobalOperatorTable];
RETURN
};
family ← CONS[class.name, family]; -- maybe should put at end
GlobalOperatorTable ← List.PutAssoc[key: familyName, val: family, aList: GlobalOperatorTable];
};
OpFamiliesNames: PUBLIC PROC[] RETURNS[LIST OF ATOM]~ {
effects: Returns the list of all Op families
names: LIST OF ATOMNIL;
FOR l:List.AList ← GlobalOperatorTable, l.rest UNTIL l = NIL DO
names ← CONS[NARROW[l.first.key], names];
ENDLOOP;
RETURN[names];
};
OpFamilyNames: PUBLIC PROC[familyName: ATOM] RETURNS[LIST OF ATOM]~ {
effects: Returns the list of Op Names associated with familyName.
SIGNALS notFound if no association exists
family: LIST OF REFNARROW[List.Assoc[key: familyName, aList: GlobalOperatorTable]];
names: LIST OF ATOMNIL;
IF family=NIL THEN ERROR notFound;
FOR l:LIST OF REF ← family, l.rest UNTIL l = NIL DO
names ← CONS[NARROW[l.first], names];
ENDLOOP;
RETURN[names];
};
Operator Precedence
CompareOps: PUBLIC PROC[op1, op2: ATOM] RETURNS[Basics.Comparison]~ {
effects: compute operator precedence
SELECT op1 FROM
$sum, $difference => SELECT op2 FROM
$sum, $difference => RETURN[equal];
$negation => RETURN[less];
$product, $fraction, $pow => RETURN[less];
$dDx, $partialDeriv => RETURN[less];
ENDCASE => RETURN[equal];
$negation => SELECT op2 FROM
$sum, $difference => RETURN[greater];
$negation => RETURN[equal];
$product, $fraction => RETURN[equal];
$pow => RETURN[less];
$dDx, $partialDeriv => RETURN[less];
ENDCASE => RETURN[equal];
$product, $fraction => SELECT op2 FROM
$sum, $difference => RETURN[greater];
$negation => RETURN[equal];
$product, $fraction => RETURN[equal];
$pow => RETURN[less];
$dDx, $partialDeriv => RETURN[less];
ENDCASE => RETURN[equal];
ENDCASE => RETURN[equal];
};
Utility Proc
RopesFromAtoms: PUBLIC PROC [in: LIST OF ATOM] RETURNS[LIST OF ROPE] ~ {
Apply RopeFromAtom to each element if NOT descriptions, else DescriptionFromName to each element.
out, out2: LIST OF ROPE;
IF in = NIL THEN RETURN[NIL];
out ← out2 ← LIST[Convert.RopeFromAtom[from: in.first, quote: FALSE] ];
FOR l: LIST OF ATOM ← in.rest, l.rest UNTIL l=NIL DO
out2 ← out2.rest ← LIST[Convert.RopeFromAtom[from: l.first, quote: FALSE] ];
ENDLOOP;
RETURN[out];
};
KillAssoc: PUBLIC PROC [key: REF ANY, aList: AList] RETURNS[AList]~ {
kills the value associated with key in aList, if any. Destructive to list structure, and only removes the first occurrence. Like List.DRemove.
l, l1: AList ← NIL;
l ← aList;
UNTIL l = NIL DO
IF l.first.key = key THEN {
IF l1 = NIL THEN RETURN[l.rest]; -- ref was first object on list
l1.rest ← l.rest;
RETURN[aList];
};
l1 ← l;
l ← l.rest;
ENDLOOP;
RETURN [aList]; -- not found
};
Signals & Errors
notFound: PUBLIC ERROR = CODE;
Start Code (Reset Database)
ResetAtomClasses[];
ResetCompoundClasses[];
ResetMatrixClasses[];
ResetOperatorTable[];
END.