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
@@ -0,0 +1,240 @@
|
|
1
|
+
import itertools
|
2
|
+
import re
|
3
|
+
from collections import UserDict
|
4
|
+
from collections.abc import Iterator
|
5
|
+
from dataclasses import dataclass
|
6
|
+
from functools import singledispatch
|
7
|
+
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
|
8
|
+
|
9
|
+
from sympy import Symbol
|
10
|
+
|
11
|
+
from classiq.interface.exceptions import (
|
12
|
+
ClassiqExpansionError,
|
13
|
+
ClassiqInternalExpansionError,
|
14
|
+
)
|
15
|
+
from classiq.interface.generator.expressions.evaluated_expression import (
|
16
|
+
EvaluatedExpression,
|
17
|
+
)
|
18
|
+
from classiq.interface.generator.expressions.expression import Expression
|
19
|
+
from classiq.interface.generator.expressions.expression_constants import (
|
20
|
+
CPARAM_EXECUTION_SUFFIX_PATTERN,
|
21
|
+
)
|
22
|
+
from classiq.interface.generator.expressions.qmod_struct_instance import (
|
23
|
+
QmodStructInstance,
|
24
|
+
)
|
25
|
+
from classiq.interface.generator.functions.type_name import TypeName
|
26
|
+
from classiq.interface.model.handle_binding import (
|
27
|
+
FieldHandleBinding,
|
28
|
+
HandleBinding,
|
29
|
+
SlicedHandleBinding,
|
30
|
+
SubscriptHandleBinding,
|
31
|
+
)
|
32
|
+
from classiq.interface.model.quantum_function_call import ArgValue
|
33
|
+
from classiq.interface.model.quantum_type import (
|
34
|
+
QuantumBitvector,
|
35
|
+
QuantumType,
|
36
|
+
)
|
37
|
+
|
38
|
+
if TYPE_CHECKING:
|
39
|
+
from classiq.model_expansions.closure import FunctionClosure
|
40
|
+
|
41
|
+
T = TypeVar("T")
|
42
|
+
|
43
|
+
|
44
|
+
@dataclass(frozen=True)
|
45
|
+
class QuantumSymbol:
|
46
|
+
handle: HandleBinding
|
47
|
+
quantum_type: QuantumType
|
48
|
+
|
49
|
+
@property
|
50
|
+
def is_subscript(self) -> bool:
|
51
|
+
return isinstance(self.handle, (SubscriptHandleBinding, SlicedHandleBinding))
|
52
|
+
|
53
|
+
def emit(self) -> HandleBinding:
|
54
|
+
return self.handle
|
55
|
+
|
56
|
+
def __getitem__(self, item: Union[slice, int]) -> "QuantumSymbol":
|
57
|
+
if isinstance(item, int):
|
58
|
+
return self._subscript(item)
|
59
|
+
|
60
|
+
return self._slice(item.start, item.stop)
|
61
|
+
|
62
|
+
def _slice(self, start: int, end: int) -> "QuantumSymbol":
|
63
|
+
if not isinstance(self.quantum_type, QuantumBitvector):
|
64
|
+
raise ClassiqExpansionError(
|
65
|
+
f"{self.quantum_type.type_name} is not subscriptable"
|
66
|
+
)
|
67
|
+
if start >= end:
|
68
|
+
raise ClassiqExpansionError(
|
69
|
+
f"{self.quantum_type.type_name} slice '{self.handle}[{start}:{end}]' "
|
70
|
+
f"has non-positive length"
|
71
|
+
)
|
72
|
+
array_length = self.quantum_type.length_value
|
73
|
+
if start < 0 or end > array_length:
|
74
|
+
raise ClassiqExpansionError(
|
75
|
+
f"Slice [{start}:{end}] is out of bounds of "
|
76
|
+
f"{self.quantum_type.type_name} {str(self.handle)!r} of length "
|
77
|
+
f"{array_length}"
|
78
|
+
)
|
79
|
+
return QuantumSymbol(
|
80
|
+
handle=SlicedHandleBinding(
|
81
|
+
base_handle=self.handle,
|
82
|
+
start=Expression(expr=str(start)),
|
83
|
+
end=Expression(expr=str(end)),
|
84
|
+
),
|
85
|
+
quantum_type=QuantumBitvector(
|
86
|
+
element_type=self.quantum_type.element_type,
|
87
|
+
length=Expression(expr=str(end - start)),
|
88
|
+
),
|
89
|
+
)
|
90
|
+
|
91
|
+
def _subscript(self, index: int) -> "QuantumSymbol":
|
92
|
+
if not isinstance(self.quantum_type, QuantumBitvector):
|
93
|
+
raise ClassiqExpansionError(
|
94
|
+
f"{self.quantum_type.type_name} is not subscriptable"
|
95
|
+
)
|
96
|
+
array_length = self.quantum_type.length_value
|
97
|
+
if index < 0 or index >= array_length:
|
98
|
+
raise ClassiqExpansionError(
|
99
|
+
f"Subscript {index} is out of bounds of {self.quantum_type.type_name} "
|
100
|
+
f"{str(self.handle)!r} of length {array_length}"
|
101
|
+
)
|
102
|
+
return QuantumSymbol(
|
103
|
+
handle=SubscriptHandleBinding(
|
104
|
+
base_handle=self.handle,
|
105
|
+
index=Expression(expr=str(index)),
|
106
|
+
),
|
107
|
+
quantum_type=self.quantum_type.element_type,
|
108
|
+
)
|
109
|
+
|
110
|
+
@property
|
111
|
+
def fields(self) -> dict[str, "QuantumSymbol"]:
|
112
|
+
quantum_type = self.quantum_type
|
113
|
+
if not isinstance(quantum_type, TypeName):
|
114
|
+
raise ClassiqExpansionError(
|
115
|
+
f"{self.quantum_type.type_name} is not a struct"
|
116
|
+
)
|
117
|
+
return {
|
118
|
+
field_name: QuantumSymbol(
|
119
|
+
handle=FieldHandleBinding(base_handle=self.handle, field=field_name),
|
120
|
+
quantum_type=field_type,
|
121
|
+
)
|
122
|
+
for field_name, field_type in quantum_type.fields.items()
|
123
|
+
}
|
124
|
+
|
125
|
+
|
126
|
+
@singledispatch
|
127
|
+
def evaluated_to_str(value: Any) -> str:
|
128
|
+
return str(value)
|
129
|
+
|
130
|
+
|
131
|
+
@evaluated_to_str.register
|
132
|
+
def _evaluated_to_str_list(value: list) -> str:
|
133
|
+
return f"[{', '.join(evaluated_to_str(x) for x in value)}]"
|
134
|
+
|
135
|
+
|
136
|
+
@evaluated_to_str.register
|
137
|
+
def _evaluated_to_str_struct_literal(value: QmodStructInstance) -> str:
|
138
|
+
return f"struct_literal({value.struct_declaration.name}, {', '.join(f'{k}={evaluated_to_str(v)}' for k, v in value.fields.items())})"
|
139
|
+
|
140
|
+
|
141
|
+
@dataclass(frozen=True)
|
142
|
+
class Evaluated: # FIXME: Merge with EvaluatedExpression if possible
|
143
|
+
value: Any
|
144
|
+
defining_function: Optional["FunctionClosure"] = None
|
145
|
+
|
146
|
+
def as_type(self, t: type[T]) -> T:
|
147
|
+
if t is int:
|
148
|
+
return self._as_int() # type: ignore[return-value]
|
149
|
+
|
150
|
+
if not isinstance(self.value, t):
|
151
|
+
raise ClassiqExpansionError(
|
152
|
+
f"Invalid access to expression {self.value!r} as {t}"
|
153
|
+
)
|
154
|
+
|
155
|
+
return self.value
|
156
|
+
|
157
|
+
def _as_int(self) -> int:
|
158
|
+
if not isinstance(self.value, (int, float)):
|
159
|
+
raise ClassiqExpansionError(
|
160
|
+
f"Invalid access to expression {self.value!r} as {int}"
|
161
|
+
)
|
162
|
+
|
163
|
+
return int(self.value)
|
164
|
+
|
165
|
+
def emit(self) -> ArgValue:
|
166
|
+
from classiq.model_expansions.closure import FunctionClosure
|
167
|
+
|
168
|
+
if isinstance(self.value, (QuantumSymbol, FunctionClosure)):
|
169
|
+
return self.value.emit()
|
170
|
+
if isinstance(self.value, list) and all(
|
171
|
+
isinstance(item, FunctionClosure) for item in self.value
|
172
|
+
):
|
173
|
+
return [item.emit() for item in self.value]
|
174
|
+
|
175
|
+
ret = Expression(expr=evaluated_to_str(self.value))
|
176
|
+
ret._evaluated_expr = EvaluatedExpression(value=self.value)
|
177
|
+
return ret
|
178
|
+
|
179
|
+
|
180
|
+
if TYPE_CHECKING:
|
181
|
+
EvaluatedUserDict = UserDict[str, Evaluated]
|
182
|
+
else:
|
183
|
+
EvaluatedUserDict = UserDict
|
184
|
+
|
185
|
+
|
186
|
+
class Scope(EvaluatedUserDict):
|
187
|
+
def __init__(
|
188
|
+
self,
|
189
|
+
data: Optional[dict[str, Evaluated]] = None,
|
190
|
+
/,
|
191
|
+
*,
|
192
|
+
parent: Optional["Scope"] = None,
|
193
|
+
) -> None:
|
194
|
+
super().__init__(data or {})
|
195
|
+
self._parent: Optional["Scope"] = parent
|
196
|
+
|
197
|
+
@property
|
198
|
+
def parent(self) -> Optional["Scope"]:
|
199
|
+
return self._parent
|
200
|
+
|
201
|
+
def __getitem__(self, name: str) -> Evaluated:
|
202
|
+
if name in self.data:
|
203
|
+
return self.data[name]
|
204
|
+
if self._parent is not None:
|
205
|
+
return self._parent[name]
|
206
|
+
if re.search(CPARAM_EXECUTION_SUFFIX_PATTERN, name):
|
207
|
+
return Evaluated(value=Symbol(name))
|
208
|
+
raise ClassiqExpansionError(f"Variable {name!r} is undefined")
|
209
|
+
|
210
|
+
def __contains__(self, item: Any) -> bool:
|
211
|
+
return item in self.data or (self._parent is not None and item in self._parent)
|
212
|
+
|
213
|
+
def __iter__(self) -> Iterator[str]:
|
214
|
+
if self._parent is None:
|
215
|
+
return iter(self.data)
|
216
|
+
return iter(itertools.chain(self.data, self._parent))
|
217
|
+
|
218
|
+
def iter_without_top_level(self) -> Iterator[str]:
|
219
|
+
if self.parent is None:
|
220
|
+
return iter(tuple())
|
221
|
+
return iter(itertools.chain(self.data, self.parent.iter_without_top_level()))
|
222
|
+
|
223
|
+
def __or__(self, other: Any) -> "Scope": # type: ignore[override]
|
224
|
+
if not (isinstance(other, Scope) and isinstance(self, Scope)):
|
225
|
+
raise ClassiqInternalExpansionError
|
226
|
+
|
227
|
+
if self.parent is None:
|
228
|
+
parent = other.parent
|
229
|
+
elif other.parent is None:
|
230
|
+
parent = self.parent
|
231
|
+
else:
|
232
|
+
parent = self.parent | other.parent
|
233
|
+
|
234
|
+
return Scope(
|
235
|
+
(self.data or {}) | (other.data or {}),
|
236
|
+
parent=parent,
|
237
|
+
)
|
238
|
+
|
239
|
+
def clone(self) -> "Scope":
|
240
|
+
return Scope(self.data, parent=self._parent)
|
@@ -0,0 +1,150 @@
|
|
1
|
+
from collections.abc import Sequence
|
2
|
+
from typing import TYPE_CHECKING
|
3
|
+
|
4
|
+
from classiq.interface.exceptions import ClassiqError
|
5
|
+
from classiq.interface.generator.constant import Constant
|
6
|
+
from classiq.interface.generator.expressions.expression_constants import (
|
7
|
+
CPARAM_EXECUTION_SUFFIX,
|
8
|
+
)
|
9
|
+
from classiq.interface.model.classical_parameter_declaration import (
|
10
|
+
ClassicalParameterDeclaration,
|
11
|
+
)
|
12
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
13
|
+
from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model
|
14
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
15
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
16
|
+
from classiq.interface.model.quantum_function_declaration import (
|
17
|
+
NamedParamsQuantumFunctionDeclaration,
|
18
|
+
PositionalArg,
|
19
|
+
QuantumFunctionDeclaration,
|
20
|
+
)
|
21
|
+
|
22
|
+
from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
|
23
|
+
from classiq.model_expansions.evaluators.classical_expression import (
|
24
|
+
evaluate_classical_expression,
|
25
|
+
)
|
26
|
+
from classiq.model_expansions.evaluators.parameter_types import (
|
27
|
+
evaluate_type_in_quantum_symbol,
|
28
|
+
)
|
29
|
+
from classiq.model_expansions.expression_renamer import ExpressionRenamer
|
30
|
+
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
31
|
+
from classiq.qmod.builtins import BUILTIN_CONSTANTS
|
32
|
+
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
33
|
+
from classiq.qmod.builtins.functions import (
|
34
|
+
CORE_LIB_DECLS,
|
35
|
+
STD_QMOD_OPERATORS,
|
36
|
+
)
|
37
|
+
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
38
|
+
from classiq.qmod.model_state_container import QMODULE
|
39
|
+
from classiq.qmod.quantum_function import GenerativeQFunc
|
40
|
+
|
41
|
+
|
42
|
+
def get_main_renamer(
|
43
|
+
func_decls: Sequence[QuantumFunctionDeclaration],
|
44
|
+
) -> ExpressionRenamer:
|
45
|
+
for func_decl in func_decls:
|
46
|
+
if func_decl.name == MAIN_FUNCTION_NAME:
|
47
|
+
if TYPE_CHECKING:
|
48
|
+
assert isinstance(func_decl, NamedParamsQuantumFunctionDeclaration)
|
49
|
+
return ExpressionRenamer.from_positional_arg_declarations(
|
50
|
+
func_decl.positional_arg_declarations, CPARAM_EXECUTION_SUFFIX
|
51
|
+
)
|
52
|
+
return ExpressionRenamer(var_mapping={})
|
53
|
+
|
54
|
+
|
55
|
+
def add_constants_to_scope(constants: list[Constant], scope: Scope) -> None:
|
56
|
+
for constant in constants:
|
57
|
+
scope[constant.name] = Evaluated(
|
58
|
+
value=evaluate_classical_expression(constant.value, scope).value
|
59
|
+
)
|
60
|
+
|
61
|
+
|
62
|
+
def add_functions_to_scope(
|
63
|
+
functions: Sequence[NativeFunctionDefinition], scope: Scope
|
64
|
+
) -> None:
|
65
|
+
for function in functions:
|
66
|
+
if function.name not in scope:
|
67
|
+
scope[function.name] = Evaluated(
|
68
|
+
value=FunctionClosure.create(
|
69
|
+
name=function.name,
|
70
|
+
positional_arg_declarations=function.positional_arg_declarations,
|
71
|
+
body=function.body,
|
72
|
+
scope=Scope(parent=scope),
|
73
|
+
)
|
74
|
+
)
|
75
|
+
|
76
|
+
|
77
|
+
def add_generative_functions_to_scope(
|
78
|
+
functions: Sequence[GenerativeQFunc], scope: Scope
|
79
|
+
) -> None:
|
80
|
+
for function in functions:
|
81
|
+
name = function.func_decl.name
|
82
|
+
if name == MAIN_FUNCTION_NAME or name not in scope:
|
83
|
+
scope[function.func_decl.name] = Evaluated(
|
84
|
+
value=GenerativeFunctionClosure.create(
|
85
|
+
name=function.func_decl.name,
|
86
|
+
positional_arg_declarations=function.func_decl.positional_arg_declarations,
|
87
|
+
scope=Scope(parent=scope),
|
88
|
+
generative_blocks={"body": function},
|
89
|
+
)
|
90
|
+
)
|
91
|
+
|
92
|
+
|
93
|
+
def _init_builtins_scope(scope: Scope) -> None:
|
94
|
+
for builtin_function in CORE_LIB_DECLS:
|
95
|
+
scope[builtin_function.name] = Evaluated(
|
96
|
+
value=FunctionClosure.create(
|
97
|
+
name=builtin_function.name,
|
98
|
+
positional_arg_declarations=builtin_function.positional_arg_declarations,
|
99
|
+
scope=Scope(parent=scope),
|
100
|
+
is_atomic=True,
|
101
|
+
)
|
102
|
+
)
|
103
|
+
for builtin_function in STD_QMOD_OPERATORS:
|
104
|
+
scope[builtin_function.name] = Evaluated(
|
105
|
+
value=FunctionClosure.create(
|
106
|
+
name=builtin_function.name,
|
107
|
+
positional_arg_declarations=builtin_function.positional_arg_declarations,
|
108
|
+
scope=Scope(parent=scope),
|
109
|
+
)
|
110
|
+
)
|
111
|
+
for constant in BUILTIN_CONSTANTS:
|
112
|
+
value = constant.value
|
113
|
+
if not value.is_evaluated():
|
114
|
+
raise ClassiqError(
|
115
|
+
f"Unevaluated built-in constants not supported. Offending constant: "
|
116
|
+
f"{constant.name} = {value}"
|
117
|
+
)
|
118
|
+
scope[constant.name] = Evaluated(value=value.value.value)
|
119
|
+
|
120
|
+
|
121
|
+
def add_entry_point_params_to_scope(
|
122
|
+
parameters: Sequence[PositionalArg], main_closure: FunctionClosure
|
123
|
+
) -> None:
|
124
|
+
for parameter in parameters:
|
125
|
+
if isinstance(parameter, PortDeclaration):
|
126
|
+
main_closure.scope[parameter.name] = Evaluated(
|
127
|
+
value=QuantumSymbol(
|
128
|
+
handle=HandleBinding(name=parameter.name),
|
129
|
+
quantum_type=evaluate_type_in_quantum_symbol(
|
130
|
+
parameter.quantum_type, main_closure.scope, parameter.name
|
131
|
+
),
|
132
|
+
),
|
133
|
+
defining_function=main_closure,
|
134
|
+
)
|
135
|
+
elif isinstance(parameter, ClassicalParameterDeclaration):
|
136
|
+
main_closure.scope[parameter.name] = Evaluated(
|
137
|
+
value=parameter.classical_type.as_symbolic(parameter.name),
|
138
|
+
defining_function=main_closure,
|
139
|
+
)
|
140
|
+
|
141
|
+
|
142
|
+
def init_top_level_scope(model: Model, scope: Scope) -> None:
|
143
|
+
add_functions_to_scope(model.functions, scope)
|
144
|
+
add_constants_to_scope(model.constants, scope)
|
145
|
+
_init_builtins_scope(scope)
|
146
|
+
|
147
|
+
|
148
|
+
def init_builtin_types() -> None:
|
149
|
+
QMODULE.enum_decls |= BUILTIN_ENUM_DECLARATIONS
|
150
|
+
QMODULE.type_decls |= BUILTIN_STRUCT_DECLARATIONS
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from typing import Any, Optional
|
2
|
+
|
3
|
+
from sympy import Function, Integer
|
4
|
+
from sympy.logic.boolalg import BooleanFunction
|
5
|
+
|
6
|
+
|
7
|
+
class BitwiseAnd(Function):
|
8
|
+
@classmethod
|
9
|
+
def eval(cls, a: Any, b: Any) -> Optional[int]:
|
10
|
+
if isinstance(a, Integer) and isinstance(b, Integer):
|
11
|
+
return a & b
|
12
|
+
|
13
|
+
return None
|
14
|
+
|
15
|
+
|
16
|
+
class BitwiseXor(Function):
|
17
|
+
@classmethod
|
18
|
+
def eval(cls, a: Any, b: Any) -> Optional[int]:
|
19
|
+
if isinstance(a, Integer) and isinstance(b, Integer):
|
20
|
+
return a ^ b
|
21
|
+
|
22
|
+
return None
|
23
|
+
|
24
|
+
|
25
|
+
class LogicalXor(BooleanFunction):
|
26
|
+
@classmethod
|
27
|
+
def eval(cls, a: Any, b: Any) -> Optional[bool]:
|
28
|
+
if isinstance(a, bool) and isinstance(b, bool):
|
29
|
+
return a ^ b
|
30
|
+
|
31
|
+
return None
|
32
|
+
|
33
|
+
|
34
|
+
class BitwiseOr(Function):
|
35
|
+
@classmethod
|
36
|
+
def eval(cls, a: Any, b: Any) -> Optional[int]:
|
37
|
+
if isinstance(a, Integer) and isinstance(b, Integer):
|
38
|
+
return a | b
|
39
|
+
|
40
|
+
return None
|
41
|
+
|
42
|
+
|
43
|
+
class BitwiseNot(Function):
|
44
|
+
@classmethod
|
45
|
+
def eval(cls, a: Any) -> Optional[int]:
|
46
|
+
if isinstance(a, Integer):
|
47
|
+
return ~a
|
48
|
+
|
49
|
+
return None
|
@@ -0,0 +1,179 @@
|
|
1
|
+
import ast
|
2
|
+
from typing import TYPE_CHECKING, cast
|
3
|
+
|
4
|
+
from classiq.interface.exceptions import ClassiqExpansionError
|
5
|
+
|
6
|
+
MISSING_SLICE_VALUE_PLACEHOLDER = "MISSING_SLICE_VALUE"
|
7
|
+
|
8
|
+
|
9
|
+
def translate_to_sympy(expr: str) -> str:
|
10
|
+
node = ast.parse(expr)
|
11
|
+
node = ExpressionSympyTranslator().visit(node)
|
12
|
+
# node is a Module, we want an Expression
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
assert isinstance(node.body[0], ast.Expr)
|
15
|
+
expression = ast.Expression(node.body[0].value)
|
16
|
+
|
17
|
+
return ast.unparse(ast.fix_missing_locations(expression))
|
18
|
+
|
19
|
+
|
20
|
+
class ExpressionSympyTranslator(ast.NodeTransformer):
|
21
|
+
BINARY_OPERATORS: dict[type[ast.AST], str] = {
|
22
|
+
ast.BitOr: "BitwiseOr",
|
23
|
+
ast.BitAnd: "BitwiseAnd",
|
24
|
+
ast.BitXor: "BitwiseXor",
|
25
|
+
ast.Div: "do_div",
|
26
|
+
}
|
27
|
+
|
28
|
+
UNARY_OPERATORS: dict[type[ast.AST], str] = {
|
29
|
+
ast.Invert: "BitwiseNot",
|
30
|
+
ast.Not: "Not",
|
31
|
+
}
|
32
|
+
|
33
|
+
BOOLEAN_OPERATORS: dict[type[ast.AST], str] = {
|
34
|
+
ast.Or: "Or",
|
35
|
+
ast.And: "And",
|
36
|
+
}
|
37
|
+
|
38
|
+
COMPARE_OPERATORS: dict[type[ast.AST], str] = {
|
39
|
+
ast.Eq: "Eq",
|
40
|
+
ast.NotEq: "Ne",
|
41
|
+
}
|
42
|
+
|
43
|
+
SPECIAL_FUNCTIONS: dict[str, str] = {
|
44
|
+
"max": "Max",
|
45
|
+
"min": "Min",
|
46
|
+
}
|
47
|
+
|
48
|
+
def visit_BinOp(self, node: ast.BinOp) -> ast.AST:
|
49
|
+
sympy_class = self.BINARY_OPERATORS.get(node.op.__class__)
|
50
|
+
if sympy_class is not None:
|
51
|
+
left = self.visit(node.left)
|
52
|
+
right = self.visit(node.right)
|
53
|
+
|
54
|
+
new_node = ast.Call(
|
55
|
+
func=ast.Name(id=sympy_class, ctx=ast.Load()),
|
56
|
+
args=[left, right],
|
57
|
+
starargs=None,
|
58
|
+
keywords=[],
|
59
|
+
kwargs=None,
|
60
|
+
)
|
61
|
+
|
62
|
+
return new_node
|
63
|
+
return self.generic_visit(node)
|
64
|
+
|
65
|
+
def visit_Compare(self, node: ast.Compare) -> ast.AST:
|
66
|
+
if len(node.ops) > 1:
|
67
|
+
raise ClassiqExpansionError(
|
68
|
+
f"Qmod expressions do not support chained comparison, as done in {ast.unparse(node)}"
|
69
|
+
)
|
70
|
+
sympy_class = self.COMPARE_OPERATORS.get(node.ops[0].__class__)
|
71
|
+
if sympy_class is not None:
|
72
|
+
left = self.visit(node.left)
|
73
|
+
right = self.visit(node.comparators[0])
|
74
|
+
|
75
|
+
new_node = ast.Call(
|
76
|
+
func=ast.Name(id=sympy_class, ctx=ast.Load()),
|
77
|
+
args=[left, right],
|
78
|
+
starargs=None,
|
79
|
+
keywords=[],
|
80
|
+
kwargs=None,
|
81
|
+
)
|
82
|
+
|
83
|
+
return new_node
|
84
|
+
return self.generic_visit(node)
|
85
|
+
|
86
|
+
def visit_BoolOp(self, node: ast.BoolOp) -> ast.AST:
|
87
|
+
sympy_class = self.BOOLEAN_OPERATORS.get(node.op.__class__)
|
88
|
+
if sympy_class is not None:
|
89
|
+
values = [self.visit(value) for value in node.values]
|
90
|
+
|
91
|
+
new_node = ast.Call(
|
92
|
+
func=ast.Name(id=sympy_class, ctx=ast.Load()),
|
93
|
+
args=values,
|
94
|
+
starargs=None,
|
95
|
+
keywords=[],
|
96
|
+
kwargs=None,
|
97
|
+
)
|
98
|
+
|
99
|
+
return new_node
|
100
|
+
return self.generic_visit(node)
|
101
|
+
|
102
|
+
def visit_UnaryOp(self, node: ast.UnaryOp) -> ast.AST:
|
103
|
+
sympy_class = self.UNARY_OPERATORS.get(node.op.__class__)
|
104
|
+
if sympy_class is not None:
|
105
|
+
operand = self.visit(node.operand)
|
106
|
+
|
107
|
+
new_node = ast.Call(
|
108
|
+
func=ast.Name(id=sympy_class, ctx=ast.Load()),
|
109
|
+
args=[operand],
|
110
|
+
starargs=None,
|
111
|
+
keywords=[],
|
112
|
+
kwargs=None,
|
113
|
+
)
|
114
|
+
|
115
|
+
return new_node
|
116
|
+
return self.generic_visit(node)
|
117
|
+
|
118
|
+
def visit_Call(self, node: ast.Call) -> ast.AST:
|
119
|
+
if isinstance(node.func, ast.Name) and node.func.id == "Piecewise":
|
120
|
+
return self._visit_piecewise(node)
|
121
|
+
|
122
|
+
if (
|
123
|
+
not isinstance(node.func, ast.Name)
|
124
|
+
or node.func.id not in self.SPECIAL_FUNCTIONS
|
125
|
+
):
|
126
|
+
return self.generic_visit(node)
|
127
|
+
|
128
|
+
return ast.Call(
|
129
|
+
func=ast.Name(self.SPECIAL_FUNCTIONS[node.func.id]),
|
130
|
+
args=[self.visit(arg) for arg in (node.args)],
|
131
|
+
keywords=[self.visit(arg) for arg in node.keywords],
|
132
|
+
)
|
133
|
+
|
134
|
+
def _visit_piecewise(self, node: ast.Call) -> ast.AST:
|
135
|
+
# sympy Piecewise expression may include bitwise operations:
|
136
|
+
# Piecewise((0, Eq(x, 0)), (0.5, Eq(x, 1) | Eq(x, 2)), (1, True))
|
137
|
+
# ^
|
138
|
+
# We should avoid converting these to 'BitwiseOr' and such.
|
139
|
+
return ast.Call(
|
140
|
+
func=node.func,
|
141
|
+
args=[
|
142
|
+
ast.Tuple(
|
143
|
+
elts=(
|
144
|
+
self.generic_visit(cast(ast.Tuple, arg).elts[0]),
|
145
|
+
cast(ast.Tuple, arg).elts[1],
|
146
|
+
)
|
147
|
+
)
|
148
|
+
for arg in node.args
|
149
|
+
],
|
150
|
+
keywords=node.keywords,
|
151
|
+
)
|
152
|
+
|
153
|
+
def visit_Subscript(self, node: ast.Subscript) -> ast.AST:
|
154
|
+
if isinstance(node.slice, ast.Slice):
|
155
|
+
if node.slice.lower is not None:
|
156
|
+
lower = self.visit(node.slice.lower)
|
157
|
+
else:
|
158
|
+
lower = ast.Name(MISSING_SLICE_VALUE_PLACEHOLDER)
|
159
|
+
if node.slice.upper is not None:
|
160
|
+
upper = self.visit(node.slice.upper)
|
161
|
+
else:
|
162
|
+
upper = ast.Name(MISSING_SLICE_VALUE_PLACEHOLDER)
|
163
|
+
return ast.Call(
|
164
|
+
func=ast.Name("do_slice"),
|
165
|
+
args=[self.visit(node.value), lower, upper],
|
166
|
+
keywords=[],
|
167
|
+
)
|
168
|
+
return ast.Call(
|
169
|
+
func=ast.Name("do_subscript"),
|
170
|
+
args=[self.visit(node.value), self.visit(node.slice)],
|
171
|
+
keywords=[],
|
172
|
+
)
|
173
|
+
|
174
|
+
def visit_Attribute(self, node: ast.Attribute) -> ast.Call:
|
175
|
+
return ast.Call(
|
176
|
+
func=ast.Name("get_field"),
|
177
|
+
args=[node.value, ast.Constant(value=node.attr)],
|
178
|
+
keywords=[],
|
179
|
+
)
|