Propagate shape information to ConvOp gradients

Another attempt at closing #2089, as an alternative to #2095.

I just went through `theano/tensor/nnet/conv.py` from top to bottom trying to understand and clean up the shape inference code. Changes are:
* In `has_all_shape()`, `nkern` and `bsize` default to `1` so they can be omitted to just check for completeness of `imshp` and `kshp`.
* `getOutputShape()` supports symbolic shapes and shapes including `None`s. Also it returns a tuple instead of a numpy array.
* `imshp`, `kshp`, `imshp_logical`, `kshp_logical`, `outshp` and `fulloutshp` are guaranteed to be tuples after `__init__()` was called, but can contain `None`s. All the code is adapted to this.

I just tested this with `theano/sandbox/cuda/test_conv_cuda_ndarray.py:test_gemm_grads` and found that I had to disable shape inference (`infer_shape()`) by unconditionally raising a `ShapeError` for it to work. So probably something is wrong, but I cannot look into this today. Regard this as "under construction", but let me know if you have any comments.
Without the unconditional `ShapeError()` in the end, the test passes, but I get a lot of optimization failures:
```
ERROR (theano.gof.opt): Optimization failure due to: local_gpualloc_memset_0
ERROR (theano.gof.opt): TRACEBACK:
ERROR (theano.gof.opt): Traceback (most recent call last):
  File "/raid/user/jan/install/Theano-git/theano/gof/opt.py", line 1396, in process_node
    fgraph.replace_all_validate(repl_pairs, reason=lopt)
  File "/raid/user/jan/install/Theano-git/theano/gof/toolbox.py", line 208, in replace_all_validate
    fgraph.replace(r, new_r, reason=reason, verbose=False)
  File "/raid/user/jan/install/Theano-git/theano/gof/fg.py", line 462, in replace
    raise TypeError("The type of the replacement must be the same as the type of the original Variable.", r, new_r, r.type, new_r.type, str(reason))
TypeError: ('The type of the replacement must be the same as the type of the original Variable.', GpuAlloc.0, GpuAlloc{memset_0=True}.0, CudaNdarrayType(float32, 4D), CudaNdarrayType(float32, (True, False, False, False)), 'local_gpualloc_memset_0')
```
Note the changed broadcast pattern. Not sure how this is caused, and if it's a mistake in `ConvOp` or somewhere else.