classiq 0.38.0__py3-none-any.whl → 0.40.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 (154) hide show
  1. classiq/__init__.py +22 -22
  2. classiq/_internals/api_wrapper.py +13 -1
  3. classiq/_internals/client.py +12 -2
  4. classiq/analyzer/analyzer.py +3 -1
  5. classiq/applications/__init__.py +1 -8
  6. classiq/applications/chemistry/__init__.py +6 -0
  7. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +1 -1
  8. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  9. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +25 -6
  10. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +1 -1
  11. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +1 -1
  12. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +2 -4
  13. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +13 -16
  14. classiq/{applications_model_constructors → applications}/combinatorial_helpers/pyomo_utils.py +4 -2
  15. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +3 -10
  16. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +4 -6
  17. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +3 -5
  18. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  19. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +4 -6
  20. classiq/applications/combinatorial_optimization/__init__.py +11 -3
  21. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +9 -10
  22. classiq/applications/finance/__init__.py +3 -2
  23. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +24 -14
  24. classiq/applications/grover/__init__.py +11 -0
  25. classiq/applications/libraries/qmci_library.py +35 -0
  26. classiq/applications/qsvm/__init__.py +5 -1
  27. classiq/execution/all_hardware_devices.py +13 -0
  28. classiq/executor.py +2 -1
  29. classiq/interface/_version.py +1 -1
  30. classiq/interface/analyzer/result.py +1 -5
  31. classiq/interface/applications/qsvm.py +4 -2
  32. classiq/interface/ast_node.py +23 -0
  33. classiq/interface/backend/backend_preferences.py +5 -5
  34. classiq/interface/backend/quantum_backend_providers.py +7 -7
  35. classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
  36. classiq/interface/executor/execution_preferences.py +4 -9
  37. classiq/interface/executor/execution_request.py +2 -37
  38. classiq/interface/executor/vqe_result.py +1 -1
  39. classiq/interface/generator/application_apis/chemistry_declarations.py +2 -4
  40. classiq/interface/generator/application_apis/finance_declarations.py +1 -1
  41. classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -0
  42. classiq/interface/generator/builtin_api_builder.py +0 -5
  43. classiq/interface/generator/constant.py +2 -3
  44. classiq/interface/generator/expressions/expression.py +2 -4
  45. classiq/interface/generator/expressions/qmod_qarray_proxy.py +82 -0
  46. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +22 -1
  47. classiq/interface/generator/expressions/qmod_sized_proxy.py +22 -0
  48. classiq/interface/generator/functions/__init__.py +2 -2
  49. classiq/interface/generator/functions/builtins/__init__.py +15 -0
  50. classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
  51. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +8 -6
  52. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +10 -4
  53. classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
  54. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +893 -319
  55. classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
  56. classiq/interface/generator/functions/classical_type.py +31 -21
  57. classiq/interface/generator/functions/function_declaration.py +2 -2
  58. classiq/interface/generator/hartree_fock.py +10 -2
  59. classiq/interface/generator/model/classical_main_validator.py +1 -1
  60. classiq/interface/generator/model/model.py +1 -1
  61. classiq/interface/generator/model/preferences/preferences.py +4 -2
  62. classiq/interface/generator/quantum_function_call.py +1 -1
  63. classiq/interface/generator/types/struct_declaration.py +2 -4
  64. classiq/interface/model/call_synthesis_data.py +3 -3
  65. classiq/interface/model/classical_if.py +13 -0
  66. classiq/interface/model/classical_parameter_declaration.py +2 -3
  67. classiq/interface/model/{quantum_if_operation.py → control.py} +39 -21
  68. classiq/interface/model/handle_binding.py +3 -2
  69. classiq/interface/model/invert.py +10 -0
  70. classiq/interface/model/model.py +2 -1
  71. classiq/interface/model/power.py +12 -0
  72. classiq/interface/model/quantum_function_call.py +9 -4
  73. classiq/interface/model/quantum_lambda_function.py +3 -9
  74. classiq/interface/model/quantum_statement.py +3 -2
  75. classiq/interface/model/quantum_type.py +8 -9
  76. classiq/interface/model/quantum_variable_declaration.py +2 -2
  77. classiq/interface/model/repeat.py +13 -0
  78. classiq/interface/model/resolvers/function_call_resolver.py +21 -0
  79. classiq/interface/model/statement_block.py +18 -4
  80. classiq/interface/model/validations/handles_validator.py +8 -12
  81. classiq/interface/model/within_apply_operation.py +4 -4
  82. classiq/interface/server/routes.py +0 -4
  83. classiq/qmod/__init__.py +6 -2
  84. classiq/qmod/builtins/classical_functions.py +34 -39
  85. classiq/qmod/builtins/functions.py +287 -300
  86. classiq/qmod/builtins/operations.py +217 -16
  87. classiq/qmod/builtins/structs.py +50 -48
  88. classiq/qmod/declaration_inferrer.py +30 -18
  89. classiq/qmod/native/expression_to_qmod.py +5 -4
  90. classiq/qmod/native/pretty_printer.py +48 -26
  91. classiq/qmod/qmod_constant.py +29 -5
  92. classiq/qmod/qmod_parameter.py +56 -34
  93. classiq/qmod/qmod_struct.py +2 -2
  94. classiq/qmod/qmod_variable.py +87 -43
  95. classiq/qmod/quantum_callable.py +8 -4
  96. classiq/qmod/quantum_expandable.py +25 -20
  97. classiq/qmod/quantum_function.py +29 -2
  98. classiq/qmod/symbolic.py +79 -69
  99. classiq/qmod/symbolic_expr.py +1 -1
  100. classiq/qmod/symbolic_type.py +1 -4
  101. classiq/qmod/utilities.py +29 -0
  102. {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/METADATA +1 -1
  103. {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/RECORD +122 -141
  104. classiq/applications/benchmarking/__init__.py +0 -9
  105. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  106. classiq/applications/numpy_utils.py +0 -37
  107. classiq/applications_model_constructors/__init__.py +0 -25
  108. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  109. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  110. classiq/builtin_functions/__init__.py +0 -43
  111. classiq/builtin_functions/amplitude_loading.py +0 -3
  112. classiq/builtin_functions/binary_ops.py +0 -1
  113. classiq/builtin_functions/exponentiation.py +0 -5
  114. classiq/builtin_functions/qpe.py +0 -4
  115. classiq/builtin_functions/qsvm.py +0 -7
  116. classiq/builtin_functions/range_types.py +0 -5
  117. classiq/builtin_functions/standard_gates.py +0 -1
  118. classiq/builtin_functions/state_preparation.py +0 -6
  119. classiq/builtin_functions/suzuki_trotter.py +0 -3
  120. classiq/interface/executor/error_mitigation.py +0 -6
  121. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  122. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py +0 -0
  123. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  124. classiq/model/__init__.py +0 -14
  125. classiq/model/composite_function_generator.py +0 -33
  126. classiq/model/function_handler.py +0 -462
  127. classiq/model/logic_flow.py +0 -149
  128. classiq/model/logic_flow_change_handler.py +0 -71
  129. classiq/model/model.py +0 -229
  130. classiq/quantum_functions/__init__.py +0 -17
  131. classiq/quantum_functions/annotation_parser.py +0 -205
  132. classiq/quantum_functions/decorators.py +0 -22
  133. classiq/quantum_functions/function_library.py +0 -181
  134. classiq/quantum_functions/function_parser.py +0 -74
  135. classiq/quantum_functions/quantum_function.py +0 -236
  136. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  137. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +0 -0
  138. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  139. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +0 -0
  140. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  141. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  142. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -0
  143. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  144. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  145. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +0 -0
  146. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  147. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +0 -0
  148. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +0 -0
  149. /classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +0 -0
  150. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  151. /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
  152. /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
  153. /classiq/{quantum_register.py → interface/model/quantum_register.py} +0 -0
  154. {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/WHEEL +0 -0
@@ -18,10 +18,10 @@ from classiq.interface.model.variable_declaration_statement import (
18
18
  VariableDeclarationStatement,
19
19
  )
20
20
 
21
- from classiq.applications_model_constructors.libraries.ampltitude_estimation_library import (
21
+ from classiq.applications.libraries.ampltitude_estimation_library import (
22
22
  AE_CLASSICAL_LIBRARY,
23
23
  )
24
- from classiq.applications_model_constructors.libraries.qmci_library import QMCI_LIBRARY
24
+ from classiq.applications.libraries.qmci_library import QMCI_LIBRARY
25
25
  from classiq.exceptions import ClassiqError
26
26
 
27
27
  _OUTPUT_VARIABLE_NAME = "result"
@@ -75,16 +75,26 @@ def construct_finance_model(
75
75
  },
76
76
  body=[
77
77
  VariableDeclarationStatement(name="unitary_port"),
78
+ QuantumFunctionCall(
79
+ function="allocate",
80
+ positional_args=[
81
+ Expression(expr=f"{num_unitary_qubits}"),
82
+ HandleBinding(name="unitary_port"),
83
+ ],
84
+ ),
85
+ QuantumFunctionCall(
86
+ function="allocate_num",
87
+ positional_args=[
88
+ Expression(expr=f"{phase_port_size}"),
89
+ Expression(expr="False"),
90
+ Expression(expr=f"{phase_port_size}"),
91
+ HandleBinding(name="phase_port"),
92
+ ],
93
+ ),
78
94
  QuantumFunctionCall(
79
95
  function="qmci",
80
- params={
81
- "num_phase_qubits": Expression(expr=f"{phase_port_size}"),
82
- "num_unitary_qubits": Expression(
83
- expr=f"{num_unitary_qubits}"
84
- ),
85
- },
86
96
  operands={
87
- "sp_op": QuantumLambdaFunction(
97
+ "space_transform": QuantumLambdaFunction(
88
98
  body=[
89
99
  QuantumFunctionCall(
90
100
  function=finance_function,
@@ -97,16 +107,16 @@ def construct_finance_model(
97
107
  ),
98
108
  },
99
109
  inouts={
100
- "func_port": HandleBinding(name="reg"),
101
- "obj_port": HandleBinding(name="ind"),
110
+ "func_port": HandleBinding(name="arg0"),
111
+ "obj_port": HandleBinding(name="arg1"),
102
112
  },
103
113
  ),
104
114
  ],
105
115
  ),
106
116
  },
107
- outputs={
108
- "phase_port": HandleBinding(name="phase_port"),
109
- "unitary_port": HandleBinding(name="unitary_port"),
117
+ inouts={
118
+ "phase": HandleBinding(name="phase_port"),
119
+ "packed_vars": HandleBinding(name="unitary_port"),
110
120
  },
111
121
  ),
112
122
  ],
@@ -0,0 +1,11 @@
1
+ from typing import List
2
+
3
+ from .grover_model_constructor import construct_grover_model
4
+
5
+ __all__ = [
6
+ "construct_grover_model",
7
+ ]
8
+
9
+
10
+ def __dir__() -> List[str]:
11
+ return __all__
@@ -0,0 +1,35 @@
1
+ from typing import cast
2
+
3
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
4
+
5
+ from classiq.qmod import ( # type:ignore[attr-defined]
6
+ QArray,
7
+ QBit,
8
+ QCallable,
9
+ QNum,
10
+ Z,
11
+ amplitude_estimation,
12
+ qfunc,
13
+ )
14
+
15
+
16
+ @qfunc
17
+ def qmci(
18
+ space_transform: QCallable[QArray[QBit], QBit],
19
+ phase: QNum,
20
+ packed_vars: QArray[QBit],
21
+ ) -> None:
22
+ amplitude_estimation(
23
+ lambda reg: Z(reg[reg.len - 1]),
24
+ lambda reg: space_transform(reg[0 : reg.len - 1], reg[reg.len - 1]),
25
+ phase,
26
+ packed_vars,
27
+ )
28
+
29
+
30
+ QMCI_LIBRARY = [
31
+ cast(
32
+ NativeFunctionDefinition,
33
+ qmci.create_model().function_dict["qmci"],
34
+ ),
35
+ ]
@@ -4,5 +4,9 @@ from classiq.interface.generator.expressions.enums.qsvm_feature_map_entanglement
4
4
 
5
5
  from ..qsvm import qsvm_data_generation
6
6
  from .qsvm import * # noqa: F403
7
+ from .qsvm_model_constructor import construct_qsvm_model
7
8
 
8
- __all__ = ["QSVMFeatureMapEntanglement"]
9
+ __all__ = [
10
+ "QSVMFeatureMapEntanglement",
11
+ "construct_qsvm_model",
12
+ ]
@@ -0,0 +1,13 @@
1
+ from typing import List
2
+
3
+ from classiq.interface.hardware import HardwareInformation
4
+
5
+ from classiq._internals import async_utils
6
+ from classiq._internals.api_wrapper import ApiWrapper
7
+
8
+
9
+ def get_all_hardware_devices() -> List[HardwareInformation]:
10
+ """
11
+ Returns a list of all hardware devices known to Classiq.
12
+ """
13
+ return async_utils.run(ApiWrapper.call_get_all_hardware_devices())
classiq/executor.py CHANGED
@@ -29,9 +29,10 @@ from classiq.interface.generator.quantum_program import QuantumProgram
29
29
  from classiq._internals.api_wrapper import ApiWrapper
30
30
  from classiq._internals.async_utils import syncify_function
31
31
  from classiq.execution.jobs import ExecutionJob
32
- from classiq.model.model import DEFAULT_RESULT_NAME
33
32
  from classiq.synthesis import SerializedQuantumProgram
34
33
 
34
+ DEFAULT_RESULT_NAME = "result"
35
+
35
36
  BatchExecutionResult: TypeAlias = Union[ExecutionDetails, BaseException]
36
37
  ProgramAndResult: TypeAlias = Tuple[QuantumCode, BatchExecutionResult]
37
38
  BackendPreferencesAndResult: TypeAlias = Tuple[
@@ -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.38.0'
6
+ SEMVER_VERSION = '0.40.0'
7
7
  VERSION = str(Version(SEMVER_VERSION))
@@ -2,7 +2,7 @@ from typing import Dict, List, Literal, Optional, Set, Tuple, Union
2
2
  from uuid import UUID
3
3
 
4
4
  import pydantic
5
- from pydantic import AnyHttpUrl, Field
5
+ from pydantic import Field
6
6
  from typing_extensions import Annotated
7
7
 
8
8
  from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
@@ -41,10 +41,6 @@ class QasmCode(pydantic.BaseModel):
41
41
  code: str
42
42
 
43
43
 
44
- class PreSignedS3Url(VersionedModel):
45
- url: AnyHttpUrl
46
-
47
-
48
44
  class AnalysisStatus(StrEnum):
49
45
  NONE = "none"
50
46
  SUCCESS = "success"
@@ -103,11 +103,13 @@ class QSVMData(VersionedModel):
103
103
  extra = "forbid"
104
104
 
105
105
  @pydantic.validator("data", pre=True)
106
- def set_data(cls, data):
106
+ def set_data(cls, data: Union[IterableType, ArrayLike]) -> list:
107
107
  return listify(data)
108
108
 
109
109
  @pydantic.validator("labels", pre=True)
110
- def set_labels(cls, labels):
110
+ def set_labels(
111
+ cls, labels: Optional[Union[IterableType, ArrayLike]]
112
+ ) -> Optional[list]:
111
113
  if labels is None:
112
114
  return None
113
115
  else:
@@ -0,0 +1,23 @@
1
+ from typing import Optional
2
+
3
+ import pydantic
4
+
5
+ from classiq.interface.helpers.hashable_pydantic_base_model import (
6
+ HashablePydanticBaseModel,
7
+ )
8
+
9
+
10
+ class SourceReference(pydantic.BaseModel):
11
+ start_line: int
12
+ start_column: int
13
+ end_line: int
14
+ end_column: int
15
+ file_name: Optional[str] = pydantic.Field(default=None)
16
+
17
+
18
+ class ASTNode(pydantic.BaseModel):
19
+ source_ref: Optional[SourceReference] = pydantic.Field(default=None)
20
+
21
+
22
+ class HashableASTNode(ASTNode, HashablePydanticBaseModel):
23
+ pass
@@ -12,8 +12,8 @@ from classiq.interface.backend.quantum_backend_providers import (
12
12
  AliceBobBackendNames,
13
13
  AmazonBraketBackendNames,
14
14
  AzureQuantumBackendNames,
15
- ClassiqAerBackendNames,
16
15
  ClassiqNvidiaBackendNames,
16
+ ClassiqSimulatorBackendNames,
17
17
  IonqBackendNames,
18
18
  OQCBackendNames,
19
19
  ProviderTypeVendor,
@@ -56,7 +56,7 @@ class BackendPreferences(BaseModel):
56
56
  return False
57
57
 
58
58
 
59
- AWS_DEFAULT_JOB_TIMEOUT_SECONDS = int(timedelta(minutes=5).total_seconds())
59
+ AWS_DEFAULT_JOB_TIMEOUT_SECONDS = int(timedelta(minutes=240).total_seconds())
60
60
 
61
61
 
62
62
  class AliceBobBackendPreferences(BackendPreferences):
@@ -221,13 +221,13 @@ def is_exact_simulator(backend_preferences: BackendPreferences) -> bool:
221
221
 
222
222
 
223
223
  def default_backend_preferences(
224
- backend_name: str = ClassiqAerBackendNames.AER_SIMULATOR,
224
+ backend_name: str = ClassiqSimulatorBackendNames.SIMULATOR,
225
225
  ) -> BackendPreferences:
226
226
  return ClassiqBackendPreferences(backend_name=backend_name)
227
227
 
228
228
 
229
229
  def backend_preferences_field(
230
- backend_name: str = ClassiqAerBackendNames.AER_SIMULATOR,
230
+ backend_name: str = ClassiqSimulatorBackendNames.SIMULATOR,
231
231
  ) -> Any:
232
232
  return pydantic.Field(
233
233
  default_factory=lambda: default_backend_preferences(backend_name),
@@ -252,7 +252,7 @@ __all__ = [
252
252
  "AzureCredential",
253
253
  "AzureQuantumBackendNames",
254
254
  "ClassiqBackendPreferences",
255
- "ClassiqAerBackendNames",
255
+ "ClassiqSimulatorBackendNames",
256
256
  "IBMBackendPreferences",
257
257
  "IBMBackendProvider",
258
258
  "AwsBackendPreferences",
@@ -31,11 +31,11 @@ class ProviderTypeVendor:
31
31
  OQC = Literal[ProviderVendor.OQC]
32
32
 
33
33
 
34
- class ClassiqAerBackendNames(StrEnum):
35
- AER_SIMULATOR = "aer_simulator"
36
- AER_SIMULATOR_STATEVECTOR = "aer_simulator_statevector"
37
- AER_SIMULATOR_DENSITY_MATRIX = "aer_simulator_density_matrix"
38
- AER_SIMULATOR_MATRIX_PRODUCT_STATE = "aer_simulator_matrix_product_state"
34
+ class ClassiqSimulatorBackendNames(StrEnum):
35
+ SIMULATOR = "simulator"
36
+ SIMULATOR_STATEVECTOR = "simulator_statevector"
37
+ SIMULATOR_DENSITY_MATRIX = "simulator_density_matrix"
38
+ SIMULATOR_MATRIX_PRODUCT_STATE = "simulator_matrix_product_state"
39
39
 
40
40
 
41
41
  class IonqBackendNames(StrEnum):
@@ -141,7 +141,7 @@ class ClassiqNvidiaBackendNames(StrEnum):
141
141
  SIMULATOR = "nvidia_state_vector_simulator"
142
142
 
143
143
 
144
- AllClassiqBackendNames = Union[ClassiqAerBackendNames, ClassiqNvidiaBackendNames]
144
+ AllClassiqBackendNames = Union[ClassiqSimulatorBackendNames, ClassiqNvidiaBackendNames]
145
145
 
146
146
 
147
147
  class GoogleNvidiaBackendNames(StrEnum):
@@ -166,7 +166,7 @@ EXACT_SIMULATORS = {
166
166
  AmazonBraketBackendNames.AMAZON_BRAKET_SV1,
167
167
  AmazonBraketBackendNames.AMAZON_BRAKET_TN1,
168
168
  AmazonBraketBackendNames.AMAZON_BRAKET_DM1,
169
- *ClassiqAerBackendNames,
169
+ *ClassiqSimulatorBackendNames,
170
170
  *ClassiqNvidiaBackendNames,
171
171
  }
172
172
 
@@ -3,6 +3,7 @@ from typing import Dict, Tuple
3
3
 
4
4
  import networkx as nx
5
5
  import pyomo.core as pyo
6
+ import pyomo.core.expr.numeric_expr as pyo_expr
6
7
 
7
8
  Node = int
8
9
  Edge = Tuple[Node, Node]
@@ -22,7 +23,9 @@ def build_mht_pyomo_model(
22
23
  if has_constraints:
23
24
 
24
25
  @model.Constraint(model.Nodes)
25
- def out_edges_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
26
+ def out_edges_rule(
27
+ model: pyo.ConcreteModel, idx: int
28
+ ) -> pyo_expr.ExpressionBase:
26
29
  out_nodes = [
27
30
  node_id for node_id in model.Nodes if [idx, node_id] in model.Arcs
28
31
  ]
@@ -32,7 +35,9 @@ def build_mht_pyomo_model(
32
35
  return pyo.Constraint.Feasible
33
36
 
34
37
  @model.Constraint(model.Nodes)
35
- def in_edges_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
38
+ def in_edges_rule(
39
+ model: pyo.ConcreteModel, idx: int
40
+ ) -> pyo_expr.ExpressionBase:
36
41
  in_nodes = [
37
42
  node_id for node_id in model.Nodes if [node_id, idx] in model.Arcs
38
43
  ]
@@ -41,7 +46,7 @@ def build_mht_pyomo_model(
41
46
  else:
42
47
  return pyo.Constraint.Feasible
43
48
 
44
- def obj_expression(model: pyo.ConcreteModel) -> pyo.ExpressionBase:
49
+ def obj_expression(model: pyo.ConcreteModel) -> pyo_expr.ExpressionBase:
45
50
  return sum(
46
51
  round(pubo_energy, _decimals)
47
52
  * math.prod(model.x[edge] for edge in pubo_edges)
@@ -10,8 +10,9 @@ from classiq.interface.backend.backend_preferences import (
10
10
  backend_preferences_field,
11
11
  )
12
12
  from classiq.interface.backend.pydantic_backend import MAX_EXECUTION_TIMEOUT_SECONDS
13
- from classiq.interface.backend.quantum_backend_providers import ClassiqAerBackendNames
14
- from classiq.interface.executor.error_mitigation import ErrorMitigationMethod
13
+ from classiq.interface.backend.quantum_backend_providers import (
14
+ ClassiqSimulatorBackendNames,
15
+ )
15
16
  from classiq.interface.executor.optimizer_preferences import (
16
17
  OptimizerPreferences,
17
18
  OptimizerType,
@@ -51,11 +52,6 @@ class ExecutionPreferences(pydantic.BaseModel):
51
52
  default_factory=None,
52
53
  description="Settings related to VQE execution.",
53
54
  )
54
- error_mitigation_method: Optional[ErrorMitigationMethod] = pydantic.Field(
55
- default=None,
56
- description="Error mitigation method. Currently supports complete and tensored "
57
- "measurement calibration.",
58
- )
59
55
  noise_properties: Optional[NoiseProperties] = pydantic.Field(
60
56
  default=None, description="Properties of the noise in the circuit"
61
57
  )
@@ -64,7 +60,7 @@ class ExecutionPreferences(pydantic.BaseModel):
64
60
  description="The random seed used for the execution",
65
61
  )
66
62
  backend_preferences: BackendPreferencesTypes = backend_preferences_field(
67
- backend_name=ClassiqAerBackendNames.AER_SIMULATOR
63
+ backend_name=ClassiqSimulatorBackendNames.SIMULATOR
68
64
  )
69
65
  num_shots: Optional[pydantic.PositiveInt] = pydantic.Field(default=None)
70
66
  transpile_to_hardware: TranspilationOption = pydantic.Field(
@@ -151,7 +147,6 @@ def _choose_original_or_optimizer_attribute(
151
147
 
152
148
  __all__ = [
153
149
  "ExecutionPreferences",
154
- "ErrorMitigationMethod",
155
150
  "NoiseProperties",
156
151
  "OptimizerPreferences",
157
152
  "OptimizerType",
@@ -1,21 +1,18 @@
1
1
  from datetime import datetime
2
- from typing import Any, Dict, List, Literal, Optional, Union
2
+ from typing import List, Literal, Optional, Union
3
3
 
4
4
  import pydantic
5
5
  from pydantic import BaseModel, Field
6
6
  from typing_extensions import Annotated
7
7
 
8
- from classiq.interface.backend.backend_preferences import IonqBackendPreferences
9
8
  from classiq.interface.executor.estimation import OperatorsEstimation
10
9
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
11
- from classiq.interface.executor.quantum_code import QuantumCode, QuantumInstructionSet
10
+ from classiq.interface.executor.quantum_code import QuantumCode
12
11
  from classiq.interface.generator.quantum_program import QuantumProgram
13
12
  from classiq.interface.helpers.custom_encoders import CUSTOM_ENCODERS
14
13
  from classiq.interface.helpers.versioned_model import VersionedModel
15
14
  from classiq.interface.jobs import JobStatus
16
15
 
17
- from classiq.exceptions import ClassiqValueError
18
-
19
16
 
20
17
  class QuantumProgramExecution(QuantumProgram):
21
18
  execution_type: Literal["quantum_program2"] = "quantum_program2"
@@ -42,38 +39,6 @@ class ExecutionRequest(BaseModel, json_encoders=CUSTOM_ENCODERS):
42
39
  description="preferences for the execution",
43
40
  )
44
41
 
45
- @pydantic.validator("preferences")
46
- def validate_ionq_backend(
47
- cls, preferences: ExecutionPreferences, values: Dict[str, Any]
48
- ) -> ExecutionPreferences:
49
- """
50
- This function implement the following check:
51
- BE \\ payload | IonQ program | Qasm program | Other
52
- --------------|--------------|--------------|------
53
- IonQ backend | V | V | X
54
- Other backend | X | V | V
55
- Since:
56
- - We can't execute non-programs on the IonQ backends
57
- - We can't execute IonQ programs on non-IonQ backends
58
- """
59
- quantum_program = values.get("execution_payload")
60
- is_ionq_backend = isinstance(
61
- preferences.backend_preferences, IonqBackendPreferences
62
- )
63
- if isinstance(quantum_program, QuantumCode):
64
- if (
65
- quantum_program.syntax == QuantumInstructionSet.IONQ
66
- and not is_ionq_backend
67
- ):
68
- raise ClassiqValueError("Can only execute IonQ code on IonQ backend.")
69
- else:
70
- # If we handle anything other than a program.
71
- if is_ionq_backend:
72
- raise ClassiqValueError(
73
- "IonQ backend supports only execution of QuantumPrograms"
74
- )
75
- return preferences
76
-
77
42
 
78
43
  class QuantumProgramExecutionRequest(ExecutionRequest):
79
44
  execution_payload: QuantumCodeExecution
@@ -63,7 +63,7 @@ class VQESolverResult(SolverResult, QmodPyObject):
63
63
  self.convergence_graph.show()
64
64
 
65
65
  @property
66
- def convergence_graph(self):
66
+ def convergence_graph(self) -> Image.Image:
67
67
  return Image.open(io.BytesIO(base64.b64decode(self.convergence_graph_str)))
68
68
 
69
69
  @property
@@ -24,9 +24,7 @@ from classiq.interface.model.quantum_function_declaration import (
24
24
  )
25
25
 
26
26
  MOLECULE_PROBLEM_PARAM = {"molecule_problem": Struct(name="MoleculeProblem")}
27
- MOLECULE_PROBLEM_SIZE = (
28
- "len(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'))"
29
- )
27
+ MOLECULE_PROBLEM_SIZE = "get_field(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'), 'len')"
30
28
  MOLECULE_PROBLEM_PORT = {
31
29
  "qbv": PortDeclaration(
32
30
  name="qbv",
@@ -40,7 +38,7 @@ MOLECULE_PROBLEM_PORT = {
40
38
  FOCK_HAMILTONIAN_PROBLEM_PARAM = {
41
39
  "fock_hamiltonian_problem": Struct(name="FockHamiltonianProblem")
42
40
  }
43
- FOCK_HAMILTONIAN_SIZE = "len(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'))"
41
+ FOCK_HAMILTONIAN_SIZE = "get_field(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'), 'len')"
44
42
 
45
43
  FOCK_HAMILTONIAN_PROBLEM_PORT = {
46
44
  "qbv": PortDeclaration(
@@ -31,7 +31,7 @@ class FinanceModelType(Enum):
31
31
 
32
32
 
33
33
  FINANCE_FUNCTION_PORT_SIZE_MAPPING: Mapping[FinanceModelType, str] = {
34
- FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') + len(get_field(finance_model, 'rhos')) + floor(log(sum(get_field(finance_model, 'loss')), 2)) + 1",
34
+ FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') + get_field(get_field(finance_model, 'rhos'), 'len') + floor(log(sum(get_field(finance_model, 'loss')), 2)) + 1",
35
35
  FinanceModelType.LogNormal: "get_field(finance_model, 'num_qubits')",
36
36
  }
37
37
 
@@ -10,6 +10,7 @@ from classiq.interface.generator.arith.ast_node_rewrite import AstNodeRewrite
10
10
  from classiq.interface.generator.expressions.sympy_supported_expressions import (
11
11
  SYMPY_SUPPORTED_EXPRESSIONS,
12
12
  )
13
+ from classiq.interface.generator.functions.classical_type import CLASSICAL_ATTRIBUTES
13
14
 
14
15
  from classiq.exceptions import ClassiqArithmeticError, ClassiqValueError
15
16
 
@@ -174,6 +175,7 @@ class ExpressionValidator(ast.NodeVisitor):
174
175
  if not (
175
176
  isinstance(node.value, ast.Name)
176
177
  and node.value.id in self._supported_attr_values
178
+ or node.attr in CLASSICAL_ATTRIBUTES.keys()
177
179
  ):
178
180
  raise ClassiqValueError(
179
181
  f"Attribute is not supported for value {node.value}"
@@ -4,15 +4,10 @@ from classiq.interface.generator.functions.classical_function_declaration import
4
4
  ClassicalFunctionDeclaration,
5
5
  )
6
6
  from classiq.interface.generator.types.struct_declaration import StructDeclaration
7
- from classiq.interface.model.quantum_function_declaration import (
8
- QuantumFunctionDeclaration,
9
- )
10
7
 
11
8
 
12
9
  def populate_builtin_declarations(decls: Iterable[Any]) -> None:
13
10
  for decl in decls:
14
- if isinstance(decl, QuantumFunctionDeclaration):
15
- QuantumFunctionDeclaration.BUILTIN_FUNCTION_DECLARATIONS[decl.name] = decl
16
11
  if isinstance(decl, ClassicalFunctionDeclaration):
17
12
  ClassicalFunctionDeclaration.FOREIGN_FUNCTION_DECLARATIONS[decl.name] = decl
18
13
  if isinstance(decl, StructDeclaration):
@@ -1,10 +1,9 @@
1
- import pydantic
2
-
1
+ from classiq.interface.ast_node import ASTNode
3
2
  from classiq.interface.generator.expressions.expression import Expression
4
3
  from classiq.interface.generator.functions.classical_type import ConcreteClassicalType
5
4
 
6
5
 
7
- class Constant(pydantic.BaseModel):
6
+ class Constant(ASTNode):
8
7
  name: str
9
8
  const_type: ConcreteClassicalType
10
9
  value: Expression
@@ -4,6 +4,7 @@ from typing import Any, Mapping, Optional, Type
4
4
  import pydantic
5
5
  from pydantic import PrivateAttr
6
6
 
7
+ from classiq.interface.ast_node import HashableASTNode
7
8
  from classiq.interface.generator.arith.arithmetic_expression_validator import (
8
9
  DEFAULT_SUPPORTED_FUNC_NAMES,
9
10
  )
@@ -17,14 +18,11 @@ from classiq.interface.generator.expressions.sympy_supported_expressions import
17
18
  SYMPY_SUPPORTED_EXPRESSIONS,
18
19
  )
19
20
  from classiq.interface.generator.function_params import validate_expression_str
20
- from classiq.interface.helpers.hashable_pydantic_base_model import (
21
- HashablePydanticBaseModel,
22
- )
23
21
 
24
22
  from classiq.exceptions import ClassiqError
25
23
 
26
24
 
27
- class Expression(HashablePydanticBaseModel):
25
+ class Expression(HashableASTNode):
28
26
  expr: str
29
27
  _evaluated_expr: Optional[EvaluatedExpression] = PrivateAttr(default=None)
30
28
 
@@ -0,0 +1,82 @@
1
+ from typing import Optional, Tuple, Union
2
+
3
+ from classiq.interface.generator.expressions.expression import Expression
4
+ from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
5
+ from classiq.interface.model.handle_binding import (
6
+ HandleBinding,
7
+ SlicedHandleBinding,
8
+ SubscriptHandleBinding,
9
+ )
10
+
11
+ from classiq.exceptions import ClassiqValueError
12
+
13
+ ILLEGAL_SLICING_STEP_MSG = "Slicing with a step of a quantum variable is not supported"
14
+ SLICE_OUT_OF_BOUNDS_MSG = "Slice end index out of bounds"
15
+ QARRAY_ELEMENT_NOT_SUBSCRIPTABLE = "Subscripting an element in QArray is illegal"
16
+
17
+
18
+ class QmodQArrayProxy(QmodSizedProxy):
19
+ def __init__(
20
+ self,
21
+ name: str,
22
+ size: int,
23
+ slice_: Optional[Tuple[int, int]] = None,
24
+ index_: Optional[int] = None,
25
+ ) -> None:
26
+ super().__init__(size)
27
+ self._name = name
28
+ self._slice = slice_
29
+ self._index = index_
30
+
31
+ def __getitem__(self, key: Union[slice, int]) -> "QmodQArrayProxy":
32
+ if self._index is not None:
33
+ raise ClassiqValueError(QARRAY_ELEMENT_NOT_SUBSCRIPTABLE)
34
+
35
+ new_index: Optional[int] = None
36
+
37
+ if isinstance(key, slice):
38
+ if key.step is not None:
39
+ raise ClassiqValueError(ILLEGAL_SLICING_STEP_MSG)
40
+ new_slice = self._get_new_slice(key.start, key.stop)
41
+ else:
42
+ new_slice = self._get_new_slice(key, key + 1)
43
+ new_index = new_slice[0]
44
+
45
+ if (self._slice is not None and new_slice[1] > self._slice[1]) or new_slice[
46
+ 1
47
+ ] > self._size:
48
+ raise ClassiqValueError(SLICE_OUT_OF_BOUNDS_MSG)
49
+
50
+ return QmodQArrayProxy(
51
+ self._name, self._size, slice_=new_slice, index_=new_index
52
+ )
53
+
54
+ def _get_new_slice(self, start: int, end: int) -> Tuple[int, int]:
55
+ if self._slice is not None:
56
+ return self._slice[0] + start, self._slice[0] + end
57
+ return start, end
58
+
59
+ @property
60
+ def index(self) -> Optional[int]:
61
+ return self._index
62
+
63
+ @property
64
+ def slice(self) -> Optional[Tuple[int, int]]:
65
+ return self._slice
66
+
67
+ @property
68
+ def handle(self) -> HandleBinding:
69
+ if self._index is not None:
70
+ return SubscriptHandleBinding(
71
+ name=self._name,
72
+ index=Expression(expr=str(self._index)),
73
+ )
74
+
75
+ if self._slice is not None:
76
+ return SlicedHandleBinding(
77
+ name=self._name,
78
+ start=Expression(expr=str(self._slice[0])),
79
+ end=Expression(expr=str(self._slice[1])),
80
+ )
81
+
82
+ return HandleBinding(name=self._name)