classiq 0.37.1__py3-none-any.whl → 0.65.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +49 -34
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +3 -2
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +241 -95
- classiq/_internals/async_utils.py +2 -77
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +18 -8
- classiq/_internals/authentication/password_manager.py +40 -13
- classiq/_internals/authentication/token_manager.py +11 -6
- classiq/_internals/client.py +106 -37
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +56 -50
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +50 -47
- classiq/analyzer/analyzer_utilities.py +15 -15
- classiq/analyzer/rb.py +19 -20
- classiq/analyzer/show_interactive_hack.py +30 -7
- classiq/analyzer/url_utils.py +2 -3
- classiq/applications/__init__.py +3 -12
- classiq/applications/chemistry/__init__.py +14 -10
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +170 -170
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/applications/combinatorial_helpers/allowed_constraints.py +23 -0
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +166 -0
- classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications/combinatorial_helpers/encoding_utils.py +124 -0
- classiq/applications/combinatorial_helpers/memory.py +75 -0
- classiq/applications/combinatorial_helpers/optimization_model.py +193 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications/combinatorial_helpers/transformations/encoding.py +189 -0
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +143 -0
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +120 -0
- classiq/applications/combinatorial_helpers/transformations/penalty.py +31 -0
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +74 -0
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +87 -0
- classiq/applications/combinatorial_optimization/__init__.py +24 -5
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +137 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +4 -5
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +50 -57
- classiq/applications/grover/__init__.py +9 -0
- classiq/applications/grover/grover_model_constructor.py +157 -0
- classiq/applications/hamiltonian/__init__.py +0 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +8 -8
- classiq/applications/qnn/datasets/__init__.py +9 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +30 -10
- classiq/applications/qnn/torch_utils.py +4 -3
- classiq/applications/qnn/types.py +7 -7
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +4 -10
- classiq/applications/qsvm/qsvm_data_generation.py +5 -8
- classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
- classiq/execution/__init__.py +8 -3
- classiq/execution/all_hardware_devices.py +11 -0
- classiq/execution/execution_session.py +400 -0
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +197 -25
- classiq/execution/qnn.py +79 -0
- classiq/executor.py +23 -117
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +49 -16
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +36 -32
- classiq/interface/applications/qsvm.py +28 -25
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -119
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +27 -22
- classiq/interface/backend/quantum_backend_providers.py +70 -16
- classiq/interface/chemistry/fermionic_operator.py +43 -32
- classiq/interface/chemistry/ground_state_problem.py +42 -24
- classiq/interface/chemistry/molecule.py +20 -14
- classiq/interface/chemistry/operator.py +75 -236
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +2 -4
- classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
- classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
- classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +3 -3
- classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +14 -9
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +86 -0
- classiq/interface/exceptions.py +201 -0
- classiq/interface/execution/iqcc.py +19 -0
- classiq/interface/execution/jobs.py +15 -12
- classiq/interface/execution/primitives.py +18 -0
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/executor/estimation.py +2 -2
- classiq/interface/executor/execution_preferences.py +26 -143
- classiq/interface/executor/execution_request.py +36 -56
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +34 -22
- classiq/interface/executor/{quantum_program.py → quantum_code.py} +44 -34
- classiq/interface/executor/quantum_instruction_set.py +3 -2
- classiq/interface/executor/register_initialization.py +12 -17
- classiq/interface/executor/result.py +122 -64
- classiq/interface/executor/vqe_result.py +11 -11
- classiq/interface/finance/function_input.py +42 -19
- classiq/interface/finance/gaussian_model_input.py +7 -5
- classiq/interface/finance/log_normal_model_input.py +6 -4
- classiq/interface/finance/model_input.py +6 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +27 -14
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/__init__.py +1 -0
- classiq/interface/generator/application_apis/arithmetic_declarations.py +17 -0
- classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +48 -69
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
- classiq/interface/generator/arith/argument_utils.py +57 -6
- classiq/interface/generator/arith/arithmetic.py +37 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +15 -17
- classiq/interface/generator/arith/arithmetic_expression_abc.py +70 -26
- classiq/interface/generator/arith/arithmetic_expression_parser.py +18 -12
- classiq/interface/generator/arith/arithmetic_expression_validator.py +61 -43
- classiq/interface/generator/arith/arithmetic_operations.py +19 -16
- classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
- classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
- classiq/interface/generator/arith/ast_node_rewrite.py +4 -3
- classiq/interface/generator/arith/binary_ops.py +375 -139
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -23
- classiq/interface/generator/arith/logical_ops.py +16 -12
- classiq/interface/generator/arith/machine_precision.py +3 -0
- classiq/interface/generator/arith/number_utils.py +44 -48
- classiq/interface/generator/arith/register_user_input.py +70 -27
- classiq/interface/generator/arith/unary_ops.py +57 -46
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/builtin_api_builder.py +2 -9
- classiq/interface/generator/chemistry_function_params.py +5 -5
- classiq/interface/generator/circuit_code/circuit_code.py +7 -7
- classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
- classiq/interface/generator/commuting_pauli_exponentiation.py +8 -6
- classiq/interface/generator/compiler_keywords.py +8 -0
- classiq/interface/generator/complex_type.py +13 -25
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +35 -28
- classiq/interface/generator/copy.py +47 -0
- classiq/interface/generator/custom_ansatz.py +2 -5
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +26 -8
- classiq/interface/generator/expressions/enums/__init__.py +0 -10
- classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
- classiq/interface/generator/expressions/evaluated_expression.py +21 -7
- classiq/interface/generator/expressions/expression.py +27 -15
- classiq/interface/generator/expressions/expression_constants.py +9 -3
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +59 -0
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
- classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
- classiq/interface/generator/expressions/sympy_supported_expressions.py +20 -11
- classiq/interface/generator/finance.py +3 -3
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
- classiq/interface/generator/function_params.py +42 -69
- classiq/interface/generator/functions/__init__.py +0 -22
- classiq/interface/generator/functions/builtins/__init__.py +0 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
- classiq/interface/generator/functions/classical_function_declaration.py +18 -9
- classiq/interface/generator/functions/classical_type.py +47 -166
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +13 -14
- classiq/interface/generator/functions/port_declaration.py +1 -13
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +90 -0
- classiq/interface/generator/generated_circuit_data.py +155 -22
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -23
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +12 -8
- classiq/interface/generator/hardware/hardware_data.py +76 -36
- classiq/interface/generator/hardware_efficient_ansatz.py +38 -17
- classiq/interface/generator/hartree_fock.py +14 -4
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +33 -19
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +20 -16
- classiq/interface/generator/mcx.py +29 -20
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +27 -8
- classiq/interface/generator/model/model.py +32 -203
- classiq/interface/generator/model/preferences/preferences.py +118 -43
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +27 -22
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +17 -13
- classiq/interface/generator/oracles/oracle_abc.py +9 -9
- classiq/interface/generator/partitioned_register.py +7 -7
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +47 -34
- classiq/interface/generator/qsvm.py +13 -17
- classiq/interface/generator/quantum_function_call.py +107 -87
- classiq/interface/generator/{generated_circuit.py → quantum_program.py} +50 -37
- classiq/interface/generator/range_types.py +13 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +11 -6
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +32 -39
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +16 -15
- classiq/interface/generator/state_preparation/metrics.py +5 -7
- classiq/interface/generator/state_preparation/state_preparation.py +30 -23
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
- classiq/interface/generator/transpiler_basis_gates.py +7 -3
- classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
- classiq/interface/generator/types/compilation_metadata.py +6 -0
- classiq/interface/generator/types/enum_declaration.py +54 -0
- classiq/interface/generator/types/qstruct_declaration.py +18 -0
- classiq/interface/generator/types/struct_declaration.py +15 -14
- classiq/interface/generator/ucc.py +9 -6
- classiq/interface/generator/unitary_gate.py +10 -6
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +11 -9
- classiq/interface/generator/validations/validator_functions.py +8 -6
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +31 -10
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +3 -0
- classiq/interface/helpers/custom_pydantic_types.py +40 -50
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +7 -11
- classiq/interface/helpers/validation_helpers.py +4 -21
- classiq/interface/helpers/versioned_model.py +1 -1
- classiq/interface/ide/ide_data.py +16 -20
- classiq/interface/ide/visual_model.py +130 -0
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +35 -6
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +44 -14
- classiq/interface/model/classical_if.py +15 -0
- classiq/interface/model/classical_parameter_declaration.py +33 -3
- classiq/interface/model/control.py +45 -0
- classiq/interface/model/handle_binding.py +298 -20
- classiq/interface/model/inplace_binary_operation.py +31 -26
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +87 -73
- classiq/interface/model/native_function_definition.py +16 -21
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/phase_operation.py +11 -0
- classiq/interface/model/port_declaration.py +27 -9
- classiq/interface/model/power.py +14 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +38 -21
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
- classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
- classiq/interface/model/quantum_function_call.py +146 -462
- classiq/interface/model/quantum_function_declaration.py +193 -152
- classiq/interface/model/quantum_lambda_function.py +65 -0
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +205 -67
- classiq/interface/model/quantum_variable_declaration.py +4 -26
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +58 -0
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +13 -0
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +22 -21
- classiq/interface/source_reference.py +59 -0
- classiq/model_expansions/__init__.py +0 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
- classiq/model_expansions/capturing/__init__.py +0 -0
- classiq/model_expansions/capturing/captured_vars.py +435 -0
- classiq/model_expansions/capturing/mangling_utils.py +56 -0
- classiq/model_expansions/closure.py +171 -0
- classiq/model_expansions/debug_flag.py +3 -0
- classiq/model_expansions/evaluators/__init__.py +0 -0
- classiq/model_expansions/evaluators/arg_type_match.py +158 -0
- classiq/model_expansions/evaluators/argument_types.py +42 -0
- classiq/model_expansions/evaluators/classical_expression.py +36 -0
- classiq/model_expansions/evaluators/control.py +144 -0
- classiq/model_expansions/evaluators/parameter_types.py +226 -0
- classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
- classiq/model_expansions/evaluators/type_type_match.py +90 -0
- classiq/model_expansions/expression_evaluator.py +135 -0
- classiq/model_expansions/expression_renamer.py +76 -0
- classiq/model_expansions/function_builder.py +247 -0
- classiq/model_expansions/generative_functions.py +158 -0
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/interpreters/base_interpreter.py +263 -0
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
- classiq/model_expansions/model_tables.py +18 -0
- classiq/model_expansions/quantum_operations/__init__.py +9 -0
- classiq/model_expansions/quantum_operations/bind.py +60 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
- classiq/model_expansions/quantum_operations/classicalif.py +53 -0
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +181 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
- classiq/model_expansions/quantum_operations/repeat.py +56 -0
- classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
- classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
- classiq/model_expansions/scope.py +240 -0
- classiq/model_expansions/scope_initialization.py +150 -0
- classiq/model_expansions/sympy_conversion/__init__.py +0 -0
- classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
- classiq/model_expansions/transformers/__init__.py +0 -0
- classiq/model_expansions/transformers/ast_renamer.py +26 -0
- classiq/model_expansions/transformers/var_splitter.py +299 -0
- classiq/model_expansions/utils/__init__.py +0 -0
- classiq/model_expansions/utils/counted_name_allocator.py +11 -0
- classiq/model_expansions/utils/handles_collector.py +33 -0
- classiq/model_expansions/visitors/__init__.py +0 -0
- classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
- classiq/model_expansions/visitors/variable_references.py +144 -0
- classiq/open_library/__init__.py +4 -0
- classiq/open_library/functions/__init__.py +130 -0
- classiq/open_library/functions/amplitude_estimation.py +30 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
- classiq/open_library/functions/grover.py +157 -0
- classiq/open_library/functions/hea.py +115 -0
- classiq/open_library/functions/linear_pauli_rotation.py +82 -0
- classiq/open_library/functions/modular_exponentiation.py +201 -0
- classiq/open_library/functions/qaoa_penalty.py +117 -0
- classiq/open_library/functions/qft_functions.py +54 -0
- classiq/open_library/functions/qpe.py +46 -0
- classiq/open_library/functions/qsvt.py +331 -0
- classiq/open_library/functions/state_preparation.py +301 -0
- classiq/open_library/functions/swap_test.py +27 -0
- classiq/open_library/functions/utility_functions.py +81 -0
- classiq/open_library/functions/variational.py +52 -0
- classiq/qmod/__init__.py +17 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +60 -47
- classiq/qmod/builtins/classical_functions.py +44 -38
- classiq/qmod/builtins/constants.py +10 -0
- classiq/qmod/builtins/enums.py +208 -0
- classiq/qmod/builtins/functions/__init__.py +137 -0
- classiq/qmod/builtins/functions/allocation.py +150 -0
- classiq/qmod/builtins/functions/arithmetic.py +55 -0
- classiq/qmod/builtins/functions/benchmarking.py +8 -0
- classiq/qmod/builtins/functions/chemistry.py +91 -0
- classiq/qmod/builtins/functions/exponentiation.py +105 -0
- classiq/qmod/builtins/functions/finance.py +34 -0
- classiq/qmod/builtins/functions/operators.py +16 -0
- classiq/qmod/builtins/functions/qsvm.py +24 -0
- classiq/qmod/builtins/functions/standard_gates.py +651 -0
- classiq/qmod/builtins/operations.py +379 -57
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +42 -0
- classiq/qmod/classical_function.py +8 -20
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +145 -112
- classiq/qmod/expression_query.py +39 -0
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +19 -5
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +194 -0
- classiq/qmod/native/pretty_printer.py +401 -0
- classiq/qmod/pretty_print/__init__.py +7 -0
- classiq/qmod/pretty_print/expression_to_python.py +222 -0
- classiq/qmod/pretty_print/pretty_printer.py +572 -0
- classiq/qmod/python_classical_type.py +67 -0
- classiq/qmod/qfunc.py +79 -0
- classiq/qmod/qmod_constant.py +143 -0
- classiq/qmod/qmod_parameter.py +84 -53
- classiq/qmod/qmod_variable.py +497 -100
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +278 -105
- classiq/qmod/quantum_function.py +232 -48
- classiq/qmod/semantics/__init__.py +0 -0
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
- classiq/qmod/semantics/error_manager.py +88 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +384 -0
- classiq/qmod/semantics/validation/__init__.py +0 -0
- classiq/qmod/semantics/validation/constants_validation.py +16 -0
- classiq/qmod/semantics/validation/func_call_validation.py +99 -0
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +128 -0
- classiq/qmod/symbolic.py +178 -111
- classiq/qmod/symbolic_expr.py +36 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +108 -1
- classiq/qmod/write_qmod.py +53 -0
- classiq/synthesis.py +210 -22
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -8
- classiq-0.65.3.dist-info/RECORD +521 -0
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/WHEEL +1 -1
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -17
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
- classiq/applications_model_constructors/grover_model_constructor.py +0 -227
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/exceptions.py +0 -131
- classiq/interface/executor/aws_execution_cost.py +0 -72
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -115
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -59
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -862
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
- classiq/interface/generator/functions/foreign_function_definition.py +0 -106
- classiq/interface/generator/functions/function_implementation.py +0 -103
- classiq/interface/generator/functions/native_function_definition.py +0 -153
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -42
- classiq/interface/generator/functions/register_mapping_data.py +0 -102
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -63
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -2
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
- classiq/interface/generator/types/combinatorial_problem.py +0 -26
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/numeric_reinterpretation.py +0 -25
- classiq/interface/model/operator_synthesis_data.py +0 -48
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -95
- classiq/interface/model/resolvers/function_call_resolver.py +0 -43
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -154
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -466
- classiq/model/function_handler.pyi +0 -152
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -246
- classiq/qmod/builtins/functions.py +0 -896
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -207
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- classiq-0.37.1.dist-info/RECORD +0 -418
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/pauli_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/py.typed} +0 -0
- /classiq/{interface/model/resolvers → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{interface/model/validations → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
@@ -6,24 +6,25 @@ import random
|
|
6
6
|
import re
|
7
7
|
import string
|
8
8
|
from collections import defaultdict
|
9
|
+
from collections.abc import Iterable, Mapping, Sequence
|
10
|
+
from re import Match
|
9
11
|
from typing import (
|
10
12
|
Any,
|
11
|
-
Dict,
|
12
|
-
Iterable,
|
13
|
-
List,
|
14
|
-
Mapping,
|
15
|
-
Match,
|
16
13
|
Optional,
|
17
|
-
Sequence,
|
18
|
-
Tuple,
|
19
14
|
Union,
|
20
15
|
)
|
16
|
+
from uuid import UUID, uuid4
|
21
17
|
|
22
18
|
import pydantic
|
23
|
-
from pydantic import BaseModel,
|
19
|
+
from pydantic import BaseModel, ConfigDict
|
20
|
+
from pydantic_core.core_schema import ValidationInfo
|
24
21
|
|
22
|
+
from classiq.interface.exceptions import ClassiqControlError, ClassiqValueError
|
25
23
|
from classiq.interface.generator import function_param_list, function_params as f_params
|
26
24
|
from classiq.interface.generator.arith.arithmetic import Arithmetic
|
25
|
+
from classiq.interface.generator.compiler_keywords import (
|
26
|
+
generate_original_function_name,
|
27
|
+
)
|
27
28
|
from classiq.interface.generator.control_state import ControlState
|
28
29
|
from classiq.interface.generator.function_params import (
|
29
30
|
NAME_REGEX,
|
@@ -46,8 +47,6 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
|
|
46
47
|
HashablePydanticBaseModel,
|
47
48
|
)
|
48
49
|
|
49
|
-
from classiq.exceptions import ClassiqControlError, ClassiqValueError
|
50
|
-
|
51
50
|
DEFAULT_SUFFIX_LEN: int = 6
|
52
51
|
BAD_INPUT_ERROR_MSG = "Bad input name given"
|
53
52
|
BAD_OUTPUT_ERROR_MSG = "Bad output name given"
|
@@ -62,7 +61,7 @@ LEGAL_SLICING = rf"(\-?\d+)?({SEPARATOR}(\-?\d+)?)?({SEPARATOR}(\-?\d+)?)?"
|
|
62
61
|
|
63
62
|
_ALPHANUM_CHARACTERS = string.ascii_letters + string.digits
|
64
63
|
|
65
|
-
RegNameAndSlice =
|
64
|
+
RegNameAndSlice = tuple[str, slice]
|
66
65
|
|
67
66
|
ZERO_INDICATOR = "0"
|
68
67
|
INVERSE_SUFFIX = "_qinverse"
|
@@ -79,25 +78,24 @@ class WirePair(HashablePydanticBaseModel):
|
|
79
78
|
out_wire: WireName
|
80
79
|
|
81
80
|
|
82
|
-
SUFFIX_RANDOMIZER = random.Random() #
|
81
|
+
SUFFIX_RANDOMIZER = random.Random() # noqa: S311
|
83
82
|
|
84
83
|
|
85
84
|
def split_wire_pair_to_wires(
|
86
85
|
inout: WirePair,
|
87
|
-
) ->
|
86
|
+
) -> tuple[WireName, WireName]:
|
88
87
|
return inout.in_wire, inout.out_wire
|
89
88
|
|
90
89
|
|
91
90
|
def randomize_suffix(suffix_len: int = DEFAULT_SUFFIX_LEN) -> str:
|
92
91
|
return "".join(
|
93
|
-
SUFFIX_RANDOMIZER.choice(_ALPHANUM_CHARACTERS)
|
94
|
-
for _ in range(suffix_len) # nosec B311
|
92
|
+
SUFFIX_RANDOMIZER.choice(_ALPHANUM_CHARACTERS) for _ in range(suffix_len)
|
95
93
|
)
|
96
94
|
|
97
95
|
|
98
96
|
def get_non_zero_wires(
|
99
97
|
wires: Iterable[WireName],
|
100
|
-
) ->
|
98
|
+
) -> list[WireName]:
|
101
99
|
return [wire for wire in wires if wire != ZERO_INDICATOR]
|
102
100
|
|
103
101
|
|
@@ -121,7 +119,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
121
119
|
release_by_inverse: bool = pydantic.Field(
|
122
120
|
default=False, description="Release zero inputs in inverse call."
|
123
121
|
)
|
124
|
-
control_states:
|
122
|
+
control_states: list[ControlState] = pydantic.Field(
|
125
123
|
default_factory=list,
|
126
124
|
description="Call the controlled function with the given controlled states.",
|
127
125
|
)
|
@@ -146,9 +144,15 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
146
144
|
)
|
147
145
|
name: PydanticNonEmptyString = pydantic.Field(
|
148
146
|
default=None,
|
147
|
+
validate_default=True,
|
149
148
|
description="The name of the function instance. "
|
150
149
|
"If not set, determined automatically.",
|
151
150
|
)
|
151
|
+
source_id: Optional[UUID] = pydantic.Field(default=None)
|
152
|
+
arithmetic_id: Optional[str] = pydantic.Field(default=None)
|
153
|
+
inverse_op_id: Optional[UUID] = pydantic.Field(default=None)
|
154
|
+
|
155
|
+
uuid: UUID = pydantic.Field(default_factory=uuid4)
|
152
156
|
|
153
157
|
def __eq__(self, other: Any) -> bool:
|
154
158
|
return (
|
@@ -159,14 +163,14 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
159
163
|
return hash(self.name)
|
160
164
|
|
161
165
|
@property
|
162
|
-
def non_zero_input_wires(self) ->
|
166
|
+
def non_zero_input_wires(self) -> list[WireName]:
|
163
167
|
in_out_input_wires = [
|
164
168
|
split_wire_pair_to_wires(inout)[0] for inout in self.inouts.values()
|
165
169
|
]
|
166
170
|
return get_non_zero_wires(self.inputs_dict.values()) + in_out_input_wires
|
167
171
|
|
168
172
|
@property
|
169
|
-
def non_zero_output_wires(self) ->
|
173
|
+
def non_zero_output_wires(self) -> list[WireName]:
|
170
174
|
in_out_output_wires = [
|
171
175
|
split_wire_pair_to_wires(inout)[1] for inout in self.inouts.values()
|
172
176
|
]
|
@@ -209,8 +213,9 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
209
213
|
return self.function_params.inputs_full(self.strict_zero_ios)
|
210
214
|
return self.function_params.outputs
|
211
215
|
|
212
|
-
@pydantic.
|
213
|
-
|
216
|
+
@pydantic.field_validator("name", mode="before")
|
217
|
+
@classmethod
|
218
|
+
def _create_name(cls, name: Optional[str], info: ValidationInfo) -> str:
|
214
219
|
"""
|
215
220
|
generates a name to a user defined-functions as follows:
|
216
221
|
<function_name>_<SUFFIX_MARKER>_<random_suffix>
|
@@ -218,40 +223,48 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
218
223
|
if name is not None:
|
219
224
|
match = re.fullmatch(pattern=NAME_REGEX, string=name)
|
220
225
|
if match is None:
|
221
|
-
raise
|
226
|
+
raise ClassiqValueError(BAD_CALL_NAME_ERROR_MSG)
|
222
227
|
return name
|
223
228
|
|
224
|
-
function =
|
229
|
+
function = info.data.get("function")
|
225
230
|
|
226
|
-
params =
|
227
|
-
if
|
228
|
-
|
229
|
-
|
231
|
+
params = info.data.get("function_params")
|
232
|
+
if (
|
233
|
+
isinstance(params, CustomFunction)
|
234
|
+
and function == CustomFunction.discriminator()
|
235
|
+
and params.name != ""
|
236
|
+
):
|
237
|
+
function = params.name
|
230
238
|
|
231
239
|
suffix = f"{SUFFIX_MARKER}_{randomize_suffix()}"
|
232
240
|
if not function or params is None:
|
233
241
|
return name if name else suffix
|
234
|
-
return f"{function}_{suffix}"
|
242
|
+
return f"{generate_original_function_name(function)}_{suffix}"
|
235
243
|
|
236
|
-
@pydantic.
|
237
|
-
|
238
|
-
|
239
|
-
|
244
|
+
@pydantic.model_validator(mode="before")
|
245
|
+
@classmethod
|
246
|
+
def validate_composite_name(cls, values: Any) -> dict[str, Any]:
|
247
|
+
if (
|
248
|
+
isinstance(values, dict)
|
249
|
+
and isinstance(values.get("unitary_params"), CustomFunction)
|
250
|
+
and not values.get("unitary")
|
240
251
|
):
|
241
252
|
raise ClassiqValueError(
|
242
253
|
"`PhaseEstimation` of a user define function (`CustomFunction`) must receive the function name from the `unitary` field"
|
243
254
|
)
|
244
255
|
return values
|
245
256
|
|
246
|
-
@pydantic.
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
257
|
+
@pydantic.model_validator(mode="before")
|
258
|
+
@classmethod
|
259
|
+
def _parse_function_params(cls, values: Any) -> dict[str, Any]:
|
260
|
+
if isinstance(values, dict):
|
261
|
+
f_params.parse_function_params_values(
|
262
|
+
values=values,
|
263
|
+
params_key="function_params",
|
264
|
+
discriminator_key="function",
|
265
|
+
param_classes=function_param_list.function_param_library.param_list,
|
266
|
+
default_parser_class=CustomFunction,
|
267
|
+
)
|
255
268
|
return values
|
256
269
|
|
257
270
|
# TODO: note that this checks QuantumFunctionCall input register names
|
@@ -263,7 +276,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
263
276
|
params: f_params.FunctionParams,
|
264
277
|
inputs: WireDict,
|
265
278
|
is_inverse: bool,
|
266
|
-
control_states:
|
279
|
+
control_states: list[ControlState],
|
267
280
|
strict_zero_ios: bool,
|
268
281
|
) -> None:
|
269
282
|
(
|
@@ -285,24 +298,27 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
285
298
|
if invalid_slicings:
|
286
299
|
error_msg.append(f"{BAD_INPUT_SLICING_MSG}: {invalid_slicings}")
|
287
300
|
if error_msg:
|
288
|
-
raise
|
301
|
+
raise ClassiqValueError("\n".join(error_msg))
|
289
302
|
|
290
|
-
@pydantic.
|
303
|
+
@pydantic.field_validator("strict_zero_ios")
|
304
|
+
@classmethod
|
291
305
|
def _validate_arithmetic_cannot_strict_zero_ios(
|
292
|
-
cls, strict_zero_ios: bool,
|
306
|
+
cls, strict_zero_ios: bool, info: ValidationInfo
|
293
307
|
) -> bool:
|
294
308
|
assert not (
|
295
|
-
|
309
|
+
info.data.get("function") == Arithmetic.discriminator()
|
310
|
+
and not strict_zero_ios
|
296
311
|
), "when using the Arithmetic function, assign to the expression result register via the target parameter instead of the strict_zero_ios flag"
|
297
312
|
return strict_zero_ios
|
298
313
|
|
299
|
-
@pydantic.
|
314
|
+
@pydantic.field_validator("control_states")
|
315
|
+
@classmethod
|
300
316
|
def _validate_control_states(
|
301
|
-
cls, control_states:
|
302
|
-
) ->
|
317
|
+
cls, control_states: list[ControlState], info: ValidationInfo
|
318
|
+
) -> list[ControlState]:
|
303
319
|
control_names = [ctrl_state.name for ctrl_state in control_states]
|
304
|
-
function_params =
|
305
|
-
strict_zero_ios =
|
320
|
+
function_params = info.data.get("function_params")
|
321
|
+
strict_zero_ios = info.data.get("strict_zero_ios")
|
306
322
|
if not (
|
307
323
|
isinstance(function_params, FunctionParams)
|
308
324
|
and isinstance(strict_zero_ios, bool)
|
@@ -330,10 +346,10 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
330
346
|
inputs: IOType,
|
331
347
|
fp: FunctionParams,
|
332
348
|
strict_zero_ios: bool,
|
333
|
-
control_states:
|
349
|
+
control_states: list[ControlState],
|
334
350
|
) -> None:
|
335
351
|
name_slice_pairs = [parse_io_slicing(input) for input in inputs]
|
336
|
-
slices_dict:
|
352
|
+
slices_dict: dict[str, list[slice]] = defaultdict(list)
|
337
353
|
for name, slice in name_slice_pairs:
|
338
354
|
slices_dict[name].append(slice)
|
339
355
|
|
@@ -352,10 +368,10 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
352
368
|
if not SynthesisQuantumFunctionCall._register_validate_slices(
|
353
369
|
slices_dict[name], widths[name]
|
354
370
|
):
|
355
|
-
raise
|
371
|
+
raise ClassiqValueError(BAD_INPUT_SLICING_MSG)
|
356
372
|
|
357
373
|
@staticmethod
|
358
|
-
def _register_validate_slices(slices:
|
374
|
+
def _register_validate_slices(slices: list[slice], reg_width: int) -> bool:
|
359
375
|
widths_separated = [len(range(reg_width)[reg_slice]) for reg_slice in slices]
|
360
376
|
# examples: slice(0), slice(5,None) when width <= 5, slice(5,3)
|
361
377
|
empty_slices = 0 in widths_separated
|
@@ -374,17 +390,18 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
374
390
|
|
375
391
|
return not any((empty_slices, out_of_range, overlapping_slices))
|
376
392
|
|
377
|
-
@pydantic.
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
393
|
+
@pydantic.field_validator("inputs", mode="before")
|
394
|
+
@classmethod
|
395
|
+
def _validate_inputs(cls, inputs: IOType, info: ValidationInfo) -> WireDict:
|
396
|
+
params: Optional[FunctionParams] = info.data.get("function_params")
|
397
|
+
is_inverse: bool = info.data.get("is_inverse", False)
|
398
|
+
strict_zero_ios: bool = info.data.get("strict_zero_ios", True)
|
399
|
+
control_states: list[ControlState] = info.data.get("control_states", list())
|
383
400
|
if params is None:
|
384
401
|
return dict()
|
385
402
|
if isinstance(params, CustomFunction):
|
386
403
|
if not isinstance(inputs, dict):
|
387
|
-
raise
|
404
|
+
raise ClassiqValueError(CUSTOM_FUNCTION_SINGLE_IO_ERROR)
|
388
405
|
return inputs
|
389
406
|
|
390
407
|
if isinstance(inputs, str):
|
@@ -420,7 +437,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
420
437
|
params: f_params.FunctionParams,
|
421
438
|
outputs: WireDict,
|
422
439
|
is_inverse: bool,
|
423
|
-
control_states:
|
440
|
+
control_states: list[ControlState],
|
424
441
|
strict_zero_ios: bool,
|
425
442
|
) -> None:
|
426
443
|
(
|
@@ -442,19 +459,20 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
442
459
|
if invalid_slicings:
|
443
460
|
error_msg.append(f"{BAD_OUTPUT_SLICING_MSG}: {invalid_slicings}")
|
444
461
|
if error_msg:
|
445
|
-
raise
|
446
|
-
|
447
|
-
@pydantic.
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
462
|
+
raise ClassiqValueError("\n".join(error_msg))
|
463
|
+
|
464
|
+
@pydantic.field_validator("outputs", mode="before")
|
465
|
+
@classmethod
|
466
|
+
def _validate_outputs(cls, outputs: IOType, info: ValidationInfo) -> IOType:
|
467
|
+
params = info.data.get("function_params")
|
468
|
+
is_inverse: bool = info.data.get("is_inverse", False)
|
469
|
+
strict_zero_ios: bool = info.data.get("strict_zero_ios", True)
|
470
|
+
control_states = info.data.get("control_states", list())
|
453
471
|
if params is None:
|
454
472
|
return outputs
|
455
473
|
if isinstance(params, CustomFunction):
|
456
474
|
if not isinstance(outputs, dict):
|
457
|
-
raise
|
475
|
+
raise ClassiqValueError(CUSTOM_FUNCTION_SINGLE_IO_ERROR)
|
458
476
|
return outputs
|
459
477
|
|
460
478
|
if isinstance(outputs, str):
|
@@ -484,17 +502,18 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
484
502
|
|
485
503
|
return outputs
|
486
504
|
|
487
|
-
@pydantic.
|
505
|
+
@pydantic.field_validator("power")
|
506
|
+
@classmethod
|
488
507
|
def _validate_power(
|
489
|
-
cls, power: pydantic.NonNegativeInt,
|
508
|
+
cls, power: pydantic.NonNegativeInt, info: ValidationInfo
|
490
509
|
) -> pydantic.NonNegativeInt:
|
491
|
-
function_params =
|
510
|
+
function_params = info.data.get("function_params")
|
492
511
|
if function_params is None:
|
493
512
|
return power
|
494
513
|
if power != 1 and not function_params.is_powerable(
|
495
|
-
|
514
|
+
info.data.get("strict_zero_ios")
|
496
515
|
):
|
497
|
-
raise
|
516
|
+
raise ClassiqValueError("Cannot power this operator")
|
498
517
|
return power
|
499
518
|
|
500
519
|
@staticmethod
|
@@ -519,7 +538,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
519
538
|
io_wire=io_wire,
|
520
539
|
function_name=type(params).__name__,
|
521
540
|
)
|
522
|
-
raise
|
541
|
+
raise ClassiqValueError(error_message)
|
523
542
|
|
524
543
|
@staticmethod
|
525
544
|
def _get_invalid_ios(
|
@@ -527,15 +546,15 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
527
546
|
expressions: Iterable[str],
|
528
547
|
params: f_params.FunctionParams,
|
529
548
|
io: f_params.PortDirection,
|
530
|
-
control_states:
|
549
|
+
control_states: list[ControlState],
|
531
550
|
strict_zero_ios: bool,
|
532
|
-
) ->
|
551
|
+
) -> tuple[list[str], list[str], list[str]]:
|
533
552
|
expression_matches: Iterable[Optional[Match]] = map(
|
534
553
|
functools.partial(re.fullmatch, IO_REGEX), expressions
|
535
554
|
)
|
536
555
|
|
537
|
-
valid_matches:
|
538
|
-
invalid_expressions:
|
556
|
+
valid_matches: list[Match] = []
|
557
|
+
invalid_expressions: list[str] = []
|
539
558
|
for expression, expression_match in zip(expressions, expression_matches):
|
540
559
|
(
|
541
560
|
invalid_expressions.append(expression)
|
@@ -543,8 +562,8 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
543
562
|
else valid_matches.append(expression_match)
|
544
563
|
)
|
545
564
|
|
546
|
-
invalid_slicings:
|
547
|
-
invalid_names:
|
565
|
+
invalid_slicings: list[str] = []
|
566
|
+
invalid_names: list[str] = []
|
548
567
|
valid_names = frozenset(
|
549
568
|
params.inputs_full(strict_zero_ios)
|
550
569
|
if io == PortDirection.Input
|
@@ -610,7 +629,9 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
610
629
|
control_state.name in self.inputs_dict
|
611
630
|
or control_state.name in self.outputs_dict
|
612
631
|
):
|
613
|
-
raise
|
632
|
+
raise ClassiqValueError(
|
633
|
+
f"Control name: {control_state.name} already exists"
|
634
|
+
)
|
614
635
|
|
615
636
|
inputs, outputs = dict(self.inputs_dict), dict(self.outputs_dict)
|
616
637
|
inputs.update({control_state.name: input_wire})
|
@@ -623,8 +644,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
623
644
|
call_kwargs["control_states"] = self.control_states + [control_state]
|
624
645
|
return SynthesisQuantumFunctionCall(**call_kwargs)
|
625
646
|
|
626
|
-
|
627
|
-
extra = Extra.forbid
|
647
|
+
model_config = ConfigDict(extra="forbid")
|
628
648
|
|
629
649
|
|
630
650
|
def _generate_single_io_err(
|
@@ -1,12 +1,17 @@
|
|
1
1
|
import uuid
|
2
|
-
from datetime import datetime
|
2
|
+
from datetime import datetime, timezone
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import
|
4
|
+
from typing import Optional, Union
|
5
5
|
|
6
6
|
import pydantic
|
7
7
|
from typing_extensions import TypeAlias
|
8
8
|
|
9
|
-
from classiq.interface.
|
9
|
+
from classiq.interface.exceptions import (
|
10
|
+
ClassiqMissingOutputFormatError,
|
11
|
+
ClassiqStateInitializationError,
|
12
|
+
)
|
13
|
+
from classiq.interface.execution.primitives import PrimitivesInput
|
14
|
+
from classiq.interface.executor import quantum_code
|
10
15
|
from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
|
11
16
|
from classiq.interface.executor.register_initialization import RegisterInitialization
|
12
17
|
from classiq.interface.generator.circuit_code.circuit_code import CircuitCodeInterface
|
@@ -17,31 +22,26 @@ from classiq.interface.generator.circuit_code.types_and_constants import (
|
|
17
22
|
CodeAndSyntax,
|
18
23
|
)
|
19
24
|
from classiq.interface.generator.generated_circuit_data import (
|
20
|
-
|
25
|
+
FunctionDebugInfoInterface,
|
21
26
|
GeneratedCircuitData,
|
22
27
|
)
|
23
28
|
from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
|
24
|
-
from classiq.interface.generator.model.model import ExecutionModel
|
29
|
+
from classiq.interface.generator.model.model import ExecutionModel
|
25
30
|
from classiq.interface.generator.synthesis_metadata.synthesis_duration import (
|
26
31
|
SynthesisStepDurations,
|
27
32
|
)
|
28
33
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
29
|
-
from classiq.interface.ide.
|
30
|
-
|
31
|
-
from classiq.exceptions import (
|
32
|
-
ClassiqMissingOutputFormatError,
|
33
|
-
ClassiqStateInitializationError,
|
34
|
-
)
|
34
|
+
from classiq.interface.ide.visual_model import CircuitMetrics
|
35
35
|
|
36
36
|
RegisterName: TypeAlias = str
|
37
|
-
InitialConditions: TypeAlias =
|
37
|
+
InitialConditions: TypeAlias = dict[RegisterName, int]
|
38
38
|
|
39
39
|
|
40
40
|
class TranspiledCircuitData(CircuitCodeInterface):
|
41
41
|
depth: int
|
42
|
-
count_ops:
|
43
|
-
logical_to_physical_input_qubit_map:
|
44
|
-
logical_to_physical_output_qubit_map:
|
42
|
+
count_ops: dict[str, int]
|
43
|
+
logical_to_physical_input_qubit_map: list[int]
|
44
|
+
logical_to_physical_output_qubit_map: list[int]
|
45
45
|
|
46
46
|
def get_circuit_metrics(self) -> CircuitMetrics:
|
47
47
|
return CircuitMetrics(depth=self.depth, count_ops=self.count_ops)
|
@@ -51,16 +51,25 @@ def get_uuid_as_str() -> str:
|
|
51
51
|
return str(uuid.uuid4())
|
52
52
|
|
53
53
|
|
54
|
-
|
54
|
+
def _get_formatted_utc_current_time() -> str:
|
55
|
+
# The purpose of this method is to replicate the behavior of
|
56
|
+
# datetime.utcnow().isoformat(), since `utcnow` is now deprecated
|
57
|
+
return datetime.now(timezone.utc).isoformat().split("+")[0]
|
58
|
+
|
59
|
+
|
60
|
+
class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
55
61
|
hardware_data: SynthesisHardwareData
|
56
|
-
initial_values: Optional[InitialConditions]
|
62
|
+
initial_values: Optional[InitialConditions] = pydantic.Field(default=None)
|
57
63
|
data: GeneratedCircuitData
|
58
|
-
model:
|
59
|
-
transpiled_circuit: Optional[TranspiledCircuitData]
|
60
|
-
creation_time: str = pydantic.Field(default_factory=
|
61
|
-
synthesis_duration: Optional[SynthesisStepDurations]
|
62
|
-
debug_info: Optional[
|
64
|
+
model: ExecutionModel
|
65
|
+
transpiled_circuit: Optional[TranspiledCircuitData] = pydantic.Field(default=None)
|
66
|
+
creation_time: str = pydantic.Field(default_factory=_get_formatted_utc_current_time)
|
67
|
+
synthesis_duration: Optional[SynthesisStepDurations] = pydantic.Field(default=None)
|
68
|
+
debug_info: Optional[list[FunctionDebugInfoInterface]] = pydantic.Field(
|
69
|
+
default=None
|
70
|
+
)
|
63
71
|
program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
|
72
|
+
execution_primitives_input: Optional[PrimitivesInput] = pydantic.Field(default=None)
|
64
73
|
|
65
74
|
def _hardware_agnostic_program_code(self) -> CodeAndSyntax:
|
66
75
|
circuit_code = self.program_circuit.get_code_by_priority()
|
@@ -81,15 +90,15 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
81
90
|
)
|
82
91
|
return self.program_circuit.get_code(instruction_set), instruction_set
|
83
92
|
|
84
|
-
def to_base_program(self) ->
|
93
|
+
def to_base_program(self) -> quantum_code.QuantumBaseCode:
|
85
94
|
code, syntax = self._default_program_code()
|
86
|
-
return
|
95
|
+
return quantum_code.QuantumBaseCode(code=code, syntax=syntax)
|
87
96
|
|
88
97
|
def to_program(
|
89
98
|
self,
|
90
99
|
initial_values: Optional[InitialConditions] = None,
|
91
100
|
instruction_set: Optional[QuantumInstructionSet] = None,
|
92
|
-
) ->
|
101
|
+
) -> quantum_code.QuantumCode:
|
93
102
|
initial_values = initial_values or self.initial_values
|
94
103
|
|
95
104
|
if instruction_set is not None:
|
@@ -106,7 +115,7 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
106
115
|
)
|
107
116
|
else:
|
108
117
|
registers_initialization = None
|
109
|
-
return
|
118
|
+
return quantum_code.QuantumCode(
|
110
119
|
code=code,
|
111
120
|
syntax=syntax,
|
112
121
|
output_qubits_map=self.data.qubit_mapping.physical_outputs,
|
@@ -114,7 +123,7 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
114
123
|
synthesis_execution_data=self.data.execution_data,
|
115
124
|
)
|
116
125
|
|
117
|
-
def _get_initialization_qubits(self, name: str) ->
|
126
|
+
def _get_initialization_qubits(self, name: str) -> tuple[int, ...]:
|
118
127
|
qubits = self.data.qubit_mapping.logical_inputs.get(name)
|
119
128
|
if qubits is None:
|
120
129
|
raise ClassiqStateInitializationError(
|
@@ -124,7 +133,7 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
124
133
|
|
125
134
|
def get_registers_initialization(
|
126
135
|
self, initial_values: InitialConditions
|
127
|
-
) ->
|
136
|
+
) -> dict[RegisterName, RegisterInitialization]:
|
128
137
|
return {
|
129
138
|
name: RegisterInitialization(
|
130
139
|
name=name,
|
@@ -136,11 +145,10 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
136
145
|
|
137
146
|
def save_results(self, filename: Optional[Union[str, Path]] = None) -> None:
|
138
147
|
"""
|
139
|
-
Saves
|
148
|
+
Saves quantum program results as json into a file.
|
140
149
|
Parameters:
|
141
150
|
filename (Union[str, Path]): Optional, path + filename of file.
|
142
151
|
If filename supplied add `.json` suffix.
|
143
|
-
|
144
152
|
Returns:
|
145
153
|
None
|
146
154
|
"""
|
@@ -148,11 +156,20 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
148
156
|
filename = f"synthesised_circuit_{self.creation_time}.json"
|
149
157
|
|
150
158
|
with open(filename, "w") as file:
|
151
|
-
file.write(self.
|
159
|
+
file.write(self.model_dump_json(indent=4))
|
152
160
|
|
153
161
|
@classmethod
|
154
|
-
def from_qprog(cls, qprog: str) -> "
|
155
|
-
|
162
|
+
def from_qprog(cls, qprog: str) -> "QuantumProgram":
|
163
|
+
"""
|
164
|
+
Creates a `QuantumProgram` instance from a raw quantum program string.
|
165
|
+
|
166
|
+
Args:
|
167
|
+
qprog: The raw quantum program in string format.
|
168
|
+
|
169
|
+
Returns:
|
170
|
+
QuantumProgram: The `QuantumProgram` instance.
|
171
|
+
"""
|
172
|
+
return cls.model_validate_json(qprog)
|
156
173
|
|
157
174
|
@property
|
158
175
|
def _can_use_transpiled_code(self) -> bool:
|
@@ -165,7 +182,3 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
165
182
|
if self.transpiled_circuit and self._can_use_transpiled_code
|
166
183
|
else self
|
167
184
|
)
|
168
|
-
|
169
|
-
@property
|
170
|
-
def execution_model(self) -> ExecutionModel:
|
171
|
-
return self.model.classical_model()
|
@@ -1,8 +1,11 @@
|
|
1
1
|
import math
|
2
|
-
from typing import
|
2
|
+
from typing import Generic, Optional, TypeVar
|
3
3
|
|
4
4
|
import pydantic
|
5
|
-
from pydantic
|
5
|
+
from pydantic import BaseModel, ConfigDict
|
6
|
+
from typing_extensions import Self
|
7
|
+
|
8
|
+
from classiq.interface.exceptions import ClassiqValueError
|
6
9
|
|
7
10
|
RangeType = TypeVar("RangeType", int, float)
|
8
11
|
|
@@ -13,26 +16,24 @@ DEF_ATOL: float = 1e-08
|
|
13
16
|
DEF_RTOL: float = 1e-05
|
14
17
|
|
15
18
|
|
16
|
-
class Range(
|
19
|
+
class Range(BaseModel, Generic[RangeType]):
|
17
20
|
lower_bound: Optional[RangeType] = None
|
18
21
|
upper_bound: Optional[RangeType] = None
|
22
|
+
model_config = ConfigDict(frozen=True)
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def _validate_bounds_order(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
25
|
-
lower_bound = values.get("lower_bound")
|
26
|
-
upper_bound = values.get("upper_bound")
|
24
|
+
@pydantic.model_validator(mode="after")
|
25
|
+
def _validate_bounds_order(self) -> Self:
|
26
|
+
lower_bound = self.lower_bound
|
27
|
+
upper_bound = self.upper_bound
|
27
28
|
|
28
29
|
if (
|
29
30
|
lower_bound is not None
|
30
31
|
and upper_bound is not None
|
31
32
|
and lower_bound > upper_bound
|
32
33
|
):
|
33
|
-
raise
|
34
|
+
raise ClassiqValueError("lower bound must not be greater than upper bound")
|
34
35
|
|
35
|
-
return
|
36
|
+
return self
|
36
37
|
|
37
38
|
def is_lower_bound_sat_by(
|
38
39
|
self, value: float, atol: float = DEF_ATOL, rtol: float = DEF_RTOL
|