def test_binary_classicals(): p = Program() p.inst(AND(0, 1), OR(Addr(0), Addr(1)), MOVE(0, 1), EXCHANGE(0, Addr(1))) assert p.out() == 'AND [0] [1]\n' \ 'OR [0] [1]\n' \ 'MOVE [0] [1]\n' \ 'EXCHANGE [0] [1]\n'
def while_do(self, classical_reg, q_program): """ While a classical register at index classical_reg is 1, loop q_program Equivalent to the following construction: .. code:: WHILE [c]: instr... => LABEL @START JUMP-UNLESS @END [c] instr... JUMP @START LABEL @END :param int classical_reg: The classical register to check :param Program q_program: The Quil program to loop. :return: The Quil Program with the loop instructions added. :rtype: Program """ 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(q_program) self.inst(Jump(label_start)) self.inst(JumpTarget(label_end)) return self
def unpack_classical_reg(c): """ Get the address for a classical register. :param c: A list of length 1 or an int or an Addr. :return: The address as an Addr. """ if not isinstance(c, (int, list, Addr)): raise TypeError("c should be an int or list or Addr") if isinstance(c, list) and (len(c) != 1 or not isinstance(c[0], int)): raise ValueError("if c is a list, it should be of 1 int") if isinstance(c, Addr): return c elif isinstance(c, list): return Addr(c[0]) else: return Addr(c)
def test_unary_classicals(): p = Program() p.inst(TRUE(0), FALSE(Addr(1)), NOT(2)) assert p.out() == 'TRUE [0]\n' \ 'FALSE [1]\n' \ 'NOT [2]\n'
def while_do(self, classical_reg, q_program): """ While a classical register at index classical_reg is 1, loop q_program :param int classical_reg: The classical register to check :param Program q_program: The Quil program to loop. :return: The Quil Program with the loop instructions added. :rtype: Program """ w_loop = While(Addr(classical_reg)) w_loop.Body.inst(q_program) return self.inst(w_loop)
def if_then(self, classical_reg, if_program, else_program=None): """ If the classical register at index classical reg is 1, run if_program, else run else_program. :param int classical_reg: The classical register to check as the condition :param Program if_program: A Quil program to execute if classical_reg is 1 :param Program else_program: A Quil program to execute if classical_reg is 0. This argument is optional and defaults to an empty Program. :returns: The Quil Program with the branching instructions added. :rtype: Program """ else_program = else_program if else_program is not None else Program() branch = If(Addr(classical_reg)) branch.Then.inst(if_program) branch.Else.inst(else_program) return self.inst(branch)
def if_then(self, classical_reg, if_program, else_program=None): """ If the classical register at index classical reg is 1, run if_program, else run else_program. Equivalent to the following construction: .. code:: IF [c]: instrA... ELSE: instrB... => JUMP-WHEN @THEN [c] instrB... JUMP @END LABEL @THEN instrA... LABEL @END :param int classical_reg: The classical register to check as the condition :param Program if_program: A Quil program to execute if classical_reg is 1 :param Program else_program: A Quil program to execute if classical_reg is 0. This argument is optional and defaults to an empty Program. :returns: The Quil Program with the branching instructions added. :rtype: Program """ else_program = else_program if else_program is not None else Program() label_then = LabelPlaceholder("THEN") label_end = LabelPlaceholder("END") self.inst(JumpWhen(target=label_then, condition=Addr(classical_reg))) self.inst(else_program) self.inst(Jump(label_end)) self.inst(JumpTarget(label_then)) self.inst(if_program) self.inst(JumpTarget(label_end)) return self
def test_measurement_calls(): p = Program() p.inst(MEASURE(0, 1), MEASURE(0, Addr(1))) assert p.out() == 'MEASURE 0 [1]\n' * 2
def _addr(classical): # type: (QuilParser.AddrContext) -> Addr return Addr(int(classical.classicalBit().getText()))