MathExprClassesAnalysis.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;
MathExprClassesAnalysis: 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 x-extents
fbarBox ← MathBox.Scale[fbarBox, [scaleX, 1.0]];
topSpaceBox ← MathBox.Scale[topSpaceBox, [scaleX, 1.0]];
bottomSpaceBox ← MathBox.Scale[bottomSpaceBox, [scaleX, 1.0]];
RETURN[LIST[fbarBox, partialOfBox, partialWrtBox, differandBox, wrtBox, topSpaceBox, bottomSpaceBox]];
};
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]];
};
Composition Procs for Compound Expr Classes
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, [origin], [origin]]],
[$partialWrt,
[$fractionBar, [right], [center]],
[$bottomSpace, [top], [bottom]]],
[$wrt,
[$partialWrt, [left], [right]],
[$partialWrt, [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]]],
[$differand,
[$fractionBar, [right], [right, -0.05]],
[$topSpace, [bottom], [top]]],
[$partialOf,
[$differand, [right], [left]],
[$differand, [origin], [origin]]],
[$partialWrt,
[$fractionBar, [right], [center]],
[$bottomSpace, [top], [bottom]]],
[$wrt,
[$partialWrt, [left], [right]],
[$partialWrt, [origin], [origin]]]
];
[tempBox, tempBoxes] ←
MathRules.Compose[boxes, alignments, [$fractionBar, [origin]],
[$fractionBar, [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, [center, -0.4]]];
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];
};
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]];
};
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]];
};
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]];
};
Signals & Errors
wrongBoxType: PUBLIC ERROR = CODE;
Define & Install Expression Classes
InstallAnalysisClassesAA: PROC [] ~ {
local declarations
summationClass, integrationClass, indefIntClass, nRadicalClass, radicalClass, limitClass, dDxClass, partialDerivClass: CompoundClass;
lbArg, ubArg, summandArg, llimArg, ulimArg, integrandArg, wrtArg, nArg, radicandArg, ofArg, approachesArg, differandArg: Argument;
sigmaSym, integralSym, dxSym, lineSym, radRootSym, radLineSym, integralSpaceSym, limSym, limSpaceSym, radSpaceSym, dOfSym, partialOfSym, partialWrtSym: Symbol;
numerSpSym, denomSpSym: Symbol;
define info for "summation lowerbound upperbound summand"
lbArg ← MakeArgument[$lowerbound, NIL, script];
ubArg ← MakeArgument[$upperbound, NIL, script];
summandArg ← MakeArgument[$summand, LIST[$aliasHot], normal];
sigmaSym ← MakeSymbol[$sigma, LIST[$aliasOp], normal, MathConstructors.MakeBigMathSym['\172]];
define info for indefinite & definite integrals (normal & surface)
llimArg ← MakeArgument[$lowerlimit, NIL, script];
ulimArg ← MakeArgument[$upperlimit, NIL, script];
integrandArg ← MakeArgument[$integrand, LIST[$aliasHot], normal];
wrtArg ← MakeArgument[$wrt, NIL, normal];
integralSym ← MakeSymbol[$integral, LIST[$aliasOp], normal, MathConstructors.MakeBigMathSym['\165]];
dxSym ← MakeSymbol[$dx, NIL, normal, MathConstructors.MakeItalSym['d]];
integralSpaceSym ← MakeSymbol[$space, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$thick]];
define info for "dDx differandArg wrtArg"
denomSpSym ← MakeSymbol[$bottomSpace, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$medium]];
numerSpSym ← MakeSymbol[$topSpace, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$medium]];
lineSym ← MakeSymbol[$fractionBar, LIST[$aliasLine], normal, MathConstructors.MakeLine[]];
differandArg ← MakeArgument[$differand, LIST[$aliasHot], normal];
dOfSym ← MakeSymbol[$dOf, NIL, normal, MathConstructors.MakeItalSym['d]];
define info for "PartialDeriv differandArg wrtArg"
partialOfSym ← MakeSymbol[$partialOf, NIL, normal, MathConstructors.MakeBigMathSym['\272]];
partialWrtSym ← MakeSymbol[$partialWrt, NIL, normal, MathConstructors.MakeBigMathSym['\272]];
define info for "radical n radicand"
nArg ← MakeArgument[$n, LIST[$aliasB], script];
radicandArg ← MakeArgument[$radicand, LIST[$aliasA, $aliasHot], normal];
radRootSym ← MakeSymbol[$radRoot, NIL, normal, MathConstructors.MakeBigMathSym['\174]];
radLineSym← MakeSymbol[$radLine, LIST[$aliasLine], normal, MathConstructors.MakeLine[]];
radSpaceSym ← MakeSymbol[$space, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$medium]];
define info for limits
ofArg ← MakeArgument[$of, LIST[$aliasA, $aliasHot], normal];
approachesArg ← MakeArgument[$approaches, NIL, script];
limSpaceSym ← MakeSymbol[$space, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$limit]];
limSym ← MakeSymbol[$lim, NIL, script, MathConstructors.MakePlainRope["lim"]];
summationClass ← MakeCompoundClass[$summation, op, "summation", LIST[lbArg, ubArg, summandArg], LIST[sigmaSym], SummationBoxRule, SummationCompRule, "(summation $lowerbound $upperbound $summand)"];
integrationClass ← MakeCompoundClass[$integration, op, "def integration", LIST[llimArg, ulimArg, integrandArg, wrtArg], LIST[integralSym, dxSym, integralSpaceSym], DefiniteIntBoxRule, IntegrationCompRule, "(integral $lowerlimit $upperlimit $integrand $wrt)", "Int[$integrand, $wrt, $lowerlimit, $upperlimit]"];
indefIntClass ← MakeCompoundClass[$indefInt, op, "indef integration", LIST[integrandArg, wrtArg], LIST[integralSym, dxSym, integralSpaceSym], IndefiniteIntBoxRule, IndefiniteIntCompRule, "(indefIntegral $integrand $wrt)", "int($integrand, $wrt)", "Int[$integrand, $wrt]"];
dDxClass ← MakeCompoundClass[$dDx, over, "dF / dx", LIST[differandArg, wrtArg], LIST[lineSym, dOfSym, dxSym, numerSpSym, denomSpSym], dDxBoxRule, dDxCompRule, "d $differand / d $wrt", "df($differand, $wrt)", "Diff[$differand, $wrt]"];
partialDerivClass ← MakeCompoundClass[$partialDeriv, over, "partial Derivative", LIST[differandArg, wrtArg], LIST[lineSym, partialOfSym, partialWrtSym, numerSpSym, denomSpSym], PartialDerivBoxRule, PartialDerivCompRule, "partial $differand / partial $wrt", "df($differand, $wrt)", "Diff[$differand, $wrt]"];
nRadicalClass ← MakeCompoundClass[$nRadical, radical, "nth radical", LIST[nArg, radicandArg], LIST[radRootSym, radLineSym, radSpaceSym], NRadicalBoxRule, NRadicalCompRule, "(nthRoot $radicand $n)"];
radicalClass ← MakeCompoundClass[$radical, radical, "radical", LIST[radicandArg], LIST[radRootSym, radLineSym, radSpaceSym], RadicalBoxRule, RadicalCompRule, "(Root $radicand)"];
limitClass ← MakeCompoundClass[$limit, other, "limit", LIST[approachesArg, ofArg], LIST[limSpaceSym, limSym], FixedSizeBoxRule, LimitCompRule, "(limit $approaches $of)"];
Register compound classes in user-friendly order
MathDB.InstallCompoundClass[summationClass];
MathDB.AddOperator[summationClass, $Analysis];
MathDB.InstallCompoundClass[limitClass];
MathDB.AddOperator[limitClass, $Analysis];
MathDB.InstallCompoundClass[integrationClass];
MathDB.AddOperator[integrationClass, $Analysis];
MathDB.InstallCompoundClass[indefIntClass];
MathDB.AddOperator[indefIntClass, $Analysis];
MathDB.InstallCompoundClass[dDxClass];
MathDB.AddOperator[dDxClass, $Analysis];
MathDB.InstallCompoundClass[partialDerivClass];
MathDB.AddOperator[partialDerivClass, $Analysis];
MathDB.InstallCompoundClass[radicalClass];
MathDB.AddOperator[radicalClass, $Analysis];
MathDB.InstallCompoundClass[nRadicalClass];
MathDB.AddOperator[nRadicalClass, $Analysis];
};
InstallAnalysisClassesB: PROC [] ~ {
local declarations
approxEqFormulaClass, approachesClass: CompoundClass;
relations
approxEqFormulaClass ← MakeRelationClass[$approxEqFormula, $equals, $lhs, $rhs, MathConstructors.MakeBigMathSym['\167], "a approx= b", "$lhs approx= $rhs"];
approachesClass ← MakeRelationClass[$approachesFormula, $approaches, $lhs, $rhs, MathConstructors.MakePlainSym['\256], "a -> b", "$lhs -> $rhs"];
MathDB.InstallCompoundClass[approachesClass];
MathDB.AddOperator[approachesClass, $Analysis];
MathDB.InstallCompoundClass[approxEqFormulaClass];
MathDB.AddOperator[approxEqFormulaClass, $Analysis];
};
Install Classes Defined in this Module
InstallAnalysisClassesAA[];
InstallAnalysisClassesB[];
END.