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
@@ -14,12 +14,14 @@ from typing_extensions import ParamSpec
14
14
 
15
15
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
16
16
  from classiq.interface.model.quantum_function_declaration import (
17
- QuantumFunctionDeclaration,
17
+ AnonQuantumFunctionDeclaration,
18
18
  )
19
19
  from classiq.interface.model.quantum_statement import QuantumStatement
20
20
  from classiq.interface.model.quantum_type import QuantumType
21
+ from classiq.interface.source_reference import SourceReference
21
22
 
22
- from classiq.qmod.qmod_parameter import QParam
23
+ from classiq.qmod.cparam import CInt
24
+ from classiq.qmod.utilities import get_source_ref
23
25
 
24
26
  if TYPE_CHECKING:
25
27
  from classiq.qmod.quantum_expandable import QTerminalCallable
@@ -33,23 +35,30 @@ class QExpandableInterface(ABC):
33
35
  raise NotImplementedError()
34
36
 
35
37
  @abstractmethod
36
- def add_local_handle(self, name: str, qtype: QuantumType) -> None:
38
+ def add_local_handle(
39
+ self,
40
+ name: str,
41
+ qtype: QuantumType,
42
+ source_ref: Optional[SourceReference] = None,
43
+ ) -> None:
37
44
  raise NotImplementedError()
38
45
 
39
46
 
40
47
  class QCallable(Generic[P], ABC):
41
48
  CURRENT_EXPANDABLE: ClassVar[Optional[QExpandableInterface]] = None
49
+ FRAME_DEPTH = 1
42
50
 
43
51
  def __call__(self, *args: Any, **kwargs: Any) -> None:
44
52
  assert QCallable.CURRENT_EXPANDABLE is not None
53
+ source_ref = get_source_ref(sys._getframe(self.FRAME_DEPTH))
45
54
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
46
- self.create_quantum_function_call(*args, **kwargs)
55
+ self.create_quantum_function_call(source_ref, *args, **kwargs)
47
56
  )
48
57
  return
49
58
 
50
59
  @property
51
60
  @abstractmethod
52
- def func_decl(self) -> QuantumFunctionDeclaration:
61
+ def func_decl(self) -> AnonQuantumFunctionDeclaration:
53
62
  raise NotImplementedError
54
63
 
55
64
  # Support comma-separated generic args in older Python versions
@@ -60,7 +69,7 @@ class QCallable(Generic[P], ABC):
60
69
 
61
70
  @abstractmethod
62
71
  def create_quantum_function_call(
63
- self, *args: Any, **kwargs: Any
72
+ self, source_ref_: SourceReference, *args: Any, **kwargs: Any
64
73
  ) -> QuantumFunctionCall:
65
74
  raise NotImplementedError()
66
75
 
@@ -68,7 +77,8 @@ class QCallable(Generic[P], ABC):
68
77
  class QCallableList(QCallable, Generic[P], ABC):
69
78
  if TYPE_CHECKING:
70
79
 
80
+ @property
71
81
  def len(self) -> int: ...
72
82
 
73
- def __getitem__(self, key: Union[slice, int, QParam]) -> "QTerminalCallable":
83
+ def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
74
84
  raise NotImplementedError()
@@ -1,64 +1,87 @@
1
+ import inspect
1
2
  from abc import ABC
3
+ from dataclasses import is_dataclass
4
+ from enum import Enum as PythonEnum
2
5
  from types import TracebackType
3
6
  from typing import (
4
7
  TYPE_CHECKING,
5
8
  Any,
6
9
  Callable,
7
10
  ClassVar,
8
- Dict,
9
- List,
10
11
  Optional,
11
- Type,
12
12
  Union,
13
13
  cast,
14
14
  overload,
15
15
  )
16
16
 
17
+ import pydantic
18
+ from sympy import Basic
17
19
  from typing_extensions import Self
18
20
 
21
+ from classiq.interface.exceptions import ClassiqInternalError, ClassiqValueError
19
22
  from classiq.interface.generator.expressions.expression import Expression
23
+ from classiq.interface.generator.functions.concrete_types import (
24
+ NativePythonClassicalTypes,
25
+ PythonClassicalPydanticTypes,
26
+ )
20
27
  from classiq.interface.model.classical_parameter_declaration import (
21
- ClassicalParameterDeclaration,
28
+ AnonClassicalParameterDeclaration,
22
29
  )
23
- from classiq.interface.model.port_declaration import PortDeclaration
30
+ from classiq.interface.model.port_declaration import AnonPortDeclaration
24
31
  from classiq.interface.model.quantum_function_call import (
25
32
  ArgValue,
26
- OperandIdentifier,
27
33
  QuantumFunctionCall,
28
- QuantumLambdaFunction,
29
- QuantumOperand,
30
34
  )
31
35
  from classiq.interface.model.quantum_function_declaration import (
32
- PositionalArg,
36
+ AnonPositionalArg,
37
+ AnonQuantumFunctionDeclaration,
38
+ AnonQuantumOperandDeclaration,
33
39
  QuantumFunctionDeclaration,
34
- QuantumOperandDeclaration,
40
+ )
41
+ from classiq.interface.model.quantum_lambda_function import (
42
+ OperandIdentifier,
43
+ QuantumCallable,
44
+ QuantumLambdaFunction,
35
45
  )
36
46
  from classiq.interface.model.quantum_statement import QuantumStatement
37
47
  from classiq.interface.model.quantum_type import QuantumType
38
48
  from classiq.interface.model.variable_declaration_statement import (
39
49
  VariableDeclarationStatement,
40
50
  )
51
+ from classiq.interface.source_reference import SourceReference
41
52
 
42
- from classiq.exceptions import ClassiqValueError
53
+ from classiq.qmod.generative import generative_mode_context, is_generative_mode
43
54
  from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
44
- from classiq.qmod.qmod_parameter import QParam, QParamScalar, create_param
45
- from classiq.qmod.qmod_variable import QVar, create_qvar_for_port_decl
55
+ from classiq.qmod.qmod_constant import QConstant
56
+ from classiq.qmod.qmod_parameter import (
57
+ CInt,
58
+ CParam,
59
+ CParamScalar,
60
+ create_param,
61
+ get_qmod_type,
62
+ )
63
+ from classiq.qmod.qmod_variable import (
64
+ QVar,
65
+ create_qvar_for_port_decl,
66
+ )
46
67
  from classiq.qmod.quantum_callable import QCallable, QExpandableInterface
47
- from classiq.qmod.utilities import mangle_keyword
68
+ from classiq.qmod.symbolic_expr import SymbolicExpr
69
+ from classiq.qmod.type_attribute_remover import decl_without_type_attributes
70
+ from classiq.qmod.utilities import mangle_keyword, qmod_val_to_expr_str
48
71
 
49
- ArgType = Union[QParam, QVar, QCallable]
72
+ ArgType = Union[CParam, QVar, QCallable]
50
73
 
51
74
 
52
75
  class QExpandable(QCallable, QExpandableInterface, ABC):
53
- STACK: ClassVar[List["QExpandable"]] = list()
76
+ STACK: ClassVar[list["QExpandable"]] = list()
54
77
 
55
78
  def __init__(self, py_callable: Callable) -> None:
56
79
  self._qmodule: ModelStateContainer = QMODULE
57
80
  self._py_callable: Callable = py_callable
58
- self._body: List[QuantumStatement] = list()
81
+ self._body: list[QuantumStatement] = list()
59
82
 
60
83
  @property
61
- def body(self) -> List[QuantumStatement]:
84
+ def body(self) -> list[QuantumStatement]:
62
85
  return self._body
63
86
 
64
87
  def __enter__(self) -> Self:
@@ -69,7 +92,7 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
69
92
 
70
93
  def __exit__(
71
94
  self,
72
- exc_type: Optional[Type[BaseException]],
95
+ exc_type: Optional[type[BaseException]],
73
96
  exc_val: Optional[BaseException],
74
97
  exc_tb: Optional[TracebackType],
75
98
  ) -> None:
@@ -78,160 +101,303 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
78
101
  QExpandable.STACK[-1] if QExpandable.STACK else None
79
102
  )
80
103
 
104
+ def __call__(self, *args: Any, **kwargs: Any) -> None:
105
+ super().__call__(*args, **kwargs)
106
+ self.add_function_dependencies()
107
+
81
108
  def expand(self) -> None:
82
- with self:
83
- self._py_callable(*self._get_positional_args())
109
+ if self not in QExpandable.STACK:
110
+ with self, generative_mode_context(False):
111
+ self._py_callable(*self._get_positional_args())
84
112
 
85
- def infer_rename_params(self) -> Dict[str, str]:
86
- return {}
113
+ def infer_rename_params(self) -> Optional[list[str]]:
114
+ return None
87
115
 
88
- def add_local_handle(self, name: str, qtype: QuantumType) -> None:
89
- self._body.append(VariableDeclarationStatement(name=name, quantum_type=qtype))
116
+ def add_local_handle(
117
+ self,
118
+ name: str,
119
+ qtype: QuantumType,
120
+ source_ref: Optional[SourceReference] = None,
121
+ ) -> None:
122
+ self.append_statement_to_body(
123
+ VariableDeclarationStatement(
124
+ name=name, quantum_type=qtype, source_ref=source_ref
125
+ )
126
+ )
90
127
 
91
128
  def append_statement_to_body(self, stmt: QuantumStatement) -> None:
92
129
  self._body.append(stmt)
93
130
 
94
- def _get_positional_args(self) -> List[ArgType]:
95
- result: List[ArgType] = []
96
- for arg in self.func_decl.get_positional_arg_decls():
97
- if isinstance(arg, ClassicalParameterDeclaration):
98
- rename_dict = self.infer_rename_params()
99
- actual_name = (
100
- rename_dict[arg.name] if arg.name in rename_dict else arg.name
101
- )
131
+ def _get_positional_args(self) -> list[ArgType]:
132
+ result: list[ArgType] = []
133
+ rename_params = self.infer_rename_params()
134
+ if rename_params is not None and len(rename_params) != len(
135
+ self.func_decl.positional_arg_declarations
136
+ ):
137
+ op_name = (
138
+ f" {self.func_decl.name!r}" if self.func_decl.name is not None else ""
139
+ )
140
+ raise ClassiqValueError(
141
+ f"Operand{op_name} takes {len(self.func_decl.positional_arg_declarations)} arguments but the received function takes {len(rename_params)} argument"
142
+ )
143
+ for idx, arg in enumerate(self.func_decl.positional_arg_declarations):
144
+ actual_name = (
145
+ rename_params[idx] if rename_params is not None else arg.get_name()
146
+ )
147
+ if isinstance(arg, AnonClassicalParameterDeclaration):
102
148
  result.append(
103
149
  create_param(actual_name, arg.classical_type, self._qmodule)
104
150
  )
105
- elif isinstance(arg, PortDeclaration):
106
- result.append(create_qvar_for_port_decl(arg))
151
+ elif isinstance(arg, AnonPortDeclaration):
152
+ result.append(create_qvar_for_port_decl(arg, actual_name))
107
153
  else:
108
- assert isinstance(arg, QuantumOperandDeclaration)
109
- result.append(QTerminalCallable(arg))
154
+ assert isinstance(arg, AnonQuantumOperandDeclaration)
155
+ result.append(QTerminalCallable(arg, idx))
110
156
  return result
111
157
 
112
158
  def create_quantum_function_call(
113
- self, *args: Any, **kwargs: Any
159
+ self, source_ref_: SourceReference, *args: Any, **kwargs: Any
114
160
  ) -> QuantumFunctionCall:
115
- return _create_quantum_function_call(self.func_decl, None, *args, **kwargs)
161
+ func_decl = self.func_decl
162
+ if not isinstance(func_decl, QuantumFunctionDeclaration):
163
+ raise NotImplementedError
164
+ return _create_quantum_function_call(
165
+ func_decl, None, source_ref_, *args, **kwargs
166
+ )
167
+
168
+ def add_function_dependencies(self) -> None:
169
+ called_name = self.func_decl.name
170
+ if called_name is None:
171
+ return
172
+ for expandable in QExpandable.STACK:
173
+ caller_name = expandable.func_decl.name
174
+ if caller_name is not None:
175
+ caller_deps = self._qmodule.function_dependencies[caller_name]
176
+ if called_name not in caller_deps:
177
+ caller_deps.append(called_name)
116
178
 
117
179
 
118
180
  class QLambdaFunction(QExpandable):
119
- def __init__(self, decl: QuantumFunctionDeclaration, py_callable: Callable) -> None:
181
+ def __init__(
182
+ self, decl: AnonQuantumFunctionDeclaration, py_callable: Callable
183
+ ) -> None:
120
184
  py_callable.__annotations__.pop("return", None)
121
185
  super().__init__(py_callable)
122
186
  self._decl = decl
123
187
 
124
188
  @property
125
- def func_decl(self) -> QuantumFunctionDeclaration:
189
+ def func_decl(self) -> AnonQuantumFunctionDeclaration:
126
190
  return self._decl
127
191
 
128
- def infer_rename_params(self) -> Dict[str, str]:
129
- if not self._py_callable.__annotations__:
130
- return {}
131
- return {
132
- decl_name: actual_name
133
- for decl_name, actual_name in list(
134
- zip(
135
- [arg.name for arg in self.func_decl.get_positional_arg_decls()],
136
- self._py_callable.__annotations__.keys(),
137
- )
138
- )
139
- if decl_name != actual_name
140
- }
192
+ def expand(self) -> None:
193
+ if not is_generative_mode():
194
+ super().expand()
195
+
196
+ def infer_rename_params(self) -> list[str]:
197
+ return inspect.getfullargspec(self._py_callable).args
141
198
 
142
199
 
143
200
  class QTerminalCallable(QCallable):
201
+ @overload
144
202
  def __init__(
145
203
  self,
146
204
  decl: QuantumFunctionDeclaration,
147
- index_: Optional[Union[int, QParamScalar]] = None,
205
+ param_idx: Optional[int] = None,
206
+ index_: Optional[Union[int, CParamScalar]] = None,
148
207
  ) -> None:
149
- self._decl = decl
208
+ pass
209
+
210
+ @overload
211
+ def __init__(
212
+ self,
213
+ decl: AnonQuantumFunctionDeclaration,
214
+ param_idx: int,
215
+ index_: Optional[Union[int, CParamScalar]] = None,
216
+ ) -> None:
217
+ pass
218
+
219
+ def __init__(
220
+ self,
221
+ decl: AnonQuantumFunctionDeclaration,
222
+ param_idx: Optional[int] = None,
223
+ index_: Optional[Union[int, CParamScalar]] = None,
224
+ ) -> None:
225
+ self._decl = self._override_decl_name(decl, param_idx)
150
226
  self._index = index_
151
227
 
228
+ @staticmethod
229
+ def _override_decl_name(
230
+ decl: AnonQuantumFunctionDeclaration, param_idx: Optional[int]
231
+ ) -> QuantumFunctionDeclaration:
232
+ if (
233
+ not isinstance(QCallable.CURRENT_EXPANDABLE, QLambdaFunction)
234
+ or param_idx is None
235
+ ):
236
+ return decl.rename(decl.get_name())
237
+ rename_params = QCallable.CURRENT_EXPANDABLE.infer_rename_params()
238
+ return decl.rename(new_name=rename_params[param_idx])
239
+
152
240
  @property
153
241
  def is_list(self) -> bool:
154
- return isinstance(self._decl, QuantumOperandDeclaration) and self._decl.is_list
242
+ return (
243
+ isinstance(self._decl, AnonQuantumOperandDeclaration) and self._decl.is_list
244
+ )
155
245
 
156
- def __getitem__(self, key: Union[slice, int, QParam]) -> "QTerminalCallable":
246
+ def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
157
247
  if not self.is_list:
158
248
  raise ClassiqValueError("Cannot index a non-list operand")
159
249
  if isinstance(key, slice):
160
250
  raise NotImplementedError("Operand lists don't support slicing")
161
- if isinstance(key, QParam) and not isinstance(key, QParamScalar):
251
+ if isinstance(key, CParam) and not isinstance(key, CParamScalar):
162
252
  raise ClassiqValueError("Non-classical parameter for slicing")
163
- return QTerminalCallable(self._decl, key)
253
+ if not isinstance(self._decl, AnonQuantumOperandDeclaration):
254
+ raise ClassiqInternalError
255
+ return QTerminalCallable(self._decl.element_declaration, index_=key)
164
256
 
165
257
  def __len__(self) -> int:
166
- raise ValueError(
167
- "len(<func>) is not supported for quantum callables - use <func>.len() instead (Only if it is an operand list)"
258
+ raise ClassiqValueError(
259
+ "len(<func>) is not supported for quantum callables - use <func>.len instead (Only if it is an operand list)"
168
260
  )
169
261
 
170
262
  if TYPE_CHECKING:
171
263
 
264
+ @property
172
265
  def len(self) -> int: ...
173
266
 
174
267
  else:
175
268
 
176
- def len(self) -> QParamScalar:
269
+ @property
270
+ def len(self) -> CParamScalar:
177
271
  if not self.is_list:
178
272
  raise ClassiqValueError("Cannot get length of a non-list operand")
179
- return QParamScalar(f"len({self.func_decl.name})")
273
+ return CParamScalar(f"get_field({self.func_decl.name}, 'len')")
180
274
 
181
275
  @property
182
276
  def func_decl(self) -> QuantumFunctionDeclaration:
183
277
  return self._decl
184
278
 
185
279
  def create_quantum_function_call(
186
- self, *args: Any, **kwargs: Any
280
+ self, source_ref_: SourceReference, *args: Any, **kwargs: Any
187
281
  ) -> QuantumFunctionCall:
188
282
  if self.is_list and self._index is None:
189
283
  raise ClassiqValueError(
190
284
  f"Quantum operand {self.func_decl.name!r} is a list and must be indexed"
191
285
  )
192
286
  return _create_quantum_function_call(
193
- self.func_decl, self._index, *args, **kwargs
287
+ self.func_decl, self._index, source_ref_, *args, **kwargs
288
+ )
289
+
290
+ def get_arg(self) -> QuantumCallable:
291
+ if self._index is None:
292
+ return self._decl.name
293
+ return OperandIdentifier(
294
+ name=self._decl.name, index=Expression(expr=str(self._index))
194
295
  )
195
296
 
196
297
 
197
298
  @overload
198
299
  def prepare_arg(
199
- arg_decl: PositionalArg, val: Union[QCallable, Callable[[Any], None]]
200
- ) -> QuantumOperand: ...
300
+ arg_decl: AnonPositionalArg,
301
+ val: Union[QCallable, Callable[..., None]],
302
+ func_name: Optional[str],
303
+ param_name: str,
304
+ ) -> QuantumLambdaFunction: ...
201
305
 
202
306
 
203
307
  @overload
204
- def prepare_arg(arg_decl: PositionalArg, val: Any) -> ArgValue: ...
308
+ def prepare_arg(
309
+ arg_decl: AnonPositionalArg, val: Any, func_name: Optional[str], param_name: str
310
+ ) -> ArgValue: ...
205
311
 
206
312
 
207
- def prepare_arg(arg_decl: PositionalArg, val: Any) -> ArgValue:
208
- if isinstance(arg_decl, ClassicalParameterDeclaration):
209
- return Expression(expr=str(val))
210
- elif isinstance(arg_decl, PortDeclaration):
313
+ def prepare_arg(
314
+ arg_decl: AnonPositionalArg, val: Any, func_name: Optional[str], param_name: str
315
+ ) -> ArgValue:
316
+ from classiq.qmod.quantum_function import BaseQFunc, GenerativeQFunc
317
+
318
+ if isinstance(val, BaseQFunc):
319
+ val.add_function_dependencies()
320
+ if isinstance(val, GenerativeQFunc):
321
+ QMODULE.generative_functions[val.func_decl.name] = val
322
+ if isinstance(val, QConstant):
323
+ val.add_to_model()
324
+ return Expression(expr=str(val.name))
325
+ if isinstance(arg_decl, AnonClassicalParameterDeclaration):
326
+ _validate_classical_arg(val, arg_decl, func_name)
327
+ return Expression(expr=qmod_val_to_expr_str(val))
328
+ elif isinstance(arg_decl, AnonPortDeclaration):
329
+ if not isinstance(val, QVar):
330
+ func_name_message = (
331
+ "" if func_name is None else f" of function {func_name!r}"
332
+ )
333
+ raise ClassiqValueError(
334
+ f"Argument {str(val)!r} to parameter {param_name!r}{func_name_message} "
335
+ f"has incompatible type; expected quantum variable"
336
+ )
211
337
  return val.get_handle_binding()
212
338
  else:
213
339
  if isinstance(val, list):
214
340
  if not all(isinstance(v, QCallable) or callable(v) for v in val):
215
341
  raise ClassiqValueError(
216
- f"Quantum operand {arg_decl.name!r} cannot be initialized with a list of non-callables"
342
+ f"Quantum operand {param_name!r} cannot be initialized with a "
343
+ f"list of non-callables"
217
344
  )
218
- val = cast(List[Union[QCallable, Callable[[Any], None]]], val)
219
- return [prepare_arg(arg_decl, v) for v in val]
345
+ val = cast(list[Union[QCallable, Callable[[Any], None]]], val)
346
+ return [prepare_arg(arg_decl, v, func_name, param_name) for v in val]
220
347
 
221
348
  if not isinstance(val, QCallable):
222
- val = QLambdaFunction(arg_decl, val)
223
-
224
- if not isinstance(val, QExpandable):
225
- return val.func_decl.name
226
-
227
- val.expand()
228
- return QuantumLambdaFunction(
229
- rename_params=val.infer_rename_params(), body=val.body
349
+ if not callable(val):
350
+ raise ClassiqValueError(
351
+ f"Operand argument to {param_name!r} must be a callable object"
352
+ )
353
+ new_arg_decl = decl_without_type_attributes(arg_decl)
354
+ val = QLambdaFunction(new_arg_decl, val)
355
+ val.expand()
356
+ qlambda = QuantumLambdaFunction(
357
+ pos_rename_params=val.infer_rename_params(),
358
+ body=val.body,
359
+ )
360
+ if is_generative_mode():
361
+ qlambda.set_py_callable(val._py_callable)
362
+ return qlambda
363
+
364
+ if isinstance(val, QExpandable):
365
+ val.expand()
366
+ elif isinstance(val, QTerminalCallable):
367
+ return val.get_arg()
368
+ return val.func_decl.name
369
+
370
+
371
+ def _validate_classical_arg(
372
+ arg: Any, arg_decl: AnonClassicalParameterDeclaration, func_name: Optional[str]
373
+ ) -> None:
374
+ is_native_or_compatible_type = not isinstance(
375
+ arg, (*NativePythonClassicalTypes, CParam, SymbolicExpr, Basic, PythonEnum)
376
+ ) and not is_dataclass(
377
+ arg
378
+ ) # type: ignore[unreachable]
379
+ try:
380
+ is_pydantic_classical_type = isinstance(
381
+ arg, pydantic.BaseModel
382
+ ) and not isinstance(arg, PythonClassicalPydanticTypes)
383
+ except ClassiqValueError:
384
+ is_pydantic_classical_type = False
385
+
386
+ is_incompatible_symbolic_expr = isinstance(arg, SymbolicExpr) and arg.is_quantum
387
+
388
+ if (
389
+ is_native_or_compatible_type or is_pydantic_classical_type
390
+ ) or is_incompatible_symbolic_expr:
391
+ func_name_message = f" of function {func_name!r}" if func_name else ""
392
+ raise ClassiqValueError(
393
+ f"Argument {str(arg)!r} to parameter {arg_decl.name!r}{func_name_message} "
394
+ f"has incompatible type; expected "
395
+ f"{get_qmod_type(arg_decl.classical_type).__name__}"
230
396
  )
231
397
 
232
398
 
233
399
  def _get_operand_hint_args(
234
- func: QuantumFunctionDeclaration, param: PositionalArg, param_value: str
400
+ func: AnonQuantumFunctionDeclaration, param: AnonPositionalArg, param_value: str
235
401
  ) -> str:
236
402
  return ", ".join(
237
403
  [
@@ -240,50 +406,55 @@ def _get_operand_hint_args(
240
406
  if decl.name == param.name
241
407
  else f"{decl.name}=..."
242
408
  )
243
- for decl in func.get_positional_arg_decls()
409
+ for decl in func.positional_arg_declarations
244
410
  ]
245
411
  )
246
412
 
247
413
 
248
- def _get_operand_hint(func: QuantumFunctionDeclaration, param: PositionalArg) -> str:
414
+ def _get_operand_hint(
415
+ func: AnonQuantumFunctionDeclaration, param: AnonPositionalArg
416
+ ) -> str:
249
417
  return (
250
- f"\nHint: To create an operand, do not call quantum gates directly "
251
- f"`{func.name}({_get_operand_hint_args(func, param, 'H(q)')})`. "
252
- f"Instead, use a lambda function "
253
- f"`{func.name}({_get_operand_hint_args(func, param, 'lambda: H(q)')})` "
254
- f"or a quantum function "
255
- f"`{func.name}({_get_operand_hint_args(func, param, 'my_func')})`"
418
+ f"\nHint: To call a function under {func.name!r} use a lambda function as in "
419
+ f"'{func.name}({_get_operand_hint_args(func, param, 'lambda: f(q)')})' "
420
+ f"or pass the quantum function directly as in "
421
+ f"'{func.name}({_get_operand_hint_args(func, param, 'f')})'."
256
422
  )
257
423
 
258
424
 
259
425
  def _prepare_args(
260
- decl: QuantumFunctionDeclaration, arg_list: List[Any], kwargs: Dict[str, Any]
261
- ) -> List[ArgValue]:
426
+ decl: AnonQuantumFunctionDeclaration, arg_list: list[Any], kwargs: dict[str, Any]
427
+ ) -> list[ArgValue]:
262
428
  result = []
263
- for arg_decl in decl.get_positional_arg_decls():
429
+ for idx, arg_decl in enumerate(decl.positional_arg_declarations):
430
+ arg = None
264
431
  if arg_list:
265
432
  arg = arg_list.pop(0)
266
- else:
433
+ elif arg_decl.name is not None:
267
434
  arg = kwargs.pop(mangle_keyword(arg_decl.name), None)
268
435
  if arg is None:
269
- error_message = (
270
- f"{decl.name!r} is missing required argument for {arg_decl.name!r}"
271
- )
272
- if isinstance(arg_decl, QuantumOperandDeclaration):
436
+ if arg_decl.name is not None:
437
+ param_name = repr(arg_decl.name)
438
+ else:
439
+ param_name = f"#{idx + 1}"
440
+ error_message = f"Missing required argument for parameter {param_name}"
441
+ if isinstance(arg_decl, AnonQuantumOperandDeclaration):
273
442
  error_message += _get_operand_hint(decl, arg_decl)
274
443
  raise ClassiqValueError(error_message)
275
- result.append(prepare_arg(arg_decl, arg))
444
+ param_name = arg_decl.name if arg_decl.name is not None else f"#{idx + 1}"
445
+ result.append(prepare_arg(arg_decl, arg, decl.name, param_name))
276
446
 
277
447
  return result
278
448
 
279
449
 
280
450
  def _create_quantum_function_call(
281
451
  decl_: QuantumFunctionDeclaration,
282
- index_: Optional[Union[QParamScalar, int]] = None,
452
+ index_: Optional[Union[CParamScalar, int]] = None,
453
+ source_ref_: Optional[SourceReference] = None,
283
454
  *args: Any,
284
455
  **kwargs: Any,
285
456
  ) -> QuantumFunctionCall:
286
- arg_decls = decl_.get_positional_arg_decls()
457
+ arg_decls = decl_.positional_arg_declarations
287
458
  arg_list = list(args)
288
459
  prepared_args = _prepare_args(decl_, arg_list, kwargs)
289
460
 
@@ -307,4 +478,6 @@ def _create_quantum_function_call(
307
478
  index=Expression(expr=str(index_)), name=function_ident
308
479
  )
309
480
 
310
- return QuantumFunctionCall(function=function_ident, positional_args=prepared_args)
481
+ return QuantumFunctionCall(
482
+ function=function_ident, positional_args=prepared_args, source_ref=source_ref_
483
+ )