classiq 0.37.1__py3-none-any.whl → 0.39.0__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 (280) hide show
  1. classiq/__init__.py +23 -24
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +1 -1
  3. classiq/_analyzer_extras/interactive_hardware.py +3 -3
  4. classiq/_internals/api_wrapper.py +37 -17
  5. classiq/_internals/async_utils.py +1 -74
  6. classiq/_internals/authentication/device.py +9 -4
  7. classiq/_internals/authentication/password_manager.py +25 -10
  8. classiq/_internals/authentication/token_manager.py +2 -2
  9. classiq/_internals/client.py +24 -6
  10. classiq/_internals/jobs.py +10 -7
  11. classiq/analyzer/analyzer.py +29 -29
  12. classiq/analyzer/analyzer_utilities.py +5 -5
  13. classiq/analyzer/rb.py +4 -5
  14. classiq/analyzer/show_interactive_hack.py +6 -6
  15. classiq/applications/__init__.py +1 -8
  16. classiq/applications/chemistry/__init__.py +6 -0
  17. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +9 -16
  18. classiq/applications/combinatorial_helpers/allowed_constraints.py +20 -0
  19. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
  20. classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
  21. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +150 -0
  22. classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
  23. classiq/applications/combinatorial_helpers/encoding_utils.py +122 -0
  24. classiq/applications/combinatorial_helpers/memory.py +77 -0
  25. classiq/applications/combinatorial_helpers/optimization_model.py +162 -0
  26. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
  27. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +75 -0
  28. classiq/applications/combinatorial_helpers/py.typed +0 -0
  29. classiq/applications/combinatorial_helpers/pyomo_utils.py +245 -0
  30. classiq/applications/combinatorial_helpers/solvers/__init__.py +0 -0
  31. classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
  32. classiq/applications/combinatorial_helpers/transformations/__init__.py +0 -0
  33. classiq/applications/combinatorial_helpers/transformations/encoding.py +187 -0
  34. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +142 -0
  35. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +122 -0
  36. classiq/applications/combinatorial_helpers/transformations/penalty.py +32 -0
  37. classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
  38. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +75 -0
  39. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +88 -0
  40. classiq/applications/combinatorial_optimization/__init__.py +13 -2
  41. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +134 -0
  42. classiq/applications/finance/__init__.py +3 -2
  43. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +27 -30
  44. classiq/applications/grover/__init__.py +11 -0
  45. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +20 -91
  46. classiq/applications/libraries/__init__.py +0 -0
  47. classiq/applications/libraries/qmci_library.py +35 -0
  48. classiq/applications/qnn/circuit_utils.py +2 -2
  49. classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
  50. classiq/applications/qnn/types.py +2 -2
  51. classiq/applications/qsvm/__init__.py +5 -1
  52. classiq/applications/qsvm/qsvm.py +4 -7
  53. classiq/applications/qsvm/qsvm_data_generation.py +2 -5
  54. classiq/exceptions.py +43 -1
  55. classiq/execution/all_hardware_devices.py +13 -0
  56. classiq/executor.py +12 -10
  57. classiq/interface/_version.py +1 -1
  58. classiq/interface/analyzer/analysis_params.py +6 -3
  59. classiq/interface/analyzer/result.py +12 -8
  60. classiq/interface/applications/qsvm.py +17 -3
  61. classiq/interface/ast_node.py +23 -0
  62. classiq/interface/backend/backend_preferences.py +4 -2
  63. classiq/interface/backend/pydantic_backend.py +3 -1
  64. classiq/interface/backend/quantum_backend_providers.py +1 -0
  65. classiq/interface/chemistry/fermionic_operator.py +15 -13
  66. classiq/interface/chemistry/ground_state_problem.py +18 -3
  67. classiq/interface/chemistry/molecule.py +8 -6
  68. classiq/interface/chemistry/operator.py +20 -14
  69. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -1
  70. classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
  71. classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
  72. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -2
  73. classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
  74. classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
  75. classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
  76. classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
  77. classiq/interface/combinatorial_optimization/examples/set_cover.py +2 -1
  78. classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
  79. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
  80. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +9 -3
  81. classiq/interface/executor/aws_execution_cost.py +4 -3
  82. classiq/interface/executor/estimation.py +2 -2
  83. classiq/interface/executor/execution_preferences.py +5 -34
  84. classiq/interface/executor/execution_request.py +15 -48
  85. classiq/interface/executor/optimizer_preferences.py +22 -13
  86. classiq/interface/executor/{quantum_program.py → quantum_code.py} +21 -15
  87. classiq/interface/executor/quantum_instruction_set.py +2 -1
  88. classiq/interface/executor/register_initialization.py +1 -3
  89. classiq/interface/executor/result.py +41 -10
  90. classiq/interface/executor/vqe_result.py +2 -2
  91. classiq/interface/finance/function_input.py +17 -4
  92. classiq/interface/finance/gaussian_model_input.py +3 -1
  93. classiq/interface/finance/log_normal_model_input.py +3 -1
  94. classiq/interface/finance/model_input.py +2 -0
  95. classiq/interface/generator/amplitude_loading.py +6 -3
  96. classiq/interface/generator/application_apis/__init__.py +1 -0
  97. classiq/interface/generator/application_apis/arithmetic_declarations.py +14 -0
  98. classiq/interface/generator/arith/argument_utils.py +14 -4
  99. classiq/interface/generator/arith/arithmetic.py +3 -1
  100. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +12 -13
  101. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -1
  102. classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -2
  103. classiq/interface/generator/arith/arithmetic_expression_validator.py +16 -2
  104. classiq/interface/generator/arith/arithmetic_operations.py +5 -10
  105. classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
  106. classiq/interface/generator/arith/binary_ops.py +202 -54
  107. classiq/interface/generator/arith/extremum_operations.py +5 -3
  108. classiq/interface/generator/arith/logical_ops.py +4 -2
  109. classiq/interface/generator/arith/machine_precision.py +3 -0
  110. classiq/interface/generator/arith/number_utils.py +34 -44
  111. classiq/interface/generator/arith/register_user_input.py +21 -1
  112. classiq/interface/generator/arith/unary_ops.py +16 -25
  113. classiq/interface/generator/builtin_api_builder.py +0 -5
  114. classiq/interface/generator/chemistry_function_params.py +4 -4
  115. classiq/interface/generator/commuting_pauli_exponentiation.py +3 -1
  116. classiq/interface/generator/compiler_keywords.py +4 -0
  117. classiq/interface/generator/complex_type.py +3 -10
  118. classiq/interface/generator/constant.py +2 -3
  119. classiq/interface/generator/control_state.py +5 -3
  120. classiq/interface/generator/credit_risk_example/linear_gci.py +10 -3
  121. classiq/interface/generator/credit_risk_example/weighted_adder.py +14 -4
  122. classiq/interface/generator/expressions/atomic_expression_functions.py +5 -3
  123. classiq/interface/generator/expressions/evaluated_expression.py +18 -4
  124. classiq/interface/generator/expressions/expression.py +3 -5
  125. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +33 -0
  126. classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
  127. classiq/interface/generator/finance.py +1 -1
  128. classiq/interface/generator/function_params.py +7 -6
  129. classiq/interface/generator/functions/__init__.py +2 -2
  130. classiq/interface/generator/functions/builtins/__init__.py +15 -0
  131. classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
  132. classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
  133. classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
  134. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +612 -219
  135. classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
  136. classiq/interface/generator/functions/classical_type.py +2 -4
  137. classiq/interface/generator/functions/foreign_function_definition.py +12 -4
  138. classiq/interface/generator/functions/function_declaration.py +2 -2
  139. classiq/interface/generator/functions/function_implementation.py +8 -4
  140. classiq/interface/generator/functions/native_function_definition.py +4 -2
  141. classiq/interface/generator/functions/register.py +4 -2
  142. classiq/interface/generator/functions/register_mapping_data.py +14 -10
  143. classiq/interface/generator/generated_circuit_data.py +2 -2
  144. classiq/interface/generator/grover_operator.py +5 -3
  145. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +5 -1
  146. classiq/interface/generator/hardware/hardware_data.py +6 -4
  147. classiq/interface/generator/hardware_efficient_ansatz.py +25 -8
  148. classiq/interface/generator/hartree_fock.py +13 -3
  149. classiq/interface/generator/linear_pauli_rotations.py +3 -1
  150. classiq/interface/generator/mcu.py +5 -3
  151. classiq/interface/generator/mcx.py +7 -5
  152. classiq/interface/generator/model/classical_main_validator.py +1 -1
  153. classiq/interface/generator/model/constraints.py +2 -1
  154. classiq/interface/generator/model/model.py +12 -20
  155. classiq/interface/generator/model/preferences/preferences.py +4 -3
  156. classiq/interface/generator/oracles/custom_oracle.py +4 -2
  157. classiq/interface/generator/oracles/oracle_abc.py +2 -2
  158. classiq/interface/generator/qpe.py +6 -4
  159. classiq/interface/generator/qsvm.py +5 -8
  160. classiq/interface/generator/quantum_function_call.py +21 -16
  161. classiq/interface/generator/{generated_circuit.py → quantum_program.py} +10 -14
  162. classiq/interface/generator/range_types.py +3 -1
  163. classiq/interface/generator/slice_parsing_utils.py +8 -3
  164. classiq/interface/generator/standard_gates/controlled_standard_gates.py +4 -2
  165. classiq/interface/generator/state_preparation/metrics.py +2 -1
  166. classiq/interface/generator/state_preparation/state_preparation.py +7 -5
  167. classiq/interface/generator/state_propagator.py +16 -5
  168. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  169. classiq/interface/generator/types/struct_declaration.py +10 -7
  170. classiq/interface/generator/ucc.py +6 -4
  171. classiq/interface/generator/unitary_gate.py +7 -3
  172. classiq/interface/generator/validations/flow_graph.py +6 -4
  173. classiq/interface/generator/validations/validator_functions.py +6 -4
  174. classiq/interface/hardware.py +2 -2
  175. classiq/interface/helpers/custom_encoders.py +3 -0
  176. classiq/interface/helpers/pydantic_model_helpers.py +0 -6
  177. classiq/interface/helpers/validation_helpers.py +1 -1
  178. classiq/interface/helpers/versioned_model.py +4 -1
  179. classiq/interface/ide/show.py +2 -2
  180. classiq/interface/jobs.py +72 -3
  181. classiq/interface/model/bind_operation.py +18 -11
  182. classiq/interface/model/call_synthesis_data.py +68 -0
  183. classiq/interface/model/classical_if.py +13 -0
  184. classiq/interface/model/classical_parameter_declaration.py +2 -3
  185. classiq/interface/model/control.py +16 -0
  186. classiq/interface/model/handle_binding.py +3 -2
  187. classiq/interface/model/inplace_binary_operation.py +2 -2
  188. classiq/interface/model/invert.py +10 -0
  189. classiq/interface/model/model.py +29 -22
  190. classiq/interface/model/native_function_definition.py +3 -5
  191. classiq/interface/model/power.py +12 -0
  192. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +9 -4
  193. classiq/interface/model/quantum_expressions/control_state.py +2 -2
  194. classiq/interface/model/quantum_function_call.py +33 -142
  195. classiq/interface/model/quantum_function_declaration.py +8 -0
  196. classiq/interface/model/quantum_if_operation.py +4 -5
  197. classiq/interface/model/quantum_lambda_function.py +58 -0
  198. classiq/{quantum_register.py → interface/model/quantum_register.py} +17 -9
  199. classiq/interface/model/quantum_statement.py +3 -2
  200. classiq/interface/model/quantum_type.py +58 -59
  201. classiq/interface/model/quantum_variable_declaration.py +3 -3
  202. classiq/interface/model/repeat.py +13 -0
  203. classiq/interface/model/resolvers/function_call_resolver.py +26 -0
  204. classiq/interface/model/statement_block.py +49 -0
  205. classiq/interface/model/validations/handles_validator.py +16 -18
  206. classiq/interface/model/within_apply_operation.py +11 -0
  207. classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
  208. classiq/interface/server/routes.py +5 -4
  209. classiq/qmod/__init__.py +13 -6
  210. classiq/qmod/builtins/classical_execution_primitives.py +27 -36
  211. classiq/qmod/builtins/classical_functions.py +22 -12
  212. classiq/qmod/builtins/functions.py +272 -328
  213. classiq/qmod/builtins/operations.py +171 -35
  214. classiq/qmod/builtins/structs.py +15 -15
  215. classiq/qmod/cfunc.py +42 -0
  216. classiq/qmod/classical_function.py +6 -14
  217. classiq/qmod/declaration_inferrer.py +12 -21
  218. classiq/qmod/expression_query.py +23 -0
  219. classiq/qmod/model_state_container.py +2 -0
  220. classiq/qmod/native/__init__.py +0 -0
  221. classiq/qmod/native/expression_to_qmod.py +189 -0
  222. classiq/qmod/native/pretty_printer.py +340 -0
  223. classiq/qmod/qfunc.py +27 -0
  224. classiq/qmod/qmod_constant.py +100 -0
  225. classiq/qmod/qmod_parameter.py +36 -13
  226. classiq/qmod/qmod_struct.py +3 -3
  227. classiq/qmod/qmod_variable.py +148 -31
  228. classiq/qmod/quantum_callable.py +1 -0
  229. classiq/qmod/quantum_expandable.py +18 -19
  230. classiq/qmod/quantum_function.py +41 -8
  231. classiq/qmod/symbolic.py +48 -5
  232. classiq/qmod/symbolic_expr.py +9 -0
  233. classiq/qmod/utilities.py +13 -0
  234. classiq/qmod/write_qmod.py +39 -0
  235. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/METADATA +2 -1
  236. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/RECORD +244 -225
  237. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/WHEEL +1 -1
  238. classiq/applications/benchmarking/__init__.py +0 -9
  239. classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
  240. classiq/applications/numpy_utils.py +0 -37
  241. classiq/applications_model_constructors/__init__.py +0 -17
  242. classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
  243. classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
  244. classiq/builtin_functions/__init__.py +0 -43
  245. classiq/builtin_functions/amplitude_loading.py +0 -3
  246. classiq/builtin_functions/binary_ops.py +0 -1
  247. classiq/builtin_functions/exponentiation.py +0 -5
  248. classiq/builtin_functions/qpe.py +0 -4
  249. classiq/builtin_functions/qsvm.py +0 -7
  250. classiq/builtin_functions/range_types.py +0 -5
  251. classiq/builtin_functions/standard_gates.py +0 -1
  252. classiq/builtin_functions/state_preparation.py +0 -6
  253. classiq/builtin_functions/suzuki_trotter.py +0 -3
  254. classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
  255. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  256. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
  257. classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
  258. classiq/interface/generator/types/combinatorial_problem.py +0 -26
  259. classiq/interface/model/numeric_reinterpretation.py +0 -25
  260. classiq/interface/model/operator_synthesis_data.py +0 -48
  261. classiq/model/__init__.py +0 -14
  262. classiq/model/composite_function_generator.py +0 -33
  263. classiq/model/function_handler.py +0 -466
  264. classiq/model/function_handler.pyi +0 -152
  265. classiq/model/logic_flow.py +0 -149
  266. classiq/model/logic_flow_change_handler.py +0 -71
  267. classiq/model/model.py +0 -246
  268. classiq/quantum_functions/__init__.py +0 -17
  269. classiq/quantum_functions/annotation_parser.py +0 -207
  270. classiq/quantum_functions/decorators.py +0 -22
  271. classiq/quantum_functions/function_library.py +0 -181
  272. classiq/quantum_functions/function_parser.py +0 -74
  273. classiq/quantum_functions/quantum_function.py +0 -236
  274. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
  275. /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
  276. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/pauli_helpers/__init__.py} +0 -0
  277. /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
  278. /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
  279. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +0 -0
  280. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +0 -0
@@ -1,22 +1,26 @@
1
1
  from typing import Any, Dict, Literal, Optional, Union
2
2
 
3
3
  import pydantic
4
- from pydantic import Extra
4
+ from pydantic import Extra, Field
5
+ from typing_extensions import Annotated
5
6
 
7
+ from classiq.interface.ast_node import HashableASTNode
6
8
  from classiq.interface.generator.arith.register_user_input import (
7
9
  RegisterArithmeticInfo,
8
10
  RegisterUserInput,
9
11
  )
10
12
  from classiq.interface.generator.expressions.expression import Expression
11
- from classiq.interface.helpers.hashable_pydantic_base_model import (
12
- HashablePydanticBaseModel,
13
+ from classiq.interface.generator.expressions.qmod_qscalar_proxy import (
14
+ QmodQNumProxy,
15
+ QmodQScalarProxy,
13
16
  )
17
+ from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
14
18
  from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
15
19
 
16
20
  from classiq.exceptions import ClassiqValueError
17
21
 
18
22
 
19
- class QuantumType(HashablePydanticBaseModel):
23
+ class QuantumType(HashableASTNode):
20
24
  class Config:
21
25
  extra = Extra.forbid
22
26
 
@@ -40,8 +44,16 @@ class QuantumType(HashablePydanticBaseModel):
40
44
  def set_size_in_bits(self, val: int) -> None:
41
45
  self._size_in_bits = val
42
46
 
47
+ def get_proxy(self, name: str) -> QmodSizedProxy:
48
+ return QmodSizedProxy(size=self.size_in_bits)
43
49
 
44
- class QuantumBit(QuantumType):
50
+
51
+ class QuantumScalar(QuantumType):
52
+ def get_proxy(self, name: str) -> QmodQScalarProxy:
53
+ return QmodQScalarProxy(name, size=self.size_in_bits)
54
+
55
+
56
+ class QuantumBit(QuantumScalar):
45
57
  kind: Literal["qbit"]
46
58
 
47
59
  def __init__(self, **kwargs: Any) -> None:
@@ -69,83 +81,69 @@ class QuantumBitvector(QuantumArray):
69
81
  self._size_in_bits = self.length.to_int_value()
70
82
 
71
83
 
72
- class QuantumNumeric(QuantumType):
84
+ class QuantumNumeric(QuantumScalar):
85
+ kind: Literal["qnum"]
86
+
73
87
  size: Optional[Expression] = pydantic.Field()
74
- kind: str = pydantic.Field()
88
+ is_signed: Optional[Expression] = pydantic.Field()
89
+ fraction_digits: Optional[Expression] = pydantic.Field()
75
90
 
76
91
  @pydantic.root_validator(pre=True)
77
92
  def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
78
93
  return values_with_discriminator(values, "kind", "qnum")
79
94
 
80
- _is_signed: bool = pydantic.PrivateAttr(default=False)
81
-
82
- _fraction_digits: int = pydantic.PrivateAttr(default=0)
95
+ @pydantic.root_validator
96
+ def _validate_fields(cls, values: Dict[str, Any]) -> Dict[str, Any]:
97
+ has_sign = values["is_signed"] is not None
98
+ has_fraction_digits = values["fraction_digits"] is not None
99
+ if has_sign and not has_fraction_digits or not has_sign and has_fraction_digits:
100
+ raise ClassiqValueError(
101
+ "Assign neither or both of is_signed and fraction_digits"
102
+ )
103
+ return values
83
104
 
84
105
  @property
85
- def size_in_bits_expr(self) -> Optional[Expression]:
86
- return self.size
106
+ def has_sign(self) -> bool:
107
+ return self.is_signed is not None
87
108
 
88
109
  @property
89
- def is_signed(self) -> bool:
90
- return self._is_signed
91
-
92
- def set_signed(self, val: bool) -> None:
93
- self._is_signed = val
110
+ def sign_value(self) -> bool:
111
+ return False if self.is_signed is None else self.is_signed.to_bool_value()
94
112
 
95
113
  @property
96
- def fraction_digits(self) -> int:
97
- return self._fraction_digits
114
+ def has_fraction_digits(self) -> bool:
115
+ return self.fraction_digits is not None
98
116
 
99
- def set_fraction_digits(self, val: int) -> None:
100
- self._fraction_digits = val
117
+ @property
118
+ def fraction_digits_value(self) -> int:
119
+ return (
120
+ 0 if self.fraction_digits is None else self.fraction_digits.to_int_value()
121
+ )
101
122
 
102
123
  def _update_size_in_bits_from_declaration(self) -> None:
103
124
  if self.size is not None and self.size.is_evaluated():
104
125
  self._size_in_bits = self.size.to_int_value()
105
126
 
106
-
107
- class QuantumInteger(QuantumNumeric):
108
- kind: Literal["qint"]
109
-
110
- @pydantic.root_validator(pre=True)
111
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
112
- return values_with_discriminator(values, "kind", "qint")
113
-
114
-
115
- class QuantumFixedReal(QuantumNumeric):
116
- fraction_places: Expression = pydantic.Field()
117
-
118
- kind: Literal["qfixed"]
119
-
120
- @pydantic.root_validator(pre=True)
121
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
122
- return values_with_discriminator(values, "kind", "qfixed")
123
-
124
- @property
125
- def fraction_digits(self) -> int:
126
- return self.fraction_places.to_int_value()
127
-
128
- def set_fraction_digits(self, val: int) -> None:
129
- if val != self.fraction_places.to_int_value():
130
- raise ClassiqValueError(
131
- "Cannot assign value of fixed-point number with incompatible fraction digits"
132
- )
127
+ def get_proxy(self, name: str) -> QmodQNumProxy:
128
+ return QmodQNumProxy(
129
+ name,
130
+ size=self.size_in_bits,
131
+ fraction_digits=self.fraction_digits_value,
132
+ is_signed=self.sign_value,
133
+ )
133
134
 
134
135
 
135
- ConcreteQuantumType = Union[
136
- QuantumBit,
137
- QuantumBitvector,
138
- QuantumNumeric,
139
- QuantumInteger,
140
- QuantumFixedReal,
136
+ ConcreteQuantumType = Annotated[
137
+ Union[QuantumBit, QuantumBitvector, QuantumNumeric],
138
+ Field(discriminator="kind", default_factory=QuantumBitvector),
141
139
  ]
142
140
 
143
141
 
144
142
  def register_info_to_quantum_type(reg_info: RegisterArithmeticInfo) -> QuantumNumeric:
145
143
  result = QuantumNumeric()
146
144
  result.set_size_in_bits(reg_info.size)
147
- result.set_signed(reg_info.is_signed)
148
- result.set_fraction_digits(reg_info.fraction_places)
145
+ result.is_signed = Expression(expr=str(reg_info.is_signed))
146
+ result.fraction_digits = Expression(expr=str(reg_info.fraction_places))
149
147
  return result
150
148
 
151
149
 
@@ -153,10 +151,11 @@ UNRESOLVED_SIZE = 1000
153
151
 
154
152
 
155
153
  def quantum_var_to_register(name: str, qtype: QuantumType) -> RegisterUserInput:
156
- signed = qtype.is_signed if isinstance(qtype, QuantumNumeric) else False
157
- if isinstance(qtype, (QuantumFixedReal, QuantumNumeric)):
158
- fraction_places = qtype.fraction_digits
154
+ if isinstance(qtype, QuantumNumeric):
155
+ signed = qtype.sign_value
156
+ fraction_places = qtype.fraction_digits_value
159
157
  else:
158
+ signed = False
160
159
  fraction_places = 0
161
160
  return RegisterUserInput(
162
161
  name=name,
@@ -1,8 +1,8 @@
1
1
  from typing import Any, Mapping, Optional
2
2
 
3
3
  import pydantic
4
- from pydantic import BaseModel
5
4
 
5
+ from classiq.interface.ast_node import ASTNode
6
6
  from classiq.interface.generator.expressions.expression import Expression
7
7
  from classiq.interface.model.quantum_type import (
8
8
  ConcreteQuantumType,
@@ -11,9 +11,9 @@ from classiq.interface.model.quantum_type import (
11
11
  )
12
12
 
13
13
 
14
- class QuantumVariableDeclaration(BaseModel):
14
+ class QuantumVariableDeclaration(ASTNode):
15
15
  name: str
16
- quantum_type: ConcreteQuantumType = pydantic.Field(default_factory=QuantumBitvector)
16
+ quantum_type: ConcreteQuantumType
17
17
  size: Optional[Expression] = pydantic.Field(default=None)
18
18
 
19
19
  @pydantic.validator("size")
@@ -0,0 +1,13 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from classiq.interface.generator.expressions.expression import Expression
4
+ from classiq.interface.model.quantum_statement import QuantumOperation
5
+
6
+ if TYPE_CHECKING:
7
+ from classiq.interface.model.statement_block import StatementBlock
8
+
9
+
10
+ class Repeat(QuantumOperation):
11
+ iter_var: str
12
+ count: Expression
13
+ body: "StatementBlock"
@@ -1,11 +1,17 @@
1
+ import itertools
1
2
  from typing import Any, Mapping
2
3
 
3
4
  from classiq.interface.generator.visitor import Visitor
5
+ from classiq.interface.model.control import Control
6
+ from classiq.interface.model.invert import Invert
4
7
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
5
8
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
6
9
  from classiq.interface.model.quantum_function_declaration import (
7
10
  QuantumFunctionDeclaration,
8
11
  )
12
+ from classiq.interface.model.quantum_if_operation import QuantumIf
13
+ from classiq.interface.model.repeat import Repeat
14
+ from classiq.interface.model.within_apply_operation import WithinApply
9
15
 
10
16
 
11
17
  class FunctionCallResolver(Visitor):
@@ -15,6 +21,26 @@ class FunctionCallResolver(Visitor):
15
21
  ) -> None:
16
22
  self._quantum_function_dict = quantum_function_dict
17
23
 
24
+ def visit_Invert(self, invert: Invert) -> None:
25
+ for fc in invert.body:
26
+ self.visit(fc)
27
+
28
+ def visit_Repeat(self, repeat: Repeat) -> None:
29
+ for fc in repeat.body:
30
+ self.visit(fc)
31
+
32
+ def visit_Control(self, control: Control) -> None:
33
+ for fc in control.body:
34
+ self.visit(fc)
35
+
36
+ def visit_QuantumIf(self, quantum_if: QuantumIf) -> None:
37
+ for fc in quantum_if.then:
38
+ self.visit(fc)
39
+
40
+ def visit_WithinApply(self, within_apply: WithinApply) -> None:
41
+ for fc in itertools.chain(within_apply.compute, within_apply.action):
42
+ self.visit(fc)
43
+
18
44
  def visit_QuantumFunctionCall(self, fc: QuantumFunctionCall) -> None:
19
45
  fc.resolve_function_decl(self._quantum_function_dict, check_operands=True)
20
46
  self.visit_BaseModel(fc)
@@ -0,0 +1,49 @@
1
+ from typing import List, Union
2
+
3
+ from classiq.interface.model.bind_operation import BindOperation
4
+ from classiq.interface.model.classical_if import ClassicalIf
5
+ from classiq.interface.model.control import Control
6
+ from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
7
+ from classiq.interface.model.invert import Invert
8
+ from classiq.interface.model.power import Power
9
+ from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
10
+ AmplitudeLoadingOperation,
11
+ )
12
+ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
13
+ ArithmeticOperation,
14
+ )
15
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
16
+ from classiq.interface.model.quantum_if_operation import QuantumIf
17
+ from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
18
+ from classiq.interface.model.repeat import Repeat
19
+ from classiq.interface.model.variable_declaration_statement import (
20
+ VariableDeclarationStatement,
21
+ )
22
+ from classiq.interface.model.within_apply_operation import WithinApply
23
+
24
+ ConcreteQuantumStatement = Union[
25
+ QuantumFunctionCall,
26
+ ArithmeticOperation,
27
+ AmplitudeLoadingOperation,
28
+ VariableDeclarationStatement,
29
+ BindOperation,
30
+ InplaceBinaryOperation,
31
+ Control,
32
+ Repeat,
33
+ Power,
34
+ Invert,
35
+ ClassicalIf,
36
+ QuantumIf,
37
+ WithinApply,
38
+ ]
39
+
40
+ StatementBlock = List[ConcreteQuantumStatement]
41
+
42
+ Control.update_forward_refs(StatementBlock=StatementBlock)
43
+ QuantumIf.update_forward_refs(StatementBlock=StatementBlock)
44
+ QuantumLambdaFunction.update_forward_refs(StatementBlock=StatementBlock)
45
+ Repeat.update_forward_refs(StatementBlock=StatementBlock)
46
+ Power.update_forward_refs(StatementBlock=StatementBlock)
47
+ Invert.update_forward_refs(StatementBlock=StatementBlock)
48
+ WithinApply.update_forward_refs(StatementBlock=StatementBlock)
49
+ ClassicalIf.update_forward_refs(StatementBlock=StatementBlock)
@@ -1,9 +1,8 @@
1
1
  from typing import Dict, Mapping, Set, Union
2
2
 
3
3
  from classiq.interface.generator.function_params import PortDirection
4
- from classiq.interface.generator.functions.core_lib_declarations.quantum_operators import (
5
- APPLY,
6
- OPERAND_FIELD_NAME,
4
+ from classiq.interface.generator.functions.builtins.quantum_operators import (
5
+ APPLY_OPERATOR,
7
6
  )
8
7
  from classiq.interface.model.handle_binding import (
9
8
  HandleBinding,
@@ -11,11 +10,9 @@ from classiq.interface.model.handle_binding import (
11
10
  SubscriptHandleBinding,
12
11
  )
13
12
  from classiq.interface.model.port_declaration import PortDeclaration
14
- from classiq.interface.model.quantum_function_call import (
15
- QuantumFunctionCall,
16
- QuantumLambdaFunction,
17
- )
13
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
18
14
  from classiq.interface.model.quantum_statement import QuantumOperation
15
+ from classiq.interface.model.statement_block import StatementBlock
19
16
  from classiq.interface.model.validation_handle import HandleState, ValidationHandle
20
17
  from classiq.interface.model.validations.handle_validation_base import (
21
18
  HandleValidationBase,
@@ -23,6 +20,7 @@ from classiq.interface.model.validations.handle_validation_base import (
23
20
  from classiq.interface.model.variable_declaration_statement import (
24
21
  VariableDeclarationStatement,
25
22
  )
23
+ from classiq.interface.model.within_apply_operation import WithinApply
26
24
 
27
25
  from classiq.exceptions import ClassiqValueError
28
26
 
@@ -57,12 +55,15 @@ class HandleValidator(HandleValidationBase):
57
55
  def _validation_handles_state(self) -> Mapping[str, ValidationHandle]:
58
56
  return self._handles_to_state
59
57
 
60
- def handle_call(self, call: QuantumOperation) -> None:
61
- if isinstance(call, QuantumFunctionCall) and call.function == APPLY.name:
62
- self._handle_apply(call)
63
- self._handle_inputs(call.wiring_inputs)
64
- self._handle_outputs(call.wiring_outputs)
65
- self._handle_inouts(call.wiring_inouts)
58
+ def handle_operation(self, op: QuantumOperation) -> None:
59
+ if isinstance(op, QuantumFunctionCall) and op.function == APPLY_OPERATOR.name:
60
+ call_name = op.operands[APPLY_OPERATOR.operand_names[0]]
61
+ self._handle_apply([QuantumFunctionCall(function=call_name)])
62
+ elif isinstance(op, WithinApply):
63
+ self._handle_apply(op.action)
64
+ self._handle_inputs(op.wiring_inputs)
65
+ self._handle_outputs(op.wiring_outputs)
66
+ self._handle_inouts(op.wiring_inouts)
66
67
 
67
68
  def handle_variable_declaration(
68
69
  self, declaration: VariableDeclarationStatement
@@ -130,13 +131,10 @@ class HandleValidator(HandleValidationBase):
130
131
  f"Invalid use of inout handle {handle!r}, used both in slice or subscript and whole"
131
132
  )
132
133
 
133
- def _handle_apply(self, call: QuantumFunctionCall) -> None:
134
- operand = call.operands[OPERAND_FIELD_NAME]
135
- if not isinstance(operand, QuantumLambdaFunction):
136
- return
134
+ def _handle_apply(self, body: StatementBlock) -> None:
137
135
  local_variables: Set[str] = set()
138
136
  output_capturing_variables: Set[str] = set()
139
- for statement in operand.body:
137
+ for statement in body:
140
138
  if isinstance(statement, VariableDeclarationStatement):
141
139
  local_variables.add(statement.name)
142
140
  elif isinstance(statement, QuantumOperation):
@@ -0,0 +1,11 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from classiq.interface.model.quantum_statement import QuantumOperation
4
+
5
+ if TYPE_CHECKING:
6
+ from classiq.interface.model.statement_block import StatementBlock
7
+
8
+
9
+ class WithinApply(QuantumOperation):
10
+ compute: "StatementBlock"
11
+ action: "StatementBlock"
@@ -1,10 +1,13 @@
1
+ from typing import Any
2
+
1
3
  import sympy
2
4
  from pyomo.core.base import _GeneralVarData
5
+ from pyomo.core.expr.sympy_tools import PyomoSympyBimap
3
6
 
4
7
 
5
8
  # This code is a pure copy paste from pyomo.core.expr.sympy_tools.PyomoSympyBimap.getSympySymbol
6
9
  # except one line.
7
- def get_sympy_symbol(self, pyomo_object):
10
+ def get_sympy_symbol(self: PyomoSympyBimap, pyomo_object: Any) -> sympy.Symbol:
8
11
  if pyomo_object in self.pyomo2sympy:
9
12
  return self.pyomo2sympy[pyomo_object]
10
13
  # Pyomo currently ONLY supports Real variables (not complex
@@ -44,6 +44,11 @@ TASKS_SOLVE_SUFFIX = "/tasks/solve"
44
44
  MODEL_GENERATE_PREFIX = "/generate_model"
45
45
  CHEMISTRY_GENERATE_MODEL_PATH = MODEL_GENERATE_PREFIX + "/chemistry"
46
46
 
47
+ CHEMISTRY_QMOD_PATH = "/generate_model/chemistry/qmod"
48
+ GROVER_QMOD_PATH = "/generate_model/grover/qmod"
49
+ FINANCE_QMOD_PATH = "/generate_model/finance/qmod"
50
+
51
+
47
52
  TASK_TRAIN_SUFFIX = TASKS_SUFFIX + "/train"
48
53
  TASK_TEST_SUFFIX = TASKS_SUFFIX + "/test"
49
54
  TASK_PREDICT_SUFFIX = TASKS_SUFFIX + "/predict"
@@ -73,10 +78,6 @@ FINANCE_GENERATE_MODEL_PATH = MODEL_GENERATE_PREFIX + "/finance"
73
78
 
74
79
  GROVER_GENERATE_MODEL_PATH = MODEL_GENERATE_PREFIX + "/grover"
75
80
 
76
- QMOD_PREFIX = ANALYZER_PREFIX + "/qmods"
77
- QMOD_METADATA_PATH = QMOD_PREFIX + "/metadata"
78
- QMOD_FILE_PATH = QMOD_PREFIX + "/file"
79
-
80
81
  CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX = "/execution_input"
81
82
  CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_FULL = (
82
83
  CONVERSION_PREFIX + CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX
classiq/qmod/__init__.py CHANGED
@@ -1,12 +1,16 @@
1
1
  from . import symbolic
2
2
  from .builtins import * # noqa: F403
3
3
  from .builtins import __all__ as _builtins_all
4
- from .classical_function import CFunc
4
+ from .cfunc import cfunc
5
+ from .expression_query import get_expression_numeric_attributes
6
+ from .qfunc import qfunc
7
+ from .qmod_constant import QConstant
5
8
  from .qmod_parameter import Array, QParam
6
- from .qmod_struct import QStruct
9
+ from .qmod_struct import struct
7
10
  from .qmod_variable import Input, Output, QArray, QBit, QNum
8
11
  from .quantum_callable import QCallable, QCallableList
9
- from .quantum_function import QFunc, create_model
12
+ from .quantum_function import create_model
13
+ from .write_qmod import write_qmod
10
14
 
11
15
  __all__ = [
12
16
  "QParam",
@@ -18,9 +22,12 @@ __all__ = [
18
22
  "QNum",
19
23
  "QCallable",
20
24
  "QCallableList",
21
- "QStruct",
22
- "QFunc",
23
- "CFunc",
25
+ "QConstant",
26
+ "struct",
27
+ "qfunc",
28
+ "cfunc",
24
29
  "create_model",
25
30
  "symbolic",
31
+ "write_qmod",
32
+ "get_expression_numeric_attributes",
26
33
  ] + _builtins_all
@@ -1,4 +1,4 @@
1
- from typing import Dict, List, Optional
1
+ from typing import Dict, List, Optional, Union
2
2
 
3
3
  from classiq.interface.executor.execution_preferences import QaeWithQpeEstimationMethod
4
4
  from classiq.interface.executor.iqae_result import IQAEResult
@@ -6,32 +6,38 @@ from classiq.interface.executor.result import EstimationResult, ExecutionDetails
6
6
  from classiq.interface.executor.vqe_result import VQESolverResult
7
7
  from classiq.interface.generator.expressions.enums import Optimizer
8
8
  from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
9
- from classiq.interface.generator.types.combinatorial_problem import (
10
- CombinatorialOptimizationStructDeclaration,
11
- )
12
9
 
13
10
  from classiq.applications.qsvm.qsvm import Data, Labels
11
+ from classiq.exceptions import ClassiqError
12
+
13
+ ExecutionParams = Dict[str, Union[float, int]]
14
+
15
+ _CALL_IN_QFUNC_ERROR = (
16
+ 'Cannot call "{}" in a quantum context. "{}" is a classical execution primitive.'
17
+ )
18
+
14
19
 
15
- ExecutionParams = Dict[str, float]
20
+ def _raise_error(primitive_name: str) -> None:
21
+ raise ClassiqError(_CALL_IN_QFUNC_ERROR.format(primitive_name, primitive_name))
16
22
 
17
23
 
18
24
  def save(values_to_save: dict) -> None:
19
- pass
25
+ _raise_error("save")
20
26
 
21
27
 
22
- def sample( # type: ignore
28
+ def sample( # type: ignore[return]
23
29
  execution_params: Optional[ExecutionParams] = None,
24
30
  ) -> ExecutionDetails:
25
- pass
31
+ _raise_error("sample")
26
32
 
27
33
 
28
- def estimate( # type: ignore
34
+ def estimate( # type: ignore[return]
29
35
  hamiltonian: List[QmodPyStruct], execution_params: Optional[ExecutionParams] = None
30
36
  ) -> EstimationResult:
31
- pass
37
+ _raise_error("estimate")
32
38
 
33
39
 
34
- def vqe( # type: ignore
40
+ def vqe( # type: ignore[return]
35
41
  hamiltonian: List[QmodPyStruct],
36
42
  maximize: bool,
37
43
  initial_point: List[int],
@@ -42,56 +48,43 @@ def vqe( # type: ignore
42
48
  skip_compute_variance: bool,
43
49
  alpha_cvar: float,
44
50
  ) -> VQESolverResult:
45
- pass
51
+ _raise_error("vqe")
46
52
 
47
53
 
48
- def qae_with_qpe_result_post_processing( # type: ignore
54
+ def qae_with_qpe_result_post_processing( # type: ignore[return]
49
55
  estimation_register_size: int,
50
56
  estimation_method: QaeWithQpeEstimationMethod,
51
57
  result: ExecutionDetails,
52
58
  ) -> float:
53
- pass
59
+ _raise_error("qae_with_qpe_result_post_processing")
54
60
 
55
61
 
56
- def qsvm_full_run( # type: ignore
62
+ def qsvm_full_run( # type: ignore[return]
57
63
  train_data: Data,
58
64
  train_labels: Labels,
59
65
  test_data: Data,
60
66
  test_labels: Labels,
61
67
  predict_data: Data,
62
68
  ) -> QmodPyStruct:
63
- pass
69
+ _raise_error("qsvm_full_run")
64
70
 
65
71
 
66
- def iqae( # type: ignore
72
+ def iqae( # type: ignore[return]
67
73
  epsilon: float,
68
74
  alpha: float,
69
75
  execution_params: Optional[ExecutionParams] = None,
70
76
  ) -> IQAEResult:
71
- pass
77
+ _raise_error("iqae")
72
78
 
73
79
 
74
- def molecule_ground_state_solution_post_process( # type: ignore
80
+ def molecule_ground_state_solution_post_process( # type: ignore[return]
75
81
  problem: QmodPyStruct, vqe_result: VQESolverResult
76
82
  ) -> QmodPyStruct:
77
- pass
78
-
79
-
80
- def optimization_problem_to_hamiltonian( # type: ignore
81
- problem_struct: CombinatorialOptimizationStructDeclaration, penalty_energy: float
82
- ) -> List[QmodPyStruct]:
83
- pass
84
-
85
-
86
- def get_optimization_solution( # type: ignore
87
- problem_struct: CombinatorialOptimizationStructDeclaration,
88
- vqe_result: VQESolverResult,
89
- penalty_energy: float,
90
- ) -> List[QmodPyStruct]:
91
- pass
83
+ _raise_error("molecule_ground_state_solution_post_process")
92
84
 
93
85
 
94
86
  __all__ = [
87
+ "ExecutionParams",
95
88
  "save",
96
89
  "sample",
97
90
  "estimate",
@@ -100,8 +93,6 @@ __all__ = [
100
93
  "qsvm_full_run",
101
94
  "iqae",
102
95
  "molecule_ground_state_solution_post_process",
103
- "optimization_problem_to_hamiltonian",
104
- "get_optimization_solution",
105
96
  ]
106
97
 
107
98