v0.1 Public API Contract¶
The inline-typed runtime is the machine-readable contract. This page defines the intentionally curated alpha surface.
Top-level imports¶
from stoch_ir import (
Bernoulli,
ConcreteValue,
DataType,
Normal,
RandomVariable,
SamplingCheckpoint,
Uniform,
ValueMeta,
ValueSupport,
constant,
errors,
exp,
log,
reductions,
sampling_phase,
softplus,
)
from stoch_ir import __version__
Concrete node classes, plate layouts, dependency-rewrite hooks, current phase state, lowercase distribution aliases, and generic operation implementations are internal.
Construction and transforms¶
constant(value, *, plates=(), dtype=None)
Normal(mu, sigma, *, plates=None, rng_label=None)
Uniform(low=0.0, high=1.0, *, plates=None, rng_label=None)
Bernoulli(p, *, plates=None, rng_label=None)
exp(expr)
log(expr)
softplus(expr)
expr.exp()
expr.log()
expr.softplus()
expr.abs()
abs(expr)
Free and fluent forms construct structurally equal graphs. Arithmetic supports
+, -, *, /, and //, including their reverse forms.
constant accepts supported Python and NumPy Boolean, integer, and floating
values. Metadata is authoritative and storage is canonical:
Metadata |
NumPy storage |
|---|---|
|
|
|
|
|
|
Non-scalar rank must match the number of named plates. Complex, object, and
string values are rejected. Declared plate order maps to input array-axis order;
concrete storage is transposed into canonical lexicographic order. Any
iterable-valued plate argument also accepts a bare string as one plate.
Integer inputs and operation results must fit in canonical np.int64 storage
without changing value.
When distribution plates is omitted, the canonical union of parameter plates
is used. When supplied, it is the complete output layout and must contain every
parameter plate. The distribution produces one conditionally independent draw
at each output coordinate.
Literal distribution parameters are checked exactly during construction. Symbolic support metadata raises on guaranteed invalidity and warns when invalid values remain possible, while exact elementwise checks still run before sampling. Support endpoints alone do not trigger symbolic warnings, and no operation silently clamps values or introduces an epsilon.
Expression inspection¶
Every RandomVariable exposes:
expr.dependencies # immutable Mapping[str, RandomVariable]
expr.plates # canonical tuple[str, ...]
expr.pending_phases # frozenset[str]
expr.has_value # bool
expr.value_meta # ValueMeta
Dependencies are name-sorted and preserve object aliasing in their values. Internal plate-layout and dependency-reconstruction objects are deliberately not part of the public contract.
Plates and reductions¶
expr.add_plates(*new, expect=None)
expr.check_plates(*expected)
expr.reduce_plates(*plates, reduction=reductions.MEAN)
expr.mean(*plates)
expr.sum(*plates)
expr.max(*plates)
expr.min(*plates)
expr.prod(*plates)
expr.logsumexp(*plates)
The reduction keyword is required; MEAN above is an example, not a default.
add_plates broadcasts an existing value without resampling it. If expect is
supplied, the existing plate set must match exactly before the new plates are
added.
check_plates validates without changing the graph. Reductions explicitly
remove named plates.
The public immutable reduction objects are:
reductions.MEAN
reductions.SUM
reductions.MAX
reductions.MIN
reductions.PROD
reductions.LOGSUMEXP
Their common opaque type is reductions.Reduction. Caller-defined reductions
are not a v0.1 extension point.
Phases and materialization¶
with sampling_phase("latent"):
latent = Normal(0.0, 1.0)
partial = latent.materialize(
phases=("latent",),
seed=10,
plate_sizes=None,
)
value = partial.realize(seed=11)
Phase names have no intrinsic order. Enabling a phase permanently clears that
barrier in the returned immutable graph, but sampling still waits for concrete
dependencies. A bare string denotes one phase, so phases="latent" is
equivalent to phases=("latent",).
RandomVariable.materialize returns an opaque, non-composable
SamplingCheckpoint. A checkpoint exposes:
checkpoint.pending_phases
checkpoint.is_fully_materialized
checkpoint.materialize(...)
checkpoint.value()
checkpoint.realize(...)
checkpoint.structurally_equal(other)
checkpoint.stochastically_equal(other)
value() succeeds only after the checkpoint root is concrete. realize()
enables every remaining phase and returns a ConcreteValue.
Concrete values¶
ConcreteValue contains an immutable, read-only NumPy array and exposes:
value.data
value.plates
value.shape
value.meta
value.dtype
value.support
The plate tuple is the canonical axis order of data.
Equality¶
expr == other
expr.structurally_equal(other)
checkpoint.stochastically_equal(other_checkpoint)
Structural equality compares the represented computation while ignoring object aliasing and RNG resolution. It is not algebraic or probabilistic equality. Stochastic equality is available only after materialization and additionally checks graph-derived node entropy, sharing, fixed plate sizes, and bound sampling seeds in the checkpoint’s current rewritten state. Sampled distributions are constants and do not retain historical provenance; use blocked phased checkpoints when comparing unresolved stochastic structure.
Errors¶
Documented failures live under stoch_ir.errors. All public exceptions derive
from errors.StochIRError, and all public warnings derive from
errors.StochIRWarning. The curated hierarchies cover graph validation,
plates, phases, materialization, concrete-value validation, and invalid or
possibly invalid distribution support.