reform 0.1.0

A symbolic manipulation toolkit which aims to handle expressions with billions of terms, taking up terabytes of diskspace.
Documentation
Pattern matching
================

Pattern matching is an essential part of a term manipulation system. It provides a way to
modify a term by its shape and relations instead of by the actual contents. 
We introduce `wildcards`, which are denoted
as letters followed by a question mark, to match to variables, numbers, and subexpressions.

.. note::

    To see the output for the following examples, either a ``print`` has to be added to the source code,
    or reFORM must be run with the ``-v`` command line option.

For example:

.. code-block:: reform

    expr F = f(5);
    apply {
        id f(x?) = f(x? + 1);
    }

will match the wildcard ``x?`` to ``5``, consequently add 1 to it, and yield

.. code-block:: reform

    f(6)

.. note::

    Contrary to Form, the question mark is repeated on the right hand side!

A wildcard will match any function argument if it occurs by itself 


.. code-block:: reform

    expr F = f(1+x,3);
    apply {
        id f(x?,3) = x?;
    }

yields

.. code-block:: reform

    1+x

A pattern at the ground level (not inside functions) can match to 
a subpart of the factors:

.. code-block:: reform

    expr F = f(1)*f(f(4*x));
    apply {
        id f(f(y?)) = y?;
    }

yields

.. code-block:: reform

    f(1)*x*4


If the pattern contains a term with multiple wildcards, the number needs
to match exactly.

.. code-block:: reform

    expr F = f(x1*x2);
    apply {
        id f(y1?*y2?) = f(y1,y2);
    }


yields

.. code-block:: reform

    1+x

So, 

.. code-block:: reform

    expr F = f(x1*x2*x3);
    apply {
        id f(y1?*y2?) = f(y1,y2);
    }

does not match. In this previous case, there are multiple options. ``y1`` could have matched to 
``x1`` and to ``x2``. The match that reFORM picks is deterministic. If you want to obtain `all` options,
see the ``id all`` option.


A wildcard can be restricted to a certain set of options:

.. code-block:: reform

    expr F = f(f(4))*f(f(3));
    apply {
        id f(x1?{f(4)}) = f(x1);
    }

will only match to ``f(4)``. The restriction can be any expression. However, at the moment
they are not allowed to include any wildcards. Additionally, for numbers you can use
number ranges in the sets: ``<=5,>=5,<5,>5`` to match a number in a range relative to a
reference number (5 in this example.)

.. code-block:: reform

    expr F = f(1)*f(4);
    apply {
        id f(x?{>3}) = f(x1 + 1);
    }

will only change ``f(4)``.

Fractional numbers are allowed, i.e., ``f(x?{>1/2})`` will work as intended.

A function name can also be a wildcard:

.. code-block:: reform

    expr F = g(4);
    apply {
        id f?(x?) = f?(x? + 1);
    }

yields ``g(5)``.

Ranged wildcards
----------------

The pattern matcher can also match ranges of function arguments using
ranged wildcards. These wildcard have a question mark on the front: e.g., ``?a``.

For example:

.. code-block:: reform

    expr F = f(1,2,3,4);
    apply {
        id f(?a,4) = f(?a);
    }

yields

.. code-block:: reform

    f(1,2,3)

Using a combination of ranged wildcards and wildcards, some complex patterns can
be matched:

.. code-block:: reform

    expr F = f(1,2,f(3),4)*f(1,2,f(3));
    apply {
        id f(?a,x?,?b)*f(?c,x?,?d) = f(?a,?b,?c,?d);
    }

yields

.. code-block:: reform

    f(1,2,4,1,2)

Note that ranged wildcards can be empty.

Many-mode
----------------

The ``many`` option can be used to let reFORM apply a pattern to the input
as often as possible.

.. code-block:: reform

    expr F = x^2;
    apply {
        id many x = 5;
    }

yields

.. code-block:: reform

    25

A more complicated example is shown below:

.. code-block:: reform

    expr F = x*y^4*z;
    apply {
        id many x?*y^2 = f(x?);
    }

yields

.. code-block:: reform

    f(x)*f(z)



Obtaining all matches
---------------------

All matches can be obtained using the ``all`` option to ``id``.
For example:

.. code-block:: reform

    expr F = f(1,2,f(x1*x2,x3*x4,x5*x6),x1*x3,x3*x5);
    apply {
        id all f(1,2,f(?a,x1?*x2?,?b),?c,x1?*x3?) = f(x1,x2,x3);
    }

yields

.. code-block:: reform

    f(x3,x4,x5)+f(x5,x6,x3)