Simplifier added for polynomial +, -, and *

This is a squashed commit of a bunch of changes I made,
and I provided some reasoning and notes for reference later on.

-- Added simplify keyword.
-- Now make copies before reducing, normalization, etc.
-- Added '--normalize' flag to show the normalized form of the tree.
-- Added node.strict_match().
    This is just a direct comparison, node-by-node for equality.
-- Added node.construct() to lighten syntax in visitors.
-- Added a commutative attribute to InfixOp classes.
-- node.copy now defaults to a non-recursive copy.
-- Added BFS_MODE for the Printer visitor.
    The prints nodes in the order of a breadth first search.

-- Added Simplifier visitor.
    This is only lightly tested.

-- Added Flattener and Unflattener visitors.
    Normally, additions and multiplications parse as binary trees:
        1+2+3+4 --> (((1+2) + 3) + 4)
    The Flattener converts this to a tree with one root and 4 children,
    which I write as: '(1 + 2 + 3 + 4)'. The same can be done with
    multiplication.

    Obviously, the Unflattener will return the tree to a binary state.
    The associativity may be different than the original tree that
    was flattened.

-- Added Normalizer and Denormalizer visitors.
    Normalizer applies a few transformations which allows me to handle
    certain equivalent forms without considering each form separately.

    The Normalizer will also flatten and sort terms which takes care
    of reordering issues.
        For example: ((x^2 + 1) + (1 + x^2)) has x^2 terms on opposite
        sides of the tree. That is, the expression can be simplified
        but neither (x^2 + 1) nor (1 + x^2) can be simplfied
        immediately. After normalization this will become
        (1 + 1 + x^2 + x^2), and then you can pairwise simplify (1+1)
        and (x^2 + x^2) to get (2 + 2*x^2).

    The Denormalizer undoes transformations applied by the Normalizer.

    NOTE:
    This is still very slow, which is mainly due to the sorting.
    I get a string for each child, recursively, during sorting.
    This turns into an exponential amount of work:
        for child in children:
            child.children.sort()
    This calls str once for every node in the tree. str(n) makes a linear
    pass over the subtree rooted at the n. This hits the root node once,
    nodes at level 2 twice, nodes at level 3 three times, etc. This is:
        1 + 2 * <#nodes in level 2> + 3 * <#nodes in level 3> + ...
    If the tree is binary:
        1 + 2 * 2 + 3 * 2^2 + 4 * 2^3 + ...
      = Sum from i=1 to n of (i * 2^(i-1))
      = 2^n * n - 2^n + 1

-- Added a Sorter visitor.
    This can be used to sort child nodes according to various methods.
    This is used, along with the Normalizer, to avoid having to
    handle non-commutative cases twice.

    There are different modes that offere different levels of performance
    versus the usefulness of the sort. The one I like most but which is least
    efficient is by sorting child nodes according to a string
    "<expr_type><tree_repr>", which puts ConstantExprs before PolynomialExprs
    and also sorts within similarly-type nodes to put, e.g., "3" before "3*x".

    Consider the following tree:
        ((3*x) + x + (2*x))
    This will flatten/sort to something like:
        (x + (2*x) + (3*x))