Repository: rigetticomputing/pyquil
Pull request #651 (2018-11-02 22:58:35)

Docs intro page
Updating "Introduction to Quantum Computing" page: updated code to be Forest 2.0 compatible (but note a warning msg issued for the while_do(..) code snippet), polished some of the text.


Patch:
diff --git a/docs/source/_static/theme_overrides.css b/docs/source/_static/theme_overrides.css
new file mode 100644
index 0000000..dad56c0
--- /dev/null
+++ b/docs/source/_static/theme_overrides.css
@@ -0,0 +1,15 @@
+/* Taken from https://rackerlabs.github.io/docs-rackspace/tools/rtd-tables.html */
+
+/* override table width restrictions */
+@media screen and (min-width: 767px) {
+
+   .wy-table-responsive table td {
+      /* !important prevents the common CSS stylesheets from overriding
+         this as on RTD they are loaded after this stylesheet */
+      white-space: normal !important;
+   }
+
+   .wy-table-responsive {
+      overflow: visible !important;
+   }
+}
\ No newline at end of file
diff --git a/docs/source/_templates/autosumm.rst b/docs/source/_templates/autosumm.rst
new file mode 100644
index 0000000..e03319b
--- /dev/null
+++ b/docs/source/_templates/autosumm.rst
@@ -0,0 +1,5 @@
+{{ objname | escape | underline}}
+
+.. currentmodule:: {{ module }}
+
+.. auto{{ objtype }}:: {{ objname }}
diff --git a/docs/source/advanced_usage.rst b/docs/source/advanced_usage.rst
index 4f14106..893fcea 100644
--- a/docs/source/advanced_usage.rst
+++ b/docs/source/advanced_usage.rst
@@ -3,52 +3,100 @@
 Advanced Usage
 ==============
 
-First, initialize a localQVM instance on your laptop. You should have two consoles open in your terminal to run in the
-background.
+.. note::
 
-.. code:: python
+    If you're running locally, remember set up the QVM and quilc in server mode before trying to use
+    them: :ref:`server`.
 
-    ### CONSOLE 1
-    $ quilc -S
-    port triggered: 6000.
-    [2018-09-19 11:22:37] Starting server: 0.0.0.0 : 6000.
+PyQuil Configuration Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    ### CONSOLE 2
-    $ qvm -S
-    Welcome to the Rigetti QVM
-    (Configured with 2048 MiB of workspace and 8 workers.)
-    [2018-09-20 15:39:50] Starting server on port 5000.
+Network endpoints for the Rigetti Forest infrastructure and information pertaining to QPU access are
+stored in a pair of configuration files. These files are located by default at ``~/.qcs_config`` and ``~/.forest_config``.
+The location can be changed by setting the environment variables ``QCS_CONFIG`` or ``FOREST_CONFIG`` to point to the new
+location.
 
-.. code:: python
+When running on a QMI, the values in these configuration files are automatically managed so as to
+point to the correct endpoints. When running locally, configuration files are not necessary. Thus, the average
+user will not have to do any work to get their configuration files set up.
 
-    from pyquil import Program, get_qc
-    from pyquil.gates import *
-    qvm = get_qc('9q-square-qvm')
+If for some reason you want to use an atypical configuration, you may need to modify these files.
+
+.. exec on engage
+
+The default QCS config file on any QMI looks similar to the following:
+
+::
+
+    # .qcs_config
+    [Rigetti Forest]
+    url = https://forest-server.qcs.rigetti.com
+    key = 4fd12391-11eb-52ec-35c2-262765ae4c4f
+    user_id = 4fd12391-11eb-52ec-35c2-262765ae4c4f
+
+    [QPU]
+    exec_on_engage = bash exec_on_engage.sh
+
+where
+
+ -  ``url`` is the endpoint that pyQuil hits for device information and for the 2.0 endpoints,
+ -  ``key`` stores the Forest 1.X API key,
+ -  ``user_id`` stores a Forest 2.0 user ID, and
+ -  ``exec_on_engage`` specifies the shell command that the QMI will launch when the QMI becomes QPU-engaged. It
+    would have no effect if you are running locally, but is important if you are running on the QMI. By default, it runs the
+    ``exec_on_engage.sh`` shell script. It's best to leave the configuration as is, and edit that script.
+    More documentation about ``exec_on_engage.sh`` can be found in the QCS docs
+    `here <https://www.rigetti.com/qcs/docs/guides#queuing-programs-for-auto-execution>`_.
+
+The Forest config file on any QMI has these contents, with specific IP addresses filled in:
+
+::
+
+    # .forest_config
+    [Rigetti Forest]
+    qpu_endpoint_address = None
+    qvm_address = http://10.1.165.XX:5000
+    compiler_server_address = tcp://10.1.165.XX:5555
+
+where
 
+ -  ``qpu_endpoint_address`` is the endpoint where pyQuil will try to communicate with the QPU orchestrating service
+    during QPU-engagement. It may not appear until your QMI engages, and furthermore will have no effect if you are
+    running locally. It's best to leave this alone. If you obtain access to one of our QPUs, we will fill it in for you.
+ -  ``qvm_address`` is the endpoint where pyQuil will try to communicate with the Rigetti Quantum Virtual Machine.
+    On a QMI, this points to the provided QVM instance. On a local installation, this should be set to the server endpoint
+    for a locally running QVM instance. However, pyQuil will use the default value ``http://localhost:5000`` if this file
+    isn't found, which is the correct endpoint when you run the QVM locally with ``qvm -S``.
+ -  ``compiler_server_address``: This is the endpoint where pyQuil will try to communicate with the compiler server. On a
+    QMI, this points to a provided compiler server instance. On a local installation, this should be set to the server
+    endpoint for a locally running ``quilc`` instance. However, pyQuil will use the default value ``http://localhost:6000``
+    if this isn't set, which is the correct endpoint when you run ``quilc`` locally with ``quilc -S``.
 
-Now that our local endpoints are up and running, we can start running pyQuil programs! Open a jupyter notebook (type
-..code::`jupyter notebook` in your terminal), or launch python in your terminal (type ..code::`python3`).
+.. note::
 
+     PyQuil itself reads these values out using the helper class ``pyquil._config.PyquilConfig``. PyQuil users should not
+     ever need to touch this class directly.
 
 Using Qubit Placeholders
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
-In PyQuil, we typically use integers to identify qubits
+.. note::
+    The functionality provided inline by ``QubitPlaceholders`` is similar to writing a function which returns a
+    ``Program``, with qubit indices taken as arguments to the function.
+
+In pyQuil, we typically use integers to identify qubits
 
 .. code:: python
 
-    from pyquil.quil import Program
+    from pyquil import Program
     from pyquil.gates import CNOT, H
     print(Program(H(0), CNOT(0, 1)))
 
-
 .. parsed-literal::
 
     H 0
     CNOT 0 1
 
-
-
 However, when running on real, near-term QPUs we care about what
 particular physical qubits our program will run on. In fact, we may want
 to run the same program on an assortment of different qubits. This is
@@ -59,44 +107,22 @@ where using ``QubitPlaceholder``\ s comes in.
     from pyquil.quilatom import QubitPlaceholder
     q0 = QubitPlaceholder()
     q1 = QubitPlaceholder()
-    prog = Program(H(q0), CNOT(q0, q1))
-    print(prog)
-
+    p = Program(H(q0), CNOT(q0, q1))
+    print(p)
 
 .. parsed-literal::
 
     H {q4402789176}
     CNOT {q4402789176} {q4402789120}
 
-
-
 If you try to use this program directly, it will not work
 
 .. code:: python
 
-    print(prog.out())
-
+    print(p.out())
 
 ::
 
-
-    ---------------------------------------------------------------------------
-
-    RuntimeError                              Traceback (most recent call last)
-
-    <ipython-input-3-da474d3af403> in <module>()
-    ----> 1 print(prog.out())
-
-    ...
-
-    pyquil/pyquil/quilatom.py in out(self)
-         53 class QubitPlaceholder(QuilAtom):
-         54     def out(self):
-    ---> 55         raise RuntimeError("Qubit {} has not been assigned an index".format(self))
-         56
-         57     def __str__(self):
-
-
     RuntimeError: Qubit q4402789176 has not been assigned an index
 
 
@@ -107,17 +133,14 @@ N.
 .. code:: python
 
     from pyquil.quil import address_qubits
-    print(address_qubits(prog))
-
+    print(address_qubits(p))
 
 .. parsed-literal::
 
     H 0
     CNOT 0 1
 
-
-
-The real power comes into play when you provide an explicit mapping
+The real power comes into play when you provide an explicit mapping:
 
 .. code:: python
 
@@ -126,14 +149,12 @@ The real power comes into play when you provide an explicit mapping
         q1: 19,
     }))
 
-
 .. parsed-literal::
 
     H 14
     CNOT 14 19
 
 
-
 Register
 --------
 
@@ -144,8 +165,8 @@ list of qubits to build your program.
 .. code:: python
 
     qbyte = QubitPlaceholder.register(8)
-    prog2 = Program(H(q) for q in qbyte)
-    print(address_qubits(prog2, {q: i*2 for i, q in enumerate(qbyte)}))
+    p_evens = Program(H(q) for q in qbyte)
+    print(address_qubits(p_evens, {q: i*2 for i, q in enumerate(qbyte)}))
 
 
 .. parsed-literal::
@@ -159,281 +180,129 @@ list of qubits to build your program.
     H 12
     H 14
 
+Classical Control Flow
+~~~~~~~~~~~~~~~~~~~~~~
 
-Quantum Fourier Transform (QFT)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Let us do an example that includes multi-qubit parameterized gates.
-
-Here we wish to compute the discrete Fourier transform of
-``[0, 1, 0, 0, 0, 0, 0, 0]``. We do this in three steps:
-
-1. Write a function called ``qft3`` to make a 3-qubit QFT quantum
-   program.
-2. Write a state preparation quantum program.
-3. Execute state preparation followed by the QFT on the QVM.
-
-First we define a function to make a 3-qubit QFT quantum program. This
-is a mix of Hadamard and CPHASE gates, with a final bit reversal
-correction at the end consisting of a single SWAP gate.
-
-.. code:: python
-
-    from math import pi
-
-    def qft3(q0, q1, q2):
-        p = Program()
-        p.inst( H(q2),
-                CPHASE(pi/2.0, q1, q2),
-                H(q1),
-                CPHASE(pi/4.0, q0, q2),
-                CPHASE(pi/2.0, q0, q1),
-                H(q0),
-                SWAP(q0, q2) )
-        return p
-
-There is a very important detail to recognize here: The function
-``qft3`` doesn't *compute* the QFT, but rather it *makes a quantum
-program* to compute the QFT on qubits ``q0``, ``q1``, and ``q2``.
-
-We can see what this program looks like in Quil notation by doing
-the following:
-
-.. code:: python
-
-    print(qft3(0, 1, 2))
-
-.. parsed-literal::
-
-    H 2
-    CPHASE(1.5707963267948966) 1 2
-    H 1
-    CPHASE(0.7853981633974483) 0 2
-    CPHASE(1.5707963267948966) 0 1
-    H 0
-    SWAP 0 2
-
-Next, we want to prepare a state that corresponds to the sequence we
-want to compute the discrete Fourier transform of. Fortunately, this is
-easy, we just apply an :math:`X`-gate to the zeroth qubit.
-
-.. code:: python
-
-    state_prep = Program().inst(X(0))
-
-We can verify that this works by computing its wavefunction. However, we
-need to add some "dummy" qubits, because otherwise ``wavefunction``
-would return a two-element vector.
-
-.. code:: python
-
-    add_dummy_qubits = Program().inst(I(1), I(2))
-    wavefunction = qvm.wavefunction(state_prep + add_dummy_qubits)
-    print(wavefunction)
-
-.. parsed-literal::
-
-    (1+0j)|001>
-
-If we have two quantum programs ``a`` and ``b``, we can concatenate them
-by doing ``a + b``. Using this, all we need to do is compute the QFT
-after state preparation to get our final result.
-
-.. code:: python
-
-    wavefunction = qvm.wavefunction(state_prep + qft3(0, 1, 2))
-    print(wavefunction.amplitudes)
-
-.. parsed-literal::
-
-    array([  3.53553391e-01+0.j        ,   2.50000000e-01+0.25j      ,
-             2.16489014e-17+0.35355339j,  -2.50000000e-01+0.25j      ,
-            -3.53553391e-01+0.j        ,  -2.50000000e-01-0.25j      ,
-            -2.16489014e-17-0.35355339j,   2.50000000e-01-0.25j      ])
-
-We can verify this works by computing the (inverse) FFT from NumPy.
+.. note::
 
-.. code:: python
+    Classical control flow is not yet supported on the QPU.
 
-    from numpy.fft import ifft
-    ifft([0,1,0,0,0,0,0,0], norm="ortho")
 
-.. parsed-literal::
+Here are a couple quick examples that show how much richer a Quil program
+can be with classical control flow. In this first example, we create a while
+loop by following these steps:
 
-    array([ 0.35355339+0.j        ,  0.25000000+0.25j      ,
-            0.00000000+0.35355339j, -0.25000000+0.25j      ,
-           -0.35355339+0.j        , -0.25000000-0.25j      ,
-            0.00000000-0.35355339j,  0.25000000-0.25j      ])
+1. Declare a register called ``flag_register`` to use as a boolean test for looping.
 
-Classical Control Flow
-~~~~~~~~~~~~~~~~~~~~~~
-
-Here are a couple quick examples that show how much richer the classical
-control of a Quil program can be. In this first example, we have a
-register called ``classical_flag_register`` which we use for looping.
-Then we construct the loop in the following steps:
-
-1. We first initialize this register to ``1`` with the ``init_register``
-   program so our while loop will execute. This is often called the
+2. Initialize this register to ``1`` program so our while loop will execute. This is often called the
    *loop preamble* or *loop initialization*.
 
-2. Next, we write body of the loop in a program itself. This will be a
-   program that computes an :math:`X` followed by an :math:`H` on our
+3. Write the body of the loop in its own :py:class:`~pyquil.quil.Program`. This will be a
+   program that applies an :math:`X` gate followed by a :math:`H` gate on our
    qubit.
 
-3. Lastly, we put it all together using the ``while_do`` method.
+4. Using the :py:func:`~pyquil.quil.Program.while_do` method to add control flow.
 
 .. code:: python
 
-    # Name our classical registers:
-    classical_flag_register = 2
+    from pyquil import Program
+    from pyquil.gates import *
+
+    # Initialize the Program and declare a 1 bit memory space for our boolean flag
+    outer_loop = Program()
+    flag_register = outer_loop.declare('flag_register', 'BIT')
+
+    # Set the initial flag value to 1
+    outer_loop += MOVE(flag_register, 1)
 
-    # Write out the loop initialization and body programs:
-    init_register = Program(TRUE([classical_flag_register]))
-    loop_body = Program(X(0), H(0)).measure(0, classical_flag_register)
+    # Define the body of the loop with a new Program
+    inner_loop = Program()
+    inner_loop += Program(X(0), H(0))
+    inner_loop += MEASURE(0, flag_register)
 
-    # Put it all together in a loop program:
-    loop_prog = init_register.while_do(classical_flag_register, loop_body)
+    # Run inner_loop in a loop until flag_register is 0
+    outer_loop.while_do(flag_register, inner_loop)
 
-    print(loop_prog)
+    print(outer_loop)
 
 .. parsed-literal::
 
-    TRUE [2]
+    DECLARE flag_register BIT[1]
+    MOVE flag_register 1
     LABEL @START1
-    JUMP-UNLESS @END2 [2]
+    JUMP-UNLESS @END2 flag_register
     X 0
     H 0
-    MEASURE 0 [2]
+    MEASURE 0 flag_register
     JUMP @START1
     LABEL @END2
 
-Notice that the ``init_register`` program applied a Quil instruction directly to a
+Notice that the ``outer_loop`` program applied a Quil instruction directly to a
 classical register.  There are several classical commands that can be used in this fashion:
 
-- ``TRUE`` which sets a single classical bit to be 1
-- ``FALSE`` which sets a single classical bit to be 0
 - ``NOT`` which flips a classical bit
 - ``AND`` which operates on two classical bits
-- ``OR`` which operates on two classical bits
+- ``IOR`` which operates on two classical bits
 - ``MOVE`` which moves the value of a classical bit at one classical address into another
 - ``EXCHANGE`` which swaps the value of two classical bits
 
 In this next example, we show how to do conditional branching in the
 form of the traditional ``if`` construct as in many programming
 languages. Much like the last example, we construct programs for each
-branch of the ``if``, and put it all together by using the ``if_then``
+branch of the ``if``, and put it all together by using the :py:func:`~pyquil.quil.Program.if_then`
 method.
 
 .. code:: python
 
-    # Name our classical registers:
-    test_register = 1
-    answer_register = 0
+    # Declare our memory spaces
+    branching_prog = Program()
+    test_register = branching_prog.declare('test_register', 'BIT')
+    ro = branching_prog.declare('ro', 'BIT')
 
     # Construct each branch of our if-statement. We can have empty branches
     # simply by having empty programs.
     then_branch = Program(X(0))
     else_branch = Program()
 
-    # Make a program that will put a 0 or 1 in test_register with 50% probability:
-    branching_prog = Program(H(1)).measure(1, test_register)
+    # Construct our program so that the result in test_register is equally likely to be a 0 or 1
+    branching_prog += H(1)
+    branching_prog += MEASURE(1, test_register)
 
-    # Add the conditional branching:
+    # Add the conditional branching
     branching_prog.if_then(test_register, then_branch, else_branch)
 
-    # Measure qubit 0 into our answer register:
-    branching_prog.measure(0, answer_register)
+    # Measure qubit 0 into our readout register
+    branching_prog += MEASURE(0, ro)
 
     print(branching_prog)
 
 .. parsed-literal::
 
+    DECLARE test_register BIT[1]
+    DECLARE ro BIT[1]
     H 1
-    MEASURE 1 [1]
-    JUMP-WHEN @THEN3 [1]
-    JUMP @END4
-    LABEL @THEN3
+    MEASURE 1 test_register
+    JUMP-WHEN @THEN1 test_register
+    JUMP @END2
+    LABEL @THEN1
     X 0
-    LABEL @END4
-    MEASURE 0 [0]
-
-We can run this program a few times to see what we get in the
-``answer_register``.
-
-.. code:: python
-
-    qvm.run(branching_prog, [answer_register], 10)
-
-.. parsed-literal::
-
-    [[1], [1], [1], [0], [1], [0], [0], [1], [1], [0]]
-
-Parametric Depolarizing Noise
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Rigetti QVM has support for emulating certain types of noise models.
-One such model is *parametric Pauli noise*, which is defined by a
-set of 6 probabilities:
-
--  The probabilities :math:`P_X`, :math:`P_Y`, and :math:`P_Z` which
-   define respectively the probability of a Pauli :math:`X`, :math:`Y`,
-   or :math:`Z` gate getting applied to *each* qubit after *every* gate
-   application. These probabilities are called the *gate noise
-   probabilities*.
-
--  The probabilities :math:`P_X'`, :math:`P_Y'`, and :math:`P_Z'` which
-   define respectively the probability of a Pauli :math:`X`, :math:`Y`,
-   or :math:`Z` gate getting applied to the qubit being measured
-   *before* it is measured. These probabilities are called the
-   *measurement noise probabilities*.
+    LABEL @END2
+    MEASURE 0 ro
 
-We can instantiate a noisy QVM by creating a new connection with these
-probabilities specified.
+We can run this program a few times to see what we get in the readout register ``ro``.
 
 .. code:: python
 
-    # 20% chance of a X gate being applied after gate applications and before measurements.
-    gate_noise_probs = [0.2, 0.0, 0.0]
-    meas_noise_probs = [0.2, 0.0, 0.0]
-    noisy_qvm = qvm(gate_noise=gate_noise_probs, measurement_noise=meas_noise_probs)
+    from pyquil import get_qc
 
-We can test this by applying an :math:`X`-gate and measuring. Nominally,
-we should always measure ``1``.
-
-.. code:: python
-
-    p = Program().inst(X(0)).measure(0, 0)
-    print("Without Noise: {}".format(qvm.run(p, [0], 10)))
-    print("With Noise   : {}".format(noisy_qvm.run(p, [0], 10)))
+    qc = get_qc("2q-qvm")
+    branching_prog.wrap_in_numshots_loop(10)
+    qc.run(branching_prog)
 
 .. parsed-literal::
 
-    Without Noise: [[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]
-    With Noise   : [[0], [0], [0], [0], [0], [1], [1], [1], [1], [0]]
-
-Parametric Programs
-~~~~~~~~~~~~~~~~~~~
-
-In PyQuil 1.x, there was an object named ``ParametricProgram``::
-
-    # This function returns a quantum circuit with different rotation angles on a gate on qubit 0
-    def rotator(angle):
-        return Program(RX(angle, 0))
-
-    from pyquil.parametric import ParametricProgram
-    par_p = ParametricProgram(rotator) # This produces a new type of parameterized program object
-
-This object has been removed from PyQuil 2. Please consider simply using a Python function for
-the above functionality::
-
-    par_p = rotator
-
-Or using declared classical memory::
+    [[1], [1], [1], [0], [1], [0], [0], [1], [1], [0]]
 
-    p = Program()
-    angle = p.declare('angle', 'REAL')
-    p += RX(angle, 0)
 
 Pauli Operator Algebra
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -450,17 +319,17 @@ The above sum can be constructed as follows:
 
     # Pauli term takes an operator "X", "Y", "Z", or "I"; a qubit to act on, and
     # an optional coefficient.
-    a = 0.5 * ID
+    a = 0.5 * ID()
     b = -0.75 * sX(0) * sY(1) * sZ(3)
     c = (5-2j) * sZ(1) * sX(2)
 
     # Construct a sum of Pauli terms.
     sigma = a + b + c
-    print("sigma = {}".format(sigma))
+    print(f"sigma = {sigma}")
 
 .. parsed-literal::
 
-    sigma = 0.5*I + -0.75*X0*Y1*Z3 + (5-2j)*Z1*X2
+    sigma = (0.5+0j)*I + (-0.75+0j)*X0*Y1*Z3 + (5-2j)*Z1*X2
 
 Right now, the primary thing one can do with Pauli terms and sums is to construct the
 exponential of the Pauli term, i.e., :math:`\exp[-i\beta\sigma]`.  This is
@@ -478,21 +347,19 @@ The following shows an instructive example of all three.
 
 .. code:: python
 
-    import pyquil.paulis as pl
+    from pyquil.paulis import exponential_map
 
-    # Simplification
     sigma_cubed = sigma * sigma * sigma
-    print("Simplified  : {}".format(sigma_cubed))
-    print()
+    print(f"Simplified: {sigma_cubed}\n")
 
-    #Produce Quil code to compute exp[iX]
+    # Produce Quil code to compute exp[iX]
     H = -1.0 * sX(0)
-    print("Quil to compute exp[iX] on qubit 0:")
-    print(pl.exponential_map(H)(1.0))
+    print(f"Quil to compute exp[iX] on qubit 0:\n"
+           f"{exponential_map(H)(1.0)}")
 
 .. parsed-literal::
 
-    Simplified  : (32.46875-30j)*I + (-16.734375+15j)*X0*Y1*Z3 + (71.5625-144.625j)*Z1*X2
+    Simplified: (32.46875-30j)*I + (-16.734375+15j)*X0*Y1*Z3 + (71.5625-144.625j)*Z1*X2
 
     Quil to compute exp[iX] on qubit 0:
     H 0
@@ -501,13 +368,39 @@ The following shows an instructive example of all three.
 
 ``exponential_map`` returns a function allowing you to fill in a multiplicative
 constant later. This commonly occurs in variational algorithms. The function
-``exponential_map`` is used to compute exp[-i * alpha * H] without explicitly filling in a
-value for alpha.
+``exponential_map`` is used to compute :math:`\exp[-i \alpha H]` without explicitly filling in a
+value for :math:`\alpha`.
 
 .. code:: python
 
-    expH = pl.exponential_map(H)
-    print(expH(0.0))
-    print(expH(1.0))
-    print(expH(2.0))
+    expH = exponential_map(H)
+    print(f"0:\n{expH(0.0)}\n")
+    print(f"1:\n{expH(1.0)}\n")
+    print(f"2:\n{expH(2.0)}")
+
+.. parsed-literal::
+    0:
+    H 0
+    RZ(0) 0
+    H 0
+
+    1:
+    H 0
+    RZ(-2.0) 0
+    H 0
+
+    2:
+    H 0
+    RZ(-4.0) 0
+    H 0
+
+To take it one step further, you can use :ref:`parametric_compilation` with ``exponential_map``. For instance:
+
+.. code:: python
+
+    ham = sZ(0) * sZ(1)
+    prog = Program()
+    theta = prog.declare('theta', 'REAL')
+    prog += exponential_map(ham)(theta)
+
 
diff --git a/docs/source/apidocs/.gitignore b/docs/source/apidocs/.gitignore
new file mode 100644
index 0000000..9f677d7
--- /dev/null
+++ b/docs/source/apidocs/.gitignore
@@ -0,0 +1,1 @@
+/autogen
\ No newline at end of file
diff --git a/docs/source/apidocs/compilers.rst b/docs/source/apidocs/compilers.rst
new file mode 100644
index 0000000..9f682f1
--- /dev/null
+++ b/docs/source/apidocs/compilers.rst
@@ -0,0 +1,20 @@
+Compilers
+=========
+
+An appropriate compiler is automatically created when using :py:func:`~pyquil.get_qc` and it is
+stored on the :py:class:`~pyquil.api.QuantumComputer` object as the ``compiler`` attribute.
+
+The exact process for compilation depends on whether you're targeting a QPU or a QVM, and
+you can conceive of other compilation strategies than those included with pyQuil by default.
+Therefore, we define an abstract interface that all compilers must follow. See
+:py:class:`~pyquil.api._qac.AbstractCompiler` for more, or use one of the listed compilers below.
+
+
+.. currentmodule:: pyquil.api
+.. autosummary::
+    :toctree: autogen
+
+    _qac.AbstractCompiler
+    QVMCompiler
+    LocalQVMCompiler
+    QPUCompiler
diff --git a/docs/source/apidocs/devices.rst b/docs/source/apidocs/devices.rst
new file mode 100644
index 0000000..e9addda
--- /dev/null
+++ b/docs/source/apidocs/devices.rst
@@ -0,0 +1,36 @@
+Devices
+=======
+
+An appropriate Device is automatically created when using :py:func:`~pyquil.get_qc` and it is
+stored on the :py:class:`~pyquil.api.QuantumComputer` object as the ``device`` attribute.
+
+There are properties of real quantum computers that go beyond the quantum abstract machine
+(QAM) abstraction. Real devices have performance specs, limited ISAs, and restricted topologies.
+:py:class:`~pyquil.device.AbstractDevice` provides an abstract interface for accessing
+properties of a real quantum device or for mocking out relevant properties for a more realistic
+QVM.
+
+
+.. currentmodule:: pyquil.device
+.. autosummary::
+    :toctree: autogen
+
+    AbstractDevice
+    Device
+    NxDevice
+
+The data structures used are documented here
+
+.. autosummary::
+    :toctree: autogen
+
+    ISA
+    Specs
+
+Utility functions
+~~~~~~~~~~~~~~~~~
+
+.. autofunction:: isa_from_graph
+.. autofunction:: specs_from_graph
+.. autofunction:: isa_to_graph
+.. autofunction:: gates_in_isa
diff --git a/docs/source/apidocs/program.rst b/docs/source/apidocs/program.rst
new file mode 100644
index 0000000..6ea8b9e
--- /dev/null
+++ b/docs/source/apidocs/program.rst
@@ -0,0 +1,73 @@
+.. currentmodule:: pyquil.quil
+
+Program
+=======
+
+
+.. autoclass:: pyquil.quil.Program
+
+    .. rubric:: Attributes
+    .. autosummary::
+        :toctree: autogen
+        :template: autosumm.rst
+
+        ~Program.instructions
+        ~Program.defined_gates
+        ~Program.out
+        ~Program.get_qubits
+        ~Program.is_protoquil
+
+
+    .. rubric:: Program Construction
+    .. autosummary::
+        :toctree: autogen
+        :template: autosumm.rst
+
+        ~Program.__iadd__
+        ~Program.__add__
+        ~Program.inst
+        ~Program.gate
+        ~Program.defgate
+        ~Program.define_noisy_gate
+        ~Program.define_noisy_readout
+        ~Program.no_noise
+        ~Program.measure
+        ~Program.reset
+        ~Program.measure_all
+        ~Program.alloc
+        ~Program.declare
+        ~Program.wrap_in_numshots_loop
+
+
+    .. rubric:: Control Flow
+    .. autosummary::
+        :toctree: autogen
+        :template: autosumm.rst
+
+        ~Program.while_do
+        ~Program.if_then
+
+    .. rubric:: Utility Methods
+    .. autosummary::
+        :toctree: autogen
+        :template: autosumm.rst
+
+        ~Program.copy
+        ~Program.pop
+        ~Program.dagger
+        ~Program.__getitem__
+
+
+Utility Functions
+-----------------
+
+.. autofunction:: get_default_qubit_mapping
+.. autofunction:: address_qubits
+.. autofunction:: instantiate_labels
+.. autofunction:: implicitly_declare_ro
+.. autofunction:: merge_with_pauli_noise
+.. autofunction:: merge_programs
+.. autofunction:: get_classical_addresses_from_program
+.. autofunction:: percolate_declares
+.. autofunction:: validate_protoquil
+
diff --git a/docs/source/apidocs/qam.rst b/docs/source/apidocs/qam.rst
new file mode 100644
index 0000000..b6f6470
--- /dev/null
+++ b/docs/source/apidocs/qam.rst
@@ -0,0 +1,18 @@
+QAMs
+====
+
+An appropriate QAM is automatically created when using :py:func:`~pyquil.get_qc` and it is
+stored on the :py:class:`~pyquil.api.QuantumComputer` object as the ``qam`` attribute.
+
+The Quantum Abstract Machine (QAM) provides an abstract interface for running hybrid
+quantum/classical quil programs on either a Quantum Virtual Machine (QVM, a classical simulator)
+or a Quantum Processor Unit (QPU, a real quantum device).
+
+
+.. currentmodule:: pyquil.api
+.. autosummary::
+    :toctree: autogen
+
+    _qam.QAM
+    QPU
+    QVM
diff --git a/docs/source/apidocs/quantum_computer.rst b/docs/source/apidocs/quantum_computer.rst
new file mode 100644
index 0000000..2d1685c
--- /dev/null
+++ b/docs/source/apidocs/quantum_computer.rst
@@ -0,0 +1,23 @@
+.. currentmodule:: pyquil.api
+
+Quantum Computer
+================
+
+.. autofunction:: pyquil.get_qc
+.. autofunction:: pyquil.list_quantum_computers
+
+.. autoclass:: pyquil.api.QuantumComputer
+
+   .. rubric:: Methods
+
+   .. autosummary::
+        :toctree: autogen
+        :template: autosumm.rst
+
+        ~QuantumComputer.run
+        ~QuantumComputer.run_and_measure
+        ~QuantumComputer.run_symmetrized_readout
+        ~QuantumComputer.qubits
+        ~QuantumComputer.qubit_topology
+        ~QuantumComputer.get_isa
+        ~QuantumComputer.compile
diff --git a/docs/source/basics.rst b/docs/source/basics.rst
index 5064fdd..9cea370 100644
--- a/docs/source/basics.rst
+++ b/docs/source/basics.rst
@@ -11,7 +11,7 @@ Programs and Gates
 Introduction
 ~~~~~~~~~~~~
 
-Quantum programs are written in Forest using the ``Program`` object. This ``Program`` abstraction will help us
+Quantum programs are written in Forest using the :py:class:`~pyquil.quil.Program` object. This ``Program`` abstraction will help us
 compose `Quil programs <https://arxiv.org/abs/1608.03355>`_.
 
 .. code:: python
@@ -78,8 +78,8 @@ program on the Quantum Virtual Machine (QVM). We just have to add a few lines to
     ...
 
     qc = get_qc('1q-qvm')  # You can make any 'nq-qvm' this way for any reasonable 'n'
-    compiled_program = qc.compile(p)
-    result = qc.run(compiled_program)
+    executable = qc.compile(p)
+    result = qc.run(executable)
     print(result)
 
 Congratulations! You just ran your program on the QVM. The returned value should be:
@@ -118,6 +118,7 @@ The following gates methods come standard with Quil and ``gates.py``:
 The parameterized gates take a real or complex floating point
 number as an argument.
 
+.. _declaring_memory:
 
 Declaring Memory
 ~~~~~~~~~~~~~~~~
@@ -181,7 +182,7 @@ the ``QuantumComputer`` abstraction do it for us.
 .. code:: python
 
     from pyquil import Program, get_qc
-    from pyquil.gates import *
+    from pyquil.gates import H, CNOT
 
     # Get our QuantumComputer instance, with a Quantum Virutal Machine (QVM) backend
     qc = get_qc("8q-qvm")
@@ -273,14 +274,79 @@ be executed 1000 times.
 
 Parametric Compilation
 ~~~~~~~~~~~~~~~~~~~~~~
-*Coming soon*
 
+Modern quantum algorithms are often parametric, following a hybrid model. In this hybrid
+model, the program ansatz (template of gates) is fixed, and iteratively updated with new
+parameters. These new parameters are often determined by an update given by a classical
+optimizer. Depending on the complexity of the algorithm, problem of interest, and capabilities
+of the classical optimizer, this loop may need to run many times. In order to efficiently operate
+within this hybrid model, parametric compilation can be used.
+
+Parametric compilation allows one to compile the program ansatz just once. Making use of declared
+memory regions, we can load values to the parametric gates at execution time, after compilation.
+Taking the compiler out of the execution loop for programs like this offers a huge performance
+improvement compared to compiling the program each time a parameter update is required.
+(Some more details about this and an example are found :ref:here <parametric>.)
+
+The first step is to build our parametric program, which functions like a template for all the precise programs we will
+run. Below we create a simple example program to illustrate, which puts the qubit onto the equator of the Bloch Sphere and then
+rotates it around the Z axis for some variable angle theta before applying another X pulse and measuring.
+
+.. code:: python
+
+    import numpy as np
+
+    from pyquil import Program
+    from pyquil.gates import RX, RZ, MEASURE
+
+    qubit = 0
+
+    p = Program()
+    ro = p.declare("ro", "BIT", 1)
+    theta_ref = p.declare("theta", "REAL")
+
+    p += RX(np.pi / 2, qubit)
+    p += RZ(theta, qubit)
+    p += RX(-np.pi / 2, qubit)
+
+    p += MEASURE(qubit, ro[0])
+
+.. note::
+
+    The example program, although simple, is actually more than just a toy example. It is similar to an
+    experiment which measures the qubit frequency.
+
+Notice how ``theta`` hasn't been specified yet. The next steps will have to involve a ``QuantumComputer`` or a compiler
+implementation. For simplicity, we will demonstrate with a ``QuantumComputer`` instance.
+
+.. code:: python
+
+    from pyquil import get_qc
+
+    # Get a Quantum Virtual Machine to simulate execution
+    qc = get_qc("1q-qvm")
+    executable = qc.compile(p)
+
+We are able to compile our program, even with ``theta`` still not specified. Now we want to run our program with ``theta``
+filled in for, say, 200 values between :math:`0` and :math:`2\pi`. We demonstrate this below.
+
+.. code:: python
+
+    # Somewhere to store each list of results
+    parametric_measurements = []
+
+    for theta in np.linspace(0, 2 * np.pi, 200):
+        # Get the results of the run with the value we want to execute with
+        bitstrings = qc.run(executable, {'theta': [theta]})
+        # Store our results
+        parameteric_measurements.append(bitstrings)
 
 
 Gate Modifiers
 ~~~~~~~~~~~~~~
 Gate applications in Quil can be preceded by a `gate modifier`. There are two supported modifiers:
 ``DAGGER`` and ``CONTROLLED``. The ``DAGGER`` modifier represents the dagger of the gate. For instance,
+
 .. parsed-literal::
 
     DAGGER RX(pi/3) 0
@@ -408,18 +474,75 @@ functions you can use with pyQuil are: ``quil_sin``, ``quil_cos``, ``quil_sqrt``
 Pragmas
 ~~~~~~~
 
+``PRAGMA`` directives give users more control over how Quil programs are processed or simulated but generally do not
+change the semantics of the Quil program itself. As a general rule of thumb, deleting all ``PRAGMA`` directives in a Quil
+program should leave a valid and semantically equivalent program.
+
+In pyQuil, ``PRAGMA`` directives play many roles, such as controlling the behavior of gates in noisy simulations,
+or commanding the Quil compiler to perform actions in a certain way. Here, we will cover the basics of two very
+common use cases for including a ``PRAGMA`` in your program: qubit rewiring and delays. For a more comprehensive
+review of what pragmas are and what the compiler supports, check out :ref:`compiler`. For more information about
+``PRAGMA`` in Quil, see
+`A Practical Quantum ISA <https://arxiv.org/pdf/1608.03355.pdf>`_, and
+`Simulating Quantum Processor Errors <https://www.european-lisp-symposium.org/static/proceedings/2018.pdf>`_.
+
 .. _rewiring:
 
 Specifying A Qubit Rewiring Scheme
 ----------------------------------
 
-*Coming soon*
+Qubit rewiring is one of the most powerful features of the Quil compiler. We are able to write Quil programs which are
+agnostic to the topology of the chip, and the compiler will intelligently relabel our qubits to
+give better performance.
+
+When we intend to run a program on the QPU, sometimes we write programs which use specific qubits targeting a specific
+device topology, perhaps to achieve a high-performance program. Other times, we write programs that are agnostic to the
+underlying topology, thereby making the programs more portable. Qubit rewiring accommodates both use cases in an
+automatic way.
+
+Consider the following program.
+
+.. code::
+
+    from pyquil import Program
+    from pyquil.gates import *
+
+    p = Program(X(3))
+
+We've tested this on the QVM, and we've reserved a lattice on the QPU which has qubits 4, 5, and 6, but not qubit 3.
+Rather than rewrite our program for each reservation, we modify our program to tell the compiler to do this for us.
+
+.. code::
+
+    from pyquil.quil import Pragma
+
+    p = Program(Pragma('INITIAL_REWIRING', ['"GREEDY"']))
+    p += X(3)
+
+Now, when we pass our program through the compiler (such as with :py:func:`QuantumComputer.compile`) we will get native Quil
+with the qubit reindexed to one of 4, 5, or 6. If qubit 3 is available, and we don't want that pulse to be applied to
+any other qubit, we would instead use ``Pragma('INITIAL_REWIRING', ['"NAIVE"']]``. Detailed information about the
+available options is :ref:`here <compiler_rewirings>`.
+
+.. note::
+    In general, we assume that the qubits you're supplying as input are also the ones which you prefer to 
+    operate on, and so NAIVE rewiring is the default.
 
 Asking for a Delay
 ------------------
-*Coming soon*
-(Note: time limit)
 
+At times, we may want to add a delay in our program. Usually this is associated with qubit characterization. Delays
+are not regular gate operations, and they do not affect the abstract semantics of the Quil program, so they're implemented with a ``PRAGMA`` directive.
+
+.. code::
+
+    #  ...
+    # qubit index and time in seconds must be defined and provided
+    p += Pragma('DELAY', [qubit], str(time))
+
+.. warning::
+    Keep in mind, the program duration is currently capped at 15 seconds, and the length of the program is multiplied
+    by the number of shots. If you have a 1000 shot program, where each shot contains a 100ms delay, you won't be able to execute it.
 
 Ways to Construct Programs
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/source/compiler.rst b/docs/source/compiler.rst
index cae0da6..59a85c2 100644
--- a/docs/source/compiler.rst
+++ b/docs/source/compiler.rst
@@ -18,9 +18,34 @@ hardware.
 Interacting with the Compiler
 -----------------------------
 
+After :ref:`downloading the SDK <sdkinstall>`, the Quil Compiler, ``quilc`` is available on your local machine.
+You can initialize a local ``quilc`` server by typing ``quilc -S`` into your terminal. You should see the following message.
+
+.. code:: python
+
+    $ quilc -S
+    +-----------------+
+    |  W E L C O M E  |
+    |   T O   T H E   |
+    |  R I G E T T I  |
+    |     Q U I L     |
+    | C O M P I L E R |
+    +-----------------+
+    Copyright (c) 2018 Rigetti Computing.
+
+    This is a part of the Forest SDK. By using this program
+    you agree to the End User License Agreement (EULA) supplied
+    with this program. If you did not receive the EULA, please
+    contact <support@rigetti.com>.
+
+    [2018-11-06 10:59:22] Starting server: 0.0.0.0 : 6000.
+
+To get a description of ``quilc``, and options and examples of its command line use, see :ref:`quilc_man`.
+
+
 A ``QuantumComputer`` object supplied by the function ``pyquil.api.get_qc()`` comes equipped with a
-connection to a Rigetti Quil compiler.  This can be accessed
-using the instance method ``.compile()``, as in the following:
+connection to your local Rigetti Quil compiler.  This can be accessed using the instance method ``.compile()``,
+as in the following:
 
 .. code:: python
 
@@ -60,7 +85,7 @@ class of this object changes based on context (e.g., ``QPUCompiler``, ``QVMCompi
 
 * ``compiler.quil_to_native_quil(program)``: This method converts a Quil program into native Quil,
   according to the ISA that the compiler is initialized with.  The input parameter is specified as a
-  ``Program`` object, and the output is given as a new ``Program`` object, equipped with a
+  :py:class:`~pyquil.quil.Program` object, and the output is given as a new ``Program`` object, equipped with a
   ``.metadata`` property that gives extraneous information about the compilation output (e.g., gate
   depth, as well as many others).  This call blocks until Quil compilation finishes.
 * ``compiler.native_quil_to_executable(nq_program)``: This method converts a ProtoQuil program, which
@@ -100,6 +125,8 @@ The QPU is not able to execute all possible Quil programs.  At present, a Quil p
 * This is then followed by a block of ``MEASURE`` instructions.
 
 
+.. _pragma:
+
 Region-specific compiler features through PRAGMA
 ------------------------------------------------
 
@@ -217,6 +244,7 @@ instead execute the blocks in their written order.
     MEASURE 2 ro[2]
     MEASURE 3 ro[3]
 
+.. _compiler_rewirings:
 
 Rewirings
 ~~~~~~~~~
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 31c8c3c..bfd710f 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -31,6 +31,7 @@
 # ones.
 extensions = [
     'sphinx.ext.autodoc',
+    'sphinx.ext.autosummary',
     'sphinx.ext.doctest',
     'sphinx.ext.intersphinx',
     'sphinx.ext.todo',
@@ -38,28 +39,15 @@ extensions = [
     'sphinx.ext.mathjax',
     'sphinx.ext.ifconfig',
     'sphinx.ext.viewcode',
+    'sphinx_autodoc_typehints',
 ]
 
+autosummary_generate = True
+autoclass_content = "both"
+
 import sphinx_rtd_theme
 from pyquil import __version__
 
-
-def remove_secrets(app, what, name, obj, options, signature, return_annotation):
-    if what == "class" and name == "pyquil.api.Connection":
-        import pyquil.api as pqf
-        print("Replacing endpoint secrets in pyquil.api.Connection() signature")
-        print(signature,)
-        signature = signature.replace("'{}'".format(pqf.ENDPOINT), "ENDPOINT")
-        signature = signature.replace("'{}'".format(pqf.API_KEY), "API_KEY")
-        signature = signature.replace("'{}'".format(pqf.USER_ID), "USER_ID")
-        print("--> ", signature)
-        return signature, return_annotation
-
-
-def setup(app):
-    app.connect("autodoc-process-signature", remove_secrets)
-
-
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 
@@ -142,7 +130,6 @@ pygments_style = 'sphinx'
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = True
 
-
 # -- Options for HTML output ----------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
@@ -184,6 +171,13 @@ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
 # so a file named "default.css" will overwrite the builtin "default.css".
 html_static_path = ["_static"]
 
+# See https://rackerlabs.github.io/docs-rackspace/tools/rtd-tables.html for details
+html_context = {
+    'css_files': [
+        '_static/theme_overrides.css',  # override wide tables in RTD theme
+    ],
+}
+
 # Add any extra paths that contain custom files (such as robots.txt or
 # .htaccess) here, relative to this directory. These files are copied
 # directly to the root of the documentation.
@@ -267,21 +261,21 @@ htmlhelp_basename = 'pyQuildoc'
 # -- Options for LaTeX output ---------------------------------------------
 
 latex_elements = {
-     # The paper size ('letterpaper' or 'a4paper').
-     #
-     # 'papersize': 'letterpaper',
+    # The paper size ('letterpaper' or 'a4paper').
+    #
+    # 'papersize': 'letterpaper',
 
-     # The font size ('10pt', '11pt' or '12pt').
-     #
-     # 'pointsize': '10pt',
+    # The font size ('10pt', '11pt' or '12pt').
+    #
+    # 'pointsize': '10pt',
 
-     # Additional stuff for the LaTeX preamble.
-     #
-     # 'preamble': '',
+    # Additional stuff for the LaTeX preamble.
+    #
+    # 'preamble': '',
 
-     # Latex figure (float) alignment
-     #
-     # 'figure_align': 'htbp',
+    # Latex figure (float) alignment
+    #
+    # 'figure_align': 'htbp',
 }
 
 # Grouping the document tree into LaTeX files. List of tuples
diff --git a/docs/source/exercises.rst b/docs/source/exercises.rst
index 367aeed..f369349 100644
--- a/docs/source/exercises.rst
+++ b/docs/source/exercises.rst
@@ -4,7 +4,7 @@ Exercises
 =========
 
 Exercise 1: Quantum Dice
-------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~
 
 Write a quantum program to simulate throwing an 8-sided die. The Python
 function you should produce is:
@@ -22,7 +22,7 @@ Next, extend the program to work for any kind of fair die:
         # return the result of throwing a num_sides sided die by running a quantum program
 
 Exercise 2: Controlled Gates
-----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 We can use the full generality of NumPy to construct new gate matrices.
 
@@ -36,7 +36,7 @@ We can use the full generality of NumPy to construct new gate matrices.
    controlled by qubit 0.
 
 Exercise 3: Grover's Algorithm
-------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Write a quantum program for the single-shot Grover's algorithm. The
 Python function you should produce is:
@@ -60,3 +60,265 @@ As an example: ``single_shot_grovers([0,0,1,0])`` should return 2.
    \vdots & & \ddots & \\
    2/N & & & 2/N-1
    \end{pmatrix}
+
+
+Exercise 4: Prisoner's Dilemma
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A classic strategy game is the `prisoner's dilemma <https://en.wikipedia.org/wiki/Prisoner%27s_dilemma>`_ where two
+prisoners get the minimal penalty if they collaborate and stay silent, get zero penalty if one of them defects and the
+other collaborates (incurring maximum penalty) and get intermediate penalty if they both defect. This game has an
+equilibrium where both defect and incur intermediate penalty.
+
+However, things change dramatically when we allow for quantum strategies leading to the
+`Quantum Prisoner's Dilemma <https://arxiv.org/abs/quant-ph/9806088>`_.
+
+Can you design a program that simulates this game?
+
+Exercise 5: Quantum Fourier Transform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The quantum Fourier transform (QFT) is a quantum implementation of the discrete Fourier transform. The
+Fourier transform can be used to transform a function from the time domain into the frequency domain.
+
+Compute the discrete Fourier transform of ``[0, 1, 0, 0, 0, 0, 0, 0]``, using pyQuil:
+ a. Write a state preparation quantum program.
+ b. Write a function to make a 3-qubit QFT program, taking qubit indices as arguments.
+ c. Combine your solutions to part a and b into one program and use the ``WavefunctionSimulator`` to get the solution.
+
+.. note:: For a more challenging initial state, try ``01100100``.
+
+Solution
+--------
+
+Part a: Prepare the initial state
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+We are going to apply the QFT on the *amplitudes* of the states.
+
+We want to prepare a state that corresponds to the sequence for which we
+want to compute the discrete Fourier transform. As the exercise hinted in part b, we need 3 qubits to transform
+an 8 bit sequence. It is simplest to understand if we think of the qubits as three digits in a binary string
+(aka bitstring). There are 8 possible values the bitstring can have, and in our quantum state, each of these
+possibilities has an amplitude. Our 8 indices in the QFT sequence label each of these states. For clarity:
+
+:math:`|000\rangle` => ``10000000``
+
+:math:`|001\rangle` => ``01000000``
+
+`...`
+
+:math:`|111\rangle` -> ``00000001``
+
+The sequence we want to compute is ``01000000``, so our initial state is simply :math:`|001\rangle`. For a bitstring with more
+than one ``1``, we would want an equal superposition over all the selected states. (E.g. ``01100000`` would be an
+equal superposition of :math:`|001\rangle` and :math:`|010\rangle`).
+
+To set up the :math:`|001\rangle` state, we only have to apply one :math:`X`-gate to the zeroth qubit.
+
+.. code:: python
+
+    from pyquil import Program
+    from pyquil.gates import *
+
+    state_prep = Program(X(0))
+
+We can verify that this works by computing its wavefunction with the
+:ref:`Wavefunction Simulator <wavefunction_simulator>`. However, we need to add some "dummy" qubits,
+because otherwise ``wavefunction`` would return a two-element vector for only qubit 0.
+
+.. code:: python
+
+    from pyquil.api import WavefunctionSimulator
+
+    add_dummy_qubits = Program(I(1), I(2))  # The identity gate I has no affect
+
+    wf_sim = WavefunctionSimulator()
+    wavefunction = wf_sim.wavefunction(state_prep + add_dummy_qubits)
+    print(wavefunction)
+
+.. parsed-literal::
+
+    (1+0j)|001>
+
+We'll need ``wf_sim`` for part c, too.
+
+Part b: Three qubit QFT program
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In this part, we define a function, ``qft3``, to make a 3-qubit QFT quantum program. The algorithm
+is nicely described on `this page <https://algassert.com/quantum/2014/03/07/Building-your-own-Quantum-Fourier-Transform.html>`_.
+It is a mix of Hadamard and CPHASE gates, with a SWAP gate for bit reversal correction.
+
+.. code:: python
+
+    from math import pi
+
+    def qft3(q0, q1, q2):
+        p = Program()
+        p += [SWAP(q0, q2),
+              H(q0),
+              CPHASE(-pi / 2.0, q0, q1),
+              H(q1),
+              CPHASE(-pi / 4.0, q0, q2),
+              CPHASE(-pi / 2.0, q1, q2),
+              H(q2)]
+        return p
+
+There is a very important detail to recognize here: The function
+``qft3`` doesn't *compute* the QFT, but rather it *makes a quantum
+program* to compute the QFT on qubits ``q0``, ``q1``, and ``q2``.
+
+We can see what this program looks like in Quil notation with ``print(qft(0, 1, 2))``.
+
+.. parsed-literal::
+
+    SWAP 0 2
+    H 0
+    CPHASE(-pi/2) 0 1
+    H 1
+    CPHASE(-pi/4) 0 2
+    CPHASE(-pi/2) 1 2
+    H 2
+
+Part c: Execute the QFT
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Combining parts a and b:
+
+.. code:: python
+
+    compute_qft_prog = state_prep + qft3(0, 1, 2)
+    wavefunction = wf_sim.wavefunction(compute_qft_prog)
+    print(wavefunction.amplitudes)
+
+.. parsed-literal::
+
+    array([ 3.53553391e-01+0.j        ,  2.50000000e-01-0.25j      ,
+            2.16489014e-17-0.35355339j, -2.50000000e-01-0.25j      ,
+           -3.53553391e-01+0.j        , -2.50000000e-01+0.25j      ,
+           -2.16489014e-17+0.35355339j,  2.50000000e-01+0.25j      ])
+
+
+We can verify this works by computing the *inverse* FFT on the output with NumPy and seeing that we get back our input
+(with some floating point error).
+
+.. code:: python
+
+    from numpy.fft import ifft
+    ifft(wavefunction.amplitudes, norm="ortho")
+
+.. parsed-literal::
+
+    array([0.+0.00000000e+00j, 1.+9.38127079e-17j, 0.+0.00000000e+00j,
+           0.-1.53080850e-17j, 0.+0.00000000e+00j, 0.-6.31965379e-17j,
+           0.+0.00000000e+00j, 0.-1.53080850e-17j])
+
+After ignoring the terms that are on the order of ``1e-17``, we get ``[0, 1, 0, 0, 0, 0, 0, 0]``, which was our input!
+
+Example: The Meyer-Penny Game
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To create intuition for quantum algorithms, it is useful (and fun) to play with the abstraction that
+the software provides.
+
+The Meyer-Penny Game [1]_ is a simple example we'll use from quantum game theory. The interested reader may want to read more about
+quantum game theory in the article *Toward a general theory of quantum games* [2]_. The Meyer-Penny Game goes as follows:
+
+The Starship Enterprise, during one of its deep-space missions, is facing an immediate calamity at the edge of a wormhole,
+when a powerful alien suddenly appears. The alien, named Q, offers to help Picard, the captain of the Enterprise, under the
+condition that Picard beats Q in a simple game of heads or tails.
+
+The rules
+---------
+Picard is to place a penny heads up into an opaque box. Then Picard and Q take turns to flip or not flip the penny without
+being able to see it; first Q then P then Q again. After this the penny is revealed; Q wins if it shows heads (H), while
+tails (T) makes Picard the winner.
+
+Picard vs. Q
+------------
+
+Picard quickly estimates that his chance of winning is 50% and agrees to play the game. He loses the first round and
+insists on playing again. To his surprise Q agrees, and they continue playing several rounds more, each of which Picard
+loses. How is that possible?
+
+What Picard did not anticipate is that Q has access to quantum tools. Instead of flipping the penny, Q puts the penny
+into a superposition of heads and tails proportional to the quantum state :math:`|H\rangle+|T\rangle`. Then no matter
+whether Picard flips the penny or not, it will stay in a superposition (though the relative sign might change). In the
+third step Q undoes the superposition and always finds the penny to show heads.
+
+Let's see how this works!
+
+To simulate the game we first construct the corresponding quantum circuit, which takes two qubits: one to simulate
+Picard's choice whether or not to flip the penny, and the other to represent the penny. The initial state for all qubits
+is :math:`|0\rangle` (which is mapped to :math:`|T\rangle`, tails). To simulate Picard's decision, we assume that he
+chooses randomly whether or not to flip the coin, in agreement with the optimal strategy for the classic penny-flip
+game. This random choice can be created by putting one qubit into an equal superposition, e.g. with the Hadamard gate
+:math:`H`, and then measure its state. The measurement will show heads or tails with equal probability :math:`p_h=p_t=0.5`.
+
+To simulate the penny flip game we take the second qubit and put it into its excited state
+:math:`|1\rangle` (which is mapped to :math:`|H\rangle`, heads) by applying the X (or NOT) gate. Q's first move is to
+apply the Hadamard gate H. Picard's decision about the flip is simulated as a CNOT operation where the control bit is
+the outcome of the random number generator described above. Finally Q applies a Hadamard gate again, before we measure
+the outcome. The full circuit is shown in the figure below.
+
+.. figure:: images/MeyerPennyGame.png
+    :align: center
+    :figwidth: 65%
+
+In pyQuil
+---------
+
+We first import and initialize the necessary tools [3]_
+
+.. code:: python
+
+    from pyquil import Program
+    from pyquil.api import WavefunctionSimulator
+    from pyquil.gates import *
+
+    wf_sim = WavefunctionSimulator()
+    p = Program()
+
+and then wire it all up into the overall measurement circuit; remember that qubit 0 is the penny, and qubit 1
+represents Picard's choice.
+
+.. code:: python
+
+    p += X(0)
+    p += H(0)
+    p += H(1)
+    p += CNOT(1, 0)
+    p += H(0)
+
+We use the quantum mechanics principle of deferred measurement to keep all the measurement logic separate from the gates.
+Our method call to the ``WavefunctionSimulator`` will handle measuring for us [4]_.
+
+Finally, we play the game several times. (Remember to run your :ref:`qvm server <server>`.)
+
+.. code:: python
+
+    wf_sim.run_and_measure(p, trials=10)
+
+.. parsed-literal::
+
+    array([[1, 1],
+           [1, 1],
+           [1, 1],
+           [1, 1],
+           [1, 1],
+           [1, 0],
+           [1, 1],
+           [1, 1],
+           [1, 1],
+           [1, 0]])
+
+
+In each trial, the first number is the outcome of the game, whereas the second number represents Picard's choice to flip
+or not flip the penny.
+
+Inspecting the results, we see that no matter what Picard does, Q will always win!
+
+.. [1] https://link.aps.org/doi/10.1103/PhysRevLett.82.1052
+.. [2] https://arxiv.org/abs/quant-ph/0611234
+.. [3] See more: :ref:`basics`
+.. [4] More about measurements and ``run_and_measure``: :ref:`measurement`
diff --git a/docs/source/index.rst b/docs/source/index.rst
index ed8af95..f4c29f5 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -80,6 +80,23 @@ Contents
    changes
    intro
 
+.. toctree::
+   :maxdepth: 1
+   :caption: API Reference
+
+   apidocs/program
+   apidocs/quantum_computer
+   apidocs/compilers
+   apidocs/qam
+   apidocs/devices
+
+.. toctree::
+   :caption: Man Pages
+   :maxdepth: 1
+
+   qvm-man
+   quilc-man
+
 
 Indices and Tables
 ------------------
diff --git a/docs/source/intro.rst b/docs/source/intro.rst
index 9992cb8..198fd6c 100644
--- a/docs/source/intro.rst
+++ b/docs/source/intro.rst
@@ -56,19 +56,20 @@ probabilistic bit) is a two-dimensional real vector space and a
     import numpy as np
     import matplotlib.pyplot as plt
 
+
     outcome_0 = np.array([1.0, 0.0])
     outcome_1 = np.array([0.0, 1.0])
     a = 0.75
     b = 0.25
 
-    prob_bit = a*outcome_0 + b*outcome_1
+    prob_bit = a * outcome_0 + b * outcome_1
 
-    X,Y = prob_bit
+    X, Y = prob_bit
     plt.figure()
     ax = plt.gca()
-    ax.quiver(X,Y,angles='xy',scale_units='xy',scale=1)
-    ax.set_xlim([0,1])
-    ax.set_ylim([0,1])
+    ax.quiver(X, Y, angles='xy', scale_units='xy', scale=1)
+    ax.set_xlim([0, 1])
+    ax.set_ylim([0, 1])
     plt.draw()
     plt.show()
 
@@ -91,11 +92,11 @@ Physicists have introduced a convenient notation for the vector transposes and d
 products we used in the previous example. This notation, called Dirac notation in honor
 of the great theoretical physicist Paul Dirac, allows us to define
 
-.. math::  \vec{v} = |\,v\rangle \\ \vec{v}^T = \langle v\,| \\ \vec{u}^T.\vec{v} = \langle u\,|\,v \rangle.
+.. math::  \vec{v} = \vert v\rangle \\ \vec{v}^T = \langle v \vert \\ \vec{u}^T \cdot \vec{v} = \langle u \vert v \rangle
 
 Thus, we can rewrite our "measurement rule" in this notation as
 
-.. math::  Pr(0) = \langle v\,|\,0 \rangle = a \\ Pr(1) = \langle v\,|\,1 \rangle = b.
+.. math::  Pr(0) = \langle v \vert 0 \rangle = a \\ Pr(1) = \langle v\vert 1 \rangle = b
 
 We will use this notation throughout the rest of this introduction.
 
@@ -112,7 +113,7 @@ programmers). Their states can be represented as
     |\,u\rangle = \frac{1}{2}|\,0_u\rangle + \frac{1}{2}|\,1_u\rangle \\
    |\,v\rangle = \frac{1}{2}|\,0_v\rangle + \frac{1}{2}|\,1_v\rangle,
 
-where \\(1\_u\\) represents the 1 outcome on coin \\(u\\). The
+where \\(1\_u\\) represents the outcome 1 on coin \\(u\\). The
 **combined system** of the two coins has four possible outcomes \\(\\{
 0\_u0\_v,\\;0\_u1\_v,\\;1\_u0\_v,\\;1\_u1\_v \\}\\) that are the basis
 states of a larger four-dimensional vector space. The rule for
@@ -124,11 +125,7 @@ individual states, e.g.
 Then, the combined space is simply the space spanned by the tensor products
 of all pairs of basis vectors of the two smaller spaces.
 
-We will talk more about these larger spaces in the quantum case, but it is
-important to note that not all composite states can be written as tensor
-products of sub-states. (Consider the state \\(\\frac{1}{2}|\\,0\_u0\_v\\rangle + \\frac{1}{2}|\\,1\_u1\_v\\rangle\\).) In general, the combined state for \\(n\\)
-probabilistic bits is a vector of size \\(2^n\\) and is given by
-\\(\\bigotimes\_{i=0}^{n-1}\|\\,v\_i\\rangle\\).
+Similarly, the combined state for \\(n\\) such probabilistic bits is a vector of size \\(2^n\\) and is given by \\(\\bigotimes\_{i=0}^{n-1}\|\\,v\_i\\rangle\\). We will talk more about these larger spaces in the quantum case, but it is important to note that not all composite states can be written as tensor products of sub-states (e.g. consider the state \\(\\frac{1}{2}|\\,0\_u0\_v\\rangle + \\frac{1}{2}|\\,1\_u1\_v\\rangle\\)). The most general composite state of \\(n\\) probabilistic bits can be written as \\(\\sum\_{j=0}^{2^n - 1} a\_{j} (\\bigotimes\_{i=0}^{n-1}\|\\,b\_{ij}\\rangle\\)) where each \\(b\_{ij} \\in \\{0, 1\\}\\) and \\(a_j \\in \\mathbb{R}\\), i.e. as a linear combination (with real coefficients) of tensor products of basis states. Note that this still gives us \\(2^n\\) possible states.
 
 Qubits
 ^^^^^^
@@ -155,7 +152,7 @@ recover acceptable probabilities for outcomes based on our new complex
 vector.
 
 This switch to complex vectors means that rather than representing a
-state vector in a plane, we instead to represent the vector on a
+state vector in a plane, we instead represent the vector on a
 sphere (called the Bloch sphere in quantum mechanics literature).
 From this perspective the quantum state corresponding to an
 outcome of 0 is represented by:
@@ -169,9 +166,7 @@ use the convention that a qubit's \\(\\{\|\\,0\\rangle,
 positive and negative unit vectors along the z axis, respectively. These
 axes will be useful later in this document.
 
-Multiple qubits are represented in precisely the same way, but taking
-tensor products of the spaces and states. Thus \\(n\\) qubits have
-\\(2^n\\) possible states.
+Multiple qubits are represented in precisely the same way, by taking linear combinations (with complex coefficients, now) of tensor products of basis states. Thus \\(n\\) qubits have \\(2^n\\) possible states.
 
 An Important Distinction
 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -180,13 +175,13 @@ An important distinction between the probabilistic case described above
 and the quantum case is that probabilistic states may just mask out
 ignorance. For example a coin is physically only 0 or 1 and the
 probabilistic view merely represents our ignorance about which it actually
-is. **This is not the case in quantum mechanics**. Assuming events cannot instantaneously
-influence one another, the quantum states ---
+is. **This is not the case in quantum mechanics**. Assuming events occuring at a distance from one another cannot instantaneously
+influence each other, the quantum states ---
 as far as we know --- cannot mask any underlying state. This is what
 people mean when they say that there is no `local hidden variable theory
 <https://en.wikipedia.org/wiki/Bell's_theorem>`_ for
 quantum mechanics. These probabilistic quantum states are as real as it
-gets: they don't describe our knowledge of the quantum system, they
+gets: they don't just describe our knowledge of the quantum system, they
 describe the physical reality of the system.
 
 Some Code
@@ -195,7 +190,7 @@ Some Code
 Let us take a look at some code in pyQuil to see how these quantum states
 play out. We will dive deeper into quantum operations and pyQuil in
 the following sections. Note that in order to run these examples you will need
-to `install pyQuil and set up a connection to the Forest API <getting_started.html#getting-started>`_.
+to `install pyQuil and download the QVM and Compiler <start.html>`_.
 Each of the code snippets below will be immediately followed by its output.
 
 .. code:: python
@@ -203,8 +198,11 @@ Each of the code snippets below will be immediately followed by its output.
     # Imports for pyQuil (ignore for now)
     import numpy as np
     from pyquil.quil import Program
-    from pyquil.api import QVMConnection
-    quantum_simulator = QVMConnection()
+    from pyquil.api import WavefunctionSimulator
+
+
+    # create a WavefunctionSimulator object
+    wavefunction_simulator = WavefunctionSimulator()
 
     # pyQuil is based around operations (or gates) so we will start with the most
     # basic one: the identity operation, called I. I takes one argument, the index
@@ -218,7 +216,7 @@ Each of the code snippets below will be immediately followed by its output.
     # We can run this basic program on our connection to the simulator.
     # This call will return the state of our qubits after we run program p.
     # This api call returns a tuple, but we'll ignore the second value for now.
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
 
     # wavefunction is a Wavefunction object that stores a quantum state as a list of amplitudes
     alpha, beta = wavefunction
@@ -245,7 +243,7 @@ Applying an operation to our qubit affects the probability of each outcome.
 
     p = Program(X(0))
 
-    wavefunc = quantum_simulator.wavefunction(p)
+    wavefunc = wavefunction_simulator.wavefunction(p)
     alpha, beta = wavefunc
 
     print("Our qubit is in the state alpha={} and beta={}".format(alpha, beta))
@@ -267,18 +265,18 @@ multiple qubits to grow exponentially in size, as their vectors are tensored tog
 
     # Multiple qubits also produce the expected scaling of the state.
     p = Program(I(0), I(1))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("The quantum state is of dimension:", len(wavefunction.amplitudes))
 
     p = Program(I(0), I(1), I(2), I(3))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("The quantum state is of dimension:", len(wavefunction.amplitudes))
 
     p = Program()
     for x in range(10):
         p += I(x)
-    wavefunction = quantum_simulator.wavefunction(p)
-    print("The quantum state is of dimension:", len(wavefunction.amplitudes)  )
+    wavefunction = wavefunction_simulator.wavefunction(p)
+    print("The quantum state is of dimension:", len(wavefunction.amplitudes))
 
 
 .. parsed-literal::
@@ -294,7 +292,7 @@ those outcomes as values.
 .. code:: python
 
     # wavefunction(Program) returns a coefficient array that corresponds to outcomes in the following order
-    wavefunction = quantum_simulator.wavefunction(Program(I(0), I(1)))
+    wavefunction = wavefunction_simulator.wavefunction(Program(I(0), I(1)))
     print(wavefunction.get_outcome_probs())
 
 
@@ -307,7 +305,7 @@ Qubit Operations
 ----------------
 
 In the previous section we introduced our first two **operations**: the ``I``
-(or identity) operation and the ``X`` operation. In this section we will get into some
+(or Identity) operation and the ``X`` (or NOT) operation. In this section we will get into some
 more details on what these operations are.
 
 Quantum states are complex vectors on the Bloch sphere, and quantum operations are matrices with two properties:
@@ -316,7 +314,7 @@ Quantum states are complex vectors on the Bloch sphere, and quantum operations a
 2. When applied to a state vector on the Bloch sphere, the resulting vector
    is also on the Bloch sphere.
 
-Matrices that satisfy these two properties are called unitary matrices. Applying an operation to a quantum state is the same as multiplying a vector by one of these matrices. Such an operation is called a **gate**.
+Matrices that satisfy these two properties are called unitary matrices. Such matrices have the characteristic property that their complex conjugate transpose is equal to their inverse, a property directly linked to the requirement that the probabilities of measuring qubits in any of the allowed states must sum to 1. Applying an operation to a quantum state is the same as multiplying a vector by one of these matrices. Such an operation is called a **gate**.
 
 Since individual qubits are two-dimensional vectors, operations on
 individual qubits are 2x2 matrices. The identity matrix leaves the state vector unchanged:
@@ -346,7 +344,7 @@ so the program that applies this operation to the zero state is just
 .. code:: python
 
     p = Program(I(0))
-    print(quantum_simulator.wavefunction(p))
+    print(wavefunction_simulator.wavefunction(p))
 
 .. parsed-literal::
 
@@ -380,20 +378,21 @@ called the Pauli operators:
 
     from pyquil.gates import X, Y, Z
 
+
     p = Program(X(0))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("X|0> = ", wavefunction)
     print("The outcome probabilities are", wavefunction.get_outcome_probs())
     print("This looks like a bit flip.\n")
 
     p = Program(Y(0))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("Y|0> = ", wavefunction)
     print("The outcome probabilities are", wavefunction.get_outcome_probs())
     print("This also looks like a bit flip.\n")
 
     p = Program(Z(0))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("Z|0> = ", wavefunction)
     print("The outcome probabilities are", wavefunction.get_outcome_probs())
     print("This state looks unchanged.")
@@ -430,7 +429,7 @@ Quantum programs are built by applying successive gate operations:
 
     # Composing qubit operations is the same as multiplying matrices sequentially
     p = Program(X(0), Y(0), Z(0))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
 
     print("ZYX|0> = ", wavefunction)
     print("With outcome probabilities\n", wavefunction.get_outcome_probs())
@@ -466,25 +465,26 @@ Let's take a look at how we could use a ``CNOT`` gate in pyQuil.
 
     from pyquil.gates import CNOT
 
+
     p = Program(CNOT(0, 1))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("CNOT|00> = ", wavefunction)
-    print("With outcome probabilities\n", wavefunction.get_outcome_probs())
+    print("With outcome probabilities\n", wavefunction.get_outcome_probs(), "\n")
 
     p = Program(X(0), CNOT(0, 1))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("CNOT|01> = ", wavefunction)
-    print("With outcome probabilities\n", wavefunction.get_outcome_probs())
+    print("With outcome probabilities\n", wavefunction.get_outcome_probs(), "\n")
 
     p = Program(X(1), CNOT(0, 1))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("CNOT|10> = ", wavefunction)
-    print("With outcome probabilities\n", wavefunction.get_outcome_probs())
+    print("With outcome probabilities\n", wavefunction.get_outcome_probs(), "\n")
 
     p = Program(X(0), X(1), CNOT(0, 1))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
     print("CNOT|11> = ", wavefunction)
-    print("With outcome probabilities\n", wavefunction.get_outcome_probs())
+    print("With outcome probabilities\n", wavefunction.get_outcome_probs(), "\n")
 
 
 .. parsed-literal::
@@ -525,8 +525,10 @@ and \\(\|10\\rangle \\) states:
 .. code:: python
 
     from pyquil.gates import SWAP
+
+
     p = Program(X(0), SWAP(0,1))
-    wavefunction = quantum_simulator.wavefunction(p)
+    wavefunction = wavefunction_simulator.wavefunction(p)
 
     print("SWAP|01> = ", wavefunction)
     print("With outcome probabilities\n", wavefunction.get_outcome_probs())
@@ -577,43 +579,46 @@ Here's a simple example:
 .. code:: python
 
     # Create a program that stores the outcome of measuring qubit #0 into classical register [0]
-    classical_register_index = 0
-    p = Program(I(0)).measure(0, classical_register_index)
+    p = Program()
+    classical_register = p.declare('ro', 'BIT', 1)
+    p += Program(I(0)).measure(0, classical_register[0])
 
 Up until this point we have used the quantum simulator to cheat a little bit --- we have
 actually looked at the wavefunction that comes back. However, on real
 quantum hardware, we are unable to directly look at the wavefunction.
 Instead we only have access to the classical bits that are affected by
-measurements. This functionality is emulated by the ``run`` command.
+measurements. This functionality is emulated by :py:func:`QuantumComputer.run`. Note that the ``run`` command is to be applied on the compiled version of the program.
 
 .. code:: python
 
-    # Choose which classical registers to look in at the end of the computation
-    classical_regs = [0, 1]
-    print(quantum_simulator.run(p, classical_regs))
+    from pyquil import get_qc
+
+
+    qc = get_qc('9q-square-qvm')
+    print (qc.run(qc.compile(p)))
 
 
 .. parsed-literal::
 
-    [[0, 0]]
+    [[0]]
 
 
-We see that both registers are zero. However, if we had flipped the
+We see that the classical register reports a value of zero. However, if we had flipped the
 qubit before measurement then we obtain:
 
 .. code:: python
 
-    classical_register_index = 0
-    p = Program(X(0)) # Flip the qubit
-    p.measure(0, classical_register_index) # Measure the qubit
+    p = Program()
+    classical_register = p.declare('ro', 'BIT', 1)
+    p += Program(X(0))   # Flip the qubit
+    p.measure(0, classical_register[0])   # Measure the qubit
 
-    classical_regs = [0, 1]
-    print(quantum_simulator.run(p, classical_regs))
+    print (qc.run(qc.compile(p)))
 
 
 .. parsed-literal::
 
-    [[1, 0]]
+    [[1]]
 
 
 These measurements are deterministic, e.g. if we make them multiple
@@ -621,13 +626,15 @@ times then we always get the same outcome:
 
 .. code:: python
 
-    classical_register_index = 0
-    p = Program(X(0)) # Flip the qubit
-    p.measure(0, classical_register_index) # Measure the qubit
+    p = Program()
+    classical_register = p.declare('ro', 'BIT', 1)
+    p += Program(X(0))   # Flip the qubit
+    p.measure(0, classical_register[0])   # Measure the qubit
 
-    classical_regs = [0]
     trials = 10
-    print(quantum_simulator.run(p, classical_regs, trials))
+    p.wrap_in_numshots_loop(shots=trials)
+
+    print (qc.run(qc.compile(p)))
 
 
 .. parsed-literal::
@@ -655,9 +662,10 @@ The following pyQuil code shows how we can use the Hadamard gate:
 
     from pyquil.gates import H
 
+
     # The Hadamard produces what is called a superposition state
     coin_program = Program(H(0))
-    wavefunction = quantum_simulator.wavefunction(coin_program)
+    wavefunction = wavefunction_simulator.wavefunction(coin_program)
 
     print("H|0> = ", wavefunction)
     print("With outcome probabilities\n", wavefunction.get_outcome_probs())
@@ -687,13 +695,16 @@ extra power over regular bits.
 
 .. code:: python
 
-    # Introduce measurement
-    classical_reg = 0
-    coin_program = Program(H(0)).measure(0, classical_reg)
-    trials = 10
+    p = Program()
+    ro = p.declare('ro', 'BIT', 1)
+
+    p += Program(H(0)).measure(0, ro[0])
+
+    # Measure qubit #0 a number of times
+    p.wrap_in_numshots_loop(shots=10)
 
     # We see probabilistic results of about half 1's and half 0's
-    print(quantum_simulator.run(coin_program, [0], trials))
+    print (qc.run(qc.compile(p)))
 
 
 .. parsed-literal::
@@ -705,22 +716,22 @@ pyQuil allows us to look at the wavefunction **after** a measurement as well:
 
 .. code:: python
 
-    classical_reg = 0
     coin_program = Program(H(0))
-    print("Before measurement: H|0> = ", quantum_simulator.wavefunction(coin_program))
+    print ("Before measurement: H|0> = ", wavefunction_simulator.wavefunction(coin_program), "\n")
 
-    coin_program.measure(0, classical_reg)
-    for x in range(5):
-        print("After measurement: ", quantum_simulator.wavefunction(coin_program))
+    ro = coin_program.declare('ro', 'BIT', 1)
+    coin_program.measure(0, ro[0])
+    for _ in range(5):
+        print ("After measurement: ", wavefunction_simulator.wavefunction(coin_program))
 
 
 .. parsed-literal::
 
-    Before measurement: H|0> =  [ 0.70710678+0.j  0.70710678+0.j]
+    Before measurement: H|0> =  (0.7071067812+0j)|0> + (0.7071067812+0j)|1> 
 
     After measurement:  (1+0j)|1>
-    After measurement:  (1+0j)|0>
-    After measurement:  (1+0j)|0>
+    After measurement:  (1+0j)|1>
+    After measurement:  (1+0j)|1>
     After measurement:  (1+0j)|1>
     After measurement:  (1+0j)|1>
 
@@ -736,28 +747,27 @@ the obtained outcome and subsequently rescaled to unit norm.
 
 .. code:: python
 
-    # This happens with bigger systems too
-    classical_reg = 0
-
-    # This program prepares something called a Bell state (a special kind of "entangled state")
+    # This happens with bigger systems too, as can be seen with this program,
+    # which prepares something called a Bell state (a special kind of "entangled state")
     bell_program = Program(H(0), CNOT(0, 1))
-    wavefunction = quantum_simulator.wavefunction(bell_program)
-    print("Before measurement: Bell state = ", wavefunction)
+    wavefunction = wavefunction_simulator.wavefunction(bell_program)
+    print("Before measurement: Bell state = ", wavefunction, "\n")
 
-    bell_program.measure(0, classical_reg)
-    for x in range(5):
-        wavefunction = quantum_simulator.wavefunction(bell_program)
-        print("After measurement: ", wavefunction.get_outcome_probs())
+    classical_regs = bell_program.declare('ro', 'BIT', 2)
+    bell_program.measure(0, classical_regs[0]).measure(1, classical_regs[1])
 
+    for _ in range(5):
+        wavefunction = wavefunction_simulator.wavefunction(bell_program)
+        print("After measurement: ", wavefunction.get_outcome_probs())
 
 .. parsed-literal::
 
-    Before measurement: Bell state =  (0.7071067812+0j)|00> + (0.7071067812+0j)|11>
+    Before measurement: Bell state =  (0.7071067812+0j)|00> + (0.7071067812+0j)|11> 
 
-    After measurement:  {'00': 1.0, '01': 0.0, '10': 0.0, '11': 0.0}
     After measurement:  {'00': 0.0, '01': 0.0, '10': 0.0, '11': 1.0}
-    After measurement:  {'00': 1.0, '01': 0.0, '10': 0.0, '11': 0.0}
-    After measurement:  {'00': 1.0, '01': 0.0, '10': 0.0, '11': 0.0}
+    After measurement:  {'00': 0.0, '01': 0.0, '10': 0.0, '11': 1.0}
+    After measurement:  {'00': 0.0, '01': 0.0, '10': 0.0, '11': 1.0}
+    After measurement:  {'00': 0.0, '01': 0.0, '10': 0.0, '11': 1.0}
     After measurement:  {'00': 0.0, '01': 0.0, '10': 0.0, '11': 1.0}
 
 
@@ -779,21 +789,23 @@ quantum operations to run.
     true_branch = Program(X(7)) # if branch
     false_branch = Program(I(7)) # else branch
 
-    # Branch on classical reg [1]
-    p = Program(X(0)).measure(0, 1).if_then(1, true_branch, false_branch)
+    # Branch on ro[1]
+    p = Program()
+    ro = p.declare('ro', 'BIT', 8)
+    p += Program(X(0)).measure(0, ro[1]).if_then(ro[1], true_branch, false_branch)
 
-    # Measure qubit #7 into classical register [7]
-    p.measure(7, 7)
+    # Measure qubit #7 into ro[7]
+    p.measure(7, ro[7])
 
     # Run and check register [7]
-    print(quantum_simulator.run(p, [7]))
+    print (qc.run(qc.compile(p)))
 
 
 .. parsed-literal::
 
-    [[1]]
+    [[1 1]]
 
-A [1] here means that qubit 7 was indeed flipped.
+The second [1] here means that qubit 7 was indeed flipped.
 
 .. image:: images/branch.png
 
@@ -805,12 +817,13 @@ increasing chance of halting, but that may run forever!
 
 .. code:: python
 
-    inside_loop = Program(H(0)).measure(0, 1)
-
-    p = Program().inst(X(0)).while_do(1, inside_loop)
+    p = Program()
+    ro = p.declare('ro', 'BIT', 1)
+    inside_loop = Program(H(0)).measure(0, ro[0])
+    p.inst(X(0)).while_do(0, inside_loop)
 
-    # Run and check register [1]
-    print(quantum_simulator.run(p, [1]))
+    qc = get_qc('9q-square-qvm')
+    print (qc.run(qc.compile(p)))
 
 
 .. parsed-literal::
diff --git a/docs/source/migration.rst b/docs/source/migration.rst
index 2e791a5..720566c 100644
--- a/docs/source/migration.rst
+++ b/docs/source/migration.rst
@@ -58,6 +58,8 @@ would have the same effect as
     # disentangle, bringing us back to identity
     DAGGER BELL
 
+.. _parametric:
+
 Parametric programs
 ~~~~~~~~~~~~~~~~~~~
 
@@ -360,7 +362,7 @@ instructions to target.
     MEASURE 3 ro[3]""")
         return program
 
-Next, we modify the execution loop. Rather than reformulating the ``Program`` object each time, we build and compile it
+Next, we modify the execution loop. Rather than reformulating the :py:class:`~pyquil.quil.Program` object each time, we build and compile it
 once, then use the ``.load()`` method to transfer the parametric program to the (simulated) quantum device. We then set
 only the angle value within the inner loop, and we change to using ``.run()`` and ``.wait()`` methods to manage control
 between us and the quantum device.
@@ -388,20 +390,14 @@ becomes
 .. code:: python
 
     # set up the Program object, ONLY ONCE
-    program = build_wf_ansatz_prep()
-    program.wrap_in_numshots_loop(shots=shots)
-    nq_program = qc.compiler.quil_to_native_quil(program)
-    binary = qc.compiler.native_quil_to_executable(nq_program)
-    qc.qam.load(binary)
+    program = build_wf_ansatz_prep().wrap_in_numshots_loop(shots=shots)
+    binary = qc.compile(program)
 
     # get all the unweighted expectations for all the sample wavefunctions
     occupations = list(range(angle_min, angle_max))
     indices = list(range(4))
     for offset in occupations:
-        qc.qam.write_memory(region_name='theta', value=angle_min + offset * angle_step)
-        qc.qam.run()
-        qc.qam.wait()
-        bitstrings = qc.qam.read_memory(region_name="ro")
+        bitstrings = qc.run(binary, {'theta': [angle_min + offset * angle_step]})
 
         totals = [0, 0, 0, 0]
         for bitstring in bitstrings:
@@ -470,20 +466,14 @@ Overall, the resulting program looks like this:
     qc = setup_forest_objects()
 
     # set up the Program object, ONLY ONCE
-    program = build_wf_ansatz_prep()
-    program.wrap_in_numshots_loop(shots=shots)
-    nq_program = qc.compiler.quil_to_native_quil(program)
-    binary = qc.compiler.native_quil_to_executable(nq_program)
-    qc.qam.load(binary)
+    program = build_wf_ansatz_prep().wrap_in_numshots_loop(shots=shots)
+    binary = qc.compile(program)
 
     # get all the unweighted expectations for all the sample wavefunctions
     occupations = list(range(angle_min, angle_max))
     indices = list(range(4))
     for offset in occupations:
-        qc.qam.write_memory(region_name='theta', value=angle_min + offset * angle_step)
-        qc.qam.run()
-        qc.qam.wait()
-        bitstrings = qc.qam.read_memory(region_name="ro")
+        bitstrings = qc.run(binary, {'theta': [angle_min + offset * angle_step]})
 
         totals = [0, 0, 0, 0]
         for bitstring in bitstrings:
@@ -642,3 +632,26 @@ location:
 
 Please attach such a logfile to any request for support.
 
+Parametric Programs
+~~~~~~~~~~~~~~~~~~~
+
+In PyQuil 1.x, there was an object named ``ParametricProgram``::
+
+    # This function returns a quantum circuit with different rotation angles on a gate on qubit 0
+    def rotator(angle):
+        return Program(RX(angle, 0))
+
+    from pyquil.parametric import ParametricProgram
+    par_p = ParametricProgram(rotator) # This produces a new type of parameterized program object
+
+This object has been removed from PyQuil 2. Please consider simply using a Python function for
+the above functionality::
+
+    par_p = rotator
+
+Or using declared classical memory::
+
+    p = Program()
+    angle = p.declare('angle', 'REAL')
+    p += RX(angle, 0)
+
diff --git a/docs/source/modules.rst b/docs/source/modules.rst
index a0a2eb2..88a5a8a 100644
--- a/docs/source/modules.rst
+++ b/docs/source/modules.rst
@@ -1,14 +1,6 @@
 Source Code Documentation
 =========================
 
-pyquil.api
-----------
-
-.. automodule:: pyquil.api
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
 pyquil.device
 -------------
 
@@ -49,14 +41,6 @@ pyquil.paulis
     :undoc-members:
     :show-inheritance:
 
-pyquil.quil
------------
-
-.. automodule:: pyquil.quil
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
 pyquil.quilbase
 ---------------
 
diff --git a/docs/source/noise.rst b/docs/source/noise.rst
index 677b548..327f2ca 100644
--- a/docs/source/noise.rst
+++ b/docs/source/noise.rst
@@ -3,7 +3,6 @@
 Noise and Quantum Computation
 =============================
 
-
 Modeling Noisy Quantum Gates
 ----------------------------
 
@@ -289,6 +288,7 @@ Getting Started
 
     cxn = QVMConnection()
 
+
 Example 1: Amplitude Damping
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1266,3 +1266,47 @@ Estimate :math:`\langle Z_0^{j} Z_1^{k} Z_2^{\ell}\rangle` for :math:`jkl=110, 0
 Overall the correction can restore the contrast in our multi-qubit observables,
 though we also see that the correction can lead to slightly non-physical expectations.
 This effect is reduced the more samples we take.
+
+
+Alternative: A global Pauli error model
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Rigetti QVM has support for emulating certain types of noise models.
+One such model is *parametric Pauli noise*, which is defined by a
+set of 6 probabilities:
+
+-  The probabilities :math:`P_X`, :math:`P_Y`, and :math:`P_Z` which
+   define respectively the probability of a Pauli :math:`X`, :math:`Y`,
+   or :math:`Z` gate getting applied to *each* qubit after *every* gate
+   application. These probabilities are called the *gate noise
+   probabilities*.
+
+-  The probabilities :math:`P_X'`, :math:`P_Y'`, and :math:`P_Z'` which
+   define respectively the probability of a Pauli :math:`X`, :math:`Y`,
+   or :math:`Z` gate getting applied to the qubit being measured
+   *before* it is measured. These probabilities are called the
+   *measurement noise probabilities*.
+
+We can instantiate a noisy QVM by creating a new connection with these
+probabilities specified.
+
+.. code:: python
+
+    # 20% chance of a X gate being applied after gate applications and before measurements.
+    gate_noise_probs = [0.2, 0.0, 0.0]
+    meas_noise_probs = [0.2, 0.0, 0.0]
+    noisy_qvm = qvm(gate_noise=gate_noise_probs, measurement_noise=meas_noise_probs)
+
+We can test this by applying an :math:`X`-gate and measuring. Nominally,
+we should always measure ``1``.
+
+.. code:: python
+
+    p = Program().inst(X(0)).measure(0, 0)
+    print("Without Noise: {}".format(qvm.run(p, [0], 10)))
+    print("With Noise   : {}".format(noisy_qvm.run(p, [0], 10)))
+
+.. parsed-literal::
+
+    Without Noise: [[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]
+    With Noise   : [[0], [0], [0], [0], [0], [1], [1], [1], [1], [0]]
diff --git a/docs/source/quilc-man.rst b/docs/source/quilc-man.rst
new file mode 100644
index 0000000..ddf3058
--- /dev/null
+++ b/docs/source/quilc-man.rst
@@ -0,0 +1,134 @@
+.. _quilc_man:
+
+QUILC Man Page
+==============
+
+NAME
+~~~~
+
+``quilc`` - an optimizing, architecture-independent Quil compiler
+
+SYNOPSIS
+~~~~~~~~
+
+``quilc <options>``
+
+DESCRIPTION
+~~~~~~~~~~~
+
+The Rigetti Quil compiler, ``quilc``, is an optimizing compiler for Quil. It
+takes a general Quil program along with a qubit architecture, called an
+ISA, and produces another Quil program that is executable on that
+architecture. The compiler will also attempt to optimize the program by
+producing fewer gates and shorter gate depths. The compiler may either
+be run as a server which takes requests (as is used with PyQuil), or it
+may be run as a batch program reading from standard input.
+
+Server Mode runs the compiler as an HTTP server, taking simple POST
+requests with JSON payloads which are known to the companion library
+pyQuil.
+
+OPTIONS
+~~~~~~~
+
+``-S, --server``
+      (Server Mode) Run the compiler in Server Mode. This starts an HTTP server.
+
+``-?, -h, --help``
+      Show the help message.
+
+``-v, --version``
+      Show the version.
+
+``--verbose``
+      Print what the compiler is thinking. (Warning: It thinks a lot.)
+
+``--isa <string>``
+      Compile  for  the  qubit  architecture  defined  by  <string>,  which can be either 8Q, 20Q, 16QMUX, or a path to a QPU
+      description file.
+
+``-p, --protoquil``
+      Prescribe that the input and output must be ProtoQuil, which is Quil that is comprised of gates and measurements,  with
+      no control flow.
+
+``--port <port>``
+      (Server Mode) Run quilc in server mode on port <port>.
+
+``-d, --compute-gate-depth``
+      Print a calculated gate depth for the provided circuit as an appended Quil comment. (Requires -p.)
+
+``-2, --compute-2Q-gate-depth``
+      Print  a  calculated  multiqubit gate depth for the provided circuit as an appended Quil comment. (Requires -p. Ignores
+      the blacklist and whitelist.)
+
+``--compute-gate-volume``
+      Print a calculated gate volume for the provided circuit as an appended Quil comment. (Requires -p.)
+
+``-r, --compute-runtime``
+      Print a calculated estimated runtime for the provided circuit as an appended Quil comment. (Requires -p.)
+
+``-f, --compute-fidelity``
+      Print a calculated estimated compiled circuit fidelity for the provided circuit as an appended Quil comment.  (Requires
+      -p.)
+
+``-u, --compute-unused-qubits``
+      Print a list of unused qubits as an appended Quil comment. (Requires -p.)
+
+``-t, --show-topological-overhead``
+      Print  the  number of SWAP gates incurred for topological reasons for the provided circuit as an appended Quil comment.
+      (Requires -p.)
+
+``--gate-blacklist <gate-list>``
+      When calculating statistics, ignore the gates present in the comma-separated list of names of <gate-list>.
+
+``--gate-whitelist <gate-list>``
+      When calculating statistics, consider only the gates present in the comma-separated list of names of <gate-list>.
+
+``--time-limit <limit-ms>``
+      (Server Mode) Limit the amount of time for a single request to approximately <limit-ms> milliseconds. By default,  this
+      value is 0, which indicates an unlimited amount of time is allowed.
+
+``--without-pretty-printing``
+      Disable pretty printing of numerical quantities (e.g., multiples of pi) in compiled output.
+
+``--prefer-gate-ladders``
+      Use gate ladders, instead of the SWAP gate, to implement long-ranged gates, when possible.
+
+``-j, --json-serialize``
+      Serialize the output of compilation as a JSON object.
+
+``-s, --print-logical-schedule``
+      Include the logically parallelized schedule in JSON output. (Requires -p.)
+
+``-m, --compute-matrix-reps``
+      Print  the  matrix  representation  of  a compiled ProtoQuil program. Additionally, verify that this matrix matches the
+      matrix representation of the input program. (Requires -p. Note that this is a very expensive operation.)
+
+``--enable-state-prep-reductions``
+      Perform program optimizations by assuming that the quantum state starts in the zero state.
+
+EXAMPLES
+~~~~~~~~
+
+``quilc --isa "8Q" < file.quil``
+      Compile a Quil file (printing the result to stdout) for an eight qubit ring.
+
+SUPPORT
+~~~~~~~
+
+Contact <support@rigetti.com>.
+
+COPYRIGHT
+~~~~~~~~~
+
+Copyright (c) 2018 Rigetti Computing
+
+SEE ALSO
+~~~~~~~~
+
+:ref:`qvm(1) <qvm_man>`
+
+0.13.0 (cl-quil: 0.19.0) [e9b41e3]                        24 September 2018                                                  QUILC(1)
+
+
+
diff --git a/docs/source/qvm-man.rst b/docs/source/qvm-man.rst
new file mode 100644
index 0000000..9bd217e
--- /dev/null
+++ b/docs/source/qvm-man.rst
@@ -0,0 +1,143 @@
+.. _qvm_man:
+
+QVM Man Page
+============
+
+NAME
+~~~~
+
+``qvm`` - a quantum virtual machine for executing Quil
+
+SYNOPSIS
+~~~~~~~~
+
+``qvm <options> -e`` # Execute Mode
+
+``qvm <options> -S`` # Server Mode
+
+``qvm <options> --benchmark [n]`` # Benchmark Mode
+
+DESCRIPTION
+~~~~~~~~~~~
+
+The Rigetti QVM is a high-performance, classical implementation of a
+quantum abstract machine. Specifically, it is capable of executing Quil
+in a variety of ways. The QVM has three main modes of operation: Execute
+Mode, Server Mode, and Benchmark Mode.
+
+Execute Mode runs the QVM on a single Quil file, printing out
+information about the execution, as well as a textual representation of
+the wavefunction if ``--verbose`` is provided. (If one would like full
+access to the wavefunction as an efficient representation, one should
+use ``--shared``.)
+
+Server Mode runs the QVM as an HTTP server, taking simple POST requests
+with JSON payloads which are known to the companion library PyQuil. The
+server is useful even to a single user wishing to run a variety of
+computations.
+
+Benchmark Mode is used for stress testing the QVM on a computer.
+
+The QVM implements both a Quil interpreter and a just-in-time (JIT)
+compiler. (Note that "compilation" here does not refer to the sense
+related to translation of gate sets, but rather translation to machine
+code for rapid execution.) Interpreted mode is enabled by default and
+works for all modes of operation. JIT compilation is enabled by
+supplying the ``--compile`` option.
+
+The QVM does not have explicit options for running programs with noise
+models. Instead, the Quil program itself specifies PRAGMAs for defining
+Kraus operators and readout POVMs.
+
+OPTIONS
+~~~~~~~
+
+``-e, --execute``
+      (Execute Mode) Run the QVM in Execute Mode. Execute the Quil program supplied from stdin  and  print  some  information
+      about the course of evaluation.
+
+``-S, --server``
+      (Server Mode) Run the QVM in Server Mode. This starts an HTTP server.
+
+``--benchmark [<n>]``
+      (Benchmark Mode) Run the QVM benchmark on <n> qubits. The default is 26.
+
+``-p <port>, --port <port>``
+      (Server Mode) Run the QVM server on port <port>. The default is 5000.
+
+``--memory-limit <num-octets>``
+      Limit the amount of classical memory to <num-octets> octets usable by an individual Quil program. The default is 65536.
+
+``-w <n>, --num-workers <n>``
+      Force the number of parallel workers to be <n>. By default, this is the number of logical cores of the host machine.
+
+``--time-limit <limit-ms>``
+      (Server  Mode) Limit the amount of time for a single request to approximately <limit-ms> milliseconds. By default, this
+      value is 0, which indicates an unlimited amount of time is allowed.
+
+``--qubit-limit <n>``
+      (Server Mode) Limit requests to consuming <n> qubits.
+
+``--benchmark-type <name>``
+      (Benchmark Mode) Run the benchmark named <name>. Benchmarks include "bell", "qft", "hadamard".
+
+``-h, --help``
+      Show the help message.
+
+``-v, --version``
+      Show the version.
+
+``--verbose``
+      Print every instruction transition of the QVM with information about timing and allocation.
+
+      (Execute Mode) Print each basis state and corresponding amplitude of the evolved wavefunction.
+
+``-c, --compile``
+      JIT compile the Quil programs to make them run faster.
+
+``--safe-include-directory <dir>``
+      Only allow <dir> to be included from with the Quil INCLUDE directive.
+
+``--shared <name>``
+      (Server Mode) Run the QVM in shared memory mode. This allocates the wavefunction in POSIX shared memory  named  <name>.
+      If <name> is an empty string, then a name will be generated. The --qubits argument must be specified.
+
+
+EXAMPLES
+~~~~~~~~
+
+``qvm -e < file.quil``
+      Run a Quil file on the QVM.
+
+``printf "H 0\nCNOT 0 1\nCNOT 1 2" | qvm --verbose -e``
+      Create a 3-qubit Bell state, printing information about the execution along the way.
+
+``qvm -S -p 1234``
+      Start a QVM server for use with PyQuil on port 1234.
+
+``qvm -c --benchmark 25 --benchmark-type qft``
+      Benchmark a 25-qubit quantum Fourier transform in compiled mode.
+
+BUGS
+~~~~
+
+Shared memory mode does not work with QVMs executing noisy programs (i.e., ones where Kraus operators or POVMs are specified).
+
+The WAIT instruction does nothing.
+
+SUPPORT
+~~~~~~~
+
+Contact <support@rigetti.com>.
+
+COPYRIGHT
+~~~~~~~~~
+
+Copyright (c) 2018 Rigetti Computing
+
+SEE ALSO
+~~~~~~~~
+
+:ref:`quilc(1) <quilc_man>`
+
+version 0.16.0 (qvm: 0.20.0) [1b48c69]                    21 September 2018                                                    QVM(1)
diff --git a/docs/source/qvm.rst b/docs/source/qvm.rst
index cde5f65..ddf4e9e 100644
--- a/docs/source/qvm.rst
+++ b/docs/source/qvm.rst
@@ -1,347 +1,108 @@
 .. _qvm:
 
+The Quantum Computer
+====================
+
 The Quantum Virtual Machine (QVM)
-=================================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The Rigetti Quantum Virtual Machine is an implementation of the Quantum Abstract Machine from
 *A Practical Quantum Instruction Set Architecture*. [1]_  It is implemented in ANSI Common LISP and
-executes programs specified in the Quantum Instruction Language (Quil). Quil is an opinionated
-quantum instruction language: its basic belief is that in the near term quantum computers will
-operate as coprocessors, working in concert with traditional CPUs.  This means that Quil is
-designed to execute on a Quantum Abstract Machine that has a shared classical/quantum architecture
-at its core. The QVM is a wavefunction simulation of unitary evolution with classical control flow
+executes programs specified in the Quantum Instruction Language (Quil).
+
+Quil is an opinionated quantum instruction language: its basic belief is that in the near term quantum computers will
+operate as coprocessors, working in concert with traditional CPUs.  This means that Quil is designed to execute on
+a Quantum Abstract Machine that has a shared classical/quantum architecture at its core.
+
+The QVM is a wavefunction simulation of unitary evolution with classical control flow
 and shared quantum classical memory.
 
 .. _qvm_use:
 
 Using the QVM
 -------------
-After `downloading the SDK <rigetti.com/forest>`_,the QVM is available on your local machine. You can initialize a local
-QVM instance by doing the following:
-
+After :ref:`downloading the SDK <sdkinstall>`, the QVM is available on your local machine. You can initialize a local
+QVM server by typing ``qvm -S`` into your terminal. You should see the following message.
 
 .. code:: python
 
-    ### CONSOLE 1
     $ qvm -S
-    Configured with 2048 MiB of workspace and 8 workers.)
-    [2018-09-20 15:39:50] Starting server on port 5000.
+    ******************************
+    * Welcome to the Rigetti QVM *
+    ******************************
+    Copyright (c) 2018 Rigetti Computing.
 
+    (Configured with 2048 MiB of workspace and 8 workers.)
 
-.. code:: python
+    [2018-11-06 18:18:18] Starting server on port 5000.
 
-    from pyquil import get_qc, Program
-    from pyquil.gates import *
-    qvm = get_qc('9q-square-qvm')
-
-
-One executes quantum programs on the QVM using a ``.run(...)`` method, intended to closely mirror how one will execute programs on a
-real QPU (check out `our website to see current and legacy QPUs <rigetti.com/qpu>`_). We also offer a Wavefunction Simulator
-(formerly a part of the QVM object), which allows users to contruct and inspect wavefunctions of quantum programs. Learn more
-about :ref:`wavefunction_simulator`.
+For a detailed description of how to use the ``qvm`` from the command line, see :ref:`The QVM manual page <qvm_man>`.
 
-(For information on constructing quantum programs, please refer back to :ref:`basics`.)
-
-The ``.run(...)`` method
-~~~~~~~~~~~~~~~~~~~~~~~~
+Once the QVM is serving requests, we can run the following pyQuil program to get a ``QuantumComputer`` object which
+will use the QVM.
 
 .. code:: python
 
-    program = Program(X(0), MEASURE(0, 0))
-    results = qvm.run(program)
-    # results = [[1]]
-
-The ``.run(...)`` method takes numerous arguments, several of which are optional. The most important
-are
-
-1. the ``program`` to be executed on the QVM,
-2. the ``classical_addresses`` which to be returned from the QVM (not included above; by default, these are set to the addresses used in the program's ``MEASURE`` instructions), and
-3. the number of ``trials`` to be executed on the machine.
-
-The results returned are a *list of lists of integers*. In the above case, that's
-
-.. parsed-literal::
-
-    [[1]]
-
-Let's unpack this. The *outer* list is an
-enumeration over the trials; if you set ``trials=1`` then ``len(results)`` should equal ``1``.
-
-The *inner* list, on the other hand, is an enumeration over the results stored in the classical
-addresses. We see that the result of this program is that the classical register ``[0]`` now stores
-the state of qubit 0, which should be ``1`` after an :math:`X`-gate. We
-can of course ask for more classical registers:
-
-.. code:: python
+    from pyquil import get_qc, Program
+    from pyquil.gates import *
+    qc = get_qc('9q-square-qvm')
 
-    qvm.run(p, [0, 1, 2])
 
-.. parsed-literal::
+One executes quantum programs on the QVM using the ``.run(...)`` method, intended to closely mirror how one will
+execute programs on a real QPU. We also offer a Wavefunction Simulator (formerly a part of the ``QVM`` object),
+which allows users to contruct and inspect wavefunctions of quantum programs. Learn more
+about the Wavefunction Simulator :ref:`here <wavefunction_simulator>`. For information on constructing quantum
+programs, please refer back to :ref:`basics`.
 
-    [[1, 0, 0]]
+The ``.run(...)`` method
+------------------------
 
-The classical registers are initialized to zero, so registers ``[1]``
-and ``[2]`` come out as zero. If we stored the measurement in a
-different classical register we would obtain:
+The ``.run(...)`` method takes in a compiled program. You are responsible for compiling your program before running it.
+Remember to also start up a ``quilc`` compiler server, too, with ``quilc -S``.
 
 .. code:: python
 
-    p = Program()   # clear the old program
-    p.inst(X(0)).measure(0, 1)
-    qvm.run(p, [0, 1, 2])
-
-.. parsed-literal::
+    p = Program()
+    ro = p.declare('ro', 'BIT', 1)
+    p += X(0)
+    p += MEASURE(0, ro[0])
+    p += MEASURE(1, ro[1])
+    p.wrap_in_numshots_loop(5)
+    executable = qc.compile(p)
+    results = qc.run(executable)
+    print(results)
 
-    [[0, 1, 0]]
-
-We can also run programs multiple times and accumulate all the results
-in a single list.
-
-.. code:: python
-
-    coin_flip = Program().inst(H(0)).measure(0, 0)
-    num_flips = 5
-    qvm.run(coin_flip, [0], num_flips)
+The results returned are a *list of lists of integers*. In the above case, that's
 
 .. parsed-literal::
 
-    [[0], [1], [0], [1], [0]]
-
-Try running the above code several times. You will see that you will,
-with very high probability, get different results each time.
-
-Multi-Qubit Basis Enumeration
------------------------------
-
-The Rigetti QVM enumerates bitstrings such that qubit `0` is the least significant bit (LSB)
-and therefore on the right end of a bitstring as shown in the table below which contains some
-examples.
-
-=============== ============= ===== ========= ========= =========
- bitstring       qubit_(n-1)   ...   qubit_2   qubit_1   qubit_0
-=============== ============= ===== ========= ========= =========
-  1...101                  1   ...         1         0         1
-  0...110                  0   ...         1         1         0
-=============== ============= ===== ========= ========= =========
-
-
-
-This convention is counter to that often found in the quantum computing literature where
-bitstrings are often ordered such that the lowest-index qubit is on the left.
-The vector representation of a wavefunction assumes the "canonical" ordering of basis elements.
-I.e., for two qubits this order is ``00, 01, 10, 11``.
-In the typical Dirac notation for quantum states, the tensor product of two different degrees of
-freedom is not always explicitly understood as having a fixed order of those degrees of freedom.
-This is in contrast to the kronecker product between matrices which uses the same mathematical
-symbol and is clearly not commutative.
-This, however, becomes important when writing things down as coefficient vectors or matrices:
-
-.. math::
-
-    \ket{0}_0 \otimes \ket{1}_1 = \ket{1}_1 \otimes \ket{0}_0
-    = \ket{10}_{1,0} \equiv \begin{pmatrix} 0 \\ 0 \\ 1 \\ 0 \end{pmatrix}
-
-As a consequence there arise some subtle but important differences in the ordering of wavefunction
-and multi-qubit gate matrix coefficients.
-According to our conventions the matrix
-
-.. math::
+    [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0]]
 
-    U_{\rm CNOT(1,0)} \equiv
-    \begin{pmatrix}
-        1 & 0 & 0 & 0 \\
-        0 & 1 & 0 & 0 \\
-        0 & 0 & 0 & 1 \\
-        0 & 0 & 1 & 0
-    \end{pmatrix}
+Let's unpack this. The *outer* list is an enumeration over the trials; the argument given to
+``wrap_in_numshots_loop`` will match the length of ``results``.
 
-corresponds to the Quil instruction ``CNOT(1, 0)`` which is counter to how most other people in the
-field order their tensor product factors (or more specifically their kronecker products).
-In this convention ``CNOT(0, 1)`` is given by
-
-.. math::
-
-    U_{\rm CNOT(0,1)} \equiv
-    \begin{pmatrix}
-        1 & 0 & 0 & 0 \\
-        0 & 0 & 0 & 1 \\
-        0 & 0 & 1 & 0 \\
-        0 & 1 & 0 & 0
-    \end{pmatrix}
-
-For additional information why we decided on this basis ordering check out our note
-*Someone shouts, "|01000>!" Who is Excited?* [2]_.
+The *inner* list, on the other hand, is an enumeration over the results stored in the memory region named ``ro``, which
+we use as our readout register. We see that the result of this program is that the memory region ``ro[0]`` now stores
+the state of qubit 0, which should be ``1`` after an :math:`X`-gate. See :ref:`declaring_memory` and :ref:`measurement`
+for more details about declaring and accessing classical memory regions.
 
 .. [1] https://arxiv.org/abs/1608.03355
-.. [2] https://arxiv.org/abs/1711.02086
 
 Simulating the QPU using the QVM
 --------------------------------
 
-The QVM is a powerful tool for testing quantum programs before executing them on the QPU. In
-addition to the ``noise.py`` module for generating custom noise models for simulating noise on the
-QVM, pyQuil provides a simple interface for loading the QVM with noise models tailored to Rigetti's
-available QPUs, in just one modified line of code. This is made possible via the ``Device`` class,
-which holds hardware specification information, noise model information, and instruction set
-architecture (ISA) information regarding connectivity. This information is held in the ``Specs``,
-``ISA`` and ``NoiseModel`` attributes of the ``Device`` class, respectively.
-
-Specifically, to load a QVM with the ``NoiseModel`` information from a ``Device``, all that is
-required is to provide a ``Device`` object to the QVM during initialization:
-
-.. note::
-
-    This feature is currently deprecated, in advance of a new QPU (with new noise models). For users interested in
-    creating noise models for the QVM, you can do so by following the instructions in :ref:`noise`.
+The QVM is a powerful tool for testing quantum programs before executing them on the QPU.
 
 .. code:: python
 
-    from pyquil.api import get_devices, QVMConnection
-
-    device_name = get_device('quantum_device_name')
-    qvm = QVMConnection(device_name)
-
-By simply providing a device during QVM initialization, all programs executed on this QVM will, by
-default, have noise applied that is characteristic of the corresponding Rigetti QPU (in the case
-above, the ``agave`` device). One may then efficiently test realistic quantum algorithms on the QVM,
-in advance of running those programs on the QPU.
-
-Examples of Quantum Programs
-----------------------------
-
-To create intuition for a new class of algorithms, that will run on the Quantum Virtual Machine (QVM), it is useful (and
-fun) to play with the abstraction that the software provides.
-
-A broad class of programs that can easily be implemented on a QVM are generalizations of
-`Game Theory to incorporate Quantum Strategies <https://arxiv.org/abs/quant-ph/0611234>`_.
-
-Meyer-Penny Game
-~~~~~~~~~~~~~~~~
-
-A conceptually simple example that falls into this class is the
-`Meyer-Penny Game <https://link.aps.org/doi/10.1103/PhysRevLett.82.1052>`_. The game goes as follows: The Starship
-Enterprise, during one of its deep-space missions, is facing an immediate calamity, when a powerful alien suddenly
-appears on the bridge. The alien, named Q, offers to help Picard, the captain of the Enterprise, under the condition
-that Picard beats Q in a simple game of penny flips.
-
-The rules: Picard is to place a penny Heads up into an opaque box. Then Picard and Q take turns to flip or not flip the
-penny without being able to see it; first Q then P then Q again. After this the penny is revealed; Q wins if it shows
-Heads (H), while Tails (T) makes Picard the winner.
-
-Picard quickly estimates that his chance of winning is 50% and agrees to play the game. He loses the first round and
-insists on playing again. To his surprise Q agrees, and they continue playing several rounds more, each of which Picard
-loses. How is that possible?
-
-What Picard did not anticipate is that Q has access to quantum tools. Instead of flipping the penny, Q puts the penny
-into a superposition of Heads and Tails proportional to the quantum state :math:`|H\rangle+|T\rangle`. Then no matter
-whether Picard flips the penny or not, it will stay in a superposition (though the relative sign might change). In the
-third step Q undoes the superposition and always finds the penny to shows Heads.
-
-To simulate the game we first construct the corresponding quantum circuit, which takes two qubits -- one to simulate
-Picard's choice whether or not to flip the penny and the other to represent the penny. The initial state for all Qubits
-is :math:`|0\rangle (= |T\rangle)`. To simulate Picard's decision, we assume that he chooses randomly whether or not to
-flip the coin, in agreement with the optimal strategy for the classic penny-flip game. This random choice can be created
-by putting one qubit into an equal superposition, e.g. with the Hadamard gate H, and then measure its state. The
-measurement will show Heads or Tails with equal probability p=0.5.
-
-To simulate the penny flip game we take the second qubit and put it into its excited state
-:math:`|1\rangle (= |H\rangle)` by applying the X (or NOT) gate. Q's first move is to apply the Hadamard gate H.
-Picard's decision about the flip is simulated as a CNOT operation where the control bit is the outcome of the random
-number generator described above. Finally Q applies a Hadamard gate again, before we measure the outcome. The full
-circuit is shown in the figure below.
-
-.. figure:: images/MeyerPennyGame.png
-    :align: center
-    :figwidth: 65%
-
-First we import all the necessary tools:
-
-.. code-block:: python
-
-    from pyquil import get_qc
-    from pyquil.gates import I, H, X
-    from pyquil import Program
-    from pyquil.api import WavefunctionSimulator
-    prog = Program()
-    ro = prog.declare('classical_register', 'BIT', 2)
-    qvm = get_qc('9q-generic-qvm')
-
-Then we need to define two registers that will be used for the measurement of Picard's decision bit and the final answer
-of the penny tossing game.
-
-.. code-block:: python
-
-    prog = Program()
-    ro = prog.declare('classical_register', 'BIT', 2)
-    picard_register = ["1"]
-    answer_register = ["0"]
-
-Moreover we need to encode the two different actions of Picard, which conceptually is equivalent to an `if-else` control
-flow as:
-
-.. code-block:: python
-
-    then_branch = Program(X(0))
-    else_branch = Program(I(0))
-
-
-and then wire it all up into the overall measurement circuit:
-
-.. code-block:: python
-
-   prog = (Program()
-       # Prepare Qubits in Heads state or superposition, respectively
-       .inst(X(0), H(1))
-       # Q puts the penny into a superposition
-       .inst(H(0))
-       # Picard makes a decision and acts accordingly
-       .measure(1, picard_register)
-       .if_then(picard_register, then_branch, else_branch)
-       # Q undoes his superposition operation
-       .inst(H(0))
-       # The outcome is recorded into the answer register
-       .measure(0, answer_register))
-
-
-Finally we play the game several times
-
-.. code-block:: python
-
-   qvm.run_and_measure(prog, [0, 1], 10)
-
-
-and record the register outputs as
-
-.. code-block:: python
-
-   [[1, 1],
-    [1, 1],
-    [1, 0],
-    [1, 0],
-    [1, 0],
-    [1, 0],
-    [1, 1],
-    [1, 1],
-    [1, 0],
-    [1, 0]]
-
-Remember that the first number is the outcome of the game (value of the `answer_register`) whereas the second number is
-the outcome of Picard’s decision (value of the `picard_register`).
-
-Indeed, no matter what Picard does, Q will always win!
-
-Exercises
-~~~~~~~~~
-
-Prisoner's Dilemma
-__________________
+    qc = get_qc("QuantumComputerName")
+    qc = get_qc("QuantumComputerName-qvm")
 
-A classic strategy game is the `prisoner's dilemma <https://en.wikipedia.org/wiki/Prisoner%27s_dilemma>`_ where two
-prisoners get the minimal penalty if they collaborate and stay silent, get zero penalty if one of them defects and the
-other collaborates (incurring maximum penalty) and get intermediate penalty if they both defect. This game has an
-equilibrium where both defect and incur intermediate penalty.
+By simply providing ``-qvm`` in the device name, all programs executed on this QVM will, have the same topology as
+the named QPU. To learn how to add noise models to your virtual ``QuantumComputer`` instance, check out
+:ref:`noise`.
 
-However, things change dramatically when we allow for quantum strategies leading to the
-`Quantum Prisoner's Dilemma <https://arxiv.org/abs/quant-ph/9806088>`_.
+The Quantum Processing Unit
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Can you design a program that simulates this game?
+*Coming soon*: Detailed information about how to use :py:func:`~pyquil.get_qc` to target a QPU.
diff --git a/docs/source/start.rst b/docs/source/start.rst
index 74a1c01..7f1c14b 100644
--- a/docs/source/start.rst
+++ b/docs/source/start.rst
@@ -236,8 +236,8 @@ Import a few things from pyQuil:
     from pyquil import Program, get_qc
     from pyquil.gates import *
 
-The ``Program`` object allows us to build up a Quil program. ``get-qc`` connects us to a
-``QuantumComputer`` object, which specifies what our program should run on (see: :ref:`qvm`). We've also imported all (``*``)
+The :py:class:`~pyquil.quil.Program` object allows us to build up a Quil program. :py:func:`~pyquil.get_qc` connects us to a
+:py:class:`~pyquil.api.QuantumComputer` object, which specifies what our program should run on (see: :ref:`qvm`). We've also imported all (``*``)
 gates from the ``pyquil.gates`` module, which allows us to add operations to our program (:ref:`basics`).
 
 Next, let's construct our Bell State.
diff --git a/docs/source/wavefunction_simulator.rst b/docs/source/wavefunction_simulator.rst
index bf2a2b5..819fc27 100644
--- a/docs/source/wavefunction_simulator.rst
+++ b/docs/source/wavefunction_simulator.rst
@@ -58,96 +58,64 @@ amplitudes directly or look at a dictionary of associated outcome probabilities.
 It is important to remember that this ``wavefunction`` method is a useful debugging tool for small quantum systems, and
 cannot be feasibly obtained on a quantum processor.
 
-Meyer-Penny Game
-----------------
-
-A conceptually simple example that falls into this class is the Meyer-Penny Game. The game goes as follows:
-
-The Starship Enterprise, during one of its deep-space missions, is facing an immediate calamity, when a powerful alien
-suddenly appears on the bridge. The alien, named Q, offers to help Picard, the captain of the Enterprise, under the
-condition that Picard beats Q in a simple game of penny flips.
-
-The rules:
-~~~~~~~~~~
-Picard is to place a penny Heads up into an opaque box. Then Picard and Q take turns to flip or not flip the penny without
-being able to see it; first Q then P then Q again. After this the penny is revealed; Q wins if it shows Heads (H), while
-Tails (T) makes Picard the winner.
-
-
-Picard vs. Q
-~~~~~~~~~~~~
-
-Picard estimates that his chance of winning is 50% and agrees to play the game. He loses the first round and insists on
-playing again. To his surprise Q agrees, and they continue playing several rounds more, each of which Picard loses. How
-is that possible?
-
-What Picard did not anticipate is that Q has access to quantum tools. Instead of flipping the penny, Q puts the penny into
-a superposition of Heads and Tails proportional to the quantum state |H⟩+|T⟩. Then no matter whether Picard flips the penny
-or not, it will stay in a superposition (though the relative sign might change). In the third step Q undoes the superposition
-and always finds the penny to shows Heads.
-
-Let's see how this works!
-
-To simulate the game, we first construct the corresponding quantum circuit, which takes two qubits – one to simulate
-Picard’s choice whether or not to flip the penny and the other to represent the penny. The initial state for all Qubits
-is |0⟩(=|T⟩). To simulate Picard’s decision, we assume that he chooses randomly whether or not to flip the coin, in
-agreement with the optimal strategy for the classic penny-flip game. This random choice can be created by putting one
-qubit into an equal superposition, e.g. with the Hadamard gate H, and then measure its state. The measurement will show
-Heads or Tails with equal probability p=0.5.
-
-To simulate the penny flip game we take the second qubit and put it into its excited state |1⟩(=|H⟩) by applying the X
-(or NOT) gate. Q’s first move is to apply the Hadamard gate H. Picard’s decision about the flip is simulated as a CNOT
-operation where the control bit is the outcome of the random number generator described above. Finally Q applies a Hadamard
-gate again, before we measure the outcome.
-
-We first import the necessary tools
-
-.. code:: python
-
-    from pyquil import Program
-    from pyquil.api import WavefunctionSimulator
-    from pyquil.gates import *
-
-    wf_sim = WavefunctionSimulator()
-    prog = Program()
-    ro = prog.declare('ro', 'BIT', 2)
-
-Then we need to define two registers that will be used for the measurement of Picard’s decision bit and the final answer
-of the penny tossing game.
-
-.. code:: python
-
-    picard_register = ro[1]
-    answer_register = ro[0]
-
-We need to encode the two different actions of Picard, which conceptually is equivalent to an if-else control flow as:
-
-.. code:: python
-
-    then_branch = Program(X(0))
-    else_branch = Program(I(0))
-
-and then wire it all up into the overall measurement circuit:
-
-.. code:: python
-
-    prog.inst(X(0), H(1))
-    prog.inst(H(0))
-    prog.measure(1, picard_register)
-    prog.if_then(picard_register, then_branch, else_branch)
-    prog.inst(H(0))
-    prog.measure(0, answer_register)
-    print(prog)
-
-Finally we play the game several times
-
-.. code:: python
-
-    wf_sim.run_and_measure(prog, [0, 1], 10)
-
-Remember that the first number is the outcome of the game (value of the answer_register) whereas the second number is the
-outcome of Picard’s decision (value of the picard_register).
-
-No matter what Picard does, Q will always win!
-
-
+Multi-Qubit Basis Enumeration
+-----------------------------
+
+The WavefunctionSimulator enumerates bitstrings such that qubit ``0`` is the least significant bit (LSB)
+and therefore on the right end of a bitstring as shown in the table below which contains some
+examples.
+
+=============== ============= ===== ========= ========= =========
+ bitstring       qubit_(n-1)   ...   qubit_2   qubit_1   qubit_0
+=============== ============= ===== ========= ========= =========
+  1...101                  1   ...         1         0         1
+  0...110                  0   ...         1         1         0
+=============== ============= ===== ========= ========= =========
+
+
+
+This convention is counter to that often found in the quantum computing literature where
+bitstrings are often ordered such that the lowest-index qubit is on the left.
+The vector representation of a wavefunction assumes the "canonical" ordering of basis elements.
+I.e., for two qubits this order is ``00, 01, 10, 11``.
+In the typical Dirac notation for quantum states, the tensor product of two different degrees of
+freedom is not always explicitly understood as having a fixed order of those degrees of freedom.
+This is in contrast to the kronecker product between matrices which uses the same mathematical
+symbol and is clearly not commutative.
+This, however, becomes important when writing things down as coefficient vectors or matrices:
+
+.. math::
+
+    \ket{0}_0 \otimes \ket{1}_1 = \ket{1}_1 \otimes \ket{0}_0
+    = \ket{10}_{1,0} \equiv \begin{pmatrix} 0 \\ 0 \\ 1 \\ 0 \end{pmatrix}
+
+As a consequence there arise some subtle but important differences in the ordering of wavefunction
+and multi-qubit gate matrix coefficients.
+According to our conventions the matrix
+
+.. math::
+
+    U_{\rm CNOT(1,0)} \equiv
+    \begin{pmatrix}
+        1 & 0 & 0 & 0 \\
+        0 & 1 & 0 & 0 \\
+        0 & 0 & 0 & 1 \\
+        0 & 0 & 1 & 0
+    \end{pmatrix}
+
+corresponds to the Quil instruction ``CNOT(1, 0)`` which is counter to how most other people in the
+field order their tensor product factors (or more specifically their kronecker products).
+In this convention ``CNOT(0, 1)`` is given by
+
+.. math::
+
+    U_{\rm CNOT(0,1)} \equiv
+    \begin{pmatrix}
+        1 & 0 & 0 & 0 \\
+        0 & 0 & 0 & 1 \\
+        0 & 0 & 1 & 0 \\
+        0 & 1 & 0 & 0
+    \end{pmatrix}
+
+For additional information why we decided on this basis ordering check out our note
+`Someone shouts, "|01000>!" Who is Excited? <https://arxiv.org/abs/1711.02086>`_.
diff --git a/pyquil/_parser/PyQuilListener.py b/pyquil/_parser/PyQuilListener.py
index 0c07ee2..97bb234 100644
--- a/pyquil/_parser/PyQuilListener.py
+++ b/pyquil/_parser/PyQuilListener.py
@@ -128,11 +128,12 @@ class PyQuilListener(QuilListener):
         circuit_name = ctx.name().getText()
         variables = [variable.getText() for variable in ctx.variable()]
         qubitVariables = [qubitVariable.getText() for qubitVariable in ctx.qubitVariable()]
+        space = ' ' if qubitVariables else ''
 
         if variables:
-            raw_defcircuit = 'DEFCIRCUIT {}({}) {}:'.format(circuit_name, ', '.join(variables), ' '.join(qubitVariables))
+            raw_defcircuit = 'DEFCIRCUIT {}({}){}{}:'.format(circuit_name, ', '.join(variables), space, ' '.join(qubitVariables))
         else:
-            raw_defcircuit = 'DEFCIRCUIT {} {}:'.format(circuit_name, ' '.join(qubitVariables))
+            raw_defcircuit = 'DEFCIRCUIT {}{}{}:'.format(circuit_name, space, ' '.join(qubitVariables))
 
         raw_defcircuit += '\n    '.join([''] + [instr.out() for instr in self.result])
         self.previous_result.append(RawInstr(raw_defcircuit))
@@ -166,6 +167,13 @@ class PyQuilListener(QuilListener):
         else:
             self.result.append(RawInstr('{} {}'.format(gate_name, ' '.join(qubits))))
 
+    def exitCircuitMeasure(self, ctx: QuilParser.CircuitMeasureContext):
+        qubit = ctx.circuitQubit().getText()
+        classical = None
+        if ctx.addr():
+            classical = ctx.addr().getText()
+        self.result.append(RawInstr(f'MEASURE {qubit} {classical}' if classical else f'MEASURE {qubit}'))
+
     def exitMeasure(self, ctx: QuilParser.MeasureContext):
         qubit = _qubit(ctx.qubit())
         classical = None
@@ -200,6 +208,10 @@ class PyQuilListener(QuilListener):
         else:
             self.result.append(Reset())
 
+    def exitCircuitResetState(self, ctx: QuilParser.ResetStateContext):
+        qubit = ctx.circuitQubit().getText()
+        self.result.append(RawInstr(f'RESET {qubit}'))
+
     def exitWait(self, ctx):
         # type: (QuilParser.WaitContext) -> None
         self.result.append(Wait())
diff --git a/pyquil/_parser/Quil.g4 b/pyquil/_parser/Quil.g4
index 5ec4182..84de967 100644
--- a/pyquil/_parser/Quil.g4
+++ b/pyquil/_parser/Quil.g4
@@ -57,7 +57,9 @@ qubitVariable       : IDENTIFIER ;
 
 circuitQubit        : qubit | qubitVariable ;
 circuitGate         : name ( LPAREN param ( COMMA param )* RPAREN )? circuitQubit+ ;
-circuitInstr        : circuitGate | instr ;
+circuitMeasure      : MEASURE circuitQubit addr? ;
+circuitResetState   : RESET circuitQubit? ;
+circuitInstr        : circuitGate | circuitMeasure | circuitResetState | instr ;
 circuit             : ( TAB circuitInstr NEWLINE )* TAB circuitInstr ;
 
 // F. Measurement
diff --git a/pyquil/_parser/gen3/QuilListener.py b/pyquil/_parser/gen3/QuilListener.py
index cf235b6..04ecf77 100644
--- a/pyquil/_parser/gen3/QuilListener.py
+++ b/pyquil/_parser/gen3/QuilListener.py
@@ -143,6 +143,24 @@ class QuilListener(ParseTreeListener):
         pass
 
 
+    # Enter a parse tree produced by QuilParser#circuitMeasure.
+    def enterCircuitMeasure(self, ctx:QuilParser.CircuitMeasureContext):
+        pass
+
+    # Exit a parse tree produced by QuilParser#circuitMeasure.
+    def exitCircuitMeasure(self, ctx:QuilParser.CircuitMeasureContext):
+        pass
+
+
+    # Enter a parse tree produced by QuilParser#circuitResetState.
+    def enterCircuitResetState(self, ctx:QuilParser.CircuitResetStateContext):
+        pass
+
+    # Exit a parse tree produced by QuilParser#circuitResetState.
+    def exitCircuitResetState(self, ctx:QuilParser.CircuitResetStateContext):
+        pass
+
+
     # Enter a parse tree produced by QuilParser#circuitInstr.
     def enterCircuitInstr(self, ctx:QuilParser.CircuitInstrContext):
         pass
diff --git a/pyquil/_parser/gen3/QuilParser.py b/pyquil/_parser/gen3/QuilParser.py
index 57d9461..52f49cd 100644
--- a/pyquil/_parser/gen3/QuilParser.py
+++ b/pyquil/_parser/gen3/QuilParser.py
@@ -8,215 +8,225 @@ import sys
 def serializedATN():
     with StringIO() as buf:
         buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3H")
-        buf.write("\u01cd\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
+        buf.write("\u01dc\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
         buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
         buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23")
         buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31")
         buf.write("\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36")
         buf.write("\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t")
         buf.write("&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.\t.\4")
-        buf.write("/\t/\4\60\t\60\4\61\t\61\4\62\t\62\3\2\5\2f\n\2\3\2\6")
-        buf.write("\2i\n\2\r\2\16\2j\3\2\7\2n\n\2\f\2\16\2q\13\2\3\2\7\2")
-        buf.write("t\n\2\f\2\16\2w\13\2\3\2\3\2\3\3\3\3\3\3\5\3~\n\3\3\4")
-        buf.write("\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3")
-        buf.write("\4\3\4\3\4\3\4\5\4\u0092\n\4\3\5\3\5\3\5\3\5\3\5\7\5\u0099")
-        buf.write("\n\5\f\5\16\5\u009c\13\5\3\5\3\5\5\5\u00a0\n\5\3\5\6\5")
-        buf.write("\u00a3\n\5\r\5\16\5\u00a4\3\6\3\6\3\7\3\7\3\b\3\b\3\t")
-        buf.write("\3\t\3\t\3\t\3\t\3\t\7\t\u00b3\n\t\f\t\16\t\u00b6\13\t")
-        buf.write("\3\t\3\t\5\t\u00ba\n\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\13")
-        buf.write("\3\13\3\13\7\13\u00c6\n\13\f\13\16\13\u00c9\13\13\3\13")
-        buf.write("\3\13\3\f\3\f\3\f\3\f\7\f\u00d1\n\f\f\f\16\f\u00d4\13")
-        buf.write("\f\3\r\3\r\3\r\3\r\3\r\3\r\7\r\u00dc\n\r\f\r\16\r\u00df")
-        buf.write("\13\r\3\r\3\r\5\r\u00e3\n\r\3\r\7\r\u00e6\n\r\f\r\16\r")
-        buf.write("\u00e9\13\r\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\5\17\u00f3")
-        buf.write("\n\17\3\20\3\20\3\20\3\20\3\20\7\20\u00fa\n\20\f\20\16")
-        buf.write("\20\u00fd\13\20\3\20\3\20\5\20\u0101\n\20\3\20\6\20\u0104")
-        buf.write("\n\20\r\20\16\20\u0105\3\21\3\21\5\21\u010a\n\21\3\22")
-        buf.write("\3\22\3\22\3\22\7\22\u0110\n\22\f\22\16\22\u0113\13\22")
-        buf.write("\3\22\3\22\3\22\3\23\3\23\3\23\5\23\u011b\n\23\3\24\3")
-        buf.write("\24\5\24\u011f\n\24\3\24\3\24\3\24\5\24\u0124\n\24\3\25")
-        buf.write("\3\25\3\25\3\26\3\26\3\26\3\27\3\27\3\30\3\30\3\30\3\31")
-        buf.write("\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\33\3\33\5\33\u013b")
-        buf.write("\n\33\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\5\35\u0145")
-        buf.write("\n\35\3\35\3\35\3\35\7\35\u014a\n\35\f\35\16\35\u014d")
-        buf.write("\13\35\5\35\u014f\n\35\3\36\3\36\3\36\3\36\3\37\3\37\3")
-        buf.write("\37\3 \3 \3 \3 \3 \5 \u015d\n \3!\3!\3!\3!\5!\u0163\n")
-        buf.write("!\3\"\3\"\3\"\3\"\5\"\u0169\n\"\3#\3#\3#\3#\5#\u016f\n")
-        buf.write("#\3$\3$\3$\3$\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3")
-        buf.write("\'\3\'\5\'\u0183\n\'\3(\3(\3(\3(\3(\5(\u018a\n(\3)\3)")
-        buf.write("\3*\3*\3*\3+\3+\3+\7+\u0194\n+\f+\16+\u0197\13+\3+\5+")
-        buf.write("\u019a\n+\3,\3,\3-\3-\3-\3-\3-\3-\3-\3-\3-\3-\3-\3-\3")
-        buf.write("-\3-\3-\3-\5-\u01ae\n-\3-\3-\3-\3-\3-\3-\3-\3-\3-\7-\u01b9")
-        buf.write("\n-\f-\16-\u01bc\13-\3.\3.\3/\3/\3\60\3\60\3\60\3\60\5")
-        buf.write("\60\u01c6\n\60\3\61\3\61\3\61\3\62\3\62\3\62\2\3X\63\2")
-        buf.write("\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64")
-        buf.write("\668:<>@BDFHJLNPRTVXZ\\^`b\2\13\3\2\23\26\3\2\27\32\3")
-        buf.write("\2\33\36\3\2\"&\3\2\65\66\3\2\62\63\3\2\60\61\3\2+/\3")
-        buf.write("\2\66\67\2\u01df\2e\3\2\2\2\4}\3\2\2\2\6\u0091\3\2\2\2")
-        buf.write("\b\u0093\3\2\2\2\n\u00a6\3\2\2\2\f\u00a8\3\2\2\2\16\u00aa")
-        buf.write("\3\2\2\2\20\u00ac\3\2\2\2\22\u00bf\3\2\2\2\24\u00c7\3")
-        buf.write("\2\2\2\26\u00cc\3\2\2\2\30\u00d5\3\2\2\2\32\u00ee\3\2")
-        buf.write("\2\2\34\u00f2\3\2\2\2\36\u00f4\3\2\2\2 \u0109\3\2\2\2")
-        buf.write("\"\u0111\3\2\2\2$\u0117\3\2\2\2&\u0123\3\2\2\2(\u0125")
-        buf.write("\3\2\2\2*\u0128\3\2\2\2,\u012b\3\2\2\2.\u012d\3\2\2\2")
-        buf.write("\60\u0130\3\2\2\2\62\u0134\3\2\2\2\64\u0138\3\2\2\2\66")
-        buf.write("\u013c\3\2\2\28\u013e\3\2\2\2:\u0150\3\2\2\2<\u0154\3")
-        buf.write("\2\2\2>\u015c\3\2\2\2@\u015e\3\2\2\2B\u0164\3\2\2\2D\u016a")
-        buf.write("\3\2\2\2F\u0170\3\2\2\2H\u0174\3\2\2\2J\u0178\3\2\2\2")
-        buf.write("L\u017d\3\2\2\2N\u0184\3\2\2\2P\u018b\3\2\2\2R\u018d\3")
-        buf.write("\2\2\2T\u0190\3\2\2\2V\u019b\3\2\2\2X\u01ad\3\2\2\2Z\u01bd")
-        buf.write("\3\2\2\2\\\u01bf\3\2\2\2^\u01c5\3\2\2\2`\u01c7\3\2\2\2")
-        buf.write("b\u01ca\3\2\2\2df\5\4\3\2ed\3\2\2\2ef\3\2\2\2fo\3\2\2")
-        buf.write("\2gi\7E\2\2hg\3\2\2\2ij\3\2\2\2jh\3\2\2\2jk\3\2\2\2kl")
-        buf.write("\3\2\2\2ln\5\4\3\2mh\3\2\2\2nq\3\2\2\2om\3\2\2\2op\3\2")
-        buf.write("\2\2pu\3\2\2\2qo\3\2\2\2rt\7E\2\2sr\3\2\2\2tw\3\2\2\2")
-        buf.write("us\3\2\2\2uv\3\2\2\2vx\3\2\2\2wu\3\2\2\2xy\7\2\2\3y\3")
-        buf.write("\3\2\2\2z~\5\20\t\2{~\5\30\r\2|~\5\6\4\2}z\3\2\2\2}{\3")
-        buf.write("\2\2\2}|\3\2\2\2~\5\3\2\2\2\177\u0092\5\b\5\2\u0080\u0092")
-        buf.write("\5$\23\2\u0081\u0092\5(\25\2\u0082\u0092\5,\27\2\u0083")
-        buf.write("\u0092\5.\30\2\u0084\u0092\5\60\31\2\u0085\u0092\5\62")
-        buf.write("\32\2\u0086\u0092\5\64\33\2\u0087\u0092\5\66\34\2\u0088")
-        buf.write("\u0092\5<\37\2\u0089\u0092\5> \2\u008a\u0092\5N(\2\u008b")
-        buf.write("\u0092\5J&\2\u008c\u0092\5L\'\2\u008d\u0092\5P)\2\u008e")
-        buf.write("\u0092\5R*\2\u008f\u0092\5T+\2\u0090\u0092\58\35\2\u0091")
-        buf.write("\177\3\2\2\2\u0091\u0080\3\2\2\2\u0091\u0081\3\2\2\2\u0091")
-        buf.write("\u0082\3\2\2\2\u0091\u0083\3\2\2\2\u0091\u0084\3\2\2\2")
-        buf.write("\u0091\u0085\3\2\2\2\u0091\u0086\3\2\2\2\u0091\u0087\3")
-        buf.write("\2\2\2\u0091\u0088\3\2\2\2\u0091\u0089\3\2\2\2\u0091\u008a")
-        buf.write("\3\2\2\2\u0091\u008b\3\2\2\2\u0091\u008c\3\2\2\2\u0091")
-        buf.write("\u008d\3\2\2\2\u0091\u008e\3\2\2\2\u0091\u008f\3\2\2\2")
-        buf.write("\u0091\u0090\3\2\2\2\u0092\7\3\2\2\2\u0093\u009f\5\n\6")
-        buf.write("\2\u0094\u0095\7;\2\2\u0095\u009a\5\16\b\2\u0096\u0097")
-        buf.write("\7:\2\2\u0097\u0099\5\16\b\2\u0098\u0096\3\2\2\2\u0099")
-        buf.write("\u009c\3\2\2\2\u009a\u0098\3\2\2\2\u009a\u009b\3\2\2\2")
-        buf.write("\u009b\u009d\3\2\2\2\u009c\u009a\3\2\2\2\u009d\u009e\7")
-        buf.write("<\2\2\u009e\u00a0\3\2\2\2\u009f\u0094\3\2\2\2\u009f\u00a0")
-        buf.write("\3\2\2\2\u00a0\u00a2\3\2\2\2\u00a1\u00a3\5\f\7\2\u00a2")
-        buf.write("\u00a1\3\2\2\2\u00a3\u00a4\3\2\2\2\u00a4\u00a2\3\2\2\2")
-        buf.write("\u00a4\u00a5\3\2\2\2\u00a5\t\3\2\2\2\u00a6\u00a7\7\65")
-        buf.write("\2\2\u00a7\13\3\2\2\2\u00a8\u00a9\7\66\2\2\u00a9\r\3\2")
-        buf.write("\2\2\u00aa\u00ab\5X-\2\u00ab\17\3\2\2\2\u00ac\u00ad\7")
-        buf.write("\3\2\2\u00ad\u00b9\5\n\6\2\u00ae\u00af\7;\2\2\u00af\u00b4")
-        buf.write("\5\22\n\2\u00b0\u00b1\7:\2\2\u00b1\u00b3\5\22\n\2\u00b2")
-        buf.write("\u00b0\3\2\2\2\u00b3\u00b6\3\2\2\2\u00b4\u00b2\3\2\2\2")
-        buf.write("\u00b4\u00b5\3\2\2\2\u00b5\u00b7\3\2\2\2\u00b6\u00b4\3")
-        buf.write("\2\2\2\u00b7\u00b8\7<\2\2\u00b8\u00ba\3\2\2\2\u00b9\u00ae")
-        buf.write("\3\2\2\2\u00b9\u00ba\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb")
-        buf.write("\u00bc\7?\2\2\u00bc\u00bd\7E\2\2\u00bd\u00be\5\24\13\2")
-        buf.write("\u00be\21\3\2\2\2\u00bf\u00c0\7@\2\2\u00c0\u00c1\7\65")
-        buf.write("\2\2\u00c1\23\3\2\2\2\u00c2\u00c3\5\26\f\2\u00c3\u00c4")
-        buf.write("\7E\2\2\u00c4\u00c6\3\2\2\2\u00c5\u00c2\3\2\2\2\u00c6")
-        buf.write("\u00c9\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c7\u00c8\3\2\2\2")
-        buf.write("\u00c8\u00ca\3\2\2\2\u00c9\u00c7\3\2\2\2\u00ca\u00cb\5")
-        buf.write("\26\f\2\u00cb\25\3\2\2\2\u00cc\u00cd\7D\2\2\u00cd\u00d2")
-        buf.write("\5X-\2\u00ce\u00cf\7:\2\2\u00cf\u00d1\5X-\2\u00d0\u00ce")
-        buf.write("\3\2\2\2\u00d1\u00d4\3\2\2\2\u00d2\u00d0\3\2\2\2\u00d2")
-        buf.write("\u00d3\3\2\2\2\u00d3\27\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d5")
-        buf.write("\u00d6\7\4\2\2\u00d6\u00e2\5\n\6\2\u00d7\u00d8\7;\2\2")
-        buf.write("\u00d8\u00dd\5\22\n\2\u00d9\u00da\7:\2\2\u00da\u00dc\5")
-        buf.write("\22\n\2\u00db\u00d9\3\2\2\2\u00dc\u00df\3\2\2\2\u00dd")
-        buf.write("\u00db\3\2\2\2\u00dd\u00de\3\2\2\2\u00de\u00e0\3\2\2\2")
-        buf.write("\u00df\u00dd\3\2\2\2\u00e0\u00e1\7<\2\2\u00e1\u00e3\3")
-        buf.write("\2\2\2\u00e2\u00d7\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3\u00e7")
-        buf.write("\3\2\2\2\u00e4\u00e6\5\32\16\2\u00e5\u00e4\3\2\2\2\u00e6")
-        buf.write("\u00e9\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e7\u00e8\3\2\2\2")
-        buf.write("\u00e8\u00ea\3\2\2\2\u00e9\u00e7\3\2\2\2\u00ea\u00eb\7")
-        buf.write("?\2\2\u00eb\u00ec\7E\2\2\u00ec\u00ed\5\"\22\2\u00ed\31")
-        buf.write("\3\2\2\2\u00ee\u00ef\7\65\2\2\u00ef\33\3\2\2\2\u00f0\u00f3")
-        buf.write("\5\f\7\2\u00f1\u00f3\5\32\16\2\u00f2\u00f0\3\2\2\2\u00f2")
-        buf.write("\u00f1\3\2\2\2\u00f3\35\3\2\2\2\u00f4\u0100\5\n\6\2\u00f5")
-        buf.write("\u00f6\7;\2\2\u00f6\u00fb\5\16\b\2\u00f7\u00f8\7:\2\2")
-        buf.write("\u00f8\u00fa\5\16\b\2\u00f9\u00f7\3\2\2\2\u00fa\u00fd")
-        buf.write("\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fb\u00fc\3\2\2\2\u00fc")
-        buf.write("\u00fe\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fe\u00ff\7<\2\2")
-        buf.write("\u00ff\u0101\3\2\2\2\u0100\u00f5\3\2\2\2\u0100\u0101\3")
-        buf.write("\2\2\2\u0101\u0103\3\2\2\2\u0102\u0104\5\34\17\2\u0103")
-        buf.write("\u0102\3\2\2\2\u0104\u0105\3\2\2\2\u0105\u0103\3\2\2\2")
-        buf.write("\u0105\u0106\3\2\2\2\u0106\37\3\2\2\2\u0107\u010a\5\36")
-        buf.write("\20\2\u0108\u010a\5\6\4\2\u0109\u0107\3\2\2\2\u0109\u0108")
-        buf.write("\3\2\2\2\u010a!\3\2\2\2\u010b\u010c\7D\2\2\u010c\u010d")
-        buf.write("\5 \21\2\u010d\u010e\7E\2\2\u010e\u0110\3\2\2\2\u010f")
-        buf.write("\u010b\3\2\2\2\u0110\u0113\3\2\2\2\u0111\u010f\3\2\2\2")
-        buf.write("\u0111\u0112\3\2\2\2\u0112\u0114\3\2\2\2\u0113\u0111\3")
-        buf.write("\2\2\2\u0114\u0115\7D\2\2\u0115\u0116\5 \21\2\u0116#\3")
-        buf.write("\2\2\2\u0117\u0118\7\5\2\2\u0118\u011a\5\f\7\2\u0119\u011b")
-        buf.write("\5&\24\2\u011a\u0119\3\2\2\2\u011a\u011b\3\2\2\2\u011b")
-        buf.write("%\3\2\2\2\u011c\u0124\7\65\2\2\u011d\u011f\7\65\2\2\u011e")
-        buf.write("\u011d\3\2\2\2\u011e\u011f\3\2\2\2\u011f\u0120\3\2\2\2")
-        buf.write("\u0120\u0121\7=\2\2\u0121\u0122\7\66\2\2\u0122\u0124\7")
-        buf.write(">\2\2\u0123\u011c\3\2\2\2\u0123\u011e\3\2\2\2\u0124\'")
-        buf.write("\3\2\2\2\u0125\u0126\7\6\2\2\u0126\u0127\5*\26\2\u0127")
-        buf.write(")\3\2\2\2\u0128\u0129\7A\2\2\u0129\u012a\7\65\2\2\u012a")
-        buf.write("+\3\2\2\2\u012b\u012c\7\7\2\2\u012c-\3\2\2\2\u012d\u012e")
-        buf.write("\7\b\2\2\u012e\u012f\5*\26\2\u012f/\3\2\2\2\u0130\u0131")
-        buf.write("\7\t\2\2\u0131\u0132\5*\26\2\u0132\u0133\5&\24\2\u0133")
-        buf.write("\61\3\2\2\2\u0134\u0135\7\n\2\2\u0135\u0136\5*\26\2\u0136")
-        buf.write("\u0137\5&\24\2\u0137\63\3\2\2\2\u0138\u013a\7\13\2\2\u0139")
-        buf.write("\u013b\5\f\7\2\u013a\u0139\3\2\2\2\u013a\u013b\3\2\2\2")
-        buf.write("\u013b\65\3\2\2\2\u013c\u013d\7\f\2\2\u013d\67\3\2\2\2")
-        buf.write("\u013e\u013f\7\20\2\2\u013f\u0140\7\65\2\2\u0140\u0144")
-        buf.write("\7\65\2\2\u0141\u0142\7=\2\2\u0142\u0143\7\66\2\2\u0143")
-        buf.write("\u0145\7>\2\2\u0144\u0141\3\2\2\2\u0144\u0145\3\2\2\2")
-        buf.write("\u0145\u014e\3\2\2\2\u0146\u0147\7\21\2\2\u0147\u014b")
-        buf.write("\7\65\2\2\u0148\u014a\5:\36\2\u0149\u0148\3\2\2\2\u014a")
-        buf.write("\u014d\3\2\2\2\u014b\u0149\3\2\2\2\u014b\u014c\3\2\2\2")
-        buf.write("\u014c\u014f\3\2\2\2\u014d\u014b\3\2\2\2\u014e\u0146\3")
-        buf.write("\2\2\2\u014e\u014f\3\2\2\2\u014f9\3\2\2\2\u0150\u0151")
-        buf.write("\7\22\2\2\u0151\u0152\7\66\2\2\u0152\u0153\7\65\2\2\u0153")
-        buf.write(";\3\2\2\2\u0154\u0155\t\2\2\2\u0155\u0156\5&\24\2\u0156")
-        buf.write("=\3\2\2\2\u0157\u015d\5@!\2\u0158\u015d\5B\"\2\u0159\u015d")
-        buf.write("\5D#\2\u015a\u015d\5F$\2\u015b\u015d\5H%\2\u015c\u0157")
-        buf.write("\3\2\2\2\u015c\u0158\3\2\2\2\u015c\u0159\3\2\2\2\u015c")
-        buf.write("\u015a\3\2\2\2\u015c\u015b\3\2\2\2\u015d?\3\2\2\2\u015e")
-        buf.write("\u015f\t\3\2\2\u015f\u0162\5&\24\2\u0160\u0163\5&\24\2")
-        buf.write("\u0161\u0163\7\66\2\2\u0162\u0160\3\2\2\2\u0162\u0161")
-        buf.write("\3\2\2\2\u0163A\3\2\2\2\u0164\u0165\t\4\2\2\u0165\u0168")
-        buf.write("\5&\24\2\u0166\u0169\5&\24\2\u0167\u0169\5^\60\2\u0168")
-        buf.write("\u0166\3\2\2\2\u0168\u0167\3\2\2\2\u0169C\3\2\2\2\u016a")
-        buf.write("\u016b\7\37\2\2\u016b\u016e\5&\24\2\u016c\u016f\5&\24")
-        buf.write("\2\u016d\u016f\5^\60\2\u016e\u016c\3\2\2\2\u016e\u016d")
-        buf.write("\3\2\2\2\u016fE\3\2\2\2\u0170\u0171\7 \2\2\u0171\u0172")
-        buf.write("\5&\24\2\u0172\u0173\5&\24\2\u0173G\3\2\2\2\u0174\u0175")
-        buf.write("\7!\2\2\u0175\u0176\5&\24\2\u0176\u0177\5&\24\2\u0177")
-        buf.write("I\3\2\2\2\u0178\u0179\7\'\2\2\u0179\u017a\5&\24\2\u017a")
-        buf.write("\u017b\7\65\2\2\u017b\u017c\5&\24\2\u017cK\3\2\2\2\u017d")
-        buf.write("\u017e\7(\2\2\u017e\u017f\7\65\2\2\u017f\u0182\5&\24\2")
-        buf.write("\u0180\u0183\5&\24\2\u0181\u0183\5^\60\2\u0182\u0180\3")
-        buf.write("\2\2\2\u0182\u0181\3\2\2\2\u0183M\3\2\2\2\u0184\u0185")
-        buf.write("\t\5\2\2\u0185\u0186\5&\24\2\u0186\u0189\5&\24\2\u0187")
-        buf.write("\u018a\5&\24\2\u0188\u018a\5^\60\2\u0189\u0187\3\2\2\2")
-        buf.write("\u0189\u0188\3\2\2\2\u018aO\3\2\2\2\u018b\u018c\7\r\2")
-        buf.write("\2\u018cQ\3\2\2\2\u018d\u018e\7\16\2\2\u018e\u018f\78")
-        buf.write("\2\2\u018fS\3\2\2\2\u0190\u0191\7\17\2\2\u0191\u0195\7")
-        buf.write("\65\2\2\u0192\u0194\5V,\2\u0193\u0192\3\2\2\2\u0194\u0197")
-        buf.write("\3\2\2\2\u0195\u0193\3\2\2\2\u0195\u0196\3\2\2\2\u0196")
-        buf.write("\u0199\3\2\2\2\u0197\u0195\3\2\2\2\u0198\u019a\78\2\2")
-        buf.write("\u0199\u0198\3\2\2\2\u0199\u019a\3\2\2\2\u019aU\3\2\2")
-        buf.write("\2\u019b\u019c\t\6\2\2\u019cW\3\2\2\2\u019d\u019e\b-\1")
-        buf.write("\2\u019e\u019f\7;\2\2\u019f\u01a0\5X-\2\u01a0\u01a1\7")
-        buf.write("<\2\2\u01a1\u01ae\3\2\2\2\u01a2\u01a3\5\\/\2\u01a3\u01a4")
-        buf.write("\5X-\n\u01a4\u01ae\3\2\2\2\u01a5\u01a6\5Z.\2\u01a6\u01a7")
-        buf.write("\7;\2\2\u01a7\u01a8\5X-\2\u01a8\u01a9\7<\2\2\u01a9\u01ae")
-        buf.write("\3\2\2\2\u01aa\u01ae\5^\60\2\u01ab\u01ae\5\22\n\2\u01ac")
-        buf.write("\u01ae\5&\24\2\u01ad\u019d\3\2\2\2\u01ad\u01a2\3\2\2\2")
-        buf.write("\u01ad\u01a5\3\2\2\2\u01ad\u01aa\3\2\2\2\u01ad\u01ab\3")
-        buf.write("\2\2\2\u01ad\u01ac\3\2\2\2\u01ae\u01ba\3\2\2\2\u01af\u01b0")
-        buf.write("\f\t\2\2\u01b0\u01b1\7\64\2\2\u01b1\u01b9\5X-\t\u01b2")
-        buf.write("\u01b3\f\b\2\2\u01b3\u01b4\t\7\2\2\u01b4\u01b9\5X-\t\u01b5")
-        buf.write("\u01b6\f\7\2\2\u01b6\u01b7\t\b\2\2\u01b7\u01b9\5X-\b\u01b8")
-        buf.write("\u01af\3\2\2\2\u01b8\u01b2\3\2\2\2\u01b8\u01b5\3\2\2\2")
-        buf.write("\u01b9\u01bc\3\2\2\2\u01ba\u01b8\3\2\2\2\u01ba\u01bb\3")
-        buf.write("\2\2\2\u01bbY\3\2\2\2\u01bc\u01ba\3\2\2\2\u01bd\u01be")
-        buf.write("\t\t\2\2\u01be[\3\2\2\2\u01bf\u01c0\t\b\2\2\u01c0]\3\2")
-        buf.write("\2\2\u01c1\u01c6\5b\62\2\u01c2\u01c6\5`\61\2\u01c3\u01c6")
-        buf.write("\7*\2\2\u01c4\u01c6\7)\2\2\u01c5\u01c1\3\2\2\2\u01c5\u01c2")
-        buf.write("\3\2\2\2\u01c5\u01c3\3\2\2\2\u01c5\u01c4\3\2\2\2\u01c6")
-        buf.write("_\3\2\2\2\u01c7\u01c8\5b\62\2\u01c8\u01c9\7*\2\2\u01c9")
-        buf.write("a\3\2\2\2\u01ca\u01cb\t\n\2\2\u01cbc\3\2\2\2+ejou}\u0091")
-        buf.write("\u009a\u009f\u00a4\u00b4\u00b9\u00c7\u00d2\u00dd\u00e2")
-        buf.write("\u00e7\u00f2\u00fb\u0100\u0105\u0109\u0111\u011a\u011e")
-        buf.write("\u0123\u013a\u0144\u014b\u014e\u015c\u0162\u0168\u016e")
-        buf.write("\u0182\u0189\u0195\u0199\u01ad\u01b8\u01ba\u01c5")
+        buf.write("/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t\64")
+        buf.write("\3\2\5\2j\n\2\3\2\6\2m\n\2\r\2\16\2n\3\2\7\2r\n\2\f\2")
+        buf.write("\16\2u\13\2\3\2\7\2x\n\2\f\2\16\2{\13\2\3\2\3\2\3\3\3")
+        buf.write("\3\3\3\5\3\u0082\n\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3")
+        buf.write("\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4\u0096\n\4\3")
+        buf.write("\5\3\5\3\5\3\5\3\5\7\5\u009d\n\5\f\5\16\5\u00a0\13\5\3")
+        buf.write("\5\3\5\5\5\u00a4\n\5\3\5\6\5\u00a7\n\5\r\5\16\5\u00a8")
+        buf.write("\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\7\t\u00b7")
+        buf.write("\n\t\f\t\16\t\u00ba\13\t\3\t\3\t\5\t\u00be\n\t\3\t\3\t")
+        buf.write("\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3\13\7\13\u00ca\n\13\f")
+        buf.write("\13\16\13\u00cd\13\13\3\13\3\13\3\f\3\f\3\f\3\f\7\f\u00d5")
+        buf.write("\n\f\f\f\16\f\u00d8\13\f\3\r\3\r\3\r\3\r\3\r\3\r\7\r\u00e0")
+        buf.write("\n\r\f\r\16\r\u00e3\13\r\3\r\3\r\5\r\u00e7\n\r\3\r\7\r")
+        buf.write("\u00ea\n\r\f\r\16\r\u00ed\13\r\3\r\3\r\3\r\3\r\3\16\3")
+        buf.write("\16\3\17\3\17\5\17\u00f7\n\17\3\20\3\20\3\20\3\20\3\20")
+        buf.write("\7\20\u00fe\n\20\f\20\16\20\u0101\13\20\3\20\3\20\5\20")
+        buf.write("\u0105\n\20\3\20\6\20\u0108\n\20\r\20\16\20\u0109\3\21")
+        buf.write("\3\21\3\21\5\21\u010f\n\21\3\22\3\22\5\22\u0113\n\22\3")
+        buf.write("\23\3\23\3\23\3\23\5\23\u0119\n\23\3\24\3\24\3\24\3\24")
+        buf.write("\7\24\u011f\n\24\f\24\16\24\u0122\13\24\3\24\3\24\3\24")
+        buf.write("\3\25\3\25\3\25\5\25\u012a\n\25\3\26\3\26\5\26\u012e\n")
+        buf.write("\26\3\26\3\26\3\26\5\26\u0133\n\26\3\27\3\27\3\27\3\30")
+        buf.write("\3\30\3\30\3\31\3\31\3\32\3\32\3\32\3\33\3\33\3\33\3\33")
+        buf.write("\3\34\3\34\3\34\3\34\3\35\3\35\5\35\u014a\n\35\3\36\3")
+        buf.write("\36\3\37\3\37\3\37\3\37\3\37\3\37\5\37\u0154\n\37\3\37")
+        buf.write("\3\37\3\37\7\37\u0159\n\37\f\37\16\37\u015c\13\37\5\37")
+        buf.write("\u015e\n\37\3 \3 \3 \3 \3!\3!\3!\3\"\3\"\3\"\3\"\3\"\5")
+        buf.write("\"\u016c\n\"\3#\3#\3#\3#\5#\u0172\n#\3$\3$\3$\3$\5$\u0178")
+        buf.write("\n$\3%\3%\3%\3%\5%\u017e\n%\3&\3&\3&\3&\3\'\3\'\3\'\3")
+        buf.write("\'\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\5)\u0192\n)\3*\3*\3*")
+        buf.write("\3*\3*\5*\u0199\n*\3+\3+\3,\3,\3,\3-\3-\3-\7-\u01a3\n")
+        buf.write("-\f-\16-\u01a6\13-\3-\5-\u01a9\n-\3.\3.\3/\3/\3/\3/\3")
+        buf.write("/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\5/\u01bd\n/\3/\3/\3")
+        buf.write("/\3/\3/\3/\3/\3/\3/\7/\u01c8\n/\f/\16/\u01cb\13/\3\60")
+        buf.write("\3\60\3\61\3\61\3\62\3\62\3\62\3\62\5\62\u01d5\n\62\3")
+        buf.write("\63\3\63\3\63\3\64\3\64\3\64\2\3\\\65\2\4\6\b\n\f\16\20")
+        buf.write("\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJL")
+        buf.write("NPRTVXZ\\^`bdf\2\13\3\2\23\26\3\2\27\32\3\2\33\36\3\2")
+        buf.write("\"&\3\2\65\66\3\2\62\63\3\2\60\61\3\2+/\3\2\66\67\2\u01f0")
+        buf.write("\2i\3\2\2\2\4\u0081\3\2\2\2\6\u0095\3\2\2\2\b\u0097\3")
+        buf.write("\2\2\2\n\u00aa\3\2\2\2\f\u00ac\3\2\2\2\16\u00ae\3\2\2")
+        buf.write("\2\20\u00b0\3\2\2\2\22\u00c3\3\2\2\2\24\u00cb\3\2\2\2")
+        buf.write("\26\u00d0\3\2\2\2\30\u00d9\3\2\2\2\32\u00f2\3\2\2\2\34")
+        buf.write("\u00f6\3\2\2\2\36\u00f8\3\2\2\2 \u010b\3\2\2\2\"\u0110")
+        buf.write("\3\2\2\2$\u0118\3\2\2\2&\u0120\3\2\2\2(\u0126\3\2\2\2")
+        buf.write("*\u0132\3\2\2\2,\u0134\3\2\2\2.\u0137\3\2\2\2\60\u013a")
+        buf.write("\3\2\2\2\62\u013c\3\2\2\2\64\u013f\3\2\2\2\66\u0143\3")
+        buf.write("\2\2\28\u0147\3\2\2\2:\u014b\3\2\2\2<\u014d\3\2\2\2>\u015f")
+        buf.write("\3\2\2\2@\u0163\3\2\2\2B\u016b\3\2\2\2D\u016d\3\2\2\2")
+        buf.write("F\u0173\3\2\2\2H\u0179\3\2\2\2J\u017f\3\2\2\2L\u0183\3")
+        buf.write("\2\2\2N\u0187\3\2\2\2P\u018c\3\2\2\2R\u0193\3\2\2\2T\u019a")
+        buf.write("\3\2\2\2V\u019c\3\2\2\2X\u019f\3\2\2\2Z\u01aa\3\2\2\2")
+        buf.write("\\\u01bc\3\2\2\2^\u01cc\3\2\2\2`\u01ce\3\2\2\2b\u01d4")
+        buf.write("\3\2\2\2d\u01d6\3\2\2\2f\u01d9\3\2\2\2hj\5\4\3\2ih\3\2")
+        buf.write("\2\2ij\3\2\2\2js\3\2\2\2km\7E\2\2lk\3\2\2\2mn\3\2\2\2")
+        buf.write("nl\3\2\2\2no\3\2\2\2op\3\2\2\2pr\5\4\3\2ql\3\2\2\2ru\3")
+        buf.write("\2\2\2sq\3\2\2\2st\3\2\2\2ty\3\2\2\2us\3\2\2\2vx\7E\2")
+        buf.write("\2wv\3\2\2\2x{\3\2\2\2yw\3\2\2\2yz\3\2\2\2z|\3\2\2\2{")
+        buf.write("y\3\2\2\2|}\7\2\2\3}\3\3\2\2\2~\u0082\5\20\t\2\177\u0082")
+        buf.write("\5\30\r\2\u0080\u0082\5\6\4\2\u0081~\3\2\2\2\u0081\177")
+        buf.write("\3\2\2\2\u0081\u0080\3\2\2\2\u0082\5\3\2\2\2\u0083\u0096")
+        buf.write("\5\b\5\2\u0084\u0096\5(\25\2\u0085\u0096\5,\27\2\u0086")
+        buf.write("\u0096\5\60\31\2\u0087\u0096\5\62\32\2\u0088\u0096\5\64")
+        buf.write("\33\2\u0089\u0096\5\66\34\2\u008a\u0096\58\35\2\u008b")
+        buf.write("\u0096\5:\36\2\u008c\u0096\5@!\2\u008d\u0096\5B\"\2\u008e")
+        buf.write("\u0096\5R*\2\u008f\u0096\5N(\2\u0090\u0096\5P)\2\u0091")
+        buf.write("\u0096\5T+\2\u0092\u0096\5V,\2\u0093\u0096\5X-\2\u0094")
+        buf.write("\u0096\5<\37\2\u0095\u0083\3\2\2\2\u0095\u0084\3\2\2\2")
+        buf.write("\u0095\u0085\3\2\2\2\u0095\u0086\3\2\2\2\u0095\u0087\3")
+        buf.write("\2\2\2\u0095\u0088\3\2\2\2\u0095\u0089\3\2\2\2\u0095\u008a")
+        buf.write("\3\2\2\2\u0095\u008b\3\2\2\2\u0095\u008c\3\2\2\2\u0095")
+        buf.write("\u008d\3\2\2\2\u0095\u008e\3\2\2\2\u0095\u008f\3\2\2\2")
+        buf.write("\u0095\u0090\3\2\2\2\u0095\u0091\3\2\2\2\u0095\u0092\3")
+        buf.write("\2\2\2\u0095\u0093\3\2\2\2\u0095\u0094\3\2\2\2\u0096\7")
+        buf.write("\3\2\2\2\u0097\u00a3\5\n\6\2\u0098\u0099\7;\2\2\u0099")
+        buf.write("\u009e\5\16\b\2\u009a\u009b\7:\2\2\u009b\u009d\5\16\b")
+        buf.write("\2\u009c\u009a\3\2\2\2\u009d\u00a0\3\2\2\2\u009e\u009c")
+        buf.write("\3\2\2\2\u009e\u009f\3\2\2\2\u009f\u00a1\3\2\2\2\u00a0")
+        buf.write("\u009e\3\2\2\2\u00a1\u00a2\7<\2\2\u00a2\u00a4\3\2\2\2")
+        buf.write("\u00a3\u0098\3\2\2\2\u00a3\u00a4\3\2\2\2\u00a4\u00a6\3")
+        buf.write("\2\2\2\u00a5\u00a7\5\f\7\2\u00a6\u00a5\3\2\2\2\u00a7\u00a8")
+        buf.write("\3\2\2\2\u00a8\u00a6\3\2\2\2\u00a8\u00a9\3\2\2\2\u00a9")
+        buf.write("\t\3\2\2\2\u00aa\u00ab\7\65\2\2\u00ab\13\3\2\2\2\u00ac")
+        buf.write("\u00ad\7\66\2\2\u00ad\r\3\2\2\2\u00ae\u00af\5\\/\2\u00af")
+        buf.write("\17\3\2\2\2\u00b0\u00b1\7\3\2\2\u00b1\u00bd\5\n\6\2\u00b2")
+        buf.write("\u00b3\7;\2\2\u00b3\u00b8\5\22\n\2\u00b4\u00b5\7:\2\2")
+        buf.write("\u00b5\u00b7\5\22\n\2\u00b6\u00b4\3\2\2\2\u00b7\u00ba")
+        buf.write("\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9")
+        buf.write("\u00bb\3\2\2\2\u00ba\u00b8\3\2\2\2\u00bb\u00bc\7<\2\2")
+        buf.write("\u00bc\u00be\3\2\2\2\u00bd\u00b2\3\2\2\2\u00bd\u00be\3")
+        buf.write("\2\2\2\u00be\u00bf\3\2\2\2\u00bf\u00c0\7?\2\2\u00c0\u00c1")
+        buf.write("\7E\2\2\u00c1\u00c2\5\24\13\2\u00c2\21\3\2\2\2\u00c3\u00c4")
+        buf.write("\7@\2\2\u00c4\u00c5\7\65\2\2\u00c5\23\3\2\2\2\u00c6\u00c7")
+        buf.write("\5\26\f\2\u00c7\u00c8\7E\2\2\u00c8\u00ca\3\2\2\2\u00c9")
+        buf.write("\u00c6\3\2\2\2\u00ca\u00cd\3\2\2\2\u00cb\u00c9\3\2\2\2")
+        buf.write("\u00cb\u00cc\3\2\2\2\u00cc\u00ce\3\2\2\2\u00cd\u00cb\3")
+        buf.write("\2\2\2\u00ce\u00cf\5\26\f\2\u00cf\25\3\2\2\2\u00d0\u00d1")
+        buf.write("\7D\2\2\u00d1\u00d6\5\\/\2\u00d2\u00d3\7:\2\2\u00d3\u00d5")
+        buf.write("\5\\/\2\u00d4\u00d2\3\2\2\2\u00d5\u00d8\3\2\2\2\u00d6")
+        buf.write("\u00d4\3\2\2\2\u00d6\u00d7\3\2\2\2\u00d7\27\3\2\2\2\u00d8")
+        buf.write("\u00d6\3\2\2\2\u00d9\u00da\7\4\2\2\u00da\u00e6\5\n\6\2")
+        buf.write("\u00db\u00dc\7;\2\2\u00dc\u00e1\5\22\n\2\u00dd\u00de\7")
+        buf.write(":\2\2\u00de\u00e0\5\22\n\2\u00df\u00dd\3\2\2\2\u00e0\u00e3")
+        buf.write("\3\2\2\2\u00e1\u00df\3\2\2\2\u00e1\u00e2\3\2\2\2\u00e2")
+        buf.write("\u00e4\3\2\2\2\u00e3\u00e1\3\2\2\2\u00e4\u00e5\7<\2\2")
+        buf.write("\u00e5\u00e7\3\2\2\2\u00e6\u00db\3\2\2\2\u00e6\u00e7\3")
+        buf.write("\2\2\2\u00e7\u00eb\3\2\2\2\u00e8\u00ea\5\32\16\2\u00e9")
+        buf.write("\u00e8\3\2\2\2\u00ea\u00ed\3\2\2\2\u00eb\u00e9\3\2\2\2")
+        buf.write("\u00eb\u00ec\3\2\2\2\u00ec\u00ee\3\2\2\2\u00ed\u00eb\3")
+        buf.write("\2\2\2\u00ee\u00ef\7?\2\2\u00ef\u00f0\7E\2\2\u00f0\u00f1")
+        buf.write("\5&\24\2\u00f1\31\3\2\2\2\u00f2\u00f3\7\65\2\2\u00f3\33")
+        buf.write("\3\2\2\2\u00f4\u00f7\5\f\7\2\u00f5\u00f7\5\32\16\2\u00f6")
+        buf.write("\u00f4\3\2\2\2\u00f6\u00f5\3\2\2\2\u00f7\35\3\2\2\2\u00f8")
+        buf.write("\u0104\5\n\6\2\u00f9\u00fa\7;\2\2\u00fa\u00ff\5\16\b\2")
+        buf.write("\u00fb\u00fc\7:\2\2\u00fc\u00fe\5\16\b\2\u00fd\u00fb\3")
+        buf.write("\2\2\2\u00fe\u0101\3\2\2\2\u00ff\u00fd\3\2\2\2\u00ff\u0100")
+        buf.write("\3\2\2\2\u0100\u0102\3\2\2\2\u0101\u00ff\3\2\2\2\u0102")
+        buf.write("\u0103\7<\2\2\u0103\u0105\3\2\2\2\u0104\u00f9\3\2\2\2")
+        buf.write("\u0104\u0105\3\2\2\2\u0105\u0107\3\2\2\2\u0106\u0108\5")
+        buf.write("\34\17\2\u0107\u0106\3\2\2\2\u0108\u0109\3\2\2\2\u0109")
+        buf.write("\u0107\3\2\2\2\u0109\u010a\3\2\2\2\u010a\37\3\2\2\2\u010b")
+        buf.write("\u010c\7\5\2\2\u010c\u010e\5\34\17\2\u010d\u010f\5*\26")
+        buf.write("\2\u010e\u010d\3\2\2\2\u010e\u010f\3\2\2\2\u010f!\3\2")
+        buf.write("\2\2\u0110\u0112\7\13\2\2\u0111\u0113\5\34\17\2\u0112")
+        buf.write("\u0111\3\2\2\2\u0112\u0113\3\2\2\2\u0113#\3\2\2\2\u0114")
+        buf.write("\u0119\5\36\20\2\u0115\u0119\5 \21\2\u0116\u0119\5\"\22")
+        buf.write("\2\u0117\u0119\5\6\4\2\u0118\u0114\3\2\2\2\u0118\u0115")
+        buf.write("\3\2\2\2\u0118\u0116\3\2\2\2\u0118\u0117\3\2\2\2\u0119")
+        buf.write("%\3\2\2\2\u011a\u011b\7D\2\2\u011b\u011c\5$\23\2\u011c")
+        buf.write("\u011d\7E\2\2\u011d\u011f\3\2\2\2\u011e\u011a\3\2\2\2")
+        buf.write("\u011f\u0122\3\2\2\2\u0120\u011e\3\2\2\2\u0120\u0121\3")
+        buf.write("\2\2\2\u0121\u0123\3\2\2\2\u0122\u0120\3\2\2\2\u0123\u0124")
+        buf.write("\7D\2\2\u0124\u0125\5$\23\2\u0125\'\3\2\2\2\u0126\u0127")
+        buf.write("\7\5\2\2\u0127\u0129\5\f\7\2\u0128\u012a\5*\26\2\u0129")
+        buf.write("\u0128\3\2\2\2\u0129\u012a\3\2\2\2\u012a)\3\2\2\2\u012b")
+        buf.write("\u0133\7\65\2\2\u012c\u012e\7\65\2\2\u012d\u012c\3\2\2")
+        buf.write("\2\u012d\u012e\3\2\2\2\u012e\u012f\3\2\2\2\u012f\u0130")
+        buf.write("\7=\2\2\u0130\u0131\7\66\2\2\u0131\u0133\7>\2\2\u0132")
+        buf.write("\u012b\3\2\2\2\u0132\u012d\3\2\2\2\u0133+\3\2\2\2\u0134")
+        buf.write("\u0135\7\6\2\2\u0135\u0136\5.\30\2\u0136-\3\2\2\2\u0137")
+        buf.write("\u0138\7A\2\2\u0138\u0139\7\65\2\2\u0139/\3\2\2\2\u013a")
+        buf.write("\u013b\7\7\2\2\u013b\61\3\2\2\2\u013c\u013d\7\b\2\2\u013d")
+        buf.write("\u013e\5.\30\2\u013e\63\3\2\2\2\u013f\u0140\7\t\2\2\u0140")
+        buf.write("\u0141\5.\30\2\u0141\u0142\5*\26\2\u0142\65\3\2\2\2\u0143")
+        buf.write("\u0144\7\n\2\2\u0144\u0145\5.\30\2\u0145\u0146\5*\26\2")
+        buf.write("\u0146\67\3\2\2\2\u0147\u0149\7\13\2\2\u0148\u014a\5\f")
+        buf.write("\7\2\u0149\u0148\3\2\2\2\u0149\u014a\3\2\2\2\u014a9\3")
+        buf.write("\2\2\2\u014b\u014c\7\f\2\2\u014c;\3\2\2\2\u014d\u014e")
+        buf.write("\7\20\2\2\u014e\u014f\7\65\2\2\u014f\u0153\7\65\2\2\u0150")
+        buf.write("\u0151\7=\2\2\u0151\u0152\7\66\2\2\u0152\u0154\7>\2\2")
+        buf.write("\u0153\u0150\3\2\2\2\u0153\u0154\3\2\2\2\u0154\u015d\3")
+        buf.write("\2\2\2\u0155\u0156\7\21\2\2\u0156\u015a\7\65\2\2\u0157")
+        buf.write("\u0159\5> \2\u0158\u0157\3\2\2\2\u0159\u015c\3\2\2\2\u015a")
+        buf.write("\u0158\3\2\2\2\u015a\u015b\3\2\2\2\u015b\u015e\3\2\2\2")
+        buf.write("\u015c\u015a\3\2\2\2\u015d\u0155\3\2\2\2\u015d\u015e\3")
+        buf.write("\2\2\2\u015e=\3\2\2\2\u015f\u0160\7\22\2\2\u0160\u0161")
+        buf.write("\7\66\2\2\u0161\u0162\7\65\2\2\u0162?\3\2\2\2\u0163\u0164")
+        buf.write("\t\2\2\2\u0164\u0165\5*\26\2\u0165A\3\2\2\2\u0166\u016c")
+        buf.write("\5D#\2\u0167\u016c\5F$\2\u0168\u016c\5H%\2\u0169\u016c")
+        buf.write("\5J&\2\u016a\u016c\5L\'\2\u016b\u0166\3\2\2\2\u016b\u0167")
+        buf.write("\3\2\2\2\u016b\u0168\3\2\2\2\u016b\u0169\3\2\2\2\u016b")
+        buf.write("\u016a\3\2\2\2\u016cC\3\2\2\2\u016d\u016e\t\3\2\2\u016e")
+        buf.write("\u0171\5*\26\2\u016f\u0172\5*\26\2\u0170\u0172\7\66\2")
+        buf.write("\2\u0171\u016f\3\2\2\2\u0171\u0170\3\2\2\2\u0172E\3\2")
+        buf.write("\2\2\u0173\u0174\t\4\2\2\u0174\u0177\5*\26\2\u0175\u0178")
+        buf.write("\5*\26\2\u0176\u0178\5b\62\2\u0177\u0175\3\2\2\2\u0177")
+        buf.write("\u0176\3\2\2\2\u0178G\3\2\2\2\u0179\u017a\7\37\2\2\u017a")
+        buf.write("\u017d\5*\26\2\u017b\u017e\5*\26\2\u017c\u017e\5b\62\2")
+        buf.write("\u017d\u017b\3\2\2\2\u017d\u017c\3\2\2\2\u017eI\3\2\2")
+        buf.write("\2\u017f\u0180\7 \2\2\u0180\u0181\5*\26\2\u0181\u0182")
+        buf.write("\5*\26\2\u0182K\3\2\2\2\u0183\u0184\7!\2\2\u0184\u0185")
+        buf.write("\5*\26\2\u0185\u0186\5*\26\2\u0186M\3\2\2\2\u0187\u0188")
+        buf.write("\7\'\2\2\u0188\u0189\5*\26\2\u0189\u018a\7\65\2\2\u018a")
+        buf.write("\u018b\5*\26\2\u018bO\3\2\2\2\u018c\u018d\7(\2\2\u018d")
+        buf.write("\u018e\7\65\2\2\u018e\u0191\5*\26\2\u018f\u0192\5*\26")
+        buf.write("\2\u0190\u0192\5b\62\2\u0191\u018f\3\2\2\2\u0191\u0190")
+        buf.write("\3\2\2\2\u0192Q\3\2\2\2\u0193\u0194\t\5\2\2\u0194\u0195")
+        buf.write("\5*\26\2\u0195\u0198\5*\26\2\u0196\u0199\5*\26\2\u0197")
+        buf.write("\u0199\5b\62\2\u0198\u0196\3\2\2\2\u0198\u0197\3\2\2\2")
+        buf.write("\u0199S\3\2\2\2\u019a\u019b\7\r\2\2\u019bU\3\2\2\2\u019c")
+        buf.write("\u019d\7\16\2\2\u019d\u019e\78\2\2\u019eW\3\2\2\2\u019f")
+        buf.write("\u01a0\7\17\2\2\u01a0\u01a4\7\65\2\2\u01a1\u01a3\5Z.\2")
+        buf.write("\u01a2\u01a1\3\2\2\2\u01a3\u01a6\3\2\2\2\u01a4\u01a2\3")
+        buf.write("\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a8\3\2\2\2\u01a6\u01a4")
+        buf.write("\3\2\2\2\u01a7\u01a9\78\2\2\u01a8\u01a7\3\2\2\2\u01a8")
+        buf.write("\u01a9\3\2\2\2\u01a9Y\3\2\2\2\u01aa\u01ab\t\6\2\2\u01ab")
+        buf.write("[\3\2\2\2\u01ac\u01ad\b/\1\2\u01ad\u01ae\7;\2\2\u01ae")
+        buf.write("\u01af\5\\/\2\u01af\u01b0\7<\2\2\u01b0\u01bd\3\2\2\2\u01b1")
+        buf.write("\u01b2\5`\61\2\u01b2\u01b3\5\\/\n\u01b3\u01bd\3\2\2\2")
+        buf.write("\u01b4\u01b5\5^\60\2\u01b5\u01b6\7;\2\2\u01b6\u01b7\5")
+        buf.write("\\/\2\u01b7\u01b8\7<\2\2\u01b8\u01bd\3\2\2\2\u01b9\u01bd")
+        buf.write("\5b\62\2\u01ba\u01bd\5\22\n\2\u01bb\u01bd\5*\26\2\u01bc")
+        buf.write("\u01ac\3\2\2\2\u01bc\u01b1\3\2\2\2\u01bc\u01b4\3\2\2\2")
+        buf.write("\u01bc\u01b9\3\2\2\2\u01bc\u01ba\3\2\2\2\u01bc\u01bb\3")
+        buf.write("\2\2\2\u01bd\u01c9\3\2\2\2\u01be\u01bf\f\t\2\2\u01bf\u01c0")
+        buf.write("\7\64\2\2\u01c0\u01c8\5\\/\t\u01c1\u01c2\f\b\2\2\u01c2")
+        buf.write("\u01c3\t\7\2\2\u01c3\u01c8\5\\/\t\u01c4\u01c5\f\7\2\2")
+        buf.write("\u01c5\u01c6\t\b\2\2\u01c6\u01c8\5\\/\b\u01c7\u01be\3")
+        buf.write("\2\2\2\u01c7\u01c1\3\2\2\2\u01c7\u01c4\3\2\2\2\u01c8\u01cb")
+        buf.write("\3\2\2\2\u01c9\u01c7\3\2\2\2\u01c9\u01ca\3\2\2\2\u01ca")
+        buf.write("]\3\2\2\2\u01cb\u01c9\3\2\2\2\u01cc\u01cd\t\t\2\2\u01cd")
+        buf.write("_\3\2\2\2\u01ce\u01cf\t\b\2\2\u01cfa\3\2\2\2\u01d0\u01d5")
+        buf.write("\5f\64\2\u01d1\u01d5\5d\63\2\u01d2\u01d5\7*\2\2\u01d3")
+        buf.write("\u01d5\7)\2\2\u01d4\u01d0\3\2\2\2\u01d4\u01d1\3\2\2\2")
+        buf.write("\u01d4\u01d2\3\2\2\2\u01d4\u01d3\3\2\2\2\u01d5c\3\2\2")
+        buf.write("\2\u01d6\u01d7\5f\64\2\u01d7\u01d8\7*\2\2\u01d8e\3\2\2")
+        buf.write("\2\u01d9\u01da\t\n\2\2\u01dag\3\2\2\2-insy\u0081\u0095")
+        buf.write("\u009e\u00a3\u00a8\u00b8\u00bd\u00cb\u00d6\u00e1\u00e6")
+        buf.write("\u00eb\u00f6\u00ff\u0104\u0109\u010e\u0112\u0118\u0120")
+        buf.write("\u0129\u012d\u0132\u0149\u0153\u015a\u015d\u016b\u0171")
+        buf.write("\u0177\u017d\u0191\u0198\u01a4\u01a8\u01bc\u01c7\u01c9")
+        buf.write("\u01d4")
         return buf.getvalue()
 
 
@@ -272,47 +282,50 @@ class QuilParser ( Parser ):
     RULE_qubitVariable = 12
     RULE_circuitQubit = 13
     RULE_circuitGate = 14
-    RULE_circuitInstr = 15
-    RULE_circuit = 16
-    RULE_measure = 17
-    RULE_addr = 18
-    RULE_defLabel = 19
-    RULE_label = 20
-    RULE_halt = 21
-    RULE_jump = 22
-    RULE_jumpWhen = 23
-    RULE_jumpUnless = 24
-    RULE_resetState = 25
-    RULE_wait = 26
-    RULE_memoryDescriptor = 27
-    RULE_offsetDescriptor = 28
-    RULE_classicalUnary = 29
-    RULE_classicalBinary = 30
-    RULE_logicalBinaryOp = 31
-    RULE_arithmeticBinaryOp = 32
-    RULE_move = 33
-    RULE_exchange = 34
-    RULE_convert = 35
-    RULE_load = 36
-    RULE_store = 37
-    RULE_classicalComparison = 38
-    RULE_nop = 39
-    RULE_include = 40
-    RULE_pragma = 41
-    RULE_pragma_name = 42
-    RULE_expression = 43
-    RULE_function = 44
-    RULE_sign = 45
-    RULE_number = 46
-    RULE_imaginaryN = 47
-    RULE_realN = 48
+    RULE_circuitMeasure = 15
+    RULE_circuitResetState = 16
+    RULE_circuitInstr = 17
+    RULE_circuit = 18
+    RULE_measure = 19
+    RULE_addr = 20
+    RULE_defLabel = 21
+    RULE_label = 22
+    RULE_halt = 23
+    RULE_jump = 24
+    RULE_jumpWhen = 25
+    RULE_jumpUnless = 26
+    RULE_resetState = 27
+    RULE_wait = 28
+    RULE_memoryDescriptor = 29
+    RULE_offsetDescriptor = 30
+    RULE_classicalUnary = 31
+    RULE_classicalBinary = 32
+    RULE_logicalBinaryOp = 33
+    RULE_arithmeticBinaryOp = 34
+    RULE_move = 35
+    RULE_exchange = 36
+    RULE_convert = 37
+    RULE_load = 38
+    RULE_store = 39
+    RULE_classicalComparison = 40
+    RULE_nop = 41
+    RULE_include = 42
+    RULE_pragma = 43
+    RULE_pragma_name = 44
+    RULE_expression = 45
+    RULE_function = 46
+    RULE_sign = 47
+    RULE_number = 48
+    RULE_imaginaryN = 49
+    RULE_realN = 50
 
     ruleNames =  [ "quil", "allInstr", "instr", "gate", "name", "qubit", 
                    "param", "defGate", "variable", "matrix", "matrixRow", 
                    "defCircuit", "qubitVariable", "circuitQubit", "circuitGate", 
-                   "circuitInstr", "circuit", "measure", "addr", "defLabel", 
-                   "label", "halt", "jump", "jumpWhen", "jumpUnless", "resetState", 
-                   "wait", "memoryDescriptor", "offsetDescriptor", "classicalUnary", 
+                   "circuitMeasure", "circuitResetState", "circuitInstr", 
+                   "circuit", "measure", "addr", "defLabel", "label", "halt", 
+                   "jump", "jumpWhen", "jumpUnless", "resetState", "wait", 
+                   "memoryDescriptor", "offsetDescriptor", "classicalUnary", 
                    "classicalBinary", "logicalBinaryOp", "arithmeticBinaryOp", 
                    "move", "exchange", "convert", "load", "store", "classicalComparison", 
                    "nop", "include", "pragma", "pragma_name", "expression", 
@@ -441,48 +454,48 @@ class QuilParser ( Parser ):
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 99
+            self.state = 103
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << QuilParser.DEFGATE) | (1 << QuilParser.DEFCIRCUIT) | (1 << QuilParser.MEASURE) | (1 << QuilParser.LABEL) | (1 << QuilParser.HALT) | (1 << QuilParser.JUMP) | (1 << QuilParser.JUMPWHEN) | (1 << QuilParser.JUMPUNLESS) | (1 << QuilParser.RESET) | (1 << QuilParser.WAIT) | (1 << QuilParser.NOP) | (1 << QuilParser.INCLUDE) | (1 << QuilParser.PRAGMA) | (1 << QuilParser.DECLARE) | (1 << QuilParser.NEG) | (1 << QuilParser.NOT) | (1 << QuilParser.TRUE) | (1 << QuilParser.FALSE) | (1 << QuilParser.AND) | (1 << QuilParser.IOR) | (1 << QuilParser.XOR) | (1 << QuilParser.OR) | (1 << QuilParser.ADD) | (1 << QuilParser.SUB) | (1 << QuilParser.MUL) | (1 << QuilParser.DIV) | (1 << QuilParser.MOVE) | (1 << QuilParser.EXCHANGE) | (1 << QuilParser.CONVERT) | (1 << QuilParser.EQ) | (1 << QuilParser.GT) | (1 << QuilParser.GE) | (1 << QuilParser.LT) | (1 << QuilParser.LE) | (1 << QuilParser.LOAD) | (1 << QuilParser.STORE) | (1 << QuilParser.IDENTIFIER))) != 0):
-                self.state = 98
+                self.state = 102
                 self.allInstr()
 
 
-            self.state = 109
+            self.state = 113
             self._errHandler.sync(self)
             _alt = self._interp.adaptivePredict(self._input,2,self._ctx)
             while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                 if _alt==1:
-                    self.state = 102 
+                    self.state = 106 
                     self._errHandler.sync(self)
                     _la = self._input.LA(1)
                     while True:
-                        self.state = 101
+                        self.state = 105
                         self.match(QuilParser.NEWLINE)
-                        self.state = 104 
+                        self.state = 108 
                         self._errHandler.sync(self)
                         _la = self._input.LA(1)
                         if not (_la==QuilParser.NEWLINE):
                             break
 
-                    self.state = 106
+                    self.state = 110
                     self.allInstr() 
-                self.state = 111
+                self.state = 115
                 self._errHandler.sync(self)
                 _alt = self._interp.adaptivePredict(self._input,2,self._ctx)
 
-            self.state = 115
+            self.state = 119
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             while _la==QuilParser.NEWLINE:
-                self.state = 112
+                self.state = 116
                 self.match(QuilParser.NEWLINE)
-                self.state = 117
+                self.state = 121
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
 
-            self.state = 118
+            self.state = 122
             self.match(QuilParser.EOF)
         except RecognitionException as re:
             localctx.exception = re
@@ -529,22 +542,22 @@ class QuilParser ( Parser ):
         localctx = QuilParser.AllInstrContext(self, self._ctx, self.state)
         self.enterRule(localctx, 2, self.RULE_allInstr)
         try:
-            self.state = 123
+            self.state = 127
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.DEFGATE]:
                 self.enterOuterAlt(localctx, 1)
-                self.state = 120
+                self.state = 124
                 self.defGate()
                 pass
             elif token in [QuilParser.DEFCIRCUIT]:
                 self.enterOuterAlt(localctx, 2)
-                self.state = 121
+                self.state = 125
                 self.defCircuit()
                 pass
             elif token in [QuilParser.MEASURE, QuilParser.LABEL, QuilParser.HALT, QuilParser.JUMP, QuilParser.JUMPWHEN, QuilParser.JUMPUNLESS, QuilParser.RESET, QuilParser.WAIT, QuilParser.NOP, QuilParser.INCLUDE, QuilParser.PRAGMA, QuilParser.DECLARE, QuilParser.NEG, QuilParser.NOT, QuilParser.TRUE, QuilParser.FALSE, QuilParser.AND, QuilParser.IOR, QuilParser.XOR, QuilParser.OR, QuilParser.ADD, QuilParser.SUB, QuilParser.MUL, QuilParser.DIV, QuilParser.MOVE, QuilParser.EXCHANGE, QuilParser.CONVERT, QuilParser.EQ, QuilParser.GT, QuilParser.GE, QuilParser.LT, QuilParser.LE, QuilParser.LOAD, QuilParser.STORE, QuilParser.IDENTIFIER]:
                 self.enterOuterAlt(localctx, 3)
-                self.state = 122
+                self.state = 126
                 self.instr()
                 pass
             else:
@@ -655,97 +668,97 @@ class QuilParser ( Parser ):
         localctx = QuilParser.InstrContext(self, self._ctx, self.state)
         self.enterRule(localctx, 4, self.RULE_instr)
         try:
-            self.state = 143
+            self.state = 147
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.IDENTIFIER]:
                 self.enterOuterAlt(localctx, 1)
-                self.state = 125
+                self.state = 129
                 self.gate()
                 pass
             elif token in [QuilParser.MEASURE]:
                 self.enterOuterAlt(localctx, 2)
-                self.state = 126
+                self.state = 130
                 self.measure()
                 pass
             elif token in [QuilParser.LABEL]:
                 self.enterOuterAlt(localctx, 3)
-                self.state = 127
+                self.state = 131
                 self.defLabel()
                 pass
             elif token in [QuilParser.HALT]:
                 self.enterOuterAlt(localctx, 4)
-                self.state = 128
+                self.state = 132
                 self.halt()
                 pass
             elif token in [QuilParser.JUMP]:
                 self.enterOuterAlt(localctx, 5)
-                self.state = 129
+                self.state = 133
                 self.jump()
                 pass
             elif token in [QuilParser.JUMPWHEN]:
                 self.enterOuterAlt(localctx, 6)
-                self.state = 130
+                self.state = 134
                 self.jumpWhen()
                 pass
             elif token in [QuilParser.JUMPUNLESS]:
                 self.enterOuterAlt(localctx, 7)
-                self.state = 131
+                self.state = 135
                 self.jumpUnless()
                 pass
             elif token in [QuilParser.RESET]:
                 self.enterOuterAlt(localctx, 8)
-                self.state = 132
+                self.state = 136
                 self.resetState()
                 pass
             elif token in [QuilParser.WAIT]:
                 self.enterOuterAlt(localctx, 9)
-                self.state = 133
+                self.state = 137
                 self.wait()
                 pass
             elif token in [QuilParser.NEG, QuilParser.NOT, QuilParser.TRUE, QuilParser.FALSE]:
                 self.enterOuterAlt(localctx, 10)
-                self.state = 134
+                self.state = 138
                 self.classicalUnary()
                 pass
             elif token in [QuilParser.AND, QuilParser.IOR, QuilParser.XOR, QuilParser.OR, QuilParser.ADD, QuilParser.SUB, QuilParser.MUL, QuilParser.DIV, QuilParser.MOVE, QuilParser.EXCHANGE, QuilParser.CONVERT]:
                 self.enterOuterAlt(localctx, 11)
-                self.state = 135
+                self.state = 139
                 self.classicalBinary()
                 pass
             elif token in [QuilParser.EQ, QuilParser.GT, QuilParser.GE, QuilParser.LT, QuilParser.LE]:
                 self.enterOuterAlt(localctx, 12)
-                self.state = 136
+                self.state = 140
                 self.classicalComparison()
                 pass
             elif token in [QuilParser.LOAD]:
                 self.enterOuterAlt(localctx, 13)
-                self.state = 137
+                self.state = 141
                 self.load()
                 pass
             elif token in [QuilParser.STORE]:
                 self.enterOuterAlt(localctx, 14)
-                self.state = 138
+                self.state = 142
                 self.store()
                 pass
             elif token in [QuilParser.NOP]:
                 self.enterOuterAlt(localctx, 15)
-                self.state = 139
+                self.state = 143
                 self.nop()
                 pass
             elif token in [QuilParser.INCLUDE]:
                 self.enterOuterAlt(localctx, 16)
-                self.state = 140
+                self.state = 144
                 self.include()
                 pass
             elif token in [QuilParser.PRAGMA]:
                 self.enterOuterAlt(localctx, 17)
-                self.state = 141
+                self.state = 145
                 self.pragma()
                 pass
             elif token in [QuilParser.DECLARE]:
                 self.enterOuterAlt(localctx, 18)
-                self.state = 142
+                self.state = 146
                 self.memoryDescriptor()
                 pass
             else:
@@ -816,39 +829,39 @@ class QuilParser ( Parser ):
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 145
+            self.state = 149
             self.name()
-            self.state = 157
+            self.state = 161
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.LPAREN:
-                self.state = 146
+                self.state = 150
                 self.match(QuilParser.LPAREN)
-                self.state = 147
+                self.state = 151
                 self.param()
-                self.state = 152
+                self.state = 156
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 while _la==QuilParser.COMMA:
-                    self.state = 148
+                    self.state = 152
                     self.match(QuilParser.COMMA)
-                    self.state = 149
+                    self.state = 153
                     self.param()
-                    self.state = 154
+                    self.state = 158
                     self._errHandler.sync(self)
                     _la = self._input.LA(1)
 
-                self.state = 155
+                self.state = 159
                 self.match(QuilParser.RPAREN)
 
 
-            self.state = 160 
+            self.state = 164 
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             while True:
-                self.state = 159
+                self.state = 163
                 self.qubit()
-                self.state = 162 
+                self.state = 166 
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 if not (_la==QuilParser.INT):
@@ -891,7 +904,7 @@ class QuilParser ( Parser ):
         self.enterRule(localctx, 8, self.RULE_name)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 164
+            self.state = 168
             self.match(QuilParser.IDENTIFIER)
         except RecognitionException as re:
             localctx.exception = re
@@ -930,7 +943,7 @@ class QuilParser ( Parser ):
         self.enterRule(localctx, 10, self.RULE_qubit)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 166
+            self.state = 170
             self.match(QuilParser.INT)
         except RecognitionException as re:
             localctx.exception = re
@@ -970,7 +983,7 @@ class QuilParser ( Parser ):
         self.enterRule(localctx, 12, self.RULE_param)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 168
+            self.state = 172
             self.expression(0)
         except RecognitionException as re:
             localctx.exception = re
@@ -1043,39 +1056,39 @@ class QuilParser ( Parser ):
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 170
+            self.state = 174
             self.match(QuilParser.DEFGATE)
-            self.state = 171
+            self.state = 175
             self.name()
-            self.state = 183
+            self.state = 187
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.LPAREN:
-                self.state = 172
+                self.state = 176
                 self.match(QuilParser.LPAREN)
-                self.state = 173
+                self.state = 177
                 self.variable()
-                self.state = 178
+                self.state = 182
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 while _la==QuilParser.COMMA:
-                    self.state = 174
+                    self.state = 178
                     self.match(QuilParser.COMMA)
-                    self.state = 175
+                    self.state = 179
                     self.variable()
-                    self.state = 180
+                    self.state = 184
                     self._errHandler.sync(self)
                     _la = self._input.LA(1)
 
-                self.state = 181
+                self.state = 185
                 self.match(QuilParser.RPAREN)
 
 
-            self.state = 185
+            self.state = 189
             self.match(QuilParser.COLON)
-            self.state = 186
+            self.state = 190
             self.match(QuilParser.NEWLINE)
-            self.state = 187
+            self.state = 191
             self.matrix()
         except RecognitionException as re:
             localctx.exception = re
@@ -1117,9 +1130,9 @@ class QuilParser ( Parser ):
         self.enterRule(localctx, 16, self.RULE_variable)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 189
+            self.state = 193
             self.match(QuilParser.PERCENTAGE)
-            self.state = 190
+            self.state = 194
             self.match(QuilParser.IDENTIFIER)
         except RecognitionException as re:
             localctx.exception = re
@@ -1168,20 +1181,20 @@ class QuilParser ( Parser ):
         self.enterRule(localctx, 18, self.RULE_matrix)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 197
+            self.state = 201
             self._errHandler.sync(self)
             _alt = self._interp.adaptivePredict(self._input,11,self._ctx)
             while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                 if _alt==1:
-                    self.state = 192
+                    self.state = 196
                     self.matrixRow()
-                    self.state = 193
+                    self.state = 197
                     self.match(QuilParser.NEWLINE) 
-                self.state = 199
+                self.state = 203
                 self._errHandler.sync(self)
                 _alt = self._interp.adaptivePredict(self._input,11,self._ctx)
 
-            self.state = 200
+            self.state = 204
             self.matrixRow()
         except RecognitionException as re:
             localctx.exception = re
@@ -1234,19 +1247,19 @@ class QuilParser ( Parser ):
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 202
+            self.state = 206
             self.match(QuilParser.TAB)
-            self.state = 203
+            self.state = 207
             self.expression(0)
-            self.state = 208
+            self.state = 212
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             while _la==QuilParser.COMMA:
-                self.state = 204
+                self.state = 208
                 self.match(QuilParser.COMMA)
-                self.state = 205
+                self.state = 209
                 self.expression(0)
-                self.state = 210
+                self.state = 214
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
 
@@ -1328,49 +1341,49 @@ class QuilParser ( Parser ):
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 211
+            self.state = 215
             self.match(QuilParser.DEFCIRCUIT)
-            self.state = 212
+            self.state = 216
             self.name()
-            self.state = 224
+            self.state = 228
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.LPAREN:
-                self.state = 213
+                self.state = 217
                 self.match(QuilParser.LPAREN)
-                self.state = 214
+                self.state = 218
                 self.variable()
-                self.state = 219
+                self.state = 223
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 while _la==QuilParser.COMMA:
-                    self.state = 215
+                    self.state = 219
                     self.match(QuilParser.COMMA)
-                    self.state = 216
+                    self.state = 220
                     self.variable()
-                    self.state = 221
+                    self.state = 225
                     self._errHandler.sync(self)
                     _la = self._input.LA(1)
 
-                self.state = 222
+                self.state = 226
                 self.match(QuilParser.RPAREN)
 
 
-            self.state = 229
+            self.state = 233
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             while _la==QuilParser.IDENTIFIER:
-                self.state = 226
+                self.state = 230
                 self.qubitVariable()
-                self.state = 231
+                self.state = 235
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
 
-            self.state = 232
+            self.state = 236
             self.match(QuilParser.COLON)
-            self.state = 233
+            self.state = 237
             self.match(QuilParser.NEWLINE)
-            self.state = 234
+            self.state = 238
             self.circuit()
         except RecognitionException as re:
             localctx.exception = re
@@ -1409,7 +1422,7 @@ class QuilParser ( Parser ):
         self.enterRule(localctx, 24, self.RULE_qubitVariable)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 236
+            self.state = 240
             self.match(QuilParser.IDENTIFIER)
         except RecognitionException as re:
             localctx.exception = re
@@ -1452,17 +1465,17 @@ class QuilParser ( Parser ):
         localctx = QuilParser.CircuitQubitContext(self, self._ctx, self.state)
         self.enterRule(localctx, 26, self.RULE_circuitQubit)
         try:
-            self.state = 240
+            self.state = 244
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.INT]:
                 self.enterOuterAlt(localctx, 1)
-                self.state = 238
+                self.state = 242
                 self.qubit()
                 pass
             elif token in [QuilParser.IDENTIFIER]:
                 self.enterOuterAlt(localctx, 2)
-                self.state = 239
+                self.state = 243
                 self.qubitVariable()
                 pass
             else:
@@ -1533,39 +1546,39 @@ class QuilParser ( Parser ):
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 242
+            self.state = 246
             self.name()
-            self.state = 254
+            self.state = 258
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.LPAREN:
-                self.state = 243
+                self.state = 247
                 self.match(QuilParser.LPAREN)
-                self.state = 244
+                self.state = 248
                 self.param()
-                self.state = 249
+                self.state = 253
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 while _la==QuilParser.COMMA:
-                    self.state = 245
+                    self.state = 249
                     self.match(QuilParser.COMMA)
-                    self.state = 246
+                    self.state = 250
                     self.param()
-                    self.state = 251
+                    self.state = 255
                     self._errHandler.sync(self)
                     _la = self._input.LA(1)
 
-                self.state = 252
+                self.state = 256
                 self.match(QuilParser.RPAREN)
 
 
-            self.state = 257 
+            self.state = 261 
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             while True:
-                self.state = 256
+                self.state = 260
                 self.circuitQubit()
-                self.state = 259 
+                self.state = 263 
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 if not (_la==QuilParser.IDENTIFIER or _la==QuilParser.INT):
@@ -1579,6 +1592,116 @@ class QuilParser ( Parser ):
             self.exitRule()
         return localctx
 
+    class CircuitMeasureContext(ParserRuleContext):
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def MEASURE(self):
+            return self.getToken(QuilParser.MEASURE, 0)
+
+        def circuitQubit(self):
+            return self.getTypedRuleContext(QuilParser.CircuitQubitContext,0)
+
+
+        def addr(self):
+            return self.getTypedRuleContext(QuilParser.AddrContext,0)
+
+
+        def getRuleIndex(self):
+            return QuilParser.RULE_circuitMeasure
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterCircuitMeasure" ):
+                listener.enterCircuitMeasure(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitCircuitMeasure" ):
+                listener.exitCircuitMeasure(self)
+
+
+
+
+    def circuitMeasure(self):
+
+        localctx = QuilParser.CircuitMeasureContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 30, self.RULE_circuitMeasure)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 265
+            self.match(QuilParser.MEASURE)
+            self.state = 266
+            self.circuitQubit()
+            self.state = 268
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            if _la==QuilParser.IDENTIFIER or _la==QuilParser.LBRACKET:
+                self.state = 267
+                self.addr()
+
+
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
+    class CircuitResetStateContext(ParserRuleContext):
+
+        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+            super().__init__(parent, invokingState)
+            self.parser = parser
+
+        def RESET(self):
+            return self.getToken(QuilParser.RESET, 0)
+
+        def circuitQubit(self):
+            return self.getTypedRuleContext(QuilParser.CircuitQubitContext,0)
+
+
+        def getRuleIndex(self):
+            return QuilParser.RULE_circuitResetState
+
+        def enterRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "enterCircuitResetState" ):
+                listener.enterCircuitResetState(self)
+
+        def exitRule(self, listener:ParseTreeListener):
+            if hasattr( listener, "exitCircuitResetState" ):
+                listener.exitCircuitResetState(self)
+
+
+
+
+    def circuitResetState(self):
+
+        localctx = QuilParser.CircuitResetStateContext(self, self._ctx, self.state)
+        self.enterRule(localctx, 32, self.RULE_circuitResetState)
+        self._la = 0 # Token type
+        try:
+            self.enterOuterAlt(localctx, 1)
+            self.state = 270
+            self.match(QuilParser.RESET)
+            self.state = 272
+            self._errHandler.sync(self)
+            _la = self._input.LA(1)
+            if _la==QuilParser.IDENTIFIER or _la==QuilParser.INT:
+                self.state = 271
+                self.circuitQubit()
+
+
+        except RecognitionException as re:
+            localctx.exception = re
+            self._errHandler.reportError(self, re)
+            self._errHandler.recover(self, re)
+        finally:
+            self.exitRule()
+        return localctx
+
     class CircuitInstrContext(ParserRuleContext):
 
         def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
@@ -1589,6 +1712,14 @@ class QuilParser ( Parser ):
             return self.getTypedRuleContext(QuilParser.CircuitGateContext,0)
 
 
+        def circuitMeasure(self):
+            return self.getTypedRuleContext(QuilParser.CircuitMeasureContext,0)
+
+
+        def circuitResetState(self):
+            return self.getTypedRuleContext(QuilParser.CircuitResetStateContext,0)
+
+
         def instr(self):
             return self.getTypedRuleContext(QuilParser.InstrContext,0)
 
@@ -1610,20 +1741,32 @@ class QuilParser ( Parser ):
     def circuitInstr(self):
 
         localctx = QuilParser.CircuitInstrContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 30, self.RULE_circuitInstr)
+        self.enterRule(localctx, 34, self.RULE_circuitInstr)
         try:
-            self.state = 263
+            self.state = 278
             self._errHandler.sync(self)
-            la_ = self._interp.adaptivePredict(self._input,20,self._ctx)
+            la_ = self._interp.adaptivePredict(self._input,22,self._ctx)
             if la_ == 1:
                 self.enterOuterAlt(localctx, 1)
-                self.state = 261
+                self.state = 274
                 self.circuitGate()
                 pass
 
             elif la_ == 2:
                 self.enterOuterAlt(localctx, 2)
-                self.state = 262
+                self.state = 275
+                self.circuitMeasure()
+                pass
+
+            elif la_ == 3:
+                self.enterOuterAlt(localctx, 3)
+                self.state = 276
+                self.circuitResetState()
+                pass
+
+            elif la_ == 4:
+                self.enterOuterAlt(localctx, 4)
+                self.state = 277
                 self.instr()
                 pass
 
@@ -1678,27 +1821,27 @@ class QuilParser ( Parser ):
     def circuit(self):
 
         localctx = QuilParser.CircuitContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 32, self.RULE_circuit)
+        self.enterRule(localctx, 36, self.RULE_circuit)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 271
+            self.state = 286
             self._errHandler.sync(self)
-            _alt = self._interp.adaptivePredict(self._input,21,self._ctx)
+            _alt = self._interp.adaptivePredict(self._input,23,self._ctx)
             while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                 if _alt==1:
-                    self.state = 265
+                    self.state = 280
                     self.match(QuilParser.TAB)
-                    self.state = 266
+                    self.state = 281
                     self.circuitInstr()
-                    self.state = 267
+                    self.state = 282
                     self.match(QuilParser.NEWLINE) 
-                self.state = 273
+                self.state = 288
                 self._errHandler.sync(self)
-                _alt = self._interp.adaptivePredict(self._input,21,self._ctx)
+                _alt = self._interp.adaptivePredict(self._input,23,self._ctx)
 
-            self.state = 274
+            self.state = 289
             self.match(QuilParser.TAB)
-            self.state = 275
+            self.state = 290
             self.circuitInstr()
         except RecognitionException as re:
             localctx.exception = re
@@ -1742,19 +1885,19 @@ class QuilParser ( Parser ):
     def measure(self):
 
         localctx = QuilParser.MeasureContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 34, self.RULE_measure)
+        self.enterRule(localctx, 38, self.RULE_measure)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 277
+            self.state = 292
             self.match(QuilParser.MEASURE)
-            self.state = 278
+            self.state = 293
             self.qubit()
-            self.state = 280
+            self.state = 295
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.IDENTIFIER or _la==QuilParser.LBRACKET:
-                self.state = 279
+                self.state = 294
                 self.addr()
 
 
@@ -1801,33 +1944,33 @@ class QuilParser ( Parser ):
     def addr(self):
 
         localctx = QuilParser.AddrContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 36, self.RULE_addr)
+        self.enterRule(localctx, 40, self.RULE_addr)
         self._la = 0 # Token type
         try:
-            self.state = 289
+            self.state = 304
             self._errHandler.sync(self)
-            la_ = self._interp.adaptivePredict(self._input,24,self._ctx)
+            la_ = self._interp.adaptivePredict(self._input,26,self._ctx)
             if la_ == 1:
                 self.enterOuterAlt(localctx, 1)
-                self.state = 282
+                self.state = 297
                 self.match(QuilParser.IDENTIFIER)
                 pass
 
             elif la_ == 2:
                 self.enterOuterAlt(localctx, 2)
-                self.state = 284
+                self.state = 299
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 if _la==QuilParser.IDENTIFIER:
-                    self.state = 283
+                    self.state = 298
                     self.match(QuilParser.IDENTIFIER)
 
 
-                self.state = 286
+                self.state = 301
                 self.match(QuilParser.LBRACKET)
-                self.state = 287
+                self.state = 302
                 self.match(QuilParser.INT)
-                self.state = 288
+                self.state = 303
                 self.match(QuilParser.RBRACKET)
                 pass
 
@@ -1870,12 +2013,12 @@ class QuilParser ( Parser ):
     def defLabel(self):
 
         localctx = QuilParser.DefLabelContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 38, self.RULE_defLabel)
+        self.enterRule(localctx, 42, self.RULE_defLabel)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 291
+            self.state = 306
             self.match(QuilParser.LABEL)
-            self.state = 292
+            self.state = 307
             self.label()
         except RecognitionException as re:
             localctx.exception = re
@@ -1914,12 +2057,12 @@ class QuilParser ( Parser ):
     def label(self):
 
         localctx = QuilParser.LabelContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 40, self.RULE_label)
+        self.enterRule(localctx, 44, self.RULE_label)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 294
+            self.state = 309
             self.match(QuilParser.AT)
-            self.state = 295
+            self.state = 310
             self.match(QuilParser.IDENTIFIER)
         except RecognitionException as re:
             localctx.exception = re
@@ -1955,10 +2098,10 @@ class QuilParser ( Parser ):
     def halt(self):
 
         localctx = QuilParser.HaltContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 42, self.RULE_halt)
+        self.enterRule(localctx, 46, self.RULE_halt)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 297
+            self.state = 312
             self.match(QuilParser.HALT)
         except RecognitionException as re:
             localctx.exception = re
@@ -1998,12 +2141,12 @@ class QuilParser ( Parser ):
     def jump(self):
 
         localctx = QuilParser.JumpContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 44, self.RULE_jump)
+        self.enterRule(localctx, 48, self.RULE_jump)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 299
+            self.state = 314
             self.match(QuilParser.JUMP)
-            self.state = 300
+            self.state = 315
             self.label()
         except RecognitionException as re:
             localctx.exception = re
@@ -2047,14 +2190,14 @@ class QuilParser ( Parser ):
     def jumpWhen(self):
 
         localctx = QuilParser.JumpWhenContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 46, self.RULE_jumpWhen)
+        self.enterRule(localctx, 50, self.RULE_jumpWhen)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 302
+            self.state = 317
             self.match(QuilParser.JUMPWHEN)
-            self.state = 303
+            self.state = 318
             self.label()
-            self.state = 304
+            self.state = 319
             self.addr()
         except RecognitionException as re:
             localctx.exception = re
@@ -2098,14 +2241,14 @@ class QuilParser ( Parser ):
     def jumpUnless(self):
 
         localctx = QuilParser.JumpUnlessContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 48, self.RULE_jumpUnless)
+        self.enterRule(localctx, 52, self.RULE_jumpUnless)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 306
+            self.state = 321
             self.match(QuilParser.JUMPUNLESS)
-            self.state = 307
+            self.state = 322
             self.label()
-            self.state = 308
+            self.state = 323
             self.addr()
         except RecognitionException as re:
             localctx.exception = re
@@ -2145,17 +2288,17 @@ class QuilParser ( Parser ):
     def resetState(self):
 
         localctx = QuilParser.ResetStateContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 50, self.RULE_resetState)
+        self.enterRule(localctx, 54, self.RULE_resetState)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 310
+            self.state = 325
             self.match(QuilParser.RESET)
-            self.state = 312
+            self.state = 327
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.INT:
-                self.state = 311
+                self.state = 326
                 self.qubit()
 
 
@@ -2193,10 +2336,10 @@ class QuilParser ( Parser ):
     def wait(self):
 
         localctx = QuilParser.WaitContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 52, self.RULE_wait)
+        self.enterRule(localctx, 56, self.RULE_wait)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 314
+            self.state = 329
             self.match(QuilParser.WAIT)
         except RecognitionException as re:
             localctx.exception = re
@@ -2257,43 +2400,43 @@ class QuilParser ( Parser ):
     def memoryDescriptor(self):
 
         localctx = QuilParser.MemoryDescriptorContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 54, self.RULE_memoryDescriptor)
+        self.enterRule(localctx, 58, self.RULE_memoryDescriptor)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 316
+            self.state = 331
             self.match(QuilParser.DECLARE)
-            self.state = 317
+            self.state = 332
             self.match(QuilParser.IDENTIFIER)
-            self.state = 318
+            self.state = 333
             self.match(QuilParser.IDENTIFIER)
-            self.state = 322
+            self.state = 337
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.LBRACKET:
-                self.state = 319
+                self.state = 334
                 self.match(QuilParser.LBRACKET)
-                self.state = 320
+                self.state = 335
                 self.match(QuilParser.INT)
-                self.state = 321
+                self.state = 336
                 self.match(QuilParser.RBRACKET)
 
 
-            self.state = 332
+            self.state = 347
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.SHARING:
-                self.state = 324
+                self.state = 339
                 self.match(QuilParser.SHARING)
-                self.state = 325
+                self.state = 340
                 self.match(QuilParser.IDENTIFIER)
-                self.state = 329
+                self.state = 344
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
                 while _la==QuilParser.OFFSET:
-                    self.state = 326
+                    self.state = 341
                     self.offsetDescriptor()
-                    self.state = 331
+                    self.state = 346
                     self._errHandler.sync(self)
                     _la = self._input.LA(1)
 
@@ -2339,14 +2482,14 @@ class QuilParser ( Parser ):
     def offsetDescriptor(self):
 
         localctx = QuilParser.OffsetDescriptorContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 56, self.RULE_offsetDescriptor)
+        self.enterRule(localctx, 60, self.RULE_offsetDescriptor)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 334
+            self.state = 349
             self.match(QuilParser.OFFSET)
-            self.state = 335
+            self.state = 350
             self.match(QuilParser.INT)
-            self.state = 336
+            self.state = 351
             self.match(QuilParser.IDENTIFIER)
         except RecognitionException as re:
             localctx.exception = re
@@ -2395,18 +2538,18 @@ class QuilParser ( Parser ):
     def classicalUnary(self):
 
         localctx = QuilParser.ClassicalUnaryContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 58, self.RULE_classicalUnary)
+        self.enterRule(localctx, 62, self.RULE_classicalUnary)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 338
+            self.state = 353
             _la = self._input.LA(1)
             if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << QuilParser.NEG) | (1 << QuilParser.NOT) | (1 << QuilParser.TRUE) | (1 << QuilParser.FALSE))) != 0)):
                 self._errHandler.recoverInline(self)
             else:
                 self._errHandler.reportMatch(self)
                 self.consume()
-            self.state = 339
+            self.state = 354
             self.addr()
         except RecognitionException as re:
             localctx.exception = re
@@ -2459,34 +2602,34 @@ class QuilParser ( Parser ):
     def classicalBinary(self):
 
         localctx = QuilParser.ClassicalBinaryContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 60, self.RULE_classicalBinary)
+        self.enterRule(localctx, 64, self.RULE_classicalBinary)
         try:
-            self.state = 346
+            self.state = 361
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.AND, QuilParser.IOR, QuilParser.XOR, QuilParser.OR]:
                 self.enterOuterAlt(localctx, 1)
-                self.state = 341
+                self.state = 356
                 self.logicalBinaryOp()
                 pass
             elif token in [QuilParser.ADD, QuilParser.SUB, QuilParser.MUL, QuilParser.DIV]:
                 self.enterOuterAlt(localctx, 2)
-                self.state = 342
+                self.state = 357
                 self.arithmeticBinaryOp()
                 pass
             elif token in [QuilParser.MOVE]:
                 self.enterOuterAlt(localctx, 3)
-                self.state = 343
+                self.state = 358
                 self.move()
                 pass
             elif token in [QuilParser.EXCHANGE]:
                 self.enterOuterAlt(localctx, 4)
-                self.state = 344
+                self.state = 359
                 self.exchange()
                 pass
             elif token in [QuilParser.CONVERT]:
                 self.enterOuterAlt(localctx, 5)
-                self.state = 345
+                self.state = 360
                 self.convert()
                 pass
             else:
@@ -2545,28 +2688,28 @@ class QuilParser ( Parser ):
     def logicalBinaryOp(self):
 
         localctx = QuilParser.LogicalBinaryOpContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 62, self.RULE_logicalBinaryOp)
+        self.enterRule(localctx, 66, self.RULE_logicalBinaryOp)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 348
+            self.state = 363
             _la = self._input.LA(1)
             if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << QuilParser.AND) | (1 << QuilParser.IOR) | (1 << QuilParser.XOR) | (1 << QuilParser.OR))) != 0)):
                 self._errHandler.recoverInline(self)
             else:
                 self._errHandler.reportMatch(self)
                 self.consume()
-            self.state = 349
+            self.state = 364
             self.addr()
-            self.state = 352
+            self.state = 367
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.IDENTIFIER, QuilParser.LBRACKET]:
-                self.state = 350
+                self.state = 365
                 self.addr()
                 pass
             elif token in [QuilParser.INT]:
-                self.state = 351
+                self.state = 366
                 self.match(QuilParser.INT)
                 pass
             else:
@@ -2626,28 +2769,28 @@ class QuilParser ( Parser ):
     def arithmeticBinaryOp(self):
 
         localctx = QuilParser.ArithmeticBinaryOpContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 64, self.RULE_arithmeticBinaryOp)
+        self.enterRule(localctx, 68, self.RULE_arithmeticBinaryOp)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 354
+            self.state = 369
             _la = self._input.LA(1)
             if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << QuilParser.ADD) | (1 << QuilParser.SUB) | (1 << QuilParser.MUL) | (1 << QuilParser.DIV))) != 0)):
                 self._errHandler.recoverInline(self)
             else:
                 self._errHandler.reportMatch(self)
                 self.consume()
-            self.state = 355
+            self.state = 370
             self.addr()
-            self.state = 358
+            self.state = 373
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.IDENTIFIER, QuilParser.LBRACKET]:
-                self.state = 356
+                self.state = 371
                 self.addr()
                 pass
             elif token in [QuilParser.PI, QuilParser.I, QuilParser.INT, QuilParser.FLOAT]:
-                self.state = 357
+                self.state = 372
                 self.number()
                 pass
             else:
@@ -2698,22 +2841,22 @@ class QuilParser ( Parser ):
     def move(self):
 
         localctx = QuilParser.MoveContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 66, self.RULE_move)
+        self.enterRule(localctx, 70, self.RULE_move)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 360
+            self.state = 375
             self.match(QuilParser.MOVE)
-            self.state = 361
+            self.state = 376
             self.addr()
-            self.state = 364
+            self.state = 379
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.IDENTIFIER, QuilParser.LBRACKET]:
-                self.state = 362
+                self.state = 377
                 self.addr()
                 pass
             elif token in [QuilParser.PI, QuilParser.I, QuilParser.INT, QuilParser.FLOAT]:
-                self.state = 363
+                self.state = 378
                 self.number()
                 pass
             else:
@@ -2760,14 +2903,14 @@ class QuilParser ( Parser ):
     def exchange(self):
 
         localctx = QuilParser.ExchangeContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 68, self.RULE_exchange)
+        self.enterRule(localctx, 72, self.RULE_exchange)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 366
+            self.state = 381
             self.match(QuilParser.EXCHANGE)
-            self.state = 367
+            self.state = 382
             self.addr()
-            self.state = 368
+            self.state = 383
             self.addr()
         except RecognitionException as re:
             localctx.exception = re
@@ -2810,14 +2953,14 @@ class QuilParser ( Parser ):
     def convert(self):
 
         localctx = QuilParser.ConvertContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 70, self.RULE_convert)
+        self.enterRule(localctx, 74, self.RULE_convert)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 370
+            self.state = 385
             self.match(QuilParser.CONVERT)
-            self.state = 371
+            self.state = 386
             self.addr()
-            self.state = 372
+            self.state = 387
             self.addr()
         except RecognitionException as re:
             localctx.exception = re
@@ -2863,16 +3006,16 @@ class QuilParser ( Parser ):
     def load(self):
 
         localctx = QuilParser.LoadContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 72, self.RULE_load)
+        self.enterRule(localctx, 76, self.RULE_load)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 374
+            self.state = 389
             self.match(QuilParser.LOAD)
-            self.state = 375
+            self.state = 390
             self.addr()
-            self.state = 376
+            self.state = 391
             self.match(QuilParser.IDENTIFIER)
-            self.state = 377
+            self.state = 392
             self.addr()
         except RecognitionException as re:
             localctx.exception = re
@@ -2922,24 +3065,24 @@ class QuilParser ( Parser ):
     def store(self):
 
         localctx = QuilParser.StoreContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 74, self.RULE_store)
+        self.enterRule(localctx, 78, self.RULE_store)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 379
+            self.state = 394
             self.match(QuilParser.STORE)
-            self.state = 380
+            self.state = 395
             self.match(QuilParser.IDENTIFIER)
-            self.state = 381
+            self.state = 396
             self.addr()
-            self.state = 384
+            self.state = 399
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.IDENTIFIER, QuilParser.LBRACKET]:
-                self.state = 382
+                self.state = 397
                 self.addr()
                 pass
             elif token in [QuilParser.PI, QuilParser.I, QuilParser.INT, QuilParser.FLOAT]:
-                self.state = 383
+                self.state = 398
                 self.number()
                 pass
             else:
@@ -3002,30 +3145,30 @@ class QuilParser ( Parser ):
     def classicalComparison(self):
 
         localctx = QuilParser.ClassicalComparisonContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 76, self.RULE_classicalComparison)
+        self.enterRule(localctx, 80, self.RULE_classicalComparison)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 386
+            self.state = 401
             _la = self._input.LA(1)
             if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << QuilParser.EQ) | (1 << QuilParser.GT) | (1 << QuilParser.GE) | (1 << QuilParser.LT) | (1 << QuilParser.LE))) != 0)):
                 self._errHandler.recoverInline(self)
             else:
                 self._errHandler.reportMatch(self)
                 self.consume()
-            self.state = 387
+            self.state = 402
             self.addr()
-            self.state = 388
+            self.state = 403
             self.addr()
-            self.state = 391
+            self.state = 406
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.IDENTIFIER, QuilParser.LBRACKET]:
-                self.state = 389
+                self.state = 404
                 self.addr()
                 pass
             elif token in [QuilParser.PI, QuilParser.I, QuilParser.INT, QuilParser.FLOAT]:
-                self.state = 390
+                self.state = 405
                 self.number()
                 pass
             else:
@@ -3065,10 +3208,10 @@ class QuilParser ( Parser ):
     def nop(self):
 
         localctx = QuilParser.NopContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 78, self.RULE_nop)
+        self.enterRule(localctx, 82, self.RULE_nop)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 393
+            self.state = 408
             self.match(QuilParser.NOP)
         except RecognitionException as re:
             localctx.exception = re
@@ -3107,12 +3250,12 @@ class QuilParser ( Parser ):
     def include(self):
 
         localctx = QuilParser.IncludeContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 80, self.RULE_include)
+        self.enterRule(localctx, 84, self.RULE_include)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 395
+            self.state = 410
             self.match(QuilParser.INCLUDE)
-            self.state = 396
+            self.state = 411
             self.match(QuilParser.STRING)
         except RecognitionException as re:
             localctx.exception = re
@@ -3161,29 +3304,29 @@ class QuilParser ( Parser ):
     def pragma(self):
 
         localctx = QuilParser.PragmaContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 82, self.RULE_pragma)
+        self.enterRule(localctx, 86, self.RULE_pragma)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 398
+            self.state = 413
             self.match(QuilParser.PRAGMA)
-            self.state = 399
+            self.state = 414
             self.match(QuilParser.IDENTIFIER)
-            self.state = 403
+            self.state = 418
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             while _la==QuilParser.IDENTIFIER or _la==QuilParser.INT:
-                self.state = 400
+                self.state = 415
                 self.pragma_name()
-                self.state = 405
+                self.state = 420
                 self._errHandler.sync(self)
                 _la = self._input.LA(1)
 
-            self.state = 407
+            self.state = 422
             self._errHandler.sync(self)
             _la = self._input.LA(1)
             if _la==QuilParser.STRING:
-                self.state = 406
+                self.state = 421
                 self.match(QuilParser.STRING)
 
 
@@ -3224,11 +3367,11 @@ class QuilParser ( Parser ):
     def pragma_name(self):
 
         localctx = QuilParser.Pragma_nameContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 84, self.RULE_pragma_name)
+        self.enterRule(localctx, 88, self.RULE_pragma_name)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 409
+            self.state = 424
             _la = self._input.LA(1)
             if not(_la==QuilParser.IDENTIFIER or _la==QuilParser.INT):
                 self._errHandler.recoverInline(self)
@@ -3468,12 +3611,12 @@ class QuilParser ( Parser ):
         _parentState = self.state
         localctx = QuilParser.ExpressionContext(self, self._ctx, _parentState)
         _prevctx = localctx
-        _startState = 86
-        self.enterRecursionRule(localctx, 86, self.RULE_expression, _p)
+        _startState = 90
+        self.enterRecursionRule(localctx, 90, self.RULE_expression, _p)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 427
+            self.state = 442
             self._errHandler.sync(self)
             token = self._input.LA(1)
             if token in [QuilParser.LPAREN]:
@@ -3481,124 +3624,124 @@ class QuilParser ( Parser ):
                 self._ctx = localctx
                 _prevctx = localctx
 
-                self.state = 412
+                self.state = 427
                 self.match(QuilParser.LPAREN)
-                self.state = 413
+                self.state = 428
                 self.expression(0)
-                self.state = 414
+                self.state = 429
                 self.match(QuilParser.RPAREN)
                 pass
             elif token in [QuilParser.PLUS, QuilParser.MINUS]:
                 localctx = QuilParser.SignedExpContext(self, localctx)
                 self._ctx = localctx
                 _prevctx = localctx
-                self.state = 416
+                self.state = 431
                 self.sign()
-                self.state = 417
+                self.state = 432
                 self.expression(8)
                 pass
             elif token in [QuilParser.SIN, QuilParser.COS, QuilParser.SQRT, QuilParser.EXP, QuilParser.CIS]:
                 localctx = QuilParser.FunctionExpContext(self, localctx)
                 self._ctx = localctx
                 _prevctx = localctx
-                self.state = 419
+                self.state = 434
                 self.function()
-                self.state = 420
+                self.state = 435
                 self.match(QuilParser.LPAREN)
-                self.state = 421
+                self.state = 436
                 self.expression(0)
-                self.state = 422
+                self.state = 437
                 self.match(QuilParser.RPAREN)
                 pass
             elif token in [QuilParser.PI, QuilParser.I, QuilParser.INT, QuilParser.FLOAT]:
                 localctx = QuilParser.NumberExpContext(self, localctx)
                 self._ctx = localctx
                 _prevctx = localctx
-                self.state = 424
+                self.state = 439
                 self.number()
                 pass
             elif token in [QuilParser.PERCENTAGE]:
                 localctx = QuilParser.VariableExpContext(self, localctx)
                 self._ctx = localctx
                 _prevctx = localctx
-                self.state = 425
+                self.state = 440
                 self.variable()
                 pass
             elif token in [QuilParser.IDENTIFIER, QuilParser.LBRACKET]:
                 localctx = QuilParser.AddrExpContext(self, localctx)
                 self._ctx = localctx
                 _prevctx = localctx
-                self.state = 426
+                self.state = 441
                 self.addr()
                 pass
             else:
                 raise NoViableAltException(self)
 
             self._ctx.stop = self._input.LT(-1)
-            self.state = 440
+            self.state = 455
             self._errHandler.sync(self)
-            _alt = self._interp.adaptivePredict(self._input,39,self._ctx)
+            _alt = self._interp.adaptivePredict(self._input,41,self._ctx)
             while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                 if _alt==1:
                     if self._parseListeners is not None:
                         self.triggerExitRuleEvent()
                     _prevctx = localctx
-                    self.state = 438
+                    self.state = 453
                     self._errHandler.sync(self)
-                    la_ = self._interp.adaptivePredict(self._input,38,self._ctx)
+                    la_ = self._interp.adaptivePredict(self._input,40,self._ctx)
                     if la_ == 1:
                         localctx = QuilParser.PowerExpContext(self, QuilParser.ExpressionContext(self, _parentctx, _parentState))
                         self.pushNewRecursionContext(localctx, _startState, self.RULE_expression)
-                        self.state = 429
+                        self.state = 444
                         if not self.precpred(self._ctx, 7):
                             from antlr4.error.Errors import FailedPredicateException
                             raise FailedPredicateException(self, "self.precpred(self._ctx, 7)")
-                        self.state = 430
+                        self.state = 445
                         self.match(QuilParser.POWER)
-                        self.state = 431
+                        self.state = 446
                         self.expression(7)
                         pass
 
                     elif la_ == 2:
                         localctx = QuilParser.MulDivExpContext(self, QuilParser.ExpressionContext(self, _parentctx, _parentState))
                         self.pushNewRecursionContext(localctx, _startState, self.RULE_expression)
-                        self.state = 432
+                        self.state = 447
                         if not self.precpred(self._ctx, 6):
                             from antlr4.error.Errors import FailedPredicateException
                             raise FailedPredicateException(self, "self.precpred(self._ctx, 6)")
-                        self.state = 433
+                        self.state = 448
                         _la = self._input.LA(1)
                         if not(_la==QuilParser.TIMES or _la==QuilParser.DIVIDE):
                             self._errHandler.recoverInline(self)
                         else:
                             self._errHandler.reportMatch(self)
                             self.consume()
-                        self.state = 434
+                        self.state = 449
                         self.expression(7)
                         pass
 
                     elif la_ == 3:
                         localctx = QuilParser.AddSubExpContext(self, QuilParser.ExpressionContext(self, _parentctx, _parentState))
                         self.pushNewRecursionContext(localctx, _startState, self.RULE_expression)
-                        self.state = 435
+                        self.state = 450
                         if not self.precpred(self._ctx, 5):
                             from antlr4.error.Errors import FailedPredicateException
                             raise FailedPredicateException(self, "self.precpred(self._ctx, 5)")
-                        self.state = 436
+                        self.state = 451
                         _la = self._input.LA(1)
                         if not(_la==QuilParser.PLUS or _la==QuilParser.MINUS):
                             self._errHandler.recoverInline(self)
                         else:
                             self._errHandler.reportMatch(self)
                             self.consume()
-                        self.state = 437
+                        self.state = 452
                         self.expression(6)
                         pass
 
              
-                self.state = 442
+                self.state = 457
                 self._errHandler.sync(self)
-                _alt = self._interp.adaptivePredict(self._input,39,self._ctx)
+                _alt = self._interp.adaptivePredict(self._input,41,self._ctx)
 
         except RecognitionException as re:
             localctx.exception = re
@@ -3646,11 +3789,11 @@ class QuilParser ( Parser ):
     def function(self):
 
         localctx = QuilParser.FunctionContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 88, self.RULE_function)
+        self.enterRule(localctx, 92, self.RULE_function)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 443
+            self.state = 458
             _la = self._input.LA(1)
             if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << QuilParser.SIN) | (1 << QuilParser.COS) | (1 << QuilParser.SQRT) | (1 << QuilParser.EXP) | (1 << QuilParser.CIS))) != 0)):
                 self._errHandler.recoverInline(self)
@@ -3694,11 +3837,11 @@ class QuilParser ( Parser ):
     def sign(self):
 
         localctx = QuilParser.SignContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 90, self.RULE_sign)
+        self.enterRule(localctx, 94, self.RULE_sign)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 445
+            self.state = 460
             _la = self._input.LA(1)
             if not(_la==QuilParser.PLUS or _la==QuilParser.MINUS):
                 self._errHandler.recoverInline(self)
@@ -3750,32 +3893,32 @@ class QuilParser ( Parser ):
     def number(self):
 
         localctx = QuilParser.NumberContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 92, self.RULE_number)
+        self.enterRule(localctx, 96, self.RULE_number)
         try:
-            self.state = 451
+            self.state = 466
             self._errHandler.sync(self)
-            la_ = self._interp.adaptivePredict(self._input,40,self._ctx)
+            la_ = self._interp.adaptivePredict(self._input,42,self._ctx)
             if la_ == 1:
                 self.enterOuterAlt(localctx, 1)
-                self.state = 447
+                self.state = 462
                 self.realN()
                 pass
 
             elif la_ == 2:
                 self.enterOuterAlt(localctx, 2)
-                self.state = 448
+                self.state = 463
                 self.imaginaryN()
                 pass
 
             elif la_ == 3:
                 self.enterOuterAlt(localctx, 3)
-                self.state = 449
+                self.state = 464
                 self.match(QuilParser.I)
                 pass
 
             elif la_ == 4:
                 self.enterOuterAlt(localctx, 4)
-                self.state = 450
+                self.state = 465
                 self.match(QuilParser.PI)
                 pass
 
@@ -3818,12 +3961,12 @@ class QuilParser ( Parser ):
     def imaginaryN(self):
 
         localctx = QuilParser.ImaginaryNContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 94, self.RULE_imaginaryN)
+        self.enterRule(localctx, 98, self.RULE_imaginaryN)
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 453
+            self.state = 468
             self.realN()
-            self.state = 454
+            self.state = 469
             self.match(QuilParser.I)
         except RecognitionException as re:
             localctx.exception = re
@@ -3862,11 +4005,11 @@ class QuilParser ( Parser ):
     def realN(self):
 
         localctx = QuilParser.RealNContext(self, self._ctx, self.state)
-        self.enterRule(localctx, 96, self.RULE_realN)
+        self.enterRule(localctx, 100, self.RULE_realN)
         self._la = 0 # Token type
         try:
             self.enterOuterAlt(localctx, 1)
-            self.state = 456
+            self.state = 471
             _la = self._input.LA(1)
             if not(_la==QuilParser.INT or _la==QuilParser.FLOAT):
                 self._errHandler.recoverInline(self)
@@ -3886,7 +4029,7 @@ class QuilParser ( Parser ):
     def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int):
         if self._predicates == None:
             self._predicates = dict()
-        self._predicates[43] = self.expression_sempred
+        self._predicates[45] = self.expression_sempred
         pred = self._predicates.get(ruleIndex, None)
         if pred is None:
             raise Exception("No predicate with index:" + str(ruleIndex))
diff --git a/pyquil/api/_benchmark.py b/pyquil/api/_benchmark.py
index 4ae0b27..e00e526 100644
--- a/pyquil/api/_benchmark.py
+++ b/pyquil/api/_benchmark.py
@@ -76,20 +76,30 @@ class BenchmarkConnection(AbstractBenchmarker):
         return pauli_out * pauli_in.coefficient
 
     @_record_call
-    def generate_rb_sequence(self, depth, gateset, seed=None):
+    def generate_rb_sequence(self, depth, gateset, seed=None, interleaver=None):
         """
         Construct a randomized benchmarking experiment on the given qubits, decomposing into
-        gateset.
+        gateset. If interleaver is not provided, the returned sequence will have the form
 
-        The JSON payload that is parsed is a list of lists of indices, or Nones. In the
-        former case, they are the index of the gate in the gateset.
+            C_1 C_2 ... C_(depth-1) C_inv ,
+
+        where each C is a Clifford element drawn from gateset, C_{< depth} are randomly selected,
+        and C_inv is selected so that the entire sequence composes to the identity.  If an
+        interleaver G (which must be a Clifford, and which will be decomposed into the native
+        gateset) is provided, then the sequence instead takes the form
+
+            C_1 G C_2 G ... C_(depth-1) G C_inv .
+
+        The JSON response is a list of lists of indices, or Nones. In the former case, they are the
+        index of the gate in the gateset.
 
         :param int depth: The number of Clifford gates to include in the randomized benchmarking
          experiment. This is different than the number of gates in the resulting experiment.
         :param list gateset: A list of pyquil gates to decompose the Clifford elements into. These
          must generate the clifford group on the qubits of interest. e.g. for one qubit
          [RZ(np.pi/2), RX(np.pi/2)].
-        :param int seed: A positive integer that seeds the random generation of the gate sequence.
+        :param seed: A positive integer used to seed the PRNG.
+        :param interleaver: A Program object that encodes a Clifford element.
         :return: A list of pyquil programs. Each pyquil program is a circuit that represents an
          element of the Clifford group. When these programs are composed, the resulting Program
          will be the randomized benchmarking experiment of the desired depth. e.g. if the return
@@ -102,10 +112,17 @@ class BenchmarkConnection(AbstractBenchmarker):
         gateset_as_program = address_qubits(sum(gateset, Program()))
         qubits = len(gateset_as_program.get_qubits())
         gateset_for_api = gateset_as_program.out().splitlines()
+        if interleaver:
+            assert(isinstance(interleaver, Program))
+            interleaver = interleaver.out()
 
         depth = int(depth)  # needs to be jsonable, no np.int64 please!
 
-        payload = RandomizedBenchmarkingRequest(depth=depth, qubits=qubits, gateset=gateset_for_api, seed=seed)
+        payload = RandomizedBenchmarkingRequest(depth=depth,
+                                                qubits=qubits,
+                                                gateset=gateset_for_api,
+                                                seed=seed,
+                                                interleaver=interleaver)
         response = self.client.call('generate_rb_sequence', payload)  # type: RandomizedBenchmarkingResponse
 
         programs = []
@@ -174,7 +191,7 @@ class LocalBenchmarkConnection(AbstractBenchmarker):
         return pauli_out * pauli_in.coefficient
 
     @staticmethod
-    def _rb_sequence_payload(depth, gateset, seed=None):
+    def _rb_sequence_payload(depth, gateset, seed=None, interleaver=None):
         """
         Prepares a JSON payload for generating a randomized benchmarking sequence.
 
@@ -194,16 +211,30 @@ class LocalBenchmarkConnection(AbstractBenchmarker):
                    "qubits": n_qubits,
                    "gateset": gateset_for_api,
                    "seed": seed}
+
+        if interleaver:
+            assert(isinstance(interleaver, Program))
+            payload["interleaver"] = interleaver.out()
+
         return payload
 
     @_record_call
-    def generate_rb_sequence(self, depth, gateset, seed=None):
+    def generate_rb_sequence(self, depth, gateset, seed=None, interleaver=None):
         """
         Construct a randomized benchmarking experiment on the given qubits, decomposing into
-        gateset.
+        gateset. If interleaver is not provided, the returned sequence will have the form
+
+            C_1 C_2 ... C_(depth-1) C_inv ,
+
+        where each C is a Clifford element drawn from gateset, C_{< depth} are randomly selected,
+        and C_inv is selected so that the entire sequence composes to the identity.  If an
+        interleaver G (which must be a Clifford, and which will be decomposed into the native
+        gateset) is provided, then the sequence instead takes the form
+
+            C_1 G C_2 G ... C_(depth-1) G C_inv .
 
-        The JSON payload that is parsed is a list of lists of indices, or Nones. In the
-        former case, they are the index of the gate in the gateset.
+        The JSON response is a list of lists of indices, or Nones. In the former case, they are the
+        index of the gate in the gateset.
 
         :param int depth: The number of Clifford gates to include in the randomized benchmarking
          experiment. This is different than the number of gates in the resulting experiment.
@@ -211,6 +242,7 @@ class LocalBenchmarkConnection(AbstractBenchmarker):
          must generate the clifford group on the qubits of interest. e.g. for one qubit
          [RZ(np.pi/2), RX(np.pi/2)].
         :param seed: A positive integer used to seed the PRNG.
+        :param interleaver: A Program object that encodes a Clifford element.
         :return: A list of pyquil programs. Each pyquil program is a circuit that represents an
          element of the Clifford group. When these programs are composed, the resulting Program
          will be the randomized benchmarking experiment of the desired depth. e.g. if the return
@@ -218,7 +250,7 @@ class LocalBenchmarkConnection(AbstractBenchmarker):
          benchmarking experiment, which will compose to the identity program.
         """
         depth = int(depth)  # needs to be jsonable, no np.int64 please!
-        payload = self._rb_sequence_payload(depth, gateset, seed=seed)
+        payload = self._rb_sequence_payload(depth, gateset, seed=seed, interleaver=interleaver)
         response = post_json(self.session, self.endpoint + "/rb", payload).json()
         programs = []
         for clifford in response:
diff --git a/pyquil/api/_error_reporting.py b/pyquil/api/_error_reporting.py
index 01f9a3c..71ee007 100644
--- a/pyquil/api/_error_reporting.py
+++ b/pyquil/api/_error_reporting.py
@@ -184,7 +184,7 @@ Rigetti Computing support by email at support@rigetti.com for assistance.
         fh.close()
 
 
-global_error_context = ErrorContext()
+global_error_context = None
 
 
 def pyquil_protect(func, log_filename="pyquil_error.log"):
@@ -195,16 +195,17 @@ def pyquil_protect(func, log_filename="pyquil_error.log"):
     def pyquil_protect_wrapper(*args, **kwargs):
         global global_error_context
 
-        old_filename = global_error_context.filename
+        old_error_context = global_error_context
+        global_error_context = ErrorContext()
         global_error_context.filename = log_filename
 
         try:
             val = func(*args, **kwargs)
-            global_error_context.filename = old_filename
+            global_error_context = old_error_context
             return val
         except Exception as e:
             global_error_context.dump_error(e, inspect.trace())
-            global_error_context.filename = old_filename
+            global_error_context = old_error_context
             raise
 
     return pyquil_protect_wrapper
@@ -222,22 +223,24 @@ def _record_call(func):
         global global_error_context
 
         # log a call as about to take place
-        key = CallLogKey(name=func.__name__,
-                         args=[serialize_object_for_logging(arg) for arg in args],
-                         kwargs={k: serialize_object_for_logging(v) for k, v in kwargs.items()})
+        if global_error_context is not None:
+            key = CallLogKey(name=func.__name__,
+                             args=[serialize_object_for_logging(arg) for arg in args],
+                             kwargs={k: serialize_object_for_logging(v) for k, v in kwargs.items()})
 
-        pre_entry = CallLogValue(timestamp_in=datetime.utcnow(),
-                                 timestamp_out=None,
-                                 return_value=None)
-        global_error_context.log[key] = pre_entry
+            pre_entry = CallLogValue(timestamp_in=datetime.utcnow(),
+                                     timestamp_out=None,
+                                     return_value=None)
+            global_error_context.log[key] = pre_entry
 
         val = func(*args, **kwargs)
 
         # poke the return value of that call in
-        post_entry = CallLogValue(timestamp_in=pre_entry.timestamp_in,
-                                  timestamp_out=datetime.utcnow(),
-                                  return_value=serialize_object_for_logging(val))
-        global_error_context.log[key] = post_entry
+        if global_error_context is not None:
+            post_entry = CallLogValue(timestamp_in=pre_entry.timestamp_in,
+                                      timestamp_out=datetime.utcnow(),
+                                      return_value=serialize_object_for_logging(val))
+            global_error_context.log[key] = post_entry
 
         return val
 
diff --git a/pyquil/api/_qac.py b/pyquil/api/_qac.py
index 6f62c4a..caa86e5 100644
--- a/pyquil/api/_qac.py
+++ b/pyquil/api/_qac.py
@@ -22,6 +22,8 @@ from pyquil.paulis import PauliTerm
 
 
 class AbstractCompiler(ABC):
+    """The abstract interface for a compiler."""
+
     def get_version_info(self) -> dict:
         """
         Return version information for this compiler and its dependencies.
@@ -66,20 +68,30 @@ class AbstractBenchmarker(ABC):
 
     @abstractmethod
     def generate_rb_sequence(self, depth: int, gateset: List[Gate],
-                             seed: int = None) -> List[Program]:
+                             seed: int = None, interleaver: Program = None) -> List[Program]:
         """
         Construct a randomized benchmarking experiment on the given qubits, decomposing into
-        gateset.
+        gateset. If interleaver is not provided, the returned sequence will have the form
+
+            C_1 C_2 ... C_(depth-1) C_inv ,
+
+        where each C is a Clifford element drawn from gateset, C_{< depth} are randomly selected,
+        and C_inv is selected so that the entire sequence composes to the identity.  If an
+        interleaver G (which must be a Clifford, and which will be decomposed into the native
+        gateset) is provided, then the sequence instead takes the form
+
+            C_1 G C_2 G ... C_(depth-1) G C_inv .
 
-        The JSON payload that is parsed is a list of lists of indices, or Nones. In the
-        former case, they are the index of the gate in the gateset.
+        The JSON response is a list of lists of indices, or Nones. In the former case, they are the
+        index of the gate in the gateset.
 
-        :param depth: The number of Clifford gates to include in the randomized benchmarking
+        :param int depth: The number of Clifford gates to include in the randomized benchmarking
          experiment. This is different than the number of gates in the resulting experiment.
-        :param gateset: A list of pyquil gates to decompose the Clifford elements into. These
+        :param list gateset: A list of pyquil gates to decompose the Clifford elements into. These
          must generate the clifford group on the qubits of interest. e.g. for one qubit
          [RZ(np.pi/2), RX(np.pi/2)].
-        :param seed: A positive integer that seeds the random generation of the gate sequence.
+        :param seed: A positive integer used to seed the PRNG.
+        :param interleaver: A Program object that encodes a Clifford element.
         :return: A list of pyquil programs. Each pyquil program is a circuit that represents an
          element of the Clifford group. When these programs are composed, the resulting Program
          will be the randomized benchmarking experiment of the desired depth. e.g. if the return
diff --git a/pyquil/api/_quantum_computer.py b/pyquil/api/_quantum_computer.py
index 55240f5..e0e691f 100644
--- a/pyquil/api/_quantum_computer.py
+++ b/pyquil/api/_quantum_computer.py
@@ -113,27 +113,55 @@ class QuantumComputer:
         self.symmetrize_readout = symmetrize_readout
 
     def qubits(self) -> List[int]:
+        """
+        Return a sorted list of this QuantumComputer's device's qubits
+
+        See :py:func:`AbstractDevice.qubits` for more.
+        """
         return self.device.qubits()
 
     def qubit_topology(self) -> nx.graph:
+        """
+        Return a NetworkX graph representation of this QuantumComputer's device's qubit
+        connectivity.
+
+        See :py:func:`AbstractDevice.qubit_topology` for more.
+        """
         return self.device.qubit_topology()
 
     def get_isa(self, oneq_type: str = 'Xhalves',
                 twoq_type: str = 'CZ') -> ISA:
+        """
+        Return a target ISA for this QuantumComputer's device.
+
+        See :py:func:`AbstractDevice.get_isa` for more.
+
+        :param oneq_type: The family of one-qubit gates to target
+        :param twoq_type: The family of two-qubit gates to target
+        """
         return self.device.get_isa(oneq_type=oneq_type, twoq_type=twoq_type)
 
     @_record_call
-    def run(self, executable: Executable) -> np.ndarray:
+    def run(self, executable: Executable,
+            memory_map: Dict[str, List[Union[int, float]]] = None) -> np.ndarray:
         """
-        Run a quil executable.
+        Run a quil executable. If the executable contains declared parameters, then a memory
+        map must be provided, which defines the runtime values of these parameters.
 
         :param executable: The program to run. You are responsible for compiling this first.
-        :return: A numpy array of shape (trials, len(ro-register)) that contains 0s and 1s
+        :param memory_map: The mapping of declared parameters to their values. The values
+            are a list of floats or integers.
+        :return: A numpy array of shape (trials, len(ro-register)) that contains 0s and 1s.
         """
-        return self.qam.load(executable) \
-            .run() \
+        self.qam.load(executable)
+        if memory_map:
+            for region_name, values_list in memory_map.items():
+                for offset, value in enumerate(values_list):
+                    # TODO gh-658: have write_memory take a list rather than value + offset
+                    self.qam.write_memory(region_name=region_name, offset=offset, value=value)
+        return self.qam.run() \
             .wait() \
-            .read_memory(region_name="ro")
+            .read_memory(region_name='ro')
 
     @_record_call
     def run_symmetrized_readout(self, program: Program, trials: int) -> np.ndarray:
@@ -184,7 +212,7 @@ class QuantumComputer:
         into a 2d numpy array of bitstrings, consider::
 
             bitstrings = qc.run_and_measure(...)
-            bitstring_array = np.vstack(bitstrings[q] for q in sorted(qc.qubits())).T
+            bitstring_array = np.vstack(bitstrings[q] for q in qc.qubits()).T
             bitstring_array.shape  # (trials, len(qc.qubits()))
 
         .. note::
@@ -216,6 +244,20 @@ class QuantumComputer:
     def compile(self, program: Program,
                 to_native_gates: bool = True,
                 optimize: bool = True) -> Message:
+        """
+        A high-level interface to program compilation.
+
+        Compilation currently consists of two stages. Please see the :py:class:`AbstractCompiler`
+        docs for more information. This function does all stages of compilation.
+
+        Right now both ``to_native_gates`` and ``optimize`` must be either both set or both
+        unset. More modular compilation passes may be available in the future.
+
+        :param program: A Program
+        :param to_native_gates: Whether to compile non-native gates to native gates.
+        :param optimize: Whether to optimize programs to reduce the number of operations.
+        :return: An executable binary suitable for passing to :py:func:`QuantumComputer.run`.
+        """
         flags = [to_native_gates, optimize]
         assert all(flags) or all(not f for f in flags), "Must turn quilc all on or all off"
         quilc = all(flags)
@@ -438,7 +480,7 @@ def get_qc(name: str, *, as_qvm: bool = None, noisy: bool = None,
         the default values for URL endpoints, ping time, and status time will be used. Your
         user id and API key will be read from ~/.pyquil_config. If you deign to change any
         of these parameters, pass your own :py:class:`ForestConnection` object.
-    :return:
+    :return: A pre-configured QuantumComputer
     """
     if connection is None:
         connection = ForestConnection()
diff --git a/pyquil/quil.py b/pyquil/quil.py
index 76a8d58..20ac84e 100644
--- a/pyquil/quil.py
+++ b/pyquil/quil.py
@@ -40,6 +40,14 @@ from pyquil.quilbase import (DefGate, Gate, Measurement, Pragma, AbstractInstruc
 
 
 class Program(object):
+    """A list of pyQuil instructions that comprise a quantum program.
+
+    >>> from pyquil import Program
+    >>> from pyquil.gates import *
+    >>> p = Program()
+    >>> p += H(0)
+    >>> p += CNOT(0, 1)
+    """
     def __init__(self, *instructions):
         self._defined_gates = []
         # Implementation note: the key difference between the private _instructions and
@@ -61,7 +69,7 @@ class Program(object):
         # default number of shots to loop through
         self.num_shots = 1
 
-        # Note to developers: Have you changed this method? Have you change the fields which
+        # Note to developers: Have you changed this method? Have you changed the fields which
         # live on `Program`? Please update `Program.copy()`!
 
     def copy(self):
@@ -351,7 +359,7 @@ class Program(object):
         label_start = LabelPlaceholder("START")
         label_end = LabelPlaceholder("END")
         self.inst(JumpTarget(label_start))
-        self.inst(JumpUnless(target=label_end, condition=Addr(classical_reg)))
+        self.inst(JumpUnless(target=label_end, condition=classical_reg))
         self.inst(q_program)
         self.inst(Jump(label_start))
         self.inst(JumpTarget(label_end))
@@ -500,7 +508,7 @@ class Program(object):
 
     def is_protoquil(self):
         """
-        Protoquil programs may only contain gates, Pragmas, and final global RESETs. It may not
+        Protoquil programs may only contain gates, Pragmas, and an initial global RESET. It may not
         contain classical instructions or jumps.
 
         :return: True if the Program is Protoquil, False otherwise
@@ -632,7 +640,7 @@ class Program(object):
         return not self.__eq__(other)
 
     def __len__(self):
-        return len(self._instructions)
+        return len(self.instructions)
 
     def __str__(self):
         """
diff --git a/pyquil/quilbase.py b/pyquil/quilbase.py
index 45fda3f..f099cfb 100644
--- a/pyquil/quilbase.py
+++ b/pyquil/quilbase.py
@@ -304,6 +304,7 @@ class JumpConditional(AbstractInstruction):
     """
     Abstract representation of an conditional jump instruction.
     """
+    op = NotImplemented
 
     def __init__(self, target, condition):
         if not isinstance(target, (Label, LabelPlaceholder)):
@@ -400,6 +401,7 @@ class LogicalBinaryOp(AbstractInstruction):
     """
     The abstract class for binary logical classical instructions.
     """
+    op = NotImplemented
 
     def __init__(self, left, right):
         if not isinstance(left, MemoryReference):
diff --git a/requirements.txt b/requirements.txt
index aa03603..e7f0381 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -19,3 +19,4 @@ tox
 # docs
 sphinx
 sphinx_rtd_theme
+sphinx_autodoc_typehints


Test patch:
diff --git a/pyquil/tests/test_parser.py b/pyquil/tests/test_parser.py
index a37adaa..f3d2ccf 100644
--- a/pyquil/tests/test_parser.py
+++ b/pyquil/tests/test_parser.py
@@ -212,8 +212,14 @@ def test_def_circuit():
 DEFCIRCUIT bell a b:
     H a
     CNOT a b
+""".strip()
+    defcircuit_no_qubits = """
+DEFCIRCUIT bell:
+    H 0
+    CNOT 0 1
 """.strip()
     parse_equals(defcircuit, RawInstr(defcircuit))
+    parse_equals(defcircuit_no_qubits, RawInstr(defcircuit_no_qubits))
 
 
 def test_parse_reset_qubit():
@@ -226,3 +232,34 @@ RESET
 RESET 5
     """.strip()
     parse_equals(reset_qubit, ResetQubit(Qubit(5)))
+
+
+def test_defcircuit_measure_qubit():
+    defcircuit_measure_named_qubits = """
+DEFCIRCUIT test_defcirc_measure_named a b:
+    MEASURE a b
+""".strip()
+    defcircuit_measure_qubits = """
+DEFCIRCUIT test_defcirc_measure_qubits:
+    MEASURE 0 ro
+""".strip()
+    defcircuit_measure_qubits_mixed = """
+DEFCIRCUIT test_defcirc_measure_mixed q:
+    MEASURE q ro
+""".strip()
+    parse_equals(defcircuit_measure_named_qubits, RawInstr(defcircuit_measure_named_qubits))
+    parse_equals(defcircuit_measure_qubits, RawInstr(defcircuit_measure_qubits))
+    parse_equals(defcircuit_measure_qubits_mixed, RawInstr(defcircuit_measure_qubits_mixed))
+
+
+def test_defcircuit_reset_named_qubit():
+    defcircuit_reset_named_qubit = """
+DEFCIRCUIT test_defcirc_reset_named_qubit a:
+    RESET a
+""".strip()
+    defcircuit_reset_qubit = """
+DEFCIRCUIT test_defcirc_reset_qubit:
+    RESET 1
+""".strip()
+    parse_equals(defcircuit_reset_named_qubit, RawInstr(defcircuit_reset_named_qubit))
+    parse_equals(defcircuit_reset_qubit, RawInstr(defcircuit_reset_qubit))
diff --git a/pyquil/tests/test_quantum_computer.py b/pyquil/tests/test_quantum_computer.py
index a97b1b3..fcab654 100644
--- a/pyquil/tests/test_quantum_computer.py
+++ b/pyquil/tests/test_quantum_computer.py
@@ -10,6 +10,7 @@ from pyquil.api._qac import AbstractCompiler
 from pyquil.api._quantum_computer import _get_flipped_protoquil_program, _parse_name
 from pyquil.device import NxDevice, gates_in_isa
 from pyquil.gates import *
+from pyquil.quilbase import Declare, MemoryReference
 from pyquil.noise import decoherence_noise_with_asymmetric_ro
 from rpcq.messages import PyQuilExecutableResponse
 
@@ -284,9 +285,11 @@ def test_run_and_measure(local_qvm_quilc):
     qc = get_qc("9q-generic-qvm")
     prog = Program(I(8))
     trials = 11
-    with local_qvm():   # Redundant with test fixture.
+    # note to devs: this is included as an example in the run_and_measure docstrings
+    # so if you change it here ... change it there!
+    with local_qvm():  # Redundant with test fixture.
         bitstrings = qc.run_and_measure(prog, trials)
-    bitstring_array = np.vstack(bitstrings[q] for q in sorted(qc.qubits())).T
+    bitstring_array = np.vstack(bitstrings[q] for q in qc.qubits()).T
     assert bitstring_array.shape == (trials, len(qc.qubits()))
 
 
@@ -319,3 +322,25 @@ def test_qvm_compile_pickiness(forest):
 
     # Yot ok
     qc.run(nq)
+
+
+def test_run_with_parameters(forest):
+    device = NxDevice(nx.complete_graph(3))
+    qc = QuantumComputer(
+        name='testy!',
+        qam=QVM(connection=forest),
+        device=device,
+        compiler=DummyCompiler()
+    )
+    bitstrings = qc.run(
+        executable=Program(
+            Declare(name='theta', memory_type='REAL'),
+            Declare(name='ro', memory_type='BIT'),
+            RX(MemoryReference('theta'), 0),
+            MEASURE(0, MemoryReference('ro'))
+        ).wrap_in_numshots_loop(1000),
+        memory_map={'theta': [np.pi]}
+    )
+
+    assert bitstrings.shape == (1000, 1)
+    assert all([bit == 1 for bit in bitstrings])
diff --git a/pyquil/tests/test_quil.py b/pyquil/tests/test_quil.py
index 53017fe..145d869 100644
--- a/pyquil/tests/test_quil.py
+++ b/pyquil/tests/test_quil.py
@@ -115,7 +115,7 @@ def test_len_nested():
     p = Program(H(0)).measure(0, 0)
     q = Program(H(0), CNOT(0, 1))
     p.if_then(MemoryReference("ro", 0), q)
-    assert len(p) == 8
+    assert len(p) == 9
 
 
 def test_plus_operator():
@@ -456,22 +456,28 @@ def test_define_qft():
 
 
 def test_control_flows():
-    classical_flag_register = 2
-    p = Program(X(0), H(0)).measure(0, classical_flag_register)
-
-    # run p in a loop until classical_flag_register is 0
-    loop_prog = Program(X(0)).measure(0, classical_flag_register)
-    loop_prog.while_do(classical_flag_register, p)
-    assert loop_prog.out() == ('DECLARE ro BIT[3]\n'
-                               'X 0\n'
-                               'MEASURE 0 ro[2]\n'
-                               'LABEL @START1\n'
-                               'JUMP-UNLESS @END2 ro[2]\n'
-                               'X 0\n'
-                               'H 0\n'
-                               'MEASURE 0 ro[2]\n'
-                               'JUMP @START1\n'
-                               'LABEL @END2\n')
+    outer_loop = Program()
+    classical_flag_register = outer_loop.declare('classical_flag_register', 'BIT')
+    outer_loop += MOVE(classical_flag_register, 1)  # initialize
+
+    inner_loop = Program()
+    inner_loop += Program(X(0), H(0))
+    inner_loop += MEASURE(0, classical_flag_register)
+
+    # run inner_loop in a loop until classical_flag_register is 0
+    outer_loop.while_do(classical_flag_register, inner_loop)
+    assert outer_loop.out() == '\n'.join([
+        "DECLARE classical_flag_register BIT[1]",
+        "MOVE classical_flag_register 1",
+        "LABEL @START1",
+        "JUMP-UNLESS @END2 classical_flag_register",
+        "X 0",
+        "H 0",
+        "MEASURE 0 classical_flag_register",
+        "JUMP @START1",
+        "LABEL @END2",
+        ""
+    ])
 
 
 def test_control_flows_2():