classiq 0.38.0__py3-none-any.whl → 0.65.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +47 -32
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
- classiq/_internals/api_wrapper.py +235 -97
- classiq/_internals/async_utils.py +1 -3
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +10 -5
- classiq/_internals/authentication/password_manager.py +18 -6
- classiq/_internals/authentication/token_manager.py +10 -5
- classiq/_internals/client.py +94 -33
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +60 -57
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +24 -19
- classiq/analyzer/analyzer_utilities.py +10 -10
- classiq/analyzer/rb.py +15 -15
- classiq/analyzer/show_interactive_hack.py +27 -4
- classiq/analyzer/url_utils.py +2 -3
- classiq/applications/__init__.py +3 -12
- classiq/applications/chemistry/__init__.py +14 -10
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
- classiq/applications/combinatorial_optimization/__init__.py +20 -6
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +4 -5
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
- classiq/applications/grover/__init__.py +9 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +6 -6
- classiq/applications/qnn/datasets/__init__.py +9 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +30 -10
- classiq/applications/qnn/torch_utils.py +4 -3
- classiq/applications/qnn/types.py +5 -5
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +3 -6
- classiq/applications/qsvm/qsvm_data_generation.py +3 -3
- classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
- classiq/execution/__init__.py +8 -3
- classiq/execution/all_hardware_devices.py +11 -0
- classiq/execution/execution_session.py +400 -0
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +197 -25
- classiq/execution/qnn.py +79 -0
- classiq/executor.py +20 -115
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +43 -13
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +28 -32
- classiq/interface/applications/qsvm.py +20 -29
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -121
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +25 -22
- classiq/interface/backend/quantum_backend_providers.py +69 -16
- classiq/interface/chemistry/fermionic_operator.py +30 -21
- classiq/interface/chemistry/ground_state_problem.py +28 -25
- classiq/interface/chemistry/molecule.py +14 -10
- classiq/interface/chemistry/operator.py +64 -231
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/debug_info.py +86 -0
- classiq/{exceptions.py → interface/exceptions.py} +37 -9
- classiq/interface/execution/iqcc.py +19 -0
- classiq/interface/execution/jobs.py +15 -12
- classiq/interface/execution/primitives.py +18 -0
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/executor/execution_preferences.py +26 -114
- classiq/interface/executor/execution_request.py +24 -46
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +17 -14
- classiq/interface/executor/quantum_code.py +28 -24
- classiq/interface/executor/quantum_instruction_set.py +2 -2
- classiq/interface/executor/register_initialization.py +11 -14
- classiq/interface/executor/result.py +83 -56
- classiq/interface/executor/vqe_result.py +10 -10
- classiq/interface/finance/function_input.py +35 -25
- classiq/interface/finance/gaussian_model_input.py +5 -5
- classiq/interface/finance/log_normal_model_input.py +4 -4
- classiq/interface/finance/model_input.py +4 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +22 -12
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +48 -69
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
- classiq/interface/generator/arith/argument_utils.py +46 -5
- classiq/interface/generator/arith/arithmetic.py +35 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
- classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
- classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
- classiq/interface/generator/arith/arithmetic_operations.py +14 -6
- classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
- classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
- classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
- classiq/interface/generator/arith/binary_ops.py +218 -130
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -25
- classiq/interface/generator/arith/logical_ops.py +14 -12
- classiq/interface/generator/arith/number_utils.py +12 -6
- classiq/interface/generator/arith/register_user_input.py +60 -37
- classiq/interface/generator/arith/unary_ops.py +49 -29
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/builtin_api_builder.py +2 -9
- classiq/interface/generator/chemistry_function_params.py +3 -3
- classiq/interface/generator/circuit_code/circuit_code.py +7 -7
- classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
- classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
- classiq/interface/generator/compiler_keywords.py +5 -1
- classiq/interface/generator/complex_type.py +13 -18
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +34 -29
- classiq/interface/generator/copy.py +47 -0
- classiq/interface/generator/custom_ansatz.py +2 -5
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
- classiq/interface/generator/expressions/enums/__init__.py +0 -10
- classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
- classiq/interface/generator/expressions/evaluated_expression.py +5 -5
- classiq/interface/generator/expressions/expression.py +26 -14
- classiq/interface/generator/expressions/expression_constants.py +9 -3
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
- classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
- classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
- classiq/interface/generator/finance.py +2 -2
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
- classiq/interface/generator/function_params.py +36 -64
- classiq/interface/generator/functions/__init__.py +0 -22
- classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
- classiq/interface/generator/functions/classical_function_declaration.py +18 -9
- classiq/interface/generator/functions/classical_type.py +47 -166
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +13 -14
- classiq/interface/generator/functions/port_declaration.py +1 -13
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +90 -0
- classiq/interface/generator/generated_circuit_data.py +153 -20
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -25
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
- classiq/interface/generator/hardware/hardware_data.py +72 -34
- classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
- classiq/interface/generator/hartree_fock.py +13 -5
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +32 -20
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +17 -15
- classiq/interface/generator/mcx.py +24 -17
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +26 -8
- classiq/interface/generator/model/model.py +27 -190
- classiq/interface/generator/model/preferences/preferences.py +115 -41
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +15 -13
- classiq/interface/generator/oracles/oracle_abc.py +7 -7
- classiq/interface/generator/partitioned_register.py +7 -7
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +41 -30
- classiq/interface/generator/qsvm.py +9 -10
- classiq/interface/generator/quantum_function_call.py +88 -73
- classiq/interface/generator/quantum_program.py +41 -24
- classiq/interface/generator/range_types.py +11 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +5 -5
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +16 -15
- classiq/interface/generator/state_preparation/metrics.py +4 -7
- classiq/interface/generator/state_preparation/state_preparation.py +25 -20
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
- classiq/interface/generator/transpiler_basis_gates.py +7 -3
- classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
- classiq/interface/generator/types/compilation_metadata.py +6 -0
- classiq/interface/generator/types/enum_declaration.py +54 -0
- classiq/interface/generator/types/qstruct_declaration.py +18 -0
- classiq/interface/generator/types/struct_declaration.py +7 -11
- classiq/interface/generator/ucc.py +5 -4
- classiq/interface/generator/unitary_gate.py +5 -5
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +7 -7
- classiq/interface/generator/validations/validator_functions.py +4 -4
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +29 -8
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +2 -2
- classiq/interface/helpers/custom_pydantic_types.py +40 -50
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +7 -5
- classiq/interface/helpers/validation_helpers.py +3 -20
- classiq/interface/helpers/versioned_model.py +1 -4
- classiq/interface/ide/ide_data.py +16 -20
- classiq/interface/ide/visual_model.py +130 -0
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +29 -69
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +32 -9
- classiq/interface/model/classical_if.py +15 -0
- classiq/interface/model/classical_parameter_declaration.py +33 -3
- classiq/interface/model/control.py +45 -0
- classiq/interface/model/handle_binding.py +298 -20
- classiq/interface/model/inplace_binary_operation.py +29 -24
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +69 -61
- classiq/interface/model/native_function_definition.py +17 -20
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/phase_operation.py +11 -0
- classiq/interface/model/port_declaration.py +27 -9
- classiq/interface/model/power.py +14 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
- classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
- classiq/interface/model/quantum_function_call.py +141 -343
- classiq/interface/model/quantum_function_declaration.py +190 -157
- classiq/interface/model/quantum_lambda_function.py +33 -32
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +177 -40
- classiq/interface/model/quantum_variable_declaration.py +3 -25
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +40 -14
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +7 -5
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +17 -21
- classiq/interface/source_reference.py +59 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
- classiq/model_expansions/capturing/__init__.py +0 -0
- classiq/model_expansions/capturing/captured_vars.py +435 -0
- classiq/model_expansions/capturing/mangling_utils.py +56 -0
- classiq/model_expansions/closure.py +171 -0
- classiq/model_expansions/debug_flag.py +3 -0
- classiq/model_expansions/evaluators/__init__.py +0 -0
- classiq/model_expansions/evaluators/arg_type_match.py +158 -0
- classiq/model_expansions/evaluators/argument_types.py +42 -0
- classiq/model_expansions/evaluators/classical_expression.py +36 -0
- classiq/model_expansions/evaluators/control.py +144 -0
- classiq/model_expansions/evaluators/parameter_types.py +226 -0
- classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
- classiq/model_expansions/evaluators/type_type_match.py +90 -0
- classiq/model_expansions/expression_evaluator.py +135 -0
- classiq/model_expansions/expression_renamer.py +76 -0
- classiq/model_expansions/function_builder.py +247 -0
- classiq/model_expansions/generative_functions.py +158 -0
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/interpreters/base_interpreter.py +263 -0
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
- classiq/model_expansions/model_tables.py +18 -0
- classiq/model_expansions/quantum_operations/__init__.py +9 -0
- classiq/model_expansions/quantum_operations/bind.py +60 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
- classiq/model_expansions/quantum_operations/classicalif.py +53 -0
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +181 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
- classiq/model_expansions/quantum_operations/repeat.py +56 -0
- classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
- classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
- classiq/model_expansions/scope.py +240 -0
- classiq/model_expansions/scope_initialization.py +150 -0
- classiq/model_expansions/sympy_conversion/__init__.py +0 -0
- classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
- classiq/model_expansions/transformers/__init__.py +0 -0
- classiq/model_expansions/transformers/ast_renamer.py +26 -0
- classiq/model_expansions/transformers/var_splitter.py +299 -0
- classiq/model_expansions/utils/__init__.py +0 -0
- classiq/model_expansions/utils/counted_name_allocator.py +11 -0
- classiq/model_expansions/utils/handles_collector.py +33 -0
- classiq/model_expansions/visitors/__init__.py +0 -0
- classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
- classiq/model_expansions/visitors/variable_references.py +144 -0
- classiq/open_library/__init__.py +4 -0
- classiq/open_library/functions/__init__.py +130 -0
- classiq/open_library/functions/amplitude_estimation.py +30 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
- classiq/open_library/functions/grover.py +157 -0
- classiq/open_library/functions/hea.py +115 -0
- classiq/open_library/functions/linear_pauli_rotation.py +82 -0
- classiq/open_library/functions/modular_exponentiation.py +201 -0
- classiq/open_library/functions/qaoa_penalty.py +117 -0
- classiq/open_library/functions/qft_functions.py +54 -0
- classiq/open_library/functions/qpe.py +46 -0
- classiq/open_library/functions/qsvt.py +331 -0
- classiq/open_library/functions/state_preparation.py +301 -0
- classiq/open_library/functions/swap_test.py +27 -0
- classiq/open_library/functions/utility_functions.py +81 -0
- classiq/open_library/functions/variational.py +52 -0
- classiq/qmod/__init__.py +10 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +36 -14
- classiq/qmod/builtins/classical_functions.py +39 -43
- classiq/qmod/builtins/constants.py +10 -0
- classiq/qmod/builtins/enums.py +208 -0
- classiq/qmod/builtins/functions/__init__.py +137 -0
- classiq/qmod/builtins/functions/allocation.py +150 -0
- classiq/qmod/builtins/functions/arithmetic.py +55 -0
- classiq/qmod/builtins/functions/benchmarking.py +8 -0
- classiq/qmod/builtins/functions/chemistry.py +91 -0
- classiq/qmod/builtins/functions/exponentiation.py +105 -0
- classiq/qmod/builtins/functions/finance.py +34 -0
- classiq/qmod/builtins/functions/operators.py +16 -0
- classiq/qmod/builtins/functions/qsvm.py +24 -0
- classiq/qmod/builtins/functions/standard_gates.py +651 -0
- classiq/qmod/builtins/operations.py +373 -40
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +4 -8
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +143 -101
- classiq/qmod/expression_query.py +20 -4
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +18 -6
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +16 -11
- classiq/qmod/native/pretty_printer.py +187 -97
- classiq/qmod/pretty_print/__init__.py +7 -0
- classiq/qmod/pretty_print/expression_to_python.py +222 -0
- classiq/qmod/pretty_print/pretty_printer.py +572 -0
- classiq/qmod/python_classical_type.py +67 -0
- classiq/qmod/qfunc.py +60 -8
- classiq/qmod/qmod_constant.py +93 -26
- classiq/qmod/qmod_parameter.py +68 -59
- classiq/qmod/qmod_variable.py +468 -155
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +269 -96
- classiq/qmod/quantum_function.py +196 -41
- classiq/qmod/semantics/__init__.py +0 -0
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
- classiq/qmod/semantics/error_manager.py +88 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +384 -0
- classiq/qmod/semantics/validation/__init__.py +0 -0
- classiq/qmod/semantics/validation/constants_validation.py +16 -0
- classiq/qmod/semantics/validation/func_call_validation.py +99 -0
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +128 -0
- classiq/qmod/symbolic.py +147 -123
- classiq/qmod/symbolic_expr.py +27 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +98 -4
- classiq/qmod/write_qmod.py +17 -3
- classiq/synthesis.py +210 -22
- {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/METADATA +16 -9
- classiq-0.65.4.dist-info/RECORD +521 -0
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -25
- classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
- classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/interface/executor/aws_execution_cost.py +0 -73
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
- classiq/interface/generator/functions/foreign_function_definition.py +0 -114
- classiq/interface/generator/functions/function_implementation.py +0 -107
- classiq/interface/generator/functions/native_function_definition.py +0 -155
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -44
- classiq/interface/generator/functions/register_mapping_data.py +0 -106
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -74
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/call_synthesis_data.py +0 -68
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -94
- classiq/interface/model/resolvers/function_call_resolver.py +0 -43
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -156
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -462
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -229
- classiq/qmod/builtins/functions.py +0 -913
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -205
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- classiq-0.38.0.dist-info/RECORD +0 -454
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
- /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
- /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
- /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
- {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/WHEEL +0 -0
classiq/qmod/quantum_function.py
CHANGED
@@ -1,60 +1,116 @@
|
|
1
1
|
import ast
|
2
2
|
import functools
|
3
|
-
from
|
3
|
+
from abc import abstractmethod
|
4
|
+
from collections import defaultdict
|
5
|
+
from dataclasses import is_dataclass
|
6
|
+
from enum import EnumMeta
|
7
|
+
from inspect import isclass
|
8
|
+
from typing import Any, Callable, Optional, get_origin
|
4
9
|
|
10
|
+
from classiq.interface.exceptions import ClassiqError
|
5
11
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
12
|
+
from classiq.interface.generator.functions.port_declaration import (
|
13
|
+
PortDeclarationDirection,
|
14
|
+
)
|
6
15
|
from classiq.interface.generator.model.constraints import Constraints
|
7
16
|
from classiq.interface.generator.model.preferences.preferences import Preferences
|
8
|
-
from classiq.interface.
|
9
|
-
from classiq.interface.model.
|
17
|
+
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
18
|
+
from classiq.interface.model.model import Model
|
19
|
+
from classiq.interface.model.native_function_definition import (
|
20
|
+
NativeFunctionDefinition,
|
21
|
+
)
|
10
22
|
from classiq.interface.model.quantum_function_declaration import (
|
11
|
-
|
23
|
+
NamedParamsQuantumFunctionDeclaration,
|
12
24
|
)
|
13
25
|
|
14
|
-
from classiq.exceptions import ClassiqError
|
15
26
|
from classiq.qmod.classical_function import CFunc
|
16
27
|
from classiq.qmod.declaration_inferrer import infer_func_decl
|
28
|
+
from classiq.qmod.generative import set_frontend_interpreter
|
17
29
|
from classiq.qmod.qmod_constant import QConstant
|
18
|
-
from classiq.qmod.qmod_parameter import
|
30
|
+
from classiq.qmod.qmod_parameter import CArray, CParam
|
19
31
|
from classiq.qmod.qmod_variable import QVar
|
20
32
|
from classiq.qmod.quantum_callable import QCallable, QCallableList
|
21
33
|
from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
|
22
|
-
from classiq.qmod.utilities import mangle_keyword
|
34
|
+
from classiq.qmod.utilities import mangle_keyword
|
23
35
|
|
24
36
|
|
25
|
-
|
26
|
-
|
27
|
-
|
37
|
+
class BaseQFunc(QExpandable):
|
38
|
+
def __init__(
|
39
|
+
self,
|
40
|
+
py_callable: Callable,
|
41
|
+
compilation_metadata: Optional[CompilationMetadata] = None,
|
42
|
+
) -> None:
|
43
|
+
super().__init__(py_callable)
|
44
|
+
self.compilation_metadata = compilation_metadata
|
45
|
+
|
46
|
+
@property
|
47
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
48
|
+
raise NotImplementedError
|
28
49
|
|
50
|
+
@property
|
51
|
+
def _has_inputs(self) -> bool:
|
52
|
+
return any(
|
53
|
+
port.direction == PortDeclarationDirection.Input
|
54
|
+
for port in self.func_decl.port_declarations
|
55
|
+
)
|
29
56
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
preferences: Optional[Preferences] = None,
|
35
|
-
classical_execution_function: Optional[CFunc] = None,
|
36
|
-
) -> SerializedModel:
|
37
|
-
return entry_point.create_model(
|
38
|
-
constraints, execution_preferences, preferences, classical_execution_function
|
39
|
-
).get_model()
|
57
|
+
def update_compilation_metadata(self, **kwargs: Any) -> None:
|
58
|
+
if kwargs["should_synthesize_separately"] and self._has_inputs:
|
59
|
+
raise ClassiqError("Can't synthesize separately a function with inputs")
|
60
|
+
self.compilation_metadata = self._compilation_metadata.model_copy(update=kwargs)
|
40
61
|
|
62
|
+
@property
|
63
|
+
def _compilation_metadata(self) -> CompilationMetadata:
|
64
|
+
if self.compilation_metadata is None:
|
65
|
+
return CompilationMetadata()
|
66
|
+
return self.compilation_metadata
|
41
67
|
|
42
|
-
|
43
|
-
def
|
68
|
+
@abstractmethod
|
69
|
+
def create_model(
|
70
|
+
self,
|
71
|
+
constraints: Optional[Constraints] = None,
|
72
|
+
execution_preferences: Optional[ExecutionPreferences] = None,
|
73
|
+
preferences: Optional[Preferences] = None,
|
74
|
+
classical_execution_function: Optional[CFunc] = None,
|
75
|
+
) -> Model:
|
76
|
+
pass
|
77
|
+
|
78
|
+
|
79
|
+
class QFunc(BaseQFunc):
|
80
|
+
FRAME_DEPTH = 3
|
81
|
+
|
82
|
+
def __init__(
|
83
|
+
self,
|
84
|
+
py_callable: Callable,
|
85
|
+
compilation_metadata: Optional[CompilationMetadata] = None,
|
86
|
+
) -> None:
|
44
87
|
_validate_no_gen_params(py_callable.__annotations__)
|
45
|
-
super().__init__(py_callable)
|
88
|
+
super().__init__(py_callable, compilation_metadata)
|
46
89
|
functools.update_wrapper(self, py_callable)
|
90
|
+
self.compilation_metadata: Optional[CompilationMetadata] = None
|
47
91
|
|
48
92
|
@property
|
49
|
-
def
|
50
|
-
|
51
|
-
self.
|
52
|
-
|
93
|
+
def pure_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
94
|
+
if type(self.func_decl) is NamedParamsQuantumFunctionDeclaration:
|
95
|
+
return self.func_decl
|
96
|
+
return NamedParamsQuantumFunctionDeclaration(
|
97
|
+
**{
|
98
|
+
k: v
|
99
|
+
for k, v in self.func_decl.model_dump().items()
|
100
|
+
if k in NamedParamsQuantumFunctionDeclaration.model_fields
|
101
|
+
}
|
53
102
|
)
|
54
103
|
|
104
|
+
@property
|
105
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
106
|
+
name = self._py_callable.__name__
|
107
|
+
if hasattr(self._qmodule, "native_defs") and name in self._qmodule.native_defs:
|
108
|
+
return self._qmodule.native_defs[name]
|
109
|
+
return infer_func_decl(self._py_callable, qmodule=self._qmodule)
|
110
|
+
|
55
111
|
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
112
|
+
self.expand()
|
56
113
|
super().__call__(*args, **kwargs)
|
57
|
-
self._add_native_func_def()
|
58
114
|
|
59
115
|
def create_model(
|
60
116
|
self,
|
@@ -63,12 +119,17 @@ class QFunc(QExpandable):
|
|
63
119
|
preferences: Optional[Preferences] = None,
|
64
120
|
classical_execution_function: Optional[CFunc] = None,
|
65
121
|
) -> Model:
|
122
|
+
self._qmodule.enum_decls = dict()
|
66
123
|
self._qmodule.type_decls = dict()
|
124
|
+
self._qmodule.qstruct_decls = dict()
|
67
125
|
self._qmodule.native_defs = dict()
|
68
126
|
self._qmodule.constants = dict()
|
127
|
+
self._qmodule.functions_compilation_metadata = dict()
|
128
|
+
self._qmodule.generative_functions = dict()
|
129
|
+
self._qmodule.function_dependencies = defaultdict(list)
|
69
130
|
QConstant.set_current_model(self._qmodule)
|
70
|
-
self.
|
71
|
-
model_extra_settings:
|
131
|
+
self.expand()
|
132
|
+
model_extra_settings: list[tuple[str, Any]] = [
|
72
133
|
("constraints", constraints),
|
73
134
|
("execution_preferences", execution_preferences),
|
74
135
|
("preferences", preferences),
|
@@ -78,20 +139,51 @@ class QFunc(QExpandable):
|
|
78
139
|
model_extra_settings.append(
|
79
140
|
("classical_execution_code", classical_execution_function.code)
|
80
141
|
)
|
81
|
-
|
142
|
+
model = Model(
|
82
143
|
constants=list(self._qmodule.constants.values()),
|
83
144
|
functions=list(self._qmodule.native_defs.values()),
|
145
|
+
enums=list(self._qmodule.enum_decls.values()),
|
84
146
|
types=list(self._qmodule.type_decls.values()),
|
147
|
+
qstructs=list(self._qmodule.qstruct_decls.values()),
|
148
|
+
functions_compilation_metadata=self._qmodule.functions_compilation_metadata,
|
85
149
|
**{key: value for key, value in model_extra_settings if value},
|
86
150
|
)
|
151
|
+
if len(self._qmodule.generative_functions) > 0:
|
152
|
+
return self._create_generative_model(model)
|
153
|
+
return model
|
154
|
+
|
155
|
+
def _create_generative_model(self, model_stub: Model) -> Model:
|
156
|
+
from classiq.model_expansions.interpreters.frontend_generative_interpreter import (
|
157
|
+
FrontendGenerativeInterpreter,
|
158
|
+
)
|
159
|
+
from classiq.qmod.semantics.annotation.call_annotation import (
|
160
|
+
resolve_function_calls,
|
161
|
+
)
|
87
162
|
|
88
|
-
|
163
|
+
generative_functions = list(self._qmodule.generative_functions.values())
|
164
|
+
resolve_function_calls(
|
165
|
+
model_stub,
|
166
|
+
dict(model_stub.function_dict)
|
167
|
+
| {
|
168
|
+
gen_func.func_decl.name: gen_func.func_decl
|
169
|
+
for gen_func in generative_functions
|
170
|
+
},
|
171
|
+
)
|
172
|
+
interpreter = FrontendGenerativeInterpreter(model_stub, generative_functions)
|
173
|
+
set_frontend_interpreter(interpreter)
|
174
|
+
return interpreter.expand()
|
175
|
+
|
176
|
+
def expand(self) -> None:
|
89
177
|
if self.func_decl.name in self._qmodule.native_defs:
|
90
178
|
return
|
91
|
-
|
179
|
+
super().expand()
|
92
180
|
self._qmodule.native_defs[self.func_decl.name] = NativeFunctionDefinition(
|
93
|
-
**self.func_decl.
|
181
|
+
**{**self.func_decl.model_dump(), **{"body": self.body}}
|
94
182
|
)
|
183
|
+
if self.compilation_metadata is not None:
|
184
|
+
self._qmodule.functions_compilation_metadata[self.func_decl.name] = (
|
185
|
+
self.compilation_metadata
|
186
|
+
)
|
95
187
|
|
96
188
|
def _add_constants_from_classical_code(
|
97
189
|
self, classical_execution_function: CFunc
|
@@ -120,14 +212,15 @@ class QFunc(QExpandable):
|
|
120
212
|
|
121
213
|
|
122
214
|
class ExternalQFunc(QTerminalCallable):
|
215
|
+
_decl: NamedParamsQuantumFunctionDeclaration
|
216
|
+
|
123
217
|
def __init__(self, py_callable: Callable) -> None:
|
124
|
-
|
125
|
-
|
126
|
-
raise ClassiqError(f"Definition of {py_callable.__name__!r} not found")
|
218
|
+
self._py_callable = py_callable
|
219
|
+
decl = infer_func_decl(py_callable)
|
127
220
|
|
128
221
|
py_callable.__annotations__.pop("return", None)
|
129
222
|
if py_callable.__annotations__.keys() != {
|
130
|
-
mangle_keyword(arg.name) for arg in decl.
|
223
|
+
mangle_keyword(arg.name) for arg in decl.positional_arg_declarations
|
131
224
|
}:
|
132
225
|
raise ClassiqError(
|
133
226
|
f"Parameter type hints for {py_callable.__name__!r} do not match imported declaration"
|
@@ -135,24 +228,86 @@ class ExternalQFunc(QTerminalCallable):
|
|
135
228
|
super().__init__(decl)
|
136
229
|
functools.update_wrapper(self, py_callable)
|
137
230
|
|
231
|
+
@property
|
232
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
233
|
+
return self._decl
|
234
|
+
|
235
|
+
@property
|
236
|
+
def pure_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
237
|
+
return self.func_decl
|
238
|
+
|
239
|
+
def get_implementation(self) -> NativeFunctionDefinition:
|
240
|
+
model = QFunc(self._py_callable).create_model()
|
241
|
+
return [
|
242
|
+
func for func in model.functions if func.name == self._py_callable.__name__
|
243
|
+
][0]
|
244
|
+
|
245
|
+
|
246
|
+
class GenerativeQFunc(BaseQFunc):
|
247
|
+
FRAME_DEPTH = 3
|
248
|
+
|
249
|
+
def __init__(
|
250
|
+
self,
|
251
|
+
py_callable: Callable,
|
252
|
+
func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
|
253
|
+
compilation_metadata: Optional[CompilationMetadata] = None,
|
254
|
+
) -> None:
|
255
|
+
super().__init__(py_callable, compilation_metadata)
|
256
|
+
self._func_decl = func_decl
|
257
|
+
|
258
|
+
@property
|
259
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
260
|
+
if self._func_decl is None:
|
261
|
+
self._func_decl = infer_func_decl(self._py_callable, self._qmodule)
|
262
|
+
return self._func_decl
|
263
|
+
|
264
|
+
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
265
|
+
self._qmodule.generative_functions[self.func_decl.name] = self
|
266
|
+
super().__call__(*args, **kwargs)
|
267
|
+
|
268
|
+
def create_model(
|
269
|
+
self,
|
270
|
+
constraints: Optional[Constraints] = None,
|
271
|
+
execution_preferences: Optional[ExecutionPreferences] = None,
|
272
|
+
preferences: Optional[Preferences] = None,
|
273
|
+
classical_execution_function: Optional[CFunc] = None,
|
274
|
+
) -> Model:
|
275
|
+
def _dec_main(*args: Any, **kwargs: Any) -> None:
|
276
|
+
self(*args, **kwargs)
|
277
|
+
|
278
|
+
_dec_main.__annotations__ = self._py_callable.__annotations__
|
279
|
+
|
280
|
+
return QFunc(_dec_main).create_model(
|
281
|
+
constraints=constraints,
|
282
|
+
execution_preferences=execution_preferences,
|
283
|
+
preferences=preferences,
|
284
|
+
classical_execution_function=classical_execution_function,
|
285
|
+
)
|
286
|
+
|
138
287
|
|
139
288
|
ILLEGAL_PARAM_ERROR = "Unsupported type hint '{annotation}' for argument '{name}'."
|
140
289
|
|
141
290
|
|
142
291
|
class IllegalParamsError(ClassiqError):
|
143
|
-
_HINT =
|
292
|
+
_HINT = (
|
293
|
+
"\nNote - QMOD functions can declare classical parameters using the type hints "
|
294
|
+
"'CInt', 'CReal', 'CBool', and 'CArray'."
|
295
|
+
)
|
144
296
|
|
145
297
|
def __init__(self, message: str) -> None:
|
146
298
|
super().__init__(message + self._HINT)
|
147
299
|
|
148
300
|
|
149
|
-
def _validate_no_gen_params(annotations:
|
301
|
+
def _validate_no_gen_params(annotations: dict[str, Any]) -> None:
|
150
302
|
_illegal_params = {
|
151
303
|
name: annotation
|
152
304
|
for name, annotation in annotations.items()
|
153
305
|
if not (
|
154
306
|
name == "return"
|
155
|
-
or
|
307
|
+
or (isclass(annotation) and issubclass(annotation, CParam))
|
308
|
+
or (isclass(annotation) and is_dataclass(annotation))
|
309
|
+
or (isclass(annotation) and isinstance(annotation, EnumMeta))
|
310
|
+
or get_origin(annotation) is CArray
|
156
311
|
or (get_origin(annotation) or annotation) is QCallable
|
157
312
|
or (get_origin(annotation) or annotation) is QCallableList
|
158
313
|
or QVar.from_type_hint(annotation) is not None
|
File without changes
|
File without changes
|
@@ -0,0 +1,92 @@
|
|
1
|
+
from collections.abc import Iterator, Mapping
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from classiq.interface.exceptions import ClassiqError
|
6
|
+
from classiq.interface.generator.visitor import Visitor
|
7
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
8
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
9
|
+
from classiq.interface.model.quantum_function_declaration import (
|
10
|
+
AnonQuantumOperandDeclaration,
|
11
|
+
QuantumFunctionDeclaration,
|
12
|
+
QuantumOperandDeclaration,
|
13
|
+
)
|
14
|
+
from classiq.interface.model.quantum_lambda_function import (
|
15
|
+
QuantumLambdaFunction,
|
16
|
+
)
|
17
|
+
|
18
|
+
from classiq.qmod.builtins.functions import BUILTIN_FUNCTION_DECLARATIONS
|
19
|
+
from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
|
20
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
21
|
+
from classiq.qmod.semantics.lambdas import get_renamed_parameters
|
22
|
+
|
23
|
+
|
24
|
+
def _annotate_function_call_decl(
|
25
|
+
fc: QuantumFunctionCall,
|
26
|
+
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
27
|
+
) -> None:
|
28
|
+
if fc._func_decl is None:
|
29
|
+
func_decl = function_dict.get(fc.func_name)
|
30
|
+
if func_decl is None:
|
31
|
+
raise ClassiqError(
|
32
|
+
f"Error resolving function {fc.func_name}, the function is not found in included library."
|
33
|
+
)
|
34
|
+
fc.set_func_decl(func_decl)
|
35
|
+
|
36
|
+
for arg, param in zip(fc.positional_args, fc.func_decl.positional_arg_declarations):
|
37
|
+
if not isinstance(param, AnonQuantumOperandDeclaration):
|
38
|
+
continue
|
39
|
+
args: list
|
40
|
+
if isinstance(arg, list):
|
41
|
+
args = arg
|
42
|
+
else:
|
43
|
+
args = [arg]
|
44
|
+
for qlambda in args:
|
45
|
+
if isinstance(qlambda, QuantumLambdaFunction):
|
46
|
+
qlambda.set_op_decl(param)
|
47
|
+
|
48
|
+
|
49
|
+
class _CallLambdaAnnotator(Visitor):
|
50
|
+
def __init__(
|
51
|
+
self, quantum_functions: Mapping[str, QuantumFunctionDeclaration]
|
52
|
+
) -> None:
|
53
|
+
self._quantum_functions = dict(quantum_functions)
|
54
|
+
self._current_operands: dict[str, QuantumOperandDeclaration] = {}
|
55
|
+
|
56
|
+
@contextmanager
|
57
|
+
def set_operands(
|
58
|
+
self, operands: dict[str, QuantumOperandDeclaration]
|
59
|
+
) -> Iterator[None]:
|
60
|
+
previous_operands = self._current_operands
|
61
|
+
self._current_operands = operands
|
62
|
+
yield
|
63
|
+
self._current_operands = previous_operands
|
64
|
+
|
65
|
+
def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
|
66
|
+
with self.set_operands(func.operand_declarations_dict):
|
67
|
+
self.generic_visit(func)
|
68
|
+
|
69
|
+
def visit_QuantumLambdaFunction(self, lambda_func: QuantumLambdaFunction) -> None:
|
70
|
+
lambda_operands = get_renamed_parameters(lambda_func)[1]
|
71
|
+
with self.set_operands(self._current_operands | lambda_operands):
|
72
|
+
self.generic_visit(lambda_func)
|
73
|
+
|
74
|
+
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
75
|
+
_annotate_function_call_decl(
|
76
|
+
call, self._quantum_functions | self._current_operands
|
77
|
+
)
|
78
|
+
self.generic_visit(call)
|
79
|
+
|
80
|
+
|
81
|
+
def resolve_function_calls(
|
82
|
+
root: Any,
|
83
|
+
quantum_function_dict: Mapping[str, QuantumFunctionDeclaration],
|
84
|
+
) -> None:
|
85
|
+
all_functions: Mapping[str, QuantumFunctionDeclaration] = {
|
86
|
+
**BUILTIN_FUNCTION_DECLARATIONS,
|
87
|
+
**quantum_function_dict,
|
88
|
+
}
|
89
|
+
with ErrorManager().ignore_errors_context():
|
90
|
+
QStructAnnotator().visit(quantum_function_dict)
|
91
|
+
QStructAnnotator().visit(root)
|
92
|
+
_CallLambdaAnnotator(all_functions).visit(root)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from classiq.interface.generator.functions.type_name import TypeName
|
2
|
+
from classiq.interface.generator.visitor import Visitor
|
3
|
+
|
4
|
+
from classiq.qmod.model_state_container import QMODULE
|
5
|
+
|
6
|
+
|
7
|
+
class QStructAnnotator(Visitor):
|
8
|
+
def __init__(self) -> None:
|
9
|
+
self._visited: set[TypeName] = set()
|
10
|
+
|
11
|
+
def visit_TypeName(self, type_name: TypeName) -> None:
|
12
|
+
decl = QMODULE.qstruct_decls.get(type_name.name)
|
13
|
+
if decl is None or type_name.has_fields or (type_name in self._visited):
|
14
|
+
return
|
15
|
+
self._visited.add(type_name)
|
16
|
+
new_fields = {
|
17
|
+
field_name: field_type.model_copy()
|
18
|
+
for field_name, field_type in decl.fields.items()
|
19
|
+
}
|
20
|
+
# We first visit the new fields and then set to deal with recursive
|
21
|
+
# qstructs
|
22
|
+
self.visit(new_fields)
|
23
|
+
type_name.set_fields(new_fields)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
from collections.abc import Iterator
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from classiq.interface.ast_node import ASTNode
|
6
|
+
from classiq.interface.exceptions import CLASSIQ_SLACK_COMMUNITY_LINK
|
7
|
+
from classiq.interface.source_reference import SourceReferencedError
|
8
|
+
|
9
|
+
|
10
|
+
class ErrorManager:
|
11
|
+
def __new__(cls) -> "ErrorManager":
|
12
|
+
if not hasattr(cls, "_instance"):
|
13
|
+
cls._instance = super().__new__(cls)
|
14
|
+
return cls._instance
|
15
|
+
|
16
|
+
def __init__(self) -> None:
|
17
|
+
if hasattr(self, "_instantiated"):
|
18
|
+
return
|
19
|
+
self._instantiated = True
|
20
|
+
self._errors: list[SourceReferencedError] = []
|
21
|
+
self._current_nodes_stack: list[ASTNode] = []
|
22
|
+
self._call_stack: list[str] = []
|
23
|
+
self._ignore_errors: bool = False
|
24
|
+
|
25
|
+
@contextmanager
|
26
|
+
def ignore_errors_context(self) -> Iterator[None]:
|
27
|
+
previous = self._ignore_errors
|
28
|
+
self._ignore_errors = True
|
29
|
+
try:
|
30
|
+
yield
|
31
|
+
finally:
|
32
|
+
self._ignore_errors = previous
|
33
|
+
|
34
|
+
@property
|
35
|
+
def annotated_errors(self) -> list[str]:
|
36
|
+
return [str(error) for error in self._errors]
|
37
|
+
|
38
|
+
def add_error(self, error: str) -> None:
|
39
|
+
if not self._ignore_errors:
|
40
|
+
self._errors.append(
|
41
|
+
SourceReferencedError(
|
42
|
+
error=error.replace(CLASSIQ_SLACK_COMMUNITY_LINK, ""),
|
43
|
+
source_ref=(
|
44
|
+
self._current_nodes_stack[-1].source_ref
|
45
|
+
if self._current_nodes_stack
|
46
|
+
else None
|
47
|
+
),
|
48
|
+
function=self.current_function,
|
49
|
+
)
|
50
|
+
)
|
51
|
+
|
52
|
+
def get_errors(self) -> list[SourceReferencedError]:
|
53
|
+
return self._errors
|
54
|
+
|
55
|
+
def clear(self) -> None:
|
56
|
+
self._current_nodes_stack = []
|
57
|
+
self._errors = []
|
58
|
+
|
59
|
+
def has_errors(self) -> bool:
|
60
|
+
return len(self._errors) > 0
|
61
|
+
|
62
|
+
def report_errors(self, error_type: type[Exception]) -> None:
|
63
|
+
if self.has_errors():
|
64
|
+
errors = self.annotated_errors
|
65
|
+
self.clear()
|
66
|
+
raise error_type("\n\t" + "\n\t".join(errors))
|
67
|
+
|
68
|
+
@property
|
69
|
+
def current_function(self) -> Optional[str]:
|
70
|
+
return self._call_stack[-1] if self._call_stack else None
|
71
|
+
|
72
|
+
@contextmanager
|
73
|
+
def node_context(self, node: ASTNode) -> Iterator[None]:
|
74
|
+
self._current_nodes_stack.append(node)
|
75
|
+
yield
|
76
|
+
self._current_nodes_stack.pop()
|
77
|
+
|
78
|
+
@contextmanager
|
79
|
+
def call(self, func_name: str) -> Iterator[None]:
|
80
|
+
self._call_stack.append(func_name)
|
81
|
+
yield
|
82
|
+
self._call_stack.pop()
|
83
|
+
|
84
|
+
|
85
|
+
def append_error(node: ASTNode, message: str) -> None:
|
86
|
+
instance = ErrorManager()
|
87
|
+
with instance.node_context(node):
|
88
|
+
instance.add_error(message)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
2
|
+
from classiq.interface.model.quantum_function_declaration import (
|
3
|
+
AnonQuantumOperandDeclaration,
|
4
|
+
QuantumOperandDeclaration,
|
5
|
+
)
|
6
|
+
from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
|
7
|
+
|
8
|
+
from classiq import AnonClassicalParameterDeclaration
|
9
|
+
|
10
|
+
|
11
|
+
def get_renamed_parameters(
|
12
|
+
lambda_func: QuantumLambdaFunction,
|
13
|
+
) -> tuple[list[str], dict[str, QuantumOperandDeclaration], list[PortDeclaration]]:
|
14
|
+
renamed_parameters: list[str] = []
|
15
|
+
renamed_operands: dict[str, QuantumOperandDeclaration] = {}
|
16
|
+
renamed_ports: list[PortDeclaration] = []
|
17
|
+
for idx, param in enumerate(lambda_func.func_decl.positional_arg_declarations):
|
18
|
+
param_name = lambda_func.pos_rename_params[idx]
|
19
|
+
if isinstance(param, AnonClassicalParameterDeclaration):
|
20
|
+
renamed_parameters.append(param_name)
|
21
|
+
elif isinstance(param, AnonQuantumOperandDeclaration):
|
22
|
+
renamed_operands[param_name] = param.rename(param_name)
|
23
|
+
else:
|
24
|
+
renamed_ports.append(param.rename(param_name))
|
25
|
+
return renamed_parameters, renamed_operands, renamed_ports
|