Repository navigation
v0.5.0
Quivers 0.5.0 is the typed-prior release: structured matrix-valued priors on weight matrices via an axis-role syntax, a major inference-layer expansion, and an example gallery rebuilt from scratch to exercise the new surface.
Headline additions
Axis-role surface on every distribution clause
Kernel declarations, latent priors, sample steps, and observe steps accept an optional over <axes> [iid over <axes>] post-clause. over names the event axes of the family; remaining axes are iid (categorically a product of independent distributions). Axis names resolve against the named factors of the surrounding morphism's dom/cod; dom/cod are shortcuts when that side is a single unfactored object.
The axis count must match the family's declared event_rank (0 / 1 / 2 for scalar / vector / matrix families); mismatch is a compile-time error rather than a silent reinterpretation. This preserves the categorical distinction between, for example, a flat MVN over dim(A)·dim(B) with dense covariance and a MatrixNormal over (A, B) with Kronecker structure V ⊗ U.
latent W : Euclidean(D) -> Euclidean(K)
~ MatrixNormal(loc, row_cov, col_cov) over (dom, cod)
Unified kernel keyword
The continuous and stochastic declaration keywords are removed in favor of a single kernel keyword. A kernel f : A -> B declaration without a ~ clause declares a finite-set lookup-table kernel; with ~ Family [options] [axes] it declares a parametric kernel whose family parameters are produced from the input by a neural parameter network at sample time. This collapses two keywords whose distinction was already in the type signature into one whose name reads as "Markov kernel" everywhere.
Latent morphism priors
A latent f : A -> B ~ Family(args) [options] [over <axes>] clause puts a prior on the morphism's representing tensor. The morphism becomes a sample site whose value is drawn afresh at each forward pass; the inference layer integrates it as if there were an explicit top-of-program bind step. This is the right surface for factor analysis, PPCA, BNNs, and other "matrix of weights with prior" models.
Four new conditional families
ConditionalMatrixNormal— Matrix-Normal with Kronecker covarianceV ⊗ U, event_rank 2. The natural prior for a weight matrix whose row and column correlations factor separately.ConditionalInverseWishart— Conjugate prior for the covariance of a multivariate normal (Gelman et al. 2013 §3.6), event_rank 2.ConditionalGaussianProcess— RBF / Matern 5/2 / linear kernels with learnable length scale and amplitude; Cholesky factorization on the jittered kernel matrix; event_rank 1.ConditionalHorseshoe— Carvalho-Polson-Scott global-local shrinkage with a 16-point Gauss-Legendre quadrature giving the exact marginal log-prob; event_rank 1.
Surface DSL homogenization
The program-block surface is reorganized around a single Kleisli-bind sigil <-, type-annotated indexing on the binder, scoped marginalization, and !-prefixed effect signatures:
| Pre-0.5 surface | 0.5 surface |
|---|---|
draw v ~ F |
v <- F |
draw v : A -> K ~ F |
v : A <- F |
observe r[n] ~ F for n in N |
observe r : N <- F |
marginalize c (unscoped) |
marginalize c : A <- F in { … } |
posterior P (M) [v] |
program P(v) : … ! Pure over M |
output |
export |
Programs carry an effect signature ! Sample, Score, Marginal, Pure. The compiler verifies that the body's actual effects are a subset of the declared set; ! Pure rejects any sample / score / marginal binds.
Grouped marginalize with multi-observe fibration
marginalize cls : K <- Dirichlet(probs)
over Item
in {
observe r1 : Resp1 via idx1 <- Normal(...)
observe r2 : Resp2 via idx2 <- Bernoulli(...)
}
The over G clause on the header declares the grouping plate; each observe carries its own via idx clause naming the per-observe fibration into the shared plate. The runtime scatter-sums per-axis log-likelihoods into a single per-group accumulator before the reduction. Realizes the right Kan extension along the coproduct fibration in Kern.
Agenda-based weighted-deduction framework
A declarative deduction { … } block backed by a general agenda-engine runtime (quivers.stochastic.agenda):
- One engine, seven parameters (item algebra, rule set, semiring, axiom source, goal predicate, start symbol, depth bound) subsumes CKY, Earley, Viterbi, semi-naive Datalog, A* parsing, Knuth's algorithm, and depth-first MLTT proof search.
- Charts as first-class differentiable values:
view.weight(item),view.enumerate(pattern),view.goal_weight()return torch tensors with autograd. - Pre-registered stdlib deductions: CCG, Lambek, STLC, MLTT, Datalog, Dijkstra, HMM, ViterbiHMM, EditDistance.
Structural compression surface
A four-block pattern (signature { ... } encoder { ... } decoder { ... } loss { ... }) factors out transformers, tree LSTMs, graph NNs, autoregressive LMs, variational autoencoders (Kingma & Welling, 2014), and the vector inside-outside parser (Le & Zuidema, 2014) as instances of one F-algebra / F-coalgebra interface.
Inference layer overhaul
Six layers on a shared LatentRegistry:
- Nine guides:
AutoNormalGuide,AutoDeltaGuide,AutoMultivariateNormalGuide,AutoLowRankMultivariateNormalGuide,AutoLaplaceApproximation,AutoNormalizingFlow,AutoIAFGuide,AutoNeuralSplineGuide,AutoMixtureGuide. - Four objectives × four gradient estimators:
ELBO,IWAEBound(Burda, Grosse & Salakhutdinov, 2016),RenyiBound(Li & Turner, 2016),VRIWAEBound(Daudel, Douc & Roueff, 2023); reparameterized, sticking-the-landing (Roeder, Wu & Duvenaud, 2017), DReG (Tucker, Lawson, Gu & Maddison, 2019), score-function. - MCMC kernels:
HMCKernel,NUTSKernel(Hoffman & Gelman, 2014) with Nesterov dual-averaging step-size adaptation and Welford-online mass-matrix adaptation; R-hat (Vehtari et al. 2021), ESS, and divergence diagnostics onMCMCResult. - Hybrid samplers:
AutoDAIS(Geffner & Domke, 2021),WarmupThenHMC. - Posterior consumption:
Predictiveconsuming either aGuideor anMCMCResult.
Categorical refinements
- Quantale duality:
Quantale.dual()returns aDualQuantalewhosetensor_opandjoinswap roles under the de-Morgan involution; user-defined quantales (CustomQuantale) and semigroupoids (CustomSemigroupoid) take inline DSL operations with associativity / identity smoke checks at build time. CompositionRule → BilinearForm | Semigroupoid → Quantalehierarchy: non-associative bilinear forms and identity-less semigroupoids ship alongside quantales; operadic n-ary contractions via einsum-styleEinsumWiringspecs land anyn-ary morphism under a named composition rule.- First-class transformations: change-of-base transformations (softmax, L1/L2 normalization, Bayes inversion, quantale homomorphisms) are values: let-bindable, composable with
>>>, passable intochange_base. - Shape-aware change-of-base:
Morphism.change_baseaccepts bothQuantaleHomomorphism(pointwise) andMorphismTransformation(shape-aware) values; the seam type-checks at composition time.
Example gallery (36 examples)
Regression (Bayesian, beta, Dirichlet, NegBin, horseshoe, ZIP); latent-variable (factor analysis, PPCA, LDA, IRT-2PL, PMF, BNN, GMM, VAE); time-series and state-space (HMM discrete, continuous HMM, linear-Gaussian SSM, deep Markov, AR(1), stochastic volatility, changepoint, Weibull survival); sequence architectures (vanilla RNN LM, LSTM LM, GRU LM, bidirectional RNN LM, transformer LM, seq2seq with encoder + decoder); formal grammars (PCFG, CCG, Lambek calculus, multimodal TLG, custom rules, Montague NLI, quantifier scope). Each example exercises at least one distinguishing quivers feature (axis-role priors, marginalize, change_base, encoder blocks, scan, deduction declarations, structural compression) and runs end-to-end on synthetic data with a recovery test.
Major refactors
src/quivers/continuous/bayesian.pyrenamed toplate.pyand further split:_DeterministicMorphism,cumsum,softmax,cholesky_quad_formmoved toquivers.continuous.deterministic;CholeskyFactorcontinuous space moved toquivers.continuous.spaces;LKJCorrelationFactorandTruncatedmoved toquivers.continuous.families;plate.pynow strictly the plate / vectorised-observe / grouped-marginalize machinery.src/quivers/dsl/compiler.py(~6300 LOC) split into a packagesrc/quivers/dsl/compiler/with one module per concern (_prelude,core,declarations,programs,structural,deductions,resolution,expressions); public import paths unchanged.
Documentation
- A new
Denotational Semanticschapter giving a formal compositional semantics for the DSL across discrete, stochastic, and continuous strata, plus an adequacy theorem connecting the compiler implementation to the denotation. - Two-track tutorial (QVR DSL track and Python API track), with side-by-side Pyro / NumPyro / Stan / PyMC comparisons in the QVR track.
Breaking changes (pre-1.0 clean cut)
No backward-compatibility shims. User code that relied on the pre-0.5 surface should follow the migration table above. The loss= keyword on SVI is aliased as objective=; the posterior= positional argument on Predictive replaces the keyword form; imports from quivers.core.extra_quantales move to quivers.core.quantales.
Full changelog
See CHANGELOG.md for the line-item diff (axis-role surface, every new family, refactor list, deprecation table, and per-section additions).
Full Changelog: v0.4.1...v0.5.0