classiq 0.40.0__py3-none-any.whl → 0.41.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 (81) hide show
  1. classiq/__init__.py +4 -2
  2. classiq/_internals/api_wrapper.py +3 -21
  3. classiq/applications/chemistry/chemistry_model_constructor.py +86 -100
  4. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +6 -24
  5. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +33 -45
  6. classiq/applications/combinatorial_optimization/__init__.py +2 -0
  7. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +29 -26
  8. classiq/applications/finance/finance_model_constructor.py +23 -26
  9. classiq/applications/grover/grover_model_constructor.py +37 -38
  10. classiq/applications/qsvm/qsvm.py +1 -2
  11. classiq/applications/qsvm/qsvm_model_constructor.py +15 -16
  12. classiq/execution/__init__.py +4 -0
  13. classiq/execution/execution_session.py +151 -0
  14. classiq/execution/qnn.py +80 -0
  15. classiq/executor.py +2 -109
  16. classiq/interface/_version.py +1 -1
  17. classiq/interface/analyzer/analysis_params.py +11 -0
  18. classiq/interface/applications/qsvm.py +0 -8
  19. classiq/interface/ast_node.py +12 -2
  20. classiq/interface/backend/backend_preferences.py +25 -1
  21. classiq/interface/backend/quantum_backend_providers.py +4 -4
  22. classiq/interface/executor/execution_preferences.py +4 -59
  23. classiq/interface/executor/execution_result.py +22 -1
  24. classiq/interface/generator/arith/arithmetic_expression_validator.py +0 -2
  25. classiq/interface/generator/arith/binary_ops.py +88 -25
  26. classiq/interface/generator/arith/unary_ops.py +28 -19
  27. classiq/interface/generator/expressions/atomic_expression_functions.py +6 -2
  28. classiq/interface/generator/expressions/enums/__init__.py +10 -0
  29. classiq/interface/generator/expressions/enums/classical_enum.py +5 -1
  30. classiq/interface/generator/expressions/expression.py +9 -2
  31. classiq/interface/generator/expressions/qmod_qarray_proxy.py +7 -0
  32. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +0 -1
  33. classiq/interface/generator/expressions/sympy_supported_expressions.py +10 -1
  34. classiq/interface/generator/functions/builtins/internal_operators.py +7 -62
  35. classiq/interface/generator/functions/builtins/open_lib_functions.py +810 -2
  36. classiq/interface/generator/functions/classical_type.py +1 -3
  37. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  38. classiq/interface/model/bind_operation.py +3 -1
  39. classiq/interface/model/call_synthesis_data.py +2 -13
  40. classiq/interface/model/classical_if.py +3 -1
  41. classiq/interface/model/classical_parameter_declaration.py +13 -0
  42. classiq/interface/model/control.py +3 -101
  43. classiq/interface/model/inplace_binary_operation.py +3 -1
  44. classiq/interface/model/invert.py +3 -1
  45. classiq/interface/model/port_declaration.py +8 -1
  46. classiq/interface/model/power.py +3 -1
  47. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +4 -2
  48. classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -1
  49. classiq/interface/model/quantum_expressions/quantum_expression.py +11 -1
  50. classiq/interface/model/quantum_function_call.py +4 -10
  51. classiq/interface/model/quantum_function_declaration.py +26 -4
  52. classiq/interface/model/quantum_lambda_function.py +1 -20
  53. classiq/interface/model/quantum_statement.py +9 -2
  54. classiq/interface/model/repeat.py +3 -1
  55. classiq/interface/model/statement_block.py +19 -13
  56. classiq/interface/model/validations/handles_validator.py +8 -2
  57. classiq/interface/model/variable_declaration_statement.py +3 -1
  58. classiq/interface/model/within_apply_operation.py +3 -1
  59. classiq/interface/server/routes.py +0 -5
  60. classiq/qmod/__init__.py +1 -2
  61. classiq/qmod/builtins/classical_execution_primitives.py +22 -2
  62. classiq/qmod/builtins/functions.py +51 -1
  63. classiq/qmod/builtins/operations.py +6 -36
  64. classiq/qmod/declaration_inferrer.py +8 -15
  65. classiq/qmod/native/__init__.py +9 -0
  66. classiq/qmod/native/expression_to_qmod.py +12 -9
  67. classiq/qmod/native/pretty_printer.py +4 -4
  68. classiq/qmod/pretty_print/__init__.py +9 -0
  69. classiq/qmod/pretty_print/expression_to_python.py +221 -0
  70. classiq/qmod/pretty_print/pretty_printer.py +421 -0
  71. classiq/qmod/qmod_parameter.py +7 -4
  72. classiq/qmod/quantum_callable.py +2 -1
  73. classiq/qmod/quantum_expandable.py +4 -3
  74. classiq/qmod/quantum_function.py +4 -16
  75. classiq/qmod/symbolic.py +1 -6
  76. classiq/synthesis.py +15 -16
  77. {classiq-0.40.0.dist-info → classiq-0.41.1.dist-info}/METADATA +5 -4
  78. {classiq-0.40.0.dist-info → classiq-0.41.1.dist-info}/RECORD +79 -76
  79. classiq/interface/model/common_model_types.py +0 -23
  80. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  81. {classiq-0.40.0.dist-info → classiq-0.41.1.dist-info}/WHEEL +0 -0
@@ -154,7 +154,11 @@ class InplacableBinaryOpParams(
154
154
  if self.inplace_arg is None:
155
155
  return 0
156
156
  arg = self.left_arg if self.inplace_arg == ArgToInplace.LEFT else self.right_arg
157
- return max(0, arg.integer_part_size - self.result_register.integer_part_size) # type: ignore[attr-defined]
157
+ return max(
158
+ 0, arg.integer_part_size - self.result_register.integer_part_size # type: ignore[attr-defined]
159
+ ) + max(
160
+ 0, arg.fraction_places - self.result_register.fraction_places # type: ignore[attr-defined]
161
+ )
158
162
 
159
163
  def _carried_arguments(self) -> Tuple[Optional[LeftDataT], Optional[RightDataT]]:
160
164
  if self.inplace_arg == ArgToInplace.RIGHT and isinstance(
@@ -259,15 +263,21 @@ class Adder(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
259
263
  output_name = "sum"
260
264
 
261
265
  def _get_result_register(self) -> RegisterArithmeticInfo:
262
- lb = argument_utils.lower_bound(self.left_arg) + argument_utils.lower_bound(
263
- self.right_arg
266
+ left_arg = argument_utils.limit_fraction_places(
267
+ self.left_arg, machine_precision=self.machine_precision
264
268
  )
265
- ub = argument_utils.upper_bound(self.left_arg) + argument_utils.upper_bound(
266
- self.right_arg
269
+ right_arg = argument_utils.limit_fraction_places(
270
+ self.right_arg, machine_precision=self.machine_precision
271
+ )
272
+ lb = argument_utils.lower_bound(left_arg) + argument_utils.lower_bound(
273
+ right_arg
274
+ )
275
+ ub = argument_utils.upper_bound(left_arg) + argument_utils.upper_bound(
276
+ right_arg
267
277
  )
268
278
  fraction_places = max(
269
- argument_utils.fraction_places(self.left_arg),
270
- argument_utils.fraction_places(self.right_arg),
279
+ argument_utils.fraction_places(left_arg),
280
+ argument_utils.fraction_places(right_arg),
271
281
  )
272
282
  return RegisterArithmeticInfo(
273
283
  size=self.output_size or self._get_output_size(ub, lb, fraction_places),
@@ -291,16 +301,47 @@ class Adder(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
291
301
  class Subtractor(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
292
302
  output_name = "difference"
293
303
 
304
+ @staticmethod
305
+ def _get_effective_arg(
306
+ arg: RegisterOrConst, machine_precision: int
307
+ ) -> RegisterOrConst:
308
+ return argument_utils.limit_fraction_places(
309
+ arg, machine_precision=machine_precision
310
+ )
311
+
312
+ @property
313
+ def effective_left_arg(self) -> RegisterOrConst:
314
+ return self._get_effective_arg(self.left_arg, self.machine_precision)
315
+
316
+ @property
317
+ def effective_right_arg(self) -> RegisterOrConst:
318
+ return self._get_effective_arg(self.right_arg, self.machine_precision)
319
+
320
+ @staticmethod
321
+ def _is_arg_trimmed_register(arg: RegisterOrConst, machine_precision: int) -> bool:
322
+ return (
323
+ isinstance(arg, RegisterArithmeticInfo)
324
+ and arg.fraction_places > machine_precision
325
+ )
326
+
327
+ @property
328
+ def left_arg_is_trimmed_register(self) -> bool:
329
+ return self._is_arg_trimmed_register(self.left_arg, self.machine_precision)
330
+
331
+ @property
332
+ def right_arg_is_trimmed_register(self) -> bool:
333
+ return self._is_arg_trimmed_register(self.right_arg, self.machine_precision)
334
+
294
335
  def _get_result_register(self) -> RegisterArithmeticInfo:
295
336
  bounds = (
296
- argument_utils.lower_bound(self.left_arg)
297
- - argument_utils.upper_bound(self.right_arg),
298
- argument_utils.upper_bound(self.left_arg)
299
- - argument_utils.lower_bound(self.right_arg),
337
+ argument_utils.lower_bound(self.effective_left_arg)
338
+ - argument_utils.upper_bound(self.effective_right_arg),
339
+ argument_utils.upper_bound(self.effective_left_arg)
340
+ - argument_utils.lower_bound(self.effective_right_arg),
300
341
  )
301
342
  fraction_places = max(
302
- argument_utils.fraction_places(self.left_arg),
303
- argument_utils.fraction_places(self.right_arg),
343
+ argument_utils.fraction_places(self.effective_left_arg),
344
+ argument_utils.fraction_places(self.effective_right_arg),
304
345
  )
305
346
 
306
347
  return RegisterArithmeticInfo(
@@ -313,38 +354,60 @@ class Subtractor(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
313
354
  def _get_output_size(
314
355
  self, bounds: Tuple[float, float], fraction_places: int
315
356
  ) -> int:
316
- if isinstance(self.right_arg, float) and self.right_arg == 0:
317
- assert isinstance(self.left_arg, RegisterArithmeticInfo)
318
- return self.left_arg.size
357
+ if isinstance(self.right_arg, float) and self.effective_right_arg == 0:
358
+ assert isinstance(self.effective_left_arg, RegisterArithmeticInfo)
359
+ return self.effective_left_arg.size
319
360
  integer_part_size = number_utils.bounds_to_integer_part_size(*bounds)
320
361
  size_needed = integer_part_size + fraction_places
321
362
  return size_needed
322
363
 
323
364
  def garbage_output_size(self) -> pydantic.NonNegativeInt:
324
- if not isinstance(self.right_arg, RegisterArithmeticInfo):
365
+ if (
366
+ not self.left_arg_is_trimmed_register
367
+ and not self.right_arg_is_trimmed_register
368
+ ):
369
+ return self._untrimmed_garbage_output_size()
370
+ if not self.is_inplaced():
371
+ return 0
372
+ inplace_arg_name = (
373
+ self.left_arg_name
374
+ if self.inplace_arg == ArgToInplace.LEFT
375
+ else self.right_arg_name
376
+ )
377
+ return max(
378
+ 0,
379
+ self._inputs[inplace_arg_name].fraction_places
380
+ - self.result_register.fraction_places,
381
+ )
382
+
383
+ def _untrimmed_garbage_output_size(self) -> pydantic.NonNegativeInt:
384
+ if not isinstance(self.effective_right_arg, RegisterArithmeticInfo):
325
385
  adder_params = Adder(
326
- left_arg=self.left_arg,
327
- right_arg=-self.right_arg,
386
+ left_arg=self.effective_left_arg,
387
+ right_arg=-self.effective_right_arg,
328
388
  output_size=self.output_size,
329
389
  inplace_arg=self.inplace_arg,
330
390
  )
331
391
  return adder_params.garbage_output_size()
332
392
 
333
393
  negation_params = Negation(
334
- arg=self.right_arg,
394
+ arg=self.effective_right_arg,
335
395
  output_size=self.negation_output_size,
336
396
  inplace=self.should_inplace_negation,
337
397
  )
338
398
  negation_result = negation_params.result_register
339
- if self.output_size is None and max(self.right_arg.bounds) > 0:
399
+ if self.output_size is None and max(self.effective_right_arg.bounds) > 0:
340
400
  negation_result = negation_result.copy(
341
401
  update=dict(
342
402
  is_signed=True,
343
- bounds=(-max(self.right_arg.bounds), -min(self.right_arg.bounds)),
403
+ bounds=(
404
+ -max(self.effective_right_arg.bounds),
405
+ -min(self.effective_right_arg.bounds),
406
+ ),
344
407
  )
345
408
  )
346
409
  adder_params = Adder(
347
- left_arg=self.left_arg,
410
+ left_arg=self.effective_left_arg,
348
411
  right_arg=negation_result,
349
412
  output_size=self.output_size,
350
413
  inplace_arg=self.arg_to_inplace_adder,
@@ -359,10 +422,10 @@ class Subtractor(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
359
422
  return self.inplace_arg == ArgToInplace.LEFT
360
423
 
361
424
  def _expected_negation_output_size(self) -> int:
362
- return argument_utils.fraction_places(self.right_arg) + min(
425
+ return argument_utils.fraction_places(self.effective_right_arg) + min(
363
426
  self.result_register.integer_part_size,
364
427
  number_utils.bounds_to_integer_part_size(
365
- *(-bound for bound in argument_utils.bounds(self.right_arg))
428
+ *(-bound for bound in argument_utils.bounds(self.effective_right_arg))
366
429
  ),
367
430
  )
368
431
 
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, Iterable, Optional
1
+ from typing import TYPE_CHECKING, Final, Iterable, Optional
2
2
 
3
3
  import pydantic
4
4
 
@@ -11,7 +11,7 @@ from classiq.interface.generator.function_params import get_zero_input_name
11
11
 
12
12
  from classiq.exceptions import ClassiqValueError
13
13
 
14
- UNARY_ARG_NAME: str = "arg"
14
+ UNARY_ARG_NAME: Final[str] = "arg"
15
15
 
16
16
 
17
17
  class UnaryOpParams(ArithmeticOperationParams):
@@ -19,17 +19,16 @@ class UnaryOpParams(ArithmeticOperationParams):
19
19
  inplace: bool = False
20
20
 
21
21
  def garbage_output_size(self) -> pydantic.NonNegativeInt:
22
- return int(self.is_inplaced()) * max(
23
- self.arg.size - self.result_register.size, 0
22
+ return int(self.is_inplaced()) * (
23
+ max(self.arg.integer_part_size - self.result_register.integer_part_size, 0)
24
+ + max(self.arg.fraction_places - self.result_register.fraction_places, 0)
24
25
  )
25
26
 
26
27
  def should_add_zero_inputs(self) -> bool:
27
- return not self.is_inplaced() or self.should_add_zero_input_for_extension()
28
+ return not self.is_inplaced() or self.zero_input_for_extension() > 0
28
29
 
29
- def should_add_zero_input_for_extension(
30
- self, output_size: Optional[int] = None
31
- ) -> bool:
32
- return (output_size or self.result_register.size) > self.arg.size
30
+ def zero_input_for_extension(self) -> pydantic.NonNegativeInt:
31
+ return max(0, self.result_register.size - self.arg.size)
33
32
 
34
33
  def _create_ios(self) -> None:
35
34
  self._inputs = {UNARY_ARG_NAME: self.arg}
@@ -41,8 +40,8 @@ class UnaryOpParams(ArithmeticOperationParams):
41
40
  zero_input_register = self.result_register
42
41
  self._zero_inputs = {zero_input_name: zero_input_register}
43
42
  return
44
- if self.should_add_zero_input_for_extension():
45
- output_extension_size = self.result_register.size - self.arg.size
43
+ if self.zero_input_for_extension() > 0:
44
+ output_extension_size = self.zero_input_for_extension()
46
45
  self._create_zero_input_registers({zero_input_name: output_extension_size})
47
46
  if self.garbage_output_size() > 0:
48
47
  self._outputs[self.garbage_output_name] = RegisterArithmeticInfo(
@@ -80,23 +79,33 @@ class BitwiseInvert(UnaryOpParams):
80
79
  class Negation(UnaryOpParams):
81
80
  output_name = "negated"
82
81
 
83
- def _expected_result_size(self) -> pydantic.PositiveInt:
84
- if self.arg.size == 1:
82
+ @staticmethod
83
+ def _expected_result_size(arg: RegisterArithmeticInfo) -> pydantic.PositiveInt:
84
+ if arg.size == 1:
85
85
  return 1
86
- return self.arg.fraction_places + number_utils.bounds_to_integer_part_size(
87
- *(-bound for bound in self.arg.bounds)
86
+ return arg.fraction_places + number_utils.bounds_to_integer_part_size(
87
+ *(-bound for bound in arg.bounds)
88
88
  )
89
89
 
90
90
  def _get_result_register(self) -> RegisterArithmeticInfo:
91
- is_signed = max(self.arg.bounds) > 0 and self._include_sign
92
- bounds = (-max(self.arg.bounds), -min(self.arg.bounds))
91
+ eff_arg = self.arg.limit_fraction_places(self.machine_precision)
92
+ is_signed = max(eff_arg.bounds) > 0 and self._include_sign
93
+ bounds = (-max(eff_arg.bounds), -min(eff_arg.bounds))
93
94
  return RegisterArithmeticInfo(
94
- size=self.output_size or self._expected_result_size(),
95
- fraction_places=self.arg.fraction_places,
95
+ size=self.output_size or self._expected_result_size(eff_arg),
96
+ fraction_places=eff_arg.fraction_places,
96
97
  is_signed=is_signed,
97
98
  bounds=bounds if (is_signed or min(bounds) >= 0) else None,
98
99
  )
99
100
 
101
+ def zero_input_for_extension(self) -> pydantic.NonNegativeInt:
102
+ eff_arg = self.arg.limit_fraction_places(self.machine_precision)
103
+ if (self.output_size or eff_arg.size) == 1:
104
+ return 0
105
+ return (
106
+ self.output_size or self._expected_result_size(self.arg)
107
+ ) - self.arg.size
108
+
100
109
 
101
110
  class Sign(UnaryOpParams):
102
111
  output_name = "sign"
@@ -1,3 +1,5 @@
1
+ from classiq.interface.generator.functions.classical_type import CLASSICAL_ATTRIBUTES
2
+
1
3
  SUPPORTED_BUILTIN_FUNCTIONS = {"len", "sum", "print"}
2
4
 
3
5
  SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS = {
@@ -9,8 +11,6 @@ SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS = {
9
11
  "get_type",
10
12
  "struct_literal",
11
13
  "get_field",
12
- "fraction_digits",
13
- "is_signed",
14
14
  "molecule_problem_to_hamiltonian",
15
15
  "fock_hamiltonian_problem_to_hamiltonian",
16
16
  "molecule_ground_state_solution_post_process",
@@ -20,3 +20,7 @@ SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS = {
20
20
  "BitwiseOr",
21
21
  *SUPPORTED_BUILTIN_FUNCTIONS,
22
22
  }
23
+
24
+ SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS_QMOD = (
25
+ SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS - CLASSICAL_ATTRIBUTES
26
+ )
@@ -8,3 +8,13 @@ from .pauli import Pauli
8
8
  from .qsvm_feature_map_entanglement import QSVMFeatureMapEntanglement
9
9
 
10
10
  BUILTIN_ENUMS = dict(filter(lambda pair: isinstance(pair[1], EnumMeta), vars().items()))
11
+
12
+ __all__ = [
13
+ "Element",
14
+ "FermionMapping",
15
+ "FinanceFunctionType",
16
+ "LadderOperator",
17
+ "Optimizer",
18
+ "Pauli",
19
+ "QSVMFeatureMapEntanglement",
20
+ ]
@@ -2,4 +2,8 @@ import enum
2
2
 
3
3
 
4
4
  class ClassicalEnum(int, enum.Enum):
5
- pass
5
+ def __str__(self) -> str:
6
+ return f"{type(self).__name__}.{self.name}"
7
+
8
+ def __repr__(self) -> str:
9
+ return str(self)
@@ -1,4 +1,5 @@
1
1
  import ast
2
+ import sys
2
3
  from typing import Any, Mapping, Optional, Type
3
4
 
4
5
  import pydantic
@@ -9,7 +10,7 @@ from classiq.interface.generator.arith.arithmetic_expression_validator import (
9
10
  DEFAULT_SUPPORTED_FUNC_NAMES,
10
11
  )
11
12
  from classiq.interface.generator.expressions.atomic_expression_functions import (
12
- SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS,
13
+ SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS_QMOD,
13
14
  )
14
15
  from classiq.interface.generator.expressions.evaluated_expression import (
15
16
  EvaluatedExpression,
@@ -34,13 +35,19 @@ class Expression(HashableASTNode):
34
35
  @pydantic.validator("expr")
35
36
  def validate_expression(cls, expr: str) -> str:
36
37
  supported_functions = (
37
- SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS
38
+ SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS_QMOD
38
39
  | set(SYMPY_SUPPORTED_EXPRESSIONS)
39
40
  | set(DEFAULT_SUPPORTED_FUNC_NAMES)
40
41
  )
41
42
  validate_expression_str(expr, supported_functions=supported_functions)
42
43
  return expr
43
44
 
45
+ @pydantic.validator("expr")
46
+ def format_expression(cls, expr: str) -> str:
47
+ if sys.version_info >= (3, 9):
48
+ expr = ast.unparse(ast.parse(expr))
49
+ return expr
50
+
44
51
  def is_evaluated(self) -> bool:
45
52
  return self._evaluated_expr is not None
46
53
 
@@ -80,3 +80,10 @@ class QmodQArrayProxy(QmodSizedProxy):
80
80
  )
81
81
 
82
82
  return HandleBinding(name=self._name)
83
+
84
+ def __len__(self) -> int:
85
+ if (slice_ := self.slice) is not None:
86
+ return slice_[1] - slice_[0]
87
+ elif self.index is not None:
88
+ return 1
89
+ return self._size
@@ -50,5 +50,4 @@ class QmodQNumProxy(QmodQScalarProxy):
50
50
  "size": self.size,
51
51
  "is_signed": self.is_signed,
52
52
  "fraction_digits": self.fraction_digits,
53
- "len": self.size,
54
53
  }
@@ -58,7 +58,16 @@ SPECIAL_FUNCTIONS: List[str] = [
58
58
  "catalan",
59
59
  ]
60
60
  PIECEWISE_FUNCTIONS: List[str] = ["Piecewise", "Heaviside"]
61
- CONSTANTS: List[str] = ["pi", "E", "I", "GoldenRatio", "EulerGamma", "Catalan"]
61
+ NUMERIC_CONSTANTS: List[str] = [
62
+ "pi",
63
+ "E",
64
+ "I",
65
+ "GoldenRatio",
66
+ "EulerGamma",
67
+ "Catalan",
68
+ ]
69
+ CONSTANTS: List[str] = NUMERIC_CONSTANTS + ["true", "false"]
70
+
62
71
  DATA_TYPES: List[str] = ["Matrix"]
63
72
  LOGIC_OPERATORS: List[str] = [
64
73
  "And",
@@ -1,62 +1,7 @@
1
- from classiq.interface.generator.functions.builtins.quantum_operators import (
2
- get_single_empty_operand_operator,
3
- )
4
- from classiq.interface.generator.functions.classical_type import Bool, Integer
5
- from classiq.interface.generator.functions.port_declaration import (
6
- PortDeclarationDirection,
7
- )
8
- from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
9
- from classiq.interface.model.port_declaration import PortDeclaration
10
- from classiq.interface.model.quantum_function_declaration import (
11
- QuantumFunctionDeclaration,
12
- QuantumOperandDeclaration,
13
- )
14
-
15
- _CTRL_FIELD_NAME = "ctrl"
16
- CONTROL_OPERATOR = get_single_empty_operand_operator(
17
- operator_name="control",
18
- port_declarations={
19
- _CTRL_FIELD_NAME: PortDeclaration(
20
- name=_CTRL_FIELD_NAME,
21
- direction=PortDeclarationDirection.Inout,
22
- )
23
- },
24
- )
25
-
26
- REPEAT_OPERATOR = QuantumFunctionDeclaration(
27
- name="repeat",
28
- param_decls={"count": Integer()},
29
- operand_declarations={
30
- "iteration": QuantumOperandDeclaration(
31
- name="iteration", param_decls={"index": Integer()}
32
- )
33
- },
34
- )
35
- POWER_OPERATOR = get_single_empty_operand_operator(
36
- operator_name="power", param_decls={"power": Integer()}
37
- )
38
- INVERT_OPERATOR = get_single_empty_operand_operator(operator_name="invert")
39
-
40
- IF_OPERATOR = QuantumFunctionDeclaration(
41
- name="if",
42
- param_decls={"condition": Bool()},
43
- operand_declarations={
44
- "then": QuantumOperandDeclaration(name="then"),
45
- "else": QuantumOperandDeclaration(name="else"),
46
- },
47
- )
48
- COMPUTE = get_single_empty_operand_operator(operator_name="compute")
49
- UNCOMPUTE = get_single_empty_operand_operator(operator_name="uncompute")
50
-
51
-
52
- INTERNAL_OPERATORS = nameables_to_dict(
53
- [
54
- CONTROL_OPERATOR,
55
- REPEAT_OPERATOR,
56
- POWER_OPERATOR,
57
- INVERT_OPERATOR,
58
- IF_OPERATOR,
59
- COMPUTE,
60
- UNCOMPUTE,
61
- ]
62
- )
1
+ CTRL_VAR_PREFIX = "ctrl__"
2
+ CONTROL_OPERATOR_NAME = "control"
3
+ INVERT_OPERATOR_NAME = "invert"
4
+ REPEAT_OPERATOR_NAME = "iteration"
5
+ POWER_OPERATOR_NAME = "power"
6
+ COMPUTE_OPERATOR_NAME = "compute"
7
+ UNCOMPUTE_OPERATOR_NAME = "uncompute"