quivers.analysis¶
Static analysis and inspection utilities derive chain shapes, initialization recipes, saturation diagnostics, scope paths, and plate graphs without rewriting a compiled model. The package-level exports cover the training diagnostics; the plate and scope modules support the REPL and can also be used by downstream tooling.
analysis
¶
Algebra-guided training tooling.
This package inspects a compiled QVR program and returns chain metadata,
initialization recipes, and source-keyed diagnostics without rewriting the
program. It accepts either a
quivers.dsl.ast_nodes.Module AST or its
runtime quivers.continuous.programs.MonadicProgram.
The pieces:
ChainShape(quivers.analysis.chain_shape): walks a program's let / latent steps and tags each one with its source location, governing algebra, and intermediate dimensionality. This metadata supplies the initialization and saturation analyses.recommend_init(quivers.analysis.init_spec): given a program, produces a per-latentInitSpecfrom each algebra's initialization recipe. Pair withapply_init_specto materialize the initial values onto the program's learnable parameters.saturation_warnings(quivers.analysis.saturation): given a program, returns source-keyed warnings about latents that, under the recommended init, would saturate the surrounding algebra's value range.
See Analysis Pipelines: Fitting and Diagnostics for the user-facing workflow.
StepKind
module-attribute
¶
The kind tag of a StepShape: a stochastic bind (latent,
observe, marginalize) or a deterministic let.
NodeKind
module-attribute
¶
The kind tag of a PlateNode, which selects how a renderer draws it.
SCOPE_SEPARATOR
module-attribute
¶
The separator between the segments of a scoped path such as
"prog::x".
TOP_LEVEL_KINDS
module-attribute
¶
TOP_LEVEL_KINDS: tuple[ScopeKind, ...] = ('object', 'space', 'morphism', 'rule', 'program', 'deduction', 'signature', 'encoder', 'decoder', 'loss', 'bundle', 'contraction', 'composition', 'category')
The top-level container kinds, those reachable directly from the
compiler's public accessors, in the order ReplSession.browse()
walks them for output.
ScopeKind
module-attribute
¶
ScopeKind = Literal['object', 'space', 'morphism', 'rule', 'program', 'deduction', 'signature', 'encoder', 'decoder', 'loss', 'bundle', 'contraction', 'composition', 'category', 'param', 'sample-site', 'observe-site', 'let-site', 'marginalize-site', 'score-site', 'return-site', 'atom', 'deduction-rule', 'lexicon-entry', 'sort', 'constructor', 'binder', 'vertex-kind', 'edge-kind', 'op-rule', 'init-rule', 'message-rule', 'update-rule', 'var-init', 'decoder-head', 'composition-entry', 'bundle-member']
The kind tag carried by every ScopedRef, used for pretty-printing,
click-target classification, and the :browse section grouping.
ChainShape
didactic-model
¶
ChainShape(*, algebra_name: str = '', object_cardinalities: Mapping[str, int] = field(default_factory=dict, opaque=True), steps: tuple[StepShape, ...] = ())
Bases: Model
Sequence of StepShape records for a program.
| ATTRIBUTE | DESCRIPTION |
|---|---|
algebra_name |
Name of the program's governing algebra (the top-level
TYPE:
|
object_cardinalities |
Cardinality of every
TYPE:
|
steps |
Per-step metadata in source order.
TYPE:
|
stochastic_depth
property
¶
Number of stochastic-bind steps (latent, observe,
or marginalize).
algebra
property
¶
algebra: Algebra | None
Resolve algebra_name against the algebra
registry. Returns None if the name is unknown (e.g. a
user-defined inline composition rule not registered).
from_module
classmethod
¶
from_module(module: Module) -> 'ChainShape'
Build a ChainShape from a compiled
Module AST.
Walks the module's statement list, captures the algebra
name from any top-level CompositionDecl, captures
every ObjectDecl's numeric cardinality, then walks
the unique ProgramDecl's steps in source order.
MarginalizeStep bodies are walked recursively;
their inner steps are recorded after the enclosing
MarginalizeStep.
Source code in src/quivers/analysis/chain_shape.py
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | |
StepShape
didactic-model
¶
StepShape(*, name: str, kind: StepKind, source_line: int = 0, source_col: int = 0, depth: int = 0, algebra_name: str = '', intermediate_size: int | None = None)
Bases: Model
Per-step metadata derived by ChainShape.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
Bound variable name (the LHS of the step).
TYPE:
|
kind |
One of
TYPE:
|
source_line, source_col |
Source position where the step was declared.
TYPE:
|
depth |
The 1-indexed position of the step in the chain of
stochastic binds (
TYPE:
|
algebra_name |
Name of the program's governing algebra.
TYPE:
|
intermediate_size |
Cardinality of the bound coordinate's intermediate axis,
when statically inferable from the AST.
TYPE:
|
InitSpec
didactic-model
¶
InitSpec(*, distribution: Literal['normal', 'uniform', 'constant'] = 'normal', mean: float = 0.0, std: float = 1.0, lower: float = float('-inf'), upper: float = float('inf'), rationale: str = '')
Bases: Model
Parameters of a one-dimensional initial distribution.
| ATTRIBUTE | DESCRIPTION |
|---|---|
distribution |
One of
TYPE:
|
mean |
Location parameter for
TYPE:
|
std |
Scale parameter for
TYPE:
|
lower, upper |
Bounds for
TYPE:
|
rationale |
One-line explanation of the recipe, suitable for surfacing
in a warning or in
TYPE:
|
Edge
didactic-model
¶
Bases: Model
One directed dependency edge in the plate diagram.
Plate
didactic-model
¶
Bases: Model
One plate (indexing axis) of the diagram.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
The plate object's name (
TYPE:
|
cardinality |
The plate's size if statically inferable from the
module's
TYPE:
|
parent |
Name of an enclosing plate, or
TYPE:
|
PlateGraph
didactic-model
¶
PlateGraph(*, program_name: str, domain: str = '', codomain: str = '', nodes: tuple[PlateNode, ...] = (), plates: tuple[Plate, ...] = (), edges: tuple[Edge, ...] = ())
Bases: Model
Structural plate diagram of a single QVR program.
PlateNode
didactic-model
¶
PlateNode(*, name: str, kind: NodeKind, family: str | None = None, plates: tuple[str, ...] = (), args: tuple[str, ...] = (), scope_path: str = '')
Bases: Model
One random variable / deterministic intermediate.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
The variable's bound name in the program (
TYPE:
|
kind |
TYPE:
|
family |
The distribution family name (
TYPE:
|
plates |
The plates this node sits inside, ordered from outermost to innermost. Empty tuple for scalar nodes.
TYPE:
|
args |
The variable names this node's family / let-expression references. The graph's edges are derived from these.
TYPE:
|
scope_path |
The
TYPE:
|
SaturationWarning
didactic-model
¶
SaturationWarning(*, name: str, source_line: int = 0, source_col: int = 0, algebra_name: str = '', depth: int = 0, intermediate_size: int | None = None, init_spec: InitSpec | None = None)
Bases: Model
One saturation-risk diagnosis at a specific source location.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
Latent variable name.
TYPE:
|
source_line, source_col |
Position of the latent declaration in the source.
TYPE:
|
algebra_name |
Governing algebra at the latent's location.
TYPE:
|
depth |
Chain depth of the latent (number of stochastic-bind steps from the program entry, 1-indexed).
TYPE:
|
intermediate_size |
Inferred plate / shared-axis size.
TYPE:
|
init_spec |
The recommended algebra-specific initialization for this latent.
TYPE:
|
message
¶
One-line human-readable diagnosis suitable for surfacing
at qvr check / Compiler warning level.
Source code in src/quivers/analysis/saturation.py
ScopedRef
didactic-model
¶
ScopedRef(*, name: str, kind: ScopeKind, path: str, parent_kind: ScopeKind | None = None, node: object = field(opaque=True))
Bases: Model
One resolved binding.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
Last path segment.
TYPE:
|
kind |
Categorical tag indicating which declaration / step kind this ref points at.
TYPE:
|
path |
The full
TYPE:
|
parent_kind |
TYPE:
|
apply_init_spec
¶
Materialize an InitSpec onto a learnable tensor.
Delegates to torch.nn.init for normal / uniform and
to a plain fill_ for constant. The tensor's shape is
preserved; only its entries are overwritten in-place.
| PARAMETER | DESCRIPTION |
|---|---|
parameter
|
The tensor to overwrite in place.
TYPE:
|
spec
|
The recipe to draw the new entries from.
TYPE:
|
Source code in src/quivers/analysis/init_spec.py
recommend_init
¶
Per-latent algebra-specific initialization recipe.
Walks the program's ChainShape, looks up the governing
algebra, and returns a mapping from latent variable name to the
InitSpec that places the chain at the algebra's
mid-saturation point at depth-and-size.
| PARAMETER | DESCRIPTION |
|---|---|
module
|
The parsed QVR module whose program is analysed.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict[str, InitSpec]
|
The recipe for each latent, keyed by variable name; empty when the module declares no governing algebra. |
Source code in src/quivers/analysis/init_spec.py
build_plate_graph
¶
build_plate_graph(compiler, program_name: str) -> PlateGraph | None
Build the :class:PlateGraph for program_name.
Returns None if program_name isn't a registered program
on compiler. Walks the program's draws and any nested
marginalize body recursively. Marginalized sample sites
(the variable bound by the marginalize header) get
kind="marginalized" so renderers can shade them
differently from a plain "latent".
| PARAMETER | DESCRIPTION |
|---|---|
compiler
|
A
TYPE:
|
program_name
|
The name of the program to diagram.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
PlateGraph or None
|
The program's plate graph, or |
Source code in src/quivers/analysis/plate_graph.py
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | |
render_daft
¶
render_daft(graph: PlateGraph) -> str
Return a Python script that uses daft to render the
plate diagram. The script defines a build_pgm() function
returning a daft.PGM instance, ready for the user to
render() and save.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The plate graph to draw.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
Python source defining |
Source code in src/quivers/analysis/plate_render.py
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | |
render_dot
¶
render_dot(graph: PlateGraph) -> str
Return Graphviz DOT source. Plates become cluster_*
subgraphs; nodes carry shape attributes based on kind.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The plate graph to draw.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
Graphviz DOT source. |
Source code in src/quivers/analysis/plate_render.py
render_mermaid
¶
render_mermaid(graph: PlateGraph) -> str
Return Mermaid graph TD source for graph.
Each plate becomes a subgraph cluster. Each node is
drawn as a circle (( )) if latent, a double-circle
((( ))) if observed, an octagon ({{ }}) if
marginalized, and a hexagon (([ ])) if deterministic.
Edges follow the graph's edges field.
Mermaid lacks a native plate / nested-plate primitive; the subgraph blocks approximate it well enough that GitHub-rendered markdown and mermaid.live both display the structure.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The plate graph to draw.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
Mermaid |
Source code in src/quivers/analysis/plate_render.py
render_table
¶
render_table(graph: PlateGraph)
Return a rich.table.Table describing graph.
The caller is responsible for printing it (Console.print for
the plain prompt; RichLog.write for the Textual TUI).
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The plate graph to tabulate.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Table
|
One row per node, with its kind, family, plates, and parents. |
Source code in src/quivers/analysis/plate_render.py
render_table_plain
¶
render_table_plain(graph: PlateGraph) -> str
Plain-text rendering of the table, for non-Rich callers.
Used by :plate from qvr repl --plain and from the Jupyter
kernel.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The plate graph to tabulate.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The table as aligned plain text. |
Source code in src/quivers/analysis/plate_render.py
render_tikz
¶
render_tikz(graph: PlateGraph) -> str
Return a LaTeX snippet using tikz and the bayesnet
package conventions. Computes positions by laying nodes out
in columns (one per depth level) and rows (one per plate
stack); good enough for diagrams up to ~20 nodes.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The plate graph to draw.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
A LaTeX |
Source code in src/quivers/analysis/plate_render.py
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
saturation_warnings
¶
saturation_warnings(module: Module) -> tuple[SaturationWarning, ...]
Per-latent saturation diagnoses.
Returns a warning for every latent step in the program at
depth ≥ 2 or with intermediate size > 1 under an algebra whose
algebra-specific recipe differs materially from a default
Normal(0, 1) init. The threshold for "differs materially"
is the absolute distance between the recipe's mean and 0
(Normal default) plus the relative distance between its std
and 1; we surface a warning when either pulls the
recommendation more than 20% away from the default.
Suppressing warnings: declare the latent with an explicit init
via the DSL surface (when available) or apply the recommended
init programmatically via
quivers.analysis.init_spec.apply_init_spec.
| PARAMETER | DESCRIPTION |
|---|---|
module
|
The parsed QVR module whose program is analysed.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple[SaturationWarning, ...]
|
One warning per latent whose recommended init departs from the default; empty when the module declares no governing algebra. |
Source code in src/quivers/analysis/saturation.py
find_all_references
¶
find_all_references(compiler, name: str) -> list[ScopedRef]
Find every binding in compiler's module whose final
path segment equals name.
Returns refs sorted by depth (top-level first) then by path
lexicographic order. Used by :where NAME to surface every
scope a bare name appears in.
| PARAMETER | DESCRIPTION |
|---|---|
compiler
|
A
TYPE:
|
name
|
The bare name to search for.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ScopedRef]
|
Every binding whose final path segment is |
Source code in src/quivers/analysis/scope.py
resolve_scoped_path
¶
resolve_scoped_path(compiler, path: str) -> ScopedRef | None
Resolve a ::-separated path against compiler's
elaborated module. Returns None if any segment fails to
resolve.
| PARAMETER | DESCRIPTION |
|---|---|
compiler
|
A
|
path
|
A non-empty
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ScopedRef | None
|
The terminal binding, or |
Source code in src/quivers/analysis/scope.py
scope_children
¶
Return the named children of ref's scope, or an empty
mapping if ref.kind introduces no further bindings.
Idempotent + pure; callers can cache. Reads only the AST
fields exposed on each declaration shape, so adding a new
declaration kind requires registering one entry in
_SCOPE_DISPATCH.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
The binding whose scope is listed.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Mapping[str, ScopedRef]
|
The child bindings, keyed by name. |
Source code in src/quivers/analysis/scope.py
split_path
¶
Split "a::b::c" into ["a", "b", "c"]. Leading or
trailing separators yield empty segments, which the resolver
rejects.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
A
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
The path's segments, in order. |