MathConstructorsImpl.mesa
Carl Waldspurger, August 30, 1986 7:12:37 pm PDT
Bier, November 20, 1986 2:02:38 pm PST
Arnon, December 11, 1986 8:52:07 am PST
High Level Expression Constructors.
DIRECTORY
MathExpr,
MathRules,
MathTypes,
MathBox,
ImagerFont,
ImagerTransformation,
Imager,
Rope,
Vector,
Convert,
MathConstructors,
XRope;
MathConstructorsImpl: CEDAR PROGRAM
IMPORTS MathRules, MathExpr, Convert, Rope, XRope
EXPORTS MathConstructors ~
BEGIN
Type Abbreviations
EXPR: TYPE ~ MathExpr.EXPR;
ROPE: TYPE ~ Rope.ROPE;
Atoms
MakePlainSym: PUBLIC PROC[c: CHAR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$plainSym, Rope.FromChar[c]]];
};
MakePlainRope: PUBLIC PROC[r: ROPE] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$plainSym, r]];
};
MakeOverlaySym: PUBLIC PROC[r: ROPE] RETURNS[EXPR] ~ {
effects: Returns a symbol expression which is all the chars in r superimposed.
RETURN[MathExpr.MakeAtomicExpr[$overlaySym, r]];
};
MakeBigMathSym: PUBLIC PROC[c: CHAR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$bigMathSym, XRope.FromChar[c, XRope.technical]]];
};
MakeXCSym: PUBLIC PROC[c: CHAR, cset: CHAR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$bigMathSym, XRope.FromChar[c, cset]]];
};
MakeSmallMathSym: PUBLIC PROC[c: CHAR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$smallMathSym, XRope.FromChar[c, XRope.greek]]];
};
MakeItalSym: PUBLIC PROC[c: CHAR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$italicSym, Rope.FromChar[c]]];
};
MakeMathItalSym: PUBLIC PROC[c: CHAR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$mathItalicSym, XRope.FromChar[c, XRope.greek]]];
};
MakeLine: PUBLIC PROC[] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$line, "LINE"]];
};
MakeSpace: PUBLIC PROC[size: ATOM] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$space, Convert.RopeFromAtom[size, FALSE]]];
};
MakePlaceHolder: PUBLIC PROC[] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeAtomicExpr[$placeholder, XRope.FromChar['\140, XRope.technical]]];
};
MakeInfinity: PUBLIC PROC[] RETURNS[EXPR] ~ {
effects: Constructs and returns an expression for +infinity.
RETURN[MathExpr.MakeAtomicExpr[$infinity, XRope.FromChar['\147, XRope.jis1]]];
};
MakeBool: PUBLIC PROC[n: ROPE] RETURNS[EXPR] ~ {
effects: Constructs and returns an bool expression for n.
SIGNALS badFormat if n is not a legal integer.
IF n.Length[] = 0 THEN ERROR badFormat;
IF NOT Rope.Equal[n, "TRUE"] AND NOT Rope.Equal[n, "FALSE"] THEN ERROR badFormat;
RETURN[MathExpr.MakeAtomicExpr[$bool, n]];
};
MakeInt: PUBLIC PROC[n: ROPE] RETURNS[EXPR] ~ {
effects: Constructs and returns an integer expression for n.
SIGNALS badFormat if n is not a legal integer.
IF n.Length[] = 0 THEN ERROR badFormat;
SELECT n.Fetch[0] FROM
IN ['0..'9] => NULL;
'- => IF n.Length[] = 1 THEN ERROR badFormat; -- a lone minus sign is invalid
ENDCASE => ERROR badFormat;
check that each char in n is a legal digit
FOR i:INT IN[1..n.Length[]-1] DO
SELECT n.Fetch[i] FROM
IN ['0..'9] => NULL;
ENDCASE => ERROR badFormat;
ENDLOOP;
RETURN[MathExpr.MakeAtomicExpr[$integer, n]];
};
MakeReal: PUBLIC PROC[r: REAL] RETURNS[EXPR] ~ {
effects: Constructs and returns a real expression for n.
RETURN[MathExpr.MakeAtomicExpr[$real, Convert.RopeFromReal[r]]];
};
MakeVariable: PUBLIC PROC[var: ROPE] RETURNS[EXPR] ~ {
effects: Constructs and returns a variable expression for var.
SIGNALS badFormat if n is not a legal variable (e.g. invalid chars).
IF var.Length[] = 0 THEN ERROR badFormat;
check that each char is an alphabetic char A thru Z, either case (disabled 9/30/86)
FOR i:INT IN[0..var.Length[]-1] DO
SELECT var.Fetch[i] FROM
IN ['A..'Z], IN ['a..'z] => NULL;
ENDCASE => ERROR badFormat;
ENDLOOP;
RETURN[MathExpr.MakeAtomicExpr[$variable, var]];
};
GreekNameToChar: PUBLIC PROC[name: ROPE] RETURNS[CHAR] ~ {
effects: Returns the greek TeX character named by name.
SIGNALS badFormat if names is unrecognized
RETURN[
SELECT TRUE FROM
Rope.Equal["Gamma", name] => '\104,
Rope.Equal["Delta", name] => '\105,
Rope.Equal["Theta", name] => '\113,
Rope.Equal["Lambda", name] => '\116,
Rope.Equal["Xi", name] => '\121,
Rope.Equal["Pi", name] => '\123,
Rope.Equal["Sigma", name] => '\126,
Rope.Equal["Upsilon", name] => '\131,
Rope.Equal["Phi", name] => '\132,
Rope.Equal["Psi", name] => '\134,
Rope.Equal["Omega", name] => '\135,
Rope.Equal["alpha", name] => '\141,
Rope.Equal["beta", name] => '\142,
Rope.Equal["gamma", name] => '\144,
Rope.Equal["delta", name] => '\145,
Rope.Equal["epsilon", name] => '\146,
Rope.Equal["zeta", name] => '\151,
Rope.Equal["eta", name] => '\152,
Rope.Equal["theta", name] => '\153,
Rope.Equal["iota", name] => '\154,
Rope.Equal["kappa", name] => '\155,
Rope.Equal["lambda", name] => '\156,
Rope.Equal["mu", name] => '\157,
Rope.Equal["nu", name] => '\160,
Rope.Equal["xi", name] => '\161,
Rope.Equal["pi", name] => '\163,
Rope.Equal["rho", name] => '\165,
Rope.Equal["sigma", name] => '\166,
Rope.Equal["tau", name] => '\170,
Rope.Equal["upsilon", name] => '\171,
Rope.Equal["phi", name] => '\172,
Rope.Equal["chi", name] => '\173,
Rope.Equal["psi", name] => '\174,
Rope.Equal["omega", name] => '\175,
ENDCASE => ERROR badFormat -- name unrecognized as a greek letter
];
};
CharToGreekName: PUBLIC PROC[c: CHAR] RETURNS[ROPE] ~ {
effects: Returns the name associated with the greek TeX character c.
If no such association exists, returns "unknown".
RETURN[
SELECT c FROM
'\104 => "Gamma",
'\105 => "Delta",
'\113 => "Theta",
'\116 => "Lambda",
'\121 => "Xi",
'\123 => "Pi",
'\126 => "Sigma",
'\131 => "Upsilon",
'\132 => "Phi",
'\134 => "Psi",
'\135 => "Omega",
'\141 => "alpha",
'\142 => "beta",
'\144 => "gamma",
'\145 => "delta",
'\146 => "epsilon",
'\151 => "zeta",
'\152=> "eta",
'\153 => "theta",
'\154 => "iota",
'\155 => "kappa",
'\156 => "lambda",
'\157 => "mu",
'\160 => "nu",
'\161 => "xi",
'\163 => "pi",
'\165 => "rho",
'\166 => "sigma",
'\170 => "tau",
'\171 => "upsilon",
'\172 => "phi",
'\173 => "chi",
'\174 => "psi",
'\175 => "omega",
ENDCASE => "unknown"
];
};
MakeGreekVar: PUBLIC PROC[name: ROPE] RETURNS[EXPR] ~ {
effects: Constructs and returns a greek variable expression for the
lowercase greek letter associated with name (e.g. "gamma", "lambda").
SIGNALS badFormat if name does not name a greek letter.
greekRope: ROPE ← XRope.FromChar[GreekNameToChar[name ! badFormat => {ERROR badFormat}], XRope.greek];
RETURN[MathExpr.MakeAtomicExpr[$greekVar, greekRope]];
};
Binary Ops
MakeSum: PUBLIC PROC[addend, augend: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$sum, LIST[[$addend, addend], [$augend, augend]]]];
};
MakeDifference: PUBLIC PROC[subtrahend, minuend: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$difference, LIST[[$subtrahend, subtrahend], [$minuend, minuend]]]];
};
MakeAnd: PUBLIC PROC[a, b: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$and, LIST[[$a, a], [$b, b]]]];
};
MakeOr: PUBLIC PROC[a, b: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$or, LIST[[$a, a], [$b, b]]]];
};
Other
MakeComplex: PUBLIC PROC[a, b: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$complex, LIST[[$a, a], [$b, b]]]];
};
MakeProduct: PUBLIC PROC[multiplier, multiplicand: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$product, LIST[[$multiplier, multiplier], [$multiplicand, multiplicand]]]];
};
MakeFraction: PUBLIC PROC[numerator, denominator: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$fraction, LIST[[$numerator, numerator], [$denominator, denominator]]]];
};
MakePow: PUBLIC PROC[base, exponent: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$pow, LIST[[$base, base], [$exponent, exponent]]]];
};
MakeSubscript: PUBLIC PROC[base, subscript: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$subscript, LIST[[$base, base], [$subscript, subscript]]]];
};
MakeParen: PUBLIC PROC[a: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$paren, LIST[[$a, a]]]];
};
Relations
MakeEqFormula: PUBLIC PROC[lhs, rhs: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$eqFormula, LIST[[$lhs, lhs], [$rhs, rhs]]]];
};
MakeNotEqFormula: PUBLIC PROC[lhs, rhs: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$notEqFormula, LIST[[$lhs, lhs], [$rhs, rhs]]]];
};
MakeLtFormula: PUBLIC PROC[lhs, rhs: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$ltFormula, LIST[[$lhs, lhs], [$rhs, rhs]]]];
};
MakeLeFormula: PUBLIC PROC[lhs, rhs: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$leFormula, LIST[[$lhs, lhs], [$rhs, rhs]]]];
};
MakeGtFormula: PUBLIC PROC[lhs, rhs: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$gtFormula, LIST[[$lhs, lhs], [$rhs, rhs]]]];
};
MakeGeFormula: PUBLIC PROC[lhs, rhs: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$geFormula, LIST[[$lhs, lhs], [$rhs, rhs]]]];
};
Radical
MakeRadical: PUBLIC PROC[radicand, n: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$nRadical, LIST[[$radicand, radicand], [$n, n]]]];
};
Ops
MakeSummation: PUBLIC PROC[lb, ub, summand: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$summation, LIST[[$lowerbound, lb], [$summand, summand], [$upperbound, ub]]]];
};
MakeIntegral: PUBLIC PROC[llim, ulim, integrand, wrt: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$integration, LIST[[$lowerlimit, llim], [$upperlimit, ulim], [$integrand, integrand], [$wrt, wrt]]]];
};
MakeIndefiniteIntegral: PUBLIC PROC[integrand, wrt: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$indefInt, LIST[[$integrand, integrand], [$wrt, wrt]]]];
};
Unary Ops
MakeNot: PUBLIC PROC[a: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$not, LIST[[$a, a]]]];
};
MakeNegation: PUBLIC PROC[a: EXPR] RETURNS[EXPR] ~ {
RETURN[MathExpr.MakeCompoundExpr[$negation, LIST[[$a, a]]]];
};
Matrices
MakeSet: PUBLIC PROC[cardinality: NAT, elements: LIST OF EXPR, row: BOOL] RETURNS[EXPR] ~ {
RETURN[ MakeVectorConstruct[$set, cardinality, elements, row] ];
};
MakePoint: PUBLIC PROC[dimension: NAT, elements: LIST OF EXPR, row: BOOL] RETURNS[EXPR] ~ {
RETURN[ MakeVectorConstruct[$point, dimension, elements, row] ];
};
MakeSequence: PUBLIC PROC[dimension: NAT, elements: LIST OF EXPR, row: BOOL] RETURNS[EXPR] ~ {
RETURN[ MakeVectorConstruct[$sequence, dimension, elements, row] ];
};
MakeVector: PUBLIC PROC[dimension: NAT, elements: LIST OF EXPR, row: BOOL] RETURNS[EXPR] ~ {
RETURN[ MakeVectorConstruct[$vector, dimension, elements, row] ];
};
MakeVectorConstruct: PROC[class: ATOM, dimension: NAT, elements: LIST OF EXPR, row: BOOL] RETURNS[EXPR] ~ {
effects: Constructs and returns a vector expression of size dimension from elements.
SIGNALS badFormat if dimension doesn't exactly match dimension(elements).
local declarations
elts, eltsPointer: LIST OF MathExpr.TaggedMathExpr ← NIL;
rowCount, colCount: NAT ← 0;
IF row THEN rowCount ← 1 ELSE colCount ← 1; -- row vec has 1 row, col vec has 1 col
FOR l: LIST OF EXPR ← elements, l.rest UNTIL l = NIL DO
IF row THEN colCount ← colCount + 1 ELSE rowCount ← rowCount + 1;
IF elts =NIL THEN
elts ← eltsPointer ← LIST[ [MathRules.AtomFromRowCol[rowCount, colCount], l.first] ]
ELSE
eltsPointer ← eltsPointer.rest ← LIST[ [MathRules.AtomFromRowCol[rowCount, colCount], l.first] ];
ENDLOOP;
complain if dimension does not agree with length(elements)
IF row THEN {
IF colCount # dimension THEN ERROR badFormat; -- wrong # elements
}
ELSE {
IF rowCount # dimension THEN ERROR badFormat; -- wrong # elements
};
RETURN[MathExpr.MakeMatrixExpr[class, rowCount, colCount, elts]];
};
MakeMatrix: PUBLIC PROC[nRows, nCols: NAT, rows: LIST OF LIST OF EXPR]
RETURNS[EXPR] ~ {
effects: Constructs and returns a matrix expression of size nRows by nCols from rows.
SIGNALS badFormat if dimensions given don't exactly match dimension(rows).
local declarations
elements, elementsPointer: LIST OF MathExpr.TaggedMathExpr ← NIL;
rowCount, colCount: NAT ← 0;
FOR l: LIST OF LIST OF EXPR ← rows, l.rest UNTIL l = NIL DO
rowCount ← rowCount + 1;
colCount ← 0;
FOR elts: LIST OF EXPR ← l.first, elts.rest UNTIL elts = NIL DO
rowColEntry: MathExpr.TaggedMathExpr;
colCount ← colCount + 1;
rowColEntry ← [MathRules.AtomFromRowCol[rowCount, colCount], elts.first];
elements ← CONS[[MathRules.AtomFromRowCol[rowCount, colCount], elts.first], elements];
IF elements = NIL THEN elements ← elementsPointer ← LIST[rowColEntry] ELSE elementsPointer ← elementsPointer.rest ← LIST[rowColEntry]; -- 3/4/87 - store elements in proper order
ENDLOOP;
IF colCount # nCols THEN ERROR badFormat; -- wrong # cols for this row
ENDLOOP;
IF rowCount # nRows THEN ERROR badFormat; -- wrong # rows
RETURN[MathExpr.MakeMatrixExpr[$matrix, nRows, nCols, elements]];
};
Signals & Errors
wrongAtomValueType: PUBLIC ERROR = CODE;
wrongBoxType: PUBLIC ERROR = CODE;
badFormat: PUBLIC ERROR = CODE;
END.