# Engine Comparison: Native vs RETE-UL
## Overview
Rust Rule Engine currently has **2 separate engines**, each suitable for different use cases:
1. **Native Engine** (`RustRuleEngine`) - General-purpose rule engine
2. **RETE-UL Engine** (`IncrementalEngine`) - High-performance pattern matcher
---
## Feature Comparison
| **Core Features** |
| Basic Rules (when/then) | ✅ | ✅ | = |
| GRL Syntax Support | ✅ | ✅ (via loader) | = |
| Salience/Priority | ✅ | ✅ | = |
| No-Loop | ✅ | ✅ | = |
| **Performance** |
| Simple Rules (< 100) | ⚡ Good | ⚡⚡ Better | RETE |
| Complex Rules (> 100) | 🐌 Slower | ⚡⚡⚡ Much Faster | **RETE** |
| Incremental Updates | ❌ No | ✅ Yes (2x faster) | **RETE** |
| Memoization | ❌ No | ✅ Yes (99% hit rate) | **RETE** |
| **Pattern Matching** |
| Basic Conditions | ✅ | ✅ | = |
| EXISTS Pattern | ✅ | ✅ | = |
| FORALL Pattern | ✅ | ✅ | = |
| Variable Binding ($var) | ❌ No | ✅ Yes | **RETE** |
| Multi-Object Patterns | ❌ No | ✅ Yes (JOINs) | **RETE** |
| Cross-Pattern Variables | ❌ No | ✅ Yes | **RETE** |
| **Working Memory** |
| Basic Facts | ✅ | ✅ | = |
| FactHandles | ❌ No | ✅ Yes | **RETE** |
| Insert/Update/Retract | Basic | ✅ Full (Drools-style) | **RETE** |
| Type Indexing | ❌ No | ✅ Yes (O(1) lookup) | **RETE** |
| Change Tracking | ❌ No | ✅ Yes | **RETE** |
| **Agenda Control** |
| Basic Agenda | ✅ | ✅ | = |
| Activation Groups | ✅ | ✅ | = |
| Agenda Groups | ✅ | ✅ | = |
| Ruleflow Groups | ✅ | ✅ | = |
| Lock-on-Active | ✅ | ✅ | = |
| **Integration** |
| Plugin System | ✅ Yes (44+ actions) | ❌ Not yet | **Native** |
| Action Handlers | ✅ Yes | ⚠️ Basic | **Native** |
| Analytics | ✅ Yes | ❌ No | **Native** |
| Workflow Engine | ✅ Yes | ❌ No | **Native** |
| REST API | ✅ Yes | ❌ No | **Native** |
| **Ease of Use** |
| Learning Curve | 🟢 Easy | 🟡 Medium | **Native** |
| API Simplicity | 🟢 Simple | 🟡 Medium | **Native** |
| Documentation | ✅ Complete | ✅ Complete | = |
| **Compatibility** |
| Drools Compatibility | ~60% | ~95% | **RETE** |
| Forward Chaining | ✅ | ✅ | = |
| Backward Chaining | ❌ | ❌ | = |
---
## Performance Benchmarks
### Small Rule Sets (< 50 rules)
| Load Time | ~1ms | ~1ms | ≈ Same |
| First Execution | 50µs | 60µs | Native faster |
| Repeated Execution | 45µs | 25µs | **RETE 1.8x faster** |
| Memory Usage | 2KB | 3KB | Native lower |
**Verdict**: Native engine has lower overhead for small rule sets.
### Large Rule Sets (> 100 rules)
| Load Time | ~5ms | ~6ms | ≈ Same |
| First Execution | 500µs | 200µs | **RETE 2.5x faster** |
| Repeated Execution | 480µs | 30µs | **RETE 16x faster** |
| Incremental Update | N/A | 35µs | **RETE only** |
| Memory Usage | 10KB | 25KB | Native lower |
**Verdict**: RETE-UL excels with large rule sets.
### Real-Time Updates (Streaming)
| Fact Insert | 100µs | 40µs | **RETE 2.5x faster** |
| Fact Update | 150µs (re-eval all) | 35µs (incremental) | **RETE 4.3x faster** |
| Throughput | 6,667 updates/s | 28,571 updates/s | **RETE 4.3x higher** |
**Verdict**: RETE-UL is optimized for streaming data.
---
## Use Case Recommendations
### ✅ Use Native Engine When:
1. **Plugin Integration Required**
- Need built-in string/math/date utilities
- Want action handlers (SendEmail, LogToDatabase, etc.)
- Require workflow engine features
2. **Simple Business Rules**
- < 50 rules
- Straightforward conditions (no complex patterns)
- Don't need incremental updates
3. **Analytics & Monitoring**
- Need rule performance tracking
- Want REST API integration
- Require coverage analysis
4. **Getting Started / Prototyping**
- Learning curve is easier
- Simpler API
- More batteries included
5. **Low Memory Environments**
- Memory constraints
- Minimal overhead needed
**Example Use Cases**:
- Small business rule engine
- Configuration-driven logic
- Simple validation rules
- Integration with existing plugins
```rust
// Native Engine - Simple and batteries included
let kb = KnowledgeBase::new("MyApp");
let mut engine = RustRuleEngine::new(kb);
engine.load_rules_from_file("rules.grl")?;
engine.execute(&facts)?;
```
### ✅ Use RETE-UL Engine When:
1. **High Performance Required**
- > 100 rules
- Real-time processing
- Streaming data
- Low latency requirements
2. **Complex Pattern Matching**
- Variable binding across facts
- Multi-object patterns (JOINs)
- Cross-pattern constraints
- Drools-style patterns
3. **Incremental Updates**
- Facts change frequently
- Need to track changes
- Want selective re-evaluation
4. **Drools Migration**
- Porting from Drools
- Need 95% compatibility
- Complex rule sets
5. **Working Memory Management**
- Need FactHandles
- Insert/Update/Retract operations
- Fact metadata tracking
**Example Use Cases**:
- High-frequency trading systems
- Real-time fraud detection
- Complex expert systems
- Event stream processing
- IoT data processing
```rust
// RETE-UL Engine - High performance pattern matching
let mut engine = IncrementalEngine::new();
GrlReteLoader::load_from_file("rules.grl", &mut engine)?;
// Incremental updates - only affected rules re-evaluated
let handle = engine.insert("Order".to_string(), order);
engine.update(handle, updated_order)?; // 35µs!
```
---
## Migration Path
### From Native → RETE-UL
**What you gain**:
- ✅ 2-16x performance improvement
- ✅ Incremental updates
- ✅ Pattern matching capabilities
- ✅ Drools compatibility
**What you lose** (temporarily):
- ❌ Plugin system integration
- ❌ Action handlers
- ❌ Analytics
- ❌ REST API
**Migration Steps**:
1. Keep existing Native engine for features
2. Use RETE-UL for performance-critical rules
3. Load same GRL files with `GrlReteLoader`
4. Test performance improvements
5. Gradually migrate rules
**Code Example**:
```rust
// Before: Native Engine
let mut native = RustRuleEngine::new(kb);
native.load_rules_from_file("rules.grl")?;
// After: RETE-UL Engine
let mut rete = IncrementalEngine::new();
GrlReteLoader::load_from_file("rules.grl", &mut rete)?;
// Both support same GRL syntax!
```
### Hybrid Approach
Use **both engines** for different purposes:
```rust
// Native for plugin-rich rules
let mut native_engine = RustRuleEngine::new(kb);
native_engine.load_rules_from_file("business_logic.grl")?;
// RETE for performance-critical rules
let mut rete_engine = IncrementalEngine::new();
GrlReteLoader::load_from_file("streaming_rules.grl", &mut rete_engine)?;
// Execute both
native_engine.execute(&facts)?;
rete_engine.fire_all();
```
---
## Architecture Comparison
### Native Engine Architecture
```
GRL File → Parser → AST → Condition Evaluator → Action Executor → Plugins
↓
Pattern Matcher
↓
Basic Agenda
```
**Characteristics**:
- Direct AST evaluation
- No intermediate network
- Plugin integration points
- Action handler system
### RETE-UL Engine Architecture
```
GRL File → GrlReteLoader → ReteUlNode Tree → Incremental Engine → Working Memory
↓ ↓
Alpha/Beta Nodes Advanced Agenda
↓ ↓
Memoization Activation Groups
↓ ↓
Pattern Matcher Priority Queue
```
**Characteristics**:
- RETE-UL algorithm
- Node-based network
- Incremental propagation
- Dependency tracking
---
## Roadmap
### Native Engine Future
- ✅ Plugin system (done)
- ✅ Analytics (done)
- ✅ Workflow engine (done)
- 🔄 RETE integration layer
- 🔄 Hybrid mode
### RETE-UL Engine Future
- ✅ Core RETE-UL (done)
- ✅ GRL loader (done)
- ✅ Pattern matching (done)
- 🔄 Plugin integration
- 🔄 Action handlers
- 🔄 Analytics
- 🔄 Unified API with Native
### Unified API (Future)
Goal: Single API that auto-selects optimal engine:
```rust
// Future: Unified API
let mut engine = UnifiedEngine::new()
.with_mode(EngineMode::Auto) // Auto-select based on rules
.with_plugins(true)
.with_rete(true);
// Automatically uses:
// - Native for plugin-heavy rules
// - RETE for performance-critical rules
engine.load_rules_from_file("rules.grl")?;
engine.execute(&facts)?;
```
---
## Recommendations
### 🎯 Default Choice: **Depends on Your Needs**
**Start with Native Engine if**:
- You're new to rule engines
- Need plugins/action handlers
- Have < 50 rules
- Want simpler API
**Start with RETE-UL if**:
- Performance is critical
- Have > 100 rules
- Need pattern matching
- Migrating from Drools
### 🚀 Production Recommendation
For **production systems**, consider:
1. **Prototype with Native** (faster development)
2. **Benchmark with RETE-UL** (if performance issues)
3. **Use Hybrid** (best of both worlds)
### 📈 Scalability
| < 20 | ✅ | ✅ | Native (simpler) |
| 20-50 | ✅ | ✅✅ | Native or RETE |
| 50-100 | ⚠️ | ✅✅ | RETE preferred |
| 100-500 | ❌ | ✅✅✅ | **RETE only** |
| > 500 | ❌ | ✅✅✅ | **RETE only** |
---
## Conclusion
**Both engines are production-ready** for their respective use cases:
- **Native Engine**: Best for **feature-rich** applications with moderate rule counts
- **RETE-UL Engine**: Best for **high-performance** applications with complex patterns
**No need to choose just one** - use both engines where appropriate!
---
## Quick Decision Tree
```
┌─ Need plugins/action handlers?
│ └─ YES → Native Engine ✅
│ └─ NO → Continue
│
├─ Have > 100 rules?
│ └─ YES → RETE-UL Engine ✅
│ └─ NO → Continue
│
├─ Need pattern matching (variable binding, JOINs)?
│ └─ YES → RETE-UL Engine ✅
│ └─ NO → Continue
│
├─ Need real-time streaming updates?
│ └─ YES → RETE-UL Engine ✅
│ └─ NO → Continue
│
└─ Default → Native Engine ✅ (easier to start)
```
---
**Last Updated**: 2025-10-31
**Version**: rust-rule-engine v0.9.2