classiq 0.33.0__py3-none-any.whl → 0.34.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 (35) hide show
  1. classiq/_internals/api_wrapper.py +9 -20
  2. classiq/_internals/jobs.py +9 -2
  3. classiq/executor.py +3 -10
  4. classiq/interface/_version.py +1 -1
  5. classiq/interface/backend/backend_preferences.py +17 -0
  6. classiq/interface/backend/pydantic_backend.py +8 -0
  7. classiq/interface/backend/quantum_backend_providers.py +13 -1
  8. classiq/interface/chemistry/ground_state_problem.py +1 -1
  9. classiq/interface/chemistry/operator.py +198 -0
  10. classiq/interface/executor/execution_request.py +2 -12
  11. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +2 -2
  12. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +20 -110
  13. classiq/interface/generator/generated_circuit.py +8 -44
  14. classiq/interface/generator/generated_circuit_data.py +2 -11
  15. classiq/interface/generator/model/preferences/preferences.py +2 -2
  16. classiq/interface/generator/quantum_function_call.py +1 -1
  17. classiq/interface/hardware.py +1 -0
  18. classiq/interface/ide/show.py +1 -14
  19. classiq/interface/model/quantum_function_call.py +9 -339
  20. classiq/interface/model/quantum_statement.py +3 -2
  21. classiq/interface/server/routes.py +5 -6
  22. classiq/model/function_handler.pyi +88 -88
  23. classiq/qmod/declaration_inferrer.py +34 -17
  24. classiq/qmod/model_state_container.py +6 -3
  25. classiq/qmod/qmod_builtins.py +892 -4
  26. classiq/qmod/qmod_parameter.py +24 -8
  27. classiq/qmod/quantum_expandable.py +6 -2
  28. classiq/qmod/quantum_function.py +9 -9
  29. {classiq-0.33.0.dist-info → classiq-0.34.0.dist-info}/METADATA +1 -1
  30. {classiq-0.33.0.dist-info → classiq-0.34.0.dist-info}/RECORD +31 -35
  31. classiq/interface/model/clients/__init__.py +0 -0
  32. classiq/interface/model/clients/qmod/__init__.py +0 -0
  33. classiq/interface/model/clients/qmod/qmod_builtins.py +0 -905
  34. classiq/interface/model/semantics.py +0 -15
  35. {classiq-0.33.0.dist-info → classiq-0.34.0.dist-info}/WHEEL +0 -0
@@ -1,8 +1,7 @@
1
1
  import json
2
- from typing import Any, Dict, Optional, Protocol, Type, TypeVar, Union
2
+ from typing import Dict, Optional, Protocol, Type, TypeVar
3
3
 
4
4
  import pydantic
5
- from pydantic import parse_obj_as
6
5
 
7
6
  import classiq.interface.pyomo_extension # noqa: F401 - patches pyomo to add few features
8
7
  from classiq.interface.analyzer import analysis_params, result as analysis_result
@@ -19,10 +18,7 @@ from classiq._internals.enum_utils import StrEnum
19
18
  from classiq._internals.jobs import JobPoller
20
19
  from classiq.exceptions import ClassiqAPIError, ClassiqValueError
21
20
 
22
- _FAIL_FAST_INDICATOR = "{"
23
21
  ResultType = TypeVar("ResultType", bound=pydantic.BaseModel)
24
- OtherResultType = TypeVar("OtherResultType", bound=pydantic.BaseModel)
25
- _Circuit = Union[generator_result.GeneratedCircuit, generator_result.ExecutionCircuit]
26
22
 
27
23
 
28
24
  class HTTPMethod(StrEnum):
@@ -45,16 +41,6 @@ def _parse_job_response(
45
41
  return output_type.parse_obj(description)
46
42
 
47
43
 
48
- def _parse_job_response_multiple_outputs(
49
- job_result: JobDescription[JSONObject],
50
- output_type: Any, # UnionType in Python 3.10,
51
- ) -> Union[ResultType, OtherResultType]:
52
- description = job_result.description
53
- if job_result.status != JobStatus.COMPLETED:
54
- raise ClassiqAPIError(description["details"])
55
- return parse_obj_as(output_type, description)
56
-
57
-
58
44
  class ApiWrapper:
59
45
  @classmethod
60
46
  async def _call_task_pydantic(
@@ -82,15 +68,16 @@ class ApiWrapper:
82
68
  return res
83
69
 
84
70
  @classmethod
85
- async def call_generation_task(cls, model: ModelInput) -> _Circuit:
71
+ async def call_generation_task(
72
+ cls, model: ModelInput
73
+ ) -> generator_result.GeneratedCircuit:
86
74
  poller = JobPoller(base_url=routes.TASKS_GENERATE_FULL_PATH)
87
75
  result = await poller.run_pydantic(model, timeout_sec=None)
88
- return _parse_job_response_multiple_outputs(result, _Circuit)
76
+ return _parse_job_response(result, generator_result.GeneratedCircuit)
89
77
 
90
78
  @classmethod
91
79
  async def call_execute_generated_circuit(
92
- cls,
93
- circuit: _Circuit,
80
+ cls, circuit: generator_result.GeneratedCircuit
94
81
  ) -> execution_request.ExecutionJobDetails:
95
82
  data = await cls._call_task_pydantic(
96
83
  http_method=HTTPMethod.POST,
@@ -231,7 +218,9 @@ class ApiWrapper:
231
218
  async def call_generate_hamiltonian_task(
232
219
  cls, problem: ground_state_problem.CHEMISTRY_PROBLEMS_TYPE
233
220
  ) -> operator.PauliOperator:
234
- poller = JobPoller(base_url=routes.CHEMISTRY_GENERATE_HAMILTONIAN_FULL_PATH)
221
+ poller = JobPoller(
222
+ base_url=routes.GENERATE_HAMILTONIAN_FULL_PATH, use_versioned_url=False
223
+ )
235
224
  result = await poller.run_pydantic(problem, timeout_sec=None)
236
225
  return _parse_job_response(result, operator.PauliOperator)
237
226
 
@@ -52,11 +52,18 @@ class JobPoller:
52
52
  DEV_INTERVAL = 0.05
53
53
 
54
54
  def __init__(
55
- self, base_url: str, required_headers: Optional[Set[str]] = None
55
+ self,
56
+ base_url: str,
57
+ required_headers: Optional[Set[str]] = None,
58
+ use_versioned_url: bool = True,
56
59
  ) -> None:
57
60
  self._required_headers = required_headers or set()
58
61
  client_instance = client()
59
- self._base_url = client_instance.make_versioned_url(base_url)
62
+ self._base_url = (
63
+ client_instance.make_versioned_url(base_url)
64
+ if use_versioned_url
65
+ else base_url
66
+ )
60
67
  self._async_client = client_instance.async_client()
61
68
  self._mode = client_instance.config.mode
62
69
 
classiq/executor.py CHANGED
@@ -3,7 +3,6 @@ import functools
3
3
  from typing import Optional, Tuple, Union
4
4
 
5
5
  import more_itertools
6
- from pydantic import parse_raw_as
7
6
  from typing_extensions import TypeAlias
8
7
 
9
8
  from classiq.interface.backend.backend_preferences import BackendPreferencesTypes
@@ -19,10 +18,7 @@ from classiq.interface.executor.execution_request import (
19
18
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
20
19
  from classiq.interface.executor.quantum_program import MultipleArguments, QuantumProgram
21
20
  from classiq.interface.executor.result import ExecutionDetails
22
- from classiq.interface.generator.generated_circuit import (
23
- ExecutionCircuit,
24
- GeneratedCircuit,
25
- )
21
+ from classiq.interface.generator.generated_circuit import GeneratedCircuit
26
22
 
27
23
  from classiq._internals.api_wrapper import ApiWrapper
28
24
  from classiq._internals.async_utils import syncify_function
@@ -40,11 +36,8 @@ _MAX_ARGUMENTS_SIZE = 1024
40
36
 
41
37
  def _parse_serialized_qprog(
42
38
  quantum_program: SerializedQuantumProgram,
43
- ) -> Union[GeneratedCircuit, ExecutionCircuit]:
44
- return parse_raw_as(
45
- Union[GeneratedCircuit, ExecutionCircuit], # type:ignore[arg-type]
46
- quantum_program,
47
- )
39
+ ) -> GeneratedCircuit:
40
+ return GeneratedCircuit.parse_raw(quantum_program)
48
41
 
49
42
 
50
43
  async def execute_async(quantum_program: SerializedQuantumProgram) -> ExecutionJob:
@@ -3,5 +3,5 @@ from packaging.version import Version
3
3
  # This file was generated automatically
4
4
  # Please don't track in version control (DONTTRACK)
5
5
 
6
- SEMVER_VERSION = '0.33.0'
6
+ SEMVER_VERSION = '0.34.0'
7
7
  VERSION = str(Version(SEMVER_VERSION))
@@ -9,6 +9,7 @@ from pydantic import BaseModel, validator
9
9
  from classiq.interface.backend import pydantic_backend
10
10
  from classiq.interface.backend.quantum_backend_providers import (
11
11
  EXACT_SIMULATORS,
12
+ AliceBobBackendNames,
12
13
  AmazonBraketBackendNames,
13
14
  AzureQuantumBackendNames,
14
15
  ClassiqAerBackendNames,
@@ -55,6 +56,19 @@ class BackendPreferences(BaseModel):
55
56
  AWS_DEFAULT_JOB_TIMEOUT_SECONDS = int(timedelta(minutes=5).total_seconds())
56
57
 
57
58
 
59
+ class AliceBobBackendPreferences(BackendPreferences):
60
+ backend_service_provider: ProviderTypeVendor.ALICE_BOB
61
+ api_key: pydantic_backend.PydanticAliceBobApiKeyType = pydantic.Field(
62
+ ..., description="AliceBob API key"
63
+ )
64
+
65
+ @pydantic.root_validator(pre=True)
66
+ def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
67
+ return values_with_discriminator(
68
+ values, "backend_service_provider", ProviderVendor.ALICE_AND_BOB
69
+ )
70
+
71
+
58
72
  class ClassiqBackendPreferences(BackendPreferences):
59
73
  backend_service_provider: ProviderTypeVendor.CLASSIQ
60
74
 
@@ -214,6 +228,7 @@ BackendPreferencesTypes = Union[
214
228
  AwsBackendPreferences,
215
229
  IonqBackendPreferences,
216
230
  GCPBackendPreferences,
231
+ AliceBobBackendPreferences,
217
232
  ]
218
233
 
219
234
  __all__ = [
@@ -230,6 +245,8 @@ __all__ = [
230
245
  "IonqBackendNames",
231
246
  "ClassiqNvidiaBackendNames",
232
247
  "GCPBackendPreferences",
248
+ "AliceBobBackendPreferences",
249
+ "AliceBobBackendNames",
233
250
  ]
234
251
 
235
252
 
@@ -6,7 +6,9 @@ import pydantic
6
6
  AZURE_QUANTUM_RESOURCE_ID_REGEX = r"^/subscriptions/([a-fA-F0-9-]*)/resourceGroups/([^\s/]*)/providers/Microsoft\.Quantum/Workspaces/([^\s/]*)$"
7
7
 
8
8
  _IONQ_API_KEY_LENGTH: int = 32
9
+ _ALICE_BOB_API_KEY_LENGTH: int = 72
9
10
  INVALID_API_KEY: str = _IONQ_API_KEY_LENGTH * "a"
11
+ INVALID_API_KEY_ALICE_BOB: str = _ALICE_BOB_API_KEY_LENGTH * "a"
10
12
  MAX_EXECUTION_TIMEOUT_SECONDS = timedelta(hours=4).total_seconds()
11
13
 
12
14
  if TYPE_CHECKING:
@@ -18,6 +20,7 @@ if TYPE_CHECKING:
18
20
  PydanticIonQApiKeyType = str
19
21
  PydanticArgumentNameType = str
20
22
  PydanticExecutionParameter = str
23
+ PydanticAliceBobApiKeyType = str
21
24
  else:
22
25
  # TODO Simplify regular expressions in this file
23
26
 
@@ -32,6 +35,11 @@ else:
32
35
  PydanticIonQApiKeyType = pydantic.constr(
33
36
  regex=f"[A-Za-z0-9]{{{_IONQ_API_KEY_LENGTH}}}"
34
37
  )
38
+
39
+ PydanticAliceBobApiKeyType = pydantic.constr(
40
+ regex=f"[A-Za-z0-9]{{{_ALICE_BOB_API_KEY_LENGTH}}}"
41
+ )
42
+
35
43
  PydanticExecutionTimeout = pydantic.conint(gt=0, le=MAX_EXECUTION_TIMEOUT_SECONDS)
36
44
 
37
45
  PydanticArgumentNameType = pydantic.constr(regex="[_a-zA-Z][_a-zA-Z0-9]*")
@@ -16,6 +16,7 @@ class ProviderVendor(StrEnum):
16
16
  AMAZON_BRAKET = "Amazon Braket"
17
17
  IONQ = "IonQ"
18
18
  GOOGLE = "Google"
19
+ ALICE_AND_BOB = "Alice and Bob"
19
20
 
20
21
 
21
22
  class ProviderTypeVendor:
@@ -25,6 +26,7 @@ class ProviderTypeVendor:
25
26
  AMAZON_BRAKET = Literal[ProviderVendor.AMAZON_BRAKET]
26
27
  IONQ = Literal[ProviderVendor.IONQ]
27
28
  GOOGLE = Literal[ProviderVendor.GOOGLE]
29
+ ALICE_BOB = Literal[ProviderVendor.ALICE_AND_BOB]
28
30
 
29
31
 
30
32
  class ClassiqAerBackendNames(StrEnum):
@@ -143,6 +145,17 @@ class GoogleNvidiaBackendNames(StrEnum):
143
145
  CUQUANTUM = "cuquantum"
144
146
 
145
147
 
148
+ class AliceBobBackendNames(StrEnum):
149
+ PHYSICAL_CATS_40 = "EMU:40Q:PHYSICAL_CATS"
150
+ PERFECT_QUBITS = "EMU:20Q:PERFECT_QUBITS"
151
+ LOGICAL_TARGET = "EMU:40Q:LOGICAL_TARGET"
152
+ PHYSICAL_CATS_6 = "EMU:6Q:PHYSICAL_CATS"
153
+ LOGICAL_EARLY = "EMU:15Q:LOGICAL_EARLY"
154
+ LESCANNE = "EMU:1Q:LESCANNE_2020"
155
+ TRANSMONS = "EMU:7Q:TRANSMONS"
156
+ FATCAT = "QPU:1Q:FATCAT_0"
157
+
158
+
146
159
  EXACT_SIMULATORS = {
147
160
  IonqBackendNames.SIMULATOR,
148
161
  AzureQuantumBackendNames.IONQ_SIMULATOR,
@@ -156,7 +169,6 @@ EXACT_SIMULATORS = {
156
169
 
157
170
  AllIBMQBackendNames = IBMQHardwareNames
158
171
 
159
-
160
172
  AllBackendsNameByVendor = Union[
161
173
  AllIBMQBackendNames,
162
174
  AzureQuantumBackendNames,
@@ -64,7 +64,7 @@ class GroundStateProblem(HashablePydanticBaseModel):
64
64
 
65
65
 
66
66
  class MoleculeProblem(GroundStateProblem):
67
- molecule: Molecule = pydantic.Field(remove_hierarchy=True)
67
+ molecule: Molecule
68
68
  basis: str = pydantic.Field(default="sto3g", description="Molecular basis set")
69
69
  freeze_core: bool = pydantic.Field(default=False)
70
70
  remove_orbitals: List[int] = pydantic.Field(
@@ -224,6 +224,204 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
224
224
  frozen = True
225
225
 
226
226
 
227
+ class PauliOperatorV1(HashablePydanticBaseModel):
228
+ """
229
+ Specification of a Pauli sum operator.
230
+ """
231
+
232
+ pauli_list: PydanticPauliList = pydantic.Field(
233
+ description="A list of tuples each containing a pauli string comprised of I,X,Y,Z characters and a complex coefficient; for example [('IZ', 0.1), ('XY', 0.2)].",
234
+ )
235
+ is_hermitian: bool = pydantic.Field(default=False)
236
+ has_complex_coefficients: bool = pydantic.Field(default=True)
237
+
238
+ def show(self) -> str:
239
+ if self.is_hermitian:
240
+ # If the operator is hermitian then the coefficients must be numeric
241
+ return "\n".join(
242
+ f"{summand[1].real:+.3f} * {summand[0]}" for summand in self.pauli_list # type: ignore[union-attr]
243
+ )
244
+ return "\n".join(
245
+ f"+({summand[1]:+.3f}) * {summand[0]}" for summand in self.pauli_list
246
+ )
247
+
248
+ @pydantic.validator("pauli_list", each_item=True, pre=True)
249
+ def _validate_pauli_monomials(
250
+ cls, monomial: Tuple[PydanticPauliMonomialStr, ParameterComplexType]
251
+ ) -> Tuple[PydanticPauliMonomialStr, ParameterComplexType]:
252
+ _PauliMonomialLengthValidator( # type: ignore[call-arg]
253
+ monomial=monomial
254
+ ) # Validate the length of the monomial.
255
+ coeff = cls._validate_monomial_coefficient(monomial[1])
256
+ parsed_monomial = _PauliMonomialParser(string=monomial[0], coeff=coeff) # type: ignore[call-arg]
257
+ return (parsed_monomial.string, parsed_monomial.coeff)
258
+
259
+ @staticmethod
260
+ def _validate_monomial_coefficient(
261
+ coeff: Union[sympy.Expr, ParameterComplexType]
262
+ ) -> ParameterComplexType:
263
+ if isinstance(coeff, str):
264
+ validate_expression_str(coeff)
265
+ elif isinstance(coeff, sympy.Expr):
266
+ coeff = str(coeff)
267
+ return coeff
268
+
269
+ @pydantic.validator("pauli_list")
270
+ def _validate_pauli_list(cls, pauli_list: PydanticPauliList) -> PydanticPauliList:
271
+ if not all_equal(len(summand[0]) for summand in pauli_list):
272
+ raise ValueError("Pauli strings have incompatible lengths.")
273
+ return pauli_list
274
+
275
+ @pydantic.root_validator
276
+ def _validate_hermitianity(cls, values: Dict[str, Any]) -> Dict[str, Any]:
277
+ pauli_list = values.get("pauli_list", [])
278
+ if all(isinstance(summand[1], complex) for summand in pauli_list):
279
+ values["is_hermitian"] = all(
280
+ np.isclose(complex(summand[1]).real, summand[1])
281
+ for summand in pauli_list
282
+ )
283
+ if values.get("is_hermitian", False):
284
+ values["has_complex_coefficients"] = False
285
+ values["pauli_list"] = [
286
+ (summand[0], complex(summand[1].real)) for summand in pauli_list
287
+ ]
288
+ else:
289
+ values["has_complex_coefficients"] = not all(
290
+ np.isclose(complex(summand[1]).real, summand[1])
291
+ for summand in pauli_list
292
+ if isinstance(summand[1], complex)
293
+ )
294
+ return values
295
+
296
+ def __mul__(self, coefficient: complex) -> "PauliOperatorV1":
297
+ multiplied_ising = [
298
+ (monomial[0], self._multiply_monomial_coefficient(monomial[1], coefficient))
299
+ for monomial in self.pauli_list
300
+ ]
301
+ return self.__class__(pauli_list=multiplied_ising)
302
+
303
+ @staticmethod
304
+ def _multiply_monomial_coefficient(
305
+ monomial_coefficient: ParameterComplexType, coefficient: complex
306
+ ) -> ParameterComplexType:
307
+ if isinstance(monomial_coefficient, ParameterType):
308
+ return str(sympy.sympify(monomial_coefficient) * coefficient)
309
+ return monomial_coefficient * coefficient
310
+
311
+ @property
312
+ def is_commutative(self) -> bool:
313
+ return all(
314
+ self._is_sub_pauli_commutative(
315
+ [summand[0][qubit_num] for summand in self.pauli_list]
316
+ )
317
+ for qubit_num in range(self.num_qubits)
318
+ )
319
+
320
+ @staticmethod
321
+ def _is_sub_pauli_commutative(qubit_pauli_string: Union[List[str], str]) -> bool:
322
+ unique_paulis = set(qubit_pauli_string) - {"I"}
323
+ return len(unique_paulis) <= 1
324
+
325
+ @property
326
+ def num_qubits(self) -> int:
327
+ return len(self.pauli_list[0][0])
328
+
329
+ def to_matrix(self) -> np.ndarray:
330
+ if not all(isinstance(summand[1], complex) for summand in self.pauli_list):
331
+ raise ClassiqValueError(
332
+ "Supporting only Hamiltonian with numeric coefficients."
333
+ )
334
+ return sum(
335
+ cast(complex, summand[1]) * to_pauli_matrix(summand[0])
336
+ for summand in self.pauli_list
337
+ ) # type: ignore[return-value]
338
+
339
+ @staticmethod
340
+ def _extend_pauli_string(
341
+ pauli_string: PydanticPauliMonomialStr, num_extra_qubits: int
342
+ ) -> PydanticPauliMonomialStr:
343
+ return "I" * num_extra_qubits + pauli_string
344
+
345
+ def extend(self, num_extra_qubits: int) -> "PauliOperatorV1":
346
+ new_pauli_list = [
347
+ (self._extend_pauli_string(pauli_string, num_extra_qubits), coeff)
348
+ for (pauli_string, coeff) in self.pauli_list
349
+ ]
350
+ return self.copy(update={"pauli_list": new_pauli_list}, deep=True)
351
+
352
+ @staticmethod
353
+ def _reorder_pauli_string(
354
+ pauli_string: PydanticPauliMonomialStr,
355
+ order: Collection[int],
356
+ new_num_qubits: int,
357
+ ) -> PydanticPauliMonomialStr:
358
+ reversed_pauli_string = pauli_string[::-1]
359
+ reversed_new_pauli_string = ["I"] * new_num_qubits
360
+
361
+ for logical_pos, actual_pos in enumerate(order):
362
+ reversed_new_pauli_string[actual_pos] = reversed_pauli_string[logical_pos]
363
+
364
+ return "".join(reversed(reversed_new_pauli_string))
365
+
366
+ @staticmethod
367
+ def _validate_reorder(
368
+ order: Collection[int],
369
+ num_qubits: int,
370
+ num_extra_qubits: int,
371
+ ) -> None:
372
+ if num_extra_qubits < 0:
373
+ raise ValueError("Number of extra qubits cannot be negative")
374
+
375
+ if len(order) != num_qubits:
376
+ raise ValueError("The qubits order doesn't match the Pauli operator")
377
+
378
+ if len(order) != len(set(order)):
379
+ raise ValueError("The qubits order is not one-to-one")
380
+
381
+ if not all(pos < num_qubits + num_extra_qubits for pos in order):
382
+ raise ValueError("The qubits order contains qubits which do no exist")
383
+
384
+ @classmethod
385
+ def reorder(
386
+ cls,
387
+ operator: "PauliOperatorV1",
388
+ order: Collection[int],
389
+ num_extra_qubits: int = 0,
390
+ ) -> "PauliOperatorV1":
391
+ cls._validate_reorder(order, operator.num_qubits, num_extra_qubits)
392
+
393
+ new_num_qubits = operator.num_qubits + num_extra_qubits
394
+ new_pauli_list = [
395
+ (cls._reorder_pauli_string(pauli_string, order, new_num_qubits), coeff)
396
+ for pauli_string, coeff in operator.pauli_list
397
+ ]
398
+ return cls(pauli_list=new_pauli_list)
399
+
400
+ @classmethod
401
+ def from_unzipped_lists(
402
+ cls,
403
+ operators: List[List[Pauli]],
404
+ coefficients: Optional[List[complex]] = None,
405
+ ) -> "PauliOperatorV1":
406
+ if coefficients is None:
407
+ coefficients = [1] * len(operators)
408
+
409
+ if len(operators) != len(coefficients):
410
+ raise ValueError(
411
+ f"The number of coefficients ({len(coefficients)}) must be equal to the number of pauli operators ({len(operators)})"
412
+ )
413
+
414
+ return cls(
415
+ pauli_list=[
416
+ (pauli_integers_to_str(op), coeff)
417
+ for op, coeff in zip(operators, coefficients)
418
+ ]
419
+ )
420
+
421
+ class Config:
422
+ frozen = True
423
+
424
+
227
425
  # This class validates the length of a monomial.
228
426
  @pydantic.dataclasses.dataclass
229
427
  class _PauliMonomialLengthValidator:
@@ -15,10 +15,7 @@ from classiq.interface.executor.quantum_program import (
15
15
  )
16
16
  from classiq.interface.executor.result import EstimationResult, ExecutionDetails
17
17
  from classiq.interface.executor.vqe_result import VQESolverResult
18
- from classiq.interface.generator.generated_circuit import (
19
- ExecutionCircuit,
20
- GeneratedCircuit,
21
- )
18
+ from classiq.interface.generator.generated_circuit import GeneratedCircuit
22
19
  from classiq.interface.helpers.versioned_model import VersionedModel
23
20
  from classiq.interface.jobs import JobStatus
24
21
 
@@ -29,10 +26,6 @@ class GeneratedCircuitExecution(GeneratedCircuit):
29
26
  execution_type: Literal["generated_circuit"] = "generated_circuit"
30
27
 
31
28
 
32
- class BareGeneratedCircuitExecution(ExecutionCircuit):
33
- execution_type: Literal["bare_generated_circuit"] = "bare_generated_circuit"
34
-
35
-
36
29
  class QuantumProgramExecution(QuantumProgram):
37
30
  execution_type: Literal["quantum_program"] = "quantum_program"
38
31
 
@@ -42,10 +35,7 @@ class EstimateOperatorsExecution(OperatorsEstimation):
42
35
 
43
36
 
44
37
  ExecutionPayloads = Union[
45
- GeneratedCircuitExecution,
46
- BareGeneratedCircuitExecution,
47
- QuantumProgramExecution,
48
- EstimateOperatorsExecution,
38
+ GeneratedCircuitExecution, QuantumProgramExecution, EstimateOperatorsExecution
49
39
  ]
50
40
 
51
41
 
@@ -441,11 +441,11 @@ ADD_FUNCTION = QuantumFunctionDeclaration(
441
441
  port_declarations={
442
442
  "left": PortDeclaration(
443
443
  name="left",
444
- direction=PortDeclarationDirection.Input,
444
+ direction=PortDeclarationDirection.Inout,
445
445
  ),
446
446
  "right": PortDeclaration(
447
447
  name="right",
448
- direction=PortDeclarationDirection.Input,
448
+ direction=PortDeclarationDirection.Inout,
449
449
  ),
450
450
  "result": PortDeclaration(
451
451
  name="result",