/** @page libsbml-csharp-math Mathematical Expressions and their Manipulation

This section describes libSBML's facilities for working with SBML
representations of mathematical expressions.

@section math-overview Basic concepts

LibSBML uses <a
href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">Abstract Syntax
Trees</a> (ASTs) to provide a canonical, in-memory representation for all
mathematical formulas regardless of their original format (i.e., C-like
infix strings or <a href="http://www.w3.org/Math/">MathML</a>).  In
libSBML, an AST is a collection of one or more objects of type @link
libsbml.ASTNode ASTNode@endlink.  An AST @em node in libSBML is a recursive
structure containing a pointer to the node's value (which might be, for
example, a number or a symbol) and a list of children nodes.  Each @link
libsbml.ASTNode ASTNode@endlink node may have none, one, two, or more child
depending on its type.  The following diagram illustrates an example of how
the mathematical expression <code>"1 + 2"</code> is represented as an AST
with one @em plus node having two @em integer children nodes for the
numbers @c 1 and @c 2.  The figure also shows the corresponding <a
href="http://www.w3.org/Math/">MathML&nbsp;2.0</a> representation:

@htmlinclude astnode-illustration.html

The following are noteworthy about the AST representation in libSBML:

@li A numerical value represented in <a
href="http://www.w3.org/Math/">MathML&nbsp;2.0</a> as a real number with an
exponent is preserved as such in the AST node representation, even if the
number could be stored in a @c double data type.  This is done so that when
an SBML model is read in and then written out again, the amount of change
introduced by libSBML to the SBML during the round-trip activity is
minimized.
 
@li Rational numbers are represented in an AST node using separate
numerator and denominator values.  These can be retrieved using the methods
libsbml.ASTNode.getNumerator() and libsbml.ASTNode.getDenominator().

@li The children of an @link libsbml.ASTNode ASTNode@endlink are other
@link libsbml.ASTNode ASTNode@endlink objects.  The list of
children is empty for nodes that are leaf elements, such as numbers.
For nodes that are actually roots of expression subtrees, the list of
children points to the parsed objects that make up the rest of the
expression.

For many applications, the details of ASTs are irrelevant because the
applications can use the text-string based translation functions such as
libsbml.libsbml.formulaToString() and libsbml.libsbml.parseFormula().  If
you find the complexity of using the AST representation of expressions too
high for your purposes, perhaps the string-based functions will be more
suitable.

Finally, it is worth noting that the AST and MathML handling code in
libSBML remains written in C, not C++, as all of libSBML was originally
written in C.  Readers may occasionally wonder why some aspects are more
C-like than following a C++ style, and that's the reason.


@section math-convert Converting between ASTs and Text Strings

SBML Level 2 represents mathematical expressions using <a
href="http://www.w3.org/Math/">MathML&nbsp;2.0</a> (more specifically, a
subset of the <em>content</em> portion of MathML&nbsp;2.0), but most
software applications using libSBML do not use MathML directly.  Instead,
applications generally either interact with mathematics in text-string
form, or else they use the API for working with Abstract Syntax Trees
(described below).  LibSBML provides support for both approaches.  The
libSBML formula parser has been carefully engineered so that
transformations from MathML to infix string notation <em>and back</em> is
possible with a minimum of disruption to the structure of the mathematical
expression.

The example below shows a simple program that, when run, takes a MathML
string compiled into the program, converts it to an AST, converts
<em>that</em> to an infix representation of the formula, compares it to the
expected form of that formula, and finally translates that formula back to
MathML and displays it.  The output displayed on the terminal should have
the same structure as the MathML it started with.  The program is a simple
example of using the various MathML and AST reading and writing methods,
and shows that libSBML preserves the ordering and structure of the
mathematical expressions.

@verbatim
using System;
using libsbml;

public class Example
{
    public static void Main(String[] args)
    {
        String expected = "1 + f(x)";
        String input_mathml = "<?xml version='1.0' encoding='UTF-8'?>"
          + "<math xmlns='http://www.w3.org/1998/Math/MathML'>"
          + "  <apply> <plus/> <cn> 1 </cn>"
          + "                  <apply> <ci> f </ci> <ci> x </ci> </apply>"
          + "  </apply>"
          + "</math>";

        ASTNode ast_result   = libsbml.libsbml.readMathMLFromString(input_mathml);
        String ast_as_string = libsbml.libsbml.formulaToString(ast_result);

        if (ast_as_string == expected)
        {
            Console.WriteLine("Got expected result.");
        }
        else
        {
            Console.WriteLine("Mismatch after readMathMLFromString().");
            Environment.Exit(1);
        }

        ASTNode new_mathml = libsbml.libsbml.parseFormula(ast_as_string);
        String new_string = libsbml.libsbml.writeMathMLToString(new_mathml);

        Console.WriteLine("Result of writing AST to string:");
        Console.WriteLine(new_string);
    }
}
@endverbatim

The text-string form of mathematical formulas produced by
libsbml.libsbml.formulaToString() and read by
libsbml.libsbml.parseFormula() are simple C-inspired infix notation taken
from SBML Level&nbsp;1.  It is summarized in the next section below.  A
formula in this text-string form therefore can be handed to a program that
understands SBML Level&nbsp;1 mathematical expressions, or used as part of
a translation system.  In summary, the functions available are the
following:

@li libsbml.libsbml.formulaToString(ASTNode) \f$\rightarrow\f$
@c string
reads an AST, converts it to a text string in SBML Level&nbsp;1 formula
syntax, and returns it.  The caller owns the character string returned and
should free it after it is no longer needed.

@li libsbml.libsbml.parseFormula(string) \f$\rightarrow\f$ @link libsbml.ASTNode ASTNode@endlink
reads a text-string containing a mathematical expression in
SBML Level&nbsp;1 syntax, and returns an AST corresponding to the
expression.


@section math-diffs The String Formula Syntax and Differences with MathML

The text-string formula syntax is an infix notation essentially derived
from the syntax of the C programming language and was originally used in
SBML Level&nbsp;1.  The formula strings may contain operators, function
calls, symbols, and white space characters.  The allowable white space
characters are tab and space.  The following are illustrative examples of
formulas expressed in the syntax:

@verbatim
0.10 * k4^2
@endverbatim
@verbatim
(vm * s1)/(km + s1)
@endverbatim

The following table shows the precedence rules in this syntax.  In the
Class column, @em operand implies the construct is an operand, @em prefix
implies the operation is applied to the following arguments, @em unary
implies there is one argument, and @em binary implies there are two
arguments.  The values in the Precedence column show how the order of
different types of operation are determined.  For example, the expression
<em>a * b + c</em> is evaluated as <em>(a * b) + c</em> because the @c *
operator has higher precedence.  The Associates column shows how the order
of similar precedence operations is determined; for example, <em>a - b +
c</em> is evaluated as <em>(a - b) + c</em> because the @c + and @c -
operators are left-associative.  The precedence and associativity rules are
taken from the C programming language, except for the symbol @c ^, which is
used in C for a different purpose.  (Exponentiation can be invoked using
either @c ^ or the function @c power.)

@htmlinclude  math-precedence-table.html

A program parsing a formula in an SBML model should assume that names
appearing in the formula are the identifiers of @link libsbml.Species
Species@endlink, @link libsbml.Parameter Parameter@endlink, @link
libsbml.Compartment Compartment@endlink, @link libsbml.FunctionDefinition
FunctionDefinition@endlink, or @link libsbml.Reaction Reaction@endlink
objects defined in a model.  When a function call is involved, the syntax
consists of a function identifier, followed by optional white space,
followed by an opening parenthesis, followed by a sequence of zero or more
arguments separated by commas (with each comma optionally preceded and/or
followed by zero or more white space characters), followed by a closing
parenthesis.  There is an almost one-to-one mapping between the list of
predefined functions available, and those defined in MathML.  All of the
MathML funcctions are recognized; this set is larger than the functions
defined in SBML Level 1.  In the subset of functions that overlap between
MathML and SBML Level 1, there exist a few differences.  The following
table summarizes the differences between the predefined functions in SBML
Level 1 and the MathML equivalents in SBML Level 2:

@htmlinclude math-functions.html


@section math-ast Methods for working with libSBML's Abstract Syntax Trees

Every @link libsbml.ASTNode ASTNode@endlink in a libSBML AST has an
associated type, a value taken from a set of constants with names beginning
with <code>AST_</code> and defined in the interface class @link
libsbml.libsbml libsbml@endlink.  The list of possible types is quite long,
because it covers all the mathematical functions that are permitted in
SBML's subset of MathML.  The values are shown in the following table;
their names hopefully evoke the construct that they represent:

<center>
<table width="80%" cellspacing="1" cellspacing="1" border="0">
 <tr><td><code></code></td><td><code></code></td><td><code></code></td></tr>
 <tr><td><code>AST_UNKNOWN</code></td><td><code>AST_FUNCTION_ARCCOTH</code></td><td><code>AST_FUNCTION_POWER</code></td></tr>
 <tr><td><code>AST_PLUS</code></td><td><code>AST_FUNCTION_ARCCSC</code></td><td><code>AST_FUNCTION_ROOT</code></td></tr>
 <tr><td><code>AST_MINUS</code></td><td><code>AST_FUNCTION_ARCCSCH</code></td><td><code>AST_FUNCTION_SEC</code></td></tr>
 <tr><td><code>AST_TIMES</code></td><td><code>AST_FUNCTION_ARCSEC</code></td><td><code>AST_FUNCTION_SECH</code></td></tr>
 <tr><td><code>AST_DIVIDE</code></td><td><code>AST_FUNCTION_ARCSECH</code></td><td><code>AST_FUNCTION_SIN</code></td></tr>
 <tr><td><code>AST_POWER</code></td><td><code>AST_FUNCTION_ARCSIN</code></td><td><code>AST_FUNCTION_SINH</code></td></tr>
 <tr><td><code>AST_INTEGER</code></td><td><code>AST_FUNCTION_ARCSINH</code></td><td><code>AST_FUNCTION_TAN</code></td></tr>
 <tr><td><code>AST_REAL</code></td><td><code>AST_FUNCTION_ARCTAN</code></td><td><code>AST_FUNCTION_TANH</code></td></tr>
 <tr><td><code>AST_REAL_E</code></td><td><code>AST_FUNCTION_ARCTANH</code></td><td><code>AST_LOGICAL_AND</code></td></tr>
 <tr><td><code>AST_RATIONAL</code></td><td><code>AST_FUNCTION_CEILING</code></td><td><code>AST_LOGICAL_NOT</code></td></tr>
 <tr><td><code>AST_NAME</code></td><td><code>AST_FUNCTION_COS</code></td><td><code>AST_LOGICAL_OR</code></td></tr>
 <tr><td><code>AST_NAME_TIME</code></td><td><code>AST_FUNCTION_COSH</code></td><td><code>AST_LOGICAL_XOR</code></td></tr>
 <tr><td><code>AST_CONSTANT_E</code></td><td><code>AST_FUNCTION_COT</code></td><td><code>AST_RELATIONAL_EQ</code></td></tr>
 <tr><td><code>AST_CONSTANT_FALSE</code></td><td><code>AST_FUNCTION_COTH</code></td><td><code>AST_RELATIONAL_GEQ</code></td></tr>
 <tr><td><code>AST_CONSTANT_PI</code></td><td><code>AST_FUNCTION_CSC</code></td><td><code>AST_RELATIONAL_GT</code></td></tr>
 <tr><td><code>AST_CONSTANT_TRUE</code></td><td><code>AST_FUNCTION_CSCH</code></td><td><code>AST_RELATIONAL_LEQ</code></td></tr>
 <tr><td><code>AST_LAMBDA</code></td><td><code>AST_FUNCTION_EXP</code></td><td><code>AST_RELATIONAL_LT</code></td></tr>
 <tr><td><code>AST_FUNCTION</code></td><td><code>AST_FUNCTION_FACTORIAL</code></td><td><code>AST_RELATIONAL_NEQ</code></td></tr>
 <tr><td><code>AST_FUNCTION_ABS</code></td><td><code>AST_FUNCTION_FLOOR</code></td><td><code></code></td></tr>
 <tr><td><code>AST_FUNCTION_ARCCOS</code></td><td><code>AST_FUNCTION_LN</code></td></tr>
 <tr><td><code>AST_FUNCTION_ARCCOSH</code></td><td><code>AST_FUNCTION_LOG</code></td></tr>
 <tr><td><code>AST_FUNCTION_ARCCOT</code></td><td><code>AST_FUNCTION_PIECEWISE</code></td></tr>
</table>
</center>

There are a number of methods for interrogating the type of an ASTNode and
for testing whether a node belongs to a general category of constructs.
The methods are the following:

@li @c int @link libsbml.ASTNode.getType() ASTNode.getType()@endlink returns the type of
this AST node.

@li @c bool @link libsbml.ASTNode.isConstant() ASTNode.isConstant()@endlink returns @c true if this
AST node is a MathML constant (@c true, @c false, @c pi, @c exponentiale),
@c false otherwise.

@li @c bool @link libsbml.ASTNode.isBoolean() ASTNode.isBoolean()@endlink returns @c true if this
AST node returns a boolean value (by being either a logical operator, a
relational operator, or the constant @c true or @c false).

@li @c bool @link libsbml.ASTNode.isFunction() ASTNode.isFunction()@endlink returns @c true if this
AST node is a function (i.e., a MathML defined function such as @c exp or
else a function defined by a FunctionDefinition in the Model).

@li @c bool @link libsbml.ASTNode.isInfinity() ASTNode.isInfinity()@endlink returns @c true if this
AST node is the special IEEE 754 value infinity.

@li @c bool @link libsbml.ASTNode.isInteger() ASTNode.isInteger()@endlink returns @c true if this
AST node is holding an integer value.

@li @c bool @link libsbml.ASTNode.isNumber() ASTNode.isNumber()@endlink  returns @c true if this
AST node is holding any number.

@li @c bool @link libsbml.ASTNode.isLambda() ASTNode.isLambda()@endlink  returns @c true if this
AST node is a MathML @c lambda construct.

@li @c bool @link libsbml.ASTNode.isLog10() ASTNode.isLog10()@endlink  returns @c true if this
AST node represents the @c log10 function, specifically, that its type is
@c AST_FUNCTION_LOG and it has two children, the first of which is an integer
equal to 10.

@li @c bool @link libsbml.ASTNode.isLogical() ASTNode.isLogical()@endlink  returns @c true if this
AST node is a logical operator (@c and, @c or, @c not, @c xor).

@li @c bool @link libsbml.ASTNode.isName() ASTNode.isName()@endlink  returns @c true if this
AST node is a user-defined name or (in SBML Level 2) one of the two special
@c csymbol constructs "delay" or "time".

@li @c bool @link libsbml.ASTNode.isNaN() ASTNode.isNaN()@endlink  returns @c true if this
AST node has the special IEEE 754 value "not a number" (NaN).

@li @c bool @link libsbml.ASTNode.isNegInfinity() ASTNode.isNegInfinity()@endlink  returns @c true if this
AST node has the special IEEE 754 value of negative infinity.

@li @c bool @link libsbml.ASTNode.isOperator() ASTNode.isOperator()@endlink  returns @c true if this
AST node is an operator (e.g., @c +, @c -, etc.)

@li @c bool @link libsbml.ASTNode.isPiecewise() ASTNode.isPiecewise()@endlink  returns @c true if this
AST node is the MathML @c piecewise function.

@li @c bool @link libsbml.ASTNode.isRational() ASTNode.isRational()@endlink  returns @c true if this
AST node is a rational number having a numerator and a denominator.

@li @c bool @link libsbml.ASTNode.isReal() ASTNode.isReal()@endlink  returns @c true if this
AST node is a real number (specifically, @c AST_REAL_E or @c AST_RATIONAL).

@li @c bool @link libsbml.ASTNode.isRelational() ASTNode.isRelational()@endlink  returns @c true if this
AST node is a relational operator.

@li @c bool @link libsbml.ASTNode.isSqrt() ASTNode.isSqrt()@endlink  returns @c true if this
AST node is the square-root operator

@li @c bool @link libsbml.ASTNode.isUMinus() ASTNode.isUMinus()@endlink  returns @c true if this
AST node is a unary minus.

@li @c bool @link libsbml.ASTNode.isUnknown() ASTNode.isUnknown()@endlink  returns @c true if this
AST node's type is unknown.


Programs manipulating AST node structures should check the type of a given
node before calling methods that return a value from the node.  The
following meethods are available for returning values from nodes:

@li @c int @link libsbml.ASTNode.getInteger() ASTNode.getInteger()@endlink 

@li @c char @link libsbml.ASTNode.getCharacter() ASTNode.getCharacter()@endlink 

@li @c string @link libsbml.ASTNode.getName() ASTNode.getName()@endlink 

@li @c int @link libsbml.ASTNode.getNumerator() ASTNode.getNumerator()@endlink 

@li @c int @link libsbml.ASTNode.getDenominator() ASTNode.getDenominator()@endlink 

@li @c double @link libsbml.ASTNode.getReal() ASTNode.getReal()@endlink 

@li @c double @link libsbml.ASTNode.getMantissa() ASTNode.getMantissa()@endlink 

@li @c int @link libsbml.ASTNode.getExponent() ASTNode.getExponent()@endlink 

Finally (and rather predictably), libSBML provides methods for setting the
values of AST nodes.

@li @link libsbml.ASTNode.setCharacter(char)
ASTNode.setCharacter(char)@endlink sets the value of this @link
libsbml.ASTNode ASTNode@endlink to the given character.  If character is one
of @c +, @c -, @c *, @c / or @c ^, the node type will be to the appropriate
operator type.  For all other characters, the node type will be set to @c
AST_UNKNOWN.

@li @link libsbml.ASTNode.setName(string) ASTNode.setName(string)@endlink
sets the value of this AST node to the given name.  The node type will be
set (to @c AST_NAME) <em>only if</em> the AST node was previously an
operator (@link libsbml.ASTNode.isOperator() isOperator()@endlink
<code>!= 0</code>) or number (@link libsbml.ASTNode.isNumber()
isNumber()@endlink <code>!= 0</code>).  This allows names to be set for
@c AST_FUNCTIONs and the like.

@li @link libsbml.ASTNode.setValue(int) ASTNode.setValue(int)@endlink
sets the value of the node to the given integer.

@li @link libsbml.ASTNode.setValue(int, int) ASTNode.setValue(int,
int)@endlink sets the value of this @link libsbml.ASTNode ASTNode@endlink
to the given rational in two parts: the numerator and denominator.  The
node type is set to @c AST_RATIONAL.

@li @link libsbml.ASTNode.setValue(double) ASTNode.setValue(double)@endlink
sets the value of this @link libsbml.ASTNode ASTNode@endlink to the given
floating-point number and sets the node type to @c AST_REAL.

@li @link libsbml.ASTNode.setValue(double, int) ASTNode.setValue(double,
int)@endlink sets the value of this @link libsbml.ASTNode ASTNode@endlink
to the given floating-point number in two parts: the mantissa and the
exponent.  The node type is set to @c AST_REAL_E.


The following are some miscellaneous methods for manipulating ASTs:

@li @link libsbml.ASTNode ASTNode@endlink @link
libsbml.ASTNode.ASTNode(int) ASTNode.ASTNode(int)@endlink creates a new
@link libsbml.ASTNode ASTNode@endlink object and returns a pointer to it.
The returned node will have the type identified by the code passed as the
argument, or a type of @c AST_UNKNOWN if no type is explicitly given or the
type code is unrecognized.

@li unsigned int @link libsbml.ASTNode.getNumChildren()
ASTNode.getNumChildren()@endlink returns the number of children of this AST
node or 0 is this node has no children.

@li @link libsbml.ASTNode.addChild(ASTNode)
ASTNode.addChild(ASTNode)@endlink adds the given node as a child of this
AST node.  Child nodes are added in left-to-right order.

@li @link libsbml.ASTNode.prependChild(ASTNode)
ASTNode.prependChild(ASTNode)@endlink adds the given node as a child of
this AST node.  This method adds child nodes in right-to-left order.

@li @link libsbml.ASTNode ASTNode@endlink @link libsbml.ASTNode.getChild (long) ASTNode.getChild
(long)@endlink returns the nth child of this AST node or @c NULL if
this node has no nth child (n &gt; (@link libsbml.ASTNode.getNumChildren()
ASTNode.getNumChildren()@endlink - 1)).

@li @link libsbml.ASTNode ASTNode@endlink @link libsbml.ASTNode.getLeftChild()
ASTNode.getLeftChild()@endlink returns the left child of this AST node.
This is equivalent to @link libsbml.ASTNode.getChild()
ASTNode.getChild(0)@endlink;

@li @link libsbml.ASTNode ASTNode@endlink @link libsbml.ASTNode.getRightChild()
ASTNode.getRightChild()@endlink returns the right child of this AST node or
@c NULL if this node has no right child.

@li @link libsbml.ASTNode.swapChildren(ASTNode)
ASTNode.swapChildren(ASTNode)@endlink swaps the children of this @link libsbml.ASTNode ASTNode@endlink
with the children of @c that @link libsbml.ASTNode ASTNode@endlink.

@li @link libsbml.ASTNode.setType(int) ASTNode.setType(int)@endlink
sets the type of this @link libsbml.ASTNode ASTNode@endlink to the type identified by the
type code passed as argument, or to @c AST_UNKNOWN if the type
is unrecognized.

@section math-reading Reading and Writing MathML from/to ASTs

As mentioned above, applications often can avoid working with raw MathML by
using either libSBML's text-string interface or the AST API.  However, when
needed, reading MathML content directly and creating ASTs, as well as the
converse task of writing MathML, is easily done using two methods designed
for this purpose:

@li @link libsbml.ASTNode ASTNode@endlink @link
libsbml.libsbml.readMathMLFromString(string)
readMathMLFromString(string)@endlink reads raw MathML from a text string,
constructs an AST from it, then returns the root @link libsbml.ASTNode
ASTNode@endlink of the resulting expression tree.

@li @c string @link libsbml.libsbml.writeMathMLToString(ASTNode)
writeMathMLToString(ASTNode)@endlink writes an AST to a string.  The caller
owns the character string returned and should free it after it is no longer
needed.



*/
