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
@@ -1,166 +1,50 @@
|
|
1
|
-
import
|
2
|
-
import
|
3
|
-
|
1
|
+
from collections.abc import Iterable, Mapping, Sequence
|
2
|
+
from typing import (
|
3
|
+
Literal,
|
4
|
+
Optional,
|
5
|
+
Union,
|
6
|
+
)
|
4
7
|
|
5
8
|
import pydantic
|
6
|
-
from pydantic import BaseModel
|
7
9
|
|
10
|
+
from classiq.interface.exceptions import ClassiqError, ClassiqValueError
|
8
11
|
from classiq.interface.generator.expressions.expression import Expression
|
9
|
-
from classiq.interface.generator.function_params import NAME_REGEX
|
10
|
-
from classiq.interface.generator.functions import FunctionDeclaration
|
11
12
|
from classiq.interface.generator.functions.port_declaration import (
|
12
13
|
PortDeclarationDirection,
|
13
14
|
)
|
14
|
-
from classiq.interface.generator.quantum_function_call import (
|
15
|
-
BAD_CALL_NAME_ERROR_MSG,
|
16
|
-
SUFFIX_MARKER,
|
17
|
-
randomize_suffix,
|
18
|
-
)
|
19
|
-
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
20
|
-
from classiq.interface.model.bind_operation import BindOperation
|
21
15
|
from classiq.interface.model.handle_binding import (
|
16
|
+
ConcreteHandleBinding,
|
22
17
|
HandleBinding,
|
23
|
-
SlicedHandleBinding,
|
24
|
-
SubscriptHandleBinding,
|
25
|
-
)
|
26
|
-
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
27
|
-
from classiq.interface.model.numeric_reinterpretation import (
|
28
|
-
NumericReinterpretationOperation,
|
29
|
-
)
|
30
|
-
from classiq.interface.model.operator_synthesis_data import OperatorSynthesisData
|
31
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
32
|
-
AmplitudeLoadingOperation,
|
33
|
-
)
|
34
|
-
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
35
|
-
ArithmeticOperation,
|
36
18
|
)
|
19
|
+
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
37
20
|
from classiq.interface.model.quantum_function_declaration import (
|
38
21
|
QuantumFunctionDeclaration,
|
39
|
-
QuantumOperandDeclaration,
|
40
22
|
)
|
41
|
-
from classiq.interface.model.
|
42
|
-
|
43
|
-
|
44
|
-
from classiq.interface.model.variable_declaration_statement import (
|
45
|
-
VariableDeclarationStatement,
|
23
|
+
from classiq.interface.model.quantum_lambda_function import (
|
24
|
+
OperandIdentifier,
|
25
|
+
QuantumOperand,
|
46
26
|
)
|
27
|
+
from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
|
47
28
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
outputs: Mapping[str, HandleBinding],
|
54
|
-
inouts: Mapping[str, HandleBinding],
|
55
|
-
) -> None:
|
56
|
-
inputs_and_inouts = inputs.keys() & inouts.keys()
|
57
|
-
if inputs_and_inouts:
|
58
|
-
raise ClassiqValueError(
|
59
|
-
f"{inputs_and_inouts} are used as ports in both inputs and inouts"
|
60
|
-
)
|
61
|
-
|
62
|
-
outputs_and_inouts = outputs.keys() & inouts.keys()
|
63
|
-
if outputs_and_inouts:
|
64
|
-
raise ClassiqValueError(
|
65
|
-
f"{outputs_and_inouts} are used as ports in both outputs and inouts"
|
66
|
-
)
|
67
|
-
|
68
|
-
|
69
|
-
def _validate_no_duplicated_handles(
|
70
|
-
inputs: Mapping[str, HandleBinding],
|
71
|
-
outputs: Mapping[str, HandleBinding],
|
72
|
-
inouts: Mapping[str, HandleBinding],
|
73
|
-
) -> None:
|
74
|
-
inputs_and_inouts = get_unique_handle_names(inputs) & get_unique_handle_names(
|
75
|
-
inouts
|
76
|
-
)
|
77
|
-
if inputs_and_inouts:
|
78
|
-
raise ClassiqValueError(
|
79
|
-
f"{inputs_and_inouts} are used as handles in both inputs and inouts"
|
80
|
-
)
|
81
|
-
|
82
|
-
outputs_and_inouts = get_unique_handle_names(outputs) & get_unique_handle_names(
|
83
|
-
inouts
|
84
|
-
)
|
85
|
-
if outputs_and_inouts:
|
86
|
-
raise ClassiqValueError(
|
87
|
-
f"{outputs_and_inouts} are used as handles in both outputs and inouts"
|
88
|
-
)
|
89
|
-
|
90
|
-
|
91
|
-
def _validate_no_mixing_sliced_and_whole_handles(
|
92
|
-
inouts: Mapping[str, HandleBinding],
|
93
|
-
) -> None:
|
94
|
-
inout_handle_names_to_types = {
|
95
|
-
handle_name: {type(handle) for handle in handles}
|
96
|
-
for handle_name, handles in itertools.groupby(
|
97
|
-
inouts.values(), lambda handle: handle.name
|
98
|
-
)
|
99
|
-
}
|
100
|
-
invalid_handles = [
|
101
|
-
handle
|
102
|
-
for handle, types in inout_handle_names_to_types.items()
|
103
|
-
if len(types) > 1
|
104
|
-
]
|
105
|
-
if invalid_handles:
|
106
|
-
raise ClassiqValueError(
|
107
|
-
f"Inout handles {', '.join(invalid_handles)} mix sliced and whole handles"
|
108
|
-
)
|
109
|
-
|
110
|
-
|
111
|
-
ArgValue = Union[Expression, "QuantumOperand", SlicedHandleBinding, HandleBinding]
|
112
|
-
|
113
|
-
|
114
|
-
class OperandIdentifier(BaseModel):
|
115
|
-
name: str
|
116
|
-
index: Expression
|
29
|
+
ArgValue = Union[
|
30
|
+
Expression,
|
31
|
+
QuantumOperand,
|
32
|
+
ConcreteHandleBinding,
|
33
|
+
]
|
117
34
|
|
118
35
|
|
119
36
|
class QuantumFunctionCall(QuantumOperation):
|
37
|
+
kind: Literal["QuantumFunctionCall"]
|
38
|
+
|
120
39
|
function: Union[str, OperandIdentifier] = pydantic.Field(
|
121
40
|
description="The function that is called"
|
122
41
|
)
|
123
|
-
|
124
|
-
release_by_inverse: bool = pydantic.Field(
|
125
|
-
default=False, description="Release zero inputs in inverse call."
|
126
|
-
)
|
127
|
-
should_control: bool = pydantic.Field(
|
128
|
-
default=True,
|
129
|
-
description="False value indicates this call shouldn't be controlled even if the flow is controlled.",
|
130
|
-
)
|
131
|
-
inputs: Dict[str, HandleBinding] = pydantic.Field(
|
132
|
-
default_factory=dict,
|
133
|
-
description="A mapping from the input name to the wire it connects to",
|
134
|
-
)
|
135
|
-
inouts: Dict[
|
136
|
-
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
137
|
-
] = pydantic.Field(
|
138
|
-
default_factory=dict,
|
139
|
-
description="A mapping from in/out name to the wires that connect to it",
|
140
|
-
)
|
141
|
-
outputs: Dict[str, HandleBinding] = pydantic.Field(
|
142
|
-
default_factory=dict,
|
143
|
-
description="A mapping from the output name to the wire it connects to",
|
144
|
-
)
|
145
|
-
name: PydanticNonEmptyString = pydantic.Field(
|
146
|
-
default=None,
|
147
|
-
description="The name of the function instance. "
|
148
|
-
"If not set, determined automatically.",
|
149
|
-
)
|
150
|
-
operands: Dict[str, "QuantumOperand"] = pydantic.Field(
|
151
|
-
description="Function calls passed to the operator",
|
152
|
-
default_factory=dict,
|
153
|
-
)
|
154
|
-
positional_args: List[ArgValue] = pydantic.Field(default_factory=list)
|
42
|
+
positional_args: list[ArgValue] = pydantic.Field(default_factory=list)
|
155
43
|
|
156
44
|
_func_decl: Optional[QuantumFunctionDeclaration] = pydantic.PrivateAttr(
|
157
45
|
default=None
|
158
46
|
)
|
159
47
|
|
160
|
-
_operator_synthesis_data: OperatorSynthesisData = pydantic.PrivateAttr(
|
161
|
-
default_factory=OperatorSynthesisData
|
162
|
-
)
|
163
|
-
|
164
48
|
@property
|
165
49
|
def func_decl(self) -> QuantumFunctionDeclaration:
|
166
50
|
if self._func_decl is None:
|
@@ -168,7 +52,7 @@ class QuantumFunctionCall(QuantumOperation):
|
|
168
52
|
|
169
53
|
return self._func_decl
|
170
54
|
|
171
|
-
def set_func_decl(self, fd: Optional[
|
55
|
+
def set_func_decl(self, fd: Optional[QuantumFunctionDeclaration]) -> None:
|
172
56
|
if fd is not None and not isinstance(fd, QuantumFunctionDeclaration):
|
173
57
|
raise ClassiqValueError(
|
174
58
|
"the declaration of a quantum function call cannot be set to a non-quantum function declaration."
|
@@ -183,352 +67,152 @@ class QuantumFunctionCall(QuantumOperation):
|
|
183
67
|
|
184
68
|
@property
|
185
69
|
def wiring_inputs(self) -> Mapping[str, HandleBinding]:
|
186
|
-
return self.
|
70
|
+
return self._get_pos_port_args_by_direction(PortDeclarationDirection.Input)
|
187
71
|
|
188
72
|
@property
|
189
|
-
def
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
73
|
+
def inputs(self) -> Sequence[HandleBinding]:
|
74
|
+
return [
|
75
|
+
handle
|
76
|
+
for _, _, handle in self._get_handles_by_direction(
|
77
|
+
PortDeclarationDirection.Input
|
78
|
+
)
|
79
|
+
]
|
195
80
|
|
196
81
|
@property
|
197
|
-
def
|
198
|
-
return
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
result.extend(self.outputs.values())
|
208
|
-
return result
|
209
|
-
|
210
|
-
def __eq__(self, other: Any) -> bool:
|
211
|
-
return isinstance(other, QuantumFunctionCall) and self.name == other.name
|
212
|
-
|
213
|
-
def __hash__(self) -> int:
|
214
|
-
return hash(self.name)
|
215
|
-
|
216
|
-
@pydantic.validator("name", pre=True, always=True)
|
217
|
-
def _create_name(cls, name: Optional[str], values: Dict[str, Any]) -> str:
|
218
|
-
"""
|
219
|
-
generates a name to a user defined-functions as follows:
|
220
|
-
<function_name>_<SUFFIX_MARKER>_<random_suffix>
|
221
|
-
"""
|
222
|
-
if name is not None:
|
223
|
-
match = re.fullmatch(pattern=NAME_REGEX, string=name)
|
224
|
-
if match is None:
|
225
|
-
raise ValueError(BAD_CALL_NAME_ERROR_MSG)
|
226
|
-
return name
|
227
|
-
|
228
|
-
function = values.get("function")
|
229
|
-
if isinstance(function, OperandIdentifier):
|
230
|
-
function = function.name
|
231
|
-
|
232
|
-
suffix = f"{SUFFIX_MARKER}_{randomize_suffix()}"
|
233
|
-
if not function:
|
234
|
-
return name if name else suffix
|
235
|
-
return f"{function}_{suffix}"
|
82
|
+
def readable_inputs(self) -> Sequence[HandleMetadata]:
|
83
|
+
return [
|
84
|
+
HandleMetadata(
|
85
|
+
handle=handle,
|
86
|
+
readable_location=self._get_readable_location(param_idx, param),
|
87
|
+
)
|
88
|
+
for param_idx, param, handle in self._get_handles_by_direction(
|
89
|
+
PortDeclarationDirection.Input
|
90
|
+
)
|
91
|
+
]
|
236
92
|
|
237
93
|
@property
|
238
|
-
def
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
(
|
243
|
-
param
|
244
|
-
for param in self.positional_args
|
245
|
-
if isinstance(param, Expression)
|
246
|
-
),
|
247
|
-
)
|
248
|
-
)
|
94
|
+
def wiring_inouts(
|
95
|
+
self,
|
96
|
+
) -> Mapping[str, ConcreteHandleBinding]:
|
97
|
+
return self._get_pos_port_args_by_direction(PortDeclarationDirection.Inout)
|
249
98
|
|
250
99
|
@property
|
251
|
-
def
|
252
|
-
return
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
param
|
257
|
-
for param in self.positional_args
|
258
|
-
if not isinstance(param, (Expression, HandleBinding))
|
259
|
-
),
|
100
|
+
def inouts(self) -> Sequence[HandleBinding]:
|
101
|
+
return [
|
102
|
+
handle
|
103
|
+
for _, _, handle in self._get_handles_by_direction(
|
104
|
+
PortDeclarationDirection.Inout
|
260
105
|
)
|
261
|
-
|
106
|
+
]
|
262
107
|
|
263
108
|
@property
|
264
|
-
def
|
265
|
-
return
|
266
|
-
|
267
|
-
|
268
|
-
(
|
269
|
-
param
|
270
|
-
for param in self.positional_args
|
271
|
-
if isinstance(param, HandleBinding)
|
272
|
-
),
|
109
|
+
def readable_inouts(self) -> Sequence[HandleMetadata]:
|
110
|
+
return [
|
111
|
+
HandleMetadata(
|
112
|
+
handle=handle,
|
113
|
+
readable_location=self._get_readable_location(param_idx, param),
|
273
114
|
)
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
if port_decl.direction == PortDeclarationDirection.Input:
|
279
|
-
self.inputs[name] = self.pos_port_args[name]
|
280
|
-
elif port_decl.direction == PortDeclarationDirection.Output:
|
281
|
-
self.outputs[name] = self.pos_port_args[name]
|
282
|
-
else:
|
283
|
-
self.inouts[name] = self.pos_port_args[name]
|
284
|
-
|
285
|
-
def _reduce_positional_args_to_keywords(self) -> None:
|
286
|
-
self.params.update(self.pos_param_args)
|
287
|
-
self.operands.update(self.pos_operand_args)
|
288
|
-
self._update_pos_port_params()
|
289
|
-
|
290
|
-
def resolve_function_decl(
|
291
|
-
self,
|
292
|
-
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
293
|
-
check_operands: bool,
|
294
|
-
) -> None:
|
295
|
-
if self._func_decl is None:
|
296
|
-
func_decl = function_dict.get(self.func_name)
|
297
|
-
if func_decl is None:
|
298
|
-
raise ClassiqValueError(
|
299
|
-
f"Error resolving function {self.func_name}, the function is not found in included library."
|
300
|
-
)
|
301
|
-
self.set_func_decl(func_decl)
|
302
|
-
|
303
|
-
if self.positional_args:
|
304
|
-
self._reduce_positional_args_to_keywords()
|
305
|
-
|
306
|
-
_check_params_against_declaration(
|
307
|
-
set(self.params.keys()),
|
308
|
-
set(self.func_decl.param_decls.keys()),
|
309
|
-
self.func_decl.name,
|
310
|
-
)
|
311
|
-
_check_ports_against_declaration(self, self.func_decl)
|
312
|
-
_check_params_against_declaration(
|
313
|
-
set(self.operands.keys()),
|
314
|
-
set(self.func_decl.operand_declarations.keys()),
|
315
|
-
self.func_name,
|
316
|
-
)
|
317
|
-
if check_operands:
|
318
|
-
_check_operands_against_declaration(self, self.func_decl, function_dict)
|
319
|
-
|
320
|
-
for name, op in self.operands.items():
|
321
|
-
op_decl = self.func_decl.operand_declarations[name]
|
322
|
-
for qlambda in get_lambda_defs(op):
|
323
|
-
if isinstance(qlambda, QuantumLambdaFunction):
|
324
|
-
qlambda.set_op_decl(op_decl)
|
115
|
+
for param_idx, param, handle in self._get_handles_by_direction(
|
116
|
+
PortDeclarationDirection.Inout
|
117
|
+
)
|
118
|
+
]
|
325
119
|
|
326
120
|
@property
|
327
|
-
def
|
328
|
-
return self.
|
329
|
-
|
330
|
-
def set_operator_synthesis_data(
|
331
|
-
self, operator_synthesis_data: OperatorSynthesisData
|
332
|
-
) -> None:
|
333
|
-
self._operator_synthesis_data = operator_synthesis_data
|
334
|
-
|
335
|
-
@staticmethod
|
336
|
-
def _has_repetitions(name_list: Sequence[str]) -> bool:
|
337
|
-
return len(set(name_list)) < len(name_list)
|
338
|
-
|
339
|
-
@pydantic.root_validator()
|
340
|
-
def validate_handles(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
341
|
-
inputs = values.get("inputs", dict())
|
342
|
-
outputs = values.get("outputs", dict())
|
343
|
-
inouts = values.get("inouts", dict())
|
344
|
-
|
345
|
-
_validate_no_duplicated_ports(inputs, outputs, inouts)
|
346
|
-
_validate_no_duplicated_handles(inputs, outputs, inouts)
|
347
|
-
_validate_no_mixing_sliced_and_whole_handles(inouts)
|
348
|
-
|
349
|
-
return values
|
350
|
-
|
351
|
-
|
352
|
-
ConcreteQuantumStatement = Union[
|
353
|
-
QuantumFunctionCall,
|
354
|
-
ArithmeticOperation,
|
355
|
-
AmplitudeLoadingOperation,
|
356
|
-
VariableDeclarationStatement,
|
357
|
-
BindOperation,
|
358
|
-
NumericReinterpretationOperation,
|
359
|
-
InplaceBinaryOperation,
|
360
|
-
QuantumIfOperation,
|
361
|
-
]
|
362
|
-
|
363
|
-
|
364
|
-
class QuantumLambdaFunction(BaseModel):
|
365
|
-
"""
|
366
|
-
The definition of an anonymous function passed as operand to higher-level functions
|
367
|
-
"""
|
368
|
-
|
369
|
-
rename_params: Dict[str, str] = pydantic.Field(
|
370
|
-
default_factory=dict,
|
371
|
-
description="Mapping of the declared param to the actual variable name used ",
|
372
|
-
)
|
373
|
-
|
374
|
-
body: List[ConcreteQuantumStatement] = pydantic.Field(
|
375
|
-
description="A list of function calls passed to the operator"
|
376
|
-
)
|
377
|
-
|
378
|
-
_func_decl: Optional[QuantumOperandDeclaration] = pydantic.PrivateAttr(default=None)
|
121
|
+
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
122
|
+
return self._get_pos_port_args_by_direction(PortDeclarationDirection.Output)
|
379
123
|
|
380
124
|
@property
|
381
|
-
def
|
382
|
-
return
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
class LambdaListComprehension(BaseModel):
|
389
|
-
"""
|
390
|
-
Specification of a list of lambda functions iteratively
|
391
|
-
"""
|
392
|
-
|
393
|
-
count: Expression = pydantic.Field(
|
394
|
-
description="The number of lambda functions in the list"
|
395
|
-
)
|
396
|
-
|
397
|
-
index_var: str = pydantic.Field(
|
398
|
-
description="The name of the integer variable holding the iteration index"
|
399
|
-
)
|
400
|
-
|
401
|
-
func: QuantumLambdaFunction = pydantic.Field(
|
402
|
-
description="A lambda function definition replicated for index values 0 to count-1"
|
403
|
-
)
|
404
|
-
|
405
|
-
|
406
|
-
QuantumCallable = Union[str, QuantumLambdaFunction]
|
407
|
-
QuantumOperand = Union[QuantumCallable, List[QuantumCallable], LambdaListComprehension]
|
408
|
-
|
409
|
-
QuantumFunctionCall.update_forward_refs()
|
410
|
-
QuantumIfOperation.update_forward_refs(QuantumOperand=QuantumOperand)
|
411
|
-
|
412
|
-
|
413
|
-
def get_lambda_defs(operand: QuantumOperand) -> List[QuantumCallable]:
|
414
|
-
if isinstance(operand, list):
|
415
|
-
return operand
|
416
|
-
elif isinstance(operand, LambdaListComprehension):
|
417
|
-
return [operand.func]
|
418
|
-
else:
|
419
|
-
return [operand]
|
420
|
-
|
421
|
-
|
422
|
-
def _check_ports_against_declaration(
|
423
|
-
call: QuantumFunctionCall, decl: QuantumFunctionDeclaration
|
424
|
-
) -> None:
|
425
|
-
call_input_names = set(call.inputs.keys())
|
426
|
-
|
427
|
-
_check_params_against_declaration(
|
428
|
-
call_input_names,
|
429
|
-
decl.ports_by_declaration_direction(PortDeclarationDirection.Input),
|
430
|
-
call.func_name,
|
431
|
-
)
|
432
|
-
|
433
|
-
call_output_names = set(call.outputs.keys())
|
434
|
-
|
435
|
-
_check_params_against_declaration(
|
436
|
-
call_output_names,
|
437
|
-
decl.ports_by_declaration_direction(PortDeclarationDirection.Output),
|
438
|
-
call.func_name,
|
439
|
-
)
|
440
|
-
|
441
|
-
inout_params = set(call.inouts.keys())
|
442
|
-
|
443
|
-
_check_params_against_declaration(
|
444
|
-
inout_params,
|
445
|
-
decl.ports_by_declaration_direction(PortDeclarationDirection.Inout),
|
446
|
-
call.func_name,
|
447
|
-
)
|
448
|
-
|
449
|
-
|
450
|
-
def _check_operand_against_declaration(
|
451
|
-
call: QuantumFunctionCall,
|
452
|
-
operand_decl: QuantumOperandDeclaration,
|
453
|
-
operand_argument: QuantumOperand,
|
454
|
-
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
455
|
-
in_list: bool = False,
|
456
|
-
) -> None:
|
457
|
-
if isinstance(operand_argument, list):
|
458
|
-
if in_list:
|
459
|
-
raise ClassiqValueError(
|
460
|
-
f"{str(operand_argument)!r} argument to {call.func_decl.name!r} is not "
|
461
|
-
f"a valid operand. Nested operand lists are not permitted"
|
125
|
+
def outputs(self) -> Sequence[HandleBinding]:
|
126
|
+
return [
|
127
|
+
handle
|
128
|
+
for _, _, handle in self._get_handles_by_direction(
|
129
|
+
PortDeclarationDirection.Output
|
462
130
|
)
|
463
|
-
|
464
|
-
|
465
|
-
|
131
|
+
]
|
132
|
+
|
133
|
+
@property
|
134
|
+
def readable_outputs(self) -> Sequence[HandleMetadata]:
|
135
|
+
return [
|
136
|
+
HandleMetadata(
|
137
|
+
handle=handle,
|
138
|
+
readable_location=self._get_readable_location(param_idx, param),
|
466
139
|
)
|
467
|
-
|
468
|
-
|
469
|
-
if isinstance(operand_argument, str):
|
470
|
-
if operand_argument not in function_dict:
|
471
|
-
raise ClassiqValueError(
|
472
|
-
f"{operand_argument!r} argument to {call.func_decl.name!r} is not a "
|
473
|
-
f"registered function"
|
140
|
+
for param_idx, param, handle in self._get_handles_by_direction(
|
141
|
+
PortDeclarationDirection.Output
|
474
142
|
)
|
475
|
-
|
476
|
-
elif isinstance(operand_argument, QuantumLambdaFunction):
|
477
|
-
if operand_argument.func_decl is None:
|
478
|
-
return
|
479
|
-
operand_arg_decl = operand_argument.func_decl
|
480
|
-
elif isinstance(operand_argument, LambdaListComprehension):
|
481
|
-
if operand_argument.func.func_decl is None:
|
482
|
-
return
|
483
|
-
operand_arg_decl = operand_argument.func.func_decl
|
484
|
-
else:
|
485
|
-
raise ClassiqValueError(
|
486
|
-
f"{str(operand_argument)!r} argument to {call.func_decl.name!r} is not a "
|
487
|
-
f"valid operand"
|
488
|
-
)
|
489
|
-
num_arg_parameters = len(operand_arg_decl.get_positional_arg_decls())
|
490
|
-
num_decl_parameters = len(operand_decl.get_positional_arg_decls())
|
491
|
-
if num_arg_parameters != num_decl_parameters:
|
492
|
-
raise ClassiqValueError(
|
493
|
-
f"Signature of argument {operand_argument!r} to {call.func_decl.name!r} "
|
494
|
-
f"does not match the signature of parameter {operand_decl.name!r}. "
|
495
|
-
f"{operand_decl.name!r} accepts {num_decl_parameters} parameters but "
|
496
|
-
f"{operand_argument!r} accepts {num_arg_parameters} parameters"
|
497
|
-
)
|
143
|
+
]
|
498
144
|
|
145
|
+
@property
|
146
|
+
def params(self) -> list[Expression]:
|
147
|
+
return [
|
148
|
+
param for param in self.positional_args if isinstance(param, Expression)
|
149
|
+
]
|
499
150
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
504
|
-
) -> None:
|
505
|
-
for operand_parameter, operand_argument in call.operands.items():
|
506
|
-
_check_operand_against_declaration(
|
507
|
-
call,
|
508
|
-
decl.operand_declarations[operand_parameter],
|
509
|
-
operand_argument,
|
510
|
-
function_dict,
|
511
|
-
)
|
151
|
+
@property
|
152
|
+
def params_dict(self) -> dict[str, Expression]:
|
153
|
+
return dict(zip(self.func_decl.param_names, self.params))
|
512
154
|
|
155
|
+
@property
|
156
|
+
def operands(self) -> list["QuantumOperand"]:
|
157
|
+
return [
|
158
|
+
param
|
159
|
+
for param in self.positional_args
|
160
|
+
if not isinstance(param, (Expression, HandleBinding))
|
161
|
+
]
|
513
162
|
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
163
|
+
@property
|
164
|
+
def ports(self) -> list[HandleBinding]:
|
165
|
+
return [
|
166
|
+
param for param in self.positional_args if isinstance(param, HandleBinding)
|
167
|
+
]
|
168
|
+
|
169
|
+
def _get_handles_by_direction(
|
170
|
+
self, direction: PortDeclarationDirection
|
171
|
+
) -> list[tuple[int, AnonPortDeclaration, HandleBinding]]:
|
172
|
+
return [
|
173
|
+
(idx, port_decl, handle)
|
174
|
+
for idx, port_decl, handle in self._get_handles_with_declarations()
|
175
|
+
if direction == port_decl.direction
|
176
|
+
]
|
177
|
+
|
178
|
+
def _get_pos_port_args_by_direction(
|
179
|
+
self, direction: PortDeclarationDirection
|
180
|
+
) -> dict[str, HandleBinding]:
|
181
|
+
# This is a hack for handles to wires reduction tests,
|
182
|
+
# that initialize function definitions or calls not in the scope of a model,
|
183
|
+
# so there is no function resolution annotation.
|
184
|
+
if self._func_decl is None:
|
185
|
+
return dict()
|
186
|
+
return {
|
187
|
+
port_decl.get_name(): handle
|
188
|
+
for _, port_decl, handle in self._get_handles_with_declarations()
|
189
|
+
if direction == port_decl.direction
|
190
|
+
}
|
191
|
+
|
192
|
+
def _get_handles_with_declarations(
|
193
|
+
self,
|
194
|
+
) -> Iterable[tuple[int, AnonPortDeclaration, HandleBinding]]:
|
195
|
+
return [
|
196
|
+
(idx, port, handle)
|
197
|
+
for idx, (port, handle) in enumerate(
|
198
|
+
zip(
|
199
|
+
(port_decl for port_decl in self.func_decl.port_declarations),
|
200
|
+
(
|
201
|
+
param
|
202
|
+
for param in self.positional_args
|
203
|
+
if isinstance(param, HandleBinding)
|
204
|
+
),
|
205
|
+
)
|
206
|
+
)
|
207
|
+
]
|
529
208
|
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
209
|
+
def _get_readable_location(
|
210
|
+
self, param_index: int, param_decl: AnonPortDeclaration
|
211
|
+
) -> str:
|
212
|
+
param_name = (
|
213
|
+
repr(param_decl.name) if param_decl.name is not None else f"#{param_index}"
|
214
|
+
)
|
215
|
+
param_text = (
|
216
|
+
f" for parameter {param_name}" if len(self.positional_args) > 1 else ""
|
534
217
|
)
|
218
|
+
return f"as an argument{param_text} of function {self.func_name!r}"
|