Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add second version of the general problem solver

  • Loading branch information...
commit dd27d9e75b62c4a7a613c855843195d821d1e455 1 parent fabedce
Ola Bini authored September 13, 2008

Showing 1 changed file with 79 additions and 0 deletions. Show diff stats Hide diff stats

  1. 79  lib/ch04/gps2.rb
79  lib/ch04/gps2.rb
... ...
@@ -0,0 +1,79 @@
  1
+require 'gps'
  2
+require 'gps_no_clobber'
  3
+require 'dbg'
  4
+
  5
+module Enumerable
  6
+  def some?
  7
+    self.each do |v|
  8
+      result = yield v
  9
+      return result if result
  10
+    end
  11
+  end
  12
+end
  13
+
  14
+class GPS::Op
  15
+  def convert!
  16
+    unless self.add_list.any? { |l| l.is_a?(Array) && l.first == :executing } 
  17
+      self.add_list << [:executing, self.action]
  18
+    end
  19
+    self
  20
+  end
  21
+end
  22
+
  23
+GPS::SCHOOL_OPS.each do |op|
  24
+  op.convert!
  25
+end
  26
+
  27
+class GPS2 < GPS
  28
+  class << self
  29
+    def op(action, parts = {})
  30
+      GPS::Op.new(action, 
  31
+             parts[:preconds], 
  32
+             parts[:add_list], 
  33
+             parts[:del_list]).convert!
  34
+    end
  35
+  end
  36
+  
  37
+  def solve(*goals)
  38
+    achieve_all([[:start]] + @state, goals, []).grep(Array)
  39
+  end
  40
+  
  41
+  def achieve_all(state, goals, goal_stack)
  42
+    current_state = goals.inject(state) do |current_state, g|
  43
+      return [] if current_state.empty?
  44
+      achieve(current_state, g, goal_stack)
  45
+    end
  46
+    if goals.subset_of?(current_state)
  47
+      current_state
  48
+    else
  49
+      []
  50
+    end
  51
+  end
  52
+  
  53
+  def achieve(state, goal, goal_stack)
  54
+    dbg_indent(:gps, goal_stack.length, "Goal: %p", goal)
  55
+
  56
+    if state.include?(goal)
  57
+      state
  58
+    elsif goal_stack.include?(goal)
  59
+      []
  60
+    else
  61
+      @ops.find_all do |op| 
  62
+        appropriate?(goal, op) 
  63
+      end.some? do |op| 
  64
+        apply(state, goal, op, goal_stack)
  65
+      end || []
  66
+    end
  67
+  end
  68
+  
  69
+  def apply(state, goal, op, goal_stack)
  70
+    dbg_indent(:gps, goal_stack.length, "Consider: %p", op.action)
  71
+
  72
+    state2 = achieve_all(state, op.preconds, [goal] + goal_stack)
  73
+
  74
+    unless state2.empty?
  75
+      dbg_indent(:gps, goal_stack.length, "Action: %p", op.action)
  76
+      (state2 - op.del_list) + op.add_list
  77
+    end
  78
+  end
  79
+end

0 notes on commit dd27d9e

Please sign in to comment.
Something went wrong with that request. Please try again.