Execute a program on the QVM.

        Note that the QAM is stateful. Subsequent calls to :py:func:`execute` will not
        automatically reset the wavefunction or the classical RAM. If this is desired,
        consider starting your program with ``RESET``.

        :return: ``self`` to support method chaining.

def execute(self, program: Program):
        """
        Execute a program on the QVM.

        Note that the QAM is stateful. Subsequent calls to :py:func:`execute` will not
        automatically reset the wavefunction or the classical RAM. If this is desired,
        consider starting your program with ``RESET``.

        :return: ``self`` to support method chaining.
        """
        # TODO: why are DEFGATEs not just included in the list of instructions?
        for dg in program.defined_gates:
            if dg.parameters is not None:
                raise NotImplementedError("PyQVM does not support parameterized DEFGATEs")
            self.defined_gates[dg.name] = dg.matrix

        # initialize program counter
        self.program = program
        self.program_counter = 0

        halted = len(program) == 0
        while not halted:
            halted = self.transition()

        return self