classiq 0.38.0__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 (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.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.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.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,384 @@
1
+ import ast
2
+ from collections.abc import Iterator, Mapping, Sequence
3
+ from contextlib import contextmanager
4
+ from typing import (
5
+ Optional,
6
+ )
7
+
8
+ from classiq.interface.exceptions import ClassiqSemanticError
9
+ from classiq.interface.generator.expressions.expression import Expression
10
+ from classiq.interface.generator.function_params import PortDirection
11
+ from classiq.interface.generator.functions.classical_type import CLASSICAL_ATTRIBUTES
12
+ from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
13
+ from classiq.interface.generator.functions.port_declaration import (
14
+ PortDeclarationDirection,
15
+ )
16
+ from classiq.interface.generator.visitor import Visitor
17
+ from classiq.interface.model.handle_binding import (
18
+ FieldHandleBinding,
19
+ HandleBinding,
20
+ SlicedHandleBinding,
21
+ SubscriptHandleBinding,
22
+ )
23
+ from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
24
+ from classiq.interface.model.model import Model
25
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
26
+ from classiq.interface.model.port_declaration import PortDeclaration
27
+ from classiq.interface.model.quantum_expressions.quantum_expression import (
28
+ QuantumExpressionOperation,
29
+ )
30
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
31
+ from classiq.interface.model.quantum_function_declaration import (
32
+ QuantumFunctionDeclaration,
33
+ QuantumOperandDeclaration,
34
+ )
35
+ from classiq.interface.model.quantum_lambda_function import (
36
+ QuantumLambdaFunction,
37
+ )
38
+ from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
39
+ from classiq.interface.model.validation_handle import HandleState
40
+ from classiq.interface.model.variable_declaration_statement import (
41
+ VariableDeclarationStatement,
42
+ )
43
+ from classiq.interface.model.within_apply_operation import WithinApply
44
+
45
+ from classiq.model_expansions.visitors.variable_references import VarRefCollector
46
+ from classiq.qmod.builtins.functions import (
47
+ BUILTIN_FUNCTION_DECLARATIONS,
48
+ )
49
+ from classiq.qmod.semantics.annotation.call_annotation import resolve_function_calls
50
+ from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
51
+ from classiq.qmod.semantics.error_manager import ErrorManager
52
+ from classiq.qmod.semantics.lambdas import get_renamed_parameters
53
+ from classiq.qmod.semantics.validation.constants_validation import (
54
+ check_duplicate_constants,
55
+ )
56
+ from classiq.qmod.semantics.validation.func_call_validation import (
57
+ check_no_overlapping_quantum_args,
58
+ validate_call_arguments,
59
+ )
60
+ from classiq.qmod.semantics.validation.function_name_collisions_validation import (
61
+ _check_function_name_collisions,
62
+ )
63
+ from classiq.qmod.semantics.validation.handle_validation import resolve_handle
64
+ from classiq.qmod.semantics.validation.main_validation import validate_main_function
65
+ from classiq.qmod.semantics.validation.types_validation import (
66
+ check_cstruct_has_fields,
67
+ check_duplicate_types,
68
+ check_qstruct_fields_are_defined,
69
+ check_qstruct_flexibility,
70
+ check_qstruct_has_fields,
71
+ check_qstruct_is_not_recursive,
72
+ )
73
+
74
+ HANDLE_BINDING_PART_MESSAGE = {
75
+ SubscriptHandleBinding: "array subscript",
76
+ SlicedHandleBinding: "array slice",
77
+ FieldHandleBinding: "field access",
78
+ }
79
+
80
+
81
+ class StaticScope:
82
+ def __init__(
83
+ self,
84
+ parameters: list[str],
85
+ operands: dict[str, QuantumOperandDeclaration],
86
+ variables_to_states: dict[str, HandleState],
87
+ variables_to_types: dict[str, ConcreteQuantumType],
88
+ ) -> None:
89
+ self.parameters = parameters
90
+ self.operands = operands
91
+ self.variable_states = variables_to_states
92
+ self.variables_to_types = variables_to_types
93
+
94
+
95
+ class StaticSemanticsVisitor(Visitor):
96
+ def __init__(
97
+ self,
98
+ functions_dict: Mapping[str, QuantumFunctionDeclaration],
99
+ constants: list[str],
100
+ ) -> None:
101
+ self._scope: list[StaticScope] = []
102
+ self._error_manager = ErrorManager()
103
+ self._functions_dict = functions_dict
104
+ self._constants = constants
105
+
106
+ @property
107
+ def current_scope(self) -> StaticScope:
108
+ return self._scope[-1]
109
+
110
+ @contextmanager
111
+ def scoped_visit(self, scope: StaticScope) -> Iterator[None]:
112
+ self._scope.append(scope)
113
+ yield
114
+ self._scope.pop()
115
+
116
+ def visit_Model(self, model: Model) -> None:
117
+ check_duplicate_types([*model.enums, *model.types, *model.qstructs])
118
+ check_duplicate_constants(model.constants)
119
+ for qstruct in model.qstructs:
120
+ check_qstruct_has_fields(qstruct)
121
+ if check_qstruct_fields_are_defined(
122
+ qstruct
123
+ ) and check_qstruct_is_not_recursive(qstruct):
124
+ check_qstruct_flexibility(qstruct)
125
+ for cstruct in model.types:
126
+ check_cstruct_has_fields(cstruct)
127
+ validate_main_function(model.main_func)
128
+ self.visit_BaseModel(model)
129
+
130
+ def visit_NativeFunctionDefinition(
131
+ self, func_def: NativeFunctionDefinition
132
+ ) -> None:
133
+ scope = StaticScope(
134
+ parameters=list(func_def.param_names) + self._constants,
135
+ operands=dict(func_def.operand_declarations_dict),
136
+ variables_to_states=initialize_variables_to_state(
137
+ func_def.port_declarations
138
+ ),
139
+ variables_to_types={
140
+ port.name: port.quantum_type for port in func_def.port_declarations
141
+ },
142
+ )
143
+ with self.scoped_visit(scope), self._error_manager.call(func_def.name):
144
+ parameter_declaration_names = [
145
+ decl.name for decl in func_def.positional_arg_declarations
146
+ ]
147
+ seen_names: set[str] = set()
148
+ for name in parameter_declaration_names:
149
+ if name in seen_names:
150
+ self._error_manager.add_error(
151
+ f"duplicate parameter declaration name {name!r}"
152
+ )
153
+ seen_names.add(name)
154
+ if len(func_def.body) == 0:
155
+ return
156
+ self.visit(func_def.body)
157
+ with self._error_manager.node_context(func_def.body[-1]):
158
+ for port_decl in func_def.port_declarations:
159
+ handle_state = self.current_scope.variable_states[port_decl.name]
160
+ expected_terminal_state = EXPECTED_TERMINAL_STATES.get(
161
+ port_decl.direction
162
+ )
163
+ if (
164
+ expected_terminal_state is not None
165
+ and handle_state is not expected_terminal_state
166
+ ):
167
+ self._error_manager.add_error(
168
+ f"At the end of the function, port `{port_decl.name}` is expected to be {expected_terminal_state.name.lower()} but it isn't"
169
+ )
170
+
171
+ def visit_WithinApply(self, within_apply: WithinApply) -> None:
172
+ initial_variables_to_state = self.current_scope.variable_states.copy()
173
+ scope = StaticScope(
174
+ parameters=self.current_scope.parameters,
175
+ operands=self.current_scope.operands,
176
+ variables_to_states=self.current_scope.variable_states.copy(),
177
+ variables_to_types=self.current_scope.variables_to_types.copy(),
178
+ )
179
+ with self.scoped_visit(scope):
180
+ self.visit(within_apply.compute)
181
+ compute_captured_variables = {
182
+ var
183
+ for var, state in self.current_scope.variable_states.items()
184
+ if var in initial_variables_to_state
185
+ and state != initial_variables_to_state[var]
186
+ }
187
+ self.visit(within_apply.action)
188
+ variables_to_state = self.current_scope.variable_states.copy()
189
+ self.current_scope.variable_states.update(
190
+ {
191
+ var: state
192
+ for var, state in variables_to_state.items()
193
+ if var in self.current_scope.variable_states
194
+ and var not in compute_captured_variables
195
+ }
196
+ )
197
+
198
+ def visit_QuantumOperation(self, op: QuantumOperation) -> None:
199
+ with self._error_manager.node_context(op):
200
+ if isinstance(op, QuantumFunctionCall):
201
+ validate_call_arguments(
202
+ op,
203
+ {
204
+ **self._functions_dict,
205
+ **self.current_scope.operands,
206
+ },
207
+ )
208
+ elif isinstance(op, InplaceBinaryOperation) and isinstance(
209
+ op.value, HandleBinding
210
+ ):
211
+ check_no_overlapping_quantum_args(
212
+ [op.target, op.value], op.operation.value
213
+ )
214
+ self._handle_inputs(op.readable_inputs)
215
+ self._handle_outputs(op.readable_outputs)
216
+ self._handle_inouts(op.readable_inouts)
217
+ self.generic_visit(op)
218
+
219
+ def visit_VariableDeclarationStatement(
220
+ self, declaration: VariableDeclarationStatement
221
+ ) -> None:
222
+ handle_wiring_state = self.current_scope.variable_states.get(declaration.name)
223
+ if handle_wiring_state is not None:
224
+ self._error_manager.add_error(
225
+ f"Trying to declare a variable of the same name as previously declared variable {declaration.name}"
226
+ )
227
+ return
228
+
229
+ self.current_scope.variable_states[declaration.name] = HandleState.UNINITIALIZED
230
+ self.current_scope.variables_to_types[declaration.name] = (
231
+ declaration.quantum_type
232
+ )
233
+
234
+ def visit_QuantumLambdaFunction(self, lambda_func: QuantumLambdaFunction) -> None:
235
+ renamed_parameters, renamed_operands, renamed_ports = get_renamed_parameters(
236
+ lambda_func
237
+ )
238
+ scope = StaticScope(
239
+ parameters=self.current_scope.parameters + renamed_parameters,
240
+ operands={**self.current_scope.operands, **renamed_operands},
241
+ variables_to_states={
242
+ **self.current_scope.variable_states.copy(),
243
+ **initialize_variables_to_state(renamed_ports),
244
+ },
245
+ variables_to_types=self.current_scope.variables_to_types
246
+ | {port.name: port.quantum_type for port in renamed_ports},
247
+ )
248
+ with self.scoped_visit(scope):
249
+ self.generic_visit(lambda_func)
250
+
251
+ def visit_HandleBinding(self, handle: HandleBinding) -> None:
252
+ resolve_handle(self.current_scope, handle)
253
+
254
+ def visit_Expression(self, expr: Expression) -> None:
255
+ if len(self._scope) == 0:
256
+ return
257
+ vrc = VarRefCollector(ignore_duplicated_handles=True, unevaluated=True)
258
+ vrc.visit(ast.parse(expr.expr))
259
+ handles = [
260
+ HandleMetadata(handle=handle)
261
+ for handle in vrc.var_handles
262
+ if handle.name in self.current_scope.variable_states
263
+ and (
264
+ not isinstance(handle, FieldHandleBinding)
265
+ or handle.field not in CLASSICAL_ATTRIBUTES
266
+ )
267
+ ]
268
+ self._handle_inouts(handles)
269
+
270
+ def visit_QuantumExpressionOperation(self, op: QuantumExpressionOperation) -> None:
271
+ self.visit_Expression(op.expression)
272
+ self.visit_QuantumOperation(op)
273
+
274
+ def _handle_state_changing_ios(
275
+ self,
276
+ ios: Sequence[HandleMetadata],
277
+ state: HandleState,
278
+ state_change_verb: str,
279
+ ) -> None:
280
+ for handle_metadata in ios:
281
+ handle_binding = handle_metadata.handle
282
+ if isinstance(
283
+ handle_binding,
284
+ (SubscriptHandleBinding, SlicedHandleBinding, FieldHandleBinding),
285
+ ):
286
+ self._error_manager.add_error(
287
+ f"Cannot use {HANDLE_BINDING_PART_MESSAGE[type(handle_binding)]} of variable {handle_binding.name!r} in {state_change_verb} context"
288
+ )
289
+ continue
290
+ handle_wiring_state = self.current_scope.variable_states.get(
291
+ handle_binding.name
292
+ )
293
+ if handle_wiring_state is not state:
294
+ state_prefix = (
295
+ ""
296
+ if handle_wiring_state is None
297
+ else f"{handle_wiring_state.name.lower()} "
298
+ )
299
+ location = (
300
+ f" {handle_metadata.readable_location}"
301
+ if handle_metadata.readable_location is not None
302
+ else ""
303
+ )
304
+ self._error_manager.add_error(
305
+ f"Cannot use {state_prefix}quantum variable {handle_binding.name!r}"
306
+ f"{location}"
307
+ )
308
+
309
+ self.current_scope.variable_states[handle_binding.name] = ~state
310
+
311
+ def _handle_inputs(self, inputs: Sequence[HandleMetadata]) -> None:
312
+ self._handle_state_changing_ios(
313
+ inputs, HandleState.INITIALIZED, "uninitialization"
314
+ )
315
+
316
+ def _handle_outputs(self, outputs: Sequence[HandleMetadata]) -> None:
317
+ self._handle_state_changing_ios(
318
+ outputs, HandleState.UNINITIALIZED, "initialization"
319
+ )
320
+
321
+ def _handle_inouts(self, inouts: Sequence[HandleMetadata]) -> None:
322
+ for handle_metadata in inouts:
323
+ handle_binding = handle_metadata.handle
324
+
325
+ if handle_binding.name not in self.current_scope.variable_states:
326
+ ErrorManager().add_error(
327
+ f"Variable {handle_binding.name!r} is not defined"
328
+ )
329
+ return
330
+ handle_wiring_state = self.current_scope.variable_states[
331
+ handle_binding.name
332
+ ]
333
+
334
+ if handle_wiring_state is not HandleState.INITIALIZED:
335
+ state_prefix = (
336
+ ""
337
+ if handle_wiring_state is None
338
+ else f"{handle_wiring_state.name.lower()} "
339
+ )
340
+ location = (
341
+ f" {handle_metadata.readable_location}"
342
+ if handle_metadata.readable_location is not None
343
+ else ""
344
+ )
345
+ self._error_manager.add_error(
346
+ f"Cannot use {state_prefix}quantum variable {handle_binding.name!r}"
347
+ f"{location}"
348
+ )
349
+
350
+
351
+ def static_semantics_analysis_pass(
352
+ model: Model, error_type: Optional[type[Exception]] = ClassiqSemanticError
353
+ ) -> None:
354
+ _check_function_name_collisions(model, error_type)
355
+ QStructAnnotator().visit(model)
356
+ functions = {**BUILTIN_FUNCTION_DECLARATIONS, **model.function_dict}
357
+ resolve_function_calls(model, functions)
358
+ StaticSemanticsVisitor(
359
+ functions,
360
+ [const.name for const in model.constants],
361
+ ).visit(model)
362
+ if error_type is not None:
363
+ ErrorManager().report_errors(error_type)
364
+
365
+
366
+ EXPECTED_TERMINAL_STATES: dict[PortDeclarationDirection, HandleState] = {
367
+ PortDeclarationDirection.Output: HandleState.INITIALIZED,
368
+ PortDeclarationDirection.Inout: HandleState.INITIALIZED,
369
+ }
370
+
371
+
372
+ def initialize_variables_to_state(
373
+ port_declarations: Sequence[PortDeclaration],
374
+ ) -> dict[str, HandleState]:
375
+ variables_to_state: dict[str, HandleState] = dict()
376
+
377
+ for port_decl in port_declarations:
378
+ variables_to_state[port_decl.name] = (
379
+ HandleState.INITIALIZED
380
+ if port_decl.direction.includes_port_direction(PortDirection.Input)
381
+ else HandleState.UNINITIALIZED
382
+ )
383
+
384
+ return variables_to_state
File without changes
@@ -0,0 +1,16 @@
1
+ from collections.abc import Sequence
2
+
3
+ from classiq.interface.generator.constant import Constant
4
+
5
+ from classiq.qmod.builtins import BUILTIN_CONSTANTS
6
+ from classiq.qmod.semantics.error_manager import ErrorManager
7
+
8
+
9
+ def check_duplicate_constants(constants: Sequence[Constant]) -> None:
10
+ known_constants = {constant.name: constant for constant in BUILTIN_CONSTANTS}
11
+ for constant in constants:
12
+ if constant.name in known_constants:
13
+ with ErrorManager().node_context(constant):
14
+ ErrorManager().add_error(f"Constant {constant.name!r} already exists")
15
+ else:
16
+ known_constants[constant.name] = constant
@@ -0,0 +1,99 @@
1
+ from collections.abc import Mapping
2
+
3
+ from classiq.interface.exceptions import ClassiqError
4
+ from classiq.interface.generator.expressions.expression import Expression
5
+ from classiq.interface.model.handle_binding import HandleBinding
6
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
7
+ from classiq.interface.model.quantum_function_declaration import (
8
+ AnonQuantumFunctionDeclaration,
9
+ AnonQuantumOperandDeclaration,
10
+ QuantumFunctionDeclaration,
11
+ )
12
+ from classiq.interface.model.quantum_lambda_function import (
13
+ OperandIdentifier,
14
+ QuantumLambdaFunction,
15
+ QuantumOperand,
16
+ )
17
+
18
+ from classiq.qmod.semantics.error_manager import ErrorManager
19
+
20
+
21
+ def validate_call_arguments(
22
+ fc: QuantumFunctionCall,
23
+ function_dict: Mapping[str, QuantumFunctionDeclaration],
24
+ ) -> None:
25
+ pos_args = fc.positional_args
26
+ pos_params = fc.func_decl.positional_arg_declarations
27
+ if len(pos_args) != len(pos_params):
28
+ ErrorManager().add_error(
29
+ f"Function {fc.func_name} takes {len(pos_params)} arguments but "
30
+ f"{len(pos_args)} were given."
31
+ )
32
+ for arg, param in zip(pos_args, pos_params):
33
+ if not isinstance(arg, (Expression, HandleBinding)) and isinstance(
34
+ param, AnonQuantumOperandDeclaration
35
+ ):
36
+ _check_operand_against_declaration(param, arg, function_dict, fc.func_name)
37
+ check_no_overlapping_quantum_args(fc.ports, fc.func_name)
38
+
39
+
40
+ def _check_operand_against_declaration(
41
+ operand_decl: AnonQuantumOperandDeclaration,
42
+ operand_argument: QuantumOperand,
43
+ function_dict: Mapping[str, QuantumFunctionDeclaration],
44
+ func_name: str,
45
+ in_list: bool = False,
46
+ ) -> None:
47
+ if isinstance(operand_argument, list):
48
+ if in_list:
49
+ ErrorManager().add_error(
50
+ f"{str(operand_argument)!r} argument to {func_name!r} is not "
51
+ f"a valid operand. Nested operand lists are not permitted."
52
+ )
53
+ return
54
+ for arg in operand_argument:
55
+ _check_operand_against_declaration(
56
+ operand_decl, arg, function_dict, func_name, in_list=True
57
+ )
58
+ return
59
+ operand_arg_decl: AnonQuantumFunctionDeclaration
60
+ operand_argument_for_decl = operand_argument
61
+ if isinstance(operand_argument_for_decl, OperandIdentifier):
62
+ operand_argument_for_decl = operand_argument_for_decl.name
63
+ if isinstance(operand_argument_for_decl, str):
64
+ if operand_argument_for_decl not in function_dict:
65
+ ErrorManager().add_error(
66
+ f"{operand_argument!r} argument to {func_name!r} is not a "
67
+ f"registered function."
68
+ )
69
+ return
70
+ operand_arg_decl = function_dict[operand_argument_for_decl]
71
+ elif isinstance(operand_argument_for_decl, QuantumLambdaFunction):
72
+ operand_arg_decl = operand_argument_for_decl.func_decl
73
+ else:
74
+ raise ClassiqError(
75
+ f"{str(operand_argument)!r} argument to {func_name!r} is not a "
76
+ f"valid operand."
77
+ )
78
+ num_arg_parameters = len(operand_arg_decl.positional_arg_declarations)
79
+ num_decl_parameters = len(operand_decl.positional_arg_declarations)
80
+ if num_arg_parameters != num_decl_parameters:
81
+ ErrorManager().add_error(
82
+ f"Signature of argument {operand_argument!r} to {func_name!r} "
83
+ f"does not match the signature of parameter {operand_decl.name!r}. "
84
+ f"{operand_decl.name!r} accepts {num_decl_parameters} parameters but "
85
+ f"{operand_argument!r} accepts {num_arg_parameters} parameters."
86
+ )
87
+
88
+
89
+ def check_no_overlapping_quantum_args(
90
+ args: list[HandleBinding], func_name: str
91
+ ) -> None:
92
+ for idx, arg in enumerate(args):
93
+ for other_arg in args[idx + 1 :]:
94
+ if arg.overlaps(other_arg):
95
+ ErrorManager().add_error(
96
+ f"Cannot use the same part of variable {arg.name!r} in multiple "
97
+ f"arguments to function {func_name!r}."
98
+ )
99
+ break
@@ -0,0 +1,23 @@
1
+ from typing import Optional
2
+
3
+ from classiq.interface.model.model import Model
4
+
5
+ from classiq.qmod.builtins.functions import CORE_LIB_DECLS
6
+
7
+
8
+ def _check_function_name_collisions(
9
+ model: Model, error_type: Optional[type[Exception]]
10
+ ) -> None:
11
+ if error_type is None:
12
+ return
13
+ redefined_functions = [
14
+ function.name
15
+ for function in CORE_LIB_DECLS
16
+ if function.name in model.function_dict
17
+ ]
18
+ if len(redefined_functions) == 1:
19
+ raise error_type(
20
+ f"Cannot redefine built-in function {redefined_functions[0]!r}"
21
+ )
22
+ elif len(redefined_functions) > 1:
23
+ raise error_type(f"Cannot redefine built-in functions: {redefined_functions}")
@@ -0,0 +1,85 @@
1
+ from typing import TYPE_CHECKING, Optional, Union
2
+
3
+ from classiq.interface.generator.functions.type_name import TypeName
4
+ from classiq.interface.model.handle_binding import (
5
+ ConcreteHandleBinding,
6
+ FieldHandleBinding,
7
+ HandleBinding,
8
+ NestedHandleBinding,
9
+ SlicedHandleBinding,
10
+ SubscriptHandleBinding,
11
+ )
12
+ from classiq.interface.model.quantum_type import QuantumBitvector, QuantumType
13
+
14
+ import classiq.qmod.semantics.error_manager as error_manager
15
+ from classiq.qmod.model_state_container import QMODULE
16
+
17
+ if TYPE_CHECKING:
18
+ from classiq.qmod.semantics.static_semantics_visitor import StaticScope
19
+
20
+
21
+ def resolve_handle(scope: "StaticScope", handle: HandleBinding) -> None:
22
+ if handle.name not in scope.variables_to_types:
23
+ error_manager.append_error(handle, f"Variable {handle.name!r} is undefined.")
24
+ return
25
+ _resolve_handle_recursively(scope.variables_to_types[handle.name], handle)
26
+
27
+
28
+ def _resolve_handle_recursively(
29
+ qtype: QuantumType, handle: ConcreteHandleBinding
30
+ ) -> Optional[QuantumType]:
31
+ if isinstance(handle, NestedHandleBinding):
32
+ return _resolve_nested_handle(qtype, handle)
33
+ return qtype
34
+
35
+
36
+ def _resolve_nested_handle(
37
+ qtype: QuantumType, handle: NestedHandleBinding
38
+ ) -> Optional[QuantumType]:
39
+ nested_qtype = _resolve_handle_recursively(qtype, handle.base_handle)
40
+ if nested_qtype is None:
41
+ return None
42
+ if isinstance(handle, (SubscriptHandleBinding, SlicedHandleBinding)):
43
+ return _resolve_subscript_sliced_handle(nested_qtype, handle)
44
+ if TYPE_CHECKING:
45
+ assert isinstance(handle, FieldHandleBinding)
46
+ return _resolve_field_handle(nested_qtype, handle)
47
+
48
+
49
+ def _resolve_subscript_sliced_handle(
50
+ qtype: QuantumType, handle: Union[SubscriptHandleBinding, SlicedHandleBinding]
51
+ ) -> Optional[QuantumType]:
52
+ if not isinstance(qtype, QuantumBitvector):
53
+ error_manager.append_error(handle, f"{qtype.type_name} is not subscriptable.")
54
+ return None
55
+ return qtype.element_type if isinstance(handle, SubscriptHandleBinding) else qtype
56
+
57
+
58
+ def _validate_field_access(qtype: QuantumType, handle: FieldHandleBinding) -> bool:
59
+ if not isinstance(qtype, TypeName):
60
+ error_manager.append_error(handle, f"{qtype.type_name} has no fields.")
61
+ return False
62
+ if qtype.name not in QMODULE.qstruct_decls:
63
+ error_manager.append_error(
64
+ handle, f"{qtype.type_name} is not a quantum struct."
65
+ )
66
+ return False
67
+ if handle.field not in qtype.fields:
68
+ error_manager.append_error(
69
+ handle,
70
+ f"Struct {qtype.type_name} has no field {handle.field!r}. "
71
+ f"Available fields: {', '.join(qtype.fields.keys())}",
72
+ )
73
+ return False
74
+
75
+ return True
76
+
77
+
78
+ def _resolve_field_handle(
79
+ qtype: QuantumType, handle: FieldHandleBinding
80
+ ) -> Optional[QuantumType]:
81
+ if _validate_field_access(qtype, handle):
82
+ if TYPE_CHECKING:
83
+ assert isinstance(qtype, TypeName)
84
+ return qtype.fields[handle.field]
85
+ return None
@@ -0,0 +1,33 @@
1
+ from classiq.interface.generator.functions.classical_type import (
2
+ ClassicalArray,
3
+ ClassicalList,
4
+ )
5
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
6
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
7
+ from classiq.interface.model.quantum_function_declaration import PositionalArg
8
+
9
+ from classiq import ClassicalParameterDeclaration
10
+ from classiq.qmod.semantics.error_manager import append_error
11
+
12
+
13
+ def validate_main_function(func: NativeFunctionDefinition) -> None:
14
+ for param in func.positional_arg_declarations:
15
+ _validate_main_param(param)
16
+
17
+
18
+ def _validate_main_param(param: PositionalArg) -> None:
19
+ if isinstance(param, ClassicalParameterDeclaration):
20
+ _validate_main_classical_param_type(param.classical_type, param.name)
21
+
22
+
23
+ def _validate_main_classical_param_type(
24
+ param: ConcreteClassicalType, param_name: str
25
+ ) -> None:
26
+ if isinstance(param, ClassicalList):
27
+ append_error(
28
+ param,
29
+ f"Classical array parameter {param_name!r} of function 'main' must must "
30
+ f"specify array length",
31
+ )
32
+ if isinstance(param, ClassicalArray):
33
+ _validate_main_classical_param_type(param.element_type, param_name)