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,11 +1,16 @@
1
1
  from typing import Sequence, Union
2
2
 
3
+ from classiq.interface.generator.functions.type_name import TypeName
4
+ from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
5
+ from classiq.interface.model.quantum_type import QuantumBitvector
6
+
3
7
  from classiq import EnumDeclaration, StructDeclaration
8
+ from classiq.qmod.model_state_container import QMODULE
4
9
  from classiq.qmod.semantics.error_manager import ErrorManager
5
10
 
6
11
 
7
12
  def check_duplicate_types(
8
- types: Sequence[Union[EnumDeclaration, StructDeclaration]]
13
+ types: Sequence[Union[EnumDeclaration, StructDeclaration, QStructDeclaration]]
9
14
  ) -> None:
10
15
  known_types = {
11
16
  type_.name for type_ in EnumDeclaration.BUILTIN_ENUM_DECLARATIONS.values()
@@ -19,3 +24,105 @@ def check_duplicate_types(
19
24
  ErrorManager().add_error(f"Type {type_.name!r} already exists")
20
25
  else:
21
26
  known_types.add(type_.name)
27
+
28
+
29
+ def check_qstruct_flexibility(qstruct: QStructDeclaration) -> None:
30
+ _check_qstruct_no_array_without_size_and_element_size(qstruct)
31
+ _check_qstruct_at_most_one_type_without_size(qstruct)
32
+
33
+
34
+ def _check_qstruct_no_array_without_size_and_element_size(
35
+ qstruct: QStructDeclaration,
36
+ ) -> None:
37
+ offending_array_fields = [
38
+ field_name
39
+ for field_name, field_type in qstruct.fields.items()
40
+ if isinstance(field_type, QuantumBitvector)
41
+ and not field_type.has_length
42
+ and not field_type.element_type.has_size_in_bits
43
+ ]
44
+ if len(offending_array_fields) > 0:
45
+ with ErrorManager().node_context(qstruct):
46
+ ErrorManager().add_error(
47
+ f"Quantum struct {qstruct.name} contains arrays whose neither length "
48
+ f"nor element size are constants. Offending fields: "
49
+ f"{', '.join(offending_array_fields)}"
50
+ )
51
+
52
+
53
+ def _check_qstruct_at_most_one_type_without_size(qstruct: QStructDeclaration) -> None:
54
+ fields_without_size = [
55
+ field_name
56
+ for field_name, field_type in qstruct.fields.items()
57
+ if not field_type.has_size_in_bits
58
+ ]
59
+ if len(fields_without_size) > 1:
60
+ with ErrorManager().node_context(qstruct):
61
+ ErrorManager().add_error(
62
+ f"Quantum struct {qstruct.name} has more than one field whose size is "
63
+ f"not constant. Offending fields: {', '.join(fields_without_size)}"
64
+ )
65
+
66
+
67
+ def check_qstruct_fields_are_defined(qstruct: QStructDeclaration) -> bool:
68
+ all_defined = True
69
+ for field_type in qstruct.fields.values():
70
+ if (
71
+ isinstance(field_type, TypeName)
72
+ and field_type.name not in QMODULE.qstruct_decls
73
+ ):
74
+ with ErrorManager().node_context(field_type):
75
+ ErrorManager().add_error(
76
+ f"Quantum struct {field_type.name!r} is not defined."
77
+ )
78
+ all_defined = False
79
+ return all_defined
80
+
81
+
82
+ def check_qstruct_has_fields(qstruct: QStructDeclaration) -> None:
83
+ if len(qstruct.fields) == 0:
84
+ with ErrorManager().node_context(qstruct):
85
+ ErrorManager().add_error(
86
+ f"Quantum struct {qstruct.name!r} must have at least one field."
87
+ )
88
+
89
+
90
+ def check_cstruct_has_fields(cstruct: StructDeclaration) -> None:
91
+ if len(cstruct.variables) == 0:
92
+ with ErrorManager().node_context(cstruct):
93
+ ErrorManager().add_error(
94
+ f"Classical struct {cstruct.name!r} must have at least one field."
95
+ )
96
+
97
+
98
+ def check_qstruct_is_not_recursive(qstruct: QStructDeclaration) -> bool:
99
+ non_recursive = True
100
+ for main_field_name, main_field in qstruct.fields.items():
101
+ if (
102
+ not isinstance(main_field, TypeName)
103
+ or main_field.name not in QMODULE.qstruct_decls
104
+ ):
105
+ continue
106
+ main_field_qstruct = QMODULE.qstruct_decls[main_field.name]
107
+ seen_qstructs = {qstruct.name}
108
+ stack = [main_field_qstruct]
109
+ while stack:
110
+ qstruct = stack.pop()
111
+ if qstruct.name in seen_qstructs:
112
+ with ErrorManager().node_context(qstruct):
113
+ ErrorManager().add_error(
114
+ f"Declaration of field {main_field_name!r} in quantum struct "
115
+ f"{qstruct.name!r} creates a recursive definition."
116
+ )
117
+ non_recursive = False
118
+ break
119
+ seen_qstructs.add(qstruct.name)
120
+ stack.extend(
121
+ [
122
+ QMODULE.qstruct_decls[field.name]
123
+ for field in qstruct.fields.values()
124
+ if isinstance(field, TypeName)
125
+ and field.name in QMODULE.qstruct_decls
126
+ ]
127
+ )
128
+ return non_recursive
@@ -0,0 +1,32 @@
1
+ from classiq.interface.generator.visitor import Transformer
2
+ from classiq.interface.model.port_declaration import PortDeclaration
3
+ from classiq.interface.model.quantum_function_declaration import (
4
+ AnonQuantumOperandDeclaration,
5
+ )
6
+ from classiq.interface.model.quantum_type import QuantumBitvector, QuantumNumeric
7
+
8
+
9
+ def decl_without_type_attributes(
10
+ operand_declaration: AnonQuantumOperandDeclaration,
11
+ ) -> AnonQuantumOperandDeclaration:
12
+ remover = AttributeRemover()
13
+ return operand_declaration.copy(
14
+ update=dict(
15
+ positional_arg_declarations=[
16
+ remover.visit(arg) if isinstance(arg, PortDeclaration) else arg
17
+ for arg in operand_declaration.positional_arg_declarations
18
+ ]
19
+ )
20
+ )
21
+
22
+
23
+ class AttributeRemover(Transformer):
24
+ """Remove attributes that could be expressions such as length, fraction places, etc."""
25
+
26
+ def visit_QuantumNumeric(self, node: QuantumNumeric) -> QuantumNumeric:
27
+ return QuantumNumeric(source_ref=node.source_ref)
28
+
29
+ def visit_QuantumBitvector(self, node: QuantumBitvector) -> QuantumBitvector:
30
+ return QuantumBitvector(
31
+ element_type=self.visit(node.element_type), source_ref=node.source_ref
32
+ )
classiq/qmod/utilities.py CHANGED
@@ -5,9 +5,9 @@ import keyword
5
5
  import sys
6
6
  from enum import Enum as PythonEnum
7
7
  from types import FrameType
8
- from typing import Any, get_args, get_origin
8
+ from typing import Any, Literal, Optional, get_args, get_origin, overload
9
9
 
10
- from classiq.interface.ast_node import SourceReference
10
+ from classiq.interface.source_reference import SourceReference
11
11
 
12
12
  DEFAULT_DECIMAL_PRECISION = 4
13
13
 
@@ -18,8 +18,19 @@ def mangle_keyword(name: str) -> str:
18
18
  return name
19
19
 
20
20
 
21
+ @overload
21
22
  def unmangle_keyword(name: str) -> str:
22
- assert name
23
+ pass
24
+
25
+
26
+ @overload
27
+ def unmangle_keyword(name: None) -> None:
28
+ pass
29
+
30
+
31
+ def unmangle_keyword(name: Optional[str]) -> Optional[str]:
32
+ if name is None:
33
+ return None
23
34
  if name[-1] == "_" and keyword.iskeyword(name[:-1]):
24
35
  name = name[:-1]
25
36
  return name
@@ -29,9 +40,19 @@ def version_portable_get_args(py_type: type) -> tuple:
29
40
  if get_origin(py_type) is None:
30
41
  return tuple()
31
42
  if sys.version_info[0:2] < (3, 10):
32
- return get_args(py_type) # The result of __class_getitem__
43
+ type_args = get_args(py_type) # The result of __class_getitem__
33
44
  else:
34
- return get_args(py_type)[0]
45
+ type_args = get_args(py_type)[0]
46
+ if not isinstance(type_args, tuple):
47
+ return type_args
48
+ return tuple(
49
+ (
50
+ version_portable_get_args(type_arg)
51
+ if get_origin(type_arg) == Literal
52
+ else type_arg
53
+ )
54
+ for type_arg in type_args
55
+ )
35
56
 
36
57
 
37
58
  def get_source_ref(frame: FrameType) -> SourceReference:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: classiq
3
- Version: 0.43.3
3
+ Version: 0.44.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  Home-page: https://classiq.io
6
6
  License: Proprietary
@@ -39,12 +39,12 @@ Requires-Dist: matplotlib (>=3.4.3,<4.0.0)
39
39
  Requires-Dist: networkx (>=2.5.1,<3.0.0)
40
40
  Requires-Dist: numexpr (>=2.7.3,<3.0.0)
41
41
  Requires-Dist: numpy (>=1.20.1,<2.0.0)
42
- Requires-Dist: packaging (>=22.0,<23.0)
42
+ Requires-Dist: packaging (>=23.2,<24.0)
43
43
  Requires-Dist: pandas (>=1.4.0,<3.0.0)
44
44
  Requires-Dist: plotly (>=5.7.0,<6.0.0)
45
45
  Requires-Dist: pydantic (>=1.9.1,<2.0.0)
46
46
  Requires-Dist: scipy (>=1.10.1,<2.0.0)
47
- Requires-Dist: sympy (>=1.9.0,<1.11.0)
47
+ Requires-Dist: sympy (>=1.13.0,<2.0.0)
48
48
  Requires-Dist: tabulate (>=0.8.9,<1)
49
49
  Requires-Dist: torch (>=2.0,<3.0) ; extra == "qml"
50
50
  Requires-Dist: torchvision (>=0.15,<1.0) ; extra == "qml"