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,83 @@
1
+ /* Custom CSS for KBS Documentation */
2
+
3
+ /* SVG image styling */
4
+ img[src$=".svg"] {
5
+ max-width: 100%;
6
+ height: auto;
7
+ margin: 2em 0;
8
+ border-radius: 8px;
9
+ background: transparent;
10
+ }
11
+
12
+ /* Code block enhancements */
13
+ .highlight pre {
14
+ border-radius: 8px;
15
+ padding: 1em;
16
+ }
17
+
18
+ /* Improve table styling */
19
+ table {
20
+ border-collapse: collapse;
21
+ width: 100%;
22
+ margin: 1.5em 0;
23
+ }
24
+
25
+ table th {
26
+ background-color: rgba(187, 134, 252, 0.2);
27
+ font-weight: bold;
28
+ }
29
+
30
+ table td, table th {
31
+ padding: 0.75em;
32
+ border: 1px solid rgba(255, 255, 255, 0.1);
33
+ }
34
+
35
+ table tr:hover {
36
+ background-color: rgba(187, 134, 252, 0.1);
37
+ }
38
+
39
+ /* Admonition customization */
40
+ .admonition {
41
+ border-radius: 8px;
42
+ margin: 1.5em 0;
43
+ }
44
+
45
+ /* Implementation reference links */
46
+ strong + a[href*="lib/kbs"] {
47
+ font-family: monospace;
48
+ font-size: 0.9em;
49
+ color: #03dac6;
50
+ }
51
+
52
+ /* Enhance inline code */
53
+ code {
54
+ background-color: rgba(187, 134, 252, 0.15);
55
+ padding: 0.2em 0.4em;
56
+ border-radius: 4px;
57
+ font-size: 0.9em;
58
+ }
59
+
60
+ /* Navigation improvements */
61
+ .md-nav__title {
62
+ font-weight: bold;
63
+ }
64
+
65
+ /* Search result highlighting */
66
+ .md-search-result__article--document {
67
+ border-left: 3px solid #bb86fc;
68
+ }
69
+
70
+ /* Smooth scrolling for anchor links */
71
+ html {
72
+ scroll-behavior: smooth;
73
+ }
74
+
75
+ /* Figure captions for SVG diagrams */
76
+ em {
77
+ display: block;
78
+ text-align: center;
79
+ font-style: italic;
80
+ color: rgba(255, 255, 255, 0.6);
81
+ margin-top: -1.5em;
82
+ margin-bottom: 1.5em;
83
+ }
@@ -0,0 +1,136 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 700" style="background: transparent;">
2
+ <defs>
3
+ <style>
4
+ .title { font: bold 18px monospace; fill: #e0e0e0; }
5
+ .component-title { font: bold 14px monospace; fill: #bb86fc; }
6
+ .label { font: 12px monospace; fill: #e0e0e0; }
7
+ .code { font: 11px monospace; fill: #03dac6; }
8
+ .comment { font: italic 10px monospace; fill: #888; }
9
+ .box { fill: #2d2d2d; stroke: #bb86fc; stroke-width: 2; }
10
+ .core-box { fill: #3d2d4d; stroke: #bb86fc; stroke-width: 3; }
11
+ .storage-box { fill: #2d3d3d; stroke: #03dac6; stroke-width: 2; }
12
+ .agent-box { fill: #4d3d2d; stroke: #cf6679; stroke-width: 2; }
13
+ .arrow { stroke: #bb86fc; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
14
+ .data-arrow { stroke: #03dac6; stroke-width: 2; fill: none; marker-end: url(#data-arrowhead); stroke-dasharray: 5,3; }
15
+ </style>
16
+ <marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
17
+ <polygon points="0 0, 10 3, 0 6" fill="#bb86fc" />
18
+ </marker>
19
+ <marker id="data-arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
20
+ <polygon points="0 0, 10 3, 0 6" fill="#03dac6" />
21
+ </marker>
22
+ </defs>
23
+
24
+ <!-- Title -->
25
+ <text x="500" y="30" class="title" text-anchor="middle">Blackboard Architecture</text>
26
+
27
+ <!-- Central Blackboard Memory -->
28
+ <rect x="350" y="70" width="300" height="200" class="core-box" rx="8"/>
29
+ <text x="500" y="95" class="component-title" text-anchor="middle">Blackboard Memory</text>
30
+ <text x="500" y="115" class="comment" text-anchor="middle">(Central Shared Workspace)</text>
31
+
32
+ <!-- Memory components -->
33
+ <text x="370" y="140" class="label">• Facts (persistent)</text>
34
+ <text x="370" y="160" class="label">• Message Queue</text>
35
+ <text x="370" y="180" class="label">• Audit Log</text>
36
+ <text x="370" y="200" class="label">• Observer notifications</text>
37
+ <text x="370" y="220" class="label">• Transaction support</text>
38
+ <text x="370" y="240" class="code">UUID-based fact tracking</text>
39
+
40
+ <!-- Agents (top) -->
41
+ <text x="500" y="315" class="component-title" text-anchor="middle">Agents / Knowledge Sources</text>
42
+
43
+ <!-- Agent 1 -->
44
+ <rect x="50" y="330" width="200" height="100" class="agent-box" rx="5"/>
45
+ <text x="150" y="355" class="component-title" text-anchor="middle">Trading Agent</text>
46
+ <text x="150" y="380" class="code" text-anchor="middle">Reads: stock prices</text>
47
+ <text x="150" y="397" class="code" text-anchor="middle">Writes: buy/sell orders</text>
48
+ <text x="150" y="414" class="code" text-anchor="middle">Priority: 10</text>
49
+
50
+ <!-- Agent 2 -->
51
+ <rect x="280" y="330" width="200" height="100" class="agent-box" rx="5"/>
52
+ <text x="380" y="355" class="component-title" text-anchor="middle">Risk Agent</text>
53
+ <text x="380" y="380" class="code" text-anchor="middle">Reads: orders, portfolio</text>
54
+ <text x="380" y="397" class="code" text-anchor="middle">Writes: risk alerts</text>
55
+ <text x="380" y="414" class="code" text-anchor="middle">Priority: 20</text>
56
+
57
+ <!-- Agent 3 -->
58
+ <rect x="510" y="330" width="200" height="100" class="agent-box" rx="5"/>
59
+ <text x="610" y="355" class="component-title" text-anchor="middle">Analytics Agent</text>
60
+ <text x="610" y="380" class="code" text-anchor="middle">Reads: all facts</text>
61
+ <text x="610" y="397" class="code" text-anchor="middle">Writes: insights</text>
62
+ <text x="610" y="414" class="code" text-anchor="middle">Priority: 5</text>
63
+
64
+ <!-- Agent 4 -->
65
+ <rect x="750" y="330" width="200" height="100" class="agent-box" rx="5"/>
66
+ <text x="850" y="355" class="component-title" text-anchor="middle">Execution Agent</text>
67
+ <text x="850" y="380" class="code" text-anchor="middle">Reads: approved orders</text>
68
+ <text x="850" y="397" class="code" text-anchor="middle">Writes: executions</text>
69
+ <text x="850" y="414" class="code" text-anchor="middle">Priority: 30</text>
70
+
71
+ <!-- Arrows from agents to blackboard -->
72
+ <path d="M 150 330 L 400 270" class="arrow"/>
73
+ <path d="M 380 330 L 450 270" class="arrow"/>
74
+ <path d="M 610 330 L 550 270" class="arrow"/>
75
+ <path d="M 850 330 L 600 270" class="arrow"/>
76
+
77
+ <!-- RETE Engine -->
78
+ <rect x="100" y="90" width="180" height="80" class="box" rx="5"/>
79
+ <text x="190" y="115" class="component-title" text-anchor="middle">RETE Engine</text>
80
+ <text x="190" y="135" class="code" text-anchor="middle">Pattern matching</text>
81
+ <text x="190" y="152" class="code" text-anchor="middle">Rule execution</text>
82
+
83
+ <!-- Arrow from RETE to Blackboard -->
84
+ <path d="M 280 130 L 350 130" class="arrow"/>
85
+
86
+ <!-- Persistence Layer (bottom) -->
87
+ <text x="500" y="485" class="component-title" text-anchor="middle">Persistence Layer (Pluggable)</text>
88
+
89
+ <!-- SQLite Store -->
90
+ <rect x="100" y="500" width="220" height="150" class="storage-box" rx="5"/>
91
+ <text x="210" y="525" class="component-title" text-anchor="middle">SQLite Store</text>
92
+ <text x="210" y="550" class="label" text-anchor="middle">Tables:</text>
93
+ <text x="210" y="570" class="code" text-anchor="middle">• facts</text>
94
+ <text x="210" y="587" class="code" text-anchor="middle">• messages</text>
95
+ <text x="210" y="604" class="code" text-anchor="middle">• audit_log</text>
96
+ <text x="210" y="625" class="comment" text-anchor="middle">✓ ACID transactions</text>
97
+ <text x="210" y="642" class="comment" text-anchor="middle">✓ Durable</text>
98
+
99
+ <!-- Redis Store -->
100
+ <rect x="350" y="500" width="220" height="150" class="storage-box" rx="5"/>
101
+ <text x="460" y="525" class="component-title" text-anchor="middle">Redis Store</text>
102
+ <text x="460" y="550" class="label" text-anchor="middle">Data Structures:</text>
103
+ <text x="460" y="570" class="code" text-anchor="middle">• fact:{uuid} (hash)</text>
104
+ <text x="460" y="587" class="code" text-anchor="middle">• facts:type:{t} (set)</text>
105
+ <text x="460" y="604" class="code" text-anchor="middle">• messages (zset)</text>
106
+ <text x="460" y="625" class="comment" text-anchor="middle">✓ 100x faster</text>
107
+ <text x="460" y="642" class="comment" text-anchor="middle">✓ Distributed</text>
108
+
109
+ <!-- Hybrid Store -->
110
+ <rect x="600" y="500" width="220" height="150" class="storage-box" rx="5"/>
111
+ <text x="710" y="525" class="component-title" text-anchor="middle">Hybrid Store</text>
112
+ <text x="710" y="550" class="label" text-anchor="middle">Best of Both:</text>
113
+ <text x="710" y="570" class="code" text-anchor="middle">• Redis for facts</text>
114
+ <text x="710" y="587" class="code" text-anchor="middle">• SQLite for audit</text>
115
+ <text x="710" y="604" class="code" text-anchor="middle">• Fast + durable</text>
116
+ <text x="710" y="625" class="comment" text-anchor="middle">✓ </text>
117
+ <text x="710" y="642" class="comment" text-anchor="middle">✓ Full audit trail</text>
118
+
119
+ <!-- Arrows from Blackboard to Storage -->
120
+ <path d="M 400 270 L 210 500" class="data-arrow"/>
121
+ <path d="M 500 270 L 460 500" class="data-arrow"/>
122
+ <path d="M 600 270 L 710 500" class="data-arrow"/>
123
+
124
+ <!-- Message Flow Indicator -->
125
+ <rect x="850" y="90" width="130" height="160" class="box" rx="5" stroke-dasharray="5,3"/>
126
+ <text x="915" y="110" class="component-title" text-anchor="middle">Message Flow</text>
127
+ <text x="915" y="135" class="code" text-anchor="middle">1. Agent writes fact</text>
128
+ <text x="915" y="155" class="code" text-anchor="middle">2. RETE matches</text>
129
+ <text x="915" y="175" class="code" text-anchor="middle">3. Rules fire</text>
130
+ <text x="915" y="195" class="code" text-anchor="middle">4. New facts added</text>
131
+ <text x="915" y="215" class="code" text-anchor="middle">5. Other agents see</text>
132
+ <text x="915" y="235" class="code" text-anchor="middle">6. Cycle continues</text>
133
+
134
+ <!-- Legend -->
135
+ <text x="50" y="690" class="comment">Purple: Control/Logic | Teal: Data Storage | Pink: Agents/Knowledge Sources</text>
136
+ </svg>
@@ -0,0 +1,101 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 700" style="background: transparent;">
2
+ <defs>
3
+ <style>
4
+ .title { font: bold 16px monospace; fill: #e0e0e0; }
5
+ .node-title { font: bold 12px monospace; fill: #bb86fc; }
6
+ .label { font: 11px monospace; fill: #e0e0e0; }
7
+ .beta-box { fill: #2d3d4d; stroke: #03dac6; stroke-width: 2; }
8
+ .alpha-box { fill: #3d2d4d; stroke: #bb86fc; stroke-width: 2; }
9
+ .join-box { fill: #2d4d3d; stroke: #4daf50; stroke-width: 2; }
10
+ .neg-box { fill: #4d2d2d; stroke: #cf6679; stroke-width: 2; }
11
+ .prod-box { fill: #4d4d2d; stroke: #ffa500; stroke-width: 2; }
12
+ .arrow { stroke: #bb86fc; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
13
+ .arrow-beta { stroke: #03dac6; stroke-width: 2; fill: none; marker-end: url(#arrowhead-beta); }
14
+ </style>
15
+ <marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
16
+ <polygon points="0 0, 10 3, 0 6" fill="#bb86fc" />
17
+ </marker>
18
+ <marker id="arrowhead-beta" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
19
+ <polygon points="0 0, 10 3, 0 6" fill="#03dac6" />
20
+ </marker>
21
+ </defs>
22
+
23
+ <!-- Title -->
24
+ <text x="300" y="30" class="title" text-anchor="middle">Compiled RETE Network</text>
25
+ <text x="300" y="50" class="label" text-anchor="middle" style="font-style: italic; fill: #888;">Example rule with negation</text>
26
+
27
+ <!-- Root Beta Memory -->
28
+ <rect x="200" y="80" width="200" height="50" class="beta-box" rx="5"/>
29
+ <text x="300" y="105" class="node-title" text-anchor="middle">Root Beta Memory</text>
30
+ <text x="300" y="120" class="label" text-anchor="middle">(dummy token)</text>
31
+
32
+ <!-- Arrow from root to join -->
33
+ <path d="M 250 130 L 250 180" class="arrow-beta"/>
34
+
35
+ <!-- AlphaMemory(stock) on right -->
36
+ <rect x="420" y="150" width="150" height="60" class="alpha-box" rx="5"/>
37
+ <text x="495" y="175" class="node-title" text-anchor="middle">AlphaMemory</text>
38
+ <text x="495" y="195" class="label" text-anchor="middle">:stock</text>
39
+
40
+ <!-- Arrow from alpha to join -->
41
+ <path d="M 420 180 L 310 200" class="arrow"/>
42
+
43
+ <!-- JoinNode1 -->
44
+ <rect x="200" y="180" width="110" height="50" class="join-box" rx="5"/>
45
+ <text x="255" y="205" class="node-title" text-anchor="middle">JoinNode1</text>
46
+ <text x="255" y="220" class="label" text-anchor="middle">test: ?sym</text>
47
+
48
+ <!-- Arrow from join to beta1 -->
49
+ <path d="M 255 230 L 255 270" class="arrow-beta"/>
50
+
51
+ <!-- BetaMemory1 -->
52
+ <rect x="180" y="270" width="150" height="50" class="beta-box" rx="5"/>
53
+ <text x="255" y="295" class="node-title" text-anchor="middle">BetaMemory1</text>
54
+ <text x="255" y="310" class="label" text-anchor="middle">(stock tokens)</text>
55
+
56
+ <!-- Arrow from beta1 to negation -->
57
+ <path d="M 255 320 L 255 370" class="arrow-beta"/>
58
+
59
+ <!-- AlphaMemory(alert) on right -->
60
+ <rect x="420" y="350" width="150" height="60" class="alpha-box" rx="5"/>
61
+ <text x="495" y="375" class="node-title" text-anchor="middle">AlphaMemory</text>
62
+ <text x="495" y="395" class="label" text-anchor="middle">:alert</text>
63
+
64
+ <!-- Arrow from alpha alert to negation -->
65
+ <path d="M 420 380 L 340 390" class="arrow"/>
66
+
67
+ <!-- NegationNode -->
68
+ <rect x="170" y="370" width="170" height="50" class="neg-box" rx="5"/>
69
+ <text x="255" y="395" class="node-title" text-anchor="middle">NegationNode</text>
70
+ <text x="255" y="410" class="label" text-anchor="middle">NOT :alert, test: ?sym</text>
71
+
72
+ <!-- Arrow from negation to beta2 -->
73
+ <path d="M 255 420 L 255 460" class="arrow-beta"/>
74
+
75
+ <!-- BetaMemory2 (implicit) -->
76
+ <rect x="180" y="460" width="150" height="50" class="beta-box" rx="5"/>
77
+ <text x="255" y="485" class="node-title" text-anchor="middle">BetaMemory2</text>
78
+ <text x="255" y="500" class="label" text-anchor="middle">(matched tokens)</text>
79
+
80
+ <!-- Arrow from beta2 to production -->
81
+ <path d="M 255 510 L 255 560" class="arrow"/>
82
+
83
+ <!-- ProductionNode -->
84
+ <rect x="160" y="560" width="190" height="70" class="prod-box" rx="5"/>
85
+ <text x="255" y="590" class="node-title" text-anchor="middle">ProductionNode</text>
86
+ <text x="255" y="610" class="label" text-anchor="middle">Rule: "example"</text>
87
+ <text x="255" y="625" class="label" text-anchor="middle">Action: print ?sym</text>
88
+
89
+ <!-- Legend -->
90
+ <text x="50" y="670" class="label" style="font-size: 10px;">Legend:</text>
91
+ <rect x="120" y="655" width="40" height="20" class="beta-box" rx="2"/>
92
+ <text x="165" y="670" class="label" style="font-size: 10px;">Beta</text>
93
+ <rect x="210" y="655" width="40" height="20" class="alpha-box" rx="2"/>
94
+ <text x="255" y="670" class="label" style="font-size: 10px;">Alpha</text>
95
+ <rect x="300" y="655" width="40" height="20" class="join-box" rx="2"/>
96
+ <text x="345" y="670" class="label" style="font-size: 10px;">Join</text>
97
+ <rect x="385" y="655" width="40" height="20" class="neg-box" rx="2"/>
98
+ <text x="430" y="670" class="label" style="font-size: 10px;">Negation</text>
99
+ <rect x="480" y="655" width="40" height="20" class="prod-box" rx="2"/>
100
+ <text x="525" y="670" class="label" style="font-size: 10px;">Production</text>
101
+ </svg>
@@ -0,0 +1,117 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 700" style="background: transparent;">
2
+ <defs>
3
+ <style>
4
+ .title { font: bold 18px monospace; fill: #e0e0e0; }
5
+ .step-label { font: bold 14px monospace; fill: #bb86fc; }
6
+ .node-label { font: 12px monospace; fill: #e0e0e0; }
7
+ .code-label { font: 11px monospace; fill: #03dac6; }
8
+ .box { fill: #2d2d2d; stroke: #bb86fc; stroke-width: 2; }
9
+ .highlight-box { fill: #3d2d4d; stroke: #bb86fc; stroke-width: 3; }
10
+ .flow-arrow { stroke: #cf6679; stroke-width: 3; fill: none; marker-end: url(#flow-arrow); }
11
+ .data-arrow { stroke: #03dac6; stroke-width: 2; fill: none; marker-end: url(#data-arrow); stroke-dasharray: 5,5; }
12
+ </style>
13
+ <marker id="flow-arrow" markerWidth="12" markerHeight="12" refX="10" refY="3" orient="auto">
14
+ <polygon points="0 0, 12 3, 0 6" fill="#cf6679" />
15
+ </marker>
16
+ <marker id="data-arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
17
+ <polygon points="0 0, 10 3, 0 6" fill="#03dac6" />
18
+ </marker>
19
+ </defs>
20
+
21
+ <!-- Title -->
22
+ <text x="450" y="30" class="title" text-anchor="middle">Fact Assertion Flow</text>
23
+ <text x="450" y="50" class="code-label" text-anchor="middle">engine.add_fact(:stock, symbol: "AAPL", price: 150)</text>
24
+
25
+ <!-- Step 1: WorkingMemory.add_fact -->
26
+ <rect x="50" y="80" width="280" height="80" class="highlight-box" rx="5"/>
27
+ <text x="190" y="105" class="step-label" text-anchor="middle">1. WorkingMemory.add_fact(fact)</text>
28
+ <text x="190" y="130" class="code-label" text-anchor="middle">@facts &lt;&lt; fact</text>
29
+ <text x="190" y="147" class="code-label" text-anchor="middle">notify_observers(:add, fact)</text>
30
+
31
+ <!-- Arrow to Step 2 -->
32
+ <path d="M 190 160 L 190 200" class="flow-arrow"/>
33
+
34
+ <!-- Step 2: ReteEngine.update -->
35
+ <rect x="50" y="200" width="280" height="80" class="highlight-box" rx="5"/>
36
+ <text x="190" y="225" class="step-label" text-anchor="middle">2. ReteEngine.update(:add, fact)</text>
37
+ <text x="190" y="250" class="code-label" text-anchor="middle">For each alpha_memory:</text>
38
+ <text x="190" y="267" class="code-label" text-anchor="middle">if fact.matches?(pattern)</text>
39
+
40
+ <!-- Arrow to Step 3 -->
41
+ <path d="M 190 280 L 190 320" class="flow-arrow"/>
42
+
43
+ <!-- Step 3: AlphaMemory.activate -->
44
+ <rect x="50" y="320" width="280" height="100" class="highlight-box" rx="5"/>
45
+ <text x="190" y="345" class="step-label" text-anchor="middle">3. AlphaMemory.activate(fact)</text>
46
+ <text x="190" y="370" class="code-label" text-anchor="middle">return unless @linked</text>
47
+ <text x="190" y="387" class="code-label" text-anchor="middle">@items &lt;&lt; fact</text>
48
+ <text x="190" y="404" class="code-label" text-anchor="middle">For each successor join_node:</text>
49
+
50
+ <!-- Arrow to Step 4 -->
51
+ <path d="M 190 420 L 190 460" class="flow-arrow"/>
52
+
53
+ <!-- Step 4: JoinNode.right_activate -->
54
+ <rect x="50" y="460" width="280" height="120" class="highlight-box" rx="5"/>
55
+ <text x="190" y="485" class="step-label" text-anchor="middle">4. JoinNode.right_activate(fact)</text>
56
+ <text x="190" y="510" class="code-label" text-anchor="middle">return unless @left_linked &amp;&amp; @right_linked</text>
57
+ <text x="190" y="527" class="code-label" text-anchor="middle">For each token in beta_memory:</text>
58
+ <text x="190" y="544" class="code-label" text-anchor="middle">if perform_join_tests(token, fact)</text>
59
+ <text x="190" y="561" class="code-label" text-anchor="middle">new_token = Token.new(token, fact, self)</text>
60
+
61
+ <!-- Arrow to Step 5 -->
62
+ <path d="M 190 580 L 190 620" class="flow-arrow"/>
63
+
64
+ <!-- Step 5: Token Propagation -->
65
+ <rect x="50" y="620" width="280" height="60" class="highlight-box" rx="5"/>
66
+ <text x="190" y="645" class="step-label" text-anchor="middle">5. Propagate Token</text>
67
+ <text x="190" y="667" class="code-label" text-anchor="middle">@successors.each { |s| s.activate(new_token) }</text>
68
+
69
+ <!-- Right side: Data structures -->
70
+ <text x="550" y="105" class="step-label">Data Structures Updated:</text>
71
+
72
+ <!-- Working Memory -->
73
+ <rect x="450" y="130" width="400" height="80" class="box" rx="5"/>
74
+ <text x="650" y="155" class="step-label" text-anchor="middle">Working Memory</text>
75
+ <text x="650" y="180" class="node-label" text-anchor="middle">@facts = [</text>
76
+ <text x="650" y="197" class="code-label" text-anchor="middle">stock(symbol: "AAPL", price: 150)</text>
77
+ <text x="650" y="205" class="node-label" text-anchor="middle">]</text>
78
+
79
+ <!-- Data flow arrow from step 1 -->
80
+ <path d="M 330 120 L 450 160" class="data-arrow"/>
81
+
82
+ <!-- Alpha Memory -->
83
+ <rect x="450" y="250" width="400" height="80" class="box" rx="5"/>
84
+ <text x="650" y="275" class="step-label" text-anchor="middle">Alpha Memory (stock pattern)</text>
85
+ <text x="650" y="300" class="node-label" text-anchor="middle">@items = [</text>
86
+ <text x="650" y="317" class="code-label" text-anchor="middle">stock(symbol: "AAPL", price: 150)</text>
87
+ <text x="650" y="325" class="node-label" text-anchor="middle">]</text>
88
+
89
+ <!-- Data flow arrow from step 3 -->
90
+ <path d="M 330 360 L 450 280" class="data-arrow"/>
91
+
92
+ <!-- Beta Memory -->
93
+ <rect x="450" y="370" width="400" height="100" class="box" rx="5"/>
94
+ <text x="650" y="395" class="step-label" text-anchor="middle">Beta Memory (after join)</text>
95
+ <text x="650" y="420" class="node-label" text-anchor="middle">@tokens = [</text>
96
+ <text x="650" y="437" class="code-label" text-anchor="middle">Token(parent: root_token,</text>
97
+ <text x="650" y="454" class="code-label" text-anchor="middle">fact: stock(symbol: "AAPL", price: 150))</text>
98
+ <text x="650" y="462" class="node-label" text-anchor="middle">]</text>
99
+
100
+ <!-- Data flow arrow from step 4 -->
101
+ <path d="M 330 520 L 450 420" class="data-arrow"/>
102
+
103
+ <!-- Production Node -->
104
+ <rect x="450" y="500" width="400" height="100" class="box" rx="5"/>
105
+ <text x="650" y="525" class="step-label" text-anchor="middle">Production Node (if fully matched)</text>
106
+ <text x="650" y="550" class="node-label" text-anchor="middle">@tokens = [</text>
107
+ <text x="650" y="567" class="code-label" text-anchor="middle">Token(...) // ready to fire</text>
108
+ <text x="650" y="584" class="node-label" text-anchor="middle">]</text>
109
+ <text x="650" y="592" class="code-label" text-anchor="middle">Call engine.run() to execute rule actions</text>
110
+
111
+ <!-- Data flow arrow from step 5 -->
112
+ <path d="M 330 650 L 450 550" class="data-arrow"/>
113
+
114
+ <!-- Legend -->
115
+ <text x="50" y="695" class="code-label">Pink arrows: Control flow</text>
116
+ <text x="350" y="695" class="code-label">Teal dashed: Data updates</text>
117
+ </svg>
@@ -0,0 +1,65 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 380">
2
+ <defs>
3
+ <style>
4
+ .box { fill: #1e293b; stroke: #60a5fa; stroke-width: 2; }
5
+ .text { fill: #e2e8f0; font-family: 'Courier New', monospace; font-size: 13px; }
6
+ .title { fill: #60a5fa; font-family: 'Courier New', monospace; font-size: 14px; font-weight: bold; }
7
+ .label { fill: #94a3b8; font-family: 'Courier New', monospace; font-size: 12px; }
8
+ .arrow { stroke: #60a5fa; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
9
+ .cycle-arrow { stroke: #22d3ee; stroke-width: 2; fill: none; marker-end: url(#arrowhead-cyan); }
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
+ <marker id="arrowhead-cyan" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
15
+ <polygon points="0 0, 10 3, 0 6" fill="#22d3ee" />
16
+ </marker>
17
+ </defs>
18
+
19
+ <!-- Left side: Facts (DATA) -->
20
+ <text x="100" y="30" text-anchor="middle" class="title">Facts (DATA)</text>
21
+ <rect x="30" y="50" width="140" height="80" rx="5" class="box"/>
22
+ <text x="100" y="75" text-anchor="middle" class="label">Current State</text>
23
+ <text x="100" y="95" text-anchor="middle" class="label">:stock</text>
24
+ <text x="100" y="110" text-anchor="middle" class="label">:portfolio</text>
25
+
26
+ <!-- Right side: Rules (LOGIC) -->
27
+ <text x="500" y="30" text-anchor="middle" class="title">Rules (LOGIC)</text>
28
+ <rect x="430" y="50" width="140" height="80" rx="5" class="box"/>
29
+ <text x="500" y="75" text-anchor="middle" class="label">IF-THEN Logic</text>
30
+ <text x="500" y="95" text-anchor="middle" class="label">Conditions</text>
31
+ <text x="500" y="110" text-anchor="middle" class="label">Actions</text>
32
+
33
+ <!-- Arrow from Facts to Pattern Match -->
34
+ <path d="M 170 90 L 240 90" class="arrow"/>
35
+
36
+ <!-- Arrow from Rules to Pattern Match -->
37
+ <path d="M 430 90 L 360 90" class="arrow"/>
38
+
39
+ <!-- Center: Pattern Match and Execution -->
40
+ <rect x="210" y="170" width="180" height="140" rx="5" class="box"/>
41
+ <text x="300" y="195" text-anchor="middle" class="title">IF conditions</text>
42
+ <text x="300" y="215" text-anchor="middle" class="title">match facts</text>
43
+
44
+ <line x1="230" y1="230" x2="370" y2="230" stroke="#60a5fa" stroke-width="1" opacity="0.3"/>
45
+
46
+ <text x="300" y="255" text-anchor="middle" class="title">THEN execute</text>
47
+ <text x="300" y="275" text-anchor="middle" class="title">action</text>
48
+
49
+ <!-- Arrow pointing down to Pattern Match box -->
50
+ <path d="M 300 130 L 300 170" class="arrow"/>
51
+
52
+ <!-- Arrow from action box to new facts -->
53
+ <path d="M 300 310 L 300 340" class="arrow"/>
54
+ <text x="380" y="328" class="label">May create</text>
55
+ <text x="380" y="345" class="label">new facts</text>
56
+
57
+ <!-- New facts box at bottom -->
58
+ <rect x="210" y="345" width="180" height="30" rx="3" class="box"/>
59
+ <text x="300" y="365" text-anchor="middle" class="label">Facts added/removed</text>
60
+
61
+ <!-- Cycle arrow going back up -->
62
+ <path d="M 390 360 L 550 360 L 550 90 L 570 90" class="cycle-arrow"/>
63
+ <text x="555" y="225" class="label" fill="#22d3ee">↻</text>
64
+ <text x="490" y="372" class="label" fill="#22d3ee">(cycle continues)</text>
65
+ </svg>
@@ -0,0 +1,42 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 450 280">
2
+ <defs>
3
+ <style>
4
+ .box { fill: #1e293b; stroke: #60a5fa; stroke-width: 2; }
5
+ .text { fill: #e2e8f0; font-family: 'Courier New', monospace; font-size: 14px; }
6
+ .title { fill: #60a5fa; font-family: 'Courier New', monospace; font-size: 16px; font-weight: bold; }
7
+ .label { fill: #94a3b8; font-family: 'Courier New', monospace; font-size: 13px; }
8
+ .value { fill: #a5f3fc; font-family: 'Courier New', monospace; font-size: 13px; }
9
+ </style>
10
+ </defs>
11
+
12
+ <!-- Main container box -->
13
+ <rect x="30" y="20" width="390" height="240" rx="5" class="box"/>
14
+
15
+ <!-- Title -->
16
+ <text x="225" y="50" text-anchor="middle" class="title">Fact</text>
17
+
18
+ <!-- Separator line -->
19
+ <line x1="50" y1="65" x2="400" y2="65" stroke="#60a5fa" stroke-width="1" opacity="0.3"/>
20
+
21
+ <!-- Type section -->
22
+ <text x="70" y="95" class="label">Type:</text>
23
+ <text x="140" y="95" class="value">:temperature</text>
24
+
25
+ <!-- Separator line -->
26
+ <line x1="50" y1="110" x2="400" y2="110" stroke="#60a5fa" stroke-width="1" opacity="0.3"/>
27
+
28
+ <!-- Attributes section -->
29
+ <text x="70" y="140" class="label">Attributes:</text>
30
+
31
+ <text x="90" y="170" class="label">location:</text>
32
+ <text x="200" y="170" class="value">"server_room"</text>
33
+
34
+ <text x="90" y="195" class="label">value:</text>
35
+ <text x="200" y="195" class="value">85</text>
36
+
37
+ <text x="90" y="220" class="label">timestamp:</text>
38
+ <text x="200" y="220" class="value">2025-01-15 10:30:00</text>
39
+
40
+ <text x="90" y="245" class="label">sensor_id:</text>
41
+ <text x="200" y="245" class="value">42</text>
42
+ </svg>
@@ -0,0 +1,47 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 420">
2
+ <defs>
3
+ <style>
4
+ .box { fill: #1e293b; stroke: #60a5fa; stroke-width: 2; }
5
+ .text { fill: #e2e8f0; font-family: 'Courier New', monospace; font-size: 14px; }
6
+ .title { fill: #60a5fa; font-family: 'Courier New', monospace; font-size: 12px; font-weight: bold; }
7
+ .arrow { stroke: #60a5fa; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
8
+ .code { fill: #94a3b8; font-family: 'Courier New', monospace; font-size: 11px; }
9
+ </style>
10
+ <marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
11
+ <polygon points="0 0, 10 3, 0 6" fill="#60a5fa" />
12
+ </marker>
13
+ </defs>
14
+
15
+ <!-- Step 1: Add Facts -->
16
+ <rect x="50" y="20" width="400" height="60" rx="5" class="box"/>
17
+ <text x="250" y="40" text-anchor="middle" class="title">1. ADD FACTS</text>
18
+ <text x="250" y="62" text-anchor="middle" class="code">kb.fact :temperature, value: 85</text>
19
+
20
+ <!-- Arrow 1 -->
21
+ <path d="M 250 80 L 250 110" class="arrow"/>
22
+
23
+ <!-- Step 2: Pattern Matching -->
24
+ <rect x="50" y="110" width="400" height="60" rx="5" class="box"/>
25
+ <text x="250" y="130" text-anchor="middle" class="title">2. PATTERN MATCHING</text>
26
+ <text x="250" y="152" text-anchor="middle" class="code">RETE network finds matching rules</text>
27
+
28
+ <!-- Arrow 2 -->
29
+ <path d="M 250 170 L 250 200" class="arrow"/>
30
+
31
+ <!-- Step 3: Fire Rules -->
32
+ <rect x="50" y="200" width="400" height="60" rx="5" class="box"/>
33
+ <text x="250" y="220" text-anchor="middle" class="title">3. FIRE RULES</text>
34
+ <text x="250" y="242" text-anchor="middle" class="code">Execute actions for complete matches</text>
35
+
36
+ <!-- Arrow 3 -->
37
+ <path d="M 250 260 L 250 290" class="arrow"/>
38
+
39
+ <!-- Step 4: Actions May Add/Remove Facts -->
40
+ <rect x="50" y="290" width="400" height="80" rx="5" class="box"/>
41
+ <text x="250" y="310" text-anchor="middle" class="title">4. ACTIONS MAY ADD/REMOVE FACTS</text>
42
+ <text x="250" y="332" text-anchor="middle" class="code">Cycle continues until no rules fire</text>
43
+
44
+ <!-- Feedback arrow -->
45
+ <path d="M 450 320 L 480 320 L 480 50 L 460 50" class="arrow"/>
46
+ <text x="485" y="185" class="text" font-size="11">↻</text>
47
+ </svg>