Quantum Variables
A model operates on quantum objects, by modifying their states using different kinds of operations. Quantum objects represent values that are stored on one or more qubits. The simplest quantum object is a single qubit, representing the values 0 or 1 when measured. Other types of quantum objects are stored on multiple qubits and represent numeric values or arrays of qubits. Quantum objects are managed in Qmod using quantum variables. Variables are introduced into the scope of a quantum function through the declaration of arguments or the declaration of local variables. A quantum variable establishes its reference to some object by explicitly initializing it. This is often done by passing it as the output argument of a function, such asallocate().
Once initialized, the state of the object it references can be modified, but the variable’s
reference itself is immutable.
- Python
- Native
A quantum variable is declared as a function argument using a Python class as a
type hint. The same Python class is instantiated to declare a local variable,
in which case the name of the variable is optionally specified as a constructor
argument and otherwise inferred automatically.
Managing Quantum Variables
Here are the rules for managing quantum variables:- Local variables and output-only arguments (arguments declared with the
outputmodifier) are uninitialized upon declaration. - Quantum arguments declared without a modifier or with the
inputmodifier are guaranteed to be initialized. - A variable is initialized in one of the following ways:
- It is passed as the output-only argument of a function
- It is used as the left-value of an assignment
- It occurs on the right side of a
->(bind) statement
- Once initialized, a variable can be used as an argument in any number of quantum
function calls, as long as it is not an output only or input-only argument (an argument
declared with the
outputorinputmodifier). - An initialized variable returns to its uninitialized state in one of the following ways:
- It is passed as the input-only argument of a function
- It occurs on the left side of a
->(bind) statement
a must be initialized prior to applying X()
on it, since it is declared as an output-only argument of function main. Similarly, the local
variable b is uninitialized upon declaration, and subsequently initialized through
the call to prepare_state, to which it is passed as an output-only argument.
- Python
- Native
Allocate
The allocate statement is used to initialize quantum variables, allocating a sequence of qubits to store the new quantum object. The number of qubits allocated, and the numeric type attributes in the case of a numeric variable, are either explicitly specified, or derived from the variable’s type.Syntax
- Python
- Native
SIGNED and UNSIGNED built-in constants instead
of True and False respectively when specifying the sign-bool-expr.
Semantics
- Prior to an allocate statement var must be uninitialized, and subsequently it becomes initialized.
- The size-int-expr, if specified, must agree with the declared size of the variable. If the variable declaration does not determine the size, the type of the variable is inferred to accommodate the specified size. See more under Quantum Types.
- For variables of type
qnum, sign-bool-expr and frac-digits-int-expr, if specified, must agree with the quantum type of the variable. Here too, if the variable declaration does not determine these numeric properties, they are inferred per the specified values.
Example
The following example demonstrates three uses ofallocate on two local variables and one
output parameter of main. Note how the overall size of the quantum object is used in
the inference of its type.
- Python
- Native
Free
The free statement is used to declare that a quantum variable is back to its initial state, and no longer used. Subsequently, the variable becomes uninitialized and its qubits can are reclaimed by the compiler for subsequent use.Syntax
- Python
- Native
Semantics
- Prior to a free statement var must be initialized, and subsequently it becomes uninitialized.
- The quantum object referenced by var must be in the state when it is freed. This property is not enforced by the compiler.
- Local variables that are explicitly freed are not considered uncomputation candidates, and are not restricted to permutable use contexts. See more under Uncomputation.
Example
Explicitly freeing a variable is typically not needed and is only used for specific purposes. The following example demonstrates the use offree in a phase-kickback pattern. It is
used to release an auxiliary qubit that is known to be returned to state , despite
having applied the Hadamard gate to it.
- Python
- Native
free, is to encapsulate the calls to H in a function
with an as unchecked const parameter.
Drop
The drop statement is used to declare that a quantum variable is no longer used and should be exluded from any future uncomputation. Subsequently, the variable becomes uninitialized, while its qubits retain their current state — which may be dirty and entangled with functional qubits — and cannot be reused.Syntax
- Python
- Native
Semantics
- Prior to a drop statement var must be initialized, and subsequently it becomes uninitialized.
- Local variables that are explicitly dropped are not considered uncomputation candidates, and are not restricted to permutable use contexts. See more under Uncomputation.
Example
Explicitly dropping a variable is typically not needed and is only used for specific purposes. The following example demonstrates the use ofdrop in a swap test algorithm,
where the two quantum states cannot be uncomputed, yet we do not wish to measure
them.
- Python
- Native
Concatenation Operator
The concatenation operator is used to combine a sequence of quantum objects (or their parts) into a quantum array.- Python
- Native
A concatenation is a Python list containing quantum objects.[ path-expressions ]path-expressions is a comma-separated sequence of one or more quantum
path expressions.
hadamard_transform to a specific set of qubits drawn from two quantum
variables:
- Python
- Native
v1 and v2 and
a qubit v3.
The model uses a concatenation operator to create a quantum array and apply
hadamard_transform to it.
The quantum array comprises the last bit of v1, the entirety of v3, the
middle two qubits of v2, and the first qubit of v1.