Sindbad~EG File Manager
\documentclass{amsart}
\usepackage{comment}
%\usepackage{showkeys}
\usepackage{lineno}
\usepackage{url}
\linenumbers
\begin{document}
\title{Web MathXpert}
\author{Michael Beeson}
\date{\today}
\maketitle
\section{Introduction}
Web MathXpert is a Web-based version of
MathXpert. It allows users to access MathXpert from
their web browser, without any additional software.
This document is a technical description of its architecture
and implementation, intended for interested software designers
and programmers.
Web MathXpert is composed of two parts:
The {\em MathXpert Engine}, which runs on a server
and does not interact directly with users, and
the ``client'', which interacts with users.
The Engine does all the mathematical computations,
typesetting, and produces (instructions to draw the) graphs.
All interactions with the user are handled by the client,
which is an ordinary ``front-end'', involving no mathematical
computations, but simply interface programming (in PHP and Javascript).
As the original author of MathXpert, I have prepared both
the Engine and the client. In the future both will become
open-source projects. I anticipate that the Engine can become
the core of several different projects, which are not discussed
in this document. MathXpert's stated purpose is to
``help students learn algebra, trigonometry, and calculus.''
It will be natural to incorporate MathXpert as one component of
websites that complement MathXpert with other learning tools.
Only if someone wishes to add to the mathematical capabilities
of MathXpert would it be necessary to modify the Engine. I think
most projects that would use MathXpert would simply communicate
with the existing Engine. Compare to \TeX, which is a complicated
program that needs little modification, but there are many
different client programs that provide an environment making it
convenient to use \TeX.
\section{Architecture Overview}
Web MathXpert is based on a client-server architecture as follows:
\smallskip
\begin{itemize}
\item The {\em MathXpert Engine}, or for short just the {\em Engine} runs on a server.
\item The Engine contains that part of MathXpert's code that performs calculations and
makes graphs.
\item The Engine does not directly interact with a user.
\item The Engine runs until purposefully stopped or restarted.
\item The Engine is written in C and is based on the MathXpert source code.
\item The Engine can handle many clients simultaneously and/or sequentially.
It communicates with the clients via TCP sockets, as described below.
\item Each {\em client} of the engine is a way for the user to interact with MathXpert.
In Web MathXpert, the client is a web browser window (located anywhere on the Internet).%
\footnote{In principle, the client could be an application program on a computer or phone;
that would be the easy way, for example, to make a Mac OS version of MathXpert.}
\item The client will present {\em document windows} allowing the user
to interact with MathXpert documents. The document windows will be either {\em symbolic}
or {\em graphical}, corresponding to two ways of viewing documents in MathXpert.
\item Before a document is initialized, the client will use ``entry pages'' to assist
the user to select or enter an appropriate problem, so that a document can be initialized.
Thus each session has a pre-document phase, and then a phase of interacting with the document,
in which the problem is solved or the graph is made and manipulated. Then that session is
over; for the next problem, one starts over.
\item The engine and the client will communicate
via {\em messages}, which are discussed below.
\item Rendering in the document windows is to be done by SVG graphics.
All browsers are able to render SVG.
\item The SVG code is generated by C code in the Engine.%
\footnote{ The reasons for choosing SVG graphics are as follows: The client must have some way to
display math formulas and graphics. SVG code is device-independent, consists of
text, is device-independent, and supported by all modern browsers. }
\end{itemize}
\section{Further features of the architecture}
In this section we specify some MathXpert-specific features of the Engine/client relations.
\begin{itemize}
\item A single running instance of the {\em Engine} can serve many clients.
That is because MathXpert can create and manage many documents; each
one can be tagged with a {\em SessionId}. Each client (browser session)
opens one document. Each document can be opened (viewed and manipulated)
as a symbolic document or as a graphic document. When a symbolic document is
open, a press of the {\em Graph} button will open another browser window in which a
graph of the current line of the symbolic document will be displayed. But actually,
it is another view of the same document. The user can open another document,
but that will be a different session.
\item MathXpert has the {\em Document} data structure. Each document is managed by the Engine
on behalf of a particular client. The document data structure is not available directly
to the client. Instead, the client views the document, either via a graphical view, or
via a symbolic view. The Engine responds to many messages by making
changes to the document, and then calling {\em SendSymbolDocument}
or {\em SendGraphDocument} to send a response to the client.
Each response consists of SVG graphics elements sufficient to display the whole
calculation or graph. The exact manner of display is up to the client.
\item The parser is part of the Engine. No parsing will be done by the
client, either in PHP or the browser. Only strings
are passed between Engine and Client. (These are UTF-8 strings.)%
\footnote{SVG graphics elements can be treated as one string, containing newline characters; such
a string looks like an array of strings to the human eye, but it is just a string.
Passing SVG graphics this way through a socket demonstrated in the
PolygonDemo proof-of-concept program.}
\item In Windows MathXpert, a user can define a function, which is then available to
all documents. User-defined functions will not be supported in WebMathXpert.%
\item The Engine will not be able to save or open MathXpert documents. For brevity,
we omit discussion of the reasons for this decision.
\item Strings that are displayed in the browser come from the {\em Localizer},
which is part of the Engine. This delivers natural-language
text in the {\em selected language}. The Localizer is described more
fully below. These strings are UTF-8 encoded, so that should be the default
encoding used by the interface. The Localizer is discussed more fully below.
\item The Engine is not a multi-threaded program. Although it can simultaneously be
connected to multiple clients, it can therefore respond to only one message at a time.
Therefore the response to messages must be speedy.
\item The Engine is intended to run for long periods of time without restarting.
If a document is left unattended by its owner for long enough (presently an hour),
it will be destroyed, so as to no longer occupy memory and a place in the hash table.%
\footnote{There is a {\em destroyDocument} message that a client could send the Engine,
but the interface never sends it. There is no good way to tell
on the client side when the PHP session is closing. Sending it when the browser window closes
is not right, since {\em SymbolDoc.php} closes every time a message needs to be sent, by
posting a hidden form; then it is reopened to process that form.
}
\end{itemize}
\section{SVG graphics and documents}
The purpose of this section is to introduce and explain the division of responsibilities
between Engine and client with regard to the display of symbolic documents.
In particular, some (but not all) of the messages that are used to communicate about documents
are discussed. Some of the points in this section are illustrated in the
{\em ParseAndDisplay} demo, which is available at
\smallskip
\noindent
\url{https://www.mathxpert.org/ParseAndDisplay.php}.
\subsection{Coordinates}
The Engine maintains a fixed coordinate system for symbolic documents, called ``papyrus
coordinates'', and uses just two font sizes, ``tenpoint'' and ``eightpoint'', in accordance
with the usual conventions for typesetting mathematics.
The actual font size used for display is the
responsibility of the interface, which controls it by setting or resetting the SVG ViewBox.
The ParseAndDisplay demo illustrates this with buttons for {\em Larger Type} and {\em Smaller Type}.
Papyrus coordinates are ``square'', i.e., 16 units horizontal and vertical is the same distance
on the papyrus, and hence should be on the user's screen also. These ``units'' are CSS
pixels, which are intended by CSS to be about the same size on every device.
As an example, when the user selects a rectangle, the interface must convert the rectangle to papyrus
coordinates before sending a {\em SelectedRectangle} message to the Engine. It is the responsibility of the interface
to handle the conversions between the ``papyrus coordinates'' used by the Engine and local
coordinates in the user's window. The Engine knows nothing about local coordinates.
\subsection{Fonts}
The Engine does not specify the fonts to be used for display of formulas; this
should technically be
an interface matter. However, the choice is limited, since the fonts must be available on
all browsers and must be suitable for mathematics. In particular, the UTF-8 characters for
parts of large integral signs vary widely in size and shape from one font to another. We have tested
the generated SVG code with Times New Roman and Cambria Math, which are not very different.
We used Times New Roman. See the ParseAndDisplay demo code,
which can easily be edited to use several different fonts listed there, so the curious can
see for themselves. Of course, the interface is free to use other fonts for text not
generated by the Engine.
\smallskip
{\em Changing type size}. The Engine uses only two fonts (12 point and 8 point; the latter is
used in exponents and subscripts). Changing the visible type size is done by the interface, using
a concept of SVG called the ViewBox. This is demonstrated
both in {\em ParseAndDisplay.php} and in {\em SymbolicDoc.php}.
Changing the type size by changing the ViewBox of the {\tt <svg>} elements does not
change their location, e.g., the reason strings will still begin in the same place.
That is different than what happens if you just use the usual keys to increase size in the browser;
then if size is increased, the reasons move to the right and perhaps off-screen. There are
some further subtleties to changing type size that are not discussed here, as this is an
interface issue. Our point here is mainly that it {\em is} an interface issue: the
Engine does not know what the current type size is, although it does know where every formula
would be if the type size were the default.
\subsection{ The document as the interface sees it}
From the interface's viewpoint, the document
(at any given time) consists of a number of {\tt <svg>} elements. These are labeled with
{\tt class} and {\tt id}. For example, class {\tt line} and id {\tt line0} would be
the SVG graphics for the display of the formula in line 0, i.e., the problem. Class
{\tt reason} is for the justifications (or reasons) for the steps. The possible classes
are given precisely and completely in a table far below; for now we are just explaining
general principles. But for example, there are classes {\tt assumption}, {\tt comment},
{\tt hint}, {\tt menuitem}, {\tt matherror}, and others.
When a document is being viewed graphically, it will have other {\tt <svg>} elements,
containing code to draw the axes, the title, the ticks, the axis labels, the tick labels,
and the graph paper. The {\tt <svg>} elements generated by the Engine all have absolute
positioning, meaning that they will be placed at the locations specified by the Engine
relative to least ancestor with relative or absolute positioning. It is the
interface's responsibility to place these {\tt <svg>} elements properly. They
can easily be manipulated by Javascript using the DOM model. For example, assumptions
and hints are generated with {\tt display:none}; when it is desired to display them,
they are cloned and the clone is given {\tt display:block}.
\subsection{Document creation}
A document is created at the first communication from the interface. That allows the Engine
to allocate a heap for that document (each document has its own heap), so memory is available.
That heap can be used immediately,
but before the document can be used to make graphs or calculations,
the interface or Engine must specify a {\em topic} and a {\em problem};
the problem must parse and be ``checked'' as appropriate for the topic. Each topic is either a graphics
topic or a symbolic topic; in Windows MathXpert, there were correspondingly two kinds of
documents. In Web MathXpert, there is only one kind of document, but a document can be
{\em viewed} symbolically or graphically. The interface has two main files, {\tt SymbolicDoc.php}
and {\tt GraphDoc.php}, to provide these two views.
Before the topic and problem are selected and checked, the document is said to
be ``uninitialized.'' After an initial interaction with the interface, during which
the document is initialized, the Engine will finally call either {\em sendGraphDocument}
or {\em sendSymbolDocument}, and the resulting cascade of {\tt <svg>} elements will be
sent to the browser for display.
\subsection{ Updating a document}
From the interface's point of view, these {\tt <svg>} elements are ``blobs'' with a
known size and position (relative to their parent), and labeled with class and id and
other CSS and SVG properties such as {\tt display}. While it is certainly possible for skilled
Javascript programmers to manipulate them in more detail, the plan we followed is that
the Engine creates these elements (including colors, etc.) and the interface just displays them
at the right time and place. If the user wants to change the graph line color to purple,
for example, just tell the Engine to do it, and the whole document will be redrawn.
More explicitly, the Engine will send SVG code for the whole document to the client PHP file,
which will send the SVG, as well as a few lines of Javascript, to the browser.
A symbolic document is updated
\begin{itemize}
\item after taking the next
step of a computation.
\item in response to the {\em Undo} command.
\item when the user's window changes width.
\end{itemize}
The document does not need to be updated to increase or decrease the type size,
since the Engine does not even know about the type size.
It does not need to be updated to display a hint or the assumptions, since those
elements are already present (with {\tt display:none}), so Javascript can display
them on demand without communicating with the Engine.
When the Engine updates a graphical document, similarly SVG graphics will be sent to the
client. SVG graphics to redraw the whole graph
will be sent. That will happen, for example, if the user clicks buttons to double or halve
the vertical or horizontal range of the graph, or they select a rectangle and then click {\em Draw};
or they change the value of a parameter; or
if they choose to adjust the colors or graph paper.
In Windows MathXpert, there is a {\em Hand} tool that permits dragging the graph.
The graph is redrawn on every mouse-move. That won't work over the Internet.
Instead, the graph is
actually three times the visible linear dimensions, so the user can drag the graph
without calling the server. Then, on mouse-up, the Engine is notified of the new
position, and at that point recalculates the three-times-larger graph.
\subsection{ Line breaking}
Windows MathXpert could break lines that won't fit in the window.
But this feature is not implemented in Web MathExpert.
One reason for that is that, without line breaks, the redisplay on resizing the
browser window can be handled locally. It is only necessary to adjust the starting
$x$-coordinate of the reason strings. But if line breaks were implemented, the breaks
would change on resize, so the Engine would have to re-send the whole document; and
the changed parts would flicker. Moreover, and I think more importantly,
it's difficult to select a mathematical
expression that extends across a line break, and it's not difficult to scroll the
browser window horizontally to view a line that is too long to fit.
\section{The Localizer}
As of September 2023, Windows MathXpert ran in English, French, Spanish, Italian, and German.
In November 2023, I converted all those file to UTF-8.
In February 2024, I used ChatGPT to translate the files storing natural-language
strings into Dutch. This was more time-consuming that I originally hoped;
ChatGPT would then only do translations in chunks of 50 to 100 strings. I speak Dutch,
so I could check the translations. Sometimes it balks
at a longer input, sometimes it just makes mistakes (with the format of the strings).
In April-May 2024, ChatGPT translated MathXpert into Chinese. These translations have
not been checked by a native speaker.
\footnote{
It is not the case that you can just give ChatGPT ten large files to translate
and be done with the next language. ChatGPT itself is quite adamant that it is for interactive
use, for conversations, not for batch translation. But it doesn't remember the past, so you
can have a long series of fifty-line translations, and it never complains, hey, you are actually
doing batch translations!
}
\section{Messages}
The communication between the Engine and the clients is by means of messages sent over
sockets. Each client interacts with the Engine about one MathXpert document, which is maintained
by the Engine. The client sends messages to the Engine, and in response the Engine updates
the document, and then sends the client SVG graphics sufficient to present the entire document
to the user. This approach permits the Engine to make short, rapid responses (thus remaining
free to interact with other clients), and also enables client pages to avoid needing to
retain information about the document. (A few exceptions to this principle will be discussed below.)
\subsection{Overview of messages}
\begin{itemize}
\item
All communication between the Engine and client is done by sending
UTF-8 strings through sockets.
\item Messages from the client to the Engine are either {\em requests}
or {\em responses} or {\em notifications}.
\item Responses supply information requested by the engine, e.g., the argument
of an operation, as in {\em Add what to both sides of the equation?}
\item Notifications require no response (other than a formal ``ok''). For example,
the title of a graph has been moved to a new position, or a parameter increment has been changed.
(Technically, these are ``Ajax messages'', sent by XHR or the {\tt fetch} API without closing
the browser window.)
\item Requests ask the engine to do something, e.g.,
apply a certain operation to the currently selected formula, or
take one autostep, or ``undo''. These usually require the screen to be redrawn, so after
updating the document in the Engine's memory, the Engine calls {\em sendGraphDocument} or
{\em SendSymbolDocument}.
\item Generally menu items in MathXpert correspond to requests, but not
every request corresponds to a menu item.
\item Every message has a {\em name} and a {\em parameter}. Both are
UTF-8 strings.
\item Some messages are ``pre-document'', meaning before the document is
initialized by a choice of topic and problem, and checking that the problem
fits the topic. Responses to such messages should go to a PHP page that is
not designed to display a document, but to assist in getting a document prepared.
\item Other messages are ``post-document'', meaning that the response should go
to a page designed to display a document, either graphically (like {\em GraphDoc.php})
or symbolically (like {\em SymbolDoc.php}). The response to such a message will be SVG
graphics sufficient to display the calculation or graph.
\subsection{Symbolic and Graphical Views}
Each session with Web MathXpert
will begin with some pre-document messages, allowing the user to select a topic and
select or enter a problem. Then either a symbolic or graphical view of the document
will be initiated by an appropriate message. There may be several ways to arrive
at a topic and problem, depending on whether the user had a problem in mind to begin
with, or wants to use a problem from the MathXpert Problem Library, or possibly to edit
a library problem. Whatever the sequence, eventually a document will be initiated;
after that the messages sent will be ``post-document'' messages.
Generally speaking, from a symbolic view one continues a calculation to solve a problem,
while from a graphical view, one manipulates a graph using various tools. There is
an important exception to this work flow: the {\em Graph} button, which appears
in a symbolic view, but leads to a graphical view. That button
opens a new browser tab with a graphical view.%
\footnote{For example, {\em SymbolicDoc.php} implements that button in Javascript,
by submitting a hidden form to {\tt PHP\_SELF}; the processing of that form sends
a {\em graphButton} message to the Engine, but with code causing the Engine's response to
be sent to a new tab.}
The original tab is still open and the symbolic calculation can be continued in that tab.
\end{itemize}
\subsection{Use of Ajax in requesting information from the user.}
Before reading this section, the user should have a good understanding of the
basic architecture described above, and should have read some of the PHP code in
SymbolicDoc.php; otherwise this section may seem pretty arcane.
It may happen that the Engine is unable to satisfy a request. For example,
consider the request {\em parseAndDisplay}, which provides a string in the parameter
and hopes to receive SVG graphics to display the formula in two-dimensional form.
Perhaps the formula provided in the parameter
might fail to parse. Then the request cannot be satisfied. Then the Engine
sends an error message, which is an {\tt <svg >} element of class {\tt parserError}.
As mentioned, the Engine may sometimes need to request more information from the
client, e.g., ``Add what to both sides?''
The communication between the Engine and the client is not symmetric: the Engine cannot
send a message to the client in the same way that the clients sends a message to the Engine,
since it is the Engine that maintains the document. So when a (mathematical) operation needs
an argument (from the user), the Engine conveys this request in the form of an {\tt <svg>}
element of class {\tt needsargprompt}, with an id that encodes additional information about
the request. The client, whose job it is to display all the SVG code it has, but only when
and as appropriate, looks for elements of class {\tt needsargprompt}, and if one is present,
it gets the user's immediate attention to that request by putting up a modal dialog, allowing
the user to supply the requested information.
When the user submits data in that dialog, the client sends a {\em checkArg} message to the
Engine. This message is sent via Ajax, so a reply can
be received without giving up control in the Javascript code. The Engine can decide if the proposed
argument is acceptable or not, and if not, supply an error message. The client can receive
this message and display the error message without closing the dialog, let alone the whole page.
Finally when the argument is acceptable , the
client sends an {\em execOpWithArg} message to the Engine, whose parameter includes the
commandID of the operation, and the text entered as the arg by the user (which we now know
will parse and be an acceptable argument to that operation).%
\footnote{Technically, it is Javascript running the dialog box, on the browser; but only
PHP code on the server can send a message to the Engine. So, in practice, the Javascript uses
either XHR or the {\tt fetch} API to make a request to the PHP page, which upon receipt
sends the {\em execOpWithArg}
message to the server. This trick enables, in effect, Javascript to send a message to the Engine.
See the file {\tt FetchMessage.js} for the details.
}
The page can then die
in peace, knowing that the operation can at least be tried, and new SVG code for the
document will come in response to the {\em execOpWithArg} message. If the user cancels
out of the dialog, no message is sent to the Engine, and Javascript has to no longer
highlight the selected rectangle, just as if the user had clicked outside the menu.
\section{Components of the Engine}
MathXpert was already well-organized into components.
These may be grouped as follows:
\begin{itemize}
\item The {\em Operations} library, which contains code for the mathematical operations
that can be invoked to advance a calculation one more step, thus updating Symbolic documents.
\item The {\em Autostepper}, which contains code for deciding which operation to apply next
and where to apply it. This supports the Autostep, Autofinish, Hint, and Showstep buttons.
\item The {\em Prover}, which contains code for maintaining a list of assumptions,
and implementing the ``prove, refute, assume'' algorithm for checking required assumptions
of an operation.
\item The {\em Heap Manager}. MathXpert does not use malloc and free, or a reference-count
system of memory management, but supplies a separate heap to each document, from which memory
is managed by functions that behave like malloc and free.
\item The {\em Parser} takes a string to be parsed, and produces a term.
It needs a heap to work with.
\item The {\em SVGGenerator} is given a term,
and produces SVG code to display that term, along with the rectangle required to do so
without line breaks.
\item The {\em Bignum} library, which computes with arbitrary precision integers and rationals.%
\footnote{
Floating point numbers in MathXpert are just doubles; you can't ask for $\pi$ to 100 decimal places.
}
\item The {\em Problem Library} contains some 6500 mathematical formulas,
which are accessed
in response to {\em GetProblem} messages, whose parameters include a {\tt topic}
and {\tt problem\_number}. The response to such a message is SVG graphics to display
the selected problem.%
\footnote{These problems have been carefully constructed and
the auto-generated solutions have all been examined by hand. It is not envisaged
to expand this list of problems for WebMathXpert. Also, these problems are
used in autotesting MathXpert after changes to the source code.
}
Other messages to communicate with the Problem Library are detailed below.
\item The {\em Grapher} produces 2d graphs, with careful attention to the
singularities and jumps. More precisely, the Grapher initializes or updates graph documents
in response to messages.
The graph document has a slot for storing the
singularities and a slot for the jumps. These can be requested by appropriate
messages (in MathXpert there is a menu item {\em View Singularities}). The
Grapher can respond to a number of different messages, corresponding to menu items,
button presses, and mouse operations in MathXpert.
When the engine receives a request to initialize or update a graph (document), the
Grapher handles that request. First, it updates the internal document data structure.
Then, it sends a response to the client, which includes SVG graphics for the graph.
In Windows MathXpert, double-buffering is used
for efficient, flicker-free updating. Modern browsers use ``layers'', which presumably
use double-buffering. The Engine's responsibility ends when the SVG
graphics has been passed to the client. In the planning stage, I was worried about the
fact that double-buffering might be needed. But as it turned out, the browsers handle
it beautifully, so nothing additional had to be done.
\item {\em Scrolling.} It is the interface's responsibility to
handle the display of the document. In particular, if new lines are generated at the
bottom of a calculation, scrolling the window will be required. That is the responsibility
of the interface, not the Engine. The Engine does not know the height of the browser window.
\item The {\em Localizer}, which is responsible for displaying natural-language text in
the {\em selected language}. Natural-language text is used
in interface elements such as menus, ``reason strings'' (justifications of steps),
error messages, etc. For each supported language, there are C source files containing the
required strings in text arrays of UTF-8 strings. When such text is required, the functions
in {\tt natlang.c} are called;
these functions all return strings in the {\em selected language},
which is set by calling {\tt set\_language}. (This architecture supports
the ability to switch from English to French mid-computation.)%
\footnote{If you switch languages mid-computation, say from English to Chinese, only
the part {\em after the switch} will be in Chinese. You could always undo some steps
and redo them in Chinese. But the English steps may have some strange italics that they
didn't have before you switched to Chinese. This is a consequence of some code that decides,
for example, whether ``by'' should be printed in italics (as two variables) or in Roman (as an English
word). This code is different for each language. Since ``by'' is not a Chinese word, it is
printed in italics after the switch, as in ``divide {\em by} 12.''
Only the document as a whole has a language, not
each line within the document, so every line is printed using the rules for Chinese.
Not many people will switch languages mid-document and those that do,
will not care about italics very much, so we judge this situation acceptable.}
The Localizer controls translations of strings generated by the Engine. There are also
a few hundred strings used only by the interface. These are translated by Javascript
in the interface; translation tables are found in {\em TranslateEnterPages.js} and {\em EnterProblem.php}.
These tables are used to translate the text in various kinds of HTML and SVG elements.
The Engine sends Javascript to
define the variable {\em languageNumber}, which is used to control these translations.
\item The Engine responds to the {\em AutoStep} and {\em AutoFinish}
messages with SVG graphics.
This is the most delicate and complex part of the Engine; I advise against
attempting to improve it, because any change always has unforeseen effects on
other auto-generated solutions.
\item {\em Document Initialization}. The interface must provide a way (or ways) to
select a {\tt topic} and a {\tt problem}. These are the parameters to the
{\em CreateDocument} message. The different ways in which this can be done are discussed below.
\end{itemize}
\section{Parsing and displaying terms}
The client can issue a request {\em ParseAndDisplay}.
Remember that the client does not know what a term is, so it cannot directly receive
a term. It can only receive SVG graphics.
The {\em ParseAndDisplay} request has a string parameter
for the (text form of the) term to be parsed, and a point representing the upper left corner of
the desired display.
If the term does not parse, the Engine responds with a parser error message,
which is in the selected language. It will be returned as an SVG element of
class {\tt ParserErrorMessage}.
If the term does parse to a term $t$, the Engine uses its {\em termToSVG},
which returns SVG graphics code for displaying $t$.
The client can then display the term, but must supply the {\tt <svg>} tags.
The use of SVG graphics is the main innovation in the Engine, compared to
Windows MathXpert. Therefore it has been demonstrated in the proof-of-
concept program {\em ParseAndDisplay}, which can be seen at
\url{www.mathxpert.org/ParseAndDisplay.php}
This program was used to fine-tune MathXpert's typesetting.
\subsection{Selecting terms, or parts of a graph}
The client must be able to manage the mouse (or other pointer) and
allow the user to select a rectangle in a document window. In a symbolic view,
that rectangle will be used to select a term that the user can do something to
or with. In a graphics document, it will be used to select the next drawing window.
On {\tt mouse\_up}, or more generally, {\tt pointer\_up},
it sends a {\em SelectedRectangleSymbol} or {\em SelectedRectangleGraph}
message to the Engine and awaits the
response, which will be SVG code generated by {\em SendSymbolDocument}.
or {\em SendGraphDocument}.
The Engine responds to a {\em SelectedRectangleSymbol} message
by finding the largest subterm of the active line that is
contained in the selected rectangle. That term becomes the {\em selected term}
(which is stored as part of the document). The response to the message is
SVG graphics for the whole document; the selected term receives different coloring,
so the selected term will appear highlighted.
A {\tt <rect>} element for the rectangle of that term is also included, which is
be displayed first, before the terms are written over it.%
\footnote{Color selection, including the highlight color, is stored in the document;
the client may provide tools for changing those selections, as is possible in Windows MathXpert.}
The response also includes a list of operations, which the user may choose from. The
client will have to present that list to the user and allow a choice.
When the user selects an item from that list, a message {\em ApplyOperation} will be
sent to the Engine, with the selected operation as a parameter. (The Engine already knows
the selected subterm). If the operation succeeds, the document will be updated as described
above. If it does not, the response contains (in addition to the other SVG code) an
SVG element of class {\tt matherror} to explain why the operation failed (or at least,
{\em that} it failed). The interface should display that message and allow it to be dismissed.%
\footnote{Windows MathXpert supports selecting more than one term at once. This
feature is not supported in Web MathXpert.}
\section{SendGraphDocument}
Many of the messages that can be sent to the Engine result in certain changes to the
document, followed by a call to {\em SendGraphDocument}, which sends {\tt <svg>} elements
to the PHP page that sent a message to the Engine. These {\tt <svg>} elements are tagged
with a {\tt class} and an {\tt id}. Some of them are marked with {\tt display:none}, so
they can be displayed on demand by Javascript that changes their {\tt display} property.
For example, there are elements of class {\tt hint} and class {\tt assumption} that are
treated that way. Then the user's request to get a hint, or view the assumptions, can be
handled in the browser by Javascript, without going back to the Engine.
In Table~\ref{table:graphelements}, we present a complete table of the possible elements that compose a graphical view of a document, i.e., elements that might be received from {\em sendGraphDocument}.
These elements receive ids that begin with the class name, such as {\tt graph1} or {\tt param2}.
Note that elements of class {\tt authorscommentary} are send
as an ordinary {\tt <div>} with {\tt style=display:none}, because the browser cannot break lines
in SVG text. All the other elements are sent as SVG. {\tt graph} elements have absolute positioning,
so they need to be placed inside an element with relative or absolute positioning.
\begin{table}[htp]
\caption{Elements of a Graphical Document}
\label{table:graphelements}
\begin{center}
\begin{tabular}{r|l}
{\em Class} & {\em Description} \\
\hline
{\tt graph} & graph, with axes, ticks, labels \\
{\tt param} & parameter (of the graph function) \\
{\tt title} & code to display the formula as the title of the graph \\
{\tt jump} & one entry in the table of jumps \\
{\tt singularity} & one entry in the table of singularities \\
{\tt assumption} & one assumption \\
{\tt commentary} & commentary by the author of a stored problem \\
{\tt tooltip} & tooltip text\\
\end{tabular}
\end{center}
\label{default}
\end{table}%
Except for classes {\tt graph} and {\tt title}, the Engine sends these elements with property {\tt display:none}, so
they are invisible until the interface (using Javascript and the DOM) changes that property,
for example to display the singularities in a popup window. The page {\em GraphDoc.php}
illustrates these techniques.
\begin{table}[htp]
\caption{Initial visibility}
\label{table:graphelementsvisibility}
\begin{center}
\begin{tabular}{r|l}
{\em Class} & {\tt display}\\
\hline
{\tt graph} & {\tt block}\\
{\tt param} & {\tt block}\\
{\tt title} & {\tt block}\\
{\tt jump} & {\tt none} \\
{\tt singularity} & {\tt none} \\
{\tt assumption} & {\tt none} \\
{\tt commentary} & {\tt none} \\
{\tt tooltip} & {\tt none}\\
\end{tabular}
\end{center}
\label{default}
\end{table}%
\section{SendSymbolDocument}
Many of the messages that can be sent to the Engine result in certain changes to the
document, followed by a call to {\em SendSymbolDocument}, which sends {\tt <svg>} elements
to the PHP page that sent a message to the Engine. Some messages are appropriate for a
symbolic (view of a) document, while others are for a graphical (view of a) document.
The Engine answers every message, so it is up to the interface programmer not to send
a symbolic message from a graphical view.%
\footnote{Only one message, {\em graphButton}, is sent from {\em SymbolDoc.php} and
processed by {\em GraphDoc.php}. Other messages from those two files are processed by the
sending file. But interface programmers must take care to process (the responses to)
pre-document messages in the correct file.}
The task of the client is to display these various SVG elements to the user
at the appropriate time and place.
Table~\ref{table:symbolelements} shows the
classes of SVG elements that are generated by {\em sendSymbolDocument}.
\begin{table}[htp]
\caption{Elements of a Symbolic Document}
\label{table:symbolelements}
\begin{center}
\begin{tabular}{r|l}
{\em Class} & {\em Description} \\
\hline
{\tt line} & one line of the solution \\
{\tt reason} & the justification for a line \\
{\tt highlight} & the term selection rectangle(s) \\
{\tt assumption} & one assumption \\
{\tt hint} & one hint \\
{\tt menuitem} & one menu item \\
{\tt needsargprompt} & prompt for a dialog \\
{\tt remark} & one remark \\
{\tt comment} & one comment \\
{\tt finalremark} & for example, {\em That's the answer.} \\
{\tt matherror} & why an operation failed \\
{\tt tooltip} & tooltip text\\
{\tt progressTitle} & title of a progress-report \\
{\tt progress} & text to put in a progress report \\
{\tt commentary} & commentary by the author of a stored problem
\end{tabular}
\end{center}
\label{default}
\end{table}%
Lines, reasons, highlights, finalremarks,
and some comments arrive with \goodbreak\noindent{\tt display:block}; the other elements arrive with {\tt display:none}.
Elements that arrive with {\tt display:block} have coordinates already and need no further
manipulation by the client. Elements that arrive with {\tt display:none} can be displayed
at the interface's discretion. Menu items are meant to be assembled into a menu,
from which the user can make a choice, sending a {\em SelectMenuChoice} message. Hints,
assumptions, matherrors, and authorscommentary are intended for display in a modal dialog, which the user will read and then dismiss; also comments and remarks with {\tt display:none}.
See {\em SymbolDoc.php} for a demonstration of how the interface carries out
the task of displaying the SVG elements.
\section{Initializing a Document}
A document requires a problem and a topic to initialize. There are
several ways to request a new document.
The {\em topic} is one of those specified in {\tt topics.h}. There
about a hundred different topics.
The {\em problem} is a term, but not just any term: it must be appropriate for the
topic. In order to initialize a document, there are several possible paths:
\begin{itemize}
\item Select a topic and problem from the MathXpert Problem Library.
\item Select a topic and problem from the Problem Library, and then edit the problem.
\item Pick one of about 20 kinds of graphs, or about 20 kinds of symbolic problems,
and then enter your own problem.
\item Begin as if entering a problem, but then use the ``arrow button'' to get a random problem
of the chosen kind (which you can then edit or accept).
\end{itemize}
In this section, we describe and discuss the ``pre-document'' part of the
interface. Web MathXpert's introductory page presents the user with three choices:
\begin{itemize}
\item {Make a Graph}
\item {Enter a Problem}
\item {MathXpert Problem Library}
\end{itemize}
These choices represent three different pathways, each of which eventually
leads to the selection of a
problem and a topic.
We will discuss these three choices one by one, in reverse order.
\subsection{The MathXpert Problem Library}
The Engine contains (in C source code) about 6500 problems. To understand how this library
can be used, it is necessary to understand how a MathXpert document is created.
Choosing {\em MathXpert Problem Library} leads to
{\tt GetProblem.php}. This page
provides a Javascript picker element to access the problems from the
Problem Library and display them.%
\footnote{This is a third-party ``spinner'' control. Perhaps someone can
design a better way to access the Problem Library, but this does work.}
At the top of the page, the user can access the
Localizer to select one of the supported natural languages. Then the user can
browse the available topics and problems. One problem at a time will be displayed
or ``selected.''
The user can click on
{\em Accept the Selected Problem} to initialize a MathXpert document and proceed to use
it with the Engine. The newly initialized document will be sent (in SVG graphics form)
via {\em SendGraphDocument} or {\em SendSymbolDocument}, according to the topic. The
interface file {\em GetProblem.php} ensures that the Engine's response is directed
to a PHP page designed for a graphical view or a symbolic view, as appropriate, e.g.,
to SymbolDoc.php or GraphDoc.php. Those two PHP files constitute the interface for
working with a MathXpert document once it has been created.
The rest of this subsection is of interest only to programmers who may try to improve
the interface to the Problem Library.
The file {tdefn.h} defines topic numbers and names for the topics. Those names are
just internal identifiers. For example tdefn.h contains the line
{\tt \#define \_ordinary\_graph\_sincos 10}
\noindent
A programmer can ask the Engine for all the problems for a given topic.
You can ask for each of these things to be delivered as parseable ascii text,
or as an SVG graphics element. See Table~\ref{table:askproblems}.
One can also ask for the information, how many problems does the Library contain
for a specified topic?
\begin{table}[ht]
\caption{Messages to access the Problem Library}
\begin{center}
\begin{tabular}{l|l}
{\em Message} & {\em parameter} \\
\hline
AskProblemsText & topic \\
AskProblemsSVG & topic \\
AsknProblems & (unused nonempty parameter)
\end{tabular}
\end{center}
\label{table:askproblems}
\end{table}%
For the message requesting SVG, each SVG element is a string (containing newlines
and ending with a newline) suitable for placing in an existing {\tt <svg>} element
(or a dynamically created element). The {\tt <svg>} and {\tt </svg>} tags are
{\em not} included in the message response.%
\footnote{The {\em GetProblem.php} file demonstrates how such SVG text can
be dynamically written into an SVG element in the web page.}
After each problem, a second newline
is added, so the problems are separated by double newlines in the response; then
an array of problems is easily created by ``exploding'' the response on double newline.
In GetProblem.php, the ``subjects'' are hard-coded, and the range of topics for
each subject is also hard-coded, taken from tdefn.h. Then the problems are requested
using {\em AskProblemsSVG}. The message {\em asknProblems} is used to initialize a control
while the problems are still downloading. The ``subjects'' belong to the interface only;
the Engine knows nothing of grouping topics by subject, so this can be changed arbitrarily
in GetProblem.php.
When the user accepts a problem, the message
{\em InitSymbolDocFromTopicAndProblem} is sent. Its parameter
carries the topic number
and the text form of the selected
problem, separated by '+', which generally serves to combine several data items into
one (string) parameter.
In the case of a problem from the MathXpert Problem Library, it is guaranteed that
the problem will be compatible with the topic, so the response to that message will
be generated by {\em sendGraphDocument} or {\em sendSymbolDocument}, and {\tt GetProblem.php}
will direct the output to either {\tt GraphDoc.php} or {\tt SymbolDoc.php}.
\subsection{Entering your own problem}
Initializing a MathXpert document requires a problem and a topic; it is not enough just to
have a parseable formula as a problem. There are about a hundred topics; even showing them to
a user would be bewildering, as the MathXpert Problem Library probably is. Instead, the
page {\tt EnterProblem.php} reduces the choice to 16 ``kinds'' of problem, starting with
{\em Simplify} and {\em Solve an Equation}. In a few cases there is an additional selector
element; for example, under {\em Solve Linear Equations}, a selector offers the choice of
many ways to solve linear equations. The user's (optional) selection tells MathXpert how to
proceed if {\em Autostep} or {\em Showstep} or {\em Autofinish} is selected. This is
one use of the ``topic'': it controls the choice of method. Another use is to control the
step size: beginners should see all the steps of solving $4x+2 = 11$, more experienced students
want that solved in one or two steps.
Choosing a ``kind of problem'' leads to a ``problem entry page.'' There are many of these pages,
with names like {\tt EnterSimplify.php}. Each one has one, two, or in some cases optionally more,
fields in which formulas can be entered. Below the entry fields is a {\tt Display} button;
if all goes well, the entered problem appears below the {\tt Display} button in typeset
mathematical notation. This means that not only did the entered problem parse correctly
(i.e., the syntax was correct), but also that the Engine has judged that the formulas entered
are compatible with the selected kind of problem.
Here is what happens behind the scenes: First, the ``entry page'' has selected a topic,
the ``default topic'' for this kind of problem. There may have been different possible
choices, for example one may provide more details in the steps; but some choice is made.
Then a message {\em setupAndCheckSymbol} is sent, with certain parameters, including
the text form of the problem and the topic number. When that message is processed,
the Engine checks whether the problem is acceptable for that topic. If not,
it responds with error messages, which the entry page displays.
The user can then try again.
But if (or when) the problem is acceptable, the Engine creates and initializes an
appropriate document. The response it sends to the entry page is the SVG to display
the problem in typeset form. That is an element with class {\tt termSVG} and id {\tt parsedTerm}.
When such a response is received, the entry page makes visible the
{\em Do the Math} button. Clicking that button sends a {\em startSolving} message to
the Engine, which in turn results in a call to {\em sendSymbolDocument}, whose
response is directed to {\tt SymbolDoc.php}, completing the document-initialization phase.
\subsection{Making a Graph}
Similarly, when making a graph you must choose what kind of graph you want to make;
you are sent to {\tt MakeGraph.php}, where
there are twelve kinds to choose from. Each choice is illustrated by a small sample
of that kind of graph. In two of those cases, namely
{\em Differential Equations} and
{\em Approximate Integration}, a selector allows the user a selector
to refine what kind of problem
is intended. Picking one of those twelve kinds of graphs sends you to an entry page,
for example {\tt EnterOrdinaryGraph.php}. You get one or two, or sometimes optionally more,
entry fields and a {\em Display} button. As with symbolic problems, {\em Display} leads to
a typeset version and a check whether the input is appropriate. Behind the scenes,
a {\em setupAndCheckGraph} message is sent. If all goes well, the {\em Draw} button is
shown. Clicking {\em Draw} sends a {\em drawAll} message (``all'' because there may be
several graphs). The result of that is a {\em sendGraphDocument} message, with response
directed to {\tt GraphDoc.php}, completing the document-initialization phase.
\section{Messages}
In this section, we list all possible messages to which the Engine can respond.
The real authority for this is file {\em ProcessMessage.c}; at the time of writing,
the following corresponds to that file.
\begin{verbatim}
// pre-document messages
askTopicStrings
askSubjectStrings
askProblemsText
askProblemsSVG
asknProblems
initSymbolDocFromLibrary
initGraphDocFromLibrary
setupAndCheckGraph
setupAndCheckSymbol
startSolving
// Ajax messages, response is NOT the whole document
// but a message for local use in javascript.
randomProblem
checkArg
askPointSlope
// Messages from and to a symbol document.
// Response is sendSymbolDoc
autoStep
showStep
autoFinish
undo
hint
finished
selectedRectangleSymbol
selectMenuChoice
execOpWithArg
symbolWindowResized
// one message from a symbol document to a graph document
graphButton
// Messages from and to a graph document.
// Response is SendGraphDoc
selectedRectangleGraph
incrementActiveParameter
decrementActiveParameter
decrementParameter
incrementParameter
horizontalzoomout
horizontalzoomin
verticalzoomout
verticalzoomin
doublezoomout
doublezoomin
graphWindowResized
toggleDirectionField
toggleErase
circularAspect
setGraphPaper
updateParameters
parameterIncrementChanged
drawAll
zoomAtPoint
graphMoved
\end{verbatim}
\section{Overview of the interface}
While the main focus of this document is the communication between the Engine and the
interface, nevertheless we will describe the architecture of the interface as well.
There is nothing particularly innovative about it: it is all standard PHP and Javascript.
One thing worthy of note is that, unlike the usual Web architecture, there is no
database whatsoever. MathXpert does not collect or use any data about its users or
what they do. You can use MathXpert completely anonymously. On the other hand,
you are not {\em compelled} to be anonymous; you can provide some information that will
enable MathXpert to report your performance to an external server. The potential uses
of this feature will be discussed below.
In programming this interface, I stuck to pure PHP and Javascript, eschewing all
``modern frameworks.'' My reasons for this are (1) it was not very difficult to accomplish
all that I required; (2) PHP and Javascript have been pounded on for many years now,
and both of them work quite reliably; and (3) frameworks come and go, while PHP and
Javascript are here to stay, so by writing in those languages, I avoid obsolescence.
I followed this principle: {\em Don't hassle the user.} Don't ask them questions to
clarify their intent, such as {\em What is the independent variable?} Don't even tell
them what the rules are for determining the independent variable. Just get it right
by yourself, and the user will never even know it was an issue. Don't ask them to specify
the ranges of $x$ and $y$ for a graph--just get them right. And, be sure that if the user
wants to adjust them, the graph can be directly manipulated after it is drawn.
Of course, if the program expects variables in the last half of the alphabet and parameters
in the first half, a user who expects otherwise may be surprised; but that is the price
of getting things mostly right and mostly hassle-free.
There is only one type of document in Web MathXpert,
but a document can be viewed symbolically or graphically. It is a useful shorthand
to speak of ``symbolic documents'' or ``graphical documents'', depending on how the document
is being viewed. Hence the two most important pages in the interface are {\em SymbolicDoc.php}
and {\em GraphDoc.php}, which manage the symbolic and graphical views, respectively.
But before a document is created, the user must somehow get a problem to work on; there
are several ways to accomplish that. Therefore the interface falls
naturally into three parts: SymbolicDoc, GraphDoc, and the ``pre-document'' pages for
getting a problem. We will devote the next three sections to these topics.
\section{ Managing a symbolic document}
\subsection{Document re-sent at every step} It is fundamental to the design that
most messages are sent to the Engine with the submission of a form, so the current
page will close, and the response to the message will be the entire SVG needed to
display the document. That will not be apparent to the user, who will see for example
just one more line in a calculation. A few messages are Ajax messages that do not
close the page. Except for these messages, the response to every message is the
whole document: either {\em sendSymbolDocument} or {\em sendGraphDocument} is called.
\subsection{Translation} As mentioned above, the Engine provides natural-language text
in the supported languages for text used in reasons for steps, hints, error messages,
remarks, and the like. Text that is created only in the interface, such as prompts
for data entry fields, is translated in {\tt translateEntryPages.js}, with a similar
tables also in {\tt EnterProblem.php} and {\tt MakeGraph.php}. Other
pages call upon {\tt translateEntryPages.js} to replace text by its translation,
using the id of an HTML or SVG element and Javascript to replace the text by its
translation, using the variable {\em language}. That variable is set by a selector
in the top page {\tt index.php}, or in {\tt SymbolicDoc.php} after a calculation has begun.
It is passed as a parameter with most messages to the Engine, so the Engine can know what
language to generate.
\subsection{Type Size} In {\tt index.php} and {\tt SymbolicDoc.php}, there is a selector
providing choices to control the type size. The choices from this selector determine the
value of {\em scaleFactor}, which is $1.0$ when {\em Normal size} is chosen. The
effects of this selector are managed in {\tt TypeSize.js}. The value of
{\em scaleFactor} is used to change the {\tt width}, {\tt height}, and {\tt style.top} of
SVG elements, but the {\tt viewBox} is not changed, resulting in changing the size of the
text on the screen. Not changing {\tt style.right} results in the reasons beginning at
about the same column. In order that the size should not revert to ``normal'' at each
line, when the page is re-sent by the Engine, {\em scaleFactor} is saved in Javascript's ``local storage.''
The Engine never knows anything about {\em scaleFactor}. There is no such thing as a
{\em TypeSizeChanged} message.
\subsection{Selection Rectangle}
The user selects a rectangle with the mouse or other pointer device.
SymbolicDoc.php manages that selection, and at {\em pointerUp} it sends a
{\em selectedRectangleSymbol} message to the Engine.
It has to de-scale the coordinates of the rectangle by {\em scaleFactor}, as the Engine
knows where formulas would be if {\em scaleFactor} were 1. The Engine finds the selected
term and ``snaps'' the rectangle to the box that just contains that term, sending it
back with the document as SVG of class {\tt highlight}, containing one or more {\tt <rect>}
elements.
\subsection{Operation Selection Menu}
At the same time, the Engine produces the menu items for the Operation Selection Menu,
and sends them as SVG of class {\tt menuitem}. SymbolicDoc.php assembles these items into
a menu and decides where to put it, and operates the menu. When the user makes a choice,
it sends a {\em selectMenuChoice} message telling the Engine which choice was made.
The Engine then tries to execute that operation (either on or with the selected term);
if it succeeds the document is updated with the new line, and sent to the browser (of course
without the selected term and menu); if it fails, there will be an error message
(SVG of class {\tt mathError}) instead of a new line.
\subsection{Buttons at the top of SymbolicDoc.php} There is a row of buttons at the top,
including {\em AutoStep}, {\em AutoFinish}, and {\em ShowStep}.
{\em Autostep} takes one step in auto mode, sending
back a document with one more line (unless it's finished). {\em Autofinish} sends back a completed
document. {\em Showstep} is intended to show the user how they could accomplish the
{\em AutoStep} result
using the menu; a term will be automatically selected, the Operation Selection Menu will
appear, and an item will be highlighted in that menu, which if selected, should duplicate
the {\em AutoStep} result. I cannot guarantee that this will always work, but it is pretty good.
In Windows MathXpert, the cursor was animated to imitate the term selection and menu choice,
but for security reasons, Javascript is not allowed to move the cursor, so we just highlight
the suggested selection (in a color that usually doesn't appear in the menu). The menu will
still operate normally. {\em Undo} causes the document to revert to its condition before the
last step. (That is surprisingly complex, but happens entirely inside the Engine--all the
interface has to do is display the document.)
The buttons themselves are drawn with SVG graphics, as defined in \goodbreak\noindent{\tt ButtonDefinitions.svg}.
Several of what appear to be images are just UTF-8 characters, such as the ``eye'' that is used
for the Show Assumptions button.
\subsection{Assumptions} MathXpert analyzes the domain of the problem when the document
is initialized, and maintains a list of assumptions that starts with the domain of the problem,
but may grow as certain operations require making more assumptions; for example you can only
take the square root of positive things. The current assumptions are sent with the document
as SVG of class {\tt assumption}. SymbolicDoc.php displays them (in a modal popup) when the
Assumptions button is clicked.
\section{Managing a graphical document}
The graphical view of a document is managed by {\tt GraphDoc.php}. The browser window
is divided into two parts: at the left is the Graph Toolbar, containing tools with which
to manipulate the graph. At the right is the graph itself. The Engine knows only about
the graph, and does not manage the Toolbar at all.
\subsection{Initial display} Although the Engine doesn't manage the Toolbar, it
must know the {\em width} of the
Toolbar, in order to send the graph in CSS pixel coordinates in the browser window. This
is accomplished by sending the width of the Toolbar as a parameter with some messages and
storing it as a PHP session variable. The initial job of GraphDoc.php is to display the
Toolbar and the graph itself, as sent by the Engine using {\em sendGraphDocument}. The
display of the graph is done just by the PHP {\tt echo} command, outputting the SVG
produced by {\em sendGraphDocument}. The initial display of the Toolbar has a little
sublety, in that exactly which tools are available depends on the topic. For example,
on polar graphs, aspect ratio 1 must be maintained, so you don't have buttons that
allow horizontal or vertical zoom, but only zooming in both directions at the same time.
And the DirectionField button only appears on differential equations where a direction field
makes sense. The code for deciding which buttons to show and where to put them is in
{\tt AdjustToolbar.js}.
\subsection{Implementing the Toolbar} Some of the Toolbar buttons immediately send
a message
to the Engine, which in response changes the document and sends it afresh with
{\em sendGraphDocument}. That applies, for example, to all the zoom buttons, and the
Circle button (which enforces aspect ratio 1), and the Show Direction Field button.
Then there are several buttons that control what function the mouse (or pointer) will have.
It can be used for the Point-Slope tool, or for a selection rectangle, which can be
either centered at mousedown, or have a corner at mousedown. Simple Javascript draws
the selection rectangle, and a message is sent only when the Draw button is pressed.
\subsection{Direct manipulation} Touchscreens and trackpads give the user the ability
to directly scroll (using two fingers) or zoom (using pinch gestures). These effects
are managed in Javascript, as you certainly cannot make a roundtrip to the Engine at
every mousemove. When the scroll or zoom is completed, the Engine is notified of
the change, and at that point the document is sent again with {\em sendGraphDocument}.
The graph is actually drawn with three times the visible width and height, so when it
is initially displayed, you are looking at the middle of nine rectangles. There is
thus a lot of SVG in the browser that you do not see. That SVG can be used to support
scrolling and zooming. You can scroll or zoom as much as one window width or height.
If you try hard, you can scroll to that limit and see the edge of the Universe, but
normally, you would release the mouse or pointer before moving that far.
During zooming, the graph paper may change the number of lines per inch, but when the
graph is sent again, the graph paper will resume its normal appearance.
\subsection{Graph paper} The Toolbar offers a button showing samples of the different
graph papers available (including plain black and plain white). You can view the samples
and then select a new graph paper if desired.
\subsection{Color selection not available} There is no way to change the color scheme
of a graph (other than changing the graph paper). Since MathXpert is anonymous, there is
no way to save a user's color preferences (other than PHP session variables or Javascript
local storage), so such choices would only be temporary, and the defaults are good, so in
our view this is one less distraction from the mathematics. In the future, if a way
to change colors should be desired, it should be accomplished by direct manipulation:
right-click on the thing you want to change, rather than through complicated dialogs.
\subsection{Singularities and assumptions} The Engine calculates and sends these,
as SVG elements of class {\tt singularity} and {\tt assumption}. The interface displays
them in a modal element when the corresponding Toolbar buttons are clicked. For example
if you graph $1/\sqrt x$, you will get the assumption $0 < x$ and the singularity $x = 0$.
\subsection{Parameters} It is encourage to make graphs with parameters, for example $\sin ax$.
There will be a button on the toolbar for each parameter. In the example, there will be a button
labeled $a$, and next to it two buttons labeled $+$ and $-$, which will increment and decrement
the value of $a$. If you want to change the value of $a$ directly, or change the increment,
click on $a$ itself; the dialog you get is created and manage by file {\tt AdjustParameter.js}.
Next to the increment/decrement buttons is a green-circle button, whose tooltip explains that
green means show only the graph for the current value of the parameter, and red means keep all
the graphs. Typically with an ordinary graph, you want just one at a time, and with a
differential equation, you want a lot of solutions showing.
\subsection{Instant animation of parameters} In addition to changing the parameter by one increment
at a time, you can also use a slider to vary the parameter movie-style through a range of
values. For example, you might try $\sin ax$ or $y = x^3-ax$. The display will move rapidly
through a range of fifty graphs for different values of the parameters. This is accomplished
without a round-trip to the server, by sending all fifty graphs to the browser with the document;
each graph is really just a list of coordinates of about 600 points. Then when the slider is
used, Javascript changes the visibility of those graphs, making just one visible--the one that
corresponds to the position of the slider.%
\footnote{For programmers: browsers are proprietary, so we can't see exactly how this is
accomplished, but there must be double-buffering of the ``layers'' involved. You can change
the visibility of many graphs instantly. By contrast, if you try to insert and remove things
from the DOM, it takes a comparatively long time, perhaps because the DOM is laid out again after
every insertion.}
When there are two (or more) parameters, as in the example $y = ax+b$, you get a slider for both
parameters. But just one of them at a time is ``active'', which means it has fifty invisible graphs
for the slider values. The active slider has a green knob.
When you click another slider, you make that one active, and the Engine
sends a different fifty graphs, and gives its slider a green knob.%
\footnote{The need for a round-trip to the server introduces a 200-millisecond delay; so click
slowly when changing the active parameter.}
In the spirit of ``don't hassle the user'', you are not asked about the increment between
your parameter values. Maybe you think your slider is too jerky. Then use the parameter button,
and you can decrease the parameter increment, after which you will have new invisible graphs and
your slider may work better.%
\footnote{For programmers: Therefore, the {\em parameterIncrementChanged} message must get the whole
document in response; since nothing visible will change, it could otherwise have been
an Ajax message, but as mentioned, it's slow to insert fifty new graphs into the DOM, you
might as well send the whole document.}
\subsection{Integer versus real parameters}. Parameters with names $n$, $m$, $k$, or
the same in uppercase, will not get sliders. They should be used when a slider would not
make sense, as in the upper limit of a sum, or a Lissajous pattern $(\sin mx, cos nx)$.
\section{Getting a problem}
Here ``problem'' also can mean ``function to graph.'' To understand the
process of getting a problem, you must remember that you must choose or enter
not only a problem, but the {\em topic} of that problem; there are 179 topics,
which is an overwhelming quantity of choices. The topics are organized into a
more manageable number of ``problem types'', so the process can be viewed as
a two-step process, of selecting a problem type and then a topic.
To get a problem, you
begin by choosing either {\em Make a Graph}, {\em Enter a Problem}, or
{\em MathXpert Problem Library}. We will describe how each of these works in turn.
\subsection{Make a graph or enter a problem}
If you choose {\em Make a graph}, you will go to {\tt MakeGraph.php}, which presents
a choice of kinds of graph you can make. These choices correspond to problem types.
Similarly, {\em Enter a problem} leads to {\tt EnterProblem.php}, which presents
a choice of the kinds of problems you can solve. Having picked a problem type from
one of these pages, you go to an ``entry page'', where you can enter your actual problem.
You then click {\em Display} to confirm that you typed it correctly, and then
{\em Do the Math} or {\em Solve the Equation} or {\em Draw} to move on to the
calculation or graph.
These entry pages have names beginning with {\em Enter}; there are quite a few of them.
A few of them have include commands leading to, for example, {\tt OneGraph.php} or
{\tt SeveralGraphs.php}, but there is a tension between code re-use and code complexity,
as if the same code is used for several topics, there is a lot of echoing PHP into Javascript
that is hard to read and maintain, so I often chose to write separate code, whose common
parts I
pasted and edited.
\subsection{The arrow button}
In the entry pages, there is an ``arrow button'' to the right of the first entry field.
Clicking that button picks a random topic (under the problem type you have chosen) and a
random problem from the Problem Libary. If you do not have a particular problem
already in mind, this is an easy way to get a problem; and you also can edit that
problem. The code to handle the arrow button is in {\tt arrowButton.js}. It is a bit
tricky as it involves creating new entry fields dynamically. For example if the random
problem is three linear equations, we will need to create a new entry field for the
third equation.
\subsection{MathXpert Problem Library}
This choice leads you to a three-column selector control, which allows you to
select a problem type, a topic, and a problem. The currently selected problem is
visible against a light blue background below the selector. You have two buttons
at the top of the page: {\em Accept selected problem} and {\em Edit selected problem}.
If you accept, you will go immediate to either GraphDoc.php or SymbolicDoc.php.
Problem selection is finished.
I wrote page {\tt GetProblem.php}, which downloads the entire MathXpert Problem Library,
some 6500 problems, so it can be examined by the selector control. That, however,
took an unacceptably long time. So, I wrote the much more complex GetProblemAsync.php,
which downloads the problems asynchronously, so the scrolling selector control is
immediately responsive. Any programmer who wants to study this code should probably
first look at the synchronous version, which is not actually used now, but still
included for study.
At the top of {\tt GetProblem.php}, you have two buttons: {\em Accept Selected Problem}
and {\em Edit Selected Problem}. Choosing {\em Edit} takes you to the appropriate entry
page, with the selected problem pre-entered. (This is accomplished using the same
code as the arrow button uses, but for the selected problem rather than a random problem.)
Choosing {\em Accept} takes you directly to either GraphDoc.php or SymbolicDoc.php.
Problem selection is finished.
\end{document}
\section{Opportunities for open-source developers}
There is work to be done just in improving Web MathXpert: First, the demonstration interfaces can be made
more professional. Second, browsers on various devices and operating systems
can be supported.
But beyond improving Web MathXpert, one can build various projects that {\em use}
Web MathXpert. The first one of these would be {\em Math Champs} (for want of
a better name at the moment). This would be based on an existing project
{\em Web Grades}, which I used when teaching calculus. If my students took
more than half the steps themselves, then when the problem was solved, they got a
button to submit the solution. A database would then record the username, topic,
and problem, and the date. Their homework grade was based on this data.
Since Web MathXpert is (deliberately) anonymous, it requires no credentials, and
keeps no records. {\em Math Champs}, on the other hand, would need to maintain
a database of its users and what problems they have solved. To facilitate
communication with programs like {\em MathChamps}, Web MathXpert keeps track of
a ``user score'' on each symbolic problem. This is the percentage of steps that
were not taken with the assistance of AutoStep or AutoFinish.%
\footnote{Of course, nothing prevents a determined student from repeatedly
using Showstep and Undo, and then taking that step again manually. But a student
who did this would learn a lot, and probably deserve the resulting high user score.}
In Web Grades, if your user score exceeded 50\%, you would get a choice ``submit as homework''
when your solution was complete. In Web MathXpert, you will get a button {\em Share}.
Clicking that button gives you
would be similar, but would allow anyone to
register. The Engine would not be involved at all in direct communication with
Math Champs. The database would be maintained as usual with PHP/SQL, and the
Web MathXpert client would be responsible for logging in the user, presenting
the {\em Submit} button after solution, and telling the Math Champs server to
record the new data. {\em MathChamps} can then, for example, keep a public ``leaderboard''
to show who solved the most problems that day, that week, etc. Maybe some
students want to play that game. It should be easy for a teacher to use the
data from {\em MathChamps} for grading purposes, too. Note that no username
is needed to use Web MathXpert, which requires and maintains no data whatsoever.
Another project would involve the solution of word problems. Video explanations
could connect to MathXpert when the solution requires calculation.
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists