kbs 0.1.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +85 -57
- data/docs/advanced/performance.md +109 -76
- data/docs/advanced/testing.md +399 -263
- data/docs/api/blackboard.md +1 -1
- data/docs/api/engine.md +77 -8
- data/docs/api/facts.md +3 -3
- data/docs/api/rules.md +110 -40
- data/docs/architecture/blackboard.md +108 -117
- data/docs/assets/images/fact-rule-relationship.svg +65 -0
- data/docs/assets/images/fact-structure.svg +42 -0
- data/docs/assets/images/inference-cycle.svg +47 -0
- data/docs/assets/images/kb-components.svg +43 -0
- data/docs/assets/images/rule-structure.svg +44 -0
- data/docs/assets/images/trading-signal-network.svg +1 -1
- data/docs/examples/index.md +219 -5
- data/docs/guides/blackboard-memory.md +89 -58
- data/docs/guides/dsl.md +24 -24
- data/docs/guides/getting-started.md +109 -107
- data/docs/guides/writing-rules.md +470 -311
- data/docs/index.md +16 -18
- data/docs/quick-start.md +92 -99
- data/docs/what-is-a-fact.md +694 -0
- data/docs/what-is-a-knowledge-base.md +350 -0
- data/docs/what-is-a-rule.md +833 -0
- data/examples/.gitignore +1 -0
- data/examples/advanced_example_dsl.rb +1 -1
- data/examples/ai_enhanced_kbs_dsl.rb +1 -1
- data/examples/car_diagnostic_dsl.rb +1 -1
- data/examples/concurrent_inference_demo.rb +0 -1
- data/examples/concurrent_inference_demo_dsl.rb +0 -1
- data/examples/csv_trading_system_dsl.rb +1 -1
- data/examples/iot_demo_using_dsl.rb +1 -1
- data/examples/portfolio_rebalancing_system_dsl.rb +1 -1
- data/examples/rule_source_demo.rb +123 -0
- data/examples/stock_trading_advanced_dsl.rb +1 -1
- data/examples/temp_dsl.txt +6214 -5269
- data/examples/timestamped_trading_dsl.rb +1 -1
- data/examples/trading_demo_dsl.rb +1 -1
- data/examples/working_demo_dsl.rb +1 -1
- data/lib/kbs/decompiler.rb +204 -0
- data/lib/kbs/dsl/knowledge_base.rb +100 -1
- data/lib/kbs/dsl.rb +3 -1
- data/lib/kbs/engine.rb +41 -0
- data/lib/kbs/version.rb +1 -1
- data/lib/kbs.rb +14 -12
- data/mkdocs.yml +30 -30
- metadata +15 -10
- data/docs/DOCUMENTATION_STATUS.md +0 -158
- data/docs/examples/expert-systems.md +0 -1031
- data/docs/examples/multi-agent.md +0 -1335
- data/docs/examples/stock-trading.md +0 -488
- data/examples/knowledge_base.db +0 -0
- data/examples/temp.txt +0 -7693
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# What is a Knowledge Base?
|
|
2
|
+
|
|
3
|
+
A **knowledge base** in KBS is a container that holds **facts** (what you know) and **rules** (how to reason about what you know), providing automated inference and decision-making capabilities.
|
|
4
|
+
|
|
5
|
+
## Core Concept
|
|
6
|
+
|
|
7
|
+
Think of a knowledge base as a reasoning system that:
|
|
8
|
+
|
|
9
|
+
1. **Stores facts** - Pieces of information about your domain (e.g., "temperature is 85°F", "stock price is $150")
|
|
10
|
+
2. **Defines rules** - Patterns that trigger actions when facts match (e.g., "IF temperature > 80°F THEN alert")
|
|
11
|
+
3. **Performs inference** - Automatically detects when rules should fire and executes their actions
|
|
12
|
+
4. **Maintains consistency** - Keeps track of what's true and propagates changes efficiently
|
|
13
|
+
|
|
14
|
+
## Anatomy of a Knowledge Base
|
|
15
|
+
|
|
16
|
+
A knowledge base consists of three main components:
|
|
17
|
+
|
|
18
|
+
### 1. Facts (Data)
|
|
19
|
+
|
|
20
|
+
Facts represent knowledge about your domain. Each fact has:
|
|
21
|
+
- **Type** - Category of information (e.g., `:temperature`, `:stock`, `:sensor`)
|
|
22
|
+
- **Attributes** - Key-value pairs describing the fact (e.g., `value: 85, location: "server_room"`)
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
kb.fact :temperature, value: 85, location: "server_room"
|
|
26
|
+
kb.fact :stock, symbol: "AAPL", price: 150.25, volume: 1_200_000
|
|
27
|
+
kb.fact :sensor, id: 42, status: "active"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Rules (Logic)
|
|
31
|
+
|
|
32
|
+
Rules define IF-THEN patterns that trigger actions when facts match conditions:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
rule "high_temperature_alert" do
|
|
36
|
+
# IF these conditions match...
|
|
37
|
+
on :temperature, value: greater_than(80), location: :loc?
|
|
38
|
+
|
|
39
|
+
# THEN execute this action
|
|
40
|
+
perform do |facts, bindings|
|
|
41
|
+
puts "⚠️ High temperature at #{bindings[:loc?]}"
|
|
42
|
+
send_alert(bindings[:loc?])
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Working Memory (State)
|
|
48
|
+
|
|
49
|
+
Working memory holds the current set of active facts. As facts are added/removed, the RETE engine automatically:
|
|
50
|
+
|
|
51
|
+
- Matches facts against rule conditions
|
|
52
|
+
- Tracks partial matches
|
|
53
|
+
- Fires rules when all conditions are satisfied
|
|
54
|
+
|
|
55
|
+
## How Knowledge Bases Work
|
|
56
|
+
|
|
57
|
+
### The Inference Cycle
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
*The inference cycle continuously processes facts through pattern matching and rule firing until no more rules can fire.*
|
|
62
|
+
|
|
63
|
+
### Example Flow
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
kb = KBS.knowledge_base do
|
|
67
|
+
# Define rule
|
|
68
|
+
rule "stock_alert" do
|
|
69
|
+
on :stock, symbol: :sym?, price: greater_than(100)
|
|
70
|
+
perform do |facts, bindings|
|
|
71
|
+
puts "#{bindings[:sym?]} is expensive!"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Add fact (triggers pattern matching)
|
|
76
|
+
fact :stock, symbol: "AAPL", price: 150
|
|
77
|
+
|
|
78
|
+
# Execute inference
|
|
79
|
+
run # → Outputs: "AAPL is expensive!"
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Knowledge Base Types
|
|
84
|
+
|
|
85
|
+
KBS provides two implementations:
|
|
86
|
+
|
|
87
|
+
### 1. In-Memory Knowledge Base
|
|
88
|
+
|
|
89
|
+
**Class**: `KBS::DSL::KnowledgeBase`
|
|
90
|
+
**Created via**: `KBS.knowledge_base do ... end`
|
|
91
|
+
|
|
92
|
+
**Characteristics:**
|
|
93
|
+
|
|
94
|
+
- ✅ Fast - All data in RAM
|
|
95
|
+
- ✅ Simple - No configuration needed
|
|
96
|
+
- ✅ Perfect for: Short-lived processes, prototyping, testing
|
|
97
|
+
- ⚠️ Volatile - Data lost when process ends
|
|
98
|
+
|
|
99
|
+
**Example:**
|
|
100
|
+
```ruby
|
|
101
|
+
kb = KBS.knowledge_base do
|
|
102
|
+
rule "momentum_buy" do
|
|
103
|
+
on :stock, price_change: greater_than(5)
|
|
104
|
+
perform { puts "Strong momentum detected!" }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
fact :stock, symbol: "NVDA", price_change: 7.2
|
|
108
|
+
run
|
|
109
|
+
end
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 2. Blackboard Knowledge Base
|
|
113
|
+
|
|
114
|
+
**Class**: `KBS::Blackboard::Engine`
|
|
115
|
+
**Created via**: `KBS::Blackboard::Engine.new`
|
|
116
|
+
|
|
117
|
+
**Characteristics:**
|
|
118
|
+
|
|
119
|
+
- ✅ Persistent - Facts survive restarts
|
|
120
|
+
- ✅ Auditable - Complete history of changes
|
|
121
|
+
- ✅ Multi-agent - Supports concurrent reasoning
|
|
122
|
+
- ✅ Flexible storage - SQLite, Redis, or Hybrid
|
|
123
|
+
- ⚠️ Slower - I/O overhead
|
|
124
|
+
|
|
125
|
+
**Example:**
|
|
126
|
+
```ruby
|
|
127
|
+
engine = KBS::Blackboard::Engine.new(db_path: 'kb.db')
|
|
128
|
+
|
|
129
|
+
engine.add_rule(rule)
|
|
130
|
+
engine.add_fact(:stock, symbol: "AAPL", price: 150)
|
|
131
|
+
engine.run
|
|
132
|
+
|
|
133
|
+
# Facts persist even after restart
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Key Differences from Databases
|
|
137
|
+
|
|
138
|
+
| Aspect | Knowledge Base | Database |
|
|
139
|
+
|--------|---------------|----------|
|
|
140
|
+
| **Purpose** | Reasoning & inference | Storage & retrieval |
|
|
141
|
+
| **Operation** | Automatic rule firing | Manual queries |
|
|
142
|
+
| **Logic** | Declarative rules | Procedural code |
|
|
143
|
+
| **Updates** | Propagate through network | Independent transactions |
|
|
144
|
+
| **Focus** | "What should happen when..." | "What data exists..." |
|
|
145
|
+
|
|
146
|
+
**Example Comparison:**
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
# Database approach (manual logic)
|
|
150
|
+
stocks = db.query("SELECT * FROM stocks WHERE price_change > 5")
|
|
151
|
+
stocks.each do |stock|
|
|
152
|
+
if stock.volume > 1_000_000
|
|
153
|
+
send_alert(stock.symbol)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Knowledge base approach (declarative rules)
|
|
158
|
+
kb.rule "momentum_alert" do
|
|
159
|
+
on :stock, price_change: greater_than(5), volume: greater_than(1_000_000)
|
|
160
|
+
perform { |facts, b| send_alert(b[:symbol?]) }
|
|
161
|
+
end
|
|
162
|
+
kb.run # Automatically fires for all matching facts
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Common Usage Patterns
|
|
166
|
+
|
|
167
|
+
### 1. Event Processing
|
|
168
|
+
|
|
169
|
+
Monitor streams of events and trigger actions:
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
kb = KBS.knowledge_base do
|
|
173
|
+
rule "sensor_timeout" do
|
|
174
|
+
on :sensor, id: :sid?, expected: true
|
|
175
|
+
without :reading, sensor_id: :sid? # No recent reading
|
|
176
|
+
perform { |facts, b| alert_timeout(b[:sid?]) }
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Events flow in
|
|
180
|
+
fact :sensor, id: 1, expected: true
|
|
181
|
+
fact :reading, sensor_id: 2, value: 42 # Sensor 1 has no reading!
|
|
182
|
+
run
|
|
183
|
+
end
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 2. Decision Support
|
|
187
|
+
|
|
188
|
+
Encode business rules and compliance checks:
|
|
189
|
+
|
|
190
|
+
```ruby
|
|
191
|
+
kb = KBS.knowledge_base do
|
|
192
|
+
rule "approve_loan" do
|
|
193
|
+
on :applicant, credit_score: greater_than(700), income: :income?
|
|
194
|
+
on :loan, amount: :amount?
|
|
195
|
+
perform do |facts, b|
|
|
196
|
+
if b[:income?] > b[:amount?] * 0.3
|
|
197
|
+
approve_loan!
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### 3. Complex Event Detection
|
|
205
|
+
|
|
206
|
+
Find patterns across multiple related facts:
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
kb = KBS.knowledge_base do
|
|
210
|
+
rule "golden_cross" do
|
|
211
|
+
on :ma_50, value: :fast?
|
|
212
|
+
on :ma_200, value: :slow?
|
|
213
|
+
perform do |facts, b|
|
|
214
|
+
if b[:fast?] > b[:slow?]
|
|
215
|
+
puts "Golden cross detected - bullish signal"
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 4. State Machine Management
|
|
223
|
+
|
|
224
|
+
Model workflows and state transitions:
|
|
225
|
+
|
|
226
|
+
```ruby
|
|
227
|
+
kb = KBS.knowledge_base do
|
|
228
|
+
rule "order_to_shipping" do
|
|
229
|
+
on :order, id: :oid?, status: "paid"
|
|
230
|
+
on :inventory, available: greater_than(0)
|
|
231
|
+
|
|
232
|
+
perform do |facts, b|
|
|
233
|
+
order = query(:order, id: b[:oid?]).first
|
|
234
|
+
retract order
|
|
235
|
+
fact :order, id: b[:oid?], status: "shipping"
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Relationship to Other Components
|
|
242
|
+
|
|
243
|
+
A knowledge base integrates several KBS components:
|
|
244
|
+
|
|
245
|
+

|
|
246
|
+
|
|
247
|
+
*A knowledge base is composed of three layers: the DSL provides the user interface, working memory stores facts, and the RETE engine performs pattern matching and inference.*
|
|
248
|
+
|
|
249
|
+
## When to Use a Knowledge Base
|
|
250
|
+
|
|
251
|
+
✅ **Good fit:**
|
|
252
|
+
|
|
253
|
+
- Complex business rules that change frequently
|
|
254
|
+
- Multi-condition pattern matching
|
|
255
|
+
- Event correlation and monitoring
|
|
256
|
+
- Expert systems and decision support
|
|
257
|
+
- Workflow and state machine management
|
|
258
|
+
- Real-time stream processing
|
|
259
|
+
|
|
260
|
+
❌ **Not ideal for:**
|
|
261
|
+
|
|
262
|
+
- Simple CRUD operations
|
|
263
|
+
- Pure data storage without logic
|
|
264
|
+
- High-throughput data pipelines (use specialized tools)
|
|
265
|
+
- When performance is more critical than maintainability
|
|
266
|
+
|
|
267
|
+
## Advanced Concepts
|
|
268
|
+
|
|
269
|
+
### Variable Binding (Join Tests)
|
|
270
|
+
|
|
271
|
+
Variables link facts across multiple conditions:
|
|
272
|
+
|
|
273
|
+
```ruby
|
|
274
|
+
rule "order_fulfillment" do
|
|
275
|
+
on :order, product_id: :pid?, quantity: :qty?
|
|
276
|
+
on :inventory, product_id: :pid?, available: :avail?
|
|
277
|
+
# :pid? creates a join - both facts must have same product_id
|
|
278
|
+
|
|
279
|
+
perform do |facts, b|
|
|
280
|
+
if b[:avail?] >= b[:qty?]
|
|
281
|
+
ship_order(b[:pid?])
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Negation (Absence Testing)
|
|
288
|
+
|
|
289
|
+
Rules can fire based on *missing* facts:
|
|
290
|
+
|
|
291
|
+
```ruby
|
|
292
|
+
rule "missing_config" do
|
|
293
|
+
on :system, initialized: true
|
|
294
|
+
without :config, loaded: true # No config fact exists
|
|
295
|
+
perform { raise "Configuration missing!" }
|
|
296
|
+
end
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Priority Control
|
|
300
|
+
|
|
301
|
+
Control rule firing order (Blackboard only):
|
|
302
|
+
|
|
303
|
+
```ruby
|
|
304
|
+
rule "critical_alert" do
|
|
305
|
+
priority 100 # High priority fires first
|
|
306
|
+
on :alert, level: "critical"
|
|
307
|
+
perform { shutdown_system! }
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
rule "log_alert" do
|
|
311
|
+
priority 1 # Low priority fires last
|
|
312
|
+
on :alert, level: :level?
|
|
313
|
+
perform { |facts, b| log(b[:level?]) }
|
|
314
|
+
end
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Performance Considerations
|
|
318
|
+
|
|
319
|
+
Knowledge bases excel when:
|
|
320
|
+
|
|
321
|
+
- Rules are stable (compiled once)
|
|
322
|
+
- Facts change frequently (efficient incremental matching)
|
|
323
|
+
- Multiple rules share patterns (network node sharing)
|
|
324
|
+
|
|
325
|
+
**Optimization Tips:**
|
|
326
|
+
|
|
327
|
+
1. **Order conditions by selectivity** - Most restrictive first
|
|
328
|
+
2. **Use specific patterns** - `value: 85` better than `value: greater_than(0)`
|
|
329
|
+
3. **Limit negations** - Each negation adds overhead
|
|
330
|
+
4. **Batch fact additions** - Add all facts, then call `run` once
|
|
331
|
+
5. **Use indices** - Blackboard stores support indexed queries
|
|
332
|
+
|
|
333
|
+
## Further Reading
|
|
334
|
+
|
|
335
|
+
- **[DSL Reference](guides/dsl.md)** - Complete guide to defining rules
|
|
336
|
+
- **[RETE Algorithm](architecture/rete-algorithm.md)** - How pattern matching works
|
|
337
|
+
- **[Blackboard Architecture](architecture/blackboard.md)** - Persistent knowledge bases
|
|
338
|
+
- **[Getting Started](quick-start.md)** - Practical examples
|
|
339
|
+
- **[API Documentation](api/index.md)** - Class and method reference
|
|
340
|
+
|
|
341
|
+
## Summary
|
|
342
|
+
|
|
343
|
+
A **knowledge base** is:
|
|
344
|
+
|
|
345
|
+
- A container for **facts** (data) and **rules** (logic)
|
|
346
|
+
- An inference engine that automatically detects when rules should fire
|
|
347
|
+
- A declarative way to express "IF these patterns exist THEN take this action"
|
|
348
|
+
- Available in both **in-memory** (fast, volatile) and **blackboard** (persistent, auditable) implementations
|
|
349
|
+
|
|
350
|
+
Think of it as a database that actively reasons about its contents rather than passively storing them.
|