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,247 @@
|
|
1
|
+
from collections.abc import Iterator, Sequence
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from dataclasses import dataclass, field
|
4
|
+
from typing import Generic, Optional, TypeVar
|
5
|
+
|
6
|
+
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
7
|
+
from classiq.interface.generator.compiler_keywords import (
|
8
|
+
EXPANDED_KEYWORD,
|
9
|
+
LAMBDA_KEYWORD,
|
10
|
+
)
|
11
|
+
from classiq.interface.generator.functions.builtins.internal_operators import (
|
12
|
+
WITHIN_APPLY_NAME,
|
13
|
+
)
|
14
|
+
from classiq.interface.model.model import MAIN_FUNCTION_NAME
|
15
|
+
from classiq.interface.model.native_function_definition import (
|
16
|
+
NativeFunctionDefinition,
|
17
|
+
)
|
18
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
19
|
+
from classiq.interface.model.quantum_function_declaration import (
|
20
|
+
PositionalArg,
|
21
|
+
)
|
22
|
+
from classiq.interface.model.quantum_statement import QuantumStatement
|
23
|
+
from classiq.interface.model.variable_declaration_statement import (
|
24
|
+
VariableDeclarationStatement,
|
25
|
+
)
|
26
|
+
from classiq.interface.source_reference import SourceReference
|
27
|
+
|
28
|
+
from classiq.model_expansions.capturing.captured_vars import (
|
29
|
+
CapturedVars,
|
30
|
+
validate_captured_directions,
|
31
|
+
)
|
32
|
+
from classiq.model_expansions.closure import (
|
33
|
+
Closure,
|
34
|
+
FunctionClosure,
|
35
|
+
GenerativeFunctionClosure,
|
36
|
+
)
|
37
|
+
from classiq.model_expansions.evaluators.quantum_type_utils import (
|
38
|
+
is_signature_monomorphic,
|
39
|
+
)
|
40
|
+
from classiq.model_expansions.scope import Scope
|
41
|
+
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
42
|
+
|
43
|
+
ClosureType = TypeVar("ClosureType", bound=Closure)
|
44
|
+
|
45
|
+
|
46
|
+
@dataclass
|
47
|
+
class Block:
|
48
|
+
statements: list[QuantumStatement] = field(default_factory=list)
|
49
|
+
captured_vars: CapturedVars = field(default_factory=CapturedVars)
|
50
|
+
|
51
|
+
@property
|
52
|
+
def variable_declarations(self) -> list[VariableDeclarationStatement]:
|
53
|
+
return [
|
54
|
+
stmt
|
55
|
+
for stmt in self.statements
|
56
|
+
if isinstance(stmt, VariableDeclarationStatement)
|
57
|
+
]
|
58
|
+
|
59
|
+
|
60
|
+
@dataclass
|
61
|
+
class OperationContext(Generic[ClosureType]):
|
62
|
+
closure: ClosureType
|
63
|
+
blocks: dict[str, Block] = field(default_factory=dict)
|
64
|
+
|
65
|
+
@property
|
66
|
+
def name(self) -> str:
|
67
|
+
return self.closure.name
|
68
|
+
|
69
|
+
@property
|
70
|
+
def positional_arg_declarations(self) -> Sequence[PositionalArg]:
|
71
|
+
return self.closure.positional_arg_declarations
|
72
|
+
|
73
|
+
def statements(self, block_name: str) -> list[QuantumStatement]:
|
74
|
+
return self.blocks[block_name].statements
|
75
|
+
|
76
|
+
|
77
|
+
@dataclass
|
78
|
+
class FunctionContext(OperationContext[FunctionClosure]):
|
79
|
+
@classmethod
|
80
|
+
def create(cls, original_function: FunctionClosure) -> "FunctionContext":
|
81
|
+
return cls(original_function, {"body": Block()})
|
82
|
+
|
83
|
+
@property
|
84
|
+
def body(self) -> list[QuantumStatement]:
|
85
|
+
return self.statements("body")
|
86
|
+
|
87
|
+
@property
|
88
|
+
def is_lambda(self) -> bool:
|
89
|
+
return self.closure.is_lambda
|
90
|
+
|
91
|
+
|
92
|
+
class OperationBuilder:
|
93
|
+
def __init__(
|
94
|
+
self, functions_scope: Scope, counted_name_allocator: CountedNameAllocator
|
95
|
+
) -> None:
|
96
|
+
self._operations: list[OperationContext] = []
|
97
|
+
self._blocks: list[str] = []
|
98
|
+
self._functions_scope = functions_scope
|
99
|
+
self._current_source_ref: Optional[SourceReference] = None
|
100
|
+
self._counted_name_allocator = counted_name_allocator
|
101
|
+
|
102
|
+
@property
|
103
|
+
def current_operation(self) -> Closure:
|
104
|
+
return self._operations[-1].closure
|
105
|
+
|
106
|
+
@property
|
107
|
+
def current_scope(self) -> Scope:
|
108
|
+
return self.current_operation.scope
|
109
|
+
|
110
|
+
@property
|
111
|
+
def current_function(self) -> FunctionClosure:
|
112
|
+
return self._get_last_function(self._operations)
|
113
|
+
|
114
|
+
@property
|
115
|
+
def parent_function(self) -> FunctionClosure:
|
116
|
+
return self._get_last_function(self._operations[:-1])
|
117
|
+
|
118
|
+
@staticmethod
|
119
|
+
def _get_last_function(operations: list[OperationContext]) -> FunctionClosure:
|
120
|
+
for operation in reversed(operations):
|
121
|
+
if isinstance(operation.closure, FunctionClosure):
|
122
|
+
return operation.closure
|
123
|
+
raise ClassiqInternalExpansionError("No function found")
|
124
|
+
|
125
|
+
@property
|
126
|
+
def current_block(self) -> Block:
|
127
|
+
return self._operations[-1].blocks[self._blocks[-1]]
|
128
|
+
|
129
|
+
@property
|
130
|
+
def _current_statements(self) -> list[QuantumStatement]:
|
131
|
+
return self.current_block.statements
|
132
|
+
|
133
|
+
def emit_statement(self, statement: QuantumStatement) -> None:
|
134
|
+
if self._current_source_ref is not None:
|
135
|
+
statement.source_ref = self._current_source_ref
|
136
|
+
self._current_statements.append(statement)
|
137
|
+
|
138
|
+
@property
|
139
|
+
def current_statement(self) -> QuantumStatement:
|
140
|
+
return self._current_statements[-1]
|
141
|
+
|
142
|
+
@contextmanager
|
143
|
+
def block_context(self, block_name: str) -> Iterator[None]:
|
144
|
+
self._blocks.append(block_name)
|
145
|
+
self._operations[-1].blocks[block_name] = Block()
|
146
|
+
yield
|
147
|
+
captured_vars = self.current_block.captured_vars
|
148
|
+
if (
|
149
|
+
not isinstance(self.current_operation, FunctionClosure)
|
150
|
+
and self.current_operation.name != WITHIN_APPLY_NAME
|
151
|
+
):
|
152
|
+
validate_captured_directions(
|
153
|
+
captured_vars.filter_vars(
|
154
|
+
self.current_function, self.current_block.variable_declarations
|
155
|
+
),
|
156
|
+
report_outin=False,
|
157
|
+
)
|
158
|
+
self.current_operation.captured_vars.update(
|
159
|
+
captured_vars.filter_vars(self.current_function)
|
160
|
+
)
|
161
|
+
self._blocks.pop()
|
162
|
+
|
163
|
+
@contextmanager
|
164
|
+
def operation_context(
|
165
|
+
self, original_operation: Closure
|
166
|
+
) -> Iterator[OperationContext]:
|
167
|
+
context: OperationContext
|
168
|
+
if isinstance(original_operation, FunctionClosure):
|
169
|
+
context = FunctionContext.create(original_operation)
|
170
|
+
else:
|
171
|
+
context = OperationContext(closure=original_operation)
|
172
|
+
self._operations.append(context)
|
173
|
+
yield context
|
174
|
+
self._finalize_within_apply()
|
175
|
+
self._propagate_captured_vars()
|
176
|
+
self._operations.pop()
|
177
|
+
|
178
|
+
def _finalize_within_apply(self) -> None:
|
179
|
+
if self.current_operation.name != WITHIN_APPLY_NAME:
|
180
|
+
return
|
181
|
+
within_captured_vars = self._operations[-1].blocks["within"].captured_vars
|
182
|
+
self.current_operation.captured_vars.update(
|
183
|
+
within_captured_vars.filter_vars(self.current_function).negate()
|
184
|
+
)
|
185
|
+
|
186
|
+
def _propagate_captured_vars(self) -> None:
|
187
|
+
captured_vars = self.current_operation.captured_vars
|
188
|
+
if isinstance(self.current_operation, FunctionClosure):
|
189
|
+
captured_vars = captured_vars.set_propagated()
|
190
|
+
validate_captured_directions(captured_vars)
|
191
|
+
if len(self._operations) < 2:
|
192
|
+
return
|
193
|
+
parent_block = self._operations[-2].blocks[self._blocks[-1]]
|
194
|
+
parent_block.captured_vars.update(
|
195
|
+
captured_vars.filter_vars(self.parent_function)
|
196
|
+
)
|
197
|
+
|
198
|
+
@contextmanager
|
199
|
+
def source_ref_context(
|
200
|
+
self, source_ref: Optional[SourceReference]
|
201
|
+
) -> Iterator[None]:
|
202
|
+
previous_source_ref = self._current_source_ref
|
203
|
+
self._current_source_ref = source_ref
|
204
|
+
yield
|
205
|
+
self._current_source_ref = previous_source_ref
|
206
|
+
|
207
|
+
def create_definition(
|
208
|
+
self, function_context: FunctionContext
|
209
|
+
) -> NativeFunctionDefinition:
|
210
|
+
name = self._get_expanded_function_name(function_context)
|
211
|
+
new_parameters: list[PortDeclaration] = [
|
212
|
+
param
|
213
|
+
for param in function_context.positional_arg_declarations
|
214
|
+
if isinstance(param, PortDeclaration)
|
215
|
+
]
|
216
|
+
|
217
|
+
return NativeFunctionDefinition(
|
218
|
+
name=name,
|
219
|
+
body=function_context.body,
|
220
|
+
positional_arg_declarations=new_parameters,
|
221
|
+
)
|
222
|
+
|
223
|
+
def _get_expanded_function_name(self, function_context: FunctionContext) -> str:
|
224
|
+
name = function_context.name
|
225
|
+
|
226
|
+
if name == MAIN_FUNCTION_NAME:
|
227
|
+
return name
|
228
|
+
|
229
|
+
if name in self.current_scope:
|
230
|
+
orig_func = self.current_scope[name].value
|
231
|
+
if (
|
232
|
+
isinstance(orig_func, FunctionClosure)
|
233
|
+
and not isinstance(orig_func, GenerativeFunctionClosure)
|
234
|
+
and is_signature_monomorphic(orig_func.positional_arg_declarations)
|
235
|
+
):
|
236
|
+
return name
|
237
|
+
|
238
|
+
for _ in self.current_scope:
|
239
|
+
name = self._counted_name_allocator.allocate(
|
240
|
+
f"{name}_{LAMBDA_KEYWORD + '_0_0_' if function_context.is_lambda else ''}{EXPANDED_KEYWORD}"
|
241
|
+
)
|
242
|
+
if name not in self.current_scope:
|
243
|
+
break
|
244
|
+
else:
|
245
|
+
raise ClassiqInternalExpansionError("Could not allocate function name")
|
246
|
+
|
247
|
+
return name
|
@@ -0,0 +1,158 @@
|
|
1
|
+
from collections.abc import Mapping
|
2
|
+
from typing import TYPE_CHECKING, Any
|
3
|
+
|
4
|
+
from classiq.interface.generator.expressions.qmod_struct_instance import (
|
5
|
+
QmodStructInstance,
|
6
|
+
)
|
7
|
+
from classiq.interface.generator.functions.type_name import Struct
|
8
|
+
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
9
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
10
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
11
|
+
from classiq.interface.model.quantum_function_declaration import (
|
12
|
+
PositionalArg,
|
13
|
+
QuantumFunctionDeclaration,
|
14
|
+
QuantumOperandDeclaration,
|
15
|
+
)
|
16
|
+
from classiq.interface.model.quantum_statement import QuantumStatement
|
17
|
+
|
18
|
+
from classiq.model_expansions.closure import (
|
19
|
+
FunctionClosure,
|
20
|
+
GenerativeClosure,
|
21
|
+
)
|
22
|
+
from classiq.model_expansions.scope import Evaluated, QuantumSymbol
|
23
|
+
from classiq.qmod.generative import generative_mode_context, set_frontend_interpreter
|
24
|
+
from classiq.qmod.model_state_container import QMODULE
|
25
|
+
from classiq.qmod.qmod_parameter import CParamStruct
|
26
|
+
from classiq.qmod.qmod_variable import QNum, _create_qvar_for_qtype
|
27
|
+
from classiq.qmod.quantum_callable import QCallable
|
28
|
+
from classiq.qmod.quantum_expandable import (
|
29
|
+
QExpandable,
|
30
|
+
QTerminalCallable,
|
31
|
+
)
|
32
|
+
from classiq.qmod.quantum_function import QFunc
|
33
|
+
from classiq.qmod.semantics.annotation.call_annotation import resolve_function_calls
|
34
|
+
from classiq.qmod.symbolic_expr import SymbolicExpr
|
35
|
+
|
36
|
+
if TYPE_CHECKING:
|
37
|
+
from classiq.model_expansions.interpreters.generative_interpreter import (
|
38
|
+
GenerativeInterpreter,
|
39
|
+
)
|
40
|
+
|
41
|
+
|
42
|
+
class LenList(list):
|
43
|
+
@property
|
44
|
+
def len(self) -> int:
|
45
|
+
return len(self)
|
46
|
+
|
47
|
+
def __getitem__(self, item: Any) -> Any:
|
48
|
+
if isinstance(item, QNum):
|
49
|
+
return SymbolicExpr(f"{self}[{item}]", True)
|
50
|
+
return super().__getitem__(item)
|
51
|
+
|
52
|
+
@classmethod
|
53
|
+
def wrap(cls, obj: Any) -> Any:
|
54
|
+
if not isinstance(obj, list):
|
55
|
+
return obj
|
56
|
+
return LenList([cls.wrap(item) for item in obj])
|
57
|
+
|
58
|
+
|
59
|
+
def translate_ast_arg_to_python_qmod(param: PositionalArg, evaluated: Evaluated) -> Any:
|
60
|
+
if isinstance(param, PortDeclaration):
|
61
|
+
quantum_symbol = evaluated.as_type(QuantumSymbol)
|
62
|
+
return _create_qvar_for_qtype(
|
63
|
+
quantum_symbol.quantum_type, quantum_symbol.handle
|
64
|
+
)
|
65
|
+
if isinstance(param, QuantumOperandDeclaration):
|
66
|
+
if param.is_list:
|
67
|
+
func_list: list[FunctionClosure] = evaluated.as_type(list)
|
68
|
+
return LenList(
|
69
|
+
[
|
70
|
+
QTerminalCallable(
|
71
|
+
QuantumOperandDeclaration(
|
72
|
+
name=param.name,
|
73
|
+
positional_arg_declarations=param.positional_arg_declarations,
|
74
|
+
),
|
75
|
+
index_=idx,
|
76
|
+
)
|
77
|
+
for idx in range(len(func_list))
|
78
|
+
]
|
79
|
+
)
|
80
|
+
else:
|
81
|
+
func = evaluated.as_type(FunctionClosure)
|
82
|
+
return QTerminalCallable(
|
83
|
+
QuantumFunctionDeclaration(
|
84
|
+
name=param.name if func.is_lambda else func.name,
|
85
|
+
positional_arg_declarations=func.positional_arg_declarations,
|
86
|
+
),
|
87
|
+
)
|
88
|
+
classical_value = evaluated.value
|
89
|
+
if isinstance(classical_value, QmodStructInstance):
|
90
|
+
return CParamStruct(
|
91
|
+
expr=param.name,
|
92
|
+
struct_type=Struct(name=classical_value.struct_declaration.name),
|
93
|
+
qmodule=QMODULE,
|
94
|
+
)
|
95
|
+
return LenList.wrap(classical_value)
|
96
|
+
|
97
|
+
|
98
|
+
class _InterpreterExpandable(QFunc):
|
99
|
+
def __init__(self, interpreter: "GenerativeInterpreter"):
|
100
|
+
super().__init__(lambda: None)
|
101
|
+
self._interpreter = interpreter
|
102
|
+
|
103
|
+
def append_statement_to_body(self, stmt: QuantumStatement) -> None:
|
104
|
+
current_operation = self._interpreter._builder._operations[-1]
|
105
|
+
dummy_function = NativeFunctionDefinition(
|
106
|
+
name=current_operation.name,
|
107
|
+
positional_arg_declarations=current_operation.positional_arg_declarations,
|
108
|
+
body=self._interpreter._builder._current_statements + [stmt],
|
109
|
+
)
|
110
|
+
declarative_functions = {
|
111
|
+
name: func
|
112
|
+
for name, func in self._qmodule.native_defs.items()
|
113
|
+
if name not in self._interpreter._top_level_scope
|
114
|
+
}
|
115
|
+
self._interpreter.update_declarative_functions(
|
116
|
+
declarative_functions, self._qmodule
|
117
|
+
)
|
118
|
+
self._interpreter.update_generative_functions(
|
119
|
+
self._qmodule.generative_functions
|
120
|
+
)
|
121
|
+
func_decls = self._get_function_declarations()
|
122
|
+
for dec_func in declarative_functions.values():
|
123
|
+
resolve_function_calls(dec_func, func_decls)
|
124
|
+
resolve_function_calls(dummy_function, func_decls)
|
125
|
+
stmt = dummy_function.body[-1]
|
126
|
+
with generative_mode_context(False):
|
127
|
+
self._interpreter.emit_statement(stmt)
|
128
|
+
|
129
|
+
def _get_function_declarations(self) -> Mapping[str, QuantumFunctionDeclaration]:
|
130
|
+
return {
|
131
|
+
name: QuantumFunctionDeclaration(
|
132
|
+
name=name,
|
133
|
+
positional_arg_declarations=evaluated.value.positional_arg_declarations,
|
134
|
+
)
|
135
|
+
for name, evaluated in self._interpreter._builder.current_scope.items()
|
136
|
+
if isinstance(evaluated, Evaluated)
|
137
|
+
and isinstance(evaluated.value, FunctionClosure)
|
138
|
+
} | nameables_to_dict(self._interpreter._get_function_declarations())
|
139
|
+
|
140
|
+
|
141
|
+
def emit_generative_statements(
|
142
|
+
interpreter: "GenerativeInterpreter",
|
143
|
+
operation: GenerativeClosure,
|
144
|
+
args: list[Evaluated],
|
145
|
+
) -> None:
|
146
|
+
python_qmod_args = [
|
147
|
+
translate_ast_arg_to_python_qmod(param, arg)
|
148
|
+
for param, arg in zip(operation.positional_arg_declarations, args)
|
149
|
+
]
|
150
|
+
interpreter_expandable = _InterpreterExpandable(interpreter)
|
151
|
+
QExpandable.STACK.append(interpreter_expandable)
|
152
|
+
QCallable.CURRENT_EXPANDABLE = interpreter_expandable
|
153
|
+
set_frontend_interpreter(interpreter)
|
154
|
+
for block_name, generative_function in operation.generative_blocks.items():
|
155
|
+
with interpreter._builder.block_context(block_name), generative_mode_context(
|
156
|
+
True
|
157
|
+
):
|
158
|
+
generative_function._py_callable(*python_qmod_args)
|
File without changes
|
@@ -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)
|