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
@@ -1,30 +1,60 @@
1
- from typing import Mapping
1
+ from collections.abc import Mapping, Sequence
2
+ from typing import Literal
2
3
 
3
4
  import pydantic
4
5
 
5
- from classiq.interface.model.handle_binding import HandleBinding
6
- from classiq.interface.model.quantum_statement import QuantumOperation
7
-
8
- from classiq.exceptions import ClassiqValueError
6
+ from classiq.interface.exceptions import ClassiqValueError
7
+ from classiq.interface.model.handle_binding import ConcreteHandleBinding, HandleBinding
8
+ from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
9
9
 
10
10
  BIND_INPUT_NAME = "bind_input"
11
11
  BIND_OUTPUT_NAME = "bind_output"
12
12
 
13
13
 
14
14
  class BindOperation(QuantumOperation):
15
- in_handle: HandleBinding
16
- out_handle: HandleBinding
15
+ kind: Literal["BindOperation"]
16
+
17
+ in_handles: list[ConcreteHandleBinding]
18
+ out_handles: list[ConcreteHandleBinding]
17
19
 
18
20
  @property
19
21
  def wiring_inputs(self) -> Mapping[str, HandleBinding]:
20
- return {BIND_INPUT_NAME: self.in_handle}
22
+ return {
23
+ f"{BIND_INPUT_NAME}_{i}": handle for i, handle in enumerate(self.in_handles)
24
+ }
25
+
26
+ @property
27
+ def readable_inputs(self) -> Sequence[HandleMetadata]:
28
+ return [
29
+ HandleMetadata(
30
+ handle=handle,
31
+ readable_location="on the left-hand side of a bind statement",
32
+ )
33
+ for handle in self.in_handles
34
+ ]
21
35
 
22
36
  @property
23
37
  def wiring_outputs(self) -> Mapping[str, HandleBinding]:
24
- return {BIND_OUTPUT_NAME: self.out_handle}
38
+ return {
39
+ f"{BIND_OUTPUT_NAME}_{i}": handle
40
+ for i, handle in enumerate(self.out_handles)
41
+ }
25
42
 
26
- @pydantic.validator("in_handle", "out_handle")
27
- def validate_handle(cls, handle: HandleBinding) -> HandleBinding:
28
- if not handle.is_bindable():
29
- raise ClassiqValueError(f"Cannot bind '{handle}'") # noqa: B907
30
- return handle
43
+ @property
44
+ def readable_outputs(self) -> Sequence[HandleMetadata]:
45
+ return [
46
+ HandleMetadata(
47
+ handle=handle,
48
+ readable_location="on the right-hand side of a bind statement",
49
+ )
50
+ for handle in self.out_handles
51
+ ]
52
+
53
+ @pydantic.field_validator("in_handles", "out_handles")
54
+ @classmethod
55
+ def validate_handle(cls, handles: list[HandleBinding]) -> list[HandleBinding]:
56
+ for handle in handles:
57
+ if not handle.is_bindable():
58
+ raise ClassiqValueError(f"Cannot bind '{handle}'")
59
+
60
+ return handles
@@ -0,0 +1,15 @@
1
+ from typing import TYPE_CHECKING, Literal
2
+
3
+ from classiq.interface.generator.expressions.expression import Expression
4
+ from classiq.interface.model.quantum_statement import QuantumOperation
5
+
6
+ if TYPE_CHECKING:
7
+ from classiq.interface.model.statement_block import StatementBlock
8
+
9
+
10
+ class ClassicalIf(QuantumOperation):
11
+ kind: Literal["ClassicalIf"]
12
+
13
+ condition: Expression
14
+ then: "StatementBlock"
15
+ else_: "StatementBlock"
@@ -1,8 +1,38 @@
1
+ from typing import Any, Literal
2
+
1
3
  import pydantic
2
4
 
3
- from classiq.interface.generator.functions.classical_type import ConcreteClassicalType
5
+ from classiq.interface.exceptions import ClassiqInternalError
6
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
7
+ from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
8
+ from classiq.interface.model.parameter import Parameter
4
9
 
5
10
 
6
- class ClassicalParameterDeclaration(pydantic.BaseModel):
7
- name: str
11
+ class AnonClassicalParameterDeclaration(Parameter):
12
+ kind: Literal["ClassicalParameterDeclaration"]
8
13
  classical_type: ConcreteClassicalType
14
+
15
+ @pydantic.model_validator(mode="before")
16
+ @classmethod
17
+ def _set_kind(cls, values: Any) -> dict[str, Any]:
18
+ return values_with_discriminator(
19
+ values, "kind", "ClassicalParameterDeclaration"
20
+ )
21
+
22
+ def rename(self, new_name: str) -> "ClassicalParameterDeclaration":
23
+ if type(self) not in (
24
+ AnonClassicalParameterDeclaration,
25
+ ClassicalParameterDeclaration,
26
+ ):
27
+ raise ClassiqInternalError
28
+ return ClassicalParameterDeclaration(
29
+ **{
30
+ **self.__dict__,
31
+ "name": new_name,
32
+ "kind": "ClassicalParameterDeclaration",
33
+ }
34
+ )
35
+
36
+
37
+ class ClassicalParameterDeclaration(AnonClassicalParameterDeclaration):
38
+ name: str
@@ -0,0 +1,45 @@
1
+ from typing import TYPE_CHECKING, Literal, Optional
2
+
3
+ import pydantic
4
+
5
+ from classiq.interface.generator.arith.arithmetic import compute_arithmetic_result_type
6
+ from classiq.interface.model.quantum_expressions.quantum_expression import (
7
+ QuantumExpressionOperation,
8
+ )
9
+ from classiq.interface.model.quantum_type import QuantumType
10
+
11
+ if TYPE_CHECKING:
12
+ from classiq.interface.model.statement_block import StatementBlock
13
+
14
+
15
+ class Control(QuantumExpressionOperation):
16
+ kind: Literal["Control"]
17
+ body: "StatementBlock"
18
+ else_block: Optional["StatementBlock"] = None
19
+
20
+ _ctrl_size: int = pydantic.PrivateAttr(default=0)
21
+ _result_type: Optional[QuantumType] = pydantic.PrivateAttr(
22
+ default=None,
23
+ )
24
+
25
+ @property
26
+ def ctrl_size(self) -> int:
27
+ return self._ctrl_size
28
+
29
+ def set_ctrl_size(self, ctrl_size: int) -> None:
30
+ self._ctrl_size = ctrl_size
31
+
32
+ @property
33
+ def result_type(self) -> QuantumType:
34
+ assert self._result_type is not None
35
+ return self._result_type
36
+
37
+ def initialize_var_types(
38
+ self,
39
+ var_types: dict[str, QuantumType],
40
+ machine_precision: int,
41
+ ) -> None:
42
+ super().initialize_var_types(var_types, machine_precision)
43
+ self._result_type = compute_arithmetic_result_type(
44
+ self.expression.expr, var_types, machine_precision
45
+ )
@@ -1,46 +1,324 @@
1
- from pydantic import BaseModel, Extra
1
+ from collections.abc import Sequence
2
+ from itertools import chain
3
+ from typing import TYPE_CHECKING, Any, Union
2
4
 
5
+ import pydantic
6
+ from pydantic import ConfigDict, Field
7
+ from typing_extensions import Self
8
+
9
+ from classiq.interface.ast_node import ASTNode
3
10
  from classiq.interface.generator.expressions.expression import Expression
4
11
 
12
+ HANDLE_ID_SEPARATOR = "___"
5
13
 
6
- class HandleBinding(BaseModel):
7
- name: str
8
14
 
9
- class Config:
10
- frozen = True
11
- extra = Extra.forbid
15
+ class HandleBinding(ASTNode):
16
+ name: str = Field(default=None)
17
+ model_config = ConfigDict(frozen=True, extra="forbid")
12
18
 
13
19
  def __str__(self) -> str:
14
20
  return self.name
15
21
 
22
+ @property
23
+ def qmod_expr(self) -> str:
24
+ return self.name
25
+
16
26
  def is_bindable(self) -> bool:
17
27
  return True
18
28
 
29
+ @property
30
+ def identifier(self) -> str:
31
+ return self.name
19
32
 
20
- class SubscriptHandleBinding(HandleBinding):
21
- index: Expression
33
+ def collapse(self) -> "HandleBinding":
34
+ return self
22
35
 
23
- class Config:
24
- frozen = True
25
- extra = Extra.forbid
36
+ def prefixes(self) -> Sequence["HandleBinding"]:
37
+ """
38
+ Split the handle into prefixes:
39
+ a.b[0].c --> [a, a.b, a.b[0], a.b[0].c]
40
+ """
41
+ return [self]
26
42
 
27
- def __str__(self) -> str:
28
- return f"{self.name}[{self.index}]"
43
+ def _tail_overlaps(self, other_handle: "HandleBinding") -> bool:
44
+ return self.name == other_handle.name
45
+
46
+ def overlaps(self, other_handle: "HandleBinding") -> bool:
47
+ self_prefixes = self.collapse().prefixes()
48
+ other_prefixes = other_handle.collapse().prefixes()
49
+ return all(
50
+ self_prefix._tail_overlaps(other_prefix)
51
+ for self_prefix, other_prefix in zip(self_prefixes, other_prefixes)
52
+ )
53
+
54
+ def rename(self, name: str) -> Self:
55
+ return self.model_copy(update=dict(name=name))
56
+
57
+ def replace_prefix(
58
+ self, prefix: "HandleBinding", replacement: "HandleBinding"
59
+ ) -> "HandleBinding":
60
+ if self == prefix:
61
+ return replacement
62
+ return self
63
+
64
+ def __contains__(self, other_handle: "HandleBinding") -> bool:
65
+ return self.collapse() in other_handle.collapse().prefixes()
66
+
67
+
68
+ class NestedHandleBinding(HandleBinding):
69
+ base_handle: "ConcreteHandleBinding"
70
+
71
+ @pydantic.model_validator(mode="before")
72
+ @classmethod
73
+ def _set_name(cls, values: Any) -> dict[str, Any]:
74
+ if isinstance(values, dict):
75
+ orig = values
76
+ while "base_handle" in dict(values):
77
+ values = dict(values)["base_handle"]
78
+ orig["name"] = dict(values).get("name")
79
+ return orig
80
+ if isinstance(values, NestedHandleBinding):
81
+ values.name = values.base_handle.name
82
+ return values.model_dump()
83
+ return values
29
84
 
30
85
  def is_bindable(self) -> bool:
31
86
  return False
32
87
 
88
+ def prefixes(self) -> Sequence["HandleBinding"]:
89
+ return list(chain.from_iterable([self.base_handle.prefixes(), [self]]))
90
+
91
+ def rename(self, name: str) -> Self:
92
+ return self.model_copy(
93
+ update=dict(name=name, base_handle=self.base_handle.rename(name))
94
+ )
95
+
96
+ def replace_prefix(
97
+ self, prefix: HandleBinding, replacement: HandleBinding
98
+ ) -> HandleBinding:
99
+ if self == prefix:
100
+ return replacement
101
+ new_base_handle = self.base_handle.replace_prefix(prefix, replacement)
102
+ if new_base_handle is not self.base_handle:
103
+ return self.model_copy(
104
+ update=dict(name=new_base_handle.name, base_handle=new_base_handle)
105
+ )
106
+ return self
107
+
108
+
109
+ class SubscriptHandleBinding(NestedHandleBinding):
110
+ index: Expression
111
+ model_config = ConfigDict(frozen=True, extra="forbid")
112
+
113
+ def __str__(self) -> str:
114
+ return f"{self.base_handle}[{self.index}]"
115
+
116
+ @property
117
+ def qmod_expr(self) -> str:
118
+ return f"{self.base_handle.qmod_expr}[{self.index}]"
119
+
120
+ @property
121
+ def identifier(self) -> str:
122
+ return f"{self.base_handle.identifier}{HANDLE_ID_SEPARATOR}{self.index}"
123
+
124
+ def collapse(self) -> HandleBinding:
125
+ if isinstance(self.base_handle, SlicedHandleBinding):
126
+ return SubscriptHandleBinding(
127
+ base_handle=self.base_handle.base_handle,
128
+ index=self._get_collapsed_index(),
129
+ ).collapse()
130
+ return SubscriptHandleBinding(
131
+ base_handle=self.base_handle.collapse(),
132
+ index=self.index,
133
+ )
134
+
135
+ def _get_collapsed_index(self) -> Expression:
136
+ if TYPE_CHECKING:
137
+ assert isinstance(self.base_handle, SlicedHandleBinding)
138
+ if self.index.is_evaluated() and self.base_handle.start.is_evaluated():
139
+ return Expression(
140
+ expr=str(
141
+ self.base_handle.start.to_int_value() + self.index.to_int_value()
142
+ )
143
+ )
144
+ return Expression(expr=f"({self.base_handle.start})+({self.index})")
33
145
 
34
- class SlicedHandleBinding(HandleBinding):
146
+ def _tail_overlaps(self, other_handle: "HandleBinding") -> bool:
147
+ if isinstance(other_handle, SubscriptHandleBinding):
148
+ return self.index == other_handle.index
149
+ if (
150
+ isinstance(other_handle, SlicedHandleBinding)
151
+ and self.index.is_evaluated()
152
+ and other_handle._is_evaluated()
153
+ ):
154
+ return (
155
+ other_handle.start.to_int_value()
156
+ <= self.index.to_int_value()
157
+ < other_handle.end.to_int_value()
158
+ )
159
+ return False
160
+
161
+ def replace_prefix(
162
+ self, prefix: HandleBinding, replacement: HandleBinding
163
+ ) -> HandleBinding:
164
+ if (
165
+ isinstance(prefix, SlicedHandleBinding)
166
+ and self.base_handle == prefix.base_handle
167
+ and self.index.is_evaluated()
168
+ and prefix._is_evaluated()
169
+ and prefix.start.to_int_value()
170
+ <= self.index.to_int_value()
171
+ < prefix.end.to_int_value()
172
+ ):
173
+ return SubscriptHandleBinding(
174
+ base_handle=replacement,
175
+ index=Expression(
176
+ expr=str(self.index.to_int_value() - prefix.start.to_int_value())
177
+ ),
178
+ )
179
+ return super().replace_prefix(prefix, replacement)
180
+
181
+
182
+ class SlicedHandleBinding(NestedHandleBinding):
35
183
  start: Expression
36
184
  end: Expression
37
-
38
- class Config:
39
- frozen = True
40
- extra = Extra.forbid
185
+ model_config = ConfigDict(frozen=True, extra="forbid")
41
186
 
42
187
  def __str__(self) -> str:
43
- return f"{self.name}[{self.start}:{self.end}]"
188
+ return f"{self.base_handle}[{self.start}:{self.end}]"
44
189
 
45
- def is_bindable(self) -> bool:
190
+ @property
191
+ def qmod_expr(self) -> str:
192
+ return f"{self.base_handle.qmod_expr}[{self.start}:{self.end}]"
193
+
194
+ @property
195
+ def identifier(self) -> str:
196
+ return (
197
+ f"{self.base_handle.identifier}{HANDLE_ID_SEPARATOR}{self.start}_{self.end}"
198
+ )
199
+
200
+ def collapse(self) -> HandleBinding:
201
+ if isinstance(self.base_handle, SlicedHandleBinding):
202
+ return SlicedHandleBinding(
203
+ base_handle=self.base_handle.base_handle,
204
+ start=self._get_collapsed_start(),
205
+ end=self._get_collapsed_stop(),
206
+ ).collapse()
207
+ return SlicedHandleBinding(
208
+ base_handle=self.base_handle.collapse(),
209
+ start=self.start,
210
+ end=self.end,
211
+ )
212
+
213
+ def _tail_overlaps(self, other_handle: "HandleBinding") -> bool:
214
+ if not self._is_evaluated():
215
+ return False
216
+ start = self.start.to_int_value()
217
+ end = self.end.to_int_value()
218
+ if (
219
+ isinstance(other_handle, SubscriptHandleBinding)
220
+ and other_handle.index.is_evaluated()
221
+ ):
222
+ return start <= other_handle.index.to_int_value() < end
223
+ if (
224
+ isinstance(other_handle, SlicedHandleBinding)
225
+ and other_handle._is_evaluated()
226
+ ):
227
+ other_start = other_handle.start.to_int_value()
228
+ other_end = other_handle.end.to_int_value()
229
+ return start <= other_start < end or other_start <= start < other_end
46
230
  return False
231
+
232
+ def _get_collapsed_start(self) -> Expression:
233
+ if TYPE_CHECKING:
234
+ assert isinstance(self.base_handle, SlicedHandleBinding)
235
+ if self.start.is_evaluated() and self.base_handle.start.is_evaluated():
236
+ return Expression(
237
+ expr=str(
238
+ self.base_handle.start.to_int_value() + self.start.to_int_value()
239
+ )
240
+ )
241
+ return Expression(expr=f"({self.base_handle.start})+({self.start})")
242
+
243
+ def _get_collapsed_stop(self) -> Expression:
244
+ if TYPE_CHECKING:
245
+ assert isinstance(self.base_handle, SlicedHandleBinding)
246
+ if self._is_evaluated() and self.base_handle.start.is_evaluated():
247
+ return Expression(
248
+ expr=str(
249
+ self.end.to_int_value()
250
+ - self.start.to_int_value()
251
+ + self.base_handle.start.to_int_value()
252
+ )
253
+ )
254
+ return Expression(
255
+ expr=f"({self.end})-({self.start})+({self.base_handle.start})"
256
+ )
257
+
258
+ def replace_prefix(
259
+ self, prefix: HandleBinding, replacement: HandleBinding
260
+ ) -> HandleBinding:
261
+ if self == prefix:
262
+ return replacement
263
+ if (
264
+ isinstance(prefix, SlicedHandleBinding)
265
+ and self.base_handle == prefix.base_handle
266
+ and self._is_evaluated()
267
+ and prefix._is_evaluated()
268
+ ):
269
+ prefix_start = prefix.start.to_int_value()
270
+ prefix_end = prefix.end.to_int_value()
271
+ self_start = self.start.to_int_value()
272
+ self_end = self.end.to_int_value()
273
+ if (
274
+ prefix_start <= self_start < prefix_end
275
+ and prefix_start < self_end <= prefix_end
276
+ ):
277
+ return SlicedHandleBinding(
278
+ base_handle=replacement,
279
+ start=Expression(expr=str(self_start - prefix_start)),
280
+ end=Expression(expr=str(self_end - prefix_start)),
281
+ )
282
+ return super().replace_prefix(prefix, replacement)
283
+
284
+ def _is_evaluated(self) -> bool:
285
+ return self.start.is_evaluated() and self.end.is_evaluated()
286
+
287
+
288
+ class FieldHandleBinding(NestedHandleBinding):
289
+ field: str
290
+ model_config = ConfigDict(frozen=True, extra="forbid")
291
+
292
+ def __str__(self) -> str:
293
+ return f"{self.base_handle}.{self.field}"
294
+
295
+ @property
296
+ def qmod_expr(self) -> str:
297
+ return f"get_field({self.base_handle.qmod_expr}, '{self.field}')"
298
+
299
+ @property
300
+ def identifier(self) -> str:
301
+ return f"{self.base_handle.identifier}{HANDLE_ID_SEPARATOR}{self.field}"
302
+
303
+ def collapse(self) -> HandleBinding:
304
+ return FieldHandleBinding(
305
+ base_handle=self.base_handle.collapse(),
306
+ field=self.field,
307
+ )
308
+
309
+ def _tail_overlaps(self, other_handle: "HandleBinding") -> bool:
310
+ return (
311
+ isinstance(other_handle, FieldHandleBinding)
312
+ and self.field == other_handle.field
313
+ )
314
+
315
+
316
+ ConcreteHandleBinding = Union[
317
+ HandleBinding,
318
+ SubscriptHandleBinding,
319
+ SlicedHandleBinding,
320
+ FieldHandleBinding,
321
+ ]
322
+ SubscriptHandleBinding.model_rebuild()
323
+ SlicedHandleBinding.model_rebuild()
324
+ FieldHandleBinding.model_rebuild()
@@ -1,38 +1,43 @@
1
- from typing import Mapping
1
+ from collections.abc import Mapping, Sequence
2
+ from typing import Literal, Union
2
3
 
3
- import pydantic
4
-
5
- from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
6
- from classiq.interface.model.handle_binding import HandleBinding
7
- from classiq.interface.model.quantum_statement import QuantumOperation
8
-
9
- from classiq._internals.enum_utils import StrEnum
10
- from classiq.exceptions import ClassiqValueError
4
+ from classiq.interface.enum_utils import StrEnum
5
+ from classiq.interface.generator.expressions.expression import Expression
6
+ from classiq.interface.model.handle_binding import ConcreteHandleBinding, HandleBinding
7
+ from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
11
8
 
12
9
 
13
10
  class BinaryOperation(StrEnum):
14
- Addition = "addition"
15
- Xor = "xor"
16
-
17
- @property
18
- def internal_function(self) -> str:
19
- return {
20
- BinaryOperation.Addition: "modular_add",
21
- BinaryOperation.Xor: "integer_xor",
22
- }[self]
11
+ Addition = "inplace_add"
12
+ Xor = "inplace_xor"
23
13
 
24
14
 
25
15
  class InplaceBinaryOperation(QuantumOperation):
26
- target: HandleBinding
27
- value: HandleBinding
16
+ kind: Literal["InplaceBinaryOperation"]
17
+
18
+ target: ConcreteHandleBinding
19
+ value: Union[ConcreteHandleBinding, Expression]
28
20
  operation: BinaryOperation
29
21
 
30
22
  @property
31
23
  def wiring_inouts(self) -> Mapping[str, HandleBinding]:
32
- return nameables_to_dict([self.target, self.value])
24
+ inouts = {self.target.name: self.target}
25
+ if isinstance(self.value, HandleBinding):
26
+ inouts[self.value.name] = self.value
27
+ return inouts
33
28
 
34
- @pydantic.validator("target", "value")
35
- def validate_handle(cls, handle: HandleBinding) -> HandleBinding:
36
- if not handle.is_bindable():
37
- raise ClassiqValueError(f"Cannot bind '{handle!r}'")
38
- return handle
29
+ @property
30
+ def readable_inouts(self) -> Sequence[HandleMetadata]:
31
+ suffix = f" of an in-place {self.operation.name.lower()} statement"
32
+ readable_inouts = [
33
+ HandleMetadata(
34
+ handle=self.target, readable_location=f"as the target{suffix}"
35
+ )
36
+ ]
37
+ if isinstance(self.value, HandleBinding):
38
+ readable_inouts.append(
39
+ HandleMetadata(
40
+ handle=self.value, readable_location=f"as the value{suffix}"
41
+ )
42
+ )
43
+ return readable_inouts
@@ -0,0 +1,12 @@
1
+ from typing import TYPE_CHECKING, Literal
2
+
3
+ from classiq.interface.model.quantum_statement import QuantumOperation
4
+
5
+ if TYPE_CHECKING:
6
+ from classiq.interface.model.statement_block import StatementBlock
7
+
8
+
9
+ class Invert(QuantumOperation):
10
+ kind: Literal["Invert"]
11
+
12
+ body: "StatementBlock"