classiq 0.38.0__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 +47 -32
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
- classiq/_internals/api_wrapper.py +235 -97
- classiq/_internals/async_utils.py +1 -3
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +10 -5
- classiq/_internals/authentication/password_manager.py +18 -6
- classiq/_internals/authentication/token_manager.py +10 -5
- classiq/_internals/client.py +94 -33
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +60 -57
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +24 -19
- classiq/analyzer/analyzer_utilities.py +10 -10
- classiq/analyzer/rb.py +15 -15
- classiq/analyzer/show_interactive_hack.py +27 -4
- 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 +165 -158
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
- classiq/applications/combinatorial_optimization/__init__.py +20 -6
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
- 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 +48 -42
- classiq/applications/grover/__init__.py +9 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +6 -6
- 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 +1 -1
- 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 +5 -5
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +3 -6
- classiq/applications/qsvm/qsvm_data_generation.py +3 -3
- 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 +20 -115
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +43 -13
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +28 -32
- classiq/interface/applications/qsvm.py +20 -29
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -121
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +25 -22
- classiq/interface/backend/quantum_backend_providers.py +69 -16
- classiq/interface/chemistry/fermionic_operator.py +30 -21
- classiq/interface/chemistry/ground_state_problem.py +28 -25
- classiq/interface/chemistry/molecule.py +14 -10
- classiq/interface/chemistry/operator.py +64 -231
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
- 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/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -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/debug_info.py +86 -0
- classiq/{exceptions.py → interface/exceptions.py} +37 -9
- 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/execution_preferences.py +26 -114
- classiq/interface/executor/execution_request.py +24 -46
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +17 -14
- classiq/interface/executor/quantum_code.py +28 -24
- classiq/interface/executor/quantum_instruction_set.py +2 -2
- classiq/interface/executor/register_initialization.py +11 -14
- classiq/interface/executor/result.py +83 -56
- classiq/interface/executor/vqe_result.py +10 -10
- classiq/interface/finance/function_input.py +35 -25
- classiq/interface/finance/gaussian_model_input.py +5 -5
- classiq/interface/finance/log_normal_model_input.py +4 -4
- classiq/interface/finance/model_input.py +4 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +22 -12
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- 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 +46 -5
- classiq/interface/generator/arith/arithmetic.py +35 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
- classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
- classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
- classiq/interface/generator/arith/arithmetic_operations.py +14 -6
- 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 +3 -2
- classiq/interface/generator/arith/binary_ops.py +218 -130
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -25
- classiq/interface/generator/arith/logical_ops.py +14 -12
- classiq/interface/generator/arith/number_utils.py +12 -6
- classiq/interface/generator/arith/register_user_input.py +60 -37
- classiq/interface/generator/arith/unary_ops.py +49 -29
- 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 +3 -3
- 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 +7 -7
- classiq/interface/generator/compiler_keywords.py +5 -1
- classiq/interface/generator/complex_type.py +13 -18
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +34 -29
- 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 +21 -5
- 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 +5 -5
- classiq/interface/generator/expressions/expression.py +26 -14
- 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 +34 -8
- 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 +19 -11
- classiq/interface/generator/finance.py +2 -2
- 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 +36 -64
- classiq/interface/generator/functions/__init__.py +0 -22
- 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 +153 -20
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -25
- 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 +9 -9
- classiq/interface/generator/hardware/hardware_data.py +72 -34
- classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
- classiq/interface/generator/hartree_fock.py +13 -5
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +32 -20
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +17 -15
- classiq/interface/generator/mcx.py +24 -17
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +26 -8
- classiq/interface/generator/model/model.py +27 -190
- classiq/interface/generator/model/preferences/preferences.py +115 -41
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +15 -13
- classiq/interface/generator/oracles/oracle_abc.py +7 -7
- 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 +41 -30
- classiq/interface/generator/qsvm.py +9 -10
- classiq/interface/generator/quantum_function_call.py +88 -73
- classiq/interface/generator/quantum_program.py +41 -24
- classiq/interface/generator/range_types.py +11 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +5 -5
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -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 +4 -7
- classiq/interface/generator/state_preparation/state_preparation.py +25 -20
- 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 +7 -11
- classiq/interface/generator/ucc.py +5 -4
- classiq/interface/generator/unitary_gate.py +5 -5
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +7 -7
- classiq/interface/generator/validations/validator_functions.py +4 -4
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +29 -8
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +2 -2
- 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 -5
- classiq/interface/helpers/validation_helpers.py +3 -20
- classiq/interface/helpers/versioned_model.py +1 -4
- 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 +29 -69
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +32 -9
- 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 +29 -24
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +69 -61
- classiq/interface/model/native_function_definition.py +17 -20
- 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 +30 -18
- 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 +141 -343
- classiq/interface/model/quantum_function_declaration.py +190 -157
- classiq/interface/model/quantum_lambda_function.py +33 -32
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +177 -40
- classiq/interface/model/quantum_variable_declaration.py +3 -25
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +40 -14
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +7 -5
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +17 -21
- classiq/interface/source_reference.py +59 -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 +10 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +36 -14
- classiq/qmod/builtins/classical_functions.py +39 -43
- 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 +373 -40
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +4 -8
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +143 -101
- classiq/qmod/expression_query.py +20 -4
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +18 -6
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +16 -11
- classiq/qmod/native/pretty_printer.py +187 -97
- 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 +60 -8
- classiq/qmod/qmod_constant.py +93 -26
- classiq/qmod/qmod_parameter.py +68 -59
- classiq/qmod/qmod_variable.py +468 -155
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +269 -96
- classiq/qmod/quantum_function.py +196 -41
- 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 +147 -123
- classiq/qmod/symbolic_expr.py +27 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +98 -4
- classiq/qmod/write_qmod.py +17 -3
- classiq/synthesis.py +210 -22
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
- classiq-0.65.3.dist-info/RECORD +521 -0
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -25
- classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
- classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
- 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/interface/executor/aws_execution_cost.py +0 -73
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
- 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/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 -1229
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
- classiq/interface/generator/functions/foreign_function_definition.py +0 -114
- classiq/interface/generator/functions/function_implementation.py +0 -107
- classiq/interface/generator/functions/native_function_definition.py +0 -155
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -44
- classiq/interface/generator/functions/register_mapping_data.py +0 -106
- 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 -74
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/call_synthesis_data.py +0 -68
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -94
- 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 -156
- 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 -462
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -229
- classiq/qmod/builtins/functions.py +0 -913
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -205
- 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.38.0.dist-info/RECORD +0 -454
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
- /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
- /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
- /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
classiq/qmod/qmod_variable.py
CHANGED
@@ -1,37 +1,49 @@
|
|
1
1
|
import abc
|
2
2
|
import sys
|
3
|
+
from collections.abc import Iterator, Mapping
|
3
4
|
from contextlib import contextmanager
|
4
|
-
from typing import
|
5
|
-
from typing import (
|
5
|
+
from typing import ( # type: ignore[attr-defined]
|
6
6
|
TYPE_CHECKING,
|
7
|
+
Annotated,
|
7
8
|
Any,
|
8
9
|
ForwardRef,
|
9
10
|
Generic,
|
10
|
-
Iterator,
|
11
11
|
Literal,
|
12
12
|
Optional,
|
13
|
-
Tuple,
|
14
|
-
Type,
|
15
13
|
TypeVar,
|
16
14
|
Union,
|
15
|
+
_GenericAlias,
|
16
|
+
cast,
|
17
17
|
get_args,
|
18
18
|
get_origin,
|
19
|
-
overload,
|
20
19
|
)
|
21
20
|
|
22
|
-
from typing_extensions import
|
21
|
+
from typing_extensions import ParamSpec, Self, _AnnotatedAlias
|
23
22
|
|
23
|
+
from classiq.interface.exceptions import ClassiqValueError
|
24
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
|
+
)
|
25
29
|
from classiq.interface.generator.functions.port_declaration import (
|
26
30
|
PortDeclarationDirection,
|
27
31
|
)
|
28
|
-
from classiq.interface.
|
29
|
-
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
|
30
41
|
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
31
42
|
AmplitudeLoadingOperation,
|
32
43
|
)
|
33
44
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
34
45
|
ArithmeticOperation,
|
46
|
+
ArithmeticOperationKind,
|
35
47
|
)
|
36
48
|
from classiq.interface.model.quantum_type import (
|
37
49
|
QuantumBit,
|
@@ -39,17 +51,24 @@ from classiq.interface.model.quantum_type import (
|
|
39
51
|
QuantumNumeric,
|
40
52
|
QuantumType,
|
41
53
|
)
|
54
|
+
from classiq.interface.source_reference import SourceReference
|
42
55
|
|
43
|
-
from classiq.
|
44
|
-
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
|
45
63
|
from classiq.qmod.quantum_callable import QCallable
|
46
64
|
from classiq.qmod.symbolic_expr import Symbolic, SymbolicExpr
|
47
65
|
from classiq.qmod.symbolic_type import SymbolicTypes
|
48
|
-
from classiq.qmod.utilities import
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
66
|
+
from classiq.qmod.utilities import (
|
67
|
+
get_source_ref,
|
68
|
+
unwrap_forward_ref,
|
69
|
+
varname,
|
70
|
+
version_portable_get_args,
|
71
|
+
)
|
53
72
|
|
54
73
|
|
55
74
|
def _is_input_output_typehint(type_hint: Any) -> bool:
|
@@ -77,28 +96,59 @@ def _no_current_expandable() -> Iterator[None]:
|
|
77
96
|
QCallable.CURRENT_EXPANDABLE = current_expandable
|
78
97
|
|
79
98
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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:
|
84
131
|
QCallable.CURRENT_EXPANDABLE.add_local_handle(
|
85
|
-
|
132
|
+
name, self.get_qmod_type(), source_ref
|
86
133
|
)
|
134
|
+
self._expr_str = expr_str if expr_str is not None else str(name)
|
87
135
|
|
88
|
-
@abc.abstractmethod
|
89
136
|
def get_handle_binding(self) -> HandleBinding:
|
90
|
-
|
137
|
+
return self._base_handle
|
91
138
|
|
92
139
|
@abc.abstractmethod
|
93
140
|
def get_qmod_type(self) -> QuantumType:
|
94
141
|
raise NotImplementedError()
|
95
142
|
|
96
143
|
@staticmethod
|
97
|
-
def from_type_hint(type_hint: Any) -> Optional[
|
144
|
+
def from_type_hint(type_hint: Any) -> Optional[type["QVar"]]:
|
98
145
|
if _is_input_output_typehint(type_hint):
|
99
146
|
return QVar.from_type_hint(type_hint.__args__[0])
|
100
147
|
type_ = get_origin(type_hint) or type_hint
|
101
148
|
if issubclass(type_, QVar):
|
149
|
+
if issubclass(type_, QStruct):
|
150
|
+
with _no_current_expandable():
|
151
|
+
type_("DUMMY")._add_qmod_qstruct(qmodule=QMODULE)
|
102
152
|
return type_
|
103
153
|
return None
|
104
154
|
|
@@ -107,6 +157,16 @@ class QVar:
|
|
107
157
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
108
158
|
raise NotImplementedError()
|
109
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
|
+
|
110
170
|
@classmethod
|
111
171
|
def port_direction(cls, type_hint: Any) -> PortDeclarationDirection:
|
112
172
|
if _is_input_output_typehint(type_hint):
|
@@ -115,6 +175,16 @@ class QVar:
|
|
115
175
|
assert type_hint == cls or get_origin(type_hint) == cls
|
116
176
|
return PortDeclarationDirection.Inout
|
117
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
|
+
|
118
188
|
|
119
189
|
_Q = TypeVar("_Q", bound=QVar)
|
120
190
|
Output = Annotated[_Q, PortDeclarationDirection.Output]
|
@@ -122,11 +192,25 @@ Input = Annotated[_Q, PortDeclarationDirection.Input]
|
|
122
192
|
|
123
193
|
|
124
194
|
class QScalar(QVar, SymbolicExpr):
|
125
|
-
|
126
|
-
QVar.__init__(self, name)
|
127
|
-
SymbolicExpr.__init__(self, name)
|
195
|
+
CONSTRUCTOR_DEPTH: int = 2
|
128
196
|
|
129
|
-
def
|
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:
|
130
214
|
# Fixme: Arithmetic operations are not yet supported on slices (see CAD-12670)
|
131
215
|
if TYPE_CHECKING:
|
132
216
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
@@ -134,30 +218,33 @@ class QScalar(QVar, SymbolicExpr):
|
|
134
218
|
ArithmeticOperation(
|
135
219
|
expression=Expression(expr=str(expr)),
|
136
220
|
result_var=self.get_handle_binding(),
|
137
|
-
|
221
|
+
operation_kind=kind,
|
222
|
+
source_ref=source_ref,
|
138
223
|
)
|
139
224
|
)
|
140
225
|
|
141
|
-
def _insert_amplitude_loading(
|
226
|
+
def _insert_amplitude_loading(
|
227
|
+
self, expr: SymbolicTypes, source_ref: SourceReference
|
228
|
+
) -> None:
|
142
229
|
if TYPE_CHECKING:
|
143
230
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
144
231
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
145
232
|
AmplitudeLoadingOperation(
|
146
233
|
expression=Expression(expr=str(expr)),
|
147
234
|
result_var=self.get_handle_binding(),
|
235
|
+
source_ref=source_ref,
|
148
236
|
)
|
149
237
|
)
|
150
238
|
|
151
|
-
def get_handle_binding(self) -> HandleBinding:
|
152
|
-
return HandleBinding(name=self._name)
|
153
|
-
|
154
239
|
def __ior__(self, other: Any) -> Self:
|
155
240
|
if not isinstance(other, get_args(SymbolicTypes)):
|
156
241
|
raise TypeError(
|
157
242
|
f"Invalid argument {other!r} for out-of-place arithmetic operation"
|
158
243
|
)
|
159
244
|
|
160
|
-
self._insert_arith_operation(
|
245
|
+
self._insert_arith_operation(
|
246
|
+
other, ArithmeticOperationKind.Assignment, get_source_ref(sys._getframe(1))
|
247
|
+
)
|
161
248
|
return self
|
162
249
|
|
163
250
|
def __ixor__(self, other: Any) -> Self:
|
@@ -166,7 +253,20 @@ class QScalar(QVar, SymbolicExpr):
|
|
166
253
|
f"Invalid argument {other!r} for in-place arithmetic operation"
|
167
254
|
)
|
168
255
|
|
169
|
-
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
|
+
)
|
170
270
|
return self
|
171
271
|
|
172
272
|
def __imul__(self, other: Any) -> Self:
|
@@ -175,7 +275,7 @@ class QScalar(QVar, SymbolicExpr):
|
|
175
275
|
f"Invalid argument {other!r} for out of ampltiude encoding operation"
|
176
276
|
)
|
177
277
|
|
178
|
-
self._insert_amplitude_loading(other)
|
278
|
+
self._insert_amplitude_loading(other, get_source_ref(sys._getframe(1)))
|
179
279
|
return self
|
180
280
|
|
181
281
|
|
@@ -184,6 +284,15 @@ class QBit(QScalar):
|
|
184
284
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
185
285
|
return QuantumBit()
|
186
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
|
+
|
187
296
|
def get_qmod_type(self) -> QuantumType:
|
188
297
|
return QuantumBit()
|
189
298
|
|
@@ -192,80 +301,111 @@ _P = ParamSpec("_P")
|
|
192
301
|
|
193
302
|
|
194
303
|
class QNum(Generic[_P], QScalar):
|
195
|
-
|
196
|
-
|
197
|
-
@overload
|
198
|
-
def __init__(self, name: str):
|
199
|
-
pass
|
200
|
-
|
201
|
-
@overload
|
202
|
-
def __init__(
|
203
|
-
self,
|
204
|
-
name: str,
|
205
|
-
size: Union[int, QParam[int]],
|
206
|
-
is_signed: Union[bool, QParam[bool]],
|
207
|
-
fraction_digits: Union[int, QParam[int]],
|
208
|
-
):
|
209
|
-
pass
|
304
|
+
CONSTRUCTOR_DEPTH: int = 3
|
210
305
|
|
211
306
|
def __init__(
|
212
307
|
self,
|
213
|
-
name: str,
|
214
|
-
size: Union[int,
|
215
|
-
is_signed: Union[bool,
|
216
|
-
fraction_digits: Union[int,
|
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,
|
217
313
|
):
|
218
|
-
if (
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
):
|
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:
|
224
319
|
raise ClassiqValueError(
|
225
|
-
"
|
320
|
+
"Cannot assign 'is_signed' without 'fraction_digits'"
|
226
321
|
)
|
227
|
-
|
228
|
-
|
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
|
+
)
|
229
336
|
self._fraction_digits = (
|
230
|
-
|
337
|
+
fraction_digits
|
338
|
+
if fraction_digits is None or isinstance(fraction_digits, Expression)
|
339
|
+
else Expression(expr=str(fraction_digits))
|
231
340
|
)
|
232
|
-
super().__init__(name)
|
341
|
+
super().__init__(name, _expr_str=_expr_str, depth=3)
|
233
342
|
|
234
343
|
@classmethod
|
235
|
-
def
|
236
|
-
type_args =
|
344
|
+
def _get_attributes(cls, type_hint: Any) -> tuple[Any, Any, Any]:
|
345
|
+
type_args = version_portable_get_args(type_hint)
|
237
346
|
if len(type_args) == 0:
|
238
|
-
return
|
239
|
-
type_args
|
240
|
-
if len(type_args) != 3:
|
347
|
+
return None, None, None
|
348
|
+
if len(type_args) not in (1, 3):
|
241
349
|
raise ClassiqValueError(
|
242
|
-
"QNum receives three type arguments: QNum[size: int |
|
243
|
-
"is_signed: bool |
|
350
|
+
"QNum receives three type arguments: QNum[size: int | CInt, "
|
351
|
+
"is_signed: bool | CBool, fraction_digits: int | CInt]"
|
244
352
|
)
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
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
|
+
)
|
360
|
+
|
361
|
+
@classmethod
|
362
|
+
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
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
|
+
),
|
249
378
|
)
|
250
379
|
|
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)
|
388
|
+
|
251
389
|
def get_qmod_type(self) -> QuantumType:
|
252
|
-
return
|
390
|
+
return QuantumNumeric(
|
253
391
|
size=self._size,
|
254
392
|
is_signed=self._is_signed,
|
255
393
|
fraction_digits=self._fraction_digits,
|
256
394
|
)
|
257
395
|
|
258
396
|
@property
|
259
|
-
def
|
260
|
-
|
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')")
|
261
402
|
|
262
403
|
@property
|
263
|
-
def
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
return QParamScalar(f"is_signed({self._name})")
|
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')")
|
269
409
|
|
270
410
|
# Support comma-separated generic args in older Python versions
|
271
411
|
if sys.version_info[0:2] < (3, 10):
|
@@ -275,101 +415,274 @@ class QNum(Generic[_P], QScalar):
|
|
275
415
|
|
276
416
|
|
277
417
|
class QArray(ArrayBase[_P], QVar):
|
418
|
+
CONSTRUCTOR_DEPTH: int = 3
|
419
|
+
|
420
|
+
# TODO [CAD-18620]: improve type hints
|
278
421
|
def __init__(
|
279
422
|
self,
|
280
|
-
name: str,
|
281
|
-
element_type: _GenericAlias = QBit,
|
282
|
-
length: Optional[Union[int,
|
283
|
-
|
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,
|
284
427
|
) -> None:
|
285
|
-
if element_type is not QBit:
|
286
|
-
raise ClassiqValueError(UNSUPPORTED_ELEMENT_TYPE)
|
287
428
|
self._element_type = element_type
|
288
|
-
self._length =
|
289
|
-
|
290
|
-
|
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)
|
291
435
|
|
292
|
-
def
|
293
|
-
|
294
|
-
|
295
|
-
return SlicedHandleBinding(
|
296
|
-
name=self._name,
|
297
|
-
start=Expression(expr=str(self._slice[0])),
|
298
|
-
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)
|
299
439
|
)
|
300
440
|
|
301
|
-
def
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
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)
|
321
462
|
):
|
322
|
-
raise ClassiqValueError(
|
323
|
-
|
324
|
-
|
325
|
-
|
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
|
+
)
|
326
475
|
|
327
476
|
def __len__(self) -> int:
|
328
477
|
raise ClassiqValueError(
|
329
|
-
"len(<var>) is not supported for quantum variables - use <var>.len
|
478
|
+
"len(<var>) is not supported for quantum variables - use <var>.len instead"
|
330
479
|
)
|
331
480
|
|
332
481
|
if TYPE_CHECKING:
|
333
482
|
|
483
|
+
@property
|
334
484
|
def len(self) -> int: ...
|
335
485
|
|
336
486
|
else:
|
337
487
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
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))
|
342
512
|
|
343
513
|
@classmethod
|
344
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
|
+
|
345
519
|
length_expr: Optional[Expression] = None
|
346
|
-
if
|
347
|
-
length_expr = Expression(
|
348
|
-
|
349
|
-
|
350
|
-
|
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)
|
351
571
|
|
352
572
|
def get_qmod_type(self) -> QuantumType:
|
353
|
-
|
354
|
-
return QuantumBitvector(length=Expression(expr=str(self._length)))
|
355
|
-
return QuantumBitvector()
|
573
|
+
return TypeName(name=self._struct_name)
|
356
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__)
|
357
580
|
|
358
|
-
|
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))
|
633
|
+
|
634
|
+
|
635
|
+
def _create_qvar_for_qtype(
|
636
|
+
qtype: QuantumType, origin: HandleBinding, expr_str: Optional[str] = None
|
637
|
+
) -> QVar:
|
359
638
|
# prevent addition to local handles, since this is used for ports
|
360
639
|
with _no_current_expandable():
|
361
|
-
if
|
362
|
-
return QBit(
|
363
|
-
elif isinstance(
|
364
|
-
return QNum(
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
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
|