+@node Information About Expressions, Substituting Symbols, Methods and Functions, Methods and Functions
+@c node-name, next, previous, up
+@section Getting information about expressions
+
+@subsection Checking expression types
+@cindex @code{is_ex_of_type()}
+@cindex @code{ex_to_numeric()}
+@cindex @code{ex_to_@dots{}}
+@cindex @code{Converting ex to other classes}
+@cindex @code{info()}
+
+Sometimes it's useful to check whether a given expression is a plain number,
+a sum, a polynomial with integer coefficients, or of some other specific type.
+GiNaC provides two functions for this (the first one is actually a macro):
+
+@example
+bool is_ex_of_type(const ex & e, TYPENAME t);
+bool ex::info(unsigned flag);
+@end example
+
+When the test made by @code{is_ex_of_type()} returns true, it is safe to
+call one of the functions @code{ex_to_@dots{}}, where @code{@dots{}} is
+one of the class names (@xref{The Class Hierarchy}, for a list of all
+classes). For example, assuming @code{e} is an @code{ex}:
+
+@example
+@{
+ @dots{}
+ if (is_ex_of_type(e, numeric))
+ numeric n = ex_to_numeric(e);
+ @dots{}
+@}
+@end example
+
+@code{is_ex_of_type()} allows you to check whether the top-level object of
+an expression @samp{e} is an instance of the GiNaC class @samp{t}
+(@xref{The Class Hierarchy}, for a list of all classes). This is most useful,
+e.g., for checking whether an expression is a number, a sum, or a product:
+
+@example
+@{
+ symbol x("x");
+ ex e1 = 42;
+ ex e2 = 4*x - 3;
+ is_ex_of_type(e1, numeric); // true
+ is_ex_of_type(e2, numeric); // false
+ is_ex_of_type(e1, add); // false
+ is_ex_of_type(e2, add); // true
+ is_ex_of_type(e1, mul); // false
+ is_ex_of_type(e2, mul); // false
+@}
+@end example
+
+The @code{info()} method is used for checking certain attributes of
+expressions. The possible values for the @code{flag} argument are defined
+in @file{ginac/flags.h}, the most important being explained in the following
+table:
+
+@cartouche
+@multitable @columnfractions .30 .70
+@item @strong{Flag} @tab @strong{Returns true if the object is@dots{}}
+@item @code{numeric}
+@tab @dots{}a number (same as @code{is_ex_of_type(..., numeric)})
+@item @code{real}
+@tab @dots{}a real integer, rational or float (i.e. is not complex)
+@item @code{rational}
+@tab @dots{}an exact rational number (integers are rational, too)
+@item @code{integer}
+@tab @dots{}a (non-complex) integer
+@item @code{crational}
+@tab @dots{}an exact (complex) rational number (such as @math{2/3+7/2*I})
+@item @code{cinteger}
+@tab @dots{}a (complex) integer (such as @math{2-3*I})
+@item @code{positive}
+@tab @dots{}not complex and greater than 0
+@item @code{negative}
+@tab @dots{}not complex and less than 0
+@item @code{nonnegative}
+@tab @dots{}not complex and greater than or equal to 0
+@item @code{posint}
+@tab @dots{}an integer greater than 0
+@item @code{negint}
+@tab @dots{}an integer less than 0
+@item @code{nonnegint}
+@tab @dots{}an integer greater than or equal to 0
+@item @code{even}
+@tab @dots{}an even integer
+@item @code{odd}
+@tab @dots{}an odd integer
+@item @code{prime}
+@tab @dots{}a prime integer (probabilistic primality test)
+@item @code{relation}
+@tab @dots{}a relation (same as @code{is_ex_of_type(..., relational)})
+@item @code{relation_equal}
+@tab @dots{}a @code{==} relation
+@item @code{relation_not_equal}
+@tab @dots{}a @code{!=} relation
+@item @code{relation_less}
+@tab @dots{}a @code{<} relation
+@item @code{relation_less_or_equal}
+@tab @dots{}a @code{<=} relation
+@item @code{relation_greater}
+@tab @dots{}a @code{>} relation
+@item @code{relation_greater_or_equal}
+@tab @dots{}a @code{>=} relation
+@item @code{symbol}
+@tab @dots{}a symbol (same as @code{is_ex_of_type(..., symbol)})
+@item @code{list}
+@tab @dots{}a list (same as @code{is_ex_of_type(..., lst)})
+@item @code{polynomial}
+@tab @dots{}a polynomial (i.e. only consists of sums and products of numbers and symbols with positive integer powers)
+@item @code{integer_polynomial}
+@tab @dots{}a polynomial with (non-complex) integer coefficients
+@item @code{cinteger_polynomial}
+@tab @dots{}a polynomial with (possibly complex) integer coefficients (such as @math{2-3*I})
+@item @code{rational_polynomial}
+@tab @dots{}a polynomial with (non-complex) rational coefficients
+@item @code{crational_polynomial}
+@tab @dots{}a polynomial with (possibly complex) rational coefficients (such as @math{2/3+7/2*I})
+@item @code{rational_function}
+@tab @dots{}a rational function (@math{x+y}, @math{z/(x+y)})
+@item @code{algebraic}
+@tab @dots{}an algebraic object (@math{sqrt(2)}, @math{sqrt(x)-1})
+@end multitable
+@end cartouche
+
+
+@subsection Accessing subexpressions
+@cindex @code{nops()}
+@cindex @code{op()}
+@cindex @code{has()}
+@cindex container
+@cindex @code{relational} (class)
+
+GiNaC provides the two methods
+
+@example
+unsigned ex::nops();
+ex ex::op(unsigned i);
+@end example
+
+for accessing the subexpressions in the container-like GiNaC classes like
+@code{add}, @code{mul}, @code{lst}, and @code{function}. @code{nops()}
+determines the number of subexpressions (@samp{operands}) contained, while
+@code{op()} returns the @code{i}-th (0..@code{nops()-1}) subexpression.
+In the case of a @code{power} object, @code{op(0)} will return the basis
+and @code{op(1)} the exponent.
+
+The left-hand and right-hand side expressions of objects of class
+@code{relational} (and only of these) can also be accessed with the methods
+
+@example
+ex ex::lhs();
+ex ex::rhs();
+@end example
+
+Finally, the method
+
+@example
+bool ex::has(const ex & other);
+@end example
+
+checks whether an expression contains the given subexpression @code{other}.
+This only works reliably if @code{other} is of an atomic class such as a
+@code{numeric} or a @code{symbol}. It is, e.g., not possible to verify that
+@code{a+b+c} contains @code{a+c} (or @code{a+b}) as a subexpression.
+
+
+@subsection Comparing expressions
+@cindex @code{is_equal()}
+@cindex @code{is_zero()}
+
+Expressions can be compared with the usual C++ relational operators like
+@code{==}, @code{>}, and @code{<} but if the expressions contain symbols,
+the result is usually not determinable and the result will be @code{false},
+except in the case of the @code{!=} operator. You should also be aware that
+GiNaC will only do the most trivial test for equality (subtracting both
+expressions), so something like @code{(pow(x,2)+x)/x==x+1} will return
+@code{false}.
+
+Actually, if you construct an expression like @code{a == b}, this will be
+represented by an object of the @code{relational} class (@xref{Relations}.)
+which is not evaluated until (explicitly or implicitely) cast to a @code{bool}.
+
+There are also two methods
+
+@example
+bool ex::is_equal(const ex & other);
+bool ex::is_zero();
+@end example
+
+for checking whether one expression is equal to another, or equal to zero,
+respectively.
+
+@strong{Warning:} You will also find an @code{ex::compare()} method in the
+GiNaC header files. This method is however only to be used internally by
+GiNaC to establish a canonical sort order for terms, and using it to compare
+expressions will give very surprising results.
+
+
+@node Substituting Symbols, Polynomial Arithmetic, Information About Expressions, Methods and Functions
+@c node-name, next, previous, up
+@section Substituting symbols
+@cindex @code{subs()}
+
+Symbols can be replaced with expressions via the @code{.subs()} method:
+
+@example
+ex ex::subs(const ex & e);
+ex ex::subs(const lst & syms, const lst & repls);
+@end example
+
+In the first form, @code{subs()} accepts a relational of the form
+@samp{symbol == expression} or a @code{lst} of such relationals. E.g.
+
+@example
+@{
+ symbol x("x"), y("y");
+ ex e1 = 2*x^2-4*x+3;
+ cout << "e1(7) = " << e1.subs(x == 7) << endl;
+ ex e2 = x*y + x;
+ cout << "e2(-2, 4) = " << e2.subs(lst(x == -2, y == 4)) << endl;
+@}
+@end example
+
+will print @samp{73} and @samp{-10}, respectively.
+
+If you specify multiple substitutions, they are performed in parallel, so e.g.
+@code{subs(lst(x == y, y == x))} exchanges @samp{x} and @samp{y}.
+
+The second form of @code{subs()} takes two lists, one for the symbols and
+one for the expressions to be substituted (both lists must contain the same
+number of elements). Using this form, you would write @code{subs(lst(x, y), lst(y, x))}
+to exchange @samp{x} and @samp{y}.
+
+
+@node Polynomial Arithmetic, Rational Expressions, Substituting Symbols, Methods and Functions