refactor gate class

instead of the gate constructor accepting a matrix, it will
accept a standard quantum gate name.  It will ensure that
the gate name is known and that the associated matrix is unitary.

this refactor is so we can add methods to the gate class to get
matrices from (json, python, ...?) files instead of insisting
that the constructor is given a matrix
refactor quantum circuit class

refactor quantum circuit class into two circuit classes: a conceptual
circuit and low-level circuit with quantum gates and associated
operations