classiq 0.88.0__py3-none-any.whl → 0.90.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 (103) hide show
  1. classiq/__init__.py +1 -0
  2. classiq/_internals/api_wrapper.py +16 -32
  3. classiq/_internals/config.py +1 -1
  4. classiq/analyzer/show_interactive_hack.py +26 -1
  5. classiq/applications/chemistry/chemistry_model_constructor.py +14 -2
  6. classiq/applications/combinatorial_helpers/pyomo_utils.py +9 -6
  7. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -2
  8. classiq/applications/combinatorial_optimization/combinatorial_problem.py +16 -8
  9. classiq/evaluators/classical_expression.py +63 -41
  10. classiq/evaluators/control.py +31 -52
  11. classiq/evaluators/expression_evaluator.py +8 -4
  12. classiq/evaluators/parameter_types.py +200 -104
  13. classiq/evaluators/qmod_annotated_expression.py +10 -9
  14. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +2 -2
  15. classiq/evaluators/qmod_expression_visitors/qmod_expression_renamer.py +1 -1
  16. classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +66 -5
  17. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +12 -37
  18. classiq/evaluators/qmod_node_evaluators/constant_evaluation.py +8 -17
  19. classiq/evaluators/qmod_node_evaluators/measurement_evaluation.py +1 -1
  20. classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +7 -1
  21. classiq/evaluators/qmod_node_evaluators/name_evaluation.py +0 -1
  22. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +9 -1
  23. classiq/evaluators/qmod_node_evaluators/utils.py +33 -0
  24. classiq/evaluators/qmod_type_inference/classical_type_inference.py +4 -7
  25. classiq/interface/_version.py +1 -1
  26. classiq/interface/analyzer/analysis_params.py +2 -26
  27. classiq/interface/analyzer/result.py +4 -0
  28. classiq/interface/backend/backend_preferences.py +1 -1
  29. classiq/interface/chemistry/ground_state_problem.py +16 -2
  30. classiq/interface/executor/optimizer_preferences.py +0 -112
  31. classiq/interface/generator/application_apis/chemistry_declarations.py +3 -1
  32. classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -7
  33. classiq/interface/generator/arith/register_user_input.py +1 -1
  34. classiq/interface/generator/expressions/evaluated_expression.py +3 -13
  35. classiq/interface/generator/expressions/expression_types.py +8 -22
  36. classiq/interface/generator/expressions/proxies/classical/classical_proxy.py +2 -2
  37. classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +1 -2
  38. classiq/interface/generator/functions/classical_type.py +24 -3
  39. classiq/interface/generator/functions/concrete_types.py +1 -1
  40. classiq/interface/generator/functions/function_declaration.py +0 -4
  41. classiq/interface/generator/functions/type_name.py +25 -0
  42. classiq/interface/generator/generated_circuit_data.py +4 -0
  43. classiq/interface/generator/hardware_efficient_ansatz.py +1 -1
  44. classiq/interface/generator/preferences/qasm_to_qmod_params.py +14 -0
  45. classiq/interface/generator/quantum_function_call.py +3 -3
  46. classiq/interface/generator/user_defined_function_params.py +0 -3
  47. classiq/interface/helpers/model_normalizer.py +0 -6
  48. classiq/interface/ide/ide_data.py +1 -1
  49. classiq/interface/ide/visual_model.py +3 -2
  50. classiq/interface/model/block.py +5 -1
  51. classiq/interface/model/handle_binding.py +2 -2
  52. classiq/interface/model/port_declaration.py +2 -1
  53. classiq/interface/model/quantum_expressions/arithmetic_operation.py +16 -12
  54. classiq/interface/model/quantum_lambda_function.py +1 -1
  55. classiq/interface/model/quantum_statement.py +2 -4
  56. classiq/interface/model/quantum_type.py +47 -4
  57. classiq/interface/server/routes.py +2 -3
  58. classiq/model_expansions/atomic_expression_functions_defs.py +4 -22
  59. classiq/model_expansions/capturing/captured_vars.py +7 -3
  60. classiq/model_expansions/closure.py +8 -0
  61. classiq/model_expansions/interpreters/base_interpreter.py +84 -22
  62. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +1 -1
  63. classiq/model_expansions/interpreters/generative_interpreter.py +7 -5
  64. classiq/model_expansions/quantum_operations/allocate.py +92 -21
  65. classiq/model_expansions/quantum_operations/assignment_result_processor.py +28 -27
  66. classiq/model_expansions/quantum_operations/call_emitter.py +32 -26
  67. classiq/model_expansions/quantum_operations/classical_var_emitter.py +6 -2
  68. classiq/model_expansions/quantum_operations/emitter.py +39 -69
  69. classiq/model_expansions/quantum_operations/expression_evaluator.py +13 -2
  70. classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -5
  71. classiq/model_expansions/quantum_operations/variable_decleration.py +16 -11
  72. classiq/model_expansions/scope.py +36 -29
  73. classiq/model_expansions/scope_initialization.py +3 -6
  74. classiq/model_expansions/sympy_conversion/sympy_to_python.py +6 -2
  75. classiq/model_expansions/transformers/model_renamer.py +35 -64
  76. classiq/model_expansions/transformers/type_modifier_inference.py +6 -6
  77. classiq/model_expansions/visitors/boolean_expression_transformers.py +7 -31
  78. classiq/model_expansions/visitors/symbolic_param_inference.py +9 -3
  79. classiq/open_library/functions/__init__.py +2 -0
  80. classiq/open_library/functions/state_preparation.py +140 -5
  81. classiq/qmod/builtins/functions/allocation.py +8 -8
  82. classiq/qmod/builtins/functions/arithmetic.py +1 -1
  83. classiq/qmod/builtins/functions/chemistry.py +64 -0
  84. classiq/qmod/builtins/functions/exponentiation.py +7 -13
  85. classiq/qmod/builtins/functions/qsvm.py +1 -1
  86. classiq/qmod/builtins/operations.py +38 -10
  87. classiq/qmod/generative.py +2 -4
  88. classiq/qmod/native/pretty_printer.py +1 -1
  89. classiq/qmod/pretty_print/pretty_printer.py +1 -1
  90. classiq/qmod/qmod_constant.py +1 -1
  91. classiq/qmod/qmod_parameter.py +2 -2
  92. classiq/qmod/qmod_variable.py +62 -16
  93. classiq/qmod/quantum_expandable.py +1 -1
  94. classiq/synthesis.py +37 -1
  95. classiq/visualization.py +1 -1
  96. {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/METADATA +2 -2
  97. {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/RECORD +98 -102
  98. classiq/evaluators/arg_type_match.py +0 -168
  99. classiq/evaluators/classical_type_inference.py +0 -121
  100. classiq/interface/combinatorial_optimization/optimization_problem.py +0 -17
  101. classiq/interface/combinatorial_optimization/result.py +0 -9
  102. classiq/model_expansions/transformers/ast_renamer.py +0 -26
  103. {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/WHEEL +0 -0
@@ -1,5 +1,6 @@
1
1
  import inspect
2
2
  import sys
3
+ import warnings
3
4
  from collections.abc import Mapping
4
5
  from types import FrameType
5
6
  from typing import (
@@ -12,7 +13,7 @@ from typing import (
12
13
  overload,
13
14
  )
14
15
 
15
- from classiq.interface.exceptions import ClassiqValueError
16
+ from classiq.interface.exceptions import ClassiqDeprecationWarning, ClassiqValueError
16
17
  from classiq.interface.generator.expressions.expression import Expression
17
18
  from classiq.interface.generator.functions.builtins.internal_operators import (
18
19
  REPEAT_OPERATOR_NAME,
@@ -516,27 +517,54 @@ def invert(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
516
517
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(invert_stmt)
517
518
 
518
519
 
520
+ @overload
521
+ def phase(phase_expr: Union[SymbolicExpr, float], theta: float = 1.0) -> None:
522
+ pass
523
+
524
+
525
+ @overload
526
+ def phase(*, expr: Union[SymbolicExpr, float], theta: float = 1.0) -> None:
527
+ pass
528
+
529
+
519
530
  @suppress_return_value
520
- def phase(expr: SymbolicExpr, theta: float = 1.0) -> None:
531
+ def phase(
532
+ phase_expr: Union[SymbolicExpr, float, None] = None,
533
+ theta: float = 1.0,
534
+ expr: Any = None,
535
+ ) -> None:
521
536
  """
522
- Applies a state-dependent phase shift to the quantum state.
537
+ Applies a state-dependent or fixed phase shift (Z rotation) to the quantum state.
523
538
 
524
- This operation multiplies each basis state |x> by a complex phase factor `theta * expr(x)`,
525
- where `expr` is a symbolic expression dependent on the state value `x`, and `theta` is a scalar multiplier.
539
+ This operation multiplies each computational-basis state $|x_1,x_2,\\ldots,x_n\\rangle$
540
+ by a complex phase factor $\\theta * \\text{phase_expr}(x_1,x_2,\\ldots,x_n)$, where
541
+ `phase_expr` is a symbolic expression that contains quantum variables $x_1,x_2,\\ldots,x_n$,
542
+ and `theta` is a scalar multiplier. If `phase_expr` contains no quantum variables,
543
+ all states are rotated by the same fixed angle.
526
544
 
527
545
  Args:
528
- expr: A symbolic expression that evaluates to an angle (in radians) as a function of the quantum state value `x`.
529
- theta: (Optional) A scalar multiplier for the evaluated expression. Defaults to 1.0.
546
+ phase_expr: A symbolic expression that evaluates to an angle (in radians) as a function of the state of the quantum variables occurring in it, if any, or otherwise a fixed value. Execution parameters are only allowed if no quantum variables occur in the expression.
547
+ theta: (Optional, allowed only together with quantum expressions) A scalar multiplier for the evaluated expression, optionally containing execution parameters. Defaults to 1.0.
530
548
 
531
549
  Note:
532
- The `phase` operation is equivalent to a Z-rotation up to a global phase. It is commonly used
533
- to apply relative phase shifts conditioned on the quantum state.
550
+ The `phase` statement is a generalization of the `PHASE()` atomic function, and
551
+ they are equivalent when the phase_expr is a single-qubit variable.
534
552
  """
535
553
  assert QCallable.CURRENT_EXPANDABLE is not None
554
+ if expr is not None:
555
+ warnings.warn(
556
+ "Parameter 'expr' of function 'phase' has been renamed to "
557
+ "'phase_expr'. Parameter 'expr' will no longer be supported starting on "
558
+ "2025-09-19 at the earliest.\nHint: Change `phase(expr=..., theta=...)` to "
559
+ "`phase(phase_expr=..., theta=...)` or `phase(..., ...)`.",
560
+ category=ClassiqDeprecationWarning,
561
+ stacklevel=2,
562
+ )
563
+ phase_expr = expr
536
564
  source_ref = get_source_ref(sys._getframe(1))
537
565
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
538
566
  PhaseOperation(
539
- expression=Expression(expr=str(expr)),
567
+ expression=Expression(expr=str(phase_expr)),
540
568
  theta=Expression(expr=str(theta)),
541
569
  source_ref=source_ref,
542
570
  )
@@ -4,10 +4,8 @@ from typing import TYPE_CHECKING, Any, Optional
4
4
 
5
5
  from classiq.interface.exceptions import ClassiqError
6
6
  from classiq.interface.generator.expressions.expression import Expression
7
- from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
8
- AnyClassicalValue,
9
- )
10
7
 
8
+ from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
11
9
  from classiq.qmod.cparam import CParamScalar
12
10
 
13
11
  if TYPE_CHECKING:
@@ -47,6 +45,6 @@ def get_frontend_interpreter() -> "GenerativeInterpreter":
47
45
 
48
46
  def interpret_expression(expr: str) -> Any:
49
47
  val = get_frontend_interpreter().evaluate(Expression(expr=expr)).value
50
- if isinstance(val, AnyClassicalValue):
48
+ if isinstance(val, QmodAnnotatedExpression):
51
49
  return CParamScalar(str(val))
52
50
  return val
@@ -312,7 +312,7 @@ class DSLPrettyPrinter(ModelVisitor):
312
312
  return control
313
313
 
314
314
  def visit_PhaseOperation(self, op: PhaseOperation) -> str:
315
- theta = f", {self.visit(op.theta)}" if op.theta else ""
315
+ theta = f", {self.visit(op.theta)}" if op.theta.expr != "1.0" else ""
316
316
  phase = f"{self._indent}phase ({self.visit(op.expression)}{theta});\n"
317
317
  return phase
318
318
 
@@ -461,7 +461,7 @@ class PythonPrettyPrinter(ModelVisitor):
461
461
 
462
462
  def visit_PhaseOperation(self, op: PhaseOperation) -> str:
463
463
  self._imports["phase"] = 1
464
- theta = f", {self.visit(op.theta)}" if op.theta is not None else ""
464
+ theta = f", {self.visit(op.theta)}" if op.theta.expr != "1.0" else ""
465
465
  return f"{self._indent}phase({self.visit(op.expression)}{theta})\n"
466
466
 
467
467
  def visit_ClassicalIf(self, op: ClassicalIf) -> str:
@@ -138,7 +138,7 @@ class QConstant(SymbolicExpr):
138
138
  f"Constant {self.name!r} of type {self._py_type.__name__!r} does not "
139
139
  f"have a 'len' property"
140
140
  )
141
- len_expr = f"get_field({self.name}, 'len')"
141
+ len_expr = f"{self.name}.len"
142
142
  if is_generative_mode():
143
143
  return interpret_expression(len_expr)
144
144
  return cast(int, CParamScalar(len_expr))
@@ -100,7 +100,7 @@ class CParamList(CParam):
100
100
  if is_generative_mode():
101
101
  with generative_mode_context(False):
102
102
  return interpret_expression(str(self.len))
103
- return CParamScalar(f"get_field({self}, 'len')")
103
+ return CParamScalar(f"{self}.len")
104
104
 
105
105
 
106
106
  class CParamStruct(CParam):
@@ -135,7 +135,7 @@ class CParamStruct(CParam):
135
135
  )
136
136
 
137
137
  return create_param(
138
- f"get_field({variable_name},{field_name!r})",
138
+ f"{variable_name}.{field_name}",
139
139
  field_type.model_copy(deep=True),
140
140
  qmodule=qmodule,
141
141
  )
@@ -9,6 +9,7 @@ from typing import ( # type: ignore[attr-defined]
9
9
  ForwardRef,
10
10
  Generic,
11
11
  Literal,
12
+ NoReturn,
12
13
  Optional,
13
14
  Protocol,
14
15
  TypeVar,
@@ -155,7 +156,7 @@ class QVar(Symbolic):
155
156
  if is_generative_mode():
156
157
  with generative_mode_context(False):
157
158
  return interpret_expression(str(self.size))
158
- return CParamScalar(f"get_field({self}, 'size')")
159
+ return CParamScalar(f"{self}.size")
159
160
 
160
161
  @property
161
162
  def type_name(self) -> str:
@@ -228,8 +229,8 @@ class QScalar(QVar, SymbolicExpr):
228
229
 
229
230
  def __ior__(self, other: Any) -> Self:
230
231
  if not isinstance(other, SYMBOLIC_TYPES):
231
- raise TypeError(
232
- f"Invalid argument {other!r} for out-of-place arithmetic operation"
232
+ raise ClassiqValueError(
233
+ f"Invalid argument {str(other)!r} for out-of-place arithmetic operation"
233
234
  )
234
235
 
235
236
  self._insert_arith_operation(
@@ -239,8 +240,8 @@ class QScalar(QVar, SymbolicExpr):
239
240
 
240
241
  def __ixor__(self, other: Any) -> Self:
241
242
  if not isinstance(other, SYMBOLIC_TYPES):
242
- raise TypeError(
243
- f"Invalid argument {other!r} for in-place arithmetic operation"
243
+ raise ClassiqValueError(
244
+ f"Invalid argument {str(other)!r} for in-place arithmetic operation"
244
245
  )
245
246
 
246
247
  self._insert_arith_operation(
@@ -250,8 +251,8 @@ class QScalar(QVar, SymbolicExpr):
250
251
 
251
252
  def __iadd__(self, other: Any) -> Self:
252
253
  if not isinstance(other, SYMBOLIC_TYPES):
253
- raise TypeError(
254
- f"Invalid argument {other!r} for in-place arithmetic operation"
254
+ raise ClassiqValueError(
255
+ f"Invalid argument {str(other)!r} for in-place arithmetic operation"
255
256
  )
256
257
 
257
258
  self._insert_arith_operation(
@@ -261,13 +262,58 @@ class QScalar(QVar, SymbolicExpr):
261
262
 
262
263
  def __imul__(self, other: Any) -> Self:
263
264
  if not isinstance(other, SYMBOLIC_TYPES):
264
- raise TypeError(
265
- f"Invalid argument {other!r} for out of ampltiude encoding operation"
265
+ raise ClassiqValueError(
266
+ f"Invalid argument {str(other)!r} for out of ampltiude encoding operation"
266
267
  )
267
268
 
268
269
  self._insert_amplitude_loading(other, get_source_ref(sys._getframe(1)))
269
270
  return self
270
271
 
272
+ def __iand__(self, other: Any) -> NoReturn:
273
+ raise ClassiqNotImplementedError(
274
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '-='"
275
+ )
276
+
277
+ def __ifloordiv__(self, other: Any) -> NoReturn:
278
+ raise ClassiqNotImplementedError(
279
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '//='"
280
+ )
281
+
282
+ def __ilshift__(self, other: Any) -> NoReturn:
283
+ raise ClassiqNotImplementedError(
284
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '<<='"
285
+ )
286
+
287
+ def __imod__(self, other: Any) -> NoReturn:
288
+ raise ClassiqNotImplementedError(
289
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '%='"
290
+ )
291
+
292
+ def __imatmul__(self, other: Any) -> NoReturn:
293
+ raise ClassiqNotImplementedError(
294
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '@='"
295
+ )
296
+
297
+ def __ipow__(self, other: Any) -> NoReturn:
298
+ raise ClassiqNotImplementedError(
299
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '**='"
300
+ )
301
+
302
+ def __irshift__(self, other: Any) -> NoReturn:
303
+ raise ClassiqNotImplementedError(
304
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '>>='"
305
+ )
306
+
307
+ def __isub__(self, other: Any) -> NoReturn:
308
+ raise ClassiqNotImplementedError(
309
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '-='"
310
+ )
311
+
312
+ def __itruediv__(self, other: Any) -> NoReturn:
313
+ raise ClassiqNotImplementedError(
314
+ f"{self.get_qmod_type().raw_qmod_type_name} does not support '/='"
315
+ )
316
+
271
317
 
272
318
  class QBit(QScalar):
273
319
  """A type representing a single qubit.
@@ -386,7 +432,7 @@ class QNum(Generic[_P], QScalar):
386
432
  name: Union[None, str, HandleBinding] = None,
387
433
  size: Union[int, CInt, Expression, SymbolicExpr, None] = None,
388
434
  is_signed: Union[bool, CBool, Expression, SymbolicExpr, None] = None,
389
- fraction_digits: Union[int, CInt, Expression, None] = None,
435
+ fraction_digits: Union[int, CInt, Expression, SymbolicExpr, None] = None,
390
436
  _expr_str: Optional[str] = None,
391
437
  ):
392
438
  if size is None and (is_signed is not None or fraction_digits is not None):
@@ -439,14 +485,14 @@ class QNum(Generic[_P], QScalar):
439
485
  if is_generative_mode():
440
486
  with generative_mode_context(False):
441
487
  return interpret_expression(str(self.fraction_digits))
442
- return CParamScalar(f"get_field({self}, 'fraction_digits')")
488
+ return CParamScalar(f"{self}.fraction_digits")
443
489
 
444
490
  @property
445
491
  def is_signed(self) -> Union[CParamScalar, bool]:
446
492
  if is_generative_mode():
447
493
  with generative_mode_context(False):
448
494
  return interpret_expression(str(self.is_signed))
449
- return CParamScalar(f"get_field({self}, 'is_signed')")
495
+ return CParamScalar(f"{self}.is_signed")
450
496
 
451
497
  def get_maximal_bounds(self) -> tuple[float, float]:
452
498
  if not is_generative_mode():
@@ -480,7 +526,7 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
480
526
  self,
481
527
  name: Union[None, str, HandleBinding] = None,
482
528
  element_type: Union[_GenericAlias, QuantumType] = QBit,
483
- length: Optional[Union[int, SymbolicExpr, Expression]] = None,
529
+ length: Optional[Union[int, CInt, SymbolicExpr, Expression]] = None,
484
530
  _expr_str: Optional[str] = None,
485
531
  ) -> None:
486
532
  self._element_type = element_type
@@ -548,7 +594,7 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
548
594
  if is_generative_mode():
549
595
  with generative_mode_context(False):
550
596
  return interpret_expression(str(self.len))
551
- return CParamScalar(f"get_field({self}, 'len')")
597
+ return CParamScalar(f"{self}.len")
552
598
 
553
599
  @classmethod
554
600
  def to_qvar(
@@ -623,7 +669,7 @@ class QStruct(QVar):
623
669
  field_name: field_class.to_qvar(
624
670
  FieldHandleBinding(base_handle=base_handle, field=field_name),
625
671
  field_type,
626
- f"get_field({expr_str if expr_str is not None else str(origin)}, '{field_name}')",
672
+ f"{expr_str if expr_str is not None else str(origin)}.{field_name}",
627
673
  )
628
674
  for field_name, (field_class, field_type) in field_types.items()
629
675
  }
@@ -677,7 +723,7 @@ def _create_qvar_for_qtype(
677
723
  field_name: _create_qvar_for_qtype(
678
724
  field_type,
679
725
  FieldHandleBinding(base_handle=origin, field=field_name),
680
- f"get_field({expr_str if expr_str is not None else str(origin)}, '{field_name}')",
726
+ f"{expr_str if expr_str is not None else str(origin)}.{field_name}",
681
727
  )
682
728
  for field_name, field_type in struct_decl.fields.items()
683
729
  },
@@ -286,7 +286,7 @@ class QTerminalCallable(QCallable):
286
286
  def len(self) -> CParamScalar:
287
287
  if not self.is_list:
288
288
  raise ClassiqValueError("Cannot get length of a non-list operand")
289
- return CParamScalar(f"get_field({self.func_decl.name}, 'len')")
289
+ return CParamScalar(f"{self.func_decl.name}.len")
290
290
 
291
291
  @property
292
292
  def func_decl(self) -> QuantumFunctionDeclaration:
classiq/synthesis.py CHANGED
@@ -1,10 +1,14 @@
1
1
  from typing import Any, Optional, Union
2
2
 
3
- from classiq.interface.analyzer.result import QasmCode
3
+ from classiq.interface.analyzer.result import QasmCode, QmodCode
4
4
  from classiq.interface.exceptions import ClassiqError, ClassiqValueError
5
5
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
6
6
  from classiq.interface.generator.model.constraints import Constraints
7
7
  from classiq.interface.generator.model.preferences.preferences import Preferences
8
+ from classiq.interface.generator.preferences.qasm_to_qmod_params import (
9
+ QasmToQmodParams,
10
+ QmodFormat,
11
+ )
8
12
  from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model, SerializedModel
9
13
 
10
14
  from classiq import QuantumProgram
@@ -87,12 +91,43 @@ def synthesize(
87
91
  serialized_model = model_obj.get_model()
88
92
  else:
89
93
  serialized_model = model
94
+ if preferences is not None:
95
+ serialized_model = set_preferences(
96
+ serialized_model, preferences=preferences
97
+ )
98
+ if constraints is not None:
99
+ serialized_model = set_constraints(
100
+ serialized_model, constraints=constraints
101
+ )
90
102
  result = async_utils.run(synthesize_async(serialized_model))
91
103
  if auto_show:
92
104
  show(result)
93
105
  return result
94
106
 
95
107
 
108
+ async def qasm_to_qmod_async(params: QasmToQmodParams) -> QmodCode:
109
+ return await ApiWrapper.call_qasm_to_qmod_task(params)
110
+
111
+
112
+ def qasm_to_qmod(qasm: str, qmod_format: QmodFormat) -> str:
113
+ """
114
+ Decompiles QASM to Native/Python Qmod.
115
+
116
+ Args:
117
+ qasm: QASM 2 or QASM 3 code
118
+ qmod_format: The requested output format
119
+
120
+ Returns:
121
+ The decompiled Qmod program
122
+ """
123
+
124
+ return async_utils.run(
125
+ qasm_to_qmod_async(
126
+ QasmToQmodParams(qasm=QasmCode(code=qasm), qmod_format=qmod_format)
127
+ )
128
+ ).code
129
+
130
+
96
131
  def set_preferences(
97
132
  serialized_model: SerializedModel,
98
133
  preferences: Optional[Preferences] = None,
@@ -241,6 +276,7 @@ def update_execution_preferences(
241
276
 
242
277
  __all__ = [
243
278
  "SerializedModel",
279
+ "qasm_to_qmod",
244
280
  "set_constraints",
245
281
  "set_execution_preferences",
246
282
  "set_preferences",
classiq/visualization.py CHANGED
@@ -19,7 +19,7 @@ async def visualize_async(
19
19
  raise error
20
20
  analyzer_data = await ApiWrapper.get_analyzer_app_data(data_id)
21
21
  visual_model = await ApiWrapper.call_visualization_task(analyzer_data)
22
- return SerializedVisualModel(visual_model.model_dump_json(indent=2))
22
+ return SerializedVisualModel(visual_model.model_dump_json())
23
23
 
24
24
 
25
25
  def visualize(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: classiq
3
- Version: 0.88.0
3
+ Version: 0.90.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
@@ -47,7 +47,7 @@ Requires-Dist: openfermionpyscf ; extra == "chemistry"
47
47
  Requires-Dist: packaging (>=23.2,<24.0)
48
48
  Requires-Dist: pandas (>=1.4.0,<3.0.0)
49
49
  Requires-Dist: plotly (>=5.7.0,<6.0.0)
50
- Requires-Dist: pydantic (>=2.9.0,<2.10.0)
50
+ Requires-Dist: pydantic (>=2.10.4,<3.0.0)
51
51
  Requires-Dist: pydantic-settings (>=2.4.0,<3.0.0)
52
52
  Requires-Dist: scipy (>=1.10.0,<2.0.0) ; python_version < "3.12"
53
53
  Requires-Dist: scipy (>=1.11.0,<2.0.0) ; python_version >= "3.12"