<> <> DIRECTORY MathExpr, MathRules, MathDB, MathTypes, MathBox, ImagerFont, ImagerTransformation, Imager, Rope USING [ROPE, Fetch, Length, Substr, Equal, FromChar], Vector USING [VEC], Convert USING [RopeFromReal, AtomFromRope, RopeFromAtom], MathConstructors; MathConstructorsImpl: CEDAR PROGRAM IMPORTS MathBox, MathRules, ImagerFont, Imager, ImagerTransformation, MathExpr, MathDB, Convert, Rope EXPORTS MathConstructors ~ BEGIN <> EXPR: TYPE ~ MathExpr.EXPR; BOX: TYPE ~ MathBox.BOX; ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector.VEC; AtomBoxProc: TYPE ~ MathRules.AtomBoxProc; AtomPaintProc: TYPE ~ MathRules.AtomPaintProc; AtomToASRopeProc: TYPE ~ MathRules.AtomToASRopeProc; 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; AtomClass: TYPE ~ MathExpr.AtomClass; AtomFlavor: TYPE ~ MathExpr.AtomFlavor; CompoundClass: TYPE ~ MathExpr.CompoundClass; FormatClass: TYPE ~ MathTypes.FormatClass; MatrixClass: TYPE ~ MathExpr.MatrixClass; Style: TYPE ~ MathTypes.Style; <> 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; MakeAtomClass: PROC[name: ATOM, formatClass: FormatClass, flavor: AtomFlavor, style: Style, boxRule: AtomBoxProc, paintRule: AtomPaintProc, cvtASRule: AtomToASRopeProc _ NIL] RETURNS[AtomClass] ~ MathExpr.MakeAtomClass; MakeCompoundClass: PROC[name: ATOM, formatClass: FormatClass, description: ROPE, args: LIST OF Argument, syms: LIST OF Symbol, boxRule: CompoundBoxProc, compBox: CompositionProc, cvtAS: ROPE _ NIL] RETURNS[CompoundClass] ~ MathExpr.MakeCompoundClass; <> smallGap: REAL = 0.05; medGap: REAL = 0.10; bigGap: REAL = 0.25; <> <<>> <<>> <> <<>> GreekVarToASRope: AtomToASRopeProc ~ { IF value.Length[] < 1 THEN RETURN["unknown"] ELSE RETURN[CharToGreekName[value.Fetch[0]]]; }; PlaceHolderToASRope: AtomToASRopeProc ~ { RETURN["?"]; }; InfinityToASRope: AtomToASRopeProc ~ { RETURN["infinity"]; }; <> PaintChar: AtomPaintProc ~ { <> <> IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType ELSE { font: ImagerFont.Font _ ImagerFont.Find[style.font]; extents: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, value]; xFactor: REAL _ absBox.Width[] / (extents.leftExtent + extents.rightExtent); yFactor: REAL _ absBox.Height[] / (extents.descent + extents.ascent); Imager.SetXY[context, absBox.Offset[]]; Imager.SetFont[context, ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]]; Imager.ShowRope[context, value]; }; }; PaintOverlay: AtomPaintProc ~ { <> << This is useful for things like negated symbols (/ slashed through)... >> <<>> <> IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType ELSE { font: ImagerFont.Font _ ImagerFont.Find[style.font]; extents: ImagerFont.Extents _ OverlayBox[value, style]; xFactor: REAL _ absBox.Width[] / (extents.rightExtent + extents.leftExtent); yFactor: REAL _ absBox.Height[] / (extents.ascent + extents.descent); <> font _ ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]; <> FOR i:INT IN [0..value.Length[]-1] DO char: ROPE _ value.Substr[i, 1]; box: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, char]; position: VEC _ [MathRules.AlignHorizontal[box, [center], absBox, [center]], MathRules.AlignVertical[box, [center], absBox, [center]]]; Imager.SetXY[context, position]; Imager.SetFont[context, font]; Imager.ShowRope[context, char]; ENDLOOP; }; }; PaintRope: AtomPaintProc ~ { <> <> IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType ELSE { font: ImagerFont.Font _ ImagerFont.Find[style.font]; extents: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, value]; xFactor: REAL _ absBox.Width[] / (extents.rightExtent + extents.leftExtent); yFactor: REAL _ absBox.Height[] / (extents.ascent + extents.descent); Imager.SetXY[context, absBox.Offset[]]; Imager.SetFont[context, ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]]; Imager.ShowRope[context, value]; }; }; PaintLine: AtomPaintProc ~ { <> <> r: Imager.Rectangle _ [x: absBox.Offset[].x + absBox.Extents[].leftExtent, y: absBox.Offset[].y + absBox.Extents[].descent, w: absBox.Width[], h: absBox.Height[]]; Imager.MaskRectangle[context, r]; }; PaintSpace: AtomPaintProc ~ { <> RETURN; }; <> LineBox: AtomBoxProc ~ { <> << Note that this is always a dummy value>> <> RETURN[[leftExtent: 0.0, rightExtent: 1.0, descent: 0.0, ascent: 0.03]]; }; CharBox: AtomBoxProc ~ { <> font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[style.font], style.scale]; RETURN[ImagerFont.RopeBoundingBox[font, value]]; }; OverlayBox: AtomBoxProc ~ { <> font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[style.font], style.scale]; farLeft, farRight, farUp, farDown: REAL _ 0.0; -- extreme edges of overlayed extents FOR i:INT IN [0..value.Length[]-1] DO box: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, value.Substr[i, 1]]; farLeft _ MAX[farLeft, box.leftExtent]; farRight _ MAX[farRight, box.rightExtent]; farUp _ MAX[farUp, box.ascent]; farDown _ MAX[farDown, box.descent]; ENDLOOP; RETURN[[leftExtent: farLeft, rightExtent: farRight, descent: farDown, ascent: farUp]]; }; RopeBox: AtomBoxProc ~ { <> font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[style.font], style.scale]; RETURN[ImagerFont.RopeBoundingBox[font, value]]; }; SpaceBox: AtomBoxProc ~ { <> size: ATOM _ Convert.AtomFromRope[value]; RETURN[ SELECT size FROM $null => [leftExtent: 0.0, rightExtent: 0.001, descent: 0.0, ascent: 0.001], $thin => [leftExtent: 0.0, rightExtent: 0.05, ascent: 0.05, descent: 0.0], $medium => [leftExtent: 0.0, rightExtent: 0.12, ascent: 0.12, descent: 0.0], $thick => [leftExtent: 0.0, rightExtent: 0.25, ascent: 0.25, descent: 0.0], $veryThick => [leftExtent: 0.0, rightExtent: 0.4, ascent: 0.4, descent: 0.0], $matrix => [leftExtent: 0.0, rightExtent: 0.9, ascent: 0.65, descent: 0.0], $limit => [leftExtent: 0.0, rightExtent: 0.25, ascent: 0.12, descent: 0.0], $product => [leftExtent: 0.0, rightExtent: 0.001, ascent: 0.21, descent: -0.19] <> ENDCASE => [leftExtent: 0.0, rightExtent: 0.05, ascent: 0.05, descent: 0.0] ]; }; <> <> FixedSizeBoxRule: CompoundBoxProc ~ { <> RETURN[boxes]; }; FractionBoxRule: CompoundBoxProc ~ { <> <> 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]; <> scaleX: REAL _ 1.1 * MAX[numBox.Width[], denomBox.Width[]] / fbarBox.Width[]; <> fbarBox _ MathBox.Scale[fbarBox, [scaleX, 1.0]]; RETURN[LIST[fbarBox, numBox, denomBox, topSpaceBox, bottomSpaceBox]]; }; ParenBoxRule: CompoundBoxProc ~ { <> <<>> leftParenBox: BOX _ MathBox.GetBox[$leftParen, boxes]; rightParenBox: BOX _ MathBox.GetBox[$rightParen, boxes]; aBox: BOX _ MathBox.GetBox[$a, boxes]; <> scaleFactor: REAL _ MAX[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]]; }; NRadicalBoxRule: CompoundBoxProc ~ { <> <> 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]; <> <> rootScale: REAL _ ((2 * spaceBox.Height[]) + radicandBox.Height[]) / radRootBox.Height[]; lineScale: VEC _ [radicandBox.Width[]/radLineBox.Width[], 1.0]; <> radRootBox _ MathBox.Scale[radRootBox, [rootScale, rootScale]]; radLineBox _ MathBox.Scale[radLineBox, lineScale]; RETURN[LIST[radRootBox, radLineBox, nBox, radicandBox, spaceBox]]; }; RadicalBoxRule: CompoundBoxProc ~ { <> <> radRootBox: BOX _ MathBox.GetBox[$radRoot, boxes]; radLineBox: BOX _ MathBox.GetBox[$radLine, boxes]; spaceBox: BOX _ MathBox.GetBox[$space, boxes]; radicandBox: BOX _ MathBox.GetBox[$radicand, boxes]; <> <> rootScale: REAL _ ((2 * spaceBox.Height[]) + radicandBox.Height[]) / radRootBox.Height[]; lineScale: VEC _ [radicandBox.Width[]/radLineBox.Width[], 1.0]; <> radRootBox _ MathBox.Scale[radRootBox, [rootScale, rootScale]]; radLineBox _ MathBox.Scale[radLineBox, lineScale]; RETURN[LIST[radRootBox, radLineBox, radicandBox, spaceBox]]; }; FunctionBoxRule: CompoundBoxProc ~ { <> <> 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]; <> <> scaleFactor: REAL _ MAX[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]]; }; <> PowCompRule: CompositionProc ~ { <> 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 { <> horizOffsetBase _ [origin, hintBox.Offset[].x + hintBox.Extents[].rightExtent]; IF (hintBox.Height[] * baseBox.Height[]) > exponentBox.Height[] THEN { vertOffsetExponent _ [bottom, 0.2]; <> 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 { <> 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 ~ { <> 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]]]; <> tempBox _ tempBox.ChangeSuperHint[MathBox.GetBox[$base, tempBoxes]]; RETURN[tempBox, tempBoxes]; }; FractionCompRule: 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]]], [$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]; }; ListCompRule: CompositionProc ~ { <> 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 ~ { <> 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]; }; LimitCompRule: CompositionProc ~ { <> 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 ~ { <> << $summand)>> tempBox: BOX; tempBoxes: LIST OF BOX; alignments: LIST OF Alignment2D _ NIL; vertSigmaOffset, vertSummandOffset: Offset; SELECT MathBox.GetBox[$summand, boxes].FormatClass[] FROM over => { 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 ~ { <> 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 ~ { <> 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 ~ { <> << $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 => { 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]]], [$wrt, [$dx, [left], [right]], [$dx, [origin], [origin]]]]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$lowerlimit, [origin]], [$integral, [center, -0.2]]]; RETURN[tempBox, tempBoxes]; }; IndefiniteIntCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; vertIntegralOffset, vertIntegrandOffset: Offset; alignments: LIST OF Alignment2D _ NIL; SELECT MathBox.GetBox[$integrand, boxes].FormatClass[] FROM over => { 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]]], [$wrt, [$dx, [left], [right]], [$dx, [origin], [origin]]]]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$integral, [origin]], [$integral, [center, -0.2]]]; RETURN[tempBox, tempBoxes]; }; UnaryOpCompRule: CompositionProc ~ { <> 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 ~ { <> << symbols $aliasLeftSpace & $aliasRightSpace.>> <<>> tempBox: BOX; tempBoxes: LIST OF BOX; leftVertOffsetA, leftVertOffsetOp, rightVertOffsetB, rightVertOffsetOp: Offset; alignments: LIST OF Alignment2D; <> 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 ~ { <> << symbols $aliasLeftSpace & $aliasRightSpace.>> <<>> tempBox: BOX; tempBoxes: LIST OF BOX; leftVertOffsetLHS, leftVertOffsetRel, rightVertOffsetRHS, rightVertOffsetRel: Offset; alignments: LIST OF Alignment2D; <> 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 ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; alignments: LIST OF Alignment2D _ LIST[[$a, [$plus, [right], [left, -smallGap]], [$plus, [origin], [origin]]], [$b, [$plus, [left], [right, smallGap]], [$plus, [origin], [origin]]], [$i, [$b, [left], [right, smallGap]], [$b, [origin], [origin]]]]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$a, [origin]], [$plus, [origin]]]; RETURN[tempBox, tempBoxes]; }; FactorialCompRule: CompositionProc ~ { <> 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 ~ { <> << $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]; }; <> <<>> MakeBinOpClass: PUBLIC PROC[class, op, a, b: ATOM, operation: EXPR, description: ROPE, cvtAS: ROPE] RETURNS[CompoundClass] ~ { <> << 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, MakeSpace[$thin]]; rightSpace: Symbol _ MakeSymbol[$rightThinSpace, LIST[$aliasRightSpace], normal, 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: ROPE] RETURNS[CompoundClass] ~ { <> << 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, MakeSpace[$thick]]; rightSpace: Symbol _ MakeSymbol[$rightSpace, LIST[$aliasRightSpace], normal, MakeSpace[$thick]]; RETURN[MakeCompoundClass[class, relation, description, LIST[lhsArg, rhsArg], LIST[relSym, leftSpace, rightSpace], FixedSizeBoxRule, RelationCompRule, cvtAS]]; }; MakeUnaryOpClass: PUBLIC PROC[class, op, arg: ATOM, operation: EXPR, description: ROPE, cvtAS: ROPE] RETURNS[CompoundClass] ~ { <> << 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, MakeSpace[$medium]]; unaryOpSym: Symbol _ MakeSymbol[op, LIST[$aliasUnaryOp], normal, operation]; RETURN[MakeCompoundClass[class, unaryOp, description, LIST[argArg], LIST[unaryOpSym, spaceSym], FixedSizeBoxRule, UnaryOpCompRule, cvtAS]]; }; <> <> MakePlainSym: PROC[c: CHAR] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$plainSym, Rope.FromChar[c]]]; }; MakePlainRope: PROC[r: ROPE] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$plainSym, r]]; }; MakeOverlaySym: PROC[r: ROPE] RETURNS[EXPR] ~ { <> RETURN[MathExpr.MakeAtomicExpr[$overlaySym, r]]; }; MakeBigMathSym: PROC[c: CHAR] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$bigMathSym, Rope.FromChar[c]]]; }; MakeSmallMathSym: PROC[c: CHAR] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$smallMathSym, Rope.FromChar[c]]]; }; MakeItalSym: PROC[c: CHAR] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$italicSym, Rope.FromChar[c]]]; }; MakeMathItalSym: PROC[c: CHAR] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$mathItalicSym, Rope.FromChar[c]]]; }; MakeLine: PROC[] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$line, "LINE"]]; }; MakeSpace: PROC[size: ATOM] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$space, Convert.RopeFromAtom[size, FALSE]]]; }; MakePlaceHolder: PUBLIC PROC[] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeAtomicExpr[$placeholder, "\056\057"]]; }; MakeInfinity: PUBLIC PROC[] RETURNS[EXPR] ~ { <> RETURN[MathExpr.MakeAtomicExpr[$infinity, "\061"]]; }; MakeInt: PUBLIC PROC[n: ROPE] RETURNS[EXPR] ~ { <> << 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; <> 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] ~ { <> RETURN[MathExpr.MakeAtomicExpr[$real, Convert.RopeFromReal[r]]]; }; MakeVariable: PUBLIC PROC[var: ROPE] RETURNS[EXPR] ~ { <> << SIGNALS badFormat if n is not a legal variable (e.g. invalid chars).>> <<>> IF var.Length[] = 0 THEN ERROR badFormat; <<>> <> 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: PROC[name: ROPE] RETURNS[CHAR] ~ { <> << SIGNALS badFormat if names is unrecognized>> RETURN[ SELECT TRUE FROM Rope.Equal["alpha", name, FALSE] => '\013, Rope.Equal["beta", name, FALSE] => '\014, Rope.Equal["gamma", name, FALSE] => '\015, Rope.Equal["delta", name, FALSE] => '\016, Rope.Equal["epsilon", name, FALSE] => '\017, Rope.Equal["zeta", name, FALSE] => '\020, Rope.Equal["eta", name, FALSE] => '\021, Rope.Equal["theta", name, FALSE] => '\022, Rope.Equal["iota", name, FALSE] => '\023, Rope.Equal["kappa", name, FALSE] => '\024, Rope.Equal["lambda", name, FALSE] => '\025, Rope.Equal["mu", name, FALSE] => '\026, Rope.Equal["nu", name, FALSE] => '\027, Rope.Equal["xi", name, FALSE] => '\030, Rope.Equal["pi", name, FALSE] => '\031, Rope.Equal["rho", name, FALSE] => '\032, Rope.Equal["sigma", name, FALSE] => '\033, Rope.Equal["tau", name, FALSE] => '\034, Rope.Equal["upsilon", name, FALSE] => '\035, Rope.Equal["phi", name, FALSE] => '\036, Rope.Equal["chi", name, FALSE] => '\037, Rope.Equal["psi", name, FALSE] => '\040, Rope.Equal["omega", name, FALSE] => '\041, ENDCASE => ERROR badFormat -- name unrecognized as a greek letter ]; }; CharToGreekName: PROC[c: CHAR] RETURNS[ROPE] ~ { <> << If no such association exists, returns "unknown".>> RETURN[ SELECT c FROM '\013 => "alpha", '\014 => "beta", '\015 => "gamma", '\016 => "delta", '\017 => "epsilon", '\020 => "zeta", '\021 => "eta", '\022 => "theta", '\023 => "iota", '\024 => "kappa", '\025 => "lambda", '\026 => "mu", '\027 => "nu", '\030 => "xi", '\031 => "pi", '\032 => "rho", '\033 => "sigma", '\034 => "tau", '\035 => "upsilon", '\036 => "phi", '\037 => "chi", '\040 => "psi", '\041 => "omega", ENDCASE => "unknown" ]; }; MakeGreekVar: PUBLIC PROC[name: ROPE] RETURNS[EXPR] ~ { <> << lowercase greek letter associated with name (e.g. "gamma", "lambda").>> << SIGNALS badFormat if name does not name a greek letter.>> <<>> greekRope: ROPE _ Rope.FromChar[GreekNameToChar[name ! badFormat => {ERROR badFormat}]]; RETURN[MathExpr.MakeAtomicExpr[$greekVar, greekRope]]; }; <> 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]]]]; }; <> <<>> MakeMatrix: PUBLIC PROC[nRows, nCols: NAT, rows: LIST OF LIST OF EXPR] RETURNS[EXPR] ~ { <> << SIGNALS badFormat if dimensions given don't exactly match dimension(rows).>> <> elements: 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 colCount _ colCount + 1; elements _ CONS[[MathRules.AtomFromRowCol[rowCount, colCount], elts.first], elements]; 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]]; }; MakeVector: PUBLIC PROC[dimension: NAT, elements: LIST OF EXPR, row: BOOL] RETURNS[EXPR] ~ { <> << SIGNALS badFormat if dimension doesn't exactly match dimension(elements).>> <> elts: 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; elts _ CONS[[MathRules.AtomFromRowCol[rowCount, colCount], l.first], elts]; ENDLOOP; <> IF row THEN { IF colCount # dimension THEN ERROR badFormat; -- wrong # elements } ELSE { IF rowCount # dimension THEN ERROR badFormat; -- wrong # elements }; RETURN[MathExpr.MakeMatrixExpr[$vector, rowCount, colCount, elts]]; }; <> <<>> 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]]]]; }; <> 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]]]]; }; <> MakeRadical: PUBLIC PROC[radicand, n: EXPR] RETURNS[EXPR] ~ { RETURN[MathExpr.MakeCompoundExpr[$nRadical, LIST[[$radicand, radicand], [$n, n]]]]; }; <> 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]]]]; }; <> <<>> 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]]]]; }; <> wrongAtomValueType: PUBLIC ERROR = CODE; wrongBoxType: PUBLIC ERROR = CODE; badFormat: PUBLIC ERROR = CODE; <> DefineClasses: PROC [] ~ { <> cmr10, cmti10, cmmi10, cmex10, cmsy10: Style; integerClass, realClass, variableClass, plainSymClass, overlaySymClass, smallMathSymClass, bigMathSymClass, italSymClass, mathItalSymClass, lineClass, placeholderClass, spaceClass, greekVarClass, infinityClass: AtomClass; sumClass, summationClass, fractionClass, integrationClass, indefIntClass, differenceClass, powClass, eqFormulaClass, approxEqFormulaClass, notEqFormulaClass, ltFormulaClass, leFormulaClass, geFormulaClass, gtFormulaClass, nRadicalClass, radicalClass, complexClass, productClass, orClass, notClass, negationClass, andClass, parenClass, subscriptClass, listClass, functionClass, altFunctionClass, limitClass, factorialClass, approachesClass: CompoundClass; matrixClass, vectorClass: MatrixClass; lbArg, ubArg, summandArg, llimArg, ulimArg, integrandArg, wrtArg, baseArg, exponentArg, numeratorArg, denominatorArg, nArg, radicandArg, realPartArg, imaginaryPartArg, aParenArg, subscriptArg, carArg, cdrArg, fArg, argsArg, ofArg, approachesArg, factorialArg: Argument; plusSym, sigmaSym, integralSym, dxSym, lineSym, radRootSym, radLineSym, iSym, leftParenSym, rightParenSym, numerSpSym, denomSpSym, integralSpaceSym, commaSym, listSpSym, funSpaceSym, funLParenSym, funRParenSym, altFunLP, altFunRP, limSym, factorialSym, factorialSpSym, limSpaceSym, radSpaceSym: Symbol; <> MathDB.ResetAtomClasses[]; MathDB.ResetCompoundClasses[]; MathDB.ResetMatrixClasses[]; <<>> <> cmr10 _ [font: "xerox/pressfonts/cmr60"]; -- standard times roman (1 unit high) cmti10 _ [font: "xerox/pressfonts/cmti60"]; -- italic (1 unit high) cmex10 _ [font: "xerox/pressfonts/cmex60"]; -- math extentsion font (1 unit high) cmmi10 _ [font: "xerox/pressfonts/cmmi60"]; -- math italic font (1 unit high) cmsy10 _ [font: "xerox/pressfonts/cmsy60"]; -- math symbols font (1 unit high) <> integerClass _ MakeAtomClass[$integer, atom, argument, cmr10, RopeBox, PaintRope]; realClass _ MakeAtomClass[$real, atom, argument, cmr10, RopeBox, PaintRope]; variableClass _ MakeAtomClass[$variable, atom, argument, cmti10, RopeBox, PaintRope]; greekVarClass _ MakeAtomClass[$greekVar, atom, argument, cmmi10, CharBox, PaintChar, GreekVarToASRope]; plainSymClass _ MakeAtomClass[$plainSym, atom, symbol, cmr10, RopeBox, PaintRope]; overlaySymClass _ MakeAtomClass[$overlaySym, atom, symbol, cmr10, OverlayBox, PaintOverlay]; bigMathSymClass _ MakeAtomClass[$bigMathSym, atom, symbol, cmex10, CharBox, PaintChar]; smallMathSymClass _ MakeAtomClass[$smallMathSym, atom, symbol, cmsy10, CharBox, PaintChar]; mathItalSymClass _ MakeAtomClass[$mathItalicSym, atom, symbol, cmmi10, CharBox, PaintChar]; italSymClass _ MakeAtomClass[$italicSym, atom, symbol, cmti10, CharBox, PaintChar]; lineClass _ MakeAtomClass[$line, atom, symbol, cmr10, LineBox, PaintLine]; placeholderClass _ MakeAtomClass[$placeholder, atom, placeholder, cmmi10, RopeBox, PaintRope, PlaceHolderToASRope]; spaceClass _ MakeAtomClass[$space, atom, symbol, cmr10, SpaceBox, PaintSpace]; infinityClass _ MakeAtomClass[$infinity, atom, argument, cmsy10, CharBox, PaintChar, InfinityToASRope]; <> MathDB.InstallAtomClass[integerClass]; MathDB.InstallAtomClass[realClass]; MathDB.InstallAtomClass[variableClass]; MathDB.InstallAtomClass[greekVarClass]; MathDB.InstallAtomClass[plainSymClass]; MathDB.InstallAtomClass[overlaySymClass]; MathDB.InstallAtomClass[italSymClass]; MathDB.InstallAtomClass[smallMathSymClass]; MathDB.InstallAtomClass[bigMathSymClass]; MathDB.InstallAtomClass[mathItalSymClass]; MathDB.InstallAtomClass[lineClass]; MathDB.InstallAtomClass[placeholderClass]; MathDB.InstallAtomClass[spaceClass]; MathDB.InstallAtomClass[infinityClass]; <> realPartArg _ MakeArgument[$a, LIST[$aliasA, $aliasHot], normal]; imaginaryPartArg _ MakeArgument[$b, LIST[$aliasB], normal]; iSym _ MakeSymbol[$i, NIL, normal, MakeItalSym['i]]; plusSym _ MakeSymbol[$plus, LIST[$aliasBinOp], normal, MakePlainSym['+]]; <> lbArg _ MakeArgument[$lowerbound, NIL, script]; ubArg _ MakeArgument[$upperbound, NIL, script]; summandArg _ MakeArgument[$summand, LIST[$aliasHot], normal]; sigmaSym _ MakeSymbol[$sigma, LIST[$aliasOp], normal, MakeBigMathSym['\130]]; <> 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, MakeBigMathSym['\132]]; dxSym _ MakeSymbol[$dx, NIL, normal, MakeItalSym['d]]; integralSpaceSym _ MakeSymbol[$space, LIST[$aliasSpace], normal, MakeSpace[$thick]]; <> baseArg _ MakeArgument[$base, LIST[$aliasA, $aliasHot], normal]; exponentArg _ MakeArgument[$exponent, LIST[$aliasB], script]; subscriptArg _ MakeArgument[$subscript, LIST[$aliasB], script]; <> numeratorArg _ MakeArgument[$numerator, LIST[$aliasA, $aliasHot], normal]; denominatorArg _ MakeArgument[$denominator, LIST[$aliasB], normal]; denomSpSym _ MakeSymbol[$bottomSpace, LIST[$aliasSpace], normal, MakeSpace[$thin]]; numerSpSym _ MakeSymbol[$topSpace, LIST[$aliasSpace], normal, MakeSpace[$thin]]; lineSym _ MakeSymbol[$fractionBar, LIST[$aliasLine], normal, MakeLine[]]; <> nArg _ MakeArgument[$n, LIST[$aliasB], script]; radicandArg _ MakeArgument[$radicand, LIST[$aliasA, $aliasHot], normal]; radRootSym _ MakeSymbol[$radRoot, NIL, normal, MakeBigMathSym['\162]]; radLineSym_ MakeSymbol[$radLine, LIST[$aliasLine], normal, MakeLine[]]; radSpaceSym _ MakeSymbol[$space, LIST[$aliasSpace], normal, MakeSpace[$medium]]; <> aParenArg _ MakeArgument[$a, LIST[$aliasA, $aliasHot], normal]; leftParenSym _ MakeSymbol[$leftParen, NIL, normal, MakeBigMathSym['\040]]; rightParenSym _ MakeSymbol[$rightParen, NIL, normal, MakeBigMathSym['\041]]; <> carArg _ MakeArgument[$car, LIST[$aliasA, $aliasHot], normal]; cdrArg _ MakeArgument[$cdr, LIST[$aliasB], normal]; commaSym _ MakeSymbol[$comma, NIL, normal, MakeItalSym[',]]; listSpSym _ MakeSymbol[$space, LIST[$aliasSpace], normal, MakeSpace[$thick]]; <> fArg _ MakeArgument[$f, LIST[$aliasA, $aliasHot], normal]; argsArg _ MakeArgument[$args, LIST[$aliasB], normal]; funSpaceSym _ MakeSymbol[$space, LIST[$aliasSpace], normal, MakeSpace[$medium]]; funLParenSym _ MakeSymbol[$leftParen, NIL, normal, MakePlainSym['\050]]; funRParenSym _ MakeSymbol[$rightParen, NIL, normal, MakePlainSym['\051]]; altFunLP _ MakeSymbol[$leftParen, NIL, normal, MakeSpace[$null]]; altFunRP _ MakeSymbol[$rightParen, NIL, normal, MakeSpace[$null]]; <> ofArg _ MakeArgument[$of, LIST[$aliasA, $aliasHot], normal]; approachesArg _ MakeArgument[$approaches, NIL, script]; limSpaceSym _ MakeSymbol[$space, LIST[$aliasSpace], normal, MakeSpace[$limit]]; limSym _ MakeSymbol[$lim, NIL, script, MakePlainRope["lim"]]; <> factorialArg _ MakeArgument[$a, LIST[$aliasA, $aliasHot], normal]; factorialSym _ MakeSymbol[$bang, NIL, normal, MakePlainSym['!]]; factorialSpSym _ MakeSymbol[$space, LIST[$aliasSpace], normal, MakeSpace[$thin]]; <> <<>> <> sumClass _ MakeBinOpClass[$sum, $plus, $addend, $augend, MakePlainSym['+], "a + b", "$addend + $augend"]; differenceClass _ MakeBinOpClass[$difference, $minus, $subtrahend, $minuend, MakePlainSym['\173], "a - b", "$subtrahend - $minuend"]; productClass _ MakeBinOpClass[$product, $times, $multiplier, $multiplicand, MakeSpace[$product], "a * b", "$multiplier * $multiplicand"]; andClass _ MakeBinOpClass[$and, $andOp, $a, $b, MakeSmallMathSym['\136], "a AND b", "$a & $b"]; orClass _ MakeBinOpClass[$or, $orOp, $a, $b, MakeSmallMathSym['\137], "a OR b", "$a | $b"]; <> negationClass _ MakeUnaryOpClass[$negation, $minus, $a, MakePlainSym['-], "-a", "-$a"]; notClass _ MakeUnaryOpClass[$not, $notOp, $a, MakeSmallMathSym['\072], "~a", "~ $a"]; <> eqFormulaClass _ MakeRelationClass[$eqFormula, $equals, $lhs, $rhs, MakePlainSym['=], "lhs = rhs", "$lhs = $rhs"]; notEqFormulaClass _ MakeRelationClass[$notEqFormula, $equals, $lhs, $rhs, MakeOverlaySym["=/"], "lhs # rhs", "$lhs # $rhs"]; ltFormulaClass _ MakeRelationClass[$ltFormula, $lt, $lhs, $rhs, MakeMathItalSym['<], "lhs < rhs", "$lhs < $rhs"]; gtFormulaClass _ MakeRelationClass[$gtFormula, $gt, $lhs, $rhs, MakeMathItalSym['>], "lhs > rhs", "$lhs > $rhs"]; leFormulaClass _ MakeRelationClass[$leFormula, $le, $lhs, $rhs, MakeSmallMathSym['\024], "lhs <= rhs", "$lhs <= $rhs"]; geFormulaClass _ MakeRelationClass[$geFormula, $ge, $lhs, $rhs, MakeSmallMathSym['\025], "lhs >= rhs", "$lhs >= $rhs"]; approxEqFormulaClass _ MakeRelationClass[$approxEqFormula, $equals, $lhs, $rhs, MakeSmallMathSym['\031], "lhs approx= rhs", "$lhs approx= $rhs"]; approachesClass _ MakeRelationClass[$approachesFormula, $approaches, $lhs, $rhs, MakeSmallMathSym['\041], "lhs -> rhs", "$lhs -> $rhs"]; <> listClass _ MakeCompoundClass[$list, other, "a, b", LIST[carArg, cdrArg], LIST[commaSym, listSpSym], FixedSizeBoxRule, ListCompRule, "($car $cdr)"]; functionClass _ MakeCompoundClass[$function, other, "function(args)", LIST[fArg, argsArg], LIST[funLParenSym, funRParenSym, funSpaceSym], FunctionBoxRule, FunctionCompRule, "(function $f $args)"]; altFunctionClass _ MakeCompoundClass[$altFunction, other, "function args", LIST[fArg, argsArg], LIST[altFunLP, altFunRP, funSpaceSym], FixedSizeBoxRule, FunctionCompRule, "(function $f $args)"]; complexClass _ MakeCompoundClass[$complex, other, "a + bi", LIST[realPartArg, imaginaryPartArg], LIST[iSym, plusSym], FixedSizeBoxRule, ComplexCompRule, "($a + $bi)"]; summationClass _ MakeCompoundClass[$summation, op, "summation", LIST[lbArg, ubArg, summandArg], LIST[sigmaSym], FixedSizeBoxRule, SummationCompRule, "(summation $lowerbound $upperbound $summand)"]; integrationClass _ MakeCompoundClass[$integration, op, "def integration", LIST[llimArg, ulimArg, integrandArg, wrtArg], LIST[integralSym, dxSym, integralSpaceSym], FixedSizeBoxRule, IntegrationCompRule, "(integral $lowerlimit $upperlimit $integrand $wrt)"]; indefIntClass _ MakeCompoundClass[$indefInt, op, "indef integration", LIST[integrandArg, wrtArg], LIST[integralSym, dxSym, integralSpaceSym], FixedSizeBoxRule, IndefiniteIntCompRule, "(indefIntegral $integrand $wrt)"]; powClass _ MakeCompoundClass[$pow, other, "a^b", LIST[baseArg, exponentArg], NIL, FixedSizeBoxRule, PowCompRule, "$base^$exponent"]; subscriptClass _ MakeCompoundClass[$subscript, other, "a sub b", LIST[baseArg, subscriptArg], NIL, FixedSizeBoxRule, SubscriptCompRule, "$baseSub$subscript"]; parenClass _ MakeCompoundClass[$paren, paren, "( a )", LIST[aParenArg], LIST[leftParenSym, rightParenSym], ParenBoxRule, ParenCompRule, "( $a )"]; fractionClass _ MakeCompoundClass[$fraction, over, "a / b", LIST[numeratorArg, denominatorArg], LIST[lineSym, numerSpSym, denomSpSym], FractionBoxRule, FractionCompRule, "$numerator / $denominator"]; 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)"]; factorialClass _ MakeCompoundClass[$factorial, other, "a!", LIST[factorialArg], LIST[factorialSym, factorialSpSym], FixedSizeBoxRule, FactorialCompRule, "$a!"]; <> <<>> <> MathDB.InstallCompoundClass[sumClass]; MathDB.InstallCompoundClass[differenceClass]; MathDB.InstallCompoundClass[andClass]; MathDB.InstallCompoundClass[orClass]; <> MathDB.InstallCompoundClass[notClass]; MathDB.InstallCompoundClass[negationClass]; <> MathDB.InstallCompoundClass[listClass]; MathDB.InstallCompoundClass[factorialClass]; MathDB.InstallCompoundClass[functionClass]; MathDB.InstallCompoundClass[altFunctionClass]; MathDB.InstallCompoundClass[powClass]; MathDB.InstallCompoundClass[subscriptClass]; MathDB.InstallCompoundClass[parenClass]; MathDB.InstallCompoundClass[complexClass]; MathDB.InstallCompoundClass[productClass]; MathDB.InstallCompoundClass[summationClass]; MathDB.InstallCompoundClass[limitClass]; MathDB.InstallCompoundClass[approachesClass]; MathDB.InstallCompoundClass[integrationClass]; MathDB.InstallCompoundClass[indefIntClass]; MathDB.InstallCompoundClass[fractionClass]; MathDB.InstallCompoundClass[radicalClass]; MathDB.InstallCompoundClass[nRadicalClass]; <> MathDB.InstallCompoundClass[eqFormulaClass]; MathDB.InstallCompoundClass[notEqFormulaClass]; MathDB.InstallCompoundClass[ltFormulaClass]; MathDB.InstallCompoundClass[leFormulaClass]; MathDB.InstallCompoundClass[gtFormulaClass]; MathDB.InstallCompoundClass[geFormulaClass]; MathDB.InstallCompoundClass[approxEqFormulaClass]; <> matrixClass _ MathExpr.MakeMatrixClass[$matrix, matrix, MakeBigMathSym['\042], MakeBigMathSym['\043], MakeSpace[$matrix]]; vectorClass _ MathExpr.MakeMatrixClass[$vector, matrix, MakeBigMathSym['\042], MakeBigMathSym['\043], MakeSpace[$matrix]]; <> MathDB.InstallMatrixClass[matrixClass]; MathDB.InstallMatrixClass[vectorClass]; }; <> DefineClasses[]; END.