classiq 0.37.1__py3-none-any.whl → 0.65.3__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.
- classiq/__init__.py +49 -34
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +3 -2
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +241 -95
- classiq/_internals/async_utils.py +2 -77
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +18 -8
- classiq/_internals/authentication/password_manager.py +40 -13
- classiq/_internals/authentication/token_manager.py +11 -6
- classiq/_internals/client.py +106 -37
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +56 -50
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +50 -47
- classiq/analyzer/analyzer_utilities.py +15 -15
- classiq/analyzer/rb.py +19 -20
- classiq/analyzer/show_interactive_hack.py +30 -7
- classiq/analyzer/url_utils.py +2 -3
- classiq/applications/__init__.py +3 -12
- classiq/applications/chemistry/__init__.py +14 -10
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +170 -170
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/applications/combinatorial_helpers/allowed_constraints.py +23 -0
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +166 -0
- classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications/combinatorial_helpers/encoding_utils.py +124 -0
- classiq/applications/combinatorial_helpers/memory.py +75 -0
- classiq/applications/combinatorial_helpers/optimization_model.py +193 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications/combinatorial_helpers/transformations/encoding.py +189 -0
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +143 -0
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +120 -0
- classiq/applications/combinatorial_helpers/transformations/penalty.py +31 -0
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +74 -0
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +87 -0
- classiq/applications/combinatorial_optimization/__init__.py +24 -5
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +137 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +4 -5
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +50 -57
- classiq/applications/grover/__init__.py +9 -0
- classiq/applications/grover/grover_model_constructor.py +157 -0
- classiq/applications/hamiltonian/__init__.py +0 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +8 -8
- classiq/applications/qnn/datasets/__init__.py +9 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +30 -10
- classiq/applications/qnn/torch_utils.py +4 -3
- classiq/applications/qnn/types.py +7 -7
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +4 -10
- classiq/applications/qsvm/qsvm_data_generation.py +5 -8
- classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
- classiq/execution/__init__.py +8 -3
- classiq/execution/all_hardware_devices.py +11 -0
- classiq/execution/execution_session.py +400 -0
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +197 -25
- classiq/execution/qnn.py +79 -0
- classiq/executor.py +23 -117
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +49 -16
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +36 -32
- classiq/interface/applications/qsvm.py +28 -25
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -119
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +27 -22
- classiq/interface/backend/quantum_backend_providers.py +70 -16
- classiq/interface/chemistry/fermionic_operator.py +43 -32
- classiq/interface/chemistry/ground_state_problem.py +42 -24
- classiq/interface/chemistry/molecule.py +20 -14
- classiq/interface/chemistry/operator.py +75 -236
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +2 -4
- classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
- classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
- classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +3 -3
- classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +14 -9
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +86 -0
- classiq/interface/exceptions.py +201 -0
- classiq/interface/execution/iqcc.py +19 -0
- classiq/interface/execution/jobs.py +15 -12
- classiq/interface/execution/primitives.py +18 -0
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/executor/estimation.py +2 -2
- classiq/interface/executor/execution_preferences.py +26 -143
- classiq/interface/executor/execution_request.py +36 -56
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +34 -22
- classiq/interface/executor/{quantum_program.py → quantum_code.py} +44 -34
- classiq/interface/executor/quantum_instruction_set.py +3 -2
- classiq/interface/executor/register_initialization.py +12 -17
- classiq/interface/executor/result.py +122 -64
- classiq/interface/executor/vqe_result.py +11 -11
- classiq/interface/finance/function_input.py +42 -19
- classiq/interface/finance/gaussian_model_input.py +7 -5
- classiq/interface/finance/log_normal_model_input.py +6 -4
- classiq/interface/finance/model_input.py +6 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +27 -14
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/__init__.py +1 -0
- classiq/interface/generator/application_apis/arithmetic_declarations.py +17 -0
- classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +48 -69
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
- classiq/interface/generator/arith/argument_utils.py +57 -6
- classiq/interface/generator/arith/arithmetic.py +37 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +15 -17
- classiq/interface/generator/arith/arithmetic_expression_abc.py +70 -26
- classiq/interface/generator/arith/arithmetic_expression_parser.py +18 -12
- classiq/interface/generator/arith/arithmetic_expression_validator.py +61 -43
- classiq/interface/generator/arith/arithmetic_operations.py +19 -16
- classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
- classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
- classiq/interface/generator/arith/ast_node_rewrite.py +4 -3
- classiq/interface/generator/arith/binary_ops.py +375 -139
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -23
- classiq/interface/generator/arith/logical_ops.py +16 -12
- classiq/interface/generator/arith/machine_precision.py +3 -0
- classiq/interface/generator/arith/number_utils.py +44 -48
- classiq/interface/generator/arith/register_user_input.py +70 -27
- classiq/interface/generator/arith/unary_ops.py +57 -46
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/builtin_api_builder.py +2 -9
- classiq/interface/generator/chemistry_function_params.py +5 -5
- classiq/interface/generator/circuit_code/circuit_code.py +7 -7
- classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
- classiq/interface/generator/commuting_pauli_exponentiation.py +8 -6
- classiq/interface/generator/compiler_keywords.py +8 -0
- classiq/interface/generator/complex_type.py +13 -25
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +35 -28
- classiq/interface/generator/copy.py +47 -0
- classiq/interface/generator/custom_ansatz.py +2 -5
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +26 -8
- classiq/interface/generator/expressions/enums/__init__.py +0 -10
- classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
- classiq/interface/generator/expressions/evaluated_expression.py +21 -7
- classiq/interface/generator/expressions/expression.py +27 -15
- classiq/interface/generator/expressions/expression_constants.py +9 -3
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +59 -0
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
- classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
- classiq/interface/generator/expressions/sympy_supported_expressions.py +20 -11
- classiq/interface/generator/finance.py +3 -3
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
- classiq/interface/generator/function_params.py +42 -69
- classiq/interface/generator/functions/__init__.py +0 -22
- classiq/interface/generator/functions/builtins/__init__.py +0 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
- classiq/interface/generator/functions/classical_function_declaration.py +18 -9
- classiq/interface/generator/functions/classical_type.py +47 -166
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +13 -14
- classiq/interface/generator/functions/port_declaration.py +1 -13
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +90 -0
- classiq/interface/generator/generated_circuit_data.py +155 -22
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -23
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +12 -8
- classiq/interface/generator/hardware/hardware_data.py +76 -36
- classiq/interface/generator/hardware_efficient_ansatz.py +38 -17
- classiq/interface/generator/hartree_fock.py +14 -4
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +33 -19
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +20 -16
- classiq/interface/generator/mcx.py +29 -20
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +27 -8
- classiq/interface/generator/model/model.py +32 -203
- classiq/interface/generator/model/preferences/preferences.py +118 -43
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +27 -22
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +17 -13
- classiq/interface/generator/oracles/oracle_abc.py +9 -9
- classiq/interface/generator/partitioned_register.py +7 -7
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +47 -34
- classiq/interface/generator/qsvm.py +13 -17
- classiq/interface/generator/quantum_function_call.py +107 -87
- classiq/interface/generator/{generated_circuit.py → quantum_program.py} +50 -37
- classiq/interface/generator/range_types.py +13 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +11 -6
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +32 -39
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +16 -15
- classiq/interface/generator/state_preparation/metrics.py +5 -7
- classiq/interface/generator/state_preparation/state_preparation.py +30 -23
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
- classiq/interface/generator/transpiler_basis_gates.py +7 -3
- classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
- classiq/interface/generator/types/compilation_metadata.py +6 -0
- classiq/interface/generator/types/enum_declaration.py +54 -0
- classiq/interface/generator/types/qstruct_declaration.py +18 -0
- classiq/interface/generator/types/struct_declaration.py +15 -14
- classiq/interface/generator/ucc.py +9 -6
- classiq/interface/generator/unitary_gate.py +10 -6
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +11 -9
- classiq/interface/generator/validations/validator_functions.py +8 -6
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +31 -10
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +3 -0
- classiq/interface/helpers/custom_pydantic_types.py +40 -50
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +7 -11
- classiq/interface/helpers/validation_helpers.py +4 -21
- classiq/interface/helpers/versioned_model.py +1 -1
- classiq/interface/ide/ide_data.py +16 -20
- classiq/interface/ide/visual_model.py +130 -0
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +35 -6
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +44 -14
- classiq/interface/model/classical_if.py +15 -0
- classiq/interface/model/classical_parameter_declaration.py +33 -3
- classiq/interface/model/control.py +45 -0
- classiq/interface/model/handle_binding.py +298 -20
- classiq/interface/model/inplace_binary_operation.py +31 -26
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +87 -73
- classiq/interface/model/native_function_definition.py +16 -21
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/phase_operation.py +11 -0
- classiq/interface/model/port_declaration.py +27 -9
- classiq/interface/model/power.py +14 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +38 -21
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
- classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
- classiq/interface/model/quantum_function_call.py +146 -462
- classiq/interface/model/quantum_function_declaration.py +193 -152
- classiq/interface/model/quantum_lambda_function.py +65 -0
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +205 -67
- classiq/interface/model/quantum_variable_declaration.py +4 -26
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +58 -0
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +13 -0
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +22 -21
- classiq/interface/source_reference.py +59 -0
- classiq/model_expansions/__init__.py +0 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
- classiq/model_expansions/capturing/__init__.py +0 -0
- classiq/model_expansions/capturing/captured_vars.py +435 -0
- classiq/model_expansions/capturing/mangling_utils.py +56 -0
- classiq/model_expansions/closure.py +171 -0
- classiq/model_expansions/debug_flag.py +3 -0
- classiq/model_expansions/evaluators/__init__.py +0 -0
- classiq/model_expansions/evaluators/arg_type_match.py +158 -0
- classiq/model_expansions/evaluators/argument_types.py +42 -0
- classiq/model_expansions/evaluators/classical_expression.py +36 -0
- classiq/model_expansions/evaluators/control.py +144 -0
- classiq/model_expansions/evaluators/parameter_types.py +226 -0
- classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
- classiq/model_expansions/evaluators/type_type_match.py +90 -0
- classiq/model_expansions/expression_evaluator.py +135 -0
- classiq/model_expansions/expression_renamer.py +76 -0
- classiq/model_expansions/function_builder.py +247 -0
- classiq/model_expansions/generative_functions.py +158 -0
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/interpreters/base_interpreter.py +263 -0
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
- classiq/model_expansions/model_tables.py +18 -0
- classiq/model_expansions/quantum_operations/__init__.py +9 -0
- classiq/model_expansions/quantum_operations/bind.py +60 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
- classiq/model_expansions/quantum_operations/classicalif.py +53 -0
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +181 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
- classiq/model_expansions/quantum_operations/repeat.py +56 -0
- classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
- classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
- classiq/model_expansions/scope.py +240 -0
- classiq/model_expansions/scope_initialization.py +150 -0
- classiq/model_expansions/sympy_conversion/__init__.py +0 -0
- classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
- classiq/model_expansions/transformers/__init__.py +0 -0
- classiq/model_expansions/transformers/ast_renamer.py +26 -0
- classiq/model_expansions/transformers/var_splitter.py +299 -0
- classiq/model_expansions/utils/__init__.py +0 -0
- classiq/model_expansions/utils/counted_name_allocator.py +11 -0
- classiq/model_expansions/utils/handles_collector.py +33 -0
- classiq/model_expansions/visitors/__init__.py +0 -0
- classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
- classiq/model_expansions/visitors/variable_references.py +144 -0
- classiq/open_library/__init__.py +4 -0
- classiq/open_library/functions/__init__.py +130 -0
- classiq/open_library/functions/amplitude_estimation.py +30 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
- classiq/open_library/functions/grover.py +157 -0
- classiq/open_library/functions/hea.py +115 -0
- classiq/open_library/functions/linear_pauli_rotation.py +82 -0
- classiq/open_library/functions/modular_exponentiation.py +201 -0
- classiq/open_library/functions/qaoa_penalty.py +117 -0
- classiq/open_library/functions/qft_functions.py +54 -0
- classiq/open_library/functions/qpe.py +46 -0
- classiq/open_library/functions/qsvt.py +331 -0
- classiq/open_library/functions/state_preparation.py +301 -0
- classiq/open_library/functions/swap_test.py +27 -0
- classiq/open_library/functions/utility_functions.py +81 -0
- classiq/open_library/functions/variational.py +52 -0
- classiq/qmod/__init__.py +17 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +60 -47
- classiq/qmod/builtins/classical_functions.py +44 -38
- classiq/qmod/builtins/constants.py +10 -0
- classiq/qmod/builtins/enums.py +208 -0
- classiq/qmod/builtins/functions/__init__.py +137 -0
- classiq/qmod/builtins/functions/allocation.py +150 -0
- classiq/qmod/builtins/functions/arithmetic.py +55 -0
- classiq/qmod/builtins/functions/benchmarking.py +8 -0
- classiq/qmod/builtins/functions/chemistry.py +91 -0
- classiq/qmod/builtins/functions/exponentiation.py +105 -0
- classiq/qmod/builtins/functions/finance.py +34 -0
- classiq/qmod/builtins/functions/operators.py +16 -0
- classiq/qmod/builtins/functions/qsvm.py +24 -0
- classiq/qmod/builtins/functions/standard_gates.py +651 -0
- classiq/qmod/builtins/operations.py +379 -57
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +42 -0
- classiq/qmod/classical_function.py +8 -20
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +145 -112
- classiq/qmod/expression_query.py +39 -0
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +19 -5
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +194 -0
- classiq/qmod/native/pretty_printer.py +401 -0
- classiq/qmod/pretty_print/__init__.py +7 -0
- classiq/qmod/pretty_print/expression_to_python.py +222 -0
- classiq/qmod/pretty_print/pretty_printer.py +572 -0
- classiq/qmod/python_classical_type.py +67 -0
- classiq/qmod/qfunc.py +79 -0
- classiq/qmod/qmod_constant.py +143 -0
- classiq/qmod/qmod_parameter.py +84 -53
- classiq/qmod/qmod_variable.py +497 -100
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +278 -105
- classiq/qmod/quantum_function.py +232 -48
- classiq/qmod/semantics/__init__.py +0 -0
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
- classiq/qmod/semantics/error_manager.py +88 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +384 -0
- classiq/qmod/semantics/validation/__init__.py +0 -0
- classiq/qmod/semantics/validation/constants_validation.py +16 -0
- classiq/qmod/semantics/validation/func_call_validation.py +99 -0
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +128 -0
- classiq/qmod/symbolic.py +178 -111
- classiq/qmod/symbolic_expr.py +36 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +108 -1
- classiq/qmod/write_qmod.py +53 -0
- classiq/synthesis.py +210 -22
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -8
- classiq-0.65.3.dist-info/RECORD +521 -0
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/WHEEL +1 -1
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -17
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
- classiq/applications_model_constructors/grover_model_constructor.py +0 -227
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/exceptions.py +0 -131
- classiq/interface/executor/aws_execution_cost.py +0 -72
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -115
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -59
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -862
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
- classiq/interface/generator/functions/foreign_function_definition.py +0 -106
- classiq/interface/generator/functions/function_implementation.py +0 -103
- classiq/interface/generator/functions/native_function_definition.py +0 -153
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -42
- classiq/interface/generator/functions/register_mapping_data.py +0 -102
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -63
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -2
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
- classiq/interface/generator/types/combinatorial_problem.py +0 -26
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/numeric_reinterpretation.py +0 -25
- classiq/interface/model/operator_synthesis_data.py +0 -48
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -95
- classiq/interface/model/resolvers/function_call_resolver.py +0 -43
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -154
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -466
- classiq/model/function_handler.pyi +0 -152
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -246
- classiq/qmod/builtins/functions.py +0 -896
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -207
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- classiq-0.37.1.dist-info/RECORD +0 -418
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/pauli_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/py.typed} +0 -0
- /classiq/{interface/model/resolvers → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{interface/model/validations → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
classiq/qmod/qmod_variable.py
CHANGED
@@ -1,34 +1,49 @@
|
|
1
1
|
import abc
|
2
|
+
import sys
|
3
|
+
from collections.abc import Iterator, Mapping
|
2
4
|
from contextlib import contextmanager
|
3
|
-
from typing import (
|
5
|
+
from typing import ( # type: ignore[attr-defined]
|
4
6
|
TYPE_CHECKING,
|
7
|
+
Annotated,
|
5
8
|
Any,
|
6
9
|
ForwardRef,
|
7
10
|
Generic,
|
8
|
-
Iterator,
|
9
11
|
Literal,
|
10
12
|
Optional,
|
11
|
-
Tuple,
|
12
|
-
Type,
|
13
13
|
TypeVar,
|
14
14
|
Union,
|
15
|
+
_GenericAlias,
|
16
|
+
cast,
|
15
17
|
get_args,
|
16
18
|
get_origin,
|
17
19
|
)
|
18
20
|
|
19
|
-
from typing_extensions import
|
21
|
+
from typing_extensions import ParamSpec, Self, _AnnotatedAlias
|
20
22
|
|
23
|
+
from classiq.interface.exceptions import ClassiqValueError
|
21
24
|
from classiq.interface.generator.expressions.expression import Expression
|
25
|
+
from classiq.interface.generator.expressions.qmod_qarray_proxy import (
|
26
|
+
ILLEGAL_SLICE_MSG,
|
27
|
+
ILLEGAL_SLICING_STEP_MSG,
|
28
|
+
)
|
22
29
|
from classiq.interface.generator.functions.port_declaration import (
|
23
30
|
PortDeclarationDirection,
|
24
31
|
)
|
25
|
-
from classiq.interface.
|
26
|
-
from classiq.interface.
|
32
|
+
from classiq.interface.generator.functions.type_name import TypeName
|
33
|
+
from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
|
34
|
+
from classiq.interface.model.handle_binding import (
|
35
|
+
FieldHandleBinding,
|
36
|
+
HandleBinding,
|
37
|
+
SlicedHandleBinding,
|
38
|
+
SubscriptHandleBinding,
|
39
|
+
)
|
40
|
+
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
27
41
|
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
28
42
|
AmplitudeLoadingOperation,
|
29
43
|
)
|
30
44
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
31
45
|
ArithmeticOperation,
|
46
|
+
ArithmeticOperationKind,
|
32
47
|
)
|
33
48
|
from classiq.interface.model.quantum_type import (
|
34
49
|
QuantumBit,
|
@@ -36,15 +51,24 @@ from classiq.interface.model.quantum_type import (
|
|
36
51
|
QuantumNumeric,
|
37
52
|
QuantumType,
|
38
53
|
)
|
54
|
+
from classiq.interface.source_reference import SourceReference
|
39
55
|
|
40
|
-
from classiq.
|
41
|
-
from classiq.qmod.
|
56
|
+
from classiq.qmod.cparam import ArrayBase, CInt, CParamScalar
|
57
|
+
from classiq.qmod.generative import (
|
58
|
+
generative_mode_context,
|
59
|
+
interpret_expression,
|
60
|
+
is_generative_mode,
|
61
|
+
)
|
62
|
+
from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
42
63
|
from classiq.qmod.quantum_callable import QCallable
|
43
|
-
from classiq.qmod.symbolic_expr import SymbolicExpr
|
64
|
+
from classiq.qmod.symbolic_expr import Symbolic, SymbolicExpr
|
44
65
|
from classiq.qmod.symbolic_type import SymbolicTypes
|
45
|
-
|
46
|
-
|
47
|
-
|
66
|
+
from classiq.qmod.utilities import (
|
67
|
+
get_source_ref,
|
68
|
+
unwrap_forward_ref,
|
69
|
+
varname,
|
70
|
+
version_portable_get_args,
|
71
|
+
)
|
48
72
|
|
49
73
|
|
50
74
|
def _is_input_output_typehint(type_hint: Any) -> bool:
|
@@ -72,28 +96,59 @@ def _no_current_expandable() -> Iterator[None]:
|
|
72
96
|
QCallable.CURRENT_EXPANDABLE = current_expandable
|
73
97
|
|
74
98
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
99
|
+
def _infer_variable_name(name: Any, depth: int) -> Any:
|
100
|
+
if name is not None:
|
101
|
+
return name
|
102
|
+
name = varname(depth + 1)
|
103
|
+
if name is None:
|
104
|
+
raise ClassiqValueError(
|
105
|
+
"Could not infer variable name. Please specify the variable name explicitly"
|
106
|
+
)
|
107
|
+
return name
|
108
|
+
|
109
|
+
|
110
|
+
class QVar(Symbolic):
|
111
|
+
CONSTRUCTOR_DEPTH: int = 1
|
112
|
+
|
113
|
+
def __init__(
|
114
|
+
self,
|
115
|
+
origin: Union[None, str, HandleBinding] = None,
|
116
|
+
*,
|
117
|
+
expr_str: Optional[str] = None,
|
118
|
+
depth: int = 2,
|
119
|
+
) -> None:
|
120
|
+
name = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
121
|
+
super().__init__(str(name), True)
|
122
|
+
source_ref = (
|
123
|
+
get_source_ref(sys._getframe(depth))
|
124
|
+
if isinstance(name, str)
|
125
|
+
else name.source_ref
|
126
|
+
)
|
127
|
+
self._base_handle: HandleBinding = (
|
128
|
+
HandleBinding(name=name) if isinstance(name, str) else name
|
129
|
+
)
|
130
|
+
if isinstance(name, str) and QCallable.CURRENT_EXPANDABLE is not None:
|
79
131
|
QCallable.CURRENT_EXPANDABLE.add_local_handle(
|
80
|
-
|
132
|
+
name, self.get_qmod_type(), source_ref
|
81
133
|
)
|
134
|
+
self._expr_str = expr_str if expr_str is not None else str(name)
|
82
135
|
|
83
|
-
@abc.abstractmethod
|
84
136
|
def get_handle_binding(self) -> HandleBinding:
|
85
|
-
|
137
|
+
return self._base_handle
|
86
138
|
|
87
139
|
@abc.abstractmethod
|
88
140
|
def get_qmod_type(self) -> QuantumType:
|
89
141
|
raise NotImplementedError()
|
90
142
|
|
91
143
|
@staticmethod
|
92
|
-
def from_type_hint(type_hint: Any) -> Optional[
|
144
|
+
def from_type_hint(type_hint: Any) -> Optional[type["QVar"]]:
|
93
145
|
if _is_input_output_typehint(type_hint):
|
94
146
|
return QVar.from_type_hint(type_hint.__args__[0])
|
95
147
|
type_ = get_origin(type_hint) or type_hint
|
96
148
|
if issubclass(type_, QVar):
|
149
|
+
if issubclass(type_, QStruct):
|
150
|
+
with _no_current_expandable():
|
151
|
+
type_("DUMMY")._add_qmod_qstruct(qmodule=QMODULE)
|
97
152
|
return type_
|
98
153
|
return None
|
99
154
|
|
@@ -102,6 +157,16 @@ class QVar:
|
|
102
157
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
103
158
|
raise NotImplementedError()
|
104
159
|
|
160
|
+
@classmethod
|
161
|
+
@abc.abstractmethod
|
162
|
+
def to_qvar(
|
163
|
+
cls,
|
164
|
+
origin: Union[str, HandleBinding],
|
165
|
+
type_hint: Any,
|
166
|
+
expr_str: Optional[str],
|
167
|
+
) -> Self:
|
168
|
+
raise NotImplementedError()
|
169
|
+
|
105
170
|
@classmethod
|
106
171
|
def port_direction(cls, type_hint: Any) -> PortDeclarationDirection:
|
107
172
|
if _is_input_output_typehint(type_hint):
|
@@ -110,6 +175,16 @@ class QVar:
|
|
110
175
|
assert type_hint == cls or get_origin(type_hint) == cls
|
111
176
|
return PortDeclarationDirection.Inout
|
112
177
|
|
178
|
+
def __str__(self) -> str:
|
179
|
+
return self._expr_str
|
180
|
+
|
181
|
+
@property
|
182
|
+
def size(self) -> Union[CParamScalar, int]:
|
183
|
+
if is_generative_mode():
|
184
|
+
with generative_mode_context(False):
|
185
|
+
return interpret_expression(str(self.size))
|
186
|
+
return CParamScalar(f"get_field({self}, 'size')")
|
187
|
+
|
113
188
|
|
114
189
|
_Q = TypeVar("_Q", bound=QVar)
|
115
190
|
Output = Annotated[_Q, PortDeclarationDirection.Output]
|
@@ -117,11 +192,25 @@ Input = Annotated[_Q, PortDeclarationDirection.Input]
|
|
117
192
|
|
118
193
|
|
119
194
|
class QScalar(QVar, SymbolicExpr):
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
195
|
+
CONSTRUCTOR_DEPTH: int = 2
|
196
|
+
|
197
|
+
def __init__(
|
198
|
+
self,
|
199
|
+
origin: Union[None, str, HandleBinding] = None,
|
200
|
+
*,
|
201
|
+
_expr_str: Optional[str] = None,
|
202
|
+
depth: int = 2,
|
203
|
+
) -> None:
|
204
|
+
origin = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
205
|
+
QVar.__init__(self, origin, expr_str=_expr_str, depth=depth)
|
206
|
+
SymbolicExpr.__init__(self, str(origin), True)
|
207
|
+
|
208
|
+
def _insert_arith_operation(
|
209
|
+
self,
|
210
|
+
expr: SymbolicTypes,
|
211
|
+
kind: ArithmeticOperationKind,
|
212
|
+
source_ref: SourceReference,
|
213
|
+
) -> None:
|
125
214
|
# Fixme: Arithmetic operations are not yet supported on slices (see CAD-12670)
|
126
215
|
if TYPE_CHECKING:
|
127
216
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
@@ -129,30 +218,33 @@ class QScalar(QVar, SymbolicExpr):
|
|
129
218
|
ArithmeticOperation(
|
130
219
|
expression=Expression(expr=str(expr)),
|
131
220
|
result_var=self.get_handle_binding(),
|
132
|
-
|
221
|
+
operation_kind=kind,
|
222
|
+
source_ref=source_ref,
|
133
223
|
)
|
134
224
|
)
|
135
225
|
|
136
|
-
def _insert_amplitude_loading(
|
226
|
+
def _insert_amplitude_loading(
|
227
|
+
self, expr: SymbolicTypes, source_ref: SourceReference
|
228
|
+
) -> None:
|
137
229
|
if TYPE_CHECKING:
|
138
230
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
139
231
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
140
232
|
AmplitudeLoadingOperation(
|
141
233
|
expression=Expression(expr=str(expr)),
|
142
234
|
result_var=self.get_handle_binding(),
|
235
|
+
source_ref=source_ref,
|
143
236
|
)
|
144
237
|
)
|
145
238
|
|
146
|
-
def get_handle_binding(self) -> HandleBinding:
|
147
|
-
return HandleBinding(name=self._name)
|
148
|
-
|
149
239
|
def __ior__(self, other: Any) -> Self:
|
150
240
|
if not isinstance(other, get_args(SymbolicTypes)):
|
151
241
|
raise TypeError(
|
152
242
|
f"Invalid argument {other!r} for out-of-place arithmetic operation"
|
153
243
|
)
|
154
244
|
|
155
|
-
self._insert_arith_operation(
|
245
|
+
self._insert_arith_operation(
|
246
|
+
other, ArithmeticOperationKind.Assignment, get_source_ref(sys._getframe(1))
|
247
|
+
)
|
156
248
|
return self
|
157
249
|
|
158
250
|
def __ixor__(self, other: Any) -> Self:
|
@@ -161,7 +253,20 @@ class QScalar(QVar, SymbolicExpr):
|
|
161
253
|
f"Invalid argument {other!r} for in-place arithmetic operation"
|
162
254
|
)
|
163
255
|
|
164
|
-
self._insert_arith_operation(
|
256
|
+
self._insert_arith_operation(
|
257
|
+
other, ArithmeticOperationKind.InplaceXor, get_source_ref(sys._getframe(1))
|
258
|
+
)
|
259
|
+
return self
|
260
|
+
|
261
|
+
def __iadd__(self, other: Any) -> Self:
|
262
|
+
if not isinstance(other, get_args(SymbolicTypes)):
|
263
|
+
raise TypeError(
|
264
|
+
f"Invalid argument {other!r} for in-place arithmetic operation"
|
265
|
+
)
|
266
|
+
|
267
|
+
self._insert_arith_operation(
|
268
|
+
other, ArithmeticOperationKind.InplaceAdd, get_source_ref(sys._getframe(1))
|
269
|
+
)
|
165
270
|
return self
|
166
271
|
|
167
272
|
def __imul__(self, other: Any) -> Self:
|
@@ -170,7 +275,7 @@ class QScalar(QVar, SymbolicExpr):
|
|
170
275
|
f"Invalid argument {other!r} for out of ampltiude encoding operation"
|
171
276
|
)
|
172
277
|
|
173
|
-
self._insert_amplitude_loading(other)
|
278
|
+
self._insert_amplitude_loading(other, get_source_ref(sys._getframe(1)))
|
174
279
|
return self
|
175
280
|
|
176
281
|
|
@@ -179,113 +284,405 @@ class QBit(QScalar):
|
|
179
284
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
180
285
|
return QuantumBit()
|
181
286
|
|
287
|
+
@classmethod
|
288
|
+
def to_qvar(
|
289
|
+
cls,
|
290
|
+
origin: Union[str, HandleBinding],
|
291
|
+
type_hint: Any,
|
292
|
+
expr_str: Optional[str],
|
293
|
+
) -> "QBit":
|
294
|
+
return QBit(origin, _expr_str=expr_str)
|
295
|
+
|
182
296
|
def get_qmod_type(self) -> QuantumType:
|
183
297
|
return QuantumBit()
|
184
298
|
|
185
299
|
|
186
|
-
|
300
|
+
_P = ParamSpec("_P")
|
301
|
+
|
187
302
|
|
303
|
+
class QNum(Generic[_P], QScalar):
|
304
|
+
CONSTRUCTOR_DEPTH: int = 3
|
305
|
+
|
306
|
+
def __init__(
|
307
|
+
self,
|
308
|
+
name: Union[None, str, HandleBinding] = None,
|
309
|
+
size: Union[int, CInt, Expression, SymbolicExpr, None] = None,
|
310
|
+
is_signed: Union[bool, Expression, SymbolicExpr, None] = None,
|
311
|
+
fraction_digits: Union[int, CInt, Expression, None] = None,
|
312
|
+
_expr_str: Optional[str] = None,
|
313
|
+
):
|
314
|
+
if size is None and (is_signed is not None or fraction_digits is not None):
|
315
|
+
raise ClassiqValueError(
|
316
|
+
"Cannot assign 'is_signed' and 'fraction_digits' without 'size'"
|
317
|
+
)
|
318
|
+
if is_signed is not None and fraction_digits is None:
|
319
|
+
raise ClassiqValueError(
|
320
|
+
"Cannot assign 'is_signed' without 'fraction_digits'"
|
321
|
+
)
|
322
|
+
if is_signed is None and fraction_digits is not None:
|
323
|
+
raise ClassiqValueError(
|
324
|
+
"Cannot assign 'fraction_digits' without 'is_signed'"
|
325
|
+
)
|
326
|
+
self._size = (
|
327
|
+
size
|
328
|
+
if size is None or isinstance(size, Expression)
|
329
|
+
else Expression(expr=str(size))
|
330
|
+
)
|
331
|
+
self._is_signed = (
|
332
|
+
is_signed
|
333
|
+
if is_signed is None or isinstance(is_signed, Expression)
|
334
|
+
else Expression(expr=str(is_signed))
|
335
|
+
)
|
336
|
+
self._fraction_digits = (
|
337
|
+
fraction_digits
|
338
|
+
if fraction_digits is None or isinstance(fraction_digits, Expression)
|
339
|
+
else Expression(expr=str(fraction_digits))
|
340
|
+
)
|
341
|
+
super().__init__(name, _expr_str=_expr_str, depth=3)
|
188
342
|
|
189
|
-
|
190
|
-
|
343
|
+
@classmethod
|
344
|
+
def _get_attributes(cls, type_hint: Any) -> tuple[Any, Any, Any]:
|
345
|
+
type_args = version_portable_get_args(type_hint)
|
346
|
+
if len(type_args) == 0:
|
347
|
+
return None, None, None
|
348
|
+
if len(type_args) not in (1, 3):
|
349
|
+
raise ClassiqValueError(
|
350
|
+
"QNum receives three type arguments: QNum[size: int | CInt, "
|
351
|
+
"is_signed: bool | CBool, fraction_digits: int | CInt]"
|
352
|
+
)
|
353
|
+
if len(type_args) == 1:
|
354
|
+
return unwrap_forward_ref(type_args[0]), None, None
|
355
|
+
return (
|
356
|
+
unwrap_forward_ref(type_args[0]),
|
357
|
+
unwrap_forward_ref(type_args[1]),
|
358
|
+
unwrap_forward_ref(type_args[2]),
|
359
|
+
)
|
191
360
|
|
192
361
|
@classmethod
|
193
362
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
194
|
-
|
195
|
-
|
196
|
-
|
363
|
+
size, is_signed, fraction_digits = cls._get_attributes(type_hint)
|
364
|
+
return QuantumNumeric(
|
365
|
+
size=(
|
366
|
+
Expression(expr=get_type_hint_expr(size)) if size is not None else None
|
367
|
+
),
|
368
|
+
is_signed=(
|
369
|
+
Expression(expr=get_type_hint_expr(is_signed))
|
370
|
+
if is_signed is not None
|
371
|
+
else None
|
372
|
+
),
|
373
|
+
fraction_digits=(
|
374
|
+
Expression(expr=get_type_hint_expr(fraction_digits))
|
375
|
+
if fraction_digits is not None
|
376
|
+
else None
|
377
|
+
),
|
378
|
+
)
|
197
379
|
|
198
|
-
|
380
|
+
@classmethod
|
381
|
+
def to_qvar(
|
382
|
+
cls,
|
383
|
+
origin: Union[str, HandleBinding],
|
384
|
+
type_hint: Any,
|
385
|
+
expr_str: Optional[str],
|
386
|
+
) -> "QNum":
|
387
|
+
return QNum(origin, *cls._get_attributes(type_hint), _expr_str=expr_str)
|
199
388
|
|
200
389
|
def get_qmod_type(self) -> QuantumType:
|
201
|
-
return
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
390
|
+
return QuantumNumeric(
|
391
|
+
size=self._size,
|
392
|
+
is_signed=self._is_signed,
|
393
|
+
fraction_digits=self._fraction_digits,
|
394
|
+
)
|
206
395
|
|
207
396
|
@property
|
208
|
-
def fraction_digits(self) ->
|
209
|
-
|
397
|
+
def fraction_digits(self) -> Union[CParamScalar, int]:
|
398
|
+
if is_generative_mode():
|
399
|
+
with generative_mode_context(False):
|
400
|
+
return interpret_expression(str(self.fraction_digits))
|
401
|
+
return CParamScalar(f"get_field({self}, 'fraction_digits')")
|
210
402
|
|
211
403
|
@property
|
212
|
-
def is_signed(self) ->
|
213
|
-
|
404
|
+
def is_signed(self) -> Union[CParamScalar, bool]:
|
405
|
+
if is_generative_mode():
|
406
|
+
with generative_mode_context(False):
|
407
|
+
return interpret_expression(str(self.is_signed))
|
408
|
+
return CParamScalar(f"get_field({self}, 'is_signed')")
|
214
409
|
|
410
|
+
# Support comma-separated generic args in older Python versions
|
411
|
+
if sys.version_info[0:2] < (3, 10):
|
215
412
|
|
216
|
-
|
413
|
+
def __class_getitem__(cls, args) -> _GenericAlias:
|
414
|
+
return _GenericAlias(cls, args)
|
217
415
|
|
218
416
|
|
219
417
|
class QArray(ArrayBase[_P], QVar):
|
220
|
-
|
221
|
-
|
222
|
-
|
418
|
+
CONSTRUCTOR_DEPTH: int = 3
|
419
|
+
|
420
|
+
# TODO [CAD-18620]: improve type hints
|
421
|
+
def __init__(
|
422
|
+
self,
|
423
|
+
name: Union[None, str, HandleBinding] = None,
|
424
|
+
element_type: Union[_GenericAlias, QuantumType] = QBit,
|
425
|
+
length: Optional[Union[int, SymbolicExpr, Expression]] = None,
|
426
|
+
_expr_str: Optional[str] = None,
|
427
|
+
) -> None:
|
428
|
+
self._element_type = element_type
|
429
|
+
self._length = (
|
430
|
+
length
|
431
|
+
if length is None or isinstance(length, Expression)
|
432
|
+
else Expression(expr=str(length))
|
433
|
+
)
|
434
|
+
super().__init__(name, expr_str=_expr_str)
|
223
435
|
|
224
|
-
def
|
225
|
-
|
226
|
-
|
227
|
-
return SlicedHandleBinding(
|
228
|
-
name=self._name,
|
229
|
-
start=Expression(expr=str(self._slice[0])),
|
230
|
-
end=Expression(expr=str(self._slice[1])),
|
436
|
+
def __getitem__(self, key: Union[slice, int, SymbolicExpr]) -> Any:
|
437
|
+
return (
|
438
|
+
self._get_slice(key) if isinstance(key, slice) else self._get_subscript(key)
|
231
439
|
)
|
232
440
|
|
233
|
-
def
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
441
|
+
def __setitem__(self, *args: Any) -> None:
|
442
|
+
pass
|
443
|
+
|
444
|
+
def _get_subscript(self, index: Union[slice, int, SymbolicExpr]) -> Any:
|
445
|
+
if isinstance(index, SymbolicExpr) and index.is_quantum:
|
446
|
+
raise ClassiqValueError("Non-classical parameter for slicing")
|
447
|
+
|
448
|
+
return _create_qvar_for_qtype(
|
449
|
+
self.get_qmod_type().element_type,
|
450
|
+
SubscriptHandleBinding(
|
451
|
+
base_handle=self._base_handle,
|
452
|
+
index=Expression(expr=str(index)),
|
453
|
+
),
|
454
|
+
expr_str=f"{self}[{index}]",
|
455
|
+
)
|
456
|
+
|
457
|
+
def _get_slice(self, slice_: slice) -> Any:
|
458
|
+
if slice_.step is not None:
|
459
|
+
raise ClassiqValueError(ILLEGAL_SLICING_STEP_MSG)
|
460
|
+
if not isinstance(slice_.start, (int, SymbolicExpr)) or not isinstance(
|
461
|
+
slice_.stop, (int, SymbolicExpr)
|
462
|
+
):
|
463
|
+
raise ClassiqValueError(ILLEGAL_SLICE_MSG)
|
464
|
+
|
465
|
+
return QArray(
|
466
|
+
name=SlicedHandleBinding(
|
467
|
+
base_handle=self._base_handle,
|
468
|
+
start=Expression(expr=str(slice_.start)),
|
469
|
+
end=Expression(expr=str(slice_.stop)),
|
470
|
+
),
|
471
|
+
element_type=self._element_type,
|
472
|
+
length=slice_.stop - slice_.start,
|
473
|
+
_expr_str=f"{self}[{slice_.start}:{slice_.stop}]",
|
474
|
+
)
|
248
475
|
|
249
476
|
def __len__(self) -> int:
|
250
|
-
raise
|
251
|
-
"len(<var>) is not supported for quantum variables - use <var>.len
|
477
|
+
raise ClassiqValueError(
|
478
|
+
"len(<var>) is not supported for quantum variables - use <var>.len instead"
|
252
479
|
)
|
253
480
|
|
254
481
|
if TYPE_CHECKING:
|
255
482
|
|
483
|
+
@property
|
256
484
|
def len(self) -> int: ...
|
257
485
|
|
258
486
|
else:
|
259
487
|
|
260
|
-
|
261
|
-
|
488
|
+
@property
|
489
|
+
def len(self) -> Union[CParamScalar, int]:
|
490
|
+
if is_generative_mode():
|
491
|
+
with generative_mode_context(False):
|
492
|
+
return interpret_expression(str(self.len))
|
493
|
+
return CParamScalar(f"get_field({self}, 'len')")
|
494
|
+
|
495
|
+
@classmethod
|
496
|
+
def _get_attributes(cls, type_hint: Any) -> tuple[type[QVar], Any]:
|
497
|
+
type_args = version_portable_get_args(type_hint)
|
498
|
+
if len(type_args) == 0:
|
499
|
+
return QBit, None
|
500
|
+
first_arg = unwrap_forward_ref(type_args[0])
|
501
|
+
if len(type_args) == 1:
|
502
|
+
if isinstance(first_arg, (str, int)):
|
503
|
+
return QBit, first_arg
|
504
|
+
return first_arg, None
|
505
|
+
if len(type_args) != 2:
|
506
|
+
raise ClassiqValueError(
|
507
|
+
"QArray receives two type arguments: QArray[element_type: QVar, "
|
508
|
+
"length: int | CInt]"
|
509
|
+
)
|
510
|
+
second_arg = unwrap_forward_ref(type_args[1])
|
511
|
+
return cast(tuple[type[QVar], Any], (first_arg, second_arg))
|
262
512
|
|
263
513
|
@classmethod
|
264
514
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
515
|
+
api_element_type, length = cls._get_attributes(type_hint)
|
516
|
+
api_element_class = get_origin(api_element_type) or api_element_type
|
517
|
+
element_type = api_element_class.to_qmod_quantum_type(api_element_type)
|
518
|
+
|
265
519
|
length_expr: Optional[Expression] = None
|
266
|
-
if
|
267
|
-
length_expr = Expression(expr=get_type_hint_expr(
|
268
|
-
|
520
|
+
if length is not None:
|
521
|
+
length_expr = Expression(expr=get_type_hint_expr(length))
|
522
|
+
|
523
|
+
return QuantumBitvector(element_type=element_type, length=length_expr)
|
524
|
+
|
525
|
+
@classmethod
|
526
|
+
def to_qvar(
|
527
|
+
cls,
|
528
|
+
origin: Union[str, HandleBinding],
|
529
|
+
type_hint: Any,
|
530
|
+
expr_str: Optional[str],
|
531
|
+
) -> "QArray":
|
532
|
+
return QArray(origin, *cls._get_attributes(type_hint), _expr_str=expr_str)
|
533
|
+
|
534
|
+
def get_qmod_type(self) -> QuantumBitvector:
|
535
|
+
if isinstance(self._element_type, QuantumType):
|
536
|
+
element_type = self._element_type
|
537
|
+
else:
|
538
|
+
element_class = get_origin(self._element_type) or self._element_type
|
539
|
+
element_type = element_class.to_qmod_quantum_type(self._element_type)
|
540
|
+
return QuantumBitvector(
|
541
|
+
element_type=element_type,
|
542
|
+
length=self._length,
|
543
|
+
)
|
544
|
+
|
545
|
+
|
546
|
+
class QStruct(QVar):
|
547
|
+
CONSTRUCTOR_DEPTH: int = 2
|
548
|
+
|
549
|
+
_struct_name: str
|
550
|
+
_fields: Mapping[str, QVar]
|
551
|
+
|
552
|
+
def __init__(
|
553
|
+
self,
|
554
|
+
origin: Union[None, str, HandleBinding] = None,
|
555
|
+
_struct_name: Optional[str] = None,
|
556
|
+
_fields: Optional[Mapping[str, QVar]] = None,
|
557
|
+
_expr_str: Optional[str] = None,
|
558
|
+
) -> None:
|
559
|
+
name = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
560
|
+
if _struct_name is None or _fields is None:
|
561
|
+
with _no_current_expandable():
|
562
|
+
temp_var = QStruct.to_qvar(name, type(self), _expr_str)
|
563
|
+
_struct_name = temp_var._struct_name
|
564
|
+
_fields = temp_var._fields
|
565
|
+
self._struct_name = _struct_name
|
566
|
+
self._fields = _fields
|
567
|
+
for field_name, var in _fields.items():
|
568
|
+
setattr(self, field_name, var)
|
569
|
+
super().__init__(name, expr_str=_expr_str)
|
570
|
+
self._add_qmod_qstruct(qmodule=QMODULE)
|
269
571
|
|
270
572
|
def get_qmod_type(self) -> QuantumType:
|
271
|
-
return
|
573
|
+
return TypeName(name=self._struct_name)
|
574
|
+
|
575
|
+
@classmethod
|
576
|
+
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
577
|
+
with _no_current_expandable():
|
578
|
+
type_hint("DUMMY")
|
579
|
+
return TypeName(name=type_hint.__name__)
|
580
|
+
|
581
|
+
@classmethod
|
582
|
+
def to_qvar(
|
583
|
+
cls,
|
584
|
+
origin: Union[str, HandleBinding],
|
585
|
+
type_hint: Any,
|
586
|
+
expr_str: Optional[str],
|
587
|
+
) -> "QStruct":
|
588
|
+
field_types = {
|
589
|
+
field_name: (QVar.from_type_hint(field_type), field_type)
|
590
|
+
for field_name, field_type in type_hint.__annotations__.items()
|
591
|
+
}
|
592
|
+
illegal_fields = [
|
593
|
+
(field_name, field_type)
|
594
|
+
for field_name, (field_class, field_type) in field_types.items()
|
595
|
+
if field_class is None
|
596
|
+
]
|
597
|
+
if len(illegal_fields) > 0:
|
598
|
+
raise ClassiqValueError(
|
599
|
+
f"Field {illegal_fields[0][0]!r} of quantum struct "
|
600
|
+
f"{type_hint.__name__} has a non-quantum type "
|
601
|
+
f"{illegal_fields[0][1].__name__}."
|
602
|
+
)
|
603
|
+
base_handle = HandleBinding(name=origin) if isinstance(origin, str) else origin
|
604
|
+
with _no_current_expandable():
|
605
|
+
field_vars = {
|
606
|
+
field_name: cast(type[QVar], field_class).to_qvar(
|
607
|
+
FieldHandleBinding(base_handle=base_handle, field=field_name),
|
608
|
+
field_type,
|
609
|
+
f"get_field({expr_str if expr_str is not None else str(origin)}, '{field_name}')",
|
610
|
+
)
|
611
|
+
for field_name, (field_class, field_type) in field_types.items()
|
612
|
+
}
|
613
|
+
return QStruct(
|
614
|
+
origin,
|
615
|
+
_struct_name=type_hint.__name__,
|
616
|
+
_fields=field_vars,
|
617
|
+
_expr_str=expr_str,
|
618
|
+
)
|
619
|
+
|
620
|
+
def _add_qmod_qstruct(self, *, qmodule: ModelStateContainer) -> None:
|
621
|
+
if self._struct_name in qmodule.qstruct_decls:
|
622
|
+
return
|
623
|
+
|
624
|
+
struct_decl = QStructDeclaration(
|
625
|
+
name=self._struct_name,
|
626
|
+
fields={name: qvar.get_qmod_type() for name, qvar in self._fields.items()},
|
627
|
+
)
|
628
|
+
qmodule.qstruct_decls[self._struct_name] = struct_decl
|
629
|
+
|
630
|
+
|
631
|
+
def create_qvar_for_port_decl(port: AnonPortDeclaration, name: str) -> QVar:
|
632
|
+
return _create_qvar_for_qtype(port.quantum_type, HandleBinding(name=name))
|
272
633
|
|
273
634
|
|
274
|
-
def
|
635
|
+
def _create_qvar_for_qtype(
|
636
|
+
qtype: QuantumType, origin: HandleBinding, expr_str: Optional[str] = None
|
637
|
+
) -> QVar:
|
275
638
|
# prevent addition to local handles, since this is used for ports
|
276
639
|
with _no_current_expandable():
|
277
|
-
if
|
278
|
-
return QBit(
|
279
|
-
elif isinstance(
|
280
|
-
return QNum(
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
640
|
+
if isinstance(qtype, QuantumBit):
|
641
|
+
return QBit(origin, _expr_str=expr_str)
|
642
|
+
elif isinstance(qtype, QuantumNumeric):
|
643
|
+
return QNum(
|
644
|
+
origin,
|
645
|
+
qtype.size,
|
646
|
+
qtype.is_signed,
|
647
|
+
qtype.fraction_digits,
|
648
|
+
_expr_str=expr_str,
|
649
|
+
)
|
650
|
+
elif isinstance(qtype, TypeName):
|
651
|
+
struct_decl = QMODULE.qstruct_decls[qtype.name]
|
652
|
+
return QStruct(
|
653
|
+
origin,
|
654
|
+
struct_decl.name,
|
655
|
+
{
|
656
|
+
field_name: _create_qvar_for_qtype(
|
657
|
+
field_type,
|
658
|
+
FieldHandleBinding(base_handle=origin, field=field_name),
|
659
|
+
f"get_field({expr_str if expr_str is not None else str(origin)}, '{field_name}')",
|
660
|
+
)
|
661
|
+
for field_name, field_type in struct_decl.fields.items()
|
662
|
+
},
|
663
|
+
_expr_str=expr_str,
|
664
|
+
)
|
665
|
+
if TYPE_CHECKING:
|
666
|
+
assert isinstance(qtype, QuantumBitvector)
|
667
|
+
return QArray(origin, qtype.element_type, qtype.length, _expr_str=expr_str)
|
668
|
+
|
669
|
+
|
670
|
+
def get_qvar(qtype: QuantumType, origin: HandleBinding) -> "QVar":
|
671
|
+
if isinstance(qtype, QuantumBit):
|
672
|
+
return QBit(origin)
|
673
|
+
elif isinstance(qtype, QuantumBitvector):
|
674
|
+
return QArray(origin, qtype.element_type, qtype.length)
|
675
|
+
elif isinstance(qtype, QuantumNumeric):
|
676
|
+
return QNum(origin, qtype.size, qtype.is_signed, qtype.fraction_digits)
|
677
|
+
elif isinstance(qtype, TypeName):
|
678
|
+
return QStruct(
|
679
|
+
origin,
|
680
|
+
qtype.name,
|
681
|
+
{
|
682
|
+
field_name: get_qvar(
|
683
|
+
field_type, FieldHandleBinding(base_handle=origin, field=field_name)
|
684
|
+
)
|
685
|
+
for field_name, field_type in qtype.fields.items()
|
686
|
+
},
|
687
|
+
)
|
688
|
+
raise NotImplementedError
|