Simulator and nodes now handle time explicitly

Previously, time was tracked in a node stored in model.t,
which was automatically connected to many nodes.
Now, whether or not a node has access to the current timestep
depends on the function that the node computes
(if the node computes a function).

If a node's function accepts 0 arguments, it is not passed any.

If a node's function accepts 1 argument, it is passed
the current timestep.

If a node's function accepts 2 or more arguments
(even if those are passed as *args) it is passed both
the current timestep and x, which is a numpy array with all of its
input connections.

Changes made to augment or support this:
- simulator.Simulator's signaldict has a __time__ key
  whose value is the current timestep
- nonlinearities.PythonFunction has a `n_args` property that determines
  how many arguments the function accepts
- simulator.Simulator does not "probe" time, but instead exposes
  a `time` function that returns a numpy array of the timesteps,
  which is generated using `np.linspace`. This is mostly for plotting.
  - By default, this is done using the model's dt.
    If a `dt` is passed, it uses that instead (for probes that
    are sampled at a different rate than model's dt;
    see test_ensemble.py for an example that uses this).
Node now defaults to dimension 0

- Most nodes don't require input anyhow, so this makes
  modellers be more explicit when the node will use input
Introspection no longer used in PythonFunction

- Instead, the number of inputs (`PythonFunction.nin`) is used
Removing n_args = 0 case everywhere
Removed has_input logic
Changed time to trange