classiq 0.43.3__py3-none-any.whl → 0.45.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 (220) hide show
  1. classiq/__init__.py +8 -3
  2. classiq/_internals/api_wrapper.py +2 -2
  3. classiq/_internals/authentication/auth0.py +1 -1
  4. classiq/_internals/authentication/device.py +5 -1
  5. classiq/_internals/authentication/token_manager.py +5 -4
  6. classiq/_internals/client.py +5 -8
  7. classiq/_internals/config.py +1 -2
  8. classiq/_internals/host_checker.py +34 -13
  9. classiq/_internals/jobs.py +3 -3
  10. classiq/analyzer/analyzer.py +1 -1
  11. classiq/analyzer/analyzer_utilities.py +1 -1
  12. classiq/analyzer/rb.py +1 -1
  13. classiq/applications/chemistry/chemistry_model_constructor.py +13 -7
  14. classiq/applications/combinatorial_helpers/allowed_constraints.py +4 -1
  15. classiq/applications/combinatorial_helpers/arithmetic/isolation.py +1 -1
  16. classiq/applications/combinatorial_helpers/encoding_mapping.py +1 -1
  17. classiq/applications/combinatorial_helpers/encoding_utils.py +2 -1
  18. classiq/applications/combinatorial_helpers/optimization_model.py +1 -1
  19. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +1 -1
  20. classiq/applications/combinatorial_helpers/pyomo_utils.py +1 -2
  21. classiq/applications/combinatorial_helpers/transformations/encoding.py +1 -1
  22. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -4
  23. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +1 -1
  24. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -1
  25. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
  26. classiq/applications/finance/finance_model_constructor.py +4 -3
  27. classiq/applications/grover/grover_model_constructor.py +7 -5
  28. classiq/applications/hamiltonian/__init__.py +0 -0
  29. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  30. classiq/applications/qnn/circuit_utils.py +1 -1
  31. classiq/applications/qnn/datasets/dataset_base_classes.py +2 -1
  32. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  33. classiq/applications/qnn/qlayer.py +3 -2
  34. classiq/applications/qnn/torch_utils.py +2 -1
  35. classiq/applications/qsvm/qsvm_model_constructor.py +1 -1
  36. classiq/execution/execution_session.py +1 -1
  37. classiq/execution/jobs.py +5 -2
  38. classiq/interface/_version.py +1 -1
  39. classiq/interface/analyzer/cytoscape_graph.py +1 -2
  40. classiq/interface/analyzer/result.py +2 -3
  41. classiq/interface/ast_node.py +1 -18
  42. classiq/interface/backend/backend_preferences.py +11 -18
  43. classiq/interface/backend/ionq/ionq_quantum_program.py +1 -1
  44. classiq/interface/backend/pydantic_backend.py +0 -5
  45. classiq/interface/backend/quantum_backend_providers.py +4 -3
  46. classiq/interface/chemistry/fermionic_operator.py +1 -2
  47. classiq/interface/chemistry/ground_state_problem.py +2 -3
  48. classiq/interface/chemistry/molecule.py +1 -2
  49. classiq/interface/chemistry/operator.py +8 -10
  50. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  51. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +1 -1
  52. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  53. classiq/interface/debug_info/__init__.py +0 -0
  54. classiq/interface/debug_info/debug_info.py +32 -0
  55. classiq/{exceptions.py → interface/exceptions.py} +4 -0
  56. classiq/interface/executor/aws_execution_cost.py +2 -2
  57. classiq/interface/executor/execution_preferences.py +2 -47
  58. classiq/interface/executor/execution_result.py +1 -2
  59. classiq/interface/executor/optimizer_preferences.py +2 -3
  60. classiq/interface/executor/quantum_code.py +1 -2
  61. classiq/interface/executor/quantum_instruction_set.py +2 -2
  62. classiq/interface/executor/register_initialization.py +1 -2
  63. classiq/interface/executor/result.py +29 -14
  64. classiq/interface/finance/function_input.py +6 -11
  65. classiq/interface/generator/amplitude_loading.py +2 -3
  66. classiq/interface/generator/ansatz_library.py +1 -1
  67. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  68. classiq/interface/generator/application_apis/chemistry_declarations.py +78 -60
  69. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +19 -10
  70. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  71. classiq/interface/generator/application_apis/finance_declarations.py +37 -44
  72. classiq/interface/generator/application_apis/qsvm_declarations.py +21 -15
  73. classiq/interface/generator/arith/arithmetic.py +10 -8
  74. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +1 -2
  75. classiq/interface/generator/arith/arithmetic_expression_abc.py +22 -3
  76. classiq/interface/generator/arith/arithmetic_expression_parser.py +3 -4
  77. classiq/interface/generator/arith/arithmetic_expression_validator.py +1 -2
  78. classiq/interface/generator/arith/arithmetic_param_getters.py +1 -2
  79. classiq/interface/generator/arith/arithmetic_result_builder.py +15 -11
  80. classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
  81. classiq/interface/generator/arith/binary_ops.py +7 -7
  82. classiq/interface/generator/arith/endianness.py +1 -1
  83. classiq/interface/generator/arith/extremum_operations.py +44 -21
  84. classiq/interface/generator/arith/logical_ops.py +1 -2
  85. classiq/interface/generator/arith/register_user_input.py +1 -2
  86. classiq/interface/generator/arith/unary_ops.py +1 -2
  87. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  88. classiq/interface/generator/chemistry_function_params.py +1 -2
  89. classiq/interface/generator/circuit_code/circuit_code.py +1 -2
  90. classiq/interface/generator/circuit_code/types_and_constants.py +1 -2
  91. classiq/interface/generator/commuting_pauli_exponentiation.py +1 -2
  92. classiq/interface/generator/constant.py +1 -1
  93. classiq/interface/generator/control_state.py +1 -2
  94. classiq/interface/generator/custom_ansatz.py +1 -2
  95. classiq/interface/generator/expressions/atomic_expression_functions.py +1 -0
  96. classiq/interface/generator/expressions/enums/finance_functions.py +4 -5
  97. classiq/interface/generator/expressions/evaluated_expression.py +1 -2
  98. classiq/interface/generator/expressions/expression.py +1 -2
  99. classiq/interface/generator/expressions/expression_constants.py +3 -1
  100. classiq/interface/generator/expressions/non_symbolic_expr.py +1 -1
  101. classiq/interface/generator/expressions/qmod_qarray_proxy.py +53 -70
  102. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -7
  103. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +35 -0
  104. classiq/interface/generator/expressions/qmod_sized_proxy.py +1 -1
  105. classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
  106. classiq/interface/generator/function_params.py +2 -3
  107. classiq/interface/generator/functions/builtins/core_library/__init__.py +4 -2
  108. classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +41 -41
  109. classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +52 -42
  110. classiq/interface/generator/functions/builtins/open_lib_functions.py +1095 -3347
  111. classiq/interface/generator/functions/builtins/quantum_operators.py +9 -22
  112. classiq/interface/generator/functions/classical_function_declaration.py +14 -6
  113. classiq/interface/generator/functions/classical_type.py +7 -114
  114. classiq/interface/generator/functions/concrete_types.py +55 -0
  115. classiq/interface/generator/functions/function_declaration.py +10 -10
  116. classiq/interface/generator/functions/port_declaration.py +1 -2
  117. classiq/interface/generator/functions/type_name.py +80 -0
  118. classiq/interface/generator/generated_circuit_data.py +3 -3
  119. classiq/interface/generator/grover_diffuser.py +1 -2
  120. classiq/interface/generator/grover_operator.py +1 -2
  121. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +1 -2
  122. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +1 -2
  123. classiq/interface/generator/hardware/hardware_data.py +1 -2
  124. classiq/interface/generator/hardware_efficient_ansatz.py +2 -3
  125. classiq/interface/generator/hartree_fock.py +1 -2
  126. classiq/interface/generator/linear_pauli_rotations.py +1 -2
  127. classiq/interface/generator/mcmt_method.py +1 -1
  128. classiq/interface/generator/mcu.py +1 -2
  129. classiq/interface/generator/mcx.py +1 -2
  130. classiq/interface/generator/model/constraints.py +2 -3
  131. classiq/interface/generator/model/model.py +12 -2
  132. classiq/interface/generator/model/preferences/preferences.py +7 -3
  133. classiq/interface/generator/model/quantum_register.py +1 -2
  134. classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
  135. classiq/interface/generator/oracles/custom_oracle.py +1 -2
  136. classiq/interface/generator/oracles/oracle_abc.py +1 -2
  137. classiq/interface/generator/partitioned_register.py +1 -2
  138. classiq/interface/generator/piecewise_linear_amplitude_loading.py +1 -2
  139. classiq/interface/generator/preferences/optimization.py +1 -2
  140. classiq/interface/generator/qpe.py +1 -2
  141. classiq/interface/generator/qsvm.py +2 -3
  142. classiq/interface/generator/quantum_function_call.py +4 -2
  143. classiq/interface/generator/quantum_program.py +6 -7
  144. classiq/interface/generator/range_types.py +1 -1
  145. classiq/interface/generator/register_role.py +8 -2
  146. classiq/interface/generator/slice_parsing_utils.py +1 -2
  147. classiq/interface/generator/standard_gates/controlled_standard_gates.py +1 -2
  148. classiq/interface/generator/state_preparation/metrics.py +2 -3
  149. classiq/interface/generator/state_preparation/state_preparation.py +1 -2
  150. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +1 -3
  151. classiq/interface/generator/transpiler_basis_gates.py +1 -1
  152. classiq/interface/generator/types/builtin_enum_declarations.py +38 -45
  153. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +1 -2
  154. classiq/interface/generator/types/enum_declaration.py +1 -2
  155. classiq/interface/generator/types/qstruct_declaration.py +17 -0
  156. classiq/interface/generator/types/struct_declaration.py +2 -3
  157. classiq/interface/generator/ucc.py +1 -2
  158. classiq/interface/generator/unitary_gate.py +1 -2
  159. classiq/interface/generator/validations/flow_graph.py +1 -2
  160. classiq/interface/generator/validations/validator_functions.py +1 -2
  161. classiq/interface/hardware.py +1 -1
  162. classiq/interface/helpers/validation_helpers.py +2 -19
  163. classiq/interface/ide/visual_model.py +10 -4
  164. classiq/interface/interface_version.py +1 -0
  165. classiq/interface/jobs.py +2 -3
  166. classiq/interface/model/bind_operation.py +26 -7
  167. classiq/interface/model/classical_parameter_declaration.py +8 -5
  168. classiq/interface/model/control.py +5 -5
  169. classiq/interface/model/handle_binding.py +185 -12
  170. classiq/interface/model/inplace_binary_operation.py +17 -6
  171. classiq/interface/model/model.py +29 -7
  172. classiq/interface/model/native_function_definition.py +8 -4
  173. classiq/interface/model/parameter.py +13 -0
  174. classiq/interface/model/port_declaration.py +21 -4
  175. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +22 -8
  176. classiq/interface/model/quantum_expressions/arithmetic_operation.py +30 -6
  177. classiq/interface/model/quantum_expressions/quantum_expression.py +4 -9
  178. classiq/interface/model/quantum_function_call.py +136 -194
  179. classiq/interface/model/quantum_function_declaration.py +147 -165
  180. classiq/interface/model/quantum_lambda_function.py +23 -6
  181. classiq/interface/model/quantum_statement.py +34 -8
  182. classiq/interface/model/quantum_type.py +41 -11
  183. classiq/interface/model/quantum_variable_declaration.py +1 -1
  184. classiq/interface/model/statement_block.py +2 -0
  185. classiq/interface/model/validation_handle.py +8 -2
  186. classiq/interface/server/global_versions.py +4 -4
  187. classiq/interface/server/routes.py +2 -0
  188. classiq/interface/source_reference.py +59 -0
  189. classiq/qmod/__init__.py +2 -3
  190. classiq/qmod/builtins/classical_execution_primitives.py +1 -1
  191. classiq/qmod/builtins/functions.py +39 -11
  192. classiq/qmod/builtins/operations.py +172 -41
  193. classiq/qmod/classical_function.py +1 -1
  194. classiq/qmod/declaration_inferrer.py +102 -57
  195. classiq/qmod/expression_query.py +1 -1
  196. classiq/qmod/model_state_container.py +2 -0
  197. classiq/qmod/native/pretty_printer.py +71 -53
  198. classiq/qmod/pretty_print/pretty_printer.py +98 -52
  199. classiq/qmod/qfunc.py +11 -5
  200. classiq/qmod/qmod_constant.py +1 -1
  201. classiq/qmod/qmod_parameter.py +27 -4
  202. classiq/qmod/qmod_variable.py +405 -174
  203. classiq/qmod/quantum_callable.py +3 -3
  204. classiq/qmod/quantum_expandable.py +128 -68
  205. classiq/qmod/quantum_function.py +24 -5
  206. classiq/qmod/semantics/annotation.py +13 -15
  207. classiq/qmod/semantics/error_manager.py +36 -10
  208. classiq/qmod/semantics/static_semantics_visitor.py +164 -76
  209. classiq/qmod/semantics/validation/func_call_validation.py +43 -97
  210. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  211. classiq/qmod/semantics/validation/types_validation.py +108 -1
  212. classiq/qmod/symbolic.py +2 -1
  213. classiq/qmod/type_attribute_remover.py +32 -0
  214. classiq/qmod/utilities.py +26 -5
  215. classiq/{interface/ide/show.py → show.py} +1 -1
  216. {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/METADATA +3 -3
  217. {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/RECORD +219 -207
  218. classiq/qmod/qmod_struct.py +0 -13
  219. /classiq/{_internals → interface}/enum_utils.py +0 -0
  220. {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/WHEEL +0 -0
@@ -1,4 +1,4 @@
1
- from classiq._internals.enum_utils import StrEnum
1
+ from classiq.interface.enum_utils import StrEnum
2
2
 
3
3
 
4
4
  class UncomputationMethods(StrEnum):
@@ -4,6 +4,7 @@ from classiq.interface.chemistry.ground_state_problem import (
4
4
  CHEMISTRY_PROBLEMS_TYPE,
5
5
  GroundStateProblem,
6
6
  )
7
+ from classiq.interface.exceptions import ClassiqValueError
7
8
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
8
9
  from classiq.interface.generator.function_params import (
9
10
  DEFAULT_INPUT_NAME,
@@ -11,8 +12,6 @@ from classiq.interface.generator.function_params import (
11
12
  FunctionParams,
12
13
  )
13
14
 
14
- from classiq.exceptions import ClassiqValueError
15
-
16
15
 
17
16
  class ChemistryFunctionParams(FunctionParams):
18
17
  gs_problem: CHEMISTRY_PROBLEMS_TYPE
@@ -2,6 +2,7 @@ from typing import Dict, Optional
2
2
 
3
3
  import pydantic
4
4
 
5
+ from classiq.interface.exceptions import ClassiqMissingOutputFormatError
5
6
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
6
7
  from classiq.interface.generator.circuit_code.types_and_constants import (
7
8
  INSTRUCTION_SET_TO_FORMAT,
@@ -12,8 +13,6 @@ from classiq.interface.generator.circuit_code.types_and_constants import (
12
13
  )
13
14
  from classiq.interface.generator.model.preferences.preferences import QuantumFormat
14
15
 
15
- from classiq.exceptions import ClassiqMissingOutputFormatError
16
-
17
16
 
18
17
  class CircuitCodeInterface(pydantic.BaseModel):
19
18
  outputs: Dict[QuantumFormat, Code]
@@ -2,12 +2,11 @@ from typing import Dict, Tuple
2
2
 
3
3
  from typing_extensions import TypeAlias
4
4
 
5
+ from classiq.interface.enum_utils import StrEnum
5
6
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
6
7
  from classiq.interface.generator.model.preferences.preferences import QuantumFormat
7
8
  from classiq.interface.hardware import Provider
8
9
 
9
- from classiq._internals.enum_utils import StrEnum
10
-
11
10
  Code: TypeAlias = str
12
11
  CodeAndSyntax: TypeAlias = Tuple[Code, QuantumInstructionSet]
13
12
 
@@ -2,6 +2,7 @@ import pydantic
2
2
 
3
3
  from classiq.interface.chemistry import operator
4
4
  from classiq.interface.chemistry.operator import PauliOperator
5
+ from classiq.interface.exceptions import ClassiqValueError
5
6
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
6
7
  from classiq.interface.generator.function_params import (
7
8
  DEFAULT_INPUT_NAME,
@@ -10,8 +11,6 @@ from classiq.interface.generator.function_params import (
10
11
  )
11
12
  from classiq.interface.generator.parameters import ParameterFloatType
12
13
 
13
- from classiq.exceptions import ClassiqValueError
14
-
15
14
 
16
15
  class CommutingPauliExponentiation(FunctionParams):
17
16
  """
@@ -1,6 +1,6 @@
1
1
  from classiq.interface.ast_node import ASTNode
2
2
  from classiq.interface.generator.expressions.expression import Expression
3
- from classiq.interface.generator.functions.classical_type import ConcreteClassicalType
3
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
4
4
 
5
5
 
6
6
  class Constant(ASTNode):
@@ -5,10 +5,9 @@ from typing import Any, Dict
5
5
  import pydantic
6
6
  from pydantic import BaseModel
7
7
 
8
+ from classiq.interface.exceptions import ClassiqValueError
8
9
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
9
10
 
10
- from classiq.exceptions import ClassiqValueError
11
-
12
11
  _DEFAULT_CONTROL_NAME: str = "ctrl"
13
12
  _DEFAULT_NUM_CONTROL_QUBITS = 1
14
13
  _INVALID_CONTROL_STATE = "invalid_control_state"
@@ -2,6 +2,7 @@ from typing import Dict, Type
2
2
 
3
3
  import pydantic
4
4
 
5
+ from classiq.interface.enum_utils import StrEnum
5
6
  from classiq.interface.generator.ansatz_library import (
6
7
  EntanglingLayersArgs,
7
8
  HypercubeArgs,
@@ -11,8 +12,6 @@ from classiq.interface.generator.ansatz_library import (
11
12
  TwoLocalArgs,
12
13
  )
13
14
 
14
- from classiq._internals.enum_utils import StrEnum
15
-
16
15
 
17
16
  class CustomAnsatzType(StrEnum):
18
17
  TwoLocal = "TwoLocal"
@@ -24,6 +24,7 @@ SUPPORTED_CLASSIQ_SYMPY_WRAPPERS = {
24
24
  "BitwiseXor",
25
25
  "BitwiseNot",
26
26
  "BitwiseOr",
27
+ "LogicalXor",
27
28
  }
28
29
 
29
30
  SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS = {
@@ -1,12 +1,11 @@
1
- from typing import TYPE_CHECKING, Dict
1
+ from typing import Dict
2
2
 
3
- if TYPE_CHECKING:
4
- from classiq.qmod.builtins.enums import FinanceFunctionType
3
+ from classiq.interface.generator.types.builtin_enum_declarations import (
4
+ FinanceFunctionType,
5
+ )
5
6
 
6
7
 
7
8
  def get_finance_function_dict() -> Dict[str, "FinanceFunctionType"]:
8
- from classiq.qmod.builtins.enums import FinanceFunctionType
9
-
10
9
  return {
11
10
  "var": FinanceFunctionType.VAR,
12
11
  "expected shortfall": FinanceFunctionType.SHORTFALL,
@@ -6,6 +6,7 @@ from sympy import Expr
6
6
  from typing_extensions import get_args
7
7
 
8
8
  from classiq.interface.backend.pydantic_backend import EXECUTION_PARAMETER_PATTERN
9
+ from classiq.interface.exceptions import ClassiqValueError
9
10
  from classiq.interface.generator.expressions.expression_types import (
10
11
  ExpressionValue,
11
12
  QmodStructInstance,
@@ -13,8 +14,6 @@ from classiq.interface.generator.expressions.expression_types import (
13
14
  )
14
15
  from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
15
16
 
16
- from classiq.exceptions import ClassiqValueError
17
-
18
17
 
19
18
  @dataclass(frozen=True)
20
19
  class EvaluatedExpression:
@@ -6,6 +6,7 @@ import pydantic
6
6
  from pydantic import PrivateAttr
7
7
 
8
8
  from classiq.interface.ast_node import HashableASTNode
9
+ from classiq.interface.exceptions import ClassiqError
9
10
  from classiq.interface.generator.arith.arithmetic_expression_validator import (
10
11
  DEFAULT_SUPPORTED_FUNC_NAMES,
11
12
  )
@@ -20,8 +21,6 @@ from classiq.interface.generator.expressions.sympy_supported_expressions import
20
21
  )
21
22
  from classiq.interface.generator.function_params import validate_expression_str
22
23
 
23
- from classiq.exceptions import ClassiqError
24
-
25
24
 
26
25
  class Expression(HashableASTNode):
27
26
  expr: str
@@ -1,5 +1,5 @@
1
1
  import keyword
2
- from typing import Set
2
+ from typing import Final, FrozenSet, Set
3
3
 
4
4
  from classiq.interface.generator.arith.arithmetic_expression_parser import (
5
5
  DEFAULT_SUPPORTED_FUNC_NAMES,
@@ -18,3 +18,5 @@ SUPPORTED_FUNC_NAMES: Set[str] = (
18
18
  )
19
19
  BOOLEAN_LITERALS = {"True", "False"}
20
20
  FORBIDDEN_LITERALS: Set[str] = set(keyword.kwlist) - SUPPORTED_FUNC_NAMES
21
+ CPARAM_EXECUTION_SUFFIX: Final[str] = "_param"
22
+ RESERVED_EXPRESSIONS: FrozenSet[str] = frozenset({"i"})
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import Any, NoReturn
4
4
 
5
- from classiq.exceptions import ClassiqArithmeticError
5
+ from classiq.interface.exceptions import ClassiqArithmeticError
6
6
 
7
7
 
8
8
  class NonSymbolicExpr:
@@ -1,5 +1,8 @@
1
- from typing import Any, Callable, Mapping, Optional, Tuple, Union
1
+ from typing import TYPE_CHECKING, Any, Mapping, Union
2
2
 
3
+ from sympy import Integer
4
+
5
+ from classiq.interface.exceptions import ClassiqValueError
3
6
  from classiq.interface.generator.expressions.expression import Expression
4
7
  from classiq.interface.generator.expressions.non_symbolic_expr import NonSymbolicExpr
5
8
  from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
@@ -9,109 +12,89 @@ from classiq.interface.model.handle_binding import (
9
12
  SubscriptHandleBinding,
10
13
  )
11
14
 
12
- from classiq.exceptions import ClassiqValueError
15
+ if TYPE_CHECKING:
16
+ from classiq.interface.model.quantum_type import QuantumType
17
+
13
18
 
14
19
  ILLEGAL_SLICING_STEP_MSG = "Slicing with a step of a quantum variable is not supported"
15
- SLICE_OUT_OF_BOUNDS_MSG = "Slice end index out of bounds"
16
- QARRAY_ELEMENT_NOT_SUBSCRIPTABLE = "Subscripting an element in QArray is illegal"
20
+ SLICE_OUT_OF_BOUNDS_MSG = "Slice indices out of bounds"
21
+ SUBSCRIPT_OUT_OF_BOUNDS_MSG = "Subscript index out of bounds"
22
+ ILLEGAL_SLICE_MSG = "Quantum array slice must be of the form [<int-value>:<int-value>]."
23
+ ILLEGAL_SLICE_BOUNDS_MSG = (
24
+ "The quantum array slice start value ({}) must be lower than its stop value ({})."
25
+ )
17
26
 
18
27
 
19
28
  class QmodQArrayProxy(NonSymbolicExpr, QmodSizedProxy):
20
29
  def __init__(
21
30
  self,
22
31
  handle: HandleBinding,
23
- element_proxy: Callable[[HandleBinding], QmodSizedProxy],
32
+ element_type: "QuantumType",
24
33
  element_size: int,
25
34
  length: int,
26
35
  ) -> None:
27
36
  super().__init__(handle, element_size * length)
28
37
  self._length = length
29
- self._element_proxy = element_proxy
38
+ self._element_type = element_type
30
39
  self._element_size = element_size
31
40
 
32
- def __getitem__(self, key: Union[slice, int]) -> "QmodSizedProxy":
33
- if self._index is not None:
34
- raise TypeError(QARRAY_ELEMENT_NOT_SUBSCRIPTABLE)
41
+ def __getitem__(self, key: Union[slice, int, Integer]) -> "QmodSizedProxy":
42
+ return (
43
+ self._get_slice(key) if isinstance(key, slice) else self._get_subscript(key)
44
+ )
35
45
 
36
- new_index: Optional[int] = None
46
+ def _get_subscript(self, index: Union[int, Integer]) -> "QmodSizedProxy":
47
+ if isinstance(index, Integer):
48
+ index = int(index)
49
+ if index < 0 or index >= self._length:
50
+ raise ClassiqValueError(SUBSCRIPT_OUT_OF_BOUNDS_MSG)
37
51
 
38
- if isinstance(key, slice):
39
- if key.step is not None:
40
- raise ClassiqValueError(ILLEGAL_SLICING_STEP_MSG)
41
- new_slice = self._get_new_slice(key.start, key.stop)
42
- else:
43
- new_slice = self._get_new_slice(key, key + 1)
44
- new_index = new_slice[0]
52
+ return self._element_type.get_proxy(
53
+ SubscriptHandleBinding(
54
+ base_handle=self.handle,
55
+ index=Expression(expr=str(index)),
56
+ )
57
+ )
45
58
 
46
- if (self._slice is not None and new_slice[1] > self._slice[1]) or new_slice[
47
- 1
48
- ] > self._size:
59
+ def _get_slice(self, slice_: slice) -> "QmodSizedProxy":
60
+ if slice_.step is not None:
61
+ raise ClassiqValueError(ILLEGAL_SLICING_STEP_MSG)
62
+ if isinstance(slice_.start, Integer):
63
+ slice_ = slice(int(slice_.start), slice_.stop)
64
+ if isinstance(slice_.stop, Integer):
65
+ slice_ = slice(slice_.start, int(slice_.stop))
66
+ if not isinstance(slice_.start, int) or not isinstance(slice_.stop, int):
67
+ raise ClassiqValueError(ILLEGAL_SLICE_MSG)
68
+ if slice_.start >= slice_.stop:
69
+ raise ClassiqValueError(
70
+ ILLEGAL_SLICE_BOUNDS_MSG.format(slice_.start, slice_.stop)
71
+ )
72
+ if slice_.start < 0 or slice_.stop > self._length:
49
73
  raise ClassiqValueError(SLICE_OUT_OF_BOUNDS_MSG)
50
74
 
51
- new_handle = self._get_new_handle(new_index, new_slice)
52
- if new_index is not None:
53
- return self._element_proxy(new_handle)
54
75
  return QmodQArrayProxy(
55
- new_handle,
56
- self._element_proxy,
76
+ SlicedHandleBinding(
77
+ base_handle=self.handle,
78
+ start=Expression(expr=str(slice_.start)),
79
+ end=Expression(expr=str(slice_.stop)),
80
+ ),
81
+ self._element_type,
57
82
  self._element_size,
58
- self._length,
83
+ slice_.stop - slice_.start,
59
84
  )
60
85
 
61
- def _get_new_slice(self, start: int, end: int) -> Tuple[int, int]:
62
- if self._slice is not None:
63
- return self._slice[0] + start, self._slice[0] + end
64
- return start, end
65
-
66
86
  @property
67
87
  def type_name(self) -> str:
68
88
  return "Quantum array"
69
89
 
70
- @property
71
- def _index(self) -> Optional[int]:
72
- if not isinstance(self._handle, SubscriptHandleBinding):
73
- return None
74
- return self._handle.index.to_int_value()
75
-
76
- @property
77
- def _slice(self) -> Optional[Tuple[int, int]]:
78
- if not isinstance(self._handle, SlicedHandleBinding):
79
- return None
80
- return self._handle.start.to_int_value(), self._handle.end.to_int_value()
81
-
82
- def _get_new_handle(
83
- self, new_index: Optional[int], new_slice: Tuple[int, int]
84
- ) -> HandleBinding:
85
- if new_index is not None:
86
- return SubscriptHandleBinding(
87
- name=self.handle.name,
88
- index=Expression(expr=str(new_index)),
89
- )
90
- return SlicedHandleBinding(
91
- name=self.handle.name,
92
- start=Expression(expr=str(new_slice[0])),
93
- end=Expression(expr=str(new_slice[1])),
94
- )
95
-
96
90
  @property
97
91
  def len(self) -> int:
98
92
  return self._length
99
93
 
100
94
  @property
101
95
  def fields(self) -> Mapping[str, Any]:
102
- return {
103
- "len": self.len,
104
- }
96
+ return {**super().fields, "len": self.len}
105
97
 
106
98
  @property
107
99
  def size(self) -> int:
108
- if (slice_ := self._slice) is not None:
109
- length = slice_[1] - slice_[0]
110
- elif self._index is not None:
111
- length = 1
112
- else:
113
- length = self._length
114
- return length * self._element_size
115
-
116
- def __str__(self) -> str:
117
- return str(self.handle)
100
+ return self.len * self._element_size
@@ -2,11 +2,10 @@ from typing import Any, Mapping
2
2
 
3
3
  from sympy import Symbol
4
4
 
5
+ from classiq.interface.exceptions import ClassiqValueError
5
6
  from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
6
7
  from classiq.interface.model.handle_binding import HandleBinding
7
8
 
8
- from classiq.exceptions import ClassiqValueError
9
-
10
9
 
11
10
  class QmodQScalarProxy(Symbol, QmodSizedProxy):
12
11
  def __new__(cls, handle: HandleBinding, **assumptions: bool) -> "QmodQScalarProxy":
@@ -42,10 +41,6 @@ class QmodQNumProxy(QmodQScalarProxy):
42
41
  def type_name(self) -> str:
43
42
  return "Quantum numeric"
44
43
 
45
- @property
46
- def size(self) -> int:
47
- return self._size
48
-
49
44
  @property
50
45
  def fraction_digits(self) -> int:
51
46
  return self._fraction_digits
@@ -57,7 +52,7 @@ class QmodQNumProxy(QmodQScalarProxy):
57
52
  @property
58
53
  def fields(self) -> Mapping[str, Any]:
59
54
  return {
60
- "size": self.size,
55
+ **super().fields,
61
56
  "is_signed": self.is_signed,
62
57
  "fraction_digits": self.fraction_digits,
63
58
  }
@@ -0,0 +1,35 @@
1
+ from typing import TYPE_CHECKING, Mapping
2
+
3
+ from classiq.interface.generator.expressions.non_symbolic_expr import NonSymbolicExpr
4
+ from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
5
+ from classiq.interface.model.handle_binding import (
6
+ FieldHandleBinding,
7
+ HandleBinding,
8
+ )
9
+
10
+ if TYPE_CHECKING:
11
+ from classiq.interface.model.quantum_type import QuantumType
12
+
13
+
14
+ class QmodQStructProxy(NonSymbolicExpr, QmodSizedProxy):
15
+ def __init__(
16
+ self,
17
+ handle: HandleBinding,
18
+ struct_name: str,
19
+ fields: Mapping[str, "QuantumType"],
20
+ ) -> None:
21
+ self._fields = {
22
+ name: type_.get_proxy(FieldHandleBinding(base_handle=handle, field=name))
23
+ for name, type_ in fields.items()
24
+ }
25
+ size = sum(proxy.size for proxy in self._fields.values())
26
+ super().__init__(handle, size)
27
+ self._struct_name = struct_name
28
+
29
+ @property
30
+ def type_name(self) -> str:
31
+ return self._struct_name
32
+
33
+ @property
34
+ def fields(self) -> Mapping[str, QmodSizedProxy]:
35
+ return {**super().fields, **self._fields}
@@ -30,4 +30,4 @@ class QmodSizedProxy:
30
30
 
31
31
  @property
32
32
  def fields(self) -> Mapping[str, Any]:
33
- return {}
33
+ return {"size": self._size}
@@ -66,7 +66,8 @@ NUMERIC_CONSTANTS: List[str] = [
66
66
  "EulerGamma",
67
67
  "Catalan",
68
68
  ]
69
- CONSTANTS: List[str] = NUMERIC_CONSTANTS + ["true", "false"]
69
+ BOOLEAN_CONSTANTS: List[str] = ["true", "false"]
70
+ CONSTANTS: List[str] = NUMERIC_CONSTANTS + BOOLEAN_CONSTANTS
70
71
 
71
72
  DATA_TYPES: List[str] = ["Matrix"]
72
73
  LOGIC_OPERATORS: List[str] = [
@@ -19,6 +19,8 @@ import pydantic
19
19
  import sympy
20
20
  from pydantic.fields import ModelField
21
21
 
22
+ from classiq.interface.enum_utils import StrEnum
23
+ from classiq.interface.exceptions import ClassiqValueError
22
24
  from classiq.interface.generator.arith.arithmetic_expression_validator import (
23
25
  validate_expression,
24
26
  )
@@ -28,9 +30,6 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
28
30
  HashablePydanticBaseModel,
29
31
  )
30
32
 
31
- from classiq._internals.enum_utils import StrEnum
32
- from classiq.exceptions import ClassiqValueError
33
-
34
33
  FunctionParamsDiscriminator = str
35
34
 
36
35
  IOName = PydanticNonEmptyString
@@ -3,12 +3,14 @@ from classiq.interface.generator.application_apis.combinatorial_optimization_dec
3
3
  from classiq.interface.generator.application_apis.finance_declarations import * # noqa: F403
4
4
  from classiq.interface.generator.application_apis.qsvm_declarations import * # noqa: F403
5
5
  from classiq.interface.model.quantum_function_declaration import (
6
- QuantumFunctionDeclaration,
6
+ NamedParamsQuantumFunctionDeclaration,
7
7
  )
8
8
 
9
9
  from .atomic_quantum_functions import * # noqa: F403
10
10
  from .exponentiation_functions import * # noqa: F403
11
11
 
12
12
  CORE_LIB_DECLS = [
13
- func for func in vars().values() if isinstance(func, QuantumFunctionDeclaration)
13
+ func
14
+ for func in vars().values()
15
+ if isinstance(func, NamedParamsQuantumFunctionDeclaration)
14
16
  ]