Compiles and runs a program. The optional program argument
        supplies the initial state and memory. Else qubits and classical
        bits start from zero states.

def run(self, ket: State = None) -> State:
        """Compiles and runs a program. The optional program argument
        supplies the initial state and memory. Else qubits and classical
        bits start from zero states.
        """
        if ket is None:
            qubits = self.qubits
            ket = zero_state(qubits)

        ket = self._initilize(ket)

        pc = 0
        while pc >= 0 and pc < len(self):
            instr = self.instructions[pc]
            ket = ket.update({PC: pc + 1})
            ket = instr.run(ket)
            pc = ket.memory[PC]

        return ket