diff --git a/jenkins/ext/VAL b/jenkins/ext/VAL index 249ed5f4..faf1764f 160000 --- a/jenkins/ext/VAL +++ b/jenkins/ext/VAL @@ -1 +1 @@ -Subproject commit 249ed5f45775f2dadd45b53e2ee383e1b5c5d869 +Subproject commit faf1764fc58f8d896395fe61210ee99089569d65 diff --git a/jenkins/ext/pddl-tools b/jenkins/ext/pddl-tools index 48be4f34..d3f55be7 160000 --- a/jenkins/ext/pddl-tools +++ b/jenkins/ext/pddl-tools @@ -1 +1 @@ -Subproject commit 48be4f34502ee5d1aa426570114d78e727a5e393 +Subproject commit d3f55be7d5653b5881ced5a8617904a07e605f46 diff --git a/jenkins/ext/random-state b/jenkins/ext/random-state index 9c298638..11eaf401 160000 --- a/jenkins/ext/random-state +++ b/jenkins/ext/random-state @@ -1 +1 @@ -Subproject commit 9c29863875387a92c035d22c99ab0a82f1c3dd9a +Subproject commit 11eaf4010d7730da2853c8e809f4aad9bb49af79 diff --git a/shop3/buildapp/Makefile b/shop3/buildapp/Makefile index ee568061..52e596dd 100644 --- a/shop3/buildapp/Makefile +++ b/shop3/buildapp/Makefile @@ -6,7 +6,8 @@ shop-app: buildapp-script shop-app-entrypoints.lisp install: shop-app install -c -m 555 shop-app ${DESTDIR}/bin/shop - cd ${DESTDIR}/bin && ln -s shop ess-shop && ln -s shop tree-compare + install -c -m 555 shop-app ${DESTDIR}/bin/ess-shop + install -c -m 555 shop-app ${DESTDIR}/bin/tree-compare clean: rm -f shop-app diff --git a/shop3/buildapp/README.md b/shop3/buildapp/README.md new file mode 100644 index 00000000..d70dceb8 --- /dev/null +++ b/shop3/buildapp/README.md @@ -0,0 +1,19 @@ +# Building SHOP applications with `buildapp` + +`buildapp` is Zach Beane's tool for building stand-alone applications in Common Lisp, compatible with both SBCL and CCL. For more details, see [its webpage](https://www.xach.com/lisp/buildapp/). + +If you have buildapp installed, you can use it to build SHOP-based applications with the contents of this directory. + +The applications that can be built are: + +- `ess-shop` -- given a domain and a problem, output a plan for the problem using `find-plans-stack`. +- `shop` -- given a domain and a problem, output a plan for the problem using `find-plans` ("classic SHOP"). Note that this does not offer the full functionality of `ess-shop`. +- `tree-compare` -- compare two files that contain SHOP planning trees. + +# Build instructions + +It is sufficient to do `make install` to get the above three applications installed, if `buildapp` is in your `PATH`. Note that the Makefile supports the standard `DESTDIR` make variable. For example, I use `make install DESTDIR=~/.local/` + +# For assistance + +For questions, post discussions in the GitHub SHOP3 project. Report bugs in issues. diff --git a/shop3/buildapp/shop-app-entrypoints.lisp b/shop3/buildapp/shop-app-entrypoints.lisp index 63902d6d..283525b0 100644 --- a/shop3/buildapp/shop-app-entrypoints.lisp +++ b/shop3/buildapp/shop-app-entrypoints.lisp @@ -15,7 +15,8 @@ ;;; ;;;--------------------------------------------------------------------------- (defpackage :shop-app - (:use :shop3 :iterate :common-lisp)) + (:use :shop3 :iterate :common-lisp) + (:import-from #:shop-hddl #:hddl-plan)) (in-package :shop-app) (defvar *interactive* t @@ -44,36 +45,53 @@ (as i from 1) (format stream "~3d:~t~a:~t~,2f~%" i step cost)) + (finish-output stream) (when (eq stream t) (print-separator stream)))) -(defun print-ess-tree (tree &optional (stream t)) +(defun print-ess-tree (tree &optional (stream-arg t)) (let ((*print-length* nil) ;; (*print-right-margin* 10000) ;; best guess at package for output - (*package* (symbol-package (shop::problem-name shop::*problem*)))) + (*package* (symbol-package (shop::problem-name shop::*problem*))) + (stream (if (eq stream-arg t) *standard-output* stream-arg))) + ;; print functions (pprint (plan-tree:plan-tree->sexp tree) stream) - (when (eq stream t) + (terpri stream) + (finish-output stream) + (when (eq stream-arg t) (print-separator stream)))) -(defun print-classic-tree (tree &optional (stream t)) +(defun print-classic-tree (tree &optional (stream-arg t)) (let ((*print-length* nil) ;; (*print-right-margin* 10000) ;; best guess at package for output - (*package* (symbol-package (shop::problem-name shop::*problem*)))) + (*package* (symbol-package (shop::problem-name shop::*problem*))) + (stream (if (eq stream-arg t) *standard-output* stream-arg))) (pprint tree stream) (terpri stream) - (force-output stream) - (when (eq stream t) + (finish-output stream) + (when (eq stream-arg t) (print-separator stream)))) +(defun print-hddl-plan (plan tree &optional (stream-arg t)) + (let ((hddl-plan (hddl-plan plan tree))) + ;; (terpri *error-output*) + ;; (pprint hddl-plan *error-output*) + ;; (terpri *error-output*) + (let ((*print-length* nil) + ;; (*print-right-margin* 10000) + ;; best guess at package for output + (*package* (symbol-package (shop::problem-name shop::*problem*)))) + (shop-hddl:print-hddl-plan hddl-plan (if (eq stream-arg t) *standard-output* stream-arg))))) + +(defun print-pddl-plan (plan domain &optional (stream-arg t)) + (shop:write-pddl-plan plan :domain domain :stream stream-arg)) + + (defun common/options () (list - (clingon:make-option - :flag - :description "Print plan tree as well as plan." - :key :plan-tree - :long-name "tree") + (clingon:make-option :counter :description "Verbose output." @@ -86,22 +104,39 @@ :description "Print plan to file." :key :plan-file :required nil - :long-name "plan-file") + :long-name "plan-file"))) + +(defun ess/options () + (append + (list + (clingon:make-option + :flag + :description "Print plan in PDDL format." + :key :pddl + :long-name "pddl" + ) + (clingon:make-option + :string + :description "Print PDDL output to file." + :key :pddl-file + :required nil + :long-name "pddl-file") + (clingon:make-option + :flag + :description "Print plan tree as well as plan." + :key :plan-tree + :long-name "tree") (clingon:make-option :string :description "Print plan tree to file." :key :tree-file :required nil - :long-name "tree-file"))) - -(defun ess/options () - (append - (list + :long-name "tree-file") (clingon:make-option - :flag - :description "Print HDDL output (plan and tree)." - :key :hddl - :long-name "hddl") + :flag + :description "Print HDDL output (plan and tree)." + :key :hddl + :long-name "hddl") (clingon:make-option :string :description "Print HDDL output to file." @@ -116,55 +151,83 @@ (defun tree-compare/options () nil) +(defun load-shop-file (filename) + (let ((*package* (find-package :shop-user))) + (unless (load filename :if-does-not-exist t) + (error "File ~a failed to load." filename)))) + +;; (eval-when (:load-toplevel :execute) +;; (trace shop-hddl::plan-tree->decompositions) +;; (trace shop-hddl::forest-roots)) + +(trace write-pddl-plan) (defun ess/handler (cmd) (let ((args (clingon:command-arguments cmd)) (plan-tree (or (clingon:getopt cmd :plan-tree) (clingon:getopt cmd :tree-file))) + (pddl (or (clingon:getopt cmd :pddl) + (clingon:getopt cmd :pddl-file))) (hddl (or (clingon:getopt cmd :hddl) (clingon:getopt cmd :hddl-file))) + (verbosity (clingon:getopt cmd :verbose)) (shop::*define-silently* (zerop (clingon:getopt cmd :verbose)))) (handler-bind ((error (lambda (x) (unless *interactive* - (format *error-output* "~a" x) + (format *error-output* "~&ESS-SHOP ERROR:~a~%" x) + #+sbcl(sb-debug:print-backtrace :stream *error-output*) (uiop:quit 1))))) (iter (for x in args) - (unless (load x :if-does-not-exist t) - (error "File ~a failed to load." x))) + (load-shop-file x)) (let ((retvals - (find-plans-stack shop::*problem* :plan-tree plan-tree :unpack-returns nil :verbose (clingon:getopt cmd :verbose)))) + (find-plans-stack shop::*problem* :plan-tree (or plan-tree hddl) :unpack-returns nil :verbose verbosity))) (unless retvals (error "Unable to find a plan for problem ~a" (shop::problem-name shop::*problem*))) - (let ((plan-stream (alexandria:if-let ((plan-path (clingon:getopt cmd :plan-file))) - (open plan-path :direction :output :if-exists :supersede) - t))) - (unwind-protect - (print-plan (shop:plan (first retvals)) plan-stream) - (unless (eq plan-stream t) (close plan-stream)))) - (when plan-tree - (let ((stream (alexandria:if-let ((plan-path (clingon:getopt cmd :tree-file))) - (open plan-path :direction :output :if-exists :supersede) - t))) - (unwind-protect - (print-ess-tree (tree (first retvals)) stream) - (unless (eq stream t) (close stream))))) + + (when pddl + (let ((domain (find-domain (domain-name shop::*problem*)))) + (if (clingon:getopt cmd :pddl-file) + (write-pddl-plan (plan (first retvals)) :domain domain + :filename (clingon:getopt cmd :pddl-file)) + (write-pddl-plan (plan (first retvals)) :domain domain)))) + + ;; print the plan sequence + (unless (or hddl pddl) + (if (clingon:getopt cmd :plan-file) + (let ((plan-stream (open (clingon:getopt cmd :plan-file) :direction :output :if-exists :supersede))) + (unwind-protect + (print-plan (shop:plan (first retvals)) plan-stream) + (unless (eq plan-stream t) (close plan-stream)))) + (print-plan (shop:plan (first retvals)) t)) + + ;; print the plan-tree (if appropriate) + (when plan-tree + (if (clingon:getopt cmd :tree-file) + (let ((stream (open (clingon:getopt cmd :tree-file) :direction :output :if-exists :supersede))) + (unwind-protect + (print-ess-tree (tree (first retvals)) stream) + (close stream))) + (print-ess-tree (tree (first retvals)) t)))) + + ;; print the HDDL, if appropriate (when hddl - (let ((stream (alexandria:if-let ((plan-path (clingon:getopt cmd :hddl-file))) - (open plan-path :direction :output :if-exists :supersede) - t))) - ;;; FIXME: update this... - (unwind-protect - (print-ess-tree (tree (first retvals)) stream) - (unless (eq stream t) (close stream))))) - )))) + (let ((plan (plan (first retvals))) + (tree (tree (first retvals)))) + (if (clingon:getopt cmd :hddl-file) + (let ((stream + (open (clingon:getopt cmd :hddl-file) :direction :output :if-exists :supersede))) + (unwind-protect + (print-hddl-plan plan tree stream) + (unless (eq stream t) (close stream)))) + (print-hddl-plan plan tree t)))))))) (defun classic/handler (cmd) (let ((args (clingon:command-arguments cmd)) - (plan-tree (or (clingon:getopt cmd :plan-tree) - (clingon:getopt cmd :tree-file))) + ;; (plan-tree (or (clingon:getopt cmd :plan-tree) + ;; (clingon:getopt cmd :tree-file))) (shop::*define-silently* (zerop (clingon:getopt cmd :verbose)))) (handler-bind ((error (lambda (x) @@ -172,11 +235,12 @@ (format *error-output* "~a" x) (uiop:quit 1))))) (iter (for x in args) - (unless (load x :if-does-not-exist t) - (error "File ~a failed to load." x))) - (multiple-value-bind (plans time trees) - (find-plans shop::*problem* :plan-tree plan-tree :verbose (clingon:getopt cmd :verbose)) - (declare (ignore time)) ; at least for now... + (load-shop-file x)) + (multiple-value-bind (plans ;; time trees + ) + (find-plans shop::*problem* :plan-tree nil ;plan-tree + :verbose (clingon:getopt cmd :verbose)) + ;;(declare (ignore time)) ; at least for now... (unless plans (error "Unable to find a plan for problem ~a" (shop::problem-name shop::*problem*))) @@ -186,20 +250,21 @@ (unwind-protect (print-plan (first plans) plan-stream) (unless (eq plan-stream t) (close plan-stream)))) - (when plan-tree - (let ((stream (alexandria:if-let ((plan-path (clingon:getopt cmd :tree-file))) - (open plan-path :direction :output :if-exists :supersede) - t))) - (unwind-protect - (print-classic-tree (first trees) stream) - (unless (eq stream t) (close stream))))))))) + ;; (when plan-tree + ;; (let ((stream (alexandria:if-let ((plan-path (clingon:getopt cmd :tree-file))) + ;; (open plan-path :direction :output :if-exists :supersede) + ;; t))) + ;; (unwind-protect + ;; (print-classic-tree (first trees) stream) + ;; (unless (eq stream t) (close stream))))) + )))) (defun tree-compare/handler (cmd) (let ((args (clingon:command-arguments cmd))) (handler-bind ((error (lambda (x) (unless *interactive* - (format *error-output* "~a" x) + (format *error-output* "TREE-COMPARE ERROR: ~a" x) (uiop:quit 2))))) (flet ((load-file (filename) (uiop:with-input-file (str filename :if-does-not-exist :error) @@ -210,8 +275,8 @@ cmd args)) (let ((tree1 (load-file (first args))) (tree2 (load-file (second args)))) - (setf tree1 (shop::canonically-order tree1) - tree2 (shop::canonically-order tree2)) + (setf tree1 (shop::canonically-order-plan-tree tree1) + tree2 (shop::canonically-order-plan-tree tree2)) (cond ((equalp tree1 tree2) (format t "~&Trees match.~%") (uiop:quit 0)) diff --git a/shop3/buildapp/test.sh b/shop3/buildapp/test.sh index b5a5348d..439b52de 100755 --- a/shop3/buildapp/test.sh +++ b/shop3/buildapp/test.sh @@ -210,43 +210,45 @@ elif [ "$RES" != "$EXPECTED" ]; then exit 1 fi -echo "Test SHOP with 2 arguments and plan-tree" +# echo "Test SHOP with 2 arguments and plan-tree" -PLAN=$(mktemp -t "planXXXXXX") -PLAN_TREE=$(mktemp -t "treeXXXXXX") -shop --tree-file ${PLAN_TREE} --plan-file ${PLAN} logistic.lisp Log_ran_problems_15.lisp -EC=$? -if [ "$EC" -ne 0 ]; then - echo "Failed to run planner successfully"; - exit $EC -else - RES=`cat ${PLAN}` - if [ "$RES" != "$EXPECTED" ]; then - echo "Plan result did not equal the expected." - exit 1 - fi - compare_trees -fi +# PLAN=$(mktemp -t "planXXXXXX") +# PLAN_TREE=$(mktemp -t "treeXXXXXX") +# shop --tree-file ${PLAN_TREE} --plan-file ${PLAN} logistic.lisp Log_ran_problems_15.lisp +# EC=$? +# if [ "$EC" -ne 0 ]; then +# echo "Failed to run planner successfully"; +# exit $EC +# else +# RES=`cat ${PLAN}` +# if [ "$RES" != "$EXPECTED" ]; then +# echo "Plan result did not equal the expected." +# exit 1 +# fi +# compare_trees +# fi +# echo "... ok" -echo "Test SHOP with 1 argument and plan tree" -INPUT=$(mktemp -t "inputXXXXXX") -cat logistic.lisp > ${INPUT} -cat Log_ran_problems_15.lisp >> ${INPUT} -PLAN=$(mktemp -t "planXXXXXX") -PLAN_TREE=$(mktemp -t "treeXXXXXX") -shop --tree-file ${PLAN_TREE} --plan-file ${PLAN} ${INPUT} -EC=$? -if [ "$EC" -ne 0 ]; then - echo "Failed to run planner successfully"; - exit $EC -else - RES=`cat ${PLAN}` - if [ "$RES" != "$EXPECTED" ]; then - echo "Plan result did not equal the expected." - exit 1 - fi - compare_trees -fi +# echo "Test SHOP with 1 argument and plan tree" +# INPUT=$(mktemp -t "inputXXXXXX") +# cat logistic.lisp > ${INPUT} +# cat Log_ran_problems_15.lisp >> ${INPUT} +# PLAN=$(mktemp -t "planXXXXXX") +# PLAN_TREE=$(mktemp -t "treeXXXXXX") +# shop --tree-file ${PLAN_TREE} --plan-file ${PLAN} ${INPUT} +# EC=$? +# if [ "$EC" -ne 0 ]; then +# echo "Failed to run planner successfully"; +# exit $EC +# else +# RES=`cat ${PLAN}` +# if [ "$RES" != "$EXPECTED" ]; then +# echo "Plan result did not equal the expected." +# exit 1 +# fi +# compare_trees +# fi +# echo "... ok" echo "Test ESS-SHOP with 2 arguments" @@ -260,6 +262,7 @@ elif [ "$RES" != "$EXPECTED" ]; then echo "Plan result did not equal the expected." exit 1 fi +echo "... ok" echo "Test ESS-SHOP with 1 argument" INPUT=$(mktemp -t "input.XXXXXXXXXXX") @@ -274,6 +277,7 @@ elif [ "$RES" != "$EXPECTED" ]; then echo "Plan result did not equal the expected." exit 1 fi +echo "... ok" echo "Test ESS SHOP with 2 arguments and plan-tree" @@ -293,11 +297,11 @@ else # These don't compare properly because the ESS trees have INOP nodes in them # compare_trees fi +echo "... ok" echo "Test ESS SHOP with 1 argument and plan tree" INPUT=$(mktemp -t "inputXXXXXX") -cat logistic.lisp > ${INPUT} -cat Log_ran_problems_15.lisp >> ${INPUT} +cat logistic.lisp Log_ran_problems_15.lisp > ${INPUT} PLAN=$(mktemp -t "planXXXXXX") PLAN_TREE=$(mktemp -t "treeXXXXXX") ess-shop --tree-file ${PLAN_TREE} --plan-file ${PLAN} ${INPUT} @@ -314,6 +318,6 @@ else # These don't compare properly because the ESS trees have INOP nodes in them # compare_trees fi - +echo "... ok" exit 0 diff --git a/shop3/decls.lisp b/shop3/decls.lisp index 27082055..0df8efd0 100644 --- a/shop3/decls.lisp +++ b/shop3/decls.lisp @@ -89,6 +89,7 @@ (defvar *operator-tasks*) ; record of the task atom for operators (declaim (type hash-table *operator-tasks* *task-operator*)) (defvar *task-operator*) ; inverse of *operator-tasks* +(defvar *reduction-labels*) ; support recording method labels in plan tree (hash-table) (defparameter *optimize-cost* nil) ; whether to optimize with branch and bound (defparameter *optimal-plan* 'fail) ; optimal plan found so far (defparameter *optimal-cost* 0) ; cost of *optimal-plan* @@ -110,6 +111,7 @@ (defvar *unifiers-found* nil) ;associated with *PLANS-FOUND* (defvar *states-found* nil) ;associated with *PLANS-FOUND* [2004/09/14:rpg] +(declaim (special *random-generator*)) ; imported from shop.theorem-prover package (defvar *hand-steer* nil "This variable will be DYNAMICALLY bound and used to indicate whether the user @@ -911,3 +913,12 @@ task keyword of TASK and LIBRARY-TASK are the same.") (member thing '(&optional &rest) :test #'eq))) (if (find-if #'rest-or-optional-p types) `(values ,@types) `(values ,@types &optional)))) + +;;;--------------------------------------------------------------------------- +;;; CL:CHECK-TYPE messes up SBCL's type checking, because on continuation +;;; it allows the user to supply an object of a new type. Change it to just +;;; raise a type error. [2024/08/02:rpg] +;;;--------------------------------------------------------------------------- +(defmacro check-type (place type) + `(unless (typep ,place ',type) + (error 'type-error :datum ,place :expected-type ',type))) diff --git a/shop3/docs/Makefile b/shop3/docs/Makefile index 985deb9d..523212b4 100644 --- a/shop3/docs/Makefile +++ b/shop3/docs/Makefile @@ -19,14 +19,15 @@ clean: rm -f include-stamp LISP_SOURCE_DIRS := .. ../common ../explicit-stack-search ../io ../looping-tasks ../minimal-subtree ../pddl \ - ../plan-grapher ../planning-engine ../planning-tree ../shop-theorem-prover.api ../theorem-prover ../unification + ../plan-grapher ../planning-engine ../planning-tree ../shop-theorem-prover.api ../theorem-prover \ + ../unification ../hddl LISP_SOURCES := $(foreach dir,$(LISP_SOURCE_DIRS), $(wildcard $(dir)/*.lisp)) LISP_ASDS := $(foreach dir,$(LISP_SOURCE_DIRS), $(wildcard $(dir)/*.asd)) include-stamp: $(LISP_SOURCES} $(LISP_ASDS) sbcl --no-userinit --eval '(require :asdf)' \ --eval '(progn (require :sb-texinfo)(asdf:load-system :shop3 :force :all) (require :shop3-thmpr-api) (require :shop3/plan-grapher))' \ - --eval '(sb-texinfo:generate-includes "include/" (list :shop3 :shop3.unifier :shop3.common :shop3.theorem-prover :shop3.theorem-prover-api :shop3.plan-grapher :shop-user) :base-package :shop3 :extra-symbols (list (quote shop3.unifier::binding) (quote shop3.common::insert-atom) (quote shop3.common::remove-atom) (quote shop3.common::atom-in-state-p) (quote shop3.common::state-all-atoms-for-predicate) (quote shop3.common::state-candidate-atoms-for-goal)))' \ + --eval '(sb-texinfo:generate-includes "include/" (list :shop3 :shop3.unifier :shop3.common :shop3.theorem-prover :shop3.theorem-prover-api :shop3.plan-grapher :shop-user :hddl-translator) :base-package :shop3 :extra-symbols (list (quote shop3.unifier::binding) (quote shop3.common::insert-atom) (quote shop3.common::remove-atom) (quote shop3.common::atom-in-state-p) (quote shop3.common::state-all-atoms-for-predicate) (quote shop3.common::state-candidate-atoms-for-goal)))' \ --eval '(quit)' touch include-stamp diff --git a/shop3/docs/shop2.pdf b/shop3/docs/shop2.pdf deleted file mode 100644 index ee798cb1..00000000 Binary files a/shop3/docs/shop2.pdf and /dev/null differ diff --git a/shop3/docs/shop3-manual.texinfo b/shop3/docs/shop3-manual.texinfo index ecfbd09b..1694dca0 100644 --- a/shop3/docs/shop3-manual.texinfo +++ b/shop3/docs/shop3-manual.texinfo @@ -76,8 +76,10 @@ College Park, MD 20742, USA * Introduction:: * Execution Environment:: * Running SHOP3:: +* SHOP3 Command-line Applications:: * The SHOP3 Formalism:: * PDDL Support:: +* HDDL Support:: * The SHOP Theorem Prover:: * The SHOP Unifier:: * Plan Grapher:: @@ -293,7 +295,7 @@ To enable it you may have to @c @emph{C@sub{2}} [@emph{name@sub{3}}] @emph{C@sub{3}} @dots{} @c [@emph{name@sub{n}}] @emph{C@sub{n}})” -@node Running SHOP3, The SHOP3 Formalism, Execution Environment, Top +@node Running SHOP3, SHOP3 Command-line Applications, Execution Environment, Top @chapter Running @sysname{} @findex find-plans @findex find-plans-stack @@ -395,7 +397,7 @@ full state trajectories for the plans. @include include/fun-shop-find-plans.texinfo -@node find-plans-stack, do-problems, find-plans, Executing the Planner +@node find-plans-stack, Planning Example, find-plans, Executing the Planner @subsection @code{find-plans-stack} @include include/fun-shop-find-plans-stack.texinfo @@ -500,7 +502,7 @@ For example, @end example -@node do-problems, Common Keyword Arguments, find-plans-stack, Executing the Planner +@node do-problems, Common Keyword Arguments, Planning Example, Executing the Planner @subsection @code{do-problems} The @code{do-problems} function has one mandatory argument, which can either be @@ -982,9 +984,50 @@ defined, @sysname{} invokes that routine with the argument @code{'(and (on ?b1 ? @end lisp @end itemize +@node SHOP3 Command-line Applications, The SHOP3 Formalism, Running SHOP3, Top +@chapter @sysname{} Command-line Applications +@cindex Command-line applications -@node The SHOP3 Formalism, PDDL Support, Running SHOP3, Top +Version 3.11 of @sysname{} introduces the first, @emph{experimental} +@sysname{} command-line applications. These applications are built +using Zack Beane's @url{https://www.xach.com/lisp/buildapp/, Buildapp}, +and we do not yet supply pre-built executables. Ideally, those will be +supplied in Docker containers. + +The command-line applications can be built by going to the +@t{shop3/buildapp/} directory in the source repository and running the +enclosed @t{Makefile}. The Makefile supports the standard @t{DESTDIR} +variable, so that, for example, one can make the applications and +install them in your user directory with a command line like this: + +@example +make clean ; make DESTDIR=~/.local install +@end example + +@t{make} dependencies do @strong{not} propagate from the lisp files that +make up @sysname{}, so for now, at least, it is safest to always run @code{make +clean} before building. + +The three applications that will be installed are: +@enumerate +@item @t{shop} +@item @t{ess-shop} and +@item @t{tree-compare} +@end enumerate + +The former two will read in one or two files, expected to contain a +domain and a problem definition. They will generate plans for @emph{the +most recently defined} problem and the domain it references or, if that +problem does not specify a domain, the most recently defined domain. +They are intended to parallel the way other planners are used. + +@t{tree-compare} as its name suggests, will compare two different +@sysname{} plan trees. It is even more experimental than the other two +applications, and there are still issues with ``classic'' @sysname plan +trees. + +@node The SHOP3 Formalism, PDDL Support, SHOP3 Command-line Applications, Top @chapter The @sysname{} Formalism The inputs to @sysname{} are a @emph{planning domain} and either a single @emph{planning problem} or a @emph{planning problem set}. Planning @@ -1763,7 +1806,6 @@ to be presented in any special order-- @code{:add}, @code{:delete}, etc. are processed as @emph{keyword} (named) arguments. @menu -* Internal Operators:: * Operators must be deterministic:: * Protection conditions:: * Operators Legacy Syntax:: @@ -2257,7 +2299,7 @@ we've covered so far about @sysname. -@node PDDL Support, The SHOP Theorem Prover, The SHOP3 Formalism, Top +@node PDDL Support, HDDL Support, The SHOP3 Formalism, Top @chapter PDDL Support @anchor{#pddl-compatibility} The current release of @sysname{} provides a preliminary capability to @@ -2533,7 +2575,28 @@ existential preconditions, since they are typically used together. @end itemize -@node The SHOP Theorem Prover, The SHOP Unifier, PDDL Support, Top +@node HDDL Support, The SHOP Theorem Prover, PDDL Support, Top +@chapter HDDL Support +@cindex HDDL +@cindex @code{HDDL-translator} package +@cindex @code{shop-hddl} nickname for @code{HDDL-translator} package + +@sysname version 3.11 introduces support for generating HDDL-format +plans from ESS-@sysname{} -- @code{find-plans-stack} and @emph{not} +classic @sysname -- @code{find-plans}. The HDDL plan format is +documented +@url{https://ipc2020.hierarchical-task.net/benchmarks/output-format, +here}. + +HDDL plans are @emph{not} created by some keyword argument to +@code{find-plans-stack}, instead they are created by two functions in +the @code{HDDL-translator} package (whose nicknames include @code{shop-hddl}: + +@include include/fun-shop-hddl-hddl-plan.texinfo + +@include include/fun-shop-hddl-print-hddl-plan.texinfo + +@node The SHOP Theorem Prover, The SHOP Unifier, HDDL Support, Top @chapter The SHOP Theorem Prover @anchor{#using-the-shop-theorem-prover} One of the main extensions that SIFT has made to @sysname{} is to make its diff --git a/shop3/explicit-stack-search/decls.lisp b/shop3/explicit-stack-search/decls.lisp index 963cba4d..5e06116f 100644 --- a/shop3/explicit-stack-search/decls.lisp +++ b/shop3/explicit-stack-search/decls.lisp @@ -26,7 +26,8 @@ in this search MODE." :initarg :world-state :accessor state :accessor world-state - :documentation "SHOP2 world state object." + :type tagged-state + :documentation "SHOP world state object." ) (protections :initarg :protections diff --git a/shop3/explicit-stack-search/explicit-search.lisp b/shop3/explicit-stack-search/explicit-search.lisp index 95de9fba..b35040c9 100644 --- a/shop3/explicit-stack-search/explicit-search.lisp +++ b/shop3/explicit-stack-search/explicit-search.lisp @@ -8,8 +8,6 @@ NIL "When building an ENHANCED-PLAN-TREE, do not record causal links. Defaults to NIL.") -(defvar *include-rationale* nil) - (defgeneric unfold-loop-task (domain state) (:documentation "Driver for the looping tasks.")) @@ -24,7 +22,6 @@ (:gc t) (:no-dependencies t) (:repairable t) - (:rationale t) (:state-type symbol) (:out-stream (or t stream)) (:which (member :first :all)) @@ -37,7 +34,6 @@ (defun find-plans-stack (problem &key domain (verbose 0) plan-tree (gc *gc*) (no-dependencies nil) repairable - rationale (state-type :mixed state-type-supplied-p) (out-stream t) (which :first) @@ -59,7 +55,6 @@ Keyword arguments: * no-dependencies : if building a plan tree, build it *without* causal dependencies. Default: `nil`. * repairable : return plans that can be repaired. Default: `nil`. -* rationale : build a plan tree with rationale information. Default: `nil`. * state-type : what state type should be used for representing world states? (Note: world-state/SHOP state, *not* search-state). Default: `:mixed`. * out-stream : where should output be printed. Default: `t` (standard output). @@ -105,7 +100,6 @@ objects." (*plans-found* nil) (*enhanced-plan-tree* plan-tree) (*no-dependencies* no-dependencies) - (*include-rationale* rationale) (*record-dependencies-p* (and *enhanced-plan-tree* (not *no-dependencies*))) (*verbose* verbose) (*which* which) @@ -497,15 +491,7 @@ of PLAN-RETURN objects." (format t "~%Subtree2: ~s" (make-add-child-to-tree :parent parent :child child)) |# (push - (if *include-rationale* - (make-add-child-to-tree :parent (apply-substitution - (plan-tree::complex-tree-node-task parent) unifier) - :child (apply-substitution - (plan-tree::complex-tree-node-children - child) - unifier)) - ;; else - (make-add-child-to-tree :parent parent :child child)) + (make-add-child-to-tree :parent parent :child child) backtrack-stack) (when *record-dependencies-p* (let ((depends (make-dependencies parent depends (plan-tree-lookup state)))) @@ -514,7 +500,7 @@ of PLAN-RETURN objects." (make-add-dependencies :dependencies depends)))))) (multiple-value-setq (top-tasks tasks) (apply-method-bindings current-task top-tasks tasks - reduction unifier)) + reduction unifier label)) (trace-print :methods label (world-state state) "~2%Depth ~s, applying method ~s~% task ~s~% reduction ~s" depth label current-task reduction) diff --git a/shop3/explicit-stack-search/plan-repair.lisp b/shop3/explicit-stack-search/plan-repair.lisp index fda604cf..d2c20c94 100644 --- a/shop3/explicit-stack-search/plan-repair.lisp +++ b/shop3/explicit-stack-search/plan-repair.lisp @@ -30,61 +30,65 @@ DIVERGENCE: Divergence between the expected state after EXECUTED, specified as ( SEARCH-STATE: Search state object PLAN-TREE-HASH: Hash table indexing and optimizing access to PLAN-TREE. This is optional -- we can manage access anyway, but it will be slower. -Returns: (1) new plan (2) new plan tree (enhanced plan tree, not old-style SHOP plan tree) -\(3\) plan tree lookup table (4) search-state object." +Returns: + 1. new plan WITHOUT COSTS or INTERNAL ACTIONS + 2. new plan tree (enhanced plan tree, not old-style SHOP plan tree) + 3. plan tree lookup table + 4. search-state object." (check-type divergence divergence-list) (let ((*verbose* verbose)) - (handler-bind - ((no-failed-task #'(lambda (nft) - (format *error-output* "Got no failed task error: ~a~%" nft) - (force-output *error-output*) - (case no-failed-task - (:error (cerror "Just continue and return unmodified plan" - "Divergence should cause some task failure.")) - (:retry (return-from repair-plan :no-failed-task)))))) - (multiple-value-bind (failed ; tree node -- this is the node that must be *replanned*, not the node whose preconditions are violated. It's the *parent* of the node that has actually failed. - failed-action) ; The failed action is EITHER the first action whose dependencies are broken OR the leftmost leaf child of the leftmost broken complex task - ;; we find the failed tree node by looking UP from the actions in the plan. - (subtree:find-failed-task domain plan plan-tree executed - divergence :plan-tree-hash plan-tree-hash) - (verbose-format "~&Failing task is:~%~T~A~%Failing action is:~%~T~A~%" failed failed-action) - (if failed - (let ((new-search-state (freeze-state executed failed-action divergence search-state))) - #+nil(break "Inspect NEW-SEARCH-STATE.") - (multiple-value-bind (new-plans new-plan-trees lookup-tables final-search-state) - (let ((*plan-tree* nil) ; plan tree should never be true when using Explicit Stack Search. - (*enhanced-plan-tree* t)) - (replan-from-failure domain failed new-search-state :verbose verbose)) - (when new-plans - (let ((new-plan (first new-plans)) - (new-plan-tree (first new-plan-trees)) - (new-lookup-table (first lookup-tables)) - (plan-has-costs (numberp (second (first new-plans))))) - (multiple-value-bind (prefix suffix) - (extract-suffix new-plan executed) - (values - ;; new plan sequence - (append prefix - (if plan-has-costs - (list (cons :divergence divergence) 0.0) - (list (cons :divergence divergence))) - suffix) - new-plan-tree - new-lookup-table - final-search-state)))))) - ;; the old plan is good - (multiple-value-bind (prefix suffix) - (extract-suffix plan executed) - (signal 'no-failed-task) - (values - (append prefix - (if (numberp (second plan)) ;plan with costs? - (list (cons :divergence divergence) 0.0) - (list (cons :divergence divergence))) - suffix) - plan-tree - plan-tree-hash - search-state))))))) + (verbose-format "Divergence after step ~d (from 1) is:~%~s~%" (length executed) divergence) + (handler-bind + ((no-failed-task #'(lambda (nft) + (format *error-output* "Got no failed task error: ~a~%" nft) + (force-output *error-output*) + (case no-failed-task + (:error (cerror "Just continue and return unmodified plan" + "Divergence should cause some task failure.")) + (:retry (return-from repair-plan :no-failed-task)))))) + (multiple-value-bind (failed ; tree node -- this is the node that must be *replanned*, not the node whose preconditions are violated. + ; It's the *parent* of the node that has actually failed. + failed-action ; The failed action is EITHER the first action whose dependencies are broken + ; OR the leftmost leaf child of the leftmost broken complex task + ) + ;; we find the failed tree node by looking UP from the actions in the plan. + (subtree:find-failed-task domain plan plan-tree executed + divergence :plan-tree-hash plan-tree-hash) + (verbose-format "~&Failing task is:~%~T~A~%Failing action is:~%~T~A~%" failed failed-action) + (if failed + (let ((new-search-state (freeze-state executed failed-action divergence search-state))) + #+nil(break "Inspect NEW-SEARCH-STATE.") + (multiple-value-bind (new-plans new-plan-trees lookup-tables final-search-state) + (let ((*plan-tree* nil) ; plan tree should never be true when using Explicit Stack Search. + (*enhanced-plan-tree* t)) + (replan-from-failure domain failed new-search-state :verbose verbose)) + (when new-plans + (let ((new-plan (first new-plans)) + (new-plan-tree (first new-plan-trees)) + (new-lookup-table (first lookup-tables))) + (multiple-value-bind (prefix suffix) + (extract-suffix new-plan executed) + (values + ;; new plan sequence + (append (shorter-plan prefix) + (list (cons :divergence divergence)) + (shorter-plan suffix)) + new-plan-tree + new-lookup-table + final-search-state)))))) + ;; the old plan is good + (multiple-value-bind (prefix suffix) + (extract-suffix plan executed) + (signal 'no-failed-task) + (values + (append prefix + (if (numberp (second plan)) ;plan with costs? + (list (cons :divergence divergence) 0.0) + (list (cons :divergence divergence))) + suffix) + plan-tree + plan-tree-hash + search-state))))))) (defgeneric find-failed-stack-entry (failed obj) (:documentation "Find and return the stack entry that corresponds @@ -193,6 +197,20 @@ BEFORE the insertion of FAILED into the plan tree.") (return (values new-prefix plan-copy)))))) +;;; SHOP assigns integers as world state tags according to a +;;; magic formula. This tells us what will be the world state +;;; tag after the actions in EXECUTED are executed. +(defun find-world-state-tag (executed) + ;; we have to find the index of the last executed action. The + ;; NUMBERP check is to make sure that we can handle plans + ;; with and without the cost numbers. + (* (if (some #'numberp executed) ; if there are costs in the plan + (/ (length executed) 2) + (length executed)) + ;; magic constant for the tag increment per + ;; operator. + 2)) + (defun freeze-state (executed failed-action divergence search-state) "Arguments: PLAN: sequence of primitive actions. @@ -210,28 +228,24 @@ Modified search state object." ;; we have to find the index of the last executed action. The ;; NUMBERP check is to make sure that we can handle plans ;; with and without the cost numbers. - (world-state-tag (* (if (some #'numberp executed) ; if there are costs in the plan - (/ (length executed) 2) - (length executed)) - ;; magic constant for the tag increment per - ;; operator. - 2)) + (world-state-tag (find-world-state-tag executed)) ;; can't correctly apply state updates beyond here - (failed-action-tag (tag-for-action failed-action)) + (failed-action-tag + (tag-for-action failed-action)) (new-state-obj (shop2.common::copy-state world-state))) (assert (integerp world-state-tag)) #+nil(break "Inside FREEZE-STATE") - ;; this gives us the state right after the execution of the "failed" action. - (shop2.common:retract-state-changes new-state-obj (1+ world-state-tag)) - #+ignore(break "Inside FREEZE-STATE, before adding divergences, world state is: ~S" new-state-obj) + ;; this gives us the state right after the execution of the action immediately + ;; before the divergence (i.e., after EXECUTED). + (shop.common:retract-state-changes new-state-obj (1+ world-state-tag)) ;; now put the divergences into effect, taking sleazy advantage of the fact that the ;; world state tag increments by two. (let ((new-tag - (shop2.common:tag-state new-state-obj 1))) + (shop.common:tag-state new-state-obj 1))) (iter (for (op fact) in divergence) (ecase op - (:add (shop2.common:add-atom-to-state fact new-state-obj 0 :execution-divergence)) - (:delete (shop2.common:delete-atom-from-state fact new-state-obj 0 :execution-divergence)))) + (:add (shop.common:add-atom-to-state fact new-state-obj 0 :execution-divergence)) + (:delete (shop.common:delete-atom-from-state fact new-state-obj 0 :execution-divergence)))) ;; now make it impossible to backtrack before this point... (setf (shop2.common::tagged-state-block-at new-state-obj) new-tag)) #+ignore(break "After freezing, before rolling forward, state is: ~s" new-state-obj) @@ -250,10 +264,10 @@ Modified search state object." ;; now put the new world state in place... (setf (world-state search-state) new-state-obj) - (format t "~&At start of plan repair, state is: ~%") - (print-current-state :state new-state-obj - :sorted t) - #+nil (break "Check it out..." ) + (when (> *verbose* 1) + (format t "~&At start of plan repair, state is: ~%") + (print-current-state :state new-state-obj + :sorted t)) search-state))) diff --git a/shop3/explicit-stack-search/plan-tree.lisp b/shop3/explicit-stack-search/plan-tree.lisp index 71118ba0..18eb1224 100644 --- a/shop3/explicit-stack-search/plan-tree.lisp +++ b/shop3/explicit-stack-search/plan-tree.lisp @@ -88,23 +88,27 @@ cross-links for VAL using information in TABLE.")) (defun make-cross-links (&optional (table *table-for-load-form*)) (iter (for (val var) in-hashtable table) (unless (listp val) - (appending + (appending (cross-links-for var val table))))) (defmethod make-instantiator ((obj primitive-tree-node)) `(make-primitive-tree-node ,@ (slot-fillers obj))) (defstruct (complex-tree-node (:include tree-node)) - children + (children nil :type list) + ;; FIXME: Move this slot to a structure that is guaranteed to have a method name? + ;; the pseudo-tree children won't... (method-name nil :type (or null symbol))) + + (defmethod make-instantiator ((obj complex-tree-node)) `(make-complex-tree-node ,@ (slot-fillers obj))) (defmethod cross-links-for ((var-name symbol) (obj complex-tree-node) (table hash-table)) (append (call-next-method) `((setf (complex-tree-node-children ,var-name) - (list + (list ,@(mapcar #'(lambda (x) (slot-value-translator x table)) (complex-tree-node-children obj))))))) @@ -138,7 +142,7 @@ and building a toplogically sorted list of nodes.")) (defun obj-bindings (hash-table) "Return an ordered list of variable-name instantiator pairs for use in a LET form." - (append + (append (iter (for (item var-name) in-hashtable hash-table) ;; proposition or task (when (listp item) @@ -190,6 +194,7 @@ and building a toplogically sorted list of nodes.")) (call-next-method) (mapc #'make-table-entries (complex-tree-node-children obj))) +;; FIXME: likely this should be a pseudo-node (defstruct (pseudo-node (:include complex-tree-node))) ;;; maybe should revise this and have complex-tree-node as mixin, since @@ -211,6 +216,31 @@ Particularly useful for structures, but could be generally applicable." (print-unreadable-object ,args ,@body))) +(defmethod print-object ((node complex-tree-node) stream) + (print-unreadably (node stream) + (print-unreadable-object (node stream :type t :identity nil) + (format stream "~A --~A-> ~a" + (tree-node-task node) + (alexandria:if-let ((method-name (complex-tree-node-method-name node))) + method-name "") + (let* ((children (complex-tree-node-children node)) + (n (length children))) + (ecase n + (0 "no children") + (1 + (let ((child (first children))) + (etypecase child + ((or ordered-tree-node unordered-tree-node) + (let ((n (length (complex-tree-node-children child)))) + (format nil "~d ~a child~:[~;ren~]" + n + (if (typep child 'ordered-tree-node) + "ordered" + "unordered") + (> n 1)))) + (primitive-tree-node "1 primitive child") + (complex-tree-node "1 complex child")))))))))) + (defmethod print-object ((d dependency) str) (print-unreadably (d str) @@ -234,14 +264,14 @@ Particularly useful for structures, but could be generally applicable." (complex-tree-node-children d)))) -(defmethod print-object ((d complex-tree-node) str) - (print-unreadably (d str) - (format str "Complex: ~S :CHILDREN ~A" - (or (tree-node-expanded-task d) - (tree-node-task d)) - (complex-tree-node-children d)) - #+ignore(when (tree-node-dependencies d) - (format str " :DEPENDENCIES ~S "(tree-node-dependencies d))))) +;; (defmethod print-object ((d complex-tree-node) str) +;; (print-unreadably (d str) +;; (format str "Complex: ~S :CHILDREN ~A" +;; (or (tree-node-expanded-task d) +;; (tree-node-task d)) +;; (complex-tree-node-children d)) +;; #+ignore(when (tree-node-dependencies d) +;; (format str " :DEPENDENCIES ~S "(tree-node-dependencies d))))) (defmethod print-object ((d ordered-tree-node) str) @@ -263,7 +293,7 @@ Particularly useful for structures, but could be generally applicable." (:method ((top top-node)) (mapcar #'plan-tree->sexp (complex-tree-node-children top))) (:method ((cn complex-tree-node)) - `(,(tree-node-task cn) . ,(mapcar #'plan-tree->sexp (complex-tree-node-children cn)))) + `(,(or (tree-node-expanded-task cn) (tree-node-task cn)) . ,(mapcar #'plan-tree->sexp (complex-tree-node-children cn)))) (:method ((on ordered-tree-node)) (mapcar #'plan-tree->sexp (complex-tree-node-children on))) (:method ((un unordered-tree-node)) @@ -276,7 +306,8 @@ Particularly useful for structures, but could be generally applicable." (labels ((tree-search (plan-tree) (etypecase plan-tree (primitive-tree-node - (when (eq task (tree-node-task plan-tree)) + (when (or (eq task (tree-node-task plan-tree)) + (eq task (tree-node-expanded-task plan-tree))) plan-tree)) (complex-tree-node (iter (for tree-node in (complex-tree-node-children plan-tree)) @@ -327,6 +358,16 @@ Particularly useful for structures, but could be generally applicable." (when result (return-from find-tree-node-if result)))))))) (tree-search plan-tree))) +(defun all-primitive-nodes (plan-tree) + (let (retval) + (labels ((tree-search (plan-tree) + (etypecase plan-tree + (primitive-tree-node (push plan-tree retval)) + (complex-tree-node + (mapc #'tree-search (complex-tree-node-children plan-tree)))))) + (tree-search plan-tree) + retval))) + (defgeneric copy-plan-tree-node (node) (:method ((node primitive-tree-node)) (copy-primitive-tree-node node)) diff --git a/shop3/hddl/hddl-plan.lisp b/shop3/hddl/hddl-plan.lisp new file mode 100644 index 00000000..34127af7 --- /dev/null +++ b/shop3/hddl/hddl-plan.lisp @@ -0,0 +1,327 @@ +;;;--------------------------------------------------------------------------- +;;; Copyright Smart Information Flow Technologies, d/b/a SIFT, LLC +;;; All rights reserved. +;;; +;;; SIFT PROPRIETARY +;;;--------------------------------------------------------------------------- +;;; File Description: +;;; +;;; Code for translating SHOP plans (currently only as generated by ESS/ +;;; FIND-PLANS-STACK) into HDDL format plans. +;;; +;;; History/Bugs/Notes: +;;; +;;; [2023/10/31:rpg] Created. +;;; +;;;--------------------------------------------------------------------------- + + +(in-package :common-lisp-user) + +(defpackage hddl-translator + (:nicknames #:shop-hddl #:hddl-shop) + (:export #:hddl-plan #:print-hddl-plan) + (:use :common-lisp :alexandria :iterate)) + +(in-package :hddl-translator) + +;;;--------------------------------------------------------------------------- +;;; Type declarations for specifying function return values that make +;;; SBCL happy. +;;;--------------------------------------------------------------------------- + +(deftype only-values (&rest value-spec) + `(values ,@value-spec &optional)) + +(deftype only-value (value-spec) + `(values ,value-spec &optional)) + +(defstruct decomposition-record + (node-id -1 :type fixnum) + task + (method-name nil :type symbol) + (children () :type list ; of integers + )) + +;;;--------------------------------------------------------------------------- +;;; API that is intended to work for both original SHOP plan trees and ESS +;;; SHOP plan trees. Not really exercised right now, because it's proven too +;;; hard to support HDDL output from classic SHOP. +;;;--------------------------------------------------------------------------- + +(defun tree-node-task (node) + (cond ((typep node 'shop:primitive-node) + (shop:primitive-node-task node)) + ((typep node 'shop:complex-node) + (shop:complex-node-task node)) + ((plan-tree:tree-node-p node) + (let ((task (plan-tree:tree-node-task node)) + (expanded-task (plan-tree:tree-node-expanded-task node))) + (cond ((shop:groundp expanded-task) + expanded-task) + ((shop:groundp task) + task) + (t (error "Task for tree node ~a is not ground." node))))) + (t (error 'type-error :expected-type '(or shop:primitive-node shop:complex-node plan-tree:tree-node) + :datum node)))) + +(defun complex-node-task (node) + (cond ((or (shop:complex-node-p node) + (typep node 'plan-tree:complex-tree-node)) + (tree-node-task node)) + (t (error 'type-error :expected-type '(or shop:complex-node plan-tree:complex-tree-node) + :datum node)))) + +(defun complex-node-p (node) + (or (shop:complex-node-p node) + (typep node 'plan-tree:complex-tree-node))) + +(defun primitive-node-p (node) + (or (shop:primitive-node-p node) + (typep node 'plan-tree:primitive-tree-node))) + +(defun complex-node-reduction-label (node) + (cond ((shop:complex-node-p node) + (shop:complex-node-reduction-label node)) + ((typep node 'plan-tree:complex-tree-node) + (plan-tree:complex-tree-node-method-name node)) + (t (error 'type-error :expected-type '(or shop:complex-node plan-tree:complex-tree-node) + :datum node)))) + +;;;--------------------------------------------------------------------------- +;;; End of plan tree abstraction API +;;;--------------------------------------------------------------------------- + + +;;; for translation to HDDL, pseudo nodes like unordered and ordered nodes +;;; need to be removed from the plan tree. The RESOLVE-EXTENDED-PLAN-TREE-CHILD(REN) +;;; functions do that +(declaim (ftype (function (plan-tree:tree-node) + #-allegro + (only-value list) ; .. of tree nodes + #+allegro + (values list) + ) + resolve-extended-plan-tree-child) + (ftype (function (list) ; of tree nodes + #-allegro (only-value list) ; list of tree nodes + #+allegro (values list) + ) + resolve-extended-plan-tree-children)) + +;;(defvar *node-rewrite-fun*) + + +(defun resolve-extended-plan-tree-children (children) + (alexandria:mappend #'resolve-extended-plan-tree-child children)) + + +(defun resolve-extended-plan-tree-child (child) + "If CHILD is a pseudo-node (e.g., ordered or unordered), skip it and +return its children instead. Needed for ESS plan trees. + Also handle domain-specific rewriting of the plan-tree. + This function will always return a LIST of children." + #+ignore(when *node-rewrite-fun* + (when-let ((rewritten (funcall *node-rewrite-fun* child))) + (return-from resolve-extended-plan-tree-child + (resolve-extended-plan-tree-children rewritten)))) + (etypecase child + ((or plan-tree:pseudo-node plan-tree:top-node) + (resolve-extended-plan-tree-children (plan-tree:complex-tree-node-children child))) + (plan-tree:tree-node (list child)))) + +(defun complex-node-children (node) + (cond ((shop:complex-node-p node) + (shop:complex-node-children node)) + ((typep node 'plan-tree:complex-tree-node) + (resolve-extended-plan-tree-children (plan-tree:complex-tree-node-children node))) + (t (error 'type-error :expected-type '(or shop:complex-node plan-tree:complex-tree-node) + :datum node)))) + +(defvar *task-indices*) +(defvar *next-index*) + +(declaim (ftype (function (list) #-allegro (only-values fixnum boolean) + #+allegro (values fixnum boolean)) + task-index) + ;; FIXME: could give better type for parameter below + (ftype (function (t) #-allegro (only-values fixnum boolean) + #+allegro (values fixnum boolean)) + node-index)) +(defun task-index (task) + (if-let ((value (gethash task *task-indices*))) + (values value t) + (let ((index + (setf (gethash task *task-indices*) *next-index*))) + (incf *next-index*) + (values index nil)))) + +(defun node-index (node) + (task-index (tree-node-task node))) + +(defun hddl-plan (plan tree &key orphans-ok (verbose 0)) + "Take a SHOP PLAN and TREE (really a forest) as input and produce an +HDDL plan encoded as an s-expression. Note that currently only the extended +plan trees produced by `find-plans-stack` can be used with this function. +Classic SHOP plans do not contain all the required information." + ;; set up tables for indexing + (let ((*next-index* 1) + (*task-indices* (make-hash-table :test 'eq))) + (let ((indexed-plan (index-shop-plan (shop:shorter-plan plan))) + (root-tasks (forest-roots tree)) + roots decompositions) + ;; (format t "~&*next-index* = ~d~%Root tasks are: ~S~%" *next-index* root-tasks) + (setf roots + (iter (for root in root-tasks) + (as i = (task-index root)) + (collecting i))) + (setf decompositions (plan-tree->decompositions tree :orphans-ok orphans-ok :verbose verbose)) + `(:hddl-plan + :actions ,indexed-plan + :roots ,roots + :decompositions ,decompositions + )))) + +(defun plan-tree->decompositions (tree &key orphans-ok (verbose 0)) + (declare (optimize debug)) + (let* ((open (etypecase tree + (list tree) + (plan-tree:top-node (resolve-extended-plan-tree-child tree)))) + (top-nodes (copy-list open))) + ;; (format t "~&Starting to compute decompositions:~%") + ;; (iter (for x in top-nodes) + ;; (format t "~&~T~S = ~d~%" + ;; x (node-index x))) + ;; first pass for indexing + (iter + (while open) + (as node = (pop open)) + (with found) + ;; Don't index internal operators + (unless (shop::internal-operator-p + (shop:task-name (tree-node-task node))) + (setf found (nth-value 1 (task-index (tree-node-task node)))) + (cond ((primitive-node-p node) + (unless found + (error "Found new primitive node: all primitive nodes should be indexed already."))) + ((typep node 'plan-tree:pseudo-node) + (error "Tried to index a pseudo-node.")) + ((complex-node-p node) + (when (and found (not (find node top-nodes :test 'eq))) + (error "Found a previously indexed complex node ~A in indexing pass." node)) + (let* ((children (complex-node-children node)) + (cc (remove-if #'primitive-node-p children))) + (appendf open cc))))))) + + (let ((open (etypecase tree + (list tree) + (plan-tree:top-node (resolve-extended-plan-tree-child tree)))) + ;; note that visited is 0-indexed and the indices have 1 as their origin. + (visited (make-array (1- *next-index*) :element-type 'boolean :initial-element nil)) + retval) + (flet ((set-visited (i) + (setf (aref visited (1- i)) t)) + (arr-index->index (i) + (1+ i))) + (iter + (while open) + (as node = (pop open)) + (with id) (with found) + (multiple-value-setq (id found) (task-index (tree-node-task node))) + (unless found + (error "All nodes should have been indexed before the pass to construct the decomposition records.")) + (set-visited id) ; convert 1-based to 0 + (when (complex-node-p node) + ;; children here have been resolved so that pseudo-nodes + ;; have been skipped + (let ((children (complex-node-children node))) + (iter (for child in children) + (with cindex) (with found) + (unless (shop::internal-operator-p + (shop:task-name (tree-node-task child))) + (multiple-value-setq (cindex found) + (node-index child)) + (unless found + (error "Unable to find an index for node ~a child of ~a" + child node)) + (if (complex-node-p child) + (push child open) + ;; must mark primitive nodes here + (set-visited cindex)) + (collecting cindex into child-indices)) + (finally + (push (make-decomposition-record :node-id id + :task (tree-node-task node) + :method-name (complex-node-reduction-label node) + :children child-indices) + retval)))))) + (unless (every #'identity visited) + (unless (and orphans-ok (< verbose 1)) + (let ((unvisited (iter (for x in-vector visited with-index i) + (unless x (collecting (arr-index->index i)))))) ; correct zero-based to 1-based + (if orphans-ok + (format t ";;; PLAN-TREE->DECOMPOSITIONS: Some tree node~p ~:[was~;were~] not visited when building the decomposition records: ~{~d~^,~}" + (length unvisited) + (> (length unvisited) 1) + unvisited) + (error "Some tree node~p ~:[was~;were~] not visited when building the decomposition records: ~{~d~^,~}" + (length unvisited) + (> (length unvisited) 1) + unvisited))))) + (sort retval #'< :key #'(lambda (dr) (decomposition-record-node-id dr)))))) + +#-allegro +(declaim (ftype (function (symbol) (only-value symbol)) + hddl-action-name)) +(defun hddl-action-name (shop-action-name) + "Return a new action name for HDDL. Typically the SHOP +action name only with any leading exclamation marks removed. + +Takes symbol as argument and returns symbol in same package." + (let* ((name (symbol-name shop-action-name)) + (new-name (string-left-trim '(#\!) name))) + (nth-value 0 (intern new-name (symbol-package shop-action-name))))) + + +(defun print-hddl-plan (hddl-plan &optional (stream t)) + "Takes an HDDL plan, an S-EXPRESSION produced by HDDL-PLAN, +and prints it to STREAM in the IPC format." + (destructuring-bind (keyword &rest plan) hddl-plan + (assert (eq keyword :hddl-plan)) + (format stream "~&==>~%") + (let ((*print-right-margin* most-positive-fixnum) + (*print-case* :downcase)) + ;; print the plan steps + (iter (for (i . act) in (getf plan :actions)) + (format stream "~d (~a~{ ~a~})~%" + i (hddl-action-name (first act)) (rest act))) + ;; print the plan decompositions + (format stream "~&root ~{~d~^ ~}~%" (getf plan :roots)) + (let ((tree-decompositions (getf plan :decompositions))) + (iter (for decomp in (sort (copy-list tree-decompositions) #'< + :key #'(lambda (x) (decomposition-record-node-id x)))) + (format stream "~d ~a -> ~a~{ ~d~}~%" + (decomposition-record-node-id decomp) + (decomposition-record-task decomp) + (decomposition-record-method-name decomp) + (decomposition-record-children decomp))))) + (format stream "~&<==~%") + (finish-output stream))) + +#-allegro +(declaim (ftype (function (list) (only-value list)) + index-shop-plan)) +(defun index-shop-plan (action-list) + (iter (for a in action-list) + (multiple-value-bind (i found) + (task-index a) + (when found (error "Found a duplicate task ~S (previously indexed) in plan-list" + a)) + (collecting (cons i a))))) + +(defun forest-roots (plan-tree) + (mapcar #'tree-node-task + (etypecase plan-tree + (plan-tree::top-node + (resolve-extended-plan-tree-children (plan-tree:complex-tree-node-children plan-tree))) + (list plan-tree)))) diff --git a/shop3/minimal-subtree/minimal-subtree.lisp b/shop3/minimal-subtree/minimal-subtree.lisp index b5201e86..9cac695c 100644 --- a/shop3/minimal-subtree/minimal-subtree.lisp +++ b/shop3/minimal-subtree/minimal-subtree.lisp @@ -16,7 +16,7 @@ ;;; Note: the current version of this file assumes that the primitive ;;; task s-expressions in PLAN and PLAN-TREE are EQ -- i.e., pointers -;;; to the same lists. If you pull the plans out of SHOP2, that will +;;; to the same lists. If you pull the plans out of SHOP, that will ;;; be the case, but if you save and reload plans, it might not be. ;;; Caveat lisper! (defmethod find-failed-task ((domain domain) plan @@ -98,4 +98,3 @@ checking (i.e., top-down)." (find-if #'(lambda (x) (and (eq (first x) :delete) (equalp (second x) prop))) divergence-list)) - diff --git a/shop3/package.lisp b/shop3/package.lisp index c72c76e9..c1b36efb 100644 --- a/shop3/package.lisp +++ b/shop3/package.lisp @@ -63,6 +63,8 @@ (:documentation "The SHOP3 package is the package that exposes SHOP3's API.") (:use :common-lisp :shop3.unifier :shop3.common :shop3.theorem-prover :iterate) + ;; override this... + (:shadow #:check-type) (:import-from #:shop3.common #:domain-core) (:import-from #:shop3.theorem-prover #:+numerical-comparisons+ #:fluent-value @@ -70,13 +72,15 @@ #:fluents-mixin #:fluent-function-p #:fluent-expr-p - #:fluent-comparison-p) + #:fluent-comparison-p + #:*random-generator*) ;; so can be imported into prepare-return-values (:intern #:make-plan-copy) (:import-from #:shop3.unifier #:+primitive-property-name+ #:primitive-symbol-p) + (:shadowing-import-from #:shop3.theorem-prover #:random #:shop-random) + #+sbcl (:shadow #:defconstant) - (:shadow #:domain) (:export #:shop-fail #:domain-axioms #:domain-name @@ -86,6 +90,9 @@ #:*domain* #:*current-state* #:*inferences* #:*external-access* #:*attribution-list* #:*state-encoding* + #:*random-generator* + #:shop-random + ;; quash some default definition messages #:*define-silently* @@ -259,10 +266,13 @@ #:complex-node-p #:complex-node-task #:complex-node-children + #:complex-node-reduction-label + #:complex-node #:primitive-node-p #:primitive-node-task #:primitive-node-cost #:primitive-node-position + #:primitive-node #:remove-internal-operators #:tree-node-task #:tree-node-task-name @@ -306,8 +316,13 @@ #:validator-export #:write-pddl-plan + ;; Class that encapsulates SHOP's many return values + #:plan-return + ;; exporting so that it can be overridden - plan-value)) + #:plan-value + + #:shop-random)) (defpackage plan-tree (:nicknames shop-extended-plan-tree) @@ -320,6 +335,7 @@ #:consumer #:prop #:tree-node + #:tree-node-p #:tree-node-task #:tree-node-expanded-task #:tree-node-dependencies diff --git a/shop3/pddl/pddl-helpers.lisp b/shop3/pddl/pddl-helpers.lisp index f8abf6ad..b385e73b 100644 --- a/shop3/pddl/pddl-helpers.lisp +++ b/shop3/pddl/pddl-helpers.lisp @@ -18,11 +18,12 @@ (defpackage shop3-pddl-helpers (:use #:common-lisp #:iterate #:pddl-utils #:shop3) (:nicknames #:shop3.pddl.helpers #:shop2-pddl-helpers) - (:shadowing-import-from #:pddl-utils #:problem) + ;;(:shadowing-import-from #:pddl-utils #:problem) (:shadowing-import-from #:shop3 #:domain-name #:make-problem #:domain + ;; #:problem #:*validator-progname*) - (:shadow #:problem-name) + (:shadow #:problem-name #:problem) (:export #:typed-object-list->facts #:translate-openstacks-problem #:check-repair @@ -50,7 +51,7 @@ (every #'(lambda (x) (or (eq (first x) :add) (eq (first x) :delete))) (rest divergence)))) - (let* ((effects + (let* ((effects (iter (for (op literal) in (rest divergence)) (collecting (ecase op diff --git a/shop3/pddl/pddl.lisp b/shop3/pddl/pddl.lisp index f86e7e45..b223dc70 100644 --- a/shop3/pddl/pddl.lisp +++ b/shop3/pddl/pddl.lisp @@ -90,7 +90,7 @@ This is an easier to use interface to the validator-export function, qv." (when (and filename stream-supplied-p) (error "Cannot supply both a filename and stream destination for write-pddl-plan.")) (when filename - (setf stream (open filename :direction :output))) + (setf stream (open filename :direction :output :if-exists :supersede))) (unwind-protect (validator-export shop3-domain shop-plan stream) (when filename (close stream))))) diff --git a/shop3/pddl/validate-repairs.lisp b/shop3/pddl/validate-repairs.lisp index 4acbf0de..aa7f6a28 100644 --- a/shop3/pddl/validate-repairs.lisp +++ b/shop3/pddl/validate-repairs.lisp @@ -1,6 +1,6 @@ ;;;--------------------------------------------------------------------------- ;;; Copyright Smart Information Flow Technologies, d/b/a SIFT, LLC -;;; +;;; ;;; ;;;--------------------------------------------------------------------------- ;;; File Description: @@ -19,7 +19,7 @@ (on-failure nil)) (let* ((shop-domain (etypecase shop-domain (symbol (shop2:find-domain shop-domain)) - (shop2::domain shop-domain))) + (shop::domain shop-domain))) (pddl-domain (coerce-pddl-argument pddl-domain)) (pddl-problem (coerce-pddl-argument pddl-problem)) (pddl-plan-sexp (pddl-plan-for-replan repaired-plan :shop-domain shop-domain :package package)) @@ -116,7 +116,7 @@ the divergence pseudo-action injected so that validate can process the result." (let ((new-plan (copy-list repaired-plan))) (setf (nth pos new-plan) (list (intern (string :divergence) package))) - (pddl-utils:pddlify-tree (shop2::pddl-plan shop-domain new-plan))))) + (pddl-utils:pddlify-tree (shop::pddl-plan shop-domain new-plan))))) (defun find-divergence (shop-plan) (find-if #'(lambda (x) (when (listp x) ; ignore costs, if present diff --git a/shop3/planning-engine/search.lisp b/shop3/planning-engine/search.lisp index e32d7cda..c827454f 100644 --- a/shop3/planning-engine/search.lisp +++ b/shop3/planning-engine/search.lisp @@ -285,26 +285,26 @@ of SHOP2." do (trace-print :methods label state "~2%Depth ~s, applying method ~s~% task ~s~% precond ~s~% reduction ~s" depth label task1 (fourth method) reduction) - (trace-print :tasks task-name state - "~2%Depth ~s, reduced task ~s~% reduction ~s" - depth task1 reduction) - (multiple-value-bind (top-tasks1 tasks1) - (apply-method-bindings task1 top-tasks tasks reduction u1) - (cond ((or results methods) ; is there more work to do? - (let ((*more-tasks-p* t)) ; yes, there is + (trace-print :tasks task-name state + "~2%Depth ~s, reduced task ~s~% reduction ~s" + depth task1 reduction) + (multiple-value-bind (top-tasks1 tasks1) + (apply-method-bindings task1 top-tasks tasks reduction u1 label) + (cond ((or results methods) ; is there more work to do? + (let ((*more-tasks-p* t)) ; yes, there is + (seek-plans domain state tasks1 top-tasks1 partial-plan + partial-plan-cost (1+ depth) which-plans + protections u1)) + (when-done + (return-from seek-plans-nonprimitive nil))) + (t (return-from seek-plans-nonprimitive ; no, tail call ok (seek-plans domain state tasks1 top-tasks1 partial-plan partial-plan-cost (1+ depth) which-plans - protections u1)) - (when-done - (return-from seek-plans-nonprimitive nil))) - (t (return-from seek-plans-nonprimitive ; no, tail call ok - (seek-plans domain state tasks1 top-tasks1 partial-plan - partial-plan-cost (1+ depth) which-plans - protections u1))))))))))) - -(defun apply-method-bindings (task top-tasks tasks reduction unifier) + protections u1))))))))))) + +(defun apply-method-bindings (task top-tasks tasks reduction unifier &optional method-label) (when *plan-tree* - (record-reduction task reduction unifier)) + (record-reduction task reduction unifier method-label)) (let ((top-tasks1 (replace-task-top-list top-tasks task reduction)) (new-task-net (replace-task-main-list tasks task reduction))) (values top-tasks1 new-task-net))) diff --git a/shop3/planning-tree/tree-accessors.lisp b/shop3/planning-tree/tree-accessors.lisp index 75b2d003..0a172de4 100644 --- a/shop3/planning-tree/tree-accessors.lisp +++ b/shop3/planning-tree/tree-accessors.lisp @@ -55,14 +55,16 @@ (in-package :shop) (defstruct (complex-node (:type list) - (:constructor make-complex-node (task children))) + (:constructor make-complex-node (task children &key reduction-label))) task + (reduction-label nil :type symbol) children) (defun complex-node-p (tree-node) "Is TREE-NODE a representation of a complex node (i.e., not an operator) in the SHOP2 tree format as described in SHOP2?" - (and (listp (first tree-node)) + (and (listp tree-node) + (listp (first tree-node)) (symbolp (first (first tree-node))))) (deftype complex-node () @@ -84,7 +86,8 @@ the SHOP2 tree format as described in SHOP2?" (defun primitive-node-p (tree-node) "Is TREE-NODE a representation of a primitive node (i.e., an operator) in the SHOP2 tree format as described in SHOP2?" - (and (= (length tree-node) 3) + (and (listp tree-node) + (= (length tree-node) 3) (numberp (primitive-node-cost tree-node)) (integerp (primitive-node-position tree-node)) (listp (primitive-node-task tree-node)))) @@ -243,7 +246,7 @@ parent." (labels ((list-iter (lst acc) (if (null lst) acc - (let ((new (node-iter (first lst)))) + (let ((new (node-iter (complex-node-task lst)))) (reverse (list-iter (cdr lst) (append new acc)))))) (node-iter (node) (when (complex-node-p node) @@ -258,6 +261,8 @@ parent." between trees." (labels ((list-iter (lst1 lst2) (cond ((null lst1) + ;; note in the following we take advantage of the fact that FORMAT + ;; returns NIL (if (null lst2) t (format t "~&NIL does not match ~s~%" lst2))) @@ -273,8 +278,8 @@ between trees." (node-iter (n1 n2) (cond ((primitive-node-p n1) (cond ((primitive-node-p n2) - (assert (not (equalp n1 n2))) - (format t "~&Primitive nodes do not match:~%~T~S~%~T~S~%" n1 n2)))) + (if (equalp n1 n2) t + (format t "~&Primitive nodes do not match:~%~T~S~%~T~S~%" n1 n2))))) ((primitive-node-p n2) (format t "~&Node:~%~T~S~%~TDoes not match primitive node:~%~T~S~%" n1 n2)) (t (assert (and (complex-node-p n1) @@ -285,6 +290,12 @@ between trees." (complex-node-task n1) (complex-node-task n2)) (return-from node-iter nil)) + (unless (eq (complex-node-reduction-label n1) + (complex-node-reduction-label n2)) + (format t "Mismatching complex-node method labels:~%~T~S~%~T~S~%" + (complex-node-reduction-label n1) + (complex-node-reduction-label n2)) + (return-from node-iter nil)) (if (equalp (complex-node-children n1) (complex-node-children n2)) t @@ -328,7 +339,8 @@ tree (although they will be EQUALP." (primitive-node-position node))) ((complex-node-p node) (make-complex-node (complex-node-task node) - (list-iter (complex-node-children node)))) + (list-iter (complex-node-children node)) + :reduction-label (complex-node-reduction-label node))) (t (error 'type-error :expected-type 'tree-node :datum node))))) ;; Ugh: SHOP plan "trees" are really forests. Most of the time. @@ -344,11 +356,11 @@ tree (although they will be EQUALP." (member node (complex-node-children n) :test 'eq))) (find-complex-node-if #'match-if-child tree :node-fun t))) -(defun canonically-order (tree &optional (keep-empty nil)) +(defun canonically-order-plan-tree (tree &optional (keep-empty nil)) (labels ((list-iter (lst) (let ((elts (remove nil (mapcar #'node-iter lst)))) - (sort elts #'<= :key #'min-start))) + (sort (copy-list elts) #'<= :key #'min-start))) (node-iter (node) (etypecase node (primitive-node @@ -358,7 +370,9 @@ tree (although they will be EQUALP." (complex-node (when (or keep-empty (complex-node-children node)) (make-complex-node (complex-node-task node) - (list-iter (complex-node-children node)))))))) + (list-iter (complex-node-children node)) + :reduction-label + (complex-node-reduction-label node))))))) ;; Ugh: SHOP plan "trees" are really forests. Most of the time. (if (or (primitive-node-p tree) (complex-node-p tree)) (node-iter tree) diff --git a/shop3/planning-tree/tree-reductions.lisp b/shop3/planning-tree/tree-reductions.lisp index 5309dcd0..c908e3f9 100644 --- a/shop3/planning-tree/tree-reductions.lisp +++ b/shop3/planning-tree/tree-reductions.lisp @@ -65,12 +65,16 @@ ;;; ------------------------------------------------------------------------ ; This function records the parents of each subtask in a reduction. -(defun record-reduction (task1 reduction unifier) +(defun record-reduction (task1 reduction unifier &optional method-label) (declare (ignore unifier)) (let ((all-subtasks (extract-subtasks reduction))) (iter (for subtask in all-subtasks) (setf (gethash subtask *subtask-parents*) - task1)))) + task1)) + (when method-label + (mapc #'(lambda (subtask) + (setf (gethash subtask *reduction-labels*) method-label)) + all-subtasks)))) (defun extract-subtasks (reduction) (cond @@ -95,7 +99,8 @@ (defun extract-tree (plan) (strip-tree-tags (let* ((operator-nodes (plan-operator-nodes plan)) - ;; all-nodes are either operator-nodes or complex tasks + ;; all-nodes are either primitive-nodes or complex tasks + ;; this is kind of gross... (all-nodes (plan-tree-nodes operator-nodes)) (*node-children-table* (create-node-children-table *subtask-parents* all-nodes operator-nodes)) (root-tasks (node-children nil *node-children-table*))) @@ -127,6 +132,13 @@ we check for that case at the top." (strip-one tree) (mapcar #'strip-one tree)))) +(defun lookup-reduction-label (obj) + (let ((task + (etypecase obj + (primitive-node (operator-task obj)) + (list obj)))) + (gethash task *reduction-labels*))) + (defun extract-subtree (root-node nodes) "Recursively build the subtree below ROOT-NODE from the set of possible nodes in NODES. At the top level, it returns @@ -135,9 +147,15 @@ ROOT-NODE is a PRIMITIVE-NODE." (let ((children (node-children root-node *node-children-table*))) (cond (children - (make-complex-node root-node - (mapcar #'(lambda (child) (extract-subtree child nodes)) - children))) + ;; again, this is ugly because primitive nodes will be nodes, complex nodes are + ;; still only "naked" tasks. + (let ((label (lookup-reduction-label (first children)))) + (unless label (break "Didn't record a reduction label for ~s child of ~s" + (first children) root-node)) + (make-complex-node root-node + (mapcar #'(lambda (child) (extract-subtree child nodes)) + children) + :reduction-label label))) ((primitive-node-p root-node) root-node) (t @@ -243,6 +261,7 @@ expanded -- if it is part of a failed search branch then or (c) TASK itself." (extend-plan-tree-nodes (rest base-nodes) (cons parent (cons node acc))) (extend-plan-tree-nodes (rest base-nodes) (cons node acc)))))) +;;; OPERATOR-TASK here actually applies to an operator NODE... ;;; this function is necessary because the operators are not EQ ;;; to their tasks, which must be looked up in *operator-tasks* (declaim (ftype (function (primitive-node) (values list &optional)) diff --git a/shop3/shop-version.lisp-expr b/shop3/shop-version.lisp-expr index 53c86a00..5411ed34 100644 --- a/shop3/shop-version.lisp-expr +++ b/shop3/shop-version.lisp-expr @@ -1 +1,2 @@ -"3.10.0" ; 3.10 introduces :plan-num-limit +"3.12.0" ; 3.11 introduces command-line applications and HDDL plan output +; 3.12 introduces the use of random-state for repeatability diff --git a/shop3/shop3.asd b/shop3/shop3.asd index 60bd7bd2..ac61478b 100644 --- a/shop3/shop3.asd +++ b/shop3/shop3.asd @@ -51,6 +51,8 @@ ;;; portions thereof marked with this legend must also reproduce the ;;; markings. +;;; Robert P. Goldman + (defpackage :shop-asd (:use :common-lisp :asdf) (:nicknames :shop2-asd :shop3-asd) @@ -140,7 +142,9 @@ minimal affected subtree." (find-package :shop3)) (asdf:component-version (asdf:find-system "shop3"))))) (:file "plan-printer" :depends-on ("package" - "decls")))) + "decls")) + (:file "hddl-plan" :pathname "hddl/hddl-plan" + :depends-on ("explicit-stack-search" "tree")))) (defsystem :shop3/common :serial t @@ -156,7 +160,7 @@ minimal affected subtree." (defsystem :shop3/theorem-prover :serial t :pathname "theorem-prover/" - :depends-on ("shop3/common" "shop3/unifier") + :depends-on ("shop3/common" "shop3/unifier" (:version "random-state" "1.0.1")) :version (:read-file-form "shop-version.lisp-expr") :components ((:file "package-thpr") (:file "decls") @@ -173,6 +177,17 @@ minimal affected subtree." (:file "tracer") (:file "unify"))) +;;;--------------------------------------------------------------------------- +;;; Extensions +;;;--------------------------------------------------------------------------- + +(defsystem "shop3/pddl-helpers" + :depends-on ("shop3" "pddl-utils") + :pathname "pddl/" + :serial t ; pddl-helpers contains defpackage + :components ((:file "pddl-helpers") + (:file "validate-repairs"))) + (defsystem :shop3/plan-grapher :depends-on ("shop3" "cl-dot") @@ -183,14 +198,6 @@ minimal affected subtree." (:file "graph-plan-tree")) ) -(defsystem "shop3/pddl-helpers" - :depends-on ("shop3" "pddl-utils") - :pathname "pddl/" - :serial t ; pddl-helpers contains defpackage - :components ((:file "pddl-helpers") - (:file "validate-repairs"))) - - ;;;--------------------------------------------------------------------------- ;;; Testing ;;;--------------------------------------------------------------------------- @@ -238,7 +245,7 @@ minimal affected subtree." (search-tests . :search-tests) ; 9 (plan-num-limit-tests . :plan-num-limit-tests) ; 25 ) - :num-checks 1094 + :num-checks 1101 :depends-on ((:version "shop3" (:read-file-form "shop-version.lisp-expr")) "shop3/openstacks" "shop3/pddl-helpers" @@ -279,7 +286,7 @@ minimal affected subtree." (:file "analogical-replay") (:file "minimal-subtree-tests") (:file "sort-by-tests") ; 7 checks - (:file "plan-tree-tests") ; 40 checks + (:file "plan-tree-tests") ; 43 checks (:file "search-tests") ; 9 checks (:file "plan-num-limit-tests") ; 21 checks )) @@ -351,7 +358,8 @@ minimal affected subtree." "Log_ran_problems_50" "Log_ran_problems_55" "Log_ran_problems_60")))) - (:file "replan-tests" :pathname "tests/replan-tests"))) + (:file "replan-tests" :pathname "tests/replan-tests") + (:file "hddl-tests" :pathname "tests/hddl-tests"))) (defsystem shop3/test-satellite diff --git a/shop3/shop3.lisp b/shop3/shop3.lisp index be48cd3d..f2b56e3d 100644 --- a/shop3/shop3.lisp +++ b/shop3/shop3.lisp @@ -168,6 +168,7 @@ MPL/GPL/LGPL triple license. For details, see the software source file.") ;; [mpelican:20090226.1825CST] obsolete, please use state-type arg or default-state-type slot in domain class (*state-encoding* :obsolete-state-encoding-variable) (*plan-tree* plan-tree) + (*reduction-labels* (make-hash-table :test 'eq)) (*collect-state* (or collect-state plan-tree)) (*subtask-parents* (make-subtask-parents-table)) (*operator-tasks* (make-operator-task-table)) diff --git a/shop3/silent-shop-test.lisp b/shop3/silent-shop-test.lisp new file mode 100644 index 00000000..9e1cc3fa --- /dev/null +++ b/shop3/silent-shop-test.lisp @@ -0,0 +1,6 @@ + +(defmethod asdf:perform :around ((op asdf:test-op) + (component shop2-asd::shop-tester-mixin)) + (let ((shop::*silent* t)) + (declare (special shop::*silent*)) + (call-next-method))) diff --git a/shop3/tests/hddl-tests.lisp b/shop3/tests/hddl-tests.lisp new file mode 100644 index 00000000..e80ecbd4 --- /dev/null +++ b/shop3/tests/hddl-tests.lisp @@ -0,0 +1,1237 @@ +(defpackage shop-hddl-tests + (:use common-lisp iterate fiveam hddl-translator) + (:import-from #:shop #:find-plans #:find-plans-stack) + ) +(in-package :shop-hddl-tests) + +(def-suite* hddl-plan-tests) + +(defmacro load-log-problem () + `(progn + (unless (shop:find-domain 'shop-user::logistics nil) + (load (asdf:system-relative-pathname "shop3" + "examples/logistic/logistic.lisp"))) + (unless (shop:find-problem 'shop-user::log-ran-15-1 nil) + (load (asdf:system-relative-pathname "shop3" + "examples/logistic/Log_ran_problems_15.lisp"))))) + +(defvar *plan*) +(defvar *tree*) + +(defmacro with-plan-and-tree ((planvar treevar &key ess) &body body) + `(,(if ess + 'with-ess-plan-and-tree + 'with-shop2-plan-and-tree) + (,planvar ,treevar) ,@body)) + +(defmacro with-shop2-plan-and-tree ((planvar treevar) &body body) + (let ((plans (gensym)) + (trees (gensym)) + (ignore (gensym))) + `(multiple-value-bind (,plans ,ignore ,trees) + (find-plans 'shop-user::log-ran-15-1 :plan-tree t :verbose 0) + (declare (ignore ,ignore)) + (unless (and ,plans ,trees) (error "Expected a plan and tree for test case.")) + (let ((,planvar (first ,plans)) + (,treevar (first ,trees))) + ,@body)))) + +(defmacro with-ess-plan-and-tree ((planvar treevar) &body body) + (let ((returns (gensym))) + `(let ((,returns (find-plans-stack 'shop-user::log-ran-15-1 :plan-tree t :verbose 0 :unpack-returns nil))) + (unless ,returns (error "Expected successful planning")) + (let ((,planvar (shop::plan (first ,returns))) + (,treevar (shop::tree (first , returns)))) + ,@body)))) + +(defmacro with-hddl-plan ((hddl-planvar ess-plan ess-tree) &body body) + `(let ((,hddl-planvar (hddl-plan ,ess-plan ,ess-tree))) + ,@body)) + +#+ignore +(test plan-test + (load-log-problem) + (with-plan-and-tree (plan tree) + (is (equalp expected-plan plan)) + (is (equalp expected-tree tree)))) + +(test plan-test-ess + (load-log-problem) + (with-plan-and-tree (plan tree :ess t) + (is (equalp expected-plan plan)) + ;; (is (equalp expected-tree tree)) + )) + + + +#+ignore +(test translate-tree + (load-log-problem) + (with-plan-and-tree (plan tree) + (let ((hddl-plan-sexp + (hddl-plan plan tree))) + (is-true hddl-plan-sexp) + (let ((max-act 124) + (act-alist (getf (rest hddl-plan-sexp) :actions)) + (root-list (getf (rest hddl-plan-sexp) :roots))) + (is (= max-act (length act-alist))) + (is (= 15 (length root-list))) + (is (equalp (alexandria:iota 15 :start (1+ max-act)) + root-list)))))) + +;;; this works do far... +(test translate-tree-ess + (load-log-problem) + (with-plan-and-tree (plan tree :ess t) + (with-hddl-plan (hddl-plan-sexp plan tree) + (is-true hddl-plan-sexp) + (is (equalp (iter (for i from 1) + (as step in (shop:shorter-plan plan)) + (collecting (cons i step))) + (getf (rest hddl-plan-sexp) :actions))) + (let ((decomps (getf (rest hddl-plan-sexp) :decompositions)) + (roots (getf (rest hddl-plan-sexp) :roots))) + (flet ((find-decomp (n) + (or (find n decomps :key (lambda (x) (hddl-translator::decomposition-record-node-id x))) + (error "No decomposition with node-id ~d" n)))) + (is (equalp (mapcar #'shop::strip-task-sexp (rest (shop::problem-tasks (shop:find-problem 'shop-user::log-ran-15-1 nil)))) + (iter (for root-no in roots) + (as node = (find-decomp root-no)) + (collecting (hddl-translator::decomposition-record-task node))))))) + (let ((max-act 124) + (act-alist (getf (rest hddl-plan-sexp) :actions)) + (root-list (getf (rest hddl-plan-sexp) :roots))) + (is (= max-act (length act-alist))) + (is (= 15 (length root-list))) + (is (equalp (alexandria:iota 15 :start (1+ max-act)) + root-list)))))) + +(test hddl-test-ess + (load-log-problem) + (with-plan-and-tree (plan tree :ess t) + (with-hddl-plan (hddl-plan plan tree) + hddl-plan + ) + ;;(is (equalp expected-plan plan)) + ;; (is (equalp expected-tree tree)) + )) + + +(in-package :shop-user) +(defparameter shop-hddl-tests::expected-plan + '((!DRIVE-TRUCK TRUCK8-1 LOC8-1 + LOC8-3) + 1.0 + (!LOAD-TRUCK PACKAGE1 TRUCK8-1 + LOC8-3) + 1.0 + (!DRIVE-TRUCK TRUCK2-1 LOC2-1 + LOC2-2) + 1.0 + (!LOAD-TRUCK PACKAGE3 TRUCK2-1 + LOC2-2) + 1.0 + (!DRIVE-TRUCK TRUCK6-1 LOC6-1 + LOC6-3) + 1.0 + (!LOAD-TRUCK PACKAGE4 TRUCK6-1 + LOC6-3) + 1.0 + (!DRIVE-TRUCK TRUCK2-1 LOC2-2 + LOC2-3) + 1.0 + (!LOAD-TRUCK PACKAGE6 TRUCK2-1 + LOC2-3) + 1.0 + (!DRIVE-TRUCK TRUCK1-1 LOC1-1 + LOC1-2) + 1.0 + (!LOAD-TRUCK PACKAGE7 TRUCK1-1 + LOC1-2) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK6-1 LOC6-3)) + 0 + (!LOAD-TRUCK PACKAGE8 TRUCK6-1 + LOC6-3) + 1.0 + (!DRIVE-TRUCK TRUCK5-1 LOC5-1 + LOC5-2) + 1.0 + (!LOAD-TRUCK PACKAGE9 TRUCK5-1 + LOC5-2) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK2-1 LOC2-3)) + 0 + (!LOAD-TRUCK PACKAGE11 TRUCK2-1 + LOC2-3) + 1.0 + (!DRIVE-TRUCK TRUCK2-1 LOC2-3 + LOC2-2) + 1.0 + (!LOAD-TRUCK PACKAGE12 TRUCK2-1 + LOC2-2) + 1.0 + (!DRIVE-TRUCK TRUCK7-1 LOC7-1 + LOC7-2) + 1.0 + (!LOAD-TRUCK PACKAGE13 TRUCK7-1 + LOC7-2) + 1.0 + (!DRIVE-TRUCK TRUCK8-1 LOC8-3 + LOC8-2) + 1.0 + (!LOAD-TRUCK PACKAGE15 TRUCK8-1 + LOC8-2) + 1.0 + (!DRIVE-TRUCK TRUCK8-1 LOC8-2 + LOC8-1) + 1.0 + (!UNLOAD-TRUCK PACKAGE1 TRUCK8-1 + LOC8-1) + 1.0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE1 LOC1-1)) + 0 + (!DRIVE-TRUCK TRUCK2-1 LOC2-2 + LOC2-3) + 1.0 + (!UNLOAD-TRUCK PACKAGE3 TRUCK2-1 + LOC2-3) + 1.0 + (!DRIVE-TRUCK TRUCK6-1 LOC6-3 + LOC6-2) + 1.0 + (!UNLOAD-TRUCK PACKAGE4 TRUCK6-1 + LOC6-2) + 1.0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 LOC5-1)) + 0 + (!DRIVE-TRUCK TRUCK2-1 LOC2-3 + LOC2-1) + 1.0 + (!UNLOAD-TRUCK PACKAGE6 TRUCK2-1 + LOC2-1) + 1.0 + (!DRIVE-TRUCK TRUCK1-1 LOC1-2 + LOC1-1) + 1.0 + (!UNLOAD-TRUCK PACKAGE7 TRUCK1-1 + LOC1-1) + 1.0 + (!DRIVE-TRUCK TRUCK6-1 LOC6-2 + LOC6-1) + 1.0 + (!UNLOAD-TRUCK PACKAGE8 TRUCK6-1 + LOC6-1) + 1.0 + (!DRIVE-TRUCK TRUCK5-1 LOC5-2 + LOC5-1) + 1.0 + (!UNLOAD-TRUCK PACKAGE9 TRUCK5-1 + LOC5-1) + 1.0 + (!FLY-AIRPLANE PLANE2 LOC4-1 + LOC7-1) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK2-1 LOC2-1)) + 0 + (!UNLOAD-TRUCK PACKAGE11 TRUCK2-1 + LOC2-1) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK2-1 LOC2-1)) + 0 + (!UNLOAD-TRUCK PACKAGE12 TRUCK2-1 + LOC2-1) + 1.0 + (!DRIVE-TRUCK TRUCK7-1 LOC7-2 + LOC7-1) + 1.0 + (!UNLOAD-TRUCK PACKAGE13 TRUCK7-1 + LOC7-1) + 1.0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE2 LOC7-1)) + 0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK8-1 LOC8-1)) + 0 + (!UNLOAD-TRUCK PACKAGE15 TRUCK8-1 + LOC8-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE2 PLANE1 + LOC1-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE5 PLANE3 + LOC5-1) + 1.0 + (!FLY-AIRPLANE PLANE3 LOC5-1 + LOC2-1) + 1.0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE1 LOC1-1)) + 0 + (!LOAD-AIRPLANE PACKAGE10 PLANE2 + LOC7-1) + 1.0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 LOC2-1)) + 0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 LOC2-1)) + 0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE2 LOC7-1)) + 0 + (!LOAD-AIRPLANE PACKAGE14 PLANE2 + LOC7-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE6 PLANE3 + LOC2-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE7 PLANE1 + LOC1-1) + 1.0 + (!FLY-AIRPLANE PLANE1 LOC1-1 + LOC6-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE11 PLANE3 + LOC2-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE12 PLANE3 + LOC2-1) + 1.0 + (!FLY-AIRPLANE PLANE3 LOC2-1 + LOC5-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE13 PLANE2 + LOC7-1) + 1.0 + (!FLY-AIRPLANE PLANE2 LOC7-1 + LOC8-1) + 1.0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE2 LOC8-1)) + 0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE1 LOC6-1)) + 0 + (!LOAD-AIRPLANE PACKAGE8 PLANE1 + LOC6-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE9 PLANE3 + LOC5-1) + 1.0 + (!FLY-AIRPLANE PLANE3 LOC5-1 + LOC1-1) + 1.0 + (!LOAD-AIRPLANE PACKAGE15 PLANE2 + LOC8-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE10 + PLANE2 LOC8-1) + 1.0 + (!FLY-AIRPLANE PLANE2 LOC8-1 + LOC6-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE7 PLANE1 + LOC6-1) + 1.0 + (!FLY-AIRPLANE PLANE1 LOC6-1 + LOC2-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE5 PLANE3 + LOC1-1) + 1.0 + (!FLY-AIRPLANE PLANE3 LOC1-1 + LOC6-1) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK8-1 LOC8-1)) + 0 + (!LOAD-TRUCK PACKAGE10 TRUCK8-1 + LOC8-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE14 + PLANE2 LOC6-1) + 1.0 + (!FLY-AIRPLANE PLANE2 LOC6-1 + LOC3-1) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK6-1 LOC6-1)) + 0 + (!LOAD-TRUCK PACKAGE7 TRUCK6-1 + LOC6-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE2 PLANE1 + LOC2-1) + 1.0 + (!FLY-AIRPLANE PLANE1 LOC2-1 + LOC1-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE6 PLANE3 + LOC6-1) + 1.0 + (!FLY-AIRPLANE PLANE3 LOC6-1 + LOC3-1) + 1.0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 LOC3-1)) + 0 + (!DRIVE-TRUCK TRUCK8-1 LOC8-1 + LOC8-3) + 1.0 + (!UNLOAD-TRUCK PACKAGE10 TRUCK8-1 + LOC8-3) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK6-1 LOC6-1)) + 0 + (!LOAD-TRUCK PACKAGE14 TRUCK6-1 + LOC6-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE13 + PLANE2 LOC3-1) + 1.0 + (!FLY-AIRPLANE PLANE2 LOC3-1 + LOC5-1) + 1.0 + (!DRIVE-TRUCK TRUCK6-1 LOC6-1 + LOC6-3) + 1.0 + (!UNLOAD-TRUCK PACKAGE7 TRUCK6-1 + LOC6-3) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE8 PLANE1 + LOC1-1) + 1.0 + (!DRIVE-TRUCK TRUCK6-1 LOC6-3 + LOC6-1) + 1.0 + (!LOAD-TRUCK PACKAGE6 TRUCK6-1 + LOC6-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE11 + PLANE3 LOC3-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE12 + PLANE3 LOC3-1) + 1.0 + (!FLY-AIRPLANE PLANE3 LOC3-1 + LOC4-1) + 1.0 + (!DRIVE-TRUCK TRUCK6-1 LOC6-1 + LOC6-3) + 1.0 + (!UNLOAD-TRUCK PACKAGE14 TRUCK6-1 + LOC6-3) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 LOC3-1)) + 0 + (!LOAD-TRUCK PACKAGE13 TRUCK3-1 + LOC3-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE15 + PLANE2 LOC5-1) + 1.0 + (!DRIVE-TRUCK TRUCK6-1 LOC6-3 + LOC6-2) + 1.0 + (!UNLOAD-TRUCK PACKAGE6 TRUCK6-1 + LOC6-2) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 LOC3-1)) + 0 + (!LOAD-TRUCK PACKAGE11 TRUCK3-1 + LOC3-1) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 LOC3-1)) + 0 + (!LOAD-TRUCK PACKAGE12 TRUCK3-1 + LOC3-1) + 1.0 + (!UNLOAD-AIRPLANE PACKAGE9 PLANE3 + LOC4-1) + 1.0 + (!DRIVE-TRUCK TRUCK3-1 LOC3-1 + LOC3-2) + 1.0 + (!UNLOAD-TRUCK PACKAGE11 TRUCK3-1 + LOC3-2) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 LOC3-2)) + 0 + (!UNLOAD-TRUCK PACKAGE13 TRUCK3-1 + LOC3-2) + 1.0 + (!DRIVE-TRUCK TRUCK3-1 LOC3-2 + LOC3-3) + 1.0 + (!UNLOAD-TRUCK PACKAGE12 TRUCK3-1 + LOC3-3) + 1.0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK4-1 LOC4-1)) + 0 + (!LOAD-TRUCK PACKAGE9 TRUCK4-1 + LOC4-1) + 1.0 + (!DRIVE-TRUCK TRUCK4-1 LOC4-1 + LOC4-2) + 1.0 + (!UNLOAD-TRUCK PACKAGE9 TRUCK4-1 + LOC4-2) + 1.0)) + +(defparameter shop-hddl-tests::expected-tree + '(((OBJ-AT PACKAGE1 LOC8-1) + SAME-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK8-1 + PACKAGE1 LOC8-3 LOC8-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK8-1 LOC8-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK8-1 + LOC8-1 LOC8-3) + 0))) + (1.0 + (!LOAD-TRUCK PACKAGE1 + TRUCK8-1 LOC8-3) + 1) + ((TRUCK-AT TRUCK8-1 LOC8-1) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK8-1 + LOC8-2 LOC8-1) + 22))) + (1.0 + (!UNLOAD-TRUCK PACKAGE1 + TRUCK8-1 LOC8-1) + 23))))) + ((OBJ-AT PACKAGE3 LOC2-3) + SAME-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK2-1 + PACKAGE3 LOC2-2 LOC2-3) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK2-1 LOC2-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK2-1 + LOC2-1 LOC2-2) + 2))) + (1.0 + (!LOAD-TRUCK PACKAGE3 + TRUCK2-1 LOC2-2) + 3) + ((TRUCK-AT TRUCK2-1 LOC2-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK2-1 + LOC2-2 LOC2-3) + 25))) + (1.0 + (!UNLOAD-TRUCK PACKAGE3 + TRUCK2-1 LOC2-3) + 26))))) + ((OBJ-AT PACKAGE4 LOC6-2) + SAME-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK6-1 + PACKAGE4 LOC6-3 LOC6-2) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK6-1 LOC6-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK6-1 + LOC6-1 LOC6-3) + 4))) + (1.0 + (!LOAD-TRUCK PACKAGE4 + TRUCK6-1 LOC6-3) + 5) + ((TRUCK-AT TRUCK6-1 LOC6-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK6-1 + LOC6-3 LOC6-2) + 27))) + (1.0 + (!UNLOAD-TRUCK PACKAGE4 + TRUCK6-1 LOC6-2) + 28))))) + ((OBJ-AT PACKAGE6 LOC6-2) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK2-1 + PACKAGE6 LOC2-3 LOC2-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK2-1 LOC2-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK2-1 + LOC2-2 LOC2-3) + 6))) + (1.0 + (!LOAD-TRUCK PACKAGE6 + TRUCK2-1 LOC2-3) + 7) + ((TRUCK-AT TRUCK2-1 LOC2-1) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK2-1 + LOC2-3 LOC2-1) + 30))) + (1.0 + (!UNLOAD-TRUCK PACKAGE6 + TRUCK2-1 LOC2-1) + 31))) + ((AIR-DELIVER-OBJ PACKAGE6 + LOC2-1 LOC6-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE3 LOC5-1 + LOC2-1) + 50) + (1.0 + (!LOAD-AIRPLANE PACKAGE6 + PLANE3 LOC2-1) + 57) + ((FLY-AIRPLANE PLANE3 LOC6-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE3 + LOC1-1 LOC6-1) + 76))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE6 + PLANE3 LOC6-1) + 85))) + ((IN-CITY-DELIVERY TRUCK6-1 + PACKAGE6 LOC6-1 LOC6-2) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK6-1 LOC6-1) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK6-1 + LOC6-3 LOC6-1) + 97))) + (1.0 + (!LOAD-TRUCK PACKAGE6 + TRUCK6-1 LOC6-1) + 98) + ((TRUCK-AT TRUCK6-1 LOC6-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK6-1 + LOC6-3 LOC6-2) + 107))) + (1.0 + (!UNLOAD-TRUCK PACKAGE6 + TRUCK6-1 LOC6-2) + 108))))) + ((OBJ-AT PACKAGE7 LOC6-3) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK1-1 + PACKAGE7 LOC1-2 LOC1-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK1-1 LOC1-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK1-1 + LOC1-1 LOC1-2) + 8))) + (1.0 + (!LOAD-TRUCK PACKAGE7 + TRUCK1-1 LOC1-2) + 9) + ((TRUCK-AT TRUCK1-1 LOC1-1) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK1-1 + LOC1-2 LOC1-1) + 32))) + (1.0 + (!UNLOAD-TRUCK PACKAGE7 + TRUCK1-1 LOC1-1) + 33))) + ((AIR-DELIVER-OBJ PACKAGE7 + LOC1-1 LOC6-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE1 + LOC1-1)) + 51) + (1.0 + (!LOAD-AIRPLANE PACKAGE7 + PLANE1 LOC1-1) + 58) + ((FLY-AIRPLANE PLANE1 LOC6-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE1 + LOC6-1)) + 66))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE7 + PLANE1 LOC6-1) + 73))) + ((IN-CITY-DELIVERY TRUCK6-1 + PACKAGE7 LOC6-1 LOC6-3) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK6-1 LOC6-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK6-1 + LOC6-1)) + 81))) + (1.0 + (!LOAD-TRUCK PACKAGE7 + TRUCK6-1 LOC6-1) + 82) + ((TRUCK-AT TRUCK6-1 LOC6-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK6-1 + LOC6-1 LOC6-3) + 94))) + (1.0 + (!UNLOAD-TRUCK PACKAGE7 + TRUCK6-1 LOC6-3) + 95))))) + ((OBJ-AT PACKAGE8 LOC1-1) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK6-1 + PACKAGE8 LOC6-3 LOC6-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK6-1 LOC6-3) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK6-1 + LOC6-3)) + 10))) + (1.0 + (!LOAD-TRUCK PACKAGE8 + TRUCK6-1 LOC6-3) + 11) + ((TRUCK-AT TRUCK6-1 LOC6-1) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK6-1 + LOC6-2 LOC6-1) + 34))) + (1.0 + (!UNLOAD-TRUCK PACKAGE8 + TRUCK6-1 LOC6-1) + 35))) + ((AIR-DELIVER-OBJ PACKAGE8 + LOC6-1 LOC1-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE1 LOC1-1 + LOC6-1) + 59) + (1.0 + (!LOAD-AIRPLANE PACKAGE8 + PLANE1 LOC6-1) + 67) + ((FLY-AIRPLANE PLANE1 LOC1-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE1 + LOC2-1 LOC1-1) + 84))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE8 + PLANE1 LOC1-1) + 96))))) + ((OBJ-AT PACKAGE9 LOC4-2) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK5-1 + PACKAGE9 LOC5-2 LOC5-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK5-1 LOC5-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK5-1 + LOC5-1 LOC5-2) + 12))) + (1.0 + (!LOAD-TRUCK PACKAGE9 + TRUCK5-1 LOC5-2) + 13) + ((TRUCK-AT TRUCK5-1 LOC5-1) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK5-1 + LOC5-2 LOC5-1) + 36))) + (1.0 + (!UNLOAD-TRUCK PACKAGE9 + TRUCK5-1 LOC5-1) + 37))) + ((AIR-DELIVER-OBJ PACKAGE9 + LOC5-1 LOC4-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE3 LOC2-1 + LOC5-1) + 62) + (1.0 + (!LOAD-AIRPLANE PACKAGE9 + PLANE3 LOC5-1) + 68) + ((FLY-AIRPLANE PLANE3 LOC4-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE3 + LOC3-1 LOC4-1) + 101))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE9 + PLANE3 LOC4-1) + 113))) + ((IN-CITY-DELIVERY TRUCK4-1 + PACKAGE9 LOC4-1 LOC4-2) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK4-1 LOC4-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK4-1 + LOC4-1)) + 120))) + (1.0 + (!LOAD-TRUCK PACKAGE9 + TRUCK4-1 LOC4-1) + 121) + ((TRUCK-AT TRUCK4-1 LOC4-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK4-1 + LOC4-1 LOC4-2) + 122))) + (1.0 + (!UNLOAD-TRUCK PACKAGE9 + TRUCK4-1 LOC4-2) + 123))))) + ((OBJ-AT PACKAGE11 LOC3-2) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK2-1 + PACKAGE11 LOC2-3 LOC2-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK2-1 LOC2-3) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK2-1 + LOC2-3)) + 14))) + (1.0 + (!LOAD-TRUCK PACKAGE11 + TRUCK2-1 LOC2-3) + 15) + ((TRUCK-AT TRUCK2-1 LOC2-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK2-1 + LOC2-1)) + 39))) + (1.0 + (!UNLOAD-TRUCK PACKAGE11 + TRUCK2-1 LOC2-1) + 40))) + ((AIR-DELIVER-OBJ PACKAGE11 + LOC2-1 LOC3-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 + LOC2-1)) + 53) + (1.0 + (!LOAD-AIRPLANE PACKAGE11 + PLANE3 LOC2-1) + 60) + ((FLY-AIRPLANE PLANE3 LOC3-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE3 + LOC6-1 LOC3-1) + 86))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE11 + PLANE3 LOC3-1) + 99))) + ((IN-CITY-DELIVERY TRUCK3-1 + PACKAGE11 LOC3-1 LOC3-2) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK3-1 LOC3-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 + LOC3-1)) + 109))) + (1.0 + (!LOAD-TRUCK PACKAGE11 + TRUCK3-1 LOC3-1) + 110) + (1.0 + (!UNLOAD-TRUCK PACKAGE11 + TRUCK3-1 LOC3-2) + 115) + ((TRUCK-AT TRUCK3-1 LOC3-2) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 + LOC3-2)) + 116))))))) + ((OBJ-AT PACKAGE12 LOC3-3) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK2-1 + PACKAGE12 LOC2-2 LOC2-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK2-1 LOC2-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK2-1 + LOC2-3 LOC2-2) + 16))) + (1.0 + (!LOAD-TRUCK PACKAGE12 + TRUCK2-1 LOC2-2) + 17) + ((TRUCK-AT TRUCK2-1 LOC2-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK2-1 + LOC2-1)) + 41))) + (1.0 + (!UNLOAD-TRUCK PACKAGE12 + TRUCK2-1 LOC2-1) + 42))) + ((AIR-DELIVER-OBJ PACKAGE12 + LOC2-1 LOC3-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 + LOC2-1)) + 54) + (1.0 + (!LOAD-AIRPLANE PACKAGE12 + PLANE3 LOC2-1) + 61) + ((FLY-AIRPLANE PLANE3 LOC3-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 + LOC3-1)) + 87))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE12 + PLANE3 LOC3-1) + 100))) + ((IN-CITY-DELIVERY TRUCK3-1 + PACKAGE12 LOC3-1 LOC3-3) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK3-1 LOC3-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 + LOC3-1)) + 111))) + (1.0 + (!LOAD-TRUCK PACKAGE12 + TRUCK3-1 LOC3-1) + 112) + ((TRUCK-AT TRUCK3-1 LOC3-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK3-1 + LOC3-2 LOC3-3) + 118))) + (1.0 + (!UNLOAD-TRUCK PACKAGE12 + TRUCK3-1 LOC3-3) + 119))))) + ((OBJ-AT PACKAGE13 LOC3-2) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK7-1 + PACKAGE13 LOC7-2 LOC7-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK7-1 LOC7-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK7-1 + LOC7-1 LOC7-2) + 18))) + (1.0 + (!LOAD-TRUCK PACKAGE13 + TRUCK7-1 LOC7-2) + 19) + ((TRUCK-AT TRUCK7-1 LOC7-1) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK7-1 + LOC7-2 LOC7-1) + 43))) + (1.0 + (!UNLOAD-TRUCK PACKAGE13 + TRUCK7-1 LOC7-1) + 44))) + ((AIR-DELIVER-OBJ PACKAGE13 + LOC7-1 LOC3-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE2 + LOC7-1)) + 55) + (1.0 + (!LOAD-AIRPLANE PACKAGE13 + PLANE2 LOC7-1) + 63) + ((FLY-AIRPLANE PLANE2 LOC3-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE2 + LOC6-1 LOC3-1) + 80))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE13 + PLANE2 LOC3-1) + 92))) + ((IN-CITY-DELIVERY TRUCK3-1 + PACKAGE13 LOC3-1 LOC3-2) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK3-1 LOC3-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK3-1 + LOC3-1)) + 104))) + (1.0 + (!LOAD-TRUCK PACKAGE13 + TRUCK3-1 LOC3-1) + 105) + ((TRUCK-AT TRUCK3-1 LOC3-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK3-1 + LOC3-1 LOC3-2) + 114))) + (1.0 + (!UNLOAD-TRUCK PACKAGE13 + TRUCK3-1 LOC3-2) + 117))))) + ((OBJ-AT PACKAGE15 LOC5-1) + DIFFERENT-CITY-DELIVER + (((IN-CITY-DELIVERY TRUCK8-1 + PACKAGE15 LOC8-2 LOC8-1) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK8-1 LOC8-2) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK8-1 + LOC8-3 LOC8-2) + 20))) + (1.0 + (!LOAD-TRUCK PACKAGE15 + TRUCK8-1 LOC8-2) + 21) + ((TRUCK-AT TRUCK8-1 LOC8-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK8-1 + LOC8-1)) + 46))) + (1.0 + (!UNLOAD-TRUCK PACKAGE15 + TRUCK8-1 LOC8-1) + 47))) + ((AIR-DELIVER-OBJ PACKAGE15 + LOC8-1 LOC5-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE2 LOC7-1 + LOC8-1) + 64) + (1.0 + (!LOAD-AIRPLANE PACKAGE15 + PLANE2 LOC8-1) + 70) + ((FLY-AIRPLANE PLANE2 LOC5-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE2 + LOC3-1 LOC5-1) + 93))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE15 + PLANE2 LOC5-1) + 106))))) + ((OBJ-AT PACKAGE2 LOC2-1) + DIFFERENT-CITY-DELIVER + (((AIR-DELIVER-OBJ PACKAGE2 + LOC1-1 LOC2-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE1 + LOC1-1)) + 24) + (1.0 + (!LOAD-AIRPLANE PACKAGE2 + PLANE1 LOC1-1) + 48) + ((FLY-AIRPLANE PLANE1 LOC2-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE1 + LOC6-1 LOC2-1) + 74))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE2 + PLANE1 LOC2-1) + 83))))) + ((OBJ-AT PACKAGE5 LOC1-1) + DIFFERENT-CITY-DELIVER + (((AIR-DELIVER-OBJ PACKAGE5 + LOC5-1 LOC1-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE3 + LOC5-1)) + 29) + (1.0 + (!LOAD-AIRPLANE PACKAGE5 + PLANE3 LOC5-1) + 49) + ((FLY-AIRPLANE PLANE3 LOC1-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE3 + LOC5-1 LOC1-1) + 69))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE5 + PLANE3 LOC1-1) + 75))))) + ((OBJ-AT PACKAGE10 LOC8-3) + DIFFERENT-CITY-DELIVER + (((AIR-DELIVER-OBJ PACKAGE10 + LOC7-1 LOC8-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE2 LOC4-1 + LOC7-1) + 38) + (1.0 + (!LOAD-AIRPLANE PACKAGE10 + PLANE2 LOC7-1) + 52) + ((FLY-AIRPLANE PLANE2 LOC8-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE2 + LOC8-1)) + 65))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE10 + PLANE2 LOC8-1) + 71))) + ((IN-CITY-DELIVERY TRUCK8-1 + PACKAGE10 LOC8-1 LOC8-3) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK8-1 LOC8-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK8-1 + LOC8-1)) + 77))) + (1.0 + (!LOAD-TRUCK PACKAGE10 + TRUCK8-1 LOC8-1) + 78) + ((TRUCK-AT TRUCK8-1 LOC8-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK8-1 + LOC8-1 LOC8-3) + 88))) + (1.0 + (!UNLOAD-TRUCK PACKAGE10 + TRUCK8-1 LOC8-3) + 89))))) + ((OBJ-AT PACKAGE14 LOC6-3) + DIFFERENT-CITY-DELIVER + (((AIR-DELIVER-OBJ PACKAGE14 + LOC7-1 LOC6-1) + NIL + ((0 + (!ADD-PROTECTION + (AIRPLANE-AT PLANE2 + LOC7-1)) + 45) + (1.0 + (!LOAD-AIRPLANE PACKAGE14 + PLANE2 LOC7-1) + 56) + ((FLY-AIRPLANE PLANE2 LOC6-1) + NIL + ((1.0 + (!FLY-AIRPLANE PLANE2 + LOC8-1 LOC6-1) + 72))) + (1.0 + (!UNLOAD-AIRPLANE PACKAGE14 + PLANE2 LOC6-1) + 79))) + ((IN-CITY-DELIVERY TRUCK6-1 + PACKAGE14 LOC6-1 LOC6-3) + TRUCK-ACROSS-TOWN + (((TRUCK-AT TRUCK6-1 LOC6-1) + NIL + ((0 + (!ADD-PROTECTION + (TRUCK-AT TRUCK6-1 + LOC6-1)) + 90))) + (1.0 + (!LOAD-TRUCK PACKAGE14 + TRUCK6-1 LOC6-1) + 91) + ((TRUCK-AT TRUCK6-1 LOC6-3) + NIL + ((1.0 + (!DRIVE-TRUCK TRUCK6-1 + LOC6-1 LOC6-3) + 102))) + (1.0 + (!UNLOAD-TRUCK PACKAGE14 + TRUCK6-1 LOC6-3) + 103))))))) diff --git a/shop3/tests/plan-tree-tests.lisp b/shop3/tests/plan-tree-tests.lisp index b6f3c238..a474c91c 100644 --- a/shop3/tests/plan-tree-tests.lisp +++ b/shop3/tests/plan-tree-tests.lisp @@ -7,651 +7,907 @@ #:*task-operator* #:primitive-node-p #:operator-task - #:canonically-order) + #:canonically-order-plan-tree) (:use :common-lisp :fiveam :shop3)) (in-package plan-tree-tests) (defparameter +expected-plan-tree+ '(((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE1 SHOP3-USER::LOC8-1) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 - SHOP3-USER::PACKAGE1 SHOP3-USER::LOC8-3 SHOP3-USER::LOC8-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1 - SHOP3-USER::LOC8-3) - 0))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE1 SHOP3-USER::TRUCK8-1 - SHOP3-USER::LOC8-3) - 1) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-2 - SHOP3-USER::LOC8-1) - 22))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE1 - SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) - 23))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE3 SHOP3-USER::LOC2-3) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 - SHOP3-USER::PACKAGE3 SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-3) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-1 SHOP3-USER::LOC2-2) - 2))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE3 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) - 3) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-3) - 25))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE3 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) - 26))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE4 SHOP3-USER::LOC6-2) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 - SHOP3-USER::PACKAGE4 SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-2) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) - 4))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE4 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - 5) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-2) - 27))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE4 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) - 28))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE6 SHOP3-USER::LOC6-2) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 - SHOP3-USER::PACKAGE6 SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-3) - 6))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE6 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) - 7) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-1) - 30))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE6 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) - 31))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE6 - SHOP3-USER::LOC2-1 SHOP3-USER::LOC6-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1 - SHOP3-USER::LOC2-1) - 50) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE6 - SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1) - 57) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC6-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 - SHOP3-USER::LOC1-1 SHOP3-USER::LOC6-1) - 76))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE6 - SHOP3-USER::PLANE3 SHOP3-USER::LOC6-1) - 85))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 - SHOP3-USER::PACKAGE6 SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-2) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-1) - 97))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE6 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - 98) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-2) - 107))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE6 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) - 108))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE7 SHOP3-USER::LOC6-3) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK1-1 - SHOP3-USER::PACKAGE7 SHOP3-USER::LOC1-2 SHOP3-USER::LOC1-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK1-1 - SHOP3-USER::LOC1-1 SHOP3-USER::LOC1-2) - 8))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE7 - SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-2) - 9) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-1) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK1-1 - SHOP3-USER::LOC1-2 SHOP3-USER::LOC1-1) - 32))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE7 - SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-1) - 33))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE7 - SHOP3-USER::LOC1-1 SHOP3-USER::LOC6-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1)) - 51) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE7 - SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) - 58) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC6-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE1 - SHOP3-USER::LOC6-1)) - 66))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE7 - SHOP3-USER::PLANE1 SHOP3-USER::LOC6-1) - 73))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 - SHOP3-USER::PACKAGE7 SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-1)) - 81))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE7 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - 82) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) - 94))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE7 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - 95))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE8 SHOP3-USER::LOC1-1) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 - SHOP3-USER::PACKAGE8 SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-3)) - 10))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE8 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - 11) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-2 SHOP3-USER::LOC6-1) - 34))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE8 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - 35))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE8 - SHOP3-USER::LOC6-1 SHOP3-USER::LOC1-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1 - SHOP3-USER::LOC6-1) - 59) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE8 - SHOP3-USER::PLANE1 SHOP3-USER::LOC6-1) - 67) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE1 - SHOP3-USER::LOC2-1 SHOP3-USER::LOC1-1) - 84))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE8 - SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) - 96))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE9 SHOP3-USER::LOC4-2) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK5-1 - SHOP3-USER::PACKAGE9 SHOP3-USER::LOC5-2 SHOP3-USER::LOC5-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK5-1 - SHOP3-USER::LOC5-1 SHOP3-USER::LOC5-2) - 12))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE9 - SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-2) - 13) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-1) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK5-1 - SHOP3-USER::LOC5-2 SHOP3-USER::LOC5-1) - 36))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE9 - SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-1) - 37))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE9 - SHOP3-USER::LOC5-1 SHOP3-USER::LOC4-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1 - SHOP3-USER::LOC5-1) - 62) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE9 - SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) - 68) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 - SHOP3-USER::LOC3-1 SHOP3-USER::LOC4-1) - 101))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE9 - SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) - 113))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK4-1 - SHOP3-USER::PACKAGE9 SHOP3-USER::LOC4-1 SHOP3-USER::LOC4-2) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK4-1 - SHOP3-USER::LOC4-1)) - 120))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE9 - SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-1) - 121) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK4-1 - SHOP3-USER::LOC4-1 SHOP3-USER::LOC4-2) - 122))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE9 - SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-2) - 123))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE11 SHOP3-USER::LOC3-2) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 - SHOP3-USER::PACKAGE11 SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-3)) - 14))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE11 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) - 15) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-1)) - 39))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE11 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) - 40))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE11 - SHOP3-USER::LOC2-1 SHOP3-USER::LOC3-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1)) - 53) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE11 - SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1) - 60) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 - SHOP3-USER::LOC6-1 SHOP3-USER::LOC3-1) - 86))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE11 - SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) - 99))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK3-1 - SHOP3-USER::PACKAGE11 SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-2) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 - SHOP3-USER::LOC3-1)) - 109))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE11 - SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) - 110) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE11 - SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) - 115) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 - SHOP3-USER::LOC3-2)) - 116))))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE12 SHOP3-USER::LOC3-3) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 - SHOP3-USER::PACKAGE12 SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-2) - 16))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE12 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) - 17) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 - SHOP3-USER::LOC2-1)) - 41))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE12 - SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) - 42))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE12 - SHOP3-USER::LOC2-1 SHOP3-USER::LOC3-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1)) - 54) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE12 - SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1) - 61) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 - SHOP3-USER::LOC3-1)) - 87))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE12 - SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) - 100))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK3-1 - SHOP3-USER::PACKAGE12 SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-3) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 - SHOP3-USER::LOC3-1)) - 111))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE12 - SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) - 112) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK3-1 - SHOP3-USER::LOC3-2 SHOP3-USER::LOC3-3) - 118))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE12 - SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-3) - 119))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE13 SHOP3-USER::LOC3-2) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK7-1 - SHOP3-USER::PACKAGE13 SHOP3-USER::LOC7-2 SHOP3-USER::LOC7-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK7-1 - SHOP3-USER::LOC7-1 SHOP3-USER::LOC7-2) - 18))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE13 - SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-2) - 19) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-1) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK7-1 - SHOP3-USER::LOC7-2 SHOP3-USER::LOC7-1) - 43))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE13 - SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-1) - 44))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE13 - SHOP3-USER::LOC7-1 SHOP3-USER::LOC3-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1)) - 55) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE13 - SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1) - 63) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC3-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 - SHOP3-USER::LOC6-1 SHOP3-USER::LOC3-1) - 80))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE13 - SHOP3-USER::PLANE2 SHOP3-USER::LOC3-1) - 92))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK3-1 - SHOP3-USER::PACKAGE13 SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-2) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 - SHOP3-USER::LOC3-1)) - 104))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE13 - SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) - 105) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK3-1 - SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-2) - 114))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE13 - SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) - 117))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE15 SHOP3-USER::LOC5-1) - (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 - SHOP3-USER::PACKAGE15 SHOP3-USER::LOC8-2 SHOP3-USER::LOC8-1) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-2) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 - SHOP3-USER::LOC8-3 SHOP3-USER::LOC8-2) - 20))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE15 - SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-2) - 21) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 - SHOP3-USER::LOC8-1)) - 46))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE15 - SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) - 47))) - ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE15 - SHOP3-USER::LOC8-1 SHOP3-USER::LOC5-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1 - SHOP3-USER::LOC8-1) - 64) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE15 - SHOP3-USER::PLANE2 SHOP3-USER::LOC8-1) - 70) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 - SHOP3-USER::LOC3-1 SHOP3-USER::LOC5-1) - 93))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE15 - SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) - 106))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE2 SHOP3-USER::LOC2-1) - (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE2 - SHOP3-USER::LOC1-1 SHOP3-USER::LOC2-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1)) - 24) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE2 - SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) - 48) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC2-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE1 - SHOP3-USER::LOC6-1 SHOP3-USER::LOC2-1) - 74))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE2 - SHOP3-USER::PLANE1 SHOP3-USER::LOC2-1) - 83))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE5 SHOP3-USER::LOC1-1) - (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE5 - SHOP3-USER::LOC5-1 SHOP3-USER::LOC1-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1)) - 29) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE5 - SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) - 49) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 - SHOP3-USER::LOC5-1 SHOP3-USER::LOC1-1) - 69))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE5 - SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) - 75))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE10 SHOP3-USER::LOC8-3) - (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE10 - SHOP3-USER::LOC7-1 SHOP3-USER::LOC8-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1 - SHOP3-USER::LOC7-1) - 38) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE10 - SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1) - 52) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC8-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE2 - SHOP3-USER::LOC8-1)) - 65))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE10 - SHOP3-USER::PLANE2 SHOP3-USER::LOC8-1) - 71))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 - SHOP3-USER::PACKAGE10 SHOP3-USER::LOC8-1 SHOP3-USER::LOC8-3) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 - SHOP3-USER::LOC8-1)) - 77))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE10 - SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) - 78) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 - SHOP3-USER::LOC8-1 SHOP3-USER::LOC8-3) - 88))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE10 - SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) - 89))))) - ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE14 SHOP3-USER::LOC6-3) - (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE14 - SHOP3-USER::LOC7-1 SHOP3-USER::LOC6-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1)) - 45) - (1.0 - (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE14 - SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1) - 56) - ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC6-1) - ((1.0 - (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 - SHOP3-USER::LOC8-1 SHOP3-USER::LOC6-1) - 72))) - (1.0 - (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE14 - SHOP3-USER::PLANE2 SHOP3-USER::LOC6-1) - 79))) - ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 - SHOP3-USER::PACKAGE14 SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) - (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - ((0 - (SHOP3-USER::!ADD-PROTECTION - (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-1)) - 90))) - (1.0 - (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE14 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) - 91) - ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - ((1.0 - (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 - SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) - 102))) - (1.0 - (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE14 - SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) - 103))))))) + SHOP3-USER::SAME-CITY-DELIVER + (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 + SHOP3-USER::PACKAGE1 SHOP3-USER::LOC8-3 SHOP3-USER::LOC8-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 + SHOP3-USER::LOC8-1 SHOP3-USER::LOC8-3) + 0))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE1 + SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) + 1) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 + SHOP3-USER::LOC8-2 SHOP3-USER::LOC8-1) + 22))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE1 + SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) + 23))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE3 SHOP3-USER::LOC2-3) + SHOP3-USER::SAME-CITY-DELIVER + (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 + SHOP3-USER::PACKAGE3 SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-3) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-1 SHOP3-USER::LOC2-2) + 2))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE3 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) + 3) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-3) + 25))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE3 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) + 26))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE4 SHOP3-USER::LOC6-2) + SHOP3-USER::SAME-CITY-DELIVER + (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 + SHOP3-USER::PACKAGE4 SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-2) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE4 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) + 28) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) + 4))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE4 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + 5) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-2) + 27))))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE6 SHOP3-USER::LOC6-2) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE6 + SHOP3-USER::LOC2-1 SHOP3-USER::LOC6-1) + SHOP3-USER::FLY-AIRPLANE-FROM-ANY-OTHER-AIRPORT + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1 + SHOP3-USER::LOC2-1) + 50) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE6 + SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1) + 57) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC6-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 + SHOP3-USER::LOC1-1 SHOP3-USER::LOC6-1) + 76))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE6 + SHOP3-USER::PLANE3 SHOP3-USER::LOC6-1) + 85))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 + SHOP3-USER::PACKAGE6 SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-2) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-1) + 97))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE6 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + 98) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-2) + 107))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE6 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-2) + 108))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 + SHOP3-USER::PACKAGE6 SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-1) + 30))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE6 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) + 31) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-3) + 6))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE6 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) + 7))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE7 SHOP3-USER::LOC6-3) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE7 + SHOP3-USER::LOC1-1 SHOP3-USER::LOC6-1) + SHOP3-USER::AIRPLANE-AT-THE-CURRENT-AIRPORT + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1)) + 51) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE7 + SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + 58) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC6-1) + SHOP3-USER::AIRPLANE-ALREADY-THERE + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE1 + SHOP3-USER::LOC6-1)) + 66))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE7 + SHOP3-USER::PLANE1 SHOP3-USER::LOC6-1) + 73))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 + SHOP3-USER::PACKAGE7 SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE7 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + 82) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) + 94))) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-1)) + 81))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE7 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + 95))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK1-1 + SHOP3-USER::PACKAGE7 SHOP3-USER::LOC1-2 SHOP3-USER::LOC1-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE7 + SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-2) + 9) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-1) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK1-1 + SHOP3-USER::LOC1-2 SHOP3-USER::LOC1-1) + 32))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE7 + SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-1) + 33) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK1-1 SHOP3-USER::LOC1-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK1-1 + SHOP3-USER::LOC1-1 SHOP3-USER::LOC1-2) + 8))))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE8 SHOP3-USER::LOC1-1) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK1-1 + SHOP3-USER::PACKAGE8 SHOP3-USER::LOC1-1 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 + SHOP3-USER::PACKAGE8 SHOP3-USER::LOC6-3 SHOP3-USER::LOC6-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE8 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + 35) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-3)) + 10))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE8 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + 11) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-2 SHOP3-USER::LOC6-1) + 34))))) + ((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE8 + SHOP3-USER::LOC6-1 SHOP3-USER::LOC1-1) + SHOP3-USER::FLY-AIRPLANE-FROM-ANY-OTHER-AIRPORT + (((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + NIL NIL) + (1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1 + SHOP3-USER::LOC6-1) + 59) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE8 + SHOP3-USER::PLANE1 SHOP3-USER::LOC6-1) + 67) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE1 + SHOP3-USER::LOC2-1 SHOP3-USER::LOC1-1) + 84))) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + NIL NIL) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE8 + SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + 96) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + NIL NIL))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE9 SHOP3-USER::LOC4-2) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE9 + SHOP3-USER::LOC5-1 SHOP3-USER::LOC4-1) + SHOP3-USER::FLY-AIRPLANE-FROM-ANY-OTHER-AIRPORT + (((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + (1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1 + SHOP3-USER::LOC5-1) + 62) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE9 + SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + 68) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 + SHOP3-USER::LOC3-1 SHOP3-USER::LOC4-1) + 101))) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE9 + SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + 113) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC4-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC4-1) + NIL NIL))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK4-1 + SHOP3-USER::PACKAGE9 SHOP3-USER::LOC4-1 SHOP3-USER::LOC4-2) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK4-1 + SHOP3-USER::LOC4-1)) + 120))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE9 + SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-1) + 121) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK4-1 + SHOP3-USER::LOC4-1 SHOP3-USER::LOC4-2) + 122))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE9 + SHOP3-USER::TRUCK4-1 SHOP3-USER::LOC4-2) + 123))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK5-1 + SHOP3-USER::PACKAGE9 SHOP3-USER::LOC5-2 SHOP3-USER::LOC5-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK5-1 + SHOP3-USER::LOC5-1 SHOP3-USER::LOC5-2) + 12))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE9 + SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-2) + 13) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-1) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK5-1 + SHOP3-USER::LOC5-2 SHOP3-USER::LOC5-1) + 36))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE9 + SHOP3-USER::TRUCK5-1 SHOP3-USER::LOC5-1) + 37))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE11 SHOP3-USER::LOC3-2) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE11 + SHOP3-USER::LOC2-1 SHOP3-USER::LOC3-1) + SHOP3-USER::AIRPLANE-AT-THE-CURRENT-AIRPORT + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1)) + 53) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE11 + SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1) + 60) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 + SHOP3-USER::LOC6-1 SHOP3-USER::LOC3-1) + 86))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE11 + SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) + 99))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK3-1 + SHOP3-USER::PACKAGE11 SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-2) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE11 + SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) + 110) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 + SHOP3-USER::LOC3-2)) + 116))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE11 + SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) + 115) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 + SHOP3-USER::LOC3-1)) + 109))))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 + SHOP3-USER::PACKAGE11 SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE11 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) + 15) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-1)) + 39))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE11 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) + 40) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-3) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-3)) + 14))))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE12 SHOP3-USER::LOC3-3) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE12 + SHOP3-USER::LOC2-1 SHOP3-USER::LOC3-1) + SHOP3-USER::AIRPLANE-AT-THE-CURRENT-AIRPORT + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1)) + 54) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE12 + SHOP3-USER::PLANE3 SHOP3-USER::LOC2-1) + 61) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) + SHOP3-USER::AIRPLANE-ALREADY-THERE + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 + SHOP3-USER::LOC3-1)) + 87))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE12 + SHOP3-USER::PLANE3 SHOP3-USER::LOC3-1) + 100))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK3-1 + SHOP3-USER::PACKAGE12 SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-3) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 + SHOP3-USER::LOC3-1)) + 111))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE12 + SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) + 112) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK3-1 + SHOP3-USER::LOC3-2 SHOP3-USER::LOC3-3) + 118))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE12 + SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-3) + 119))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 + SHOP3-USER::PACKAGE12 SHOP3-USER::LOC2-2 SHOP3-USER::LOC2-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE12 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) + 17) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-1)) + 41))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE12 + SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-1) + 42) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK2-1 SHOP3-USER::LOC2-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK2-1 + SHOP3-USER::LOC2-3 SHOP3-USER::LOC2-2) + 16))))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE13 SHOP3-USER::LOC3-2) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE13 + SHOP3-USER::LOC7-1 SHOP3-USER::LOC3-1) + SHOP3-USER::AIRPLANE-AT-THE-CURRENT-AIRPORT + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1)) + 55) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE13 + SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1) + 63) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC3-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 + SHOP3-USER::LOC6-1 SHOP3-USER::LOC3-1) + 80))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE13 + SHOP3-USER::PLANE2 SHOP3-USER::LOC3-1) + 92))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK3-1 + SHOP3-USER::PACKAGE13 SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-2) + SHOP3-USER::TRUCK-ACROSS-TOWN + ((1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE13 + SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) + 105) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK3-1 + SHOP3-USER::LOC3-1 SHOP3-USER::LOC3-2) + 114))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE13 + SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-2) + 117) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 SHOP3-USER::LOC3-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK3-1 + SHOP3-USER::LOC3-1)) + 104))))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK7-1 + SHOP3-USER::PACKAGE13 SHOP3-USER::LOC7-2 SHOP3-USER::LOC7-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK7-1 + SHOP3-USER::LOC7-1 SHOP3-USER::LOC7-2) + 18))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE13 + SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-2) + 19) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-1) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK7-1 + SHOP3-USER::LOC7-2 SHOP3-USER::LOC7-1) + 43))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE13 + SHOP3-USER::TRUCK7-1 SHOP3-USER::LOC7-1) + 44))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE15 SHOP3-USER::LOC5-1) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE15 + SHOP3-USER::LOC8-1 SHOP3-USER::LOC5-1) + SHOP3-USER::FLY-AIRPLANE-FROM-ANY-OTHER-AIRPORT + (((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + NIL NIL) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE15 + SHOP3-USER::PLANE2 SHOP3-USER::LOC8-1) + 70) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 + SHOP3-USER::LOC3-1 SHOP3-USER::LOC5-1) + 93))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE15 + SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) + 106) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC5-1) + NIL NIL) + (1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1 + SHOP3-USER::LOC8-1) + 64) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + NIL NIL))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK5-1 + SHOP3-USER::PACKAGE15 SHOP3-USER::LOC5-1 SHOP3-USER::LOC5-1) + NIL NIL) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 + SHOP3-USER::PACKAGE15 SHOP3-USER::LOC8-2 SHOP3-USER::LOC8-1) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-2) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 + SHOP3-USER::LOC8-3 SHOP3-USER::LOC8-2) + 20))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE15 + SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-2) + 21) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 + SHOP3-USER::LOC8-1)) + 46))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE15 + SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) + 47))))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE2 SHOP3-USER::LOC2-1) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE2 + SHOP3-USER::LOC1-1 SHOP3-USER::LOC2-1) + SHOP3-USER::AIRPLANE-AT-THE-CURRENT-AIRPORT + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1)) + 24) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE2 + SHOP3-USER::PLANE1 SHOP3-USER::LOC1-1) + 48) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC2-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE1 + SHOP3-USER::LOC6-1 SHOP3-USER::LOC2-1) + 74))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE2 + SHOP3-USER::PLANE1 SHOP3-USER::LOC2-1) + 83))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK2-1 + SHOP3-USER::PACKAGE2 SHOP3-USER::LOC2-1 SHOP3-USER::LOC2-1) + NIL NIL) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK1-1 + SHOP3-USER::PACKAGE2 SHOP3-USER::LOC1-1 SHOP3-USER::LOC1-1) + NIL NIL))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE5 SHOP3-USER::LOC1-1) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE5 + SHOP3-USER::LOC5-1 SHOP3-USER::LOC1-1) + SHOP3-USER::AIRPLANE-AT-THE-CURRENT-AIRPORT + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1)) + 29) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE5 + SHOP3-USER::PLANE3 SHOP3-USER::LOC5-1) + 49) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE3 + SHOP3-USER::LOC5-1 SHOP3-USER::LOC1-1) + 69))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE5 + SHOP3-USER::PLANE3 SHOP3-USER::LOC1-1) + 75))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK1-1 + SHOP3-USER::PACKAGE5 SHOP3-USER::LOC1-1 SHOP3-USER::LOC1-1) + NIL NIL) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK5-1 + SHOP3-USER::PACKAGE5 SHOP3-USER::LOC5-1 SHOP3-USER::LOC5-1) + NIL NIL))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE10 SHOP3-USER::LOC8-3) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE10 + SHOP3-USER::LOC7-1 SHOP3-USER::LOC8-1) + SHOP3-USER::FLY-AIRPLANE-FROM-ANY-OTHER-AIRPORT + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC4-1 + SHOP3-USER::LOC7-1) + 38) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE10 + SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1) + 52) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC8-1) + SHOP3-USER::AIRPLANE-ALREADY-THERE + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE2 + SHOP3-USER::LOC8-1)) + 65))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE10 + SHOP3-USER::PLANE2 SHOP3-USER::LOC8-1) + 71) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE1 SHOP3-USER::LOC8-1) + NIL NIL))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 + SHOP3-USER::PACKAGE10 SHOP3-USER::LOC8-1 SHOP3-USER::LOC8-3) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 + SHOP3-USER::LOC8-1)) + 77))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE10 + SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1) + 78) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 + SHOP3-USER::LOC8-1 SHOP3-USER::LOC8-3) + 88))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE10 + SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) + 89))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK7-1 + SHOP3-USER::PACKAGE10 SHOP3-USER::LOC7-1 SHOP3-USER::LOC7-1) + NIL NIL))) + ((SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE14 SHOP3-USER::LOC6-3) + SHOP3-USER::DIFFERENT-CITY-DELIVER + (((SHOP3-USER::AIR-DELIVER-OBJ SHOP3-USER::PACKAGE14 + SHOP3-USER::LOC7-1 SHOP3-USER::LOC6-1) + SHOP3-USER::AIRPLANE-AT-THE-CURRENT-AIRPORT + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::AIRPLANE-AT SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1)) + 45) + (1.0 + (SHOP3-USER::!LOAD-AIRPLANE SHOP3-USER::PACKAGE14 + SHOP3-USER::PLANE2 SHOP3-USER::LOC7-1) + 56) + ((SHOP3-USER::FLY-AIRPLANE SHOP3-USER::PLANE2 SHOP3-USER::LOC6-1) + SHOP3-USER::FLY-AIRPLANE-IN + ((1.0 + (SHOP3-USER::!FLY-AIRPLANE SHOP3-USER::PLANE2 + SHOP3-USER::LOC8-1 SHOP3-USER::LOC6-1) + 72))) + (1.0 + (SHOP3-USER::!UNLOAD-AIRPLANE SHOP3-USER::PACKAGE14 + SHOP3-USER::PLANE2 SHOP3-USER::LOC6-1) + 79))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK6-1 + SHOP3-USER::PACKAGE14 SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) + SHOP3-USER::TRUCK-ACROSS-TOWN + (((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + SHOP3-USER::TRUCK-IN-RIGHT-LOCATION + ((0 + (SHOP3-USER::!ADD-PROTECTION + (SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-1)) + 90))) + (1.0 + (SHOP3-USER::!LOAD-TRUCK SHOP3-USER::PACKAGE14 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-1) + 91) + ((SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + SHOP3-USER::TRUCK-NOT-IN-RIGHT-LOCATION + ((1.0 + (SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK6-1 + SHOP3-USER::LOC6-1 SHOP3-USER::LOC6-3) + 102))) + (1.0 + (SHOP3-USER::!UNLOAD-TRUCK SHOP3-USER::PACKAGE14 + SHOP3-USER::TRUCK6-1 SHOP3-USER::LOC6-3) + 103))) + ((SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK7-1 + SHOP3-USER::PACKAGE14 SHOP3-USER::LOC7-1 SHOP3-USER::LOC7-1) + NIL NIL))))) (defparameter +expected-operator-nodes+ '((1.0 @@ -1211,45 +1467,63 @@ (mapcar #'(lambda (x) (primitive-node-task x)) all-primitive-nodes)))))))) - -(test plan-tree ; 27 checks +(test canonical-ordering ; 3 tests (multiple-value-bind (plans ignore trees) (find-plans 'log-ran-15-1 :plan-tree t :verbose 0) - ;; a good test would involve grabbing the *subtask-parents* and the - ;; *operator-tasks* tables. Need to think about how to get those - ;; saved. [2023/05/26:rpg] (declare (ignore ignore)) - (let* ((tree (canonically-order (first trees))) - (root (first tree))) - (is-true (every #'complex-node-p tree)) - ;; expected-plan-tree is really a forest, - ;; as is TREE. - (loop for atree in (canonically-order +expected-plan-tree+) - as other = (find (complex-node-task atree) - tree - :key #'complex-node-task - :test 'equalp) - do (is (equalp atree other))) - (is (equalp - '(SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE1 SHOP3-USER::LOC8-1) - (complex-node-task (first tree)))) - (is (equalp (tree-node-task (first tree)) - (complex-node-task (first tree)))) - (let ((first-subtask - (first (complex-node-children (first tree))))) - (is-true (complex-node-p first-subtask)) - (is (equalp '(SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 - SHOP3-USER::PACKAGE1 SHOP3-USER::LOC8-3 SHOP3-USER::LOC8-1) - (tree-node-task first-subtask))) - (let ((truck-at (first (complex-node-children first-subtask)))) - (is-true (complex-node-p truck-at)) - (is (equalp '(SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) - (complex-node-task truck-at))) - (is (= 1 (length (complex-node-children truck-at)))) - (let ((prim (first (complex-node-children truck-at)))) - (is-true (primitive-node-p prim)) - (is (equalp '(SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1 - SHOP3-USER::LOC8-3) - (primitive-node-task prim))) - (is (= (primitive-node-position prim) 0)) - (is (= (primitive-node-cost prim) 1)))))))) + (is-true (first trees)) + (let* ((tree (first trees)) + (tree-length (length tree)) + (ordered (canonically-order-plan-tree tree)) + (ordered-tree-length (length ordered))) + (is-true (= tree-length ordered-tree-length) + "Canonically ordering tree changes its length from ~d to ~d" + tree-length ordered-tree-length))) + (let* ((tree +expected-plan-tree+) + (tree-length (length tree)) + (ordered (canonically-order-plan-tree tree)) + (ordered-tree-length (length ordered))) + (is-true (= tree-length ordered-tree-length) + "Canonically ordering +expected-tree+ changes its length from ~d to ~d" + tree-length ordered-tree-length))) + + +(test plan-tree ; 27 checks + (let* ((trees + (nth-value 2 (find-plans 'log-ran-15-1 :plan-tree t :verbose 0))) + (tree (canonically-order-plan-tree (first trees)))) + (is-true (every #'complex-node-p tree)) + ;; expected-plan-tree is really a forest, + ;; as is TREE. + (loop for atree in (canonically-order-plan-tree +expected-plan-tree+) + as task = (complex-node-task atree) + as other = (find task + tree + :key #'complex-node-task + :test 'equalp) + unless other + do (error "Did not find a tree rooted at ~S in newly-computed plan tree." task) + do (is (equalp atree other))) + (is (equalp + '(SHOP3-USER::OBJ-AT SHOP3-USER::PACKAGE1 SHOP3-USER::LOC8-1) + (complex-node-task (first tree)))) + (is (equalp (tree-node-task (first tree)) + (complex-node-task (first tree)))) + (let ((first-subtask + (first (complex-node-children (first tree))))) + (is-true (complex-node-p first-subtask)) + (is (equalp '(SHOP3-USER::IN-CITY-DELIVERY SHOP3-USER::TRUCK8-1 + SHOP3-USER::PACKAGE1 SHOP3-USER::LOC8-3 SHOP3-USER::LOC8-1) + (tree-node-task first-subtask))) + (let ((truck-at (first (complex-node-children first-subtask)))) + (is-true (complex-node-p truck-at)) + (is (equalp '(SHOP3-USER::TRUCK-AT SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-3) + (complex-node-task truck-at))) + (is (= 1 (length (complex-node-children truck-at)))) + (let ((prim (first (complex-node-children truck-at)))) + (is-true (primitive-node-p prim)) + (is (equalp '(SHOP3-USER::!DRIVE-TRUCK SHOP3-USER::TRUCK8-1 SHOP3-USER::LOC8-1 + SHOP3-USER::LOC8-3) + (primitive-node-task prim))) + (is (= (primitive-node-position prim) 0)) + (is (= (primitive-node-cost prim) 1))))))) diff --git a/shop3/tests/theorem-prover-tests.lisp b/shop3/tests/theorem-prover-tests.lisp index 6f1fa1ca..d6d319f2 100644 --- a/shop3/tests/theorem-prover-tests.lisp +++ b/shop3/tests/theorem-prover-tests.lisp @@ -43,7 +43,7 @@ ;;; ---------------------------------------------------------------------- (defpackage shop-theorem-prover-tests - (:shadowing-import-from #:shop3.theorem-prover #:fail) + (:shadowing-import-from #:shop3.theorem-prover #:fail #:random) (:import-from #:shop3.theorem-prover #:seek-satisfiers #:*domain*) (:use common-lisp shop3.theorem-prover fiveam)) @@ -207,4 +207,26 @@ (is (eq (second ; the value (first (second expansion))) ;the binding form '*domain*))))) +(def-suite* test-new-random :in theorem-prover-tests) +(test random-repeatable + (fiveam:is (eq 'random 'shopthpr::random)) + (fiveam:is-false (eq 'random 'cl:random)) + (let ((new-generator (random-state:make-generator :squirrel (random-state:hopefully-sufficiently-random-seed))) + sequence1 sequence2) + (let ((shopthpr:*random-generator* (random-state:copy new-generator))) + (fiveam:is (equalp shopthpr:*random-generator* new-generator)) + (setf sequence1 (let (sequence) + (dotimes (x 10) + (push + (random 10) + sequence)) + sequence))) + (let ((shopthpr:*random-generator* (random-state:copy new-generator))) + (setf sequence2 (let (sequence) + (dotimes (x 10) + (push + (random 10) + sequence)) + sequence))) + (fiveam:is (equalp sequence1 sequence2)))) diff --git a/shop3/theorem-prover/decls.lisp b/shop3/theorem-prover/decls.lisp index b3999ce4..9857cf14 100644 --- a/shop3/theorem-prover/decls.lisp +++ b/shop3/theorem-prover/decls.lisp @@ -80,6 +80,22 @@ the first match.") state inside FIND-SATISFIERS, qv., giving axioms access to the state data structure.")) +(defparameter *random-generator* + ;;; by default use non-repeatable randomness + (random-state:make-generator :squirrel) + "For cross-implementation repeatability, use the RANDOM-STATE library +for random generation.") + +(defun shop-random (limit &optional (random-state *random-generator*)) + "SHOP-specific random number generator, based on RANDOM-STATE library. +API as for CL:RANDOM-STATE." + (random limit random-state)) + +(defun random (limit &optional (random-state *random-generator*)) + "SHOP-specific random number generator, based on RANDOM-STATE library. +Synonym for SHOP-RANDOM. API as for CL:RANDOM-STATE." + (random-state:random limit random-state)) + (defgeneric axioms (thpr-domain predicate) (:documentation "Return a list of all the SHOP axioms for PREDICATE in THPR-DOMAIN.") diff --git a/shop3/theorem-prover/package-thpr.lisp b/shop3/theorem-prover/package-thpr.lisp index f493a155..3071e502 100644 --- a/shop3/theorem-prover/package-thpr.lisp +++ b/shop3/theorem-prover/package-thpr.lisp @@ -62,6 +62,7 @@ (:nicknames :shopthpr :shop.theorem-prover) (:use :common-lisp :shop3.common :shop3.unifier :iterate) (:import-from #:shop3.common #:add-atom-to-state #:state-atoms #:domain-core) + (:shadow #:random) ;; make these symbols available for import ;; to pddl/fluents.lisp (package shop.pddl-fluents) (:intern @@ -79,6 +80,8 @@ #:*state* #:*domain* + #:*random-generator* + #:def-logical-keyword ;; the unifier interface