Created
September 9, 2011 05:04
-
-
Save ecounysis/1205528 to your computer and use it in GitHub Desktop.
GPS from PAIP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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