classiq 0.43.2__py3-none-any.whl → 0.44.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. classiq/__init__.py +7 -1
  2. classiq/_internals/client.py +4 -7
  3. classiq/_internals/host_checker.py +34 -12
  4. classiq/_internals/jobs.py +2 -2
  5. classiq/applications/chemistry/chemistry_model_constructor.py +12 -6
  6. classiq/applications/combinatorial_helpers/allowed_constraints.py +4 -1
  7. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
  8. classiq/applications/finance/finance_model_constructor.py +3 -2
  9. classiq/applications/grover/grover_model_constructor.py +7 -5
  10. classiq/applications/hamiltonian/__init__.py +0 -0
  11. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  12. classiq/applications/qnn/qlayer.py +1 -1
  13. classiq/exceptions.py +4 -0
  14. classiq/interface/_version.py +1 -1
  15. classiq/interface/ast_node.py +1 -18
  16. classiq/interface/backend/backend_preferences.py +15 -16
  17. classiq/interface/backend/ionq/ionq_quantum_program.py +1 -1
  18. classiq/interface/backend/pydantic_backend.py +0 -5
  19. classiq/interface/backend/quantum_backend_providers.py +3 -2
  20. classiq/interface/chemistry/operator.py +5 -1
  21. classiq/interface/debug_info/__init__.py +0 -0
  22. classiq/interface/debug_info/debug_info.py +32 -0
  23. classiq/interface/executor/execution_preferences.py +1 -45
  24. classiq/interface/executor/result.py +25 -12
  25. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  26. classiq/interface/generator/application_apis/chemistry_declarations.py +78 -60
  27. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +19 -10
  28. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  29. classiq/interface/generator/application_apis/finance_declarations.py +36 -22
  30. classiq/interface/generator/application_apis/qsvm_declarations.py +21 -15
  31. classiq/interface/generator/arith/arithmetic_expression_abc.py +21 -1
  32. classiq/interface/generator/arith/binary_ops.py +5 -4
  33. classiq/interface/generator/arith/extremum_operations.py +43 -19
  34. classiq/interface/generator/constant.py +1 -1
  35. classiq/interface/generator/expressions/atomic_expression_functions.py +1 -0
  36. classiq/interface/generator/expressions/expression_constants.py +3 -1
  37. classiq/interface/generator/expressions/qmod_qarray_proxy.py +52 -66
  38. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +35 -0
  39. classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
  40. classiq/interface/generator/functions/builtins/core_library/__init__.py +4 -2
  41. classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +41 -41
  42. classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +52 -42
  43. classiq/interface/generator/functions/builtins/open_lib_functions.py +1095 -3347
  44. classiq/interface/generator/functions/builtins/quantum_operators.py +9 -22
  45. classiq/interface/generator/functions/classical_function_declaration.py +14 -6
  46. classiq/interface/generator/functions/classical_type.py +7 -76
  47. classiq/interface/generator/functions/concrete_types.py +55 -0
  48. classiq/interface/generator/functions/function_declaration.py +10 -10
  49. classiq/interface/generator/functions/type_name.py +104 -0
  50. classiq/interface/generator/generated_circuit_data.py +3 -3
  51. classiq/interface/generator/model/model.py +11 -0
  52. classiq/interface/generator/model/preferences/preferences.py +5 -0
  53. classiq/interface/generator/quantum_function_call.py +3 -0
  54. classiq/interface/generator/quantum_program.py +2 -2
  55. classiq/interface/generator/register_role.py +7 -1
  56. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +1 -3
  57. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +1 -2
  58. classiq/interface/generator/types/qstruct_declaration.py +17 -0
  59. classiq/interface/generator/types/struct_declaration.py +1 -1
  60. classiq/interface/helpers/validation_helpers.py +1 -17
  61. classiq/interface/ide/visual_model.py +9 -2
  62. classiq/interface/interface_version.py +1 -0
  63. classiq/interface/model/bind_operation.py +25 -5
  64. classiq/interface/model/classical_parameter_declaration.py +8 -5
  65. classiq/interface/model/control.py +5 -5
  66. classiq/interface/model/handle_binding.py +185 -12
  67. classiq/interface/model/inplace_binary_operation.py +16 -4
  68. classiq/interface/model/model.py +28 -5
  69. classiq/interface/model/native_function_definition.py +8 -4
  70. classiq/interface/model/parameter.py +14 -0
  71. classiq/interface/model/port_declaration.py +20 -2
  72. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +21 -6
  73. classiq/interface/model/quantum_expressions/arithmetic_operation.py +30 -6
  74. classiq/interface/model/quantum_expressions/quantum_expression.py +4 -9
  75. classiq/interface/model/quantum_function_call.py +135 -192
  76. classiq/interface/model/quantum_function_declaration.py +147 -165
  77. classiq/interface/model/quantum_lambda_function.py +24 -6
  78. classiq/interface/model/quantum_statement.py +34 -8
  79. classiq/interface/model/quantum_type.py +61 -10
  80. classiq/interface/model/quantum_variable_declaration.py +1 -1
  81. classiq/interface/model/statement_block.py +2 -0
  82. classiq/interface/model/validation_handle.py +7 -0
  83. classiq/interface/server/global_versions.py +4 -4
  84. classiq/interface/server/routes.py +2 -0
  85. classiq/interface/source_reference.py +59 -0
  86. classiq/qmod/__init__.py +2 -3
  87. classiq/qmod/builtins/functions.py +39 -11
  88. classiq/qmod/builtins/operations.py +171 -40
  89. classiq/qmod/declaration_inferrer.py +99 -56
  90. classiq/qmod/expression_query.py +1 -1
  91. classiq/qmod/model_state_container.py +2 -0
  92. classiq/qmod/native/pretty_printer.py +71 -53
  93. classiq/qmod/pretty_print/pretty_printer.py +98 -52
  94. classiq/qmod/qfunc.py +11 -5
  95. classiq/qmod/qmod_parameter.py +1 -2
  96. classiq/qmod/qmod_variable.py +364 -172
  97. classiq/qmod/quantum_callable.py +3 -3
  98. classiq/qmod/quantum_expandable.py +119 -65
  99. classiq/qmod/quantum_function.py +15 -3
  100. classiq/qmod/semantics/annotation.py +12 -13
  101. classiq/qmod/semantics/error_manager.py +36 -10
  102. classiq/qmod/semantics/static_semantics_visitor.py +163 -75
  103. classiq/qmod/semantics/validation/func_call_validation.py +42 -96
  104. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  105. classiq/qmod/semantics/validation/types_validation.py +108 -1
  106. classiq/qmod/type_attribute_remover.py +32 -0
  107. classiq/qmod/utilities.py +26 -5
  108. {classiq-0.43.2.dist-info → classiq-0.44.0.dist-info}/METADATA +3 -3
  109. {classiq-0.43.2.dist-info → classiq-0.44.0.dist-info}/RECORD +111 -99
  110. classiq/qmod/qmod_struct.py +0 -13
  111. /classiq/{interface/ide/show.py → show.py} +0 -0
  112. {classiq-0.43.2.dist-info → classiq-0.44.0.dist-info}/WHEEL +0 -0
@@ -1,35 +1,22 @@
1
- from typing import Any
2
-
3
1
  from classiq.interface.model.quantum_function_declaration import (
4
- QuantumFunctionDeclaration,
2
+ NamedParamsQuantumFunctionDeclaration,
5
3
  QuantumOperandDeclaration,
6
4
  )
7
5
 
8
-
9
- def get_single_empty_operand_operator(
10
- operator_name: str, **kwargs: Any
11
- ) -> QuantumFunctionDeclaration:
12
- operand_field_name = "operand"
13
- return QuantumFunctionDeclaration(
14
- name=operator_name,
15
- operand_declarations={
16
- operand_field_name: QuantumOperandDeclaration(name=operand_field_name)
17
- },
18
- **kwargs,
19
- )
20
-
21
-
22
- PERMUTE_OPERATOR = QuantumFunctionDeclaration(
6
+ PERMUTE_OPERATOR = NamedParamsQuantumFunctionDeclaration(
23
7
  name="permute",
24
- operand_declarations={
25
- "functions": QuantumOperandDeclaration(
8
+ positional_arg_declarations=[
9
+ QuantumOperandDeclaration(
26
10
  name="functions",
27
11
  is_list=True,
28
12
  )
29
- },
13
+ ],
30
14
  )
31
15
 
32
- APPLY_OPERATOR = get_single_empty_operand_operator(operator_name="apply")
16
+ APPLY_OPERATOR = NamedParamsQuantumFunctionDeclaration(
17
+ name="apply",
18
+ positional_arg_declarations=[QuantumOperandDeclaration(name="operand")],
19
+ )
33
20
 
34
21
  STD_QMOD_OPERATORS = [
35
22
  PERMUTE_OPERATOR,
@@ -1,11 +1,14 @@
1
- from typing import ClassVar, Dict, Mapping, Optional
1
+ from typing import ClassVar, Dict, Optional, Sequence
2
2
 
3
3
  import pydantic
4
4
 
5
- from classiq.interface.generator.functions.classical_type import ConcreteClassicalType
5
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
6
6
  from classiq.interface.generator.functions.function_declaration import (
7
7
  FunctionDeclaration,
8
8
  )
9
+ from classiq.interface.model.classical_parameter_declaration import (
10
+ ClassicalParameterDeclaration,
11
+ )
9
12
 
10
13
 
11
14
  class ClassicalFunctionDeclaration(FunctionDeclaration):
@@ -13,6 +16,12 @@ class ClassicalFunctionDeclaration(FunctionDeclaration):
13
16
  Facilitates the creation of a common classical function interface object.
14
17
  """
15
18
 
19
+ name: str
20
+
21
+ positional_parameters: Sequence[ClassicalParameterDeclaration] = pydantic.Field(
22
+ default_factory=list,
23
+ )
24
+
16
25
  return_type: Optional[ConcreteClassicalType] = pydantic.Field(
17
26
  description="The type of the classical value that is returned by the function (for classical functions)",
18
27
  default=None,
@@ -26,10 +35,9 @@ class ClassicalFunctionDeclaration(FunctionDeclaration):
26
35
  Dict[str, "ClassicalFunctionDeclaration"]
27
36
  ] = {}
28
37
 
29
- def update_logic_flow(
30
- self, function_dict: Mapping[str, "ClassicalFunctionDeclaration"]
31
- ) -> None:
32
- pass
38
+ @property
39
+ def param_decls(self) -> Sequence[ClassicalParameterDeclaration]:
40
+ return self.positional_parameters
33
41
 
34
42
 
35
43
  ClassicalFunctionDeclaration.update_forward_refs()
@@ -1,14 +1,18 @@
1
- from typing import Any, Dict, List, Literal, Union
1
+ from typing import TYPE_CHECKING, Any, Dict, List, Literal, Union
2
2
 
3
3
  import pydantic
4
- from pydantic import Extra, Field
4
+ from pydantic import Extra
5
5
  from sympy import IndexedBase, Symbol
6
- from typing_extensions import Annotated
7
6
 
8
7
  from classiq.interface.ast_node import HashableASTNode
9
8
  from classiq.interface.generator.expressions.expression_types import RuntimeExpression
10
9
  from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
11
10
 
11
+ if TYPE_CHECKING:
12
+ from classiq.interface.generator.functions.concrete_types import (
13
+ ConcreteClassicalType,
14
+ )
15
+
12
16
  CLASSICAL_ATTRIBUTES = {"len", "size", "is_signed", "fraction_digits"}
13
17
 
14
18
  NamedSymbol = Union[IndexedBase, Symbol]
@@ -97,20 +101,6 @@ class ClassicalList(ClassicalType):
97
101
  return CArray[self.element_type.qmod_type] # type:ignore[name-defined]
98
102
 
99
103
 
100
- class Pauli(ClassicalType):
101
- kind: Literal["pauli"]
102
-
103
- @pydantic.root_validator(pre=True)
104
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
105
- return values_with_discriminator(values, "kind", "pauli")
106
-
107
- @property
108
- def qmod_type(self) -> type:
109
- from classiq.qmod.builtins.enums import Pauli
110
-
111
- return Pauli
112
-
113
-
114
104
  class StructMetaType(ClassicalType):
115
105
  kind: Literal["type_proxy"]
116
106
 
@@ -119,27 +109,6 @@ class StructMetaType(ClassicalType):
119
109
  return values_with_discriminator(values, "kind", "type_proxy")
120
110
 
121
111
 
122
- class TypeName(ClassicalType):
123
- kind: Literal["struct_instance"]
124
- name: str = pydantic.Field(description="The type name of the instance")
125
-
126
- @pydantic.root_validator(pre=True)
127
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
128
- return values_with_discriminator(values, "kind", "struct_instance")
129
-
130
- @property
131
- def qmod_type(self) -> type:
132
- return type(self.name, (TypeName,), dict())
133
-
134
-
135
- class Enum(TypeName):
136
- pass
137
-
138
-
139
- class Struct(TypeName):
140
- pass
141
-
142
-
143
112
  class ClassicalArray(ClassicalType):
144
113
  kind: Literal["array"]
145
114
  element_type: "ConcreteClassicalType"
@@ -197,44 +166,6 @@ class IQAERes(OpaqueHandle):
197
166
  return values_with_discriminator(values, "kind", "iqae_result")
198
167
 
199
168
 
200
- class LadderOperator(ClassicalType):
201
- kind: Literal["ladder_operator"]
202
-
203
- @pydantic.root_validator(pre=True)
204
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
205
- return values_with_discriminator(values, "kind", "ladder_operator")
206
-
207
- @property
208
- def qmod_type(self) -> type:
209
- from classiq.qmod.builtins.enums import LadderOperator
210
-
211
- return LadderOperator
212
-
213
-
214
- ConcreteClassicalType = Annotated[
215
- Union[
216
- Integer,
217
- Real,
218
- Bool,
219
- ClassicalList,
220
- Pauli,
221
- StructMetaType,
222
- TypeName,
223
- ClassicalArray,
224
- VQEResult,
225
- Histogram,
226
- Estimation,
227
- LadderOperator,
228
- IQAERes,
229
- ],
230
- Field(discriminator="kind"),
231
- ]
232
- ClassicalList.update_forward_refs()
233
- ClassicalArray.update_forward_refs()
234
-
235
- PythonClassicalTypes = (int, float, bool, list, Enum)
236
-
237
-
238
169
  def as_symbolic(symbols: Dict[str, ClassicalType]) -> Dict[str, RuntimeExpression]:
239
170
  return {
240
171
  param_name: param_type.as_symbolic(param_name)
@@ -0,0 +1,55 @@
1
+ from typing import Union
2
+
3
+ from pydantic import Field
4
+ from typing_extensions import Annotated
5
+
6
+ from classiq.interface.generator.functions.classical_type import (
7
+ Bool,
8
+ ClassicalArray,
9
+ ClassicalList,
10
+ Estimation,
11
+ Histogram,
12
+ Integer,
13
+ IQAERes,
14
+ Real,
15
+ StructMetaType,
16
+ VQEResult,
17
+ )
18
+ from classiq.interface.generator.functions.type_name import Enum, TypeName
19
+ from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
20
+ from classiq.interface.model.quantum_type import (
21
+ QuantumBit,
22
+ QuantumBitvector,
23
+ QuantumNumeric,
24
+ RegisterQuantumType,
25
+ )
26
+
27
+ ConcreteClassicalType = Annotated[
28
+ Union[
29
+ Integer,
30
+ Real,
31
+ Bool,
32
+ ClassicalList,
33
+ StructMetaType,
34
+ TypeName,
35
+ ClassicalArray,
36
+ VQEResult,
37
+ Histogram,
38
+ Estimation,
39
+ IQAERes,
40
+ ],
41
+ Field(discriminator="kind"),
42
+ ]
43
+ ClassicalList.update_forward_refs(ConcreteClassicalType=ConcreteClassicalType)
44
+ ClassicalArray.update_forward_refs(ConcreteClassicalType=ConcreteClassicalType)
45
+
46
+ PythonClassicalTypes = (int, float, bool, list, Enum)
47
+
48
+ ConcreteQuantumType = Annotated[
49
+ Union[QuantumBit, QuantumBitvector, QuantumNumeric, TypeName],
50
+ Field(discriminator="kind", default_factory=QuantumBitvector),
51
+ ]
52
+ QuantumBitvector.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
53
+ TypeName.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
54
+ QStructDeclaration.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
55
+ RegisterQuantumType.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
@@ -1,23 +1,23 @@
1
1
  import abc
2
- from typing import Dict
2
+ from typing import Sequence
3
3
 
4
4
  import pydantic
5
5
 
6
- from classiq.interface.ast_node import ASTNode
7
- from classiq.interface.generator.functions.classical_type import ConcreteClassicalType
6
+ from classiq.interface.model.classical_parameter_declaration import (
7
+ AnonClassicalParameterDeclaration,
8
+ )
9
+ from classiq.interface.model.parameter import Parameter
8
10
 
9
11
 
10
- class FunctionDeclaration(ASTNode, abc.ABC):
12
+ class FunctionDeclaration(Parameter, abc.ABC):
11
13
  """
12
14
  Facilitates the creation of a common function interface object.
13
15
  """
14
16
 
15
- name: str = pydantic.Field(description="The name of the function")
16
-
17
- param_decls: Dict[str, ConcreteClassicalType] = pydantic.Field(
18
- description="The expected interface of the functions parameters",
19
- default_factory=dict,
20
- )
17
+ @property
18
+ @abc.abstractmethod
19
+ def param_decls(self) -> Sequence[AnonClassicalParameterDeclaration]:
20
+ pass
21
21
 
22
22
  class Config:
23
23
  extra = pydantic.Extra.forbid
@@ -0,0 +1,104 @@
1
+ from typing import TYPE_CHECKING, Any, Dict, Literal, Mapping, Optional
2
+
3
+ import pydantic
4
+
5
+ from classiq.interface.generator.expressions.qmod_qstruct_proxy import QmodQStructProxy
6
+ from classiq.interface.generator.functions.classical_type import (
7
+ ClassicalType,
8
+ )
9
+ from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
10
+ from classiq.interface.model.handle_binding import FieldHandleBinding, HandleBinding
11
+ from classiq.interface.model.quantum_type import (
12
+ QuantumType,
13
+ )
14
+
15
+ if TYPE_CHECKING:
16
+ from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
17
+
18
+ from classiq.qmod.qmod_variable import QStruct
19
+
20
+
21
+ class TypeName(ClassicalType, QuantumType): # type:ignore[misc]
22
+ kind: Literal["struct_instance"]
23
+ name: str = pydantic.Field(description="The type name of the instance")
24
+ _assigned_fields: Optional[Mapping[str, "ConcreteQuantumType"]] = (
25
+ pydantic.PrivateAttr(default=None)
26
+ )
27
+
28
+ @pydantic.root_validator(pre=True)
29
+ def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
30
+ return values_with_discriminator(values, "kind", "struct_instance")
31
+
32
+ @property
33
+ def qmod_type(self) -> type:
34
+ return type(self.name, (TypeName,), dict())
35
+
36
+ def _update_size_in_bits_from_declaration(self) -> None:
37
+ fields_types = list(self.fields.values())
38
+ for field_type in fields_types:
39
+ field_type._update_size_in_bits_from_declaration()
40
+ if all(field_type.has_size_in_bits for field_type in fields_types):
41
+ self._size_in_bits = sum(
42
+ field_type.size_in_bits for field_type in fields_types
43
+ )
44
+
45
+ def get_proxy(self, handle: "HandleBinding") -> "QmodQStructProxy":
46
+ from classiq.interface.generator.expressions.qmod_qstruct_proxy import (
47
+ QmodQStructProxy,
48
+ )
49
+
50
+ return QmodQStructProxy(
51
+ handle=handle, struct_name=self.name, fields=self.fields
52
+ )
53
+
54
+ @property
55
+ def qmod_type_name(self) -> str:
56
+ return self.name
57
+
58
+ @property
59
+ def type_name(self) -> str:
60
+ return self.name
61
+
62
+ def to_qvar(self, origin: HandleBinding) -> "QStruct":
63
+ from classiq.qmod.qmod_variable import QStruct
64
+
65
+ return QStruct(
66
+ origin,
67
+ self.name,
68
+ {
69
+ field_name: field_type.to_qvar(
70
+ FieldHandleBinding(base_handle=origin, field=field_name)
71
+ )
72
+ for field_name, field_type in self.fields.items()
73
+ },
74
+ )
75
+
76
+ @property
77
+ def fields(self) -> Mapping[str, "ConcreteQuantumType"]:
78
+ from classiq.qmod.model_state_container import QMODULE
79
+
80
+ if self._assigned_fields is None:
81
+ qstruct_fields = QMODULE.qstruct_decls[self.name].fields
82
+ self._assigned_fields = {
83
+ field_name: field_type.copy()
84
+ for field_name, field_type in qstruct_fields.items()
85
+ }
86
+
87
+ return self._assigned_fields
88
+
89
+ def _set_fields(self, fields: Mapping[str, "ConcreteQuantumType"]) -> None:
90
+ from classiq.qmod.model_state_container import QMODULE
91
+
92
+ QMODULE.qstruct_decls[self.name].fields = fields
93
+
94
+
95
+ class Enum(TypeName):
96
+ pass
97
+
98
+
99
+ class Struct(TypeName):
100
+ @property
101
+ def qmod_type(self) -> type:
102
+ type_ = super().qmod_type
103
+ type_.__dataclass_fields__ = [] # type:ignore[attr-defined]
104
+ return type_
@@ -21,7 +21,7 @@ VISUALIZATION_HIDE_LIST = [
21
21
  "control",
22
22
  "mcx",
23
23
  "iteration",
24
- "operand",
24
+ "stmt_block",
25
25
  ]
26
26
 
27
27
 
@@ -94,9 +94,9 @@ class GeneratedCircuitData(pydantic.BaseModel):
94
94
  return cls(width=0)
95
95
 
96
96
 
97
- class FunctionDebugInfo(pydantic.BaseModel):
97
+ class FunctionDebugInfoInterface(pydantic.BaseModel):
98
98
  generated_function: Optional[GeneratedFunction]
99
- children: List["FunctionDebugInfo"]
99
+ children: List["FunctionDebugInfoInterface"]
100
100
  relative_qubits: Tuple[int, ...]
101
101
  absolute_qubits: Optional[Tuple[int, ...]]
102
102
  is_basis_gate: Optional[bool]
@@ -7,9 +7,11 @@ from classiq.interface.executor.execution_preferences import ExecutionPreference
7
7
  from classiq.interface.generator.constant import Constant
8
8
  from classiq.interface.generator.function_params import ArithmeticIODict
9
9
  from classiq.interface.generator.types.enum_declaration import EnumDeclaration
10
+ from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
10
11
  from classiq.interface.generator.types.struct_declaration import StructDeclaration
11
12
  from classiq.interface.helpers.validation_helpers import is_list_unique
12
13
  from classiq.interface.helpers.versioned_model import VersionedModel
14
+ from classiq.interface.model.quantum_type import RegisterQuantumTypeDict
13
15
 
14
16
  from classiq.exceptions import ClassiqValueError
15
17
 
@@ -33,6 +35,11 @@ class ClassiqBaseModel(VersionedModel, ABC):
33
35
  description="user-defined structs",
34
36
  )
35
37
 
38
+ qstructs: List[QStructDeclaration] = pydantic.Field(
39
+ default_factory=list,
40
+ description="user-defined quantum structs",
41
+ )
42
+
36
43
  constants: List[Constant] = pydantic.Field(
37
44
  default_factory=list,
38
45
  )
@@ -58,3 +65,7 @@ class ExecutionModel(ClassiqBaseModel):
58
65
  description="Mapping between a measured register name and its arithmetic type",
59
66
  default_factory=dict,
60
67
  )
68
+ circuit_output_types: RegisterQuantumTypeDict = pydantic.Field(
69
+ description="Mapping between a measured register name and its qmod type",
70
+ default=dict(),
71
+ )
@@ -127,6 +127,11 @@ class Preferences(pydantic.BaseModel, extra=pydantic.Extra.forbid):
127
127
  "transpiled circuit and its depth",
128
128
  )
129
129
 
130
+ solovay_kitaev_max_iterations: Optional[pydantic.PositiveInt] = pydantic.Field(
131
+ None,
132
+ description="Maximum iterations for the Solovay-Kitaev algorithm (if applied).",
133
+ )
134
+
130
135
  timeout_seconds: pydantic.PositiveInt = pydantic.Field(
131
136
  default=300, description="Generation timeout in seconds"
132
137
  )
@@ -18,6 +18,7 @@ from typing import (
18
18
  Tuple,
19
19
  Union,
20
20
  )
21
+ from uuid import UUID, uuid4
21
22
 
22
23
  import pydantic
23
24
  from pydantic import BaseModel, Extra
@@ -150,6 +151,8 @@ class SynthesisQuantumFunctionCall(BaseModel):
150
151
  "If not set, determined automatically.",
151
152
  )
152
153
 
154
+ uuid: UUID = pydantic.Field(default_factory=uuid4)
155
+
153
156
  def __eq__(self, other: Any) -> bool:
154
157
  return (
155
158
  isinstance(other, SynthesisQuantumFunctionCall) and self.name == other.name
@@ -17,7 +17,7 @@ from classiq.interface.generator.circuit_code.types_and_constants import (
17
17
  CodeAndSyntax,
18
18
  )
19
19
  from classiq.interface.generator.generated_circuit_data import (
20
- FunctionDebugInfo,
20
+ FunctionDebugInfoInterface,
21
21
  GeneratedCircuitData,
22
22
  )
23
23
  from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
@@ -59,7 +59,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
59
59
  transpiled_circuit: Optional[TranspiledCircuitData]
60
60
  creation_time: str = pydantic.Field(default_factory=datetime.utcnow().isoformat)
61
61
  synthesis_duration: Optional[SynthesisStepDurations]
62
- debug_info: Optional[List[FunctionDebugInfo]]
62
+ debug_info: Optional[List[FunctionDebugInfoInterface]]
63
63
  program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
64
64
 
65
65
  def _hardware_agnostic_program_code(self) -> CodeAndSyntax:
@@ -10,6 +10,7 @@ class RegisterRole(StrEnum):
10
10
  ZERO_INPUT = "zero_input"
11
11
  ZERO_OUTPUT = "zero_output"
12
12
  GARBAGE_OUTPUT = "garbage_output"
13
+ EXPLICIT_ZERO_INPUT = "explicit_zero_input"
13
14
 
14
15
  @staticmethod
15
16
  def output_roles(include_garbage: bool = False) -> Set["RegisterRole"]:
@@ -24,4 +25,9 @@ class RegisterRole(StrEnum):
24
25
 
25
26
  @staticmethod
26
27
  def input_roles() -> Set["RegisterRole"]:
27
- return {RegisterRole.INPUT, RegisterRole.ZERO_INPUT, RegisterRole.AUXILIARY}
28
+ return {
29
+ RegisterRole.INPUT,
30
+ RegisterRole.ZERO_INPUT,
31
+ RegisterRole.AUXILIARY,
32
+ RegisterRole.EXPLICIT_ZERO_INPUT,
33
+ }
@@ -1,11 +1,9 @@
1
- from typing import Dict, Final, Optional, Set
1
+ from typing import Dict, Optional, Set
2
2
 
3
3
  import pydantic
4
4
 
5
5
  from classiq.interface.backend.pydantic_backend import PydanticExecutionParameter
6
6
 
7
- CPARAM_EXECUTION_SUFFIX: Final[str] = "_param"
8
-
9
7
 
10
8
  class FunctionExecutionData(pydantic.BaseModel):
11
9
  power_parameter: Optional[PydanticExecutionParameter] = pydantic.Field(default=None)
@@ -2,10 +2,9 @@ import functools
2
2
 
3
3
  from classiq.interface.generator.functions.classical_type import (
4
4
  ClassicalList,
5
- Enum,
6
5
  Real,
7
- Struct,
8
6
  )
7
+ from classiq.interface.generator.functions.type_name import Enum, Struct
9
8
  from classiq.interface.generator.types.struct_declaration import StructDeclaration
10
9
  from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
11
10
 
@@ -0,0 +1,17 @@
1
+ from typing import TYPE_CHECKING, Mapping
2
+
3
+ import pydantic
4
+
5
+ from classiq.interface.ast_node import HashableASTNode
6
+
7
+ if TYPE_CHECKING:
8
+ from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
9
+
10
+
11
+ class QStructDeclaration(HashableASTNode):
12
+ name: str
13
+
14
+ fields: Mapping[str, "ConcreteQuantumType"] = pydantic.Field(
15
+ default_factory=dict,
16
+ description="Dictionary of field names and their quantum types",
17
+ )
@@ -3,7 +3,7 @@ from typing import Any, ClassVar, Dict, Mapping
3
3
  import pydantic
4
4
 
5
5
  from classiq.interface.ast_node import HashableASTNode
6
- from classiq.interface.generator.functions.classical_type import ConcreteClassicalType
6
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
7
7
 
8
8
  from classiq.exceptions import ClassiqValueError
9
9
 
@@ -1,4 +1,4 @@
1
- from typing import Hashable, List, Mapping, Optional
1
+ from typing import Hashable, List, Mapping
2
2
 
3
3
  from classiq.interface.helpers.pydantic_model_helpers import Nameable
4
4
 
@@ -16,19 +16,3 @@ def validate_nameables_mapping(
16
16
  raise ClassiqValueError(
17
17
  f"{declaration_type} declaration names should match the keys of their names."
18
18
  )
19
-
20
-
21
- def validate_nameables_no_overlap(
22
- left_nameables_dict: Optional[Mapping[str, Nameable]],
23
- right_nameables_dict: Optional[Mapping[str, Nameable]],
24
- left_declaration_type: str,
25
- right_declaration_type: str,
26
- ) -> Optional[str]:
27
- if left_nameables_dict is None or right_nameables_dict is None:
28
- return None
29
-
30
- matched_names = left_nameables_dict.keys() & right_nameables_dict.keys()
31
- if matched_names:
32
- return f"{left_declaration_type} declaration names overlap with {right_declaration_type} declaration names: {matched_names}"
33
-
34
- return None
@@ -9,8 +9,9 @@ from classiq._internals.enum_utils import StrEnum
9
9
 
10
10
 
11
11
  class OperationLevel(StrEnum):
12
- USER_DEFINED = "USER_DEFINED"
13
- ENGINE_GENERATED = "ENGINE_GENERATED"
12
+ QMOD_FUNCTION_CALL = "QMOD_CALL"
13
+ QMOD_STATEMENT = "QMOD_STATEMENT"
14
+ ENGINE_FUNCTION_CALL = "ENGINE_CALL"
14
15
  BASIS_GATE = "BASIS_GATE"
15
16
  UNKNOWN = "UNKNOWN"
16
17
 
@@ -41,6 +42,12 @@ class OperationLink(pydantic.BaseModel):
41
42
  qubits: Tuple[int, ...]
42
43
  type: str
43
44
 
45
+ class Config:
46
+ allow_mutation = False
47
+
48
+ def __hash__(self) -> int:
49
+ return hash((type(self), self.label, self.qubits, self.type))
50
+
44
51
 
45
52
  class OperationLinks(pydantic.BaseModel):
46
53
  inputs: List[OperationLink]
@@ -0,0 +1 @@
1
+ INTERFACE_VERSION = "2"