MathExprClassesSet.mesa
Carl Waldspurger, August 30, 1986 7:12:37 pm PDT
Bier, November 20, 1986 2:02:38 pm PST
Arnon, March 24, 1987 4:15:37 pm PST
DIRECTORY
MathExpr,
MathRules,
MathDB,
MathTypes,
MathBox,
Imager,
Rope,
Vector,
MathConstructors;
MathExprClassesSet: CEDAR PROGRAM
IMPORTS MathBox, MathRules, MathExpr,
MathDB, MathConstructors
~
BEGIN
Type Abbreviations from Imported Interfaces
EXPR: TYPE ~ MathExpr.EXPR;
BOX: TYPE ~ MathBox.BOX;
ROPE: TYPE ~ Rope.ROPE;
VEC: TYPE ~ Vector.VEC;
CompoundBoxProc: TYPE ~ MathRules.CompoundBoxProc;
CompositionProc: TYPE ~ MathRules.CompositionProc;
Alignment2D: TYPE ~ MathRules.Alignment2D;
Offset: TYPE ~ MathRules.Offset;
Size: TYPE ~ MathRules.Size;
Argument: TYPE ~ MathExpr.Argument;
Symbol: TYPE ~ MathExpr.Symbol;
CompoundClass: TYPE ~ MathExpr.CompoundClass;
FormatClass: TYPE ~ MathTypes.FormatClass;
Style: TYPE ~ MathTypes.Style;
Procedure Abbreviations from Imported Interfaces
MakeArgument: PROC[name: ATOM, aliases: LIST OF ATOM, size: Size] RETURNS[Argument] ~ MathExpr.MakeArgument;
MakeSymbol: PROC[name: ATOM, aliases: LIST OF ATOM, size: Size, value: EXPR] RETURNS[Symbol] ~ MathExpr.MakeSymbol;
MakeCompoundClass: PROC[name: ATOM, formatClass: FormatClass, description: ROPE, args: LIST OF Argument, syms: LIST OF Symbol, boxRule: CompoundBoxProc, compBox: CompositionProc, cvtAS, cvtReduce, cvtSMP, cvtOther: ROPENIL] RETURNS[CompoundClass] ~ MathExpr.MakeCompoundClass;
Constants
smallGap: REAL = 0.05;
medGap: REAL = 0.10;
bigGap: REAL = 0.25;
Box Procs for Compound Expr Classes
FixedSizeBoxRule: CompoundBoxProc ~ {
effects: Returns unaltered boxes (i.e. no resizing takes place)
RETURN[boxes];
};
FractionBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($fractionBar $numerator $denominator)
should ENABLE noSuchBox
fbarBox: BOX ← MathBox.GetBox[$fractionBar, boxes];
numBox: BOX ← MathBox.GetBox[$numerator, boxes];
denomBox: BOX ← MathBox.GetBox[$denominator, boxes];
topSpaceBox: BOX ← MathBox.GetBox[$topSpace, boxes];
bottomSpaceBox: BOX ← MathBox.GetBox[$bottomSpace, boxes];
fraction bar must be as wide as the wider of numerator, denominator
scaleX: REAL ← 1.1 * MAX[numBox.Width[], denomBox.Width[] ] / fbarBox.Width[];
adjust fbarBox extents
fbarBox ← MathBox.Scale[fbarBox, [scaleX, 1.0]];
RETURN[LIST[fbarBox, numBox, denomBox, topSpaceBox, bottomSpaceBox]];
};
dDxBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($dDx $differand $wrt)
should ENABLE noSuchBox
fbarBox: BOX ← MathBox.GetBox[$fractionBar, boxes];
dOfBox: BOX ← MathBox.GetBox[$dOf, boxes];
dxBox: BOX ← MathBox.GetBox[$dx, boxes];
differandBox: BOX ← MathBox.GetBox[$differand, boxes];
wrtBox: BOX ← MathBox.GetBox[$wrt, boxes];
topSpaceBox: BOX ← MathBox.GetBox[$topSpace, boxes];
bottomSpaceBox: BOX ← MathBox.GetBox[$bottomSpace, boxes];
fraction bar must be as wide as the wider of numerator, denominator
scaleX: REAL ← 1.1 * MAX[dOfBox.Width[]+differandBox.Width[], dxBox.Width[]+wrtBox.Width[] ] / fbarBox.Width[];
adjust fbarBox extents
fbarBox ← MathBox.Scale[fbarBox, [scaleX, 1.0]];
RETURN[LIST[fbarBox, dOfBox, dxBox, differandBox, wrtBox, topSpaceBox, bottomSpaceBox]];
};
PartialDerivBoxRule: CompoundBoxProc ~ {
should ENABLE noSuchBox
fbarBox: BOX ← MathBox.GetBox[$fractionBar, boxes];
partialOfBox: BOX ← MathBox.GetBox[$partialOf, boxes];
partialWrtBox: BOX ← MathBox.GetBox[$partialWrt, boxes];
differandBox: BOX ← MathBox.GetBox[$differand, boxes];
wrtBox: BOX ← MathBox.GetBox[$wrt, boxes];
topSpaceBox: BOX ← MathBox.GetBox[$topSpace, boxes];
bottomSpaceBox: BOX ← MathBox.GetBox[$bottomSpace, boxes];
fraction bar must be as wide as the wider of numerator, denominator
scaleX: REAL ← 1.1 * MAX[partialOfBox.Width[]+differandBox.Width[], partialWrtBox.Width[]+wrtBox.Width[] ] / fbarBox.Width[];
adjust fbarBox extents
fbarBox ← MathBox.Scale[fbarBox, [scaleX, 1.0]];
RETURN[LIST[fbarBox, partialOfBox, partialWrtBox, differandBox, wrtBox, topSpaceBox, bottomSpaceBox]];
};
ParenBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($paren $a)
leftParenBox: BOX ← MathBox.GetBox[$leftParen, boxes];
rightParenBox: BOX ← MathBox.GetBox[$rightParen, boxes];
aBox: BOX ← MathBox.GetBox[$a, boxes];
right and left parentheses must be as tall as expression "a"
scaleFactor: REALMAX[0.25, 1.1 * aBox.Height[] / leftParenBox.Height[]];
leftParenBox ← MathBox.Scale[leftParenBox, [scaleFactor, scaleFactor]];
rightParenBox ← MathBox.Scale[rightParenBox, [scaleFactor, scaleFactor]];
RETURN[LIST[aBox, leftParenBox, rightParenBox]];
};
CurlyBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($curly $a)
leftCurlyBox: BOX ← MathBox.GetBox[$leftCurly, boxes];
rightCurlyBox: BOX ← MathBox.GetBox[$rightCurly, boxes];
aBox: BOX ← MathBox.GetBox[$a, boxes];
right and left curly brackets must be as tall as expression "a"
scaleFactor: REALMAX[0.25, 1.1 * aBox.Height[] / leftCurlyBox.Height[]];
leftCurlyBox ← MathBox.Scale[leftCurlyBox, [scaleFactor, scaleFactor]];
rightCurlyBox ← MathBox.Scale[rightCurlyBox, [scaleFactor, scaleFactor]];
RETURN[LIST[aBox, leftCurlyBox, rightCurlyBox]];
};
SquareBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($square $a)
leftSquareBox: BOX ← MathBox.GetBox[$leftSquare, boxes];
rightSquareBox: BOX ← MathBox.GetBox[$rightSquare, boxes];
aBox: BOX ← MathBox.GetBox[$a, boxes];
right and left square brackets must be as tall as expression "a"
scaleFactor: REALMAX[0.25, 1.1 * aBox.Height[] / leftSquareBox.Height[]];
leftSquareBox ← MathBox.Scale[leftSquareBox, [scaleFactor, scaleFactor]];
rightSquareBox ← MathBox.Scale[rightSquareBox, [scaleFactor, scaleFactor]];
RETURN[LIST[aBox, leftSquareBox, rightSquareBox]];
};
AbsBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($abs $a)
leftBox: BOX ← MathBox.GetBox[$leftAbs, boxes];
rightBox: BOX ← MathBox.GetBox[$rightAbs, boxes];
aBox: BOX ← MathBox.GetBox[$a, boxes];
right and left absolute value bars must be as tall as expression "a"
scaleFactor: REALMAX[0.25, 1.1 * aBox.Height[] / leftBox.Height[]];
leftBox ← MathBox.Scale[leftBox, [scaleFactor, scaleFactor]];
rightBox ← MathBox.Scale[rightBox, [scaleFactor, scaleFactor]];
RETURN[LIST[aBox, leftBox, rightBox]];
};
NRadicalBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($radRoot $radLine $n $radicand)
should ENABLE noSuchBox
radRootBox: BOX ← MathBox.GetBox[$radRoot, boxes];
radLineBox: BOX ← MathBox.GetBox[$radLine, boxes];
nBox: BOX ← MathBox.GetBox[$n, boxes];
spaceBox: BOX ← MathBox.GetBox[$space, boxes];
radicandBox: BOX ← MathBox.GetBox[$radicand, boxes];
line must be exactly as long as radicand,
root symbol must be as tall as radicand + 2*space
rootScale: REAL ← ((2 * spaceBox.Height[]) + radicandBox.Height[]) / radRootBox.Height[];
lineScale: VEC ← [radicandBox.Width[]/radLineBox.Width[], 1.0];
adjust symbol extents
radRootBox ← MathBox.Scale[radRootBox, [rootScale, rootScale]];
radLineBox ← MathBox.Scale[radLineBox, lineScale];
RETURN[LIST[radRootBox, radLineBox, nBox, radicandBox, spaceBox]];
};
SummationBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($summation $lowerbound $upperbound $summand)
dsa 4/17/87
should ENABLE noSuchBox
sigmaBox: BOX ← MathBox.GetBox[$sigma, boxes];
lowerboundBox: BOX ← MathBox.GetBox[$lowerbound, boxes];
upperboundBox: BOX ← MathBox.GetBox[$upperbound, boxes];
summandBox: BOX ← MathBox.GetBox[$summand, boxes];
spaceBox: BOX ← MathBox.GetBox[$space, boxes];
summation sign must grow if summand does
scaleFac: REALMAX[summandBox.Height[]/sigmaBox.Height[], 1.0];
adjust symbol extents
sigmaBox ← MathBox.Scale[sigmaBox, [scaleFac, scaleFac] ];
RETURN[LIST[sigmaBox, lowerboundBox, upperboundBox, summandBox]];
};
IndefiniteIntBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($integral $integrand $dx $wrt)
dsa 4/17/87
should ENABLE noSuchBox
integralBox: BOX ← MathBox.GetBox[$integral, boxes];
integrandBox: BOX ← MathBox.GetBox[$integrand, boxes];
spaceBox: BOX ← MathBox.GetBox[$space, boxes];
dxBox: BOX ← MathBox.GetBox[$dx, boxes];
wrtBox: BOX ← MathBox.GetBox[$wrt, boxes];
integral sign must grow if integrand does
scaleFac: REALMAX[integrandBox.Height[]/integralBox.Height[], 1.0];
adjust symbol extents
integralBox ← MathBox.Scale[integralBox, [scaleFac, scaleFac] ];
RETURN[LIST[integralBox, integrandBox, dxBox, wrtBox, spaceBox]];
};
DefiniteIntBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($integral $lowerlimit $upperlimit $integrand $dx $wrt)
dsa 4/17/87
should ENABLE noSuchBox
integralBox: BOX ← MathBox.GetBox[$integral, boxes];
lowerlimitBox: BOX ← MathBox.GetBox[$lowerlimit, boxes];
upperlimitBox: BOX ← MathBox.GetBox[$upperlimit, boxes];
integrandBox: BOX ← MathBox.GetBox[$integrand, boxes];
spaceBox: BOX ← MathBox.GetBox[$space, boxes];
dxBox: BOX ← MathBox.GetBox[$dx, boxes];
wrtBox: BOX ← MathBox.GetBox[$wrt, boxes];
integral sign must grow if integrand does
scaleFac: REALMAX[integrandBox.Height[]/integralBox.Height[], 1.0];
adjust symbol extents
integralBox ← MathBox.Scale[integralBox, [scaleFac, scaleFac] ];
RETURN[LIST[integralBox, lowerlimitBox, upperlimitBox, integrandBox, dxBox, wrtBox, spaceBox]];
};
RadicalBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($radRoot $radLine $radicand)
should ENABLE noSuchBox
radRootBox: BOX ← MathBox.GetBox[$radRoot, boxes];
radLineBox: BOX ← MathBox.GetBox[$radLine, boxes];
spaceBox: BOX ← MathBox.GetBox[$space, boxes];
radicandBox: BOX ← MathBox.GetBox[$radicand, boxes];
line must be exactly as long as radicand,
root symbol must be as tall as radicand + 2*space
rootScale: REAL ← ((2 * spaceBox.Height[]) + radicandBox.Height[]) / radRootBox.Height[];
lineScale: VEC ← [radicandBox.Width[]/radLineBox.Width[], 1.0];
adjust symbol extents
radRootBox ← MathBox.Scale[radRootBox, [rootScale, rootScale]];
radLineBox ← MathBox.Scale[radLineBox, lineScale];
RETURN[LIST[radRootBox, radLineBox, radicandBox, spaceBox]];
};
FunctionBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($f $space $args $leftParen $rightParen)
should ENABLE noSuchBox
lParenBox: BOX ← MathBox.GetBox[$leftParen, boxes];
rParenBox: BOX ← MathBox.GetBox[$rightParen, boxes];
spaceBox: BOX ← MathBox.GetBox[$space, boxes];
fBox: BOX ← MathBox.GetBox[$f, boxes];
argsBox: BOX ← MathBox.GetBox[$args, boxes];
parens must be as big as args
right and left parentheses must be as tall as expression "a"
scaleFactor: REALMAX[1.0, 1.1 * argsBox.Height[] / lParenBox.Height[]];
lParenBox ← MathBox.Scale[lParenBox, [scaleFactor, scaleFactor]];
rParenBox ← MathBox.Scale[rParenBox, [scaleFactor, scaleFactor]];
RETURN[LIST[fBox, spaceBox, lParenBox, rParenBox, argsBox]];
};
BinaryFunctionBoxRule: CompoundBoxProc ~ {
effects: Sizes boxes for expr of form ($f $space $firstArg $secondArg $leftParen $rightParen)
should ENABLE noSuchBox
commaBox: BOX ← MathBox.GetBox[$comma, boxes];
lParenBox: BOX ← MathBox.GetBox[$leftParen, boxes];
rParenBox: BOX ← MathBox.GetBox[$rightParen, boxes];
spaceBox: BOX ← MathBox.GetBox[$space, boxes];
fBox: BOX ← MathBox.GetBox[$f, boxes];
firstArgBox: BOX ← MathBox.GetBox[$firstArg, boxes];
secondArgBox: BOX ← MathBox.GetBox[$secondArg, boxes];
right and left parentheses must be as tall as max of expressions "a" and "b"
scaleFactor: REALMAX[
1.0,
1.1 * MAX[firstArgBox.Height[], secondArgBox.Height[] ] / lParenBox.Height[]
];
lParenBox ← MathBox.Scale[lParenBox, [scaleFactor, scaleFactor]];
commaBox ← MathBox.Scale[commaBox, [scaleFactor, scaleFactor]];
rParenBox ← MathBox.Scale[rParenBox, [scaleFactor, scaleFactor]];
RETURN[LIST[fBox, spaceBox, commaBox, lParenBox, rParenBox, firstArgBox, secondArgBox]];
};
Composition Procs for Compound Expr Classes
PowCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($exponent $base)
tempBox: BOX;
tempBoxes: LIST OF BOX;
vertOffsetExponent, vertOffsetBase, horizOffsetBase: Offset;
alignments: LIST OF Alignment2D ← NIL;
baseBox: BOX ← MathBox.GetBox[$base, boxes];
exponentBox: BOX ← MathBox.GetBox[$exponent, boxes];
hintBox: BOX ← baseBox.SuperscriptHint[]; -- hint about where to place subscript w/i base
IF hintBox # NIL THEN {
hint, so align exponent with base via hintBox
horizOffsetBase ← [origin, hintBox.Offset[].x + hintBox.Extents[].rightExtent];
IF (hintBox.Height[] * baseBox.Height[]) > exponentBox.Height[] THEN {
vertOffsetExponent ← [bottom, 0.2];
top of hint box inside base box
vertOffsetBase ← [origin, hintBox.Offset[].y + hintBox.Extents[].ascent];
}
ELSE {
vertOffsetExponent ← [bottom];
0.8 way up on hint box
vertOffsetBase ← [origin, 0.8 * (hintBox.Offset[].y + hintBox.Extents[].ascent)];
};
}
ELSE {
no hint, so align exponent directly with base
horizOffsetBase ← [right];
IF baseBox.Height[] > exponentBox.Height[] THEN {
vertOffsetExponent ← [bottom, 0.2];
vertOffsetBase ← [top];
}
ELSE {
vertOffsetExponent ← [bottom];
vertOffsetBase ← [top, -0.2];
};
};
alignments ← LIST[
[$exponent,
[$base, [left], horizOffsetBase],
[$base, vertOffsetExponent, vertOffsetBase]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$base, [origin]], [$base, [origin]]];
RETURN[tempBox, tempBoxes];
};
SubscriptCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($base $subscript)
tempBox: BOX;
tempBoxes: LIST OF BOX;
vertOffsetSubscript, vertOffsetBase: Offset;
alignments: LIST OF Alignment2D ← NIL;
IF MathBox.GetBox[$base, boxes].Height[] >
MathBox.GetBox[$subscript, boxes].Height[] THEN {
vertOffsetSubscript ← [top, -0.2];
vertOffsetBase ← [bottom];
}
ELSE {
vertOffsetSubscript ← [top];
vertOffsetBase ← [bottom, +0.2];
};
alignments ← LIST[
[$subscript,
[$base, [left], [right]],
[$base, vertOffsetSubscript, vertOffsetBase]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$base, [origin]], [$base, [origin]]];
make hint to place superscript over base instead of entire expression
tempBox ← tempBox.ChangeSuperHint[MathBox.GetBox[$base, tempBoxes]];
RETURN[tempBox, tempBoxes];
};
FractionCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($fractionBar $numerator $denominator)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$topSpace,
[$fractionBar, [center], [center]],
[$fractionBar, [bottom], [top]]],
[$bottomSpace,
[$fractionBar, [center], [center]],
[$fractionBar, [top], [bottom]]],
[$numerator,
[$fractionBar, [center], [center]],
[$topSpace, [bottom], [top]]],
[$denominator,
[$fractionBar, [center], [center]],
[$bottomSpace, [top], [bottom]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$fractionBar, [origin]],
[$fractionBar, [origin]]];
RETURN[tempBox, tempBoxes];
};
dDxCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($fractionBar $differand $wrt)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$topSpace,
[$fractionBar, [center], [center]],
[$fractionBar, [bottom], [top]]],
[$bottomSpace,
[$fractionBar, [center], [center]],
[$fractionBar, [top], [bottom]]],
[$dOf,
[$fractionBar, [left], [left, 0.05]],
[$topSpace, [bottom], [top]]],
[$differand,
[$dOf, [left], [right]],
[$dOf, [bottom], [bottom]]],
[$dx,
[$fractionBar, [left], [left, 0.05]],
[$bottomSpace, [top], [bottom]]],
[$wrt,
[$dx, [left], [right]],
[$dx, [origin], [origin]]]
];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$fractionBar, [origin]],
[$fractionBar, [origin]]];
RETURN[tempBox, tempBoxes];
};
PartialDerivCompRule: CompositionProc ~ {
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$topSpace,
[$fractionBar, [center], [center]],
[$fractionBar, [bottom], [top]]],
[$bottomSpace,
[$fractionBar, [center], [center]],
[$fractionBar, [top], [bottom]]],
[$partialOf,
[$fractionBar, [left], [left, 0.05]],
[$topSpace, [bottom], [top]]],
[$differand,
[$partialOf, [left], [right]],
[$partialOf, [bottom], [bottom]]],
[$partialWrt,
[$fractionBar, [left], [left, 0.05]],
[$bottomSpace, [top], [bottom]]],
[$wrt,
[$partialWrt, [left], [right]],
[$partialWrt, [origin], [origin]]]
];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$fractionBar, [origin]],
[$fractionBar, [origin]]];
RETURN[tempBox, tempBoxes];
};
AboveCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($above $topArg $bottomArg)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$bottomSpace,
[$bottomArg, [center], [center]],
[$bottomArg, [bottom], [top]]],
[$topSpace,
[$bottomArg, [center], [center]],
[$bottomSpace, [bottom], [top]]],
[$topArg,
[$bottomArg, [center], [center]],
[$topSpace, [bottom], [top]]]
];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$topArg, [origin]],
[$bottomSpace, [top]]];
RETURN[tempBox, tempBoxes];
};
HatCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($hat $base $hat)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$bottomSpace,
[$base, [center], [center]],
[$base, [bottom], [top]]],
[$hat,
[$base, [center], [center]],
[$bottomSpace, [bottom], [top]]]
];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$base, [origin]], [$base, [origin]]];
RETURN[tempBox, tempBoxes];
};
ListCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($comma $car $cdr) with symbol $space.
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$car,
[$comma, [right], [left]],
[$comma, [origin], [origin]]],
[$space,
[$comma, [left], [right]],
[$comma, [origin], [origin]]],
[$cdr,
[$space, [left], [right]],
[$comma, [origin], [origin]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$car, [origin]], [$comma, [origin]]];
RETURN[tempBox, tempBoxes];
};
FunctionCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($f $space $args $leftParen $rightParen)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$leftParen,
[$args, [right], [left]],
[$args, [center], [center]]],
[$rightParen,
[$args, [left], [right]],
[$args, [center], [center]]],
[$space,
[$leftParen, [right], [left]],
[$args, [origin], [origin]]],
[$f,
[$space, [right], [left]],
[$args, [origin], [origin]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$f, [origin]], [$f, [origin]]];
RETURN[tempBox, tempBoxes];
};
BinaryFunctionCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($f $space $firstArg $secondArg $comma $leftParen $rightParen)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$leftParen,
[$firstArg, [right], [left]],
[$firstArg, [center], [center]]],
[$comma,
[$firstArg, [left], [right]],
[$firstArg, [origin], [origin]]],
[$secondArg,
[$comma, [left], [right, medGap]],
[$comma, [origin], [origin]]],
[$rightParen,
[$secondArg, [left], [right]],
[$secondArg, [center], [center]]],
[$space,
[$leftParen, [right], [left]],
[$firstArg, [origin], [origin]]],
[$f,
[$space, [right], [left]],
[$firstArg, [origin], [origin]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$f, [origin]], [$f, [origin]]];
RETURN[tempBox, tempBoxes];
};
LimitCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($lim $approaches $of $space)
tempBox: BOX;
tempBoxes: LIST OF BOX;
limBox: BOX ← MathBox.GetBox[$lim, boxes];
approachesBox: BOX ← MathBox.GetBox[$approaches, boxes];
alignments: LIST OF Alignment2D;
IF approachesBox.Width[] > limBox.Width[] THEN {
alignments ← LIST[
[$space,
[$of, [right], [left]],
[$of, [center], [center]]],
[$approaches,
[$space, [right], [left]],
[$space, [top], [bottom]]],
[$lim,
[$approaches, [center], [center]],
[$space, [bottom], [top]]]];
}
ELSE {
alignments ← LIST[
[$space,
[$of, [right], [left]],
[$of, [center], [center]]],
[$lim,
[$space, [right], [left]],
[$space, [bottom], [top]]],
[$approaches,
[$lim, [center], [center]],
[$space, [top], [bottom]]]];
};
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$approaches, [origin]], [$of, [origin]]];
RETURN[tempBox, tempBoxes];
};
SummationCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($summation $lowerbound $upperbound
$summand)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← NIL;
vertSigmaOffset, vertSummandOffset: Offset;
SELECT MathBox.GetBox[$summand, boxes].FormatClass[] FROM
over, radical, matrix => {
vertSigmaOffset ← [center];
vertSummandOffset ← [center];
};
ENDCASE => {
vertSummandOffset ← [origin];
vertSigmaOffset ← [center, -0.2];
};
alignments ← LIST[
[$lowerbound,
[$sigma, [center], [center]],
[$sigma, [top], [bottom, -smallGap]]],
[$upperbound,
[$sigma, [center], [center]],
[$sigma, [bottom], [top, +smallGap]]],
[$summand,
[$sigma, [left], [right, medGap]],
[$sigma, vertSummandOffset, vertSigmaOffset]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$sigma, [origin]], [$sigma, [center, -0.2]]];
RETURN[tempBox, tempBoxes];
};
NRadicalCompRule: CompositionProc ~ {
effects: Compose layout for expr of form ($radRoot $radLine $n $radicand)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$radRoot,
[$radicand, [right], [left]],
[$radicand, [center], [center]]],
[$space,
[$radicand, [center], [center]],
[$radicand, [bottom], [top]]],
[$radLine,
[$radRoot, [left], [right]],
[$radRoot, [top], [top]]],
[$n,
[$radRoot, [right], [left, bigGap]],
[$radRoot, [bottom], [center, +smallGap]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$n, [origin]], [$radicand, [origin]]];
RETURN[tempBox, tempBoxes];
};
RadicalCompRule: CompositionProc ~ {
effects: Compose layout for expr of form ($radRoot $radLine $radicand)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$radRoot,
[$radicand, [right], [left]],
[$radicand, [center], [center]]],
[$space,
[$radicand, [center], [center]],
[$radicand, [bottom], [top]]],
[$radLine,
[$radRoot, [left], [right]],
[$radRoot, [top], [top]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$radicand, [origin]],
[$radicand, [origin]]];
RETURN[tempBox, tempBoxes];
};
IntegrationCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($integral $lowerlimit
$upperlimit $integrand $dx $wrt)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← NIL;
vertIntegralOffset, vertIntegrandOffset: Offset;
SELECT MathBox.GetBox[$integrand, boxes].FormatClass[] FROM
over, radical, matrix => {
vertIntegralOffset ← [center];
vertIntegrandOffset ← [center];
};
ENDCASE => {
vertIntegralOffset ← [center, -0.2];
vertIntegrandOffset ← [origin];
};
alignments ← LIST[
[$lowerlimit,
[$integral, [right], [left, +bigGap]],
[$integral, [top], [bottom, -smallGap]]],
[$upperlimit,
[$integral, [right], [right]],
[$integral, [bottom], [top, +smallGap]]],
[$integrand,
[$integral, [left], [right]],
[$integral, vertIntegrandOffset, vertIntegralOffset]],
[$space,
[$integrand, [left], [right]],
[$integrand, [origin], [origin]]],
[$dx,
[$space, [left], [right]],
[$space, [origin], [origin]]], -- Carl's original y-alignment
[$integral, vertIntegrandOffset, vertIntegralOffset ]], -- dsa 4/15/87
[$wrt,
[$dx, [left], [right]],
[$dx, [origin], [origin]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$lowerlimit, [origin]], [$integral, [center, -0.2]]];
RETURN[tempBox, tempBoxes];
};
IndefiniteIntCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($integral $integrand $dx $wrt)
tempBox: BOX;
tempBoxes: LIST OF BOX;
vertIntegralOffset, vertIntegrandOffset: Offset;
alignments: LIST OF Alignment2D ← NIL;
SELECT MathBox.GetBox[$integrand, boxes].FormatClass[] FROM
over, radical, matrix => {
vertIntegralOffset ← [center];
vertIntegrandOffset ← [center];
};
ENDCASE => {
vertIntegralOffset ← [center, -0.2];
vertIntegrandOffset ← [origin];
};
alignments LIST[
[$integrand,
[$integral, [left], [right]],
[$integral, vertIntegrandOffset, vertIntegralOffset ]],
[$space,
[$integrand, [left], [right]],
[$integrand, [origin], [origin]]],
[$dx,
[$space, [left], [right,]],
[$space, [origin], [origin]]], -- Carl's original y-alignment
[$integral, vertIntegrandOffset, vertIntegralOffset ]], -- dsa 4/15/87
[$wrt,
[$dx, [left], [right]],
[$dx, [origin], [origin]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$integral, [origin]],
[$integral, [center, -0.2]]];
RETURN[tempBox, tempBoxes];
};
UnaryOpCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($aliasUnaryOp $aliasA).
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$aliasSpace,
[$aliasUnaryOp, [left], [right]],
[$aliasUnaryOp, [origin], [origin]]],
[$aliasA,
[$aliasSpace, [left], [right]],
[$aliasSpace, [origin], [origin]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$aliasUnaryOp, [origin]],
[$aliasUnaryOp, [origin]]];
RETURN[tempBox, tempBoxes];
};
BinaryOpCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($aliasBinOp $aliasA $aliasB) with
symbols $aliasLeftSpace & $aliasRightSpace.
tempBox: BOX;
tempBoxes: LIST OF BOX;
leftVertOffsetA, leftVertOffsetOp, rightVertOffsetB, rightVertOffsetOp: Offset;
alignments: LIST OF Alignment2D;
set vertical offset depending on format classes of A & B arguments
SELECT MathBox.GetBox[$aliasA, boxes].FormatClass[] FROM
over => {
leftVertOffsetA ← [origin];
leftVertOffsetOp ← [center];
};
matrix => {
leftVertOffsetA ← [center];
leftVertOffsetOp ← [center];
};
ENDCASE => {
leftVertOffsetA ← [origin];
leftVertOffsetOp ← [origin];
};
SELECT MathBox.GetBox[$aliasB, boxes].FormatClass[] FROM
over => {
rightVertOffsetB ← [origin];
rightVertOffsetOp ← [center];
};
matrix => {
rightVertOffsetB ← [center];
rightVertOffsetOp ← [center];
};
ENDCASE => {
rightVertOffsetB ← [origin];
rightVertOffsetOp ← [origin];
};
alignments ← LIST[
[$aliasLeftSpace,
[$aliasBinOp, [right], [left]],
[$aliasBinOp, [origin], [origin]]],
[$aliasA,
[$aliasLeftSpace, [right], [left]],
[$aliasBinOp, leftVertOffsetA, leftVertOffsetOp]],
[$aliasRightSpace,
[$aliasBinOp, [left], [right]],
[$aliasBinOp, [origin], [origin]]],
[$aliasB,
[$aliasRightSpace, [left], [right]],
[$aliasBinOp, rightVertOffsetB, rightVertOffsetOp]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$aliasA, [origin]], [$aliasBinOp, [origin]]];
RETURN[tempBox, tempBoxes];
};
RelationCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($aliasRelation $aliasLHS $aliasRHS) with
symbols $aliasLeftSpace & $aliasRightSpace.
tempBox: BOX;
tempBoxes: LIST OF BOX;
leftVertOffsetLHS, leftVertOffsetRel, rightVertOffsetRHS, rightVertOffsetRel: Offset;
alignments: LIST OF Alignment2D;
set vertical offset depending on format classes of lhs & rhs arguments
SELECT MathBox.GetBox[$aliasLHS, boxes].FormatClass[] FROM
over => {
leftVertOffsetLHS ← [origin];
leftVertOffsetRel ← [center];
};
matrix => {
leftVertOffsetLHS ← [center];
leftVertOffsetRel ← [center];
};
ENDCASE => {
leftVertOffsetLHS ← [origin];
leftVertOffsetRel ← [origin];
};
SELECT MathBox.GetBox[$aliasRHS, boxes].FormatClass[] FROM
over => {
rightVertOffsetRHS ← [origin];
rightVertOffsetRel ← [center];
};
matrix => {
rightVertOffsetRHS ← [center];
rightVertOffsetRel ← [center];
};
ENDCASE => {
rightVertOffsetRHS ← [origin];
rightVertOffsetRel ← [origin];
};
alignments ← LIST[
[$aliasLeftSpace,
[$aliasRelation, [right], [left]],
[$aliasRelation, [origin], [origin]]],
[$aliasLHS,
[$aliasLeftSpace, [right], [left]],
[$aliasRelation, leftVertOffsetLHS, leftVertOffsetRel]],
[$aliasRightSpace,
[$aliasRelation, [left], [right]],
[$aliasRelation, [origin], [origin]]],
[$aliasRHS,
[$aliasRightSpace, [left], [right]],
[$aliasRelation, rightVertOffsetRHS, rightVertOffsetRel]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$aliasLHS, [origin]],
[$aliasRelation, [origin]]];
RETURN[tempBox, tempBoxes];
};
ComplexCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($complex $a $b)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ←
LIST[
[$a, [$plus, [right], [left, -medGap]],
[$plus, [origin], [origin]]],
[$leftParen, [$a, [right], [left, -medGap]],
[$plus, [origin], [origin]]],
[$b, [$plus, [left], [right, medGap]],
[$plus, [origin], [origin]]],
[$i, [$b, [left], [right, medGap]],
[$b, [origin], [origin]]],
[$rightParen, [$i, [left], [right, medGap]],
[$plus, [origin], [origin]]]
];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$a, [origin]], [$plus, [origin]]];
RETURN[tempBox, tempBoxes];
};
FactorialCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($bang $a $space)
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$space,
[$a, [left], [right]],
[$a, [origin], [origin]]],
[$bang,
[$space, [left], [right]],
[$a, [origin], [origin]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$a, [origin]], [$a, [origin]]];
RETURN[tempBox, tempBoxes];
};
ParenCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($paren $a) with symbols
$leftParen and $rightParen
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$leftParen,
[$a, [right], [left]],
[$a, [center], [center]]],
[$rightParen,
[$a, [left], [right]],
[$a, [center], [center]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$leftParen, [origin]],
[$self, [center, -0.25]]];
RETURN[tempBox, tempBoxes];
};
CurlyCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($curly $a) with symbols
$leftCurly and $rightCurly
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$leftCurly,
[$a, [right], [left]],
[$a, [center], [center]]],
[$rightCurly,
[$a, [left], [right]],
[$a, [center], [center]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$leftCurly, [origin]],
[$self, [center, -0.25]]];
RETURN[tempBox, tempBoxes];
};
SquareCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($square $a) with symbols
$leftSquare and $rightSquare
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$leftSquare,
[$a, [right], [left]],
[$a, [center], [center]]],
[$rightSquare,
[$a, [left], [right]],
[$a, [center], [center]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$leftSquare, [origin]],
[$self, [center, -0.25]]];
RETURN[tempBox, tempBoxes];
};
AbsCompRule: CompositionProc ~ {
effects: Composes layout for expr of form ($abs $a) with symbols
$absBar and $absBar
tempBox: BOX;
tempBoxes: LIST OF BOX;
alignments: LIST OF Alignment2D ← LIST[
[$leftAbs,
[$a, [right], [left]],
[$a, [center], [center]]],
[$rightAbs,
[$a, [left], [right]],
[$a, [center], [center]]]];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$leftAbs, [origin]],
[$self, [center, -0.25]]];
RETURN[tempBox, tempBoxes];
};
Class Constructors
MakeUnaryOpClass: PUBLIC PROC[class, op, arg: ATOM, operation: EXPR, description: ROPE, cvtAS, cvtReduce, cvtSMP, cvtOther: ROPENIL] RETURNS[CompoundClass] ~ {
effects: Creates and returns standard unary operation compound class named "class".
The alignment is "operation arg"; alignment is thru baselines.
Both op, arg are of fixed size "normal".
argArg: Argument ← MakeArgument[arg, LIST[$aliasA, $aliasHot], normal];
spaceSym: Symbol ← MakeSymbol[$Space, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$medium]];
unaryOpSym: Symbol ← MakeSymbol[op, LIST[$aliasUnaryOp], normal, operation];
RETURN[MakeCompoundClass[class, unaryOp, description, LIST[argArg], LIST[unaryOpSym, spaceSym], FixedSizeBoxRule, UnaryOpCompRule, cvtAS, cvtReduce, cvtSMP, cvtOther]];
};
MakeBinOpClass: PUBLIC PROC[class, op, a, b: ATOM, operation: EXPR,
description: ROPE, cvtAS, cvtReduce, cvtSMP, cvtOther: ROPENIL] RETURNS[CompoundClass] ~ {
effects: Creates and returns standard binary operation compound class named "class".
The alignment is "a operation b"; alignment is thru baselines.
All of a, b, op are of fixed size "normal".
aArg: Argument ← MakeArgument[a, LIST[$aliasA, $aliasHot], normal];
bArg: Argument ← MakeArgument[b, LIST[$aliasB], normal];
opSym: Symbol ← MakeSymbol[op, LIST[$aliasBinOp], normal, operation];
leftSpace: Symbol ← MakeSymbol[$leftThinSpace, LIST[$aliasLeftSpace], normal, MathConstructors.MakeSpace[$thin]];
rightSpace: Symbol ← MakeSymbol[$rightThinSpace, LIST[$aliasRightSpace], normal, MathConstructors.MakeSpace[$thin]];
RETURN[MakeCompoundClass[class, binaryOp, description, LIST[aArg, bArg], LIST[opSym, leftSpace, rightSpace], FixedSizeBoxRule, BinaryOpCompRule, cvtAS, cvtReduce, cvtSMP, cvtOther]];
};
MakeRelationClass: PUBLIC PROC[class, rel, lhs, rhs: ATOM, relation: EXPR,
description: ROPE, cvtAS, cvtReduce, cvtSMP, cvtOther: ROPENIL] RETURNS[CompoundClass] ~ {
effects: Creates and returns standard relation compound class named "class".
The alignment is "lhs relation rhs"; alignment is thru baselines.
All of lhs, rhs, rel are of fixed size "normal".
lhsArg: Argument ← MakeArgument[lhs, LIST[$aliasLHS, $aliasHot], normal];
rhsArg: Argument ← MakeArgument[rhs, LIST[$aliasRHS], normal];
relSym: Symbol ← MakeSymbol[rel, LIST[$aliasRelation], normal, relation];
leftSpace: Symbol ← MakeSymbol[$leftSpace, LIST[$aliasLeftSpace], normal, MathConstructors.MakeSpace[$thick]];
rightSpace: Symbol ← MakeSymbol[$rightSpace, LIST[$aliasRightSpace], normal, MathConstructors.MakeSpace[$thick]];
RETURN[MakeCompoundClass[class, relation, description, LIST[lhsArg, rhsArg], LIST[relSym, leftSpace, rightSpace], FixedSizeBoxRule, RelationCompRule, cvtAS, cvtReduce, cvtSMP, cvtOther]];
};
Signals & Errors
wrongBoxType: PUBLIC ERROR = CODE;
Define & Install Expression Classes
InstallSetClassesA: PROC [] ~ {
local declarations
differenceClass: CompoundClass;
differenceClass ← MakeBinOpClass[$difference, $minus, $subtrahend, $minuend, MathConstructors.MakePlainSym['-], "a - b", "$subtrahend - $minuend", "$subtrahend - $minuend", "Minus[$subtrahend, $minuend]"];
differenceClass ← MakeBinOpClass[$difference, $minus, $subtrahend, $minuend, MathConstructors.MakePlainSym['-], "a - b", "$subtrahend - $minuend", "difference($subtrahend, $minuend)", "Minus[$subtrahend, $minuend]"];
Register compound classes in user-friendly order
MathDB.InstallCompoundClass[differenceClass];
MathDB.AddOperator[differenceClass, $Set];
};
InstallSetClassesB: PROC [] ~ {
local declarations
eqFormulaClass, notEqFormulaClass, subsetClass, elementOfClass, unionClass, intersectClass: CompoundClass;
relations
eqFormulaClass ← MakeRelationClass[$eqFormula, $equals, $lhs, $rhs, MathConstructors.MakePlainSym['=], "a = b", "$lhs = $rhs", "equal($lhs, $rhs)", "Eq[$lhs, $rhs]"];
notEqFormulaClass ← MakeRelationClass[$notEqFormula, $equals, $lhs, $rhs, MathConstructors.MakeOverlaySym["=/"], "a # b", "$lhs # $rhs"];
subsetClass ← MakeRelationClass[$subset, $subset, $lhs, $rhs, MathConstructors.MakeBigMathSym['\133], "a subset b", "$lhs subset $rhs"];
elementOfClass ← MakeRelationClass[$elementOf, $elementOf, $lhs, $rhs, MathConstructors.MakeBigMathSym['\112], "a elementOf b", "$lhs elementOf $rhs"];
unionClass ← MakeRelationClass[$union, $union, $lhs, $rhs, MathConstructors.MakeBigMathSym['\127], "a union b", "$lhs union $rhs"];
intersectClass ← MakeRelationClass[$intersect, $intersect, $lhs, $rhs, MathConstructors.MakeBigMathSym['\126], "a intersect b", "$lhs intersect $rhs"];
MathDB.InstallCompoundClass[eqFormulaClass];
MathDB.AddOperator[eqFormulaClass, $Set];
MathDB.InstallCompoundClass[notEqFormulaClass];
MathDB.AddOperator[notEqFormulaClass, $Set];
MathDB.InstallCompoundClass[subsetClass];
MathDB.AddOperator[subsetClass, $Set];
MathDB.InstallCompoundClass[elementOfClass];
MathDB.AddOperator[elementOfClass, $Set];
MathDB.InstallCompoundClass[unionClass];
MathDB.AddOperator[unionClass, $Set];
MathDB.InstallCompoundClass[intersectClass];
MathDB.AddOperator[intersectClass, $Set];
};
Install Classes Defined in this Module
InstallSetClassesA[];
InstallSetClassesB[];
END.