This library is in flux. APIs may change without notice. Generated from source with koruc 0.1.7 on 11/4/2026.
Quantity
import std/quantitystd/quantity — quantity calculus over arbitrary-precision decimals,
quantity.kz · 30 tors· 20 internal
std/quantity — quantity calculus over arbitrary-precision decimals, · 41 more lines
std/quantity — quantity calculus over arbitrary-precision decimals,
taint-sourced like std/num.
Port source: isa-physics `plex/lib/structural_arithmetic/tensor_quantity.py`
(Q = dimension + magnitude + uncertainty) and the isar-proofs
`ISAR/QuantityKernel.lean` (DimExpr free abelian group over the 7 SI bases,
MetricExpr exact-rational layer, propagateVarAdd/Mul linearized variance
laws plus the shared-source covariance term).
A `qty` is ONE canonical marked string:
"<num>|<dim>|<unc>[@<cov>]"
<num>: std/num canonical decimal e.g. "9.81e0"
<dim>: all 7 SI exps, fixed order "m^1 s^-2 kg^0 A^0 K^0 mol^0 cd^0"
<unc>: num canon or "-" e.g. "1e-1" / "1e-1@bias"
<cov>: shared-source tag; absent "-"
Canonical => quantity equivalence is string equality (`qty:equiv`).
A "-" uncertainty is "0e0" internally: no uncertainty contributes zero
variance, and pack writes "-" back out.
Covariance model (linearized, GUM-adjacent): `unc@<group>` asserts the
whole sigma stems from shared source <group>. A leading '-' on the tag
marks a negated instance (what qty:neg produces): same group opposite
sign is a FULLY ANTI-CORRELATED source, and the covariance term flips
sign — a−b sharing a bias cancels it. Same group + sign adds 2·u_a·u_b;
different groups => | mixed-cov — the correlation is unknowable, so the
op refuses the axis instead of silently assuming independence. One-sided
tags propagate conservatively: independent sigma, tag carried forward.
Taint: same shape as std/num — `ingest`/`ingest-owned` issue <external!>,
`parse`/`lit` discharge it into <exact!>, ops consume <!exact> linearly,
`dup` forks, `free` deallocates, `render` swaps to <std/io:allocated!>.
`qty:mag` unwraps the magnitude INTO the number tower as <std/num:exact!>
— the lawful crossing between the two marks; `qty:unpack` decomposes the
pack into marked fields, `qty:pack` reassembles it.
Boundary vs impl: the zig procs below are ONLY mark-boundary machinery —
ingest/split/pack/unpack issue and consume marks, dim-* compose the
canonical dim vector, cov-* carry the shared-source policy. Every
arithmetic law is a Koru impl (`~name = ...`) calling std/num tors —
the decimal core lives in ONE place (num.kz) and ops compose through the
tor mechanism: data crosses boundaries, logic does not.
Phantom lifecycles
Derived from the phantom labels in the declarations below — state! issues an
obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.
string 10 states external!external!allocated!exact!exact!sexpr!// Boundary — mark machinery only
~pub tor ingest { s: string } -> string<external!>~pub tor ingest-owned { s: string<!allocated> } -> string<external!>// The parse boundary: splits "mag+-unc@cov unit" into RAW field strings and
// issues <std/num:external!> on the numeric fields — num:parse discharges
// them in `canon`. dim/cov come out owned (<std/io:allocated!>).
~pub tor split { s: string<!external> }
| fields {
mag: string<std.num:external!>,
unc: string<std.num:external!>,
scale: string<std.num:external!>,
dim: string<std.io:allocated!>,
cov: string<std.io:allocated!>
}
| bad string<std.io:allocated!>~pub tor parse { s: string<!external> }
| exact string<exact!>
| bad string<std.io:allocated!>// Trusted literal: same boundary, issued <external!> because the fields still
// have to be validated — the mark means "unparsed", and parse is the only
// discharge that canonicalizes. `bad` stays an unmarked message: the caller
// wrote s themselves; the owned buffers are freed here rather than pushed
// onto the caller as an obligation.
~pub tor lit { source: Source }
| exact string<exact!>
| bad string// Symbolic literal: a canonical sexpr magnitude plus unit text — `lit` for
// the MetricSymbolic lane. The unit's scale multiplies through the
// magnitude symbolically (lit-sym(π,"g") -> (1e-3*π) kg). unc/cov are
// literal text, validated at the boundary like `lit`'s fields.
~pub tor lit-sym {
mag: string<std.sym:!sexpr>,
unit: string,
unc: string,
cov: string
}
| exact string<exact!>
| bad-lit string~pub tor pack {
mag: string<std.num:!exact>,
unc: string<std.num:!exact>,
dim: string<std.io:!allocated>,
cov: string<std.io:!allocated>
} -> string<exact!>// Same pack, symbolic lane: the mag field holds sexpr canon — identical
// pack shape, a different mark at the boundary.
~pub tor pack-sym {
mag: string<std.sym:!sexpr>,
unc: string<std.num:!exact>,
dim: string<std.io:!allocated>,
cov: string<std.io:!allocated>
} -> string<exact!>~pub tor unpack { n: string<!exact> }
| num {
mag: string<std.num:exact!>,
unc: string<std.num:exact!>,
dim: string<std.io:allocated!>,
cov: string<std.io:allocated!>
}
| sym {
mag: string<std.sym:sexpr!>,
unc: string<std.num:exact!>,
dim: string<std.io:allocated!>,
cov: string<std.io:allocated!>
}// Unit text -> (scale, canonical dim) — the same table split's grammar
// uses. Scale comes out <std/num:external!>: unparsed decimal text that
// num:parse discharges. | bad names the unknown-unit axis.
~pub tor unit-dim { s: string }
| ok { scale: string<std.num:external!>, dim: string<std.io:allocated!> }
| bad-unit// Dim algebra — borrowed canonical dim text in, owned canonical text out.
// The free abelian group: compose adds, invert negates, scale multiplies.
~pub tor dim-compose {
a: string<std.io:allocated>,
b: string<std.io:allocated>
} -> string<std.io:allocated!>~pub tor dim-invert { a: string<std.io:allocated> } -> string<std.io:allocated!>~pub tor dim-scale {
a: string<std.io:allocated>,
n: i64
} -> string<std.io:allocated!>~pub tor dim-eq { a: string<std.io:allocated>, b: string<std.io:allocated> }
| same
| diff// The covariance-join policy, in one place. Tags: "-", "g", "-g" (negated
// instance of shared source g — what qty:neg emits).
// "-" + "-" -> | indep "-" (both independent)
// "-" + t -> | indep t (one-sided: independent sigma, tag kept)
// g + g -> | corr g (positive full correlation)
// g + "-g" -> | opp g (negated instance: anti-correlated)
// g1 + g2 -> | mixed (correlation unknowable — refuse)
~pub tor cov-join { a: string<std.io:allocated>, b: string<std.io:allocated> }
| indep string<std.io:allocated!>
| corr string<std.io:allocated!>
| opp string<std.io:allocated!>
| mixed// Flip a cov tag's instance sign — the tag negation qty:neg applies.
// "-" stays "-" (no source to flip).
~pub tor cov-flip { c: string<std.io:allocated> } -> string<std.io:allocated!>~pub tor add { a: string<!exact>, b: string<!exact> }
| exact string<exact!>
| dim-mismatch
| mixed-cov// Negation: magnitude flips, sigma keeps its size, the cov tag flips sign —
// "-g" is the same shared source seen through a negated instance, which is
// what makes bias cancellation in `sub` lawful.
~pub tor neg { n: string<!exact> } -> string<exact!>~pub tor sub { a: string<!exact>, b: string<!exact> }
| exact string<exact!>
| dim-mismatch
| mixed-cov~pub tor mul { a: string<!exact>, b: string<!exact> }
| exact string<exact!>
| mixed-cov
| bad string
| sym-unc~pub tor div { a: string<!exact>, b: string<!exact>, prec: i64 }
| exact string<exact!>
| div-zero
| mixed-cov
| bad string
| sym-unc~pub tor pow { a: string<!exact>, n: i64 }
| exact string<exact!>
| div-zero
| sym-unc// Accessors and linearity
//
// equiv: the equivalence law. Canonical packs are string-equal iff equal —
// dims are normalized at pack time, so m/s·s == m is a string comparison.
~pub tor equiv { a: string<exact>, b: string<exact> }
| same
| diff// Unwrap the magnitude — a lane union: decimal canon under
// <std/num:exact!>, symbolic canon under <std/sym:sexpr!>.
~pub tor mag { q: string<!exact> }
| num string<std.num:exact!>
| sym string<std.sym:sexpr!>// The dimension vector as canonical text — for diagnostics and print.
~pub tor dim { q: string<!exact> } -> string<std.io:allocated!>// The sigma as canonical decimal text ("0e0" when the quantity is certain).
~pub tor unc { q: string<!exact> } -> string<std.io:allocated!>// The shared-source tag ("-" when independent).
~pub tor cov { q: string<!exact> } -> string<std.io:allocated!>~pub tor dup { n: string<!exact> } -> { a: string<exact!>, b: string<exact!> }~pub tor free { n: string<!exact> }// Render: the canonical pack text, handed to the io tower as <allocated!>.
~pub tor render { n: string<!exact> } -> string<std.io:allocated!>