Extending DSL Emissions¶
This guide shows how to add custom emission methods to the DSL so you can encapsulate reusable branch-emission behavior as fluent builder calls.
Abstraction hierarchy¶
Emission clauses are built on one public base class:
nkdsl.AbstractEmissionClause
Your subclass is registered with:
nkdsl.register_emission_clause()or the generic decorator
nkdsl.register()
After registration, the clause becomes a fluent method on
nkdsl.SymbolicDiscreteJaxOperator.
What every emission clause must provide¶
Minimum requirements:
Subclass
nkdsl.AbstractEmissionClause.Implement
build_emission(self, ctx, *args, **kwargs).Return
nkdsl.dsl.emissions.types.EmissionClauseSpec.
EmissionClauseSpec supports these modes:
"emit""emit_if""emit_elseif""emit_else"
Optional but recommended:
Set
clause_namefor a stable public method name.Validate arguments and fail fast with clear
ValueErrormessages.Add branch tags for diagnostics clarity.
Name resolution rules¶
If you set clause_name, that name is used for the fluent method.
Otherwise nkDSL derives a name from the class name.
Names must satisfy all of the following:
valid Python identifier
must not start with
_must not collide with reserved builder method names
Example: conditional emission convenience clause¶
The clause below emits a branch only when one site value is above a cutoff.
import netket as nk
import nkdsl
from nkdsl.dsl.emissions.types import EmissionClauseSpec
class EmitWhenAtLeast(nkdsl.AbstractEmissionClause):
clause_name = "emit_when_at_least"
def build_emission(self, ctx, label: str = "i", cutoff: int = 1):
predicate = ctx.site(label).value >= int(cutoff)
return EmissionClauseSpec(
mode="emit_if",
predicate=predicate,
update=nkdsl.identity(),
matrix_element=ctx.site(label).value,
tag="emit-when-at-least",
)
nkdsl.register_emission_clause(EmitWhenAtLeast, replace=True)
Usage:
hi = nk.hilbert.Fock(n_max=3, N=4)
op = (
nkdsl.SymbolicDiscreteJaxOperator(hi, "custom-emission")
.for_each_site("i")
.emit_when_at_least("i", cutoff=2)
.emit_else(nkdsl.identity(), matrix_element=0.0, tag="fallback")
.build()
)
Practical checklist before shipping a custom emission clause¶
Does the clause return a valid
EmissionClauseSpec?Are conditional modes used in legal sequence (
if -> elseif* -> else?)?Are branch tags set when diagnostics readability matters?
Did you add tests for valid and invalid usage paths?
Discoverability¶
You can inspect currently available emission clause names at runtime:
names = nkdsl.available_emission_clause_names()
print(names)