classiq 0.38.0__py3-none-any.whl → 0.65.4__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 (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/METADATA +16 -9
  414. classiq-0.65.4.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/WHEEL +0 -0
classiq/qmod/qfunc.py CHANGED
@@ -1,25 +1,77 @@
1
- from typing import Callable, Optional, Union, overload
1
+ from collections.abc import Iterator
2
+ from contextlib import contextmanager
3
+ from typing import Callable, Literal, Optional, Union, overload
4
+
5
+ from classiq.interface.exceptions import ClassiqInternalError
2
6
 
3
7
  from classiq.qmod.quantum_callable import QCallable
4
- from classiq.qmod.quantum_function import ExternalQFunc, QFunc
8
+ from classiq.qmod.quantum_function import (
9
+ BaseQFunc,
10
+ ExternalQFunc,
11
+ GenerativeQFunc,
12
+ QFunc,
13
+ )
14
+
15
+ _GENERATIVE_SWITCH = False
16
+
17
+
18
+ @contextmanager
19
+ def set_global_generative_switch() -> Iterator[None]:
20
+ global _GENERATIVE_SWITCH
21
+ previous = _GENERATIVE_SWITCH
22
+ _GENERATIVE_SWITCH = True
23
+ try:
24
+ yield
25
+ finally:
26
+ _GENERATIVE_SWITCH = previous
5
27
 
6
28
 
7
29
  @overload
8
- def qfunc(func: Callable, *, external: bool = False) -> QFunc: ...
30
+ def qfunc(func: Callable) -> QFunc: ...
9
31
 
10
32
 
11
33
  @overload
12
- def qfunc(func: None = None, *, external: bool) -> Callable[[Callable], QCallable]: ...
34
+ def qfunc(
35
+ *,
36
+ external: Literal[True],
37
+ synthesize_separately: Literal[False] = False,
38
+ ) -> Callable[[Callable], ExternalQFunc]: ...
13
39
 
14
40
 
41
+ @overload
15
42
  def qfunc(
16
- func: Optional[Callable] = None, *, external: bool = False
43
+ *,
44
+ generative: Literal[True],
45
+ synthesize_separately: bool = False,
46
+ ) -> Callable[[Callable], GenerativeQFunc]: ...
47
+
48
+
49
+ @overload
50
+ def qfunc(*, synthesize_separately: bool) -> Callable[[Callable], QFunc]: ...
51
+
52
+
53
+ def qfunc(
54
+ func: Optional[Callable] = None,
55
+ *,
56
+ external: bool = False,
57
+ generative: bool = False,
58
+ synthesize_separately: bool = False,
17
59
  ) -> Union[Callable[[Callable], QCallable], QCallable]:
18
60
  def wrapper(func: Callable) -> QCallable:
19
- if external:
61
+ qfunc: BaseQFunc
62
+ if generative or _GENERATIVE_SWITCH:
63
+ qfunc = GenerativeQFunc(func)
64
+ elif external:
65
+ if synthesize_separately:
66
+ raise ClassiqInternalError(
67
+ "External functions can't be marked as synthesized separately"
68
+ )
20
69
  return ExternalQFunc(func)
21
-
22
- return QFunc(func)
70
+ else:
71
+ qfunc = QFunc(func)
72
+ if synthesize_separately:
73
+ qfunc.update_compilation_metadata(should_synthesize_separately=True)
74
+ return qfunc
23
75
 
24
76
  if func is not None:
25
77
  return wrapper(func)
@@ -1,20 +1,37 @@
1
1
  import inspect
2
- from typing import Any, Optional
2
+ from dataclasses import is_dataclass
3
+ from typing import Any, Optional, cast, get_origin
3
4
 
5
+ from classiq.interface.exceptions import ClassiqError, ClassiqValueError
4
6
  from classiq.interface.generator.constant import Constant
5
7
  from classiq.interface.generator.expressions.expression import Expression
6
- from classiq.interface.generator.functions.classical_type import QStructBase
8
+ from classiq.interface.generator.functions.classical_type import (
9
+ ClassicalArray,
10
+ ClassicalList,
11
+ )
7
12
 
8
- from classiq.exceptions import ClassiqError
13
+ from classiq.qmod.cparam import CArray, CParamScalar
9
14
  from classiq.qmod.declaration_inferrer import python_type_to_qmod
15
+ from classiq.qmod.generative import (
16
+ get_frontend_interpreter,
17
+ interpret_expression,
18
+ is_generative_mode,
19
+ )
10
20
  from classiq.qmod.model_state_container import ModelStateContainer
11
- from classiq.qmod.qmod_parameter import QParam, QParamStruct
21
+ from classiq.qmod.qmod_parameter import CParam, CParamList, CParamStruct
22
+ from classiq.qmod.symbolic_expr import SymbolicExpr
23
+ from classiq.qmod.utilities import qmod_val_to_expr_str
12
24
 
25
+ QMODULE_ERROR_MESSAGE = (
26
+ "Error trying to add a constant to a model without a current QModule."
27
+ )
13
28
 
14
- class QConstant:
29
+
30
+ class QConstant(SymbolicExpr):
15
31
  CURRENT_QMODULE: Optional[ModelStateContainer] = None
16
32
 
17
33
  def __init__(self, name: str, py_type: type, value: Any) -> None:
34
+ super().__init__(name, False)
18
35
  self.name = name
19
36
  self._py_type = py_type
20
37
  self._value = value
@@ -24,53 +41,103 @@ class QConstant:
24
41
  QConstant.CURRENT_QMODULE = qmodule
25
42
 
26
43
  def add_to_model(self) -> None:
44
+ from classiq.qmod.builtins.constants import __all__ as builtin_constants
45
+
46
+ if self.name in builtin_constants:
47
+ return
27
48
  if QConstant.CURRENT_QMODULE is None:
28
- raise ClassiqError(
29
- "Error trying to add a constant to a model without a current QModule."
30
- )
49
+ raise ClassiqError(QMODULE_ERROR_MESSAGE)
31
50
 
32
- expr = str(self._value)
51
+ expr = qmod_val_to_expr_str(self._value)
33
52
  if (
34
53
  self.name in QConstant.CURRENT_QMODULE.constants
35
54
  and expr != QConstant.CURRENT_QMODULE.constants[self.name].value.expr
36
55
  ):
37
56
  raise ClassiqError(f"Constant {self.name} is already defined in the model")
38
57
 
58
+ constant = self._get_constant_node()
59
+ QConstant.CURRENT_QMODULE.constants[self.name] = constant
60
+ if is_generative_mode():
61
+ get_frontend_interpreter().add_constant(constant)
62
+
63
+ def _get_constant_node(self) -> Constant:
39
64
  if isinstance(self._value, QConstant):
40
- QConstant.CURRENT_QMODULE.constants[self.name] = Constant(
65
+ if QConstant.CURRENT_QMODULE is None:
66
+ raise ClassiqError(QMODULE_ERROR_MESSAGE)
67
+ return Constant(
41
68
  name=self.name,
42
69
  const_type=QConstant.CURRENT_QMODULE.constants[
43
70
  self._value.name
44
71
  ].const_type,
45
72
  value=Expression(expr=self._value.name),
46
73
  )
47
- else:
48
- qmod_type = python_type_to_qmod(
49
- self._py_type, qmodule=QConstant.CURRENT_QMODULE
50
- )
51
- if qmod_type is None:
52
- raise ClassiqError("Invalid QMOD type")
53
74
 
54
- QConstant.CURRENT_QMODULE.constants[self.name] = Constant(
55
- name=self.name,
56
- const_type=qmod_type,
57
- value=Expression(expr=expr),
58
- )
75
+ qmod_type = python_type_to_qmod(
76
+ self._py_type, qmodule=QConstant.CURRENT_QMODULE
77
+ )
78
+ if qmod_type is None:
79
+ raise ClassiqError("Invalid QMOD type")
59
80
 
60
- def __getattr__(self, name: str) -> QParam:
81
+ expr = qmod_val_to_expr_str(self._value)
82
+ return Constant(
83
+ name=self.name,
84
+ const_type=qmod_type,
85
+ value=Expression(expr=expr),
86
+ )
87
+
88
+ def __getattr__(self, name: str) -> CParam:
61
89
  self.add_to_model()
62
90
 
91
+ if name == "is_quantum":
92
+ return False # type:ignore[return-value]
93
+
63
94
  py_type = type(self._value)
64
95
  if (
65
96
  QConstant.CURRENT_QMODULE is None
66
97
  or not inspect.isclass(py_type)
67
- or not issubclass(py_type, QStructBase)
98
+ or not is_dataclass(py_type)
68
99
  ):
69
100
  return self.__getattribute__(name)
70
101
 
71
- return QParamStruct.get_field(
102
+ return CParamStruct.get_field(
72
103
  QConstant.CURRENT_QMODULE, self.name, py_type.__name__, name
73
104
  )
74
105
 
75
- def __str__(self) -> str:
76
- return self.name
106
+ def __getitem__(self, item: Any) -> CParam:
107
+ self.add_to_model()
108
+
109
+ assert QConstant.CURRENT_QMODULE is not None
110
+
111
+ qmod_type = python_type_to_qmod(
112
+ self._py_type, qmodule=QConstant.CURRENT_QMODULE
113
+ )
114
+ if qmod_type is None:
115
+ raise ClassiqError("Invalid QMOD type")
116
+
117
+ if not isinstance(qmod_type, (ClassicalList, ClassicalArray)):
118
+ raise ClassiqError("Invalid subscript to non-list constant")
119
+
120
+ return CParamList(
121
+ self.name,
122
+ qmod_type,
123
+ QConstant.CURRENT_QMODULE,
124
+ )[item]
125
+
126
+ def __len__(self) -> int:
127
+ raise ClassiqValueError(
128
+ "len(<const>) is not supported for classical constants - use <const>.len "
129
+ "instead"
130
+ )
131
+
132
+ @property
133
+ def len(self) -> int:
134
+ self.add_to_model()
135
+ if get_origin(self._py_type) != CArray:
136
+ raise ClassiqValueError(
137
+ f"Constant {self.name!r} of type {self._py_type.__name__!r} does not "
138
+ f"have a 'len' property"
139
+ )
140
+ len_expr = f"get_field({self.name}, 'len')"
141
+ if is_generative_mode():
142
+ return interpret_expression(len_expr)
143
+ return cast(int, CParamScalar(len_expr))
@@ -1,46 +1,38 @@
1
- import sys
2
- from typing import ( # type: ignore[attr-defined]
3
- TYPE_CHECKING,
4
- Any,
5
- Generic,
6
- TypeVar,
7
- Union,
8
- _GenericAlias,
9
- )
10
-
11
- from typing_extensions import ParamSpec
1
+ from typing import TYPE_CHECKING, Any, Union
12
2
 
3
+ from classiq.interface.exceptions import ClassiqValueError
13
4
  from classiq.interface.generator.functions.classical_type import (
5
+ Bool,
14
6
  ClassicalArray,
15
7
  ClassicalList,
16
8
  ClassicalType,
17
- Struct,
9
+ Integer,
10
+ Real,
11
+ )
12
+ from classiq.interface.generator.functions.type_name import Struct, TypeName
13
+
14
+ from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
15
+ from classiq.qmod.cparam import ( # noqa: F401
16
+ Array,
17
+ ArrayBase,
18
+ CArray,
19
+ CBool,
20
+ CInt,
21
+ CParam,
22
+ CParamScalar,
23
+ CReal,
18
24
  )
19
-
20
- from classiq import StructDeclaration
21
- from classiq.exceptions import ClassiqValueError
22
25
  from classiq.qmod.model_state_container import ModelStateContainer
23
26
  from classiq.qmod.symbolic_expr import Symbolic, SymbolicExpr
24
27
 
25
- _T = TypeVar("_T")
26
-
27
-
28
28
  if TYPE_CHECKING:
29
29
 
30
- class QParam(SymbolicExpr, Generic[_T]):
31
- pass
32
-
30
+ SymbolicSuperclass = SymbolicExpr
33
31
  else:
32
+ SymbolicSuperclass = Symbolic
34
33
 
35
- class QParam(Symbolic, Generic[_T]):
36
- pass
37
-
38
-
39
- class QParamScalar(QParam, SymbolicExpr):
40
- pass
41
34
 
42
-
43
- class QParamList(QParam):
35
+ class CParamList(CParam):
44
36
  def __init__(
45
37
  self,
46
38
  expr: str,
@@ -51,23 +43,33 @@ class QParamList(QParam):
51
43
  self._qmodule = qmodule
52
44
  self._list_type = list_type
53
45
 
54
- def __getitem__(self, key: Any) -> QParam:
46
+ def __getitem__(self, key: Any) -> CParam:
47
+ param_type = self._list_type.element_type
48
+ if isinstance(key, slice):
49
+ param_type = self._list_type
50
+ start = key.start if key.start is not None else ""
51
+ stop = key.stop if key.stop is not None else ""
52
+ if key.step is not None:
53
+ key = f"{start}:{key.step}:{stop}"
54
+ else:
55
+ key = f"{start}:{stop}"
55
56
  return create_param(
56
57
  f"({self})[{key}]",
57
- self._list_type.element_type,
58
+ param_type,
58
59
  qmodule=self._qmodule,
59
60
  )
60
61
 
61
62
  def __len__(self) -> int:
62
63
  raise ClassiqValueError(
63
- "len(<expr>) is not supported for QMod lists - use <expr>.len() instead"
64
+ "len(<expr>) is not supported for QMod lists - use <expr>.len instead"
64
65
  )
65
66
 
66
- def len(self) -> QParamScalar:
67
- return QParamScalar(f"len({self})")
67
+ @property
68
+ def len(self) -> CParamScalar:
69
+ return CParamScalar(f"get_field({self}, 'len')")
68
70
 
69
71
 
70
- class QParamStruct(QParam):
72
+ class CParamStruct(CParam):
71
73
  def __init__(
72
74
  self, expr: str, struct_type: Struct, *, qmodule: ModelStateContainer
73
75
  ) -> None:
@@ -75,8 +77,8 @@ class QParamStruct(QParam):
75
77
  self._qmodule = qmodule
76
78
  self._struct_type = struct_type
77
79
 
78
- def __getattr__(self, field_name: str) -> QParam:
79
- return QParamStruct.get_field(
80
+ def __getattr__(self, field_name: str) -> CParam:
81
+ return CParamStruct.get_field(
80
82
  self._qmodule, str(self), self._struct_type.name, field_name
81
83
  )
82
84
 
@@ -86,15 +88,16 @@ class QParamStruct(QParam):
86
88
  variable_name: str,
87
89
  struct_name: str,
88
90
  field_name: str,
89
- ) -> QParam:
90
- struct_decl = StructDeclaration.BUILTIN_STRUCT_DECLARATIONS.get(
91
+ ) -> CParam:
92
+ struct_decl = BUILTIN_STRUCT_DECLARATIONS.get(
91
93
  struct_name, qmodule.type_decls.get(struct_name)
92
94
  )
93
95
  assert struct_decl is not None
94
96
  field_type = struct_decl.variables.get(field_name)
95
97
  if field_type is None:
96
98
  raise ClassiqValueError(
97
- f"Struct {struct_name!r} doesn't have field {field_name!r}"
99
+ f"{struct_name} {variable_name!r} has no field {field_name!r}. "
100
+ f"Available fields: {', '.join(struct_decl.variables.keys())}"
98
101
  )
99
102
 
100
103
  return create_param(
@@ -104,27 +107,33 @@ class QParamStruct(QParam):
104
107
  )
105
108
 
106
109
 
107
- _P = ParamSpec("_P")
108
-
109
-
110
- class ArrayBase(Generic[_P]):
111
- # Support comma-separated generic args in older Python versions
112
- if sys.version_info[0:2] < (3, 10):
113
-
114
- def __class_getitem__(cls, args) -> _GenericAlias:
115
- return _GenericAlias(cls, args)
116
-
117
-
118
- class Array(ArrayBase[_P]):
119
- pass
120
-
121
-
122
110
  def create_param(
123
111
  expr_str: str, ctype: ClassicalType, qmodule: ModelStateContainer
124
- ) -> QParam:
112
+ ) -> CParam:
125
113
  if isinstance(ctype, (ClassicalList, ClassicalArray)):
126
- return QParamList(expr_str, ctype, qmodule=qmodule)
114
+ return CParamList(expr_str, ctype, qmodule=qmodule)
127
115
  elif isinstance(ctype, Struct):
128
- return QParamStruct(expr_str, ctype, qmodule=qmodule)
116
+ return CParamStruct(expr_str, ctype, qmodule=qmodule)
129
117
  else:
130
- return QParamScalar(expr_str)
118
+ return CParamScalar(expr_str)
119
+
120
+
121
+ def get_qmod_type(ctype: ClassicalType) -> type:
122
+ if isinstance(ctype, Integer):
123
+ return CInt
124
+ elif isinstance(ctype, Real):
125
+ return CReal
126
+ elif isinstance(ctype, Bool):
127
+ return CBool
128
+ elif isinstance(ctype, ClassicalList):
129
+ return CArray[get_qmod_type(ctype.element_type)] # type: ignore[misc]
130
+ elif isinstance(ctype, ClassicalArray):
131
+ return CArray[get_qmod_type(ctype.element_type), ctype.size] # type: ignore[misc]
132
+ elif isinstance(ctype, TypeName):
133
+ type_ = type(ctype.name, (TypeName,), dict())
134
+ if isinstance(ctype, Struct):
135
+ type_.__dataclass_fields__ = [] # type:ignore[attr-defined]
136
+ return type_
137
+ raise NotImplementedError(
138
+ f"{ctype.__class__.__name__!r} has no QMOD SDK equivalent"
139
+ )