Skip to content

QIEC lowering

The exact QVR to QIEC lowering.

qiec_lowering

Exact QVR to QIEC lowering.

Quivers owns this adapter. Didactic orders and negotiates its stages and checks the first-order indexed-family projection. Name resolution, stable identity, effect elaboration, runtime checking, and the QIEC ABI remain source-language responsibilities.

QVR_SOURCE_VERSION module-attribute

QVR_SOURCE_VERSION = 'qvr-source/v0.20'

The source protocol a QvrQiecLowerer route accepts.

lower_qvr_to_qiec checks its source_version argument against this identifier, which names the QVR surface the elaboration reads.

QIEC_STATEMENT_TYPES module-attribute

The declaration classes that make up the QIEC surface of a module.

qiec_projection keeps these statements and non_qiec_projection drops them, so the tuple fixes where the two routes divide a module.

QvrQiecSource dataclass

QvrQiecSource(syntax: Module, module_name: str, file_path: str = '<source>', elaborate_programs: bool = True)

A parsed QVR projection plus the identity absent from the AST root.

PARAMETER DESCRIPTION
syntax

The projected module.

TYPE: Module

module_name

The name every stable identity derives from.

TYPE: str

file_path

The path recorded on diagnostics.

TYPE: str DEFAULT: '<source>'

elaborate_programs

Whether program declarations become computations. A caller that has found a program using a construct the elaboration does not yet cover lowers the rest of the module without it.

TYPE: bool DEFAULT: True

CheckedQvrQiec dataclass

CheckedQvrQiec(module: QiecModule)

The checked result passed between Didactic's ordered stages.

PARAMETER DESCRIPTION
module

The kernel module the stages produced.

TYPE: QiecModule

QvrQiecLowerer

Quivers-owned implementation of Didactic's extension-lowering protocol.

check

check(source: QvrQiecSource) -> CheckedQvrQiec

Elaborate a source module and recheck the result.

The recheck is deliberate rather than redundant: it rebuilds a registry from the lowered module alone, so a bug in elaboration surfaces here instead of reaching a backend.

PARAMETER DESCRIPTION
source

The QIEC projection, its module name, and its file path.

TYPE: QvrQiecSource

RETURNS DESCRIPTION
CheckedQvrQiec

The checked module.

RAISES DESCRIPTION
QiecDiagnosticError

If elaboration rejects the source, carrying a stable code and a source position.

KernelError

If the lowered module fails its independent recheck.

Source code in src/quivers/dsl/qiec_lowering.py
def check(self, source: QvrQiecSource, /) -> CheckedQvrQiec:
    """Elaborate a source module and recheck the result.

    The recheck is deliberate rather than redundant: it rebuilds a
    registry from the lowered module alone, so a bug in elaboration
    surfaces here instead of reaching a backend.

    Parameters
    ----------
    source : QvrQiecSource
        The QIEC projection, its module name, and its file path.

    Returns
    -------
    CheckedQvrQiec
        The checked module.

    Raises
    ------
    QiecDiagnosticError
        If elaboration rejects the source, carrying a stable code and
        a source position.
    KernelError
        If the lowered module fails its independent recheck.
    """
    module = _Elaborator(source).elaborate()
    validate_module(module)
    return CheckedQvrQiec(module)

lower

lower(checked: CheckedQvrQiec) -> QiecModule

Return the checked module.

Checking and lowering are one step here, because the elaborator produces the kernel module directly, so this unwraps rather than transforms.

PARAMETER DESCRIPTION
checked

The result of check.

TYPE: CheckedQvrQiec

RETURNS DESCRIPTION
QiecModule

The lowered module.

Source code in src/quivers/dsl/qiec_lowering.py
def lower(self, checked: CheckedQvrQiec, /) -> QiecModule:
    """Return the checked module.

    Checking and lowering are one step here, because the elaborator
    produces the kernel module directly, so this unwraps rather than
    transforms.

    Parameters
    ----------
    checked : CheckedQvrQiec
        The result of `check`.

    Returns
    -------
    QiecModule
        The lowered module.
    """
    return checked.module

validate

validate(target: QiecModule) -> None

Recheck a module and confirm it survives serialization.

PARAMETER DESCRIPTION
target

The module to validate.

TYPE: QiecModule

RAISES DESCRIPTION
KernelError

If the module fails its recheck, or if a dump and load round trip does not return an equal module. The second is checked because identities downstream are content addressed: a module that changed under serialization would hash differently on the other side of the boundary.

Source code in src/quivers/dsl/qiec_lowering.py
def validate(self, target: QiecModule, /) -> None:
    """Recheck a module and confirm it survives serialization.

    Parameters
    ----------
    target : QiecModule
        The module to validate.

    Raises
    ------
    KernelError
        If the module fails its recheck, or if a dump and load round
        trip does not return an equal module. The second is checked
        because identities downstream are content addressed: a module
        that changed under serialization would hash differently on
        the other side of the boundary.
    """
    validate_module(target)
    decoded = loads(dumps(target))
    if decoded != target:
        raise KernelError("QIEC module changed during canonical serialization")

has_qiec_surface

has_qiec_surface(module: Module) -> bool

Return whether a parsed module has anything to elaborate through QIEC.

PARAMETER DESCRIPTION
module

The parsed module to inspect.

TYPE: Module

RETURNS DESCRIPTION
bool

True when at least one statement belongs to the QIEC surface or is a program or deduction the elaboration turns into computations. Callers use this to decide whether the QIEC route runs at all, so a module of other declarations pays nothing for it.

Source code in src/quivers/dsl/qiec_lowering.py
def has_qiec_surface(module: surface.Module) -> bool:
    """Return whether a parsed module has anything to elaborate through QIEC.

    Parameters
    ----------
    module : surface.Module
        The parsed module to inspect.

    Returns
    -------
    bool
        True when at least one statement belongs to the QIEC surface or
        is a program or deduction the elaboration turns into
        computations. Callers
        use this to decide whether the QIEC route runs at all, so a
        module of other declarations pays nothing for it.
    """

    return any(
        isinstance(
            statement,
            (
                *QIEC_STATEMENT_TYPES,
                surface.DeductionDecl,
                surface.SignatureDecl,
                surface.EncoderDecl,
                surface.DecoderDecl,
                surface.LossDecl,
            ),
        )
        or (
            isinstance(statement, surface.DefineDecl)
            and isinstance(statement.expr, surface.ExprParser)
        )
        or (
            isinstance(statement, surface.ProgramDecl)
            and (
                statement.type_params is None
                or all(
                    isinstance(parameter, surface.ScalarParam)
                    for parameter in statement.type_params
                )
            )
        )
        for statement in module.statements
    )

qiec_projection

qiec_projection(module: Module) -> Module

Project QIEC declarations from a module with multiple neighborhoods.

PARAMETER DESCRIPTION
module

The parsed module to project.

TYPE: Module

RETURNS DESCRIPTION
Module

A module of the QIEC statements alone, in source order. The complement is non_qiec_projection, and the two partition the input, so nothing is dropped between the two routes.

Source code in src/quivers/dsl/qiec_lowering.py
def qiec_projection(module: surface.Module) -> surface.Module:
    """Project QIEC declarations from a module with multiple neighborhoods.

    Parameters
    ----------
    module : surface.Module
        The parsed module to project.

    Returns
    -------
    surface.Module
        A module of the QIEC statements alone, in source order. The
        complement is `non_qiec_projection`, and the two partition the
        input, so nothing is dropped between the two routes.
    """

    return surface.Module(
        statements=tuple(
            statement
            for statement in module.statements
            if isinstance(statement, (*QIEC_STATEMENT_TYPES, *PROGRAM_CONTEXT_TYPES))
        )
    )

non_qiec_projection

non_qiec_projection(module: Module) -> Module

Project declarations consumed by the categorical/probabilistic compiler.

PARAMETER DESCRIPTION
module

The parsed module to project.

TYPE: Module

RETURNS DESCRIPTION
Module

A module of everything outside the QIEC surface, in source order.

Source code in src/quivers/dsl/qiec_lowering.py
def non_qiec_projection(module: surface.Module) -> surface.Module:
    """Project declarations consumed by the categorical/probabilistic compiler.

    Parameters
    ----------
    module : surface.Module
        The parsed module to project.

    Returns
    -------
    surface.Module
        A module of everything outside the QIEC surface, in source
        order.
    """

    return surface.Module(
        statements=tuple(
            statement
            for statement in module.statements
            if not isinstance(statement, QIEC_STATEMENT_TYPES)
        )
    )

lower_qvr_to_qiec

lower_qvr_to_qiec(module: Module, *, module_name: str | None = None, file_path: str = '<source>', source_version: str = QVR_SOURCE_VERSION, target_version: str = QIEC_ABI, elaborate_programs: bool = True) -> QiecModule

Check and lower the QIEC projection of one parsed QVR module.

PARAMETER DESCRIPTION
module

The parsed module, which may mix QIEC and ordinary declarations.

TYPE: Module

module_name

Name the stable identities derive from. None takes it from file_path, so two files of the same stem produce the same identities and a rename is a deliberate act.

TYPE: str or None DEFAULT: None

file_path

Path recorded on diagnostics.

TYPE: str DEFAULT: '<source>'

source_version

The source protocol the module is written against.

TYPE: str DEFAULT: QVR_SOURCE_VERSION

target_version

The kernel ABI to lower to.

TYPE: str DEFAULT: QIEC_ABI

elaborate_programs

Whether program declarations become computations.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
QiecModule

The checked, lowered module.

RAISES DESCRIPTION
QiecDiagnosticError

If the source is rejected, with a stable code and a position. The code qiec-program-gap names a program construct, such as a parsing chart or a network-parameterized morphism, whose elaboration is not yet defined; a caller may lower the module again without its programs.

KernelError

If the lowered module fails its independent recheck.

Source code in src/quivers/dsl/qiec_lowering.py
def lower_qvr_to_qiec(
    module: surface.Module,
    *,
    module_name: str | None = None,
    file_path: str = "<source>",
    source_version: str = QVR_SOURCE_VERSION,
    target_version: str = QIEC_ABI,
    elaborate_programs: bool = True,
) -> QiecModule:
    """Check and lower the QIEC projection of one parsed QVR module.

    Parameters
    ----------
    module : surface.Module
        The parsed module, which may mix QIEC and ordinary declarations.
    module_name : str or None
        Name the stable identities derive from. None takes it from
        `file_path`, so two files of the same stem produce the same
        identities and a rename is a deliberate act.
    file_path : str
        Path recorded on diagnostics.
    source_version : str
        The source protocol the module is written against.
    target_version : str
        The kernel ABI to lower to.
    elaborate_programs : bool
        Whether ``program`` declarations become computations.

    Returns
    -------
    QiecModule
        The checked, lowered module.

    Raises
    ------
    QiecDiagnosticError
        If the source is rejected, with a stable code and a position. The
        code ``qiec-program-gap`` names a program construct, such as a
        parsing chart or a network-parameterized morphism, whose
        elaboration is not yet defined; a caller may lower the module
        again without its programs.
    KernelError
        If the lowered module fails its independent recheck.
    """

    if module_name is None:
        module_name = _module_name(file_path)
    source = QvrQiecSource(
        qiec_projection(module), module_name, file_path, elaborate_programs
    )
    return lower_checked(
        source,
        QvrQiecLowerer(),
        source_version=source_version,
        target_version=target_version,
    )