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,168 +0,0 @@
1
- from collections.abc import Sequence
2
- from enum import Enum
3
- from typing import Any
4
-
5
- from classiq.interface.exceptions import ClassiqExpansionError
6
- from classiq.interface.generator.expressions.proxies.classical.qmod_struct_instance import (
7
- QmodStructInstance,
8
- )
9
- from classiq.interface.generator.expressions.proxies.quantum.qmod_sized_proxy import (
10
- QmodSizedProxy,
11
- )
12
- from classiq.interface.generator.functions.classical_type import (
13
- StructMetaType,
14
- )
15
- from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
16
- from classiq.interface.generator.functions.type_name import (
17
- TypeName,
18
- )
19
- from classiq.interface.model.classical_parameter_declaration import (
20
- AnonClassicalParameterDeclaration,
21
- )
22
- from classiq.interface.model.port_declaration import AnonPortDeclaration
23
- from classiq.interface.model.quantum_function_declaration import (
24
- AnonPositionalArg,
25
- AnonQuantumOperandDeclaration,
26
- )
27
-
28
- from classiq.evaluators.type_type_match import check_signature_match
29
- from classiq.model_expansions.closure import FunctionClosure
30
- from classiq.model_expansions.scope import Evaluated, QuantumVariable
31
- from classiq.qmod.model_state_container import QMODULE
32
- from classiq.qmod.qmod_parameter import CInt, get_qmod_type
33
-
34
-
35
- def check_type_match(
36
- parameters: Sequence[AnonPositionalArg],
37
- arguments: list[Evaluated],
38
- function_name: str,
39
- ) -> None:
40
- if len(parameters) != len(arguments):
41
- raise ClassiqExpansionError(
42
- f"Function {function_name!r} takes {len(parameters)} arguments but "
43
- f"{len(arguments)} were given"
44
- )
45
- for parameter, evaluated_arg in zip(parameters, arguments):
46
- check_arg_type_match(evaluated_arg.value, parameter, function_name)
47
-
48
-
49
- def check_arg_type_match(
50
- argument: Any, parameter: AnonPositionalArg, function_name: str
51
- ) -> None:
52
- message_prefix = (
53
- f"Argument {str(argument)!r} to parameter {parameter.name!r} of function "
54
- f"{function_name!r} has incompatible type; "
55
- )
56
- if isinstance(parameter, AnonPortDeclaration):
57
- error_message = message_prefix + "expected quantum variable"
58
- _check_qvar_type_match(argument, error_message)
59
- elif isinstance(parameter, AnonQuantumOperandDeclaration):
60
- if parameter.is_list:
61
- error_message = message_prefix + "expected list of operands"
62
- _check_operand_list_type_match(
63
- argument, parameter, function_name, error_message
64
- )
65
- else:
66
- error_message = message_prefix + "expected operand"
67
- _check_operand_type_match(argument, parameter, function_name, error_message)
68
- elif isinstance(parameter, AnonClassicalParameterDeclaration):
69
- error_message = (
70
- message_prefix + f"expected {_resolve_type_name(parameter.classical_type)}"
71
- )
72
- _check_classical_type_match(argument, parameter, error_message, function_name)
73
- else:
74
- raise ClassiqExpansionError(
75
- f"unexpected parameter declaration type: {type(parameter).__name__}"
76
- )
77
-
78
-
79
- def _check_qvar_type_match(argument: Any, error_message: str) -> None:
80
- if not isinstance(argument, QuantumVariable):
81
- raise ClassiqExpansionError(error_message)
82
-
83
-
84
- def _check_operand_list_type_match(
85
- argument: Any,
86
- parameter: AnonQuantumOperandDeclaration,
87
- function_name: str,
88
- error_message: str,
89
- ) -> None:
90
- if not isinstance(argument, list) or any(
91
- not isinstance(op, FunctionClosure) for op in argument
92
- ):
93
- raise ClassiqExpansionError(error_message)
94
- for idx, operand in enumerate(argument):
95
- if operand.positional_arg_declarations is not None:
96
- check_signature_match(
97
- parameter.positional_arg_declarations,
98
- operand.positional_arg_declarations,
99
- f"operand #{idx + 1} in parameter {parameter.name!r} "
100
- f"in function {function_name!r}",
101
- )
102
-
103
-
104
- def _check_operand_type_match(
105
- argument: Any,
106
- parameter: AnonQuantumOperandDeclaration,
107
- function_name: str,
108
- error_message: str,
109
- ) -> None:
110
- if not isinstance(argument, FunctionClosure):
111
- raise ClassiqExpansionError(error_message)
112
- if argument.positional_arg_declarations is not None:
113
- check_signature_match(
114
- parameter.positional_arg_declarations,
115
- argument.positional_arg_declarations,
116
- f"operand {parameter.name!r} in function {function_name!r}",
117
- )
118
-
119
-
120
- def _check_classical_type_match(
121
- argument: Any,
122
- parameter: AnonClassicalParameterDeclaration,
123
- error_message: str,
124
- function_name: str,
125
- ) -> None:
126
- classical_type = parameter.classical_type
127
- type_name = _resolve_type_name(classical_type)
128
- type_is_struct = (
129
- isinstance(classical_type, TypeName)
130
- and classical_type.name in QMODULE.type_decls
131
- )
132
- type_is_enum = (
133
- isinstance(classical_type, TypeName)
134
- and classical_type.name in QMODULE.enum_decls
135
- )
136
- arg_is_qvar = isinstance(argument, QmodSizedProxy)
137
- arg_is_builtin = argument.__class__.__module__ == "builtins"
138
- arg_is_int = isinstance(argument, int)
139
- arg_is_enum = isinstance(argument, Enum)
140
- arg_is_struct = isinstance(argument, QmodStructInstance)
141
- arg_struct_name = None if not arg_is_struct else argument.struct_declaration.name
142
- # FIXME: Remove suzuki_trotter overloading (CLS-2912)
143
- if function_name == "suzuki_trotter" and parameter.name == "pauli_operator":
144
- return
145
- if (
146
- arg_is_qvar
147
- or (arg_is_builtin and type_is_struct)
148
- or (arg_is_builtin and not arg_is_int and type_is_enum)
149
- or (arg_is_struct and (not type_is_struct or arg_struct_name != type_name))
150
- or (
151
- arg_is_enum
152
- and get_qmod_type(classical_type) != CInt
153
- and (not type_is_enum or type(argument).__name__ != type_name)
154
- )
155
- ):
156
- raise ClassiqExpansionError(error_message)
157
-
158
-
159
- def _resolve_type_name(classical_type: ConcreteClassicalType) -> str:
160
- if isinstance(classical_type, StructMetaType):
161
- type_name = "Struct"
162
- else:
163
- type_name = get_qmod_type(classical_type).__name__
164
- if not isinstance(classical_type, TypeName):
165
- return type_name
166
- if type_name not in QMODULE.type_decls and type_name not in QMODULE.enum_decls:
167
- raise ClassiqExpansionError(f"Undefined type {type_name}")
168
- return type_name
@@ -1,121 +0,0 @@
1
- from typing import TYPE_CHECKING, Any, Union
2
-
3
- from classiq.interface.exceptions import ClassiqExpansionError
4
- from classiq.interface.generator.expressions.expression import Expression
5
- from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
6
- AnyClassicalValue,
7
- )
8
- from classiq.interface.generator.expressions.proxies.classical.classical_array_proxy import (
9
- ClassicalSequenceProxy,
10
- _is_int,
11
- )
12
- from classiq.interface.generator.expressions.proxies.classical.classical_struct_proxy import (
13
- ClassicalStructProxy,
14
- )
15
- from classiq.interface.generator.expressions.proxies.classical.qmod_struct_instance import (
16
- QmodStructInstance,
17
- )
18
- from classiq.interface.generator.functions.classical_type import (
19
- ClassicalArray,
20
- ClassicalTuple,
21
- ClassicalType,
22
- )
23
- from classiq.interface.generator.functions.type_name import TypeName
24
- from classiq.interface.generator.types.struct_declaration import StructDeclaration
25
- from classiq.interface.helpers.backward_compatibility import zip_strict
26
-
27
-
28
- def infer_classical_type(val: Any, classical_type: ClassicalType) -> ClassicalType:
29
- if isinstance(classical_type, TypeName):
30
- return _infer_classical_struct_type(val, classical_type)
31
- if isinstance(classical_type, (ClassicalArray, ClassicalTuple)):
32
- return _infer_classical_array_type(val, classical_type)
33
- return classical_type
34
-
35
-
36
- def _infer_classical_struct_type(val: Any, classical_type: TypeName) -> ClassicalType:
37
- if not isinstance(val, (QmodStructInstance, ClassicalStructProxy)):
38
- return classical_type
39
- if classical_type.is_enum:
40
- raise ClassiqExpansionError(
41
- f"{classical_type.type_name!r} expected, got {str(val)!r}"
42
- )
43
- decl = classical_type.classical_struct_decl
44
- new_fields = {
45
- field_name: infer_classical_type(field_val, field_type)
46
- for (field_name, field_val), field_type in zip_strict(
47
- val.fields.items(),
48
- decl.variables.values(),
49
- strict=True,
50
- )
51
- }
52
- new_classical_type = TypeName(name=decl.name)
53
- new_classical_type.set_classical_struct_decl(
54
- StructDeclaration(name=decl.name, variables=new_fields)
55
- )
56
- return new_classical_type
57
-
58
-
59
- def _infer_classical_array_type(
60
- val: Any, classical_type: Union[ClassicalArray, ClassicalTuple]
61
- ) -> ClassicalType:
62
- if isinstance(val, ClassicalSequenceProxy):
63
- val_length = val.length
64
- elif isinstance(val, list):
65
- val_length = len(val)
66
- elif isinstance(val, AnyClassicalValue):
67
- return classical_type
68
- else:
69
- raise ClassiqExpansionError(f"Array expected, got {str(val)!r}")
70
- if isinstance(val_length, int) and (
71
- (
72
- isinstance(classical_type, ClassicalArray)
73
- and classical_type.length is not None
74
- and classical_type.length.is_evaluated()
75
- and _is_int(classical_type.length.value.value)
76
- and val_length != (type_length := int(classical_type.length.value.value))
77
- )
78
- or (
79
- isinstance(classical_type, ClassicalTuple)
80
- and val_length != (type_length := classical_type.length)
81
- )
82
- ):
83
- raise ClassiqExpansionError(
84
- f"Type mismatch: Argument has {val_length} items but "
85
- f"{type_length} expected"
86
- )
87
- new_classical_type = _infer_inner_array_types(classical_type, val, val_length)
88
- if classical_type.is_generative:
89
- new_classical_type.set_generative()
90
- return new_classical_type
91
-
92
-
93
- def _infer_inner_array_types(
94
- classical_type: ClassicalType, val: Any, val_length: Any
95
- ) -> ClassicalType:
96
- if isinstance(classical_type, ClassicalTuple):
97
- return ClassicalTuple(
98
- element_types=(
99
- infer_classical_type(val[idx], element_type)
100
- for idx, element_type in enumerate(classical_type.element_types)
101
- ),
102
- )
103
- if TYPE_CHECKING:
104
- assert isinstance(classical_type, ClassicalArray)
105
- if _is_int(val_length) and val_length != 0:
106
- return ClassicalTuple(
107
- element_types=(
108
- infer_classical_type(val[i], classical_type.element_type)
109
- for i in range(int(val_length))
110
- ),
111
- )
112
- element_type: ClassicalType
113
- if val_length == 0:
114
- element_type = classical_type.element_type
115
- else:
116
- element_type = infer_classical_type(val[0], classical_type.element_type)
117
- if _is_int(val_length):
118
- length = Expression(expr=str(int(val_length)))
119
- else:
120
- length = None
121
- return ClassicalArray(element_type=element_type, length=length)
@@ -1,17 +0,0 @@
1
- from typing import Any
2
-
3
- import pydantic
4
- from pydantic import BaseModel
5
-
6
- from classiq.interface.executor.optimizer_preferences import CombinatorialOptimizer
7
-
8
-
9
- class MaxCutProblem(BaseModel):
10
- qaoa_reps: pydantic.PositiveInt = pydantic.Field(
11
- default=1, description="Number of layers in qaoa ansatz."
12
- )
13
- optimizer_preferences: CombinatorialOptimizer = pydantic.Field(
14
- default_factory=CombinatorialOptimizer,
15
- description="preferences for the VQE execution",
16
- )
17
- serialized_graph: dict[str, Any]
@@ -1,9 +0,0 @@
1
- from classiq.interface.helpers.versioned_model import VersionedModel
2
-
3
-
4
- class AnglesResult(VersionedModel):
5
- initial_point: list[float]
6
-
7
-
8
- class PyomoObjectResult(VersionedModel):
9
- details: str
@@ -1,26 +0,0 @@
1
- import ast
2
-
3
- _POSSIBLE_HANDLE_AST_TYPES = (ast.Subscript, ast.Attribute, ast.Name)
4
-
5
-
6
- class _ASTRenamer(ast.NodeTransformer):
7
- def __init__(self, sub: dict[str, str]) -> None:
8
- self._sub = sub
9
-
10
- def visit(self, node: ast.AST) -> ast.AST:
11
- if isinstance(node, _POSSIBLE_HANDLE_AST_TYPES):
12
- node_expr = ast.unparse(node)
13
- if node_expr in self._sub:
14
- return ast.Name(id=self._sub[node_expr])
15
- return super().visit(node)
16
-
17
- def visit_Call(self, node: ast.Call) -> ast.Call:
18
- return ast.Call(
19
- func=node.func,
20
- args=[self.visit(arg) for arg in node.args],
21
- keywords=[],
22
- )
23
-
24
-
25
- def rename_variables(expr: str, sub: dict[str, str]) -> str:
26
- return ast.unparse(_ASTRenamer(sub).visit(ast.parse(expr)))