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.
- classiq/__init__.py +1 -0
- classiq/_internals/api_wrapper.py +16 -32
- classiq/_internals/config.py +1 -1
- classiq/analyzer/show_interactive_hack.py +26 -1
- classiq/applications/chemistry/chemistry_model_constructor.py +14 -2
- classiq/applications/combinatorial_helpers/pyomo_utils.py +9 -6
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -2
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +16 -8
- classiq/evaluators/classical_expression.py +63 -41
- classiq/evaluators/control.py +31 -52
- classiq/evaluators/expression_evaluator.py +8 -4
- classiq/evaluators/parameter_types.py +200 -104
- classiq/evaluators/qmod_annotated_expression.py +10 -9
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +2 -2
- classiq/evaluators/qmod_expression_visitors/qmod_expression_renamer.py +1 -1
- classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +66 -5
- classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +12 -37
- classiq/evaluators/qmod_node_evaluators/constant_evaluation.py +8 -17
- classiq/evaluators/qmod_node_evaluators/measurement_evaluation.py +1 -1
- classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +7 -1
- classiq/evaluators/qmod_node_evaluators/name_evaluation.py +0 -1
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +9 -1
- classiq/evaluators/qmod_node_evaluators/utils.py +33 -0
- classiq/evaluators/qmod_type_inference/classical_type_inference.py +4 -7
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +2 -26
- classiq/interface/analyzer/result.py +4 -0
- classiq/interface/backend/backend_preferences.py +1 -1
- classiq/interface/chemistry/ground_state_problem.py +16 -2
- classiq/interface/executor/optimizer_preferences.py +0 -112
- classiq/interface/generator/application_apis/chemistry_declarations.py +3 -1
- classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -7
- classiq/interface/generator/arith/register_user_input.py +1 -1
- classiq/interface/generator/expressions/evaluated_expression.py +3 -13
- classiq/interface/generator/expressions/expression_types.py +8 -22
- classiq/interface/generator/expressions/proxies/classical/classical_proxy.py +2 -2
- classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +1 -2
- classiq/interface/generator/functions/classical_type.py +24 -3
- classiq/interface/generator/functions/concrete_types.py +1 -1
- classiq/interface/generator/functions/function_declaration.py +0 -4
- classiq/interface/generator/functions/type_name.py +25 -0
- classiq/interface/generator/generated_circuit_data.py +4 -0
- classiq/interface/generator/hardware_efficient_ansatz.py +1 -1
- classiq/interface/generator/preferences/qasm_to_qmod_params.py +14 -0
- classiq/interface/generator/quantum_function_call.py +3 -3
- classiq/interface/generator/user_defined_function_params.py +0 -3
- classiq/interface/helpers/model_normalizer.py +0 -6
- classiq/interface/ide/ide_data.py +1 -1
- classiq/interface/ide/visual_model.py +3 -2
- classiq/interface/model/block.py +5 -1
- classiq/interface/model/handle_binding.py +2 -2
- classiq/interface/model/port_declaration.py +2 -1
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +16 -12
- classiq/interface/model/quantum_lambda_function.py +1 -1
- classiq/interface/model/quantum_statement.py +2 -4
- classiq/interface/model/quantum_type.py +47 -4
- classiq/interface/server/routes.py +2 -3
- classiq/model_expansions/atomic_expression_functions_defs.py +4 -22
- classiq/model_expansions/capturing/captured_vars.py +7 -3
- classiq/model_expansions/closure.py +8 -0
- classiq/model_expansions/interpreters/base_interpreter.py +84 -22
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +1 -1
- classiq/model_expansions/interpreters/generative_interpreter.py +7 -5
- classiq/model_expansions/quantum_operations/allocate.py +92 -21
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +28 -27
- classiq/model_expansions/quantum_operations/call_emitter.py +32 -26
- classiq/model_expansions/quantum_operations/classical_var_emitter.py +6 -2
- classiq/model_expansions/quantum_operations/emitter.py +39 -69
- classiq/model_expansions/quantum_operations/expression_evaluator.py +13 -2
- classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -5
- classiq/model_expansions/quantum_operations/variable_decleration.py +16 -11
- classiq/model_expansions/scope.py +36 -29
- classiq/model_expansions/scope_initialization.py +3 -6
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +6 -2
- classiq/model_expansions/transformers/model_renamer.py +35 -64
- classiq/model_expansions/transformers/type_modifier_inference.py +6 -6
- classiq/model_expansions/visitors/boolean_expression_transformers.py +7 -31
- classiq/model_expansions/visitors/symbolic_param_inference.py +9 -3
- classiq/open_library/functions/__init__.py +2 -0
- classiq/open_library/functions/state_preparation.py +140 -5
- classiq/qmod/builtins/functions/allocation.py +8 -8
- classiq/qmod/builtins/functions/arithmetic.py +1 -1
- classiq/qmod/builtins/functions/chemistry.py +64 -0
- classiq/qmod/builtins/functions/exponentiation.py +7 -13
- classiq/qmod/builtins/functions/qsvm.py +1 -1
- classiq/qmod/builtins/operations.py +38 -10
- classiq/qmod/generative.py +2 -4
- classiq/qmod/native/pretty_printer.py +1 -1
- classiq/qmod/pretty_print/pretty_printer.py +1 -1
- classiq/qmod/qmod_constant.py +1 -1
- classiq/qmod/qmod_parameter.py +2 -2
- classiq/qmod/qmod_variable.py +62 -16
- classiq/qmod/quantum_expandable.py +1 -1
- classiq/synthesis.py +37 -1
- classiq/visualization.py +1 -1
- {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/METADATA +2 -2
- {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/RECORD +98 -102
- classiq/evaluators/arg_type_match.py +0 -168
- classiq/evaluators/classical_type_inference.py +0 -121
- classiq/interface/combinatorial_optimization/optimization_problem.py +0 -17
- classiq/interface/combinatorial_optimization/result.py +0 -9
- classiq/model_expansions/transformers/ast_renamer.py +0 -26
- {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(
|
|
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
|
|
525
|
-
|
|
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
|
-
|
|
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`
|
|
533
|
-
|
|
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(
|
|
567
|
+
expression=Expression(expr=str(phase_expr)),
|
|
540
568
|
theta=Expression(expr=str(theta)),
|
|
541
569
|
source_ref=source_ref,
|
|
542
570
|
)
|
classiq/qmod/generative.py
CHANGED
|
@@ -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,
|
|
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
|
|
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:
|
classiq/qmod/qmod_constant.py
CHANGED
|
@@ -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"
|
|
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))
|
classiq/qmod/qmod_parameter.py
CHANGED
|
@@ -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"
|
|
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"
|
|
138
|
+
f"{variable_name}.{field_name}",
|
|
139
139
|
field_type.model_copy(deep=True),
|
|
140
140
|
qmodule=qmodule,
|
|
141
141
|
)
|
classiq/qmod/qmod_variable.py
CHANGED
|
@@ -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"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
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(
|
|
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.
|
|
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.
|
|
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"
|