diff --git a/jenkins/ext/pddl-tools b/jenkins/ext/pddl-tools index e1c2718e..48be4f34 160000 --- a/jenkins/ext/pddl-tools +++ b/jenkins/ext/pddl-tools @@ -1 +1 @@ -Subproject commit e1c2718ecf208fe5c56cdabb169fa7045658ef7c +Subproject commit 48be4f34502ee5d1aa426570114d78e727a5e393 diff --git a/shop3/decls.lisp b/shop3/decls.lisp index eb62324c..e12db6ab 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 (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* diff --git a/shop3/explicit-stack-search/explicit-search.lisp b/shop3/explicit-stack-search/explicit-search.lisp index 95de9fba..07c9cf0d 100644 --- a/shop3/explicit-stack-search/explicit-search.lisp +++ b/shop3/explicit-stack-search/explicit-search.lisp @@ -514,7 +514,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/hddl/hddl-plan.lisp b/shop3/hddl/hddl-plan.lisp new file mode 100644 index 00000000..fbfcb6ad --- /dev/null +++ b/shop3/hddl/hddl-plan.lisp @@ -0,0 +1,198 @@ +(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) + +(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 + )) + +(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) + (plan-tree:tree-node-task 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 ((shop:complex-node-p node) + (shop:complex-node-task node)) + ((typep node 'plan-tree:complex-tree-node) + (plan-tree: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 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)))) + +;;; 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)) + +(defun resolve-extended-plan-tree-children (children) + (alexandria:mappend #'resolve-extended-plan-tree-child children)) + + +(defun resolve-extended-plan-tree-child (child) + (etypecase child + ((or plan-tree:ordered-tree-node plan-tree:unordered-tree-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)))) + +(defun hddl-plan (plan tree) + "Take a SHOP PLAN and TREE (really a forest) as input and produce an +HDDL plan encoded as an s-expression." + (multiple-value-bind (indexed-plan task-indices) + (index-shop-plan (shop:shorter-plan plan)) + (let ((next-index (1+ (caar (last indexed-plan)))) + (root-tasks (forest-roots tree)) + roots decompositions) + (labels ((task-index (task) + (if-let ((value (gethash task task-indices))) + value + (prog1 + (setf (gethash task task-indices) next-index) + (incf next-index)))) + (node-index (node) + (task-index (tree-node-task node)))) + (setf roots + (iter (for root in root-tasks) + (setf (gethash root task-indices) next-index) + (collecting next-index) + (incf next-index))) + (setf decompositions + (let ((open (etypecase tree + (list tree) + (plan-tree:top-node (resolve-extended-plan-tree-child tree)))) + retval + (visited (make-hash-table :test 'eql))) + (iter + (while open) + (as node = (pop open)) + (as id = (task-index (tree-node-task node))) + (unless (gethash id visited) + (when (complex-node-p node) + (setf (gethash id visited) t) + (let ((children (complex-node-children node))) + (iter (for child in children) + (with index) + (unless (shop::internal-operator-p + (shop:task-name (tree-node-task child))) + (setf index (node-index child)) + (when (complex-node-p child) + (push child open)) + (collecting index into child-indices)) + (finally (push (make-decomposition-record :node-id id + :task (complex-node-task node) + :method-name (complex-node-reduction-label node) + :children child-indices) + retval) + (setf open (append children open)))))))) + (reverse retval)))) + `(:hddl-plan + :actions ,indexed-plan + :roots ,roots + :decompositions ,decompositions + )))) + +#-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 tree-decompositions) + (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) (values list hash-table &optional)) + index-shop-plan)) +(defun index-shop-plan (action-list) + (let ((hash-table (make-hash-table :test 'eq)) + (assoc-table + (iter (for a in action-list) + (as i from 1) + (collecting (cons i a))))) + (iter (for (i . act) in assoc-table) + (setf (gethash act hash-table) i)) + (values assoc-table hash-table))) + +(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/hddl/package.lisp b/shop3/hddl/package.lisp new file mode 100644 index 00000000..191f7f6f --- /dev/null +++ b/shop3/hddl/package.lisp @@ -0,0 +1,6 @@ +(in-package :common-lisp-user) + +(defpackage hddl-translator + (:nicknames #:shop-hddl #:hddl-shop) + (:export #:hddl-plan) + (:use :common-lisp :alexandria :iterate)) diff --git a/shop3/package.lisp b/shop3/package.lisp index 088bcd00..62d0e4c2 100644 --- a/shop3/package.lisp +++ b/shop3/package.lisp @@ -243,7 +243,7 @@ #:adl-mixin #:adl-domain #:fluents-mixin - + ;; MIXIN #:pure-logic-domain-mixin @@ -259,10 +259,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 @@ -284,7 +287,7 @@ #:singleton-variable #:incorrect-arity-error #:incomplete-dependency-error - + ;; things you might want to use in your domain definitions #:variablep @@ -316,6 +319,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/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 899331fa..c772e28b 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) @@ -285,6 +288,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 +337,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. @@ -359,7 +369,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..31f64921 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 + (alexandria:nconcf *reduction-labels* + (mapcar #'(lambda (subtask) (cons subtask 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*))) @@ -135,9 +140,11 @@ 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))) + (let ((label (alexandria:assoc-value *reduction-labels* (first children)))) + (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 +250,9 @@ 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)))))) +;;; Introduced an OPERATOR-NODE structure as a way of better + +;;; I think 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/shop3.asd b/shop3/shop3.asd index 0dfcd80e..c81bf43f 100644 --- a/shop3/shop3.asd +++ b/shop3/shop3.asd @@ -140,7 +140,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 @@ -173,6 +175,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 +196,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 ;;;--------------------------------------------------------------------------- @@ -373,7 +378,8 @@ shop3." "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..9c3d6f40 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* nil) (*collect-state* (or collect-state plan-tree)) (*subtask-parents* (make-subtask-parents-table)) (*operator-tasks* (make-operator-task-table)) diff --git a/shop3/tests/hddl-tests.lisp b/shop3/tests/hddl-tests.lisp new file mode 100644 index 00000000..b1f18cd3 --- /dev/null +++ b/shop3/tests/hddl-tests.lisp @@ -0,0 +1,1209 @@ +(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)))) + +#+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) + (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)))))) + + +(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)))))))