classiq 0.38.0__py3-none-any.whl → 0.40.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 (154) hide show
  1. classiq/__init__.py +22 -22
  2. classiq/_internals/api_wrapper.py +13 -1
  3. classiq/_internals/client.py +12 -2
  4. classiq/analyzer/analyzer.py +3 -1
  5. classiq/applications/__init__.py +1 -8
  6. classiq/applications/chemistry/__init__.py +6 -0
  7. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +1 -1
  8. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  9. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +25 -6
  10. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +1 -1
  11. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +1 -1
  12. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +2 -4
  13. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +13 -16
  14. classiq/{applications_model_constructors → applications}/combinatorial_helpers/pyomo_utils.py +4 -2
  15. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +3 -10
  16. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +4 -6
  17. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +3 -5
  18. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  19. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +4 -6
  20. classiq/applications/combinatorial_optimization/__init__.py +11 -3
  21. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +9 -10
  22. classiq/applications/finance/__init__.py +3 -2
  23. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +24 -14
  24. classiq/applications/grover/__init__.py +11 -0
  25. classiq/applications/libraries/qmci_library.py +35 -0
  26. classiq/applications/qsvm/__init__.py +5 -1
  27. classiq/execution/all_hardware_devices.py +13 -0
  28. classiq/executor.py +2 -1
  29. classiq/interface/_version.py +1 -1
  30. classiq/interface/analyzer/result.py +1 -5
  31. classiq/interface/applications/qsvm.py +4 -2
  32. classiq/interface/ast_node.py +23 -0
  33. classiq/interface/backend/backend_preferences.py +5 -5
  34. classiq/interface/backend/quantum_backend_providers.py +7 -7
  35. classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
  36. classiq/interface/executor/execution_preferences.py +4 -9
  37. classiq/interface/executor/execution_request.py +2 -37
  38. classiq/interface/executor/vqe_result.py +1 -1
  39. classiq/interface/generator/application_apis/chemistry_declarations.py +2 -4
  40. classiq/interface/generator/application_apis/finance_declarations.py +1 -1
  41. classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -0
  42. classiq/interface/generator/builtin_api_builder.py +0 -5
  43. classiq/interface/generator/constant.py +2 -3
  44. classiq/interface/generator/expressions/expression.py +2 -4
  45. classiq/interface/generator/expressions/qmod_qarray_proxy.py +82 -0
  46. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +22 -1
  47. classiq/interface/generator/expressions/qmod_sized_proxy.py +22 -0
  48. classiq/interface/generator/functions/__init__.py +2 -2
  49. classiq/interface/generator/functions/builtins/__init__.py +15 -0
  50. classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
  51. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +8 -6
  52. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +10 -4
  53. classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
  54. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +893 -319
  55. classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
  56. classiq/interface/generator/functions/classical_type.py +31 -21
  57. classiq/interface/generator/functions/function_declaration.py +2 -2
  58. classiq/interface/generator/hartree_fock.py +10 -2
  59. classiq/interface/generator/model/classical_main_validator.py +1 -1
  60. classiq/interface/generator/model/model.py +1 -1
  61. classiq/interface/generator/model/preferences/preferences.py +4 -2
  62. classiq/interface/generator/quantum_function_call.py +1 -1
  63. classiq/interface/generator/types/struct_declaration.py +2 -4
  64. classiq/interface/model/call_synthesis_data.py +3 -3
  65. classiq/interface/model/classical_if.py +13 -0
  66. classiq/interface/model/classical_parameter_declaration.py +2 -3
  67. classiq/interface/model/{quantum_if_operation.py → control.py} +39 -21
  68. classiq/interface/model/handle_binding.py +3 -2
  69. classiq/interface/model/invert.py +10 -0
  70. classiq/interface/model/model.py +2 -1
  71. classiq/interface/model/power.py +12 -0
  72. classiq/interface/model/quantum_function_call.py +9 -4
  73. classiq/interface/model/quantum_lambda_function.py +3 -9
  74. classiq/interface/model/quantum_statement.py +3 -2
  75. classiq/interface/model/quantum_type.py +8 -9
  76. classiq/interface/model/quantum_variable_declaration.py +2 -2
  77. classiq/interface/model/repeat.py +13 -0
  78. classiq/interface/model/resolvers/function_call_resolver.py +21 -0
  79. classiq/interface/model/statement_block.py +18 -4
  80. classiq/interface/model/validations/handles_validator.py +8 -12
  81. classiq/interface/model/within_apply_operation.py +4 -4
  82. classiq/interface/server/routes.py +0 -4
  83. classiq/qmod/__init__.py +6 -2
  84. classiq/qmod/builtins/classical_functions.py +34 -39
  85. classiq/qmod/builtins/functions.py +287 -300
  86. classiq/qmod/builtins/operations.py +217 -16
  87. classiq/qmod/builtins/structs.py +50 -48
  88. classiq/qmod/declaration_inferrer.py +30 -18
  89. classiq/qmod/native/expression_to_qmod.py +5 -4
  90. classiq/qmod/native/pretty_printer.py +48 -26
  91. classiq/qmod/qmod_constant.py +29 -5
  92. classiq/qmod/qmod_parameter.py +56 -34
  93. classiq/qmod/qmod_struct.py +2 -2
  94. classiq/qmod/qmod_variable.py +87 -43
  95. classiq/qmod/quantum_callable.py +8 -4
  96. classiq/qmod/quantum_expandable.py +25 -20
  97. classiq/qmod/quantum_function.py +29 -2
  98. classiq/qmod/symbolic.py +79 -69
  99. classiq/qmod/symbolic_expr.py +1 -1
  100. classiq/qmod/symbolic_type.py +1 -4
  101. classiq/qmod/utilities.py +29 -0
  102. {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/METADATA +1 -1
  103. {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/RECORD +122 -141
  104. classiq/applications/benchmarking/__init__.py +0 -9
  105. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  106. classiq/applications/numpy_utils.py +0 -37
  107. classiq/applications_model_constructors/__init__.py +0 -25
  108. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  109. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  110. classiq/builtin_functions/__init__.py +0 -43
  111. classiq/builtin_functions/amplitude_loading.py +0 -3
  112. classiq/builtin_functions/binary_ops.py +0 -1
  113. classiq/builtin_functions/exponentiation.py +0 -5
  114. classiq/builtin_functions/qpe.py +0 -4
  115. classiq/builtin_functions/qsvm.py +0 -7
  116. classiq/builtin_functions/range_types.py +0 -5
  117. classiq/builtin_functions/standard_gates.py +0 -1
  118. classiq/builtin_functions/state_preparation.py +0 -6
  119. classiq/builtin_functions/suzuki_trotter.py +0 -3
  120. classiq/interface/executor/error_mitigation.py +0 -6
  121. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  122. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py +0 -0
  123. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  124. classiq/model/__init__.py +0 -14
  125. classiq/model/composite_function_generator.py +0 -33
  126. classiq/model/function_handler.py +0 -462
  127. classiq/model/logic_flow.py +0 -149
  128. classiq/model/logic_flow_change_handler.py +0 -71
  129. classiq/model/model.py +0 -229
  130. classiq/quantum_functions/__init__.py +0 -17
  131. classiq/quantum_functions/annotation_parser.py +0 -205
  132. classiq/quantum_functions/decorators.py +0 -22
  133. classiq/quantum_functions/function_library.py +0 -181
  134. classiq/quantum_functions/function_parser.py +0 -74
  135. classiq/quantum_functions/quantum_function.py +0 -236
  136. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  137. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +0 -0
  138. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  139. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +0 -0
  140. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  141. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  142. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -0
  143. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  144. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  145. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +0 -0
  146. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  147. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +0 -0
  148. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +0 -0
  149. /classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +0 -0
  150. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  151. /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
  152. /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
  153. /classiq/{quantum_register.py → interface/model/quantum_register.py} +0 -0
  154. {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/WHEEL +0 -0
@@ -12,6 +12,7 @@ from typing import ( # type: ignore[attr-defined]
12
12
 
13
13
  from typing_extensions import ParamSpec
14
14
 
15
+ from classiq.interface.ast_node import SourceReference
15
16
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
16
17
  from classiq.interface.model.quantum_function_declaration import (
17
18
  QuantumFunctionDeclaration,
@@ -19,7 +20,8 @@ from classiq.interface.model.quantum_function_declaration import (
19
20
  from classiq.interface.model.quantum_statement import QuantumStatement
20
21
  from classiq.interface.model.quantum_type import QuantumType
21
22
 
22
- from classiq.qmod.qmod_parameter import QParam
23
+ from classiq.qmod.qmod_parameter import CInt
24
+ from classiq.qmod.utilities import get_source_ref
23
25
 
24
26
  if TYPE_CHECKING:
25
27
  from classiq.qmod.quantum_expandable import QTerminalCallable
@@ -42,8 +44,9 @@ class QCallable(Generic[P], ABC):
42
44
 
43
45
  def __call__(self, *args: Any, **kwargs: Any) -> None:
44
46
  assert QCallable.CURRENT_EXPANDABLE is not None
47
+ source_ref = get_source_ref(sys._getframe(1))
45
48
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
46
- self.create_quantum_function_call(*args, **kwargs)
49
+ self.create_quantum_function_call(source_ref, *args, **kwargs)
47
50
  )
48
51
  return
49
52
 
@@ -60,7 +63,7 @@ class QCallable(Generic[P], ABC):
60
63
 
61
64
  @abstractmethod
62
65
  def create_quantum_function_call(
63
- self, *args: Any, **kwargs: Any
66
+ self, source_ref_: SourceReference, *args: Any, **kwargs: Any
64
67
  ) -> QuantumFunctionCall:
65
68
  raise NotImplementedError()
66
69
 
@@ -68,7 +71,8 @@ class QCallable(Generic[P], ABC):
68
71
  class QCallableList(QCallable, Generic[P], ABC):
69
72
  if TYPE_CHECKING:
70
73
 
74
+ @property
71
75
  def len(self) -> int: ...
72
76
 
73
- def __getitem__(self, key: Union[slice, int, QParam]) -> "QTerminalCallable":
77
+ def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
74
78
  raise NotImplementedError()
@@ -17,6 +17,7 @@ from typing import (
17
17
 
18
18
  from typing_extensions import Self
19
19
 
20
+ from classiq.interface.ast_node import SourceReference
20
21
  from classiq.interface.generator.expressions.expression import Expression
21
22
  from classiq.interface.model.classical_parameter_declaration import (
22
23
  ClassicalParameterDeclaration,
@@ -32,10 +33,7 @@ from classiq.interface.model.quantum_function_declaration import (
32
33
  QuantumFunctionDeclaration,
33
34
  QuantumOperandDeclaration,
34
35
  )
35
- from classiq.interface.model.quantum_lambda_function import (
36
- QuantumLambdaFunction,
37
- QuantumOperand,
38
- )
36
+ from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
39
37
  from classiq.interface.model.quantum_statement import QuantumStatement
40
38
  from classiq.interface.model.quantum_type import QuantumType
41
39
  from classiq.interface.model.variable_declaration_statement import (
@@ -45,12 +43,12 @@ from classiq.interface.model.variable_declaration_statement import (
45
43
  from classiq.exceptions import ClassiqValueError
46
44
  from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
47
45
  from classiq.qmod.qmod_constant import QConstant
48
- from classiq.qmod.qmod_parameter import QParam, QParamScalar, create_param
46
+ from classiq.qmod.qmod_parameter import CInt, CParam, CParamScalar, create_param
49
47
  from classiq.qmod.qmod_variable import QVar, create_qvar_for_port_decl
50
48
  from classiq.qmod.quantum_callable import QCallable, QExpandableInterface
51
49
  from classiq.qmod.utilities import mangle_keyword
52
50
 
53
- ArgType = Union[QParam, QVar, QCallable]
51
+ ArgType = Union[CParam, QVar, QCallable]
54
52
 
55
53
 
56
54
  class QExpandable(QCallable, QExpandableInterface, ABC):
@@ -112,9 +110,11 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
112
110
  return result
113
111
 
114
112
  def create_quantum_function_call(
115
- self, *args: Any, **kwargs: Any
113
+ self, source_ref_: SourceReference, *args: Any, **kwargs: Any
116
114
  ) -> QuantumFunctionCall:
117
- return _create_quantum_function_call(self.func_decl, None, *args, **kwargs)
115
+ return _create_quantum_function_call(
116
+ self.func_decl, None, source_ref_, *args, **kwargs
117
+ )
118
118
 
119
119
 
120
120
  class QLambdaFunction(QExpandable):
@@ -141,7 +141,7 @@ class QTerminalCallable(QCallable):
141
141
  def __init__(
142
142
  self,
143
143
  decl: QuantumFunctionDeclaration,
144
- index_: Optional[Union[int, QParamScalar]] = None,
144
+ index_: Optional[Union[int, CParamScalar]] = None,
145
145
  ) -> None:
146
146
  self._decl = decl
147
147
  self._index = index_
@@ -150,51 +150,53 @@ class QTerminalCallable(QCallable):
150
150
  def is_list(self) -> bool:
151
151
  return isinstance(self._decl, QuantumOperandDeclaration) and self._decl.is_list
152
152
 
153
- def __getitem__(self, key: Union[slice, int, QParam]) -> "QTerminalCallable":
153
+ def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
154
154
  if not self.is_list:
155
155
  raise ClassiqValueError("Cannot index a non-list operand")
156
156
  if isinstance(key, slice):
157
157
  raise NotImplementedError("Operand lists don't support slicing")
158
- if isinstance(key, QParam) and not isinstance(key, QParamScalar):
158
+ if isinstance(key, CParam) and not isinstance(key, CParamScalar):
159
159
  raise ClassiqValueError("Non-classical parameter for slicing")
160
160
  return QTerminalCallable(self._decl, key)
161
161
 
162
162
  def __len__(self) -> int:
163
163
  raise ClassiqValueError(
164
- "len(<func>) is not supported for quantum callables - use <func>.len() instead (Only if it is an operand list)"
164
+ "len(<func>) is not supported for quantum callables - use <func>.len instead (Only if it is an operand list)"
165
165
  )
166
166
 
167
167
  if TYPE_CHECKING:
168
168
 
169
+ @property
169
170
  def len(self) -> int: ...
170
171
 
171
172
  else:
172
173
 
173
- def len(self) -> QParamScalar:
174
+ @property
175
+ def len(self) -> CParamScalar:
174
176
  if not self.is_list:
175
177
  raise ClassiqValueError("Cannot get length of a non-list operand")
176
- return QParamScalar(f"len({self.func_decl.name})")
178
+ return CParamScalar(f"{self.func_decl.name}.len")
177
179
 
178
180
  @property
179
181
  def func_decl(self) -> QuantumFunctionDeclaration:
180
182
  return self._decl
181
183
 
182
184
  def create_quantum_function_call(
183
- self, *args: Any, **kwargs: Any
185
+ self, source_ref_: SourceReference, *args: Any, **kwargs: Any
184
186
  ) -> QuantumFunctionCall:
185
187
  if self.is_list and self._index is None:
186
188
  raise ClassiqValueError(
187
189
  f"Quantum operand {self.func_decl.name!r} is a list and must be indexed"
188
190
  )
189
191
  return _create_quantum_function_call(
190
- self.func_decl, self._index, *args, **kwargs
192
+ self.func_decl, self._index, source_ref_, *args, **kwargs
191
193
  )
192
194
 
193
195
 
194
196
  @overload
195
197
  def prepare_arg(
196
- arg_decl: PositionalArg, val: Union[QCallable, Callable[[Any], None]]
197
- ) -> QuantumOperand: ...
198
+ arg_decl: PositionalArg, val: Union[QCallable, Callable[..., None]]
199
+ ) -> QuantumLambdaFunction: ...
198
200
 
199
201
 
200
202
  @overload
@@ -279,7 +281,8 @@ def _prepare_args(
279
281
 
280
282
  def _create_quantum_function_call(
281
283
  decl_: QuantumFunctionDeclaration,
282
- index_: Optional[Union[QParamScalar, int]] = None,
284
+ index_: Optional[Union[CParamScalar, int]] = None,
285
+ source_ref_: Optional[SourceReference] = None,
283
286
  *args: Any,
284
287
  **kwargs: Any,
285
288
  ) -> QuantumFunctionCall:
@@ -307,4 +310,6 @@ def _create_quantum_function_call(
307
310
  index=Expression(expr=str(index_)), name=function_ident
308
311
  )
309
312
 
310
- return QuantumFunctionCall(function=function_ident, positional_args=prepared_args)
313
+ return QuantumFunctionCall(
314
+ function=function_ident, positional_args=prepared_args, source_ref=source_ref_
315
+ )
@@ -1,8 +1,11 @@
1
1
  import ast
2
2
  import functools
3
+ import warnings
4
+ from inspect import isclass
3
5
  from typing import Any, Callable, Dict, List, Optional, Tuple, get_origin
4
6
 
5
7
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
8
+ from classiq.interface.generator.functions.classical_type import CStructBase
6
9
  from classiq.interface.generator.model.constraints import Constraints
7
10
  from classiq.interface.generator.model.preferences.preferences import Preferences
8
11
  from classiq.interface.model.model import Model, SerializedModel
@@ -15,7 +18,7 @@ from classiq.exceptions import ClassiqError
15
18
  from classiq.qmod.classical_function import CFunc
16
19
  from classiq.qmod.declaration_inferrer import infer_func_decl
17
20
  from classiq.qmod.qmod_constant import QConstant
18
- from classiq.qmod.qmod_parameter import QParam
21
+ from classiq.qmod.qmod_parameter import CArray, CParam, QParam
19
22
  from classiq.qmod.qmod_variable import QVar
20
23
  from classiq.qmod.quantum_callable import QCallable, QCallableList
21
24
  from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
@@ -34,6 +37,10 @@ def create_model(
34
37
  preferences: Optional[Preferences] = None,
35
38
  classical_execution_function: Optional[CFunc] = None,
36
39
  ) -> SerializedModel:
40
+ if entry_point.func_decl.name != "main":
41
+ raise ClassiqError(
42
+ f"The entry point function must be named 'main', got '{entry_point.func_decl.name}'"
43
+ )
37
44
  return entry_point.create_model(
38
45
  constraints, execution_preferences, preferences, classical_execution_function
39
46
  ).get_model()
@@ -42,6 +49,18 @@ def create_model(
42
49
  class QFunc(QExpandable):
43
50
  def __init__(self, py_callable: Callable) -> None:
44
51
  _validate_no_gen_params(py_callable.__annotations__)
52
+ if any(
53
+ get_origin(annotation) == QParam
54
+ for annotation in py_callable.__annotations__.values()
55
+ ):
56
+ warnings.warn(
57
+ "QParam is deprecated and will be removed in a future release. Use the "
58
+ "new classical parameter types instead:\n * QParam[int] -> CInt\n * QParam[float] "
59
+ "-> CReal\n * QParam[bool] -> CBool\n * QParam[list[int]] -> "
60
+ "CArray[CInt]",
61
+ category=DeprecationWarning,
62
+ stacklevel=4,
63
+ )
45
64
  super().__init__(py_callable)
46
65
  functools.update_wrapper(self, py_callable)
47
66
 
@@ -140,7 +159,10 @@ ILLEGAL_PARAM_ERROR = "Unsupported type hint '{annotation}' for argument '{name}
140
159
 
141
160
 
142
161
  class IllegalParamsError(ClassiqError):
143
- _HINT = "\nNote - QMOD functions can declare classical parameters using the type hint 'QParam'."
162
+ _HINT = (
163
+ "\nNote - QMOD functions can declare classical parameters using the type hints "
164
+ "'CInt', 'CReal', 'CBool', and 'CArray'."
165
+ )
144
166
 
145
167
  def __init__(self, message: str) -> None:
146
168
  super().__init__(message + self._HINT)
@@ -153,6 +175,11 @@ def _validate_no_gen_params(annotations: Dict[str, Any]) -> None:
153
175
  if not (
154
176
  name == "return"
155
177
  or get_origin(annotation) is QParam
178
+ or isclass(annotation)
179
+ and issubclass(annotation, CParam)
180
+ or isclass(annotation)
181
+ and issubclass(annotation, CStructBase)
182
+ or get_origin(annotation) is CArray
156
183
  or (get_origin(annotation) or annotation) is QCallable
157
184
  or (get_origin(annotation) or annotation) is QCallableList
158
185
  or QVar.from_type_hint(annotation) is not None
classiq/qmod/symbolic.py CHANGED
@@ -1,10 +1,21 @@
1
1
  import sys
2
- from typing import Optional, Tuple, Type, get_args, get_origin, overload
2
+ from typing import (
3
+ TYPE_CHECKING,
4
+ Any,
5
+ List,
6
+ Optional,
7
+ Tuple,
8
+ Type,
9
+ TypeVar,
10
+ get_args,
11
+ get_origin,
12
+ overload,
13
+ )
3
14
 
4
15
  from classiq.exceptions import ClassiqValueError
5
16
  from classiq.qmod import model_state_container
6
17
  from classiq.qmod.declaration_inferrer import python_type_to_qmod
7
- from classiq.qmod.qmod_parameter import QParam, QParamScalar, create_param
18
+ from classiq.qmod.qmod_parameter import CParam, CParamScalar, QParam, create_param
8
19
  from classiq.qmod.symbolic_expr import SymbolicExpr
9
20
  from classiq.qmod.symbolic_type import SymbolicTypes
10
21
 
@@ -15,20 +26,18 @@ GoldenRatio = SymbolicExpr("GoldenRatio")
15
26
  EulerGamma = SymbolicExpr("EulerGamma")
16
27
  Catalan = SymbolicExpr("Catalan")
17
28
 
29
+ T = TypeVar("T", bound=CParam)
30
+
18
31
 
19
32
  @overload
20
- def symbolic_function(
21
- *args: SymbolicTypes, return_type: None = None
22
- ) -> QParamScalar: ...
33
+ def symbolic_function(*args: Any, return_type: None = None) -> CParamScalar: ...
23
34
 
24
35
 
25
36
  @overload
26
- def symbolic_function(*args: SymbolicTypes, return_type: Type[QParam]) -> QParam: ...
37
+ def symbolic_function(*args: Any, return_type: Type[T]) -> T: ...
27
38
 
28
39
 
29
- def symbolic_function(
30
- *args: SymbolicTypes, return_type: Optional[Type[QParam]] = None
31
- ) -> QParam:
40
+ def symbolic_function(*args: Any, return_type: Optional[Type[T]] = None) -> CParam:
32
41
  qmodule = (
33
42
  model_state_container.QMODULE
34
43
  ) # FIXME: https://classiq.atlassian.net/browse/CAD-15126
@@ -36,14 +45,15 @@ def symbolic_function(
36
45
  expr = f"{sys._getframe(1).f_code.co_name}({','.join(str_args)})"
37
46
 
38
47
  if return_type is None:
39
- return QParamScalar(expr)
48
+ return CParamScalar(expr)
40
49
 
41
- if get_origin(return_type) is not QParam:
42
- raise ClassiqValueError(
43
- f"Unsupported return type for symbolic function: {return_type}"
44
- )
50
+ if get_origin(return_type) is QParam:
51
+ return_type = get_args(return_type)[0]
52
+
53
+ if TYPE_CHECKING:
54
+ assert return_type is not None
45
55
 
46
- qmod_type = python_type_to_qmod(get_args(return_type)[0], qmodule=qmodule)
56
+ qmod_type = python_type_to_qmod(return_type, qmodule=qmodule)
47
57
  if qmod_type is None:
48
58
  raise ClassiqValueError(
49
59
  f"Unsupported return type for symbolic function: {return_type}"
@@ -56,211 +66,211 @@ def symbolic_function(
56
66
  )
57
67
 
58
68
 
59
- def sin(x: SymbolicTypes) -> QParamScalar:
69
+ def sin(x: SymbolicTypes) -> CParamScalar:
60
70
  return symbolic_function(x)
61
71
 
62
72
 
63
- def cos(x: SymbolicTypes) -> QParamScalar:
73
+ def cos(x: SymbolicTypes) -> CParamScalar:
64
74
  return symbolic_function(x)
65
75
 
66
76
 
67
- def tan(x: SymbolicTypes) -> QParamScalar:
77
+ def tan(x: SymbolicTypes) -> CParamScalar:
68
78
  return symbolic_function(x)
69
79
 
70
80
 
71
- def cot(x: SymbolicTypes) -> QParamScalar:
81
+ def cot(x: SymbolicTypes) -> CParamScalar:
72
82
  return symbolic_function(x)
73
83
 
74
84
 
75
- def sec(x: SymbolicTypes) -> QParamScalar:
85
+ def sec(x: SymbolicTypes) -> CParamScalar:
76
86
  return symbolic_function(x)
77
87
 
78
88
 
79
- def csc(x: SymbolicTypes) -> QParamScalar:
89
+ def csc(x: SymbolicTypes) -> CParamScalar:
80
90
  return symbolic_function(x)
81
91
 
82
92
 
83
- def asin(x: SymbolicTypes) -> QParamScalar:
93
+ def asin(x: SymbolicTypes) -> CParamScalar:
84
94
  return symbolic_function(x)
85
95
 
86
96
 
87
- def acos(x: SymbolicTypes) -> QParamScalar:
97
+ def acos(x: SymbolicTypes) -> CParamScalar:
88
98
  return symbolic_function(x)
89
99
 
90
100
 
91
- def atan(x: SymbolicTypes) -> QParamScalar:
101
+ def atan(x: SymbolicTypes) -> CParamScalar:
92
102
  return symbolic_function(x)
93
103
 
94
104
 
95
- def acot(x: SymbolicTypes) -> QParamScalar:
105
+ def acot(x: SymbolicTypes) -> CParamScalar:
96
106
  return symbolic_function(x)
97
107
 
98
108
 
99
- def asec(x: SymbolicTypes) -> QParamScalar:
109
+ def asec(x: SymbolicTypes) -> CParamScalar:
100
110
  return symbolic_function(x)
101
111
 
102
112
 
103
- def acsc(x: SymbolicTypes) -> QParamScalar:
113
+ def acsc(x: SymbolicTypes) -> CParamScalar:
104
114
  return symbolic_function(x)
105
115
 
106
116
 
107
- def sinh(x: SymbolicTypes) -> QParamScalar:
117
+ def sinh(x: SymbolicTypes) -> CParamScalar:
108
118
  return symbolic_function(x)
109
119
 
110
120
 
111
- def cosh(x: SymbolicTypes) -> QParamScalar:
121
+ def cosh(x: SymbolicTypes) -> CParamScalar:
112
122
  return symbolic_function(x)
113
123
 
114
124
 
115
- def tanh(x: SymbolicTypes) -> QParamScalar:
125
+ def tanh(x: SymbolicTypes) -> CParamScalar:
116
126
  return symbolic_function(x)
117
127
 
118
128
 
119
- def coth(x: SymbolicTypes) -> QParamScalar:
129
+ def coth(x: SymbolicTypes) -> CParamScalar:
120
130
  return symbolic_function(x)
121
131
 
122
132
 
123
- def sech(x: SymbolicTypes) -> QParamScalar:
133
+ def sech(x: SymbolicTypes) -> CParamScalar:
124
134
  return symbolic_function(x)
125
135
 
126
136
 
127
- def csch(x: SymbolicTypes) -> QParamScalar:
137
+ def csch(x: SymbolicTypes) -> CParamScalar:
128
138
  return symbolic_function(x)
129
139
 
130
140
 
131
- def asinh(x: SymbolicTypes) -> QParamScalar:
141
+ def asinh(x: SymbolicTypes) -> CParamScalar:
132
142
  return symbolic_function(x)
133
143
 
134
144
 
135
- def acosh(x: SymbolicTypes) -> QParamScalar:
145
+ def acosh(x: SymbolicTypes) -> CParamScalar:
136
146
  return symbolic_function(x)
137
147
 
138
148
 
139
- def atanh(x: SymbolicTypes) -> QParamScalar:
149
+ def atanh(x: SymbolicTypes) -> CParamScalar:
140
150
  return symbolic_function(x)
141
151
 
142
152
 
143
- def acoth(x: SymbolicTypes) -> QParamScalar:
153
+ def acoth(x: SymbolicTypes) -> CParamScalar:
144
154
  return symbolic_function(x)
145
155
 
146
156
 
147
- def asech(x: SymbolicTypes) -> QParamScalar:
157
+ def asech(x: SymbolicTypes) -> CParamScalar:
148
158
  return symbolic_function(x)
149
159
 
150
160
 
151
- def exp(x: SymbolicTypes) -> QParamScalar:
161
+ def exp(x: SymbolicTypes) -> CParamScalar:
152
162
  return symbolic_function(x)
153
163
 
154
164
 
155
- def log(x: SymbolicTypes, base: SymbolicTypes = E) -> QParamScalar:
165
+ def log(x: SymbolicTypes, base: SymbolicTypes = E) -> CParamScalar:
156
166
  return symbolic_function(x, base)
157
167
 
158
168
 
159
- def ln(x: SymbolicTypes) -> QParamScalar:
169
+ def ln(x: SymbolicTypes) -> CParamScalar:
160
170
  return symbolic_function(x)
161
171
 
162
172
 
163
- def sqrt(x: SymbolicTypes) -> QParamScalar:
173
+ def sqrt(x: SymbolicTypes) -> CParamScalar:
164
174
  return symbolic_function(x)
165
175
 
166
176
 
167
- def abs(x: SymbolicTypes) -> QParamScalar:
177
+ def abs(x: SymbolicTypes) -> CParamScalar:
168
178
  return symbolic_function(x)
169
179
 
170
180
 
171
- def floor(x: SymbolicTypes) -> QParamScalar:
181
+ def floor(x: SymbolicTypes) -> CParamScalar:
172
182
  return symbolic_function(x)
173
183
 
174
184
 
175
- def ceiling(x: SymbolicTypes) -> QParamScalar:
185
+ def ceiling(x: SymbolicTypes) -> CParamScalar:
176
186
  return symbolic_function(x)
177
187
 
178
188
 
179
- def erf(x: SymbolicTypes) -> QParamScalar:
189
+ def erf(x: SymbolicTypes) -> CParamScalar:
180
190
  return symbolic_function(x)
181
191
 
182
192
 
183
- def erfc(x: SymbolicTypes) -> QParamScalar:
193
+ def erfc(x: SymbolicTypes) -> CParamScalar:
184
194
  return symbolic_function(x)
185
195
 
186
196
 
187
- def gamma(x: SymbolicTypes) -> QParamScalar:
197
+ def gamma(x: SymbolicTypes) -> CParamScalar:
188
198
  return symbolic_function(x)
189
199
 
190
200
 
191
- def beta(x: SymbolicTypes) -> QParamScalar:
201
+ def beta(x: SymbolicTypes) -> CParamScalar:
192
202
  return symbolic_function(x)
193
203
 
194
204
 
195
- def besselj(x: SymbolicTypes) -> QParamScalar:
205
+ def besselj(x: SymbolicTypes) -> CParamScalar:
196
206
  return symbolic_function(x)
197
207
 
198
208
 
199
- def bessely(x: SymbolicTypes) -> QParamScalar:
209
+ def bessely(x: SymbolicTypes) -> CParamScalar:
200
210
  return symbolic_function(x)
201
211
 
202
212
 
203
- def besseli(x: SymbolicTypes) -> QParamScalar:
213
+ def besseli(x: SymbolicTypes) -> CParamScalar:
204
214
  return symbolic_function(x)
205
215
 
206
216
 
207
- def besselk(x: SymbolicTypes) -> QParamScalar:
217
+ def besselk(x: SymbolicTypes) -> CParamScalar:
208
218
  return symbolic_function(x)
209
219
 
210
220
 
211
- def dirichlet_eta(x: SymbolicTypes) -> QParamScalar:
221
+ def dirichlet_eta(x: SymbolicTypes) -> CParamScalar:
212
222
  return symbolic_function(x)
213
223
 
214
224
 
215
- def polygamma(x: SymbolicTypes) -> QParamScalar:
225
+ def polygamma(x: SymbolicTypes) -> CParamScalar:
216
226
  return symbolic_function(x)
217
227
 
218
228
 
219
- def loggamma(x: SymbolicTypes) -> QParamScalar:
229
+ def loggamma(x: SymbolicTypes) -> CParamScalar:
220
230
  return symbolic_function(x)
221
231
 
222
232
 
223
- def factorial(x: SymbolicTypes) -> QParamScalar:
233
+ def factorial(x: SymbolicTypes) -> CParamScalar:
224
234
  return symbolic_function(x)
225
235
 
226
236
 
227
- def binomial(x: SymbolicTypes) -> QParamScalar:
237
+ def binomial(x: SymbolicTypes) -> CParamScalar:
228
238
  return symbolic_function(x)
229
239
 
230
240
 
231
- def subfactorial(x: SymbolicTypes) -> QParamScalar:
241
+ def subfactorial(x: SymbolicTypes) -> CParamScalar:
232
242
  return symbolic_function(x)
233
243
 
234
244
 
235
- def primorial(x: SymbolicTypes) -> QParamScalar:
245
+ def primorial(x: SymbolicTypes) -> CParamScalar:
236
246
  return symbolic_function(x)
237
247
 
238
248
 
239
- def bell(x: SymbolicTypes) -> QParamScalar:
249
+ def bell(x: SymbolicTypes) -> CParamScalar:
240
250
  return symbolic_function(x)
241
251
 
242
252
 
243
- def bernoulli(x: SymbolicTypes) -> QParamScalar:
253
+ def bernoulli(x: SymbolicTypes) -> CParamScalar:
244
254
  return symbolic_function(x)
245
255
 
246
256
 
247
- def euler(x: SymbolicTypes) -> QParamScalar:
257
+ def euler(x: SymbolicTypes) -> CParamScalar:
248
258
  return symbolic_function(x)
249
259
 
250
260
 
251
- def catalan(x: SymbolicTypes) -> QParamScalar:
261
+ def catalan(x: SymbolicTypes) -> CParamScalar:
252
262
  return symbolic_function(x)
253
263
 
254
264
 
255
- def Piecewise(*args: Tuple[SymbolicTypes, SymbolicTypes]) -> QParamScalar: # noqa: N802
265
+ def Piecewise(*args: Tuple[SymbolicTypes, SymbolicTypes]) -> CParamScalar: # noqa: N802
256
266
  return symbolic_function(*args)
257
267
 
258
268
 
259
- def max(x: SymbolicTypes, y: SymbolicTypes) -> QParamScalar:
269
+ def max(x: SymbolicTypes, y: SymbolicTypes) -> CParamScalar:
260
270
  return symbolic_function(x, y)
261
271
 
262
272
 
263
- def min(x: SymbolicTypes, y: SymbolicTypes) -> QParamScalar:
273
+ def min(x: SymbolicTypes, y: SymbolicTypes) -> CParamScalar:
264
274
  return symbolic_function(x, y)
265
275
 
266
276
 
@@ -276,7 +286,7 @@ def logical_not(x: SymbolicTypes) -> SymbolicExpr:
276
286
  return SymbolicExpr._unary_op(x, "not")
277
287
 
278
288
 
279
- def mod_inverse(a: SymbolicTypes, m: SymbolicTypes) -> QParamScalar:
289
+ def mod_inverse(a: SymbolicTypes, m: SymbolicTypes) -> CParamScalar:
280
290
  return symbolic_function(a, m)
281
291
 
282
292
 
@@ -346,5 +356,5 @@ __all__ = [
346
356
  ]
347
357
 
348
358
 
349
- def __dir__():
359
+ def __dir__() -> List[str]:
350
360
  return __all__
@@ -12,7 +12,7 @@ class Symbolic:
12
12
  return self._expr
13
13
 
14
14
  def __repr__(self) -> str:
15
- return self._expr
15
+ return self.__str__()
16
16
 
17
17
  def __bool__(self) -> bool:
18
18
  try:
@@ -1,8 +1,5 @@
1
1
  from typing import Tuple, Union
2
2
 
3
- from classiq.qmod.qmod_parameter import QParam
4
3
  from classiq.qmod.symbolic_expr import SymbolicExpr
5
4
 
6
- SymbolicTypes = Union[
7
- QParam, SymbolicExpr, int, float, bool, Tuple["SymbolicTypes", ...]
8
- ]
5
+ SymbolicTypes = Union[SymbolicExpr, int, float, bool, Tuple["SymbolicTypes", ...]]
classiq/qmod/utilities.py CHANGED
@@ -1,7 +1,12 @@
1
+ import inspect
2
+ import itertools
1
3
  import keyword
2
4
  import sys
5
+ from types import FrameType
3
6
  from typing import get_args, get_origin
4
7
 
8
+ from classiq.interface.ast_node import SourceReference
9
+
5
10
  DEFAULT_DECIMAL_PRECISION = 4
6
11
 
7
12
 
@@ -25,3 +30,27 @@ def version_portable_get_args(py_type: type) -> tuple:
25
30
  return get_args(py_type) # The result of __class_getitem__
26
31
  else:
27
32
  return get_args(py_type)[0]
33
+
34
+
35
+ def get_source_ref(frame: FrameType) -> SourceReference:
36
+ filename = inspect.getfile(frame)
37
+ lineno = frame.f_lineno
38
+ if sys.version_info[0:2] < (3, 11) or frame.f_lasti < 0:
39
+ source_ref = SourceReference(
40
+ file_name=filename,
41
+ start_line=lineno,
42
+ start_column=-1,
43
+ end_line=-1,
44
+ end_column=-1,
45
+ )
46
+ else:
47
+ positions_gen = frame.f_code.co_positions()
48
+ positions = next(itertools.islice(positions_gen, frame.f_lasti // 2, None))
49
+ source_ref = SourceReference(
50
+ file_name=filename,
51
+ start_line=positions[0],
52
+ start_column=positions[2],
53
+ end_line=positions[1],
54
+ end_column=positions[3],
55
+ )
56
+ return source_ref
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: classiq
3
- Version: 0.38.0
3
+ Version: 0.40.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  Home-page: https://classiq.io
6
6
  License: Proprietary