codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
class Rule attr_reader :rule_name, :lhs_list, :rhs def initialize(rule_name, lhs_list, rhs_str) @rule_name = rule_name @lhs_list = lhs_list @rhs = rhs_str end end class RuleFactory @@rule_num = 0 def RuleFactory.make_rule(lhs_list, rhs) @@rule_num += 1 Rule.new("R#{@@rule_num}", lhs_list, rhs) end def RuleFactory.clear_number @@rule_num = 0 end end class WorkingMemory def initialize @knowledge_list = [] end def find_knowledge(find_str) return nil if nil == @knowledge_list @knowledge_list.find { |know| know == find_str } end def add_knowledge(knowledge) return if find_knowledge(knowledge) @knowledge_list << knowledge end def load_from_file(file_path) File.open(file_path, 'r') do |file| file.each_line do |line| line[-1] = '' if line[-1] == 10 # '\n' is 10(ascii) add_knowledge(line) end end end def clear @knowledge_list.clear end end class ProductionMemory def initialize @rule_list = [] end def add_rule(rule) @rule_list << rule end # 등록된 순서대로 리턴 def find_rules(rhs_str) # find rule RHS @rule_list.select { |rule| rule.rhs == rhs_str } end def load_from_file(file_path) RuleFactory.clear_number File.open(file_path, 'r') do |file| file.each_line do |line| line[-1] = '' if line[-1] == 10 # '\n' is 10(ascii) # split | split_lhsrhs = line.split('|') # split , split_each_lhs = split_lhsrhs[0].split(',') add_rule(RuleFactory.make_rule(split_each_lhs, split_lhsrhs[1])) end end end def clear @rule_list.clear end end class RuleInterpreter def initialize @wm = nil @pm = nil @prev_fired_rule = nil @unsatisfied_chain_stack =[] end def set_working_memory(wm) @wm = wm end def set_production_memory(pm) @pm = pm end def set_goal(goal_str) @goal = goal_str end def fire_rule(rule) # rhs 의 정보를 WM 으로 넣음 @wm.add_knowledge(rule.rhs) puts "Fired #{rule.rule_name}" @prev_fired_rule = rule end def do_bwd_recursive(target_knowledge) # 찾아야 할 지식이 rhs 로 있는 rule 후보들을 찾음 next_candidate_rules = @pm.find_rules(target_knowledge) while( next_candidate_rules.length > 0 ) # 남은 후보 중에서 하나를 선택 selected_rule = select_rule_with_conflict(next_candidate_rules) # 이전에 fire 한 rule 만 남음 break if nil == selected_rule # WM 에 있는 것들은 통과, 없는 것들에 대해 리스트 뽑기 unsatisfied_lhs_list = selected_rule.lhs_list.select do |lhs| nil == @wm.find_knowledge(lhs) end if unsatisfied_lhs_list # 만족하지 못하는 lhs 들을 찾아서 들어감(DFS) unsatisfied_lhs_list.each do |lhs| break if !do_bwd_recursive(lhs) unsatisfied_lhs_list.delete(lhs) end end # 만족하지 못하는 lhs 를 어떤 rule 로도 만들 수 없음 if unsatisfied_lhs_list && unsatisfied_lhs_list.length > 0 next_candidate_rules.delete(selected_rule) puts "Abandoned #{selected_rule.rule_name}" next end # WM 에 전부 있으면 여기까지 진입가능 # rule 을 fire fire_rule(selected_rule) # target_knowledge 는 해결함, 이전 미해결로 리턴 return true end # 후보 중 진행 가능한 것이 없음 return nil end def do_bwd return nil if nil == @wm || nil == @pm do_bwd_recursive(@goal) end def select_rule_with_conflict(rule_list) # 3) specificity 적용, 2) Recency 는 적용하지 않음(WM의 순서를 뒤져야 함) most_preferred_rule = nil max_condition = 0 rule_list.each do |rule| # 1) refraction 을 방지 next if @prev_fired_rule == rule if nil == most_preferred_rule most_preferred_rule = rule max_condition = rule.lhs_list.length else if max_condition < rule.lhs_list.length most_preferred_rule = rule max_condition = rule.lhs_list.length end end end return most_preferred_rule if most_preferred_rule # 이전 rule 밖에 남지 않음, 다시 fire 하지 않음 return nil end end class ProductionSystem def initialize @wm = nil @pm = nil end def set_working_memory(wm) @wm = wm end def set_production_memory(pm) @pm = pm end def do_bwd(goal) interpreter = RuleInterpreter.new interpreter.set_working_memory @wm interpreter.set_production_memory @pm interpreter.set_goal goal found = interpreter.do_bwd if found puts "Success" else puts "Not Success" end end def clear_knowledge @wm = nil end def clear_rule @pm = nil end end # 데이터 넣기 ps = ProductionSystem.new pm = ProductionMemory.new pm.load_from_file 'zoo_production_rule.dat' ps.set_production_memory pm # GIRAFFE puts 'Test:: Find giraffe' wm = WorkingMemory.new wm.load_from_file 'working_memory_ex_giraffe.dat' ps.set_working_memory wm ps.do_bwd('giraffe') ps.clear_knowledge # CHEETAH puts 'Test:: Find cheetah' wm = WorkingMemory.new wm.load_from_file 'working_memory_ex_cheetah.dat' ps.set_working_memory wm ps.do_bwd('cheetah')
Private
[
?
]
Run code