Skip to main content

lemma/
lib.rs

1//! # Lemma Engine
2//!
3//! **Rules for man and machine**
4//!
5//! Lemma is a declarative programming language for expressing rules, data, and business logic
6//! in a way that is both human-readable and machine-executable.
7//!
8//! ## Quick Start
9//!
10//! ```rust,no_run
11//! use lemma::{Engine, SourceType};
12//!
13//! let mut engine = Engine::new();
14//!
15//! // Load Lemma code
16//! engine.load(r#"
17//!     spec example
18//!     data price: 100
19//!     data quantity: 5
20//!     rule total: price * quantity
21//! "#, SourceType::Path(std::sync::Arc::new(std::path::PathBuf::from("example.lemma")))).expect("failed to load");
22//!
23//! // Evaluate the spec (all rules, no data values)
24//! let now = lemma::DateTimeValue::now();
25//! let response = engine.run(None, "example", Some(&now), std::collections::HashMap::new(), false).unwrap();
26//! ```
27//!
28//! ## Core Concepts
29//!
30//! ### Specs
31//! A spec is a collection of data and rules. Specs can reference
32//! other Specs to build composable logic.
33//!
34//! ### Data
35//! Data are named values: numbers, text, dates, booleans, or typed units
36//! like `50 kilograms` or `100`.
37//!
38//! ### Rules
39//! Rules compute values based on data and other rules. They support
40//! conditional logic through "unless" clauses.
41//!
42//! ### Types
43//! Lemma has a rich type system including units (mass, length, time, money)
44//! with automatic conversions.
45
46#[cfg(test)]
47mod tests;
48
49pub(crate) mod computation;
50pub(crate) mod engine;
51pub(crate) mod error;
52pub(crate) mod evaluation;
53pub(crate) mod formatting;
54pub(crate) mod inversion;
55pub(crate) mod limits;
56pub(crate) mod literals;
57pub(crate) mod parsing;
58pub(crate) mod planning;
59pub(crate) mod registry;
60pub(crate) mod spec_set_id;
61pub(crate) mod stdlib;
62
63#[cfg(not(target_arch = "wasm32"))]
64pub mod deps;
65
66#[cfg(target_arch = "wasm32")]
67pub mod wasm;
68
69// === Construction + orchestration ===
70#[cfg(not(target_arch = "wasm32"))]
71pub use engine::{
72    collect_lemma_sources, Context, Engine, Errors, ResolvedRepository, EMBEDDED_STDLIB_REPOSITORY,
73};
74#[cfg(target_arch = "wasm32")]
75pub use engine::{Context, Engine, Errors, ResolvedRepository, EMBEDDED_STDLIB_REPOSITORY};
76
77// === Errors ===
78pub use error::{Error, ErrorDetails, ErrorKind, RequestErrorKind};
79
80// === Limits ===
81pub use limits::{
82    ResourceLimits, MAX_DATA_NAME_LENGTH, MAX_RULE_NAME_LENGTH, MAX_SPEC_NAME_LENGTH,
83};
84
85// === Source + parsing ===
86pub use parsing::ast::{
87    DataValue, DateTimeValue, EffectiveDate, LemmaRepository, LemmaSpec, Span, SpecRef,
88    TimezoneValue,
89};
90pub use parsing::source::{Source, SourceType};
91// Planning [`semantics::DataValue`] (bindings) vs parse [`ast::DataValue`]; only the parse enum is `DataValue` at the root.
92pub use parsing::lexer::{Lexer, TokenKind};
93pub use parsing::{parse, ParseResult};
94pub use planning::semantics::DataValue as BindingDataValue;
95
96// === Data input ===
97pub use planning::data_input::DataValueInput;
98
99// === Execution plan + schema ===
100pub use planning::execution_plan::{
101    type_detail_lines, DataEntry, ExecutionPlan, ExecutionPlanSerialized, SpecSchema,
102};
103pub use planning::plan;
104pub use planning::semantics::{
105    DataDefinition, DataPath, LemmaType, LiteralValue, QuantityUnit, QuantityUnits, RatioUnit,
106    RatioUnits, RulePath, Source as PlanningSource, TypeSpecification, ValueKind,
107};
108pub use planning::spec_set::LemmaSpecSet;
109
110// === Evaluation output ===
111pub use evaluation::evaluation_trace::{
112    trace_expression, ConversionTraceRole, ConversionTraceStep, EvaluationTrace, TraceBranch,
113    TraceNode, TraceNonMatchedBranch, TraceValueSource,
114};
115pub use evaluation::operations::{ComputationKind, OperationResult, VetoType};
116pub use evaluation::response::{DataGroup, Response, RuleResult};
117
118// === Inversion ===
119pub use inversion::{Bound, Domain, InversionResponse, Target, TargetOp};
120
121// === Formatting ===
122pub use formatting::{format_parse_result, format_source, format_specs};
123
124// === Registry ===
125#[cfg(all(feature = "registry", not(target_arch = "wasm32")))]
126pub use registry::resolve_registry_references;
127pub use registry::{LemmaBase, Registry, RegistryBundle, RegistryError, RegistryErrorKind};
128
129// === Spec set ID ===
130pub use spec_set_id::parse_spec_set_id;
131
132// === Stdlib ===
133pub use stdlib::UNITS_LEMMA;