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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +85 -57
  4. data/docs/advanced/performance.md +109 -76
  5. data/docs/advanced/testing.md +399 -263
  6. data/docs/api/blackboard.md +1 -1
  7. data/docs/api/engine.md +77 -8
  8. data/docs/api/facts.md +3 -3
  9. data/docs/api/rules.md +110 -40
  10. data/docs/architecture/blackboard.md +108 -117
  11. data/docs/assets/images/fact-rule-relationship.svg +65 -0
  12. data/docs/assets/images/fact-structure.svg +42 -0
  13. data/docs/assets/images/inference-cycle.svg +47 -0
  14. data/docs/assets/images/kb-components.svg +43 -0
  15. data/docs/assets/images/rule-structure.svg +44 -0
  16. data/docs/assets/images/trading-signal-network.svg +1 -1
  17. data/docs/examples/index.md +219 -5
  18. data/docs/guides/blackboard-memory.md +89 -58
  19. data/docs/guides/dsl.md +24 -24
  20. data/docs/guides/getting-started.md +109 -107
  21. data/docs/guides/writing-rules.md +470 -311
  22. data/docs/index.md +16 -18
  23. data/docs/quick-start.md +92 -99
  24. data/docs/what-is-a-fact.md +694 -0
  25. data/docs/what-is-a-knowledge-base.md +350 -0
  26. data/docs/what-is-a-rule.md +833 -0
  27. data/examples/.gitignore +1 -0
  28. data/examples/advanced_example_dsl.rb +1 -1
  29. data/examples/ai_enhanced_kbs_dsl.rb +1 -1
  30. data/examples/car_diagnostic_dsl.rb +1 -1
  31. data/examples/concurrent_inference_demo.rb +0 -1
  32. data/examples/concurrent_inference_demo_dsl.rb +0 -1
  33. data/examples/csv_trading_system_dsl.rb +1 -1
  34. data/examples/iot_demo_using_dsl.rb +1 -1
  35. data/examples/portfolio_rebalancing_system_dsl.rb +1 -1
  36. data/examples/rule_source_demo.rb +123 -0
  37. data/examples/stock_trading_advanced_dsl.rb +1 -1
  38. data/examples/temp_dsl.txt +6214 -5269
  39. data/examples/timestamped_trading_dsl.rb +1 -1
  40. data/examples/trading_demo_dsl.rb +1 -1
  41. data/examples/working_demo_dsl.rb +1 -1
  42. data/lib/kbs/decompiler.rb +204 -0
  43. data/lib/kbs/dsl/knowledge_base.rb +100 -1
  44. data/lib/kbs/dsl.rb +3 -1
  45. data/lib/kbs/engine.rb +41 -0
  46. data/lib/kbs/version.rb +1 -1
  47. data/lib/kbs.rb +14 -12
  48. data/mkdocs.yml +30 -30
  49. metadata +15 -10
  50. data/docs/DOCUMENTATION_STATUS.md +0 -158
  51. data/docs/examples/expert-systems.md +0 -1031
  52. data/docs/examples/multi-agent.md +0 -1335
  53. data/docs/examples/stock-trading.md +0 -488
  54. data/examples/knowledge_base.db +0 -0
  55. data/examples/temp.txt +0 -7693
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/kbs/dsl'
3
+ require_relative '../lib/kbs'
4
4
  require 'time'
5
5
 
6
6
  class TimestampedTradingSystem
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/kbs/dsl'
3
+ require_relative '../lib/kbs'
4
4
  include KBS::DSL::ConditionHelpers
5
5
 
6
6
  class TradingDemo
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/kbs/dsl'
3
+ require_relative '../lib/kbs'
4
4
  include KBS::DSL::ConditionHelpers
5
5
 
6
6
  # Define the knowledge base with rules
@@ -0,0 +1,204 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KBS
4
+ # Reconstruct Ruby source from YARV bytecode.
5
+ #
6
+ # YARV bytecode is a stack machine. We simulate the stack,
7
+ # translating instructions back into Ruby expressions.
8
+ #
9
+ # Usage:
10
+ # KBS::Decompiler.new(some_proc).decompile # => "proc { |x| x + 1 }"
11
+ # KBS::Decompiler.new(some_lambda).decompile # => "->(x) { x + 1 }"
12
+ # KBS::Decompiler.new(some_proc).decompile_block # => "{ |x| x + 1 }"
13
+ #
14
+ class Decompiler
15
+ def initialize(proc_obj)
16
+ @iseq = RubyVM::InstructionSequence.of(proc_obj)
17
+ @arr = @iseq.to_a
18
+ @locals = @arr[10] # [:a, :b, ...]
19
+ @params = @arr[11] # {lead_num: 2, ...}
20
+ @body = @arr[13] # [1, :EVENT, [:instruction, ...], ...]
21
+ @children = []
22
+ @iseq.each_child { |c| @children << c }
23
+ @child_index = 0
24
+ @lambda = proc_obj.lambda?
25
+ end
26
+
27
+ def decompile
28
+ expr = decompile_body(@body)
29
+ params = build_params
30
+ if @lambda
31
+ "->(#{params}) { #{expr} }"
32
+ else
33
+ "proc { |#{params}| #{expr} }"
34
+ end
35
+ end
36
+
37
+ # Returns just the block literal: { |params| body }
38
+ # Useful when the surrounding keyword (perform, satisfies, etc.)
39
+ # is supplied by the caller.
40
+ def decompile_block
41
+ expr = decompile_body(@body)
42
+ params = build_params
43
+ if params.empty?
44
+ "{ #{expr} }"
45
+ else
46
+ "{ |#{params}| #{expr} }"
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def build_params
53
+ count = @params[:lead_num] || 0
54
+ @locals.first(count).join(", ")
55
+ end
56
+
57
+ def decompile_body(body)
58
+ stack = []
59
+ statements = []
60
+ instructions = body.select { |i| i.is_a?(Array) }
61
+
62
+ instructions.each do |inst|
63
+ op = inst[0]
64
+ case op
65
+ when :getlocal_WC_0
66
+ idx = inst[1]
67
+ name = slot_to_name(idx)
68
+ stack.push(name.to_s)
69
+
70
+ when :setlocal_WC_0
71
+ idx = inst[1]
72
+ name = slot_to_name(idx)
73
+ val = stack.pop
74
+ statements << "#{name} = #{val}"
75
+
76
+ when :putobject
77
+ stack.push(inst[1].inspect)
78
+
79
+ when :putobject_INT2FIX_0_
80
+ stack.push("0")
81
+
82
+ when :putobject_INT2FIX_1_
83
+ stack.push("1")
84
+
85
+ when :putself
86
+ stack.push("self")
87
+
88
+ when :putnil
89
+ stack.push("nil")
90
+
91
+ when :putchilledstring, :putstring
92
+ stack.push(inst[1].inspect)
93
+
94
+ when :opt_plus, :opt_minus, :opt_mult, :opt_div, :opt_mod,
95
+ :opt_eq, :opt_neq, :opt_lt, :opt_le, :opt_gt, :opt_ge,
96
+ :opt_ltlt
97
+ op_sym = inst[1][:mid]
98
+ b = stack.pop
99
+ a = stack.pop
100
+ stack.push("#{a} #{op_sym} #{b}")
101
+
102
+ when :opt_send_without_block
103
+ calldata = inst[1]
104
+ method = calldata[:mid]
105
+ argc = calldata[:orig_argc]
106
+ args = stack.pop(argc)
107
+ receiver = stack.pop
108
+ call_str = format_call(receiver, method, args)
109
+ stack.push(call_str)
110
+
111
+ when :send
112
+ calldata = inst[1]
113
+ method = calldata[:mid]
114
+ argc = calldata[:orig_argc]
115
+ args = stack.pop(argc)
116
+ receiver = stack.pop
117
+
118
+ child_iseq = @children[@child_index]
119
+ @child_index += 1
120
+ child_src = decompile_child(child_iseq)
121
+
122
+ base = format_call(receiver, method, args)
123
+ stack.push("#{base} { #{child_src} }")
124
+
125
+ when :newarray
126
+ count = inst[1]
127
+ items = stack.pop(count)
128
+ stack.push("[#{items.join(', ')}]")
129
+
130
+ when :newhash
131
+ count = inst[1]
132
+ pairs = stack.pop(count)
133
+ entries = pairs.each_slice(2).map { |k, v| "#{k} => #{v}" }
134
+ stack.push("{ #{entries.join(', ')} }")
135
+
136
+ when :branchunless
137
+ condition = stack.pop
138
+ remaining = instructions[instructions.index(inst) + 1..]
139
+ true_val = extract_value(remaining, 0)
140
+ false_val = extract_value(remaining, 1)
141
+ if true_val && false_val
142
+ stack.push("#{condition} ? #{true_val} : #{false_val}")
143
+ break
144
+ end
145
+
146
+ when :leave
147
+ # ignore
148
+
149
+ when :pop
150
+ val = stack.pop
151
+ statements << val if val
152
+
153
+ else
154
+ stack.push("/* #{op} */")
155
+ end
156
+ end
157
+
158
+ all = statements + [stack.last].compact
159
+ all.join("; ")
160
+ end
161
+
162
+ def format_call(receiver, method, args)
163
+ prefix = (receiver == "self") ? "" : "#{receiver}."
164
+ if args.empty?
165
+ "#{prefix}#{method}"
166
+ else
167
+ "#{prefix}#{method}(#{args.join(', ')})"
168
+ end
169
+ end
170
+
171
+ def decompile_child(child_iseq)
172
+ child_arr = child_iseq.to_a
173
+ child_locals = child_arr[10]
174
+ child_params = child_arr[11]
175
+ child_body = child_arr[13]
176
+ count = child_params[:lead_num] || 0
177
+ param_names = child_locals.first(count).join(", ")
178
+
179
+ saved = [@locals, @params, @body]
180
+ @locals, @params, @body = child_locals, child_params, child_body
181
+ expr = decompile_body(child_body)
182
+ @locals, @params, @body = saved
183
+
184
+ if count > 0
185
+ "|#{param_names}| #{expr}"
186
+ else
187
+ expr
188
+ end
189
+ end
190
+
191
+ def extract_value(instructions, index)
192
+ values = instructions.select { |i|
193
+ i.is_a?(Array) && (i[0] == :putchilledstring || i[0] == :putstring || i[0] == :putobject)
194
+ }
195
+ val = values[index]
196
+ val[1].inspect if val
197
+ end
198
+
199
+ def slot_to_name(slot_idx)
200
+ name_idx = @locals.size + 2 - slot_idx
201
+ @locals[name_idx] || "?local_#{slot_idx}"
202
+ end
203
+ end
204
+ end
@@ -9,9 +9,11 @@ module KBS
9
9
  @engine = Engine.new
10
10
  @rules = {}
11
11
  @rule_builders = {}
12
+ @rule_source_locations = {}
12
13
  end
13
14
 
14
15
  def rule(name, &block)
16
+ @rule_source_locations[name] = block.source_location if block
15
17
  builder = RuleBuilder.new(name)
16
18
  builder.instance_eval(&block) if block_given?
17
19
  @rule_builders[name] = builder
@@ -42,7 +44,7 @@ module KBS
42
44
  end
43
45
 
44
46
  def reset
45
- @engine.working_memory.facts.clear
47
+ @engine.reset
46
48
  end
47
49
 
48
50
  def facts
@@ -65,6 +67,30 @@ module KBS
65
67
  puts "-" * 40
66
68
  end
67
69
 
70
+ def rule_source(name)
71
+ # Try file-based source first
72
+ if (location = @rule_source_locations[name])
73
+ file, line = location
74
+ if file && File.exist?(file)
75
+ source = extract_rule_source(file, line)
76
+ return source if source
77
+ end
78
+ end
79
+
80
+ # Fall back to reconstruction from internal state
81
+ reconstruct_rule_source(name)
82
+ end
83
+
84
+ def print_rule_source(name)
85
+ source = rule_source(name)
86
+ unless source
87
+ puts "No source available for rule '#{name}'"
88
+ return
89
+ end
90
+
91
+ puts source
92
+ end
93
+
68
94
  def print_rules
69
95
  puts "Knowledge Base Rules:"
70
96
  puts "-" * 40
@@ -81,6 +107,79 @@ module KBS
81
107
  end
82
108
  puts "-" * 40
83
109
  end
110
+
111
+ private
112
+
113
+ def reconstruct_rule_source(name)
114
+ builder = @rule_builders[name]
115
+ return nil unless builder
116
+
117
+ lines = []
118
+ lines << "rule #{name.inspect} do"
119
+ lines << " desc #{builder.description.inspect}" if builder.description
120
+ lines << " priority #{builder.priority}" if builder.priority != 0
121
+
122
+ builder.conditions.each do |cond|
123
+ keyword = cond.negated ? "without" : "on"
124
+ pattern_str = reconstruct_pattern(cond.pattern)
125
+ if pattern_str.empty?
126
+ lines << " #{keyword} #{cond.type.inspect}"
127
+ else
128
+ lines << " #{keyword} #{cond.type.inspect}, #{pattern_str}"
129
+ end
130
+ end
131
+
132
+ if builder.action_block
133
+ block_str = decompile_proc_block(builder.action_block)
134
+ lines << " perform #{block_str}"
135
+ end
136
+
137
+ lines << "end"
138
+ lines.join("\n")
139
+ end
140
+
141
+ def reconstruct_pattern(pattern)
142
+ return "" if pattern.empty?
143
+
144
+ pattern.map do |key, value|
145
+ val_str = if value.is_a?(Proc)
146
+ Decompiler.new(value).decompile
147
+ else
148
+ value.inspect
149
+ end
150
+ "#{key}: #{val_str}"
151
+ end.join(", ")
152
+ end
153
+
154
+ def decompile_proc_block(proc_obj)
155
+ Decompiler.new(proc_obj).decompile_block
156
+ rescue => e
157
+ "{ <decompilation failed: #{e.message}> }"
158
+ end
159
+
160
+ def extract_rule_source(file, start_line)
161
+ lines = File.readlines(file)
162
+ start_idx = start_line - 1
163
+ return nil if start_idx < 0 || start_idx >= lines.length
164
+
165
+ # source_location points to the block's `do` line, which is
166
+ # normally the same line as the `rule` call. Walk back up to
167
+ # 2 lines in case they are on separate lines.
168
+ rule_idx = start_idx.downto([start_idx - 2, 0].max).find do |i|
169
+ lines[i].match?(/\b(?:rule|defrule)\b/)
170
+ end || start_idx
171
+
172
+ base_indent = lines[rule_idx][/^\s*/].length
173
+ end_pattern = /^\s{#{base_indent}}end\b/
174
+
175
+ result = []
176
+ (rule_idx...lines.length).each do |i|
177
+ result << lines[i]
178
+ break if i > rule_idx && lines[i].match?(end_pattern)
179
+ end
180
+
181
+ result.join.chomp
182
+ end
84
183
  end
85
184
  end
86
185
  end
data/lib/kbs/dsl.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../kbs'
3
+ unless defined?(KBS::Engine)
4
+ require_relative '../kbs'
5
+ end
4
6
 
5
7
  # DSL components
6
8
  require_relative 'dsl/variable'
data/lib/kbs/engine.rb CHANGED
@@ -53,6 +53,47 @@ module KBS
53
53
  end
54
54
  end
55
55
 
56
+ # Clear all transient RETE state while preserving the compiled rule network.
57
+ #
58
+ # The RETE network has four levels of transient state:
59
+ # 1. WorkingMemory — holds all asserted facts
60
+ # 2. AlphaMemory — holds facts matching each pattern
61
+ # 3. BetaMemory — holds tokens from condition joins
62
+ # 4. ProductionNode — holds tokens ready to fire
63
+ #
64
+ # Simply clearing working memory facts doesn't cascade reliably
65
+ # through intermediate beta memories. Stale tokens in beta memories
66
+ # cause false matches when new facts are asserted on the next cycle.
67
+ #
68
+ # This method clears all four levels directly while preserving the
69
+ # root beta memory's dummy token (needed for first-condition joins).
70
+ def reset
71
+ # 1. Clear working memory directly (bypass observer — we clear everything)
72
+ @working_memory.facts.clear
73
+
74
+ # 2. Clear alpha memories and their downstream beta memories
75
+ @alpha_memories.each_value do |alpha_mem|
76
+ alpha_mem.items.clear
77
+
78
+ # Each alpha memory successor is a JoinNode or NegationNode.
79
+ # Their successors are intermediate BetaMemory nodes.
80
+ # The root beta memory is never a join node successor, so
81
+ # its dummy token is preserved.
82
+ alpha_mem.successors.each do |join_node|
83
+ next unless join_node.respond_to?(:successors)
84
+ join_node.successors.each do |beta_or_prod|
85
+ beta_or_prod.tokens.clear if beta_or_prod.respond_to?(:tokens)
86
+ end
87
+ end
88
+ end
89
+
90
+ # 3. Clear production node tokens
91
+ @production_nodes.each_value { |node| node.tokens.clear }
92
+
93
+ # 4. Clear stale child references from the root dummy token
94
+ @root_beta_memory.tokens.each { |t| t.children.clear }
95
+ end
96
+
56
97
  private
57
98
 
58
99
  def build_network_for_rule(rule)
data/lib/kbs/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KBS
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.1"
5
5
  end
data/lib/kbs.rb CHANGED
@@ -1,19 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "kbs/version"
3
+ require_relative 'kbs/version'
4
4
 
5
5
  # Core RETE classes
6
- require_relative "kbs/fact"
7
- require_relative "kbs/working_memory"
8
- require_relative "kbs/token"
9
- require_relative "kbs/alpha_memory"
10
- require_relative "kbs/beta_memory"
11
- require_relative "kbs/join_node"
12
- require_relative "kbs/negation_node"
13
- require_relative "kbs/production_node"
14
- require_relative "kbs/condition"
15
- require_relative "kbs/rule"
16
- require_relative "kbs/engine"
6
+ require_relative 'kbs/fact'
7
+ require_relative 'kbs/working_memory'
8
+ require_relative 'kbs/token'
9
+ require_relative 'kbs/alpha_memory'
10
+ require_relative 'kbs/beta_memory'
11
+ require_relative 'kbs/join_node'
12
+ require_relative 'kbs/negation_node'
13
+ require_relative 'kbs/production_node'
14
+ require_relative 'kbs/condition'
15
+ require_relative 'kbs/rule'
16
+ require_relative 'kbs/engine'
17
+ require_relative 'kbs/decompiler'
18
+ require_relative 'kbs/dsl'
17
19
 
18
20
  module KBS
19
21
  class Error < StandardError; end
data/mkdocs.yml CHANGED
@@ -143,39 +143,39 @@ extra:
143
143
 
144
144
  # Navigation
145
145
  nav:
146
- - Home: index.md
146
+ - Home:
147
+ - index.md
148
+ - What is aKnowledge Base?: what-is-a-knowledge-base.md
149
+ - What is a Fact?: what-is-a-fact.md
150
+ - What is a Rule?: what-is-a-rule.md
147
151
  - Installation: installation.md
148
152
  - Quick Start: quick-start.md
149
153
  - Architecture:
150
- - architecture/index.md
151
- - RETE Algorithm: architecture/rete-algorithm.md
152
- - Blackboard System: architecture/blackboard.md
153
- - Network Structure: architecture/network-structure.md
154
+ - architecture/index.md
155
+ - RETE Algorithm: architecture/rete-algorithm.md
156
+ - Blackboard System: architecture/blackboard.md
157
+ - Network Structure: architecture/network-structure.md
154
158
  - Guides:
155
- - guides/index.md
156
- - Getting Started: guides/getting-started.md
157
- - Writing Rules: guides/writing-rules.md
158
- - DSL Reference: guides/dsl.md
159
- - Working with Facts: guides/facts.md
160
- - Pattern Matching: guides/pattern-matching.md
161
- - Variable Binding: guides/variable-binding.md
162
- - Negation: guides/negation.md
163
- - Blackboard Memory: guides/blackboard-memory.md
164
- - Persistence Options: guides/persistence.md
165
- - Examples:
166
- - examples/index.md
167
- - Stock Trading: examples/stock-trading.md
168
- - Expert Systems: examples/expert-systems.md
169
- - Multi-Agent Systems: examples/multi-agent.md
159
+ - guides/index.md
160
+ - Getting Started: guides/getting-started.md
161
+ - Writing Rules: guides/writing-rules.md
162
+ - DSL Reference: guides/dsl.md
163
+ - Working with Facts: guides/facts.md
164
+ - Pattern Matching: guides/pattern-matching.md
165
+ - Variable Binding: guides/variable-binding.md
166
+ - Negation: guides/negation.md
167
+ - Blackboard Memory: guides/blackboard-memory.md
168
+ - Persistence Options: guides/persistence.md
169
+ - Examples: examples/index.md
170
170
  - Advanced:
171
- - advanced/index.md
172
- - Performance Tuning: advanced/performance.md
173
- - Custom Persistence: advanced/custom-persistence.md
174
- - Debugging: advanced/debugging.md
175
- - Testing Rules: advanced/testing.md
171
+ - advanced/index.md
172
+ - Performance Tuning: advanced/performance.md
173
+ - Custom Persistence: advanced/custom-persistence.md
174
+ - Debugging: advanced/debugging.md
175
+ - Testing Rules: advanced/testing.md
176
176
  - API Reference:
177
- - api/index.md
178
- - ReteEngine: api/engine.md
179
- - Facts: api/facts.md
180
- - Rules: api/rules.md
181
- - Blackboard: api/blackboard.md
177
+ - api/index.md
178
+ - ReteEngine: api/engine.md
179
+ - Facts: api/facts.md
180
+ - Rules: api/rules.md
181
+ - Blackboard: api/blackboard.md
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kbs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
@@ -13,14 +13,14 @@ dependencies:
13
13
  name: sqlite3
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
18
  version: '1.6'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '1.6'
26
26
  - !ruby/object:Gem::Dependency
@@ -90,7 +90,6 @@ files:
90
90
  - LICENSE.txt
91
91
  - README.md
92
92
  - Rakefile
93
- - docs/DOCUMENTATION_STATUS.md
94
93
  - docs/advanced/custom-persistence.md
95
94
  - docs/advanced/debugging.md
96
95
  - docs/advanced/index.md
@@ -109,16 +108,18 @@ files:
109
108
  - docs/assets/images/blackboard-architecture.svg
110
109
  - docs/assets/images/compiled-network.svg
111
110
  - docs/assets/images/fact-assertion-flow.svg
111
+ - docs/assets/images/fact-rule-relationship.svg
112
+ - docs/assets/images/fact-structure.svg
113
+ - docs/assets/images/inference-cycle.svg
114
+ - docs/assets/images/kb-components.svg
112
115
  - docs/assets/images/kbs.jpg
113
116
  - docs/assets/images/pattern-matching-trace.svg
114
117
  - docs/assets/images/rete-network-layers.svg
118
+ - docs/assets/images/rule-structure.svg
115
119
  - docs/assets/images/system-layers.svg
116
120
  - docs/assets/images/trading-signal-network.svg
117
121
  - docs/assets/js/mathjax.js
118
- - docs/examples/expert-systems.md
119
122
  - docs/examples/index.md
120
- - docs/examples/multi-agent.md
121
- - docs/examples/stock-trading.md
122
123
  - docs/guides/blackboard-memory.md
123
124
  - docs/guides/dsl.md
124
125
  - docs/guides/facts.md
@@ -132,6 +133,10 @@ files:
132
133
  - docs/index.md
133
134
  - docs/installation.md
134
135
  - docs/quick-start.md
136
+ - docs/what-is-a-fact.md
137
+ - docs/what-is-a-knowledge-base.md
138
+ - docs/what-is-a-rule.md
139
+ - examples/.gitignore
135
140
  - examples/README.md
136
141
  - examples/advanced_example.rb
137
142
  - examples/advanced_example_dsl.rb
@@ -146,17 +151,16 @@ files:
146
151
  - examples/csv_trading_system.rb
147
152
  - examples/csv_trading_system_dsl.rb
148
153
  - examples/iot_demo_using_dsl.rb
149
- - examples/knowledge_base.db
150
154
  - examples/portfolio_rebalancing_system.rb
151
155
  - examples/portfolio_rebalancing_system_dsl.rb
152
156
  - examples/redis_trading_demo.rb
153
157
  - examples/redis_trading_demo_dsl.rb
158
+ - examples/rule_source_demo.rb
154
159
  - examples/run_all.rb
155
160
  - examples/run_all_dsl.rb
156
161
  - examples/sample_stock_data.csv
157
162
  - examples/stock_trading_advanced.rb
158
163
  - examples/stock_trading_advanced_dsl.rb
159
- - examples/temp.txt
160
164
  - examples/temp_dsl.txt
161
165
  - examples/timestamped_trading.rb
162
166
  - examples/timestamped_trading_dsl.rb
@@ -180,6 +184,7 @@ files:
180
184
  - lib/kbs/blackboard/redis_audit_log.rb
181
185
  - lib/kbs/blackboard/redis_message_queue.rb
182
186
  - lib/kbs/condition.rb
187
+ - lib/kbs/decompiler.rb
183
188
  - lib/kbs/dsl.rb
184
189
  - lib/kbs/dsl/condition_helpers.rb
185
190
  - lib/kbs/dsl/knowledge_base.rb
@@ -217,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
222
  - !ruby/object:Gem::Version
218
223
  version: '0'
219
224
  requirements: []
220
- rubygems_version: 3.7.2
225
+ rubygems_version: 4.0.7
221
226
  specification_version: 4
222
227
  summary: Knowledge-Based System with RETE inference, Blackboard architecture, and
223
228
  AI integration