classiq 0.38.0__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 (137) hide show
  1. classiq/__init__.py +21 -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}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  8. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +26 -6
  9. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +1 -1
  10. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +1 -1
  11. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +2 -4
  12. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +6 -10
  13. classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_utils.py +10 -0
  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 +9 -3
  21. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +7 -8
  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/combinatorial_optimization/examples/mht.py +8 -3
  34. classiq/interface/executor/execution_request.py +2 -37
  35. classiq/interface/executor/vqe_result.py +1 -1
  36. classiq/interface/generator/builtin_api_builder.py +0 -5
  37. classiq/interface/generator/constant.py +2 -3
  38. classiq/interface/generator/expressions/expression.py +2 -4
  39. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +1 -1
  40. classiq/interface/generator/functions/__init__.py +2 -2
  41. classiq/interface/generator/functions/builtins/__init__.py +15 -0
  42. classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
  43. classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
  44. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +109 -83
  45. classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
  46. classiq/interface/generator/functions/classical_type.py +2 -4
  47. classiq/interface/generator/functions/function_declaration.py +2 -2
  48. classiq/interface/generator/hartree_fock.py +10 -2
  49. classiq/interface/generator/model/classical_main_validator.py +1 -1
  50. classiq/interface/generator/model/model.py +1 -1
  51. classiq/interface/generator/quantum_function_call.py +1 -1
  52. classiq/interface/generator/types/struct_declaration.py +2 -4
  53. classiq/interface/model/call_synthesis_data.py +3 -3
  54. classiq/interface/model/classical_if.py +13 -0
  55. classiq/interface/model/classical_parameter_declaration.py +2 -3
  56. classiq/interface/model/control.py +16 -0
  57. classiq/interface/model/handle_binding.py +3 -2
  58. classiq/interface/model/invert.py +10 -0
  59. classiq/interface/model/model.py +2 -1
  60. classiq/interface/model/power.py +12 -0
  61. classiq/interface/model/quantum_function_call.py +9 -4
  62. classiq/interface/model/quantum_if_operation.py +3 -3
  63. classiq/interface/model/quantum_lambda_function.py +3 -9
  64. classiq/interface/model/quantum_statement.py +3 -2
  65. classiq/interface/model/quantum_type.py +2 -4
  66. classiq/interface/model/quantum_variable_declaration.py +2 -2
  67. classiq/interface/model/repeat.py +13 -0
  68. classiq/interface/model/resolvers/function_call_resolver.py +26 -0
  69. classiq/interface/model/statement_block.py +21 -4
  70. classiq/interface/model/validations/handles_validator.py +8 -12
  71. classiq/interface/model/within_apply_operation.py +4 -4
  72. classiq/interface/server/routes.py +0 -4
  73. classiq/qmod/builtins/classical_functions.py +9 -9
  74. classiq/qmod/builtins/functions.py +153 -226
  75. classiq/qmod/builtins/operations.py +160 -13
  76. classiq/qmod/native/pretty_printer.py +49 -20
  77. classiq/qmod/qmod_constant.py +26 -2
  78. classiq/qmod/qmod_parameter.py +2 -1
  79. classiq/qmod/qmod_variable.py +48 -15
  80. classiq/qmod/quantum_callable.py +1 -0
  81. classiq/qmod/quantum_expandable.py +6 -7
  82. classiq/qmod/quantum_function.py +4 -0
  83. classiq/qmod/symbolic.py +2 -2
  84. {classiq-0.38.0.dist-info → classiq-0.39.0.dist-info}/METADATA +1 -1
  85. {classiq-0.38.0.dist-info → classiq-0.39.0.dist-info}/RECORD +107 -124
  86. classiq/applications/benchmarking/__init__.py +0 -9
  87. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  88. classiq/applications/numpy_utils.py +0 -37
  89. classiq/applications_model_constructors/__init__.py +0 -25
  90. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  91. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  92. classiq/builtin_functions/__init__.py +0 -43
  93. classiq/builtin_functions/amplitude_loading.py +0 -3
  94. classiq/builtin_functions/binary_ops.py +0 -1
  95. classiq/builtin_functions/exponentiation.py +0 -5
  96. classiq/builtin_functions/qpe.py +0 -4
  97. classiq/builtin_functions/qsvm.py +0 -7
  98. classiq/builtin_functions/range_types.py +0 -5
  99. classiq/builtin_functions/standard_gates.py +0 -1
  100. classiq/builtin_functions/state_preparation.py +0 -6
  101. classiq/builtin_functions/suzuki_trotter.py +0 -3
  102. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  103. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  104. classiq/model/__init__.py +0 -14
  105. classiq/model/composite_function_generator.py +0 -33
  106. classiq/model/function_handler.py +0 -462
  107. classiq/model/logic_flow.py +0 -149
  108. classiq/model/logic_flow_change_handler.py +0 -71
  109. classiq/model/model.py +0 -229
  110. classiq/quantum_functions/__init__.py +0 -17
  111. classiq/quantum_functions/annotation_parser.py +0 -205
  112. classiq/quantum_functions/decorators.py +0 -22
  113. classiq/quantum_functions/function_library.py +0 -181
  114. classiq/quantum_functions/function_parser.py +0 -74
  115. classiq/quantum_functions/quantum_function.py +0 -236
  116. /classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +0 -0
  117. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  118. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +0 -0
  119. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  120. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +0 -0
  121. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  122. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  123. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  124. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  125. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +0 -0
  126. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  127. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +0 -0
  128. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +0 -0
  129. /classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +0 -0
  130. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  131. /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
  132. /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
  133. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +0 -0
  134. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/chemistry_functions.py +0 -0
  135. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +0 -0
  136. /classiq/{quantum_register.py → interface/model/quantum_register.py} +0 -0
  137. {classiq-0.38.0.dist-info → classiq-0.39.0.dist-info}/WHEEL +0 -0
@@ -11,18 +11,22 @@ from classiq.interface.generator.functions.port_declaration import (
11
11
  )
12
12
  from classiq.interface.generator.visitor import NodeType, Visitor
13
13
  from classiq.interface.model.bind_operation import BindOperation
14
+ from classiq.interface.model.classical_if import ClassicalIf
14
15
  from classiq.interface.model.classical_parameter_declaration import (
15
16
  ClassicalParameterDeclaration,
16
17
  )
18
+ from classiq.interface.model.control import Control
17
19
  from classiq.interface.model.handle_binding import (
18
20
  HandleBinding,
19
21
  SlicedHandleBinding,
20
22
  SubscriptHandleBinding,
21
23
  )
22
24
  from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
25
+ from classiq.interface.model.invert import Invert
23
26
  from classiq.interface.model.model import Model
24
27
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
25
28
  from classiq.interface.model.port_declaration import PortDeclaration
29
+ from classiq.interface.model.power import Power
26
30
  from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
27
31
  AmplitudeLoadingOperation,
28
32
  )
@@ -37,7 +41,7 @@ from classiq.interface.model.quantum_function_declaration import (
37
41
  QuantumFunctionDeclaration,
38
42
  QuantumOperandDeclaration,
39
43
  )
40
- from classiq.interface.model.quantum_if_operation import QuantumIfOperation
44
+ from classiq.interface.model.quantum_if_operation import QuantumIf
41
45
  from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
42
46
  from classiq.interface.model.quantum_type import (
43
47
  QuantumBit,
@@ -47,11 +51,12 @@ from classiq.interface.model.quantum_type import (
47
51
  from classiq.interface.model.quantum_variable_declaration import (
48
52
  QuantumVariableDeclaration,
49
53
  )
54
+ from classiq.interface.model.repeat import Repeat
50
55
  from classiq.interface.model.statement_block import StatementBlock
51
56
  from classiq.interface.model.variable_declaration_statement import (
52
57
  VariableDeclarationStatement,
53
58
  )
54
- from classiq.interface.model.within_apply_operation import WithinApplyOperation
59
+ from classiq.interface.model.within_apply_operation import WithinApply
55
60
 
56
61
  from classiq import Bool, ClassicalList, Integer, Pauli, Real, Struct, StructDeclaration
57
62
  from classiq.qmod.native.expression_to_qmod import transform_expression
@@ -208,33 +213,57 @@ class DSLPrettyPrinter(Visitor):
208
213
  )
209
214
  return f"{self._indent}{func_call.func_name}{f'[{self.visit(func_call.function.index)}]' if isinstance(func_call.function, OperandIdentifier) else ''}{gen_time_arg_list}({quantum_args});\n"
210
215
 
211
- def visit_QuantumIfOperation(self, op: QuantumIfOperation) -> str:
216
+ def visit_Control(self, control: Control) -> str:
217
+ control_code = f"{self._indent}control ({self.visit(control.control)}) {{\n"
218
+ control_code += self._visit_body(control.body)
219
+ control_code += f"{self._indent}}}\n"
220
+ return control_code
221
+
222
+ def visit_QuantumIf(self, op: QuantumIf) -> str:
212
223
  quantum_if = f"{self._indent}quantum_if ({self.visit(op.expression)}) {{\n"
213
- operand = op.then
214
- if not isinstance(operand, QuantumLambdaFunction):
215
- raise AssertionError(
216
- "Expected quantum_if to be implemented using a lambda function"
217
- )
218
- quantum_if += self._visit_body(operand.body)
224
+ quantum_if += self._visit_body(op.then)
219
225
  quantum_if += f"{self._indent}}}\n"
220
226
  return quantum_if
221
227
 
222
- def visit_WithinApplyOperation(self, op: WithinApplyOperation) -> str:
223
- action = op.action
224
- compute = op.compute
225
- if not isinstance(action, QuantumLambdaFunction) or not isinstance(
226
- compute, QuantumLambdaFunction
227
- ):
228
- raise AssertionError(
229
- "Expected within-apply to be implemented using a lambda functions"
230
- )
228
+ def visit_ClassicalIf(self, op: ClassicalIf) -> str:
229
+ classical_if = f"{self._indent}if ({self.visit(op.condition)}) {{\n"
230
+ if not op.then:
231
+ raise AssertionError('Expected non empty "then" block')
232
+ classical_if += self._visit_body(op.then)
233
+
234
+ if op.else_:
235
+ classical_if += f"{self._indent}}} else {{\n"
236
+ classical_if += self._visit_body(op.else_)
237
+
238
+ classical_if += f"{self._indent}}}\n"
239
+ return classical_if
240
+
241
+ def visit_WithinApply(self, op: WithinApply) -> str:
231
242
  within_apply_code = f"{self._indent}within {{\n"
232
- within_apply_code += self._visit_body(compute.body)
243
+ within_apply_code += self._visit_body(op.compute)
233
244
  within_apply_code += f"{self._indent}}} apply {{\n"
234
- within_apply_code += self._visit_body(action.body)
245
+ within_apply_code += self._visit_body(op.action)
235
246
  within_apply_code += f"{self._indent}}}\n"
236
247
  return within_apply_code
237
248
 
249
+ def visit_Repeat(self, repeat: Repeat) -> str:
250
+ repeat_code = f"{self._indent}repeat ({self.visit(repeat.iter_var)}: {self.visit(repeat.count)}) {{\n"
251
+ repeat_code += self._visit_body(repeat.body)
252
+ repeat_code += f"{self._indent}}}\n"
253
+ return repeat_code
254
+
255
+ def visit_Power(self, power: Power) -> str:
256
+ power_code = f"{self._indent}power ({self.visit(power.power)}) {{\n"
257
+ power_code += self._visit_body(power.body)
258
+ power_code += f"{self._indent}}}\n"
259
+ return power_code
260
+
261
+ def visit_Invert(self, invert: Invert) -> str:
262
+ invert_code = f"{self._indent}invert {{\n"
263
+ invert_code += self._visit_body(invert.body)
264
+ invert_code += f"{self._indent}}}\n"
265
+ return invert_code
266
+
238
267
  def _visit_body(self, body: StatementBlock) -> str:
239
268
  code = ""
240
269
  self._level += 1
@@ -3,12 +3,16 @@ from typing import Any, Optional
3
3
 
4
4
  from classiq.interface.generator.constant import Constant
5
5
  from classiq.interface.generator.expressions.expression import Expression
6
- from classiq.interface.generator.functions.classical_type import QStructBase
6
+ from classiq.interface.generator.functions.classical_type import (
7
+ ClassicalArray,
8
+ ClassicalList,
9
+ QStructBase,
10
+ )
7
11
 
8
12
  from classiq.exceptions import ClassiqError
9
13
  from classiq.qmod.declaration_inferrer import python_type_to_qmod
10
14
  from classiq.qmod.model_state_container import ModelStateContainer
11
- from classiq.qmod.qmod_parameter import QParam, QParamStruct
15
+ from classiq.qmod.qmod_parameter import QParam, QParamList, QParamStruct
12
16
 
13
17
 
14
18
  class QConstant:
@@ -72,5 +76,25 @@ class QConstant:
72
76
  QConstant.CURRENT_QMODULE, self.name, py_type.__name__, name
73
77
  )
74
78
 
79
+ def __getitem__(self, item: Any) -> QParam:
80
+ self.add_to_model()
81
+
82
+ assert QConstant.CURRENT_QMODULE is not None
83
+
84
+ qmod_type = python_type_to_qmod(
85
+ self._py_type, qmodule=QConstant.CURRENT_QMODULE
86
+ )
87
+ if qmod_type is None:
88
+ raise ClassiqError("Invalid QMOD type")
89
+
90
+ if not isinstance(qmod_type, (ClassicalList, ClassicalArray)):
91
+ raise ClassiqError("Invalid subscript to non-list constant")
92
+
93
+ return QParamList(
94
+ self.name,
95
+ qmod_type,
96
+ QConstant.CURRENT_QMODULE,
97
+ )[item]
98
+
75
99
  def __str__(self) -> str:
76
100
  return self.name
@@ -60,9 +60,10 @@ class QParamList(QParam):
60
60
 
61
61
  def __len__(self) -> int:
62
62
  raise ClassiqValueError(
63
- "len(<expr>) is not supported for QMod lists - use <expr>.len() instead"
63
+ "len(<expr>) is not supported for QMod lists - use <expr>.len instead"
64
64
  )
65
65
 
66
+ @property
66
67
  def len(self) -> QParamScalar:
67
68
  return QParamScalar(f"len({self})")
68
69
 
@@ -1,8 +1,7 @@
1
1
  import abc
2
2
  import sys
3
3
  from contextlib import contextmanager
4
- from typing import _GenericAlias # type: ignore[attr-defined]
5
- from typing import (
4
+ from typing import ( # type: ignore[attr-defined]
6
5
  TYPE_CHECKING,
7
6
  Any,
8
7
  ForwardRef,
@@ -14,6 +13,7 @@ from typing import (
14
13
  Type,
15
14
  TypeVar,
16
15
  Union,
16
+ _GenericAlias,
17
17
  get_args,
18
18
  get_origin,
19
19
  overload,
@@ -25,7 +25,11 @@ from classiq.interface.generator.expressions.expression import Expression
25
25
  from classiq.interface.generator.functions.port_declaration import (
26
26
  PortDeclarationDirection,
27
27
  )
28
- from classiq.interface.model.handle_binding import HandleBinding, SlicedHandleBinding
28
+ from classiq.interface.model.handle_binding import (
29
+ HandleBinding,
30
+ SlicedHandleBinding,
31
+ SubscriptHandleBinding,
32
+ )
29
33
  from classiq.interface.model.port_declaration import PortDeclaration
30
34
  from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
31
35
  AmplitudeLoadingOperation,
@@ -50,6 +54,7 @@ from classiq.qmod.utilities import version_portable_get_args
50
54
  ILLEGAL_SLICING_STEP_MSG = "Slicing with a step of a quantum variable is not supported"
51
55
  SLICE_OUT_OF_BOUNDS_MSG = "Slice end index out of bounds"
52
56
  UNSUPPORTED_ELEMENT_TYPE = "Only QBit is supported as element type for QArray"
57
+ QARRAY_ELEMENT_NOT_SUBSCRIPTABLE = "Subscripting an element in QArray is illegal"
53
58
 
54
59
 
55
60
  def _is_input_output_typehint(type_hint: Any) -> bool:
@@ -280,34 +285,52 @@ class QArray(ArrayBase[_P], QVar):
280
285
  name: str,
281
286
  element_type: _GenericAlias = QBit,
282
287
  length: Optional[Union[int, QParam[int]]] = None,
288
+ # TODO [CAD-18620]: improve type hints
283
289
  slice_: Optional[Tuple[int, int]] = None,
290
+ index_: Optional[Union[int, QParam[int]]] = None,
284
291
  ) -> None:
285
292
  if element_type is not QBit:
286
293
  raise ClassiqValueError(UNSUPPORTED_ELEMENT_TYPE)
287
294
  self._element_type = element_type
288
295
  self._length = length
289
296
  self._slice = slice_
297
+ self._index = index_
290
298
  super().__init__(name)
291
299
 
292
300
  def get_handle_binding(self) -> HandleBinding:
293
- if self._slice is None:
294
- return HandleBinding(name=self._name)
295
- return SlicedHandleBinding(
296
- name=self._name,
297
- start=Expression(expr=str(self._slice[0])),
298
- end=Expression(expr=str(self._slice[1])),
299
- )
301
+ if self._index is not None:
302
+ return SubscriptHandleBinding(
303
+ name=self._name,
304
+ index=Expression(expr=str(self._index)),
305
+ )
306
+
307
+ if self._slice is not None:
308
+ return SlicedHandleBinding(
309
+ name=self._name,
310
+ start=Expression(expr=str(self._slice[0])),
311
+ end=Expression(expr=str(self._slice[1])),
312
+ )
313
+
314
+ return HandleBinding(name=self._name)
300
315
 
301
316
  def __getitem__(self, key: Union[slice, int, QParam]) -> "QArray":
302
- offset = self._slice[0] if self._slice is not None else 0
317
+ if self._index is not None:
318
+ raise ClassiqValueError(QARRAY_ELEMENT_NOT_SUBSCRIPTABLE)
319
+
320
+ # TODO [CAD-18620]: improve type hints
321
+ new_index: Optional[Any] = None
322
+
303
323
  if isinstance(key, slice):
304
324
  if key.step is not None:
305
325
  raise ClassiqValueError(ILLEGAL_SLICING_STEP_MSG)
306
- new_slice = (offset + key.start, offset + key.stop)
326
+ new_slice = self._get_new_slice(key.start, key.stop)
327
+
307
328
  else:
308
329
  if isinstance(key, QParam) and not isinstance(key, QParamScalar):
309
330
  raise ClassiqValueError("Non-classical parameter for slicing")
310
- new_slice = (offset + key, offset + key + 1)
331
+ new_slice = self._get_new_slice(key, key + 1)
332
+ new_index = new_slice[0]
333
+
311
334
  if (
312
335
  self._slice is not None
313
336
  and not isinstance(new_slice[1], Symbolic)
@@ -322,19 +345,29 @@ class QArray(ArrayBase[_P], QVar):
322
345
  raise ClassiqValueError(SLICE_OUT_OF_BOUNDS_MSG)
323
346
  # prevent addition to local handles, since this is used for slicing existing local handles
324
347
  with _no_current_expandable():
325
- return QArray(self._name, length=self._length, slice_=new_slice)
348
+ return QArray(
349
+ self._name, length=self._length, slice_=new_slice, index_=new_index
350
+ )
351
+
352
+ # TODO [CAD-18620]: improve type hints
353
+ def _get_new_slice(self, start: Any, end: Any) -> Tuple[Any, Any]:
354
+ if self._slice is not None:
355
+ return (self._slice[0] + start, self._slice[0] + end)
356
+ return (start, end)
326
357
 
327
358
  def __len__(self) -> int:
328
359
  raise ClassiqValueError(
329
- "len(<var>) is not supported for quantum variables - use <var>.len() instead"
360
+ "len(<var>) is not supported for quantum variables - use <var>.len instead"
330
361
  )
331
362
 
332
363
  if TYPE_CHECKING:
333
364
 
365
+ @property
334
366
  def len(self) -> int: ...
335
367
 
336
368
  else:
337
369
 
370
+ @property
338
371
  def len(self) -> QParamScalar:
339
372
  if self._length is not None:
340
373
  return QParamScalar(f"{self._length}")
@@ -68,6 +68,7 @@ class QCallable(Generic[P], ABC):
68
68
  class QCallableList(QCallable, Generic[P], ABC):
69
69
  if TYPE_CHECKING:
70
70
 
71
+ @property
71
72
  def len(self) -> int: ...
72
73
 
73
74
  def __getitem__(self, key: Union[slice, int, QParam]) -> "QTerminalCallable":
@@ -32,10 +32,7 @@ from classiq.interface.model.quantum_function_declaration import (
32
32
  QuantumFunctionDeclaration,
33
33
  QuantumOperandDeclaration,
34
34
  )
35
- from classiq.interface.model.quantum_lambda_function import (
36
- QuantumLambdaFunction,
37
- QuantumOperand,
38
- )
35
+ from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
39
36
  from classiq.interface.model.quantum_statement import QuantumStatement
40
37
  from classiq.interface.model.quantum_type import QuantumType
41
38
  from classiq.interface.model.variable_declaration_statement import (
@@ -161,15 +158,17 @@ class QTerminalCallable(QCallable):
161
158
 
162
159
  def __len__(self) -> int:
163
160
  raise ClassiqValueError(
164
- "len(<func>) is not supported for quantum callables - use <func>.len() instead (Only if it is an operand list)"
161
+ "len(<func>) is not supported for quantum callables - use <func>.len instead (Only if it is an operand list)"
165
162
  )
166
163
 
167
164
  if TYPE_CHECKING:
168
165
 
166
+ @property
169
167
  def len(self) -> int: ...
170
168
 
171
169
  else:
172
170
 
171
+ @property
173
172
  def len(self) -> QParamScalar:
174
173
  if not self.is_list:
175
174
  raise ClassiqValueError("Cannot get length of a non-list operand")
@@ -193,8 +192,8 @@ class QTerminalCallable(QCallable):
193
192
 
194
193
  @overload
195
194
  def prepare_arg(
196
- arg_decl: PositionalArg, val: Union[QCallable, Callable[[Any], None]]
197
- ) -> QuantumOperand: ...
195
+ arg_decl: PositionalArg, val: Union[QCallable, Callable[..., None]]
196
+ ) -> QuantumLambdaFunction: ...
198
197
 
199
198
 
200
199
  @overload
@@ -34,6 +34,10 @@ def create_model(
34
34
  preferences: Optional[Preferences] = None,
35
35
  classical_execution_function: Optional[CFunc] = None,
36
36
  ) -> SerializedModel:
37
+ if entry_point.func_decl.name != "main":
38
+ raise ClassiqError(
39
+ f"The entry point function must be named 'main', got '{entry_point.func_decl.name}'"
40
+ )
37
41
  return entry_point.create_model(
38
42
  constraints, execution_preferences, preferences, classical_execution_function
39
43
  ).get_model()
classiq/qmod/symbolic.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import sys
2
- from typing import Optional, Tuple, Type, get_args, get_origin, overload
2
+ from typing import List, Optional, Tuple, Type, get_args, get_origin, overload
3
3
 
4
4
  from classiq.exceptions import ClassiqValueError
5
5
  from classiq.qmod import model_state_container
@@ -346,5 +346,5 @@ __all__ = [
346
346
  ]
347
347
 
348
348
 
349
- def __dir__():
349
+ def __dir__() -> List[str]:
350
350
  return __all__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: classiq
3
- Version: 0.38.0
3
+ Version: 0.39.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  Home-page: https://classiq.io
6
6
  License: Proprietary