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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. classiq/__init__.py +7 -1
  2. classiq/_internals/client.py +4 -7
  3. classiq/_internals/host_checker.py +34 -12
  4. classiq/_internals/jobs.py +2 -2
  5. classiq/applications/chemistry/chemistry_model_constructor.py +12 -6
  6. classiq/applications/combinatorial_helpers/allowed_constraints.py +4 -1
  7. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
  8. classiq/applications/finance/finance_model_constructor.py +3 -2
  9. classiq/applications/grover/grover_model_constructor.py +7 -5
  10. classiq/applications/hamiltonian/__init__.py +0 -0
  11. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  12. classiq/applications/qnn/qlayer.py +1 -1
  13. classiq/exceptions.py +4 -0
  14. classiq/interface/_version.py +1 -1
  15. classiq/interface/ast_node.py +1 -18
  16. classiq/interface/backend/backend_preferences.py +10 -16
  17. classiq/interface/backend/ionq/ionq_quantum_program.py +1 -1
  18. classiq/interface/backend/pydantic_backend.py +0 -5
  19. classiq/interface/backend/quantum_backend_providers.py +3 -2
  20. classiq/interface/chemistry/operator.py +5 -1
  21. classiq/interface/debug_info/__init__.py +0 -0
  22. classiq/interface/debug_info/debug_info.py +32 -0
  23. classiq/interface/executor/execution_preferences.py +1 -45
  24. classiq/interface/executor/result.py +25 -12
  25. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  26. classiq/interface/generator/application_apis/chemistry_declarations.py +78 -60
  27. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +19 -10
  28. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  29. classiq/interface/generator/application_apis/finance_declarations.py +36 -22
  30. classiq/interface/generator/application_apis/qsvm_declarations.py +21 -15
  31. classiq/interface/generator/arith/arithmetic_expression_abc.py +21 -1
  32. classiq/interface/generator/arith/binary_ops.py +5 -4
  33. classiq/interface/generator/arith/extremum_operations.py +43 -19
  34. classiq/interface/generator/constant.py +1 -1
  35. classiq/interface/generator/expressions/atomic_expression_functions.py +1 -0
  36. classiq/interface/generator/expressions/expression_constants.py +3 -1
  37. classiq/interface/generator/expressions/qmod_qarray_proxy.py +52 -66
  38. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +35 -0
  39. classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
  40. classiq/interface/generator/functions/builtins/core_library/__init__.py +4 -2
  41. classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +41 -41
  42. classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +52 -42
  43. classiq/interface/generator/functions/builtins/open_lib_functions.py +1095 -3347
  44. classiq/interface/generator/functions/builtins/quantum_operators.py +9 -22
  45. classiq/interface/generator/functions/classical_function_declaration.py +14 -6
  46. classiq/interface/generator/functions/classical_type.py +7 -76
  47. classiq/interface/generator/functions/concrete_types.py +55 -0
  48. classiq/interface/generator/functions/function_declaration.py +10 -10
  49. classiq/interface/generator/functions/type_name.py +104 -0
  50. classiq/interface/generator/generated_circuit_data.py +3 -3
  51. classiq/interface/generator/model/model.py +11 -0
  52. classiq/interface/generator/model/preferences/preferences.py +5 -0
  53. classiq/interface/generator/quantum_function_call.py +3 -0
  54. classiq/interface/generator/quantum_program.py +2 -2
  55. classiq/interface/generator/register_role.py +7 -1
  56. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +1 -3
  57. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +1 -2
  58. classiq/interface/generator/types/qstruct_declaration.py +17 -0
  59. classiq/interface/generator/types/struct_declaration.py +1 -1
  60. classiq/interface/helpers/validation_helpers.py +1 -17
  61. classiq/interface/ide/visual_model.py +9 -2
  62. classiq/interface/interface_version.py +1 -0
  63. classiq/interface/model/bind_operation.py +25 -5
  64. classiq/interface/model/classical_parameter_declaration.py +8 -5
  65. classiq/interface/model/control.py +5 -5
  66. classiq/interface/model/handle_binding.py +185 -12
  67. classiq/interface/model/inplace_binary_operation.py +16 -4
  68. classiq/interface/model/model.py +28 -5
  69. classiq/interface/model/native_function_definition.py +8 -4
  70. classiq/interface/model/parameter.py +14 -0
  71. classiq/interface/model/port_declaration.py +20 -2
  72. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +21 -6
  73. classiq/interface/model/quantum_expressions/arithmetic_operation.py +30 -6
  74. classiq/interface/model/quantum_expressions/quantum_expression.py +4 -9
  75. classiq/interface/model/quantum_function_call.py +135 -192
  76. classiq/interface/model/quantum_function_declaration.py +147 -165
  77. classiq/interface/model/quantum_lambda_function.py +24 -6
  78. classiq/interface/model/quantum_statement.py +34 -8
  79. classiq/interface/model/quantum_type.py +61 -10
  80. classiq/interface/model/quantum_variable_declaration.py +1 -1
  81. classiq/interface/model/statement_block.py +2 -0
  82. classiq/interface/model/validation_handle.py +7 -0
  83. classiq/interface/server/global_versions.py +4 -4
  84. classiq/interface/server/routes.py +2 -0
  85. classiq/interface/source_reference.py +59 -0
  86. classiq/qmod/__init__.py +2 -3
  87. classiq/qmod/builtins/functions.py +39 -11
  88. classiq/qmod/builtins/operations.py +171 -40
  89. classiq/qmod/declaration_inferrer.py +99 -56
  90. classiq/qmod/expression_query.py +1 -1
  91. classiq/qmod/model_state_container.py +2 -0
  92. classiq/qmod/native/pretty_printer.py +71 -53
  93. classiq/qmod/pretty_print/pretty_printer.py +98 -52
  94. classiq/qmod/qfunc.py +11 -5
  95. classiq/qmod/qmod_parameter.py +1 -2
  96. classiq/qmod/qmod_variable.py +364 -172
  97. classiq/qmod/quantum_callable.py +3 -3
  98. classiq/qmod/quantum_expandable.py +119 -65
  99. classiq/qmod/quantum_function.py +15 -3
  100. classiq/qmod/semantics/annotation.py +12 -13
  101. classiq/qmod/semantics/error_manager.py +36 -10
  102. classiq/qmod/semantics/static_semantics_visitor.py +163 -75
  103. classiq/qmod/semantics/validation/func_call_validation.py +42 -96
  104. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  105. classiq/qmod/semantics/validation/types_validation.py +108 -1
  106. classiq/qmod/type_attribute_remover.py +32 -0
  107. classiq/qmod/utilities.py +26 -5
  108. {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/METADATA +3 -3
  109. {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/RECORD +111 -99
  110. classiq/qmod/qmod_struct.py +0 -13
  111. /classiq/{interface/ide/show.py → show.py} +0 -0
  112. {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/WHEEL +0 -0
@@ -1,4 +1,4 @@
1
- from typing import Dict, List, Optional, Tuple
1
+ from typing import Dict, List, Mapping, Optional, Tuple, Union, cast
2
2
 
3
3
  import black
4
4
 
@@ -6,21 +6,26 @@ from classiq.interface.generator.constant import Constant
6
6
  from classiq.interface.generator.expressions.expression import Expression
7
7
  from classiq.interface.generator.functions.classical_type import (
8
8
  ClassicalArray,
9
+ )
10
+ from classiq.interface.generator.functions.concrete_types import (
9
11
  ConcreteClassicalType,
10
- TypeName,
12
+ ConcreteQuantumType,
11
13
  )
12
14
  from classiq.interface.generator.functions.port_declaration import (
13
15
  PortDeclarationDirection,
14
16
  )
17
+ from classiq.interface.generator.functions.type_name import TypeName
15
18
  from classiq.interface.generator.types.enum_declaration import EnumDeclaration
19
+ from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
16
20
  from classiq.interface.generator.visitor import NodeType, Visitor
17
21
  from classiq.interface.model.bind_operation import BindOperation
18
22
  from classiq.interface.model.classical_if import ClassicalIf
19
23
  from classiq.interface.model.classical_parameter_declaration import (
20
- ClassicalParameterDeclaration,
24
+ AnonClassicalParameterDeclaration,
21
25
  )
22
26
  from classiq.interface.model.control import Control
23
27
  from classiq.interface.model.handle_binding import (
28
+ FieldHandleBinding,
24
29
  HandleBinding,
25
30
  SlicedHandleBinding,
26
31
  SubscriptHandleBinding,
@@ -29,7 +34,7 @@ from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperat
29
34
  from classiq.interface.model.invert import Invert
30
35
  from classiq.interface.model.model import Model
31
36
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
32
- from classiq.interface.model.port_declaration import PortDeclaration
37
+ from classiq.interface.model.port_declaration import AnonPortDeclaration
33
38
  from classiq.interface.model.power import Power
34
39
  from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
35
40
  AmplitudeLoadingOperation,
@@ -45,7 +50,8 @@ from classiq.interface.model.quantum_function_call import (
45
50
  QuantumFunctionCall,
46
51
  )
47
52
  from classiq.interface.model.quantum_function_declaration import (
48
- PositionalArg,
53
+ AnonPositionalArg,
54
+ AnonQuantumOperandDeclaration,
49
55
  QuantumFunctionDeclaration,
50
56
  QuantumOperandDeclaration,
51
57
  )
@@ -66,7 +72,13 @@ from classiq.interface.model.variable_declaration_statement import (
66
72
  from classiq.interface.model.within_apply_operation import WithinApply
67
73
 
68
74
  import classiq
69
- from classiq import Bool, ClassicalList, Integer, Real, StructDeclaration
75
+ from classiq import (
76
+ Bool,
77
+ ClassicalList,
78
+ Integer,
79
+ Real,
80
+ StructDeclaration,
81
+ )
70
82
  from classiq.qmod.pretty_print.expression_to_python import transform_expression
71
83
  from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
72
84
 
@@ -82,18 +94,25 @@ class VariableDeclarationAssignment(Visitor):
82
94
  return res # type: ignore[return-value]
83
95
 
84
96
  def visit_QuantumBit(self, qtype: QuantumBit) -> Tuple[str, Optional[List[str]]]:
97
+ self.pretty_printer._imports["QBit"] = 1
98
+
85
99
  return "QBit", None
86
100
 
87
101
  def visit_QuantumBitvector(
88
102
  self, qtype: QuantumBitvector
89
103
  ) -> Tuple[str, Optional[List[str]]]:
104
+ self.pretty_printer._imports["QArray"] = 1
105
+
106
+ element_type = self.pretty_printer.visit(qtype.element_type)
90
107
  if qtype.length is not None:
91
- return "QArray", ["QBit", self.pretty_printer.visit(qtype.length)]
92
- return "QArray", ["QBit"]
108
+ return "QArray", [element_type, self.pretty_printer.visit(qtype.length)]
109
+ return "QArray", [element_type]
93
110
 
94
111
  def visit_QuantumNumeric(
95
112
  self, qtype: QuantumNumeric
96
113
  ) -> Tuple[str, Optional[List[str]]]:
114
+ self.pretty_printer._imports["QNum"] = 1
115
+
97
116
  params = []
98
117
  if qtype.size is not None:
99
118
  assert qtype.is_signed is not None
@@ -106,6 +125,9 @@ class VariableDeclarationAssignment(Visitor):
106
125
 
107
126
  return "QNum", params
108
127
 
128
+ def visit_TypeName(self, qtype: TypeName) -> Tuple[str, None]:
129
+ return qtype.name, None
130
+
109
131
 
110
132
  class PythonPrettyPrinter(Visitor):
111
133
  def __init__(self, decimal_precision: int = DEFAULT_DECIMAL_PRECISION) -> None:
@@ -114,8 +136,9 @@ class PythonPrettyPrinter(Visitor):
114
136
  self._imports = {"qfunc": 1}
115
137
  self._import_enum = False
116
138
  self._import_dataclass = False
139
+ self._import_annotated = False
117
140
  self._symbolic_imports: Dict[str, int] = dict()
118
- self._functions: Optional[Dict[str, QuantumFunctionDeclaration]] = None
141
+ self._functions: Optional[Mapping[str, QuantumFunctionDeclaration]] = None
119
142
 
120
143
  def visit(self, node: NodeType) -> str:
121
144
  res = super().visit(node)
@@ -130,11 +153,12 @@ class PythonPrettyPrinter(Visitor):
130
153
  }
131
154
  enum_decls = [self.visit(decl) for decl in model.enums]
132
155
  struct_decls = [self.visit(decl) for decl in model.types]
156
+ qstruct_decls = [self.visit(qstruct_decl) for qstruct_decl in model.qstructs]
133
157
  func_defs = [self.visit(func) for func in model.functions]
134
158
  constants = [self.visit(const) for const in model.constants]
135
159
  classical_code = self.format_classical_code(model.classical_execution_code)
136
160
 
137
- code = f"{self.format_imports()}\n\n{self.join_code_parts(*constants, *enum_decls, *struct_decls, *func_defs, classical_code)}"
161
+ code = f"{self.format_imports()}\n\n{self.join_code_parts(*constants, *enum_decls, *struct_decls, *qstruct_decls, *func_defs, classical_code)}"
138
162
  return black.format_str(code, mode=black.FileMode())
139
163
 
140
164
  def format_classical_code(self, code: str) -> str:
@@ -162,6 +186,8 @@ class PythonPrettyPrinter(Visitor):
162
186
  @property
163
187
  def special_imports(self) -> str:
164
188
  imports = ""
189
+ if self._import_annotated:
190
+ imports += "from typing_extensions import Annotated\n"
165
191
  if self._import_dataclass:
166
192
  imports += "from dataclasses import dataclass\n"
167
193
  if self._import_enum:
@@ -178,7 +204,7 @@ class PythonPrettyPrinter(Visitor):
178
204
 
179
205
  def _visit_arg_decls(self, func_def: QuantumFunctionDeclaration) -> str:
180
206
  return ", ".join(
181
- self.visit(arg_decl) for arg_decl in func_def.get_positional_arg_decls()
207
+ self.visit(arg_decl) for arg_decl in func_def.positional_arg_declarations
182
208
  )
183
209
 
184
210
  def visit_QuantumFunctionDeclaration(
@@ -205,7 +231,13 @@ class PythonPrettyPrinter(Visitor):
205
231
  self._import_dataclass = True
206
232
  return f"@dataclass\nclass {struct_decl.name}:\n{self._visit_variables(struct_decl.variables)}\n"
207
233
 
208
- def _visit_variables(self, variables: Dict[str, ConcreteClassicalType]) -> str:
234
+ def visit_QStructDeclaration(self, qstruct_decl: QStructDeclaration) -> str:
235
+ self._imports["QStruct"] = 1
236
+ return f"class {qstruct_decl.name}(QStruct):\n{self._visit_variables(qstruct_decl.fields)}\n"
237
+
238
+ def _visit_variables(
239
+ self, variables: Mapping[str, Union[ConcreteClassicalType, ConcreteQuantumType]]
240
+ ) -> str:
209
241
  self._level += 1
210
242
  variables_str = "".join(
211
243
  f"{self._indent}{self.visit(field_name)}: {self.visit(var_decl)};\n"
@@ -219,8 +251,8 @@ class PythonPrettyPrinter(Visitor):
219
251
  ) -> str:
220
252
  return f"{var_decl.name}: {self.visit(var_decl.quantum_type)}"
221
253
 
222
- def visit_PortDeclaration(self, port_decl: PortDeclaration) -> str:
223
- var = self.visit_QuantumVariableDeclaration(port_decl)
254
+ def visit_AnonPortDeclaration(self, port_decl: AnonPortDeclaration) -> str:
255
+ var = f"{port_decl.name}: {self.visit(port_decl.quantum_type)}"
224
256
  var_name, var_type = var.split(": ")
225
257
  for direction in PortDeclarationDirection:
226
258
  if port_decl.direction == PortDeclarationDirection.Inout:
@@ -258,8 +290,8 @@ class PythonPrettyPrinter(Visitor):
258
290
 
259
291
  return f"QNum{params}"
260
292
 
261
- def visit_ClassicalParameterDeclaration(
262
- self, cparam: ClassicalParameterDeclaration
293
+ def visit_AnonClassicalParameterDeclaration(
294
+ self, cparam: AnonClassicalParameterDeclaration
263
295
  ) -> str:
264
296
  return f"{cparam.name}: {self.visit(cparam.classical_type)}"
265
297
 
@@ -284,11 +316,14 @@ class PythonPrettyPrinter(Visitor):
284
316
  return f"CArray[{self.visit(ctarray.element_type)}, {ctarray.size}]"
285
317
 
286
318
  def visit_TypeName(self, type_: TypeName) -> str:
319
+ self._import_type_name(type_)
320
+ return type_.name
321
+
322
+ def _import_type_name(self, type_: TypeName) -> None:
287
323
  if type_.name in dir(classiq.qmod.builtins.enums) + dir(
288
324
  classiq.qmod.builtins.structs
289
325
  ):
290
326
  self._imports[type_.name] = 1
291
- return type_.name
292
327
 
293
328
  def visit_VariableDeclarationStatement(
294
329
  self, local_decl: VariableDeclarationStatement
@@ -296,32 +331,38 @@ class PythonPrettyPrinter(Visitor):
296
331
  type_name, params = VariableDeclarationAssignment(self).visit(
297
332
  local_decl.quantum_type
298
333
  )
299
- self._imports[type_name] = 1
300
334
  params = [f'"{local_decl.name}"'] + (params or [])
301
335
  param_args = ", ".join(params)
302
336
  return f"{self._indent}{self.visit_QuantumVariableDeclaration(local_decl)} = {type_name}({param_args})\n"
303
337
 
304
- def _visit_operand_arg_decl(self, arg_decl: PositionalArg) -> str:
305
- if isinstance(arg_decl, QuantumVariableDeclaration):
306
- return self.visit(arg_decl.quantum_type)
307
- if isinstance(arg_decl, ClassicalParameterDeclaration):
308
- return self.visit(arg_decl.classical_type)
309
- if isinstance(arg_decl, QuantumOperandDeclaration):
310
- return self.visit_QuantumOperandDeclaration(arg_decl)
311
-
312
- def visit_QuantumOperandDeclaration(
313
- self, op_decl: QuantumOperandDeclaration
338
+ def _visit_operand_arg_decl(self, arg_decl: AnonPositionalArg) -> str:
339
+ if isinstance(arg_decl, AnonPortDeclaration):
340
+ type_str = self.visit(arg_decl.quantum_type)
341
+ elif isinstance(arg_decl, AnonClassicalParameterDeclaration):
342
+ type_str = self.visit(arg_decl.classical_type)
343
+ else:
344
+ type_str = self.visit_AnonQuantumOperandDeclaration(arg_decl, no_param=True)
345
+ if arg_decl.name is None:
346
+ return type_str
347
+ self._import_annotated = True
348
+ return f'Annotated[{type_str}, "{arg_decl.name}"]'
349
+
350
+ def visit_AnonQuantumOperandDeclaration(
351
+ self, op_decl: AnonQuantumOperandDeclaration, no_param: bool = False
314
352
  ) -> str:
315
- qcallable_identifier = "QCallable"
316
- if op_decl.is_list:
317
- qcallable_identifier = "QCallableList"
353
+ qcallable_identifier = "QCallableList" if op_decl.is_list else "QCallable"
318
354
  self._imports[qcallable_identifier] = 1
319
355
  args = ", ".join(
320
356
  self._visit_operand_arg_decl(arg_decl)
321
- for arg_decl in op_decl.get_positional_arg_decls()
357
+ for arg_decl in op_decl.positional_arg_declarations
322
358
  )
359
+ param_name = "" if no_param else f"{op_decl.name}: "
360
+ return f"{param_name}{qcallable_identifier}" + (f"[{args}]" if args else "")
323
361
 
324
- return f"{op_decl.name}: {qcallable_identifier}" + (f"[{args}]" if args else "")
362
+ def visit_QuantumOperandDeclaration(
363
+ self, op_decl: QuantumOperandDeclaration
364
+ ) -> str:
365
+ return self.visit_AnonQuantumOperandDeclaration(op_decl)
325
366
 
326
367
  def visit_NativeFunctionDefinition(self, func_def: NativeFunctionDefinition) -> str:
327
368
  self._level += 1
@@ -330,21 +371,27 @@ class PythonPrettyPrinter(Visitor):
330
371
  return f"{self.visit_QuantumFunctionDeclaration(func_def)} \n{body}\n"
331
372
 
332
373
  def visit_QuantumFunctionCall(self, func_call: QuantumFunctionCall) -> str:
333
- if len(func_call.get_positional_args()) <= 2 or self._functions is None:
334
- args = ", ".join(self.visit(arg) for arg in func_call.get_positional_args())
335
- else:
336
- func_decl = self._functions[func_call.func_name]
337
- args = ", ".join(
338
- f"{self.visit(arg_decl.name)}={self.visit(arg)}"
339
- for arg_decl, arg in zip(
340
- func_decl.get_positional_arg_decls(),
341
- func_call.get_positional_args(),
342
- )
343
- )
374
+ args = self._get_args(func_call)
344
375
  if func_call.func_name in dir(classiq.qmod.builtins.functions):
345
376
  self._imports[func_call.func_name] = 1
346
377
  return f"{self._indent}{func_call.func_name}{f'[{self.visit(func_call.function.index)}]' if isinstance(func_call.function, OperandIdentifier) else ''}({args})\n"
347
378
 
379
+ def _get_args(self, func_call: QuantumFunctionCall) -> str:
380
+ if len(func_call.positional_args) > 2 and self._functions is not None:
381
+ func_decl = self._functions[func_call.func_name]
382
+ if all(
383
+ param.name is not None
384
+ for param in func_decl.positional_arg_declarations
385
+ ):
386
+ return ", ".join(
387
+ f"{self.visit(cast(str, arg_decl.name))}={self.visit(arg)}"
388
+ for arg_decl, arg in zip(
389
+ func_decl.positional_arg_declarations,
390
+ func_call.positional_args,
391
+ )
392
+ )
393
+ return ", ".join(self.visit(arg) for arg in func_call.positional_args)
394
+
348
395
  def visit_Control(self, op: Control) -> str:
349
396
  self._imports["control"] = 1
350
397
  return f"{self._indent}control({self.visit(op.expression)}, {self._visit_body(op.body)})\n"
@@ -373,7 +420,7 @@ class PythonPrettyPrinter(Visitor):
373
420
  self, body: StatementBlock, operand_arguments: Optional[List[str]] = None
374
421
  ) -> str:
375
422
  if len(body) == 0:
376
- return "None"
423
+ return "lambda: []"
377
424
  argument_string = (
378
425
  (" " + ", ".join(operand_arguments)) if operand_arguments else ""
379
426
  )
@@ -406,20 +453,19 @@ class PythonPrettyPrinter(Visitor):
406
453
  )
407
454
 
408
455
  def visit_QuantumLambdaFunction(self, qlambda: QuantumLambdaFunction) -> str:
409
- assert qlambda.func_decl is not None
410
- return self._visit_body(
411
- qlambda.body,
412
- list(qlambda.rename_params.values()),
413
- )
456
+ return self._visit_body(qlambda.body, qlambda.get_rename_params())
414
457
 
415
458
  def visit_HandleBinding(self, var_ref: HandleBinding) -> str:
416
459
  return var_ref.name
417
460
 
418
461
  def visit_SlicedHandleBinding(self, var_ref: SlicedHandleBinding) -> str:
419
- return f"{var_ref.name}[{self.visit(var_ref.start)}:{self.visit(var_ref.end)}]"
462
+ return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.start)}:{self.visit(var_ref.end)}]"
420
463
 
421
464
  def visit_SubscriptHandleBinding(self, var_ref: SubscriptHandleBinding) -> str:
422
- return f"{var_ref.name}[{self.visit(var_ref.index)}]"
465
+ return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.index)}]"
466
+
467
+ def visit_FieldHandleBinding(self, var_ref: FieldHandleBinding) -> str:
468
+ return f"{self.visit(var_ref.base_handle)}.{self.visit(var_ref.field)}"
423
469
 
424
470
  def visit_ArithmeticOperation(self, arith_op: ArithmeticOperation) -> str:
425
471
  op = "^=" if arith_op.inplace_result else "|="
classiq/qmod/qfunc.py CHANGED
@@ -1,21 +1,27 @@
1
- from typing import Callable, Optional, Union, overload
1
+ from typing import Callable, Literal, Optional, Union, overload
2
2
 
3
3
  from classiq.qmod.quantum_callable import QCallable
4
- from classiq.qmod.quantum_function import ExternalQFunc, QFunc
4
+ from classiq.qmod.quantum_function import ExternalQFunc, GenerativeQFunc, QFunc
5
5
 
6
6
 
7
7
  @overload
8
- def qfunc(func: Callable, *, external: bool = False) -> QFunc: ...
8
+ def qfunc(func: Callable) -> QFunc: ...
9
9
 
10
10
 
11
11
  @overload
12
- def qfunc(func: None = None, *, external: bool) -> Callable[[Callable], QCallable]: ...
12
+ def qfunc(*, external: Literal[True]) -> Callable[[Callable], ExternalQFunc]: ...
13
+
14
+
15
+ @overload
16
+ def qfunc(*, generative: Literal[True]) -> Callable[[Callable], GenerativeQFunc]: ...
13
17
 
14
18
 
15
19
  def qfunc(
16
- func: Optional[Callable] = None, *, external: bool = False
20
+ func: Optional[Callable] = None, *, external: bool = False, generative: bool = False
17
21
  ) -> Union[Callable[[Callable], QCallable], QCallable]:
18
22
  def wrapper(func: Callable) -> QCallable:
23
+ if generative:
24
+ return GenerativeQFunc(func)
19
25
  if external:
20
26
  return ExternalQFunc(func)
21
27
 
@@ -14,10 +14,9 @@ from classiq.interface.generator.functions.classical_type import (
14
14
  ClassicalArray,
15
15
  ClassicalList,
16
16
  ClassicalType,
17
- Struct,
18
17
  )
19
18
 
20
- from classiq import StructDeclaration
19
+ from classiq import Struct, StructDeclaration
21
20
  from classiq.exceptions import ClassiqValueError
22
21
  from classiq.qmod.model_state_container import ModelStateContainer
23
22
  from classiq.qmod.symbolic_expr import Symbolic, SymbolicExpr