;;; -*- Mode: Lisp; Syntax: Common-Lisp; -*- (in-package #.*simple-planners-package-name*) ;;; Copyright 2007 by Robert St. Amant. ;;; To download the code for simple-POP and simple-GP, visit ;;; . ;;; This software is released under the license described by Peter ;;; Norvig: . If you find this ;;; software useful, please send email to . ;;; About aima-compatibility.lisp: ;;; The code in this file provides a set of quick-and-dirty glue ;;; functions to allow simple-POP and simple-GP to use the AIMA code ;;; base. (eval-when (:compile-toplevel :load-toplevel :execute) (aima-load 'search) (aima-load 'agents) (aima-load 'logic) ) ;;; ============================== ;;; AIMA extensions to handle functionality present in PAIP (defconstant +variable-prefix-char+ #\?) (defun variable? (x) "Is x a variable (a symbol starting with $)?" (and (symbolp x) (eql (char (symbol-name x) 0) +variable-prefix-char+))) (setf (symbol-function 'find-all-if) #'remove-if-not) (defun find-all (item sequence &rest keyword-args &key (test #'eql) test-not &allow-other-keys) "Find all those elements of sequence that match item, according to the 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))) ;;; See PAIP/patmatch.lisp (defun variable-p (x) "Is x a variable (a symbol beginning with +variable-prefix-char+)?" (and (symbolp x) (equal (elt (symbol-name x) 0) +variable-prefix-char+))) ;;; See PAIP/search.lisp (defun sorter (cost-fn) "Return a combiner function that sorts according to cost-fn." #'(lambda (new old) (sort (append new old) #'< :key cost-fn))) (defstructure (planning-problem (:include problem))) (defmethod goal-test ((problem planning-problem) node) (plan-solution-p (state-if-node node))) (defmethod successors ((problem planning-problem) node) (mapcar #'(lambda (successor) (cons 'action successor)) (plan-successors (state-if-node node)))) ;;; Utility (defun state-if-node (node-or-state) (if (node-p node-or-state) (node-state node-or-state) node-or-state)) ;;; ============================== ;;; Common function (defun simple-search (start goal-p successors cost-fn) (declare (ignorable goal-p successors)) (let* ((result (best-first-search (make-planning-problem :initial-state start) #'(lambda (node-or-state) (funcall cost-fn (state-if-node node-or-state)))))) (when result (node-state result))))