kbs 0.0.1 → 0.1.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 (86) 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 +235 -334
  5. data/docs/DOCUMENTATION_STATUS.md +158 -0
  6. data/docs/advanced/custom-persistence.md +775 -0
  7. data/docs/advanced/debugging.md +726 -0
  8. data/docs/advanced/index.md +8 -0
  9. data/docs/advanced/performance.md +832 -0
  10. data/docs/advanced/testing.md +691 -0
  11. data/docs/api/blackboard.md +1157 -0
  12. data/docs/api/engine.md +978 -0
  13. data/docs/api/facts.md +1212 -0
  14. data/docs/api/index.md +12 -0
  15. data/docs/api/rules.md +1034 -0
  16. data/docs/architecture/blackboard.md +553 -0
  17. data/docs/architecture/index.md +277 -0
  18. data/docs/architecture/network-structure.md +343 -0
  19. data/docs/architecture/rete-algorithm.md +737 -0
  20. data/docs/assets/css/custom.css +83 -0
  21. data/docs/assets/images/blackboard-architecture.svg +136 -0
  22. data/docs/assets/images/compiled-network.svg +101 -0
  23. data/docs/assets/images/fact-assertion-flow.svg +117 -0
  24. data/docs/assets/images/kbs.jpg +0 -0
  25. data/docs/assets/images/pattern-matching-trace.svg +136 -0
  26. data/docs/assets/images/rete-network-layers.svg +96 -0
  27. data/docs/assets/images/system-layers.svg +69 -0
  28. data/docs/assets/images/trading-signal-network.svg +139 -0
  29. data/docs/assets/js/mathjax.js +17 -0
  30. data/docs/examples/expert-systems.md +1031 -0
  31. data/docs/examples/index.md +9 -0
  32. data/docs/examples/multi-agent.md +1335 -0
  33. data/docs/examples/stock-trading.md +488 -0
  34. data/docs/guides/blackboard-memory.md +558 -0
  35. data/docs/guides/dsl.md +1321 -0
  36. data/docs/guides/facts.md +652 -0
  37. data/docs/guides/getting-started.md +383 -0
  38. data/docs/guides/index.md +23 -0
  39. data/docs/guides/negation.md +529 -0
  40. data/docs/guides/pattern-matching.md +561 -0
  41. data/docs/guides/persistence.md +451 -0
  42. data/docs/guides/variable-binding.md +491 -0
  43. data/docs/guides/writing-rules.md +755 -0
  44. data/docs/index.md +157 -0
  45. data/docs/installation.md +156 -0
  46. data/docs/quick-start.md +228 -0
  47. data/examples/README.md +2 -2
  48. data/examples/advanced_example.rb +2 -2
  49. data/examples/advanced_example_dsl.rb +224 -0
  50. data/examples/ai_enhanced_kbs.rb +1 -1
  51. data/examples/ai_enhanced_kbs_dsl.rb +538 -0
  52. data/examples/blackboard_demo_dsl.rb +50 -0
  53. data/examples/car_diagnostic.rb +1 -1
  54. data/examples/car_diagnostic_dsl.rb +54 -0
  55. data/examples/concurrent_inference_demo.rb +5 -5
  56. data/examples/concurrent_inference_demo_dsl.rb +363 -0
  57. data/examples/csv_trading_system.rb +1 -1
  58. data/examples/csv_trading_system_dsl.rb +525 -0
  59. data/examples/knowledge_base.db +0 -0
  60. data/examples/portfolio_rebalancing_system.rb +2 -2
  61. data/examples/portfolio_rebalancing_system_dsl.rb +613 -0
  62. data/examples/redis_trading_demo_dsl.rb +177 -0
  63. data/examples/run_all.rb +50 -0
  64. data/examples/run_all_dsl.rb +49 -0
  65. data/examples/stock_trading_advanced.rb +1 -1
  66. data/examples/stock_trading_advanced_dsl.rb +404 -0
  67. data/examples/temp.txt +7693 -0
  68. data/examples/temp_dsl.txt +8447 -0
  69. data/examples/timestamped_trading.rb +1 -1
  70. data/examples/timestamped_trading_dsl.rb +258 -0
  71. data/examples/trading_demo.rb +1 -1
  72. data/examples/trading_demo_dsl.rb +322 -0
  73. data/examples/working_demo.rb +1 -1
  74. data/examples/working_demo_dsl.rb +160 -0
  75. data/lib/kbs/blackboard/engine.rb +3 -3
  76. data/lib/kbs/blackboard/fact.rb +1 -1
  77. data/lib/kbs/condition.rb +1 -1
  78. data/lib/kbs/dsl/knowledge_base.rb +1 -1
  79. data/lib/kbs/dsl/variable.rb +1 -1
  80. data/lib/kbs/{rete_engine.rb → engine.rb} +1 -1
  81. data/lib/kbs/fact.rb +1 -1
  82. data/lib/kbs/version.rb +1 -1
  83. data/lib/kbs.rb +2 -2
  84. data/mkdocs.yml +181 -0
  85. metadata +66 -6
  86. data/examples/stock_trading_system.rb.bak +0 -563
@@ -0,0 +1,451 @@
1
+ # Persistence Options
2
+
3
+ KBS offers multiple storage backends for persistent facts. This guide helps you choose and configure the right storage for your use case.
4
+
5
+ ## Storage Backends
6
+
7
+ ### 1. No Persistence (Default)
8
+
9
+ Transient in-memory facts using `KBS::Engine`:
10
+
11
+ ```ruby
12
+ engine = KBS::Engine.new
13
+
14
+ # Facts exist only in memory
15
+ engine.add_fact(:sensor, { temp: 28 })
16
+
17
+ # Lost on exit
18
+ ```
19
+
20
+ **When to use:**
21
+ - Prototyping
22
+ - Short-lived processes
23
+ - Pure computation (no state retention needed)
24
+ - Testing
25
+
26
+ **Pros:**
27
+ - ✅ Fastest (no I/O)
28
+ - ✅ Zero configuration
29
+ - ✅ Simple
30
+
31
+ **Cons:**
32
+ - ❌ No persistence
33
+ - ❌ Lost on crash
34
+ - ❌ No audit trail
35
+
36
+ ### 2. SQLite (Default Persistent)
37
+
38
+ Embedded database using `KBS::Blackboard::Engine`:
39
+
40
+ ```ruby
41
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
42
+
43
+ engine.add_fact(:sensor, { temp: 28 })
44
+ engine.close
45
+
46
+ # Next run
47
+ engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
48
+ puts engine.facts.size # => 1 (persisted)
49
+ ```
50
+
51
+ **When to use:**
52
+ - Single-process applications
53
+ - Moderate fact volumes (< 1M facts)
54
+ - ACID transaction requirements
55
+ - Complete audit trails
56
+ - No external dependencies
57
+
58
+ **Pros:**
59
+ - ✅ Embedded (no server)
60
+ - ✅ ACID guarantees
61
+ - ✅ Durable
62
+ - ✅ Full audit trail
63
+ - ✅ SQL queries available
64
+
65
+ **Cons:**
66
+ - ❌ Slower than Redis
67
+ - ❌ Single writer
68
+ - ❌ Not distributed
69
+
70
+ **Configuration:**
71
+
72
+ ```ruby
73
+ engine = KBS::Blackboard::Engine.new(
74
+ db_path: 'kb.db', # Database file path
75
+ journal_mode: 'WAL' # WAL mode for better concurrency
76
+ )
77
+ ```
78
+
79
+ ### 3. Redis (High Performance)
80
+
81
+ In-memory data structure store:
82
+
83
+ ```ruby
84
+ require 'kbs/blackboard/persistence/redis_store'
85
+
86
+ store = KBS::Blackboard::Persistence::RedisStore.new(
87
+ url: 'redis://localhost:6379/0'
88
+ )
89
+
90
+ engine = KBS::Blackboard::Engine.new(store: store)
91
+ ```
92
+
93
+ **When to use:**
94
+ - High-frequency updates (> 1000 writes/sec)
95
+ - Real-time systems (trading, IoT)
96
+ - Distributed systems (multiple engines)
97
+ - Large fact volumes
98
+ - Speed is critical
99
+
100
+ **Pros:**
101
+ - ✅ 100x faster than SQLite
102
+ - ✅ Distributed (multiple engines share data)
103
+ - ✅ Perfect for real-time
104
+ - ✅ Scalable
105
+
106
+ **Cons:**
107
+ - ❌ Requires Redis server
108
+ - ❌ Volatile by default (enable RDB/AOF for persistence)
109
+ - ❌ No ACID across keys
110
+ - ❌ Less audit trail
111
+
112
+ **Configuration:**
113
+
114
+ ```ruby
115
+ store = KBS::Blackboard::Persistence::RedisStore.new(
116
+ url: 'redis://localhost:6379/0',
117
+ namespace: 'kbs', # Key prefix
118
+ ttl: 86400 # Expire facts after 24h (optional)
119
+ )
120
+ ```
121
+
122
+ **Redis Persistence Options:**
123
+
124
+ ```bash
125
+ # In redis.conf:
126
+
127
+ # RDB: Point-in-time snapshots
128
+ save 900 1 # Save after 900s if 1 key changed
129
+ save 300 10 # Save after 300s if 10 keys changed
130
+
131
+ # AOF: Append-only file (durability)
132
+ appendonly yes
133
+ appendfsync everysec # Sync to disk every second
134
+ ```
135
+
136
+ ### 4. Hybrid (Best of Both)
137
+
138
+ Combines Redis (speed) with SQLite (durability):
139
+
140
+ ```ruby
141
+ require 'kbs/blackboard/persistence/hybrid_store'
142
+
143
+ store = KBS::Blackboard::Persistence::HybridStore.new(
144
+ redis_url: 'redis://localhost:6379/0',
145
+ db_path: 'audit.db'
146
+ )
147
+
148
+ engine = KBS::Blackboard::Engine.new(store: store)
149
+ ```
150
+
151
+ **How it works:**
152
+ - **Facts**: Stored in Redis (fast access)
153
+ - **Audit log**: Written to SQLite (durable history)
154
+ - **Messages**: Redis sorted sets (fast priority queue)
155
+
156
+ **When to use:**
157
+ - Production systems requiring both speed and auditing
158
+ - Regulatory compliance (need audit trail)
159
+ - High-frequency updates with history requirements
160
+ - Distributed systems needing accountability
161
+
162
+ **Pros:**
163
+ - ✅ Fast fact access (Redis)
164
+ - ✅ Durable audit trail (SQLite)
165
+ - ✅ Best of both worlds
166
+ - ✅ Can reconstruct from audit log
167
+
168
+ **Cons:**
169
+ - ❌ Requires both Redis and SQLite
170
+ - ❌ More complex setup
171
+ - ❌ Slightly slower writes (dual write)
172
+
173
+ **Configuration:**
174
+
175
+ ```ruby
176
+ store = KBS::Blackboard::Persistence::HybridStore.new(
177
+ redis_url: 'redis://localhost:6379/0',
178
+ db_path: 'audit.db',
179
+ audit_facts: true, # Log fact changes to SQLite
180
+ audit_rules: true # Log rule firings to SQLite
181
+ )
182
+ ```
183
+
184
+ ## Choosing a Backend
185
+
186
+ ### Decision Tree
187
+
188
+ ```
189
+ Need persistence?
190
+ ├─ No → KBS::Engine (default)
191
+ └─ Yes
192
+
193
+ ├─ Need speed > 1000 ops/sec?
194
+ │ ├─ Yes
195
+ │ │ ├─ Need audit trail?
196
+ │ │ │ ├─ Yes → Hybrid Store
197
+ │ │ │ └─ No → Redis Store
198
+ │ │ └─ No → Redis Store
199
+ │ │
200
+ │ └─ No
201
+ │ ├─ Need distributed access?
202
+ │ │ └─ Yes → Redis Store
203
+ │ └─ No → SQLite Store
204
+
205
+ └─ Single machine, moderate load?
206
+ └─ SQLite Store
207
+ ```
208
+
209
+ ### By Use Case
210
+
211
+ **IoT / Real-Time Sensors:**
212
+ ```ruby
213
+ # High frequency, need speed
214
+ store = KBS::Blackboard::Persistence::RedisStore.new(
215
+ url: 'redis://localhost:6379/0'
216
+ )
217
+ ```
218
+
219
+ **Trading Systems:**
220
+ ```ruby
221
+ # Speed + audit trail for compliance
222
+ store = KBS::Blackboard::Persistence::HybridStore.new(
223
+ redis_url: 'redis://localhost:6379/0',
224
+ db_path: 'trading_audit.db'
225
+ )
226
+ ```
227
+
228
+ **Expert Systems:**
229
+ ```ruby
230
+ # Moderate load, need durability
231
+ engine = KBS::Blackboard::Engine.new(db_path: 'expert.db')
232
+ ```
233
+
234
+ **Development / Testing:**
235
+ ```ruby
236
+ # No persistence needed
237
+ engine = KBS::Engine.new
238
+ ```
239
+
240
+ ## Migration Between Backends
241
+
242
+ ### SQLite → Redis
243
+
244
+ ```ruby
245
+ # 1. Load from SQLite
246
+ sqlite_engine = KBS::Blackboard::Engine.new(db_path: 'old.db')
247
+ facts = sqlite_engine.facts
248
+
249
+ # 2. Save to Redis
250
+ redis_store = KBS::Blackboard::Persistence::RedisStore.new(
251
+ url: 'redis://localhost:6379/0'
252
+ )
253
+ redis_engine = KBS::Blackboard::Engine.new(store: redis_store)
254
+
255
+ facts.each do |fact|
256
+ redis_engine.add_fact(fact.type, fact.attributes)
257
+ end
258
+ ```
259
+
260
+ ### Redis → SQLite
261
+
262
+ ```ruby
263
+ # 1. Load from Redis
264
+ redis_store = KBS::Blackboard::Persistence::RedisStore.new(
265
+ url: 'redis://localhost:6379/0'
266
+ )
267
+ redis_engine = KBS::Blackboard::Engine.new(store: redis_store)
268
+ facts = redis_engine.facts
269
+
270
+ # 2. Save to SQLite
271
+ sqlite_engine = KBS::Blackboard::Engine.new(db_path: 'new.db')
272
+
273
+ facts.each do |fact|
274
+ sqlite_engine.add_fact(fact.type, fact.attributes)
275
+ end
276
+
277
+ sqlite_engine.close
278
+ ```
279
+
280
+ ## Performance Comparison
281
+
282
+ ### Write Performance
283
+
284
+ ```ruby
285
+ require 'benchmark'
286
+
287
+ # SQLite
288
+ sqlite_engine = KBS::Blackboard::Engine.new(db_path: 'perf.db')
289
+ Benchmark.bm do |x|
290
+ x.report("SQLite writes:") do
291
+ 10_000.times { |i| sqlite_engine.add_fact(:test, { value: i }) }
292
+ end
293
+ end
294
+ # ~5,000 ops/sec
295
+
296
+ # Redis
297
+ redis_store = KBS::Blackboard::Persistence::RedisStore.new(
298
+ url: 'redis://localhost:6379/0'
299
+ )
300
+ redis_engine = KBS::Blackboard::Engine.new(store: redis_store)
301
+ Benchmark.bm do |x|
302
+ x.report("Redis writes:") do
303
+ 10_000.times { |i| redis_engine.add_fact(:test, { value: i }) }
304
+ end
305
+ end
306
+ # ~50,000 ops/sec (10x faster)
307
+ ```
308
+
309
+ ### Read Performance
310
+
311
+ ```ruby
312
+ # SQLite
313
+ Benchmark.bm do |x|
314
+ x.report("SQLite reads:") do
315
+ 10_000.times { sqlite_engine.facts }
316
+ end
317
+ end
318
+ # ~10,000 ops/sec
319
+
320
+ # Redis
321
+ Benchmark.bm do |x|
322
+ x.report("Redis reads:") do
323
+ 10_000.times { redis_engine.facts }
324
+ end
325
+ end
326
+ # ~100,000 ops/sec (10x faster)
327
+ ```
328
+
329
+ ## Custom Persistence
330
+
331
+ Implement your own backend by subclassing `KBS::Blackboard::Persistence::Store`:
332
+
333
+ ```ruby
334
+ class PostgresStore < KBS::Blackboard::Persistence::Store
335
+ def save_fact(fact)
336
+ # Insert into PostgreSQL
337
+ end
338
+
339
+ def load_facts(type = nil)
340
+ # Query from PostgreSQL
341
+ end
342
+
343
+ def delete_fact(id)
344
+ # Delete from PostgreSQL
345
+ end
346
+
347
+ def save_message(topic, message, priority)
348
+ # Store message
349
+ end
350
+
351
+ def pop_message(topic)
352
+ # Retrieve highest priority message
353
+ end
354
+
355
+ def log_fact_change(operation, fact)
356
+ # Audit logging
357
+ end
358
+
359
+ def fact_history(fact_id)
360
+ # Get change history
361
+ end
362
+ end
363
+
364
+ # Use custom store
365
+ store = PostgresStore.new(connection_string: "...")
366
+ engine = KBS::Blackboard::Engine.new(store: store)
367
+ ```
368
+
369
+ See [Custom Persistence](../advanced/custom-persistence.md) for details.
370
+
371
+ ## Configuration Best Practices
372
+
373
+ ### SQLite
374
+
375
+ ```ruby
376
+ # Enable WAL mode for better concurrency
377
+ engine = KBS::Blackboard::Engine.new(
378
+ db_path: 'kb.db',
379
+ journal_mode: 'WAL',
380
+ synchronous: 'NORMAL', # Trade some durability for speed
381
+ cache_size: -64000 # 64MB cache
382
+ )
383
+ ```
384
+
385
+ ### Redis
386
+
387
+ ```ruby
388
+ # Connection pooling for high concurrency
389
+ store = KBS::Blackboard::Persistence::RedisStore.new(
390
+ url: 'redis://localhost:6379/0',
391
+ pool_size: 10, # Connection pool size
392
+ pool_timeout: 5 # Timeout in seconds
393
+ )
394
+ ```
395
+
396
+ ### Hybrid
397
+
398
+ ```ruby
399
+ # Balance between speed and durability
400
+ store = KBS::Blackboard::Persistence::HybridStore.new(
401
+ redis_url: 'redis://localhost:6379/0',
402
+ db_path: 'audit.db',
403
+ batch_audit_writes: true, # Batch SQLite writes
404
+ audit_batch_size: 100 # Flush every 100 changes
405
+ )
406
+ ```
407
+
408
+ ## Troubleshooting
409
+
410
+ ### SQLite Database Locked
411
+
412
+ ```ruby
413
+ # Increase busy timeout
414
+ engine = KBS::Blackboard::Engine.new(
415
+ db_path: 'kb.db',
416
+ busy_timeout: 5000 # Wait up to 5 seconds
417
+ )
418
+ ```
419
+
420
+ ### Redis Connection Issues
421
+
422
+ ```ruby
423
+ # Enable retry logic
424
+ store = KBS::Blackboard::Persistence::RedisStore.new(
425
+ url: 'redis://localhost:6379/0',
426
+ reconnect_attempts: 3,
427
+ reconnect_delay: 1.0
428
+ )
429
+ ```
430
+
431
+ ### Hybrid Sync Issues
432
+
433
+ ```ruby
434
+ # Force synchronous audit writes
435
+ store = KBS::Blackboard::Persistence::HybridStore.new(
436
+ redis_url: 'redis://localhost:6379/0',
437
+ db_path: 'audit.db',
438
+ sync_audit_writes: true # Don't batch, write immediately
439
+ )
440
+ ```
441
+
442
+ ## Next Steps
443
+
444
+ - **[Blackboard Memory](blackboard-memory.md)** - Using persistent blackboard
445
+ - **[Custom Persistence](../advanced/custom-persistence.md)** - Implementing custom stores
446
+ - **[Performance Guide](../advanced/performance.md)** - Optimizing storage performance
447
+ - **[API Reference](../api/blackboard.md)** - Complete blackboard API
448
+
449
+ ---
450
+
451
+ *Choose your backend based on speed, durability, and distribution requirements.*