ucon.kinds¶
Kind-of-Quantity (KOQ) sortal lattice. Records refinement relationships
within a single dimension (e.g. kinetic_energy ≤ energy,
equivalent_dose ≤ absorbed_dose).
See Kind-of-Quantity Problem for the conceptual framing and API › Kinds for usage.
Kind lattice: dimensional refinements for :class:~ucon.quantity.Number.
A kind refines a dimension. Energy is a dimension; kinetic energy,
potential energy, and enthalpy are kinds within that dimension. Kinds
form rooted trees, partitioned by dimensional equivalence class, and
arithmetic that crosses the partition is governed by the kind's
join_policy.
This subpackage provides storage and structural reasoning only. It is
not wired into :class:~ucon.quantity.Number in v1.9.x; users build
lattices, query LCAs, and test load-time validation in isolation. In
v2.0.0 the lattice becomes a member of UnitSystem.
AliasCollision
¶
Bases: KindError
An alias collides with another name or alias.
Aliases share the flat name/alias namespace with primary names.
The conflict_with attribute names the existing entry.
CrossDimensionParent
¶
Bases: KindError
A kind's declared parent has a different dimension.
The kind tree partitions by dimensional equivalence class. A parent edge across dimensions is structurally invalid.
DisjointKinds
¶
Bases: KindError, ValueError
Two kinds belong to disjoint trees — no common ancestor exists.
Raised by :meth:KindLattice.lca when the operands' ancestor chains
never intersect. Distinct roots cannot be joined; this is a verdict
("independent kinds, no conversion"), not a programming error, so it
joins the :class:KindError taxonomy with left/right
attributes for diagnostics. It also subclasses :class:ValueError
so existing except ValueError handlers continue to work.
JoinRefused
¶
Bases: KindError
Two sibling kinds share a parent with join_policy = REFUSE.
Raised by :meth:KindLattice.lca when the lowest common ancestor's
join_policy forbids the join. The left, right, and
parent attributes carry the involved kinds; the caller can use
them to produce a domain-appropriate diagnostic.
KindCycle
¶
Bases: KindError
A parent chain forms a cycle.
The cycle attribute lists the kind names that participate in
the cycle, in walk order.
KindError
¶
Bases: Exception
Base class for kind lattice errors.
NameCollision
¶
Bases: KindError
Two kinds share the same primary name.
When the colliding kinds live in different fibers (their dimensions
differ), the message says so and points at qualification: the flat
name index refuses cross-fiber same-names in 2.x because name-only
Kind.__eq__ would make lattice walks silently conflate them if
they coexisted. Extending equality is a breaking change reserved
for a major release; pkg:name qualification is the supported
resolution today.
KindLattice
¶
A collection of :class:Kind nodes with parent edges.
Parameters¶
kinds Initial kinds to load. Validated on construction.
Notes¶
The lattice owns canonical Kind instances and a flat name/alias
index. Lookups by alias return the kind those aliases resolve to.
get(name)
¶
Resolve a primary name or alias to its canonical :class:Kind.
Raises¶
KindNotFound
If no kind or alias matches name.
names()
¶
All registered primary names.
ancestors(kind)
¶
Return the chain [kind, parent, grandparent, ..., root].
is_descendant(child, ancestor)
¶
True if child is ancestor or any descendant of it.
lca(a, b)
¶
Lowest common ancestor of a and b.
Returns the ancestor kind and the join_policy declared at
that ancestor. The caller decides whether to honor the policy;
a convenience :meth:join consults it directly and raises
:class:JoinRefused when blocked.
Raises¶
KindNotFound
If a or b refer to unregistered kinds.
DisjointKinds
If a and b belong to disjoint trees (no common
ancestor). Distinct roots cannot be joined. Subclasses both
:class:KindError and :class:ValueError, so pre-2.1.x
except ValueError handlers keep working.
join(a, b)
¶
LCA-based join that honors join_policy.
Equivalent kinds short-circuit to a. Otherwise consults
:meth:lca; raises :class:JoinRefused when the ancestor's
policy blocks the join.
register(kind)
¶
Add a kind to an existing lattice.
Re-runs the same load-time validation. Provided primarily as a building block for parsers; users typically construct a lattice in one shot.
kinds_for_dimension(dimension)
¶
copy()
¶
Return an independent copy of this lattice.
The new lattice contains the same :class:Kind objects (which
are frozen dataclasses) but its index dicts are independent —
mutations via :meth:register on the copy do not affect the
original.
JoinPolicy
¶
Bases: Enum
Policy applied when joining sibling kinds at a parent node.
LCA lifts the result to the lowest common ancestor.
REFUSE blocks the join; the operation must be expressed via a
named formula instead.
Kind
dataclass
¶
A refinement within a dimensional equivalence class.
Parameters¶
name
Primary identifier. Must be unique across the lattice's flat
name/alias namespace.
dimension
The dimension this kind refines. All ancestors in the kind tree
must share this dimension.
parent
The parent kind, or None for a root.
join_policy
Policy applied to additions of distinct descendants of this
kind. Defaults to :attr:JoinPolicy.LCA.
aliases
Legacy or alternate names that resolve to this kind. Share the
flat name/alias namespace with primary names; collisions refuse
at load time.
Notes¶
Kind is intentionally storage-only. All structural reasoning
(parent walks, LCA, validation) lives on
:class:~ucon.kinds.lattice.KindLattice.
Equality and hashing key off name only. Two Kind instances
with the same name are treated as the same kind, regardless of
parent or join policy. This permits constructing a kind reference
by name during parse before the parent is resolvable.
lca(a, b, *, lattice)
¶
Module-level convenience for :meth:KindLattice.lca.
Takes an explicit lattice; there is no implicit global. In v2.0.0
this is the same shape as the bound method on UnitSystem.