classiq 0.53.0__py3-none-any.whl → 0.55.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 (301) hide show
  1. classiq/__init__.py +1 -3
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/__init__.py +0 -20
  4. classiq/_internals/api_wrapper.py +8 -8
  5. classiq/_internals/async_utils.py +1 -3
  6. classiq/_internals/authentication/auth0.py +5 -5
  7. classiq/_internals/authentication/device.py +5 -4
  8. classiq/_internals/authentication/password_manager.py +3 -3
  9. classiq/_internals/authentication/token_manager.py +3 -2
  10. classiq/_internals/client.py +10 -12
  11. classiq/_internals/config.py +2 -2
  12. classiq/_internals/jobs.py +7 -6
  13. classiq/_internals/type_validation.py +9 -9
  14. classiq/analyzer/__init__.py +1 -3
  15. classiq/analyzer/analyzer.py +8 -7
  16. classiq/analyzer/analyzer_utilities.py +8 -8
  17. classiq/analyzer/rb.py +11 -11
  18. classiq/applications/__init__.py +1 -3
  19. classiq/applications/chemistry/__init__.py +1 -3
  20. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  21. classiq/applications/chemistry/chemistry_model_constructor.py +10 -9
  22. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +26 -9
  23. classiq/applications/combinatorial_helpers/encoding_mapping.py +10 -10
  24. classiq/applications/combinatorial_helpers/encoding_utils.py +4 -4
  25. classiq/applications/combinatorial_helpers/memory.py +5 -7
  26. classiq/applications/combinatorial_helpers/optimization_model.py +43 -24
  27. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +4 -6
  28. classiq/applications/combinatorial_helpers/pyomo_utils.py +95 -24
  29. classiq/applications/combinatorial_helpers/sympy_utils.py +2 -2
  30. classiq/applications/combinatorial_helpers/transformations/encoding.py +8 -8
  31. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -5
  32. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +7 -9
  33. classiq/applications/combinatorial_helpers/transformations/penalty.py +1 -2
  34. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -2
  35. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +1 -2
  36. classiq/applications/combinatorial_optimization/__init__.py +1 -3
  37. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  38. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  39. classiq/applications/finance/__init__.py +1 -3
  40. classiq/applications/grover/__init__.py +1 -3
  41. classiq/applications/grover/grover_model_constructor.py +7 -9
  42. classiq/applications/hamiltonian/pauli_decomposition.py +6 -6
  43. classiq/applications/qnn/__init__.py +1 -3
  44. classiq/applications/qnn/circuit_utils.py +5 -5
  45. classiq/applications/qnn/datasets/__init__.py +1 -3
  46. classiq/applications/qnn/datasets/dataset_base_classes.py +5 -4
  47. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  48. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  49. classiq/applications/qnn/qlayer.py +3 -3
  50. classiq/applications/qnn/torch_utils.py +2 -2
  51. classiq/applications/qnn/types.py +5 -5
  52. classiq/applications/qsvm/qsvm.py +1 -3
  53. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  54. classiq/applications/qsvm/qsvm_model_constructor.py +5 -5
  55. classiq/execution/__init__.py +1 -3
  56. classiq/execution/all_hardware_devices.py +1 -3
  57. classiq/execution/execution_session.py +16 -16
  58. classiq/execution/jobs.py +4 -4
  59. classiq/execution/qaoa.py +3 -3
  60. classiq/execution/qnn.py +3 -3
  61. classiq/executor.py +3 -3
  62. classiq/interface/_version.py +1 -1
  63. classiq/interface/analyzer/analysis_params.py +9 -10
  64. classiq/interface/analyzer/cytoscape_graph.py +5 -5
  65. classiq/interface/analyzer/result.py +17 -17
  66. classiq/interface/applications/qsvm.py +6 -10
  67. classiq/interface/backend/backend_preferences.py +4 -3
  68. classiq/interface/backend/ionq/ionq_quantum_program.py +4 -5
  69. classiq/interface/backend/pydantic_backend.py +1 -2
  70. classiq/interface/chemistry/fermionic_operator.py +5 -5
  71. classiq/interface/chemistry/ground_state_problem.py +7 -8
  72. classiq/interface/chemistry/molecule.py +4 -4
  73. classiq/interface/chemistry/operator.py +11 -13
  74. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  75. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  76. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  77. classiq/interface/combinatorial_optimization/examples/mht.py +2 -3
  78. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  79. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  80. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +5 -7
  81. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  82. classiq/interface/combinatorial_optimization/result.py +1 -3
  83. classiq/interface/debug_info/debug_info.py +8 -7
  84. classiq/interface/exceptions.py +8 -6
  85. classiq/interface/execution/jobs.py +2 -2
  86. classiq/interface/execution/primitives.py +3 -3
  87. classiq/interface/executor/aws_execution_cost.py +4 -4
  88. classiq/interface/executor/execution_request.py +2 -3
  89. classiq/interface/executor/execution_result.py +3 -3
  90. classiq/interface/executor/iqae_result.py +3 -5
  91. classiq/interface/executor/optimizer_preferences.py +2 -2
  92. classiq/interface/executor/quantum_code.py +6 -6
  93. classiq/interface/executor/register_initialization.py +2 -4
  94. classiq/interface/executor/result.py +23 -27
  95. classiq/interface/executor/vqe_result.py +8 -8
  96. classiq/interface/finance/function_input.py +2 -2
  97. classiq/interface/finance/gaussian_model_input.py +5 -5
  98. classiq/interface/finance/log_normal_model_input.py +2 -2
  99. classiq/interface/finance/model_input.py +1 -2
  100. classiq/interface/generator/adjacency.py +1 -3
  101. classiq/interface/generator/ansatz_library.py +4 -4
  102. classiq/interface/generator/application_apis/finance_declarations.py +1 -1
  103. classiq/interface/generator/arith/argument_utils.py +3 -3
  104. classiq/interface/generator/arith/arithmetic.py +7 -7
  105. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +5 -5
  106. classiq/interface/generator/arith/arithmetic_expression_abc.py +11 -11
  107. classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -7
  108. classiq/interface/generator/arith/arithmetic_expression_validator.py +8 -8
  109. classiq/interface/generator/arith/arithmetic_operations.py +4 -3
  110. classiq/interface/generator/arith/arithmetic_param_getters.py +6 -6
  111. classiq/interface/generator/arith/arithmetic_result_builder.py +9 -9
  112. classiq/interface/generator/arith/ast_node_rewrite.py +2 -1
  113. classiq/interface/generator/arith/binary_ops.py +10 -13
  114. classiq/interface/generator/arith/extremum_operations.py +3 -2
  115. classiq/interface/generator/arith/logical_ops.py +7 -6
  116. classiq/interface/generator/arith/number_utils.py +4 -4
  117. classiq/interface/generator/arith/register_user_input.py +4 -4
  118. classiq/interface/generator/arith/unary_ops.py +2 -1
  119. classiq/interface/generator/builtin_api_builder.py +2 -1
  120. classiq/interface/generator/circuit_code/circuit_code.py +4 -4
  121. classiq/interface/generator/circuit_code/types_and_constants.py +3 -5
  122. classiq/interface/generator/complex_type.py +1 -2
  123. classiq/interface/generator/control_state.py +2 -2
  124. classiq/interface/generator/custom_ansatz.py +1 -3
  125. classiq/interface/generator/distance.py +3 -5
  126. classiq/interface/generator/excitations.py +3 -2
  127. classiq/interface/generator/expressions/enums/finance_functions.py +1 -3
  128. classiq/interface/generator/expressions/evaluated_expression.py +4 -3
  129. classiq/interface/generator/expressions/expression.py +4 -5
  130. classiq/interface/generator/expressions/expression_constants.py +4 -4
  131. classiq/interface/generator/expressions/qmod_qarray_proxy.py +2 -1
  132. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -1
  133. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +2 -1
  134. classiq/interface/generator/expressions/qmod_sized_proxy.py +2 -1
  135. classiq/interface/generator/expressions/qmod_struct_instance.py +2 -1
  136. classiq/interface/generator/expressions/sympy_supported_expressions.py +11 -13
  137. classiq/interface/generator/finance.py +2 -2
  138. classiq/interface/generator/function_param_library.py +6 -6
  139. classiq/interface/generator/function_params.py +13 -19
  140. classiq/interface/generator/functions/builtins/internal_operators.py +9 -1
  141. classiq/interface/generator/functions/classical_function_declaration.py +4 -3
  142. classiq/interface/generator/functions/classical_type.py +13 -13
  143. classiq/interface/generator/functions/concrete_types.py +1 -2
  144. classiq/interface/generator/functions/function_declaration.py +1 -1
  145. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  146. classiq/interface/generator/functions/type_name.py +3 -2
  147. classiq/interface/generator/generated_circuit_data.py +33 -22
  148. classiq/interface/generator/grover_diffuser.py +7 -7
  149. classiq/interface/generator/grover_operator.py +2 -2
  150. classiq/interface/generator/hardware/hardware_data.py +7 -6
  151. classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
  152. classiq/interface/generator/identity.py +5 -6
  153. classiq/interface/generator/linear_pauli_rotations.py +6 -6
  154. classiq/interface/generator/mcu.py +2 -2
  155. classiq/interface/generator/mcx.py +6 -6
  156. classiq/interface/generator/model/__init__.py +1 -3
  157. classiq/interface/generator/model/constraints.py +2 -2
  158. classiq/interface/generator/model/model.py +5 -6
  159. classiq/interface/generator/model/preferences/preferences.py +11 -6
  160. classiq/interface/generator/model/quantum_register.py +6 -11
  161. classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
  162. classiq/interface/generator/oracles/custom_oracle.py +2 -2
  163. classiq/interface/generator/oracles/oracle_abc.py +6 -5
  164. classiq/interface/generator/partitioned_register.py +6 -5
  165. classiq/interface/generator/piecewise_linear_amplitude_loading.py +8 -7
  166. classiq/interface/generator/qpe.py +4 -4
  167. classiq/interface/generator/qsvm.py +3 -3
  168. classiq/interface/generator/quantum_function_call.py +24 -29
  169. classiq/interface/generator/quantum_program.py +9 -9
  170. classiq/interface/generator/register_role.py +2 -4
  171. classiq/interface/generator/slice_parsing_utils.py +4 -3
  172. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  173. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  174. classiq/interface/generator/state_preparation/distributions.py +6 -5
  175. classiq/interface/generator/state_preparation/metrics.py +2 -4
  176. classiq/interface/generator/state_preparation/state_preparation.py +4 -4
  177. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -3
  178. classiq/interface/generator/transpiler_basis_gates.py +2 -2
  179. classiq/interface/generator/types/compilation_metadata.py +5 -0
  180. classiq/interface/generator/types/enum_declaration.py +2 -3
  181. classiq/interface/generator/types/qstruct_declaration.py +2 -1
  182. classiq/interface/generator/types/struct_declaration.py +3 -2
  183. classiq/interface/generator/ucc.py +2 -1
  184. classiq/interface/generator/unitary_gate.py +2 -2
  185. classiq/interface/generator/user_defined_function_params.py +1 -1
  186. classiq/interface/generator/validations/flow_graph.py +6 -5
  187. classiq/interface/generator/validations/validator_functions.py +3 -2
  188. classiq/interface/generator/visitor.py +9 -14
  189. classiq/interface/hardware.py +5 -6
  190. classiq/interface/helpers/custom_encoders.py +2 -2
  191. classiq/interface/helpers/custom_pydantic_types.py +8 -9
  192. classiq/interface/helpers/hashable_mixin.py +3 -2
  193. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  194. classiq/interface/helpers/pydantic_model_helpers.py +4 -3
  195. classiq/interface/helpers/validation_helpers.py +2 -2
  196. classiq/interface/ide/ide_data.py +11 -15
  197. classiq/interface/ide/visual_model.py +22 -22
  198. classiq/interface/jobs.py +2 -2
  199. classiq/interface/model/bind_operation.py +5 -4
  200. classiq/interface/model/classical_parameter_declaration.py +2 -2
  201. classiq/interface/model/control.py +22 -1
  202. classiq/interface/model/handle_binding.py +3 -2
  203. classiq/interface/model/inplace_binary_operation.py +2 -1
  204. classiq/interface/model/model.py +16 -11
  205. classiq/interface/model/native_function_definition.py +1 -1
  206. classiq/interface/model/port_declaration.py +2 -2
  207. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +3 -2
  208. classiq/interface/model/quantum_expressions/arithmetic_operation.py +4 -27
  209. classiq/interface/model/quantum_expressions/quantum_expression.py +8 -7
  210. classiq/interface/model/quantum_function_call.py +9 -14
  211. classiq/interface/model/quantum_function_declaration.py +10 -12
  212. classiq/interface/model/quantum_lambda_function.py +3 -16
  213. classiq/interface/model/quantum_statement.py +7 -3
  214. classiq/interface/model/quantum_type.py +5 -5
  215. classiq/interface/model/statement_block.py +2 -3
  216. classiq/interface/model/validation_handle.py +5 -4
  217. classiq/interface/server/global_versions.py +3 -3
  218. classiq/model_expansions/atomic_expression_functions_defs.py +3 -2
  219. classiq/model_expansions/capturing/captured_var_manager.py +4 -6
  220. classiq/model_expansions/capturing/propagated_var_stack.py +7 -7
  221. classiq/model_expansions/closure.py +83 -12
  222. classiq/model_expansions/evaluators/arg_type_match.py +3 -2
  223. classiq/model_expansions/evaluators/argument_types.py +3 -3
  224. classiq/model_expansions/evaluators/control.py +3 -3
  225. classiq/model_expansions/evaluators/parameter_types.py +7 -7
  226. classiq/model_expansions/evaluators/quantum_type_utils.py +2 -1
  227. classiq/model_expansions/evaluators/type_type_match.py +1 -1
  228. classiq/model_expansions/expression_evaluator.py +10 -9
  229. classiq/model_expansions/expression_renamer.py +6 -6
  230. classiq/model_expansions/function_builder.py +13 -12
  231. classiq/model_expansions/generative_functions.py +5 -4
  232. classiq/model_expansions/interpreter.py +20 -11
  233. classiq/model_expansions/model_tables.py +14 -14
  234. classiq/model_expansions/quantum_operations/bind.py +2 -4
  235. classiq/model_expansions/quantum_operations/classicalif.py +1 -1
  236. classiq/model_expansions/quantum_operations/control.py +81 -24
  237. classiq/model_expansions/quantum_operations/emitter.py +33 -20
  238. classiq/model_expansions/quantum_operations/expression_operation.py +47 -16
  239. classiq/model_expansions/quantum_operations/inplace_binary_operation.py +160 -35
  240. classiq/model_expansions/quantum_operations/phase.py +6 -6
  241. classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +28 -31
  242. classiq/model_expansions/quantum_operations/quantum_function_call.py +9 -0
  243. classiq/model_expansions/quantum_operations/repeat.py +1 -3
  244. classiq/model_expansions/quantum_operations/within_apply.py +0 -16
  245. classiq/model_expansions/scope.py +11 -10
  246. classiq/model_expansions/scope_initialization.py +5 -5
  247. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +6 -6
  248. classiq/model_expansions/sympy_conversion/sympy_to_python.py +2 -2
  249. classiq/model_expansions/visitors/variable_references.py +5 -4
  250. classiq/qmod/builtins/classical_execution_primitives.py +9 -9
  251. classiq/qmod/builtins/functions/__init__.py +72 -55
  252. classiq/qmod/builtins/functions/amplitude_estimation.py +4 -1
  253. classiq/qmod/builtins/functions/arithmetic.py +14 -1
  254. classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +86 -6
  255. classiq/qmod/builtins/functions/grover.py +41 -45
  256. classiq/qmod/builtins/functions/hea.py +60 -4
  257. classiq/qmod/builtins/functions/linear_pauli_rotation.py +26 -4
  258. classiq/qmod/builtins/functions/modular_exponentiation.py +90 -29
  259. classiq/qmod/builtins/functions/operators.py +1 -1
  260. classiq/qmod/builtins/functions/qaoa_penalty.py +14 -5
  261. classiq/qmod/builtins/functions/qft_functions.py +57 -0
  262. classiq/qmod/builtins/functions/qpe.py +20 -4
  263. classiq/qmod/builtins/functions/qsvt.py +49 -4
  264. classiq/qmod/builtins/functions/standard_gates.py +4 -4
  265. classiq/qmod/builtins/functions/state_preparation.py +92 -10
  266. classiq/qmod/builtins/functions/swap_test.py +7 -1
  267. classiq/qmod/builtins/functions/utility_functions.py +43 -0
  268. classiq/qmod/builtins/functions/variational.py +18 -2
  269. classiq/qmod/builtins/operations.py +117 -22
  270. classiq/qmod/cfunc.py +2 -2
  271. classiq/qmod/classical_function.py +3 -7
  272. classiq/qmod/create_model_function.py +16 -17
  273. classiq/qmod/declaration_inferrer.py +7 -10
  274. classiq/qmod/expression_query.py +3 -3
  275. classiq/qmod/generative.py +2 -1
  276. classiq/qmod/model_state_container.py +10 -8
  277. classiq/qmod/native/__init__.py +1 -3
  278. classiq/qmod/native/expression_to_qmod.py +9 -8
  279. classiq/qmod/native/pretty_printer.py +12 -6
  280. classiq/qmod/pretty_print/__init__.py +1 -3
  281. classiq/qmod/pretty_print/expression_to_python.py +13 -12
  282. classiq/qmod/pretty_print/pretty_printer.py +38 -23
  283. classiq/qmod/python_classical_type.py +8 -4
  284. classiq/qmod/qfunc.py +4 -4
  285. classiq/qmod/qmod_variable.py +11 -10
  286. classiq/qmod/quantum_expandable.py +12 -15
  287. classiq/qmod/quantum_function.py +35 -22
  288. classiq/qmod/semantics/annotation.py +1 -1
  289. classiq/qmod/semantics/error_manager.py +8 -7
  290. classiq/qmod/semantics/static_semantics_visitor.py +19 -24
  291. classiq/qmod/semantics/validation/constants_validation.py +1 -1
  292. classiq/qmod/semantics/validation/func_call_validation.py +2 -2
  293. classiq/qmod/semantics/validation/main_validation.py +33 -0
  294. classiq/qmod/semantics/validation/types_validation.py +2 -1
  295. classiq/qmod/symbolic.py +5 -8
  296. classiq/qmod/symbolic_type.py +2 -2
  297. classiq/qmod/synthesize_separately.py +1 -2
  298. {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/METADATA +1 -1
  299. {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/RECORD +300 -297
  300. classiq/qmod/builtins/functions/qft.py +0 -23
  301. {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/WHEEL +0 -0
@@ -1,6 +1,5 @@
1
1
  import ast
2
2
  import re
3
- from typing import Tuple
4
3
 
5
4
  from classiq.interface.exceptions import (
6
5
  ClassiqExpansionError,
@@ -23,6 +22,7 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
23
22
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
24
23
  from classiq.interface.model.quantum_type import (
25
24
  QuantumNumeric,
25
+ QuantumType,
26
26
  )
27
27
  from classiq.interface.model.variable_declaration_statement import (
28
28
  VariableDeclarationStatement,
@@ -41,6 +41,10 @@ from classiq.model_expansions.visitors.boolean_expression_transformers import (
41
41
  from classiq.qmod import builtins
42
42
  from classiq.qmod.builtins.functions import X, allocate
43
43
 
44
+ HANDLE_ERROR_MESSAGE = (
45
+ "Quantum variable '{handle_str}' cannot appear on both sides of the assignment"
46
+ )
47
+
44
48
 
45
49
  def _is_constant(expr: str) -> bool:
46
50
  try:
@@ -97,7 +101,7 @@ class QuantumAssignmentOperationEmitter(
97
101
  if (
98
102
  op.operation_kind != ArithmeticOperationKind.InplaceXor
99
103
  or op.result_type.size_in_bits > 1
100
- or not _is_res_boolean(op)
104
+ or not self._is_res_boolean(op)
101
105
  or target.quantum_type.size_in_bits > 1
102
106
  or _is_constant(expression.expr)
103
107
  ):
@@ -129,7 +133,7 @@ class QuantumAssignmentOperationEmitter(
129
133
 
130
134
  def _optimize_boolean_expression(
131
135
  self, op: ArithmeticOperation, expression: Expression
132
- ) -> Tuple[ArithmeticOperation, Expression, bool]:
136
+ ) -> tuple[ArithmeticOperation, Expression, bool]:
133
137
  if (
134
138
  self._interpreter._is_frontend
135
139
  or op.operation_kind
@@ -137,7 +141,8 @@ class QuantumAssignmentOperationEmitter(
137
141
  ArithmeticOperationKind.Assignment,
138
142
  ArithmeticOperationKind.InplaceXor,
139
143
  )
140
- or not _all_vars_boolean(op)
144
+ or not self._all_vars_boolean(op)
145
+ or not self._is_res_boolean(op)
141
146
  ):
142
147
  return op, expression, False
143
148
  optimizer = BooleanExpressionOptimizer()
@@ -150,7 +155,7 @@ class QuantumAssignmentOperationEmitter(
150
155
 
151
156
  def _adapt_boolean_inplace(
152
157
  self, op: ArithmeticOperation, expression: Expression, is_bool_opt: bool
153
- ) -> Tuple[ArithmeticOperation, Expression, bool]:
158
+ ) -> tuple[ArithmeticOperation, Expression, bool]:
154
159
  adapter = BooleanExpressionFuncLibAdapter(is_bool_opt)
155
160
  adapted_expression = self._evaluate_expression(
156
161
  Expression(expr=ast.unparse(adapter.visit(ast.parse(expression.expr))))
@@ -223,34 +228,26 @@ class QuantumAssignmentOperationEmitter(
223
228
  self._interpreter.emit_statement(allocate_call)
224
229
  return True
225
230
 
231
+ @staticmethod
232
+ def _get_updated_op_split_symbols(
233
+ op: QuantumAssignmentOperation,
234
+ symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
235
+ ) -> QuantumAssignmentOperation:
236
+ if op.result_var not in symbol_mapping:
237
+ return op
238
+ handle_str, quantum_type = symbol_mapping[op.result_var]
239
+ if handle_str in op.expression.expr:
240
+ raise ClassiqExpansionError(
241
+ HANDLE_ERROR_MESSAGE.format(handle_str=str(op.result_var))
242
+ )
243
+ new_result_handle = HandleBinding(name=handle_str)
244
+ return op.model_copy(
245
+ update=dict(result_var=new_result_handle, _result_type=quantum_type)
246
+ )
247
+
226
248
 
227
249
  def _validate_naive_inplace_handles(qe: ArithmeticOperation) -> None:
228
250
  if qe.result_var in qe.var_handles:
229
251
  raise ClassiqExpansionError(
230
- f"Quantum variable {qe.result_var.name} cannot appear on both sides of "
231
- f"the ^= assignment"
252
+ HANDLE_ERROR_MESSAGE.format(handle_str=str(qe.result_var))
232
253
  )
233
-
234
-
235
- def _all_vars_boolean(op: ArithmeticOperation) -> bool:
236
- if not all(
237
- var_type.has_size_in_bits and var_type.size_in_bits == 1
238
- for var_type in op.var_types.values()
239
- ):
240
- return False
241
- if any(
242
- isinstance(var_type, QuantumNumeric)
243
- and (var_type.sign_value or var_type.fraction_digits_value > 0)
244
- for var_type in op.var_types.values()
245
- ):
246
- return False
247
- return _is_res_boolean(op)
248
-
249
-
250
- def _is_res_boolean(op: ArithmeticOperation) -> bool:
251
- if not (op.result_type.has_size_in_bits and op.result_type.size_in_bits == 1):
252
- return False
253
- return not (
254
- isinstance(op.result_type, QuantumNumeric)
255
- and (op.result_type.sign_value or op.result_type.fraction_digits_value > 0)
256
- )
@@ -1,11 +1,20 @@
1
+ from typing import TYPE_CHECKING
2
+
1
3
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
2
4
 
3
5
  from classiq.model_expansions.closure import FunctionClosure
4
6
  from classiq.model_expansions.quantum_operations.emitter import Emitter
5
7
  from classiq.qmod.semantics.error_manager import ErrorManager
6
8
 
9
+ if TYPE_CHECKING:
10
+ from classiq.model_expansions.interpreter import Interpreter
11
+
7
12
 
8
13
  class QuantumFunctionCallEmitter(Emitter[QuantumFunctionCall]):
14
+ def __init__(self, interpreter: "Interpreter") -> None:
15
+ super().__init__(interpreter)
16
+ self._model = self._interpreter._model
17
+
9
18
  def emit(self, call: QuantumFunctionCall, /) -> None:
10
19
  function = self._interpreter.evaluate(call.function).as_type(FunctionClosure)
11
20
  args = call.positional_args
@@ -1,5 +1,3 @@
1
- from typing import Type
2
-
3
1
  from classiq.interface.generator.expressions.expression import Expression
4
2
  from classiq.interface.generator.functions.builtins.internal_operators import (
5
3
  REPEAT_OPERATOR_NAME,
@@ -24,7 +22,7 @@ class RepeatEmitter(Emitter[Repeat]):
24
22
  self._emit_propagated(repeat, i)
25
23
 
26
24
  def _emit_propagated(self, repeat: Repeat, i: int) -> None:
27
- closure_constructor: Type[FunctionClosure]
25
+ closure_constructor: type[FunctionClosure]
28
26
  extra_args: dict
29
27
  if repeat.is_generative():
30
28
  closure_constructor = GenerativeFunctionClosure
@@ -1,5 +1,4 @@
1
1
  from classiq.interface.generator.functions.builtins.internal_operators import (
2
- COMPUTE_OPERATOR_NAME,
3
2
  WITHIN_APPLY_NAME,
4
3
  )
5
4
  from classiq.interface.model.within_apply_operation import WithinApply
@@ -26,10 +25,6 @@ class WithinApplyEmitter(Emitter[WithinApply]):
26
25
  }
27
26
  )
28
27
 
29
- if self._should_wrap(within_apply.compute):
30
- self._emit_wrapped(within_apply)
31
- return
32
-
33
28
  self._emit_as_operation(within_apply)
34
29
 
35
30
  def _emit_as_operation(self, within_apply: WithinApply) -> None:
@@ -46,14 +41,3 @@ class WithinApplyEmitter(Emitter[WithinApply]):
46
41
  source_ref=within_apply.source_ref,
47
42
  )
48
43
  )
49
-
50
- def _emit_wrapped(self, within_apply: WithinApply) -> None:
51
- wrapped_compute = self._create_expanded_wrapping_function(
52
- COMPUTE_OPERATOR_NAME, within_apply.compute
53
- )
54
- wrapped_within_apply = WithinApply(
55
- compute=[wrapped_compute],
56
- action=within_apply.action,
57
- source_ref=within_apply.source_ref,
58
- )
59
- self._builder.emit_statement(wrapped_within_apply)
@@ -1,9 +1,10 @@
1
1
  import itertools
2
2
  from collections import UserDict
3
+ from collections.abc import Iterator
3
4
  from contextlib import contextmanager
4
5
  from dataclasses import dataclass
5
6
  from functools import singledispatch
6
- from typing import TYPE_CHECKING, Any, Dict, Iterator, Optional, Type, TypeVar, Union
7
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
7
8
 
8
9
  from classiq.interface.exceptions import (
9
10
  ClassiqExpansionError,
@@ -104,7 +105,7 @@ class QuantumSymbol:
104
105
  )
105
106
 
106
107
  @property
107
- def fields(self) -> Dict[str, "QuantumSymbol"]:
108
+ def fields(self) -> dict[str, "QuantumSymbol"]:
108
109
  quantum_type = self.quantum_type
109
110
  if not isinstance(quantum_type, TypeName):
110
111
  raise ClassiqExpansionError(
@@ -120,18 +121,18 @@ class QuantumSymbol:
120
121
 
121
122
 
122
123
  @singledispatch
123
- def _evaluated_to_str(value: Any) -> str:
124
+ def evaluated_to_str(value: Any) -> str:
124
125
  return str(value)
125
126
 
126
127
 
127
- @_evaluated_to_str.register
128
+ @evaluated_to_str.register
128
129
  def _evaluated_to_str_list(value: list) -> str:
129
- return f"[{', '.join(_evaluated_to_str(x) for x in value)}]"
130
+ return f"[{', '.join(evaluated_to_str(x) for x in value)}]"
130
131
 
131
132
 
132
- @_evaluated_to_str.register
133
+ @evaluated_to_str.register
133
134
  def _evaluated_to_str_struct_literal(value: QmodStructInstance) -> str:
134
- return f"struct_literal({value.struct_declaration.name}, {', '.join(f'{k}={_evaluated_to_str(v)}' for k, v in value.fields.items())})"
135
+ return f"struct_literal({value.struct_declaration.name}, {', '.join(f'{k}={evaluated_to_str(v)}' for k, v in value.fields.items())})"
135
136
 
136
137
 
137
138
  @dataclass(frozen=True)
@@ -139,7 +140,7 @@ class Evaluated: # FIXME: Merge with EvaluatedExpression if possible
139
140
  value: Any
140
141
  defining_function: Optional["Closure"] = None
141
142
 
142
- def as_type(self, t: Type[T]) -> T:
143
+ def as_type(self, t: type[T]) -> T:
143
144
  if t is int:
144
145
  return self._as_int() # type: ignore[return-value]
145
146
 
@@ -162,7 +163,7 @@ class Evaluated: # FIXME: Merge with EvaluatedExpression if possible
162
163
  if isinstance(self.value, QuantumSymbol):
163
164
  return self.value.emit()
164
165
 
165
- ret = Expression(expr=_evaluated_to_str(self.value))
166
+ ret = Expression(expr=evaluated_to_str(self.value))
166
167
  ret._evaluated_expr = EvaluatedExpression(value=self.value)
167
168
  return ret
168
169
 
@@ -176,7 +177,7 @@ else:
176
177
  class Scope(EvaluatedUserDict):
177
178
  def __init__(
178
179
  self,
179
- data: Optional[Dict[str, Evaluated]] = None,
180
+ data: Optional[dict[str, Evaluated]] = None,
180
181
  /,
181
182
  *,
182
183
  parent: Optional["Scope"] = None,
@@ -1,4 +1,4 @@
1
- from typing import List, Sequence
1
+ from collections.abc import Sequence
2
2
 
3
3
  from classiq.interface.exceptions import ClassiqError
4
4
  from classiq.interface.generator.constant import Constant
@@ -43,7 +43,7 @@ def get_main_renamer(
43
43
  return ExpressionRenamer(var_mapping={})
44
44
 
45
45
 
46
- def _add_constants_to_scope(constants: List[Constant], scope: Scope) -> None:
46
+ def _add_constants_to_scope(constants: list[Constant], scope: Scope) -> None:
47
47
  for constant in constants:
48
48
  scope[constant.name] = Evaluated(
49
49
  value=evaluate_classical_expression(constant.value, scope).value
@@ -51,7 +51,7 @@ def _add_constants_to_scope(constants: List[Constant], scope: Scope) -> None:
51
51
 
52
52
 
53
53
  def _add_functions_to_scope(
54
- functions: List[NativeFunctionDefinition], scope: Scope
54
+ functions: list[NativeFunctionDefinition], scope: Scope
55
55
  ) -> None:
56
56
  for function in functions:
57
57
  scope[function.name] = Evaluated(
@@ -65,7 +65,7 @@ def _add_functions_to_scope(
65
65
 
66
66
 
67
67
  def _add_generative_functions_to_scope(
68
- functions: List[GenerativeQFunc], scope: Scope
68
+ functions: list[GenerativeQFunc], scope: Scope
69
69
  ) -> None:
70
70
  for function in functions:
71
71
  scope[function.func_decl.name] = Evaluated(
@@ -138,7 +138,7 @@ def add_entry_point_params_to_scope(
138
138
 
139
139
 
140
140
  def init_top_level_scope(
141
- model: Model, generative_functions: List[GenerativeQFunc], scope: Scope
141
+ model: Model, generative_functions: list[GenerativeQFunc], scope: Scope
142
142
  ) -> None:
143
143
  _add_functions_to_scope(model.functions, scope)
144
144
  _add_generative_functions_to_scope(generative_functions, scope)
@@ -1,5 +1,5 @@
1
1
  import ast
2
- from typing import TYPE_CHECKING, Dict, Type, cast
2
+ from typing import TYPE_CHECKING, cast
3
3
 
4
4
  from classiq.interface.exceptions import ClassiqExpansionError
5
5
 
@@ -18,29 +18,29 @@ def translate_to_sympy(expr: str) -> str:
18
18
 
19
19
 
20
20
  class ExpressionSympyTranslator(ast.NodeTransformer):
21
- BINARY_OPERATORS: Dict[Type[ast.AST], str] = {
21
+ BINARY_OPERATORS: dict[type[ast.AST], str] = {
22
22
  ast.BitOr: "BitwiseOr",
23
23
  ast.BitAnd: "BitwiseAnd",
24
24
  ast.BitXor: "BitwiseXor",
25
25
  ast.Div: "do_div",
26
26
  }
27
27
 
28
- UNARY_OPERATORS: Dict[Type[ast.AST], str] = {
28
+ UNARY_OPERATORS: dict[type[ast.AST], str] = {
29
29
  ast.Invert: "BitwiseNot",
30
30
  ast.Not: "Not",
31
31
  }
32
32
 
33
- BOOLEAN_OPERATORS: Dict[Type[ast.AST], str] = {
33
+ BOOLEAN_OPERATORS: dict[type[ast.AST], str] = {
34
34
  ast.Or: "Or",
35
35
  ast.And: "And",
36
36
  }
37
37
 
38
- COMPARE_OPERATORS: Dict[Type[ast.AST], str] = {
38
+ COMPARE_OPERATORS: dict[type[ast.AST], str] = {
39
39
  ast.Eq: "Eq",
40
40
  ast.NotEq: "Ne",
41
41
  }
42
42
 
43
- SPECIAL_FUNCTIONS: Dict[str, str] = {
43
+ SPECIAL_FUNCTIONS: dict[str, str] = {
44
44
  "max": "Max",
45
45
  "min": "Min",
46
46
  }
@@ -1,5 +1,5 @@
1
1
  import functools
2
- from typing import Any, Dict, Optional, get_args
2
+ from typing import Any, Optional, get_args
3
3
 
4
4
  from sympy import (
5
5
  Array,
@@ -22,7 +22,7 @@ from classiq.model_expansions.sympy_conversion.arithmetics import LogicalXor
22
22
 
23
23
 
24
24
  def sympy_to_python(
25
- value: Any, locals: Optional[Dict[str, ExpressionValue]] = None
25
+ value: Any, locals: Optional[dict[str, ExpressionValue]] = None
26
26
  ) -> ExpressionValue:
27
27
  if isinstance(value, Integer):
28
28
  value = int(value)
@@ -1,6 +1,7 @@
1
1
  import ast
2
+ from collections.abc import Iterator
2
3
  from contextlib import contextmanager
3
- from typing import Dict, Iterator, List, Optional, Union
4
+ from typing import Optional, Union
4
5
 
5
6
  from classiq.interface.exceptions import (
6
7
  ClassiqExpansionError,
@@ -23,12 +24,12 @@ from classiq.interface.model.handle_binding import (
23
24
 
24
25
  class VarRefCollector(ast.NodeVisitor):
25
26
  def __init__(self, ignore_duplicated_handles: bool = False) -> None:
26
- self._var_handles: Dict[HandleBinding, bool] = {}
27
+ self._var_handles: dict[HandleBinding, bool] = {}
27
28
  self._ignore_duplicated_handles = ignore_duplicated_handles
28
29
  self._is_nested = False
29
30
 
30
31
  @property
31
- def var_handles(self) -> List[HandleBinding]:
32
+ def var_handles(self) -> list[HandleBinding]:
32
33
  return list(self._var_handles)
33
34
 
34
35
  def visit(self, node: ast.AST) -> Union[
@@ -110,7 +111,7 @@ class VarRefCollector(ast.NodeVisitor):
110
111
 
111
112
 
112
113
  class VarRefTransformer(ast.NodeTransformer):
113
- def __init__(self, var_mapping: Dict[str, str]) -> None:
114
+ def __init__(self, var_mapping: dict[str, str]) -> None:
114
115
  self.var_mapping = var_mapping
115
116
 
116
117
  def visit_Name(self, node: ast.Name) -> ast.Name:
@@ -1,4 +1,4 @@
1
- from typing import Dict, Final, List, Optional, Union
1
+ from typing import Final, Optional, Union
2
2
 
3
3
  from classiq.interface.exceptions import ClassiqError
4
4
  from classiq.interface.executor.execution_preferences import QaeWithQpeEstimationMethod
@@ -15,7 +15,7 @@ from classiq.interface.generator.functions.qmod_python_interface import QmodPySt
15
15
  from classiq.applications.qsvm.qsvm import Data, Labels
16
16
  from classiq.qmod.builtins.enums import Optimizer
17
17
 
18
- ExecutionParams = Dict[str, Union[float, int, List[int], List[float]]]
18
+ ExecutionParams = dict[str, Union[float, int, list[int], list[float]]]
19
19
 
20
20
  _CALL_IN_QFUNC_ERROR = (
21
21
  'Cannot call "{}" in a quantum context. "{}" is a classical execution primitive.'
@@ -39,28 +39,28 @@ def sample( # type: ignore[return]
39
39
 
40
40
 
41
41
  def batch_sample( # type: ignore[return]
42
- batch_execution_params: List[ExecutionParams],
42
+ batch_execution_params: list[ExecutionParams],
43
43
  ) -> MultipleExecutionDetails:
44
44
  _raise_error("batch_sample")
45
45
 
46
46
 
47
47
  def estimate( # type: ignore[return]
48
- hamiltonian: List[QmodPyStruct], execution_params: Optional[ExecutionParams] = None
48
+ hamiltonian: list[QmodPyStruct], execution_params: Optional[ExecutionParams] = None
49
49
  ) -> EstimationResult:
50
50
  _raise_error("estimate")
51
51
 
52
52
 
53
53
  def batch_estimate( # type: ignore[return]
54
- hamiltonian: List[QmodPyStruct],
55
- batch_execution_params: List[ExecutionParams],
54
+ hamiltonian: list[QmodPyStruct],
55
+ batch_execution_params: list[ExecutionParams],
56
56
  ) -> EstimationResults:
57
57
  _raise_error("batch_estimate")
58
58
 
59
59
 
60
60
  def vqe( # type: ignore[return]
61
- hamiltonian: List[QmodPyStruct],
61
+ hamiltonian: list[QmodPyStruct],
62
62
  maximize: bool,
63
- initial_point: List[float],
63
+ initial_point: list[float],
64
64
  optimizer: Optimizer,
65
65
  max_iteration: int,
66
66
  tolerance: float,
@@ -118,5 +118,5 @@ __all__ = [
118
118
  ]
119
119
 
120
120
 
121
- def __dir__() -> List[str]:
121
+ def __dir__() -> list[str]:
122
122
  return __all__
@@ -1,3 +1,6 @@
1
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
2
+
3
+ from ...quantum_function import GenerativeQFunc
1
4
  from .amplitude_estimation import *
2
5
  from .arithmetic import *
3
6
  from .benchmarking import *
@@ -14,7 +17,7 @@ from .modular_exponentiation import *
14
17
  from .modular_exponentiation import _check_msb, _ctrl_x
15
18
  from .operators import *
16
19
  from .qaoa_penalty import *
17
- from .qft import *
20
+ from .qft_functions import *
18
21
  from .qpe import *
19
22
  from .qsvm import *
20
23
  from .qsvt import *
@@ -22,6 +25,7 @@ from .standard_gates import *
22
25
  from .state_preparation import *
23
26
  from .state_preparation import _prepare_uniform_trimmed_state_step
24
27
  from .swap_test import *
28
+ from .utility_functions import *
25
29
  from .variational import *
26
30
 
27
31
  CORE_LIB_DECLS = [
@@ -86,62 +90,75 @@ CORE_LIB_DECLS = [
86
90
  )
87
91
  ]
88
92
 
93
+ OPEN_LIBRARY_UNPROCESSED_FUNCTIONS = [
94
+ qpe_flexible,
95
+ qpe,
96
+ _single_pauli,
97
+ linear_pauli_rotations,
98
+ amplitude_estimation,
99
+ phase_oracle,
100
+ reflect_about_zero,
101
+ grover_diffuser,
102
+ grover_operator,
103
+ grover_search,
104
+ hadamard_transform,
105
+ apply_to_all,
106
+ qft_no_swap,
107
+ qft_space_add_const,
108
+ cc_modular_add,
109
+ c_modular_multiply,
110
+ multiswap,
111
+ inplace_c_modular_multiply,
112
+ modular_exp,
113
+ qsvt_step,
114
+ qsvt,
115
+ projector_controlled_phase,
116
+ qsvt_inversion,
117
+ allocate_num,
118
+ qaoa_mixer_layer,
119
+ qaoa_cost_layer,
120
+ qaoa_layer,
121
+ qaoa_init,
122
+ qaoa_penalty,
123
+ full_hea,
124
+ swap_test,
125
+ prepare_uniform_trimmed_state,
126
+ prepare_uniform_interval_state,
127
+ prepare_ghz_state,
128
+ prepare_exponential_state,
129
+ prepare_bell_state,
130
+ inplace_prepare_int,
131
+ prepare_int,
132
+ switch,
133
+ qct_qst_type1,
134
+ qct_qst_type2,
135
+ qct_type2,
136
+ qst_type2,
137
+ modular_increment,
138
+ qft,
139
+ _ctrl_x,
140
+ _prepare_uniform_trimmed_state_step,
141
+ _qct_d_operator,
142
+ _qct_pi_operator,
143
+ _check_msb,
144
+ encode_in_angle,
145
+ encode_on_bloch,
146
+ ]
147
+
148
+ OPEN_LIBRARY_FUNCTIONS: list[NativeFunctionDefinition] = []
149
+
150
+
151
+ def load_open_library_implementations() -> None:
152
+ OPEN_LIBRARY_FUNCTIONS.extend(
153
+ [func.get_implementation() for func in OPEN_LIBRARY_UNPROCESSED_FUNCTIONS]
154
+ )
155
+
156
+
157
+ OPEN_LIBRARY_GENERATIVE_FUNCTIONS: list[GenerativeQFunc] = []
158
+
89
159
  OPEN_LIB_DECLS = [
90
160
  func.func_decl
91
- for func in (
92
- qpe_flexible,
93
- qpe,
94
- _single_pauli,
95
- linear_pauli_rotations,
96
- amplitude_estimation,
97
- phase_oracle,
98
- reflect_about_zero,
99
- grover_diffuser,
100
- grover_operator,
101
- grover_search,
102
- hadamard_transform,
103
- apply_to_all,
104
- qft_no_swap,
105
- qft_space_add_const,
106
- cc_modular_add,
107
- c_modular_multiply,
108
- multiswap,
109
- inplace_c_modular_multiply,
110
- modular_exp,
111
- qsvt_step,
112
- qsvt,
113
- projector_controlled_phase,
114
- qsvt_inversion,
115
- allocate_num,
116
- qaoa_mixer_layer,
117
- qaoa_cost_layer,
118
- qaoa_layer,
119
- qaoa_init,
120
- qaoa_penalty,
121
- full_hea,
122
- swap_test,
123
- prepare_uniform_trimmed_state,
124
- prepare_uniform_interval_state,
125
- prepare_ghz_state,
126
- prepare_exponential_state,
127
- prepare_bell_state,
128
- inplace_prepare_int,
129
- prepare_int,
130
- switch,
131
- qct_qst_type1,
132
- qct_qst_type2,
133
- qct_type2,
134
- qst_type2,
135
- modular_increment,
136
- qft,
137
- _ctrl_x,
138
- _prepare_uniform_trimmed_state_step,
139
- _qct_d_operator,
140
- _qct_pi_operator,
141
- _check_msb,
142
- encode_in_angle,
143
- encode_on_bloch,
144
- )
161
+ for func in OPEN_LIBRARY_GENERATIVE_FUNCTIONS + OPEN_LIBRARY_UNPROCESSED_FUNCTIONS
145
162
  ]
146
163
 
147
164
  STD_QMOD_OPERATORS = [func.func_decl for func in (apply, permute)]
@@ -1,3 +1,5 @@
1
+ from classiq.qmod.builtins.functions.grover import grover_operator
2
+ from classiq.qmod.builtins.functions.qpe import qpe
1
3
  from classiq.qmod.qfunc import qfunc
2
4
  from classiq.qmod.qmod_variable import QArray, QBit, QNum
3
5
  from classiq.qmod.quantum_callable import QCallable
@@ -24,4 +26,5 @@ def amplitude_estimation(
24
26
  phase: Assuming this variable starts from the zero state -this variable output holds the $phase=\\theta$ result in the [0,1] domain, which relates to the estimated probability $a$ through $a=\\sin^2(\\pi \\theta)$.
25
27
  packed_vars: The variable that holds the state to be estimated. Assumed to be in the zero state at the beginning of the algorithm.
26
28
  """
27
- pass
29
+ space_transform(packed_vars)
30
+ qpe(lambda: grover_operator(oracle, space_transform, packed_vars), phase)
@@ -1,9 +1,13 @@
1
1
  from typing import Literal
2
2
 
3
+ from classiq.qmod.builtins.functions.qft_functions import qft
4
+ from classiq.qmod.builtins.functions.standard_gates import PHASE
5
+ from classiq.qmod.builtins.operations import bind, repeat, within_apply
3
6
  from classiq.qmod.cparam import CInt
4
7
  from classiq.qmod.qfunc import qfunc
5
8
  from classiq.qmod.qmod_parameter import CArray, CReal
6
9
  from classiq.qmod.qmod_variable import Output, QArray, QBit, QNum
10
+ from classiq.qmod.symbolic import pi
7
11
 
8
12
 
9
13
  @qfunc(external=True)
@@ -75,4 +79,13 @@ def modular_increment(a: CInt, x: QNum) -> None:
75
79
  x: A quantum number that is assumed to be non-negative integer.
76
80
 
77
81
  """
78
- pass
82
+ array_cast: QArray = QArray("array_cast")
83
+ within_apply(
84
+ lambda: ( # type:ignore[arg-type]
85
+ bind(x, array_cast), # type:ignore[func-returns-value]
86
+ qft(array_cast),
87
+ ),
88
+ lambda: repeat(
89
+ x.size, lambda i: PHASE(a * 2 * pi * 2**i / (2**x.size), array_cast[i])
90
+ ),
91
+ )