Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""
Helper function for typechecking / type-coercing arguments to constructors for ternary
classical operators.
:param classical_reg1: Specifier for the classical memory address to be modified.
:param classical_reg2: Specifier for the left operand: a classical memory address.
:param classical_reg3: Specifier for the right operand: a classical memory address or an
immediate value.
:return: A triple of pyQuil objects suitable for use as operands.
"""
if isinstance(classical_reg1, int):
raise TypeError("Target operand of comparison must be a memory address")
classical_reg1 = unpack_classical_reg(classical_reg1)
if isinstance(classical_reg2, int):
raise TypeError("Left operand of comparison must be a memory address")
classical_reg2 = unpack_classical_reg(classical_reg2)
if not isinstance(classical_reg3, (float, int)):
classical_reg3 = unpack_classical_reg(classical_reg3)
return classical_reg1, classical_reg2, classical_reg3
def unpack_reg_val_pair(
classical_reg1: MemoryReferenceDesignator,
classical_reg2: Union[MemoryReferenceDesignator, int, float],
) -> Tuple[MemoryReference, Union[MemoryReference, int, float]]:
"""
Helper function for typechecking / type-coercing arguments to constructors for binary classical
operators.
:param classical_reg1: Specifier for the classical memory address to be modified.
:param classical_reg2: Specifier for the second argument: a classical memory address or an
immediate value.
:return: A pair of pyQuil objects suitable for use as operands.
"""
left = unpack_classical_reg(classical_reg1)
if isinstance(classical_reg2, (float, int)):
return left, classical_reg2
return left, unpack_classical_reg(classical_reg2)
classical operators.
:param classical_reg1: Specifier for the classical memory address to be modified.
:param classical_reg2: Specifier for the left operand: a classical memory address.
:param classical_reg3: Specifier for the right operand: a classical memory address or an
immediate value.
:return: A triple of pyQuil objects suitable for use as operands.
"""
if isinstance(classical_reg1, int):
raise TypeError("Target operand of comparison must be a memory address")
classical_reg1 = unpack_classical_reg(classical_reg1)
if isinstance(classical_reg2, int):
raise TypeError("Left operand of comparison must be a memory address")
classical_reg2 = unpack_classical_reg(classical_reg2)
if not isinstance(classical_reg3, (float, int)):
classical_reg3 = unpack_classical_reg(classical_reg3)
return classical_reg1, classical_reg2, classical_reg3
instr...
=>
LABEL @START
JUMP-UNLESS @END [c]
instr...
JUMP @START
LABEL @END
:param MemoryReferenceDesignator 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.
"""
label_start = LabelPlaceholder("START")
label_end = LabelPlaceholder("END")
self.inst(JumpTarget(label_start))
self.inst(JumpUnless(target=label_end, condition=unpack_classical_reg(classical_reg)))
self.inst(q_program)
self.inst(Jump(label_start))
self.inst(JumpTarget(label_end))
return self
JUMP @END
LABEL @THEN
instrA...
LABEL @END
:param classical_reg: The classical register to check as the condition
:param if_program: A Quil program to execute if classical_reg is 1
:param 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.
"""
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=unpack_classical_reg(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 LOAD(
target_reg: MemoryReferenceDesignator, region_name: str, offset_reg: MemoryReferenceDesignator
) -> ClassicalLoad:
"""
Produce a LOAD instruction.
:param target_reg: LOAD storage target.
:param region_name: Named region of memory to load from.
:param offset_reg: Offset into region of memory to load from. Must be a MemoryReference.
:return: A ClassicalLoad instance.
"""
return ClassicalLoad(
unpack_classical_reg(target_reg), region_name, unpack_classical_reg(offset_reg)
)
def EXCHANGE(
classical_reg1: MemoryReferenceDesignator, classical_reg2: MemoryReferenceDesignator
) -> ClassicalExchange:
"""
Produce an EXCHANGE instruction.
:param classical_reg1: The first classical register, which gets modified.
:param classical_reg2: The second classical register, which gets modified.
:return: A ClassicalExchange instance.
"""
left = unpack_classical_reg(classical_reg1)
right = unpack_classical_reg(classical_reg2)
return ClassicalExchange(left, right)
classical_reg2: MemoryReferenceDesignator,
classical_reg3: Union[MemoryReferenceDesignator, int, float],
) -> Tuple[MemoryReference, MemoryReference, Union[MemoryReference, int, float]]:
"""
Helper function for typechecking / type-coercing arguments to constructors for ternary
classical operators.
:param classical_reg1: Specifier for the classical memory address to be modified.
:param classical_reg2: Specifier for the left operand: a classical memory address.
:param classical_reg3: Specifier for the right operand: a classical memory address or an
immediate value.
:return: A triple of pyQuil objects suitable for use as operands.
"""
if isinstance(classical_reg1, int):
raise TypeError("Target operand of comparison must be a memory address")
classical_reg1 = unpack_classical_reg(classical_reg1)
if isinstance(classical_reg2, int):
raise TypeError("Left operand of comparison must be a memory address")
classical_reg2 = unpack_classical_reg(classical_reg2)
if not isinstance(classical_reg3, (float, int)):
classical_reg3 = unpack_classical_reg(classical_reg3)
return classical_reg1, classical_reg2, classical_reg3