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 ~ { 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 ~ { 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]; 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 ~ { 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 ~ { 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 ~ { 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 ~ { 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 ~ { 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] ~ { 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] ~ { 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] ~ { 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] ~ { 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] ~ { IF var.Length[] = 0 THEN ERROR badFormat; RETURN[MathExpr.MakeAtomicExpr[$variable, var]]; }; GreekNameToChar: PROC[name: ROPE] RETURNS[CHAR] ~ { 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] ~ { 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] ~ { 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] ~ { 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] ~ { 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. êMathConstructorsImpl.mesa Carl Waldspurger, August 30, 1986 7:12:37 pm PDT Type Abbreviations Procedure Abbreviations Constants Common Rule Procs Common AtomToASRope Procs Common Paint Procs effects: Paints value onto context in absBox check type effects: Paints value as a sequence of centered superimposed characters. This is useful for things like negated symbols (/ slashed through)... check types scale Font paint chars, one by one, on ope of each other effects: Paints value onto context in absBox check types effects: Paints a line onto context filling absBox caveats: Ignores value & style effects: none Common Box Procs & AtomToRopeProcs effects: Returns a bounding box for a line Note that this is always a dummy value don't really need any data from value; always returns protoypical line size effects: Returns a bounding box for value effects: Returns a bounding box for value as a sequence of overlayed chars effects: Returns a bounding box for value effects: Returns a bounding box for value default to $thin Common Compound Procs Box Rules effects: Returns unaltered boxes (i.e. no resizing takes place) effects: Sizes boxes for expr of form ($fractionBar $numerator $denominator) should ENABLE noSuchBox fraction bar must be as wide as the wider of numerator, denominator adjust fbarBox extents effects: Sizes boxes for expr of form ($paren $a) right and left parentheses must be as tall as expression "a" effects: Sizes boxes for expr of form ($radRoot $radLine $n $radicand) should ENABLE noSuchBox line must be exactly as long as radicand, root symbol must be as tall as radicand + 2*space adjust symbol extents effects: Sizes boxes for expr of form ($radRoot $radLine $radicand) should ENABLE noSuchBox line must be exactly as long as radicand, root symbol must be as tall as radicand + 2*space adjust symbol extents effects: Sizes boxes for expr of form ($f $space $args $leftParen $rightParen) should ENABLE noSuchBox parens must be as big as args right and left parentheses must be as tall as expression "a" Composition Rules effects: Composes layout for expr of form ($exponent $base) hint, so align exponent with base via hintBox top of hint box inside base box 0.8 way up on hint box no hint, so align exponent directly with base effects: Composes layout for expr of form ($base $subscript) make hint to place superscript over base instead of entire expression effects: Composes layout for expr of form ($fractionBar $numerator $denominator) effects: Composes layout for expr of form ($comma $car $cdr) with symbol $space. effects: Composes layout for expr of form ($f $space $args $leftParen $rightParen) effects: Composes layout for expr of form ($lim $approaches $of $space) effects: Composes layout for expr of form ($summation $lowerbound $upperbound $summand) effects: Compose layout for expr of form ($radRoot $radLine $n $radicand) effects: Compose layout for expr of form ($radRoot $radLine $radicand) effects: Composes layout for expr of form ($integral $lowerlimit $upperlimit $integrand $dx $wrt) effects: Composes layout for expr of form ($integral $integrand $dx $wrt) effects: Composes layout for expr of form ($aliasUnaryOp $aliasA). effects: Composes layout for expr of form ($aliasBinOp $aliasA $aliasB) with symbols $aliasLeftSpace & $aliasRightSpace. set vertical offset depending on format classes of A & B arguments effects: Composes layout for expr of form ($aliasRelation $aliasLHS $aliasRHS) with symbols $aliasLeftSpace & $aliasRightSpace. set vertical offset depending on format classes of lhs & rhs arguments effects: Composes layout for expr of form ($complex $a $b) effects: Composes layout for expr of form ($bang $a $space) effects: Composes layout for expr of form ($paren $a) with symbols $leftParen and $rightParen Class Constructors 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". 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". 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". High Level Expression Constructors Atoms effects: Returns a symbol expression which is all the chars in r superimposed. effects: Constructs and returns an expression for +infinity. effects: Constructs and returns an integer expression for n. SIGNALS badFormat if n is not a legal integer. check that each char in n is a legal digit effects: Constructs and returns a real expression for n. effects: Constructs and returns a variable expression for var. SIGNALS badFormat if n is not a legal variable (e.g. invalid chars). check that each char is an alphabetic char A thru Z, either case (disabled 9/30/86) FOR i:INT IN[0..var.Length[]-1] DO SELECT var.Fetch[i] FROM IN ['A..'Z], IN ['a..'z] => NULL; ENDCASE => ERROR badFormat; ENDLOOP; effects: Returns the greek TeX character named by name. SIGNALS badFormat if names is unrecognized effects: Returns the name associated with the greek TeX character c. If no such association exists, returns "unknown". effects: Constructs and returns a greek variable expression for the lowercase greek letter associated with name (e.g. "gamma", "lambda"). SIGNALS badFormat if name does not name a greek letter. Binary Ops Matrix effects: Constructs and returns a matrix expression of size nRows by nCols from rows. SIGNALS badFormat if dimensions given don't exactly match dimension(rows). local declarations effects: Constructs and returns a vector expression of size dimension from elements. SIGNALS badFormat if dimension doesn't exactly match dimension(elements). local declarations complain if dimension does not agree with length(elements) Other Relations Radical Ops Unary Ops Signals & Errors Define & Install Expression Classes local declarations (lots of 'em) reset current DB state (i.e. clean slate) plain vanilla TeX fonts define Atom Classes register atom classes define info for "complex a b" (a + bi) define info for "summation lowerbound upperbound summand" define info for indefinite & definite integrals (normal & surface) define info for "pow base exponent" & "subscript base subscript" define info for "fraction numerator denominator" define info for "radical n radicand" define info for "( a )" define info for "$list $car $cdr" define info for functions define info for limits define into for factorial define compound classes binary operations unary operations relations others register compound classes binary ops unary ops others relations define matrix classes install matrix classes Install Classes Defined in this Module Ê)ã˜Jšœ™Jšœ0™0J˜J˜codešÏk ˜ Kšœ ˜ Kšœ ˜ K˜K˜ K˜Kšœ ˜ K˜Kšœ˜Kšœœœ*˜:Kšœœœ˜Kšœœ,˜9Kšœ˜K˜—J˜šÏnœœœ˜$šœI˜PJ˜—Jšœ˜J˜Jš˜—˜Jšž™˜Jšœœ œ˜Jšœœ œ˜Jšœœœ˜Jšœœ œ˜Jšœ œ˜*Jšœœ˜.Jšœœ˜4Jšœœ˜2Jšœœ˜2Jšœ œ˜*Jšœœ˜ Jšœœ˜J˜Jšœ œ˜#Jšœœ˜Jšœ œ˜%Jšœ œ˜'Jšœœ˜-Jšœ œ˜*Jšœ œ˜)Jšœœ˜—J˜šž™J˜Jšž œœœ œœœœ#˜lJ˜Jšž œœœ œœœœœ˜sJ˜Jš ž œœœŒœœ%˜ÛJ˜Jšžœœœ)œœœœœDœœœ-˜úJ˜—J˜Jšž ™ ˜Jšœ œ˜Jšœœ˜Jšœœ˜J˜—šž™J™J™Jšž™J™šžœ˜&Jšœœœ ˜,Jšœœ"˜-J˜—J˜šžœ˜)Jšœ˜ J˜—J˜šžœ˜&Jšœ ˜J˜—J˜—˜Jšž™J˜šž œ˜Kšœ-™-K˜Kšœ ™ šœœœ ˜5šœ˜K˜4K˜FKšœ œ?˜LKšœ œ8˜EK˜K˜'Kšœc˜cK˜ K˜—K˜—K˜—K˜šž œ˜KšœI™IKšœP™PK™Kšœ ™ šœœœ˜6šœ˜K˜4K˜7Kšœ œ?˜LKšœ œ8˜EKšœ ™ KšœQ˜QKšœ-™-šœœœ˜%Kšœœ˜ K˜AKšœ œ?˜LKšœ<˜œ˜FK˜#Kšœ™KšœK˜KK˜—šœ˜Kšœ˜Kšœ™KšœS˜SK˜—K˜—šœ˜Kšœ-™-K˜šœ)œ˜1K˜#K˜K˜—šœ˜K˜K˜K˜—K˜K˜—šœ œ˜˜ K˜!K˜.K˜——˜K˜LK˜—Kšœ˜K˜—K˜šžœ˜&Kšœ=™=K˜Kšœ œ˜ Kšœ œœœ˜K˜,Kšœ œœœ˜&K˜šœUœ˜]K˜"K˜K˜—šœ˜K˜K˜ K˜K˜—šœ œ˜˜ K˜K˜/K˜——K˜˜K˜K—K˜KšœE™EK˜DK˜Kšœ˜K˜—K˜K˜šžœ˜%KšœQ™QK˜Kšœ œ˜ Kšœ œœœ˜šœ œœœ˜'˜ K˜#K˜!—˜K˜#K˜!—˜ K˜#K˜—˜K˜#K˜"K˜——K˜sK˜Kšœ˜K˜—K˜šž œ˜!KšœQ™QK˜Kšœ œ˜ Kšœ œœœ˜šœ œœœ˜'˜K˜K˜—˜K˜K˜—˜K˜K˜—K˜—K˜cK˜Kšœ˜K˜—K˜šžœ˜%KšœS™SK˜Kšœ œ˜ Kšœ œœœ˜šœ œœœ˜'˜ K˜K˜—˜ K˜K˜—˜K˜K˜—˜K˜K˜—K˜—K˜]K˜Kšœ˜K˜—K˜šž œ˜"KšœH™HK˜Kšœ œ˜ Kšœ œœœ˜Kšœœ˜*Kšœœ&˜8Kšœ œœ ˜ K˜šœ(œ˜0šœ œ˜˜K˜K˜—˜ K˜K˜—˜K˜"K˜——K˜—šœ˜šœ œ˜˜K˜K˜—˜K˜K˜—˜ K˜K˜——K˜K˜—K˜gK˜Kšœ˜K˜—˜K˜—K˜šžœ˜&KšœN™NKšœ™K˜Kšœ œ˜ Kšœ œœœ˜Kšœ œœœ˜&K˜+K˜šœ/˜9˜ K˜K˜K˜—šœ˜ K˜K˜!K˜——K˜šœ˜˜ K˜K˜&—˜K˜K˜&—˜ K˜"K˜/——K˜K˜kK˜Kšœ˜K˜—K˜šžœ˜%KšœJ™JK˜Kšœ œ˜ Kšœ œœœ˜šœ œœœ˜'˜ K˜K˜!—˜K˜ K˜—˜ K˜K˜—˜K˜$K˜,—K˜—K˜dK˜Kšœ˜K˜K˜—šžœ˜$KšœG™GK˜Kšœ œ˜ Kšœ œœœ˜šœ œœœ˜'˜ K˜K˜!—˜K˜ K˜—˜ K˜K˜—K˜—K˜mK˜Kšœ˜K˜—K˜K˜šžœ˜(KšœB™BKšœ*™*K˜Kšœ œ˜ Kšœ œœœ˜Kšœ œœœ˜&K˜0K˜šœ1˜;˜ K˜K˜K˜—šœ˜ K˜$K˜K˜—K˜—šœ œ˜˜ K˜&K˜)—˜ K˜K˜)—˜ K˜Kšœ8˜8—˜K˜K˜"—˜K˜K˜—˜K˜K˜K˜——K˜sK˜Kšœ˜K˜—K˜šžœ˜*KšœJ™JK˜Kšœ œ˜ Kšœ œœœ˜K˜0Kšœ œœœ˜'K˜šœ1˜;˜ K˜K˜K˜—šœ˜ K˜$K˜K˜—K˜—K˜šœ œœ˜˜ K˜Kšœ7˜7—˜K˜K˜"—˜K˜K˜—˜K˜K˜K˜——K˜rK˜Kšœ˜K˜—K˜šžœ˜$KšœC™CK˜Kšœ œ˜ Kšœ œœœ˜šœ œœœ˜'˜ K˜!K˜%—˜ K˜K˜$K˜——K˜sK˜Kšœ˜˜K˜——K˜K˜šžœ˜%KšœM™MK™5K™Kšœ œ˜ Kšœ œœœ˜K˜OKšœ œœ ˜ K˜KšœB™Bšœ.˜8˜ K˜K˜K˜—˜ K˜K˜K˜—šœ˜ K˜K˜K˜K˜——šœ.˜8˜ K˜K˜K˜—˜ K˜K˜K˜—šœ˜ K˜K˜K˜——K˜šœ œ˜˜K˜K˜#—˜ K˜#K˜2—˜K˜K˜#—˜ K˜$K˜5K˜——K˜jK˜Kšœ˜K˜—K˜šžœ˜%KšœT™TK™5K™Kšœ œ˜ Kšœ œœœ˜K˜UKšœ œœ ˜ K˜KšœF™Fšœ0˜:˜ K˜K˜K˜—˜ K˜K˜K˜—šœ˜ K˜K˜K˜K˜——šœ0˜:˜ K˜K˜K˜—˜ K˜K˜K˜—šœ˜ K˜K˜K˜——K˜šœ œ˜˜K˜"K˜&—˜ K˜#K˜8—˜K˜"K˜&—˜ K˜$K˜;K˜——K˜oK˜Kšœ˜K˜—K˜K˜šžœ˜$Kšœ;™;K˜Kšœ œ˜ Kšœ œœœ˜šœ œœ˜!šœ*˜.K˜,K˜WK˜G——K˜K˜_K˜Kšœ˜K˜—K˜K˜šžœ˜&Kšœ<™Kšœ!œ$˜IKšœ+œ.˜]Kšœ-œ/˜`K˜Kšœ1œœM˜žK˜—K˜šžœœœœ œœ œœ˜KšœT™TKšœJ™JKšœ2™2K™Kšœ%œ˜GKšœ&œ+˜UKšœ$œ%˜MKšœ0œ œC˜‹K˜K˜—K˜—šž"™"K˜Kšž™K˜š ž œœœœœ˜-Kšœ7˜=K˜—K˜š ž œœœœœ˜.Kšœ(˜.K˜—K˜š žœœœœœ˜/KšœO™OKšœ*˜0K˜K˜—š žœœœœœ˜/Kšœ9˜?K˜—K˜š žœœœœœ˜1Kšœ;˜AK˜—K˜š ž œœœœœ˜,Kšœ8˜>K˜—K˜š žœœœœœ˜0Kšœ<˜BK˜—K˜šžœœœœ˜"Kšœ)˜/K˜——˜š ž œœœœœ˜-Kšœ<œ˜KK˜K˜—š žœœœœœ˜0Kšœ5˜;K˜—K˜š ž œœœœœ˜-Kšœ=™=Kšœ-˜3K˜K˜—K˜š žœœœœœœ˜/Kšœ=™=Kšœ8™8K™Kšœœœ ˜'K˜šœ ˜Kšœ œ˜Kšœœœœ Ÿ˜NKšœœ ˜—K˜Kšœ*™*šœœœ˜ šœ ˜Kšœ œ˜Kšœœ ˜—Kšœ˜—Kšœ'˜-K˜—K˜š žœœœœœœ˜0Kšœ9™9Kšœ:˜@K˜—K˜š ž œœœœœœ˜6Kšœ?™?KšœN™NK™Kšœœœ ˜)K™KšœS™Sšœœœ™"šœ™Kšœ œ œ™!Kšœœ ™—Kšœ™—K™Kšœ*˜0K˜—K˜š žœœœœœ˜3Kšœ8™8Kšœ4™4šœ˜šœœœ˜Kšœœ ˜*Kšœœ ˜)Kšœœ ˜*Kšœœ ˜*Kšœœ ˜,Kšœœ ˜)Kšœœ ˜(Kšœœ ˜*Kšœœ ˜)Kšœœ ˜*Kšœœ ˜+Kšœœ ˜'Kšœœ ˜'Kšœœ ˜'Kšœœ ˜'Kšœœ ˜(Kšœœ ˜*Kšœœ ˜(Kšœœ ˜,Kšœœ ˜(Kšœœ ˜(Kšœœ ˜(Kšœœ ˜*Kšœœ Ÿ&˜BK˜—K˜—K˜—š žœœœœœ˜0KšœE™EKšœ;™;šœ˜šœ˜ K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜Kšœ ˜K˜—˜K˜—K˜——š ž œœœœœœ˜7KšœD™DKšœO™OK™AK™Kšœ œ6œ˜XKšœ0˜6K˜—˜K˜—K˜Kšž ™ K˜š žœœœœœœ˜˜oK˜—K˜š ž œœœœœœ˜MKšœ)œS˜†K˜—K˜š žœœœœœœ˜KKšœ&œ)˜YK˜—K˜Kšž ™ K™š žœœœœœœ˜/Kšœ!œ ˜7K˜—K˜š ž œœœœœœ˜4Kšœ&œ ˜Kšœœ˜3Kšœœ˜