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
@@ -0,0 +1,43 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 420">
2
+ <defs>
3
+ <style>
4
+ .outer-box { fill: none; stroke: #60a5fa; stroke-width: 2; }
5
+ .inner-box { fill: #1e293b; stroke: #94a3b8; stroke-width: 1.5; }
6
+ .text { fill: #e2e8f0; font-family: 'Courier New', monospace; font-size: 13px; }
7
+ .title { fill: #60a5fa; font-family: 'Courier New', monospace; font-size: 15px; font-weight: bold; }
8
+ .subtitle { fill: #94a3b8; font-family: 'Courier New', monospace; font-size: 11px; }
9
+ .arrow { stroke: #60a5fa; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
10
+ </style>
11
+ <marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
12
+ <polygon points="0 0, 10 3, 0 6" fill="#60a5fa" />
13
+ </marker>
14
+ </defs>
15
+
16
+ <!-- Outer container -->
17
+ <rect x="20" y="20" width="460" height="380" rx="5" class="outer-box"/>
18
+ <text x="250" y="45" text-anchor="middle" class="title">Knowledge Base</text>
19
+
20
+ <!-- DSL Layer -->
21
+ <rect x="50" y="60" width="400" height="70" rx="5" class="inner-box"/>
22
+ <text x="250" y="80" text-anchor="middle" class="text">DSL Layer (Your Interface)</text>
23
+ <text x="250" y="100" text-anchor="middle" class="subtitle">- rule(), fact(), run()</text>
24
+
25
+ <!-- Arrow DSL to Working Memory -->
26
+ <path d="M 250 130 L 250 155" class="arrow"/>
27
+
28
+ <!-- Working Memory -->
29
+ <rect x="50" y="155" width="400" height="70" rx="5" class="inner-box"/>
30
+ <text x="250" y="175" text-anchor="middle" class="text">Working Memory</text>
31
+ <text x="250" y="195" text-anchor="middle" class="subtitle">- Stores facts</text>
32
+ <text x="250" y="210" text-anchor="middle" class="subtitle">- Notifies observers</text>
33
+
34
+ <!-- Arrow Working Memory to RETE Engine -->
35
+ <path d="M 250 225 L 250 250" class="arrow"/>
36
+
37
+ <!-- RETE Engine -->
38
+ <rect x="50" y="250" width="400" height="90" rx="5" class="inner-box"/>
39
+ <text x="250" y="270" text-anchor="middle" class="text">RETE Engine</text>
40
+ <text x="250" y="290" text-anchor="middle" class="subtitle">- Pattern matching</text>
41
+ <text x="250" y="305" text-anchor="middle" class="subtitle">- Rule compilation</text>
42
+ <text x="250" y="320" text-anchor="middle" class="subtitle">- Inference execution</text>
43
+ </svg>
Binary file
@@ -0,0 +1,136 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 800" style="background: transparent;">
2
+ <defs>
3
+ <style>
4
+ .title { font: bold 18px monospace; fill: #e0e0e0; }
5
+ .phase-title { font: bold 16px monospace; fill: #bb86fc; }
6
+ .step-label { font: bold 13px monospace; fill: #cf6679; }
7
+ .node-label { font: 12px monospace; fill: #e0e0e0; }
8
+ .code-label { font: 11px monospace; fill: #03dac6; }
9
+ .comment { font: italic 11px monospace; fill: #888; }
10
+ .box { fill: #2d2d2d; stroke: #bb86fc; stroke-width: 2; }
11
+ .alpha-box { fill: #3d2d4d; stroke: #bb86fc; stroke-width: 2; }
12
+ .beta-box { fill: #2d3d3d; stroke: #03dac6; stroke-width: 2; }
13
+ .negation-box { fill: #4d2d2d; stroke: #cf6679; stroke-width: 2; }
14
+ .production-box { fill: #2d2d3d; stroke: #ffd700; stroke-width: 2; }
15
+ .flow-arrow { stroke: #cf6679; stroke-width: 2.5; fill: none; marker-end: url(#arrow); }
16
+ .inhibit-arrow { stroke: #ff5555; stroke-width: 2.5; fill: none; marker-end: url(#inhibit); stroke-dasharray: 5,3; }
17
+ </style>
18
+ <marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
19
+ <polygon points="0 0, 10 3, 0 6" fill="#cf6679" />
20
+ </marker>
21
+ <marker id="inhibit" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
22
+ <polygon points="0 0, 10 3, 0 6" fill="#ff5555" />
23
+ </marker>
24
+ </defs>
25
+
26
+ <!-- Title -->
27
+ <text x="500" y="25" class="title" text-anchor="middle">Pattern Matching Trace: Negation Example</text>
28
+ <text x="500" y="45" class="code-label" text-anchor="middle">Rule: Alert when AAPL stock exists but NO alert exists</text>
29
+
30
+ <!-- Network Structure -->
31
+ <text x="30" y="80" class="phase-title">Network Structure:</text>
32
+
33
+ <!-- Root Beta Memory -->
34
+ <rect x="30" y="95" width="140" height="60" class="beta-box" rx="5"/>
35
+ <text x="100" y="120" class="node-label" text-anchor="middle">Root Beta</text>
36
+ <text x="100" y="137" class="code-label" text-anchor="middle">[dummy token]</text>
37
+
38
+ <!-- Alpha 1: stock -->
39
+ <rect x="220" y="95" width="140" height="60" class="alpha-box" rx="5"/>
40
+ <text x="290" y="115" class="node-label" text-anchor="middle">Alpha Memory 1</text>
41
+ <text x="290" y="132" class="code-label" text-anchor="middle">stock(symbol:</text>
42
+ <text x="290" y="147" class="code-label" text-anchor="middle">"AAPL")</text>
43
+
44
+ <!-- Join Node 1 -->
45
+ <rect x="30" y="185" width="140" height="50" class="box" rx="5"/>
46
+ <text x="100" y="215" class="node-label" text-anchor="middle">Join Node 1</text>
47
+
48
+ <!-- Beta Memory 1 -->
49
+ <rect x="30" y="265" width="140" height="60" class="beta-box" rx="5"/>
50
+ <text x="100" y="290" class="node-label" text-anchor="middle">Beta Memory 1</text>
51
+ <text x="100" y="307" class="code-label" text-anchor="middle">[partial matches]</text>
52
+
53
+ <!-- Alpha 2: alert -->
54
+ <rect x="220" y="265" width="140" height="60" class="alpha-box" rx="5"/>
55
+ <text x="290" y="285" class="node-label" text-anchor="middle">Alpha Memory 2</text>
56
+ <text x="290" y="302" class="code-label" text-anchor="middle">alert(symbol:</text>
57
+ <text x="290" y="317" class="code-label" text-anchor="middle">"AAPL")</text>
58
+
59
+ <!-- Negation Node -->
60
+ <rect x="30" y="355" width="140" height="50" class="negation-box" rx="5"/>
61
+ <text x="100" y="385" class="node-label" text-anchor="middle">Negation Node</text>
62
+
63
+ <!-- Production Node -->
64
+ <rect x="30" y="435" width="140" height="50" class="production-box" rx="5"/>
65
+ <text x="100" y="465" class="node-label" text-anchor="middle">Production Node</text>
66
+
67
+ <!-- Network connections -->
68
+ <path d="M 100 155 L 100 185" class="flow-arrow"/>
69
+ <path d="M 290 155 L 150 185" class="flow-arrow"/>
70
+ <path d="M 100 235 L 100 265" class="flow-arrow"/>
71
+ <path d="M 100 325 L 100 355" class="flow-arrow"/>
72
+ <path d="M 290 325 L 150 365" class="flow-arrow"/>
73
+ <path d="M 100 405 L 100 435" class="flow-arrow"/>
74
+
75
+ <!-- Phase 1: Add stock fact -->
76
+ <text x="450" y="80" class="phase-title">Phase 1: Add Stock Fact</text>
77
+ <rect x="450" y="95" width="520" height="140" class="box" rx="5"/>
78
+
79
+ <text x="470" y="115" class="step-label">1. engine.add_fact(:stock, symbol: "AAPL", price: 150)</text>
80
+
81
+ <text x="470" y="138" class="code-label">✓ Matches Alpha Memory 1 → activates</text>
82
+ <text x="470" y="155" class="code-label">✓ Join Node 1: joins stock fact with root token</text>
83
+ <text x="470" y="172" class="code-label">✓ Creates Token(parent: root, fact: stock_fact)</text>
84
+ <text x="470" y="189" class="code-label">✓ Propagates to Beta Memory 1</text>
85
+
86
+ <text x="470" y="210" class="step-label">2. Negation Node.left_activate(token)</text>
87
+ <text x="470" y="227" class="code-label">✓ Checks Alpha Memory 2: NO alert facts found</text>
88
+
89
+ <!-- Success indicator -->
90
+ <rect x="450" y="250" width="520" height="50" class="production-box" rx="5"/>
91
+ <text x="710" y="275" class="step-label" text-anchor="middle">✓ RULE FIRES: "No alert for AAPL!"</text>
92
+ <text x="710" y="292" class="comment" text-anchor="middle">Token propagates to Production Node</text>
93
+
94
+ <!-- Phase 2: Add alert fact -->
95
+ <text x="450" y="330" class="phase-title">Phase 2: Add Alert Fact (Inhibit)</text>
96
+ <rect x="450" y="345" width="520" height="140" class="box" rx="5"/>
97
+
98
+ <text x="470" y="365" class="step-label">3. engine.add_fact(:alert, symbol: "AAPL", level: "warning")</text>
99
+
100
+ <text x="470" y="388" class="code-label">✓ Matches Alpha Memory 2 → activates</text>
101
+ <text x="470" y="405" class="code-label">✓ Negation Node.right_activate(alert_fact)</text>
102
+ <text x="470" y="422" class="code-label">✓ Finds existing token in Beta Memory 1</text>
103
+ <text x="470" y="439" class="code-label">✓ Alert fact now INHIBITS the negation condition</text>
104
+
105
+ <text x="470" y="460" class="step-label">4. Negation Node deactivates token</text>
106
+ <text x="470" y="477" class="code-label">✓ Removes token from Production Node</text>
107
+
108
+ <!-- Blocked indicator -->
109
+ <rect x="450" y="500" width="520" height="50" class="negation-box" rx="5"/>
110
+ <text x="710" y="525" class="step-label" text-anchor="middle">✗ RULE BLOCKED: Alert exists, rule does not fire</text>
111
+ <text x="710" y="542" class="comment" text-anchor="middle">Negation condition no longer satisfied</text>
112
+
113
+ <!-- Phase 3: Remove alert fact -->
114
+ <text x="450" y="580" class="phase-title">Phase 3: Remove Alert Fact (Reactivate)</text>
115
+ <rect x="450" y="595" width="520" height="130" class="box" rx="5"/>
116
+
117
+ <text x="470" y="615" class="step-label">5. engine.remove_fact(alert_fact)</text>
118
+
119
+ <text x="470" y="638" class="code-label">✓ Alpha Memory 2 deactivates alert fact</text>
120
+ <text x="470" y="655" class="code-label">✓ Negation Node.right_deactivate(alert_fact)</text>
121
+ <text x="470" y="672" class="code-label">✓ No more inhibiting facts → condition satisfied again</text>
122
+ <text x="470" y="689" class="code-label">✓ Creates new token and propagates to Production Node</text>
123
+
124
+ <text x="470" y="710" class="step-label">6. engine.run()</text>
125
+
126
+ <!-- Success indicator -->
127
+ <rect x="450" y="740" width="520" height="50" class="production-box" rx="5"/>
128
+ <text x="710" y="765" class="step-label" text-anchor="middle">✓ RULE FIRES AGAIN: "No alert for AAPL!"</text>
129
+ <text x="710" y="782" class="comment" text-anchor="middle">Negation condition satisfied once more</text>
130
+
131
+ <!-- Legend -->
132
+ <text x="30" y="540" class="comment">Purple: Alpha Memories</text>
133
+ <text x="30" y="560" class="comment">Teal: Beta Memories</text>
134
+ <text x="30" y="580" class="comment">Pink: Negation Node</text>
135
+ <text x="30" y="600" class="comment">Gold: Production Node</text>
136
+ </svg>
@@ -0,0 +1,96 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600" style="background: transparent;">
2
+ <defs>
3
+ <style>
4
+ .title { font: bold 18px monospace; fill: #e0e0e0; }
5
+ .layer-label { font: bold 14px monospace; fill: #bb86fc; }
6
+ .node-label { font: 12px monospace; fill: #e0e0e0; }
7
+ .node-box { fill: #2d2d2d; stroke: #bb86fc; stroke-width: 2; }
8
+ .beta-box { fill: #2d2d2d; stroke: #03dac6; stroke-width: 2; }
9
+ .production-box { fill: #2d2d2d; stroke: #cf6679; stroke-width: 2; }
10
+ .connection { stroke: #bb86fc; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
11
+ .beta-connection { stroke: #03dac6; stroke-width: 2; fill: none; marker-end: url(#arrowhead-teal); }
12
+ .section-label { font: bold 16px monospace; fill: #bb86fc; }
13
+ </style>
14
+ <marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
15
+ <polygon points="0 0, 10 3, 0 6" fill="#bb86fc" />
16
+ </marker>
17
+ <marker id="arrowhead-teal" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
18
+ <polygon points="0 0, 10 3, 0 6" fill="#03dac6" />
19
+ </marker>
20
+ </defs>
21
+
22
+ <!-- Title -->
23
+ <text x="400" y="30" class="title" text-anchor="middle">RETE Network Architecture</text>
24
+
25
+ <!-- Layer 1: Alpha Network -->
26
+ <text x="20" y="80" class="section-label">Layer 1: ALPHA NETWORK</text>
27
+ <text x="20" y="100" class="node-label">(Pattern Matching)</text>
28
+
29
+ <!-- Alpha Memory Nodes -->
30
+ <rect x="50" y="120" width="180" height="80" class="node-box" rx="5"/>
31
+ <text x="140" y="145" class="layer-label" text-anchor="middle">Alpha Memory 1</text>
32
+ <text x="140" y="165" class="node-label" text-anchor="middle">Pattern: stock(</text>
33
+ <text x="140" y="182" class="node-label" text-anchor="middle">symbol: "AAPL")</text>
34
+
35
+ <rect x="270" y="120" width="180" height="80" class="node-box" rx="5"/>
36
+ <text x="360" y="145" class="layer-label" text-anchor="middle">Alpha Memory 2</text>
37
+ <text x="360" y="165" class="node-label" text-anchor="middle">Pattern: alert(</text>
38
+ <text x="360" y="182" class="node-label" text-anchor="middle">symbol: "AAPL")</text>
39
+
40
+ <rect x="490" y="120" width="180" height="80" class="node-box" rx="5"/>
41
+ <text x="580" y="145" class="layer-label" text-anchor="middle">Alpha Memory 3</text>
42
+ <text x="580" y="165" class="node-label" text-anchor="middle">Pattern: order(</text>
43
+ <text x="580" y="182" class="node-label" text-anchor="middle">quantity: 100)</text>
44
+
45
+ <!-- Layer 2: Beta Network -->
46
+ <text x="20" y="280" class="section-label">Layer 2: BETA NETWORK</text>
47
+ <text x="20" y="300" class="node-label">(Join Processing)</text>
48
+
49
+ <!-- Root Beta Memory -->
50
+ <rect x="50" y="240" width="140" height="60" class="beta-box" rx="5"/>
51
+ <text x="120" y="262" class="layer-label" text-anchor="middle">Root Beta</text>
52
+ <text x="120" y="282" class="layer-label" text-anchor="middle">Memory</text>
53
+
54
+ <!-- Connection from Root to Join Node 1 -->
55
+ <path d="M 120 300 L 120 330" class="beta-connection"/>
56
+ <path d="M 140 200 L 210 330" class="connection"/>
57
+
58
+ <!-- Join Node 1 -->
59
+ <rect x="160" y="330" width="120" height="60" class="node-box" rx="5"/>
60
+ <text x="220" y="355" class="layer-label" text-anchor="middle">Join Node 1</text>
61
+ <text x="220" y="375" class="node-label" text-anchor="middle">(stock ⋈ root)</text>
62
+
63
+ <!-- Beta Memory 1 -->
64
+ <rect x="170" y="410" width="100" height="50" class="beta-box" rx="5"/>
65
+ <text x="220" y="440" class="layer-label" text-anchor="middle">Beta Mem 1</text>
66
+
67
+ <!-- Connection from Join Node 1 to Beta Memory 1 -->
68
+ <path d="M 220 390 L 220 410" class="beta-connection"/>
69
+
70
+ <!-- Connection from Beta Memory 1 to Join Node 2 -->
71
+ <path d="M 220 460 L 220 490" class="beta-connection"/>
72
+ <path d="M 360 200 L 330 490" class="connection"/>
73
+
74
+ <!-- Join Node 2 -->
75
+ <rect x="270" y="490" width="120" height="60" class="node-box" rx="5"/>
76
+ <text x="330" y="515" class="layer-label" text-anchor="middle">Join Node 2</text>
77
+ <text x="330" y="535" class="node-label" text-anchor="middle">(alert ⋈ β1)</text>
78
+
79
+ <!-- Layer 3: Production Nodes -->
80
+ <text x="480" y="440" class="section-label">Layer 3: PRODUCTION</text>
81
+ <text x="480" y="460" class="node-label">(Rule Firing)</text>
82
+
83
+ <!-- Production Node -->
84
+ <rect x="480" y="490" width="160" height="80" class="production-box" rx="5"/>
85
+ <text x="560" y="515" class="layer-label" text-anchor="middle">Production Node</text>
86
+ <text x="560" y="535" class="node-label" text-anchor="middle">Rule:</text>
87
+ <text x="560" y="552" class="node-label" text-anchor="middle">"alert_action"</text>
88
+
89
+ <!-- Connection from Join Node 2 to Production Node -->
90
+ <path d="M 390 520 L 480 520" class="connection"/>
91
+
92
+ <!-- Legend -->
93
+ <text x="50" y="585" class="node-label">Purple: Alpha/Join Nodes</text>
94
+ <text x="280" y="585" class="node-label">Teal: Beta Memories</text>
95
+ <text x="500" y="585" class="node-label">Pink: Production Nodes</text>
96
+ </svg>
@@ -0,0 +1,44 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 520 380">
2
+ <defs>
3
+ <style>
4
+ .outer-box { fill: none; stroke: #60a5fa; stroke-width: 2; }
5
+ .inner-box { fill: #1e293b; stroke: #94a3b8; stroke-width: 1.5; }
6
+ .text { fill: #e2e8f0; font-family: 'Courier New', monospace; font-size: 13px; }
7
+ .title { fill: #60a5fa; font-family: 'Courier New', monospace; font-size: 16px; font-weight: bold; }
8
+ .subtitle { fill: #94a3b8; font-family: 'Courier New', monospace; font-size: 12px; }
9
+ .check { fill: #22c55e; font-size: 16px; }
10
+ .arrow { stroke: #60a5fa; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
11
+ </style>
12
+ <marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
13
+ <polygon points="0 0, 10 3, 0 6" fill="#60a5fa" />
14
+ </marker>
15
+ </defs>
16
+
17
+ <!-- Main container -->
18
+ <rect x="20" y="20" width="480" height="340" rx="5" class="outer-box"/>
19
+ <text x="260" y="45" text-anchor="middle" class="title">Rule: "high_temperature_alert"</text>
20
+
21
+ <!-- Metadata section -->
22
+ <rect x="40" y="60" width="440" height="80" rx="5" class="inner-box"/>
23
+ <text x="260" y="80" text-anchor="middle" class="title" font-size="14">METADATA</text>
24
+ <text x="80" y="105" class="subtitle">- Name: "high_temperature_alert"</text>
25
+ <text x="80" y="125" class="subtitle">- Description: "Alert when..."</text>
26
+ <text x="350" y="125" class="subtitle">- Priority: 10</text>
27
+
28
+ <!-- Conditions section -->
29
+ <rect x="40" y="155" width="440" height="80" rx="5" class="inner-box"/>
30
+ <text x="260" y="175" text-anchor="middle" class="title" font-size="14">CONDITIONS (IF)</text>
31
+ <text x="80" y="200" class="check">✓</text>
32
+ <text x="100" y="200" class="subtitle">temperature in server_room > 80°F</text>
33
+ <text x="80" y="220" class="check">✓</text>
34
+ <text x="100" y="220" class="subtitle">sensor in server_room is active</text>
35
+
36
+ <!-- Arrow -->
37
+ <path d="M 260 235 L 260 255" class="arrow"/>
38
+ <text x="290" y="250" class="subtitle">(when ALL match)</text>
39
+
40
+ <!-- Action section -->
41
+ <rect x="40" y="255" width="440" height="80" rx="5" class="inner-box"/>
42
+ <text x="260" y="275" text-anchor="middle" class="title" font-size="14">ACTION (THEN)</text>
43
+ <text x="80" y="300" class="subtitle">→ send_alert(...)</text>
44
+ </svg>
@@ -0,0 +1,69 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 700" style="background: transparent;">
2
+ <defs>
3
+ <style>
4
+ .title { font: bold 16px monospace; fill: #e0e0e0; }
5
+ .layer-title { font: bold 14px monospace; fill: #bb86fc; }
6
+ .label { font: 12px monospace; fill: #e0e0e0; }
7
+ .layer-box { fill: #2d2d2d; stroke: #bb86fc; stroke-width: 2; }
8
+ .storage-box { fill: #2d3d3d; stroke: #03dac6; stroke-width: 2; }
9
+ .arrow { stroke: #bb86fc; stroke-width: 3; fill: none; marker-end: url(#arrowhead); }
10
+ </style>
11
+ <marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
12
+ <polygon points="0 0, 10 3, 0 6" fill="#bb86fc" />
13
+ </marker>
14
+ </defs>
15
+
16
+ <!-- Title -->
17
+ <text x="400" y="30" class="title" text-anchor="middle">KBS System Layers</text>
18
+
19
+ <!-- Application Layer -->
20
+ <rect x="100" y="60" width="600" height="70" class="layer-box" rx="8"/>
21
+ <text x="400" y="90" class="layer-title" text-anchor="middle">Application Layer</text>
22
+ <text x="400" y="110" class="label" text-anchor="middle">(Your Rules, Facts, and Business Logic)</text>
23
+
24
+ <!-- Arrow -->
25
+ <path d="M 400 130 L 400 160" class="arrow"/>
26
+
27
+ <!-- DSL Layer -->
28
+ <rect x="100" y="160" width="600" height="70" class="layer-box" rx="8"/>
29
+ <text x="400" y="190" class="layer-title" text-anchor="middle">DSL Layer</text>
30
+ <text x="400" y="210" class="label" text-anchor="middle">(Declarative Rule Definition and Pattern Matching)</text>
31
+
32
+ <!-- Arrow -->
33
+ <path d="M 400 230 L 400 260" class="arrow"/>
34
+
35
+ <!-- RETE Engine -->
36
+ <rect x="100" y="260" width="600" height="70" class="layer-box" rx="8"/>
37
+ <text x="400" y="290" class="layer-title" text-anchor="middle">RETE Engine</text>
38
+ <text x="400" y="310" class="label" text-anchor="middle">(Alpha/Beta Networks, Join Nodes, Productions)</text>
39
+
40
+ <!-- Arrow -->
41
+ <path d="M 400 330 L 400 360" class="arrow"/>
42
+
43
+ <!-- Working Memory Layer -->
44
+ <rect x="100" y="360" width="600" height="70" class="layer-box" rx="8"/>
45
+ <text x="400" y="390" class="layer-title" text-anchor="middle">Working Memory Layer</text>
46
+ <text x="400" y="410" class="label" text-anchor="middle">(Transient or Persistent Fact Storage)</text>
47
+
48
+ <!-- Fork Arrow -->
49
+ <path d="M 400 430 L 400 460" class="arrow"/>
50
+ <path d="M 400 460 L 250 460 L 250 500" class="arrow"/>
51
+ <path d="M 400 460 L 550 460 L 550 500" class="arrow"/>
52
+
53
+ <!-- In-Memory Store -->
54
+ <rect x="120" y="500" width="260" height="120" class="storage-box" rx="8"/>
55
+ <text x="250" y="530" class="layer-title" text-anchor="middle">In-Memory Store</text>
56
+ <text x="250" y="555" class="label" text-anchor="middle">(WorkingMemory)</text>
57
+ <text x="250" y="580" class="label" text-anchor="middle">✓ Fast</text>
58
+ <text x="250" y="600" class="label" text-anchor="middle">✓ Simple</text>
59
+
60
+ <!-- Blackboard System -->
61
+ <rect x="420" y="500" width="260" height="120" class="storage-box" rx="8"/>
62
+ <text x="550" y="530" class="layer-title" text-anchor="middle">Blackboard System</text>
63
+ <text x="550" y="555" class="label" text-anchor="middle">(SQLite/Redis/Hybrid)</text>
64
+ <text x="550" y="580" class="label" text-anchor="middle">✓ Persistent</text>
65
+ <text x="550" y="600" class="label" text-anchor="middle">✓ Auditable</text>
66
+
67
+ <!-- Legend -->
68
+ <text x="400" y="660" class="label" text-anchor="middle" style="font-style: italic; fill: #888;">Fact flow from top to bottom, storage choice at bottom</text>
69
+ </svg>
@@ -0,0 +1,139 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 1100" style="background: transparent;">
2
+ <defs>
3
+ <style>
4
+ .title { font: bold 16px monospace; fill: #e0e0e0; }
5
+ .node-title { font: bold 11px monospace; fill: #bb86fc; }
6
+ .label { font: 10px monospace; fill: #e0e0e0; }
7
+ .detail { font: 9px monospace; fill: #888; font-style: italic; }
8
+ .beta-box { fill: #2d3d4d; stroke: #03dac6; stroke-width: 2; }
9
+ .alpha-box { fill: #3d2d4d; stroke: #bb86fc; stroke-width: 2; }
10
+ .join-box { fill: #2d4d3d; stroke: #4daf50; stroke-width: 2; }
11
+ .neg-box { fill: #4d2d2d; stroke: #cf6679; stroke-width: 2; }
12
+ .prod-box { fill: #4d4d2d; stroke: #ffa500; stroke-width: 2; }
13
+ .arrow { stroke: #03dac6; stroke-width: 2; fill: none; marker-end: url(#arrowhead-beta); }
14
+ .arrow-alpha { stroke: #bb86fc; stroke-width: 2; fill: none; marker-end: url(#arrowhead-alpha); }
15
+ </style>
16
+ <marker id="arrowhead-beta" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
17
+ <polygon points="0 0, 10 3, 0 6" fill="#03dac6" />
18
+ </marker>
19
+ <marker id="arrowhead-alpha" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
20
+ <polygon points="0 0, 10 3, 0 6" fill="#bb86fc" />
21
+ </marker>
22
+ </defs>
23
+
24
+ <!-- Title -->
25
+ <text x="350" y="30" class="title" text-anchor="middle">Trading Signal Network</text>
26
+ <text x="350" y="50" class="detail" text-anchor="middle">3-condition rule with negation and variable bindings</text>
27
+
28
+ <!-- Root Beta Memory -->
29
+ <rect x="200" y="80" width="300" height="60" class="beta-box" rx="5"/>
30
+ <text x="350" y="105" class="node-title" text-anchor="middle">Root Beta Memory</text>
31
+ <text x="350" y="125" class="label" text-anchor="middle">[Token(parent: nil, fact: nil)]</text>
32
+
33
+ <!-- Arrow to JoinNode1 -->
34
+ <path d="M 280 140 L 280 190" class="arrow"/>
35
+
36
+ <!-- AlphaMemory(:stock) on right -->
37
+ <rect x="520" y="150" width="160" height="80" class="alpha-box" rx="5"/>
38
+ <text x="600" y="175" class="node-title" text-anchor="middle">AlphaMemory</text>
39
+ <text x="600" y="195" class="label" text-anchor="middle">:stock</text>
40
+ <text x="600" y="210" class="detail" text-anchor="middle">pattern: {symbol: :sym?,</text>
41
+ <text x="600" y="222" class="detail" text-anchor="middle">price: :price?}</text>
42
+
43
+ <!-- Arrow from alpha to join -->
44
+ <path d="M 520 190 L 370 210" class="arrow-alpha"/>
45
+
46
+ <!-- JoinNode1 -->
47
+ <rect x="200" y="190" width="170" height="50" class="join-box" rx="5"/>
48
+ <text x="285" y="212" class="node-title" text-anchor="middle">JoinNode1</text>
49
+ <text x="285" y="228" class="label" text-anchor="middle">(test: none)</text>
50
+
51
+ <!-- Arrow to BetaMemory1 -->
52
+ <path d="M 285 240 L 285 280" class="arrow"/>
53
+
54
+ <!-- BetaMemory1 -->
55
+ <rect x="170" y="280" width="230" height="60" class="beta-box" rx="5"/>
56
+ <text x="285" y="305" class="node-title" text-anchor="middle">BetaMemory1</text>
57
+ <text x="285" y="325" class="label" text-anchor="middle">[Token(parent: root, fact: stock(...))]</text>
58
+
59
+ <!-- Arrow to JoinNode2 -->
60
+ <path d="M 290 340 L 290 390" class="arrow"/>
61
+
62
+ <!-- AlphaMemory(:threshold) on right -->
63
+ <rect x="520" y="360" width="160" height="80" class="alpha-box" rx="5"/>
64
+ <text x="600" y="385" class="node-title" text-anchor="middle">AlphaMemory</text>
65
+ <text x="600" y="405" class="label" text-anchor="middle">:threshold</text>
66
+ <text x="600" y="420" class="detail" text-anchor="middle">pattern: {symbol: :sym?,</text>
67
+ <text x="600" y="432" class="detail" text-anchor="middle">buy_below: :threshold?}</text>
68
+
69
+ <!-- Arrow from alpha to join -->
70
+ <path d="M 520 400 L 380 420" class="arrow-alpha"/>
71
+
72
+ <!-- JoinNode2 -->
73
+ <rect x="200" y="390" width="180" height="60" class="join-box" rx="5"/>
74
+ <text x="290" y="415" class="node-title" text-anchor="middle">JoinNode2</text>
75
+ <text x="290" y="435" class="label" text-anchor="middle">(test: :sym? equality)</text>
76
+
77
+ <!-- Arrow to BetaMemory2 -->
78
+ <path d="M 290 450 L 290 490" class="arrow"/>
79
+
80
+ <!-- BetaMemory2 -->
81
+ <rect x="130" y="490" width="320" height="60" class="beta-box" rx="5"/>
82
+ <text x="290" y="515" class="node-title" text-anchor="middle">BetaMemory2</text>
83
+ <text x="290" y="535" class="label" text-anchor="middle">[Token(parent: token1, fact: threshold(...))]</text>
84
+
85
+ <!-- Arrow to NegationNode -->
86
+ <path d="M 295 550 L 295 600" class="arrow"/>
87
+
88
+ <!-- AlphaMemory(:order) on right -->
89
+ <rect x="520" y="580" width="160" height="70" class="alpha-box" rx="5"/>
90
+ <text x="600" y="605" class="node-title" text-anchor="middle">AlphaMemory</text>
91
+ <text x="600" y="625" class="label" text-anchor="middle">:order</text>
92
+ <text x="600" y="640" class="detail" text-anchor="middle">pattern: {symbol: :sym?}</text>
93
+
94
+ <!-- Arrow from alpha to negation -->
95
+ <path d="M 520 615 L 410 625" class="arrow-alpha"/>
96
+
97
+ <!-- NegationNode -->
98
+ <rect x="190" y="600" width="220" height="60" class="neg-box" rx="5"/>
99
+ <text x="300" y="625" class="node-title" text-anchor="middle">NegationNode</text>
100
+ <text x="300" y="645" class="label" text-anchor="middle">(test: :sym? equality)</text>
101
+
102
+ <!-- Arrow to BetaMemory3 -->
103
+ <path d="M 300 660 L 300 700" class="arrow"/>
104
+
105
+ <!-- BetaMemory3 -->
106
+ <rect x="150" y="700" width="300" height="60" class="beta-box" rx="5"/>
107
+ <text x="300" y="725" class="node-title" text-anchor="middle">BetaMemory3</text>
108
+ <text x="300" y="745" class="label" text-anchor="middle">[Token(parent: token2, fact: nil)]</text>
109
+
110
+ <!-- Arrow to ProductionNode -->
111
+ <path d="M 300 760 L 300 810" class="arrow"/>
112
+
113
+ <!-- ProductionNode -->
114
+ <rect x="160" y="810" width="280" height="90" class="prod-box" rx="5"/>
115
+ <text x="300" y="840" class="node-title" text-anchor="middle">ProductionNode</text>
116
+ <text x="300" y="860" class="label" text-anchor="middle">(rule: "trading_signal")</text>
117
+ <text x="300" y="880" class="detail" text-anchor="middle">Action: if price &lt; threshold,</text>
118
+ <text x="300" y="892" class="detail" text-anchor="middle">BUY symbol</text>
119
+
120
+ <!-- Legend -->
121
+ <text x="50" y="970" class="label" style="font-size: 11px;">Network Flow:</text>
122
+ <text x="50" y="990" class="detail">1. Dummy token starts at root</text>
123
+ <text x="50" y="1005" class="detail">2. Join with :stock facts → tokens in Beta1</text>
124
+ <text x="50" y="1020" class="detail">3. Join with :threshold (test :sym?) → tokens in Beta2</text>
125
+ <text x="50" y="1035" class="detail">4. Check NO :order exists (test :sym?) → tokens in Beta3</text>
126
+ <text x="50" y="1050" class="detail">5. Tokens reach production node → rule can fire</text>
127
+
128
+ <text x="50" y="1080" class="label" style="font-size: 11px;">Color Key:</text>
129
+ <rect x="150" y="1068" width="30" height="15" class="beta-box" rx="2"/>
130
+ <text x="185" y="1080" class="detail">Beta</text>
131
+ <rect x="230" y="1068" width="30" height="15" class="alpha-box" rx="2"/>
132
+ <text x="265" y="1080" class="detail">Alpha</text>
133
+ <rect x="310" y="1068" width="30" height="15" class="join-box" rx="2"/>
134
+ <text x="345" y="1080" class="detail">Join</text>
135
+ <rect x="390" y="1068" width="30" height="15" class="neg-box" rx="2"/>
136
+ <text x="425" y="1080" class="detail">Negation</text>
137
+ <rect x="490" y="1068" width="30" height="15" class="prod-box" rx="2"/>
138
+ <text x="525" y="1080" class="detail">Production</text>
139
+ </svg>
@@ -0,0 +1,17 @@
1
+ // MathJax configuration for KBS documentation
2
+ window.MathJax = {
3
+ tex: {
4
+ inlineMath: [["\\(", "\\)"]],
5
+ displayMath: [["\\[", "\\]"]],
6
+ processEscapes: true,
7
+ processEnvironments: true
8
+ },
9
+ options: {
10
+ ignoreHtmlClass: ".*|",
11
+ processHtmlClass: "arithmatex"
12
+ }
13
+ };
14
+
15
+ document$.subscribe(() => {
16
+ MathJax.typesetPromise()
17
+ })