Skip to content

Canonical types

Canonical type constructors shared by the kernel, prelude, and compiler.

canonical

Canonical type constructors shared by the kernel, prelude, and compiler.

These constructors live in the builtin namespace, so Site, Sampleable, Tensor, and LogWeight mean the same type in every module without any module declaring them. The prelude's handlers are typed against them, the checker types distribution construction and log-density evaluation with them, and the compiler elaborates a program's steps into them.

ELEMENT_BINDER module-attribute

ELEMENT_BINDER = TypeBinder('a')

The element-type binder a of the canonical constructors' telescopes.

SHAPE_BINDER module-attribute

SHAPE_BINDER = IndexBinder('shape', ShapeSort())

The shape-index binder of :data:TENSOR_CONSTRUCTOR's telescope.

ELEMENT module-attribute

ELEMENT = TypeVariable('a')

The type variable :data:ELEMENT_BINDER binds.

SITE_CONSTRUCTOR module-attribute

SITE_CONSTRUCTOR = builtin_constructor('Site', ELEMENT_BINDER)

Site[A]: a named sample site whose value has type A.

SAMPLEABLE_CONSTRUCTOR module-attribute

SAMPLEABLE_CONSTRUCTOR = builtin_constructor('Sampleable', ELEMENT_BINDER)

Sampleable[A]: a distribution over values of type A.

TENSOR_CONSTRUCTOR module-attribute

TENSOR_CONSTRUCTOR = builtin_constructor('Tensor', ELEMENT_BINDER, SHAPE_BINDER)

Tensor[A](shape): an array of A with a static shape index.

LOG_WEIGHT module-attribute

LOG_WEIGHT = TypeApplication(builtin_constructor('LogWeight'))

LogWeight: a log-density contribution.

BUILTIN_TYPE_CONSTRUCTORS module-attribute

BUILTIN_TYPE_CONSTRUCTORS: dict[str, TypeConstructorRef] = {'Site': SITE_CONSTRUCTOR, 'Sampleable': SAMPLEABLE_CONSTRUCTOR, 'Tensor': TENSOR_CONSTRUCTOR, 'LogWeight': LOG_WEIGHT.constructor}

The canonical names a source type may refer to without declaring them.

builtin_constructor

builtin_constructor(name: str, *binders: TypeBinder | IndexBinder) -> TypeConstructorRef

A type constructor in the builtin namespace.

PARAMETER DESCRIPTION
name

The constructor's name.

TYPE: str

*binders

Its kinding telescope.

TYPE: TypeBinder | IndexBinder DEFAULT: ()

RETURNS DESCRIPTION
TypeConstructorRef

The constructor. Its identity derives from the namespace and the name alone, so it is the same constructor in every module.

Source code in src/quivers/qiec/canonical.py
def builtin_constructor(
    name: str, *binders: TypeBinder | IndexBinder
) -> TypeConstructorRef:
    """A type constructor in the ``builtin`` namespace.

    Parameters
    ----------
    name : str
        The constructor's name.
    *binders : TypeBinder | IndexBinder
        Its kinding telescope.

    Returns
    -------
    TypeConstructorRef
        The constructor. Its identity derives from the namespace and the
        name alone, so it is the same constructor in every module.
    """
    return TypeConstructorRef(
        TypeId.derive("builtin", name),
        name,
        tuple(binders),
    )

site_type

site_type(element: TypeExpr) -> TypeApplication

The type of a sample site producing element.

PARAMETER DESCRIPTION
element

The sampled value's type.

TYPE: TypeExpr

RETURNS DESCRIPTION
TypeApplication

Site[element].

Source code in src/quivers/qiec/canonical.py
def site_type(element: TypeExpr) -> TypeApplication:
    """The type of a sample site producing ``element``.

    Parameters
    ----------
    element : TypeExpr
        The sampled value's type.

    Returns
    -------
    TypeApplication
        ``Site[element]``.
    """
    return TypeApplication(SITE_CONSTRUCTOR, (element,))

sampleable_type

sampleable_type(element: TypeExpr) -> TypeApplication

The type of a distribution over element.

PARAMETER DESCRIPTION
element

The sampled value's type.

TYPE: TypeExpr

RETURNS DESCRIPTION
TypeApplication

Sampleable[element].

Source code in src/quivers/qiec/canonical.py
def sampleable_type(element: TypeExpr) -> TypeApplication:
    """The type of a distribution over ``element``.

    Parameters
    ----------
    element : TypeExpr
        The sampled value's type.

    Returns
    -------
    TypeApplication
        ``Sampleable[element]``.
    """
    return TypeApplication(SAMPLEABLE_CONSTRUCTOR, (element,))

tensor_type

tensor_type(element: TypeExpr, dimensions: tuple[IndexTerm, ...]) -> TypeApplication

The type of an array of element with the given static shape.

PARAMETER DESCRIPTION
element

The element type.

TYPE: TypeExpr

dimensions

One index term per dimension, outermost first.

TYPE: tuple[IndexTerm, ...]

RETURNS DESCRIPTION
TypeApplication

Tensor[element](shape).

Source code in src/quivers/qiec/canonical.py
def tensor_type(
    element: TypeExpr, dimensions: tuple[IndexTerm, ...]
) -> TypeApplication:
    """The type of an array of ``element`` with the given static shape.

    Parameters
    ----------
    element : TypeExpr
        The element type.
    dimensions : tuple[IndexTerm, ...]
        One index term per dimension, outermost first.

    Returns
    -------
    TypeApplication
        ``Tensor[element](shape)``.
    """
    return TypeApplication(TENSOR_CONSTRUCTOR, (element, ShapeIndex(dimensions)))

sampled_element

sampled_element(type_: TypeExpr) -> TypeExpr | None

The value type a Sampleable produces.

PARAMETER DESCRIPTION
type_

A type that may be a sampleable application.

TYPE: TypeExpr

RETURNS DESCRIPTION
TypeExpr | None

The element type, or None when type_ is not Sampleable[A].

Source code in src/quivers/qiec/canonical.py
def sampled_element(type_: TypeExpr) -> TypeExpr | None:
    """The value type a ``Sampleable`` produces.

    Parameters
    ----------
    type_ : TypeExpr
        A type that may be a sampleable application.

    Returns
    -------
    TypeExpr | None
        The element type, or ``None`` when ``type_`` is not
        ``Sampleable[A]``.
    """
    if (
        isinstance(type_, TypeApplication)
        and type_.constructor == SAMPLEABLE_CONSTRUCTOR
        and len(type_.arguments) == 1
    ):
        argument = type_.arguments[0]
        if isinstance(argument, TypeApplication | TypeVariable):
            return argument
    return None

tensor_shape

tensor_shape(type_: TypeExpr) -> tuple[TypeExpr, tuple[IndexTerm, ...]] | None

Split a tensor type into its element type and dimensions.

PARAMETER DESCRIPTION
type_

A type that may be a tensor application.

TYPE: TypeExpr

RETURNS DESCRIPTION
tuple[TypeExpr, tuple[IndexTerm, ...]] | None

The element type and dimensions, or None when type_ is not Tensor[A](shape) with a literal shape.

Source code in src/quivers/qiec/canonical.py
def tensor_shape(type_: TypeExpr) -> tuple[TypeExpr, tuple[IndexTerm, ...]] | None:
    """Split a tensor type into its element type and dimensions.

    Parameters
    ----------
    type_ : TypeExpr
        A type that may be a tensor application.

    Returns
    -------
    tuple[TypeExpr, tuple[IndexTerm, ...]] | None
        The element type and dimensions, or ``None`` when ``type_`` is
        not ``Tensor[A](shape)`` with a literal shape.
    """
    if (
        isinstance(type_, TypeApplication)
        and type_.constructor == TENSOR_CONSTRUCTOR
        and len(type_.arguments) == 2
    ):
        element, shape = type_.arguments
        if isinstance(element, TypeApplication | TypeVariable) and isinstance(
            shape, ShapeIndex
        ):
            return element, shape.dimensions
    return None