Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HDDL output for ESS SHOP. #152

Merged
merged 33 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e31438d
Extend SHOP plan trees to record method names.
rpgoldman Jul 16, 2023
a5fc7c1
Partial HDDL export support.
rpgoldman Jul 25, 2023
6a62b65
Add shop3/hddl system.
rpgoldman Sep 1, 2023
2d55638
Update PDDL and HDDL utils to version 3.1.
rpgoldman Oct 18, 2023
405c263
Full version of HDDL plan output.
rpgoldman Oct 18, 2023
f2dd4f0
Add tests for HDDL plan generation.
rpgoldman Oct 19, 2023
31595a3
ESS plan trees can be translated into HDDL plans.
rpgoldman Oct 20, 2023
36d0d2e
Fix type declaration causing SBCL to warn.
rpgoldman Oct 24, 2023
28387d7
Fix symbol name conflict.
rpgoldman Oct 24, 2023
c602ef1
Update SHOP package names.
rpgoldman Oct 24, 2023
5012bef
Update PDDL-TOOLS library.
rpgoldman Oct 25, 2023
2587f7a
Attempt to fix plan tree tests.
rpgoldman Oct 26, 2023
5ef066e
Add HDDL output from ESS.
rpgoldman Nov 3, 2023
88404dc
Minor plan tree enhancements.
rpgoldman Nov 3, 2023
fd98ec7
Fix reduction label handling in classic SHOP trees.
rpgoldman Nov 4, 2023
e35df8d
Disable HDDL plan tree output on classic SHOP.
rpgoldman Nov 4, 2023
b4a3155
Add README for buildapp-base applications.
rpgoldman Nov 6, 2023
1f2f953
Add CL applications and HDDL support to the manual.
rpgoldman Nov 6, 2023
09f329a
Fix tree and task matching.
rpgoldman Nov 28, 2023
71853ad
Fixed indexing nodes for HDDL output.
rpgoldman Nov 6, 2023
a4d96b4
Add PDDL output option to SHOP CLI apps.
rpgoldman Nov 6, 2023
edecd0f
Revise SHOP to use the random-state library for random choices.
rpgoldman Nov 28, 2023
f394ab5
Bump version to 3.12
rpgoldman Nov 28, 2023
abafc0f
Improve documentation only.
rpgoldman Jan 18, 2024
21fcbdd
Pull out plan-repair helper functions.
rpgoldman Feb 29, 2024
3bef4b2
Export PLAN-RETURN class name.
rpgoldman Feb 29, 2024
c1393e8
Add `orphans-ok` keyword argument to `hddl-plan`.
rpgoldman Feb 29, 2024
274ada5
Remove support for `:rationale` argument.
rpgoldman Aug 2, 2024
e2fa86e
Shadow CL:CHECK-TYPE.
rpgoldman Aug 2, 2024
7605276
External updates.
rpgoldman Aug 2, 2024
ae7c77c
Update test count.
rpgoldman Aug 3, 2024
f7ac23d
Minor improvements from lacrosse-0.
rpgoldman Aug 4, 2024
fe7eb75
Use install in Makefile.
rpgoldman Aug 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion jenkins/ext/VAL
Submodule VAL updated 1 files
+966 −948 src/main.cpp
3 changes: 2 additions & 1 deletion shop3/buildapp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions shop3/buildapp/README.md
Original file line number Diff line number Diff line change
@@ -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.
195 changes: 130 additions & 65 deletions shop3/buildapp/shop-app-entrypoints.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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."
Expand All @@ -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."
Expand All @@ -116,67 +151,96 @@
(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)
(unless *interactive*
(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*)))
Expand All @@ -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)
Expand All @@ -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))
Expand Down
Loading
Loading