classiq 0.38.0__py3-none-any.whl → 0.65.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +47 -32
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
- classiq/_internals/api_wrapper.py +235 -97
- classiq/_internals/async_utils.py +1 -3
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +10 -5
- classiq/_internals/authentication/password_manager.py +18 -6
- classiq/_internals/authentication/token_manager.py +10 -5
- classiq/_internals/client.py +94 -33
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +60 -57
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +24 -19
- classiq/analyzer/analyzer_utilities.py +10 -10
- classiq/analyzer/rb.py +15 -15
- classiq/analyzer/show_interactive_hack.py +27 -4
- classiq/analyzer/url_utils.py +2 -3
- classiq/applications/__init__.py +3 -12
- classiq/applications/chemistry/__init__.py +14 -10
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
- classiq/applications/combinatorial_optimization/__init__.py +20 -6
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +4 -5
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
- classiq/applications/grover/__init__.py +9 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +6 -6
- classiq/applications/qnn/datasets/__init__.py +9 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +30 -10
- classiq/applications/qnn/torch_utils.py +4 -3
- classiq/applications/qnn/types.py +5 -5
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +3 -6
- classiq/applications/qsvm/qsvm_data_generation.py +3 -3
- classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
- classiq/execution/__init__.py +8 -3
- classiq/execution/all_hardware_devices.py +11 -0
- classiq/execution/execution_session.py +400 -0
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +197 -25
- classiq/execution/qnn.py +79 -0
- classiq/executor.py +20 -115
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +43 -13
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +28 -32
- classiq/interface/applications/qsvm.py +20 -29
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -121
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +25 -22
- classiq/interface/backend/quantum_backend_providers.py +69 -16
- classiq/interface/chemistry/fermionic_operator.py +30 -21
- classiq/interface/chemistry/ground_state_problem.py +28 -25
- classiq/interface/chemistry/molecule.py +14 -10
- classiq/interface/chemistry/operator.py +64 -231
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/debug_info.py +86 -0
- classiq/{exceptions.py → interface/exceptions.py} +37 -9
- classiq/interface/execution/iqcc.py +19 -0
- classiq/interface/execution/jobs.py +15 -12
- classiq/interface/execution/primitives.py +18 -0
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/executor/execution_preferences.py +26 -114
- classiq/interface/executor/execution_request.py +24 -46
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +17 -14
- classiq/interface/executor/quantum_code.py +28 -24
- classiq/interface/executor/quantum_instruction_set.py +2 -2
- classiq/interface/executor/register_initialization.py +11 -14
- classiq/interface/executor/result.py +83 -56
- classiq/interface/executor/vqe_result.py +10 -10
- classiq/interface/finance/function_input.py +35 -25
- classiq/interface/finance/gaussian_model_input.py +5 -5
- classiq/interface/finance/log_normal_model_input.py +4 -4
- classiq/interface/finance/model_input.py +4 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +22 -12
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +48 -69
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
- classiq/interface/generator/arith/argument_utils.py +46 -5
- classiq/interface/generator/arith/arithmetic.py +35 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
- classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
- classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
- classiq/interface/generator/arith/arithmetic_operations.py +14 -6
- classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
- classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
- classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
- classiq/interface/generator/arith/binary_ops.py +218 -130
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -25
- classiq/interface/generator/arith/logical_ops.py +14 -12
- classiq/interface/generator/arith/number_utils.py +12 -6
- classiq/interface/generator/arith/register_user_input.py +60 -37
- classiq/interface/generator/arith/unary_ops.py +49 -29
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/builtin_api_builder.py +2 -9
- classiq/interface/generator/chemistry_function_params.py +3 -3
- classiq/interface/generator/circuit_code/circuit_code.py +7 -7
- classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
- classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
- classiq/interface/generator/compiler_keywords.py +5 -1
- classiq/interface/generator/complex_type.py +13 -18
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +34 -29
- classiq/interface/generator/copy.py +47 -0
- classiq/interface/generator/custom_ansatz.py +2 -5
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
- classiq/interface/generator/expressions/enums/__init__.py +0 -10
- classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
- classiq/interface/generator/expressions/evaluated_expression.py +5 -5
- classiq/interface/generator/expressions/expression.py +26 -14
- classiq/interface/generator/expressions/expression_constants.py +9 -3
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
- classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
- classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
- classiq/interface/generator/finance.py +2 -2
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
- classiq/interface/generator/function_params.py +36 -64
- classiq/interface/generator/functions/__init__.py +0 -22
- classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
- classiq/interface/generator/functions/classical_function_declaration.py +18 -9
- classiq/interface/generator/functions/classical_type.py +47 -166
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +13 -14
- classiq/interface/generator/functions/port_declaration.py +1 -13
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +90 -0
- classiq/interface/generator/generated_circuit_data.py +153 -20
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -25
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
- classiq/interface/generator/hardware/hardware_data.py +72 -34
- classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
- classiq/interface/generator/hartree_fock.py +13 -5
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +32 -20
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +17 -15
- classiq/interface/generator/mcx.py +24 -17
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +26 -8
- classiq/interface/generator/model/model.py +27 -190
- classiq/interface/generator/model/preferences/preferences.py +115 -41
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +15 -13
- classiq/interface/generator/oracles/oracle_abc.py +7 -7
- classiq/interface/generator/partitioned_register.py +7 -7
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +41 -30
- classiq/interface/generator/qsvm.py +9 -10
- classiq/interface/generator/quantum_function_call.py +88 -73
- classiq/interface/generator/quantum_program.py +41 -24
- classiq/interface/generator/range_types.py +11 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +5 -5
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +16 -15
- classiq/interface/generator/state_preparation/metrics.py +4 -7
- classiq/interface/generator/state_preparation/state_preparation.py +25 -20
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
- classiq/interface/generator/transpiler_basis_gates.py +7 -3
- classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
- classiq/interface/generator/types/compilation_metadata.py +6 -0
- classiq/interface/generator/types/enum_declaration.py +54 -0
- classiq/interface/generator/types/qstruct_declaration.py +18 -0
- classiq/interface/generator/types/struct_declaration.py +7 -11
- classiq/interface/generator/ucc.py +5 -4
- classiq/interface/generator/unitary_gate.py +5 -5
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +7 -7
- classiq/interface/generator/validations/validator_functions.py +4 -4
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +29 -8
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +2 -2
- classiq/interface/helpers/custom_pydantic_types.py +40 -50
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +7 -5
- classiq/interface/helpers/validation_helpers.py +3 -20
- classiq/interface/helpers/versioned_model.py +1 -4
- classiq/interface/ide/ide_data.py +16 -20
- classiq/interface/ide/visual_model.py +130 -0
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +29 -69
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +32 -9
- classiq/interface/model/classical_if.py +15 -0
- classiq/interface/model/classical_parameter_declaration.py +33 -3
- classiq/interface/model/control.py +45 -0
- classiq/interface/model/handle_binding.py +298 -20
- classiq/interface/model/inplace_binary_operation.py +29 -24
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +69 -61
- classiq/interface/model/native_function_definition.py +17 -20
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/phase_operation.py +11 -0
- classiq/interface/model/port_declaration.py +27 -9
- classiq/interface/model/power.py +14 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
- classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
- classiq/interface/model/quantum_function_call.py +141 -343
- classiq/interface/model/quantum_function_declaration.py +190 -157
- classiq/interface/model/quantum_lambda_function.py +33 -32
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +177 -40
- classiq/interface/model/quantum_variable_declaration.py +3 -25
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +40 -14
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +7 -5
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +17 -21
- classiq/interface/source_reference.py +59 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
- classiq/model_expansions/capturing/__init__.py +0 -0
- classiq/model_expansions/capturing/captured_vars.py +435 -0
- classiq/model_expansions/capturing/mangling_utils.py +56 -0
- classiq/model_expansions/closure.py +171 -0
- classiq/model_expansions/debug_flag.py +3 -0
- classiq/model_expansions/evaluators/__init__.py +0 -0
- classiq/model_expansions/evaluators/arg_type_match.py +158 -0
- classiq/model_expansions/evaluators/argument_types.py +42 -0
- classiq/model_expansions/evaluators/classical_expression.py +36 -0
- classiq/model_expansions/evaluators/control.py +144 -0
- classiq/model_expansions/evaluators/parameter_types.py +226 -0
- classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
- classiq/model_expansions/evaluators/type_type_match.py +90 -0
- classiq/model_expansions/expression_evaluator.py +135 -0
- classiq/model_expansions/expression_renamer.py +76 -0
- classiq/model_expansions/function_builder.py +247 -0
- classiq/model_expansions/generative_functions.py +158 -0
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/interpreters/base_interpreter.py +263 -0
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
- classiq/model_expansions/model_tables.py +18 -0
- classiq/model_expansions/quantum_operations/__init__.py +9 -0
- classiq/model_expansions/quantum_operations/bind.py +60 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
- classiq/model_expansions/quantum_operations/classicalif.py +53 -0
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +181 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
- classiq/model_expansions/quantum_operations/repeat.py +56 -0
- classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
- classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
- classiq/model_expansions/scope.py +240 -0
- classiq/model_expansions/scope_initialization.py +150 -0
- classiq/model_expansions/sympy_conversion/__init__.py +0 -0
- classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
- classiq/model_expansions/transformers/__init__.py +0 -0
- classiq/model_expansions/transformers/ast_renamer.py +26 -0
- classiq/model_expansions/transformers/var_splitter.py +299 -0
- classiq/model_expansions/utils/__init__.py +0 -0
- classiq/model_expansions/utils/counted_name_allocator.py +11 -0
- classiq/model_expansions/utils/handles_collector.py +33 -0
- classiq/model_expansions/visitors/__init__.py +0 -0
- classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
- classiq/model_expansions/visitors/variable_references.py +144 -0
- classiq/open_library/__init__.py +4 -0
- classiq/open_library/functions/__init__.py +130 -0
- classiq/open_library/functions/amplitude_estimation.py +30 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
- classiq/open_library/functions/grover.py +157 -0
- classiq/open_library/functions/hea.py +115 -0
- classiq/open_library/functions/linear_pauli_rotation.py +82 -0
- classiq/open_library/functions/modular_exponentiation.py +201 -0
- classiq/open_library/functions/qaoa_penalty.py +117 -0
- classiq/open_library/functions/qft_functions.py +54 -0
- classiq/open_library/functions/qpe.py +46 -0
- classiq/open_library/functions/qsvt.py +331 -0
- classiq/open_library/functions/state_preparation.py +301 -0
- classiq/open_library/functions/swap_test.py +27 -0
- classiq/open_library/functions/utility_functions.py +81 -0
- classiq/open_library/functions/variational.py +52 -0
- classiq/qmod/__init__.py +10 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +36 -14
- classiq/qmod/builtins/classical_functions.py +39 -43
- classiq/qmod/builtins/constants.py +10 -0
- classiq/qmod/builtins/enums.py +208 -0
- classiq/qmod/builtins/functions/__init__.py +137 -0
- classiq/qmod/builtins/functions/allocation.py +150 -0
- classiq/qmod/builtins/functions/arithmetic.py +55 -0
- classiq/qmod/builtins/functions/benchmarking.py +8 -0
- classiq/qmod/builtins/functions/chemistry.py +91 -0
- classiq/qmod/builtins/functions/exponentiation.py +105 -0
- classiq/qmod/builtins/functions/finance.py +34 -0
- classiq/qmod/builtins/functions/operators.py +16 -0
- classiq/qmod/builtins/functions/qsvm.py +24 -0
- classiq/qmod/builtins/functions/standard_gates.py +651 -0
- classiq/qmod/builtins/operations.py +373 -40
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +4 -8
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +143 -101
- classiq/qmod/expression_query.py +20 -4
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +18 -6
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +16 -11
- classiq/qmod/native/pretty_printer.py +187 -97
- classiq/qmod/pretty_print/__init__.py +7 -0
- classiq/qmod/pretty_print/expression_to_python.py +222 -0
- classiq/qmod/pretty_print/pretty_printer.py +572 -0
- classiq/qmod/python_classical_type.py +67 -0
- classiq/qmod/qfunc.py +60 -8
- classiq/qmod/qmod_constant.py +93 -26
- classiq/qmod/qmod_parameter.py +68 -59
- classiq/qmod/qmod_variable.py +468 -155
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +269 -96
- classiq/qmod/quantum_function.py +196 -41
- classiq/qmod/semantics/__init__.py +0 -0
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
- classiq/qmod/semantics/error_manager.py +88 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +384 -0
- classiq/qmod/semantics/validation/__init__.py +0 -0
- classiq/qmod/semantics/validation/constants_validation.py +16 -0
- classiq/qmod/semantics/validation/func_call_validation.py +99 -0
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +128 -0
- classiq/qmod/symbolic.py +147 -123
- classiq/qmod/symbolic_expr.py +27 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +98 -4
- classiq/qmod/write_qmod.py +17 -3
- classiq/synthesis.py +210 -22
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
- classiq-0.65.3.dist-info/RECORD +521 -0
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -25
- classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
- classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/interface/executor/aws_execution_cost.py +0 -73
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
- classiq/interface/generator/functions/foreign_function_definition.py +0 -114
- classiq/interface/generator/functions/function_implementation.py +0 -107
- classiq/interface/generator/functions/native_function_definition.py +0 -155
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -44
- classiq/interface/generator/functions/register_mapping_data.py +0 -106
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -74
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/call_synthesis_data.py +0 -68
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -94
- classiq/interface/model/resolvers/function_call_resolver.py +0 -43
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -156
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -462
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -229
- classiq/qmod/builtins/functions.py +0 -913
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -205
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- classiq-0.38.0.dist-info/RECORD +0 -454
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
- /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
- /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
- /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,226 @@
|
|
1
|
+
from typing import Union
|
2
|
+
|
3
|
+
from classiq.interface.exceptions import (
|
4
|
+
ClassiqExpansionError,
|
5
|
+
ClassiqInternalExpansionError,
|
6
|
+
)
|
7
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
8
|
+
from classiq.interface.generator.functions.port_declaration import (
|
9
|
+
PortDeclarationDirection,
|
10
|
+
)
|
11
|
+
from classiq.interface.generator.functions.type_name import (
|
12
|
+
TypeName,
|
13
|
+
)
|
14
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
15
|
+
from classiq.interface.model.quantum_function_declaration import (
|
16
|
+
PositionalArg,
|
17
|
+
QuantumOperandDeclaration,
|
18
|
+
)
|
19
|
+
from classiq.interface.model.quantum_type import (
|
20
|
+
QuantumBit,
|
21
|
+
QuantumBitvector,
|
22
|
+
QuantumNumeric,
|
23
|
+
QuantumType,
|
24
|
+
)
|
25
|
+
|
26
|
+
from classiq.model_expansions.closure import FunctionClosure
|
27
|
+
from classiq.model_expansions.evaluators.arg_type_match import check_type_match
|
28
|
+
from classiq.model_expansions.evaluators.classical_expression import (
|
29
|
+
evaluate_classical_expression,
|
30
|
+
)
|
31
|
+
from classiq.model_expansions.evaluators.quantum_type_utils import (
|
32
|
+
copy_type_information,
|
33
|
+
set_element_type,
|
34
|
+
set_fraction_digits,
|
35
|
+
set_is_signed,
|
36
|
+
set_length,
|
37
|
+
set_size,
|
38
|
+
)
|
39
|
+
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
40
|
+
|
41
|
+
|
42
|
+
def evaluate_parameter_types_from_args(
|
43
|
+
closure: FunctionClosure, signature_scope: Scope, arguments: list[Evaluated]
|
44
|
+
) -> list[PositionalArg]:
|
45
|
+
parameters = closure.positional_arg_declarations
|
46
|
+
function_name = closure.name
|
47
|
+
check_type_match(parameters, arguments, function_name)
|
48
|
+
|
49
|
+
for parameter, argument in zip(parameters, arguments):
|
50
|
+
_update_scope(parameter, argument, closure)
|
51
|
+
|
52
|
+
parameter_names = {parameter.name for parameter in parameters}
|
53
|
+
for parameter in parameters:
|
54
|
+
if isinstance(parameter, QuantumOperandDeclaration):
|
55
|
+
parameter_value = closure.scope[parameter.name].value
|
56
|
+
_update_operand_signature_environment(
|
57
|
+
parameter_value, parameter_names, closure
|
58
|
+
)
|
59
|
+
|
60
|
+
return [
|
61
|
+
_evaluate_type_from_arg(
|
62
|
+
parameter, argument, Scope(parent=closure.scope | signature_scope)
|
63
|
+
)
|
64
|
+
for parameter, argument in zip(parameters, arguments)
|
65
|
+
]
|
66
|
+
|
67
|
+
|
68
|
+
def _update_scope(
|
69
|
+
parameter: PositionalArg, argument: Evaluated, closure: FunctionClosure
|
70
|
+
) -> None:
|
71
|
+
if not isinstance(parameter, PortDeclaration):
|
72
|
+
closure.scope[parameter.name] = argument
|
73
|
+
return
|
74
|
+
if parameter.direction is PortDeclarationDirection.Output:
|
75
|
+
return
|
76
|
+
quantum_symbol = argument.as_type(QuantumSymbol)
|
77
|
+
if not quantum_symbol.quantum_type.has_size_in_bits:
|
78
|
+
raise ClassiqExpansionError(
|
79
|
+
f"Argument {str(quantum_symbol.emit())!r} to function {closure.name!r} "
|
80
|
+
f"is not initialized"
|
81
|
+
)
|
82
|
+
casted_argument = _cast(
|
83
|
+
parameter.quantum_type,
|
84
|
+
quantum_symbol,
|
85
|
+
parameter.name,
|
86
|
+
)
|
87
|
+
closure.scope[parameter.name] = Evaluated(
|
88
|
+
value=casted_argument, defining_function=closure
|
89
|
+
)
|
90
|
+
|
91
|
+
|
92
|
+
NestedFunctionClosureT = Union[FunctionClosure, list["NestedFunctionClosureT"]]
|
93
|
+
|
94
|
+
|
95
|
+
def _update_operand_signature_environment(
|
96
|
+
operand_val: NestedFunctionClosureT,
|
97
|
+
parameter_names: set[str],
|
98
|
+
closure: FunctionClosure,
|
99
|
+
) -> None:
|
100
|
+
# We update the environment (parent) of the operand by adding closure.scope.data,
|
101
|
+
# which includes the parameters that appear in the function's signature only.
|
102
|
+
if isinstance(operand_val, list):
|
103
|
+
for operand in operand_val:
|
104
|
+
_update_operand_signature_environment(operand, parameter_names, closure)
|
105
|
+
return
|
106
|
+
if not isinstance(operand_val, FunctionClosure):
|
107
|
+
raise ClassiqInternalExpansionError
|
108
|
+
operand_val.signature_scope.update(
|
109
|
+
{
|
110
|
+
identifier: value
|
111
|
+
for identifier, value in closure.scope.data.items()
|
112
|
+
if identifier in parameter_names
|
113
|
+
}
|
114
|
+
)
|
115
|
+
|
116
|
+
|
117
|
+
def _cast(
|
118
|
+
quantum_type: QuantumType, quantum_symbol: QuantumSymbol, param_name: str
|
119
|
+
) -> QuantumSymbol:
|
120
|
+
updated_quantum_type = quantum_type.model_copy()
|
121
|
+
_inject_quantum_arg_info_to_type(updated_quantum_type, quantum_symbol, param_name)
|
122
|
+
return QuantumSymbol(
|
123
|
+
handle=quantum_symbol.handle, quantum_type=updated_quantum_type
|
124
|
+
)
|
125
|
+
|
126
|
+
|
127
|
+
def _evaluate_type_from_arg(
|
128
|
+
parameter: PositionalArg, argument: Evaluated, inner_scope: Scope
|
129
|
+
) -> PositionalArg:
|
130
|
+
if not isinstance(parameter, PortDeclaration):
|
131
|
+
return parameter
|
132
|
+
|
133
|
+
updated_quantum_type: QuantumType = evaluate_type_in_quantum_symbol(
|
134
|
+
parameter.quantum_type.model_copy(), inner_scope, parameter.name
|
135
|
+
)
|
136
|
+
if parameter.direction != PortDeclarationDirection.Output:
|
137
|
+
updated_quantum_type = _inject_quantum_arg_info_to_type(
|
138
|
+
updated_quantum_type, argument.as_type(QuantumSymbol), parameter.name
|
139
|
+
)
|
140
|
+
return parameter.model_copy(update={"quantum_type": updated_quantum_type})
|
141
|
+
|
142
|
+
|
143
|
+
def evaluate_type_in_quantum_symbol(
|
144
|
+
type_to_update: QuantumType, scope: Scope, param_name: str
|
145
|
+
) -> ConcreteQuantumType:
|
146
|
+
if isinstance(type_to_update, QuantumBitvector):
|
147
|
+
return _evaluate_qarray_in_quantum_symbol(type_to_update, scope, param_name)
|
148
|
+
elif isinstance(type_to_update, QuantumNumeric):
|
149
|
+
return _evaluate_qnum_in_quantum_symbol(type_to_update, scope, param_name)
|
150
|
+
elif isinstance(type_to_update, TypeName):
|
151
|
+
return _evaluate_qstruct_in_quantum_symbol(type_to_update, scope, param_name)
|
152
|
+
else:
|
153
|
+
assert isinstance(type_to_update, QuantumBit)
|
154
|
+
return type_to_update
|
155
|
+
|
156
|
+
|
157
|
+
def _evaluate_qarray_in_quantum_symbol(
|
158
|
+
type_to_update: QuantumBitvector, scope: Scope, param_name: str
|
159
|
+
) -> QuantumBitvector:
|
160
|
+
new_element_type = evaluate_type_in_quantum_symbol(
|
161
|
+
type_to_update.element_type, scope, param_name
|
162
|
+
)
|
163
|
+
set_element_type(type_to_update, new_element_type)
|
164
|
+
if type_to_update.length is not None:
|
165
|
+
new_length = evaluate_classical_expression(
|
166
|
+
type_to_update.length, scope
|
167
|
+
).as_type(int)
|
168
|
+
set_length(type_to_update, new_length)
|
169
|
+
return type_to_update
|
170
|
+
|
171
|
+
|
172
|
+
def _evaluate_qnum_in_quantum_symbol(
|
173
|
+
type_to_update: QuantumNumeric, scope: Scope, param_name: str
|
174
|
+
) -> QuantumNumeric:
|
175
|
+
if type_to_update.is_signed is not None:
|
176
|
+
new_is_sign = evaluate_classical_expression(
|
177
|
+
type_to_update.is_signed, scope
|
178
|
+
).as_type(bool)
|
179
|
+
set_is_signed(type_to_update, new_is_sign, param_name)
|
180
|
+
if type_to_update.fraction_digits is not None:
|
181
|
+
new_fraction_digits = evaluate_classical_expression(
|
182
|
+
type_to_update.fraction_digits, scope
|
183
|
+
).as_type(int)
|
184
|
+
set_fraction_digits(type_to_update, new_fraction_digits, param_name)
|
185
|
+
if type_to_update.size is not None:
|
186
|
+
new_size = evaluate_classical_expression(type_to_update.size, scope).as_type(
|
187
|
+
int
|
188
|
+
)
|
189
|
+
set_size(type_to_update, new_size, param_name)
|
190
|
+
return type_to_update
|
191
|
+
|
192
|
+
|
193
|
+
def _evaluate_qstruct_in_quantum_symbol(
|
194
|
+
type_to_update: TypeName, scope: Scope, param_name: str
|
195
|
+
) -> TypeName:
|
196
|
+
new_fields = {
|
197
|
+
field_name: evaluate_type_in_quantum_symbol(field_type, scope, param_name)
|
198
|
+
for field_name, field_type in type_to_update.fields.items()
|
199
|
+
}
|
200
|
+
type_to_update.set_fields(new_fields)
|
201
|
+
return type_to_update
|
202
|
+
|
203
|
+
|
204
|
+
def evaluate_types_in_quantum_symbols(
|
205
|
+
symbols: list[QuantumSymbol], scope: Scope
|
206
|
+
) -> list[QuantumSymbol]:
|
207
|
+
return [
|
208
|
+
QuantumSymbol(
|
209
|
+
handle=symbol.handle,
|
210
|
+
quantum_type=evaluate_type_in_quantum_symbol(
|
211
|
+
symbol.quantum_type, scope, str(symbol.handle)
|
212
|
+
),
|
213
|
+
)
|
214
|
+
for symbol in symbols
|
215
|
+
]
|
216
|
+
|
217
|
+
|
218
|
+
def _inject_quantum_arg_info_to_type(
|
219
|
+
parameter_type: QuantumType, quantum_symbol: QuantumSymbol, param_name: str
|
220
|
+
) -> QuantumType:
|
221
|
+
copy_type_information(
|
222
|
+
quantum_symbol.quantum_type,
|
223
|
+
parameter_type,
|
224
|
+
param_name,
|
225
|
+
)
|
226
|
+
return parameter_type
|
@@ -0,0 +1,239 @@
|
|
1
|
+
from collections.abc import Sequence
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from classiq.interface.exceptions import (
|
5
|
+
ClassiqExpansionError,
|
6
|
+
ClassiqInternalExpansionError,
|
7
|
+
)
|
8
|
+
from classiq.interface.generator.expressions.expression import Expression
|
9
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
10
|
+
from classiq.interface.generator.functions.type_name import (
|
11
|
+
TypeName,
|
12
|
+
)
|
13
|
+
from classiq.interface.model.bind_operation import BindOperation
|
14
|
+
from classiq.interface.model.inplace_binary_operation import BinaryOperation
|
15
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
16
|
+
from classiq.interface.model.quantum_function_declaration import PositionalArg
|
17
|
+
from classiq.interface.model.quantum_type import (
|
18
|
+
QuantumBit,
|
19
|
+
QuantumBitvector,
|
20
|
+
QuantumNumeric,
|
21
|
+
QuantumScalar,
|
22
|
+
QuantumType,
|
23
|
+
)
|
24
|
+
|
25
|
+
from classiq.model_expansions.scope import QuantumSymbol, Scope
|
26
|
+
|
27
|
+
|
28
|
+
def copy_type_information(
|
29
|
+
from_type: QuantumType,
|
30
|
+
to_type: QuantumType,
|
31
|
+
to_param_name: str,
|
32
|
+
) -> None:
|
33
|
+
if isinstance(to_type, QuantumBit):
|
34
|
+
set_size(to_type, from_type.size_in_bits, to_param_name)
|
35
|
+
elif isinstance(to_type, QuantumNumeric):
|
36
|
+
set_is_signed(to_type, getattr(from_type, "sign_value", None), to_param_name)
|
37
|
+
set_fraction_digits(
|
38
|
+
to_type,
|
39
|
+
getattr(from_type, "fraction_digits_value", None),
|
40
|
+
to_param_name,
|
41
|
+
)
|
42
|
+
set_size(to_type, from_type.size_in_bits, to_param_name)
|
43
|
+
elif isinstance(to_type, QuantumBitvector):
|
44
|
+
if isinstance(from_type, QuantumBitvector) and type( # noqa: E721
|
45
|
+
from_type.element_type
|
46
|
+
) == type(to_type.element_type):
|
47
|
+
copy_type_information(
|
48
|
+
from_type.element_type, to_type.element_type, to_param_name
|
49
|
+
)
|
50
|
+
set_size(to_type, from_type.size_in_bits, to_param_name)
|
51
|
+
elif isinstance(to_type, TypeName):
|
52
|
+
if isinstance(from_type, TypeName) and from_type.name == to_type.name:
|
53
|
+
for field in from_type.fields:
|
54
|
+
copy_type_information(
|
55
|
+
from_type.fields[field], to_type.fields[field], to_param_name
|
56
|
+
)
|
57
|
+
set_size(to_type, from_type.size_in_bits, to_param_name)
|
58
|
+
else:
|
59
|
+
raise ClassiqInternalExpansionError
|
60
|
+
|
61
|
+
|
62
|
+
def set_size(quantum_type: QuantumType, size: int, param_name: str) -> None:
|
63
|
+
if size <= 0:
|
64
|
+
raise ClassiqExpansionError(
|
65
|
+
f"Size for {param_name!r} was deduced to be non-positive: {size!r}"
|
66
|
+
)
|
67
|
+
|
68
|
+
if quantum_type.has_size_in_bits and quantum_type.size_in_bits != size:
|
69
|
+
raise ClassiqExpansionError(
|
70
|
+
f"Size mismatch for port {param_name!r} between declared size {quantum_type.size_in_bits} and assigned size {size}"
|
71
|
+
)
|
72
|
+
|
73
|
+
if isinstance(quantum_type, QuantumNumeric):
|
74
|
+
quantum_type.size = Expression(expr=str(size))
|
75
|
+
if not quantum_type.has_sign or not quantum_type.has_fraction_digits:
|
76
|
+
set_is_signed(quantum_type, False, param_name)
|
77
|
+
set_fraction_digits(quantum_type, 0, param_name)
|
78
|
+
elif isinstance(quantum_type, QuantumBitvector):
|
79
|
+
if quantum_type.has_length:
|
80
|
+
if size % quantum_type.length_value != 0:
|
81
|
+
raise ClassiqExpansionError(
|
82
|
+
f"Size mismatch for port {param_name!r}. Cannot fit {size} "
|
83
|
+
f"qubits into an array of {quantum_type.length_value} elements."
|
84
|
+
)
|
85
|
+
set_size(
|
86
|
+
quantum_type.element_type,
|
87
|
+
size // quantum_type.length_value,
|
88
|
+
param_name,
|
89
|
+
)
|
90
|
+
set_length_by_size(quantum_type, size, param_name)
|
91
|
+
elif isinstance(quantum_type, TypeName):
|
92
|
+
fields_without_size = [
|
93
|
+
field_type
|
94
|
+
for field_type in quantum_type.fields.values()
|
95
|
+
if not field_type.has_size_in_bits
|
96
|
+
]
|
97
|
+
if len(fields_without_size) > 1:
|
98
|
+
raise ClassiqInternalExpansionError(
|
99
|
+
f"QuantumStruct should have at most one field without "
|
100
|
+
f"predetermined size. Found {fields_without_size}."
|
101
|
+
)
|
102
|
+
if len(fields_without_size) == 1:
|
103
|
+
predetermined_size_part = sum(
|
104
|
+
field_type.size_in_bits if field_type.has_size_in_bits else 0
|
105
|
+
for field_type in quantum_type.fields.values()
|
106
|
+
)
|
107
|
+
set_size(fields_without_size[0], size - predetermined_size_part, param_name)
|
108
|
+
|
109
|
+
|
110
|
+
def set_fraction_digits(
|
111
|
+
quantum_numeric: QuantumNumeric, fraction_digits: Optional[int], param_name: str
|
112
|
+
) -> None:
|
113
|
+
if fraction_digits is not None and fraction_digits < 0:
|
114
|
+
raise ClassiqExpansionError(
|
115
|
+
f"Number of fraction digits for {param_name!r} was deduced to be negative: "
|
116
|
+
f"{fraction_digits!r}"
|
117
|
+
)
|
118
|
+
|
119
|
+
if (
|
120
|
+
fraction_digits is not None
|
121
|
+
and quantum_numeric.fraction_digits is not None
|
122
|
+
and quantum_numeric.fraction_digits.is_evaluated()
|
123
|
+
and quantum_numeric.fraction_digits_value != fraction_digits
|
124
|
+
):
|
125
|
+
raise ClassiqExpansionError(
|
126
|
+
f"Fraction digits mismatch for port {param_name!r} between declared "
|
127
|
+
f"fraction digits {quantum_numeric.fraction_digits_value!r} and assigned fraction "
|
128
|
+
f"digits {fraction_digits!r}"
|
129
|
+
)
|
130
|
+
|
131
|
+
if not (
|
132
|
+
quantum_numeric.fraction_digits is not None
|
133
|
+
and quantum_numeric.fraction_digits.is_evaluated()
|
134
|
+
):
|
135
|
+
quantum_numeric.fraction_digits = Expression(expr=str(fraction_digits or 0))
|
136
|
+
|
137
|
+
|
138
|
+
def set_is_signed(
|
139
|
+
quantum_numeric: QuantumNumeric, is_signed: Optional[bool], param_name: str
|
140
|
+
) -> None:
|
141
|
+
if (
|
142
|
+
is_signed is not None
|
143
|
+
and quantum_numeric.is_signed is not None
|
144
|
+
and quantum_numeric.is_signed.is_evaluated()
|
145
|
+
and quantum_numeric.sign_value != is_signed
|
146
|
+
):
|
147
|
+
raise ClassiqExpansionError(
|
148
|
+
f"Sign mismatch for port {param_name!r} between declared sign {quantum_numeric.sign_value!r} and assigned sign {is_signed!r}"
|
149
|
+
)
|
150
|
+
|
151
|
+
if not (
|
152
|
+
quantum_numeric.is_signed is not None
|
153
|
+
and quantum_numeric.is_signed.is_evaluated()
|
154
|
+
):
|
155
|
+
quantum_numeric.is_signed = Expression(expr=str(is_signed or False))
|
156
|
+
|
157
|
+
|
158
|
+
def set_element_type(
|
159
|
+
quantum_array: QuantumBitvector, element_type: ConcreteQuantumType
|
160
|
+
) -> None:
|
161
|
+
quantum_array.element_type = element_type
|
162
|
+
|
163
|
+
|
164
|
+
def set_length(quantum_array: QuantumBitvector, length: int) -> None:
|
165
|
+
quantum_array.length = Expression(expr=str(length))
|
166
|
+
|
167
|
+
|
168
|
+
def set_length_by_size(
|
169
|
+
quantum_array: QuantumBitvector, size: int, param_name: str
|
170
|
+
) -> None:
|
171
|
+
if size <= 0:
|
172
|
+
raise ClassiqExpansionError(
|
173
|
+
f"Size for {param_name!r} was deduced to be non-positive: {size!r}"
|
174
|
+
)
|
175
|
+
|
176
|
+
if quantum_array.has_size_in_bits and quantum_array.size_in_bits != size:
|
177
|
+
raise ClassiqExpansionError(
|
178
|
+
f"Size mismatch for port {param_name!r} between declared size "
|
179
|
+
f"{quantum_array.size_in_bits} ({quantum_array.length_value} elements of "
|
180
|
+
f"size {quantum_array.element_type.size_in_bits}) and assigned size {size}."
|
181
|
+
)
|
182
|
+
|
183
|
+
if not quantum_array.element_type.has_size_in_bits:
|
184
|
+
raise ClassiqExpansionError(
|
185
|
+
f"Could not infer element size for array {param_name!r}."
|
186
|
+
)
|
187
|
+
element_size = quantum_array.element_type.size_in_bits
|
188
|
+
|
189
|
+
if size % element_size != 0:
|
190
|
+
raise ClassiqExpansionError(
|
191
|
+
f"Size mismatch for port {param_name!r}. Cannot fit elements of type "
|
192
|
+
f"{quantum_array.element_type.qmod_type_name} (size {element_size}) into "
|
193
|
+
f"{size} qubits."
|
194
|
+
)
|
195
|
+
|
196
|
+
quantum_array.length = Expression(expr=str(size // element_size))
|
197
|
+
|
198
|
+
|
199
|
+
def validate_bind_targets(bind: BindOperation, scope: Scope) -> None:
|
200
|
+
illegal_qnum_bind_targets = []
|
201
|
+
for out_handle in bind.out_handles:
|
202
|
+
out_var = scope[out_handle.name].as_type(QuantumSymbol)
|
203
|
+
out_var_type = out_var.quantum_type
|
204
|
+
if not isinstance(out_var_type, QuantumNumeric):
|
205
|
+
continue
|
206
|
+
if not out_var_type.has_size_in_bits:
|
207
|
+
illegal_qnum_bind_targets.append(str(out_var.handle))
|
208
|
+
elif not out_var_type.has_sign:
|
209
|
+
assert not out_var_type.has_fraction_digits
|
210
|
+
illegal_qnum_bind_targets.append(str(out_var.handle))
|
211
|
+
if len(illegal_qnum_bind_targets) > 0:
|
212
|
+
raise ClassiqExpansionError(
|
213
|
+
f"QNum bind targets {illegal_qnum_bind_targets!r} must be declared or initialized with size, sign, and fraction digits"
|
214
|
+
)
|
215
|
+
|
216
|
+
|
217
|
+
def get_inplace_op_scalar_as_numeric(
|
218
|
+
var: QuantumSymbol, operation: BinaryOperation, var_kind: str
|
219
|
+
) -> QuantumNumeric:
|
220
|
+
if not isinstance(var.quantum_type, QuantumScalar):
|
221
|
+
raise ClassiqExpansionError(
|
222
|
+
f"Cannot perform inplace {operation.name.lower()} with non-scalar {var_kind} {var.handle}"
|
223
|
+
)
|
224
|
+
if isinstance(var.quantum_type, QuantumNumeric):
|
225
|
+
return var.quantum_type
|
226
|
+
if isinstance(var.quantum_type, QuantumBit):
|
227
|
+
return QuantumNumeric(
|
228
|
+
size=Expression(expr="1"),
|
229
|
+
is_signed=Expression(expr="False"),
|
230
|
+
fraction_digits=Expression(expr="0"),
|
231
|
+
)
|
232
|
+
raise ClassiqInternalExpansionError(f"Unexpected scalar type {var.quantum_type}")
|
233
|
+
|
234
|
+
|
235
|
+
def is_signature_monomorphic(params: Sequence[PositionalArg]) -> bool:
|
236
|
+
return all(
|
237
|
+
isinstance(param, PortDeclaration) and param.quantum_type.is_evaluated
|
238
|
+
for param in params
|
239
|
+
)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
from collections.abc import Sequence
|
2
|
+
|
3
|
+
from classiq.interface.exceptions import (
|
4
|
+
ClassiqExpansionError,
|
5
|
+
ClassiqInternalExpansionError,
|
6
|
+
)
|
7
|
+
from classiq.interface.model.classical_parameter_declaration import (
|
8
|
+
AnonClassicalParameterDeclaration,
|
9
|
+
)
|
10
|
+
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
11
|
+
from classiq.interface.model.quantum_function_declaration import (
|
12
|
+
AnonPositionalArg,
|
13
|
+
AnonQuantumOperandDeclaration,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
def check_signature_match(
|
18
|
+
decl_params: Sequence[AnonPositionalArg],
|
19
|
+
op_params: Sequence[AnonPositionalArg],
|
20
|
+
location_str: str,
|
21
|
+
) -> None:
|
22
|
+
if len(decl_params) != len(op_params):
|
23
|
+
raise ClassiqExpansionError(
|
24
|
+
f"{location_str} should have {len(decl_params)} parameters, "
|
25
|
+
f"not {len(op_params)}"
|
26
|
+
)
|
27
|
+
for idx, (decl_param, op_param) in enumerate(zip(decl_params, op_params)):
|
28
|
+
message_prefix = f"Argument {idx} in {location_str} has incompatible type; "
|
29
|
+
_check_type_match(op_param, decl_param, location_str, message_prefix)
|
30
|
+
|
31
|
+
|
32
|
+
def _check_type_match(
|
33
|
+
op_param: AnonPositionalArg,
|
34
|
+
decl_param: AnonPositionalArg,
|
35
|
+
location_str: str,
|
36
|
+
message_prefix: str,
|
37
|
+
) -> None:
|
38
|
+
if isinstance(decl_param, AnonPortDeclaration):
|
39
|
+
error_message = message_prefix + "expected quantum parameter"
|
40
|
+
_check_qvar_type_match(op_param, error_message)
|
41
|
+
elif isinstance(decl_param, AnonQuantumOperandDeclaration):
|
42
|
+
if decl_param.is_list:
|
43
|
+
error_message = message_prefix + "expected operand list parameter"
|
44
|
+
else:
|
45
|
+
error_message = message_prefix + "expected operand parameter"
|
46
|
+
_check_operand_type_match(op_param, decl_param, location_str, error_message)
|
47
|
+
elif isinstance(decl_param, AnonClassicalParameterDeclaration):
|
48
|
+
error_message = (
|
49
|
+
message_prefix + f"expected classical {decl_param.classical_type} parameter"
|
50
|
+
)
|
51
|
+
_check_classical_type_match(op_param, decl_param, error_message)
|
52
|
+
else:
|
53
|
+
raise ClassiqInternalExpansionError(
|
54
|
+
f"unexpected parameter declaration type: {type(decl_param).__name__}"
|
55
|
+
)
|
56
|
+
|
57
|
+
|
58
|
+
def _check_qvar_type_match(op_param: AnonPositionalArg, error_message: str) -> None:
|
59
|
+
if not isinstance(op_param, AnonPortDeclaration):
|
60
|
+
raise ClassiqExpansionError(error_message)
|
61
|
+
|
62
|
+
|
63
|
+
def _check_operand_type_match(
|
64
|
+
op_param: AnonPositionalArg,
|
65
|
+
decl_param: AnonQuantumOperandDeclaration,
|
66
|
+
location_str: str,
|
67
|
+
error_message: str,
|
68
|
+
) -> None:
|
69
|
+
if (
|
70
|
+
not isinstance(op_param, AnonQuantumOperandDeclaration)
|
71
|
+
or decl_param.is_list ^ op_param.is_list
|
72
|
+
):
|
73
|
+
raise ClassiqExpansionError(error_message)
|
74
|
+
check_signature_match(
|
75
|
+
decl_param.positional_arg_declarations,
|
76
|
+
op_param.positional_arg_declarations,
|
77
|
+
f"operand {decl_param.name} in {location_str}",
|
78
|
+
)
|
79
|
+
|
80
|
+
|
81
|
+
def _check_classical_type_match(
|
82
|
+
op_param: AnonPositionalArg,
|
83
|
+
decl_param: AnonClassicalParameterDeclaration,
|
84
|
+
error_message: str,
|
85
|
+
) -> None:
|
86
|
+
if (
|
87
|
+
not isinstance(op_param, AnonClassicalParameterDeclaration)
|
88
|
+
or decl_param.classical_type != op_param.classical_type
|
89
|
+
):
|
90
|
+
raise ClassiqExpansionError(error_message)
|
@@ -0,0 +1,135 @@
|
|
1
|
+
import ast
|
2
|
+
import re
|
3
|
+
from collections.abc import Mapping
|
4
|
+
from enum import EnumMeta
|
5
|
+
from typing import Any, Optional
|
6
|
+
|
7
|
+
from sympy import sympify
|
8
|
+
|
9
|
+
from classiq.interface.exceptions import ClassiqExpansionError
|
10
|
+
from classiq.interface.generator.constant import Constant
|
11
|
+
from classiq.interface.generator.expressions.evaluated_expression import (
|
12
|
+
EvaluatedExpression,
|
13
|
+
)
|
14
|
+
from classiq.interface.generator.expressions.expression import Expression
|
15
|
+
from classiq.interface.generator.expressions.expression_constants import (
|
16
|
+
CPARAM_EXECUTION_SUFFIX_PATTERN,
|
17
|
+
)
|
18
|
+
from classiq.interface.generator.expressions.expression_types import ExpressionValue
|
19
|
+
from classiq.interface.generator.expressions.sympy_supported_expressions import (
|
20
|
+
SYMPY_SUPPORTED_EXPRESSIONS,
|
21
|
+
)
|
22
|
+
|
23
|
+
from classiq.model_expansions.atomic_expression_functions_defs import (
|
24
|
+
ATOMIC_EXPRESSION_FUNCTIONS,
|
25
|
+
qmod_val_to_python,
|
26
|
+
)
|
27
|
+
from classiq.model_expansions.sympy_conversion.expression_to_sympy import (
|
28
|
+
translate_to_sympy,
|
29
|
+
)
|
30
|
+
from classiq.model_expansions.sympy_conversion.sympy_to_python import sympy_to_python
|
31
|
+
from classiq.qmod import symbolic
|
32
|
+
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
33
|
+
from classiq.qmod.model_state_container import QMODULE
|
34
|
+
|
35
|
+
|
36
|
+
def evaluate_constants(constants: list[Constant]) -> dict[str, EvaluatedExpression]:
|
37
|
+
result: dict[str, EvaluatedExpression] = {}
|
38
|
+
for constant in constants:
|
39
|
+
result[constant.name] = evaluate(constant.value, result)
|
40
|
+
return result
|
41
|
+
|
42
|
+
|
43
|
+
def evaluate_constants_as_python(constants: list[Constant]) -> dict[str, Any]:
|
44
|
+
evaluated = evaluate_constants(constants)
|
45
|
+
return {
|
46
|
+
constant.name: qmod_val_to_python(
|
47
|
+
evaluated[constant.name].value, constant.const_type
|
48
|
+
)
|
49
|
+
for constant in constants
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
def evaluate(
|
54
|
+
expr: Expression,
|
55
|
+
locals_dict: Mapping[str, EvaluatedExpression],
|
56
|
+
uninitialized_locals: Optional[set[str]] = None,
|
57
|
+
) -> EvaluatedExpression:
|
58
|
+
model_locals: dict[str, ExpressionValue] = {}
|
59
|
+
model_locals.update(ATOMIC_EXPRESSION_FUNCTIONS)
|
60
|
+
model_locals.update(
|
61
|
+
{
|
62
|
+
enum_decl.name: enum_decl.create_enum()
|
63
|
+
for enum_decl in (QMODULE.enum_decls | BUILTIN_ENUM_DECLARATIONS).values()
|
64
|
+
}
|
65
|
+
)
|
66
|
+
# locals override builtin-functions
|
67
|
+
model_locals.update({name: expr.value for name, expr in locals_dict.items()})
|
68
|
+
uninitialized_locals = uninitialized_locals or set()
|
69
|
+
|
70
|
+
_validate_undefined_vars(expr.expr, model_locals, uninitialized_locals)
|
71
|
+
|
72
|
+
sympy_expr = translate_to_sympy(expr.expr)
|
73
|
+
try:
|
74
|
+
sympify_result = sympify(sympy_expr, locals=model_locals)
|
75
|
+
except (TypeError, IndexError) as e:
|
76
|
+
raise ClassiqExpansionError(str(e)) from None
|
77
|
+
except AttributeError as e:
|
78
|
+
if isinstance(e.obj, EnumMeta):
|
79
|
+
raise ClassiqExpansionError(
|
80
|
+
f"Enum {e.obj.__name__} has no member {e.name!r}. Available members: "
|
81
|
+
f"{', '.join(e.obj.__members__)}"
|
82
|
+
) from e
|
83
|
+
raise
|
84
|
+
|
85
|
+
return EvaluatedExpression(
|
86
|
+
value=sympy_to_python(sympify_result, locals=model_locals)
|
87
|
+
)
|
88
|
+
|
89
|
+
|
90
|
+
def _validate_undefined_vars(
|
91
|
+
expr: str,
|
92
|
+
model_locals: dict[str, ExpressionValue],
|
93
|
+
uninitialized_locals: Optional[set[str]],
|
94
|
+
) -> None:
|
95
|
+
uninitialized_locals = uninitialized_locals or set()
|
96
|
+
id_visitor = _VarsCollector()
|
97
|
+
id_visitor.visit(ast.parse(expr))
|
98
|
+
identifiers = id_visitor.vars
|
99
|
+
undefined_vars = (
|
100
|
+
identifiers
|
101
|
+
- model_locals.keys()
|
102
|
+
- set(SYMPY_SUPPORTED_EXPRESSIONS)
|
103
|
+
- set(symbolic.__all__)
|
104
|
+
- uninitialized_locals
|
105
|
+
)
|
106
|
+
|
107
|
+
# Ignore expanded execution parameters
|
108
|
+
undefined_vars = {
|
109
|
+
var
|
110
|
+
for var in undefined_vars
|
111
|
+
if not re.search(CPARAM_EXECUTION_SUFFIX_PATTERN, var)
|
112
|
+
}
|
113
|
+
|
114
|
+
if len(undefined_vars) == 1:
|
115
|
+
undefined_var = undefined_vars.__iter__().__next__()
|
116
|
+
raise ClassiqExpansionError(f"Variable {undefined_var!r} is undefined")
|
117
|
+
elif len(undefined_vars) > 1:
|
118
|
+
raise ClassiqExpansionError(f"Variables {list(undefined_vars)} are undefined")
|
119
|
+
|
120
|
+
|
121
|
+
class _VarsCollector(ast.NodeTransformer):
|
122
|
+
def __init__(self) -> None:
|
123
|
+
self.vars: set[str] = set()
|
124
|
+
|
125
|
+
def visit_Name(self, node: ast.Name) -> None:
|
126
|
+
self.vars.add(node.id)
|
127
|
+
|
128
|
+
def visit_Call(self, node: ast.Call) -> None:
|
129
|
+
func = node.func
|
130
|
+
self.visit(func)
|
131
|
+
if not isinstance(func, ast.Name) or func.id != "struct_literal":
|
132
|
+
for arg in node.args:
|
133
|
+
self.visit(arg)
|
134
|
+
for kw in node.keywords:
|
135
|
+
self.visit(kw)
|