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
@@ -1,160 +1,193 @@
|
|
1
1
|
import dataclasses
|
2
|
-
import inspect
|
3
2
|
import sys
|
4
|
-
from
|
3
|
+
from collections.abc import Sequence
|
4
|
+
from enum import EnumMeta
|
5
|
+
from typing import (
|
6
|
+
Any,
|
7
|
+
Callable,
|
8
|
+
Literal,
|
9
|
+
Optional,
|
10
|
+
get_args,
|
11
|
+
get_origin,
|
12
|
+
overload,
|
13
|
+
)
|
5
14
|
|
6
15
|
from typing_extensions import _AnnotatedAlias
|
7
16
|
|
8
|
-
from classiq.interface.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
ConcreteClassicalType,
|
13
|
-
Integer,
|
14
|
-
QStructBase,
|
15
|
-
Real,
|
16
|
-
Struct,
|
17
|
+
from classiq.interface.exceptions import ClassiqValueError
|
18
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
19
|
+
from classiq.interface.generator.functions.port_declaration import (
|
20
|
+
PortDeclarationDirection,
|
17
21
|
)
|
22
|
+
from classiq.interface.generator.types.enum_declaration import declaration_from_enum
|
23
|
+
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
18
24
|
from classiq.interface.model.classical_parameter_declaration import (
|
19
|
-
|
25
|
+
AnonClassicalParameterDeclaration,
|
20
26
|
)
|
21
|
-
from classiq.interface.model.port_declaration import
|
27
|
+
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
22
28
|
from classiq.interface.model.quantum_function_declaration import (
|
29
|
+
AnonPositionalArg,
|
30
|
+
AnonQuantumOperandDeclaration,
|
31
|
+
NamedParamsQuantumFunctionDeclaration,
|
23
32
|
PositionalArg,
|
24
|
-
QuantumFunctionDeclaration,
|
25
|
-
QuantumOperandDeclaration,
|
26
33
|
)
|
27
34
|
|
28
|
-
from classiq import
|
35
|
+
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
36
|
+
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
29
37
|
from classiq.qmod.model_state_container import ModelStateContainer
|
30
|
-
from classiq.qmod.
|
31
|
-
from classiq.qmod.qmod_variable import QVar
|
32
|
-
from classiq.qmod.quantum_callable import
|
33
|
-
from classiq.qmod.utilities import unmangle_keyword
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
size=get_type_hint_expr(array_args[1]),
|
38
|
+
from classiq.qmod.python_classical_type import PythonClassicalType
|
39
|
+
from classiq.qmod.qmod_variable import QVar
|
40
|
+
from classiq.qmod.quantum_callable import QCallableList
|
41
|
+
from classiq.qmod.utilities import unmangle_keyword, version_portable_get_args
|
42
|
+
|
43
|
+
if sys.version_info[0:2] >= (3, 9):
|
44
|
+
from typing import Annotated
|
45
|
+
|
46
|
+
|
47
|
+
class _PythonClassicalType(PythonClassicalType):
|
48
|
+
def __init__(self, qmodule: Optional[ModelStateContainer]):
|
49
|
+
super().__init__()
|
50
|
+
self.qmodule = qmodule
|
51
|
+
|
52
|
+
def register_enum(self, py_type: EnumMeta) -> None:
|
53
|
+
if (
|
54
|
+
self.qmodule is None
|
55
|
+
or py_type.__name__ in BUILTIN_ENUM_DECLARATIONS
|
56
|
+
or py_type.__name__ in self.qmodule.enum_decls
|
57
|
+
):
|
58
|
+
return
|
59
|
+
|
60
|
+
enum_decl = declaration_from_enum(py_type)
|
61
|
+
self.qmodule.enum_decls[py_type.__name__] = enum_decl
|
62
|
+
|
63
|
+
def register_struct(self, py_type: type) -> None:
|
64
|
+
if (
|
65
|
+
self.qmodule is None
|
66
|
+
or py_type.__name__ in BUILTIN_STRUCT_DECLARATIONS
|
67
|
+
or py_type.__name__ in self.qmodule.type_decls
|
68
|
+
):
|
69
|
+
return
|
70
|
+
|
71
|
+
struct_decl = StructDeclaration(
|
72
|
+
name=py_type.__name__,
|
73
|
+
variables={
|
74
|
+
f.name: self.convert(f.type) for f in dataclasses.fields(py_type)
|
75
|
+
},
|
69
76
|
)
|
70
|
-
|
71
|
-
_add_qmod_struct(py_type, qmodule=qmodule)
|
72
|
-
return Struct(name=py_type.__name__)
|
73
|
-
return None
|
74
|
-
|
75
|
-
|
76
|
-
def _add_qmod_struct(
|
77
|
-
py_type: Type[QStructBase], *, qmodule: ModelStateContainer
|
78
|
-
) -> None:
|
79
|
-
if (
|
80
|
-
py_type.__name__ in StructDeclaration.BUILTIN_STRUCT_DECLARATIONS
|
81
|
-
or py_type.__name__ in qmodule.type_decls.keys()
|
82
|
-
):
|
83
|
-
return
|
84
|
-
|
85
|
-
qmodule.type_decls[py_type.__name__] = StructDeclaration(
|
86
|
-
name=py_type.__name__,
|
87
|
-
variables={
|
88
|
-
f.name: _python_type_to_qmod(f.type, qmodule=qmodule)
|
89
|
-
for f in dataclasses.fields(py_type)
|
90
|
-
},
|
91
|
-
)
|
77
|
+
self.qmodule.type_decls[py_type.__name__] = struct_decl
|
92
78
|
|
93
79
|
|
94
|
-
def
|
95
|
-
|
96
|
-
) ->
|
97
|
-
|
98
|
-
raise ValueError("QParam takes exactly one generic argument")
|
99
|
-
py_type = get_args(py_type)[0]
|
100
|
-
return ClassicalParameterDeclaration(
|
101
|
-
name=name, classical_type=_python_type_to_qmod(py_type, qmodule=qmodule)
|
102
|
-
)
|
80
|
+
def python_type_to_qmod(
|
81
|
+
py_type: type, *, qmodule: Optional[ModelStateContainer]
|
82
|
+
) -> Optional[ConcreteClassicalType]:
|
83
|
+
return _PythonClassicalType(qmodule).convert(py_type)
|
103
84
|
|
104
85
|
|
105
|
-
def _extract_port_decl(name: str, py_type: Any) ->
|
86
|
+
def _extract_port_decl(name: Optional[str], py_type: Any) -> AnonPortDeclaration:
|
106
87
|
# FIXME: CAD-13409
|
107
|
-
qtype:
|
88
|
+
qtype: type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
|
108
89
|
direction = qtype.port_direction(py_type)
|
109
90
|
if isinstance(py_type, _AnnotatedAlias):
|
110
91
|
py_type = py_type.__args__[0]
|
111
|
-
|
112
|
-
name=
|
92
|
+
param = AnonPortDeclaration(
|
93
|
+
name=None,
|
113
94
|
direction=direction,
|
114
95
|
quantum_type=qtype.to_qmod_quantum_type(py_type),
|
115
96
|
)
|
97
|
+
if name is not None:
|
98
|
+
param = param.rename(name)
|
99
|
+
return param
|
116
100
|
|
117
101
|
|
118
102
|
def _extract_operand_decl(
|
119
|
-
name: str, py_type: Any, qmodule: ModelStateContainer
|
120
|
-
) ->
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
103
|
+
name: Optional[str], py_type: Any, qmodule: Optional[ModelStateContainer]
|
104
|
+
) -> AnonQuantumOperandDeclaration:
|
105
|
+
is_list = (get_origin(py_type) or py_type) is QCallableList
|
106
|
+
if get_origin(py_type) is list:
|
107
|
+
is_list = True
|
108
|
+
py_type = version_portable_get_args(py_type)[0]
|
109
|
+
type_args = version_portable_get_args(py_type)
|
110
|
+
if len(type_args) > 0 and isinstance(type_args[0], list): # Callable support
|
111
|
+
type_args = tuple(type_args[0])
|
112
|
+
param_decls = [_extract_operand_param(arg_type) for arg_type in type_args]
|
113
|
+
param = AnonQuantumOperandDeclaration(
|
126
114
|
name=name,
|
127
|
-
positional_arg_declarations=_extract_positional_args(
|
128
|
-
|
115
|
+
positional_arg_declarations=_extract_positional_args(
|
116
|
+
param_decls, qmodule=qmodule
|
117
|
+
),
|
118
|
+
is_list=is_list,
|
119
|
+
)
|
120
|
+
if name is not None:
|
121
|
+
param = param.rename(name)
|
122
|
+
return param
|
123
|
+
|
124
|
+
|
125
|
+
def _extract_operand_param(py_type: Any) -> tuple[Optional[str], Any]:
|
126
|
+
if sys.version_info[0:2] < (3, 9) or get_origin(py_type) is not Annotated:
|
127
|
+
return None, py_type
|
128
|
+
args = get_args(py_type)
|
129
|
+
if len(args) == 2:
|
130
|
+
if isinstance(args[1], PortDeclarationDirection):
|
131
|
+
return None, py_type
|
132
|
+
elif isinstance(args[1], str):
|
133
|
+
return args[1], args[0]
|
134
|
+
elif get_origin(args[1]) is Literal:
|
135
|
+
return version_portable_get_args(args[1])[0], args[0]
|
136
|
+
elif len(args) == 3 and isinstance(args[1], PortDeclarationDirection):
|
137
|
+
if isinstance(args[2], str):
|
138
|
+
return args[2], Annotated[args[0], args[1]]
|
139
|
+
elif get_origin(args[2]) is Literal:
|
140
|
+
return version_portable_get_args(args[2])[0], Annotated[args[0], args[1]]
|
141
|
+
raise ClassiqValueError(
|
142
|
+
f"Operand parameter declaration must be of the form <param-type> or "
|
143
|
+
f"Annotated[<param-type>, <param-name>]. Got {py_type}"
|
129
144
|
)
|
130
145
|
|
131
146
|
|
147
|
+
@overload
|
132
148
|
def _extract_positional_args(
|
133
|
-
args:
|
134
|
-
) ->
|
135
|
-
|
136
|
-
|
149
|
+
args: Sequence[tuple[str, Any]], qmodule: Optional[ModelStateContainer]
|
150
|
+
) -> Sequence[PositionalArg]:
|
151
|
+
pass
|
152
|
+
|
153
|
+
|
154
|
+
@overload
|
155
|
+
def _extract_positional_args(
|
156
|
+
args: Sequence[tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
|
157
|
+
) -> Sequence[AnonPositionalArg]:
|
158
|
+
pass
|
159
|
+
|
160
|
+
|
161
|
+
def _extract_positional_args(
|
162
|
+
args: Sequence[tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
|
163
|
+
) -> Sequence[AnonPositionalArg]:
|
164
|
+
result: list[AnonPositionalArg] = []
|
165
|
+
for name, py_type in args:
|
137
166
|
if name == "return":
|
138
167
|
continue
|
139
168
|
name = unmangle_keyword(name)
|
140
|
-
|
141
|
-
|
169
|
+
classical_type = python_type_to_qmod(py_type, qmodule=qmodule)
|
170
|
+
if classical_type is not None:
|
171
|
+
param = AnonClassicalParameterDeclaration(
|
172
|
+
name=None,
|
173
|
+
classical_type=classical_type,
|
174
|
+
)
|
175
|
+
if name is not None:
|
176
|
+
param = param.rename(name)
|
177
|
+
result.append(param)
|
142
178
|
elif QVar.from_type_hint(py_type) is not None:
|
143
179
|
result.append(_extract_port_decl(name, py_type))
|
144
180
|
else:
|
145
|
-
assert (get_origin(py_type) or py_type) is QCallable or (
|
146
|
-
get_origin(py_type) or py_type
|
147
|
-
) is QCallableList
|
148
181
|
result.append(_extract_operand_decl(name, py_type, qmodule=qmodule))
|
149
182
|
return result
|
150
183
|
|
151
184
|
|
152
185
|
def infer_func_decl(
|
153
|
-
py_func: Callable, qmodule: ModelStateContainer
|
154
|
-
) ->
|
155
|
-
return
|
186
|
+
py_func: Callable, qmodule: Optional[ModelStateContainer] = None
|
187
|
+
) -> NamedParamsQuantumFunctionDeclaration:
|
188
|
+
return NamedParamsQuantumFunctionDeclaration(
|
156
189
|
name=unmangle_keyword(py_func.__name__),
|
157
190
|
positional_arg_declarations=_extract_positional_args(
|
158
|
-
py_func.__annotations__, qmodule=qmodule
|
191
|
+
list(py_func.__annotations__.items()), qmodule=qmodule
|
159
192
|
),
|
160
193
|
)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
from typing import TYPE_CHECKING
|
2
|
+
|
3
|
+
from classiq.interface.generator.arith.arithmetic import compute_arithmetic_result_type
|
4
|
+
from classiq.interface.generator.arith.number_utils import MAXIMAL_MACHINE_PRECISION
|
5
|
+
from classiq.interface.model.quantum_type import QuantumNumeric
|
6
|
+
|
7
|
+
from classiq.qmod.qmod_variable import QNum
|
8
|
+
from classiq.qmod.symbolic_type import SymbolicTypes
|
9
|
+
|
10
|
+
|
11
|
+
def get_expression_numeric_attributes(
|
12
|
+
vars: list[QNum],
|
13
|
+
expr: SymbolicTypes,
|
14
|
+
machine_precision: int = MAXIMAL_MACHINE_PRECISION,
|
15
|
+
) -> tuple[int, bool, int]:
|
16
|
+
"""
|
17
|
+
Computes and returns the numeric attributes of a given symbolic expression.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
vars: A list of `QNum` variables used in the symbolic expression.
|
21
|
+
expr: The symbolic expression for which numeric attributes are to be computed.
|
22
|
+
machine_precision: The precision level of the machine for the computation. Defaults to MAXIMAL_MACHINE_PRECISION = 20.
|
23
|
+
|
24
|
+
Returns:
|
25
|
+
Tuple[int, bool, int]:
|
26
|
+
A tuple containing the following numeric attributes:
|
27
|
+
- The size in bits (int) required to represent the result.
|
28
|
+
- A boolean indicating whether the result is signed (bool).
|
29
|
+
- The number of fraction digits (int) in the result.
|
30
|
+
|
31
|
+
"""
|
32
|
+
res_type = compute_arithmetic_result_type(
|
33
|
+
expr_str=str(expr),
|
34
|
+
var_types={str(var.get_handle_binding()): var.get_qmod_type() for var in vars},
|
35
|
+
machine_precision=machine_precision,
|
36
|
+
)
|
37
|
+
if TYPE_CHECKING:
|
38
|
+
assert isinstance(res_type, QuantumNumeric)
|
39
|
+
return res_type.size_in_bits, res_type.sign_value, res_type.fraction_digits_value
|
@@ -0,0 +1,42 @@
|
|
1
|
+
from collections.abc import Iterator
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import TYPE_CHECKING, Any, Optional
|
4
|
+
|
5
|
+
from classiq.interface.exceptions import ClassiqError
|
6
|
+
from classiq.interface.generator.expressions.expression import Expression
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
10
|
+
|
11
|
+
_GENERATIVE_MODE: bool = False
|
12
|
+
_FRONTEND_INTERPRETER: Optional["BaseInterpreter"] = None
|
13
|
+
|
14
|
+
|
15
|
+
def is_generative_mode() -> bool:
|
16
|
+
return _GENERATIVE_MODE
|
17
|
+
|
18
|
+
|
19
|
+
@contextmanager
|
20
|
+
def generative_mode_context(generative: bool) -> Iterator[None]:
|
21
|
+
global _GENERATIVE_MODE
|
22
|
+
previous = _GENERATIVE_MODE
|
23
|
+
_GENERATIVE_MODE = generative
|
24
|
+
try:
|
25
|
+
yield
|
26
|
+
finally:
|
27
|
+
_GENERATIVE_MODE = previous
|
28
|
+
|
29
|
+
|
30
|
+
def set_frontend_interpreter(interpreter: "BaseInterpreter") -> None:
|
31
|
+
global _FRONTEND_INTERPRETER
|
32
|
+
_FRONTEND_INTERPRETER = interpreter
|
33
|
+
|
34
|
+
|
35
|
+
def get_frontend_interpreter() -> "BaseInterpreter":
|
36
|
+
if _FRONTEND_INTERPRETER is None:
|
37
|
+
raise ClassiqError("Interpreter was not set")
|
38
|
+
return _FRONTEND_INTERPRETER
|
39
|
+
|
40
|
+
|
41
|
+
def interpret_expression(expr: str) -> Any:
|
42
|
+
return get_frontend_interpreter().evaluate(Expression(expr=expr)).value
|
@@ -1,13 +1,27 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import TYPE_CHECKING
|
2
2
|
|
3
|
-
from classiq.interface.
|
3
|
+
from classiq.interface.generator.constant import Constant
|
4
|
+
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
5
|
+
from classiq.interface.generator.types.enum_declaration import EnumDeclaration
|
6
|
+
from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
|
7
|
+
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
8
|
+
from classiq.interface.model.native_function_definition import (
|
9
|
+
NativeFunctionDefinition,
|
10
|
+
)
|
4
11
|
|
5
|
-
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from classiq.qmod.quantum_function import GenerativeQFunc
|
6
14
|
|
7
15
|
|
8
16
|
class ModelStateContainer:
|
9
|
-
|
10
|
-
|
17
|
+
enum_decls: dict[str, EnumDeclaration]
|
18
|
+
type_decls: dict[str, StructDeclaration]
|
19
|
+
qstruct_decls: dict[str, QStructDeclaration]
|
20
|
+
native_defs: dict[str, NativeFunctionDefinition]
|
21
|
+
constants: dict[str, Constant]
|
22
|
+
functions_compilation_metadata: dict[str, CompilationMetadata]
|
23
|
+
generative_functions: dict[str, "GenerativeQFunc"]
|
24
|
+
function_dependencies: dict[str, list[str]]
|
11
25
|
|
12
26
|
|
13
27
|
QMODULE = ModelStateContainer()
|
@@ -0,0 +1,194 @@
|
|
1
|
+
import ast
|
2
|
+
import re
|
3
|
+
from collections.abc import Mapping
|
4
|
+
from dataclasses import dataclass
|
5
|
+
from typing import Callable, Optional
|
6
|
+
|
7
|
+
import numpy as np
|
8
|
+
|
9
|
+
from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
|
10
|
+
|
11
|
+
IDENTIFIER = re.compile(r"[a-zA-Z_]\w*")
|
12
|
+
BINARY_OPS: Mapping[type[ast.operator], str] = {
|
13
|
+
ast.Add: "+",
|
14
|
+
ast.Sub: "-",
|
15
|
+
ast.Mult: "*",
|
16
|
+
ast.Div: "/",
|
17
|
+
ast.Mod: "%",
|
18
|
+
ast.Pow: "**",
|
19
|
+
ast.BitAnd: "&",
|
20
|
+
ast.BitOr: "|",
|
21
|
+
ast.BitXor: "^",
|
22
|
+
ast.LShift: "<<",
|
23
|
+
ast.RShift: ">>",
|
24
|
+
}
|
25
|
+
BOOL_OPS: Mapping[type[ast.boolop], str] = {ast.And: "and", ast.Or: "or"}
|
26
|
+
UNARY_OPS: Mapping[type[ast.unaryop], str] = {
|
27
|
+
ast.UAdd: "+",
|
28
|
+
ast.USub: "-",
|
29
|
+
ast.Invert: "~",
|
30
|
+
ast.Not: "not",
|
31
|
+
}
|
32
|
+
COMPARE_OPS: Mapping[type[ast.cmpop], str] = {
|
33
|
+
ast.Eq: "==",
|
34
|
+
ast.NotEq: "!=",
|
35
|
+
ast.Lt: "<",
|
36
|
+
ast.LtE: "<=",
|
37
|
+
ast.Gt: ">",
|
38
|
+
ast.GtE: ">=",
|
39
|
+
}
|
40
|
+
LIST_FORMAT_CHAR_LIMIT = 20
|
41
|
+
|
42
|
+
|
43
|
+
@dataclass
|
44
|
+
class ASTToQMODCode:
|
45
|
+
level: int
|
46
|
+
decimal_precision: Optional[int]
|
47
|
+
indent_seq: str = " "
|
48
|
+
|
49
|
+
@property
|
50
|
+
def indent(self) -> str:
|
51
|
+
return self.level * self.indent_seq
|
52
|
+
|
53
|
+
def visit(self, node: ast.AST) -> str:
|
54
|
+
return self.ast_to_code(node)
|
55
|
+
|
56
|
+
def ast_to_code(self, node: ast.AST) -> str:
|
57
|
+
if isinstance(node, ast.Module):
|
58
|
+
return self.indent.join(self.ast_to_code(child) for child in node.body)
|
59
|
+
elif isinstance(node, ast.Attribute):
|
60
|
+
# Enum attribute access
|
61
|
+
if not isinstance(node.value, ast.Name) or not isinstance(node.attr, str):
|
62
|
+
raise AssertionError("Error parsing enum attribute access")
|
63
|
+
if not (IDENTIFIER.match(node.value.id) and IDENTIFIER.match(node.attr)):
|
64
|
+
raise AssertionError("Error parsing enum attribute access")
|
65
|
+
return f"{node.value.id!s}::{node.attr!s}"
|
66
|
+
elif isinstance(node, ast.Name):
|
67
|
+
return node.id
|
68
|
+
elif isinstance(node, ast.Num):
|
69
|
+
if self.decimal_precision is None:
|
70
|
+
return str(node.n)
|
71
|
+
return str(np.round(node.n, self.decimal_precision))
|
72
|
+
elif isinstance(node, ast.Str):
|
73
|
+
return repr(node.s)
|
74
|
+
elif isinstance(node, ast.Constant):
|
75
|
+
return repr(node.value)
|
76
|
+
elif isinstance(node, ast.BinOp):
|
77
|
+
return "({} {} {})".format(
|
78
|
+
self.ast_to_code(node.left),
|
79
|
+
BINARY_OPS[type(node.op)],
|
80
|
+
self.ast_to_code(node.right),
|
81
|
+
)
|
82
|
+
elif isinstance(node, ast.UnaryOp):
|
83
|
+
unary_op = UNARY_OPS[type(node.op)]
|
84
|
+
space = " " if unary_op == "not" else ""
|
85
|
+
return f"({unary_op}{space}{self.ast_to_code(node.operand)})"
|
86
|
+
elif isinstance(node, ast.BoolOp):
|
87
|
+
return "({})".format(
|
88
|
+
(" " + BOOL_OPS[type(node.op)] + " ").join(
|
89
|
+
self.ast_to_code(value) for value in node.values
|
90
|
+
)
|
91
|
+
)
|
92
|
+
elif isinstance(node, ast.Compare):
|
93
|
+
if len(node.ops) != 1 or len(node.comparators) != 1:
|
94
|
+
raise AssertionError("Error parsing comparison expression.")
|
95
|
+
return "({} {} {})".format(
|
96
|
+
self.ast_to_code(node.left),
|
97
|
+
COMPARE_OPS[type(node.ops[0])],
|
98
|
+
self.ast_to_code(node.comparators[0]),
|
99
|
+
)
|
100
|
+
elif isinstance(node, ast.List):
|
101
|
+
elts = node.elts
|
102
|
+
elements = self.indent_items(
|
103
|
+
lambda: [self.ast_to_code(element) for element in elts]
|
104
|
+
)
|
105
|
+
return f"[{elements}]"
|
106
|
+
elif isinstance(node, ast.Subscript):
|
107
|
+
return f"{self.ast_to_code(node.value)}[{_remove_redundant_parentheses(self.ast_to_code(node.slice))}]"
|
108
|
+
elif isinstance(node, ast.Slice):
|
109
|
+
# A QMOD expression does not support slice step
|
110
|
+
if node.lower is None or node.upper is None or node.step is not None:
|
111
|
+
raise AssertionError("Error parsing slice expression.")
|
112
|
+
return f"{self.ast_to_code(node.lower)}:{self.ast_to_code(node.upper)}"
|
113
|
+
elif isinstance(node, ast.Call):
|
114
|
+
func = self.ast_to_code(node.func)
|
115
|
+
if func == "get_field":
|
116
|
+
if len(node.args) != 2:
|
117
|
+
raise AssertionError("Error parsing struct field access.")
|
118
|
+
field = str(self.ast_to_code(node.args[1])).replace("'", "")
|
119
|
+
if not IDENTIFIER.match(field):
|
120
|
+
raise AssertionError("Error parsing struct field access.")
|
121
|
+
return f"{self.ast_to_code(node.args[0])}.{field}"
|
122
|
+
elif func == "struct_literal":
|
123
|
+
if len(node.args) != 1 or not isinstance(node.args[0], ast.Name):
|
124
|
+
raise AssertionError("Error parsing struct literal.")
|
125
|
+
keywords = node.keywords
|
126
|
+
initializer_list = self.indent_items(
|
127
|
+
lambda: [
|
128
|
+
f"{keyword.arg}={self._cleaned_ast_to_code(keyword.value)}"
|
129
|
+
for keyword in keywords
|
130
|
+
if keyword.arg is not None
|
131
|
+
]
|
132
|
+
)
|
133
|
+
return f"{self.ast_to_code(node.args[0])} {{{initializer_list}}}"
|
134
|
+
else:
|
135
|
+
return "{}({})".format(
|
136
|
+
func, ", ".join(self._cleaned_ast_to_code(arg) for arg in node.args)
|
137
|
+
)
|
138
|
+
elif isinstance(node, ast.Expr):
|
139
|
+
return self._cleaned_ast_to_code(node.value)
|
140
|
+
else:
|
141
|
+
raise AssertionError("Error parsing expression: unsupported AST node.")
|
142
|
+
|
143
|
+
def indent_items(self, items: Callable[[], list[str]]) -> str:
|
144
|
+
should_indent = (
|
145
|
+
len("".join([i.strip() for i in items()])) >= LIST_FORMAT_CHAR_LIMIT
|
146
|
+
)
|
147
|
+
if should_indent:
|
148
|
+
self.level += 1
|
149
|
+
left_ws = "\n" + self.indent
|
150
|
+
inner_ws = ",\n" + self.indent
|
151
|
+
else:
|
152
|
+
left_ws = ""
|
153
|
+
inner_ws = ", "
|
154
|
+
items_ = items()
|
155
|
+
if should_indent:
|
156
|
+
self.level -= 1
|
157
|
+
right_ws = "\n" + self.indent
|
158
|
+
else:
|
159
|
+
right_ws = ""
|
160
|
+
return f"{left_ws}{inner_ws.join(items_)}{right_ws}"
|
161
|
+
|
162
|
+
def _cleaned_ast_to_code(self, node: ast.AST) -> str:
|
163
|
+
return _remove_redundant_parentheses(self.ast_to_code(node))
|
164
|
+
|
165
|
+
|
166
|
+
def _remove_redundant_parentheses(expr: str) -> str:
|
167
|
+
if not (expr.startswith("(") and expr.endswith(")")):
|
168
|
+
return expr
|
169
|
+
parentheses_map: dict[int, int] = dict()
|
170
|
+
stack: list[int] = []
|
171
|
+
for index, char in enumerate(expr):
|
172
|
+
if char == "(":
|
173
|
+
stack.append(index)
|
174
|
+
elif char == ")":
|
175
|
+
parentheses_map[stack.pop()] = index
|
176
|
+
index = 0
|
177
|
+
original_length = len(expr)
|
178
|
+
while (
|
179
|
+
index in parentheses_map
|
180
|
+
and parentheses_map[index] == original_length - index - 1
|
181
|
+
):
|
182
|
+
expr = expr[1:-1]
|
183
|
+
index += 1
|
184
|
+
return expr
|
185
|
+
|
186
|
+
|
187
|
+
def transform_expression(
|
188
|
+
expr: str,
|
189
|
+
level: int = 0,
|
190
|
+
decimal_precision: Optional[int] = DEFAULT_DECIMAL_PRECISION,
|
191
|
+
) -> str:
|
192
|
+
return ASTToQMODCode(level=level, decimal_precision=decimal_precision).visit(
|
193
|
+
ast.parse(expr)
|
194
|
+
)
|