classiq 0.67.0__py3-none-any.whl → 0.69.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. classiq/_internals/api_wrapper.py +9 -9
  2. classiq/_internals/async_utils.py +1 -1
  3. classiq/_internals/authentication/password_manager.py +1 -1
  4. classiq/_internals/client.py +1 -1
  5. classiq/applications/combinatorial_optimization/combinatorial_problem.py +8 -11
  6. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  7. classiq/applications/qnn/gradients/simple_quantum_gradient.py +1 -1
  8. classiq/applications/qnn/torch_utils.py +1 -1
  9. classiq/execution/execution_session.py +7 -3
  10. classiq/execution/jobs.py +2 -5
  11. classiq/executor.py +7 -2
  12. classiq/interface/_version.py +1 -1
  13. classiq/interface/ast_node.py +1 -1
  14. classiq/interface/backend/quantum_backend_providers.py +2 -3
  15. classiq/interface/chemistry/operator.py +12 -8
  16. classiq/interface/debug_info/back_ref_util.py +22 -0
  17. classiq/interface/debug_info/debug_info.py +26 -21
  18. classiq/interface/executor/optimizer_preferences.py +1 -0
  19. classiq/interface/generator/arith/arithmetic.py +96 -1
  20. classiq/interface/generator/arith/arithmetic_expression_parser.py +1 -1
  21. classiq/interface/generator/arith/arithmetic_param_getters.py +3 -3
  22. classiq/interface/generator/functions/classical_type.py +12 -1
  23. classiq/interface/generator/generated_circuit_data.py +64 -23
  24. classiq/interface/generator/quantum_program.py +18 -1
  25. classiq/interface/generator/types/builtin_enum_declarations.py +1 -0
  26. classiq/interface/generator/types/enum_declaration.py +45 -3
  27. classiq/interface/ide/visual_model.py +0 -2
  28. classiq/interface/model/classical_if.py +2 -2
  29. classiq/interface/model/control.py +2 -2
  30. classiq/interface/model/invert.py +2 -2
  31. classiq/interface/model/power.py +2 -2
  32. classiq/interface/model/quantum_function_call.py +4 -0
  33. classiq/interface/model/quantum_statement.py +1 -1
  34. classiq/interface/model/repeat.py +2 -2
  35. classiq/interface/model/statement_block.py +1 -1
  36. classiq/interface/model/within_apply_operation.py +2 -2
  37. classiq/interface/server/routes.py +0 -6
  38. classiq/model_expansions/generative_functions.py +4 -3
  39. classiq/model_expansions/interpreters/generative_interpreter.py +78 -18
  40. classiq/model_expansions/quantum_operations/allocate.py +3 -1
  41. classiq/model_expansions/quantum_operations/assignment_result_processor.py +52 -0
  42. classiq/model_expansions/quantum_operations/bind.py +2 -1
  43. classiq/model_expansions/quantum_operations/block_evaluator.py +76 -0
  44. classiq/model_expansions/quantum_operations/call_emitter.py +0 -13
  45. classiq/model_expansions/quantum_operations/classicalif.py +5 -4
  46. classiq/model_expansions/quantum_operations/composite_emitter.py +27 -0
  47. classiq/model_expansions/quantum_operations/emitter.py +16 -2
  48. classiq/model_expansions/quantum_operations/expression_evaluator.py +33 -0
  49. classiq/model_expansions/quantum_operations/handle_evaluator.py +28 -0
  50. classiq/model_expansions/quantum_operations/quantum_function_call.py +3 -2
  51. classiq/model_expansions/quantum_operations/repeat.py +2 -1
  52. classiq/model_expansions/quantum_operations/variable_decleration.py +2 -1
  53. classiq/model_expansions/scope_initialization.py +5 -19
  54. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +1 -1
  55. classiq/open_library/functions/__init__.py +1 -2
  56. classiq/open_library/functions/amplitude_amplification.py +11 -12
  57. classiq/open_library/functions/discrete_sine_cosine_transform.py +17 -14
  58. classiq/open_library/functions/grover.py +7 -11
  59. classiq/open_library/functions/hea.py +3 -3
  60. classiq/open_library/functions/modular_exponentiation.py +17 -33
  61. classiq/open_library/functions/qft_functions.py +2 -2
  62. classiq/open_library/functions/qsvt.py +8 -8
  63. classiq/open_library/functions/state_preparation.py +16 -17
  64. classiq/open_library/functions/swap_test.py +1 -1
  65. classiq/open_library/functions/utility_functions.py +12 -4
  66. classiq/qmod/builtins/classical_functions.py +24 -7
  67. classiq/qmod/builtins/enums.py +1 -0
  68. classiq/qmod/builtins/functions/__init__.py +2 -0
  69. classiq/qmod/builtins/functions/chemistry.py +6 -38
  70. classiq/qmod/builtins/functions/exponentiation.py +24 -0
  71. classiq/qmod/builtins/operations.py +26 -11
  72. classiq/qmod/cparam.py +32 -5
  73. classiq/qmod/python_classical_type.py +10 -4
  74. classiq/qmod/quantum_callable.py +2 -1
  75. classiq/qmod/quantum_expandable.py +30 -6
  76. classiq/qmod/quantum_function.py +3 -2
  77. classiq/qmod/semantics/error_manager.py +1 -1
  78. classiq/qmod/semantics/validation/types_validation.py +1 -1
  79. classiq/qmod/symbolic.py +2 -1
  80. classiq/qmod/utilities.py +31 -2
  81. classiq/qmod/write_qmod.py +10 -7
  82. classiq/synthesis.py +25 -9
  83. {classiq-0.67.0.dist-info → classiq-0.69.0.dist-info}/METADATA +1 -1
  84. {classiq-0.67.0.dist-info → classiq-0.69.0.dist-info}/RECORD +85 -81
  85. classiq/interface/execution/jobs.py +0 -31
  86. classiq/model_expansions/quantum_operations/shallow_emitter.py +0 -166
  87. {classiq-0.67.0.dist-info → classiq-0.69.0.dist-info}/WHEEL +0 -0
@@ -11,24 +11,18 @@ from classiq.qmod.builtins.operations import (
11
11
  )
12
12
  from classiq.qmod.cparam import CInt
13
13
  from classiq.qmod.qfunc import qfunc
14
- from classiq.qmod.qmod_variable import QArray, QBit, QNum
14
+ from classiq.qmod.qmod_variable import QArray, QBit
15
15
  from classiq.qmod.symbolic import min, mod_inverse
16
16
 
17
17
 
18
18
  @qfunc
19
19
  def _check_msb(ref: CInt, x: QArray[QBit], aux: QBit) -> None:
20
20
  within_apply(
21
- lambda: invert(lambda: qft_no_swap(x)), lambda: _ctrl_x(ref, x[0], aux)
21
+ lambda: invert(lambda: qft_no_swap(x)),
22
+ lambda: control(x[0] == ref, lambda: X(aux)),
22
23
  )
23
24
 
24
25
 
25
- @qfunc
26
- def _ctrl_x(
27
- ref: CInt, ctrl: QNum, aux: QBit
28
- ) -> None: # TODO: remove qfunc when expressions of QBit is supported
29
- control(ctrl == ref, lambda: X(aux))
30
-
31
-
32
26
  @qfunc
33
27
  def qft_space_add_const(value: CInt, phi_b: QArray[QBit]) -> None:
34
28
  """
@@ -72,27 +66,21 @@ def cc_modular_add(n: CInt, a: CInt, phi_b: QArray[QBit], c1: QBit, c2: QBit) ->
72
66
  c2: a control qubit.
73
67
 
74
68
  """
75
- ctrl: QArray[QBit] = QArray("ctrl")
76
- aux = QBit("aux")
69
+ ctrl: QArray[QBit] = QArray()
70
+ aux = QBit()
77
71
 
78
72
  within_apply(
79
- lambda: ( # type:ignore[arg-type]
80
- allocate(1, aux),
81
- bind([c1, c2], ctrl), # type:ignore[func-returns-value]
73
+ lambda: (
74
+ allocate(aux),
75
+ bind([c1, c2], ctrl),
82
76
  ),
83
- lambda: ( # type:ignore[arg-type]
84
- control( # type:ignore[func-returns-value]
85
- ctrl, lambda: qft_space_add_const(a, phi_b)
86
- ),
87
- invert( # type:ignore[func-returns-value]
88
- lambda: qft_space_add_const(n, phi_b)
89
- ),
77
+ lambda: (
78
+ control(ctrl, lambda: qft_space_add_const(a, phi_b)),
79
+ invert(lambda: qft_space_add_const(n, phi_b)),
90
80
  _check_msb(1, phi_b, aux),
91
- control( # type:ignore[func-returns-value]
92
- aux, lambda: qft_space_add_const(n, phi_b)
93
- ),
81
+ control(aux, lambda: qft_space_add_const(n, phi_b)),
94
82
  within_apply(
95
- lambda: invert( # type:ignore[func-returns-value]
83
+ lambda: invert(
96
84
  lambda: control(ctrl, lambda: qft_space_add_const(a, phi_b))
97
85
  ),
98
86
  lambda: _check_msb(0, phi_b, aux),
@@ -162,18 +150,14 @@ def inplace_c_modular_multiply(n: CInt, a: CInt, x: QArray[QBit], ctrl: QBit) ->
162
150
  x: The quantum factor.
163
151
  ctrl: The control bit.
164
152
  """
165
- b: QArray[QBit] = QArray("b")
153
+ b: QArray[QBit] = QArray()
166
154
 
167
155
  within_apply(
168
156
  lambda: allocate(x.len + 1, b),
169
- lambda: ( # type:ignore[arg-type]
157
+ lambda: (
170
158
  c_modular_multiply(n, a, b, x, ctrl),
171
- control( # type:ignore[func-returns-value]
172
- ctrl, lambda: multiswap(x, b)
173
- ),
174
- invert( # type:ignore[func-returns-value]
175
- lambda: c_modular_multiply(n, mod_inverse(a, n), b, x, ctrl)
176
- ),
159
+ control(ctrl, lambda: multiswap(x, b)),
160
+ invert(lambda: c_modular_multiply(n, mod_inverse(a, n), b, x, ctrl)),
177
161
  ),
178
162
  )
179
163
 
@@ -18,9 +18,9 @@ def qft_no_swap(qbv: QArray[QBit]) -> None:
18
18
  """
19
19
  repeat(
20
20
  qbv.len,
21
- lambda i: ( # type:ignore[arg-type]
21
+ lambda i: (
22
22
  H(qbv[i]),
23
- repeat( # type:ignore[func-returns-value]
23
+ repeat(
24
24
  qbv.len - i - 1,
25
25
  lambda j: CPHASE(
26
26
  theta=pi / (2 ** (j + 1)),
@@ -97,8 +97,8 @@ def qsvt(
97
97
  if_(
98
98
  condition=phase_seq.len % 2 == 1,
99
99
  then=lambda: IDENTITY(qvar),
100
- else_=lambda: ( # type:ignore[arg-type]
101
- u(qvar), # type:ignore[func-returns-value]
100
+ else_=lambda: (
101
+ u(qvar),
102
102
  projector_controlled_phase(
103
103
  phase_seq[phase_seq.len - 1],
104
104
  proj_cnot_2,
@@ -297,8 +297,8 @@ def qsvt_lcu(
297
297
  condition=phase_seq_odd.len > phase_seq_even.len,
298
298
  then=lambda: control(
299
299
  lcu == 0,
300
- lambda: [ # type:ignore[arg-type]
301
- u(qvar), # type:ignore[func-returns-value]
300
+ lambda: [
301
+ u(qvar),
302
302
  projector_controlled_phase(
303
303
  phase_seq_odd[phase_seq_odd.len - 1], proj_cnot_2, qvar, aux
304
304
  ),
@@ -307,8 +307,8 @@ def qsvt_lcu(
307
307
  )
308
308
  if_(
309
309
  condition=phase_seq_odd.len < phase_seq_even.len,
310
- then=lambda: ( # type:ignore[arg-type]
311
- u(qvar), # type:ignore[func-returns-value]
310
+ then=lambda: (
311
+ u(qvar),
312
312
  projector_controlled_double_phase(
313
313
  phase_seq_even[phase_seq_even.len - 1],
314
314
  phase_seq_odd[phase_seq_odd.len - 1],
@@ -319,8 +319,8 @@ def qsvt_lcu(
319
319
  ),
320
320
  control(
321
321
  lcu,
322
- lambda: [ # type:ignore[arg-type]
323
- invert(lambda: u(qvar)), # type:ignore[func-returns-value]
322
+ lambda: [
323
+ invert(lambda: u(qvar)),
324
324
  projector_controlled_phase(
325
325
  phase_seq_even[phase_seq_even.len - 1], proj_cnot_1, qvar, aux
326
326
  ),
@@ -3,12 +3,9 @@ from typing import Literal
3
3
 
4
4
  from classiq.interface.exceptions import ClassiqDeprecationWarning
5
5
 
6
- from classiq.open_library.functions.utility_functions import (
7
- hadamard_transform,
8
- modular_increment,
9
- )
6
+ from classiq.open_library.functions.utility_functions import hadamard_transform
10
7
  from classiq.qmod.builtins.functions.standard_gates import CX, IDENTITY, RY, H, X
11
- from classiq.qmod.builtins.operations import allocate, control, if_, repeat
8
+ from classiq.qmod.builtins.operations import allocate, control, if_, inplace_add, repeat
12
9
  from classiq.qmod.cparam import CBool, CInt
13
10
  from classiq.qmod.qfunc import qfunc
14
11
  from classiq.qmod.qmod_variable import Output, QArray, QBit, QNum
@@ -48,7 +45,7 @@ def allocate_num(
48
45
  allocate(num_qubits, out)
49
46
 
50
47
 
51
- def prepare_uniform_trimmed_state_apply_rotation(
48
+ def _prepare_uniform_trimmed_state_apply_rotation(
52
49
  size_lsb: CInt, lsbs_val: CInt, rotation_var: QBit
53
50
  ) -> None:
54
51
  # max hold for the case where the value is on the left side
@@ -68,7 +65,7 @@ def _prepare_uniform_trimmed_state_step(
68
65
  lsbs_val != 0, # stop condition
69
66
  lambda: control(
70
67
  ctrl_var == ctrl_val,
71
- lambda: prepare_uniform_trimmed_state_apply_rotation(
68
+ lambda: _prepare_uniform_trimmed_state_apply_rotation(
72
69
  size_lsb, lsbs_val, rotation_var
73
70
  ),
74
71
  ),
@@ -102,7 +99,7 @@ def prepare_uniform_trimmed_state(m: CInt, q: QArray[QBit]) -> None:
102
99
  if_(
103
100
  m < 2**q.len,
104
101
  # initial step without control
105
- lambda: prepare_uniform_trimmed_state_apply_rotation(
102
+ lambda: _prepare_uniform_trimmed_state_apply_rotation(
106
103
  q.len - 1, # type:ignore[arg-type]
107
104
  m,
108
105
  q[q.len - 1],
@@ -122,7 +119,7 @@ def prepare_uniform_trimmed_state(m: CInt, q: QArray[QBit]) -> None:
122
119
 
123
120
 
124
121
  @qfunc
125
- def prepare_uniform_interval_state(start: CInt, end: CInt, q: QArray[QBit]) -> None:
122
+ def prepare_uniform_interval_state(start: CInt, end: CInt, q: QNum) -> None:
126
123
  """
127
124
  [Qmod Classiq-library function]
128
125
 
@@ -144,7 +141,7 @@ def prepare_uniform_interval_state(start: CInt, end: CInt, q: QArray[QBit]) -> N
144
141
  2. The synthesis engine automatically handles the allocation, either by drawing new qubits from the available pool or by reusing existing ones.
145
142
  """
146
143
  prepare_uniform_trimmed_state(end - start, q)
147
- modular_increment(start, q)
144
+ inplace_add(start, q)
148
145
 
149
146
 
150
147
  @qfunc
@@ -199,7 +196,9 @@ def prepare_exponential_state(rate: CInt, q: QArray[QBit]) -> None:
199
196
 
200
197
 
201
198
  @qfunc
202
- def prepare_bell_state(state_num: CInt, q: Output[QArray[QBit, Literal[2]]]) -> None:
199
+ def prepare_bell_state(
200
+ state_num: CInt, qpair: Output[QArray[QBit, Literal[2]]]
201
+ ) -> None:
203
202
  """
204
203
  [Qmod Classiq-library function]
205
204
 
@@ -207,7 +206,7 @@ def prepare_bell_state(state_num: CInt, q: Output[QArray[QBit, Literal[2]]]) ->
207
206
 
208
207
  Args:
209
208
  state_num: The number of the Bell state to be prepared. Must be an integer between 0 and 3.
210
- q: The quantum variable that will receive the initialized state. Must be uninitialized.
209
+ qpair: The quantum variable that will receive the initialized state. Must be uninitialized.
211
210
 
212
211
  Bell States:
213
212
  The four Bell states are defined as follows (each state correlates to an integer between 0 and 3 as defined by the `state_num` argument):
@@ -241,11 +240,11 @@ def prepare_bell_state(state_num: CInt, q: Output[QArray[QBit, Literal[2]]]) ->
241
240
 
242
241
 
243
242
  """
244
- allocate(2, q)
245
- if_(logical_or(state_num == 1, state_num == 3), lambda: X(q[0]))
246
- if_(logical_or(state_num == 2, state_num == 3), lambda: X(q[1]))
247
- H(q[0])
248
- CX(q[0], q[1])
243
+ allocate(qpair)
244
+ if_(logical_or(state_num == 1, state_num == 3), lambda: X(qpair[0]))
245
+ if_(logical_or(state_num == 2, state_num == 3), lambda: X(qpair[1]))
246
+ H(qpair[0])
247
+ CX(qpair[0], qpair[1])
249
248
 
250
249
 
251
250
  @qfunc
@@ -21,7 +21,7 @@ def swap_test(state1: QArray[QBit], state2: QArray[QBit], test: Output[QBit]) ->
21
21
  state2: A quantum state to check its overlap with state1.
22
22
  test: A qubit for which the probability of measuring 0 is $0.5*(|\\langle state1 | state2 \\rangle |^2+1)$
23
23
  """
24
- allocate(1, test)
24
+ allocate(test)
25
25
  H(test)
26
26
  control(test, lambda: repeat(state1.len, lambda i: SWAP(state1[i], state2[i])))
27
27
  H(test)
@@ -1,5 +1,8 @@
1
+ import warnings
1
2
  from typing import Annotated
2
3
 
4
+ from classiq.interface.exceptions import ClassiqDeprecationWarning
5
+
3
6
  from classiq.open_library.functions.qft_functions import qft
4
7
  from classiq.qmod.builtins.functions.standard_gates import PHASE, H
5
8
  from classiq.qmod.builtins.operations import bind, repeat, within_apply
@@ -44,7 +47,7 @@ def hadamard_transform(target: QArray[QBit]) -> None:
44
47
  target: qubits to apply to Hadamard transform to.
45
48
 
46
49
  """
47
- apply_to_all(H, target)
50
+ repeat(target.len, lambda index: H(target[index]))
48
51
 
49
52
 
50
53
  @qfunc
@@ -69,10 +72,15 @@ def modular_increment(a: CInt, x: QNum) -> None:
69
72
  x: A quantum number that is assumed to be non-negative integer.
70
73
 
71
74
  """
72
- array_cast: QArray = QArray("array_cast")
75
+ warnings.warn(
76
+ "Function 'modular_increment' is deprecated. Use in-place-add statement in the form '<var> += <expression>' or 'inplace_add(<expression>, <var>)' instead.",
77
+ ClassiqDeprecationWarning,
78
+ stacklevel=1,
79
+ )
80
+ array_cast: QArray = QArray()
73
81
  within_apply(
74
- lambda: ( # type:ignore[arg-type]
75
- bind(x, array_cast), # type:ignore[func-returns-value]
82
+ lambda: (
83
+ bind(x, array_cast),
76
84
  qft(array_cast),
77
85
  ),
78
86
  lambda: repeat(
@@ -12,19 +12,25 @@ def qft_const_adder_phase(
12
12
  value: CInt,
13
13
  reg_len: CInt,
14
14
  ) -> CReal:
15
- return symbolic_function(bit_index, value, reg_len, return_type=CReal)
15
+ return symbolic_function(
16
+ bit_index, value, reg_len, return_type=CReal # type:ignore[type-abstract]
17
+ )
16
18
 
17
19
 
18
20
  def fock_hamiltonian_problem_to_hamiltonian(
19
21
  problem: FockHamiltonianProblem,
20
22
  ) -> CArray[PauliTerm]:
21
- return symbolic_function(problem, return_type=CArray[PauliTerm])
23
+ return symbolic_function(
24
+ problem, return_type=CArray[PauliTerm] # type:ignore[type-abstract]
25
+ )
22
26
 
23
27
 
24
28
  def molecule_problem_to_hamiltonian(
25
29
  problem: MoleculeProblem,
26
30
  ) -> CArray[PauliTerm]:
27
- return symbolic_function(problem, return_type=CArray[PauliTerm])
31
+ return symbolic_function(
32
+ problem, return_type=CArray[PauliTerm] # type:ignore[type-abstract]
33
+ )
28
34
 
29
35
 
30
36
  def grid_entangler_graph(
@@ -33,14 +39,19 @@ def grid_entangler_graph(
33
39
  grid_randomization: CBool,
34
40
  ) -> CArray[CArray[CInt]]:
35
41
  return symbolic_function(
36
- num_qubits, schmidt_rank, grid_randomization, return_type=CArray[CArray[CInt]]
42
+ num_qubits,
43
+ schmidt_rank,
44
+ grid_randomization,
45
+ return_type=CArray[CArray[CInt]], # type:ignore[type-abstract]
37
46
  )
38
47
 
39
48
 
40
49
  def hypercube_entangler_graph(
41
50
  num_qubits: CInt,
42
51
  ) -> CArray[CArray[CInt]]:
43
- return symbolic_function(num_qubits, return_type=CArray[CArray[CInt]])
52
+ return symbolic_function(
53
+ num_qubits, return_type=CArray[CArray[CInt]] # type:ignore[type-abstract]
54
+ )
44
55
 
45
56
 
46
57
  def gaussian_finance_post_process(
@@ -49,7 +60,10 @@ def gaussian_finance_post_process(
49
60
  probability: CReal,
50
61
  ) -> CReal:
51
62
  return symbolic_function(
52
- finance_model, estimation_method, probability, return_type=CReal
63
+ finance_model,
64
+ estimation_method,
65
+ probability,
66
+ return_type=CReal, # type:ignore[type-abstract]
53
67
  )
54
68
 
55
69
 
@@ -59,7 +73,10 @@ def log_normal_finance_post_process(
59
73
  probability: CReal,
60
74
  ) -> CReal:
61
75
  return symbolic_function(
62
- finance_model, estimation_method, probability, return_type=CReal
76
+ finance_model,
77
+ estimation_method,
78
+ probability,
79
+ return_type=CReal, # type:ignore[type-abstract]
63
80
  )
64
81
 
65
82
 
@@ -149,6 +149,7 @@ class Optimizer(IntEnum):
149
149
  L_BFGS_B = 3
150
150
  NELDER_MEAD = 4
151
151
  ADAM = 5
152
+ SLSQP = 6
152
153
 
153
154
 
154
155
  class Pauli(IntEnum):
@@ -64,6 +64,7 @@ CORE_LIB_DECLS = [
64
64
  inplace_prepare_state,
65
65
  inplace_prepare_amplitudes,
66
66
  single_pauli_exponent,
67
+ commuting_paulis_exponent,
67
68
  suzuki_trotter,
68
69
  qdrift,
69
70
  exponentiation_with_depth_constraint,
@@ -129,6 +130,7 @@ __all__ = [ # noqa: RUF022
129
130
  "randomized_benchmarking",
130
131
  "real_xor_constant",
131
132
  "single_pauli_exponent",
133
+ "commuting_paulis_exponent",
132
134
  "suzuki_trotter",
133
135
  "unitary",
134
136
  "RESET",
@@ -1,5 +1,3 @@
1
- from typing import Literal
2
-
3
1
  from classiq.qmod.builtins.structs import (
4
2
  FockHamiltonianProblem,
5
3
  MoleculeProblem,
@@ -13,12 +11,7 @@ from classiq.qmod.qmod_variable import QArray, QBit
13
11
  def molecule_ucc(
14
12
  molecule_problem: MoleculeProblem,
15
13
  excitations: CArray[CInt],
16
- qbv: QArray[
17
- QBit,
18
- Literal[
19
- "get_field(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'), 'len')"
20
- ],
21
- ],
14
+ qbv: QArray[QBit],
22
15
  ) -> None:
23
16
  pass
24
17
 
@@ -27,12 +20,7 @@ def molecule_ucc(
27
20
  def molecule_hva(
28
21
  molecule_problem: MoleculeProblem,
29
22
  reps: CInt,
30
- qbv: QArray[
31
- QBit,
32
- Literal[
33
- "get_field(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'), 'len')"
34
- ],
35
- ],
23
+ qbv: QArray[QBit],
36
24
  ) -> None:
37
25
  pass
38
26
 
@@ -40,12 +28,7 @@ def molecule_hva(
40
28
  @qfunc(external=True)
41
29
  def molecule_hartree_fock(
42
30
  molecule_problem: MoleculeProblem,
43
- qbv: QArray[
44
- QBit,
45
- Literal[
46
- "get_field(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'), 'len')"
47
- ],
48
- ],
31
+ qbv: QArray[QBit],
49
32
  ) -> None:
50
33
  pass
51
34
 
@@ -54,12 +37,7 @@ def molecule_hartree_fock(
54
37
  def fock_hamiltonian_ucc(
55
38
  fock_hamiltonian_problem: FockHamiltonianProblem,
56
39
  excitations: CArray[CInt],
57
- qbv: QArray[
58
- QBit,
59
- Literal[
60
- "get_field(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'), 'len')"
61
- ],
62
- ],
40
+ qbv: QArray[QBit],
63
41
  ) -> None:
64
42
  pass
65
43
 
@@ -68,12 +46,7 @@ def fock_hamiltonian_ucc(
68
46
  def fock_hamiltonian_hva(
69
47
  fock_hamiltonian_problem: FockHamiltonianProblem,
70
48
  reps: CInt,
71
- qbv: QArray[
72
- QBit,
73
- Literal[
74
- "get_field(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'), 'len')"
75
- ],
76
- ],
49
+ qbv: QArray[QBit],
77
50
  ) -> None:
78
51
  pass
79
52
 
@@ -81,11 +54,6 @@ def fock_hamiltonian_hva(
81
54
  @qfunc(external=True)
82
55
  def fock_hamiltonian_hartree_fock(
83
56
  fock_hamiltonian_problem: FockHamiltonianProblem,
84
- qbv: QArray[
85
- QBit,
86
- Literal[
87
- "get_field(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'), 'len')"
88
- ],
89
- ],
57
+ qbv: QArray[QBit],
90
58
  ) -> None:
91
59
  pass
@@ -28,6 +28,30 @@ def single_pauli_exponent(
28
28
  pass
29
29
 
30
30
 
31
+ @qfunc(external=True)
32
+ def commuting_paulis_exponent(
33
+ pauli_operator: CArray[PauliTerm],
34
+ evolution_coefficient: CReal,
35
+ qbv: QArray[
36
+ QBit, Literal["get_field(get_field(pauli_operator[0], 'pauli'), 'len')"]
37
+ ],
38
+ ) -> None:
39
+ """
40
+ [Qmod core-library function]
41
+
42
+ Exponentiates the specified commutative Pauli operator.
43
+ As all the Pauli operator's terms commute, the exponential of the whole operator
44
+ is exactly the product of exponentials of each term.
45
+ Calling this funciton with a non-commutative Pauli operator will issue an error.
46
+
47
+ Args:
48
+ pauli_operator: The Pauli operator to be exponentiated.
49
+ evolution_coefficient: A global evolution coefficient multiplying the Pauli operator.
50
+ qbv: The target quantum variable of the exponentiation.
51
+ """
52
+ pass
53
+
54
+
31
55
  @qfunc(external=True)
32
56
  def suzuki_trotter(
33
57
  pauli_operator: CArray[PauliTerm],
@@ -48,7 +48,7 @@ from classiq.qmod.qmod_variable import Input, Output, QArray, QBit, QScalar, QVa
48
48
  from classiq.qmod.quantum_callable import QCallable
49
49
  from classiq.qmod.quantum_expandable import prepare_arg
50
50
  from classiq.qmod.symbolic_expr import SymbolicExpr
51
- from classiq.qmod.utilities import get_source_ref
51
+ from classiq.qmod.utilities import Statements, get_source_ref, suppress_return_value
52
52
 
53
53
  _MISSING_VALUE: Final[int] = -1
54
54
 
@@ -63,6 +63,7 @@ def allocate(out: Output[QVar]) -> None:
63
63
  pass
64
64
 
65
65
 
66
+ @suppress_return_value
66
67
  def allocate(*args: Any, **kwargs: Any) -> None:
67
68
  """
68
69
  Initialize a quantum variable to a new quantum object in the zero state:
@@ -106,6 +107,7 @@ def allocate(*args: Any, **kwargs: Any) -> None:
106
107
  )
107
108
 
108
109
 
110
+ @suppress_return_value
109
111
  def bind(
110
112
  source: Union[Input[QVar], list[Input[QVar]]],
111
113
  destination: Union[Output[QVar], list[Output[QVar]]],
@@ -125,10 +127,11 @@ def bind(
125
127
  )
126
128
 
127
129
 
130
+ @suppress_return_value
128
131
  def if_(
129
132
  condition: Union[SymbolicExpr, bool],
130
- then: Union[QCallable, Callable[[], None]],
131
- else_: Union[QCallable, Callable[[], None], int] = _MISSING_VALUE,
133
+ then: Union[QCallable, Callable[[], Statements]],
134
+ else_: Union[QCallable, Callable[[], Statements], int] = _MISSING_VALUE,
132
135
  ) -> None:
133
136
  _validate_operand(then)
134
137
  if else_ != _MISSING_VALUE:
@@ -149,10 +152,11 @@ def if_(
149
152
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(if_stmt)
150
153
 
151
154
 
155
+ @suppress_return_value
152
156
  def control(
153
157
  ctrl: Union[SymbolicExpr, QBit, QArray[QBit]],
154
- stmt_block: Union[QCallable, Callable[[], None]],
155
- else_block: Union[QCallable, Callable[[], None], None] = None,
158
+ stmt_block: Union[QCallable, Callable[[], Statements]],
159
+ else_block: Union[QCallable, Callable[[], Statements], None] = None,
156
160
  ) -> None:
157
161
  _validate_operand(stmt_block)
158
162
  assert QCallable.CURRENT_EXPANDABLE is not None
@@ -170,6 +174,7 @@ def control(
170
174
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(control_stmt)
171
175
 
172
176
 
177
+ @suppress_return_value
173
178
  def assign(expression: SymbolicExpr, target_var: QScalar) -> None:
174
179
  """
175
180
  Initialize a scalar quantum variable using an arithmetic expression.
@@ -194,6 +199,7 @@ def assign(expression: SymbolicExpr, target_var: QScalar) -> None:
194
199
  )
195
200
 
196
201
 
202
+ @suppress_return_value
197
203
  def assign_amplitude(expression: SymbolicExpr, target_var: QScalar) -> None:
198
204
  """
199
205
  Perform an amplitude-encoding assignment operation on a quantum variable and a
@@ -216,6 +222,7 @@ def assign_amplitude(expression: SymbolicExpr, target_var: QScalar) -> None:
216
222
  )
217
223
 
218
224
 
225
+ @suppress_return_value
219
226
  def inplace_add(expression: SymbolicExpr, target_var: QScalar) -> None:
220
227
  """
221
228
  Add an arithmetic expression to a quantum variable.
@@ -238,6 +245,7 @@ def inplace_add(expression: SymbolicExpr, target_var: QScalar) -> None:
238
245
  )
239
246
 
240
247
 
248
+ @suppress_return_value
241
249
  def inplace_xor(expression: SymbolicExpr, target_var: QScalar) -> None:
242
250
  """
243
251
  Bitwise-XOR a quantum variable with an arithmetic expression.
@@ -260,9 +268,10 @@ def inplace_xor(expression: SymbolicExpr, target_var: QScalar) -> None:
260
268
  )
261
269
 
262
270
 
271
+ @suppress_return_value
263
272
  def within_apply(
264
- within: Callable[[], None],
265
- apply: Callable[[], None],
273
+ within: Callable[[], Statements],
274
+ apply: Callable[[], Statements],
266
275
  ) -> None:
267
276
  _validate_operand(within)
268
277
  _validate_operand(apply)
@@ -279,7 +288,10 @@ def within_apply(
279
288
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(within_apply_stmt)
280
289
 
281
290
 
282
- def repeat(count: Union[SymbolicExpr, int], iteration: Callable[[int], None]) -> None:
291
+ @suppress_return_value
292
+ def repeat(
293
+ count: Union[SymbolicExpr, int], iteration: Callable[[int], Statements]
294
+ ) -> None:
283
295
  _validate_operand(iteration)
284
296
  assert QCallable.CURRENT_EXPANDABLE is not None
285
297
  source_ref = get_source_ref(sys._getframe(1))
@@ -310,9 +322,10 @@ def repeat(count: Union[SymbolicExpr, int], iteration: Callable[[int], None]) ->
310
322
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(repeat_stmt)
311
323
 
312
324
 
325
+ @suppress_return_value
313
326
  def power(
314
327
  exponent: Union[SymbolicExpr, int],
315
- stmt_block: Union[QCallable, Callable[[], None]],
328
+ stmt_block: Union[QCallable, Callable[[], Statements]],
316
329
  ) -> None:
317
330
  _validate_operand(stmt_block)
318
331
  assert QCallable.CURRENT_EXPANDABLE is not None
@@ -327,7 +340,8 @@ def power(
327
340
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(power_stmt)
328
341
 
329
342
 
330
- def invert(stmt_block: Union[QCallable, Callable[[], None]]) -> None:
343
+ @suppress_return_value
344
+ def invert(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
331
345
  _validate_operand(stmt_block)
332
346
  assert QCallable.CURRENT_EXPANDABLE is not None
333
347
  source_ref = get_source_ref(sys._getframe(1))
@@ -339,6 +353,7 @@ def invert(stmt_block: Union[QCallable, Callable[[], None]]) -> None:
339
353
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(invert_stmt)
340
354
 
341
355
 
356
+ @suppress_return_value
342
357
  def phase(expr: SymbolicExpr, theta: float = 1.0) -> None:
343
358
  assert QCallable.CURRENT_EXPANDABLE is not None
344
359
  source_ref = get_source_ref(sys._getframe(1))
@@ -402,7 +417,7 @@ def _get_operand_hint(
402
417
 
403
418
 
404
419
  def _operand_to_body(
405
- callable_: Union[QCallable, Callable[[], None]], param_name: str
420
+ callable_: Union[QCallable, Callable[[], Statements]], param_name: str
406
421
  ) -> StatementBlock:
407
422
  op_name = sys._getframe(1).f_code.co_name
408
423
  if (