"""Definition objects that are being exposed to users.These are the objects returned by the `@guppy` decorator. They should not be confusedwith the compiler-internal definition objects in the `definitions` module."""fromdataclassesimportdataclassfromtypingimportAny,ClassVar,Generic,ParamSpec,TypeVar,castimportguppylang_internalsfromguppylang_internals.engineimportENGINE,CoreMetadataKeysfromguppylang_internals.tracing.objectimportTracingDefMixinfromguppylang_internals.tracing.utilimporthide_tracefromhugr.hugrimportHugrfromhugr.packageimportPackageimportguppylangfromguppylang.emulatorimportEmulatorBuilder,EmulatorInstance__all__=("GuppyDefinition","GuppyFunctionDefinition","GuppyTypeVarDefinition")P=ParamSpec("P")Out=TypeVar("Out")def_update_generator_metadata(hugr:Hugr[Any])->None:"""Update the generator metadata of a Hugr to be guppylang rather than just internals."""key=CoreMetadataKeys.GENERATOR.valuehugr.module_root.metadata[key]={"name":f"guppylang (guppylang-internals-v{guppylang_internals.__version__})","version":guppylang.__version__,}
[docs]@dataclass(frozen=True)classGuppyDefinition(TracingDefMixin):"""A general Guppy definition."""
[docs]defcompile(self)->Package:"""Compile a Guppy definition to HUGR."""package:Package=ENGINE.compile(self.id).packageformodinpackage.modules:_update_generator_metadata(mod)returnpackage
[docs]defcheck(self)->None:"""Type-check a Guppy definition."""returnENGINE.check(self.id)
[docs]@dataclass(frozen=True)classGuppyFunctionDefinition(GuppyDefinition,Generic[P,Out]):"""A Guppy function definition."""
[docs]defemulator(self,n_qubits:int,builder:EmulatorBuilder|None=None)->EmulatorInstance:"""Compile this function for emulation with the selene-sim emulator. Calls `compile()` to get the HUGR package and then builds it using the provided `EmulatorBuilder` configuration or a default one. See :py:mod:`guppylang.emulator` for more details on the emulator. Args: n_qubits: The number of qubits to allocate for the function. builder: An optional `EmulatorBuilder` to use for building the emulator instance. If not provided, the default `EmulatorBuilder` will be used. Returns: An `EmulatorInstance` that can be used to run the function in an emulator. """mod=self.compile()builder=builderorEmulatorBuilder()returnbuilder.build(mod,n_qubits=n_qubits)
[docs]@dataclass(frozen=True)classGuppyTypeVarDefinition(GuppyDefinition):"""Definition of a Guppy type variable."""# For type variables, we need a `GuppyDefinition` subclass that answers 'yes' to an# instance check on `typing.TypeVar`. This hack is needed since `typing.Generic[T]`# has a runtime check that enforces that the passed `T` is actually a `TypeVar`.__class__:ClassVar[type]=TypeVar_ty_var:TypeVar
[docs]def__eq__(self,other:object)->bool:# We need to compare as equal to an equivalent regular type varifisinstance(other,TypeVar):returnself._ty_var==otherreturnobject.__eq__(self,other)
[docs]def__getattr__(self,name:str)->Any:# Pretend to be a `TypeVar` by providing all of its attributesifhasattr(self._ty_var,name):returngetattr(self._ty_var,name)returnobject.__getattribute__(self,name)