Skip to content

Instantly share code, notes, and snippets.

@ecounysis
Created September 9, 2011 05:04
Show Gist options
  • Save ecounysis/1205528 to your computer and use it in GitHub Desktop.
Save ecounysis/1205528 to your computer and use it in GitHub Desktop.
GPS from PAIP
(defun find-all (item sequence &rest keyword-args
&key (test #'eql) test-not &allow-other-keys)
"Find all thos elements of sequence that match item,
according to keywords. Doesn't alter sequence."
(if test-not
(apply #'remove item sequence
:test-not (complement test-not) keyword-args)
(apply #'remove item sequence
:test (complement test) keyword-args)))
(defvar *state* nil "The current state: a list of conditions")
(defvar *ops* nil "A list of available operators")
(defstruct op "an operation"
(action nil) (preconds nil) (add-list nil) (del-list nil))
(defun GPS (*state* goals *ops*)
"General Problem Solver: achieve all goals using *ops*"
(if (every #'achieve goals) 'solved))
(defun achieve (goal)
"A goal is achieved if it already holds
or if there is an appropriate op for it that is applicable"
(or (member goal *state*)
(some #'apply-op
(find-all goal *ops* :test #'appropriate-p))))
(defun appropriate-p (goal op)
"An op is appropriate to a goal if the goal is in the op's add-list"
(member goal (op-add-list op)))
(defun apply-op (op)
"Print a message and update *state* if op is applicable."
(when (every #'achieve (op-preconds op))
(print (list 'executing (op-action op)))
(setf *state* (set-difference *state* (op-del-list op)))
(setf *state* (union *state* (op-add-list op)))
t))
;; smaller problem for kicks
(setf op1 (make-op :action 'drive-son-to-school
:preconds '(son-at-home car-works)
:add-list '(son-at-school)
:del-list '(son-at-home)))
(defparameter *school-ops-1* (list op1))
(gps '(son-at-home car-works) '(son-at-school) *school-ops-1*)
;; the problem from the book
(defparameter *school-ops*
(list
(make-op :action 'drive-son-to-school
:preconds '(son-at-home car-works)
:add-list '(son-at-school)
:del-list '(son-at-home)))
(make-op :action 'shop-installs-battery
:preconds '(car-needs-battery shop-knows-problem shop-has-money)
:add-list '(car-works))
(make-op :action 'tell-shop-problem
:preconds '(in-communication-with-shop)
:add-list '(shop-knows-problem))
(make-op :action 'telephone-shop
:preconds '(know-phone-number)
:add-list '(in-communication-with-shop))
(make-op :action 'look-up-number
:preconds '(have-phone-book)
:add-list '(know-phone-number))
(make-op :action 'give-shop-money
:add-list '(shop-has-money)
:del-list '(have-money))))
(gps '(son-at-home have-money have-phone-book car-needs-battery) '(son-at-school) *school-ops*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment