classiq 0.42.2__py3-none-any.whl → 0.43.1__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 (113) hide show
  1. classiq/__init__.py +2 -6
  2. classiq/_internals/api_wrapper.py +6 -12
  3. classiq/_internals/authentication/token_manager.py +5 -2
  4. classiq/_internals/jobs.py +5 -10
  5. classiq/analyzer/rb.py +3 -3
  6. classiq/applications/chemistry/chemistry_model_constructor.py +12 -8
  7. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +2 -2
  8. classiq/applications/finance/finance_model_constructor.py +16 -13
  9. classiq/applications/qsvm/__init__.py +1 -3
  10. classiq/applications/qsvm/qsvm_model_constructor.py +7 -6
  11. classiq/exceptions.py +9 -4
  12. classiq/execution/execution_session.py +5 -2
  13. classiq/execution/qnn.py +1 -1
  14. classiq/executor.py +0 -2
  15. classiq/interface/_version.py +1 -1
  16. classiq/interface/chemistry/operator.py +19 -5
  17. classiq/interface/executor/constants.py +1 -0
  18. classiq/interface/finance/function_input.py +16 -10
  19. classiq/interface/generator/application_apis/chemistry_declarations.py +2 -2
  20. classiq/interface/generator/application_apis/qsvm_declarations.py +4 -2
  21. classiq/interface/generator/arith/argument_utils.py +20 -3
  22. classiq/interface/generator/arith/arithmetic_expression_validator.py +3 -26
  23. classiq/interface/generator/arith/binary_ops.py +8 -14
  24. classiq/interface/generator/arith/extremum_operations.py +30 -0
  25. classiq/interface/generator/arith/number_utils.py +1 -1
  26. classiq/interface/generator/arith/unary_ops.py +1 -3
  27. classiq/interface/generator/compiler_keywords.py +1 -1
  28. classiq/interface/generator/expressions/atomic_expression_functions.py +13 -3
  29. classiq/interface/generator/expressions/enums/__init__.py +0 -20
  30. classiq/interface/generator/expressions/enums/finance_functions.py +11 -18
  31. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  32. classiq/interface/generator/expressions/qmod_qarray_proxy.py +52 -37
  33. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +16 -11
  34. classiq/interface/generator/expressions/qmod_sized_proxy.py +5 -5
  35. classiq/interface/generator/function_param_list_without_self_reference.py +0 -10
  36. classiq/interface/generator/function_params.py +0 -4
  37. classiq/interface/generator/functions/__init__.py +0 -20
  38. classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +2 -2
  39. classiq/interface/generator/functions/builtins/open_lib_functions.py +530 -1
  40. classiq/interface/generator/functions/classical_type.py +22 -69
  41. classiq/interface/generator/functions/port_declaration.py +0 -11
  42. classiq/interface/generator/model/__init__.py +0 -1
  43. classiq/interface/generator/model/model.py +9 -185
  44. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -1
  45. classiq/interface/generator/types/builtin_enum_declarations.py +69 -0
  46. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +2 -2
  47. classiq/interface/generator/types/enum_declaration.py +57 -0
  48. classiq/interface/jobs.py +36 -65
  49. classiq/interface/model/bind_operation.py +3 -0
  50. classiq/interface/model/classical_parameter_declaration.py +3 -0
  51. classiq/interface/model/handle_binding.py +7 -0
  52. classiq/interface/model/inplace_binary_operation.py +13 -15
  53. classiq/interface/model/model.py +8 -20
  54. classiq/interface/model/native_function_definition.py +0 -17
  55. classiq/interface/model/quantum_function_call.py +63 -182
  56. classiq/interface/model/quantum_type.py +71 -10
  57. classiq/interface/server/routes.py +0 -6
  58. classiq/qmod/__init__.py +3 -3
  59. classiq/qmod/builtins/__init__.py +10 -1
  60. classiq/qmod/builtins/classical_execution_primitives.py +4 -2
  61. classiq/qmod/builtins/enums.py +177 -0
  62. classiq/qmod/builtins/functions.py +1 -2
  63. classiq/qmod/builtins/operations.py +2 -4
  64. classiq/qmod/builtins/structs.py +16 -17
  65. classiq/qmod/declaration_inferrer.py +23 -20
  66. classiq/qmod/model_state_container.py +2 -0
  67. classiq/qmod/native/pretty_printer.py +31 -13
  68. classiq/qmod/pretty_print/pretty_printer.py +52 -27
  69. classiq/qmod/qmod_constant.py +7 -3
  70. classiq/qmod/qmod_parameter.py +2 -1
  71. classiq/qmod/qmod_struct.py +9 -33
  72. classiq/qmod/qmod_variable.py +55 -22
  73. classiq/qmod/quantum_callable.py +6 -1
  74. classiq/qmod/quantum_expandable.py +29 -11
  75. classiq/qmod/quantum_function.py +8 -4
  76. classiq/qmod/semantics/annotation.py +38 -0
  77. classiq/qmod/semantics/error_manager.py +49 -0
  78. classiq/qmod/semantics/static_semantics_visitor.py +308 -0
  79. classiq/qmod/semantics/validation/func_call_validation.py +149 -0
  80. classiq/qmod/semantics/validation/types_validation.py +21 -0
  81. classiq/qmod/symbolic.py +6 -6
  82. classiq/qmod/symbolic_expr.py +26 -11
  83. classiq/qmod/utilities.py +23 -1
  84. {classiq-0.42.2.dist-info → classiq-0.43.1.dist-info}/METADATA +2 -2
  85. {classiq-0.42.2.dist-info → classiq-0.43.1.dist-info}/RECORD +88 -103
  86. classiq/_internals/_qfunc_ext.py +0 -6
  87. classiq/applications/libraries/ampltitude_estimation_library.py +0 -11
  88. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  89. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  90. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  91. classiq/interface/generator/expressions/enums/classical_enum.py +0 -20
  92. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -6
  93. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  94. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  95. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  96. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  97. classiq/interface/generator/functions/function_implementation.py +0 -107
  98. classiq/interface/generator/functions/native_function_definition.py +0 -155
  99. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  100. classiq/interface/generator/functions/register.py +0 -44
  101. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  102. classiq/interface/generator/inequality_mixer.py +0 -51
  103. classiq/interface/generator/model/classical_main_validator.py +0 -106
  104. classiq/interface/generator/range_mixer.py +0 -56
  105. classiq/interface/generator/state_propagator.py +0 -74
  106. classiq/interface/model/resolvers/function_call_resolver.py +0 -64
  107. classiq/interface/model/validations/__init__.py +0 -0
  108. classiq/interface/model/validations/handle_validation_base.py +0 -55
  109. classiq/interface/model/validations/handles_validator.py +0 -153
  110. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  111. /classiq/{interface/generator/credit_risk_example → qmod/semantics}/__init__.py +0 -0
  112. /classiq/{interface/model/resolvers → qmod/semantics/validation}/__init__.py +0 -0
  113. {classiq-0.42.2.dist-info → classiq-0.43.1.dist-info}/WHEEL +0 -0
@@ -12,11 +12,13 @@ from classiq.interface.generator.arith.register_user_input import (
12
12
  from classiq.interface.generator.expressions.expression import Expression
13
13
  from classiq.interface.generator.expressions.qmod_qarray_proxy import QmodQArrayProxy
14
14
  from classiq.interface.generator.expressions.qmod_qscalar_proxy import (
15
+ QmodQBitProxy,
15
16
  QmodQNumProxy,
16
17
  QmodQScalarProxy,
17
18
  )
18
19
  from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
19
20
  from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
21
+ from classiq.interface.model.handle_binding import HandleBinding
20
22
 
21
23
  from classiq.exceptions import ClassiqValueError
22
24
 
@@ -45,13 +47,21 @@ class QuantumType(HashableASTNode):
45
47
  def set_size_in_bits(self, val: int) -> None:
46
48
  self._size_in_bits = val
47
49
 
48
- def get_proxy(self, name: str) -> QmodSizedProxy:
49
- return QmodSizedProxy(size=self.size_in_bits)
50
+ def get_proxy(self, handle: "HandleBinding") -> QmodSizedProxy:
51
+ return QmodSizedProxy(handle=handle, size=self.size_in_bits)
52
+
53
+ @property
54
+ def qmod_type_name(self) -> str:
55
+ raise NotImplementedError
56
+
57
+ @property
58
+ def type_name(self) -> str:
59
+ return self.get_proxy(HandleBinding(name="DUMMY")).type_name
50
60
 
51
61
 
52
62
  class QuantumScalar(QuantumType):
53
- def get_proxy(self, name: str) -> QmodQScalarProxy:
54
- return QmodQScalarProxy(name, size=self.size_in_bits)
63
+ def get_proxy(self, handle: "HandleBinding") -> QmodQScalarProxy:
64
+ return QmodQScalarProxy(handle, size=self.size_in_bits)
55
65
 
56
66
 
57
67
  class QuantumBit(QuantumScalar):
@@ -65,9 +75,19 @@ class QuantumBit(QuantumScalar):
65
75
  def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
66
76
  return values_with_discriminator(values, "kind", "qbit")
67
77
 
78
+ @property
79
+ def qmod_type_name(self) -> str:
80
+ return "QBit"
81
+
82
+ def get_proxy(self, handle: "HandleBinding") -> QmodQBitProxy:
83
+ return QmodQBitProxy(handle)
84
+
68
85
 
69
86
  class QuantumBitvector(QuantumType):
70
87
  kind: Literal["qvec"]
88
+ element_type: "ConcreteQuantumType" = Field(
89
+ discriminator="kind", default_factory=QuantumBit
90
+ )
71
91
  length: Optional[Expression]
72
92
 
73
93
  @pydantic.root_validator(pre=True)
@@ -75,11 +95,41 @@ class QuantumBitvector(QuantumType):
75
95
  return values_with_discriminator(values, "kind", "qvec")
76
96
 
77
97
  def _update_size_in_bits_from_declaration(self) -> None:
78
- if self.length is not None and self.length.is_evaluated():
79
- self._size_in_bits = self.length.to_int_value()
98
+ self.element_type._update_size_in_bits_from_declaration()
99
+ if self.element_type.has_size_in_bits and self.has_length:
100
+ assert self.length is not None
101
+ self._size_in_bits = (
102
+ self.element_type.size_in_bits * self.length.to_int_value()
103
+ )
80
104
 
81
- def get_proxy(self, name: str) -> QmodQArrayProxy:
82
- return QmodQArrayProxy(name, self.size_in_bits)
105
+ @property
106
+ def has_length(self) -> bool:
107
+ return self.length is not None and self.length.is_evaluated()
108
+
109
+ @property
110
+ def length_value(self) -> int:
111
+ if not self.has_length:
112
+ raise ClassiqValueError(
113
+ "Tried to access unevaluated length of quantum array"
114
+ )
115
+ assert self.length is not None
116
+ return self.length.to_int_value()
117
+
118
+ def get_proxy(self, handle: "HandleBinding") -> QmodQArrayProxy:
119
+ element_size = self.element_type.size_in_bits
120
+ assert self.size_in_bits % element_size == 0
121
+ return QmodQArrayProxy(
122
+ handle,
123
+ self.element_type.get_proxy,
124
+ element_size,
125
+ self.size_in_bits // element_size,
126
+ )
127
+
128
+ @property
129
+ def qmod_type_name(self) -> str:
130
+ element_type = [self.element_type.qmod_type_name]
131
+ length = [self.length.expr] if self.length is not None else []
132
+ return f"QArray[{', '.join(element_type + length)}]"
83
133
 
84
134
 
85
135
  class QuantumNumeric(QuantumScalar):
@@ -125,19 +175,30 @@ class QuantumNumeric(QuantumScalar):
125
175
  if self.size is not None and self.size.is_evaluated():
126
176
  self._size_in_bits = self.size.to_int_value()
127
177
 
128
- def get_proxy(self, name: str) -> QmodQNumProxy:
178
+ def get_proxy(self, handle: "HandleBinding") -> QmodQNumProxy:
129
179
  return QmodQNumProxy(
130
- name,
180
+ handle,
131
181
  size=self.size_in_bits,
132
182
  fraction_digits=self.fraction_digits_value,
133
183
  is_signed=self.sign_value,
134
184
  )
135
185
 
186
+ @property
187
+ def qmod_type_name(self) -> str:
188
+ if (
189
+ self.size is not None
190
+ and self.is_signed is not None
191
+ and self.fraction_digits is not None
192
+ ):
193
+ return f"QNum[{self.size.expr}, {self.is_signed.expr}, {self.fraction_digits.expr}]"
194
+ return "QNum"
195
+
136
196
 
137
197
  ConcreteQuantumType = Annotated[
138
198
  Union[QuantumBit, QuantumBitvector, QuantumNumeric],
139
199
  Field(discriminator="kind", default_factory=QuantumBitvector),
140
200
  ]
201
+ QuantumBitvector.update_forward_refs()
141
202
 
142
203
 
143
204
  def register_info_to_quantum_type(reg_info: RegisterArithmeticInfo) -> QuantumNumeric:
@@ -39,8 +39,6 @@ TASKS_GENERATE_SUFFIX = TASKS_SUFFIX + "/generate"
39
39
  TASKS_VISUALIZE_SUFFIX = TASKS_SUFFIX + "/visualize"
40
40
  TASKS_VISUAL_MODEL_SUFFIX = TASKS_SUFFIX + "/visual_model"
41
41
  TASKS_SOLVE_SUFFIX = "/tasks/solve"
42
- MODEL_GENERATE_PREFIX = "/generate_model"
43
- CHEMISTRY_GENERATE_MODEL_PATH = MODEL_GENERATE_PREFIX + "/chemistry"
44
42
 
45
43
  CHEMISTRY_QMOD_PATH = "/generate_model/chemistry/qmod"
46
44
  GROVER_QMOD_PATH = "/generate_model/grover/qmod"
@@ -70,10 +68,6 @@ GENERATE_HAMILTONIAN_FULL_PATH = (
70
68
  SYNTHESIS_NON_VERSIONED_PREFIX + GENERATE_HAMILTONIAN_SUFFIX
71
69
  )
72
70
 
73
- FINANCE_GENERATE_MODEL_PATH = MODEL_GENERATE_PREFIX + "/finance"
74
-
75
- GROVER_GENERATE_MODEL_PATH = MODEL_GENERATE_PREFIX + "/grover"
76
-
77
71
  CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX = "/execution_input"
78
72
  CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_FULL = (
79
73
  CONVERSION_PREFIX + CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX
classiq/qmod/__init__.py CHANGED
@@ -26,11 +26,11 @@ __all__ = [
26
26
  "QCallable",
27
27
  "QCallableList",
28
28
  "QConstant",
29
- "struct",
30
- "qfunc",
31
29
  "cfunc",
32
30
  "create_model",
31
+ "get_expression_numeric_attributes",
32
+ "qfunc",
33
+ "struct",
33
34
  "symbolic",
34
35
  "write_qmod",
35
- "get_expression_numeric_attributes",
36
36
  ] + _builtins_all
@@ -1,9 +1,13 @@
1
+ from classiq.interface.finance.function_input import FinanceFunctionInput
2
+
1
3
  from .classical_execution_primitives import * # noqa: F403
2
4
  from .classical_execution_primitives import (
3
5
  __all__ as _builtin_classical_execution_primitives,
4
6
  )
5
7
  from .classical_functions import * # noqa: F403
6
8
  from .classical_functions import __all__ as _builtin_classical_functions
9
+ from .enums import * # noqa: F403
10
+ from .enums import __all__ as _builtin_enums
7
11
  from .functions import * # noqa: F403
8
12
  from .functions import __all__ as _builtin_functions
9
13
  from .operations import * # noqa: F403
@@ -11,8 +15,13 @@ from .operations import __all__ as _builtin_operations
11
15
  from .structs import * # noqa: F403
12
16
  from .structs import __all__ as _builtin_structs
13
17
 
18
+ FinanceFunctionInput.update_forward_refs(
19
+ FinanceFunctionType=FinanceFunctionType # noqa: F405
20
+ )
21
+
14
22
  __all__ = (
15
- _builtin_structs
23
+ _builtin_enums
24
+ + _builtin_structs
16
25
  + _builtin_functions
17
26
  + _builtin_operations
18
27
  + _builtin_classical_execution_primitives
@@ -1,4 +1,4 @@
1
- from typing import Dict, List, Optional, Union
1
+ from typing import Dict, Final, List, Optional, Union
2
2
 
3
3
  from classiq.interface.executor.execution_preferences import QaeWithQpeEstimationMethod
4
4
  from classiq.interface.executor.iqae_result import IQAEResult
@@ -9,11 +9,11 @@ from classiq.interface.executor.result import (
9
9
  MultipleExecutionDetails,
10
10
  )
11
11
  from classiq.interface.executor.vqe_result import VQESolverResult
12
- from classiq.interface.generator.expressions.enums import Optimizer
13
12
  from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
14
13
 
15
14
  from classiq.applications.qsvm.qsvm import Data, Labels
16
15
  from classiq.exceptions import ClassiqError
16
+ from classiq.qmod.builtins.enums import Optimizer
17
17
 
18
18
  ExecutionParams = Dict[str, Union[float, int, List[int], List[float]]]
19
19
 
@@ -21,6 +21,8 @@ _CALL_IN_QFUNC_ERROR = (
21
21
  'Cannot call "{}" in a quantum context. "{}" is a classical execution primitive.'
22
22
  )
23
23
 
24
+ CARRAY_SEPARATOR: Final[str] = "_"
25
+
24
26
 
25
27
  def _raise_error(primitive_name: str) -> None:
26
28
  raise ClassiqError(_CALL_IN_QFUNC_ERROR.format(primitive_name, primitive_name))
@@ -0,0 +1,177 @@
1
+ # This file was generated automatically - do not edit manually
2
+
3
+ from enum import IntEnum
4
+
5
+
6
+ class Element(IntEnum):
7
+ H = 0
8
+ He = 1
9
+ Li = 2
10
+ Be = 3
11
+ B = 4
12
+ C = 5
13
+ N = 6
14
+ O = 7 # noqa: E741
15
+ F = 8
16
+ Ne = 9
17
+ Na = 10
18
+ Mg = 11
19
+ Al = 12
20
+ Si = 13
21
+ P = 14
22
+ S = 15
23
+ Cl = 16
24
+ Ar = 17
25
+ K = 18
26
+ Ca = 19
27
+ Sc = 20
28
+ Ti = 21
29
+ V = 22
30
+ Cr = 23
31
+ Mn = 24
32
+ Fe = 25
33
+ Co = 26
34
+ Ni = 27
35
+ Cu = 28
36
+ Zn = 29
37
+ Ga = 30
38
+ Ge = 31
39
+ As = 32
40
+ Se = 33
41
+ Br = 34
42
+ Kr = 35
43
+ Rb = 36
44
+ Sr = 37
45
+ Y = 38
46
+ Zr = 39
47
+ Nb = 40
48
+ Mo = 41
49
+ Tc = 42
50
+ Ru = 43
51
+ Rh = 44
52
+ Pd = 45
53
+ Ag = 46
54
+ Cd = 47
55
+ In = 48
56
+ Sn = 49
57
+ Sb = 50
58
+ Te = 51
59
+ I = 52 # noqa: E741
60
+ Xe = 53
61
+ Cs = 54
62
+ Ba = 55
63
+ La = 56
64
+ Ce = 57
65
+ Pr = 58
66
+ Nd = 59
67
+ Pm = 60
68
+ Sm = 61
69
+ Eu = 62
70
+ Gd = 63
71
+ Tb = 64
72
+ Dy = 65
73
+ Ho = 66
74
+ Er = 67
75
+ Tm = 68
76
+ Yb = 69
77
+ Lu = 70
78
+ Hf = 71
79
+ Ta = 72
80
+ W = 73
81
+ Re = 74
82
+ Os = 75
83
+ Ir = 76
84
+ Pt = 77
85
+ Au = 78
86
+ Hg = 79
87
+ Tl = 80
88
+ Pb = 81
89
+ Bi = 82
90
+ Po = 83
91
+ At = 84
92
+ Rn = 85
93
+ Fr = 86
94
+ Ra = 87
95
+ Ac = 88
96
+ Th = 89
97
+ Pa = 90
98
+ U = 91
99
+ Np = 92
100
+ Pu = 93
101
+ Am = 94
102
+ Cm = 95
103
+ Bk = 96
104
+ Cf = 97
105
+ Es = 98
106
+ Fm = 99
107
+ Md = 100
108
+ No = 101
109
+ Lr = 102
110
+ Rf = 103
111
+ Db = 104
112
+ Sg = 105
113
+ Bh = 106
114
+ Hs = 107
115
+ Mt = 108
116
+ Ds = 109
117
+ Rg = 110
118
+ Cn = 111
119
+ Nh = 112
120
+ Fl = 113
121
+ Mc = 114
122
+ Lv = 115
123
+ Ts = 116
124
+ Og = 117
125
+
126
+
127
+ class FermionMapping(IntEnum):
128
+ JORDAN_WIGNER = 0
129
+ PARITY = 1
130
+ BRAVYI_KITAEV = 2
131
+ FAST_BRAVYI_KITAEV = 3
132
+
133
+
134
+ class FinanceFunctionType(IntEnum):
135
+ VAR = 0
136
+ SHORTFALL = 1
137
+ X_SQUARE = 2
138
+ EUROPEAN_CALL_OPTION = 3
139
+
140
+
141
+ class LadderOperator(IntEnum):
142
+ PLUS = 0
143
+ MINUS = 1
144
+
145
+
146
+ class Optimizer(IntEnum):
147
+ COBYLA = 1
148
+ SPSA = 2
149
+ L_BFGS_B = 3
150
+ NELDER_MEAD = 4
151
+ ADAM = 5
152
+
153
+
154
+ class Pauli(IntEnum):
155
+ I = 0 # noqa: E741
156
+ X = 1
157
+ Y = 2
158
+ Z = 3
159
+
160
+
161
+ class QSVMFeatureMapEntanglement(IntEnum):
162
+ FULL = 0
163
+ LINEAR = 1
164
+ CIRCULAR = 2
165
+ SCA = 3
166
+ PAIRWISE = 4
167
+
168
+
169
+ __all__ = [
170
+ "Element",
171
+ "FermionMapping",
172
+ "FinanceFunctionType",
173
+ "LadderOperator",
174
+ "Optimizer",
175
+ "Pauli",
176
+ "QSVMFeatureMapEntanglement",
177
+ ]
@@ -1,7 +1,6 @@
1
1
  # This file was generated automatically - do not edit manually
2
2
 
3
- from classiq.interface.generator.expressions.enums.pauli import Pauli
4
-
3
+ from classiq.qmod.builtins.enums import Pauli
5
4
  from classiq.qmod.qfunc import qfunc
6
5
  from classiq.qmod.qmod_parameter import CArray, CBool, CInt, CReal
7
6
  from classiq.qmod.qmod_variable import Input, Output, QArray, QBit, QNum
@@ -56,7 +56,7 @@ def bind(
56
56
 
57
57
 
58
58
  def if_(
59
- condition: SymbolicExpr,
59
+ condition: Union[SymbolicExpr, bool],
60
60
  then: Union[QCallable, Callable[[], None]],
61
61
  else_: Union[QCallable, Callable[[], None], int] = _MISSING_VALUE,
62
62
  ) -> None:
@@ -164,9 +164,7 @@ def repeat(count: Union[SymbolicExpr, int], iteration: Callable[[int], None]) ->
164
164
  repeat.__name__,
165
165
  )
166
166
  if not isinstance(iteration_operand, QuantumLambdaFunction):
167
- raise ClassiqValueError(
168
- "`repeat`'s `iteration` argument must be a lambda function"
169
- )
167
+ raise ClassiqValueError("`repeat`'s `iteration` argument must be a callable.")
170
168
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
171
169
  Repeat(
172
170
  iter_var=inspect.getfullargspec(iteration).args[0],
@@ -1,19 +1,18 @@
1
1
  # This file was generated automatically - do not edit manually
2
2
 
3
- from classiq.interface.generator.expressions.enums.ladder_operator import LadderOperator
4
- from classiq.interface.generator.expressions.enums.pauli import Pauli
3
+ from dataclasses import dataclass
5
4
 
5
+ from classiq.qmod.builtins.enums import LadderOperator, Pauli
6
6
  from classiq.qmod.qmod_parameter import CArray, CBool, CInt, CReal
7
- from classiq.qmod.qmod_struct import struct
8
7
 
9
8
 
10
- @struct
9
+ @dataclass
11
10
  class PauliTerm:
12
11
  pauli: CArray[Pauli]
13
12
  coefficient: CReal
14
13
 
15
14
 
16
- @struct
15
+ @dataclass
17
16
  class MoleculeProblem:
18
17
  mapping: CInt
19
18
  z2_symmetries: CBool
@@ -22,27 +21,27 @@ class MoleculeProblem:
22
21
  remove_orbitals: CArray[CInt]
23
22
 
24
23
 
25
- @struct
24
+ @dataclass
26
25
  class Molecule:
27
26
  atoms: CArray["ChemistryAtom"]
28
27
  spin: CInt
29
28
  charge: CInt
30
29
 
31
30
 
32
- @struct
31
+ @dataclass
33
32
  class ChemistryAtom:
34
33
  element: CInt
35
34
  position: "Position"
36
35
 
37
36
 
38
- @struct
37
+ @dataclass
39
38
  class Position:
40
39
  x: CReal
41
40
  y: CReal
42
41
  z: CReal
43
42
 
44
43
 
45
- @struct
44
+ @dataclass
46
45
  class FockHamiltonianProblem:
47
46
  mapping: CInt
48
47
  z2_symmetries: CBool
@@ -50,19 +49,19 @@ class FockHamiltonianProblem:
50
49
  num_particles: CArray[CInt]
51
50
 
52
51
 
53
- @struct
52
+ @dataclass
54
53
  class LadderTerm:
55
54
  coefficient: CReal
56
55
  ops: CArray["LadderOp"]
57
56
 
58
57
 
59
- @struct
58
+ @dataclass
60
59
  class LadderOp:
61
60
  op: LadderOperator
62
61
  index: CInt
63
62
 
64
63
 
65
- @struct
64
+ @dataclass
66
65
  class CombinatorialOptimizationSolution:
67
66
  probability: CReal
68
67
  cost: CReal
@@ -70,7 +69,7 @@ class CombinatorialOptimizationSolution:
70
69
  count: CInt
71
70
 
72
71
 
73
- @struct
72
+ @dataclass
74
73
  class GaussianModel:
75
74
  num_qubits: CInt
76
75
  normal_max_value: CReal
@@ -80,14 +79,14 @@ class GaussianModel:
80
79
  min_loss: CInt
81
80
 
82
81
 
83
- @struct
82
+ @dataclass
84
83
  class LogNormalModel:
85
84
  num_qubits: CInt
86
85
  mu: CReal
87
86
  sigma: CReal
88
87
 
89
88
 
90
- @struct
89
+ @dataclass
91
90
  class FinanceFunction:
92
91
  f: CInt
93
92
  threshold: CReal
@@ -97,13 +96,13 @@ class FinanceFunction:
97
96
  tail_probability: CReal
98
97
 
99
98
 
100
- @struct
99
+ @dataclass
101
100
  class QsvmResult:
102
101
  test_score: CReal
103
102
  predicted_labels: CArray[CReal]
104
103
 
105
104
 
106
- @struct
105
+ @dataclass
107
106
  class QSVMFeatureMapPauli:
108
107
  feature_dimension: CInt
109
108
  reps: CInt
@@ -1,11 +1,11 @@
1
1
  import dataclasses
2
2
  import inspect
3
+ from enum import EnumMeta
3
4
  from typing import (
4
5
  Any,
5
6
  Callable,
6
7
  Dict,
7
8
  List,
8
- Mapping,
9
9
  Optional,
10
10
  Type,
11
11
  get_args,
@@ -14,22 +14,20 @@ from typing import (
14
14
 
15
15
  from typing_extensions import _AnnotatedAlias
16
16
 
17
- from classiq.interface.generator.expressions.enums.ladder_operator import (
18
- LadderOperator as LadderOperatorEnum,
19
- )
20
- from classiq.interface.generator.expressions.enums.pauli import Pauli as PauliEnum
21
17
  from classiq.interface.generator.functions.classical_type import (
22
18
  Bool,
23
19
  ClassicalArray,
24
20
  ClassicalList,
25
21
  ConcreteClassicalType,
26
- CStructBase,
22
+ Enum,
27
23
  Integer,
28
- LadderOperator as LadderOperatorType,
29
- Pauli as PauliType,
30
24
  Real,
31
25
  Struct,
32
26
  )
27
+ from classiq.interface.generator.types.enum_declaration import (
28
+ EnumDeclaration,
29
+ declaration_from_enum,
30
+ )
33
31
  from classiq.interface.model.classical_parameter_declaration import (
34
32
  ClassicalParameterDeclaration,
35
33
  )
@@ -49,10 +47,6 @@ from classiq.qmod.quantum_callable import QCallable, QCallableList
49
47
  from classiq.qmod.utilities import unmangle_keyword, version_portable_get_args
50
48
 
51
49
  OPERAND_ARG_NAME = "arg{i}"
52
- ENUM_TYPE_MAPPING: Mapping[type, type] = {
53
- PauliEnum: PauliType,
54
- LadderOperatorEnum: LadderOperatorType,
55
- }
56
50
 
57
51
 
58
52
  def python_type_to_qmod(
@@ -64,8 +58,6 @@ def python_type_to_qmod(
64
58
  return Real()
65
59
  elif py_type == bool or py_type is CBool:
66
60
  return Bool()
67
- elif py_type in ENUM_TYPE_MAPPING:
68
- return ENUM_TYPE_MAPPING[py_type]()
69
61
  elif get_origin(py_type) == list:
70
62
  return ClassicalList(
71
63
  element_type=python_type_to_qmod(get_args(py_type)[0], qmodule=qmodule)
@@ -85,15 +77,26 @@ def python_type_to_qmod(
85
77
  "CArray accepts one or two generic parameters in the form "
86
78
  "`CArray[<element-type>]` or `CArray[<element-type>, <size>]`"
87
79
  )
88
- elif inspect.isclass(py_type) and issubclass(py_type, CStructBase):
80
+ elif inspect.isclass(py_type) and dataclasses.is_dataclass(py_type):
89
81
  _add_qmod_struct(py_type, qmodule=qmodule)
90
82
  return Struct(name=py_type.__name__)
83
+ elif inspect.isclass(py_type) and isinstance(py_type, EnumMeta):
84
+ _add_qmod_enum(py_type, qmodule=qmodule)
85
+ return Enum(name=py_type.__name__)
91
86
  return None
92
87
 
93
88
 
94
- def _add_qmod_struct(
95
- py_type: Type[CStructBase], *, qmodule: ModelStateContainer
96
- ) -> None:
89
+ def _add_qmod_enum(py_type: EnumMeta, *, qmodule: ModelStateContainer) -> None:
90
+ if (
91
+ py_type.__name__ in EnumDeclaration.BUILTIN_ENUM_DECLARATIONS
92
+ or py_type.__name__ in qmodule.enum_decls
93
+ ):
94
+ return
95
+
96
+ qmodule.enum_decls[py_type.__name__] = declaration_from_enum(py_type)
97
+
98
+
99
+ def _add_qmod_struct(py_type: Type, *, qmodule: ModelStateContainer) -> None:
97
100
  if (
98
101
  py_type.__name__ in StructDeclaration.BUILTIN_STRUCT_DECLARATIONS
99
102
  or py_type.__name__ in qmodule.type_decls
@@ -148,8 +151,8 @@ def _extract_positional_args(
148
151
  inspect.isclass(py_type)
149
152
  and (
150
153
  issubclass(py_type, CParam)
151
- or issubclass(py_type, CStructBase)
152
- or py_type in ENUM_TYPE_MAPPING
154
+ or dataclasses.is_dataclass(py_type)
155
+ or isinstance(py_type, EnumMeta)
153
156
  )
154
157
  or get_origin(py_type) == CArray
155
158
  ):
@@ -1,12 +1,14 @@
1
1
  from typing import Dict
2
2
 
3
3
  from classiq.interface.generator.constant import Constant
4
+ from classiq.interface.generator.types.enum_declaration import EnumDeclaration
4
5
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
5
6
 
6
7
  from classiq import StructDeclaration
7
8
 
8
9
 
9
10
  class ModelStateContainer:
11
+ enum_decls: Dict[str, EnumDeclaration]
10
12
  type_decls: Dict[str, StructDeclaration]
11
13
  native_defs: Dict[str, NativeFunctionDefinition]
12
14
  constants: Dict[str, Constant]