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
@@ -1,95 +0,0 @@
|
|
1
|
-
from typing import Any
|
2
|
-
|
3
|
-
from classiq.interface.generator.functions.classical_type import Bool, Integer
|
4
|
-
from classiq.interface.generator.functions.port_declaration import (
|
5
|
-
PortDeclarationDirection,
|
6
|
-
)
|
7
|
-
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
8
|
-
from classiq.interface.model.port_declaration import PortDeclaration
|
9
|
-
from classiq.interface.model.quantum_function_declaration import (
|
10
|
-
QuantumFunctionDeclaration,
|
11
|
-
QuantumOperandDeclaration,
|
12
|
-
)
|
13
|
-
|
14
|
-
REPEAT_OPERATOR = QuantumFunctionDeclaration(
|
15
|
-
name="repeat",
|
16
|
-
param_decls={"count": Integer()},
|
17
|
-
operand_declarations={
|
18
|
-
"iteration": QuantumOperandDeclaration(
|
19
|
-
name="iteration", param_decls={"index": Integer()}
|
20
|
-
)
|
21
|
-
},
|
22
|
-
)
|
23
|
-
|
24
|
-
|
25
|
-
def _get_single_empty_operand_operator(
|
26
|
-
operator_name: str, **kwargs: Any
|
27
|
-
) -> QuantumFunctionDeclaration:
|
28
|
-
operand_field_name = "operand"
|
29
|
-
return QuantumFunctionDeclaration(
|
30
|
-
name=operator_name,
|
31
|
-
operand_declarations={
|
32
|
-
operand_field_name: QuantumOperandDeclaration(name=operand_field_name)
|
33
|
-
},
|
34
|
-
**kwargs,
|
35
|
-
)
|
36
|
-
|
37
|
-
|
38
|
-
INVERT_OPERATOR = _get_single_empty_operand_operator(operator_name="invert")
|
39
|
-
|
40
|
-
_CTRL_FIELD_NAME = "ctrl"
|
41
|
-
CONTROL_OPERATOR = _get_single_empty_operand_operator(
|
42
|
-
operator_name="control",
|
43
|
-
port_declarations={
|
44
|
-
_CTRL_FIELD_NAME: PortDeclaration(
|
45
|
-
name=_CTRL_FIELD_NAME,
|
46
|
-
direction=PortDeclarationDirection.Inout,
|
47
|
-
)
|
48
|
-
},
|
49
|
-
)
|
50
|
-
|
51
|
-
IF_OPERATOR = QuantumFunctionDeclaration(
|
52
|
-
name="if",
|
53
|
-
param_decls={"condition": Bool()},
|
54
|
-
operand_declarations={
|
55
|
-
"then": QuantumOperandDeclaration(name="then"),
|
56
|
-
"else": QuantumOperandDeclaration(name="else"),
|
57
|
-
},
|
58
|
-
)
|
59
|
-
|
60
|
-
|
61
|
-
PERMUTE_OPERATOR = QuantumFunctionDeclaration(
|
62
|
-
name="permute",
|
63
|
-
operand_declarations={
|
64
|
-
"functions": QuantumOperandDeclaration(
|
65
|
-
name="functions",
|
66
|
-
is_list=True,
|
67
|
-
)
|
68
|
-
},
|
69
|
-
)
|
70
|
-
|
71
|
-
POWER_OPERATOR = _get_single_empty_operand_operator(
|
72
|
-
operator_name="power", param_decls={"power": Integer()}
|
73
|
-
)
|
74
|
-
|
75
|
-
APPLY_OPERATOR = _get_single_empty_operand_operator(operator_name="apply")
|
76
|
-
|
77
|
-
COMPUTE = _get_single_empty_operand_operator(operator_name="compute")
|
78
|
-
|
79
|
-
UNCOMPUTE = _get_single_empty_operand_operator(operator_name="uncompute")
|
80
|
-
|
81
|
-
BUILTIN_QUANTUM_OPERATOR_LIST = [
|
82
|
-
REPEAT_OPERATOR,
|
83
|
-
INVERT_OPERATOR,
|
84
|
-
CONTROL_OPERATOR,
|
85
|
-
IF_OPERATOR,
|
86
|
-
PERMUTE_OPERATOR,
|
87
|
-
POWER_OPERATOR,
|
88
|
-
APPLY_OPERATOR,
|
89
|
-
COMPUTE,
|
90
|
-
UNCOMPUTE,
|
91
|
-
]
|
92
|
-
|
93
|
-
QuantumFunctionDeclaration.BUILTIN_FUNCTION_DECLARATIONS.update(
|
94
|
-
nameables_to_dict(BUILTIN_QUANTUM_OPERATOR_LIST)
|
95
|
-
)
|
@@ -1,114 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from typing import Any, Dict, List, NoReturn, Optional, Tuple, Union
|
4
|
-
|
5
|
-
import pydantic
|
6
|
-
|
7
|
-
from classiq.interface.generator.arith.register_user_input import RegisterUserInput
|
8
|
-
from classiq.interface.generator.function_params import ArithmeticIODict, IOName
|
9
|
-
from classiq.interface.generator.functions.function_implementation import (
|
10
|
-
FunctionImplementation,
|
11
|
-
)
|
12
|
-
from classiq.interface.generator.functions.port_declaration import (
|
13
|
-
SynthesisPortDeclaration,
|
14
|
-
)
|
15
|
-
from classiq.interface.generator.functions.quantum_function_declaration import (
|
16
|
-
SynthesisQuantumFunctionDeclaration,
|
17
|
-
)
|
18
|
-
from classiq.interface.generator.functions.register import Register
|
19
|
-
from classiq.interface.generator.functions.register_mapping_data import (
|
20
|
-
RegisterMappingData,
|
21
|
-
)
|
22
|
-
|
23
|
-
from classiq.exceptions import ClassiqValueError
|
24
|
-
|
25
|
-
ImplementationsType = Tuple[FunctionImplementation, ...]
|
26
|
-
|
27
|
-
|
28
|
-
class SynthesisForeignFunctionDefinition(SynthesisQuantumFunctionDeclaration):
|
29
|
-
"""
|
30
|
-
Facilitates the creation of a user-defined elementary function
|
31
|
-
|
32
|
-
This class sets extra to forbid so that it can be used in a Union and not "steal"
|
33
|
-
objects from other classes.
|
34
|
-
"""
|
35
|
-
|
36
|
-
register_mapping: RegisterMappingData = pydantic.Field(
|
37
|
-
default_factory=RegisterMappingData,
|
38
|
-
description="The PortDirection data that is common to all implementations of the function",
|
39
|
-
)
|
40
|
-
implementations: Optional[ImplementationsType] = pydantic.Field(
|
41
|
-
description="The implementations of the custom function",
|
42
|
-
)
|
43
|
-
|
44
|
-
@pydantic.validator("register_mapping")
|
45
|
-
def _validate_register_mapping(
|
46
|
-
cls, register_mapping: RegisterMappingData
|
47
|
-
) -> RegisterMappingData:
|
48
|
-
if not register_mapping.output_registers:
|
49
|
-
raise ClassiqValueError(
|
50
|
-
"The outputs of a custom function must be non-empty"
|
51
|
-
)
|
52
|
-
return register_mapping
|
53
|
-
|
54
|
-
@pydantic.validator("implementations", pre=True)
|
55
|
-
def _parse_implementations(
|
56
|
-
cls,
|
57
|
-
implementations: Optional[Union[ImplementationsType, FunctionImplementation]],
|
58
|
-
) -> Optional[ImplementationsType]:
|
59
|
-
if isinstance(implementations, FunctionImplementation):
|
60
|
-
return (implementations,)
|
61
|
-
|
62
|
-
return implementations
|
63
|
-
|
64
|
-
@pydantic.validator("implementations")
|
65
|
-
def _validate_implementations(
|
66
|
-
cls,
|
67
|
-
implementations: Optional[ImplementationsType],
|
68
|
-
values: Dict[str, Any],
|
69
|
-
) -> Optional[ImplementationsType]:
|
70
|
-
if not implementations:
|
71
|
-
raise ClassiqValueError(
|
72
|
-
"The implementations of a custom function must be non-empty."
|
73
|
-
)
|
74
|
-
|
75
|
-
register_mapping = values.get("register_mapping")
|
76
|
-
assert isinstance(register_mapping, RegisterMappingData)
|
77
|
-
for impl in implementations:
|
78
|
-
impl.validate_ranges_of_all_registers(register_mapping=register_mapping)
|
79
|
-
|
80
|
-
return implementations
|
81
|
-
|
82
|
-
@property
|
83
|
-
def inputs(self) -> ArithmeticIODict:
|
84
|
-
return _map_reg_user_input(self.register_mapping.input_registers)
|
85
|
-
|
86
|
-
@property
|
87
|
-
def outputs(self) -> ArithmeticIODict:
|
88
|
-
return _map_reg_user_input(self.register_mapping.output_registers)
|
89
|
-
|
90
|
-
def renamed(self, new_name: str) -> SynthesisForeignFunctionDefinition:
|
91
|
-
return SynthesisForeignFunctionDefinition(
|
92
|
-
name=new_name,
|
93
|
-
implementations=self.implementations,
|
94
|
-
register_mapping=self.register_mapping,
|
95
|
-
)
|
96
|
-
|
97
|
-
@property
|
98
|
-
def port_declarations(self) -> Dict[IOName, SynthesisPortDeclaration]:
|
99
|
-
raise ClassiqValueError(
|
100
|
-
"Bad usage of foreign function definition: port_declarations"
|
101
|
-
)
|
102
|
-
|
103
|
-
@port_declarations.setter
|
104
|
-
def port_declarations(self, value: Any) -> NoReturn:
|
105
|
-
raise ClassiqValueError(
|
106
|
-
"Bad usage of foreign function definition: port_declarations"
|
107
|
-
)
|
108
|
-
|
109
|
-
|
110
|
-
def _map_reg_user_input(registers: List[Register]) -> ArithmeticIODict:
|
111
|
-
return {
|
112
|
-
reg.name: RegisterUserInput(size=len(reg.qubits), name=reg.name)
|
113
|
-
for reg in registers
|
114
|
-
}
|
@@ -1,107 +0,0 @@
|
|
1
|
-
from itertools import chain
|
2
|
-
from typing import Optional, Tuple, Union
|
3
|
-
|
4
|
-
import pydantic
|
5
|
-
from pydantic import BaseModel
|
6
|
-
|
7
|
-
from classiq.interface.generator.functions.register import Register
|
8
|
-
from classiq.interface.generator.functions.register_mapping_data import (
|
9
|
-
RegisterMappingData,
|
10
|
-
)
|
11
|
-
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
12
|
-
|
13
|
-
from classiq.exceptions import ClassiqValueError
|
14
|
-
|
15
|
-
RegistersStrictType = Tuple[Register, ...]
|
16
|
-
RegistersType = Union[Register, RegistersStrictType]
|
17
|
-
|
18
|
-
|
19
|
-
def to_tuple(reg_type: RegistersType) -> RegistersStrictType:
|
20
|
-
if isinstance(reg_type, Register):
|
21
|
-
return (reg_type,)
|
22
|
-
else:
|
23
|
-
return reg_type
|
24
|
-
|
25
|
-
|
26
|
-
class FunctionImplementation(BaseModel):
|
27
|
-
"""
|
28
|
-
Facilitates the creation of a user-defined custom function implementation
|
29
|
-
"""
|
30
|
-
|
31
|
-
class Config:
|
32
|
-
validate_all = True
|
33
|
-
extra = "forbid"
|
34
|
-
|
35
|
-
name: Optional[PydanticNonEmptyString] = pydantic.Field(
|
36
|
-
default=None,
|
37
|
-
description="The name of the custom implementation",
|
38
|
-
)
|
39
|
-
|
40
|
-
serialized_circuit: PydanticNonEmptyString = pydantic.Field(
|
41
|
-
description="The QASM code of the custom function implementation",
|
42
|
-
)
|
43
|
-
|
44
|
-
auxiliary_registers: RegistersStrictType = pydantic.Field(
|
45
|
-
default_factory=tuple,
|
46
|
-
description="A tuple of auxiliary registers to the custom implementation",
|
47
|
-
)
|
48
|
-
|
49
|
-
def num_qubits_in_all_registers(self, register_mapping: RegisterMappingData) -> int:
|
50
|
-
all_input_registers = (
|
51
|
-
register_mapping.input_registers
|
52
|
-
+ register_mapping.zero_input_registers
|
53
|
-
+ list(self.auxiliary_registers)
|
54
|
-
)
|
55
|
-
input_qubits = set(
|
56
|
-
chain.from_iterable(register.qubits for register in all_input_registers)
|
57
|
-
)
|
58
|
-
return len(input_qubits)
|
59
|
-
|
60
|
-
@pydantic.validator(
|
61
|
-
"auxiliary_registers",
|
62
|
-
pre=True,
|
63
|
-
always=True,
|
64
|
-
)
|
65
|
-
def validate_all_registers_are_tuples(
|
66
|
-
cls,
|
67
|
-
registers: RegistersType,
|
68
|
-
) -> RegistersStrictType:
|
69
|
-
if isinstance(registers, Register):
|
70
|
-
return (registers,)
|
71
|
-
return registers
|
72
|
-
|
73
|
-
def validate_ranges_of_all_registers(
|
74
|
-
self, register_mapping: RegisterMappingData
|
75
|
-
) -> None:
|
76
|
-
input_registers = register_mapping.input_registers
|
77
|
-
output_registers = register_mapping.output_registers
|
78
|
-
zero_input_registers = register_mapping.zero_input_registers
|
79
|
-
auxiliary_registers = list(self.auxiliary_registers)
|
80
|
-
|
81
|
-
all_input_registers = (
|
82
|
-
input_registers + zero_input_registers + auxiliary_registers
|
83
|
-
)
|
84
|
-
input_qubits = set(
|
85
|
-
chain.from_iterable(register.qubits for register in all_input_registers)
|
86
|
-
)
|
87
|
-
num_qubits = len(input_qubits)
|
88
|
-
all_qubits = set(range(num_qubits))
|
89
|
-
if num_qubits != sum(register.width for register in all_input_registers):
|
90
|
-
raise ClassiqValueError("The input registers must not overlap.")
|
91
|
-
if input_qubits != all_qubits:
|
92
|
-
raise ClassiqValueError(
|
93
|
-
"The set of qubits contained in all registers must be consecutive."
|
94
|
-
)
|
95
|
-
|
96
|
-
all_output_registers = output_registers + auxiliary_registers
|
97
|
-
output_qubits = set(
|
98
|
-
chain.from_iterable(register.qubits for register in all_output_registers)
|
99
|
-
)
|
100
|
-
if len(output_qubits) != sum(
|
101
|
-
register.width for register in all_output_registers
|
102
|
-
):
|
103
|
-
raise ClassiqValueError("The output registers must not overlap.")
|
104
|
-
if not output_qubits == all_qubits:
|
105
|
-
raise ClassiqValueError(
|
106
|
-
"The input and output qubits must be mutually consistent."
|
107
|
-
)
|
@@ -1,155 +0,0 @@
|
|
1
|
-
from typing import Any, Dict, List, Optional
|
2
|
-
|
3
|
-
import pydantic
|
4
|
-
|
5
|
-
from classiq.interface.generator.arith.register_user_input import RegisterUserInput
|
6
|
-
from classiq.interface.generator.function_params import IOName, PortDirection
|
7
|
-
from classiq.interface.generator.functions.port_declaration import (
|
8
|
-
SynthesisPortDeclaration,
|
9
|
-
)
|
10
|
-
from classiq.interface.generator.functions.quantum_function_declaration import (
|
11
|
-
SynthesisQuantumFunctionDeclaration,
|
12
|
-
)
|
13
|
-
from classiq.interface.generator.quantum_function_call import (
|
14
|
-
SynthesisQuantumFunctionCall,
|
15
|
-
WireDict,
|
16
|
-
WireName,
|
17
|
-
)
|
18
|
-
from classiq.interface.generator.validations import flow_graph
|
19
|
-
|
20
|
-
from classiq.exceptions import ClassiqValueError
|
21
|
-
|
22
|
-
LOGIC_FLOW_DUPLICATE_NAME_ERROR_MSG = (
|
23
|
-
"Cannot have multiple function calls with the same name"
|
24
|
-
)
|
25
|
-
|
26
|
-
|
27
|
-
class IOData(pydantic.BaseModel):
|
28
|
-
wire: WireName = pydantic.Field(
|
29
|
-
description="The name of the wire of the PortDirection data."
|
30
|
-
)
|
31
|
-
reg: RegisterUserInput = pydantic.Field(
|
32
|
-
description="The register information about the PortDirection data."
|
33
|
-
)
|
34
|
-
|
35
|
-
class Config:
|
36
|
-
frozen = True
|
37
|
-
|
38
|
-
|
39
|
-
class SynthesisNativeFunctionDefinition(SynthesisQuantumFunctionDeclaration):
|
40
|
-
"""
|
41
|
-
Facilitates the creation of a user-defined composite function
|
42
|
-
|
43
|
-
This class sets extra to forbid so that it can be used in a Union and not "steal"
|
44
|
-
objects from other classes.
|
45
|
-
"""
|
46
|
-
|
47
|
-
input_ports_wiring: Dict[IOName, WireName] = pydantic.Field(
|
48
|
-
description="The mapping between the functions input ports, to inner wires",
|
49
|
-
default_factory=dict,
|
50
|
-
)
|
51
|
-
|
52
|
-
output_ports_wiring: Dict[IOName, WireName] = pydantic.Field(
|
53
|
-
description="The mapping between the functions output ports, to inner wires",
|
54
|
-
default_factory=dict,
|
55
|
-
)
|
56
|
-
|
57
|
-
body: List[SynthesisQuantumFunctionCall] = pydantic.Field(
|
58
|
-
default_factory=list, description="List of function calls to perform."
|
59
|
-
)
|
60
|
-
|
61
|
-
def validate_body(self) -> None:
|
62
|
-
function_call_names = {call.name for call in self.body}
|
63
|
-
if len(function_call_names) != len(self.body):
|
64
|
-
raise ClassiqValueError(LOGIC_FLOW_DUPLICATE_NAME_ERROR_MSG)
|
65
|
-
flow_graph.validate_legal_wiring(
|
66
|
-
self.body,
|
67
|
-
flow_input_names=list(self.input_ports_wiring.values()),
|
68
|
-
flow_output_names=list(self.output_ports_wiring.values()),
|
69
|
-
)
|
70
|
-
flow_graph.validate_acyclic_logic_flow(
|
71
|
-
self.body,
|
72
|
-
flow_input_names=list(self.input_ports_wiring.values()),
|
73
|
-
flow_output_names=list(self.output_ports_wiring.values()),
|
74
|
-
)
|
75
|
-
|
76
|
-
@classmethod
|
77
|
-
def _validate_direction_ports(
|
78
|
-
cls,
|
79
|
-
port_declarations: Dict[IOName, SynthesisPortDeclaration],
|
80
|
-
directions_external_port_wiring: WireDict,
|
81
|
-
direction: PortDirection,
|
82
|
-
) -> None:
|
83
|
-
for io_name in directions_external_port_wiring:
|
84
|
-
if (
|
85
|
-
io_name not in port_declarations
|
86
|
-
or not port_declarations[io_name].direction == direction
|
87
|
-
):
|
88
|
-
raise ClassiqValueError(
|
89
|
-
f"The wired {direction} port {io_name!r} is not declared."
|
90
|
-
)
|
91
|
-
|
92
|
-
@pydantic.root_validator
|
93
|
-
def validate_ports(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
94
|
-
port_declarations: Optional[Dict[IOName, SynthesisPortDeclaration]] = (
|
95
|
-
values.get("port_declarations")
|
96
|
-
)
|
97
|
-
if port_declarations is None:
|
98
|
-
return values
|
99
|
-
cls._validate_direction_ports(
|
100
|
-
port_declarations,
|
101
|
-
values.get("input_ports_wiring", dict()),
|
102
|
-
PortDirection.Input,
|
103
|
-
)
|
104
|
-
cls._validate_direction_ports(
|
105
|
-
port_declarations,
|
106
|
-
values.get("output_ports_wiring", dict()),
|
107
|
-
PortDirection.Output,
|
108
|
-
)
|
109
|
-
return values
|
110
|
-
|
111
|
-
@pydantic.validator("input_ports_wiring", always=True)
|
112
|
-
def _populate_input_ports_wiring(
|
113
|
-
cls, input_ports_wiring: Dict[IOName, WireName], values: Dict[str, Any]
|
114
|
-
) -> Dict[IOName, WireName]:
|
115
|
-
return _validate_ports_wiring_for_direction(
|
116
|
-
input_ports_wiring, values, PortDirection.Input
|
117
|
-
)
|
118
|
-
|
119
|
-
@pydantic.validator("output_ports_wiring", always=True)
|
120
|
-
def _populate_output_ports_wiring(
|
121
|
-
cls, output_ports_wiring: Dict[IOName, WireName], values: Dict[str, Any]
|
122
|
-
) -> Dict[IOName, WireName]:
|
123
|
-
return _validate_ports_wiring_for_direction(
|
124
|
-
output_ports_wiring, values, PortDirection.Output
|
125
|
-
)
|
126
|
-
|
127
|
-
|
128
|
-
def _get_single_port_wiring(
|
129
|
-
ports_wiring: Dict[IOName, WireName], name: str, direction: PortDirection
|
130
|
-
) -> WireName:
|
131
|
-
direction_id = "out" if direction == PortDirection.Output else "in"
|
132
|
-
return ports_wiring.get(name) or f"{name}_{direction_id}"
|
133
|
-
|
134
|
-
|
135
|
-
def _port_declarations_to_wiring(
|
136
|
-
ports_wiring: Dict[IOName, WireName],
|
137
|
-
port_decls: Dict[IOName, SynthesisPortDeclaration],
|
138
|
-
direction: PortDirection,
|
139
|
-
) -> Dict[IOName, WireName]:
|
140
|
-
return {
|
141
|
-
name: _get_single_port_wiring(ports_wiring, name, direction)
|
142
|
-
for name, port in port_decls.items()
|
143
|
-
if port.direction.includes_port_direction(direction)
|
144
|
-
}
|
145
|
-
|
146
|
-
|
147
|
-
def _validate_ports_wiring_for_direction(
|
148
|
-
ports_wiring: Dict[IOName, WireName],
|
149
|
-
values: Dict[str, Any],
|
150
|
-
direction: PortDirection,
|
151
|
-
) -> Dict[IOName, WireName]:
|
152
|
-
port_decls = values.get("port_declarations")
|
153
|
-
if port_decls is None:
|
154
|
-
return ports_wiring
|
155
|
-
return _port_declarations_to_wiring(ports_wiring, port_decls, direction)
|
@@ -1,69 +0,0 @@
|
|
1
|
-
from typing import Dict, Set
|
2
|
-
|
3
|
-
import pydantic
|
4
|
-
from pydantic import BaseModel
|
5
|
-
|
6
|
-
from classiq.interface.generator.arith.register_user_input import RegisterUserInput
|
7
|
-
from classiq.interface.generator.function_params import (
|
8
|
-
ArithmeticIODict,
|
9
|
-
IOName,
|
10
|
-
PortDirection,
|
11
|
-
)
|
12
|
-
from classiq.interface.generator.functions.port_declaration import (
|
13
|
-
SynthesisPortDeclaration,
|
14
|
-
)
|
15
|
-
from classiq.interface.helpers.validation_helpers import validate_nameables_mapping
|
16
|
-
|
17
|
-
|
18
|
-
class SynthesisQuantumFunctionDeclaration(BaseModel):
|
19
|
-
"""
|
20
|
-
Facilitates the creation of a common quantum function interface object.
|
21
|
-
"""
|
22
|
-
|
23
|
-
name: str = pydantic.Field(description="The name of the function")
|
24
|
-
|
25
|
-
port_declarations: Dict[IOName, SynthesisPortDeclaration] = pydantic.Field(
|
26
|
-
description="The input and output ports of the function.",
|
27
|
-
default_factory=dict,
|
28
|
-
)
|
29
|
-
|
30
|
-
@property
|
31
|
-
def input_set(self) -> Set[IOName]:
|
32
|
-
return set(self.inputs.keys())
|
33
|
-
|
34
|
-
@property
|
35
|
-
def output_set(self) -> Set[IOName]:
|
36
|
-
return set(self.outputs.keys())
|
37
|
-
|
38
|
-
@property
|
39
|
-
def inputs(self) -> ArithmeticIODict:
|
40
|
-
return _ports_to_registers(self.port_declarations, PortDirection.Input)
|
41
|
-
|
42
|
-
@property
|
43
|
-
def outputs(self) -> ArithmeticIODict:
|
44
|
-
return _ports_to_registers(self.port_declarations, PortDirection.Output)
|
45
|
-
|
46
|
-
@pydantic.validator("port_declarations")
|
47
|
-
def _validate_port_declarations_names(
|
48
|
-
cls, port_declarations: Dict[IOName, SynthesisPortDeclaration]
|
49
|
-
) -> Dict[IOName, SynthesisPortDeclaration]:
|
50
|
-
validate_nameables_mapping(port_declarations, "Port")
|
51
|
-
return port_declarations
|
52
|
-
|
53
|
-
class Config:
|
54
|
-
extra = pydantic.Extra.forbid
|
55
|
-
|
56
|
-
|
57
|
-
def _ports_to_registers(
|
58
|
-
port_declarations: Dict[IOName, SynthesisPortDeclaration], direction: PortDirection
|
59
|
-
) -> ArithmeticIODict:
|
60
|
-
return {
|
61
|
-
name: RegisterUserInput(
|
62
|
-
name=name,
|
63
|
-
size=port_decl.size,
|
64
|
-
is_signed=port_decl.is_signed,
|
65
|
-
fraction_places=port_decl.fraction_places,
|
66
|
-
)
|
67
|
-
for name, port_decl in port_declarations.items()
|
68
|
-
if port_decl.direction.includes_port_direction(direction)
|
69
|
-
}
|
@@ -1,44 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from operator import attrgetter
|
4
|
-
from typing import Iterable, Tuple
|
5
|
-
|
6
|
-
import pydantic
|
7
|
-
from pydantic import BaseModel
|
8
|
-
|
9
|
-
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
10
|
-
|
11
|
-
from classiq.exceptions import ClassiqValueError
|
12
|
-
|
13
|
-
QubitsType = Tuple[pydantic.NonNegativeInt, ...]
|
14
|
-
|
15
|
-
|
16
|
-
class Register(BaseModel):
|
17
|
-
"""
|
18
|
-
A user-defined custom register.
|
19
|
-
"""
|
20
|
-
|
21
|
-
name: PydanticNonEmptyString = pydantic.Field(
|
22
|
-
description="The name of the custom register",
|
23
|
-
)
|
24
|
-
|
25
|
-
qubits: QubitsType = pydantic.Field(
|
26
|
-
description="A tuple of qubits as integers as indexed within a custom function code",
|
27
|
-
)
|
28
|
-
|
29
|
-
@property
|
30
|
-
def width(self) -> pydantic.PositiveInt:
|
31
|
-
"""The number of qubits of the custom register"""
|
32
|
-
return len(self.qubits)
|
33
|
-
|
34
|
-
@pydantic.validator("qubits")
|
35
|
-
def validate_qubits(cls, qubits: QubitsType) -> QubitsType:
|
36
|
-
if len(qubits) == 0:
|
37
|
-
raise ClassiqValueError("qubits field must be non-empty.")
|
38
|
-
if len(set(qubits)) != len(qubits):
|
39
|
-
raise ClassiqValueError("All qubits of a register must be distinct.")
|
40
|
-
return qubits
|
41
|
-
|
42
|
-
|
43
|
-
def get_register_names(reg_list: Iterable[Register]) -> Iterable[str]:
|
44
|
-
return map(attrgetter("name"), reg_list)
|
@@ -1,106 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import itertools
|
4
|
-
from typing import Any, Dict, Iterable, List, Tuple
|
5
|
-
|
6
|
-
import pydantic
|
7
|
-
|
8
|
-
from classiq.interface.generator.functions.register import Register, get_register_names
|
9
|
-
from classiq.interface.generator.register_role import RegisterRole as Role
|
10
|
-
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
11
|
-
|
12
|
-
from classiq.exceptions import ClassiqValueError
|
13
|
-
|
14
|
-
REGISTER_NOT_FOUND_ERROR = "Register name not found"
|
15
|
-
|
16
|
-
|
17
|
-
class RegisterMappingData(pydantic.BaseModel):
|
18
|
-
input_registers: List[Register] = pydantic.Field(default_factory=list)
|
19
|
-
output_registers: List[Register] = pydantic.Field(default_factory=list)
|
20
|
-
zero_input_registers: List[Register] = pydantic.Field(default_factory=list)
|
21
|
-
|
22
|
-
@pydantic.root_validator()
|
23
|
-
def validate_mapping(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
24
|
-
input_registers = values.get("input_registers", list())
|
25
|
-
output_registers = values.get("output_registers", list())
|
26
|
-
zero_input_registers = values.get("zero_input_registers", list())
|
27
|
-
|
28
|
-
input_qubits = cls._get_qubit_range(input_registers)
|
29
|
-
output_qubits = cls._get_qubit_range(output_registers)
|
30
|
-
zero_input_qubits = cls._get_qubit_range(zero_input_registers)
|
31
|
-
|
32
|
-
all_input_qubits = sorted(input_qubits + zero_input_qubits)
|
33
|
-
if not cls._validate_no_overlap(all_input_qubits):
|
34
|
-
raise ClassiqValueError("overlapping input qubits are not allowed")
|
35
|
-
if not cls._validate_no_overlap(output_qubits):
|
36
|
-
raise ClassiqValueError("overlapping output qubits are not allowed")
|
37
|
-
|
38
|
-
if not output_qubits == all_input_qubits:
|
39
|
-
raise ClassiqValueError(
|
40
|
-
"output registers should be included within the input / zero input registers"
|
41
|
-
)
|
42
|
-
|
43
|
-
return values
|
44
|
-
|
45
|
-
@pydantic.validator("input_registers", "output_registers")
|
46
|
-
def validate_input_registers_are_distinct(
|
47
|
-
cls, field_value: List[Register]
|
48
|
-
) -> List[Register]:
|
49
|
-
if len(field_value) != len({io_register.name for io_register in field_value}):
|
50
|
-
raise ClassiqValueError(
|
51
|
-
"The names of PortDirection registers must be distinct."
|
52
|
-
)
|
53
|
-
return field_value
|
54
|
-
|
55
|
-
@staticmethod
|
56
|
-
def _validate_no_overlap(reg_list: List[int]) -> bool:
|
57
|
-
return len(reg_list) == len(set(reg_list))
|
58
|
-
|
59
|
-
@staticmethod
|
60
|
-
def _get_qubit_range(registers: Iterable[Register]) -> List[int]:
|
61
|
-
return sorted(itertools.chain.from_iterable(reg.qubits for reg in registers))
|
62
|
-
|
63
|
-
@property
|
64
|
-
def input_names(self) -> Iterable[str]:
|
65
|
-
return get_register_names(self.input_registers)
|
66
|
-
|
67
|
-
@property
|
68
|
-
def output_names(self) -> Iterable[str]:
|
69
|
-
return get_register_names(self.output_registers)
|
70
|
-
|
71
|
-
def validate_equal_mappings(self, other: RegisterMappingData) -> None:
|
72
|
-
if any(
|
73
|
-
[
|
74
|
-
self.input_registers != other.input_registers,
|
75
|
-
self.output_registers != other.output_registers,
|
76
|
-
self.zero_input_registers != other.zero_input_registers,
|
77
|
-
]
|
78
|
-
):
|
79
|
-
raise ClassiqValueError(
|
80
|
-
"Interface should be identical in all implementations"
|
81
|
-
)
|
82
|
-
|
83
|
-
def get_input_register(self, name: PydanticNonEmptyString) -> Register:
|
84
|
-
for reg in self.input_registers:
|
85
|
-
if reg.name == name:
|
86
|
-
return reg
|
87
|
-
raise ClassiqValueError(REGISTER_NOT_FOUND_ERROR)
|
88
|
-
|
89
|
-
def get_output_register(self, name: PydanticNonEmptyString) -> Register:
|
90
|
-
for reg in self.output_registers:
|
91
|
-
if reg.name == name:
|
92
|
-
return reg
|
93
|
-
raise ClassiqValueError(REGISTER_NOT_FOUND_ERROR)
|
94
|
-
|
95
|
-
@staticmethod
|
96
|
-
def from_registers_dict(
|
97
|
-
regs_dict: Dict[Role, Tuple[Register, ...]]
|
98
|
-
) -> RegisterMappingData:
|
99
|
-
return RegisterMappingData(
|
100
|
-
input_registers=list(regs_dict[Role.INPUT]),
|
101
|
-
output_registers=list(regs_dict[Role.OUTPUT]),
|
102
|
-
zero_input_registers=list(regs_dict[Role.ZERO_INPUT]),
|
103
|
-
)
|
104
|
-
|
105
|
-
class Config:
|
106
|
-
extra = "forbid"
|