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
@@ -0,0 +1,263 @@
|
|
1
|
+
import ast
|
2
|
+
from abc import abstractmethod
|
3
|
+
from collections import defaultdict
|
4
|
+
from collections.abc import Sequence
|
5
|
+
from contextlib import nullcontext
|
6
|
+
from functools import singledispatchmethod
|
7
|
+
from typing import Any, Optional, cast
|
8
|
+
|
9
|
+
import sympy
|
10
|
+
from pydantic import ValidationError
|
11
|
+
|
12
|
+
from classiq.interface.exceptions import (
|
13
|
+
ClassiqError,
|
14
|
+
ClassiqExpansionError,
|
15
|
+
ClassiqInternalExpansionError,
|
16
|
+
)
|
17
|
+
from classiq.interface.generator.constant import Constant
|
18
|
+
from classiq.interface.generator.expressions.expression import Expression
|
19
|
+
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
20
|
+
from classiq.interface.model.handle_binding import (
|
21
|
+
FieldHandleBinding,
|
22
|
+
HandleBinding,
|
23
|
+
SlicedHandleBinding,
|
24
|
+
SubscriptHandleBinding,
|
25
|
+
)
|
26
|
+
from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model
|
27
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
28
|
+
from classiq.interface.model.quantum_function_declaration import (
|
29
|
+
QuantumFunctionDeclaration,
|
30
|
+
)
|
31
|
+
from classiq.interface.model.quantum_lambda_function import (
|
32
|
+
OperandIdentifier,
|
33
|
+
QuantumLambdaFunction,
|
34
|
+
)
|
35
|
+
from classiq.interface.model.quantum_statement import QuantumStatement
|
36
|
+
|
37
|
+
from classiq.model_expansions.closure import (
|
38
|
+
Closure,
|
39
|
+
FunctionClosure,
|
40
|
+
)
|
41
|
+
from classiq.model_expansions.debug_flag import debug_mode
|
42
|
+
from classiq.model_expansions.evaluators.classical_expression import (
|
43
|
+
evaluate_classical_expression,
|
44
|
+
)
|
45
|
+
from classiq.model_expansions.expression_renamer import ExpressionRenamer
|
46
|
+
from classiq.model_expansions.function_builder import (
|
47
|
+
FunctionContext,
|
48
|
+
OperationBuilder,
|
49
|
+
OperationContext,
|
50
|
+
)
|
51
|
+
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
52
|
+
from classiq.model_expansions.scope_initialization import (
|
53
|
+
add_constants_to_scope,
|
54
|
+
add_entry_point_params_to_scope,
|
55
|
+
get_main_renamer,
|
56
|
+
init_builtin_types,
|
57
|
+
init_top_level_scope,
|
58
|
+
)
|
59
|
+
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
60
|
+
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
61
|
+
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
62
|
+
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
63
|
+
from classiq.qmod.model_state_container import QMODULE
|
64
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
65
|
+
|
66
|
+
|
67
|
+
class BaseInterpreter:
|
68
|
+
def __init__(self, model: Model) -> None:
|
69
|
+
self._model = model
|
70
|
+
self._top_level_scope = Scope()
|
71
|
+
self._counted_name_allocator = CountedNameAllocator()
|
72
|
+
self._builder = OperationBuilder(
|
73
|
+
self._top_level_scope, self._counted_name_allocator
|
74
|
+
)
|
75
|
+
self._expanded_functions: dict[str, NativeFunctionDefinition] = {}
|
76
|
+
|
77
|
+
init_builtin_types()
|
78
|
+
init_top_level_scope(model, self._top_level_scope)
|
79
|
+
self._functions_compilation_metadata: dict[str, CompilationMetadata] = dict(
|
80
|
+
self._model.functions_compilation_metadata
|
81
|
+
)
|
82
|
+
self._expanded_functions_compilation_metadata: dict[
|
83
|
+
str, CompilationMetadata
|
84
|
+
] = defaultdict(CompilationMetadata)
|
85
|
+
self._counted_name_allocator = CountedNameAllocator()
|
86
|
+
self._error_manager: ErrorManager = ErrorManager()
|
87
|
+
|
88
|
+
def get_main_renamer(self) -> Optional[ExpressionRenamer]:
|
89
|
+
return get_main_renamer(self._get_function_declarations())
|
90
|
+
|
91
|
+
def _expand_main_func(self) -> None:
|
92
|
+
main_closure = self._get_main_closure(
|
93
|
+
self._top_level_scope[MAIN_FUNCTION_NAME].value
|
94
|
+
)
|
95
|
+
add_entry_point_params_to_scope(
|
96
|
+
main_closure.positional_arg_declarations, main_closure
|
97
|
+
)
|
98
|
+
context = self._expand_operation(main_closure)
|
99
|
+
self._expanded_functions[main_closure.closure_id] = (
|
100
|
+
self._builder.create_definition(cast(FunctionContext, context))
|
101
|
+
)
|
102
|
+
|
103
|
+
def _get_main_closure(self, main_func: FunctionClosure) -> FunctionClosure:
|
104
|
+
return FunctionClosure.create(
|
105
|
+
name=main_func.name,
|
106
|
+
positional_arg_declarations=main_func.positional_arg_declarations,
|
107
|
+
scope=Scope(parent=self._top_level_scope),
|
108
|
+
expr_renamer=self.get_main_renamer(),
|
109
|
+
_depth=0,
|
110
|
+
body=main_func.body,
|
111
|
+
)
|
112
|
+
|
113
|
+
def expand(self) -> Model:
|
114
|
+
try:
|
115
|
+
with self._error_manager.call("main"):
|
116
|
+
self._expand_main_func()
|
117
|
+
except Exception as e:
|
118
|
+
if isinstance(e, ClassiqInternalExpansionError) or debug_mode.get():
|
119
|
+
raise e
|
120
|
+
if not isinstance(e, (ClassiqError, ValidationError)):
|
121
|
+
raise ClassiqInternalExpansionError(str(e)) from None
|
122
|
+
prefix = ""
|
123
|
+
if not isinstance(e, ClassiqExpansionError):
|
124
|
+
prefix = f"{type(e).__name__}: "
|
125
|
+
self._error_manager.add_error(f"{prefix}{e}")
|
126
|
+
finally:
|
127
|
+
self._error_manager.report_errors(ClassiqExpansionError)
|
128
|
+
|
129
|
+
return Model(
|
130
|
+
constraints=self._model.constraints,
|
131
|
+
preferences=self._model.preferences,
|
132
|
+
classical_execution_code=self._model.classical_execution_code,
|
133
|
+
execution_preferences=self._model.execution_preferences,
|
134
|
+
functions=list(self._expanded_functions.values()),
|
135
|
+
constants=self._model.constants,
|
136
|
+
enums=[
|
137
|
+
enum_decl
|
138
|
+
for name, enum_decl in QMODULE.enum_decls.items()
|
139
|
+
if name not in BUILTIN_ENUM_DECLARATIONS
|
140
|
+
],
|
141
|
+
types=[
|
142
|
+
struct_decl
|
143
|
+
for name, struct_decl in QMODULE.type_decls.items()
|
144
|
+
if name not in BUILTIN_STRUCT_DECLARATIONS
|
145
|
+
],
|
146
|
+
qstructs=list(QMODULE.qstruct_decls.values()),
|
147
|
+
debug_info=self._model.debug_info,
|
148
|
+
functions_compilation_metadata=self._expanded_functions_compilation_metadata,
|
149
|
+
)
|
150
|
+
|
151
|
+
@singledispatchmethod
|
152
|
+
def evaluate(self, expression: Any) -> Evaluated:
|
153
|
+
raise NotImplementedError(f"Cannot evaluate {expression!r}")
|
154
|
+
|
155
|
+
@evaluate.register
|
156
|
+
def evaluate_classical_expression(self, expression: Expression) -> Evaluated:
|
157
|
+
expr = evaluate_classical_expression(expression, self._builder.current_scope)
|
158
|
+
if not isinstance(expr.value, sympy.Basic):
|
159
|
+
return expr
|
160
|
+
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
161
|
+
vrc.visit(ast.parse(str(expr.value)))
|
162
|
+
for handle in vrc.var_handles:
|
163
|
+
if handle.name in self._builder.current_scope and isinstance(
|
164
|
+
self._builder.current_scope[handle.name], QuantumSymbol
|
165
|
+
):
|
166
|
+
self.evaluate(handle)
|
167
|
+
return expr
|
168
|
+
|
169
|
+
@evaluate.register
|
170
|
+
def evaluate_identifier(self, identifier: str) -> Evaluated:
|
171
|
+
return self._builder.current_scope[identifier]
|
172
|
+
|
173
|
+
@evaluate.register
|
174
|
+
def _evaluate_lambda(self, function: QuantumLambdaFunction) -> Evaluated:
|
175
|
+
return self.evaluate_lambda(function)
|
176
|
+
|
177
|
+
def evaluate_lambda(self, function: QuantumLambdaFunction) -> Evaluated:
|
178
|
+
raise NotImplementedError
|
179
|
+
|
180
|
+
@evaluate.register
|
181
|
+
def evaluate_handle_binding(self, handle_binding: HandleBinding) -> Evaluated:
|
182
|
+
return self.evaluate(handle_binding.name)
|
183
|
+
|
184
|
+
@evaluate.register
|
185
|
+
def evaluate_sliced_handle_binding(
|
186
|
+
self, sliced_handle_binding: SlicedHandleBinding
|
187
|
+
) -> Evaluated:
|
188
|
+
quantum_variable = self.evaluate(sliced_handle_binding.base_handle).as_type(
|
189
|
+
QuantumSymbol
|
190
|
+
)
|
191
|
+
start = self.evaluate(sliced_handle_binding.start).as_type(int)
|
192
|
+
end = self.evaluate(sliced_handle_binding.end).as_type(int)
|
193
|
+
return Evaluated(value=quantum_variable[start:end])
|
194
|
+
|
195
|
+
@evaluate.register
|
196
|
+
def evaluate_list(self, value: list) -> Evaluated:
|
197
|
+
return Evaluated(value=[self.evaluate(arg).value for arg in value])
|
198
|
+
|
199
|
+
@evaluate.register
|
200
|
+
def evaluate_subscript_handle(self, subscript: SubscriptHandleBinding) -> Evaluated:
|
201
|
+
base_value = self.evaluate(subscript.base_handle)
|
202
|
+
index_value = self.evaluate(subscript.index).as_type(int)
|
203
|
+
return Evaluated(value=base_value.value[index_value])
|
204
|
+
|
205
|
+
@evaluate.register
|
206
|
+
def evaluate_subscript_operand(self, subscript: OperandIdentifier) -> Evaluated:
|
207
|
+
base_value = self.evaluate(subscript.name)
|
208
|
+
index_value = self.evaluate(subscript.index).as_type(int)
|
209
|
+
return Evaluated(value=base_value.value[index_value])
|
210
|
+
|
211
|
+
@evaluate.register
|
212
|
+
def evaluate_field_access(self, field_access: FieldHandleBinding) -> Evaluated:
|
213
|
+
base_value = self.evaluate(field_access.base_handle)
|
214
|
+
return Evaluated(value=base_value.value.fields[field_access.field])
|
215
|
+
|
216
|
+
@abstractmethod
|
217
|
+
def emit(self, statement: QuantumStatement) -> None:
|
218
|
+
pass
|
219
|
+
|
220
|
+
def _expand_block(self, block: Sequence[QuantumStatement], block_name: str) -> None:
|
221
|
+
with self._builder.block_context(block_name):
|
222
|
+
for statement in block:
|
223
|
+
self.emit_statement(statement)
|
224
|
+
|
225
|
+
def emit_statement(self, statement: QuantumStatement) -> None:
|
226
|
+
source_ref = statement.source_ref
|
227
|
+
error_context = (
|
228
|
+
self._error_manager.node_context(statement)
|
229
|
+
if source_ref is not None
|
230
|
+
else nullcontext()
|
231
|
+
)
|
232
|
+
with error_context, self._builder.source_ref_context(source_ref):
|
233
|
+
self.emit(statement)
|
234
|
+
|
235
|
+
def _expand_operation(self, operation: Closure) -> OperationContext:
|
236
|
+
with self._builder.operation_context(operation) as context:
|
237
|
+
if isinstance(operation, FunctionClosure) and (
|
238
|
+
(func_def := self._expanded_functions.get(operation.closure_id))
|
239
|
+
is not None
|
240
|
+
):
|
241
|
+
captured_vars = self._top_level_scope[func_def.name].value.captured_vars
|
242
|
+
operation.captured_vars.update(captured_vars)
|
243
|
+
else:
|
244
|
+
self._expand_body(operation)
|
245
|
+
|
246
|
+
return context
|
247
|
+
|
248
|
+
def _expand_body(self, operation: Closure) -> None:
|
249
|
+
for block, block_body in operation.blocks.items():
|
250
|
+
self._expand_block(block_body, block)
|
251
|
+
|
252
|
+
def _get_function_declarations(self) -> Sequence[QuantumFunctionDeclaration]:
|
253
|
+
return [
|
254
|
+
QuantumFunctionDeclaration(
|
255
|
+
name=func_closure.name,
|
256
|
+
positional_arg_declarations=func_closure.positional_arg_declarations,
|
257
|
+
)
|
258
|
+
for func in self._top_level_scope.values()
|
259
|
+
if isinstance(func_closure := func.value, FunctionClosure)
|
260
|
+
]
|
261
|
+
|
262
|
+
def add_constant(self, constant: Constant) -> None:
|
263
|
+
add_constants_to_scope([constant], self._top_level_scope)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
2
|
+
|
3
|
+
from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
|
4
|
+
from classiq.model_expansions.interpreters.generative_interpreter import (
|
5
|
+
GenerativeInterpreter,
|
6
|
+
)
|
7
|
+
from classiq.model_expansions.quantum_operations.quantum_function_call import (
|
8
|
+
DeclarativeQuantumFunctionCallEmitter,
|
9
|
+
)
|
10
|
+
from classiq.model_expansions.scope import Scope
|
11
|
+
|
12
|
+
|
13
|
+
class FrontendGenerativeInterpreter(GenerativeInterpreter):
|
14
|
+
def emit_quantum_function_call(self, call: QuantumFunctionCall) -> None:
|
15
|
+
DeclarativeQuantumFunctionCallEmitter(self).emit(call)
|
16
|
+
|
17
|
+
def _get_main_closure(self, main_func: FunctionClosure) -> FunctionClosure:
|
18
|
+
if isinstance(main_func, GenerativeFunctionClosure):
|
19
|
+
return GenerativeFunctionClosure.create(
|
20
|
+
name=main_func.name,
|
21
|
+
positional_arg_declarations=main_func.positional_arg_declarations,
|
22
|
+
scope=Scope(parent=self._top_level_scope),
|
23
|
+
expr_renamer=self.get_main_renamer(),
|
24
|
+
_depth=0,
|
25
|
+
generative_blocks={"body": main_func.generative_blocks["body"]},
|
26
|
+
)
|
27
|
+
|
28
|
+
return super()._get_main_closure(main_func)
|
@@ -0,0 +1,249 @@
|
|
1
|
+
from functools import singledispatchmethod
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
from numpy.random import permutation
|
6
|
+
|
7
|
+
from classiq.interface.generator.expressions.expression import Expression
|
8
|
+
from classiq.interface.generator.functions.builtins.internal_operators import (
|
9
|
+
CONTROL_OPERATOR_NAME,
|
10
|
+
INVERT_OPERATOR_NAME,
|
11
|
+
WITHIN_APPLY_NAME,
|
12
|
+
)
|
13
|
+
from classiq.interface.model.allocate import Allocate
|
14
|
+
from classiq.interface.model.bind_operation import BindOperation
|
15
|
+
from classiq.interface.model.classical_if import ClassicalIf
|
16
|
+
from classiq.interface.model.control import Control
|
17
|
+
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
18
|
+
from classiq.interface.model.invert import Invert
|
19
|
+
from classiq.interface.model.model import Model
|
20
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
21
|
+
from classiq.interface.model.phase_operation import PhaseOperation
|
22
|
+
from classiq.interface.model.power import Power
|
23
|
+
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
24
|
+
QuantumAssignmentOperation,
|
25
|
+
)
|
26
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
27
|
+
from classiq.interface.model.quantum_function_declaration import (
|
28
|
+
NamedParamsQuantumFunctionDeclaration,
|
29
|
+
)
|
30
|
+
from classiq.interface.model.quantum_lambda_function import (
|
31
|
+
OperandIdentifier,
|
32
|
+
QuantumLambdaFunction,
|
33
|
+
)
|
34
|
+
from classiq.interface.model.quantum_statement import QuantumStatement
|
35
|
+
from classiq.interface.model.repeat import Repeat
|
36
|
+
from classiq.interface.model.variable_declaration_statement import (
|
37
|
+
VariableDeclarationStatement,
|
38
|
+
)
|
39
|
+
from classiq.interface.model.within_apply_operation import WithinApply
|
40
|
+
|
41
|
+
from classiq.model_expansions.closure import (
|
42
|
+
Closure,
|
43
|
+
FunctionClosure,
|
44
|
+
GenerativeClosure,
|
45
|
+
GenerativeFunctionClosure,
|
46
|
+
)
|
47
|
+
from classiq.model_expansions.generative_functions import emit_generative_statements
|
48
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
49
|
+
from classiq.model_expansions.quantum_operations import (
|
50
|
+
BindEmitter,
|
51
|
+
ClassicalIfEmitter,
|
52
|
+
QuantumFunctionCallEmitter,
|
53
|
+
RepeatEmitter,
|
54
|
+
VariableDeclarationStatementEmitter,
|
55
|
+
)
|
56
|
+
from classiq.model_expansions.quantum_operations.shallow_emitter import ShallowEmitter
|
57
|
+
from classiq.model_expansions.scope import Evaluated, Scope
|
58
|
+
from classiq.model_expansions.scope_initialization import (
|
59
|
+
add_functions_to_scope,
|
60
|
+
add_generative_functions_to_scope,
|
61
|
+
)
|
62
|
+
from classiq.qmod.builtins.functions import permute
|
63
|
+
from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
64
|
+
from classiq.qmod.quantum_function import GenerativeQFunc
|
65
|
+
|
66
|
+
|
67
|
+
class GenerativeInterpreter(BaseInterpreter):
|
68
|
+
def __init__(
|
69
|
+
self,
|
70
|
+
model: Model,
|
71
|
+
generative_functions: list[GenerativeQFunc],
|
72
|
+
) -> None:
|
73
|
+
super().__init__(model)
|
74
|
+
add_generative_functions_to_scope(generative_functions, self._top_level_scope)
|
75
|
+
|
76
|
+
def evaluate_lambda(self, function: QuantumLambdaFunction) -> Evaluated:
|
77
|
+
renamed_params = [
|
78
|
+
param.rename(function.pos_rename_params[idx])
|
79
|
+
for idx, param in enumerate(function.func_decl.positional_arg_declarations)
|
80
|
+
]
|
81
|
+
func_decl = NamedParamsQuantumFunctionDeclaration(
|
82
|
+
name=self._counted_name_allocator.allocate(
|
83
|
+
function.func_decl.name or "<lambda>"
|
84
|
+
),
|
85
|
+
positional_arg_declarations=renamed_params,
|
86
|
+
)
|
87
|
+
|
88
|
+
closure_class: type[FunctionClosure]
|
89
|
+
extra_args: dict[str, Any]
|
90
|
+
if function.is_generative():
|
91
|
+
closure_class = GenerativeFunctionClosure
|
92
|
+
extra_args = {
|
93
|
+
"generative_blocks": {
|
94
|
+
"body": GenerativeQFunc(function.py_callable, func_decl),
|
95
|
+
}
|
96
|
+
}
|
97
|
+
else:
|
98
|
+
closure_class = FunctionClosure
|
99
|
+
extra_args = {}
|
100
|
+
|
101
|
+
return Evaluated(
|
102
|
+
value=closure_class.create(
|
103
|
+
name=func_decl.name,
|
104
|
+
positional_arg_declarations=func_decl.positional_arg_declarations,
|
105
|
+
body=function.body,
|
106
|
+
scope=Scope(parent=self._builder.current_scope),
|
107
|
+
is_lambda=True,
|
108
|
+
**extra_args,
|
109
|
+
),
|
110
|
+
defining_function=self._builder.current_function,
|
111
|
+
)
|
112
|
+
|
113
|
+
@singledispatchmethod
|
114
|
+
def emit(self, statement: QuantumStatement) -> None: # type:ignore[override]
|
115
|
+
raise NotImplementedError(f"Cannot emit {statement!r}")
|
116
|
+
|
117
|
+
@emit.register
|
118
|
+
def _emit_quantum_function_call(self, call: QuantumFunctionCall) -> None:
|
119
|
+
self.emit_quantum_function_call(call)
|
120
|
+
|
121
|
+
def emit_quantum_function_call(self, call: QuantumFunctionCall) -> None:
|
122
|
+
QuantumFunctionCallEmitter(self).emit(call)
|
123
|
+
|
124
|
+
@emit.register
|
125
|
+
def emit_allocate(self, allocate: Allocate) -> None:
|
126
|
+
ShallowEmitter(self, "allocate", components=["size", "target"]).emit(allocate)
|
127
|
+
|
128
|
+
@emit.register
|
129
|
+
def emit_bind(self, bind: BindOperation) -> None:
|
130
|
+
BindEmitter(self).emit(bind)
|
131
|
+
|
132
|
+
@emit.register
|
133
|
+
def emit_quantum_assignment_operation(self, op: QuantumAssignmentOperation) -> None:
|
134
|
+
ShallowEmitter(
|
135
|
+
self, "assignment_operation", components=["expression", "result_var"]
|
136
|
+
).emit(op)
|
137
|
+
|
138
|
+
@emit.register
|
139
|
+
def emit_inplace_binary_operation(self, op: InplaceBinaryOperation) -> None:
|
140
|
+
ShallowEmitter(
|
141
|
+
self, "inplace_binary_operation", components=["target", "value"]
|
142
|
+
).emit(op)
|
143
|
+
|
144
|
+
@emit.register
|
145
|
+
def emit_variable_declaration(
|
146
|
+
self, variable_declaration: VariableDeclarationStatement
|
147
|
+
) -> None:
|
148
|
+
VariableDeclarationStatementEmitter(self).emit(variable_declaration)
|
149
|
+
|
150
|
+
@emit.register
|
151
|
+
def emit_classical_if(self, classical_if: ClassicalIf) -> None:
|
152
|
+
ClassicalIfEmitter(self).emit(classical_if)
|
153
|
+
|
154
|
+
@emit.register
|
155
|
+
def emit_within_apply(self, within_apply: WithinApply) -> None:
|
156
|
+
ShallowEmitter(
|
157
|
+
self,
|
158
|
+
WITHIN_APPLY_NAME,
|
159
|
+
components=["within", "apply", "compute", "action"],
|
160
|
+
).emit(within_apply)
|
161
|
+
|
162
|
+
@emit.register
|
163
|
+
def emit_invert(self, invert: Invert) -> None:
|
164
|
+
ShallowEmitter(self, INVERT_OPERATOR_NAME, components=["body"]).emit(invert)
|
165
|
+
|
166
|
+
@emit.register
|
167
|
+
def emit_repeat(self, repeat: Repeat) -> None:
|
168
|
+
RepeatEmitter(self).emit(repeat)
|
169
|
+
|
170
|
+
@emit.register
|
171
|
+
def emit_control(self, control: Control) -> None:
|
172
|
+
ShallowEmitter(
|
173
|
+
self,
|
174
|
+
CONTROL_OPERATOR_NAME,
|
175
|
+
components=["expression", "body", "else_block"],
|
176
|
+
).emit(control)
|
177
|
+
|
178
|
+
@emit.register
|
179
|
+
def emit_power(self, power: Power) -> None:
|
180
|
+
ShallowEmitter(self, CONTROL_OPERATOR_NAME, components=["power", "body"]).emit(
|
181
|
+
power
|
182
|
+
)
|
183
|
+
|
184
|
+
@emit.register
|
185
|
+
def emit_phase(self, phase: PhaseOperation) -> None:
|
186
|
+
ShallowEmitter(self, "phase", components=["expression", "theta"]).emit(phase)
|
187
|
+
|
188
|
+
def _expand_body(self, operation: Closure) -> None:
|
189
|
+
if isinstance(operation, FunctionClosure) and operation.name == "permute":
|
190
|
+
# special expansion since permute is generative
|
191
|
+
self._expand_permute()
|
192
|
+
elif isinstance(operation, GenerativeClosure):
|
193
|
+
args = [
|
194
|
+
self.evaluate(param.name)
|
195
|
+
for param in operation.positional_arg_declarations
|
196
|
+
]
|
197
|
+
emit_generative_statements(self, operation, args)
|
198
|
+
else:
|
199
|
+
super()._expand_body(operation)
|
200
|
+
|
201
|
+
def _expand_permute(self) -> None:
|
202
|
+
functions = self.evaluate("functions").as_type(list)
|
203
|
+
functions_permutation = permutation(np.array(range(len(functions))))
|
204
|
+
calls: list[QuantumFunctionCall] = []
|
205
|
+
for function_index in functions_permutation:
|
206
|
+
permute_call = QuantumFunctionCall(
|
207
|
+
function=OperandIdentifier(
|
208
|
+
name="functions", index=Expression(expr=f"{function_index}")
|
209
|
+
)
|
210
|
+
)
|
211
|
+
permute_call.set_func_decl(permute.func_decl)
|
212
|
+
calls.append(permute_call)
|
213
|
+
self._expand_block(calls, "body")
|
214
|
+
|
215
|
+
def update_generative_functions(
|
216
|
+
self, generative_functions: dict[str, GenerativeQFunc]
|
217
|
+
) -> None:
|
218
|
+
add_generative_functions_to_scope(
|
219
|
+
list(generative_functions.values()), self._top_level_scope
|
220
|
+
)
|
221
|
+
for name, gen_func in generative_functions.items():
|
222
|
+
if gen_func.compilation_metadata is not None:
|
223
|
+
self._functions_compilation_metadata[name] = (
|
224
|
+
gen_func.compilation_metadata
|
225
|
+
)
|
226
|
+
|
227
|
+
def update_declarative_functions(
|
228
|
+
self,
|
229
|
+
functions: dict[str, NativeFunctionDefinition],
|
230
|
+
qmodule: ModelStateContainer,
|
231
|
+
) -> None:
|
232
|
+
add_functions_to_scope(list(functions.values()), self._top_level_scope)
|
233
|
+
for dec_func_name in functions:
|
234
|
+
if dec_func_name in qmodule.functions_compilation_metadata:
|
235
|
+
self._functions_compilation_metadata[dec_func_name] = (
|
236
|
+
qmodule.functions_compilation_metadata[dec_func_name]
|
237
|
+
)
|
238
|
+
|
239
|
+
def add_purely_declarative_function(self, function: FunctionClosure) -> None:
|
240
|
+
functions_to_add = [function.name] + QMODULE.function_dependencies[
|
241
|
+
function.name
|
242
|
+
]
|
243
|
+
for func in functions_to_add:
|
244
|
+
if func not in self._expanded_functions and func in QMODULE.native_defs:
|
245
|
+
self._expanded_functions[func] = QMODULE.native_defs[func]
|
246
|
+
if func in QMODULE.functions_compilation_metadata:
|
247
|
+
self._expanded_functions_compilation_metadata[func] = (
|
248
|
+
QMODULE.functions_compilation_metadata[func]
|
249
|
+
)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
|
4
|
+
from classiq.interface.generator.functions.classical_type import QmodPyObject
|
5
|
+
|
6
|
+
|
7
|
+
class HandleTable:
|
8
|
+
_handle_map: dict[HandleIdentifier, QmodPyObject] = {}
|
9
|
+
|
10
|
+
@classmethod
|
11
|
+
def get_handle_object(cls, hid: HandleIdentifier) -> Optional[QmodPyObject]:
|
12
|
+
return cls._handle_map.get(hid)
|
13
|
+
|
14
|
+
@classmethod
|
15
|
+
def set_handle_object(cls, qmod_object: QmodPyObject) -> HandleIdentifier:
|
16
|
+
hid = HandleIdentifier(id(qmod_object))
|
17
|
+
cls._handle_map[hid] = qmod_object
|
18
|
+
return hid
|
@@ -0,0 +1,9 @@
|
|
1
|
+
from classiq.model_expansions.quantum_operations.bind import BindEmitter
|
2
|
+
from classiq.model_expansions.quantum_operations.classicalif import ClassicalIfEmitter
|
3
|
+
from classiq.model_expansions.quantum_operations.quantum_function_call import (
|
4
|
+
QuantumFunctionCallEmitter,
|
5
|
+
)
|
6
|
+
from classiq.model_expansions.quantum_operations.repeat import RepeatEmitter
|
7
|
+
from classiq.model_expansions.quantum_operations.variable_decleration import (
|
8
|
+
VariableDeclarationStatementEmitter,
|
9
|
+
)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
from classiq.interface.exceptions import ClassiqExpansionError
|
2
|
+
from classiq.interface.model.bind_operation import BindOperation
|
3
|
+
|
4
|
+
from classiq.model_expansions.evaluators.parameter_types import (
|
5
|
+
evaluate_types_in_quantum_symbols,
|
6
|
+
)
|
7
|
+
from classiq.model_expansions.evaluators.quantum_type_utils import (
|
8
|
+
set_size,
|
9
|
+
validate_bind_targets,
|
10
|
+
)
|
11
|
+
from classiq.model_expansions.quantum_operations.emitter import Emitter
|
12
|
+
from classiq.model_expansions.scope import QuantumSymbol
|
13
|
+
|
14
|
+
|
15
|
+
class BindEmitter(Emitter[BindOperation]):
|
16
|
+
def emit(self, bind: BindOperation, /) -> None:
|
17
|
+
inputs: list[QuantumSymbol] = [
|
18
|
+
self._interpreter.evaluate(arg).as_type(QuantumSymbol)
|
19
|
+
for arg in bind.in_handles
|
20
|
+
]
|
21
|
+
outputs: list[QuantumSymbol] = [
|
22
|
+
self._interpreter.evaluate(arg).as_type(QuantumSymbol)
|
23
|
+
for arg in bind.out_handles
|
24
|
+
]
|
25
|
+
inputs = evaluate_types_in_quantum_symbols(inputs, self._current_scope)
|
26
|
+
outputs = evaluate_types_in_quantum_symbols(outputs, self._current_scope)
|
27
|
+
validate_bind_targets(bind, self._current_scope)
|
28
|
+
unsized_outputs = [
|
29
|
+
output for output in outputs if not output.quantum_type.has_size_in_bits
|
30
|
+
]
|
31
|
+
|
32
|
+
if len(unsized_outputs) > 1:
|
33
|
+
raise ClassiqExpansionError(
|
34
|
+
f"Cannot perform the split operation {bind.in_handles[0].name} -> {{{', '.join(out_handle.name for out_handle in bind.out_handles)}}}:\n"
|
35
|
+
f"Quantum variables {', '.join(str(out_handle.handle) for out_handle in unsized_outputs)} are used as bind outputs, but their size cannot be inferred."
|
36
|
+
)
|
37
|
+
|
38
|
+
input_size = sum(input.quantum_type.size_in_bits for input in inputs)
|
39
|
+
output_size = sum(
|
40
|
+
output.quantum_type.size_in_bits
|
41
|
+
for output in outputs
|
42
|
+
if output.quantum_type.has_size_in_bits
|
43
|
+
)
|
44
|
+
|
45
|
+
if len(unsized_outputs) == 1:
|
46
|
+
set_size(
|
47
|
+
unsized_outputs[0].quantum_type,
|
48
|
+
input_size - output_size,
|
49
|
+
str(unsized_outputs[0].handle),
|
50
|
+
)
|
51
|
+
|
52
|
+
else:
|
53
|
+
if input_size != output_size:
|
54
|
+
raise ClassiqExpansionError(
|
55
|
+
f"The total size for the input and output of the bind operation must be the same. The in size is {input_size} and the out size is {output_size}"
|
56
|
+
)
|
57
|
+
|
58
|
+
self.emit_statement(
|
59
|
+
BindOperation(in_handles=bind.in_handles, out_handles=bind.out_handles)
|
60
|
+
)
|