Added a profile target to the make file
Added a test for static analysis which should report that we have defined a rate name without using it
Implemented a warning for rate names which are defined but not used.
To do this, it made sense to make TopRate an expression, since we have to
visit all of the expressions in a model. Now TopRate can only occur
(because of the parser) at the top level of an expression in a prefix node,
it cannot occur generally within an expression. Even still, I felt that
this was a bit cleaner than checking for that. This way, if we ever do
allow TopRate to be part of an expression (for example even as simply a
constant definition) then we won't have to make TopRate an expression
because it already will be.

As for our representation of warnings and errors, they are currently as a
list. This is a little bogus since we probably do not wish to make the same
warning more than once, for example we may have several uses of an
undefined rate name but we likely only wish to report that once. Although
there are other ways around that. This made sense because we test using
equality on the warning representation, which is a tad cludgy but means
that we are not testing on the strings thus produced (though we could
relatively easily do that).
Minor fixes to satisfy lint
Attempting a large refactor of the representation of expressions. I think I
can make this significantly simpler. I will just have one representation of
expressions which may have zero child argument expressions. They may also
have either their internal 'number' or 'name' properties set to something
which is not None.

Currently a large number of our tests are failing as they depended upon the
previous representation of expressions. I am hopeful though that this
refactoring will signficantly reduce the complexity of expressions and
allow us to implement 'reduce_expr' in a way that I am happy with.
Fixed the new expression representation's definition of 'get_value' so that now the 'TextExpression' test works
Updated the test for a missing name to raise an assertion error rather than a key error. I think this is correct since we should be checking that all expressions can be evaluated with static analysis, so in a normal run this should never occur, so it really is an assertion error.
Removed the test of the base expression visitor since I'm quite confident that we now have no need for expression visitors.
Updated expressions so that they can be compared for equality, and thus be amenable to testing. Also updated the reduction of a list of definitions, a little cleaner now, especially for the usual case of reducing the definitions.
Updated comments regarding the reduction of definitions.
Actually use inplace=False for obtaining the current values of expression in a definition list.
Added used_names to our Expression class, it is far easier than the expression visitor before, I think.
Re-introduced definition_environment which was actually used by one of the test fixtures, I'm not sure it is not being a bit too clever for its own good.
Fixed the binary operator class methods tests.
Think I fixed the removal of rate law expressions, in that I've translated the rate-law removal expression visitor into a simple function over expressions. Unfortunately there are other errors in the Bio-PEPA tests so I am not quite sure that that has worked yet.
Fixed the PepaUnusedRateName test by the simple update of the code which got the used pepa rate names, which no longer uses an expression visitor.
Fixed the TestApparentRateWithConstantDefs test by simply using 'reduce_definitions rather than constant_def_environment in the concretiser. This way around should make it easier to encorporate functional rates if we have to.
A bit of work required to get the Bio-PEPA tests to work. There is a
slightly bit of tension between the new design. It means that we have to
convert all of the incoming populations (from the numpy ode solver) into
expressions such that they can be part of the environment for reducing the
gradient expressions. Basically what I would like is some way to have a
reduction that worked properly whether the environment was full of actual
expressions or just numbers. I will have a think about this.

Also my next commit should do some clean up, in particular some commented
out code.
Tidied up after my Expression representation refactoring to satisfy flake8
Tidied up after my Expression representation refactoring to satisfy flake8