Files
Radixor/docs/architecture-and-reduction.md
Leo Galambos e7800b29c9 feat!: modularize stemmer models and release infrastructure
Move bundled stemmer dictionaries from the core artifact into independently
versioned model modules. Add model discovery and explicit model-loading APIs,
a standard model aggregate, a model BOM, and dedicated model and catalog
release workflows.

Add full PoliMorf integration, model provenance and licensing validation,
streaming model-input verification, strict dependency verification, consumer
resolution tests, Configuration Cache compatibility, and expanded JMH,
quality, documentation, and release checks.

Upgrade the CycloneDX and JMH Gradle plugins and remove Gradle 10 and Java
compiler deprecations.

BREAKING CHANGE: The core Radixor artifact no longer contains bundled stemmer
dictionaries. Applications must add the required model artifacts, the standard
model aggregate, or model dependencies managed through the Radixor model BOM.
2026-07-22 23:33:28 +02:00

3.3 KiB

Architecture and Reduction

This section explains how Radixor turns textual dictionary input into a compact compiled stemmer and how reduction affects the semantics preserved in the final runtime artifact.

Radixor is easiest to understand when separated into two related concerns:

  • architecture: what structures exist, how data moves through them, and what runtime lookup actually does,
  • reduction semantics: what it means for two subtrees to be considered equivalent and how that choice affects get() and getAll() behavior.

The short version

Radixor does not keep a large flat table of final stems. Instead, it converts dictionary entries into patch commands, stores them in a trie, reduces equivalent subtrees, and freezes the result into an immutable compiled structure.

The build-time flow is:

Dictionary -> Mutable trie -> Reduced trie -> Compiled trie

For registered models, the dictionary is an independently versioned GZip resource discovered through a descriptor and verified before this flow begins. The model resource is input to trie construction, not a precompiled trie. See Model Selection and Loading for discovery and Architecture for component and release boundaries.

Explicit descriptors and stable model IDs now use the same compiled-value path as language defaults. loadCompiled(descriptor, ...) and loadCompiled(modelId, ...) first build with serialized patch commands and then map those values to CompiledPatchCommand while preserving metadata, reduction semantics, and ranked getAll order. Very large inputs can have a high temporary construction peak; PoliMorf is verified in an isolated 6 GiB JVM rather than increasing ordinary test or Gradle daemon heaps.

At runtime, the compiled trie does not directly return the final stem string. It returns one or more stored patch commands for the addressed key, and those commands are then applied to the original input word.

Why this matters

This design gives Radixor several practical properties at once:

  • compact deployable artifacts,
  • deterministic runtime behavior,
  • support for both preferred and multiple candidate results,
  • separation of preparation-time complexity from runtime lookup.

It also explains why a large source dictionary can be transformed into a much smaller compiled artifact without discarding the operational behavior that matters to the caller.

Reading guide

Use the following pages depending on what you need to understand:

  • Architecture explains the data flow, core structures, patch-command lookup model, and why the compiled trie is efficient at runtime.
  • Reduction Semantics explains how subtree equivalence is defined, what ranked, unordered, and dominant reduction preserve, and how those choices affect observable lookup behavior.

For most readers, the best order is:

  1. Architecture
  2. Reduction Semantics