Type system: contains-unknown-type also walks down negation types

Low occurrence, but negated unknown types can have pretty far-ranging
effects (e.g., `(and vector (not foo)), where 'foo is eventually
'vector).
typep: arrays test on wild _specialised_ element type

It currently works because unknown element types are disregarded, but
we'll eventually want to have a real type on the element type, and
some set representation for specialised element types.
New function: %upgraded-array-element-type to upgrade ctypes

Much saner than mutating an array ctype to upgrade it, and then
reading the specialised element type.
Type system: fix array type intersection and unparsing

1. We need to intersect specialised element types, not just re-derive
   it from the element type.  This only affects intersections between
   unspecialised array types and T arrays.

2. Be more careful when unparsing array types: we can intersect array
   element types for relatively wide specialised element types.  We
   must always preserve the specialised element type.

3. Smoke regression tests.# Please enter the commit message for your changes. Lines starting
Really fix SVREF with unknown types

Now that array type intersection are correct (less broken?), the
kludge in bd84e72bb655e77c0c0bfeaec1c8eac7a427507b isn't useful
anymore.
Type/compiler: new utility functions to compute over types

sb!kernel:generic-abstract-type-function approximates a function over
types given an arbitrary finite set representation.

sb!kernel:list-abstract-type-function specialises on the standard
CL list representation of finite sets.

See late-type.lisp for documentation.
More aggressive ARRAY-RANK type derivation

* Use list-abstract-type-function to derive possible values for
  ARRAY-RANK even in the face of union/intersection/negation types.

* Fixes lp#1310574 (triggered by a prior fix to array type union).

* Plus tests derived from opticl.