diff --git a/.bashrc b/.bashrc new file mode 100644 index 000000000..e3e9b075e --- /dev/null +++ b/.bashrc @@ -0,0 +1,2 @@ + +conda activate pddl-generators diff --git a/.gitignore b/.gitignore index 022dce92e..52257da16 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ *.o +**/__pycache__/ Makefile.depend .tox/ +*~ +#* +*.egg-info assembly/assembly blocksworld/3ops/2pddl/2pddl blocksworld/4ops/2pddl/2pddl diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 000000000..2c222da6b --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,49 @@ +include pddl_generators/**/*.pddl +include pddl_generators/*/README* +include pddl_generators/assembly/assembly +include pddl_generators/__blocksworld/3ops/2pddl/2pddl +include pddl_generators/__blocksworld/4ops/2pddl/2pddl +include pddl_generators/__blocksworld/bwstates.1/bwstates +include pddl_generators/__blocksworld/matching/2pddl-typed +include pddl_generators/__blocksworld/matching/2pddl-untyped +include pddl_generators/briefcaseworld/briefcaseworld +include pddl_generators/depots/depots +include pddl_generators/driverlog/dlgen +include pddl_generators/elevators/generate_data +include pddl_generators/elevators/generate_pddl +include pddl_generators/ferry/ferry +include pddl_generators/freecell/freecell +include pddl_generators/fridge/fridge +include pddl_generators/goldminer/gold-miner-generator +include pddl_generators/grid/grid +include pddl_generators/gripper/gripper +include pddl_generators/grippers/grippers +include pddl_generators/hanoi/hanoi +include pddl_generators/logistics/logistics +include pddl_generators/maintenance/maintenance +include pddl_generators/miconic/miconic +include pddl_generators/miconic-fulladl/miconic +include pddl_generators/miconic-simpleadl/miconic +include pddl_generators/movie/movie +include pddl_generators/mprime/mprime +include pddl_generators/mystery/mystery +include pddl_generators/nomystery/nomystery +include pddl_generators/npuzzle/n-puzzle-generator +include pddl_generators/openstacks/generate_pddl +include pddl_generators/openstacks/generate_problems +include pddl_generators/pathways/pathways +include pddl_generators/rovers/rovgen +include pddl_generators/satellite/satgen +include pddl_generators/schedule/schedule +include pddl_generators/storage/storage +include pddl_generators/sokoban/random/sokoban-generator-typed +include pddl_generators/sokoban/random/sokoban-generator-untyped +include pddl_generators/tidybot/tidybot.jar +include pddl_generators/tpp/tpp +include pddl_generators/trucks/trucks +include pddl_generators/trucks/adl2strips/ff +include pddl_generators/tsp/tsp +include pddl_generators/turnandopen/turnandopen +include pddl_generators/tyreworld/tyreworld +include pddl_generators/visitall/grid +include pddl_generators/zenotravel/ztravel diff --git a/copy-template.sh b/copy-template.sh new file mode 100755 index 000000000..2ef2a373f --- /dev/null +++ b/copy-template.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +domain=$1 + +cp pddl_generators/__template/* -t pddl_generators/$domain/ +echo pddl_generators/$domain/__init__.py diff --git a/demo.sh b/demo.sh new file mode 100755 index 000000000..29d3a555a --- /dev/null +++ b/demo.sh @@ -0,0 +1,29 @@ +#!/bin/bash + + +pddl-generators -h | less + +pddl-generators --helpall | less + +pddl-generators blocksworld-3ops -- -h | less + +pddl-generators --seed 42 blocksworld-4ops -- 5 +pddl-generators --seed 42 blocksworld-4ops -- 5 +pddl-generators --seed 44 blocksworld-4ops -- 5 +pddl-generators --seed 44 blocksworld-4ops -- 5 +pddl-generators --seed 42 blocksworld-4ops -- 6 +pddl-generators --seed 42 blocksworld-4ops -- 6 + + + +pddl-generators visitall -- 5 5 0.5 + +pddl-generators --output-directory result visitall -- 5 5 0.5 +pddl-generators --output $HOME/problem.pddl visitall -- 5 5 0.5 +pddl-generators --output problem.pddl visitall -- 5 5 0.5 + + + +pddl-generators pathways -- -h +pddl-generators pathways -- 12 1 3 +pddl-generators --seed 33 pathways -- 12 1 3 diff --git a/environment.yml b/environment.yml new file mode 100644 index 000000000..35c98701d --- /dev/null +++ b/environment.yml @@ -0,0 +1,6 @@ +name: pddl-generators +dependencies: + - python=3.9 + - pip + - pip: + - -e . diff --git a/pddl_generators/Makefile b/pddl_generators/Makefile new file mode 100644 index 000000000..b0f5c4ec2 --- /dev/null +++ b/pddl_generators/Makefile @@ -0,0 +1,4 @@ + + +all: + for d in */ ; do cmake -S $$d -B $$d ; $(MAKE) -C $$d ; done diff --git a/pddl_generators/__init__.py b/pddl_generators/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pddl_generators/__main__.py b/pddl_generators/__main__.py new file mode 100644 index 000000000..345e320c1 --- /dev/null +++ b/pddl_generators/__main__.py @@ -0,0 +1,5 @@ + +from . import main + +main.main() + diff --git a/pddl_generators/__template/__init__.py b/pddl_generators/__template/__init__.py new file mode 100644 index 000000000..c4311e43a --- /dev/null +++ b/pddl_generators/__template/__init__.py @@ -0,0 +1,54 @@ + + +# Each module M must implement following attributes: +# +# 1. M.main : A main function which takes two argparser.Namespace instances, args and +# args2. args is largely irrelevant except args.seed , which was +# supplied by the command line argument. +# +# 2. M.parser : A parser , which parses the "rest" arguments that are specific to each domain. +# +# 3. M.domain_file : An absolute pathname to the domain pddl file, or None when the domain file is produced. + + + + + + + + +import os.path +import argparse +from pddl_generators.main import run +import pathlib + +def rel(path): return os.path.join(os.path.dirname(__file__), path) + + + +domain_file = rel("domain.pddl") + + +parser = argparse.ArgumentParser( + # choose either one which suits the best + formatter_class = argparse.ArgumentDefaultsHelpFormatter, + formatter_class = argparse.RawDescriptionHelpFormatter, + # use this to fill it manually + description = "", + # use this to read an existing README file + description = pathlib.Path(rel("README")).read_text(), + description = pathlib.Path(rel("README.txt")).read_text(), +) + + +parser.add_argument("", type=int, help="the number of ") + + +def main(args : argparse.Namespace, args2 : argparse.Namespace): + + with open(args.output, mode="w") as f: + run(args,list(map(str,[rel(PROGRAM), args.seed, args.output, *args.rest])), + stdout=f) + + pass + diff --git a/pddl_generators/main.py b/pddl_generators/main.py new file mode 100644 index 000000000..d1c709091 --- /dev/null +++ b/pddl_generators/main.py @@ -0,0 +1,140 @@ + +import os +import os.path +import glob +import argparse +import textwrap + + + + + +parser = argparse.ArgumentParser( + formatter_class = argparse.RawTextHelpFormatter, + description = + textwrap.fill( + "Generates a problem file for a given domain and a set of hyperparameters. " + "Depending on the domain, it also produces a domain file (e.g., ADL domain compiled to strips). " + "In the default behavior, it generates the file(s) to a specified location, then print " + "the absolute pathname of the problem file and the domain file in two separate lines. " + "The second line (the domain file) can be a file generated by the generator, " + "or a fixed pddl file that is shared by problems. " + "When --output STDOUT is given, the output is printed to the standard output (see options for --output). ", 100) +) + + +parser.add_argument("domain", + metavar="domain", + nargs="?", # note: for --help and --helpall to work + choices=domains, + help="domain name, one of: \n" + textwrap.fill(", ".join(domains), 100)) + +parser.add_argument("--output-directory","-d", + default="output", + metavar="DIRNAME", + help= + "Directory to store the generated files. \n" + "If the directory does not exist, it creates it first (including the parents). \n" + ) + +parser.add_argument("--output","-o", + metavar="FILENAME1", + help= + "If given, override the default name handling for problem file generation. \n" + "If the pathname is absolute, it is used as it is; DIRNAME is ignored. \n" + "If the pathname is relative, it is seen as a path relative to DIRNAME. \n" + "\n" + "If not given, the file is stored under DIRNAME and as {hash}.pddl , where \n" + "{hash} is a md5 hash of the parameters given to each generator. \n" + "\n" + "If the generator also generates a compiled domain file, it is written to a file with \n" + "a suffix {basename}-domain.pddl where {basename} is the basename of the problem file. \n" + "You can override this behavior with --output-domain. \n" + "\n" + "If the argument is STDOUT, it writes to the standard output. \n" + "If the argument is STDOUT for a domain that also generates a domain file, two outputs are \n" + "separated by a separator specified by --separator option. \n" + "\n" + "In all cases, the output contains a meta-information of how the generator was called \n" + "in a form of Lisp-style comment with each line starting with ;; . \n" + "The format mimicks File-Local Variable of Emacs \n" + "(see https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html). \n" + "\n" + "It contains several fields: \n" + "The first line contains 'pddl-generators:'. \n" + "'command:' field contains the exact command line used to run the generator, \n" + "'dict:' field which contains a dictionary which was parsed from the command line, and \n" + "'date:' field contains the date of creation. \n" + "The last line contains 'end:'. \n" + ) + +parser.add_argument("--output-domain", + metavar="FILENAME2", + help= + "If given, override the default name handling for domain file generation. \n" + "If the pathname is absolute, it is used as it is; DIRNAME is ignored. \n" + "If the pathname is relative, it is seen as a path relative to DIRNAME. \n" + "\n" + "If missing and the generator generates a new domain file for each problem instance, \n" + "the filename defaults to {basename}-domain.pddl \n" + "where {basename} is the basename of FILENAME1. \n" + "\n" + "If missing and the domain comes with a shared domain file, \n" + "the value is set to the path of the domain file inside pddl-generator source tree \n" + "(likely under site-packages/). \n" + "\n" + "Finally, if given while the domain comes with a shared domain file, \n" + "it copies the domain file to the specified location. \n" + ) + +parser.add_argument("--separator", + default=";; domain file", + help= + "See --output. When the generator produces both a problem and a domain file, \n" + "and if the --output is specified as STDOUT, two files are concatenated with \n" + "a line containing the string specified by this option. ") + +parser.add_argument("--seed","-s", + type=int, + default=42, + help="Random seed.") + +parser.add_argument("--helpall", + action="store_true", + help="Generate help messages for all domains.") + +parser.add_argument("--list","-l", + action="store_true", + help="List available domains.") + +parser.add_argument("--debug", + action="store_true", + help="Enable a more verbose debugging mode.") + +# parser.add_argument("--remove-trivial", +# action="store_true", +# help="Remove an instance whose initial state already satisfies its goal condition.\n" +# " NOT IMPLEMENTED YET, work in progress.") +# +# parser.add_argument("--remove-cost", +# action="store_true", +# help="Remove action cost from the generated instances.\n" +# " Also from the domain, if it generates a domain compiled from ADL.\n" +# " NOT IMPLEMENTED YET, work in progress.") +# +# parser.add_argument("--remove-delete", +# action="store_true", +# help="Remove delete effects from the domain, if it generates a domain compiled from ADL.\n" +# " NOT IMPLEMENTED YET, work in progress.") + + +parser.add_argument("rest", + nargs="*", + help="Remaining command line arguments for each domain.") + + +def main(args): + pass + + + diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..03a2468f2 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +#! /bin/env python3 + + +import subprocess + +print("building all PDDL generator binaries ...") +subprocess.run(["make", "-C", "pddl_generators"]) + + +from setuptools import setup, find_packages + + +setup(name='pddl-generators', + version='1.0', + description='An unofficial collection of PDDL generators, ' + 'some of which have been used to generate benchmarks for ' + 'the International Planning Competitions (IPC).', + author='Jendrik Seipp', + author_email='jendrikseipp@gmail.com', + url='https://github.com/AI-Planning/pddl-generators', + # note: the hyphen in the "package name" is converted to underscore here + entry_points={"console_scripts":["pddl-generators = pddl_generators.main:main"]}, + packages=find_packages(), + install_requires=["z3","numpy"], + include_package_data=True, + ) +