|
| 1 | +--- |
| 2 | +search: |
| 3 | + boost: 1.0 |
| 4 | +--- |
| 5 | + |
| 6 | +# Expressions |
| 7 | + |
| 8 | +Expressions in Qmod have syntax, semantics, and use, similar to expressions in |
| 9 | +conventional programming languages. |
| 10 | +They comprise literal values, variables, and operators applied to them. |
| 11 | +However, Qmod is unique in that variables can be of either [classical](https://docs.classiq.io/latest/qmod-reference/api-reference/classical-types) or |
| 12 | +[quantum](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-types) types, and quantum variables have states that can be a |
| 13 | +superposition of values, entangled with the states of other variables. |
| 14 | +Expressions over quantum variables evaluate to a superposition of correlated |
| 15 | +values. |
| 16 | +For example, if `x` is a [classical variable](https://docs.classiq.io/latest/qmod-reference/language-reference/classical-variables) |
| 17 | +of type `CInt` (an integer), then `x + 1` is a classical expression of type |
| 18 | +`CInt` comprising the operator `+` (plus) applied to `x` and the literal `1`. |
| 19 | +Similarly, if `qarr` is a [quantum variable](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-variables) |
| 20 | +of type `QArray[QNum[3]]`, then `qarr[0] > x` is a quantum expression of type |
| 21 | +`QBit`. |
| 22 | + |
| 23 | +_Unary operators_ are applied to a single operand. For instance, you can apply |
| 24 | +the unary operator `~` (bitwise-invert) to variable `x` and get the expression |
| 25 | +`~x`. |
| 26 | +_Binary operators_ are applied to two operands. For example, the operator `>` |
| 27 | +(greater-than) in the expression `qarr[0] > x` is applied to two operands, |
| 28 | +`qarr[0]` and variable `x`. |
| 29 | +The expression `qarr[0]` comprises the _subscript operator_ `[]` applied to |
| 30 | +variable `qarr` and the literal `0`. |
| 31 | +Applications of subscript (`[]`) and field-access (`.`) operators to classical |
| 32 | +and quantum variables are called _path expressions_, since they point to a |
| 33 | +partial section of the variable along a certain access path. |
| 34 | +In our case, for instance, `qarr[0]` represents the first (0) element of the |
| 35 | +array `qarr`. |
| 36 | + |
| 37 | +## Qmod Operators |
| 38 | + |
| 39 | +You can apply operators to operand expressions to create composite expressions. |
| 40 | +If at least one of the operands is quantum then the expression is quantum as |
| 41 | +well; Otherwise, it is classical. |
| 42 | + |
| 43 | +Qmod supports the following operators: |
| 44 | + |
| 45 | +### Arithmetic operators |
| 46 | + |
| 47 | +You can apply arithmetic operators to classical numbers (`CInt` and `CReal`) and |
| 48 | +quantum scalars (`QBit` and `QNum`) to create numeric expressions. |
| 49 | + |
| 50 | +- Add: + |
| 51 | +- Subtract: - (binary) |
| 52 | +- Negate: - (unary) |
| 53 | +- Multiply: \* |
| 54 | +- Power \*\* (quantum base, positive classical integer exponent) |
| 55 | +- Modulo: % limited for power of 2 |
| 56 | +- Max: max (n>=2 arguments) |
| 57 | +- Min: min (n>=2 arguments) |
| 58 | + |
| 59 | +### Bitwise operators |
| 60 | + |
| 61 | +You can apply bitwise operators to classical numbers (`CInt` and `CReal`) and |
| 62 | +quantum scalars (`QBit` and `QNum`) to create numeric expressions. |
| 63 | + |
| 64 | +- Bitwise Or: | |
| 65 | +- Bitwise And: & |
| 66 | +- Bitwise Xor: ^ |
| 67 | +- Bitwise Invert: ~ |
| 68 | + |
| 69 | +### Relational operators |
| 70 | + |
| 71 | +You can apply relational operators to classical numbers (`CInt` and `CReal`) and |
| 72 | +quantum scalars (`QBit` and `QNum`) to create Boolean expressions (of types |
| 73 | +`CBool` and `QBit`). |
| 74 | + |
| 75 | +- Equal: == |
| 76 | +- Not Equal: != |
| 77 | +- Greater Than: > |
| 78 | +- Greater Or Equal: >= |
| 79 | +- Less Than: < |
| 80 | +- Less Or Equal: <= |
| 81 | + |
| 82 | +### Logic operators |
| 83 | + |
| 84 | +You can apply logical operators to Boolean expressions (`CBool`, `QBit`, and |
| 85 | +`QNum[1]`) to create Boolean expressions (of types `CBool` and `QBit`). |
| 86 | + |
| 87 | +- Logical And: `logical_and()` (in Qmod Native: and) |
| 88 | +- Logical Or: `logical_or()` (in Qmod Native: or) |
| 89 | +- Logical Not: `logical_not()` (in Qmod Native: not) |
| 90 | + |
| 91 | +### Path operators |
| 92 | + |
| 93 | +You can use path operators to access parts of classical and quantum variables of |
| 94 | +aggregate types, namely, structs and arrays. |
| 95 | + |
| 96 | +- Field Access: _struct_ **.** _field-name_ |
| 97 | +- Array Slice: _array_ **[** _start-index_ **:** _stop-index_ **]** |
| 98 | + - In Python, _start-index_ and _stop-index_ may be omitted. |
| 99 | + If _start-index_ is omitted, a `0` will be placed in its stead. |
| 100 | + If _stop-index_ is omitted, `array.len` will be placed in its stead. |
| 101 | +- Array Subscript: _array_ **[** _index_ **]** |
| 102 | + - The index of a quantum subscript expression must be an [unsigned quantum integer](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-types/#quantum-scalar-types) variable. |
| 103 | + - In Python, if _array_ is a Python list and _index_ is a quantum variable, use the alternative syntax: **subscript(** _array_ **,** _index_ **)** |
| 104 | + - Currently, quantum subscript expressions are not supported in [phase statements](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/phase/). |
| 105 | + |
| 106 | +## Quantum Expressions |
| 107 | + |
| 108 | +Quantum expressions are expressions that involve one or more quantum variables. |
| 109 | +Quantum expressions can occur in the following contexts: |
| 110 | + |
| 111 | +- The right-value in [assignment](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/assignment) statements |
| 112 | +- The condition in [control](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/control) statements |
| 113 | +- The expression argument in [phase](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/phase) statements |
| 114 | + |
| 115 | +During computation, the value(s) of an expression are coherently correlated to |
| 116 | +the evaluation of the operators over the computational-basis values of the |
| 117 | +quantum variables it comprises, which may be in any specific superpositions and |
| 118 | +entanglement. |
| 119 | +Quantum expressions may include any combination of operators on any |
| 120 | +classical and quantum variables and literals, with the following exceptions: |
| 121 | + |
| 122 | +- All classical variables must be [compile-time](https://docs.classiq.io/latest/qmod-reference/language-reference/classical-variables/#semantics). |
| 123 | +- The right-hand side of the division (`/`) and power (`**`) operators must be |
| 124 | + a classical expression. |
| 125 | + |
| 126 | +### Examples |
| 127 | + |
| 128 | +The following model includes qubit `q` and quantum numeric `n` of size three. |
| 129 | +It uses a `control` statement with a quantum expression `n > 4` to apply |
| 130 | +`X` to `q` only when `n` is greater than four. |
| 131 | + |
| 132 | +=== "Python" |
| 133 | + |
| 134 | + ```python |
| 135 | + from classiq import qfunc, Output, QBit, QNum, allocate, control, hadamard_transform |
| 136 | + |
| 137 | + |
| 138 | + @qfunc |
| 139 | + def main(n: Output[QNum[3]], q: Output[QBit]): |
| 140 | + allocate(n) |
| 141 | + hadamard_transform(n) |
| 142 | + allocate(q) |
| 143 | + control(n > 4, lambda: X(q)) |
| 144 | + ``` |
| 145 | + |
| 146 | +=== "Native" |
| 147 | + |
| 148 | + ``` |
| 149 | + qfunc main(output n: qnum<3>, output q: qbit) { |
| 150 | + allocate(n); |
| 151 | + hadamard_transform(n); |
| 152 | + allocate(q); |
| 153 | + control(n > 4) { |
| 154 | + X(q); |
| 155 | + } |
| 156 | + } |
| 157 | + ``` |
| 158 | + |
| 159 | +After executing this model, you get $q=0$ for $n\in\{0, 1, 2, 3, 4\}$ and |
| 160 | +$q=1$ for $n\in\{5, 6, 7\}$. |
| 161 | + |
| 162 | +See [additional examples](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/assignment/#examples) |
| 163 | +on the Assignment documentation page. |
| 164 | + |
| 165 | +## Classical Expressions |
| 166 | + |
| 167 | +Classical expressions are expressions that involve classical variables and |
| 168 | +constant literals, but no quantum variables. |
| 169 | +Classical variables may have known values at [compile time, link time, or runtime]](https://docs.classiq.io/latest/qmod-reference/language-reference/classical-variables/#semantics). |
| 170 | +Classical expressions with only compile-time variables are evaluated and |
| 171 | +simplified during compilation. |
| 172 | +This applies sub-expressions of quantum expressions too. |
| 173 | +Qmod supports several built-in classical [constants and functions](https://docs.classiq.io/latest/qmod-reference/api-reference/symbolic-functions/), |
| 174 | +such as `pi` and `sin`. |
| 175 | + |
| 176 | +### Example |
| 177 | + |
| 178 | +In the following model, function `foo` accepts quantum numeric `n` and a |
| 179 | +classical integer `x`, and perform the in-place xor operation `n ^= x + 1`. |
| 180 | +Function `foo` is called twice, once with `x=1` and once with `x=-1`. |
| 181 | + |
| 182 | +=== "Python" |
| 183 | + |
| 184 | + ```python |
| 185 | + from classiq import qfunc, CInt, Output, QNum |
| 186 | + |
| 187 | + |
| 188 | + @qfunc |
| 189 | + def foo(n: QNum, x: CInt): |
| 190 | + n ^= x + 1 |
| 191 | + |
| 192 | + |
| 193 | + @qfunc |
| 194 | + def main(n: Output[QNum]): |
| 195 | + n |= 1 |
| 196 | + foo(n, 1) # n ^= 2 |
| 197 | + foo(n, -1) # n ^= 0 |
| 198 | + ``` |
| 199 | + |
| 200 | +=== "Native" |
| 201 | + |
| 202 | + ``` |
| 203 | + qfunc foo(n: qnum, x: int) { |
| 204 | + n ^= x + 1; |
| 205 | + } |
| 206 | + |
| 207 | + qfunc main(output n: qnum) { |
| 208 | + n = 1; |
| 209 | + foo(n, 1); // n ^= 2; |
| 210 | + foo(n, -1); // n ^= 0; |
| 211 | + } |
| 212 | + ``` |
| 213 | + |
| 214 | +On the first call to `foo`, the Qmod compiler assigns `x=1` and simplifies the |
| 215 | +expression `x + 1` into `2`. |
| 216 | +Therefore, the first `foo` call applies a constant-value xor `n ^= 2`. |
| 217 | +On the second call to `foo`, the expression `x + 1` is simplified to `0`. |
| 218 | +Since the assignment `n ^= 0` has no effect, the Qmod compiler removes it from |
| 219 | +the model. |
0 commit comments