Rust Rule Engine v1.16.0 🦀⚡🚀
A blazing-fast production-ready rule engine for Rust supporting both Forward and Backward Chaining. Features RETE-UL algorithm with Alpha Memory Indexing and Beta Memory Indexing, parallel execution, goal-driven reasoning, and GRL (Grule Rule Language) syntax.
🔗 GitHub | Documentation | Crates.io
🎯 Reasoning Modes
🔄 Forward Chaining (Data-Driven)
"When facts change, fire matching rules"
- Native Engine - Simple pattern matching for small rule sets
- RETE-UL - Optimized network for 100-10,000 rules with O(1) indexing
- Parallel Execution - Multi-threaded rule evaluation
Use Cases: Business rules, validation, reactive systems, decision automation
🎯 Backward Chaining (Goal-Driven)
"Given a goal, find facts/rules to prove it"
- Unification - Pattern matching with variable bindings
- Search Strategies - DFS, BFS, Iterative Deepening
- Aggregation - COUNT, SUM, AVG, MIN, MAX
- Negation - NOT queries with closed-world assumption
- Explanation - Proof trees with JSON/MD/HTML export
- Disjunction - OR patterns for alternative paths
- Nested Queries - Subqueries with shared variables
- Query Optimization - Automatic goal reordering for 10-100x speedup
Use Cases: Expert systems, diagnostics, planning, decision support, AI reasoning
🌊 Stream Processing (Event-Driven) 🆕
"Process real-time event streams with time-based windows"
- GRL Stream Syntax - Declarative stream pattern definitions
- StreamAlphaNode - RETE-integrated event filtering & windowing
- Time Windows - Sliding (continuous), tumbling (non-overlapping), and session (gap-based) 🆕
- Multi-Stream Correlation - Join events from different streams
- WorkingMemory Integration - Stream events become facts for rule evaluation
Use Cases: Real-time fraud detection, IoT monitoring, financial analytics, security alerts, CEP
Example:
rule "Fraud Alert" {
when
login: LoginEvent from stream("logins") over window(10 min, sliding) &&
purchase: PurchaseEvent from stream("purchases") over window(10 min, sliding) &&
login.user_id == purchase.user_id &&
login.ip_address != purchase.ip_address
then
Alert.trigger("IP mismatch detected");
}
🚀 Quick Start
Forward Chaining Example
use ;
let mut engine = new;
// Define rule in GRL
engine.add_rule_from_grl?;
// Add facts and execute
let mut facts = new;
facts.set;
engine.execute?;
// Result: Customer.Discount = 0.15 ✓
Backward Chaining Example
use BackwardEngine;
let mut engine = new;
// Query: "Can this order be auto-approved?"
let result = engine.query?;
if result.provable
Stream Processing Example 🆕
use parse_stream_pattern;
use ;
use WorkingMemory;
// Parse GRL stream pattern
let grl = r#"login: LoginEvent from stream("logins") over window(5 min, sliding)"#;
let = parse_stream_pattern?;
// Create stream processor
let mut node = new;
// Process events in real-time
let mut wm = new;
for event in event_stream
// Run: cargo run --example streaming_fraud_detection --features streaming
✨ What's New in v1.16.0 🎉
🪟 Session Windows for Stream Processing
Complete implementation of session-based windowing for real-time event streams! Session windows dynamically group events based on inactivity gaps rather than fixed time boundaries.
What are Session Windows?
Unlike sliding or tumbling windows, session windows adapt to natural event patterns:
Events: A(t=0), B(t=1), C(t=2), [gap 10s], D(t=12), E(t=13)
Timeout: 5 seconds
Result:
Session 1: [A, B, C] - ends when gap > 5s
Session 2: [D, E] - starts after gap > 5s
GRL Syntax:
rule "UserSessionAnalysis" {
when
activity: UserAction from stream("user-activity")
over window(5 min, session)
then
AnalyzeSession(activity);
}
Rust API:
use ;
use WindowType;
use Duration;
let window = WindowSpec ;
let mut node = new;
Perfect for:
- 📊 User Session Analytics - Track natural user behavior sessions
- 🛒 Cart Abandonment - Detect when users don't complete checkout
- 🔒 Fraud Detection - Identify unusual session patterns
- 📡 IoT Sensor Grouping - Group burst events from sensors
Features:
- ✅ Automatic session boundary detection based on inactivity
- ✅ Dynamic session sizes (adapts to activity patterns)
- ✅ O(1) event processing with minimal overhead
- ✅ Full integration with RETE network
- ✅ 7 comprehensive tests (all passing)
- ✅ Interactive demo:
cargo run --example session_window_demo --features streaming
✨ What's New in v1.15.1
🧹 Codebase Cleanup
Major cleanup and optimization of the project structure for better maintainability and developer experience!
🔧 Dependencies Optimized (-75% dev-deps)
- Removed 9 unused dev-dependencies (axum, tower, reqwest, tracing, etc.)
- Eliminated duplicate dependencies (serde, chrono already in main deps)
- Kept only essentials: criterion, tokio, serde_yaml
- Faster build times and smaller binary size
Benefits:
- ⚡ Faster compilation and CI runs
- 📚 Easier onboarding with clear example structure
- 🧹 Less code to maintain (-76% examples)
- ✅ Production-ready with all tests passing
✨ What's New in v1.15.0
➕ Array Append Operator (+=)
Added support for the += operator to append values to arrays in GRL actions! This is particularly useful for building recommendation lists, accumulating results, and managing collections.
GRL Syntax:
rule "Product Recommendation" salience 100 no-loop {
when
ShoppingCart.items contains "Laptop" &&
!(Recommendation.items contains "Mouse")
then
Recommendation.items += "Mouse"; // Append to array
Recommendation.items += "USB-C Hub"; // Multiple appends
Log("Added recommendations");
}
Rust Usage:
use ;
use GrlReteLoader;
let mut engine = new;
load_from_file?;
let mut facts = new;
facts.set;
facts.set;
engine.insert_typed_facts;
engine.fire_all;
// Result: Recommendation.items = ["Mouse", "USB-C Hub"] ✓
Integration with Rule Mining:
The += operator works seamlessly with rust-rule-miner for automatic rule generation:
// Mine association rules from historical data
let rules = miner.mine_association_rules?;
// Export to GRL with += syntax
let grl = to_grl;
// Generates: Recommendation.items += "Phone Case";
// Load and execute in RETE engine
load_from_string?;
Supported Everywhere:
- ✅ Forward chaining (RETE engine)
- ✅ Backward chaining (goal-driven reasoning)
- ✅ Parallel execution
- ✅ All action execution contexts
✨ What's New in v1.14.0 🎉
⚡ Alpha Memory Indexing - Up to 800x Faster Queries!
New hash-based indexing for alpha node fact filtering, complementing Beta Memory Indexing for complete RETE optimization!
🔍 Alpha Memory Indexing
Problem: Alpha nodes scan all facts linearly to find matches - O(n) complexity becomes slow with large datasets.
Solution: Hash-based indexing provides O(1) fact lookups - up to 800x speedup for filtered queries!
use ;
// Create alpha memory with indexing
let mut mem = new;
// Create index on frequently-queried field
mem.create_index;
// Insert facts (index updated automatically)
for i in 0..10_000
// Query using index - O(1) lookup!
let active = mem.filter;
println!;
// Without index: 10,000 comparisons (O(n))
// With index: 1 hash lookup (O(1)) → ~800x faster!
Real Benchmark Results:
| Dataset Size | Linear Scan | Indexed Lookup | Speedup |
|---|---|---|---|
| 1,000 facts | 310 µs | 396 ns | 782x |
| 10,000 facts | 3.18 ms | 396 ns | 8,030x |
| 50,000 facts | 15.9 ms | 396 ns | 40,151x 🚀 |
Key Features:
- ✅ Auto-tuning - Automatically creates indexes after 50+ queries on a field
- ✅ Multiple indexes - Index different fields independently
- ✅ Statistics tracking - Monitor index hit rates and effectiveness
- ✅ Low overhead - ~7-9% memory per index
When to Use:
// ✅ Use when:
// - Dataset > 10K facts
// - Read-heavy workload (query > insert)
// - High selectivity queries (<10% match rate)
// - Same queries repeated multiple times
// ❌ Skip when:
// - Dataset < 1K facts (overhead > benefit)
// - Write-heavy workload (insert > query)
// - Query each field only once
// 🤖 Auto-tuning mode (recommended):
let mut mem = new;
// Query many times...
for _ in 0..100
// Auto-create index when query count > 50
mem.auto_tune; // Indexes "status" automatically!
Memory Overhead:
| Index Count | Memory Usage | Overhead |
|---|---|---|
| 0 indexes | 59.31 MB | Baseline |
| 1 index | 60.32 MB | +1.7% |
| 3 indexes | 72.15 MB | +21.6% |
| 5 indexes | 85.67 MB | +44.4% |
Recommendation: Use 1-3 indexes max (~20% overhead) for best ROI.
✨ What's New in v1.13.0
⚡ Beta Memory Indexing - Up to 1,235x Faster Joins!
Comprehensive RETE optimization system with Beta Memory Indexing providing exponential speedup for multi-pattern rules!
🚀 Beta Memory Indexing
Problem: Join operations use nested loops (O(n²)) which becomes a bottleneck with large fact sets.
Solution: Hash-based indexing changes O(n²) to O(n) - providing 11x to 1,235x speedup!
use BetaMemoryIndex;
use TypedFacts;
// Create sample facts (e.g., orders with customer IDs)
let mut orders = Vecnew;
for i in 0..1000
// Build index on join key (CustomerId)
let mut index = new;
for in orders.iter.enumerate
// Perform O(1) lookup instead of O(n) scan
// Note: Key format is the Debug representation of FactValue
let key = "String(\"C50\")"; // Looking for customer C50's orders
let matches = index.lookup; // O(1) hash lookup!
println!;
// Without indexing: 1,000 comparisons (O(n))
// With indexing: 1 hash lookup (O(1)) → 1,000x faster!
Real Benchmark Results:
| Dataset Size | Nested Loop (O(n²)) | Indexed (O(n)) | Speedup |
|---|---|---|---|
| 100 facts | 1.00 ms | 92 µs | 11x |
| 1,000 facts | 113.79 ms | 672.76 µs | 169x |
| 5,000 facts | 2.63 seconds | 2.13 ms | 1,235x 🚀 |
Key Insight: At 5,000 facts, the difference between 2.6 SECONDS and 2ms is production-critical!
🔧 Memory Optimizations
Three additional optimizations focus on reducing memory footprint:
1. Node Sharing - Deduplicate identical alpha nodes
use NodeSharingRegistry;
let mut registry = new;
// Register 10,000 nodes with 100 unique patterns
for in nodes.iter.enumerate
// Result: 98.1% memory reduction (689.84 KB saved)
let stats = registry.stats;
println!;
2. Alpha Memory Compaction - Eliminate duplicate facts
use CompactAlphaMemory;
let mut memory = new;
// Insert 10,000 facts with duplicates
for fact in facts
// Result: 98.7% memory reduction (925.00 KB saved)
println!;
3. Token Pooling - Reduce allocations
use TokenPool;
let mut pool = new;
// Process 10,000 events with token reuse
for event in events
// Result: 99% fewer allocations
let stats = pool.stats;
println!;
📊 When to Use Each Optimization
| Optimization | Always Use? | Use When | Skip When |
|---|---|---|---|
| Beta Indexing ⚡ | YES | Any join operations | Never (always beneficial) |
| Alpha Indexing 🆕 | No | Read-heavy + >10K facts | Write-heavy or <1K facts |
| Node Sharing | No | Memory-constrained + 10K+ rules | Speed is priority |
| Alpha Memory Compaction | No | Many duplicate facts expected | Few duplicates |
| Token Pooling | No | 100K+ events/sec continuous | Batch/low-volume processing |
💡 Recommended Usage
Default (Most Production Systems):
// Use Beta + Alpha Indexing for maximum performance
use ;
// Alpha indexing: for filtering (auto-tune recommended)
let mut alpha_mem = new;
// Will auto-create indexes for frequently-queried fields
// Beta indexing: for joins (always use)
let mut beta_index = new;
// 150-1,235x faster joins - no downsides!
Memory-Constrained + Large Rule Sets:
use ;
High-Duplicate Workloads:
use ;
🔬 Try It Yourself
# Run interactive demos
# Run benchmarks
# View detailed HTML reports
📚 Complete Documentation
- RETE Optimization Guide - Comprehensive optimization guide
- Benchmark Results - Real benchmark data & analysis
- Optimization Demo - Interactive demonstration
- GRL + Optimization Demo - Real GRL rules with Beta Indexing
- Memory Analysis - Actual KB/MB measurements with RETE engine
New in v1.13.0:
- ✅ Beta Memory Indexing (11x to 1,235x speedup)
- ✅ Node Sharing (98.1% memory reduction)
- ✅ Alpha Memory Compaction (98.7% memory reduction)
- ✅ Token Pooling (99% fewer allocations)
- ✅ Comprehensive benchmarks with scaled datasets
- ✅ Real memory measurements (KB/MB)
- ✅ Production-ready optimization manager
- ✅ 30+ optimization tests
✨ Previous Update - v1.12.1
🌊 Stream Processing Foundation!
GRL Stream Syntax - Parse and process real-time event streams with time-based windows!
🆕 Stream Processing Features
GRL Stream Pattern Syntax:
// Stream with sliding window
login: LoginEvent from stream over window
// Stream with tumbling window
metric: MetricEvent from stream over window
// Simple stream without window
event: Event from stream
StreamAlphaNode - RETE Integration:
use parse_stream_pattern;
use ;
// Parse GRL pattern
let grl = r#"login: LoginEvent from stream("logins") over window(5 min, sliding)"#;
let = parse_stream_pattern?;
// Create stream processor
let mut node = new;
// Process events
if node.process_event
Real-World Example - Fraud Detection:
// 4 fraud detection rules implemented:
// 1. Suspicious IP changes (multiple IPs in 15 min)
// 2. High velocity purchases (>3 purchases in 15 min)
// 3. Impossible travel (location change too fast)
// 4. IP mismatch (login IP != purchase IP)
// Result: 7 alerts triggered from 16 events
cargo run --example streaming_fraud_detection --features streaming
Features Implemented:
- ✅ GRL stream syntax parser (nom-based, 15 tests)
- ✅ StreamAlphaNode for event filtering & windowing (10 tests)
- ✅ Sliding windows (continuous rolling)
- ✅ Tumbling windows (non-overlapping)
- ✅ WorkingMemory integration (stream → facts)
- ✅ Duration units: ms, sec, min, hour
- ✅ Optional event type filtering
- ✅ Multi-stream correlation
Test Coverage:
- 58 streaming tests (100% pass)
- 8 integration tests (fraud, IoT, trading, security)
- 3 end-to-end tests (GRL → RETE → WorkingMemory)
- 2 comprehensive examples
✨ Previous Update - v1.11.0
🎯 Nested Queries & Query Optimization!
Complete Phase 1.1 with nested queries (subqueries) and intelligent query optimization for 10-100x performance improvements!
🆕 Nested Queries
use *;
// Find grandparents using nested queries
let results = engine.query?;
// Complex eligibility with nested OR
query "CheckEligibility"
⚡ Query Optimization
// Enable optimization in GRL
query "OptimizedSearch"
// Manual optimization
let mut optimizer = new;
optimizer.set_selectivity; // 10% in stock
optimizer.set_selectivity; // 30% expensive
optimizer.set_selectivity; // 90% items
let optimized = optimizer.optimize_goals;
// Result: in_stock → expensive → item (10-100x faster!)
Performance Benefits:
- Before: 1000 items → 900 expensive → 270 in_stock = 2170 evaluations
- After: 10 in_stock → 8 expensive → 8 items = 26 evaluations
- Speedup: ~83x faster! 🚀
New Features:
- Nested queries with WHERE clauses
- Query optimizer with goal reordering
- Selectivity estimation (heuristic & custom)
- Join order optimization
enable-optimizationflag in GRL- 19 new tests + 9 integration tests
Testing: 485/485 tests pass (368 unit + 117 integration) • Zero regressions
📖 Nested Query Demo • Optimizer Demo • GRL Integration
📚 Documentation
Comprehensive documentation organized by topic:
🚀 Getting Started
- Quick Start - Get up and running in 5 minutes
- Installation - Installation and setup guide
- Basic Concepts - Core concepts explained
- First Rules - Write your first rules
🎯 Core Features
- GRL Syntax - Grule Rule Language reference
- Features Overview - All engine capabilities
⚡ Advanced Features
- RETE Optimization - 1,235x join speedup & memory optimizations (v1.13.0+)
- RETE Benchmarks - Real performance data & analysis (v1.13.0+)
- Streaming & CEP - Complex Event Processing
- Streaming Architecture - Deep dive into streaming
- Plugins - Custom plugins and extensions
- Performance - Optimization techniques
- Redis State - Distributed state management
📖 API Reference
- API Reference - Complete public API
- GRL Query Syntax - Backward chaining queries (v1.11.0+)
- Parser Cheat Sheet - Quick syntax reference
📝 Guides
- Backward Chaining Quick Start - Goal-driven reasoning
- RETE Integration - Combine forward + backward
- Module Management - Organize rules into modules
- Troubleshooting - Common issues and solutions
💡 Examples
- AI Integration - Combine with ML models
📜 Older Releases
See CHANGELOG.md for full version history (v0.1.0 - v0.19.0).