classiq 0.37.1__py3-none-any.whl → 0.65.3__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 (516) hide show
  1. classiq/__init__.py +49 -34
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +3 -2
  3. classiq/_analyzer_extras/interactive_hardware.py +3 -3
  4. classiq/_internals/api_wrapper.py +241 -95
  5. classiq/_internals/async_utils.py +2 -77
  6. classiq/_internals/authentication/auth0.py +26 -10
  7. classiq/_internals/authentication/authentication.py +11 -0
  8. classiq/_internals/authentication/device.py +18 -8
  9. classiq/_internals/authentication/password_manager.py +40 -13
  10. classiq/_internals/authentication/token_manager.py +11 -6
  11. classiq/_internals/client.py +106 -37
  12. classiq/_internals/config.py +3 -4
  13. classiq/_internals/host_checker.py +38 -15
  14. classiq/_internals/jobs.py +56 -50
  15. classiq/_internals/type_validation.py +9 -9
  16. classiq/analyzer/__init__.py +1 -3
  17. classiq/analyzer/analyzer.py +50 -47
  18. classiq/analyzer/analyzer_utilities.py +15 -15
  19. classiq/analyzer/rb.py +19 -20
  20. classiq/analyzer/show_interactive_hack.py +30 -7
  21. classiq/analyzer/url_utils.py +2 -3
  22. classiq/applications/__init__.py +3 -12
  23. classiq/applications/chemistry/__init__.py +14 -10
  24. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  25. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +170 -170
  26. classiq/applications/chemistry/ground_state_problem.py +1 -1
  27. classiq/applications/combinatorial_helpers/allowed_constraints.py +23 -0
  28. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
  29. classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
  30. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +166 -0
  31. classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
  32. classiq/applications/combinatorial_helpers/encoding_utils.py +124 -0
  33. classiq/applications/combinatorial_helpers/memory.py +75 -0
  34. classiq/applications/combinatorial_helpers/optimization_model.py +193 -0
  35. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
  36. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  37. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  38. classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
  39. classiq/applications/combinatorial_helpers/transformations/encoding.py +189 -0
  40. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +143 -0
  41. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +120 -0
  42. classiq/applications/combinatorial_helpers/transformations/penalty.py +31 -0
  43. classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
  44. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +74 -0
  45. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +87 -0
  46. classiq/applications/combinatorial_optimization/__init__.py +24 -5
  47. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  48. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +137 -0
  49. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  50. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  51. classiq/applications/finance/__init__.py +4 -5
  52. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +50 -57
  53. classiq/applications/grover/__init__.py +9 -0
  54. classiq/applications/grover/grover_model_constructor.py +157 -0
  55. classiq/applications/hamiltonian/__init__.py +0 -0
  56. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  57. classiq/applications/libraries/__init__.py +0 -0
  58. classiq/applications/libraries/qmci_library.py +22 -0
  59. classiq/applications/qnn/__init__.py +2 -4
  60. classiq/applications/qnn/circuit_utils.py +8 -8
  61. classiq/applications/qnn/datasets/__init__.py +9 -11
  62. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  63. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  64. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  65. classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
  66. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  67. classiq/applications/qnn/qlayer.py +30 -10
  68. classiq/applications/qnn/torch_utils.py +4 -3
  69. classiq/applications/qnn/types.py +7 -7
  70. classiq/applications/qsvm/__init__.py +6 -4
  71. classiq/applications/qsvm/qsvm.py +4 -10
  72. classiq/applications/qsvm/qsvm_data_generation.py +5 -8
  73. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  74. classiq/execution/__init__.py +8 -3
  75. classiq/execution/all_hardware_devices.py +11 -0
  76. classiq/execution/execution_session.py +400 -0
  77. classiq/execution/iqcc.py +63 -0
  78. classiq/execution/jobs.py +197 -25
  79. classiq/execution/qnn.py +79 -0
  80. classiq/executor.py +23 -117
  81. classiq/interface/_version.py +1 -1
  82. classiq/interface/analyzer/analysis_params.py +49 -16
  83. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  84. classiq/interface/analyzer/result.py +36 -32
  85. classiq/interface/applications/qsvm.py +28 -25
  86. classiq/interface/ast_node.py +16 -0
  87. classiq/interface/backend/backend_preferences.py +390 -119
  88. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  89. classiq/interface/backend/pydantic_backend.py +27 -22
  90. classiq/interface/backend/quantum_backend_providers.py +70 -16
  91. classiq/interface/chemistry/fermionic_operator.py +43 -32
  92. classiq/interface/chemistry/ground_state_problem.py +42 -24
  93. classiq/interface/chemistry/molecule.py +20 -14
  94. classiq/interface/chemistry/operator.py +75 -236
  95. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  96. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +2 -4
  97. classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
  98. classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
  99. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  100. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  101. classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
  102. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  103. classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
  104. classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
  105. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  106. classiq/interface/combinatorial_optimization/examples/set_cover.py +3 -3
  107. classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
  108. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
  109. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +14 -9
  110. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  111. classiq/interface/combinatorial_optimization/result.py +1 -3
  112. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  113. classiq/interface/debug_info/__init__.py +0 -0
  114. classiq/interface/debug_info/debug_info.py +86 -0
  115. classiq/interface/exceptions.py +201 -0
  116. classiq/interface/execution/iqcc.py +19 -0
  117. classiq/interface/execution/jobs.py +15 -12
  118. classiq/interface/execution/primitives.py +18 -0
  119. classiq/interface/executor/constants.py +1 -0
  120. classiq/interface/executor/estimation.py +2 -2
  121. classiq/interface/executor/execution_preferences.py +26 -143
  122. classiq/interface/executor/execution_request.py +36 -56
  123. classiq/interface/executor/execution_result.py +30 -8
  124. classiq/interface/executor/iqae_result.py +4 -6
  125. classiq/interface/executor/optimizer_preferences.py +34 -22
  126. classiq/interface/executor/{quantum_program.py → quantum_code.py} +44 -34
  127. classiq/interface/executor/quantum_instruction_set.py +3 -2
  128. classiq/interface/executor/register_initialization.py +12 -17
  129. classiq/interface/executor/result.py +122 -64
  130. classiq/interface/executor/vqe_result.py +11 -11
  131. classiq/interface/finance/function_input.py +42 -19
  132. classiq/interface/finance/gaussian_model_input.py +7 -5
  133. classiq/interface/finance/log_normal_model_input.py +6 -4
  134. classiq/interface/finance/model_input.py +6 -4
  135. classiq/interface/generator/adjacency.py +1 -3
  136. classiq/interface/generator/amplitude_loading.py +27 -14
  137. classiq/interface/generator/ansatz_library.py +5 -5
  138. classiq/interface/generator/application_apis/__init__.py +1 -0
  139. classiq/interface/generator/application_apis/arithmetic_declarations.py +17 -0
  140. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  141. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  142. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  143. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  144. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  145. classiq/interface/generator/arith/argument_utils.py +57 -6
  146. classiq/interface/generator/arith/arithmetic.py +37 -16
  147. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +15 -17
  148. classiq/interface/generator/arith/arithmetic_expression_abc.py +70 -26
  149. classiq/interface/generator/arith/arithmetic_expression_parser.py +18 -12
  150. classiq/interface/generator/arith/arithmetic_expression_validator.py +61 -43
  151. classiq/interface/generator/arith/arithmetic_operations.py +19 -16
  152. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  153. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  154. classiq/interface/generator/arith/ast_node_rewrite.py +4 -3
  155. classiq/interface/generator/arith/binary_ops.py +375 -139
  156. classiq/interface/generator/arith/endianness.py +1 -1
  157. classiq/interface/generator/arith/extremum_operations.py +96 -23
  158. classiq/interface/generator/arith/logical_ops.py +16 -12
  159. classiq/interface/generator/arith/machine_precision.py +3 -0
  160. classiq/interface/generator/arith/number_utils.py +44 -48
  161. classiq/interface/generator/arith/register_user_input.py +70 -27
  162. classiq/interface/generator/arith/unary_ops.py +57 -46
  163. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  164. classiq/interface/generator/builtin_api_builder.py +2 -9
  165. classiq/interface/generator/chemistry_function_params.py +5 -5
  166. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  167. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  168. classiq/interface/generator/commuting_pauli_exponentiation.py +8 -6
  169. classiq/interface/generator/compiler_keywords.py +8 -0
  170. classiq/interface/generator/complex_type.py +13 -25
  171. classiq/interface/generator/constant.py +3 -4
  172. classiq/interface/generator/control_state.py +35 -28
  173. classiq/interface/generator/copy.py +47 -0
  174. classiq/interface/generator/custom_ansatz.py +2 -5
  175. classiq/interface/generator/distance.py +3 -5
  176. classiq/interface/generator/excitations.py +3 -2
  177. classiq/interface/generator/expressions/atomic_expression_functions.py +26 -8
  178. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  179. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  180. classiq/interface/generator/expressions/evaluated_expression.py +21 -7
  181. classiq/interface/generator/expressions/expression.py +27 -15
  182. classiq/interface/generator/expressions/expression_constants.py +9 -3
  183. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  184. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  185. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +59 -0
  186. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  187. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  188. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  189. classiq/interface/generator/expressions/sympy_supported_expressions.py +20 -11
  190. classiq/interface/generator/finance.py +3 -3
  191. classiq/interface/generator/function_param_library.py +6 -6
  192. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  193. classiq/interface/generator/function_params.py +42 -69
  194. classiq/interface/generator/functions/__init__.py +0 -22
  195. classiq/interface/generator/functions/builtins/__init__.py +0 -0
  196. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  197. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  198. classiq/interface/generator/functions/classical_type.py +47 -166
  199. classiq/interface/generator/functions/concrete_types.py +55 -0
  200. classiq/interface/generator/functions/function_declaration.py +13 -14
  201. classiq/interface/generator/functions/port_declaration.py +1 -13
  202. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  203. classiq/interface/generator/functions/type_name.py +90 -0
  204. classiq/interface/generator/generated_circuit_data.py +155 -22
  205. classiq/interface/generator/grover_diffuser.py +32 -25
  206. classiq/interface/generator/grover_operator.py +34 -23
  207. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  208. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  209. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +12 -8
  210. classiq/interface/generator/hardware/hardware_data.py +76 -36
  211. classiq/interface/generator/hardware_efficient_ansatz.py +38 -17
  212. classiq/interface/generator/hartree_fock.py +14 -4
  213. classiq/interface/generator/identity.py +10 -6
  214. classiq/interface/generator/linear_pauli_rotations.py +33 -19
  215. classiq/interface/generator/mcmt_method.py +1 -1
  216. classiq/interface/generator/mcu.py +20 -16
  217. classiq/interface/generator/mcx.py +29 -20
  218. classiq/interface/generator/model/__init__.py +2 -5
  219. classiq/interface/generator/model/constraints.py +27 -8
  220. classiq/interface/generator/model/model.py +32 -203
  221. classiq/interface/generator/model/preferences/preferences.py +118 -43
  222. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +27 -22
  223. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  224. classiq/interface/generator/oracles/custom_oracle.py +17 -13
  225. classiq/interface/generator/oracles/oracle_abc.py +9 -9
  226. classiq/interface/generator/partitioned_register.py +7 -7
  227. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  228. classiq/interface/generator/preferences/optimization.py +1 -2
  229. classiq/interface/generator/qpe.py +47 -34
  230. classiq/interface/generator/qsvm.py +13 -17
  231. classiq/interface/generator/quantum_function_call.py +107 -87
  232. classiq/interface/generator/{generated_circuit.py → quantum_program.py} +50 -37
  233. classiq/interface/generator/range_types.py +13 -12
  234. classiq/interface/generator/register_role.py +18 -6
  235. classiq/interface/generator/slice_parsing_utils.py +11 -6
  236. classiq/interface/generator/standard_gates/controlled_standard_gates.py +32 -39
  237. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  238. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  239. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  240. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  241. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  242. classiq/interface/generator/state_preparation/distributions.py +16 -15
  243. classiq/interface/generator/state_preparation/metrics.py +5 -7
  244. classiq/interface/generator/state_preparation/state_preparation.py +30 -23
  245. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  246. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  247. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  248. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  249. classiq/interface/generator/types/compilation_metadata.py +6 -0
  250. classiq/interface/generator/types/enum_declaration.py +54 -0
  251. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  252. classiq/interface/generator/types/struct_declaration.py +15 -14
  253. classiq/interface/generator/ucc.py +9 -6
  254. classiq/interface/generator/unitary_gate.py +10 -6
  255. classiq/interface/generator/user_defined_function_params.py +4 -1
  256. classiq/interface/generator/validations/flow_graph.py +11 -9
  257. classiq/interface/generator/validations/validator_functions.py +8 -6
  258. classiq/interface/generator/visitor.py +23 -16
  259. classiq/interface/hardware.py +31 -10
  260. classiq/interface/helpers/classproperty.py +8 -0
  261. classiq/interface/helpers/custom_encoders.py +3 -0
  262. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  263. classiq/interface/helpers/datastructures.py +26 -0
  264. classiq/interface/helpers/hashable_mixin.py +3 -2
  265. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  266. classiq/interface/helpers/pydantic_model_helpers.py +7 -11
  267. classiq/interface/helpers/validation_helpers.py +4 -21
  268. classiq/interface/helpers/versioned_model.py +1 -1
  269. classiq/interface/ide/ide_data.py +16 -20
  270. classiq/interface/ide/visual_model.py +130 -0
  271. classiq/interface/interface_version.py +1 -0
  272. classiq/interface/jobs.py +35 -6
  273. classiq/interface/model/allocate.py +16 -0
  274. classiq/interface/model/bind_operation.py +44 -14
  275. classiq/interface/model/classical_if.py +15 -0
  276. classiq/interface/model/classical_parameter_declaration.py +33 -3
  277. classiq/interface/model/control.py +45 -0
  278. classiq/interface/model/handle_binding.py +298 -20
  279. classiq/interface/model/inplace_binary_operation.py +31 -26
  280. classiq/interface/model/invert.py +12 -0
  281. classiq/interface/model/model.py +87 -73
  282. classiq/interface/model/native_function_definition.py +16 -21
  283. classiq/interface/model/parameter.py +13 -0
  284. classiq/interface/model/phase_operation.py +11 -0
  285. classiq/interface/model/port_declaration.py +27 -9
  286. classiq/interface/model/power.py +14 -0
  287. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +38 -21
  288. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  289. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  290. classiq/interface/model/quantum_function_call.py +146 -462
  291. classiq/interface/model/quantum_function_declaration.py +193 -152
  292. classiq/interface/model/quantum_lambda_function.py +65 -0
  293. classiq/interface/model/quantum_statement.py +71 -12
  294. classiq/interface/model/quantum_type.py +205 -67
  295. classiq/interface/model/quantum_variable_declaration.py +4 -26
  296. classiq/interface/model/repeat.py +15 -0
  297. classiq/interface/model/statement_block.py +58 -0
  298. classiq/interface/model/validation_handle.py +13 -6
  299. classiq/interface/model/variable_declaration_statement.py +3 -1
  300. classiq/interface/model/within_apply_operation.py +13 -0
  301. classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
  302. classiq/interface/server/global_versions.py +6 -7
  303. classiq/interface/server/routes.py +22 -21
  304. classiq/interface/source_reference.py +59 -0
  305. classiq/model_expansions/__init__.py +0 -0
  306. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  307. classiq/model_expansions/capturing/__init__.py +0 -0
  308. classiq/model_expansions/capturing/captured_vars.py +435 -0
  309. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  310. classiq/model_expansions/closure.py +171 -0
  311. classiq/model_expansions/debug_flag.py +3 -0
  312. classiq/model_expansions/evaluators/__init__.py +0 -0
  313. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  314. classiq/model_expansions/evaluators/argument_types.py +42 -0
  315. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  316. classiq/model_expansions/evaluators/control.py +144 -0
  317. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  318. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  319. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  320. classiq/model_expansions/expression_evaluator.py +135 -0
  321. classiq/model_expansions/expression_renamer.py +76 -0
  322. classiq/model_expansions/function_builder.py +247 -0
  323. classiq/model_expansions/generative_functions.py +158 -0
  324. classiq/model_expansions/interpreters/__init__.py +0 -0
  325. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  326. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  327. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  328. classiq/model_expansions/model_tables.py +18 -0
  329. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  330. classiq/model_expansions/quantum_operations/bind.py +60 -0
  331. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  332. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  333. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  334. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  335. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  336. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  337. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  338. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  339. classiq/model_expansions/scope.py +240 -0
  340. classiq/model_expansions/scope_initialization.py +150 -0
  341. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  342. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  343. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  344. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  345. classiq/model_expansions/transformers/__init__.py +0 -0
  346. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  347. classiq/model_expansions/transformers/var_splitter.py +299 -0
  348. classiq/model_expansions/utils/__init__.py +0 -0
  349. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  350. classiq/model_expansions/utils/handles_collector.py +33 -0
  351. classiq/model_expansions/visitors/__init__.py +0 -0
  352. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  353. classiq/model_expansions/visitors/variable_references.py +144 -0
  354. classiq/open_library/__init__.py +4 -0
  355. classiq/open_library/functions/__init__.py +130 -0
  356. classiq/open_library/functions/amplitude_estimation.py +30 -0
  357. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  358. classiq/open_library/functions/grover.py +157 -0
  359. classiq/open_library/functions/hea.py +115 -0
  360. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  361. classiq/open_library/functions/modular_exponentiation.py +201 -0
  362. classiq/open_library/functions/qaoa_penalty.py +117 -0
  363. classiq/open_library/functions/qft_functions.py +54 -0
  364. classiq/open_library/functions/qpe.py +46 -0
  365. classiq/open_library/functions/qsvt.py +331 -0
  366. classiq/open_library/functions/state_preparation.py +301 -0
  367. classiq/open_library/functions/swap_test.py +27 -0
  368. classiq/open_library/functions/utility_functions.py +81 -0
  369. classiq/open_library/functions/variational.py +52 -0
  370. classiq/qmod/__init__.py +17 -10
  371. classiq/qmod/builtins/__init__.py +19 -2
  372. classiq/qmod/builtins/classical_execution_primitives.py +60 -47
  373. classiq/qmod/builtins/classical_functions.py +44 -38
  374. classiq/qmod/builtins/constants.py +10 -0
  375. classiq/qmod/builtins/enums.py +208 -0
  376. classiq/qmod/builtins/functions/__init__.py +137 -0
  377. classiq/qmod/builtins/functions/allocation.py +150 -0
  378. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  379. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  380. classiq/qmod/builtins/functions/chemistry.py +91 -0
  381. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  382. classiq/qmod/builtins/functions/finance.py +34 -0
  383. classiq/qmod/builtins/functions/operators.py +16 -0
  384. classiq/qmod/builtins/functions/qsvm.py +24 -0
  385. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  386. classiq/qmod/builtins/operations.py +379 -57
  387. classiq/qmod/builtins/structs.py +103 -80
  388. classiq/qmod/cfunc.py +42 -0
  389. classiq/qmod/classical_function.py +8 -20
  390. classiq/qmod/cparam.py +64 -0
  391. classiq/qmod/create_model_function.py +56 -0
  392. classiq/qmod/declaration_inferrer.py +145 -112
  393. classiq/qmod/expression_query.py +39 -0
  394. classiq/qmod/generative.py +42 -0
  395. classiq/qmod/model_state_container.py +19 -5
  396. classiq/qmod/native/__init__.py +7 -0
  397. classiq/qmod/native/expression_to_qmod.py +194 -0
  398. classiq/qmod/native/pretty_printer.py +401 -0
  399. classiq/qmod/pretty_print/__init__.py +7 -0
  400. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  401. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  402. classiq/qmod/python_classical_type.py +67 -0
  403. classiq/qmod/qfunc.py +79 -0
  404. classiq/qmod/qmod_constant.py +143 -0
  405. classiq/qmod/qmod_parameter.py +84 -53
  406. classiq/qmod/qmod_variable.py +497 -100
  407. classiq/qmod/quantum_callable.py +17 -7
  408. classiq/qmod/quantum_expandable.py +278 -105
  409. classiq/qmod/quantum_function.py +232 -48
  410. classiq/qmod/semantics/__init__.py +0 -0
  411. classiq/qmod/semantics/annotation/__init__.py +0 -0
  412. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  413. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  414. classiq/qmod/semantics/error_manager.py +88 -0
  415. classiq/qmod/semantics/lambdas.py +25 -0
  416. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  417. classiq/qmod/semantics/validation/__init__.py +0 -0
  418. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  419. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  420. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  421. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  422. classiq/qmod/semantics/validation/main_validation.py +33 -0
  423. classiq/qmod/semantics/validation/types_validation.py +128 -0
  424. classiq/qmod/symbolic.py +178 -111
  425. classiq/qmod/symbolic_expr.py +36 -12
  426. classiq/qmod/symbolic_type.py +2 -5
  427. classiq/qmod/type_attribute_remover.py +32 -0
  428. classiq/qmod/utilities.py +108 -1
  429. classiq/qmod/write_qmod.py +53 -0
  430. classiq/synthesis.py +210 -22
  431. {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -8
  432. classiq-0.65.3.dist-info/RECORD +521 -0
  433. {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/WHEEL +1 -1
  434. classiq/_internals/_qfunc_ext.py +0 -6
  435. classiq/applications/benchmarking/__init__.py +0 -9
  436. classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
  437. classiq/applications/numpy_utils.py +0 -37
  438. classiq/applications_model_constructors/__init__.py +0 -17
  439. classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
  440. classiq/applications_model_constructors/grover_model_constructor.py +0 -227
  441. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  442. classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
  443. classiq/builtin_functions/__init__.py +0 -43
  444. classiq/builtin_functions/amplitude_loading.py +0 -3
  445. classiq/builtin_functions/binary_ops.py +0 -1
  446. classiq/builtin_functions/exponentiation.py +0 -5
  447. classiq/builtin_functions/qpe.py +0 -4
  448. classiq/builtin_functions/qsvm.py +0 -7
  449. classiq/builtin_functions/range_types.py +0 -5
  450. classiq/builtin_functions/standard_gates.py +0 -1
  451. classiq/builtin_functions/state_preparation.py +0 -6
  452. classiq/builtin_functions/suzuki_trotter.py +0 -3
  453. classiq/exceptions.py +0 -131
  454. classiq/interface/executor/aws_execution_cost.py +0 -72
  455. classiq/interface/executor/error_mitigation.py +0 -6
  456. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -115
  457. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -59
  458. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  459. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  460. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  461. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  462. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  463. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  464. classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
  465. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  466. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  467. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  468. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -862
  469. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
  470. classiq/interface/generator/functions/foreign_function_definition.py +0 -106
  471. classiq/interface/generator/functions/function_implementation.py +0 -103
  472. classiq/interface/generator/functions/native_function_definition.py +0 -153
  473. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  474. classiq/interface/generator/functions/register.py +0 -42
  475. classiq/interface/generator/functions/register_mapping_data.py +0 -102
  476. classiq/interface/generator/inequality_mixer.py +0 -51
  477. classiq/interface/generator/model/classical_main_validator.py +0 -106
  478. classiq/interface/generator/range_mixer.py +0 -56
  479. classiq/interface/generator/state_propagator.py +0 -63
  480. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -2
  481. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  482. classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
  483. classiq/interface/generator/types/combinatorial_problem.py +0 -26
  484. classiq/interface/ide/show.py +0 -34
  485. classiq/interface/model/common_model_types.py +0 -23
  486. classiq/interface/model/numeric_reinterpretation.py +0 -25
  487. classiq/interface/model/operator_synthesis_data.py +0 -48
  488. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  489. classiq/interface/model/quantum_if_operation.py +0 -95
  490. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  491. classiq/interface/model/validations/handle_validation_base.py +0 -55
  492. classiq/interface/model/validations/handles_validator.py +0 -154
  493. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  494. classiq/model/__init__.py +0 -14
  495. classiq/model/composite_function_generator.py +0 -33
  496. classiq/model/function_handler.py +0 -466
  497. classiq/model/function_handler.pyi +0 -152
  498. classiq/model/logic_flow.py +0 -149
  499. classiq/model/logic_flow_change_handler.py +0 -71
  500. classiq/model/model.py +0 -246
  501. classiq/qmod/builtins/functions.py +0 -896
  502. classiq/qmod/qmod_struct.py +0 -37
  503. classiq/quantum_functions/__init__.py +0 -17
  504. classiq/quantum_functions/annotation_parser.py +0 -207
  505. classiq/quantum_functions/decorators.py +0 -22
  506. classiq/quantum_functions/function_library.py +0 -181
  507. classiq/quantum_functions/function_parser.py +0 -74
  508. classiq/quantum_functions/quantum_function.py +0 -236
  509. classiq-0.37.1.dist-info/RECORD +0 -418
  510. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
  511. /classiq/{interface/generator/credit_risk_example → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
  512. /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/pauli_helpers}/__init__.py +0 -0
  513. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/py.typed} +0 -0
  514. /classiq/{interface/model/resolvers → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  515. /classiq/{interface/model/validations → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  516. /classiq/{_internals → interface}/enum_utils.py +0 -0
@@ -0,0 +1,123 @@
1
+ import functools
2
+ from typing import Any, Optional, get_args
3
+
4
+ from sympy import (
5
+ Array,
6
+ Basic,
7
+ Expr,
8
+ Float,
9
+ Integer,
10
+ Matrix,
11
+ Piecewise,
12
+ Rational,
13
+ Symbol,
14
+ )
15
+ from sympy.logic.boolalg import BooleanAtom
16
+ from sympy.printing.pycode import PythonCodePrinter
17
+
18
+ from classiq.interface.exceptions import ClassiqInternalExpansionError
19
+ from classiq.interface.generator.expressions.expression_types import ExpressionValue
20
+
21
+ from classiq.model_expansions.sympy_conversion.arithmetics import LogicalXor
22
+
23
+
24
+ def sympy_to_python(
25
+ value: Any, locals: Optional[dict[str, ExpressionValue]] = None
26
+ ) -> ExpressionValue:
27
+ if isinstance(value, Integer):
28
+ value = int(value)
29
+ elif isinstance(value, Float):
30
+ value = float(value)
31
+ elif isinstance(value, BooleanAtom):
32
+ value = bool(value)
33
+ elif isinstance(value, Array):
34
+ value = sympy_to_python(value.tolist(), locals)
35
+ elif isinstance(value, Rational):
36
+ value = float(value.evalf())
37
+ elif isinstance(value, list):
38
+ value = [sympy_to_python(element, locals) for element in value]
39
+ elif isinstance(value, Matrix):
40
+ value = [sympy_to_python(element, locals) for element in value.tolist()]
41
+ elif isinstance(value, Symbol) and locals is not None and value.name in locals:
42
+ return locals[value.name]
43
+ if value is None:
44
+ value = False
45
+
46
+ if not isinstance(value, get_args(ExpressionValue)):
47
+ raise ClassiqInternalExpansionError(
48
+ f"Invalid evaluated expression {value} of type {type(value)}"
49
+ )
50
+
51
+ return value
52
+
53
+
54
+ def _conditional_true(*args: Any, **kwargs: Any) -> bool:
55
+ return True
56
+
57
+
58
+ class SympyToQuantumExpressionTranslator(PythonCodePrinter):
59
+ _operators = {**PythonCodePrinter._operators, **{"not": "~", "xor": "^"}}
60
+ _kf = {
61
+ **PythonCodePrinter._kf,
62
+ **{"max": "max", "min": "min", "Max": "max", "Min": "min"},
63
+ }
64
+ BINARY_BITWISE_OPERATORS_MAPPING = {
65
+ "BitwiseAnd": "&",
66
+ "BitwiseOr": "|",
67
+ "BitwiseXor": "^",
68
+ "LogicalXor": "^",
69
+ }
70
+ UNARY_BITWISE_OPERATORS_MAPPING = {"BitwiseNot": "~"}
71
+
72
+ @staticmethod
73
+ def _print_bitwise_binary_operator(
74
+ left_arg: Expr, right_arg: Expr, operator: str
75
+ ) -> str:
76
+ return f"(({left_arg}) {operator} ({right_arg}))"
77
+
78
+ @staticmethod
79
+ def _print_bitwise_unary_operator(arg: Expr, operator: str) -> str:
80
+ return f"({operator} ({arg}))"
81
+
82
+ def __init__(self) -> None:
83
+ super().__init__(settings={"fully_qualified_modules": False})
84
+ for binary_operator in self.BINARY_BITWISE_OPERATORS_MAPPING:
85
+ self.known_functions[binary_operator] = [
86
+ (
87
+ _conditional_true,
88
+ functools.partial(
89
+ self._print_bitwise_binary_operator,
90
+ operator=self.BINARY_BITWISE_OPERATORS_MAPPING[binary_operator],
91
+ ),
92
+ )
93
+ ]
94
+ for unary_operator in self.UNARY_BITWISE_OPERATORS_MAPPING:
95
+ self.known_functions[unary_operator] = [
96
+ (
97
+ _conditional_true,
98
+ functools.partial(
99
+ self._print_bitwise_unary_operator,
100
+ operator=self.UNARY_BITWISE_OPERATORS_MAPPING[unary_operator],
101
+ ),
102
+ )
103
+ ]
104
+
105
+ def _print_Piecewise(self, expr: Piecewise) -> str: # noqa: N802
106
+ return str(expr)
107
+
108
+ def _print_LogicalXor(self, expr: LogicalXor) -> str: # noqa: N802
109
+ return f"(({self._print(expr.args[0])}) ^ ({self._print(expr.args[1])}))"
110
+
111
+
112
+ class SympyToBoolExpressionTranslator(SympyToQuantumExpressionTranslator):
113
+ _operators = {
114
+ **SympyToQuantumExpressionTranslator._operators,
115
+ **{"not": "not ", "xor": "xor"},
116
+ }
117
+
118
+
119
+ def translate_sympy_quantum_expression(expr: Basic, preserve_bool_ops: bool) -> str:
120
+ if preserve_bool_ops:
121
+ return SympyToBoolExpressionTranslator().doprint(expr)
122
+ else:
123
+ return SympyToQuantumExpressionTranslator().doprint(expr)
File without changes
@@ -0,0 +1,26 @@
1
+ import ast
2
+
3
+ _POSSIBLE_HANDLE_AST_TYPES = (ast.Subscript, ast.Attribute, ast.Name)
4
+
5
+
6
+ class _ASTRenamer(ast.NodeTransformer):
7
+ def __init__(self, sub: dict[str, str]) -> None:
8
+ self._sub = sub
9
+
10
+ def visit(self, node: ast.AST) -> ast.AST:
11
+ if isinstance(node, _POSSIBLE_HANDLE_AST_TYPES):
12
+ node_expr = ast.unparse(node)
13
+ if node_expr in self._sub:
14
+ return ast.Name(id=self._sub[node_expr])
15
+ return super().visit(node)
16
+
17
+ def visit_Call(self, node: ast.Call) -> ast.Call:
18
+ return ast.Call(
19
+ func=node.func,
20
+ args=[self.visit(arg) for arg in node.args],
21
+ keywords=[],
22
+ )
23
+
24
+
25
+ def rename_variables(expr: str, sub: dict[str, str]) -> str:
26
+ return ast.unparse(_ASTRenamer(sub).visit(ast.parse(expr)))
@@ -0,0 +1,299 @@
1
+ import ast
2
+ from dataclasses import dataclass
3
+ from itertools import chain
4
+ from typing import TYPE_CHECKING, Callable, Optional, TypeVar, cast
5
+
6
+ from classiq.interface.exceptions import (
7
+ ClassiqExpansionError,
8
+ ClassiqInternalExpansionError,
9
+ )
10
+ from classiq.interface.generator.expressions.expression import Expression
11
+ from classiq.interface.generator.visitor import NodeType, Transformer
12
+ from classiq.interface.model.bind_operation import BindOperation
13
+ from classiq.interface.model.handle_binding import (
14
+ HandleBinding,
15
+ NestedHandleBinding,
16
+ SlicedHandleBinding,
17
+ SubscriptHandleBinding,
18
+ )
19
+ from classiq.interface.model.quantum_expressions.quantum_expression import (
20
+ QuantumExpressionOperation,
21
+ )
22
+ from classiq.interface.model.quantum_type import (
23
+ QuantumBitvector,
24
+ QuantumScalar,
25
+ QuantumType,
26
+ )
27
+ from classiq.interface.model.variable_declaration_statement import (
28
+ VariableDeclarationStatement,
29
+ )
30
+
31
+ from classiq.model_expansions.scope import QuantumSymbol, Scope
32
+ from classiq.model_expansions.visitors.variable_references import VarRefCollector
33
+
34
+ AST_NODE = TypeVar("AST_NODE", bound=NodeType)
35
+
36
+
37
+ @dataclass(frozen=True)
38
+ class SymbolPart:
39
+ source_handle: HandleBinding
40
+ target_var_name: str
41
+ target_var_type: QuantumType
42
+
43
+ @property
44
+ def target_var_handle(self) -> HandleBinding:
45
+ return HandleBinding(name=self.target_var_name)
46
+
47
+
48
+ SymbolParts = dict[HandleBinding, list[SymbolPart]]
49
+ PartNamer = Callable[[str], str]
50
+
51
+
52
+ class VarSplitter:
53
+ def __init__(self, scope: Scope):
54
+ self._scope = scope
55
+
56
+ def split_symbols(self, expression: Expression, namer: PartNamer) -> SymbolParts:
57
+ vrc = VarRefCollector(ignore_duplicated_handles=True)
58
+ vrc.visit(ast.parse(expression.expr))
59
+ symbol_names_to_split = dict.fromkeys(
60
+ handle.name
61
+ for handle in vrc.var_handles
62
+ if isinstance(self._scope[handle.name].value, QuantumSymbol)
63
+ and isinstance(handle, NestedHandleBinding)
64
+ )
65
+
66
+ symbol_handles = {
67
+ symbol: list(
68
+ dict.fromkeys(
69
+ handle.collapse()
70
+ for handle in vrc.var_handles
71
+ if handle.name == symbol.handle.name
72
+ )
73
+ )
74
+ for symbol_name in symbol_names_to_split
75
+ if isinstance(
76
+ symbol := self._scope[symbol_name].value,
77
+ QuantumSymbol,
78
+ )
79
+ }
80
+
81
+ return {
82
+ symbol.handle: [
83
+ SymbolPart(
84
+ source_handle=part.handle,
85
+ target_var_name=namer(part.handle.identifier),
86
+ target_var_type=part.quantum_type,
87
+ )
88
+ for part in self._get_symbol_parts(symbol, handles)
89
+ ]
90
+ for symbol, handles in symbol_handles.items()
91
+ }
92
+
93
+ def _get_symbol_parts(
94
+ self, symbol: QuantumSymbol, target_parts: list[HandleBinding]
95
+ ) -> list[QuantumSymbol]:
96
+ for i in range(len(target_parts)):
97
+ for j in range(i + 1, len(target_parts)):
98
+ if target_parts[i].overlaps(target_parts[j]):
99
+ raise ClassiqInternalExpansionError(
100
+ f"Handles {str(target_parts[i])!r} and "
101
+ f"{str(target_parts[j])!r} overlapping in expression"
102
+ )
103
+ return self._get_symbol_parts_unsafe(symbol, target_parts)
104
+
105
+ def _get_symbol_parts_unsafe(
106
+ self, symbol: QuantumSymbol, target_parts: list[HandleBinding]
107
+ ) -> list[QuantumSymbol]:
108
+ if all(
109
+ symbol.handle == target_part or symbol.handle not in target_part.prefixes()
110
+ for target_part in target_parts
111
+ ) or isinstance(symbol.quantum_type, QuantumScalar):
112
+ return [symbol]
113
+
114
+ if isinstance(symbol.quantum_type, QuantumBitvector):
115
+ return self._get_array_parts(symbol, target_parts)
116
+
117
+ return self._get_struct_parts(symbol, target_parts)
118
+
119
+ def _get_array_parts(
120
+ self, symbol: QuantumSymbol, target_parts: list[HandleBinding]
121
+ ) -> list[QuantumSymbol]:
122
+ if TYPE_CHECKING:
123
+ assert isinstance(symbol.quantum_type, QuantumBitvector)
124
+
125
+ if not symbol.quantum_type.has_length:
126
+ raise ClassiqExpansionError(
127
+ f"Could not determine the length of quantum array " f"{symbol.handle}."
128
+ )
129
+ target_slices = self._get_target_slices(symbol, target_parts)
130
+
131
+ symbol_parts: list[QuantumSymbol] = []
132
+ idx = 0
133
+ while idx < symbol.quantum_type.length_value:
134
+ if idx in target_slices:
135
+ stop = target_slices[idx]
136
+ if stop <= idx:
137
+ raise ClassiqInternalExpansionError(
138
+ f"Illegal sliced handle {str(symbol[idx: stop].handle)!r}"
139
+ )
140
+ symbol_parts.append(symbol[idx:stop])
141
+ idx = stop
142
+ else:
143
+ symbol_parts.extend(
144
+ self._get_symbol_parts_unsafe(symbol[idx], target_parts)
145
+ )
146
+ idx += 1
147
+
148
+ return symbol_parts
149
+
150
+ def _get_target_slices(
151
+ self, symbol: QuantumSymbol, target_parts: list[HandleBinding]
152
+ ) -> dict[int, int]:
153
+ if TYPE_CHECKING:
154
+ assert isinstance(symbol.quantum_type, QuantumBitvector)
155
+ target_items = {
156
+ idx
157
+ for idx in range(symbol.quantum_type.length_value)
158
+ for target_part in target_parts
159
+ if target_part
160
+ in SubscriptHandleBinding(
161
+ base_handle=symbol.handle, index=Expression(expr=str(idx))
162
+ )
163
+ }
164
+ target_slices = {
165
+ target_part.start.to_int_value(): target_part.end.to_int_value()
166
+ for target_part in target_parts
167
+ if isinstance(target_part, SlicedHandleBinding)
168
+ and symbol.handle == target_part.base_handle
169
+ }
170
+ self._add_unused_indices_as_slices(symbol, target_items, target_slices)
171
+ return target_slices
172
+
173
+ @staticmethod
174
+ def _add_unused_indices_as_slices(
175
+ symbol: QuantumSymbol, target_items: set[int], target_slices: dict[int, int]
176
+ ) -> None:
177
+ if TYPE_CHECKING:
178
+ assert isinstance(symbol.quantum_type, QuantumBitvector)
179
+ last_unused_idx: Optional[int] = None
180
+ array_length = symbol.quantum_type.length_value
181
+ idx = 0
182
+
183
+ while idx < array_length:
184
+ if (
185
+ idx in target_items or idx in target_slices
186
+ ) and last_unused_idx is not None:
187
+ target_slices[last_unused_idx] = idx
188
+ last_unused_idx = None
189
+
190
+ if idx in target_slices:
191
+ if target_slices[idx] <= idx:
192
+ raise ClassiqInternalExpansionError
193
+ idx = target_slices[idx]
194
+ continue
195
+
196
+ if idx not in target_items and last_unused_idx is None:
197
+ last_unused_idx = idx
198
+
199
+ idx += 1
200
+
201
+ if last_unused_idx is not None:
202
+ target_slices[last_unused_idx] = array_length
203
+
204
+ def _get_struct_parts(
205
+ self, symbol: QuantumSymbol, target_parts: list[HandleBinding]
206
+ ) -> list[QuantumSymbol]:
207
+ return list(
208
+ chain.from_iterable(
209
+ self._get_symbol_parts_unsafe(field_symbol, target_parts)
210
+ for field_symbol in symbol.fields.values()
211
+ )
212
+ )
213
+
214
+ @staticmethod
215
+ def get_bind_ops(symbol_parts: SymbolParts) -> list[BindOperation]:
216
+ return [
217
+ BindOperation(
218
+ in_handles=[handle],
219
+ out_handles=[part.target_var_handle for part in parts],
220
+ )
221
+ for handle, parts in symbol_parts.items()
222
+ ]
223
+
224
+ @staticmethod
225
+ def get_var_decls(symbol_parts: SymbolParts) -> list[VariableDeclarationStatement]:
226
+ return [
227
+ VariableDeclarationStatement(
228
+ name=part.target_var_name,
229
+ quantum_type=part.target_var_type,
230
+ )
231
+ for part in chain.from_iterable(symbol_parts.values())
232
+ ]
233
+
234
+ def rewrite(self, subject: AST_NODE, symbol_mapping: SymbolParts) -> AST_NODE:
235
+ if len(symbol_mapping) == 0:
236
+ return subject
237
+ handle_replacements = {
238
+ part.source_handle: part.target_var_handle
239
+ for parts in symbol_mapping.values()
240
+ for part in parts
241
+ }
242
+
243
+ class ReplaceSplitVars(Transformer):
244
+ @staticmethod
245
+ def visit_HandleBinding(handle: HandleBinding) -> HandleBinding:
246
+ handle = handle.collapse()
247
+ for handle_to_replace, replacement in handle_replacements.items():
248
+ handle = handle.replace_prefix(handle_to_replace, replacement)
249
+ return handle
250
+
251
+ @staticmethod
252
+ def visit_Expression(expr: Expression) -> Expression:
253
+ return self._rewrite_expression(symbol_mapping, expr)
254
+
255
+ def visit_QuantumExpressionOperation(
256
+ self, op: QuantumExpressionOperation
257
+ ) -> QuantumExpressionOperation:
258
+ op = cast(QuantumExpressionOperation, self.generic_visit(op))
259
+ previous_var_handles = list(op._var_handles)
260
+ op._var_handles = self.visit(op._var_handles)
261
+ op._var_types = {
262
+ new_handle.name: op._var_types.get(
263
+ new_handle.name, op._var_types[previous_handle.name]
264
+ )
265
+ for previous_handle, new_handle in zip(
266
+ previous_var_handles, op._var_handles
267
+ )
268
+ }
269
+ return op
270
+
271
+ return ReplaceSplitVars().visit(subject)
272
+
273
+ def _rewrite_expression(
274
+ self,
275
+ symbol_mapping: SymbolParts,
276
+ expression: Expression,
277
+ ) -> Expression:
278
+ vrc = VarRefCollector(ignore_duplicated_handles=True)
279
+ vrc.visit(ast.parse(expression.expr))
280
+
281
+ handle_names = {
282
+ part.source_handle: part.target_var_handle
283
+ for parts in symbol_mapping.values()
284
+ for part in parts
285
+ }
286
+ new_expr_str = expression.expr
287
+ for handle in vrc.var_handles:
288
+ new_handle = handle.collapse()
289
+ for handle_to_replace, replacement in handle_names.items():
290
+ new_handle = new_handle.replace_prefix(handle_to_replace, replacement)
291
+ new_expr_str = new_expr_str.replace(str(handle), str(new_handle))
292
+ if handle.qmod_expr != str(handle):
293
+ new_expr_str = new_expr_str.replace(
294
+ handle.qmod_expr, new_handle.qmod_expr
295
+ )
296
+
297
+ new_expr = Expression(expr=new_expr_str)
298
+ new_expr._evaluated_expr = expression._evaluated_expr
299
+ return new_expr
File without changes
@@ -0,0 +1,11 @@
1
+ from collections import Counter
2
+
3
+
4
+ class CountedNameAllocator:
5
+ def __init__(self) -> None:
6
+ self._count: Counter[str] = Counter()
7
+
8
+ def allocate(self, prefix: str) -> str:
9
+ allocated = f"{prefix}_{self._count[prefix]}"
10
+ self._count[prefix] += 1
11
+ return allocated
@@ -0,0 +1,33 @@
1
+ import ast
2
+
3
+ from classiq.interface.generator.expressions.expression import Expression
4
+ from classiq.interface.generator.visitor import NodeType, Visitor
5
+ from classiq.interface.model.handle_binding import HandleBinding
6
+ from classiq.interface.model.quantum_expressions.quantum_expression import (
7
+ QuantumExpressionOperation,
8
+ )
9
+
10
+ from classiq.model_expansions.visitors.variable_references import VarRefCollector
11
+
12
+
13
+ class _HandlesCollector(Visitor):
14
+ def __init__(self) -> None:
15
+ self.handles: list[HandleBinding] = []
16
+
17
+ def visit_HandleBinding(self, handle: HandleBinding) -> None:
18
+ self.handles.append(handle)
19
+
20
+ def visit_Expression(self, expression: Expression) -> None:
21
+ vrc = VarRefCollector(ignore_duplicated_handles=True)
22
+ vrc.visit(ast.parse(expression.expr))
23
+ self.handles.extend(vrc.var_handles)
24
+
25
+ def visit_QuantumExpressionOperation(self, op: QuantumExpressionOperation) -> None:
26
+ self.handles.extend(op.var_handles)
27
+ self.generic_visit(op)
28
+
29
+
30
+ def extract_handles(node: NodeType) -> list[HandleBinding]:
31
+ collector = _HandlesCollector()
32
+ collector.visit(node)
33
+ return collector.handles
File without changes