classiq 0.74.0__py3-none-any.whl → 0.76.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 (96) hide show
  1. classiq/_internals/api_wrapper.py +36 -0
  2. classiq/analyzer/show_interactive_hack.py +58 -2
  3. classiq/applications/chemistry/chemistry_model_constructor.py +8 -1
  4. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -0
  5. classiq/applications/combinatorial_optimization/combinatorial_problem.py +4 -4
  6. classiq/applications/qnn/gradients/quantum_gradient.py +3 -5
  7. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -2
  8. classiq/applications/qnn/qlayer.py +23 -19
  9. classiq/applications/qnn/types.py +1 -4
  10. classiq/execution/__init__.py +3 -0
  11. classiq/execution/execution_session.py +3 -16
  12. classiq/execution/qnn.py +2 -2
  13. classiq/execution/user_budgets.py +38 -0
  14. classiq/executor.py +7 -19
  15. classiq/interface/_version.py +1 -1
  16. classiq/interface/debug_info/debug_info.py +18 -13
  17. classiq/interface/executor/user_budget.py +56 -0
  18. classiq/interface/generator/application_apis/finance_declarations.py +3 -0
  19. classiq/interface/generator/expressions/atomic_expression_functions.py +3 -0
  20. classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +30 -124
  21. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +46 -22
  22. classiq/interface/generator/expressions/proxies/classical/qmod_struct_instance.py +7 -0
  23. classiq/interface/generator/expressions/proxies/classical/utils.py +14 -13
  24. classiq/interface/generator/expressions/proxies/quantum/qmod_qscalar_proxy.py +9 -2
  25. classiq/interface/generator/expressions/proxies/quantum/qmod_sized_proxy.py +4 -1
  26. classiq/interface/generator/expressions/sympy_supported_expressions.py +1 -0
  27. classiq/interface/generator/functions/classical_type.py +36 -1
  28. classiq/interface/generator/functions/type_name.py +32 -5
  29. classiq/interface/generator/functions/type_qualifier.py +15 -0
  30. classiq/interface/generator/generated_circuit_data.py +11 -25
  31. classiq/interface/generator/model/preferences/preferences.py +7 -0
  32. classiq/interface/generator/quantum_program.py +5 -19
  33. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +10 -13
  34. classiq/interface/helpers/backward_compatibility.py +9 -0
  35. classiq/interface/helpers/datastructures.py +6 -0
  36. classiq/interface/helpers/versioned_model.py +12 -0
  37. classiq/interface/interface_version.py +1 -1
  38. classiq/interface/model/handle_binding.py +12 -0
  39. classiq/interface/model/port_declaration.py +1 -2
  40. classiq/interface/model/quantum_lambda_function.py +2 -1
  41. classiq/interface/model/statement_block.py +9 -1
  42. classiq/interface/model/within_apply_operation.py +12 -0
  43. classiq/interface/server/routes.py +6 -0
  44. classiq/model_expansions/atomic_expression_functions_defs.py +82 -23
  45. classiq/model_expansions/capturing/captured_vars.py +2 -0
  46. classiq/model_expansions/closure.py +18 -0
  47. classiq/model_expansions/evaluators/argument_types.py +6 -5
  48. classiq/model_expansions/evaluators/classical_type_inference.py +17 -6
  49. classiq/model_expansions/evaluators/parameter_types.py +26 -13
  50. classiq/model_expansions/evaluators/type_type_match.py +2 -2
  51. classiq/model_expansions/expression_evaluator.py +1 -1
  52. classiq/model_expansions/generative_functions.py +66 -33
  53. classiq/model_expansions/interpreters/base_interpreter.py +27 -19
  54. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +26 -0
  55. classiq/model_expansions/interpreters/generative_interpreter.py +25 -1
  56. classiq/model_expansions/quantum_operations/allocate.py +27 -11
  57. classiq/model_expansions/quantum_operations/assignment_result_processor.py +220 -19
  58. classiq/model_expansions/quantum_operations/bind.py +54 -30
  59. classiq/model_expansions/quantum_operations/block_evaluator.py +42 -0
  60. classiq/model_expansions/quantum_operations/call_emitter.py +14 -12
  61. classiq/model_expansions/quantum_operations/composite_emitter.py +1 -1
  62. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +23 -9
  63. classiq/model_expansions/quantum_operations/emitter.py +21 -8
  64. classiq/model_expansions/quantum_operations/expression_evaluator.py +1 -0
  65. classiq/model_expansions/quantum_operations/handle_evaluator.py +1 -0
  66. classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -3
  67. classiq/model_expansions/scope.py +10 -7
  68. classiq/model_expansions/sympy_conversion/arithmetics.py +18 -0
  69. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +2 -0
  70. classiq/model_expansions/sympy_conversion/sympy_to_python.py +10 -1
  71. classiq/model_expansions/transformers/model_renamer.py +48 -8
  72. classiq/model_expansions/utils/handles_collector.py +1 -1
  73. classiq/model_expansions/visitors/symbolic_param_inference.py +197 -0
  74. classiq/model_expansions/visitors/variable_references.py +45 -9
  75. classiq/qmod/builtins/functions/allocation.py +2 -2
  76. classiq/qmod/builtins/functions/arithmetic.py +14 -12
  77. classiq/qmod/builtins/functions/standard_gates.py +23 -23
  78. classiq/qmod/declaration_inferrer.py +19 -7
  79. classiq/qmod/generative.py +9 -1
  80. classiq/qmod/native/expression_to_qmod.py +4 -0
  81. classiq/qmod/native/pretty_printer.py +8 -3
  82. classiq/qmod/pretty_print/pretty_printer.py +1 -1
  83. classiq/qmod/python_classical_type.py +4 -5
  84. classiq/qmod/qmod_constant.py +15 -7
  85. classiq/qmod/qmod_variable.py +30 -2
  86. classiq/qmod/quantum_function.py +19 -6
  87. classiq/qmod/semantics/lambdas.py +6 -2
  88. classiq/qmod/semantics/validation/main_validation.py +17 -4
  89. classiq/qmod/symbolic.py +8 -19
  90. classiq/qmod/symbolic_expr.py +34 -2
  91. classiq/qmod/write_qmod.py +5 -1
  92. classiq/synthesis.py +17 -31
  93. classiq/visualization.py +35 -0
  94. {classiq-0.74.0.dist-info → classiq-0.76.0.dist-info}/METADATA +1 -1
  95. {classiq-0.74.0.dist-info → classiq-0.76.0.dist-info}/RECORD +96 -91
  96. {classiq-0.74.0.dist-info → classiq-0.76.0.dist-info}/WHEEL +1 -1
@@ -4,6 +4,8 @@ import ast
4
4
  from enum import Enum as PythonEnum
5
5
  from typing import Any
6
6
 
7
+ import sympy
8
+
7
9
  from classiq.qmod.utilities import qmod_val_to_expr_str
8
10
 
9
11
 
@@ -33,10 +35,14 @@ class SymbolicExpr(Symbolic):
33
35
 
34
36
  @staticmethod
35
37
  def _binary_op(lhs: Any, rhs: Any, op: str) -> SymbolicExpr:
36
- if not isinstance(lhs, (SymbolicExpr, int, float, bool, PythonEnum)):
38
+ if not isinstance(
39
+ lhs, (SymbolicExpr, int, float, bool, PythonEnum, sympy.Basic)
40
+ ):
37
41
  raise TypeError(f"Invalid lhs argument {lhs!r} for binary operation {op!r}")
38
42
 
39
- if not isinstance(rhs, (SymbolicExpr, int, float, bool, PythonEnum)):
43
+ if not isinstance(
44
+ rhs, (SymbolicExpr, int, float, bool, PythonEnum, sympy.Basic)
45
+ ):
40
46
  raise TypeError(f"Invalid lhs argument {rhs!r} for binary operation {op!r}")
41
47
 
42
48
  lhs_str = qmod_val_to_expr_str(lhs)
@@ -171,3 +177,29 @@ class SymbolicEquality(SymbolicExpr):
171
177
  super().__init__(sym_expr._expr, sym_expr.is_quantum)
172
178
  self.lhs = lhs
173
179
  self.rhs = rhs
180
+
181
+
182
+ class SymbolicSubscriptAndField(SymbolicExpr):
183
+ def __getattr__(self, item: str) -> SymbolicSubscriptAndField:
184
+ return SymbolicSubscriptAndField(f"{self}.{item}", is_quantum=self.is_quantum)
185
+
186
+ def __getitem__(self, item: Any) -> SymbolicExpr:
187
+ if isinstance(item, slice):
188
+ start = item.start
189
+ stop = item.stop
190
+ step = item.step
191
+ item_is_quantum = (
192
+ (isinstance(start, SymbolicExpr) and start.is_quantum)
193
+ or (isinstance(stop, SymbolicExpr) and stop.is_quantum)
194
+ or (isinstance(step, SymbolicExpr) and step.is_quantum)
195
+ )
196
+ start_str = "" if start is None else qmod_val_to_expr_str(start)
197
+ stop_str = "" if stop is None else qmod_val_to_expr_str(stop)
198
+ step_str = "" if step is None else qmod_val_to_expr_str(step)
199
+ item_str = f"{start_str}:{stop_str}:{step_str}"
200
+ else:
201
+ item_is_quantum = isinstance(item, SymbolicExpr) and item.is_quantum
202
+ item_str = qmod_val_to_expr_str(item)
203
+ return SymbolicSubscriptAndField(
204
+ f"{self}[{item_str}]", is_quantum=self.is_quantum or item_is_quantum
205
+ )
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  from pathlib import Path
3
- from typing import Optional, Union
3
+ from typing import Any, Optional, Union
4
4
 
5
5
  from classiq.interface.model.model import Model, SerializedModel
6
6
 
@@ -17,6 +17,8 @@ def write_qmod(
17
17
  name: str,
18
18
  directory: Optional[Path] = None,
19
19
  decimal_precision: int = DEFAULT_DECIMAL_PRECISION,
20
+ *args: Any,
21
+ **kwargs: Any,
20
22
  ) -> None:
21
23
  """
22
24
  Creates a native Qmod file from a serialized model and outputs the synthesis options (Preferences and Constraints) to a file.
@@ -27,6 +29,8 @@ def write_qmod(
27
29
  name: The name to save the file by.
28
30
  directory: The directory to save the files in. If None, the current working directory is used.
29
31
  decimal_precision: The number of decimal places to use for numbers, set to 4 by default.
32
+ args: (placeholder)
33
+ kwargs: (placeholder)
30
34
 
31
35
  Returns:
32
36
  None
classiq/synthesis.py CHANGED
@@ -1,6 +1,4 @@
1
- from typing import Any, NewType, Optional, Union
2
-
3
- import pydantic
1
+ from typing import Any, Optional, Union
4
2
 
5
3
  from classiq.interface.analyzer.result import QasmCode
6
4
  from classiq.interface.exceptions import ClassiqError, ClassiqValueError
@@ -12,43 +10,33 @@ from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model, SerializedM
12
10
  from classiq import QuantumProgram
13
11
  from classiq._internals import async_utils
14
12
  from classiq._internals.api_wrapper import ApiWrapper
15
- from classiq.qmod.quantum_function import GenerativeQFunc, QFunc
16
-
17
- SerializedQuantumProgram = NewType("SerializedQuantumProgram", str)
13
+ from classiq.qmod.quantum_function import BaseQFunc
18
14
 
19
- CANT_PARSE_QUANTUM_PROGRAM_MSG = (
20
- "Can not parse quantum_program into GeneratedCircuit, \n"
21
- )
15
+ SerializedQuantumProgram = QuantumProgram
22
16
 
23
17
 
24
- def show(quantum_program: SerializedQuantumProgram, display_url: bool = True) -> None:
18
+ def show(quantum_program: QuantumProgram, display_url: bool = True) -> None:
25
19
  """
26
20
  Displays the interactive representation of the quantum program in the Classiq IDE.
27
21
 
28
22
  Args:
29
23
  quantum_program:
30
- The serialized quantum program to be displayed.
24
+ The quantum program to be displayed.
31
25
  display_url:
32
26
  Whether to print the url
33
27
 
34
28
  Links:
35
29
  [Visualization tool](https://docs.classiq.io/latest/reference-manual/analyzer/quantum-program-visualization-tool/)
36
30
  """
37
- try:
38
- circuit = QuantumProgram.model_validate_json(quantum_program)
39
- except pydantic.ValidationError as exc:
40
- raise ClassiqValueError(CANT_PARSE_QUANTUM_PROGRAM_MSG) from exc
41
- circuit.show() # type: ignore[attr-defined]
31
+ QuantumProgram.model_validate(quantum_program)
32
+ quantum_program.show() # type: ignore[attr-defined]
42
33
 
43
34
 
44
- async def quantum_program_from_qasm_async(qasm: str) -> SerializedQuantumProgram:
45
- quantum_program = await ApiWrapper.get_generated_circuit_from_qasm(
46
- QasmCode(code=qasm)
47
- )
48
- return SerializedQuantumProgram(quantum_program.model_dump_json())
35
+ async def quantum_program_from_qasm_async(qasm: str) -> QuantumProgram:
36
+ return await ApiWrapper.get_generated_circuit_from_qasm(QasmCode(code=qasm))
49
37
 
50
38
 
51
- def quantum_program_from_qasm(qasm: str) -> SerializedQuantumProgram:
39
+ def quantum_program_from_qasm(qasm: str) -> QuantumProgram:
52
40
  """
53
41
  generate a quantum program from a QASM file.
54
42
 
@@ -56,25 +44,24 @@ def quantum_program_from_qasm(qasm: str) -> SerializedQuantumProgram:
56
44
  qasm: A QASM2/3 string.
57
45
 
58
46
  Returns:
59
- SerializedQuantumProgram: Quantum program serialized as a string. (See: QuantumProgram)
47
+ QuantumProgram: Quantum program. (See: QuantumProgram)
60
48
  """
61
49
  return async_utils.run(quantum_program_from_qasm_async(qasm))
62
50
 
63
51
 
64
52
  async def synthesize_async(
65
53
  serialized_model: SerializedModel,
66
- ) -> SerializedQuantumProgram:
54
+ ) -> QuantumProgram:
67
55
  model = Model.model_validate_json(serialized_model)
68
- quantum_program = await ApiWrapper.call_generation_task(model)
69
- return SerializedQuantumProgram(quantum_program.model_dump_json(indent=2))
56
+ return await ApiWrapper.call_generation_task(model)
70
57
 
71
58
 
72
59
  def synthesize(
73
- model: Union[SerializedModel, QFunc, GenerativeQFunc],
60
+ model: Union[SerializedModel, BaseQFunc],
74
61
  auto_show: bool = False,
75
62
  constraints: Optional[Constraints] = None,
76
63
  preferences: Optional[Preferences] = None,
77
- ) -> SerializedQuantumProgram:
64
+ ) -> QuantumProgram:
78
65
  """
79
66
  Synthesize a model with the Classiq engine to receive a quantum program.
80
67
  [More details](https://docs.classiq.io/latest/reference-manual/synthesis/)
@@ -86,9 +73,9 @@ def synthesize(
86
73
  preferences: Preferences for the synthesis of the model. See Preferences (Optional).
87
74
 
88
75
  Returns:
89
- SerializedQuantumProgram: Quantum program serialized as a string. (See: QuantumProgram)
76
+ QuantumProgram: Quantum program. (See: QuantumProgram)
90
77
  """
91
- if isinstance(model, (QFunc, GenerativeQFunc)):
78
+ if isinstance(model, BaseQFunc):
92
79
  func_name = model._py_callable.__name__
93
80
  if func_name != MAIN_FUNCTION_NAME:
94
81
  raise ClassiqError(
@@ -252,7 +239,6 @@ def update_execution_preferences(
252
239
 
253
240
  __all__ = [
254
241
  "SerializedModel",
255
- "SerializedQuantumProgram",
256
242
  "set_constraints",
257
243
  "set_execution_preferences",
258
244
  "set_preferences",
@@ -0,0 +1,35 @@
1
+ from typing import NewType
2
+
3
+ from classiq.interface.analyzer.result import DataID
4
+ from classiq.interface.exceptions import ClassiqAPIError
5
+
6
+ from classiq._internals import async_utils
7
+ from classiq._internals.api_wrapper import ApiWrapper
8
+
9
+ SerializedVisualModel = NewType("SerializedVisualModel", str)
10
+
11
+
12
+ async def visualize_async(
13
+ data_id: DataID,
14
+ ) -> SerializedVisualModel:
15
+ try:
16
+ visual_model = await ApiWrapper.call_get_visual_model(data_id.id)
17
+ except ClassiqAPIError as error:
18
+ if error.status_code != 404:
19
+ raise error
20
+ analyzer_data = await ApiWrapper.get_analyzer_app_data(data_id)
21
+ visual_model = await ApiWrapper.call_visualization_task(analyzer_data)
22
+ return SerializedVisualModel(visual_model.model_dump_json(indent=2))
23
+
24
+
25
+ def visualize(
26
+ data_id: DataID,
27
+ ) -> SerializedVisualModel:
28
+ result = async_utils.run(visualize_async(data_id))
29
+ return result
30
+
31
+
32
+ __all__ = [
33
+ "SerializedVisualModel",
34
+ "visualize",
35
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: classiq
3
- Version: 0.74.0
3
+ Version: 0.76.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  License: Proprietary
6
6
  Keywords: quantum computing,quantum circuits,quantum algorithms,QAD,QDL