Skip to main content

steeldb/
lib.rs

1//! **A database that compiles questions instead of guessing answers.**
2//!
3//! Most systems answer a question about documents by *similarity*: find the nearest text and return it. That
4//! works until the question involves a combination (`A but not B`), a complete count, or something the
5//! documents simply do not contain — where a similarity search still returns its closest guess, and a guess is
6//! indistinguishable from an answer.
7//!
8//! SteelDB learns which categories your documents actually support, type-checks a question against them before
9//! anything runs, and executes the survivors as bitwise set algebra over compressed bitmaps. A question the
10//! data cannot answer is **refused**, with the alternatives that do exist.
11//!
12//! # Start here
13//!
14//! ```no_run
15//! use steeldb::SteelDb;
16//!
17//! # let documents: Vec<String> = Vec::new();
18//! // No model files needed: the vocabulary is discovered from the text.
19//! let db = SteelDb::ingest(documents)?;
20//!
21//! // Category names come from the words the documents use, so read them before writing a query.
22//! for c in db.categories() {
23//!     println!("can ask about {}", c.wildcard());
24//! }
25//!
26//! match db.query("(and elevation/* (not state/negated))") {
27//!     Ok(answer)   => println!("{} situations", answer.len()),
28//!     Err(refused) => println!("{refused}"),   // says what the data does contain
29//! }
30//! # Ok::<(), steeldb::Error>(())
31//! ```
32//!
33//! # Three verbs
34//!
35//! | verb | what it needs | what it costs |
36//! |---|---|---|
37//! | [`SteelDb::ingest`] | nothing — no models, no network | deterministic and free |
38//! | [`SteelDb::query`] | nothing | microseconds |
39//! | [`learn`] | credentials and a network | a model call, and a bill |
40//!
41//! The asymmetry is deliberate. `ingest` and `query` are pure; `learn` calls a language model, so it lives in
42//! its own module, is `async`, is feature-gated, and returns a *proposal* rather than changing your vocabulary.
43//! You review it and [`SteelDb::adopt`] it, at which point the same gate that governs local discovery decides
44//! what survives — a model cannot add a category a deterministic test would have rejected.
45//!
46//! [`SteelDb`] is the whole API for most uses. [`Answer`] is a *complete* set rather than a ranked sample, so
47//! counting it means something. [`Refused`] is an error rather than an empty result because those are different
48//! facts, and conflating them is how a confident wrong answer gets produced.
49//!
50//! # The query language
51//!
52//! Queries are s-expressions — operation first, nested lists, as in Lisp. The whole grammar:
53//!
54//! | form | meaning |
55//! |---|---|
56//! | `category/value` | situations carrying that exact tag |
57//! | `category/*` | any value in that category |
58//! | `(and A B)` | intersection |
59//! | `(or A B)` | union |
60//! | `(not A)` | difference |
61//! | `(num field op value)` | numeric comparison; `op` is `ge gt le lt eq ne` |
62//! | `(evidence A :min-bel f)` | only where belief in `A` reaches `f` |
63//! | `(s-path :s n (source A) (target B))` | situations on a chain sharing ≥ `n` tags per step |
64//! | `(combine-ds :max-conflict f …)` | fuse independent evidence, or refuse |
65//!
66//! There is deliberately almost no syntax to get wrong, which matters when the author is a language model.
67//!
68//! # Beyond the basics
69//!
70//! - [`evidence`] — Dempster–Shafer belief intervals, and the conflict metric that refuses to fuse
71//!   contradictory sources rather than averaging them into a consensus nobody holds.
72//! - [`programs`] — higher-order structure: s-paths, and the primal/dual s-filtration.
73//! - [`emergent`] — how the vocabulary is discovered from prose, with no model.
74//! - [`models`] — where trained weights come from. Nothing downloads without being asked.
75//! - [`linter`] — the type-checker, if you want to validate without executing.
76//!
77//! # Installing
78//!
79//! The crate is published as **`hypersteeldb`** and imported as `steeldb`:
80//!
81//! ```toml
82//! [dependencies]
83//! hypersteeldb = "0.2"
84//! ```
85//!
86//! (The bare name `steeldb` was taken on crates.io in 2023 by an unrelated project, so the package carries the
87//! longer name while the import stays short.)
88//!
89//! # Features
90//!
91//! The default build is pure Rust with no model dependencies and compiles to `wasm32`.
92//!
93//! | feature | adds |
94//! |---|---|
95//! | `embed` | static embeddings + optimal-transport discovery (links a C regex library) |
96//! | `onnx` | the trained span tagger |
97//! | `native` | candle: HRM training and inference |
98//! | `needle` | the Cactus needle3 query planner |
99//! | `agent`, `bedrock`, `paddock` | LLM-driven query planning |
100//! | `wasm` | browser bindings |
101
102pub mod api;
103pub mod artifact;
104pub use api::{Answer, Error, Interval, Options, Refused, SteelDb};
105
106pub mod agent;
107pub mod bitmap;
108pub mod db;
109pub mod vocabulary;
110#[cfg(feature = "wasm")]
111#[doc(hidden)]
112pub mod wasm;
113#[doc(hidden)]
114pub mod discover;
115#[cfg(feature = "embed")]
116pub mod discover_ontology;
117#[doc(hidden)]
118pub mod dsl_trajectories;
119pub mod evidence;
120pub mod emergent;
121#[cfg(feature = "docs")]
122pub mod docs;
123#[cfg(feature = "ocr")]
124pub mod ocr;
125pub mod grow;
126#[cfg(feature = "native")]
127pub mod hrm;
128#[doc(hidden)]
129pub mod ikl_trajectories;
130pub mod index;
131pub mod jsonl;
132pub mod learn;
133pub mod linter;
134#[cfg(feature = "native")]
135pub mod needle_model;
136pub mod mece;
137pub mod models;
138pub mod paths;
139pub mod programs;
140pub mod spans;
141pub mod registry;
142pub mod projector;
143pub mod projectors;
144#[doc(hidden)]
145pub mod trajectories;
146#[doc(hidden)]
147pub mod tagger_data;
148#[cfg(feature = "native")]
149pub mod relation_train;
150#[cfg(feature = "native")]
151pub mod tagger_train;
152pub mod text;
153pub mod tokenql;
154pub mod units;
155pub mod dimensions;
156
157pub use bitmap::{Postings, RoarPostings, SetPostings};
158pub use db::{Corpus, FolderReport, Hit, QueryOut, Stats};
159pub use index::InfonIndex;
160pub use projector::{CorpusKind, Projector, Situation};
161pub use tokenql::{evaluate, parse, Node, TokenStore};