kbs 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/deploy-github-pages.yml +52 -0
  3. data/CHANGELOG.md +68 -2
  4. data/README.md +291 -362
  5. data/docs/advanced/custom-persistence.md +775 -0
  6. data/docs/advanced/debugging.md +726 -0
  7. data/docs/advanced/index.md +8 -0
  8. data/docs/advanced/performance.md +865 -0
  9. data/docs/advanced/testing.md +827 -0
  10. data/docs/api/blackboard.md +1157 -0
  11. data/docs/api/engine.md +1047 -0
  12. data/docs/api/facts.md +1212 -0
  13. data/docs/api/index.md +12 -0
  14. data/docs/api/rules.md +1104 -0
  15. data/docs/architecture/blackboard.md +544 -0
  16. data/docs/architecture/index.md +277 -0
  17. data/docs/architecture/network-structure.md +343 -0
  18. data/docs/architecture/rete-algorithm.md +737 -0
  19. data/docs/assets/css/custom.css +83 -0
  20. data/docs/assets/images/blackboard-architecture.svg +136 -0
  21. data/docs/assets/images/compiled-network.svg +101 -0
  22. data/docs/assets/images/fact-assertion-flow.svg +117 -0
  23. data/docs/assets/images/fact-rule-relationship.svg +65 -0
  24. data/docs/assets/images/fact-structure.svg +42 -0
  25. data/docs/assets/images/inference-cycle.svg +47 -0
  26. data/docs/assets/images/kb-components.svg +43 -0
  27. data/docs/assets/images/kbs.jpg +0 -0
  28. data/docs/assets/images/pattern-matching-trace.svg +136 -0
  29. data/docs/assets/images/rete-network-layers.svg +96 -0
  30. data/docs/assets/images/rule-structure.svg +44 -0
  31. data/docs/assets/images/system-layers.svg +69 -0
  32. data/docs/assets/images/trading-signal-network.svg +139 -0
  33. data/docs/assets/js/mathjax.js +17 -0
  34. data/docs/examples/index.md +223 -0
  35. data/docs/guides/blackboard-memory.md +589 -0
  36. data/docs/guides/dsl.md +1321 -0
  37. data/docs/guides/facts.md +652 -0
  38. data/docs/guides/getting-started.md +385 -0
  39. data/docs/guides/index.md +23 -0
  40. data/docs/guides/negation.md +529 -0
  41. data/docs/guides/pattern-matching.md +561 -0
  42. data/docs/guides/persistence.md +451 -0
  43. data/docs/guides/variable-binding.md +491 -0
  44. data/docs/guides/writing-rules.md +914 -0
  45. data/docs/index.md +155 -0
  46. data/docs/installation.md +156 -0
  47. data/docs/quick-start.md +221 -0
  48. data/docs/what-is-a-fact.md +694 -0
  49. data/docs/what-is-a-knowledge-base.md +350 -0
  50. data/docs/what-is-a-rule.md +833 -0
  51. data/examples/.gitignore +1 -0
  52. data/examples/README.md +2 -2
  53. data/examples/advanced_example.rb +2 -2
  54. data/examples/advanced_example_dsl.rb +224 -0
  55. data/examples/ai_enhanced_kbs.rb +1 -1
  56. data/examples/ai_enhanced_kbs_dsl.rb +538 -0
  57. data/examples/blackboard_demo_dsl.rb +50 -0
  58. data/examples/car_diagnostic.rb +1 -1
  59. data/examples/car_diagnostic_dsl.rb +54 -0
  60. data/examples/concurrent_inference_demo.rb +5 -6
  61. data/examples/concurrent_inference_demo_dsl.rb +362 -0
  62. data/examples/csv_trading_system.rb +1 -1
  63. data/examples/csv_trading_system_dsl.rb +525 -0
  64. data/examples/iot_demo_using_dsl.rb +1 -1
  65. data/examples/portfolio_rebalancing_system.rb +2 -2
  66. data/examples/portfolio_rebalancing_system_dsl.rb +613 -0
  67. data/examples/redis_trading_demo_dsl.rb +177 -0
  68. data/examples/rule_source_demo.rb +123 -0
  69. data/examples/run_all.rb +50 -0
  70. data/examples/run_all_dsl.rb +49 -0
  71. data/examples/stock_trading_advanced.rb +1 -1
  72. data/examples/stock_trading_advanced_dsl.rb +404 -0
  73. data/examples/temp_dsl.txt +9392 -0
  74. data/examples/timestamped_trading.rb +1 -1
  75. data/examples/timestamped_trading_dsl.rb +258 -0
  76. data/examples/trading_demo.rb +1 -1
  77. data/examples/trading_demo_dsl.rb +322 -0
  78. data/examples/working_demo.rb +1 -1
  79. data/examples/working_demo_dsl.rb +160 -0
  80. data/lib/kbs/blackboard/engine.rb +3 -3
  81. data/lib/kbs/blackboard/fact.rb +1 -1
  82. data/lib/kbs/condition.rb +1 -1
  83. data/lib/kbs/decompiler.rb +204 -0
  84. data/lib/kbs/dsl/knowledge_base.rb +101 -2
  85. data/lib/kbs/dsl/variable.rb +1 -1
  86. data/lib/kbs/dsl.rb +3 -1
  87. data/lib/kbs/{rete_engine.rb → engine.rb} +42 -1
  88. data/lib/kbs/fact.rb +1 -1
  89. data/lib/kbs/version.rb +1 -1
  90. data/lib/kbs.rb +15 -13
  91. data/mkdocs.yml +181 -0
  92. metadata +74 -9
  93. data/examples/stock_trading_system.rb.bak +0 -563
data/docs/index.md ADDED
@@ -0,0 +1,155 @@
1
+ ![KBS - Knowledge-Based System](assets/images/kbs.jpg)
2
+
3
+ # KBS - Knowledge-Based Systems for Ruby
4
+
5
+ **A Ruby implementation of the RETE algorithm for building intelligent, rule-based systems with persistent memory.**
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/kbs.svg)](https://badge.fury.io/rb/kbs)
8
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%202.7-ruby.svg)](https://www.ruby-lang.org/)
9
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
10
+
11
+ ## What is KBS?
12
+
13
+ KBS (Knowledge-Based Systems) is a powerful Ruby gem that brings production rule systems to your applications. At its core is the **RETE algorithm**, a highly optimized pattern-matching engine originally developed for expert systems and now used in modern applications ranging from trading systems to IoT automation.
14
+
15
+ ### Key Features
16
+
17
+ - **🚀 RETE Algorithm**: State-of-the-art pattern matching with unlinking optimization
18
+ - **💾 Persistent Blackboard Memory**: SQLite, Redis, or hybrid storage for facts and audit trails
19
+ - **🎯 Declarative DSL**: Write rules in natural, readable Ruby syntax
20
+ - **🔄 Incremental Matching**: Process only changes, not entire fact sets
21
+ - **🚫 Negation Support**: Express "absence of pattern" conditions naturally
22
+ - **📊 Multi-Agent Systems**: Build collaborative systems with message passing
23
+ - **🔍 Full Auditability**: Complete history of fact changes and rule firings
24
+ - **⚡ High Performance**: Handle millions of facts with sub-millisecond updates
25
+
26
+ ## Quick Example
27
+
28
+ ```ruby
29
+ require 'kbs'
30
+
31
+ # Create a rule-based trading system
32
+ kb = KBS.knowledge_base do
33
+ # Define a rule using the DSL
34
+ rule "buy_signal" do
35
+ # Stock price is below threshold
36
+ on :stock, symbol: :symbol?, price: :price?
37
+ on :threshold, symbol: :symbol?, buy_below: :threshold?
38
+
39
+ # No pending order exists (negation)
40
+ without :order, symbol: :symbol?
41
+
42
+ perform do |facts, bindings|
43
+ if bindings[:price?] < bindings[:threshold?]
44
+ puts "BUY #{bindings[:symbol?]} at #{bindings[:price?]}"
45
+ end
46
+ end
47
+ end
48
+
49
+ # Add facts to working memory
50
+ fact :stock, symbol: "AAPL", price: 145.50
51
+ fact :threshold, symbol: "AAPL", buy_below: 150.0
52
+
53
+ # Fire matching rules
54
+ run # => BUY AAPL at 145.5
55
+ end
56
+ ```
57
+
58
+ ## Why RETE?
59
+
60
+ Traditional rule engines re-evaluate all rules against all facts on every change—extremely inefficient. RETE solves this through:
61
+
62
+ 1. **Network Compilation**: Rules are compiled into a discrimination network that shares common patterns
63
+ 2. **State Preservation**: Partial matches are cached between cycles
64
+ 3. **Incremental Updates**: Only changed facts propagate through the network
65
+ 4. **Unlinking Optimization (RETE)**: Empty nodes automatically disconnect to skip unnecessary work
66
+
67
+ Result: **Near-constant time** per fact change, regardless of rule set size.
68
+
69
+ ## Use Cases
70
+
71
+ ### 💹 Algorithmic Trading
72
+ Real-time market analysis, signal detection, and automated order execution with complex multi-condition rules.
73
+
74
+ ### 🏭 Industrial Automation
75
+ IoT sensor monitoring, predictive maintenance, and automated control systems with temporal reasoning.
76
+
77
+ ### 🏥 Expert Systems
78
+ Medical diagnosis, troubleshooting assistants, and decision support systems with knowledge representation.
79
+
80
+ ### 🤖 Multi-Agent Systems
81
+ Collaborative agents with shared blackboard memory for distributed problem-solving.
82
+
83
+ ### 📧 Business Rules Engines
84
+ Policy enforcement, workflow automation, and compliance checking with auditable decision trails.
85
+
86
+ ## Architecture
87
+
88
+ KBS consists of several integrated components:
89
+
90
+ - **RETE Engine**: Core pattern matching and rule execution
91
+ - **Working Memory**: Transient in-memory fact storage
92
+ - **Blackboard System**: Persistent memory with SQLite/Redis backends
93
+ - **DSL**: Natural language rule definition syntax
94
+ - **Message Queue**: Priority-based inter-agent communication
95
+ - **Audit Log**: Complete history for compliance and debugging
96
+
97
+ See [Architecture Overview](architecture/index.md) for details.
98
+
99
+ ## Getting Started
100
+
101
+ 1. **[Installation](installation.md)** - Add KBS to your project
102
+ 2. **[Quick Start](quick-start.md)** - Build your first rule-based system in 5 minutes
103
+ 3. **[RETE Algorithm](architecture/rete-algorithm.md)** - Deep dive into how it works
104
+ 4. **[Writing Rules](guides/writing-rules.md)** - Master the DSL and pattern matching
105
+ 5. **[Examples](examples/index.md)** - Learn from real-world applications
106
+
107
+ ## Performance
108
+
109
+ KBS is built for production workloads:
110
+
111
+ - **Fact Addition**: O(N) where N = activated nodes (typically << total nodes)
112
+ - **Rule Firing**: O(M) where M = matched tokens
113
+ - **Memory Efficient**: Network sharing reduces redundant storage
114
+ - **Scalable**: Tested with millions of facts, thousands of rules
115
+
116
+ Benchmarks on M2 Max:
117
+ - Add 100,000 facts: ~500ms
118
+ - Match complex 5-condition rule: <1ms per fact
119
+ - Redis backend: 100x faster than SQLite for high-frequency updates
120
+
121
+ ## Project Status
122
+
123
+ KBS is **actively maintained**:
124
+
125
+ - ✅ Core RETE implementation complete
126
+ - ✅ Persistent blackboard with multiple backends
127
+ - ✅ Full DSL support with negation
128
+ - ✅ Comprehensive test coverage
129
+ - ✅ Real-world usage in trading systems
130
+ - 🚧 Additional examples and guides in progress
131
+
132
+ ## Community & Support
133
+
134
+ - **GitHub**: [madbomber/kbs](https://github.com/madbomber/kbs)
135
+ - **RubyGems**: [kbs](https://rubygems.org/gems/kbs)
136
+ - **Issues**: [Report bugs or request features](https://github.com/madbomber/kbs/issues)
137
+ - **Discussions**: [Ask questions](https://github.com/madbomber/kbs/discussions)
138
+
139
+ ## License
140
+
141
+ KBS is released under the [MIT License](https://opensource.org/licenses/MIT).
142
+
143
+ Copyright © 2024 Dewayne VanHoozer
144
+
145
+ ## Acknowledgments
146
+
147
+ The RETE algorithm was invented by Charles Forgy in 1979. This implementation draws inspiration from:
148
+
149
+ - Forgy, C. (1982). "Rete: A Fast Algorithm for the Many Pattern/Many Object Pattern Match Problem"
150
+ - Doorenbos, R. (1995). "Production Matching for Large Learning Systems" (RETE/UL)
151
+ - Modern production rule systems: Drools, Jess, CLIPS
152
+
153
+ ---
154
+
155
+ **Ready to build intelligent systems?** Start with the [Quick Start Guide](quick-start.md)!
@@ -0,0 +1,156 @@
1
+ # Installation
2
+
3
+ ## Requirements
4
+
5
+ - **Ruby**: 2.7 or higher
6
+ - **SQLite3**: For persistent blackboard memory (optional)
7
+ - **Redis**: For high-performance persistence (optional)
8
+
9
+ ## Installing the Gem
10
+
11
+ ### From RubyGems
12
+
13
+ ```bash
14
+ gem install kbs
15
+ ```
16
+
17
+ ### Using Bundler
18
+
19
+ Add to your `Gemfile`:
20
+
21
+ ```ruby
22
+ gem 'kbs'
23
+ ```
24
+
25
+ Then run:
26
+
27
+ ```bash
28
+ bundle install
29
+ ```
30
+
31
+ ### From Source
32
+
33
+ ```bash
34
+ git clone https://github.com/madbomber/kbs.git
35
+ cd kbs
36
+ bundle install
37
+ rake install
38
+ ```
39
+
40
+ ## Optional Dependencies
41
+
42
+ ### SQLite3 (Default Blackboard Backend)
43
+
44
+ ```bash
45
+ gem install sqlite3
46
+ ```
47
+
48
+ Or in your `Gemfile`:
49
+
50
+ ```ruby
51
+ gem 'sqlite3'
52
+ ```
53
+
54
+ ### Redis (High-Performance Backend)
55
+
56
+ Install Redis server:
57
+
58
+ ```bash
59
+ # macOS
60
+ brew install redis
61
+ brew services start redis
62
+
63
+ # Ubuntu/Debian
64
+ sudo apt-get install redis-server
65
+ sudo systemctl start redis
66
+
67
+ # Docker
68
+ docker run -d -p 6379:6379 redis:latest
69
+ ```
70
+
71
+ Install Ruby Redis gem:
72
+
73
+ ```bash
74
+ gem install redis
75
+ ```
76
+
77
+ Or in your `Gemfile`:
78
+
79
+ ```ruby
80
+ gem 'redis'
81
+ ```
82
+
83
+ ## Verification
84
+
85
+ Verify the installation:
86
+
87
+ ```ruby
88
+ require 'kbs'
89
+
90
+ puts "KBS version: #{KBS::VERSION}"
91
+ # => KBS version: 0.1.0
92
+
93
+ # Test basic functionality
94
+ engine = KBS::Engine.new
95
+ engine.add_fact(:test, value: 42)
96
+ puts "✓ KBS is working!"
97
+ ```
98
+
99
+ ## Development Setup
100
+
101
+ For contributing or running tests:
102
+
103
+ ```bash
104
+ git clone https://github.com/madbomber/kbs.git
105
+ cd kbs
106
+ bundle install
107
+
108
+ # Run tests
109
+ bundle exec rake test
110
+
111
+ # Run examples
112
+ bundle exec ruby examples/working_demo.rb
113
+ ```
114
+
115
+ ## Troubleshooting
116
+
117
+ ### SQLite3 Installation Issues
118
+
119
+ On macOS with M1/M2:
120
+
121
+ ```bash
122
+ gem install sqlite3 -- --with-sqlite3-include=/opt/homebrew/opt/sqlite/include \
123
+ --with-sqlite3-lib=/opt/homebrew/opt/sqlite/lib
124
+ ```
125
+
126
+ On Ubuntu/Debian:
127
+
128
+ ```bash
129
+ sudo apt-get install libsqlite3-dev
130
+ gem install sqlite3
131
+ ```
132
+
133
+ ### Redis Connection Issues
134
+
135
+ Check Redis is running:
136
+
137
+ ```bash
138
+ redis-cli ping
139
+ # => PONG
140
+ ```
141
+
142
+ Test connection from Ruby:
143
+
144
+ ```ruby
145
+ require 'redis'
146
+ redis = Redis.new(url: 'redis://localhost:6379/0')
147
+ redis.ping
148
+ # => "PONG"
149
+ ```
150
+
151
+ ## Next Steps
152
+
153
+ - **[Quick Start Guide](quick-start.md)** - Build your first rule-based system
154
+ - **[RETE Algorithm](architecture/rete-algorithm.md)** - Understand the engine
155
+ - **[Writing Rules](guides/writing-rules.md)** - Master the DSL
156
+ - **[Examples](examples/index.md)** - See real-world applications
@@ -0,0 +1,221 @@
1
+ # Quick Start Guide
2
+
3
+ Get up and running with KBS in 5 minutes.
4
+
5
+ ## Your First Rule-Based System
6
+
7
+ Let's build a simple temperature monitoring system that alerts when readings are abnormal.
8
+
9
+ ### Step 1: Create a Knowledge Base and Define Rules
10
+
11
+ ```ruby
12
+ require 'kbs'
13
+
14
+ kb = KBS.knowledge_base do
15
+ # Rule 1: Alert on high temperature
16
+ rule "high_temperature_alert" do
17
+ on :sensor, id: :id?, temp: :temp?
18
+
19
+ perform do |facts, bindings|
20
+ if bindings[:temp?] > 75
21
+ puts "⚠️ HIGH TEMP Alert: Sensor #{bindings[:id?]} at #{bindings[:temp?]}°F"
22
+ end
23
+ end
24
+ end
25
+
26
+ # Rule 2: Alert when cooling system is offline AND temp is high
27
+ rule "critical_condition", priority: 10 do
28
+ on :sensor, id: :id?, temp: :temp?
29
+ on :cooling, id: :id?, status: "offline"
30
+
31
+ perform do |facts, bindings|
32
+ if bindings[:temp?] > 75
33
+ puts "🚨 CRITICAL: Sensor #{bindings[:id?]} at #{bindings[:temp?]}°F with cooling OFFLINE!"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ ```
39
+
40
+ ### Step 2: Add Facts
41
+
42
+ ```ruby
43
+ # Add sensor readings
44
+ kb.fact :sensor, id: "room_101", temp: 72
45
+ kb.fact :sensor, id: "server_rack", temp: 82
46
+ kb.fact :sensor, id: "storage", temp: 65
47
+
48
+ # Add cooling system status
49
+ kb.fact :cooling, id: "server_rack", status: "offline"
50
+ ```
51
+
52
+ ### Step 3: Run Rules
53
+
54
+ ```ruby
55
+ kb.run
56
+ # Output:
57
+ # => ⚠️ HIGH TEMP Alert: Sensor server_rack at 82°F
58
+ # => 🚨 CRITICAL: Sensor server_rack at 82°F with cooling OFFLINE!
59
+ ```
60
+
61
+ ## Understanding What Happened
62
+
63
+ 1. **Knowledge Base Creation**: `KBS.knowledge_base do...end` creates the RETE network and defines rules
64
+ 2. **Rule Definition**: Rules are compiled into the discrimination network using the DSL
65
+ 3. **Fact Assertion**: `kb.fact` adds facts that propagate through the network, creating partial matches
66
+ 4. **Rule Firing**: `kb.run` executes actions for all complete matches
67
+
68
+ The critical rule fires because:
69
+ - Sensor "server_rack" temp (82°F) > 75
70
+ - Cooling system for "server_rack" is offline
71
+ - Both conditions are joined on the same `:id?` variable
72
+
73
+ ## Using Negation
74
+
75
+ Rules can match on the **absence** of facts:
76
+
77
+ ```ruby
78
+ kb = KBS.knowledge_base do
79
+ # Alert when sensor has NO recent reading
80
+ rule "stale_sensor" do
81
+ on :sensor_registered, id: :id?
82
+ # No recent reading exists (negation!)
83
+ without :sensor, id: :id?
84
+
85
+ perform do |facts, bindings|
86
+ puts "⚠️ No reading from sensor #{bindings[:id?]}"
87
+ end
88
+ end
89
+
90
+ # Register sensors
91
+ fact :sensor_registered, id: "room_101"
92
+ fact :sensor_registered, id: "room_102"
93
+
94
+ # Only add reading for room_101
95
+ fact :sensor, id: "room_101", temp: 70
96
+
97
+ run
98
+ # => ⚠️ No reading from sensor room_102
99
+ end
100
+ ```
101
+
102
+ ## Persistent Blackboard Memory
103
+
104
+ For production systems, use persistent storage:
105
+
106
+ ```ruby
107
+ require 'kbs/blackboard'
108
+
109
+ # SQLite backend (default)
110
+ engine = KBS::Blackboard::Engine.new(db_path: 'monitoring.db')
111
+
112
+ kb = KBS.knowledge_base(engine: engine) do
113
+ rule "temperature_monitor" do
114
+ on :sensor, temp: greater_than(75)
115
+ perform do |facts|
116
+ puts "High temp alert!"
117
+ end
118
+ end
119
+
120
+ # Facts survive restarts
121
+ fact :sensor, id: "room_101", temp: 72
122
+
123
+ run
124
+ end
125
+
126
+ # Query historical data
127
+ audit = engine.blackboard.get_history(limit: 10)
128
+ ```
129
+
130
+ ## Next Steps
131
+
132
+ ### Learn the Fundamentals
133
+
134
+ - **[Writing Rules](guides/writing-rules.md)** - Master rule syntax and patterns
135
+ - **[Pattern Matching](guides/pattern-matching.md)** - Understand how facts match conditions
136
+ - **[Variable Binding](guides/variable-binding.md)** - Use variables to join conditions
137
+ - **[Negation](guides/negation.md)** - Express "absence" conditions
138
+
139
+ ### Explore Examples
140
+
141
+ - **[Stock Trading Examples](examples/index.md#stock-trading-systems)** - Build a trading signal system
142
+ - **[Expert System Examples](examples/index.md#expert-systems)** - Diagnostic and decision support
143
+ - **[Blackboard & Multi-Agent Examples](examples/index.md#advanced-features)** - Collaborative problem-solving
144
+
145
+ ### Advanced Topics
146
+
147
+ - **[Blackboard Memory](guides/blackboard-memory.md)** - Persistent storage and audit trails
148
+ - **[Performance Tuning](advanced/performance.md)** - Optimize for production workloads
149
+ - **[Debugging](advanced/debugging.md)** - Trace rule execution and network state
150
+
151
+ ### Understand the Engine
152
+
153
+ - **[RETE Algorithm](architecture/rete-algorithm.md)** - Deep dive into pattern matching
154
+ - **[Network Structure](architecture/network-structure.md)** - How rules are compiled
155
+ - **[API Reference](api/index.md)** - Complete class documentation
156
+
157
+ ## Common Patterns
158
+
159
+ ### Time-Based Rules
160
+
161
+ ```ruby
162
+ kb = KBS.knowledge_base do
163
+ rule "recent_spike" do
164
+ on :reading,
165
+ sensor: :id?,
166
+ temp: :temp?,
167
+ timestamp: ->(ts) { Time.now - ts < 300 } # Within 5 minutes
168
+
169
+ perform do |facts, bindings|
170
+ puts "Recent spike: #{bindings[:temp?]}°F"
171
+ end
172
+ end
173
+ end
174
+ ```
175
+
176
+ ### Threshold Comparison
177
+
178
+ ```ruby
179
+ kb = KBS.knowledge_base do
180
+ rule "above_threshold" do
181
+ on :reading, sensor: :id?, value: :val?
182
+ on :threshold, sensor: :id?, max: :max?
183
+
184
+ perform do |facts, bindings|
185
+ if bindings[:val?] > bindings[:max?]
186
+ puts "Threshold exceeded!"
187
+ end
188
+ end
189
+ end
190
+ end
191
+ ```
192
+
193
+ ### State Machine
194
+
195
+ ```ruby
196
+ kb = KBS.knowledge_base do
197
+ # Transition from "init" to "ready"
198
+ rule "init_to_ready" do
199
+ on :state, current: "init"
200
+ on :sensor, initialized: true
201
+ # No "ready" state exists yet
202
+ without :state, current: "ready"
203
+
204
+ perform do |facts|
205
+ # Note: For state transitions, you'd typically use engine methods
206
+ # This is a simplified example
207
+ puts "Transitioning to ready state"
208
+ end
209
+ end
210
+ end
211
+ ```
212
+
213
+ ## Tips
214
+
215
+ 1. **Use descriptive rule names**: Makes debugging easier
216
+ 2. **Set priorities**: Higher priority rules fire first
217
+ 3. **Call `run()` explicitly**: Rules don't fire automatically
218
+ 4. **Leverage negation**: Express "when X is absent" naturally
219
+ 5. **Profile performance**: Use `advanced/debugging.md` techniques
220
+
221
+ Ready to dive deeper? Check out the [Writing Rules Guide](guides/writing-rules.md)!