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
@@ -0,0 +1,384 @@
|
|
1
|
+
import ast
|
2
|
+
from collections.abc import Iterator, Mapping, Sequence
|
3
|
+
from contextlib import contextmanager
|
4
|
+
from typing import (
|
5
|
+
Optional,
|
6
|
+
)
|
7
|
+
|
8
|
+
from classiq.interface.exceptions import ClassiqSemanticError
|
9
|
+
from classiq.interface.generator.expressions.expression import Expression
|
10
|
+
from classiq.interface.generator.function_params import PortDirection
|
11
|
+
from classiq.interface.generator.functions.classical_type import CLASSICAL_ATTRIBUTES
|
12
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
13
|
+
from classiq.interface.generator.functions.port_declaration import (
|
14
|
+
PortDeclarationDirection,
|
15
|
+
)
|
16
|
+
from classiq.interface.generator.visitor import Visitor
|
17
|
+
from classiq.interface.model.handle_binding import (
|
18
|
+
FieldHandleBinding,
|
19
|
+
HandleBinding,
|
20
|
+
SlicedHandleBinding,
|
21
|
+
SubscriptHandleBinding,
|
22
|
+
)
|
23
|
+
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
24
|
+
from classiq.interface.model.model import Model
|
25
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
26
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
27
|
+
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
28
|
+
QuantumExpressionOperation,
|
29
|
+
)
|
30
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
31
|
+
from classiq.interface.model.quantum_function_declaration import (
|
32
|
+
QuantumFunctionDeclaration,
|
33
|
+
QuantumOperandDeclaration,
|
34
|
+
)
|
35
|
+
from classiq.interface.model.quantum_lambda_function import (
|
36
|
+
QuantumLambdaFunction,
|
37
|
+
)
|
38
|
+
from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
|
39
|
+
from classiq.interface.model.validation_handle import HandleState
|
40
|
+
from classiq.interface.model.variable_declaration_statement import (
|
41
|
+
VariableDeclarationStatement,
|
42
|
+
)
|
43
|
+
from classiq.interface.model.within_apply_operation import WithinApply
|
44
|
+
|
45
|
+
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
46
|
+
from classiq.qmod.builtins.functions import (
|
47
|
+
BUILTIN_FUNCTION_DECLARATIONS,
|
48
|
+
)
|
49
|
+
from classiq.qmod.semantics.annotation.call_annotation import resolve_function_calls
|
50
|
+
from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
|
51
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
52
|
+
from classiq.qmod.semantics.lambdas import get_renamed_parameters
|
53
|
+
from classiq.qmod.semantics.validation.constants_validation import (
|
54
|
+
check_duplicate_constants,
|
55
|
+
)
|
56
|
+
from classiq.qmod.semantics.validation.func_call_validation import (
|
57
|
+
check_no_overlapping_quantum_args,
|
58
|
+
validate_call_arguments,
|
59
|
+
)
|
60
|
+
from classiq.qmod.semantics.validation.function_name_collisions_validation import (
|
61
|
+
_check_function_name_collisions,
|
62
|
+
)
|
63
|
+
from classiq.qmod.semantics.validation.handle_validation import resolve_handle
|
64
|
+
from classiq.qmod.semantics.validation.main_validation import validate_main_function
|
65
|
+
from classiq.qmod.semantics.validation.types_validation import (
|
66
|
+
check_cstruct_has_fields,
|
67
|
+
check_duplicate_types,
|
68
|
+
check_qstruct_fields_are_defined,
|
69
|
+
check_qstruct_flexibility,
|
70
|
+
check_qstruct_has_fields,
|
71
|
+
check_qstruct_is_not_recursive,
|
72
|
+
)
|
73
|
+
|
74
|
+
HANDLE_BINDING_PART_MESSAGE = {
|
75
|
+
SubscriptHandleBinding: "array subscript",
|
76
|
+
SlicedHandleBinding: "array slice",
|
77
|
+
FieldHandleBinding: "field access",
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
class StaticScope:
|
82
|
+
def __init__(
|
83
|
+
self,
|
84
|
+
parameters: list[str],
|
85
|
+
operands: dict[str, QuantumOperandDeclaration],
|
86
|
+
variables_to_states: dict[str, HandleState],
|
87
|
+
variables_to_types: dict[str, ConcreteQuantumType],
|
88
|
+
) -> None:
|
89
|
+
self.parameters = parameters
|
90
|
+
self.operands = operands
|
91
|
+
self.variable_states = variables_to_states
|
92
|
+
self.variables_to_types = variables_to_types
|
93
|
+
|
94
|
+
|
95
|
+
class StaticSemanticsVisitor(Visitor):
|
96
|
+
def __init__(
|
97
|
+
self,
|
98
|
+
functions_dict: Mapping[str, QuantumFunctionDeclaration],
|
99
|
+
constants: list[str],
|
100
|
+
) -> None:
|
101
|
+
self._scope: list[StaticScope] = []
|
102
|
+
self._error_manager = ErrorManager()
|
103
|
+
self._functions_dict = functions_dict
|
104
|
+
self._constants = constants
|
105
|
+
|
106
|
+
@property
|
107
|
+
def current_scope(self) -> StaticScope:
|
108
|
+
return self._scope[-1]
|
109
|
+
|
110
|
+
@contextmanager
|
111
|
+
def scoped_visit(self, scope: StaticScope) -> Iterator[None]:
|
112
|
+
self._scope.append(scope)
|
113
|
+
yield
|
114
|
+
self._scope.pop()
|
115
|
+
|
116
|
+
def visit_Model(self, model: Model) -> None:
|
117
|
+
check_duplicate_types([*model.enums, *model.types, *model.qstructs])
|
118
|
+
check_duplicate_constants(model.constants)
|
119
|
+
for qstruct in model.qstructs:
|
120
|
+
check_qstruct_has_fields(qstruct)
|
121
|
+
if check_qstruct_fields_are_defined(
|
122
|
+
qstruct
|
123
|
+
) and check_qstruct_is_not_recursive(qstruct):
|
124
|
+
check_qstruct_flexibility(qstruct)
|
125
|
+
for cstruct in model.types:
|
126
|
+
check_cstruct_has_fields(cstruct)
|
127
|
+
validate_main_function(model.main_func)
|
128
|
+
self.visit_BaseModel(model)
|
129
|
+
|
130
|
+
def visit_NativeFunctionDefinition(
|
131
|
+
self, func_def: NativeFunctionDefinition
|
132
|
+
) -> None:
|
133
|
+
scope = StaticScope(
|
134
|
+
parameters=list(func_def.param_names) + self._constants,
|
135
|
+
operands=dict(func_def.operand_declarations_dict),
|
136
|
+
variables_to_states=initialize_variables_to_state(
|
137
|
+
func_def.port_declarations
|
138
|
+
),
|
139
|
+
variables_to_types={
|
140
|
+
port.name: port.quantum_type for port in func_def.port_declarations
|
141
|
+
},
|
142
|
+
)
|
143
|
+
with self.scoped_visit(scope), self._error_manager.call(func_def.name):
|
144
|
+
parameter_declaration_names = [
|
145
|
+
decl.name for decl in func_def.positional_arg_declarations
|
146
|
+
]
|
147
|
+
seen_names: set[str] = set()
|
148
|
+
for name in parameter_declaration_names:
|
149
|
+
if name in seen_names:
|
150
|
+
self._error_manager.add_error(
|
151
|
+
f"duplicate parameter declaration name {name!r}"
|
152
|
+
)
|
153
|
+
seen_names.add(name)
|
154
|
+
if len(func_def.body) == 0:
|
155
|
+
return
|
156
|
+
self.visit(func_def.body)
|
157
|
+
with self._error_manager.node_context(func_def.body[-1]):
|
158
|
+
for port_decl in func_def.port_declarations:
|
159
|
+
handle_state = self.current_scope.variable_states[port_decl.name]
|
160
|
+
expected_terminal_state = EXPECTED_TERMINAL_STATES.get(
|
161
|
+
port_decl.direction
|
162
|
+
)
|
163
|
+
if (
|
164
|
+
expected_terminal_state is not None
|
165
|
+
and handle_state is not expected_terminal_state
|
166
|
+
):
|
167
|
+
self._error_manager.add_error(
|
168
|
+
f"At the end of the function, port `{port_decl.name}` is expected to be {expected_terminal_state.name.lower()} but it isn't"
|
169
|
+
)
|
170
|
+
|
171
|
+
def visit_WithinApply(self, within_apply: WithinApply) -> None:
|
172
|
+
initial_variables_to_state = self.current_scope.variable_states.copy()
|
173
|
+
scope = StaticScope(
|
174
|
+
parameters=self.current_scope.parameters,
|
175
|
+
operands=self.current_scope.operands,
|
176
|
+
variables_to_states=self.current_scope.variable_states.copy(),
|
177
|
+
variables_to_types=self.current_scope.variables_to_types.copy(),
|
178
|
+
)
|
179
|
+
with self.scoped_visit(scope):
|
180
|
+
self.visit(within_apply.compute)
|
181
|
+
compute_captured_variables = {
|
182
|
+
var
|
183
|
+
for var, state in self.current_scope.variable_states.items()
|
184
|
+
if var in initial_variables_to_state
|
185
|
+
and state != initial_variables_to_state[var]
|
186
|
+
}
|
187
|
+
self.visit(within_apply.action)
|
188
|
+
variables_to_state = self.current_scope.variable_states.copy()
|
189
|
+
self.current_scope.variable_states.update(
|
190
|
+
{
|
191
|
+
var: state
|
192
|
+
for var, state in variables_to_state.items()
|
193
|
+
if var in self.current_scope.variable_states
|
194
|
+
and var not in compute_captured_variables
|
195
|
+
}
|
196
|
+
)
|
197
|
+
|
198
|
+
def visit_QuantumOperation(self, op: QuantumOperation) -> None:
|
199
|
+
with self._error_manager.node_context(op):
|
200
|
+
if isinstance(op, QuantumFunctionCall):
|
201
|
+
validate_call_arguments(
|
202
|
+
op,
|
203
|
+
{
|
204
|
+
**self._functions_dict,
|
205
|
+
**self.current_scope.operands,
|
206
|
+
},
|
207
|
+
)
|
208
|
+
elif isinstance(op, InplaceBinaryOperation) and isinstance(
|
209
|
+
op.value, HandleBinding
|
210
|
+
):
|
211
|
+
check_no_overlapping_quantum_args(
|
212
|
+
[op.target, op.value], op.operation.value
|
213
|
+
)
|
214
|
+
self._handle_inputs(op.readable_inputs)
|
215
|
+
self._handle_outputs(op.readable_outputs)
|
216
|
+
self._handle_inouts(op.readable_inouts)
|
217
|
+
self.generic_visit(op)
|
218
|
+
|
219
|
+
def visit_VariableDeclarationStatement(
|
220
|
+
self, declaration: VariableDeclarationStatement
|
221
|
+
) -> None:
|
222
|
+
handle_wiring_state = self.current_scope.variable_states.get(declaration.name)
|
223
|
+
if handle_wiring_state is not None:
|
224
|
+
self._error_manager.add_error(
|
225
|
+
f"Trying to declare a variable of the same name as previously declared variable {declaration.name}"
|
226
|
+
)
|
227
|
+
return
|
228
|
+
|
229
|
+
self.current_scope.variable_states[declaration.name] = HandleState.UNINITIALIZED
|
230
|
+
self.current_scope.variables_to_types[declaration.name] = (
|
231
|
+
declaration.quantum_type
|
232
|
+
)
|
233
|
+
|
234
|
+
def visit_QuantumLambdaFunction(self, lambda_func: QuantumLambdaFunction) -> None:
|
235
|
+
renamed_parameters, renamed_operands, renamed_ports = get_renamed_parameters(
|
236
|
+
lambda_func
|
237
|
+
)
|
238
|
+
scope = StaticScope(
|
239
|
+
parameters=self.current_scope.parameters + renamed_parameters,
|
240
|
+
operands={**self.current_scope.operands, **renamed_operands},
|
241
|
+
variables_to_states={
|
242
|
+
**self.current_scope.variable_states.copy(),
|
243
|
+
**initialize_variables_to_state(renamed_ports),
|
244
|
+
},
|
245
|
+
variables_to_types=self.current_scope.variables_to_types
|
246
|
+
| {port.name: port.quantum_type for port in renamed_ports},
|
247
|
+
)
|
248
|
+
with self.scoped_visit(scope):
|
249
|
+
self.generic_visit(lambda_func)
|
250
|
+
|
251
|
+
def visit_HandleBinding(self, handle: HandleBinding) -> None:
|
252
|
+
resolve_handle(self.current_scope, handle)
|
253
|
+
|
254
|
+
def visit_Expression(self, expr: Expression) -> None:
|
255
|
+
if len(self._scope) == 0:
|
256
|
+
return
|
257
|
+
vrc = VarRefCollector(ignore_duplicated_handles=True, unevaluated=True)
|
258
|
+
vrc.visit(ast.parse(expr.expr))
|
259
|
+
handles = [
|
260
|
+
HandleMetadata(handle=handle)
|
261
|
+
for handle in vrc.var_handles
|
262
|
+
if handle.name in self.current_scope.variable_states
|
263
|
+
and (
|
264
|
+
not isinstance(handle, FieldHandleBinding)
|
265
|
+
or handle.field not in CLASSICAL_ATTRIBUTES
|
266
|
+
)
|
267
|
+
]
|
268
|
+
self._handle_inouts(handles)
|
269
|
+
|
270
|
+
def visit_QuantumExpressionOperation(self, op: QuantumExpressionOperation) -> None:
|
271
|
+
self.visit_Expression(op.expression)
|
272
|
+
self.visit_QuantumOperation(op)
|
273
|
+
|
274
|
+
def _handle_state_changing_ios(
|
275
|
+
self,
|
276
|
+
ios: Sequence[HandleMetadata],
|
277
|
+
state: HandleState,
|
278
|
+
state_change_verb: str,
|
279
|
+
) -> None:
|
280
|
+
for handle_metadata in ios:
|
281
|
+
handle_binding = handle_metadata.handle
|
282
|
+
if isinstance(
|
283
|
+
handle_binding,
|
284
|
+
(SubscriptHandleBinding, SlicedHandleBinding, FieldHandleBinding),
|
285
|
+
):
|
286
|
+
self._error_manager.add_error(
|
287
|
+
f"Cannot use {HANDLE_BINDING_PART_MESSAGE[type(handle_binding)]} of variable {handle_binding.name!r} in {state_change_verb} context"
|
288
|
+
)
|
289
|
+
continue
|
290
|
+
handle_wiring_state = self.current_scope.variable_states.get(
|
291
|
+
handle_binding.name
|
292
|
+
)
|
293
|
+
if handle_wiring_state is not state:
|
294
|
+
state_prefix = (
|
295
|
+
""
|
296
|
+
if handle_wiring_state is None
|
297
|
+
else f"{handle_wiring_state.name.lower()} "
|
298
|
+
)
|
299
|
+
location = (
|
300
|
+
f" {handle_metadata.readable_location}"
|
301
|
+
if handle_metadata.readable_location is not None
|
302
|
+
else ""
|
303
|
+
)
|
304
|
+
self._error_manager.add_error(
|
305
|
+
f"Cannot use {state_prefix}quantum variable {handle_binding.name!r}"
|
306
|
+
f"{location}"
|
307
|
+
)
|
308
|
+
|
309
|
+
self.current_scope.variable_states[handle_binding.name] = ~state
|
310
|
+
|
311
|
+
def _handle_inputs(self, inputs: Sequence[HandleMetadata]) -> None:
|
312
|
+
self._handle_state_changing_ios(
|
313
|
+
inputs, HandleState.INITIALIZED, "uninitialization"
|
314
|
+
)
|
315
|
+
|
316
|
+
def _handle_outputs(self, outputs: Sequence[HandleMetadata]) -> None:
|
317
|
+
self._handle_state_changing_ios(
|
318
|
+
outputs, HandleState.UNINITIALIZED, "initialization"
|
319
|
+
)
|
320
|
+
|
321
|
+
def _handle_inouts(self, inouts: Sequence[HandleMetadata]) -> None:
|
322
|
+
for handle_metadata in inouts:
|
323
|
+
handle_binding = handle_metadata.handle
|
324
|
+
|
325
|
+
if handle_binding.name not in self.current_scope.variable_states:
|
326
|
+
ErrorManager().add_error(
|
327
|
+
f"Variable {handle_binding.name!r} is not defined"
|
328
|
+
)
|
329
|
+
return
|
330
|
+
handle_wiring_state = self.current_scope.variable_states[
|
331
|
+
handle_binding.name
|
332
|
+
]
|
333
|
+
|
334
|
+
if handle_wiring_state is not HandleState.INITIALIZED:
|
335
|
+
state_prefix = (
|
336
|
+
""
|
337
|
+
if handle_wiring_state is None
|
338
|
+
else f"{handle_wiring_state.name.lower()} "
|
339
|
+
)
|
340
|
+
location = (
|
341
|
+
f" {handle_metadata.readable_location}"
|
342
|
+
if handle_metadata.readable_location is not None
|
343
|
+
else ""
|
344
|
+
)
|
345
|
+
self._error_manager.add_error(
|
346
|
+
f"Cannot use {state_prefix}quantum variable {handle_binding.name!r}"
|
347
|
+
f"{location}"
|
348
|
+
)
|
349
|
+
|
350
|
+
|
351
|
+
def static_semantics_analysis_pass(
|
352
|
+
model: Model, error_type: Optional[type[Exception]] = ClassiqSemanticError
|
353
|
+
) -> None:
|
354
|
+
_check_function_name_collisions(model, error_type)
|
355
|
+
QStructAnnotator().visit(model)
|
356
|
+
functions = {**BUILTIN_FUNCTION_DECLARATIONS, **model.function_dict}
|
357
|
+
resolve_function_calls(model, functions)
|
358
|
+
StaticSemanticsVisitor(
|
359
|
+
functions,
|
360
|
+
[const.name for const in model.constants],
|
361
|
+
).visit(model)
|
362
|
+
if error_type is not None:
|
363
|
+
ErrorManager().report_errors(error_type)
|
364
|
+
|
365
|
+
|
366
|
+
EXPECTED_TERMINAL_STATES: dict[PortDeclarationDirection, HandleState] = {
|
367
|
+
PortDeclarationDirection.Output: HandleState.INITIALIZED,
|
368
|
+
PortDeclarationDirection.Inout: HandleState.INITIALIZED,
|
369
|
+
}
|
370
|
+
|
371
|
+
|
372
|
+
def initialize_variables_to_state(
|
373
|
+
port_declarations: Sequence[PortDeclaration],
|
374
|
+
) -> dict[str, HandleState]:
|
375
|
+
variables_to_state: dict[str, HandleState] = dict()
|
376
|
+
|
377
|
+
for port_decl in port_declarations:
|
378
|
+
variables_to_state[port_decl.name] = (
|
379
|
+
HandleState.INITIALIZED
|
380
|
+
if port_decl.direction.includes_port_direction(PortDirection.Input)
|
381
|
+
else HandleState.UNINITIALIZED
|
382
|
+
)
|
383
|
+
|
384
|
+
return variables_to_state
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from collections.abc import Sequence
|
2
|
+
|
3
|
+
from classiq.interface.generator.constant import Constant
|
4
|
+
|
5
|
+
from classiq.qmod.builtins import BUILTIN_CONSTANTS
|
6
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
7
|
+
|
8
|
+
|
9
|
+
def check_duplicate_constants(constants: Sequence[Constant]) -> None:
|
10
|
+
known_constants = {constant.name: constant for constant in BUILTIN_CONSTANTS}
|
11
|
+
for constant in constants:
|
12
|
+
if constant.name in known_constants:
|
13
|
+
with ErrorManager().node_context(constant):
|
14
|
+
ErrorManager().add_error(f"Constant {constant.name!r} already exists")
|
15
|
+
else:
|
16
|
+
known_constants[constant.name] = constant
|
@@ -0,0 +1,99 @@
|
|
1
|
+
from collections.abc import Mapping
|
2
|
+
|
3
|
+
from classiq.interface.exceptions import ClassiqError
|
4
|
+
from classiq.interface.generator.expressions.expression import Expression
|
5
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
6
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
7
|
+
from classiq.interface.model.quantum_function_declaration import (
|
8
|
+
AnonQuantumFunctionDeclaration,
|
9
|
+
AnonQuantumOperandDeclaration,
|
10
|
+
QuantumFunctionDeclaration,
|
11
|
+
)
|
12
|
+
from classiq.interface.model.quantum_lambda_function import (
|
13
|
+
OperandIdentifier,
|
14
|
+
QuantumLambdaFunction,
|
15
|
+
QuantumOperand,
|
16
|
+
)
|
17
|
+
|
18
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
19
|
+
|
20
|
+
|
21
|
+
def validate_call_arguments(
|
22
|
+
fc: QuantumFunctionCall,
|
23
|
+
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
24
|
+
) -> None:
|
25
|
+
pos_args = fc.positional_args
|
26
|
+
pos_params = fc.func_decl.positional_arg_declarations
|
27
|
+
if len(pos_args) != len(pos_params):
|
28
|
+
ErrorManager().add_error(
|
29
|
+
f"Function {fc.func_name} takes {len(pos_params)} arguments but "
|
30
|
+
f"{len(pos_args)} were given."
|
31
|
+
)
|
32
|
+
for arg, param in zip(pos_args, pos_params):
|
33
|
+
if not isinstance(arg, (Expression, HandleBinding)) and isinstance(
|
34
|
+
param, AnonQuantumOperandDeclaration
|
35
|
+
):
|
36
|
+
_check_operand_against_declaration(param, arg, function_dict, fc.func_name)
|
37
|
+
check_no_overlapping_quantum_args(fc.ports, fc.func_name)
|
38
|
+
|
39
|
+
|
40
|
+
def _check_operand_against_declaration(
|
41
|
+
operand_decl: AnonQuantumOperandDeclaration,
|
42
|
+
operand_argument: QuantumOperand,
|
43
|
+
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
44
|
+
func_name: str,
|
45
|
+
in_list: bool = False,
|
46
|
+
) -> None:
|
47
|
+
if isinstance(operand_argument, list):
|
48
|
+
if in_list:
|
49
|
+
ErrorManager().add_error(
|
50
|
+
f"{str(operand_argument)!r} argument to {func_name!r} is not "
|
51
|
+
f"a valid operand. Nested operand lists are not permitted."
|
52
|
+
)
|
53
|
+
return
|
54
|
+
for arg in operand_argument:
|
55
|
+
_check_operand_against_declaration(
|
56
|
+
operand_decl, arg, function_dict, func_name, in_list=True
|
57
|
+
)
|
58
|
+
return
|
59
|
+
operand_arg_decl: AnonQuantumFunctionDeclaration
|
60
|
+
operand_argument_for_decl = operand_argument
|
61
|
+
if isinstance(operand_argument_for_decl, OperandIdentifier):
|
62
|
+
operand_argument_for_decl = operand_argument_for_decl.name
|
63
|
+
if isinstance(operand_argument_for_decl, str):
|
64
|
+
if operand_argument_for_decl not in function_dict:
|
65
|
+
ErrorManager().add_error(
|
66
|
+
f"{operand_argument!r} argument to {func_name!r} is not a "
|
67
|
+
f"registered function."
|
68
|
+
)
|
69
|
+
return
|
70
|
+
operand_arg_decl = function_dict[operand_argument_for_decl]
|
71
|
+
elif isinstance(operand_argument_for_decl, QuantumLambdaFunction):
|
72
|
+
operand_arg_decl = operand_argument_for_decl.func_decl
|
73
|
+
else:
|
74
|
+
raise ClassiqError(
|
75
|
+
f"{str(operand_argument)!r} argument to {func_name!r} is not a "
|
76
|
+
f"valid operand."
|
77
|
+
)
|
78
|
+
num_arg_parameters = len(operand_arg_decl.positional_arg_declarations)
|
79
|
+
num_decl_parameters = len(operand_decl.positional_arg_declarations)
|
80
|
+
if num_arg_parameters != num_decl_parameters:
|
81
|
+
ErrorManager().add_error(
|
82
|
+
f"Signature of argument {operand_argument!r} to {func_name!r} "
|
83
|
+
f"does not match the signature of parameter {operand_decl.name!r}. "
|
84
|
+
f"{operand_decl.name!r} accepts {num_decl_parameters} parameters but "
|
85
|
+
f"{operand_argument!r} accepts {num_arg_parameters} parameters."
|
86
|
+
)
|
87
|
+
|
88
|
+
|
89
|
+
def check_no_overlapping_quantum_args(
|
90
|
+
args: list[HandleBinding], func_name: str
|
91
|
+
) -> None:
|
92
|
+
for idx, arg in enumerate(args):
|
93
|
+
for other_arg in args[idx + 1 :]:
|
94
|
+
if arg.overlaps(other_arg):
|
95
|
+
ErrorManager().add_error(
|
96
|
+
f"Cannot use the same part of variable {arg.name!r} in multiple "
|
97
|
+
f"arguments to function {func_name!r}."
|
98
|
+
)
|
99
|
+
break
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from classiq.interface.model.model import Model
|
4
|
+
|
5
|
+
from classiq.qmod.builtins.functions import CORE_LIB_DECLS
|
6
|
+
|
7
|
+
|
8
|
+
def _check_function_name_collisions(
|
9
|
+
model: Model, error_type: Optional[type[Exception]]
|
10
|
+
) -> None:
|
11
|
+
if error_type is None:
|
12
|
+
return
|
13
|
+
redefined_functions = [
|
14
|
+
function.name
|
15
|
+
for function in CORE_LIB_DECLS
|
16
|
+
if function.name in model.function_dict
|
17
|
+
]
|
18
|
+
if len(redefined_functions) == 1:
|
19
|
+
raise error_type(
|
20
|
+
f"Cannot redefine built-in function {redefined_functions[0]!r}"
|
21
|
+
)
|
22
|
+
elif len(redefined_functions) > 1:
|
23
|
+
raise error_type(f"Cannot redefine built-in functions: {redefined_functions}")
|
@@ -0,0 +1,85 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Optional, Union
|
2
|
+
|
3
|
+
from classiq.interface.generator.functions.type_name import TypeName
|
4
|
+
from classiq.interface.model.handle_binding import (
|
5
|
+
ConcreteHandleBinding,
|
6
|
+
FieldHandleBinding,
|
7
|
+
HandleBinding,
|
8
|
+
NestedHandleBinding,
|
9
|
+
SlicedHandleBinding,
|
10
|
+
SubscriptHandleBinding,
|
11
|
+
)
|
12
|
+
from classiq.interface.model.quantum_type import QuantumBitvector, QuantumType
|
13
|
+
|
14
|
+
import classiq.qmod.semantics.error_manager as error_manager
|
15
|
+
from classiq.qmod.model_state_container import QMODULE
|
16
|
+
|
17
|
+
if TYPE_CHECKING:
|
18
|
+
from classiq.qmod.semantics.static_semantics_visitor import StaticScope
|
19
|
+
|
20
|
+
|
21
|
+
def resolve_handle(scope: "StaticScope", handle: HandleBinding) -> None:
|
22
|
+
if handle.name not in scope.variables_to_types:
|
23
|
+
error_manager.append_error(handle, f"Variable {handle.name!r} is undefined.")
|
24
|
+
return
|
25
|
+
_resolve_handle_recursively(scope.variables_to_types[handle.name], handle)
|
26
|
+
|
27
|
+
|
28
|
+
def _resolve_handle_recursively(
|
29
|
+
qtype: QuantumType, handle: ConcreteHandleBinding
|
30
|
+
) -> Optional[QuantumType]:
|
31
|
+
if isinstance(handle, NestedHandleBinding):
|
32
|
+
return _resolve_nested_handle(qtype, handle)
|
33
|
+
return qtype
|
34
|
+
|
35
|
+
|
36
|
+
def _resolve_nested_handle(
|
37
|
+
qtype: QuantumType, handle: NestedHandleBinding
|
38
|
+
) -> Optional[QuantumType]:
|
39
|
+
nested_qtype = _resolve_handle_recursively(qtype, handle.base_handle)
|
40
|
+
if nested_qtype is None:
|
41
|
+
return None
|
42
|
+
if isinstance(handle, (SubscriptHandleBinding, SlicedHandleBinding)):
|
43
|
+
return _resolve_subscript_sliced_handle(nested_qtype, handle)
|
44
|
+
if TYPE_CHECKING:
|
45
|
+
assert isinstance(handle, FieldHandleBinding)
|
46
|
+
return _resolve_field_handle(nested_qtype, handle)
|
47
|
+
|
48
|
+
|
49
|
+
def _resolve_subscript_sliced_handle(
|
50
|
+
qtype: QuantumType, handle: Union[SubscriptHandleBinding, SlicedHandleBinding]
|
51
|
+
) -> Optional[QuantumType]:
|
52
|
+
if not isinstance(qtype, QuantumBitvector):
|
53
|
+
error_manager.append_error(handle, f"{qtype.type_name} is not subscriptable.")
|
54
|
+
return None
|
55
|
+
return qtype.element_type if isinstance(handle, SubscriptHandleBinding) else qtype
|
56
|
+
|
57
|
+
|
58
|
+
def _validate_field_access(qtype: QuantumType, handle: FieldHandleBinding) -> bool:
|
59
|
+
if not isinstance(qtype, TypeName):
|
60
|
+
error_manager.append_error(handle, f"{qtype.type_name} has no fields.")
|
61
|
+
return False
|
62
|
+
if qtype.name not in QMODULE.qstruct_decls:
|
63
|
+
error_manager.append_error(
|
64
|
+
handle, f"{qtype.type_name} is not a quantum struct."
|
65
|
+
)
|
66
|
+
return False
|
67
|
+
if handle.field not in qtype.fields:
|
68
|
+
error_manager.append_error(
|
69
|
+
handle,
|
70
|
+
f"Struct {qtype.type_name} has no field {handle.field!r}. "
|
71
|
+
f"Available fields: {', '.join(qtype.fields.keys())}",
|
72
|
+
)
|
73
|
+
return False
|
74
|
+
|
75
|
+
return True
|
76
|
+
|
77
|
+
|
78
|
+
def _resolve_field_handle(
|
79
|
+
qtype: QuantumType, handle: FieldHandleBinding
|
80
|
+
) -> Optional[QuantumType]:
|
81
|
+
if _validate_field_access(qtype, handle):
|
82
|
+
if TYPE_CHECKING:
|
83
|
+
assert isinstance(qtype, TypeName)
|
84
|
+
return qtype.fields[handle.field]
|
85
|
+
return None
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from classiq.interface.generator.functions.classical_type import (
|
2
|
+
ClassicalArray,
|
3
|
+
ClassicalList,
|
4
|
+
)
|
5
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
6
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
7
|
+
from classiq.interface.model.quantum_function_declaration import PositionalArg
|
8
|
+
|
9
|
+
from classiq import ClassicalParameterDeclaration
|
10
|
+
from classiq.qmod.semantics.error_manager import append_error
|
11
|
+
|
12
|
+
|
13
|
+
def validate_main_function(func: NativeFunctionDefinition) -> None:
|
14
|
+
for param in func.positional_arg_declarations:
|
15
|
+
_validate_main_param(param)
|
16
|
+
|
17
|
+
|
18
|
+
def _validate_main_param(param: PositionalArg) -> None:
|
19
|
+
if isinstance(param, ClassicalParameterDeclaration):
|
20
|
+
_validate_main_classical_param_type(param.classical_type, param.name)
|
21
|
+
|
22
|
+
|
23
|
+
def _validate_main_classical_param_type(
|
24
|
+
param: ConcreteClassicalType, param_name: str
|
25
|
+
) -> None:
|
26
|
+
if isinstance(param, ClassicalList):
|
27
|
+
append_error(
|
28
|
+
param,
|
29
|
+
f"Classical array parameter {param_name!r} of function 'main' must must "
|
30
|
+
f"specify array length",
|
31
|
+
)
|
32
|
+
if isinstance(param, ClassicalArray):
|
33
|
+
_validate_main_classical_param_type(param.element_type, param_name)
|