classiq 0.90.0__py3-none-any.whl → 0.91.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.

Potentially problematic release.


This version of classiq might be problematic. Click here for more details.

Files changed (41) hide show
  1. classiq/evaluators/expression_evaluator.py +24 -124
  2. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +10 -3
  3. classiq/evaluators/qmod_node_evaluators/utils.py +0 -8
  4. classiq/interface/_version.py +1 -1
  5. classiq/interface/executor/result.py +22 -3
  6. classiq/interface/generator/expressions/expression_types.py +2 -0
  7. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +3 -8
  8. classiq/interface/generator/functions/classical_type.py +2 -5
  9. classiq/interface/generator/functions/type_name.py +0 -12
  10. classiq/interface/model/quantum_type.py +0 -39
  11. classiq/model_expansions/capturing/captured_vars.py +3 -0
  12. classiq/model_expansions/function_builder.py +18 -2
  13. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +0 -10
  14. classiq/model_expansions/interpreters/generative_interpreter.py +63 -18
  15. classiq/model_expansions/quantum_operations/emitter.py +13 -3
  16. classiq/model_expansions/quantum_operations/expression_evaluator.py +49 -5
  17. classiq/model_expansions/scope.py +5 -14
  18. classiq/model_expansions/utils/handles_collector.py +7 -0
  19. classiq/qmod/builtins/operations.py +7 -3
  20. classiq/qmod/qmod_variable.py +3 -4
  21. classiq/qmod/semantics/error_manager.py +34 -15
  22. classiq/qmod/symbolic.py +15 -4
  23. classiq/qmod/utilities.py +4 -1
  24. classiq/synthesis.py +1 -2
  25. {classiq-0.90.0.dist-info → classiq-0.91.0.dist-info}/METADATA +1 -1
  26. {classiq-0.90.0.dist-info → classiq-0.91.0.dist-info}/RECORD +27 -41
  27. classiq/interface/generator/expressions/handle_identifier.py +0 -6
  28. classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +0 -41
  29. classiq/interface/generator/expressions/proxies/quantum/__init__.py +0 -0
  30. classiq/interface/generator/expressions/proxies/quantum/qmod_qarray_proxy.py +0 -80
  31. classiq/interface/generator/expressions/proxies/quantum/qmod_qscalar_proxy.py +0 -77
  32. classiq/interface/generator/expressions/proxies/quantum/qmod_qstruct_proxy.py +0 -38
  33. classiq/interface/generator/expressions/proxies/quantum/qmod_sized_proxy.py +0 -39
  34. classiq/interface/generator/expressions/type_proxy.py +0 -10
  35. classiq/model_expansions/atomic_expression_functions_defs.py +0 -395
  36. classiq/model_expansions/model_tables.py +0 -18
  37. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  38. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +0 -181
  39. classiq/model_expansions/sympy_conversion/sympy_to_python.py +0 -136
  40. classiq/model_expansions/utils/sympy_utils.py +0 -24
  41. {classiq-0.90.0.dist-info → classiq-0.91.0.dist-info}/WHEEL +0 -0
@@ -11,6 +11,7 @@ from classiq.interface.generator.functions.builtins.internal_operators import (
11
11
  CLASSICAL_IF_OPERATOR_NAME,
12
12
  CONTROL_OPERATOR_NAME,
13
13
  INVERT_OPERATOR_NAME,
14
+ POWER_OPERATOR_NAME,
14
15
  REPEAT_OPERATOR_NAME,
15
16
  WITHIN_APPLY_NAME,
16
17
  )
@@ -108,6 +109,7 @@ class GenerativeInterpreter(BaseInterpreter):
108
109
  self.infer_symbolic_parameters(
109
110
  model.functions, [gen_func.func_decl for gen_func in generative_functions]
110
111
  )
112
+ self._symbolic_parameters_switch = self.allow_symbolic_parameters()
111
113
 
112
114
  def infer_symbolic_parameters(
113
115
  self,
@@ -118,6 +120,9 @@ class GenerativeInterpreter(BaseInterpreter):
118
120
  ) -> None:
119
121
  pass
120
122
 
123
+ def allow_symbolic_parameters(self) -> bool:
124
+ return True
125
+
121
126
  def evaluate_lambda(self, function: QuantumLambdaFunction) -> Evaluated:
122
127
  func_decl = NamedParamsQuantumFunctionDeclaration(
123
128
  name=self._counted_name_allocator.allocate(
@@ -164,18 +169,28 @@ class GenerativeInterpreter(BaseInterpreter):
164
169
  QuantumFunctionCallEmitter(self).emit(call)
165
170
 
166
171
  @emit.register
167
- def _emit_allocate(self, allocate: Allocate) -> None:
168
- return self.emit_allocate(allocate)
169
-
170
172
  def emit_allocate(self, allocate: Allocate) -> None:
171
- AllocateEmitter(self).emit(allocate)
173
+ CompositeEmitter[Allocate](
174
+ self,
175
+ [
176
+ ExpressionEvaluator(
177
+ self,
178
+ "size",
179
+ readable_expression_name="allocation size",
180
+ allow_link_time_vars=self._symbolic_parameters_switch,
181
+ allow_runtime_vars=self._symbolic_parameters_switch,
182
+ ),
183
+ AllocateEmitter(
184
+ self, allow_symbolic_attrs=self._symbolic_parameters_switch
185
+ ),
186
+ ],
187
+ ).emit(allocate)
172
188
 
173
189
  @emit.register
174
- def _emit_bind(self, bind: BindOperation) -> None:
175
- self.emit_bind(bind)
176
-
177
190
  def emit_bind(self, bind: BindOperation) -> None:
178
- BindEmitter(self).emit(bind)
191
+ BindEmitter(self, allow_symbolic_size=self._symbolic_parameters_switch).emit(
192
+ bind
193
+ )
179
194
 
180
195
  @emit.register
181
196
  def emit_amplitude_loading_operation(self, op: AmplitudeLoadingOperation) -> None:
@@ -184,7 +199,12 @@ class GenerativeInterpreter(BaseInterpreter):
184
199
  [
185
200
  HandleEvaluator(self, "result_var"),
186
201
  ExpressionEvaluator(
187
- self, "expression", simplify=True, treat_qnum_as_float=True
202
+ self,
203
+ "expression",
204
+ readable_expression_name="amplitude-encoding expression",
205
+ simplify=True,
206
+ treat_qnum_as_float=True,
207
+ allow_runtime_vars=self._symbolic_parameters_switch,
188
208
  ),
189
209
  AssignmentResultProcessor(self),
190
210
  ],
@@ -223,14 +243,16 @@ class GenerativeInterpreter(BaseInterpreter):
223
243
  VariableDeclarationStatementEmitter(self).emit(variable_declaration)
224
244
 
225
245
  @emit.register
226
- def _emit_classical_if(self, classical_if: ClassicalIf) -> None:
227
- self.emit_classical_if(classical_if)
228
-
229
246
  def emit_classical_if(self, classical_if: ClassicalIf) -> None:
230
247
  CompositeEmitter[ClassicalIf](
231
248
  self,
232
249
  [
233
- ExpressionEvaluator(self, "condition"),
250
+ ExpressionEvaluator(
251
+ self,
252
+ "condition",
253
+ readable_expression_name="classical-if condition",
254
+ allow_link_time_vars=self._symbolic_parameters_switch,
255
+ ),
234
256
  IfElimination(self),
235
257
  BlockEvaluator(
236
258
  self,
@@ -278,7 +300,14 @@ class GenerativeInterpreter(BaseInterpreter):
278
300
  CompositeEmitter[Control](
279
301
  self,
280
302
  [
281
- ExpressionEvaluator(self, "expression", simplify=True),
303
+ ExpressionEvaluator(
304
+ self,
305
+ "expression",
306
+ simplify=True,
307
+ readable_expression_name="control expression",
308
+ allow_link_time_vars=self._symbolic_parameters_switch,
309
+ allow_runtime_vars=self._symbolic_parameters_switch,
310
+ ),
282
311
  BlockEvaluator(
283
312
  self,
284
313
  CONTROL_OPERATOR_NAME,
@@ -293,8 +322,13 @@ class GenerativeInterpreter(BaseInterpreter):
293
322
  CompositeEmitter[Power](
294
323
  self,
295
324
  [
296
- ExpressionEvaluator(self, "power"),
297
- BlockEvaluator(self, CONTROL_OPERATOR_NAME, "body"),
325
+ ExpressionEvaluator(
326
+ self,
327
+ "power",
328
+ readable_expression_name="power exponent",
329
+ allow_runtime_vars=self._symbolic_parameters_switch,
330
+ ),
331
+ BlockEvaluator(self, POWER_OPERATOR_NAME, "body"),
298
332
  ],
299
333
  ).emit(power)
300
334
 
@@ -303,8 +337,19 @@ class GenerativeInterpreter(BaseInterpreter):
303
337
  CompositeEmitter[PhaseOperation](
304
338
  self,
305
339
  [
306
- ExpressionEvaluator(self, "expression", simplify=True),
307
- ExpressionEvaluator(self, "theta"),
340
+ ExpressionEvaluator(
341
+ self,
342
+ "expression",
343
+ readable_expression_name="phase expression",
344
+ simplify=True,
345
+ allow_runtime_vars=self._symbolic_parameters_switch,
346
+ ),
347
+ ExpressionEvaluator(
348
+ self,
349
+ "theta",
350
+ readable_expression_name="phase theta expression",
351
+ allow_runtime_vars=self._symbolic_parameters_switch,
352
+ ),
308
353
  ],
309
354
  ).emit(phase)
310
355
 
@@ -45,7 +45,7 @@ from classiq.model_expansions.function_builder import (
45
45
  OperationBuilder,
46
46
  OperationContext,
47
47
  )
48
- from classiq.model_expansions.scope import QuantumSymbol, Scope
48
+ from classiq.model_expansions.scope import ClassicalSymbol, QuantumSymbol, Scope
49
49
  from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
50
50
  from classiq.qmod.quantum_function import GenerativeQFunc
51
51
 
@@ -240,10 +240,20 @@ class Emitter(Generic[QuantumStatementT], ABC):
240
240
  dict.fromkeys(var.name for var in expr_val.get_classical_vars().values())
241
241
  )
242
242
  return [
243
- (var, get_proxy_type(proxy))
243
+ (
244
+ var,
245
+ (
246
+ get_proxy_type(proxy)
247
+ if isinstance(proxy, ClassicalProxy)
248
+ else proxy.classical_type
249
+ ),
250
+ )
244
251
  for var in classical_vars
245
252
  if var in self._current_scope
246
- and isinstance(proxy := self._current_scope[var].value, ClassicalProxy)
253
+ and isinstance(
254
+ proxy := self._current_scope[var].value,
255
+ (ClassicalProxy, ClassicalSymbol),
256
+ )
247
257
  ]
248
258
 
249
259
  def _get_quantum_type_attributes_in_expression(
@@ -1,12 +1,18 @@
1
- from typing import TYPE_CHECKING
1
+ from typing import TYPE_CHECKING, Optional
2
2
 
3
+ from classiq.interface.exceptions import (
4
+ ClassiqExpansionError,
5
+ ClassiqInternalExpansionError,
6
+ )
3
7
  from classiq.interface.generator.expressions.expression import Expression
4
8
  from classiq.interface.generator.functions.port_declaration import (
5
9
  PortDeclarationDirection,
6
10
  )
11
+ from classiq.interface.helpers.text_utils import readable_list, s
7
12
  from classiq.interface.model.quantum_statement import QuantumOperation
8
13
 
9
14
  from classiq.model_expansions.quantum_operations.emitter import Emitter
15
+ from classiq.model_expansions.scope import ClassicalSymbol
10
16
 
11
17
  if TYPE_CHECKING:
12
18
  from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
@@ -18,13 +24,23 @@ class ExpressionEvaluator(Emitter[QuantumOperation]):
18
24
  interpreter: "BaseInterpreter",
19
25
  expression_name: str,
20
26
  *,
27
+ readable_expression_name: Optional[str] = None,
21
28
  simplify: bool = False,
22
29
  treat_qnum_as_float: bool = False,
30
+ allow_link_time_vars: bool = True,
31
+ allow_runtime_vars: bool = True,
23
32
  ) -> None:
24
33
  super().__init__(interpreter)
25
34
  self._expression_name = expression_name
26
35
  self._simplify = simplify
27
36
  self._treat_qnum_as_float = treat_qnum_as_float
37
+ self._allow_link_time_vars = allow_link_time_vars
38
+ self._allow_runtime_vars = allow_runtime_vars
39
+ if (
40
+ not allow_link_time_vars or not allow_runtime_vars
41
+ ) and readable_expression_name is None:
42
+ raise ClassiqInternalExpansionError
43
+ self._readable_expression_name = readable_expression_name
28
44
 
29
45
  def emit(self, op: QuantumOperation, /) -> bool:
30
46
  expression = getattr(op, self._expression_name)
@@ -37,13 +53,41 @@ class ExpressionEvaluator(Emitter[QuantumOperation]):
37
53
  )
38
54
  for symbol in self._get_symbols_in_expression(evaluated_expression):
39
55
  self._capture_handle(symbol.handle, PortDeclarationDirection.Inout)
40
- for var_name, var_type in self._get_classical_vars_in_expression(
41
- evaluated_expression
42
- ):
43
- self._capture_classical_var(var_name, var_type)
56
+ self._process_classical_parameters(evaluated_expression)
44
57
  op = op.model_copy(
45
58
  update={self._expression_name: evaluated_expression, "back_ref": op.uuid}
46
59
  )
47
60
  self._interpreter.add_to_debug_info(op)
48
61
  self._interpreter.emit(op)
49
62
  return True
63
+
64
+ def _process_classical_parameters(self, evaluated_expression: Expression) -> None:
65
+ link_time_vars: list[str] = []
66
+ runtime_vars: list[str] = []
67
+ for var_name, var_type in self._get_classical_vars_in_expression(
68
+ evaluated_expression
69
+ ):
70
+ if isinstance(self._current_scope[var_name].value, ClassicalSymbol):
71
+ runtime_vars.append(var_name)
72
+ else:
73
+ link_time_vars.append(var_name)
74
+ self._capture_classical_var(var_name, var_type)
75
+ if not self._allow_link_time_vars and len(link_time_vars) > 0:
76
+ link_time_message = f"link-time variable{s(link_time_vars)} {readable_list(link_time_vars, quote=True)}"
77
+ else:
78
+ link_time_message = None
79
+ if not self._allow_runtime_vars and len(runtime_vars) > 0:
80
+ runtime_message = f"runtime variable{s(runtime_vars)} {readable_list(runtime_vars, quote=True)}"
81
+ else:
82
+ runtime_message = None
83
+ if link_time_message is None:
84
+ error_message = runtime_message
85
+ elif runtime_message is None:
86
+ error_message = link_time_message
87
+ else:
88
+ error_message = f"{link_time_message} and {runtime_message}"
89
+ if error_message is not None:
90
+ raise ClassiqExpansionError(
91
+ f"The {self._readable_expression_name} cannot receive "
92
+ f"{error_message}"
93
+ )
@@ -3,7 +3,7 @@ from collections import UserDict
3
3
  from collections.abc import Iterator
4
4
  from dataclasses import dataclass
5
5
  from functools import singledispatch
6
- from typing import TYPE_CHECKING, Any, NoReturn, Optional, TypeVar, Union
6
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
7
7
 
8
8
  import sympy
9
9
 
@@ -20,7 +20,6 @@ from classiq.interface.generator.expressions.proxies.classical.qmod_struct_insta
20
20
  )
21
21
  from classiq.interface.generator.functions.classical_type import ClassicalType
22
22
  from classiq.interface.generator.functions.type_name import TypeName
23
- from classiq.interface.helpers.text_utils import readable_list, s
24
23
  from classiq.interface.model.handle_binding import (
25
24
  FieldHandleBinding,
26
25
  GeneralHandle,
@@ -235,29 +234,21 @@ def _evaluated_to_str_struct_literal(value: QmodStructInstance) -> str:
235
234
  return f"struct_literal({value.struct_declaration.name}, {', '.join(f'{k}={evaluated_to_str(v)}' for k, v in value.fields.items())})"
236
235
 
237
236
 
238
- def _raise_type_error(val: Any, t: type, location_hint: Optional[str]) -> NoReturn:
239
- if isinstance(val, QmodAnnotatedExpression) and len(val.get_classical_vars()) > 0:
240
- symbolic_vars = sorted(map(str, val.get_classical_vars().values()))
241
- suffix = f" {location_hint}" if location_hint is not None else ""
242
- raise ClassiqExpansionError(
243
- f"Cannot use execution parameter{s(symbolic_vars)} {readable_list(symbolic_vars, quote=True)} in a compile-time context{suffix}"
244
- )
245
- raise ClassiqExpansionError(f"Invalid access to expression {val!r} as {t}")
246
-
247
-
248
237
  @dataclass(frozen=True)
249
238
  class Evaluated: # FIXME: Merge with EvaluatedExpression if possible
250
239
  value: Any
251
240
  defining_function: Optional["FunctionClosure"] = None
252
241
 
253
- def as_type(self, t: type[T], location_hint: Optional[str] = None) -> T:
242
+ def as_type(self, t: type[T]) -> T:
254
243
  value = self.value
255
244
  if isinstance(value, sympy.Basic):
256
245
  value = get_sympy_val(value)
257
246
  if t is int and isinstance(value, float):
258
247
  value = int(value)
259
248
  if not isinstance(value, t):
260
- _raise_type_error(self.value, t, location_hint)
249
+ raise ClassiqExpansionError(
250
+ f"Invalid access to expression {self.value!r} as {t}"
251
+ )
261
252
 
262
253
  return value
263
254
 
@@ -7,6 +7,7 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
7
7
  QuantumExpressionOperation,
8
8
  )
9
9
 
10
+ from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
10
11
  from classiq.model_expansions.visitors.variable_references import VarRefCollector
11
12
 
12
13
 
@@ -18,6 +19,12 @@ class _HandlesCollector(Visitor):
18
19
  self.handles.append(handle)
19
20
 
20
21
  def visit_Expression(self, expression: Expression) -> None:
22
+ if expression.is_evaluated():
23
+ expr_val = expression.value.value
24
+ if isinstance(expr_val, QmodAnnotatedExpression):
25
+ self.handles.extend(expr_val.get_classical_vars().values())
26
+ self.handles.extend(expr_val.get_quantum_vars().values())
27
+ return
21
28
  vrc = VarRefCollector(ignore_duplicated_handles=True, unevaluated=True)
22
29
  vrc.visit(ast.parse(expression.expr))
23
30
  self.handles.extend(vrc.var_handles)
@@ -518,19 +518,23 @@ def invert(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
518
518
 
519
519
 
520
520
  @overload
521
- def phase(phase_expr: Union[SymbolicExpr, float], theta: float = 1.0) -> None:
521
+ def phase(
522
+ phase_expr: Union[SymbolicExpr, float], theta: Union[SymbolicExpr, float] = 1.0
523
+ ) -> None:
522
524
  pass
523
525
 
524
526
 
525
527
  @overload
526
- def phase(*, expr: Union[SymbolicExpr, float], theta: float = 1.0) -> None:
528
+ def phase(
529
+ *, expr: Union[SymbolicExpr, float], theta: Union[SymbolicExpr, float] = 1.0
530
+ ) -> None:
527
531
  pass
528
532
 
529
533
 
530
534
  @suppress_return_value
531
535
  def phase(
532
536
  phase_expr: Union[SymbolicExpr, float, None] = None,
533
- theta: float = 1.0,
537
+ theta: Union[SymbolicExpr, float] = 1.0,
534
538
  expr: Any = None,
535
539
  ) -> None:
536
540
  """
@@ -31,10 +31,6 @@ from classiq.interface.exceptions import (
31
31
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
32
32
  from classiq.interface.generator.expressions.expression import Expression
33
33
  from classiq.interface.generator.expressions.non_symbolic_expr import NonSymbolicExpr
34
- from classiq.interface.generator.expressions.proxies.quantum.qmod_qarray_proxy import (
35
- ILLEGAL_SLICE_MSG,
36
- ILLEGAL_SLICING_STEP_MSG,
37
- )
38
34
  from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
39
35
  from classiq.interface.generator.functions.port_declaration import (
40
36
  PortDeclarationDirection,
@@ -83,6 +79,9 @@ from classiq.qmod.utilities import (
83
79
  version_portable_get_args,
84
80
  )
85
81
 
82
+ ILLEGAL_SLICING_STEP_MSG = "Slicing with a step of a quantum variable is not supported"
83
+ ILLEGAL_SLICE_MSG = "Quantum array slice must be of the form [<int-value>:<int-value>]."
84
+
86
85
 
87
86
  @contextmanager
88
87
  def _no_current_expandable() -> Iterator[None]:
@@ -18,6 +18,7 @@ class ErrorManager:
18
18
  return
19
19
  self._instantiated = True
20
20
  self._errors: list[SourceReferencedError] = []
21
+ self._warnings: list[SourceReferencedError] = []
21
22
  self._current_nodes_stack: list[ASTNode] = []
22
23
  self._call_stack: list[str] = []
23
24
  self._ignore_errors: bool = False
@@ -41,38 +42,56 @@ class ErrorManager:
41
42
  def annotated_errors(self) -> list[str]:
42
43
  return [str(error) for error in self._errors]
43
44
 
45
+ @property
46
+ def annotated_warnings(self) -> list[str]:
47
+ return [str(error) for error in self._warnings]
48
+
44
49
  def add_error(
45
50
  self,
46
51
  error: str,
47
52
  *,
48
53
  source_ref: Optional[SourceReference] = None,
49
54
  function: Optional[str] = None,
55
+ warning: bool = False,
50
56
  ) -> None:
51
- if not self._ignore_errors:
52
- self._errors.append(
53
- SourceReferencedError(
54
- error=error.replace(CLASSIQ_SLACK_COMMUNITY_LINK, ""),
55
- source_ref=(
56
- source_ref
57
- if source_ref is not None
58
- else self._current_source_ref
59
- ),
60
- function=(
61
- function if function is not None else self.current_function
62
- ),
63
- )
64
- )
57
+ if self._ignore_errors:
58
+ return
59
+
60
+ source_ref_error = SourceReferencedError(
61
+ error=error.replace(CLASSIQ_SLACK_COMMUNITY_LINK, ""),
62
+ source_ref=(
63
+ source_ref if source_ref is not None else self._current_source_ref
64
+ ),
65
+ function=(function if function is not None else self.current_function),
66
+ )
67
+ if warning:
68
+ self._warnings.append(source_ref_error)
69
+ else:
70
+ self._errors.append(source_ref_error)
65
71
 
66
72
  def get_errors(self) -> list[SourceReferencedError]:
67
73
  return self._errors
68
74
 
75
+ def get_warnings(self) -> list[SourceReferencedError]:
76
+ return self._warnings
77
+
69
78
  def clear(self) -> None:
79
+ self.clear_errors()
80
+ self.clear_warnings()
81
+
82
+ def clear_errors(self) -> None:
70
83
  self._current_nodes_stack = []
71
84
  self._errors = []
72
85
 
86
+ def clear_warnings(self) -> None:
87
+ self._warnings = []
88
+
73
89
  def has_errors(self) -> bool:
74
90
  return len(self._errors) > 0
75
91
 
92
+ def has_warnings(self) -> bool:
93
+ return len(self._warnings) > 0
94
+
76
95
  def report_errors(
77
96
  self, error_type: type[Exception], mask: Optional[list[int]] = None
78
97
  ) -> None:
@@ -82,7 +101,7 @@ class ErrorManager:
82
101
  if mask is None
83
102
  else [self.annotated_errors[idx] for idx in mask]
84
103
  )
85
- self.clear()
104
+ self.clear_errors()
86
105
  raise error_type("\n\t" + "\n\t".join(errors))
87
106
 
88
107
  @property
classiq/qmod/symbolic.py CHANGED
@@ -11,9 +11,6 @@ from typing import (
11
11
  import numpy as np
12
12
 
13
13
  from classiq.interface.exceptions import ClassiqValueError
14
- from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
15
- subscript_to_str,
16
- )
17
14
 
18
15
  from classiq.qmod import model_state_container
19
16
  from classiq.qmod.declaration_inferrer import python_type_to_qmod
@@ -309,12 +306,26 @@ def sum(arr: SymbolicTypes) -> CParamScalar:
309
306
  return symbolic_function(arr)
310
307
 
311
308
 
309
+ def _subscript_to_str(index: Any) -> str:
310
+ if not isinstance(index, slice):
311
+ return str(index)
312
+ expr = ""
313
+ if index.start is not None:
314
+ expr += str(index.start)
315
+ expr += ":"
316
+ if index.stop is not None:
317
+ expr += str(index.stop)
318
+ if index.step is not None:
319
+ expr += f":{index.step}"
320
+ return expr
321
+
322
+
312
323
  def subscript(
313
324
  array: Union[list, CArray[CReal], np.ndarray],
314
325
  index: Any,
315
326
  ) -> CParamScalar:
316
327
  return CParamScalar(
317
- expr=f"{qmod_val_to_expr_str(_unwrap_numpy(array))}[{subscript_to_str(index)}]"
328
+ expr=f"{qmod_val_to_expr_str(_unwrap_numpy(array))}[{_subscript_to_str(index)}]"
318
329
  )
319
330
 
320
331
 
classiq/qmod/utilities.py CHANGED
@@ -29,6 +29,7 @@ from classiq.interface.generator.expressions.proxies.classical.qmod_struct_insta
29
29
  from classiq.interface.source_reference import SourceReference
30
30
 
31
31
  if TYPE_CHECKING:
32
+ from classiq.qmod.cparam import CParam
32
33
  from classiq.qmod.qmod_variable import QVar
33
34
 
34
35
 
@@ -162,7 +163,9 @@ def suppress_return_value(func: Callable[Params, None]) -> Callable[Params, None
162
163
  return func
163
164
 
164
165
 
165
- Statements = Union[None, list[Union[None, "QVar"]], tuple[Union[None, "QVar"], ...]]
166
+ Statements = Union[
167
+ None, list[Union[None, "QVar", "CParam"]], tuple[Union[None, "QVar", "CParam"], ...]
168
+ ]
166
169
 
167
170
 
168
171
  def _eval_qnum(val: int, size: int, is_signed: bool, fraction_digits: int) -> float:
classiq/synthesis.py CHANGED
@@ -57,8 +57,7 @@ async def synthesize_async(
57
57
  ) -> QuantumProgram:
58
58
  model = Model.model_validate_json(serialized_model)
59
59
  quantum_program = await ApiWrapper.call_generation_task(model)
60
- if quantum_program.should_warn:
61
- quantum_program.raise_warnings()
60
+ quantum_program.raise_warnings()
62
61
  return quantum_program
63
62
 
64
63
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: classiq
3
- Version: 0.90.0
3
+ Version: 0.91.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  License: Proprietary
6
6
  Keywords: quantum computing,quantum circuits,quantum algorithms,QAD,QDL