kbs 0.1.0 → 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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +85 -57
  3. data/docs/advanced/performance.md +109 -76
  4. data/docs/advanced/testing.md +399 -263
  5. data/docs/api/blackboard.md +1 -1
  6. data/docs/api/engine.md +77 -8
  7. data/docs/api/facts.md +3 -3
  8. data/docs/api/rules.md +110 -40
  9. data/docs/architecture/blackboard.md +108 -117
  10. data/docs/assets/images/fact-rule-relationship.svg +65 -0
  11. data/docs/assets/images/fact-structure.svg +42 -0
  12. data/docs/assets/images/inference-cycle.svg +47 -0
  13. data/docs/assets/images/kb-components.svg +43 -0
  14. data/docs/assets/images/rule-structure.svg +44 -0
  15. data/docs/assets/images/trading-signal-network.svg +1 -1
  16. data/docs/examples/index.md +219 -5
  17. data/docs/guides/blackboard-memory.md +89 -58
  18. data/docs/guides/dsl.md +24 -24
  19. data/docs/guides/getting-started.md +109 -107
  20. data/docs/guides/writing-rules.md +470 -311
  21. data/docs/index.md +16 -18
  22. data/docs/quick-start.md +92 -99
  23. data/docs/what-is-a-fact.md +694 -0
  24. data/docs/what-is-a-knowledge-base.md +350 -0
  25. data/docs/what-is-a-rule.md +833 -0
  26. data/examples/.gitignore +1 -0
  27. data/examples/advanced_example_dsl.rb +1 -1
  28. data/examples/ai_enhanced_kbs_dsl.rb +1 -1
  29. data/examples/car_diagnostic_dsl.rb +1 -1
  30. data/examples/concurrent_inference_demo.rb +0 -1
  31. data/examples/concurrent_inference_demo_dsl.rb +0 -1
  32. data/examples/csv_trading_system_dsl.rb +1 -1
  33. data/examples/iot_demo_using_dsl.rb +1 -1
  34. data/examples/portfolio_rebalancing_system_dsl.rb +1 -1
  35. data/examples/rule_source_demo.rb +123 -0
  36. data/examples/stock_trading_advanced_dsl.rb +1 -1
  37. data/examples/temp_dsl.txt +6214 -5269
  38. data/examples/timestamped_trading_dsl.rb +1 -1
  39. data/examples/trading_demo_dsl.rb +1 -1
  40. data/examples/working_demo_dsl.rb +1 -1
  41. data/lib/kbs/decompiler.rb +204 -0
  42. data/lib/kbs/dsl/knowledge_base.rb +100 -1
  43. data/lib/kbs/dsl.rb +3 -1
  44. data/lib/kbs/engine.rb +41 -0
  45. data/lib/kbs/version.rb +1 -1
  46. data/lib/kbs.rb +14 -12
  47. data/mkdocs.yml +30 -30
  48. metadata +15 -10
  49. data/docs/DOCUMENTATION_STATUS.md +0 -158
  50. data/docs/examples/expert-systems.md +0 -1031
  51. data/docs/examples/multi-agent.md +0 -1335
  52. data/docs/examples/stock-trading.md +0 -488
  53. data/examples/knowledge_base.db +0 -0
  54. data/examples/temp.txt +0 -7693
@@ -1,9 +1,223 @@
1
1
  # Examples
2
2
 
3
- Real-world applications of KBS.
3
+ Real-world applications demonstrating KBS capabilities. Each example is available in both low-level API and DSL versions.
4
4
 
5
- - **[Stock Trading](stock-trading.md)** - Algorithmic trading system
6
- - **[Expert Systems](expert-systems.md)** - Diagnostic and decision support
7
- - **[Multi-Agent Systems](multi-agent.md)** - Collaborative problem-solving
5
+ ## Getting Started
8
6
 
9
- See also: [Quick Start Guide](../quick-start.md)
7
+ ### Working Demo
8
+ **Files:** [`working_demo.rb`](https://github.com/madbomber/kbs/blob/main/examples/working_demo.rb) | [`working_demo_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/working_demo_dsl.rb)
9
+
10
+ Simple trading system demonstrating the basics of KBS with momentum signals, volume alerts, and price movement detection. Perfect starting point for learning KBS fundamentals.
11
+
12
+ **Features:**
13
+
14
+ - Basic rule definition and pattern matching
15
+ - Stock momentum detection
16
+ - High volume alerts
17
+ - Price change notifications
18
+
19
+ ### Advanced Example
20
+ **Files:** [`advanced_example.rb`](https://github.com/madbomber/kbs/blob/main/examples/advanced_example.rb) | [`advanced_example_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/advanced_example_dsl.rb)
21
+
22
+ More complex patterns including multi-condition rules, variable bindings, and negation patterns. Shows advanced RETE features and rule chaining.
23
+
24
+ **Features:**
25
+
26
+ - Multi-condition pattern matching
27
+ - Variable binding and join tests
28
+ - Negation (NOT conditions)
29
+ - Rule priorities
30
+
31
+ ## Stock Trading Systems
32
+
33
+ ### Basic Trading Demo
34
+ **Files:** [`trading_demo.rb`](https://github.com/madbomber/kbs/blob/main/examples/trading_demo.rb) | [`trading_demo_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/trading_demo_dsl.rb)
35
+
36
+ Foundational trading signals including momentum detection and volume analysis.
37
+
38
+ **Features:**
39
+
40
+ - Buy/sell signal generation
41
+ - Volume-based alerts
42
+ - Price momentum tracking
43
+
44
+ ### Advanced Stock Trading
45
+ **Files:** [`stock_trading_advanced.rb`](https://github.com/madbomber/kbs/blob/main/examples/stock_trading_advanced.rb) | [`stock_trading_advanced_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/stock_trading_advanced_dsl.rb)
46
+
47
+ Sophisticated trading system with technical indicators, portfolio management, and risk controls.
48
+
49
+ **Features:**
50
+
51
+ - Golden cross detection (MA crossover)
52
+ - Momentum breakout signals
53
+ - RSI indicators
54
+ - Volume ratio analysis
55
+ - Risk management rules
56
+
57
+ ### CSV Trading System
58
+ **Files:** [`csv_trading_system.rb`](https://github.com/madbomber/kbs/blob/main/examples/csv_trading_system.rb) | [`csv_trading_system_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/csv_trading_system_dsl.rb)
59
+
60
+ Complete trading system that processes historical stock data from CSV files, calculates technical indicators, and generates trading signals.
61
+
62
+ **Features:**
63
+
64
+ - CSV data ingestion
65
+ - Moving average calculations
66
+ - Technical indicator generation
67
+ - Backtesting support
68
+ - Portfolio tracking
69
+
70
+ ### Portfolio Rebalancing System
71
+ **Files:** [`portfolio_rebalancing_system.rb`](https://github.com/madbomber/kbs/blob/main/examples/portfolio_rebalancing_system.rb) | [`portfolio_rebalancing_system_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/portfolio_rebalancing_system_dsl.rb)
72
+
73
+ Sector-based portfolio management with automatic rebalancing, drift detection, and underperformer replacement.
74
+
75
+ **Features:**
76
+
77
+ - Target allocation management
78
+ - Sector drift detection
79
+ - Automatic rebalancing rules
80
+ - Underperformer identification
81
+ - Position replacement logic
82
+
83
+ ### Timestamped Trading
84
+ **Files:** [`timestamped_trading.rb`](https://github.com/madbomber/kbs/blob/main/examples/timestamped_trading.rb) | [`timestamped_trading_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/timestamped_trading_dsl.rb)
85
+
86
+ Time-aware trading system demonstrating temporal reasoning and time-based rule activation.
87
+
88
+ **Features:**
89
+
90
+ - Time-based rule conditions
91
+ - Stale data detection
92
+ - Market hours awareness
93
+ - Temporal pattern matching
94
+
95
+ ### Redis High-Frequency Trading
96
+ **Files:** [`redis_trading_demo.rb`](https://github.com/madbomber/kbs/blob/main/examples/redis_trading_demo.rb) | [`redis_trading_demo_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/redis_trading_demo_dsl.rb)
97
+
98
+ High-performance trading system using Redis for fast in-memory fact storage, ideal for low-latency trading applications.
99
+
100
+ **Features:**
101
+
102
+ - Redis-backed persistence
103
+ - High-frequency market data processing
104
+ - Fast fact lookup and updates
105
+ - Distributed knowledge base support
106
+
107
+ ## Expert Systems
108
+
109
+ ### Car Diagnostic System
110
+ **Files:** [`car_diagnostic.rb`](https://github.com/madbomber/kbs/blob/main/examples/car_diagnostic.rb) | [`car_diagnostic_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/car_diagnostic_dsl.rb)
111
+
112
+ Expert system for diagnosing car problems based on symptoms. Demonstrates classic expert system pattern with IF-THEN diagnostic rules.
113
+
114
+ **Features:**
115
+
116
+ - Symptom-based diagnosis
117
+ - Multiple diagnostic rules
118
+ - Recommendation generation
119
+ - Negation for ruling out conditions
120
+
121
+ ### IoT Monitoring System
122
+ **File:** [`iot_demo_using_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/iot_demo_using_dsl.rb)
123
+
124
+ IoT sensor monitoring system with temperature alerts, inventory management, and customer VIP upgrades. Shows real-world DSL usage patterns.
125
+
126
+ **Features:**
127
+
128
+ - Sensor monitoring
129
+ - Temperature threshold alerts
130
+ - Inventory tracking
131
+ - Multi-domain rules (IoT, inventory, CRM)
132
+
133
+ ## AI-Enhanced Systems
134
+
135
+ ### AI-Enhanced Knowledge Base
136
+ **Files:** [`ai_enhanced_kbs.rb`](https://github.com/madbomber/kbs/blob/main/examples/ai_enhanced_kbs.rb) | [`ai_enhanced_kbs_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/ai_enhanced_kbs_dsl.rb)
137
+
138
+ Integration with Large Language Models (LLMs) for AI-powered sentiment analysis, market insights, and intelligent trading decisions.
139
+
140
+ **Features:**
141
+
142
+ - LLM integration via `ruby_llm` gem
143
+ - News sentiment analysis
144
+ - AI-powered market insights
145
+ - MCP agent support
146
+ - Hybrid AI + rule-based reasoning
147
+
148
+ **Requirements:**
149
+
150
+ - Ollama running locally (or compatible LLM provider)
151
+ - `ruby_llm` and `ruby_llm-mcp` gems
152
+
153
+ ## Advanced Features
154
+
155
+ ### Blackboard Memory System
156
+ **Files:** [`blackboard_demo.rb`](https://github.com/madbomber/kbs/blob/main/examples/blackboard_demo.rb) | [`blackboard_demo_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/blackboard_demo_dsl.rb)
157
+
158
+ Demonstrates persistent blackboard architecture with SQLite storage, message queues, audit logs, and fact history tracking.
159
+
160
+ **Features:**
161
+ +
162
+ - SQLite-backed persistence
163
+ - UUID-based fact tracking
164
+ - Message queue (priority-based)
165
+ - Complete audit trail
166
+ - Fact update history
167
+ - Database statistics
168
+
169
+ ### Concurrent Inference Patterns
170
+ **Files:** [`concurrent_inference_demo.rb`](https://github.com/madbomber/kbs/blob/main/examples/concurrent_inference_demo.rb) | [`concurrent_inference_demo_dsl.rb`](https://github.com/madbomber/kbs/blob/main/examples/concurrent_inference_demo_dsl.rb)
171
+
172
+ Advanced patterns for multi-threaded knowledge bases including reactive engines, background inference, and event-driven architectures.
173
+
174
+ **Features:**
175
+
176
+ - Auto-inference mode (reactive)
177
+ - Background thread inference
178
+ - Event-driven processing
179
+ - Thread-safe fact addition
180
+ - Continuous reasoning loops
181
+
182
+ ## Running Examples
183
+
184
+ ### Run Individual Examples
185
+
186
+ Each example is executable from the command line:
187
+
188
+ ```bash
189
+ # Run a specific example
190
+ ruby examples/working_demo.rb
191
+
192
+ # Run DSL version
193
+ ruby examples/working_demo_dsl.rb
194
+
195
+ # Run AI-enhanced example (requires Ollama)
196
+ OLLAMA_MODEL=gpt-oss:latest ruby examples/ai_enhanced_kbs.rb
197
+ ```
198
+
199
+ ### Run All Examples
200
+
201
+ Run all examples at once:
202
+
203
+ ```bash
204
+ # Run all low-level API examples
205
+ ruby examples/run_all.rb
206
+
207
+ # Run all DSL examples
208
+ ruby examples/run_all_dsl.rb
209
+ ```
210
+
211
+ ## Example Organization
212
+
213
+ - **Low-level API examples** (`*.rb`) - Direct use of `KBS::Engine`, `KBS::Rule`, `KBS::Condition`
214
+ - **DSL examples** (`*_dsl.rb`) - Using `KBS.knowledge_base` and declarative syntax
215
+ - Both versions demonstrate the same functionality with different APIs
216
+
217
+ ## Further Reading
218
+
219
+ - **[Quick Start Guide](../quick-start.md)** - Step-by-step tutorial
220
+ - **[DSL Reference](../guides/dsl.md)** - Complete DSL syntax guide
221
+ - **[Writing Rules](../guides/writing-rules.md)** - Best practices for rule design
222
+ - **[Blackboard Memory](../guides/blackboard-memory.md)** - Persistence guide
223
+ - **[API Reference](../api/index.md)** - Complete API documentation
@@ -24,27 +24,34 @@ require 'kbs'
24
24
  # With SQLite (default)
25
25
  engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
26
26
 
27
- # Facts persist across restarts
28
- engine.add_fact(:sensor, { id: "bedroom", temp: 28 })
29
- engine.close
27
+ kb = KBS.knowledge_base(engine: engine) do
28
+ # Facts persist across restarts
29
+ fact :sensor, id: "bedroom", temp: 28
30
+ end
31
+
32
+ kb.close
30
33
 
31
34
  # Next run
32
35
  engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
33
- puts engine.facts.size # => 1
36
+ kb = KBS.knowledge_base(engine: engine)
37
+ puts kb.engine.facts.size # => 1
34
38
  ```
35
39
 
36
40
  ### Blackboard vs Regular Engine
37
41
 
38
42
  ```ruby
39
43
  # Regular engine (transient)
40
- regular = KBS::Engine.new
41
- regular.add_fact(:foo, { bar: 1 })
44
+ kb_regular = KBS.knowledge_base do
45
+ fact :foo, bar: 1
46
+ end
42
47
  # Lost on exit
43
48
 
44
49
  # Blackboard engine (persistent)
45
- blackboard = KBS::Blackboard::Engine.new(db_path: 'kb.db')
46
- blackboard.add_fact(:foo, { bar: 1 })
47
- blackboard.close
50
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
51
+ kb_blackboard = KBS.knowledge_base(engine: engine) do
52
+ fact :foo, bar: 1
53
+ end
54
+ kb_blackboard.close
48
55
  # Persisted to database
49
56
  ```
50
57
 
@@ -53,14 +60,16 @@ blackboard.close
53
60
  ### Fact Lifecycle
54
61
 
55
62
  ```ruby
63
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
64
+
56
65
  # Create fact
57
- fact = engine.add_fact(:sensor, { id: "bedroom", temp: 28 })
66
+ fact = engine.add_fact(:sensor, id: "bedroom", temp: 28)
58
67
 
59
68
  # Fact has UUID
60
69
  puts fact.id # => "550e8400-e29b-41d4-a716-446655440000"
61
70
 
62
71
  # Update fact
63
- engine.update_fact(fact.id, { temp: 30 })
72
+ engine.update_fact(fact.id, temp: 30)
64
73
 
65
74
  # Query fact history
66
75
  history = engine.fact_history(fact.id)
@@ -77,7 +86,8 @@ engine.delete_fact(fact.id)
77
86
  Blackboard facts support the same interface as regular facts:
78
87
 
79
88
  ```ruby
80
- fact = engine.add_fact(:stock, { symbol: "AAPL", price: 150 })
89
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
90
+ fact = engine.add_fact(:stock, symbol: "AAPL", price: 150)
81
91
 
82
92
  # Access
83
93
  fact.type # => :stock
@@ -97,6 +107,8 @@ The blackboard includes a priority-based message queue for agent communication:
97
107
  ### Sending Messages
98
108
 
99
109
  ```ruby
110
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
111
+
100
112
  # Add message to queue
101
113
  engine.send_message(:alerts, "High temperature detected", priority: 10)
102
114
  engine.send_message(:alerts, "Critical failure", priority: 100) # Higher priority
@@ -139,11 +151,13 @@ Blackboard automatically logs all changes:
139
151
  ### Fact Audit Log
140
152
 
141
153
  ```ruby
154
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
155
+
142
156
  # Add fact
143
- fact = engine.add_fact(:order, { id: 1, status: "pending" })
157
+ fact = engine.add_fact(:order, id: 1, status: "pending")
144
158
 
145
159
  # Update fact
146
- engine.update_fact(fact.id, { status: "processing" })
160
+ engine.update_fact(fact.id, status: "processing")
147
161
 
148
162
  # Delete fact
149
163
  engine.delete_fact(fact.id)
@@ -173,9 +187,15 @@ engine = KBS::Blackboard::Engine.new(
173
187
  audit_rules: true
174
188
  )
175
189
 
176
- # Add and run rules
177
- engine.add_rule(my_rule)
178
- engine.run
190
+ kb = KBS.knowledge_base(engine: engine) do
191
+ rule "my_rule" do
192
+ on :trigger, {}
193
+ perform { }
194
+ end
195
+
196
+ fact :trigger, {}
197
+ run
198
+ end
179
199
 
180
200
  # Query rule firings
181
201
  firings = engine.rule_firings(rule_name: "my_rule")
@@ -202,12 +222,12 @@ class Agent
202
222
  @engine.facts.select { |f| relevant?(f) }
203
223
  end
204
224
 
205
- def decide
225
+ def decide(observations)
206
226
  # Apply agent's expertise
207
227
  # Return action or nil
208
228
  end
209
229
 
210
- def act
230
+ def act(action)
211
231
  # Write facts to blackboard
212
232
  # Send messages to other agents
213
233
  end
@@ -277,7 +297,7 @@ class ExecutionAgent < Agent
277
297
  execute_order(order)
278
298
 
279
299
  # Update fact
280
- @engine.update_fact(order.id, { executed: true })
300
+ @engine.update_fact(order.id, executed: true)
281
301
 
282
302
  # Notify
283
303
  @engine.send_message(:notifications, "Order executed", priority: 10)
@@ -306,19 +326,21 @@ end
306
326
  Blackboard supports ACID transactions (SQLite backend):
307
327
 
308
328
  ```ruby
329
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
330
+
309
331
  # Transaction succeeds
310
332
  engine.transaction do
311
- engine.add_fact(:account, { id: 1, balance: 1000 })
312
- engine.add_fact(:account, { id: 2, balance: 500 })
333
+ engine.add_fact(:account, id: 1, balance: 1000)
334
+ engine.add_fact(:account, id: 2, balance: 500)
313
335
  end
314
336
  # Both facts committed
315
337
 
316
338
  # Transaction fails
317
339
  begin
318
340
  engine.transaction do
319
- engine.add_fact(:account, { id: 3, balance: 100 })
341
+ engine.add_fact(:account, id: 3, balance: 100)
320
342
  raise "Error!"
321
- engine.add_fact(:account, { id: 4, balance: 200 }) # Never reached
343
+ engine.add_fact(:account, id: 4, balance: 200) # Never reached
322
344
  end
323
345
  rescue => e
324
346
  puts "Transaction rolled back"
@@ -344,10 +366,11 @@ class FactObserver
344
366
  end
345
367
  end
346
368
 
369
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
347
370
  observer = FactObserver.new
348
371
  engine.memory.add_observer(observer)
349
372
 
350
- engine.add_fact(:sensor, { temp: 28 })
373
+ engine.add_fact(:sensor, temp: 28)
351
374
  # Output: Fact added: sensor - {:temp=>28}
352
375
  ```
353
376
 
@@ -402,11 +425,11 @@ engine = KBS::Blackboard::Engine.new(store: store)
402
425
  ```ruby
403
426
  # Good: Store fact UUID
404
427
  order_id = engine.add_fact(:order, { ... }).id
405
- engine.add_fact(:payment, { order_id: order_id })
428
+ engine.add_fact(:payment, order_id: order_id)
406
429
 
407
430
  # Bad: Use attribute as reference
408
- engine.add_fact(:order, { id: 1 })
409
- engine.add_fact(:payment, { order_id: 1 }) # Fragile
431
+ engine.add_fact(:order, id: 1)
432
+ engine.add_fact(:payment, order_id: 1) # Fragile
410
433
  ```
411
434
 
412
435
  ### 2. Namespace Facts by Agent
@@ -438,17 +461,19 @@ end
438
461
 
439
462
  ```ruby
440
463
  # Remove stale data
441
- KBS::Rule.new("cleanup_old_facts", priority: 1) do |r|
442
- r.conditions = [
443
- KBS::Condition.new(:market_data, {
444
- timestamp: :time?
445
- }, predicate: lambda { |f|
446
- (Time.now - f[:timestamp]) > 3600 # 1 hour old
447
- })
448
- ]
464
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
449
465
 
450
- r.action = lambda do |facts, bindings|
451
- engine.remove_fact(facts[0])
466
+ kb = KBS.knowledge_base(engine: engine) do
467
+ rule "cleanup_old_facts", priority: 1 do
468
+ on :market_data,
469
+ timestamp: :time?,
470
+ predicate: lambda { |f|
471
+ (Time.now - f[:timestamp]) > 3600 # 1 hour old
472
+ }
473
+
474
+ perform do |facts, bindings|
475
+ engine.remove_fact(facts[0])
476
+ end
452
477
  end
453
478
  end
454
479
  ```
@@ -456,15 +481,17 @@ end
456
481
  ### 5. Use Transactions for Multi-Fact Updates
457
482
 
458
483
  ```ruby
484
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
485
+
459
486
  # Good: Atomic updates
460
487
  engine.transaction do
461
- engine.update_fact(account1_id, { balance: new_balance1 })
462
- engine.update_fact(account2_id, { balance: new_balance2 })
488
+ engine.update_fact(account1_id, balance: new_balance1)
489
+ engine.update_fact(account2_id, balance: new_balance2)
463
490
  end
464
491
 
465
492
  # Bad: Separate updates (not atomic)
466
- engine.update_fact(account1_id, { balance: new_balance1 })
467
- engine.update_fact(account2_id, { balance: new_balance2 })
493
+ engine.update_fact(account1_id, balance: new_balance1)
494
+ engine.update_fact(account2_id, balance: new_balance2)
468
495
  ```
469
496
 
470
497
  ## Common Patterns
@@ -472,16 +499,18 @@ engine.update_fact(account2_id, { balance: new_balance2 })
472
499
  ### Leader Election
473
500
 
474
501
  ```ruby
475
- # Agent attempts to become leader
476
- KBS::Rule.new("become_leader") do |r|
477
- r.conditions = [
478
- KBS::Condition.new(:agent, { name: :name? }),
479
- KBS::Condition.new(:leader, {}, negated: true)
480
- ]
481
-
482
- r.action = lambda do |facts, bindings|
483
- engine.add_fact(:leader, { name: bindings[:name?] })
484
- puts "#{bindings[:name?]} is now leader"
502
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
503
+
504
+ kb = KBS.knowledge_base(engine: engine) do
505
+ # Agent attempts to become leader
506
+ rule "become_leader" do
507
+ on :agent, name: :name?
508
+ without :leader, {}
509
+
510
+ perform do |facts, bindings|
511
+ fact :leader, name: bindings[:name?]
512
+ puts "#{bindings[:name?]} is now leader"
513
+ end
485
514
  end
486
515
  end
487
516
  ```
@@ -490,7 +519,7 @@ end
490
519
 
491
520
  ```ruby
492
521
  # Acquire lock
493
- def acquire_lock(resource_id)
522
+ def acquire_lock(engine, resource_id, agent_id)
494
523
  engine.transaction do
495
524
  lock = engine.facts.find { |f|
496
525
  f.type == :lock && f[:resource_id] == resource_id
@@ -499,7 +528,7 @@ def acquire_lock(resource_id)
499
528
  if lock.nil?
500
529
  engine.add_fact(:lock, {
501
530
  resource_id: resource_id,
502
- owner: @agent_id,
531
+ owner: agent_id,
503
532
  acquired_at: Time.now
504
533
  })
505
534
  true
@@ -510,11 +539,11 @@ def acquire_lock(resource_id)
510
539
  end
511
540
 
512
541
  # Release lock
513
- def release_lock(resource_id)
542
+ def release_lock(engine, resource_id, agent_id)
514
543
  lock = engine.facts.find { |f|
515
544
  f.type == :lock &&
516
545
  f[:resource_id] == resource_id &&
517
- f[:owner] == @agent_id
546
+ f[:owner] == agent_id
518
547
  }
519
548
 
520
549
  engine.remove_fact(lock) if lock
@@ -524,6 +553,8 @@ end
524
553
  ### Event Sourcing
525
554
 
526
555
  ```ruby
556
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
557
+
527
558
  # Store events as facts
528
559
  engine.add_fact(:event, {
529
560
  type: "order_created",
@@ -533,7 +564,7 @@ engine.add_fact(:event, {
533
564
  })
534
565
 
535
566
  # Reconstruct state from events
536
- def rebuild_order(order_id)
567
+ def rebuild_order(engine, order_id)
537
568
  events = engine.facts
538
569
  .select { |f| f.type == :event && f[:aggregate_id] == order_id }
539
570
  .sort_by { |f| f[:timestamp] }
@@ -550,7 +581,7 @@ end
550
581
 
551
582
  - **[Persistence](persistence.md)** - Storage backend options
552
583
  - **[Architecture](../architecture/blackboard.md)** - Blackboard implementation details
553
- - **[Multi-Agent Example](../examples/multi-agent.md)** - Complete multi-agent system
584
+ - **[Blackboard Examples](../examples/index.md#advanced-features)** - Complete multi-agent and blackboard systems
554
585
  - **[API Reference](../api/blackboard.md)** - Complete blackboard API
555
586
 
556
587
  ---