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
@@ -0,0 +1,87 @@
|
|
1
|
+
from itertools import chain
|
2
|
+
from typing import TYPE_CHECKING, Generic
|
3
|
+
|
4
|
+
from classiq.interface.generator.functions.port_declaration import (
|
5
|
+
PortDeclarationDirection,
|
6
|
+
)
|
7
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
8
|
+
|
9
|
+
from classiq.model_expansions.closure import FunctionClosure, GenerativeClosure
|
10
|
+
from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
|
11
|
+
from classiq.model_expansions.quantum_operations.emitter import QuantumStatementT
|
12
|
+
from classiq.model_expansions.scope import Evaluated
|
13
|
+
from classiq.qmod.model_state_container import QMODULE
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from classiq.model_expansions.interpreters.generative_interpreter import (
|
17
|
+
GenerativeInterpreter,
|
18
|
+
)
|
19
|
+
|
20
|
+
|
21
|
+
class DeclarativeCallEmitter(
|
22
|
+
Generic[QuantumStatementT], CallEmitter[QuantumStatementT]
|
23
|
+
):
|
24
|
+
_interpreter: "GenerativeInterpreter"
|
25
|
+
|
26
|
+
def __init__(self, interpreter: "GenerativeInterpreter") -> None:
|
27
|
+
super().__init__(interpreter)
|
28
|
+
|
29
|
+
def should_expand_function(
|
30
|
+
self, function: FunctionClosure, args: list[Evaluated]
|
31
|
+
) -> bool:
|
32
|
+
if not super().should_expand_function(function, args):
|
33
|
+
return False
|
34
|
+
|
35
|
+
if self._is_function_purely_declarative(
|
36
|
+
function
|
37
|
+
) and self._are_args_purely_declarative(args):
|
38
|
+
self._interpreter.add_purely_declarative_function(function)
|
39
|
+
return False
|
40
|
+
|
41
|
+
return True
|
42
|
+
|
43
|
+
def _is_function_purely_declarative(self, function: FunctionClosure) -> bool:
|
44
|
+
if function.name not in QMODULE.native_defs:
|
45
|
+
return False
|
46
|
+
|
47
|
+
if isinstance(function, GenerativeClosure):
|
48
|
+
return False
|
49
|
+
|
50
|
+
if any(
|
51
|
+
not param.quantum_type.is_instantiated
|
52
|
+
for param in function.positional_arg_declarations
|
53
|
+
if isinstance(param, PortDeclaration)
|
54
|
+
and param.direction == PortDeclarationDirection.Output
|
55
|
+
):
|
56
|
+
return False
|
57
|
+
|
58
|
+
dependencies = QMODULE.function_dependencies[function.name]
|
59
|
+
return self._are_identifiers_purely_declarative(dependencies)
|
60
|
+
|
61
|
+
def _are_args_purely_declarative(self, args: list[Evaluated]) -> bool:
|
62
|
+
values = [arg.value for arg in args]
|
63
|
+
function_inputs: list[FunctionClosure] = list(
|
64
|
+
chain.from_iterable(
|
65
|
+
(
|
66
|
+
[arg]
|
67
|
+
if isinstance(arg, FunctionClosure)
|
68
|
+
else (
|
69
|
+
arg
|
70
|
+
if isinstance(arg, list)
|
71
|
+
and any(isinstance(item, FunctionClosure) for item in arg)
|
72
|
+
else []
|
73
|
+
)
|
74
|
+
)
|
75
|
+
for arg in values
|
76
|
+
)
|
77
|
+
)
|
78
|
+
if any(func.is_lambda for func in function_inputs):
|
79
|
+
return False
|
80
|
+
dependencies = [func.name for func in function_inputs if not func.is_lambda]
|
81
|
+
return self._are_identifiers_purely_declarative(dependencies)
|
82
|
+
|
83
|
+
def _are_identifiers_purely_declarative(self, dependencies: list[str]) -> bool:
|
84
|
+
return not any(
|
85
|
+
isinstance(self._current_scope[dep].value, GenerativeClosure)
|
86
|
+
for dep in dependencies
|
87
|
+
)
|
@@ -0,0 +1,181 @@
|
|
1
|
+
import ast
|
2
|
+
from abc import abstractmethod
|
3
|
+
from typing import (
|
4
|
+
TYPE_CHECKING,
|
5
|
+
Generic,
|
6
|
+
Optional,
|
7
|
+
TypeVar,
|
8
|
+
Union,
|
9
|
+
)
|
10
|
+
|
11
|
+
import sympy
|
12
|
+
|
13
|
+
from classiq.interface.debug_info.debug_info import DebugInfoCollection
|
14
|
+
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
15
|
+
from classiq.interface.generator.expressions.evaluated_expression import (
|
16
|
+
EvaluatedExpression,
|
17
|
+
)
|
18
|
+
from classiq.interface.generator.expressions.expression import Expression
|
19
|
+
from classiq.interface.generator.functions.port_declaration import (
|
20
|
+
PortDeclarationDirection,
|
21
|
+
)
|
22
|
+
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
23
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
24
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
25
|
+
from classiq.interface.model.quantum_function_declaration import (
|
26
|
+
NamedParamsQuantumFunctionDeclaration,
|
27
|
+
)
|
28
|
+
from classiq.interface.model.quantum_statement import QuantumOperation, QuantumStatement
|
29
|
+
|
30
|
+
from classiq.model_expansions.closure import Closure, GenerativeClosure
|
31
|
+
from classiq.model_expansions.function_builder import (
|
32
|
+
OperationBuilder,
|
33
|
+
OperationContext,
|
34
|
+
)
|
35
|
+
from classiq.model_expansions.scope import QuantumSymbol, Scope
|
36
|
+
from classiq.model_expansions.sympy_conversion.sympy_to_python import (
|
37
|
+
translate_sympy_quantum_expression,
|
38
|
+
)
|
39
|
+
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
40
|
+
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
41
|
+
from classiq.qmod.quantum_function import GenerativeQFunc
|
42
|
+
|
43
|
+
if TYPE_CHECKING:
|
44
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
45
|
+
|
46
|
+
QuantumStatementT = TypeVar("QuantumStatementT", bound=QuantumStatement)
|
47
|
+
|
48
|
+
|
49
|
+
class Emitter(Generic[QuantumStatementT]):
|
50
|
+
def __init__(self, interpreter: "BaseInterpreter") -> None:
|
51
|
+
self._interpreter = interpreter
|
52
|
+
|
53
|
+
self._machine_precision = self._interpreter._model.preferences.machine_precision
|
54
|
+
self._expanded_functions_compilation_metadata = (
|
55
|
+
self._interpreter._expanded_functions_compilation_metadata
|
56
|
+
)
|
57
|
+
self._functions_compilation_metadata = (
|
58
|
+
self._interpreter._functions_compilation_metadata
|
59
|
+
)
|
60
|
+
|
61
|
+
@abstractmethod
|
62
|
+
def emit(self, statement: QuantumStatementT, /) -> None:
|
63
|
+
pass
|
64
|
+
|
65
|
+
def _expand_operation(self, closure: Closure) -> OperationContext:
|
66
|
+
return self._interpreter._expand_operation(closure)
|
67
|
+
|
68
|
+
@property
|
69
|
+
def _builder(self) -> OperationBuilder:
|
70
|
+
return self._interpreter._builder
|
71
|
+
|
72
|
+
@property
|
73
|
+
def _current_scope(self) -> Scope:
|
74
|
+
return self._builder.current_scope
|
75
|
+
|
76
|
+
@property
|
77
|
+
def _top_level_scope(self) -> Scope:
|
78
|
+
return self._interpreter._top_level_scope
|
79
|
+
|
80
|
+
@property
|
81
|
+
def _expanded_functions(self) -> dict[str, NativeFunctionDefinition]:
|
82
|
+
return self._interpreter._expanded_functions
|
83
|
+
|
84
|
+
@property
|
85
|
+
def _expanded_functions_by_name(self) -> dict[str, NativeFunctionDefinition]:
|
86
|
+
return nameables_to_dict(list(self._interpreter._expanded_functions.values()))
|
87
|
+
|
88
|
+
@property
|
89
|
+
def _counted_name_allocator(self) -> CountedNameAllocator:
|
90
|
+
return self._interpreter._counted_name_allocator
|
91
|
+
|
92
|
+
@property
|
93
|
+
def _debug_info(self) -> DebugInfoCollection:
|
94
|
+
return self._interpreter._model.debug_info
|
95
|
+
|
96
|
+
def _expand_generative_context(
|
97
|
+
self,
|
98
|
+
op: QuantumOperation,
|
99
|
+
context_name: str,
|
100
|
+
block_names: Union[None, str, list[str]] = None,
|
101
|
+
func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
|
102
|
+
) -> OperationContext:
|
103
|
+
if isinstance(block_names, str):
|
104
|
+
block_names = [block_names]
|
105
|
+
block_names = block_names or ["body"]
|
106
|
+
func_decl = func_decl or NamedParamsQuantumFunctionDeclaration(
|
107
|
+
name=context_name
|
108
|
+
)
|
109
|
+
gen_closure = GenerativeClosure(
|
110
|
+
name=func_decl.name,
|
111
|
+
scope=Scope(parent=self._interpreter._builder.current_scope),
|
112
|
+
blocks={},
|
113
|
+
generative_blocks={
|
114
|
+
block_name: GenerativeQFunc(
|
115
|
+
op.get_generative_block(block_name), func_decl
|
116
|
+
)
|
117
|
+
for block_name in block_names
|
118
|
+
},
|
119
|
+
)
|
120
|
+
context = self._interpreter._expand_operation(gen_closure)
|
121
|
+
op.clear_generative_blocks()
|
122
|
+
return context
|
123
|
+
|
124
|
+
def _evaluate_expression(
|
125
|
+
self, expression: Expression, preserve_bool_ops: bool = False
|
126
|
+
) -> Expression:
|
127
|
+
evaluated_expression = self._interpreter.evaluate(expression)
|
128
|
+
if isinstance(evaluated_expression.value, sympy.Basic):
|
129
|
+
new_expression = Expression(
|
130
|
+
expr=translate_sympy_quantum_expression(
|
131
|
+
evaluated_expression.value,
|
132
|
+
preserve_bool_ops=preserve_bool_ops,
|
133
|
+
)
|
134
|
+
)
|
135
|
+
else:
|
136
|
+
new_expression = Expression(expr=str(evaluated_expression.value))
|
137
|
+
new_expression._evaluated_expr = EvaluatedExpression(
|
138
|
+
value=evaluated_expression.value
|
139
|
+
)
|
140
|
+
return new_expression
|
141
|
+
|
142
|
+
def emit_statement(self, statement: QuantumStatement) -> None:
|
143
|
+
if isinstance(statement, QuantumOperation):
|
144
|
+
self._update_captured_vars(statement)
|
145
|
+
self._builder.emit_statement(statement)
|
146
|
+
|
147
|
+
def _update_captured_vars(self, op: QuantumOperation) -> None:
|
148
|
+
handles = (
|
149
|
+
[(handle, PortDeclarationDirection.Input) for handle in op.inputs]
|
150
|
+
+ [(handle, PortDeclarationDirection.Output) for handle in op.outputs]
|
151
|
+
+ [(handle, PortDeclarationDirection.Inout) for handle in op.inouts]
|
152
|
+
)
|
153
|
+
for handle, direction in handles:
|
154
|
+
self._capture_handle(handle, direction)
|
155
|
+
|
156
|
+
def _capture_handle(
|
157
|
+
self, handle: HandleBinding, direction: PortDeclarationDirection
|
158
|
+
) -> None:
|
159
|
+
if handle.name not in self._current_scope:
|
160
|
+
return
|
161
|
+
defining_function = self._current_scope[handle.name].defining_function
|
162
|
+
if defining_function is None:
|
163
|
+
raise ClassiqInternalExpansionError
|
164
|
+
symbol: QuantumSymbol = self._interpreter.evaluate(handle).value
|
165
|
+
self._builder.current_block.captured_vars.capture_handle(
|
166
|
+
handle=symbol.handle,
|
167
|
+
quantum_type=symbol.quantum_type,
|
168
|
+
defining_function=defining_function,
|
169
|
+
direction=direction,
|
170
|
+
)
|
171
|
+
|
172
|
+
def capture_handles_in_expression(self, expr: Expression) -> None:
|
173
|
+
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
174
|
+
vrc.visit(ast.parse(expr.expr))
|
175
|
+
handles = dict.fromkeys(
|
176
|
+
handle
|
177
|
+
for handle in vrc.var_handles
|
178
|
+
if isinstance(self._current_scope[handle.name].value, QuantumSymbol)
|
179
|
+
)
|
180
|
+
for handle in handles:
|
181
|
+
self._capture_handle(handle, PortDeclarationDirection.Inout)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from typing import TYPE_CHECKING
|
2
|
+
|
3
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
4
|
+
|
5
|
+
from classiq.model_expansions.closure import FunctionClosure
|
6
|
+
from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
|
7
|
+
from classiq.model_expansions.quantum_operations.declarative_call_emitter import (
|
8
|
+
DeclarativeCallEmitter,
|
9
|
+
)
|
10
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
11
|
+
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
14
|
+
|
15
|
+
|
16
|
+
class QuantumFunctionCallEmitter(CallEmitter[QuantumFunctionCall]):
|
17
|
+
def __init__(self, interpreter: "BaseInterpreter") -> None:
|
18
|
+
super().__init__(interpreter)
|
19
|
+
self._model = self._interpreter._model
|
20
|
+
|
21
|
+
def emit(self, call: QuantumFunctionCall, /) -> None:
|
22
|
+
function = self._interpreter.evaluate(call.function).as_type(FunctionClosure)
|
23
|
+
args = call.positional_args
|
24
|
+
with ErrorManager().call(function.name):
|
25
|
+
self._emit_quantum_function_call(
|
26
|
+
function, args, self._debug_info.get(call.uuid)
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
class DeclarativeQuantumFunctionCallEmitter(
|
31
|
+
QuantumFunctionCallEmitter, DeclarativeCallEmitter
|
32
|
+
):
|
33
|
+
pass
|
@@ -0,0 +1,56 @@
|
|
1
|
+
from classiq.interface.exceptions import ClassiqExpansionError
|
2
|
+
from classiq.interface.generator.expressions.expression import Expression
|
3
|
+
from classiq.interface.generator.functions.builtins.internal_operators import (
|
4
|
+
REPEAT_OPERATOR_NAME,
|
5
|
+
)
|
6
|
+
from classiq.interface.generator.functions.classical_type import Integer
|
7
|
+
from classiq.interface.model.classical_parameter_declaration import (
|
8
|
+
ClassicalParameterDeclaration,
|
9
|
+
)
|
10
|
+
from classiq.interface.model.repeat import Repeat
|
11
|
+
|
12
|
+
from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
|
13
|
+
from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
|
14
|
+
from classiq.model_expansions.scope import Scope
|
15
|
+
from classiq.qmod.quantum_function import GenerativeQFunc
|
16
|
+
|
17
|
+
|
18
|
+
class RepeatEmitter(CallEmitter[Repeat]):
|
19
|
+
def emit(self, repeat: Repeat, /) -> None:
|
20
|
+
count = self._interpreter.evaluate(repeat.count).as_type(int)
|
21
|
+
if count < 0:
|
22
|
+
raise ClassiqExpansionError(
|
23
|
+
f"repeat count must be non-negative, got {count}"
|
24
|
+
)
|
25
|
+
op_name = self._counted_name_allocator.allocate(REPEAT_OPERATOR_NAME)
|
26
|
+
for i in range(count):
|
27
|
+
self._emit_iteration(repeat, i, op_name)
|
28
|
+
|
29
|
+
def _emit_iteration(self, repeat: Repeat, i: int, op_name: str) -> None:
|
30
|
+
closure_constructor: type[FunctionClosure]
|
31
|
+
extra_args: dict
|
32
|
+
if repeat.is_generative():
|
33
|
+
closure_constructor = GenerativeFunctionClosure
|
34
|
+
extra_args = {
|
35
|
+
"generative_blocks": {
|
36
|
+
"body": GenerativeQFunc(
|
37
|
+
repeat.get_generative_block("body"),
|
38
|
+
),
|
39
|
+
}
|
40
|
+
}
|
41
|
+
else:
|
42
|
+
closure_constructor = FunctionClosure
|
43
|
+
extra_args = {}
|
44
|
+
iteration_function = closure_constructor.create(
|
45
|
+
name=op_name,
|
46
|
+
positional_arg_declarations=[
|
47
|
+
ClassicalParameterDeclaration(
|
48
|
+
name=repeat.iter_var, classical_type=Integer()
|
49
|
+
)
|
50
|
+
],
|
51
|
+
body=repeat.body,
|
52
|
+
scope=Scope(parent=self._current_scope),
|
53
|
+
is_lambda=True,
|
54
|
+
**extra_args,
|
55
|
+
)
|
56
|
+
self._emit_quantum_function_call(iteration_function, [Expression(expr=str(i))])
|
@@ -0,0 +1,180 @@
|
|
1
|
+
import ast
|
2
|
+
from typing import TYPE_CHECKING, Any, Optional, TypeVar
|
3
|
+
|
4
|
+
from classiq.interface.generator.arith.arithmetic import compute_arithmetic_result_type
|
5
|
+
from classiq.interface.generator.expressions.expression import Expression
|
6
|
+
from classiq.interface.generator.functions.port_declaration import (
|
7
|
+
PortDeclarationDirection,
|
8
|
+
)
|
9
|
+
from classiq.interface.model.allocate import Allocate
|
10
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
11
|
+
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
12
|
+
ArithmeticOperation,
|
13
|
+
ArithmeticOperationKind,
|
14
|
+
)
|
15
|
+
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
16
|
+
QuantumAssignmentOperation,
|
17
|
+
)
|
18
|
+
from classiq.interface.model.quantum_statement import QuantumOperation, QuantumStatement
|
19
|
+
|
20
|
+
from classiq.model_expansions.closure import Closure
|
21
|
+
from classiq.model_expansions.evaluators.quantum_type_utils import (
|
22
|
+
copy_type_information,
|
23
|
+
set_size,
|
24
|
+
)
|
25
|
+
from classiq.model_expansions.quantum_operations.emitter import Emitter
|
26
|
+
from classiq.model_expansions.scope import QuantumSymbol, Scope
|
27
|
+
from classiq.model_expansions.transformers.ast_renamer import rename_variables
|
28
|
+
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
29
|
+
|
30
|
+
if TYPE_CHECKING:
|
31
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
32
|
+
|
33
|
+
|
34
|
+
QuantumOperationT = TypeVar("QuantumOperationT", bound=QuantumOperation)
|
35
|
+
_BLOCK_RENAMES = {
|
36
|
+
"compute": "within",
|
37
|
+
"action": "apply",
|
38
|
+
}
|
39
|
+
_REVERSE_BLOCK_RENAMES = {rename: name for name, rename in _BLOCK_RENAMES.items()}
|
40
|
+
|
41
|
+
|
42
|
+
class ShallowEmitter(Emitter[QuantumOperation]):
|
43
|
+
def __init__(
|
44
|
+
self,
|
45
|
+
interpreter: "BaseInterpreter",
|
46
|
+
operation_name: str,
|
47
|
+
*,
|
48
|
+
components: Optional[list[str]] = None,
|
49
|
+
) -> None:
|
50
|
+
super().__init__(interpreter)
|
51
|
+
self._operation_name = operation_name
|
52
|
+
self._components: list[str] = components or []
|
53
|
+
|
54
|
+
def emit(self, op: QuantumOperation, /) -> None:
|
55
|
+
expanded_components: dict[str, Any] = {}
|
56
|
+
blocks, expressions, handles = self._split_components(op)
|
57
|
+
|
58
|
+
if len(blocks) > 0:
|
59
|
+
if op.is_generative():
|
60
|
+
expanded_blocks = self.expand_generative_blocks(op)
|
61
|
+
else:
|
62
|
+
expanded_blocks = self.expand_blocks(op, blocks)
|
63
|
+
expanded_components.update(expanded_blocks)
|
64
|
+
|
65
|
+
for expression_name in expressions:
|
66
|
+
expression = getattr(op, expression_name)
|
67
|
+
expression = self._evaluate_expression(expression, preserve_bool_ops=True)
|
68
|
+
self.capture_handles_in_expression(expression)
|
69
|
+
expanded_components[expression_name] = expression
|
70
|
+
|
71
|
+
for handle_name in handles:
|
72
|
+
handle = getattr(op, handle_name)
|
73
|
+
expanded_components[handle_name] = self._interpreter.evaluate(
|
74
|
+
handle
|
75
|
+
).value.handle
|
76
|
+
|
77
|
+
op = op.model_copy(update=expanded_components)
|
78
|
+
if isinstance(op, QuantumAssignmentOperation):
|
79
|
+
self._post_process_assignment(op)
|
80
|
+
if isinstance(op, Allocate):
|
81
|
+
self._post_process_allocate(op)
|
82
|
+
self._builder.emit_statement(op)
|
83
|
+
|
84
|
+
def _post_process_assignment(self, op: QuantumAssignmentOperation) -> None:
|
85
|
+
if (
|
86
|
+
isinstance(op, ArithmeticOperation)
|
87
|
+
and op.operation_kind == ArithmeticOperationKind.Assignment
|
88
|
+
):
|
89
|
+
direction = PortDeclarationDirection.Output
|
90
|
+
self._update_result_type(op)
|
91
|
+
else:
|
92
|
+
direction = PortDeclarationDirection.Inout
|
93
|
+
self._capture_handle(op.result_var, direction)
|
94
|
+
|
95
|
+
def _post_process_allocate(self, allocate: Allocate) -> None:
|
96
|
+
target_symbol = self._interpreter.evaluate(allocate.target).value
|
97
|
+
if not isinstance(target_symbol, QuantumSymbol):
|
98
|
+
return
|
99
|
+
self._capture_handle(target_symbol.handle, PortDeclarationDirection.Output)
|
100
|
+
if allocate.size is None or not allocate.size.is_evaluated():
|
101
|
+
return
|
102
|
+
set_size(
|
103
|
+
target_symbol.quantum_type,
|
104
|
+
allocate.size.to_int_value(),
|
105
|
+
str(target_symbol.handle),
|
106
|
+
)
|
107
|
+
|
108
|
+
def _split_components(
|
109
|
+
self, op: QuantumOperation
|
110
|
+
) -> tuple[list[str], list[str], list[str]]:
|
111
|
+
blocks = self._filter_components(op, list)
|
112
|
+
expressions = self._filter_components(op, Expression)
|
113
|
+
handles = self._filter_components(op, HandleBinding)
|
114
|
+
return blocks, expressions, handles
|
115
|
+
|
116
|
+
def _filter_components(
|
117
|
+
self, op: QuantumOperation, component_type: type
|
118
|
+
) -> list[str]:
|
119
|
+
return [
|
120
|
+
component
|
121
|
+
for component in self._components
|
122
|
+
if isinstance(getattr(op, component, None), component_type)
|
123
|
+
]
|
124
|
+
|
125
|
+
def expand_blocks(
|
126
|
+
self, op: QuantumOperation, block_names: list[str]
|
127
|
+
) -> dict[str, list[QuantumStatement]]:
|
128
|
+
blocks = {
|
129
|
+
_BLOCK_RENAMES.get(block, block): block_statements
|
130
|
+
for block in block_names
|
131
|
+
if (block_statements := getattr(op, block)) is not None
|
132
|
+
}
|
133
|
+
block_closure = Closure(
|
134
|
+
name=self._operation_name,
|
135
|
+
scope=Scope(parent=self._current_scope),
|
136
|
+
blocks=blocks,
|
137
|
+
)
|
138
|
+
context = self._expand_operation(block_closure)
|
139
|
+
return {
|
140
|
+
block: context.statements(_BLOCK_RENAMES.get(block, block))
|
141
|
+
for block in block_names
|
142
|
+
}
|
143
|
+
|
144
|
+
def expand_generative_blocks(
|
145
|
+
self, op: QuantumOperation
|
146
|
+
) -> dict[str, list[QuantumStatement]]:
|
147
|
+
blocks = [block for block in self._components if op.has_generative_block(block)]
|
148
|
+
context = self._expand_generative_context(op, self._operation_name, blocks)
|
149
|
+
return {
|
150
|
+
_REVERSE_BLOCK_RENAMES.get(block, block): context.statements(block)
|
151
|
+
for block in blocks
|
152
|
+
}
|
153
|
+
|
154
|
+
def _update_result_type(self, op: ArithmeticOperation) -> None:
|
155
|
+
expr = str(self._evaluate_expression(op.expression))
|
156
|
+
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
157
|
+
vrc.visit(ast.parse(expr))
|
158
|
+
symbols: list[QuantumSymbol] = [
|
159
|
+
symbol
|
160
|
+
for handle in vrc.var_handles
|
161
|
+
if isinstance(
|
162
|
+
symbol := self._interpreter.evaluate(handle).value, QuantumSymbol
|
163
|
+
)
|
164
|
+
]
|
165
|
+
expr = rename_variables(
|
166
|
+
expr,
|
167
|
+
{str(symbol.handle): symbol.handle.identifier for symbol in symbols}
|
168
|
+
| {symbol.handle.qmod_expr: symbol.handle.identifier for symbol in symbols},
|
169
|
+
)
|
170
|
+
for symbol in symbols:
|
171
|
+
expr = expr.replace(symbol.handle.qmod_expr, symbol.handle.identifier)
|
172
|
+
result_type = compute_arithmetic_result_type(
|
173
|
+
expr,
|
174
|
+
{symbol.handle.identifier: symbol.quantum_type for symbol in symbols},
|
175
|
+
self._machine_precision,
|
176
|
+
)
|
177
|
+
result_symbol = self._interpreter.evaluate(op.result_var).as_type(QuantumSymbol)
|
178
|
+
copy_type_information(
|
179
|
+
result_type, result_symbol.quantum_type, str(op.result_var)
|
180
|
+
)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
2
|
+
from classiq.interface.model.variable_declaration_statement import (
|
3
|
+
VariableDeclarationStatement,
|
4
|
+
)
|
5
|
+
|
6
|
+
from classiq.model_expansions.evaluators.parameter_types import (
|
7
|
+
evaluate_type_in_quantum_symbol,
|
8
|
+
)
|
9
|
+
from classiq.model_expansions.quantum_operations.emitter import Emitter
|
10
|
+
from classiq.model_expansions.scope import Evaluated, QuantumSymbol
|
11
|
+
|
12
|
+
|
13
|
+
class VariableDeclarationStatementEmitter(Emitter[VariableDeclarationStatement]):
|
14
|
+
def emit(self, variable_declaration: VariableDeclarationStatement, /) -> None:
|
15
|
+
var_decl = variable_declaration.model_copy()
|
16
|
+
var_decl.quantum_type = variable_declaration.quantum_type.model_copy()
|
17
|
+
self._current_scope[variable_declaration.name] = Evaluated(
|
18
|
+
value=QuantumSymbol(
|
19
|
+
handle=HandleBinding(name=var_decl.name),
|
20
|
+
quantum_type=evaluate_type_in_quantum_symbol(
|
21
|
+
var_decl.quantum_type,
|
22
|
+
self._current_scope,
|
23
|
+
var_decl.name,
|
24
|
+
),
|
25
|
+
),
|
26
|
+
defining_function=self._builder.current_function,
|
27
|
+
)
|
28
|
+
self.emit_statement(var_decl)
|