vyre_primitives/lib.rs
1#![forbid(unsafe_code)]
2//! `vyre-primitives` — compositional primitives for vyre.
3//!
4//! Shape (mirrors Linux kernel `fs/` / `mm/` / `net/` — subsystem
5//! directories under one crate, feature-gated for consumers):
6//!
7//! ```text
8//! vyre-primitives/
9//! src/
10//! lib.rs # subsystem table (this file)
11//! markers.rs # unit-struct marker types, always on
12//! text/ # feature = "text"
13//! mod.rs
14//! char_class.rs
15//! utf8_validate.rs
16//! line_index.rs
17//! matching/ # feature = "matching"
18//! mod.rs
19//! bracket_match.rs
20//! bitset/ # feature = "bitset"
21//! fixpoint/ # feature = "fixpoint"
22//! graph/ # feature = "graph" (CSR + BFS + SCC + motif + toposort)
23//! hash/ # feature = "hash"
24//! label/ # feature = "label"
25//! math/ # feature = "math"
26//! nn/ # feature = "nn"
27//! parsing/ # feature = "parsing"
28//! predicate/ # feature = "predicate"
29//! reduce/ # feature = "reduce"
30//! ```
31//!
32//! Two kinds of primitive live here:
33//!
34//! 1. **Marker types** (`markers`, always on, zero deps) — unit
35//! structs the reference interpreter and backend emitters dispatch
36//! on.
37//!
38//! 2. **Tier 2.5 substrate** (per-domain feature flags) — shared
39//! `fn(...) -> Program` primitives reused by ≥ 2 Tier-3 dialects.
40//! Each domain is one folder + one feature flag. Tier 3 crates
41//! depend on `vyre-primitives` and enable only the domains they
42//! need.
43//!
44//! The path IS the interface. Subsystem `mod.rs` exposes sub-modules,
45//! not a flat namespace — callers write
46//! `vyre_primitives::text::char_class::char_class(...)` so the LEGO
47//! chain is visible at every call site.
48//!
49//! See `docs/primitives-tier.md` and `docs/lego-block-rule.md` for
50//! the tier rule, admission criteria, and Gate 1 enforcement.
51
52mod markers;
53#[cfg(feature = "vyre-foundation")]
54use std::sync::Arc;
55
56pub use markers::{
57 ArithAdd, ArithMul, BitwiseAnd, BitwiseOr, BitwiseXor, Clz, CombineOp, CompareEq, CompareLt,
58 Gather, HashBlake3, HashFnv1a, PatternMatchDfa, PatternMatchLiteral, Popcount, Reduce,
59 RegionId, Scan, Scatter, ShiftLeft, ShiftRight, Shuffle,
60};
61#[cfg(feature = "vyre-foundation")]
62use vyre_foundation::ir::model::expr::Ident;
63#[cfg(feature = "vyre-foundation")]
64use vyre_foundation::ir::{BufferDecl, DataType, Expr, Node, Program};
65
66/// Build a scalar trap program for invalid primitive builder inputs.
67///
68/// Primitive constructors are intentionally infallible for composition with
69/// registry fixtures and generated dialect code. Invalid user-controlled
70/// shapes must therefore become explicit IR traps, not host panics.
71#[cfg(feature = "vyre-foundation")]
72pub(crate) fn invalid_output_program(
73 op_id: &'static str,
74 output: &str,
75 data_type: DataType,
76 message: String,
77) -> Program {
78 Program::wrapped(
79 vec![BufferDecl::output(output, 0, data_type).with_count(1)],
80 [1, 1, 1],
81 vec![Node::Region {
82 generator: Ident::from(op_id),
83 source_region: None,
84 body: Arc::new(vec![Node::trap(Expr::u32(0), message)]),
85 }],
86 )
87}
88
89/// Domain-neutral byte-range primitive.
90///
91/// CRITIQUE_VISION_ALIGNMENT_2026-04-23 V1: the foundation tier ships a
92/// matching-flavoured `Match { pattern_id, start, end }` today. This
93/// module introduces `ByteRange { tag, start, end }` as the neutral
94/// name so new dialects do not have to adopt matching vocabulary. The
95/// bridge from foundation's legacy `Match` type is implemented in
96/// [`range`], so new dialects can adopt the neutral type without
97/// waiting on a foundation API break.
98pub mod range;
99
100/// Tier-2.5 primitive registry. See [`harness::OpEntry`]. Gated
101/// behind the `inventory-registry` feature so default builds stay
102/// dep-free; the conform harness + xtask enable the feature.
103#[cfg(feature = "inventory-registry")]
104pub mod harness;
105
106/// Text primitives.
107#[cfg(feature = "text")]
108pub mod text;
109
110/// Pattern-matching primitives.
111#[cfg(feature = "matching")]
112pub mod matching;
113
114/// Decode primitives.
115#[cfg(feature = "decode")]
116pub mod decode;
117
118/// NFA primitives — subgroup-cooperative simulator (G1 GPU perf).
119#[cfg(feature = "nfa")]
120pub mod nfa;
121
122/// Hash primitives (FNV-1a 32/64, CRC-32).
123#[cfg(feature = "hash")]
124pub mod hash;
125
126/// Math primitives (dot, scan, reduce, broadcast).
127#[cfg(feature = "math")]
128pub mod math;
129
130/// Parsing primitives (optimizer and AST scan kernels).
131#[cfg(feature = "parsing")]
132pub mod parsing;
133
134/// Neural-network primitives (attention and normalization sub-kernels).
135#[cfg(feature = "nn")]
136pub mod nn;
137
138/// Graph primitives (topological sort, reachability, CSR traversal,
139/// SCC decomposition, path reconstruction — the Tier 2.5 substrate
140/// that surgec's stdlib rules compose against).
141#[cfg(feature = "graph")]
142pub mod graph;
143
144/// Geometric / Clifford-algebra primitives (#8). Multivector products
145/// for equivariant NNs, physics simulation, robotics, 3D vision.
146#[cfg(feature = "geom")]
147pub mod geom;
148
149/// Optimization primitives (#9, #14, #46). Homotopy continuation,
150/// SOS, matroid intersection. Self: vyre's megakernel scheduler.
151#[cfg(feature = "opt")]
152pub mod opt;
153
154/// Topological-data-analysis primitives (#15, #32). Vietoris-Rips
155/// filtration + simplicial complex operations. User: TDA, persistent
156/// landscape features, call-graph topological signatures.
157#[cfg(feature = "topology")]
158pub mod topology;
159
160/// Visual pixel-map primitives. Shared packed-RGBA invocation skeletons
161/// reused by higher-level image-processing compositions.
162#[cfg(feature = "visual")]
163pub mod visual;
164
165/// Effects-typed pipeline primitives (P-1.0-V1.x).
166/// Pure-data substrate: `EffectRow` bitmask, `Handler` over a row,
167/// `handler_apply` discharges effects, `handler_compose` builds a
168/// joint handler. Reference for the foundation effects-typed
169/// `lower` pipeline (V1.3).
170#[cfg(feature = "effects")]
171pub mod effects;
172
173/// Type-discipline primitives (P-PRIM-14, …). Substructural
174/// (linear/affine/relevant/unrestricted) checks the foundation
175/// validate pipeline consumes per buffer.
176#[cfg(feature = "types")]
177pub mod types;
178
179/// Categorical primitives (P-PRIM-16/17/18). Yoneda embedding,
180/// adjoint-pair detection, Kan extension over finite categories.
181/// Consumed by the optimizer's functorial_pass_composition substrate.
182#[cfg(feature = "cat")]
183pub mod cat;
184
185/// ZX-calculus rewrite primitives (P-PRIM-5). Spider fusion,
186/// identity removal, color change. Pure-CPU on a Vec<ZxSpider> +
187/// edge multiset; no FP, no IR-builder dep.
188#[cfg(feature = "zx")]
189pub mod zx;
190
191/// d-DNNF (decomposable / deterministic NNF) compiler primitive
192/// (P-PRIM-6). Host-side CNF → d-DNNF via Shannon decomposition,
193/// linear-time model counting on the result. Used by
194/// `knowledge_compile_pass_precondition` to turn pass-precondition
195/// formulae into linear-cost evaluators.
196#[cfg(feature = "dnnf")]
197pub mod dnnf;
198
199/// Bitset primitives — `and`/`or`/`not`/`xor`/`popcount`/`any`/
200/// `contains` over packed u32 bitsets. The NodeSet / ValueSet
201/// representation every graph primitive consumes.
202#[cfg(feature = "bitset")]
203pub mod bitset;
204
205/// Reduction primitives — `count`/`min`/`max`/`sum` over bitsets and
206/// fixed-width ValueSets. Backs SURGE aggregates.
207#[cfg(feature = "reduce")]
208pub mod reduce;
209
210/// Label → NodeSet resolver — turn a TagFamily bitmask into a
211/// NodeSet bitset. Implements the `@family` lookup that surgec's
212/// label surface surfaces.
213#[cfg(feature = "label")]
214pub mod label;
215
216/// Frozen predicate primitives — the ~10 engine primitives (call_to,
217/// return_value_of, arg_of, size_argument_of, edge, in_function,
218/// in_file, in_package, literal_of, node_kind) that SURGE stdlib
219/// rules compose into every higher-level query.
220#[cfg(feature = "predicate")]
221pub mod predicate;
222
223/// Deterministic fixpoint primitive (ping-pong with convergence
224/// flag). Composes `csr_forward_traverse` + bitset OR into the
225/// transitive-closure driver every stdlib taint rule needs.
226#[cfg(feature = "fixpoint")]
227pub mod fixpoint;
228
229/// Virtual File System DMA primitives. Uses `vyre_foundation::ir`
230/// so it's gated behind the same set of features that pull
231/// vyre-foundation in as an optional dep. Any of the domain
232/// features enables vfs.
233#[cfg(any(
234 feature = "text",
235 feature = "matching",
236 feature = "decode",
237 feature = "math",
238 feature = "nn",
239 feature = "hash",
240 feature = "parsing",
241 feature = "graph",
242 feature = "bitset",
243 feature = "reduce",
244 feature = "label",
245 feature = "predicate",
246 feature = "fixpoint",
247))]
248pub mod vfs;
249
250/// Wire-format envelope re-exported from vyre-foundation.
251///
252/// Every primitive that ships its own `to_bytes` / `from_bytes` (today:
253/// `CompiledDfa`; future: serializable region tables, hash tables,
254/// parser plans) composes this envelope. Re-exporting at the
255/// vyre-primitives root keeps the import path uniform for consumers:
256/// `vyre_primitives::serial_data::WireWriter` regardless of whether
257/// the type lives at the primitive layer or higher up.
258///
259/// Available when any feature that pulls vyre-foundation is enabled
260/// (every primitive domain enables it).
261#[cfg(feature = "vyre-foundation")]
262pub mod serial_data {
263 pub use vyre_foundation::serial::envelope::{
264 test_helpers, EnvelopeError, WireReader, WireWriter,
265 };
266}
267
268#[cfg(feature = "predicate")]
269pub(crate) mod program_region {
270 use vyre_foundation::composition::mark_self_exclusive_region;
271 use std::sync::Arc;
272
273 use vyre_foundation::ir::model::expr::{GeneratorRef, Ident};
274 use vyre_foundation::ir::{Node, Program};
275
276 pub(crate) fn tag_program(parent_op_id: &str, program: Program) -> Program {
277 let parent_op_id = if program.is_non_composable_with_self() {
278 mark_self_exclusive_region(parent_op_id)
279 } else {
280 parent_op_id.to_owned()
281 };
282 Program::wrapped(
283 program.buffers().to_vec(),
284 program.workgroup_size(),
285 vec![Node::Region {
286 generator: Ident::from(parent_op_id.as_str()),
287 source_region: None,
288 body: Arc::new(reparent_program_children(&program, parent_op_id.as_str())),
289 }],
290 )
291 .with_non_composable_with_self(program.is_non_composable_with_self())
292 }
293
294 fn reparent_program_children(program: &Program, parent_op_id: &str) -> Vec<Node> {
295 let parent = GeneratorRef {
296 name: parent_op_id.to_string(),
297 };
298 program
299 .entry()
300 .iter()
301 .cloned()
302 .map(|node| reparent_entry_node(node, &parent))
303 .collect()
304 }
305
306 fn reparent_entry_node(node: Node, parent: &GeneratorRef) -> Node {
307 match node {
308 Node::Region {
309 generator, body, ..
310 } => Node::Region {
311 generator,
312 source_region: Some(parent.clone()),
313 body,
314 },
315 other => Node::Region {
316 generator: Ident::from(Program::ROOT_REGION_GENERATOR),
317 source_region: Some(parent.clone()),
318 body: Arc::new(vec![other]),
319 },
320 }
321 }
322}